source: aim.c @ 0552482

release-1.10release-1.7release-1.8release-1.9
Last change on this file since 0552482 was 0552482, checked in by Nelson Elhage <nelhage@mit.edu>, 14 years ago
aim: Remove some terrifying and fortunately dead code. It, uh, seems to send parts of a requested file to the AIM server. Signed-off-by: Geoffrey Thomas <geofft@mit.edu>
  • Property mode set to 100644
File size: 59.7 KB
Line 
1#include <stdio.h>
2#include <stdio.h>
3#include <sys/stat.h>
4#include "owl.h"
5
6/**********************************************************************/
7
8struct owlfaim_priv {
9  char *screenname;
10  char *password;
11  char *server;
12  int connected;
13};
14
15static const char *msgerrreasons[] = {
16        "Invalid error",
17        "Invalid SNAC",
18        "Rate to host",
19        "Rate to client",
20        "Not logged on",
21        "Service unavailable",
22        "Service not defined",
23        "Obsolete SNAC",
24        "Not supported by host",
25        "Not supported by client",
26        "Refused by client",
27        "Reply too big",
28        "Responses lost",
29        "Request denied",
30        "Busted SNAC payload",
31        "Insufficient rights",
32        "In local permit/deny",
33        "Too evil (sender)",
34        "Too evil (receiver)",
35        "User temporarily unavailable",
36        "No match",
37        "List overflow",
38        "Request ambiguous",
39        "Queue full",
40        "Not while on AOL",
41};
42static int msgerrreasonslen = 25;
43
44static void faimtest_debugcb(aim_session_t *sess, int level, const char *format, va_list va);
45static int faimtest_parse_login(aim_session_t *sess, aim_frame_t *fr, ...);
46static int faimtest_parse_authresp(aim_session_t *sess, aim_frame_t *fr, ...);
47int faimtest_flapversion(aim_session_t *sess, aim_frame_t *fr, ...);
48int faimtest_conncomplete(aim_session_t *sess, aim_frame_t *fr, ...);
49void addcb_bos(aim_session_t *sess, aim_conn_t *bosconn);
50static int conninitdone_bos(aim_session_t *sess, aim_frame_t *fr, ...);
51static int conninitdone_admin(aim_session_t *sess, aim_frame_t *fr, ...);
52static int conninitdone_chat     (aim_session_t *, aim_frame_t *, ...);
53int logout(aim_session_t *sess);
54
55static int faimtest_parse_connerr(aim_session_t *sess, aim_frame_t *fr, ...);
56static int faimtest_accountconfirm(aim_session_t *sess, aim_frame_t *fr, ...);
57static int faimtest_infochange(aim_session_t *sess, aim_frame_t *fr, ...);
58static int faimtest_handleredirect(aim_session_t *sess, aim_frame_t *fr, ...);
59static int faimtest_icbmparaminfo(aim_session_t *sess, aim_frame_t *fr, ...);
60static int faimtest_parse_buddyrights(aim_session_t *sess, aim_frame_t *fr, ...);
61static int faimtest_bosrights(aim_session_t *sess, aim_frame_t *fr, ...);
62static int faimtest_locrights(aim_session_t *sess, aim_frame_t *fr, ...);
63static int faimtest_reportinterval(aim_session_t *sess, aim_frame_t *fr, ...);
64/* static int reportinterval(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs); */
65static int faimtest_parse_motd(aim_session_t *sess, aim_frame_t *fr, ...);
66/* static void printuserflags(fu16_t flags); */
67static int faimtest_parse_userinfo(aim_session_t *sess, aim_frame_t *fr, ...);
68static int faimtest_parse_incoming_im_chan1(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch1_args *args);
69static int faimtest_parse_incoming_im_chan2(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args);
70static int faimtest_parse_incoming_im(aim_session_t *sess, aim_frame_t *fr, ...);
71static int faimtest_parse_oncoming(aim_session_t *sess, aim_frame_t *fr, ...);
72static int faimtest_parse_offgoing(aim_session_t *sess, aim_frame_t *fr, ...);
73int faimtest_parse_genericerr(aim_session_t *sess, aim_frame_t *fr, ...);
74static int faimtest_parse_msgerr(aim_session_t *sess, aim_frame_t *fr, ...);
75static int faimtest_parse_locerr(aim_session_t *sess, aim_frame_t *fr, ...);
76static int faimtest_parse_misses(aim_session_t *sess, aim_frame_t *fr, ...);
77static int faimtest_parse_msgack(aim_session_t *sess, aim_frame_t *fr, ...);
78static int faimtest_parse_ratechange(aim_session_t *sess, aim_frame_t *fr, ...);
79static int faimtest_parse_evilnotify(aim_session_t *sess, aim_frame_t *fr, ...);
80static int faimtest_parse_searchreply(aim_session_t *sess, aim_frame_t *fr, ...);
81static int faimtest_parse_searcherror(aim_session_t *sess, aim_frame_t *fr, ...);
82static int handlepopup(aim_session_t *sess, aim_frame_t *fr, ...);
83static int serverpause(aim_session_t *sess, aim_frame_t *fr, ...);
84static int migrate(aim_session_t *sess, aim_frame_t *fr, ...);
85static int ssirights(aim_session_t *sess, aim_frame_t *fr, ...);
86static int ssidata(aim_session_t *sess, aim_frame_t *fr, ...);
87static int ssidatanochange(aim_session_t *sess, aim_frame_t *fr, ...);
88static int offlinemsg(aim_session_t *sess, aim_frame_t *fr, ...);
89static int offlinemsgdone(aim_session_t *sess, aim_frame_t *fr, ...);
90/*
91static int faimtest_ssi_parseerr     (aim_session_t *, aim_frame_t *, ...);
92static int faimtest_ssi_parserights  (aim_session_t *, aim_frame_t *, ...);
93static int faimtest_ssi_parselist    (aim_session_t *, aim_frame_t *, ...);
94static int faimtest_ssi_parseack     (aim_session_t *, aim_frame_t *, ...);
95static int faimtest_ssi_authgiven    (aim_session_t *, aim_frame_t *, ...);
96static int faimtest_ssi_authrequest  (aim_session_t *, aim_frame_t *, ...);
97static int faimtest_ssi_authreply    (aim_session_t *, aim_frame_t *, ...);
98static int faimtest_ssi_gotadded     (aim_session_t *, aim_frame_t *, ...);
99*/
100
101void chatnav_redirect(aim_session_t *sess, struct aim_redirect_data *redir);
102void chat_redirect(aim_session_t *sess, struct aim_redirect_data *redir);
103
104/*****************************************************************/
105
106void owl_aim_init(void)
107{
108  /* this has all been moved to owl_aim_login, but we'll leave the
109   * function here, in case there's stuff we want to init in the
110   * future.  It's still called by Owl.
111   */
112     
113}
114
115void owl_aim_send_nop(owl_timer *t, void *data) {
116    if(owl_global_is_doaimevents(&g)) {
117        aim_session_t *sess = owl_global_get_aimsess(&g);
118        aim_flap_nop(sess, aim_getconn_type(sess, AIM_CONN_TYPE_BOS));
119    }
120}
121
122
123int owl_aim_login(const char *screenname, const char *password)
124{
125  struct owlfaim_priv *priv;
126  aim_conn_t *conn;
127  aim_session_t *sess;
128
129  sess=owl_global_get_aimsess(&g);
130
131  aim_session_init(sess, TRUE, 0);
132  aim_setdebuggingcb(sess, faimtest_debugcb);
133  aim_tx_setenqueue(sess, AIM_TX_IMMEDIATE, NULL);
134 
135  /* this will leak, I know and just don't care right now */
136  priv=owl_malloc(sizeof(struct owlfaim_priv));
137  memset(priv, 0, sizeof(struct owlfaim_priv));
138
139  priv->screenname = owl_strdup(screenname);
140  priv->password = owl_strdup(password);
141  priv->server = owl_strdup(FAIM_LOGIN_SERVER);
142  sess->aux_data = priv;
143
144  conn=aim_newconn(sess, AIM_CONN_TYPE_AUTH, priv->server ? priv->server : FAIM_LOGIN_SERVER);
145  /*  conn=aim_newconn(sess, AIM_CONN_TYPE_AUTH, NULL); */
146  if (!conn) {
147    owl_function_error("owl_aim_login: connection error during AIM login\n");
148    owl_global_set_aimnologgedin(&g);
149    owl_global_set_no_doaimevents(&g);
150    return (-1);
151  }
152
153  /*
154  else if (conn->fd == -1) {
155    if (conn->status & AIM_CONN_STATUS_RESOLVERR) {
156      owl_function_error("owl_aim_login: could not resolve authorize name");
157    } else if (conn->status & AIM_CONN_STATUS_CONNERR) {
158      owl_function_error("owl_aim_login: could not connect to authorizer");
159    } else {
160      owl_function_error("owl_aim_login: unknown connection error");
161    }
162    owl_global_set_aimnologgedin(&g);
163    owl_global_set_no_doaimevents(&g);
164    aim_conn_kill(sess, &conn);
165    return(-1);
166  }
167  */
168
169   
170  aim_conn_addhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_FLAPVER, faimtest_flapversion, 0);
171  aim_conn_addhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
172
173  aim_conn_addhandler(sess, conn, AIM_CB_FAM_ATH, AIM_CB_ATH_AUTHRESPONSE, faimtest_parse_login, 0);
174  aim_conn_addhandler(sess, conn, AIM_CB_FAM_ATH, AIM_CB_ATH_LOGINRESPONSE, faimtest_parse_authresp, 0);
175  /* aim_conn_addhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, gaim_connerr, 0); */
176  /* aim_conn_addhandler(sess, conn, 0x0017, 0x0007, gaim_parse_login, 0); */
177  /* aim_conn_addhandler(sess, conn, 0x0017, 0x0003, gaim_parse_auth_resp, 0); */
178   
179  /* start processing AIM events */
180  owl_global_set_doaimevents(&g);
181  /* conn->status |= AIM_CONN_STATUS_INPROGRESS; */
182  owl_function_debugmsg("owl_aim_login: sending login request for %s", screenname);
183  aim_request_login(sess, conn, screenname);
184  owl_function_debugmsg("owl_aim_login: connecting");
185
186  g.aim_nop_timer = owl_select_add_timer(30, 30, owl_aim_send_nop, NULL, NULL);
187
188  return(0);
189}
190
191static void owl_aim_unset_ignorelogin(owl_timer *t, void *data)
192{
193    owl_global_unset_ignore_aimlogin(&g);
194}
195
196/* stuff to run once login has been successful */
197void owl_aim_successful_login(const char *screenname)
198{
199  char *buff;
200  owl_function_debugmsg("doing owl_aim_successful_login");
201  owl_global_set_aimloggedin(&g, screenname);
202  owl_global_set_doaimevents(&g); /* this should already be on */
203  owl_function_makemsg("%s logged in", screenname);
204  buff=owl_sprintf("Logged in to AIM as %s", screenname);
205  owl_function_adminmsg("", buff);
206  owl_free(buff);
207
208  owl_function_debugmsg("Successful AIM login for %s", screenname);
209
210  /* start the ingorelogin timer */
211  owl_global_set_ignore_aimlogin(&g);
212  owl_select_add_timer(owl_global_get_aim_ignorelogin_timer(&g),
213                       0, owl_aim_unset_ignorelogin, NULL, NULL);
214
215  /* aim_ssi_setpresence(owl_global_get_aimsess(&g), 0x00000400); */
216  /* aim_bos_setidle(owl_global_get_aimsess(&g), owl_global_get_bosconn(&g), 5000); */
217}
218
219void owl_aim_logout(void)
220{
221  /* need to check if it's connected first, I think */
222  logout(owl_global_get_aimsess(&g));
223
224  if (owl_global_is_aimloggedin(&g)) owl_function_adminmsg("", "Logged out of AIM");
225  owl_global_set_aimnologgedin(&g);
226  owl_global_set_no_doaimevents(&g);
227  owl_select_remove_timer(g.aim_nop_timer);
228}
229
230void owl_aim_logged_out(void)
231{
232  if (owl_global_is_aimloggedin(&g)) owl_function_adminmsg("", "Logged out of AIM");
233  owl_aim_logout();
234}
235
236void owl_aim_login_error(const char *message)
237{
238  if (message) {
239    owl_function_error("%s", message);
240  } else {
241    owl_function_error("Authentication error on login");
242  }
243  owl_function_beep();
244  owl_global_set_aimnologgedin(&g);
245  owl_global_set_no_doaimevents(&g);
246  owl_select_remove_timer(g.aim_nop_timer);
247}
248
249/*
250 * I got these constants by skimming libfaim/im.c
251 *
252 * "UNICODE" actually means "UCS-2BE".
253 */
254#define AIM_CHARSET_ISO_8859_1         0x0003
255#define AIM_CHARSET_UNICODE            0x0002
256
257static int owl_aim_do_send(const char *to, const char *msg, int flags)
258{
259  int ret;
260  char *encoded;
261  struct aim_sendimext_args args;
262    gsize len;
263
264  encoded = g_convert(msg, -1, "ISO-8859-1", "UTF-8", NULL, &len, NULL);
265  if (encoded) {
266    owl_function_debugmsg("Encoded outgoing AIM as ISO-8859-1");
267    args.charset = AIM_CHARSET_ISO_8859_1;
268    args.charsubset = 0;
269    args.flags = AIM_IMFLAGS_ISO_8859_1;
270  } else {
271    owl_function_debugmsg("Encoding outgoing IM as UCS-2BE");
272    encoded = g_convert(msg, -1, "UCS-2BE", "UTF-8", NULL, &len, NULL);
273    if (!encoded) {
274      /*
275       * TODO: Strip or HTML-encode characters, or figure out how to
276       * send in a differen charset.
277       */
278      owl_function_error("Unable to encode outgoing AIM message in UCS-2");
279      return 1;
280    }
281
282    args.charset = AIM_CHARSET_UNICODE;
283    args.charsubset = 0;
284    args.flags = AIM_IMFLAGS_UNICODE;
285  }
286
287  args.destsn = to;
288  args.msg = encoded;
289  args.msglen = len;
290  args.flags |= flags;
291
292  ret=aim_im_sendch1_ext(owl_global_get_aimsess(&g), &args);
293
294  owl_free(encoded);
295
296  return(ret);
297}
298
299int owl_aim_send_im(const char *to, const char *msg)
300{
301  return owl_aim_do_send(to, msg, 0);
302}
303
304int owl_aim_send_awaymsg(const char *to, const char *msg)
305{
306  return owl_aim_do_send(to, msg, AIM_IMFLAGS_AWAY);
307}
308
309void owl_aim_addbuddy(const char *name)
310{
311
312  aim_ssi_addbuddy(owl_global_get_aimsess(&g), name, "Buddies", NULL, NULL, NULL, 0);
313
314  /*
315  aim_ssi_addbuddy(owl_global_get_aimsess(&g),
316                   name,
317                   "Buddies",
318                   NULL, NULL, NULL,
319                   aim_ssi_waitingforauth(owl_global_get_aimsess(&g)->ssi.local, "Buddies", name));
320  */
321}
322
323void owl_aim_delbuddy(const char *name)
324{
325  aim_ssi_delbuddy(owl_global_get_aimsess(&g), name, "Buddies");
326  owl_buddylist_offgoing(owl_global_get_buddylist(&g), name);
327}
328
329void owl_aim_search(const char *email)
330{
331  int ret;
332
333  owl_function_debugmsg("owl_aim_search: doing search for %s", email);
334  ret=aim_search_address(owl_global_get_aimsess(&g), 
335                         aim_getconn_type(owl_global_get_aimsess(&g), AIM_CONN_TYPE_BOS),
336                         email);
337
338  if (ret) owl_function_error("owl_aim_search: aim_search_address returned %i", ret);
339}
340
341
342int owl_aim_set_awaymsg(const char *msg)
343{
344  int len;
345  char *foo;
346  /* there is a max away message lentgh we should check against */
347
348  foo=owl_strdup(msg);
349  len=strlen(foo);
350  if (len>500) {
351    foo[500]='\0';
352    len=499;
353  }
354   
355  aim_locate_setprofile(owl_global_get_aimsess(&g),
356                        NULL, NULL, 0,
357                        "us-ascii", foo, len);
358  owl_free(foo);
359
360  /*
361  aim_bos_setprofile(owl_global_get_aimsess(&g),
362                     owl_global_get_bosconn(&g),
363                     NULL, NULL, 0, "us-ascii", msg,
364                     strlen(msg), 0);
365  */
366  return(0);
367}
368
369void owl_aim_chat_join(const char *name, int exchange)
370{
371  int ret;
372  aim_conn_t *cur;
373  /*
374  OscarData *od = g->proto_data;
375  const char *name, *exchange;
376  */
377
378  owl_function_debugmsg("Attempting to join chatroom %s exchange %i", name, exchange);
379
380  /*
381  name = g_hash_table_lookup(data, "room");
382  exchange = g_hash_table_lookup(data, "exchange");
383  */
384  if ((cur = aim_getconn_type(owl_global_get_aimsess(&g), AIM_CONN_TYPE_CHATNAV))) {
385    owl_function_debugmsg("owl_aim_chat_join: chatnav exists, creating room");
386    aim_chatnav_createroom(owl_global_get_aimsess(&g), cur, name, exchange);
387  } else {
388    /*    struct create_room *cr = g_new0(struct create_room, 1); */
389    owl_function_debugmsg("owl_aim_chat_join: chatnav does not exist, opening chatnav");
390    /*
391    cr->exchange = atoi(exchange);
392    cr->name = g_strdup(name);
393    od->create_rooms = g_slist_append(od->create_rooms, cr);
394    */
395    aim_reqservice(owl_global_get_aimsess(&g),
396                   aim_getconn_type(owl_global_get_aimsess(&g), AIM_CONN_TYPE_CHATNAV),
397                   AIM_CONN_TYPE_CHATNAV);
398    aim_reqservice(owl_global_get_aimsess(&g), NULL, AIM_CONN_TYPE_CHATNAV);
399    aim_chatnav_createroom(owl_global_get_aimsess(&g), cur, name, exchange);
400    ret=aim_chat_join(owl_global_get_aimsess(&g), owl_global_get_bosconn(&g), exchange, name, 0x0000);
401
402  }
403  return;
404  /******/
405
406
407  /* ret=aim_chat_join(owl_global_get_aimsess(&g), owl_global_get_bosconn(&g), exchange, chatroom, 0x0000); */
408  /*
409  ret=aim_chat_join(owl_global_get_aimsess(&g),
410                    aim_getconn_type(owl_global_get_aimsess(&g), AIM_CONN_TYPE_CHATNAV), exchange, chatroom, 0x0000);
411  */
412
413  aim_reqservice(owl_global_get_aimsess(&g), owl_global_get_bosconn(&g), AIM_CONN_TYPE_CHATNAV);
414  ret = aim_chatnav_createroom(owl_global_get_aimsess(&g),
415                               aim_getconn_type(owl_global_get_aimsess(&g), AIM_CONN_TYPE_CHATNAV), name, exchange);
416   ret=aim_chat_join(owl_global_get_aimsess(&g), owl_global_get_bosconn(&g), exchange, name, 0x0000);
417 
418}
419
420void owl_aim_chat_leave(const char *chatroom)
421{
422}
423
424int owl_aim_chat_sendmsg(const char *chatroom, const char *msg)
425{
426  return(0);
427}
428
429/* caller must free the return */
430char *owl_aim_normalize_screenname(const char *in)
431{
432  char *out;
433  int i, j, k;
434
435  j=strlen(in);
436  out=owl_malloc(j+30);
437  k=0;
438  for (i=0; i<j; i++) {
439    if (in[i]!=' ') {
440      out[k]=in[i];
441      k++;
442    }
443  }
444  out[k]='\0';
445  return(out);
446}
447
448int owl_aim_process_events(void)
449{
450  aim_session_t *aimsess;
451  aim_conn_t *waitingconn = NULL;
452  struct timeval tv;
453  int selstat = 0;
454  struct owlfaim_priv *priv;
455
456  aimsess=owl_global_get_aimsess(&g);
457  priv = aimsess->aux_data;
458
459  /* do a select without blocking */
460  tv.tv_sec = 0;
461  tv.tv_usec = 0;
462  waitingconn = aim_select(aimsess, &tv, &selstat);
463
464  if (selstat == -1) {
465    owl_aim_logged_out();
466  } else if (selstat == 0) { 
467    /* no events pending */
468  } else if (selstat == 1) { /* outgoing data pending */
469    aim_tx_flushqueue(aimsess);
470  } else if (selstat == 2) { /* incoming data pending */
471    /* printf("selstat == 2\n"); */
472   
473    if (aim_get_command(aimsess, waitingconn) >= 0) {
474      aim_rxdispatch(aimsess);
475    } else {
476      /* printf("connection error (type 0x%04x:0x%04x)\n", waitingconn->type, waitingconn->subtype); */
477      /* we should have callbacks for all these, else the library will do the conn_kill for us. */
478      if (waitingconn->type == AIM_CONN_TYPE_RENDEZVOUS) {
479        if (waitingconn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM) {
480          /* printf("disconnected from %s\n", aim_directim_getsn(waitingconn)); */
481          aim_conn_kill(aimsess, &waitingconn);
482          owl_aim_logged_out();
483        }
484      } else {
485        aim_conn_kill(aimsess, &waitingconn);
486        owl_aim_logged_out();
487      }
488      if (!aim_getconn_type(aimsess, AIM_CONN_TYPE_BOS)) {
489        /* printf("major connection error\n"); */
490        owl_aim_logged_out();
491        /* break; */
492      }
493    }
494  }
495  /* exit(0); */
496  return(0);
497}
498
499static void faimtest_debugcb(aim_session_t *sess, int level, const char *format, va_list va)
500{
501  return;
502}
503
504static int faimtest_parse_login(aim_session_t *sess, aim_frame_t *fr, ...)
505{
506  struct owlfaim_priv *priv = sess->aux_data;
507  struct client_info_s info = CLIENTINFO_AIM_KNOWNGOOD;
508   
509  const char *key;
510  va_list ap;
511
512  va_start(ap, fr);
513  key = va_arg(ap, const char *);
514  va_end(ap);
515
516  owl_function_debugmsg("faimtest_parse_login: %s %s %s", priv->screenname, priv->password, key);
517
518  aim_send_login(sess, fr->conn, priv->screenname, priv->password, &info, key);
519 
520  return(1);
521}
522
523
524static int faimtest_parse_authresp(aim_session_t *sess, aim_frame_t *fr, ...)
525{
526  va_list ap;
527  struct aim_authresp_info *info;
528  aim_conn_t *bosconn;
529
530  va_start(ap, fr);
531  info = va_arg(ap, struct aim_authresp_info *);
532  va_end(ap);
533
534  /* printf("Screen name: %s\n", info->sn); */
535  owl_function_debugmsg("doing faimtest_parse_authresp");
536  owl_function_debugmsg("faimtest_parse_authresp: %s", info->sn);
537
538  /*
539   * Check for error.
540   */
541  if (info->errorcode || !info->bosip || !info->cookie) {
542    /*
543    printf("Login Error Code 0x%04x\n", info->errorcode);
544    printf("Error URL: %s\n", info->errorurl);
545    */
546    if (info->errorcode==0x05) {
547      owl_aim_login_error("Incorrect nickname or password.");
548    } else if (info->errorcode==0x11) {
549      owl_aim_login_error("Your account is currently suspended.");
550    } else if (info->errorcode==0x14) {
551      owl_aim_login_error("The AOL Instant Messenger service is temporarily unavailable.");
552    } else if (info->errorcode==0x18) {
553      owl_aim_login_error("You have been connecting and disconnecting too frequently. Wait ten minutes and try again. If you continue to try, you will need to wait even longer.");
554    } else if (info->errorcode==0x1c) {
555      owl_aim_login_error("The client version you are using is too old.");
556    } else {
557      owl_aim_login_error(NULL);
558    }
559    aim_conn_kill(sess, &fr->conn);
560    return(1);
561  }
562
563  /*
564  printf("Reg status: %d\n", info->regstatus);
565  printf("Email: %s\n", info->email);
566  printf("BOS IP: %s\n", info->bosip);
567  */
568
569  /* printf("Closing auth connection...\n"); */
570  aim_conn_kill(sess, &fr->conn);
571  if (!(bosconn = aim_newconn(sess, AIM_CONN_TYPE_BOS, info->bosip))) {
572    /* printf("could not connect to BOS: internal error\n"); */
573    return(1);
574  } else if (bosconn->status & AIM_CONN_STATUS_CONNERR) {
575    /* printf("could not connect to BOS\n"); */
576    aim_conn_kill(sess, &bosconn);
577    return(1);
578  }
579  owl_global_set_bossconn(&g, bosconn);
580  owl_aim_successful_login(info->sn);
581  addcb_bos(sess, bosconn);
582  aim_sendcookie(sess, bosconn, info->cookielen, info->cookie);
583  return(1);
584}
585
586int faimtest_flapversion(aim_session_t *sess, aim_frame_t *fr, ...)
587{
588  owl_function_debugmsg("doing faimtest_flapversion");
589
590#if 0
591  /* XXX fix libfaim to support this */
592  printf("using FLAP version 0x%08x\n", /* aimutil_get32(fr->data)*/ 0xffffffff);
593
594  /*
595   * This is an alternate location for starting the login process.
596   */
597  /* XXX should do more checking to make sure its really the right AUTH conn */
598  if (fr->conn->type == AIM_CONN_TYPE_AUTH) {
599    /* do NOT send a flapversion, request_login will send it if needed */
600    aim_request_login(sess, fr->conn, priv->screenname);
601    /* printf("faimtest: login request sent\n"); */
602  }
603#endif
604
605  return 1;
606}
607
608
609int faimtest_conncomplete(aim_session_t *sess, aim_frame_t *fr, ...)
610{
611  owl_function_debugmsg("doing faimtest_conncomplete");
612  /* owl_aim_successful_login(info->sn); */
613  return 1;
614}
615
616void addcb_bos(aim_session_t *sess, aim_conn_t *bosconn)
617{
618  owl_function_debugmsg("doing addcb_bos");
619  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
620  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, conninitdone_bos, 0);
621
622  aim_conn_addhandler(sess, bosconn, 0x0013,         0x0003,                        ssirights, 0);
623  aim_conn_addhandler(sess, bosconn, 0x0013,         0x0006,                        ssidata, 0);
624  aim_conn_addhandler(sess, bosconn, 0x0013,         0x000f,                        ssidatanochange, 0);
625  aim_conn_addhandler(sess, bosconn, 0x0008,         0x0002,                        handlepopup, 0);
626  aim_conn_addhandler(sess, bosconn, 0x0009,         0x0003,                        faimtest_bosrights, 0);
627  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_REDIRECT,           faimtest_handleredirect, 0);
628  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_STS, AIM_CB_STS_SETREPORTINTERVAL,  faimtest_reportinterval, 0);
629  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_RIGHTSINFO,         faimtest_parse_buddyrights, 0);
630  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_MOTD,               faimtest_parse_motd, 0);
631  aim_conn_addhandler(sess, bosconn, 0x0004,         0x0005,                        faimtest_icbmparaminfo, 0);
632  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR,    faimtest_parse_connerr, 0);
633  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_RIGHTSINFO,         faimtest_locrights, 0);
634  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_ONCOMING,           faimtest_parse_oncoming, 0);
635  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_OFFGOING,           faimtest_parse_offgoing, 0);
636  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_INCOMING,           faimtest_parse_incoming_im, 0);
637  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_ERROR,              faimtest_parse_locerr, 0);
638  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_MISSEDCALL,         faimtest_parse_misses, 0);
639  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_RATECHANGE,         faimtest_parse_ratechange, 0);
640  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_EVIL,               faimtest_parse_evilnotify, 0);
641
642  aim_conn_addhandler(sess, bosconn, 0x000a,         0x0001,                        faimtest_parse_searcherror, 0);
643  aim_conn_addhandler(sess, bosconn, 0x000a,         0x0003,                        faimtest_parse_searchreply, 0);
644
645  /*
646  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOK, AIM_CB_LOK_ERROR, faimtest_parse_searcherror, 0);
647  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOK, 0x0003, faimtest_parse_searchreply, 0);
648  */
649 
650  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ERROR,              faimtest_parse_msgerr, 0);
651  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO,           faimtest_parse_userinfo, 0);
652  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ACK,                faimtest_parse_msgack, 0);
653
654  aim_conn_addhandler(sess, bosconn, 0x0001,         0x0001,                        faimtest_parse_genericerr, 0);
655  aim_conn_addhandler(sess, bosconn, 0x0003,         0x0001,                        faimtest_parse_genericerr, 0);
656  aim_conn_addhandler(sess, bosconn, 0x0009,         0x0001,                        faimtest_parse_genericerr, 0);
657  aim_conn_addhandler(sess, bosconn, 0x0001,         0x000b,                        serverpause, 0);
658  aim_conn_addhandler(sess, bosconn, 0x0001,         0x0012,                        migrate, 0);
659  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSG,         offlinemsg, 0);
660  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSGCOMPLETE, offlinemsgdone, 0);
661
662  /*
663  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR,     gaim_connerr, 0);
664  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, conninitdone_chatnav, 0);
665  */
666
667  /*
668  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_ERROR,              faimtest_ssi_parseerr, 0);
669  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RIGHTSINFO,         faimtest_ssi_parserights, 0);
670  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_LIST,               faimtest_ssi_parselist, 0);
671  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_NOLIST,             faimtest_ssi_parselist, 0);
672  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_SRVACK,             faimtest_ssi_parseack, 0);
673  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RECVAUTH,           faimtest_ssi_authgiven, 0);
674  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RECVAUTHREQ,        faimtest_ssi_authrequest, 0);
675  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RECVAUTHREP,        faimtest_ssi_authreply, 0);
676  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_ADDED,              faimtest_ssi_gotadded, 0);
677  */
678
679  return;
680}
681
682static int conninitdone_bos(aim_session_t *sess, aim_frame_t *fr, ...)
683{
684  owl_function_debugmsg("doing coninitdone_bos");
685
686
687  aim_reqpersonalinfo(sess, fr->conn);
688  aim_ssi_reqrights(sess);
689  aim_ssi_reqdata(sess);
690  aim_locate_reqrights(sess);
691  aim_buddylist_reqrights(sess, fr->conn);
692
693  aim_im_reqparams(sess);
694  /* aim_bos_reqrights(sess, fr->conn); */ /* XXX - Don't call this with ssi */
695
696  owl_function_debugmsg("conninitdone_bos: requesting rights");
697  aim_bos_reqrights(sess, fr->conn); /* XXX - Don't call this with ssi */
698  aim_bos_setgroupperm(sess, fr->conn, AIM_FLAG_ALLUSERS);
699  aim_bos_setprivacyflags(sess, fr->conn, AIM_PRIVFLAGS_ALLOWIDLE | AIM_PRIVFLAGS_ALLOWMEMBERSINCE);
700
701  return(1);
702}
703
704static int conninitdone_admin(aim_session_t *sess, aim_frame_t *fr, ...)
705{
706  aim_clientready(sess, fr->conn);
707  owl_function_debugmsg("conninitdone_admin: initializtion done for admin connection");
708  return(1);
709}
710
711int logout(aim_session_t *sess)
712{
713  aim_session_kill(sess);
714  owl_aim_init();
715
716  owl_function_debugmsg("libfaim logout called");
717  /*
718  if (faimtest_init() == -1)
719    printf("faimtest_init failed\n");
720  */
721
722  return(0);
723}
724
725/**************************************************************************************************/
726
727static int faimtest_parse_connerr(aim_session_t *sess, aim_frame_t *fr, ...)
728{
729  struct owlfaim_priv *priv = sess->aux_data;
730  va_list ap;
731  fu16_t code;
732  const char *msg;
733 
734  va_start(ap, fr);
735  code = va_arg(ap, int);
736  msg = va_arg(ap, const char *);
737  va_end(ap);
738 
739  owl_function_error("faimtest_parse_connerr: Code 0x%04x: %s\n", code, msg);
740  aim_conn_kill(sess, &fr->conn); /* this will break the main loop */
741 
742  priv->connected = 0;
743 
744  return 1;
745}
746
747static int faimtest_accountconfirm(aim_session_t *sess, aim_frame_t *fr, ...)
748{
749  int status;
750  va_list ap;
751 
752  va_start(ap, fr);
753  status = va_arg(ap, int); /* status code of confirmation request */
754  va_end(ap);
755
756  /* owl_function_debugmsg("faimtest_accountconfirm: Code 0x%04x: %s\n", code, msg); */
757  owl_function_debugmsg("faimtest_accountconfirm: account confirmation returned status 0x%04x (%s)\n", status, (status==0x0000)?"email sent":"unknown");
758 
759  return 1;
760}
761
762static int faimtest_infochange(aim_session_t *sess, aim_frame_t *fr, ...)
763{
764  fu16_t change = 0, perms, type;
765  int length, str;
766  const char *val;
767  va_list ap;
768 
769  va_start(ap, fr);
770  change = va_arg(ap, int);
771  perms = (fu16_t)va_arg(ap, unsigned int);
772  type = (fu16_t)va_arg(ap, unsigned int);
773  length = va_arg(ap, int);
774  val = va_arg(ap, const char *);
775  str = va_arg(ap, int);
776  va_end(ap);
777 
778  owl_function_debugmsg("faimtest_infochange: info%s: perms = %d, type = %x, length = %d, val = %s", change?" change":"", perms, type, length, str?val:"(not string)");
779 
780  return(1);
781}
782
783
784static int faimtest_handleredirect(aim_session_t *sess, aim_frame_t *fr, ...)
785{
786  va_list ap;
787  struct aim_redirect_data *redir;
788
789  owl_function_debugmsg("faimtest_handledirect:");
790 
791  va_start(ap, fr);
792  redir = va_arg(ap, struct aim_redirect_data *);
793 
794  if (redir->group == 0x0005) {  /* Adverts */
795   
796  } else if (redir->group == 0x0007) {  /* Authorizer */
797    aim_conn_t *tstconn;
798
799    owl_function_debugmsg("faimtest_handledirect: autorizer");
800   
801    tstconn = aim_newconn(sess, AIM_CONN_TYPE_AUTH, redir->ip);
802    if (!tstconn || (tstconn->status & AIM_CONN_STATUS_RESOLVERR)) {
803      owl_function_error("faimtest_handleredirect: unable to reconnect with authorizer");
804    } else {
805      aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_FLAPVER, faimtest_flapversion, 0);
806      aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
807      aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, conninitdone_admin, 0);
808      aim_conn_addhandler(sess, tstconn, 0x0007, 0x0007, faimtest_accountconfirm, 0);
809      aim_conn_addhandler(sess, tstconn, 0x0007, 0x0003, faimtest_infochange, 0);
810      aim_conn_addhandler(sess, tstconn, 0x0007, 0x0005, faimtest_infochange, 0);
811      /* Send the cookie to the Auth */
812      aim_sendcookie(sess, tstconn, redir->cookielen, redir->cookie);
813      owl_function_debugmsg("faimtest_handleredirect: sent cookie to authorizer host");
814    }
815  } else if (redir->group == 0x000d) {  /* ChatNav */
816    owl_function_debugmsg("faimtest_handledirect: chatnav");
817    chatnav_redirect(sess, redir);
818  } else if (redir->group == 0x000e) { /* Chat */
819    owl_function_debugmsg("faimtest_handledirect: chat");
820    chat_redirect(sess, redir);
821  } else {
822    owl_function_debugmsg("faimtest_handleredirect: uh oh... got redirect for unknown service 0x%04x!!", redir->group);
823  }
824  va_end(ap);
825  return 1;
826}
827
828static int faimtest_icbmparaminfo(aim_session_t *sess, aim_frame_t *fr, ...)
829{
830  struct aim_icbmparameters *params;
831  va_list ap;
832 
833  va_start(ap, fr);
834  params = va_arg(ap, struct aim_icbmparameters *);
835  va_end(ap);
836 
837  owl_function_debugmsg("faimtest_icbmparaminfo: ICBM Parameters: maxchannel = %d, default flags = 0x%08x, max msg len = %d, max sender evil = %f, max reciever evil = %f, min msg interval = %u",
838                       params->maxchan, params->flags, params->maxmsglen, ((float)params->maxsenderwarn)/10.0, ((float)params->maxrecverwarn)/10.0, params->minmsginterval);
839     
840  /*
841  * Set these to your taste, or client medium.  Setting minmsginterval
842  * higher is good for keeping yourself from getting flooded (esp
843  * if you're on a slow connection or something where that would be
844  * useful).
845  */
846  params->maxmsglen = 8000;
847  params->minmsginterval = 0; /* in milliseconds */
848  /* aim_seticbmparam(sess, params); */
849  aim_im_setparams(sess, params);
850 
851  return 1;
852}
853
854static int faimtest_parse_buddyrights(aim_session_t *sess, aim_frame_t *fr, ...)
855{
856  va_list ap;
857  fu16_t maxbuddies, maxwatchers;
858 
859  va_start(ap, fr);
860  maxbuddies = va_arg(ap, int);
861  maxwatchers = va_arg(ap, int);
862  va_end(ap);
863 
864  owl_function_debugmsg("faimtest_parse_buddyrights: Max buddies = %d / Max watchers = %d\n", maxbuddies, maxwatchers);
865 
866  /* aim_ssi_reqrights(sess, fr->conn); */
867  aim_ssi_reqrights(sess);
868 
869  return 1;
870}
871
872static int faimtest_bosrights(aim_session_t *sess, aim_frame_t *fr, ...)
873{
874  va_list ap;
875  fu16_t maxpermits, maxdenies;
876 
877  va_start(ap, fr);
878  maxpermits = va_arg(ap, int);
879  maxdenies = va_arg(ap, int);
880  va_end(ap);
881 
882  owl_function_debugmsg("faimtest_bosrights: Max permit = %d / Max deny = %d\n", maxpermits, maxdenies);
883  aim_clientready(sess, fr->conn);
884  owl_function_debugmsg("officially connected to BOS.");
885  aim_icq_reqofflinemsgs(sess);
886  return 1;
887}
888
889static int faimtest_locrights(aim_session_t *sess, aim_frame_t *fr, ...)
890{
891  va_list ap;
892  fu16_t maxsiglen;
893 
894  va_start(ap, fr);
895  maxsiglen = va_arg(ap, int);
896  va_end(ap);
897
898  owl_function_debugmsg("faimtest_locrights: rights: max signature length = %d\n", maxsiglen);
899 
900  return(1);
901}
902
903static int faimtest_reportinterval(aim_session_t *sess, aim_frame_t *fr, ...)
904{
905  struct owlfaim_priv *priv = sess->aux_data;
906  va_list ap;
907  fu16_t interval;
908
909  va_start(ap, fr);
910  interval = va_arg(ap, int);
911  va_end(ap);
912
913  owl_function_debugmsg("faimtest_reportinterval: %d (seconds?)\n", interval);
914
915  if (!priv->connected) {
916    priv->connected++;
917  }
918  /* aim_reqicbmparams(sess); */
919  aim_im_reqparams(sess);
920  /* kretch */
921  return 1;
922}
923
924static int faimtest_parse_motd(aim_session_t *sess, aim_frame_t *fr, ...)
925{
926  const char *msg;
927  fu16_t id;
928  va_list ap;
929  static int codeslen = 5;
930  static const char *codes[] = {
931    "Unknown",
932    "Mandatory upgrade",
933    "Advisory upgrade",
934    "System bulletin",
935    "Top o' the world!"
936  };
937
938  va_start(ap, fr);
939  id = va_arg(ap, int);
940  msg = va_arg(ap, const char *);
941  va_end(ap);
942
943  owl_function_debugmsg("faimtest_parse_motd: %s (%d / %s)\n", msg?msg:"nomsg", id, (id < codeslen)?codes[id]:"unknown");
944 
945  return 1;
946}
947
948/*
949static void printuserflags(fu16_t flags)
950{
951  if (flags & AIM_FLAG_UNCONFIRMED) printf("UNCONFIRMED ");
952  if (flags & AIM_FLAG_ADMINISTRATOR) printf("ADMINISTRATOR ");
953  if (flags & AIM_FLAG_AOL) printf("AOL ");
954  if (flags & AIM_FLAG_OSCAR_PAY) printf("OSCAR_PAY ");
955  if (flags & AIM_FLAG_FREE) printf("FREE ");
956  if (flags & AIM_FLAG_AWAY) printf("AWAY ");
957  if (flags & AIM_FLAG_ICQ) printf("ICQ ");
958  if (flags & AIM_FLAG_WIRELESS) printf("WIRELESS ");
959  if (flags & AIM_FLAG_ACTIVEBUDDY) printf("ACTIVEBUDDY ");
960 
961  return;
962}
963*/
964
965static int faimtest_parse_userinfo(aim_session_t *sess, aim_frame_t *fr, ...)
966{
967  aim_userinfo_t *userinfo;
968  const char *prof_encoding = NULL;
969  const char *prof = NULL;
970  fu16_t inforeq = 0;
971  owl_buddy *b;
972  va_list ap;
973  va_start(ap, fr);
974  userinfo = va_arg(ap, aim_userinfo_t *);
975  inforeq = (fu16_t)va_arg(ap, unsigned int);
976  prof_encoding = va_arg(ap, const char *);
977  prof = va_arg(ap, const char *);
978  va_end(ap);
979
980  /* right now the only reason we call this is for idle times */
981  owl_function_debugmsg("parse_userinfo sn: %s idle: %i", userinfo->sn, userinfo->idletime);
982  b=owl_buddylist_get_aim_buddy(owl_global_get_buddylist(&g),
983                                userinfo->sn);
984  if (!b) return(1);
985  owl_buddy_set_idle_since(b, userinfo->idletime);
986  return(1);
987
988  /*
989  printf("userinfo: sn: %s\n", userinfo->sn);
990  printf("userinfo: warnlevel: %f\n", aim_userinfo_warnlevel(userinfo));
991  printf("userinfo: flags: 0x%04x = ", userinfo->flags);
992  printuserflags(userinfo->flags);
993  printf("\n");
994  */
995
996  /*
997  printf("userinfo: membersince: %lu\n", userinfo->membersince);
998  printf("userinfo: onlinesince: %lu\n", userinfo->onlinesince);
999  printf("userinfo: idletime: 0x%04x\n", userinfo->idletime);
1000  printf("userinfo: capabilities = %s = 0x%08lx\n", (userinfo->present & AIM_USERINFO_PRESENT_CAPABILITIES) ? "present" : "not present", userinfo->capabilities);
1001  */
1002
1003  /*
1004  if (inforeq == AIM_GETINFO_GENERALINFO) {
1005    owl_function_debugmsg("userinfo: profile_encoding: %s\n", prof_encoding ? prof_encoding : "[none]");
1006    owl_function_debugmsg("userinfo: prof: %s\n", prof ? prof : "[none]");
1007  } else if (inforeq == AIM_GETINFO_AWAYMESSAGE) {
1008    owl_function_debugmsg("userinfo: awaymsg_encoding: %s\n", prof_encoding ? prof_encoding : "[none]");
1009    owl_function_debugmsg("userinfo: awaymsg: %s\n", prof ? prof : "[none]");
1010  } else if (inforeq == AIM_GETINFO_CAPABILITIES) {
1011    owl_function_debugmsg("userinfo: capabilities: see above\n");
1012  } else {
1013    owl_function_debugmsg("userinfo: unknown info request\n");
1014  }
1015  */
1016  return(1);
1017}
1018
1019/*
1020 * Channel 1: Standard Message
1021 */
1022static int faimtest_parse_incoming_im_chan1(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch1_args *args)
1023{
1024  owl_message *m;
1025  char *stripmsg, *nz_screenname, *wrapmsg;
1026  char *realmsg = NULL;
1027
1028  if (!args->msg) {
1029    realmsg = owl_strdup("");
1030  } else if (args->icbmflags & AIM_IMFLAGS_UNICODE) {
1031    realmsg = g_convert(args->msg, args->msglen, "UTF-8", "UCS-2BE",
1032                        NULL, NULL, NULL);
1033  } else if(args->icbmflags & AIM_IMFLAGS_ISO_8859_1) {
1034    realmsg = g_convert(args->msg, args->msglen, "UTF-8", "ISO-8859-1",
1035                        NULL, NULL, NULL);
1036  } else {
1037    realmsg = owl_strdup(args->msg);
1038  }
1039
1040  if (!realmsg) {
1041    realmsg = owl_strdup("[Error decoding incoming IM]");
1042  }
1043
1044  owl_function_debugmsg("faimtest_parse_incoming_im_chan1: message from: %s", userinfo->sn?userinfo->sn:"");
1045  /* create a message, and put it on the message queue */
1046  stripmsg=owl_text_htmlstrip(realmsg);
1047  wrapmsg=owl_text_wordwrap(stripmsg, 70);
1048  nz_screenname=owl_aim_normalize_screenname(userinfo->sn);
1049  m=owl_malloc(sizeof(owl_message));
1050  owl_message_create_aim(m,
1051                         nz_screenname,
1052                         owl_global_get_aim_screenname(&g),
1053                         wrapmsg,
1054                         OWL_MESSAGE_DIRECTION_IN,
1055                         0);
1056  if (args->icbmflags & AIM_IMFLAGS_AWAY) owl_message_set_attribute(m, "isauto", "");
1057  owl_global_messagequeue_addmsg(&g, m);
1058  owl_free(stripmsg);
1059  owl_free(wrapmsg);
1060  owl_free(nz_screenname);
1061
1062  return(1);
1063
1064  owl_function_debugmsg("faimtest_parse_incoming_im_chan1: icbm: message: %s\n", realmsg);
1065 
1066  if (args->icbmflags & AIM_IMFLAGS_MULTIPART) {
1067    aim_mpmsg_section_t *sec;
1068    int z;
1069
1070    owl_function_debugmsg("faimtest_parse_incoming_im_chan1: icbm: multipart: this message has %d parts\n", args->mpmsg.numparts);
1071   
1072    for (sec = args->mpmsg.parts, z = 0; sec; sec = sec->next, z++) {
1073      if ((sec->charset == 0x0000) || (sec->charset == 0x0003) || (sec->charset == 0xffff)) {
1074        owl_function_debugmsg("faimtest_parse_incoming_im_chan1: icbm: multipart:   part %d: charset 0x%04x, subset 0x%04x, msg = %s\n", z, sec->charset, sec->charsubset, sec->data);
1075      } else {
1076        owl_function_debugmsg("faimtest_parse_incoming_im_chan1: icbm: multipart:   part %d: charset 0x%04x, subset 0x%04x, binary or UNICODE data\n", z, sec->charset, sec->charsubset);
1077      }
1078    }
1079  }
1080 
1081  if (args->icbmflags & AIM_IMFLAGS_HASICON) {
1082    /* aim_send_im(sess, userinfo->sn, AIM_IMFLAGS_BUDDYREQ, "You have an icon"); */
1083    owl_function_debugmsg("faimtest_parse_incoming_im_chan1: icbm: their icon: iconstamp = %ld, iconlen = 0x%08x, iconsum = 0x%04x\n", args->iconstamp, args->iconlen, args->iconsum);
1084  }
1085
1086  owl_free(realmsg);
1087
1088  return(1);
1089}
1090
1091/*
1092 * Channel 2: Rendevous Request
1093 */
1094static int faimtest_parse_incoming_im_chan2(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args)
1095{
1096  /*
1097  printf("rendezvous: source sn = %s\n", userinfo->sn);
1098  printf("rendezvous: \twarnlevel = %f\n", aim_userinfo_warnlevel(userinfo));
1099  printf("rendezvous: \tclass = 0x%04x = ", userinfo->flags);
1100  printuserflags(userinfo->flags);
1101  printf("\n");
1102 
1103  printf("rendezvous: \tonlinesince = %lu\n", userinfo->onlinesince);
1104  printf("rendezvous: \tidletime = 0x%04x\n", userinfo->idletime);
1105 
1106  printf("rendezvous: message/description = %s\n", args->msg);
1107  printf("rendezvous: encoding = %s\n", args->encoding);
1108  printf("rendezvous: language = %s\n", args->language);
1109  */
1110 
1111  if (args->reqclass == AIM_CAPS_SENDFILE) {
1112    owl_function_debugmsg("faimtest_parse_incoming_im_chan2: send file!");
1113  } else if (args->reqclass == AIM_CAPS_CHAT) {
1114    owl_function_debugmsg("faimtest_parse_incoming_im_chan2: chat invite: %s, %i, %i", args->info.chat.roominfo.name, args->info.chat.roominfo.exchange, args->info.chat.roominfo.instance);
1115    /*
1116    printf("chat invitation: room name = %s\n", args->info.chat.roominfo.name);
1117    printf("chat invitation: exchange = 0x%04x\n", args->info.chat.roominfo.exchange);
1118    printf("chat invitation: instance = 0x%04x\n", args->info.chat.roominfo.instance);
1119    */
1120    /* Automatically join room... */
1121    /* printf("chat invitiation: autojoining %s...\n", args->info.chat.roominfo.name); */
1122
1123    /* aim_chat_join(sess, conn, args->info.chat.roominfo.exchange, args->info.chat.roominfo.name, args->info.chat.roominfo.instance); */
1124  } else if (args->reqclass == AIM_CAPS_BUDDYICON) {
1125    owl_function_debugmsg("faimtest_parse_incoming_im_chan2: Buddy Icon from %s, length = %u\n",
1126                          userinfo->sn, args->info.icon.length);
1127  } else if (args->reqclass == AIM_CAPS_ICQRTF) {
1128    owl_function_debugmsg("faimtest_parse_incoming_im_chan2: RTF message from %s: (fgcolor = 0x%08x, bgcolor = 0x%08x) %s\n",
1129                          userinfo->sn, args->info.rtfmsg.fgcolor, args->info.rtfmsg.bgcolor, args->info.rtfmsg.rtfmsg);
1130  } else {
1131    owl_function_debugmsg("faimtest_parse_incoming_im_chan2: icbm: unknown reqclass (%d)\n", args->reqclass);
1132  }
1133  return 1;
1134}
1135
1136static int faimtest_parse_incoming_im(aim_session_t *sess, aim_frame_t *fr, ...)
1137{
1138  fu16_t channel;
1139  aim_userinfo_t *userinfo;
1140  va_list ap;
1141  int ret = 0;
1142 
1143  va_start(ap, fr);
1144  channel = (fu16_t)va_arg(ap, unsigned int);
1145  userinfo = va_arg(ap, aim_userinfo_t *);
1146 
1147  if (channel == 1) {
1148    struct aim_incomingim_ch1_args *args;
1149    args = va_arg(ap, struct aim_incomingim_ch1_args *);
1150    ret = faimtest_parse_incoming_im_chan1(sess, fr->conn, userinfo, args);
1151  } else if (channel == 2) {
1152    struct aim_incomingim_ch2_args *args;
1153    args = va_arg(ap, struct aim_incomingim_ch2_args *);
1154    ret = faimtest_parse_incoming_im_chan2(sess, fr->conn, userinfo, args);
1155  } else {
1156    owl_function_debugmsg("faimtest_parse_incoming_im: unsupported channel 0x%04x\n", channel);
1157  }
1158  va_end(ap);
1159  owl_function_debugmsg("faimtest_parse_incoming_im: done with ICBM handling (ret = %d)\n", ret);
1160  return 1;
1161}
1162
1163static int faimtest_parse_oncoming(aim_session_t *sess, aim_frame_t *fr, ...)
1164{
1165  aim_userinfo_t *userinfo;
1166  char *nz_screenname;
1167  owl_buddy *b;
1168  va_list ap;
1169  va_start(ap, fr);
1170  userinfo = va_arg(ap, aim_userinfo_t *);
1171  va_end(ap);
1172
1173  nz_screenname=owl_aim_normalize_screenname(userinfo->sn);
1174 
1175  owl_buddylist_oncoming(owl_global_get_buddylist(&g), nz_screenname);
1176
1177  if (userinfo->present & AIM_USERINFO_PRESENT_IDLE) {
1178    owl_function_debugmsg("faimtest_parseoncoming: in empty part of userinfo present and present idle");
1179  }
1180
1181  b=owl_buddylist_get_aim_buddy(owl_global_get_buddylist(&g), nz_screenname);
1182  if (!b) {
1183    owl_function_debugmsg("Error: parse_oncoming setting idle time with no buddy present.");
1184    return(1);
1185  }
1186  if (userinfo->idletime==0) {
1187    owl_buddy_set_unidle(b);
1188  } else {
1189    owl_buddy_set_idle(b);
1190    owl_buddy_set_idle_since(b, userinfo->idletime);
1191  }
1192
1193  if (userinfo->flags & AIM_FLAG_AWAY) {
1194    owl_function_debugmsg("parse_oncoming sn: %s away flag!", userinfo->sn);
1195  }
1196 
1197  owl_function_debugmsg("parse_oncoming sn: %s idle: %i", userinfo->sn, userinfo->idletime);
1198   
1199  owl_free(nz_screenname);
1200 
1201  /*
1202    printf("%ld  %s is now online (flags: %04x = %s%s%s%s%s%s%s%s) (caps = %s = 0x%08lx)\n",
1203    time(NULL),
1204    userinfo->sn, userinfo->flags,
1205    (userinfo->flags&AIM_FLAG_UNCONFIRMED)?" UNCONFIRMED":"",
1206    (userinfo->flags&AIM_FLAG_ADMINISTRATOR)?" ADMINISTRATOR":"",
1207    (userinfo->flags&AIM_FLAG_AOL)?" AOL":"",
1208    (userinfo->flags&AIM_FLAG_OSCAR_PAY)?" OSCAR_PAY":"",
1209    (userinfo->flags&AIM_FLAG_FREE)?" FREE":"",
1210    (userinfo->flags&AIM_FLAG_AWAY)?" AWAY":"",
1211    (userinfo->flags&AIM_FLAG_ICQ)?" ICQ":"",
1212    (userinfo->flags&AIM_FLAG_WIRELESS)?" WIRELESS":"",
1213    (userinfo->present & AIM_USERINFO_PRESENT_CAPABILITIES) ? "present" : "not present",
1214    userinfo->capabilities);
1215  */
1216  return(1);
1217}
1218
1219static int faimtest_parse_offgoing(aim_session_t *sess, aim_frame_t *fr, ...)
1220{
1221  aim_userinfo_t *userinfo;
1222  char *nz_screenname;
1223  va_list ap;
1224 
1225  va_start(ap, fr);
1226  userinfo = va_arg(ap, aim_userinfo_t *);
1227  va_end(ap);
1228
1229  nz_screenname=owl_aim_normalize_screenname(userinfo->sn);
1230  owl_buddylist_offgoing(owl_global_get_buddylist(&g), nz_screenname);
1231  owl_free(nz_screenname);
1232
1233  if (userinfo->present & AIM_USERINFO_PRESENT_IDLE) {
1234    owl_function_debugmsg("parse_offgoing sn: %s idle time %i", userinfo->sn, userinfo->idletime);
1235  }
1236
1237  /*
1238  printf("%ld  %s is now offline (flags: %04x = %s%s%s%s%s%s%s%s) (caps = %s = 0x%08lx)\n",
1239         time(NULL),
1240         userinfo->sn, userinfo->flags,
1241         (userinfo->flags&AIM_FLAG_UNCONFIRMED)?" UNCONFIRMED":"",
1242         (userinfo->flags&AIM_FLAG_ADMINISTRATOR)?" ADMINISTRATOR":"",
1243         (userinfo->flags&AIM_FLAG_AOL)?" AOL":"",
1244         (userinfo->flags&AIM_FLAG_OSCAR_PAY)?" OSCAR_PAY":"",
1245         (userinfo->flags&AIM_FLAG_FREE)?" FREE":"",
1246         (userinfo->flags&AIM_FLAG_AWAY)?" AWAY":"",
1247         (userinfo->flags&AIM_FLAG_ICQ)?" ICQ":"",
1248         (userinfo->flags&AIM_FLAG_WIRELESS)?" WIRELESS":"",
1249         (userinfo->present & AIM_USERINFO_PRESENT_CAPABILITIES) ? "present" : "not present",
1250         userinfo->capabilities);
1251  */
1252 
1253  return 1;
1254}
1255
1256/* Used by chat as well. */
1257int faimtest_parse_genericerr(aim_session_t *sess, aim_frame_t *fr, ...)
1258{
1259  va_list ap;
1260  fu16_t reason;
1261 
1262  va_start(ap, fr);
1263  reason = (fu16_t)va_arg(ap, unsigned int);
1264  va_end(ap);
1265 
1266  /* printf("snac threw error (reason 0x%04x: %s)\n", reason, (reason<msgerrreasonslen)?msgerrreasons[reason]:"unknown"); */
1267  if (reason<msgerrreasonslen) owl_function_error("%s", msgerrreasons[reason]);
1268 
1269  return 1;
1270}
1271
1272static int faimtest_parse_msgerr(aim_session_t *sess, aim_frame_t *fr, ...)
1273{
1274  va_list ap;
1275  const char *destsn;
1276  fu16_t reason;
1277 
1278  va_start(ap, fr);
1279  reason = (fu16_t)va_arg(ap, unsigned int);
1280  destsn = va_arg(ap, const char *);
1281  va_end(ap);
1282 
1283  /* printf("message to %s bounced (reason 0x%04x: %s)\n", destsn, reason, (reason<msgerrreasonslen)?msgerrreasons[reason]:"unknown"); */
1284  if (reason<msgerrreasonslen) owl_function_error("%s", msgerrreasons[reason]);
1285
1286  if (reason==4) {
1287    owl_function_adminmsg("", "Could not send AIM message, user not logged on");
1288  }
1289 
1290  return 1;
1291}
1292
1293static int faimtest_parse_locerr(aim_session_t *sess, aim_frame_t *fr, ...)
1294{
1295  va_list ap;
1296  const char *destsn;
1297  fu16_t reason;
1298 
1299  va_start(ap, fr);
1300  reason = (fu16_t)va_arg(ap, unsigned int);
1301  destsn = va_arg(ap, const char *);
1302  va_end(ap);
1303 
1304  /* printf("user information for %s unavailable (reason 0x%04x: %s)\n", destsn, reason, (reason<msgerrreasonslen)?msgerrreasons[reason]:"unknown"); */
1305  if (reason<msgerrreasonslen) owl_function_error("%s", msgerrreasons[reason]);
1306 
1307  return 1;
1308}
1309
1310static int faimtest_parse_misses(aim_session_t *sess, aim_frame_t *fr, ...)
1311{
1312  static const char *missedreasons[] = {
1313    "Invalid (0)",
1314    "Message too large",
1315    "Rate exceeded",
1316    "Evil Sender",
1317    "Evil Receiver"
1318  };
1319  static int missedreasonslen = 5;
1320 
1321  va_list ap;
1322  fu16_t chan, nummissed, reason;
1323  aim_userinfo_t *userinfo;
1324 
1325  va_start(ap, fr);
1326  chan = (fu16_t)va_arg(ap, unsigned int);
1327  userinfo = va_arg(ap, aim_userinfo_t *);
1328  nummissed = (fu16_t)va_arg(ap, unsigned int);
1329  reason = (fu16_t)va_arg(ap, unsigned int);
1330  va_end(ap);
1331 
1332  owl_function_debugmsg("faimtest_parse_misses: missed %d messages from %s on channel %d (reason %d: %s)\n", nummissed, userinfo->sn, chan, reason, (reason<missedreasonslen)?missedreasons[reason]:"unknown");
1333 
1334  return 1;
1335}
1336
1337/*
1338 * Received in response to an IM sent with the AIM_IMFLAGS_ACK option.
1339 */
1340static int faimtest_parse_msgack(aim_session_t *sess, aim_frame_t *fr, ...)
1341{
1342  va_list ap;
1343  fu16_t type;
1344  const char *sn = NULL;
1345 
1346  va_start(ap, fr);
1347  type = (fu16_t)va_arg(ap, unsigned int);
1348  sn = va_arg(ap, const char *);
1349  va_end(ap);
1350 
1351  owl_function_debugmsg("faimtest_parse_msgack: 0x%04x / %s\n", type, sn);
1352 
1353  return 1;
1354}
1355
1356static int faimtest_parse_ratechange(aim_session_t *sess, aim_frame_t *fr, ...)
1357{
1358  static const char *codes[5] = {
1359    "invalid",
1360    "change",
1361    "warning",
1362    "limit",
1363    "limit cleared"
1364  };
1365  va_list ap;
1366  fu16_t code, rateclass;
1367  fu32_t windowsize, clear, alert, limit, disconnect;
1368  fu32_t currentavg, maxavg;
1369 
1370  va_start(ap, fr); 
1371 
1372  /* See code explanations below */
1373  code = (fu16_t)va_arg(ap, unsigned int);
1374 
1375  /*
1376   * See comments above aim_parse_ratechange_middle() in aim_rxhandlers.c.
1377   */
1378  rateclass = (fu16_t)va_arg(ap, unsigned int);
1379 
1380  /*
1381   * Not sure what this is exactly.  I think its the temporal
1382   * relation factor (ie, how to make the rest of the numbers
1383   * make sense in the real world).
1384   */
1385  windowsize = va_arg(ap, fu32_t);
1386 
1387  /* Explained below */
1388  clear = va_arg(ap, fu32_t);
1389  alert = va_arg(ap, fu32_t);
1390  limit = va_arg(ap, fu32_t);
1391  disconnect = va_arg(ap, fu32_t);
1392  currentavg = va_arg(ap, fu32_t);
1393  maxavg = va_arg(ap, fu32_t);
1394 
1395  va_end(ap);
1396 
1397  owl_function_debugmsg("faimtest_parse_ratechange: rate %s (rate class 0x%04x): curavg = %u, maxavg = %u, alert at %u, clear warning at %u, limit at %u, disconnect at %u (window size = %u)",
1398                        (code < 5)?codes[code]:"invalid",
1399                        rateclass,
1400                        currentavg, maxavg,
1401                        alert, clear,
1402                        limit, disconnect,
1403                        windowsize);
1404  return 1;
1405}
1406
1407static int faimtest_parse_evilnotify(aim_session_t *sess, aim_frame_t *fr, ...)
1408{
1409  va_list ap;
1410  fu16_t newevil;
1411  aim_userinfo_t *userinfo;
1412 
1413  va_start(ap, fr);
1414  newevil = (fu16_t)va_arg(ap, unsigned int);
1415  userinfo = va_arg(ap, aim_userinfo_t *);
1416  va_end(ap);
1417 
1418  /*
1419   * Evil Notifications that are lacking userinfo->sn are anon-warns
1420   * if they are an evil increases, but are not warnings at all if its
1421   * a decrease (its the natural backoff happening).
1422   *
1423   * newevil is passed as an int representing the new evil value times
1424   * ten.
1425   */
1426  owl_function_debugmsg("faimtest_parse_evilnotify: new value = %2.1f%% (caused by %s)\n", ((float)newevil)/10, (userinfo && strlen(userinfo->sn))?userinfo->sn:"anonymous");
1427 
1428  return 1;
1429}
1430
1431static int faimtest_parse_searchreply(aim_session_t *sess, aim_frame_t *fr, ...)
1432{
1433  va_list ap;
1434  const char *address, *SNs;
1435  int num, i;
1436  owl_list list;
1437 
1438  va_start(ap, fr);
1439  address = va_arg(ap, const char *);
1440  num = va_arg(ap, int);
1441  SNs = va_arg(ap, const char *);
1442  va_end(ap);
1443
1444  owl_list_create(&list);
1445 
1446  owl_function_debugmsg("faimtest_parse_searchreply: E-Mail Search Results for %s: ", address);
1447  for (i=0; i<num; i++) {
1448    owl_function_debugmsg("  %s", &SNs[i*(MAXSNLEN+1)]);
1449    owl_list_append_element(&list, (void *)&SNs[i*(MAXSNLEN+1)]);
1450  }
1451  owl_function_aimsearch_results(address, &list);
1452  owl_list_cleanup(&list, NULL);
1453  return(1);
1454}
1455
1456static int faimtest_parse_searcherror(aim_session_t *sess, aim_frame_t *fr, ...)
1457{
1458  va_list ap;
1459  const char *address;
1460 
1461  va_start(ap, fr);
1462  address = va_arg(ap, const char *);
1463  va_end(ap);
1464
1465  owl_function_error("No results searching for %s", address);
1466  owl_function_debugmsg("faimtest_parse_searcherror: E-Mail Search Results for %s: No Results or Invalid Email\n", address);
1467 
1468  return(1);
1469}
1470
1471static int handlepopup(aim_session_t *sess, aim_frame_t *fr, ...)
1472{
1473  va_list ap;
1474  const char *msg, *url;
1475  fu16_t width, height, delay;
1476 
1477  va_start(ap, fr);
1478  msg = va_arg(ap, const char *);
1479  url = va_arg(ap, const char *);
1480  width = va_arg(ap, unsigned int);
1481  height = va_arg(ap, unsigned int);
1482  delay = va_arg(ap, unsigned int);
1483  va_end(ap);
1484 
1485  owl_function_debugmsg("handlepopup: (%dx%x:%d) %s (%s)\n", width, height, delay, msg, url);
1486 
1487  return 1;
1488}
1489
1490static int serverpause(aim_session_t *sess, aim_frame_t *fr, ...)
1491{
1492  aim_sendpauseack(sess, fr->conn);
1493  return 1;
1494}
1495
1496static int migrate(aim_session_t *sess, aim_frame_t *fr, ...)
1497{
1498  va_list ap;
1499  aim_conn_t *bosconn;
1500  const char *bosip;
1501  fu8_t *cookie;
1502 
1503  va_start(ap, fr);
1504  bosip = va_arg(ap, const char *);
1505  cookie = va_arg(ap, fu8_t *);
1506  va_end(ap);
1507 
1508  owl_function_debugmsg("migrate: migration in progress -- new BOS is %s -- disconnecting", bosip);
1509  aim_conn_kill(sess, &fr->conn);
1510 
1511  if (!(bosconn = aim_newconn(sess, AIM_CONN_TYPE_BOS, bosip))) {
1512    owl_function_debugmsg("migrate: could not connect to BOS: internal error");
1513    return 1;
1514  } else if (bosconn->status & AIM_CONN_STATUS_CONNERR) {       
1515    owl_function_debugmsg("migrate: could not connect to BOS");
1516    aim_conn_kill(sess, &bosconn);
1517    return 1;
1518  }
1519 
1520  /* Login will happen all over again. */
1521  addcb_bos(sess, bosconn);
1522  /* aim_sendcookie(sess, bosconn, cookie); */ /********/
1523  return 1;
1524}
1525
1526static int ssirights(aim_session_t *sess, aim_frame_t *fr, ...)
1527{
1528  owl_function_debugmsg("ssirights: got SSI rights, requesting data\n");
1529  /* aim_ssi_reqdata(sess, fr->conn, 0, 0x0000); */
1530  aim_ssi_reqdata(sess);
1531 
1532  return(1);
1533}
1534
1535static int ssidata(aim_session_t *sess, aim_frame_t *fr, ...)
1536{
1537  va_list ap;
1538  fu8_t fmtver;
1539  fu16_t itemcount;
1540  fu32_t stamp;
1541  struct aim_ssi_item *list;
1542  /*
1543  struct aim_ssi_item *curitem;
1544  struct aim_ssi_item *l;
1545  */
1546 
1547  va_start(ap, fr);
1548  fmtver = va_arg(ap, unsigned int);
1549  itemcount = va_arg(ap, unsigned int);
1550  stamp = va_arg(ap, fu32_t);
1551  list = va_arg(ap, struct aim_ssi_item *);
1552  va_end(ap);
1553 
1554  owl_function_debugmsg("ssiddata: got SSI data (0x%02x, %d items, %u)", fmtver, itemcount, stamp);
1555  /*
1556  for (curitem=sess->ssi.local; curitem; curitem=curitem->next) {
1557    for (l = list; l; l = l->next) {
1558      owl_function_debugmsg("\t0x%04x (%s) - 0x%04x/0x%04x", l->type, l->name, l->gid, l->bid);
1559    }
1560  }
1561  */
1562  aim_ssi_enable(sess);
1563 
1564  return 1;
1565}
1566
1567static int ssidatanochange(aim_session_t *sess, aim_frame_t *fr, ...)
1568{
1569  owl_function_debugmsg("ssidatanochange: server says we have the latest SSI data already");
1570  /* aim_ssi_enable(sess, fr->conn); */
1571  aim_ssi_enable(sess);
1572  return 1;
1573}
1574
1575static int offlinemsg(aim_session_t *sess, aim_frame_t *fr, ...)
1576{
1577  va_list ap;
1578  struct aim_icq_offlinemsg *msg;
1579 
1580  va_start(ap, fr);
1581  msg = va_arg(ap, struct aim_icq_offlinemsg *);
1582  va_end(ap);
1583 
1584  if (msg->type == 0x0001) {
1585    owl_function_debugmsg("offlinemsg: from %u at %d/%d/%d %02d:%02d : %s", msg->sender, msg->year, msg->month, msg->day, msg->hour, msg->minute, msg->msg);
1586  } else {
1587    owl_function_debugmsg("unknown offline message type 0x%04x", msg->type);
1588  }
1589  return 1;
1590}
1591
1592static int offlinemsgdone(aim_session_t *sess, aim_frame_t *fr, ...)
1593{
1594  /* Tell the server to delete them. */
1595  owl_function_debugmsg("offlinemsg done: ");
1596  aim_icq_ackofflinemsgs(sess);
1597  return 1;
1598}
1599
1600
1601/******************** chat.c **************************/
1602
1603static int faimtest_chat_join(aim_session_t *sess, aim_frame_t *fr, ...)
1604{
1605  va_list ap;
1606  aim_userinfo_t *userinfo;
1607  int count;
1608  /* int i; */
1609 
1610  va_start(ap, fr);
1611  count = va_arg(ap, int);
1612  userinfo = va_arg(ap, aim_userinfo_t *);
1613  va_end(ap);
1614
1615  owl_function_debugmsg("In faimtest_chat_join");
1616  /*
1617  printf("chat: %s:  New occupants have joined:\n", aim_chat_getname(fr->conn));
1618  for (i = 0; i < count; i++)
1619    printf("chat: %s: \t%s\n", aim_chat_getname(fr->conn), userinfo[i].sn);
1620  */
1621  return 1;
1622}
1623
1624static int faimtest_chat_leave(aim_session_t *sess, aim_frame_t *fr, ...)
1625{
1626  aim_userinfo_t *userinfo;
1627  va_list ap;
1628  int count;
1629  /* int i; */
1630
1631 
1632  va_start(ap, fr);
1633  count = va_arg(ap, int);
1634  userinfo = va_arg(ap, aim_userinfo_t *);
1635  va_end(ap);
1636 
1637  /*
1638    printf("chat: %s:  Some occupants have left:\n", aim_chat_getname(fr->conn));
1639   
1640    for (i = 0; i < count; i++)
1641    printf("chat: %s: \t%s\n", aim_chat_getname(fr->conn), userinfo[i].sn);
1642  */
1643  return 1;
1644}
1645
1646static int faimtest_chat_infoupdate(aim_session_t *sess, aim_frame_t *fr, ...)
1647{
1648  va_list ap;
1649  aim_userinfo_t *userinfo;
1650  struct aim_chat_roominfo *roominfo;
1651  const char *roomname;
1652  int usercount;
1653  const char *roomdesc;
1654  fu16_t flags, unknown_d2, unknown_d5, maxmsglen, maxvisiblemsglen;
1655  fu32_t creationtime;
1656  const char *croomname;
1657  /* int i; */
1658 
1659  croomname = aim_chat_getname(fr->conn);
1660 
1661  va_start(ap, fr);
1662  roominfo = va_arg(ap, struct aim_chat_roominfo *);
1663  roomname = va_arg(ap, const char *);
1664  usercount = va_arg(ap, int);
1665  userinfo = va_arg(ap, aim_userinfo_t *);
1666  roomdesc = va_arg(ap, const char *);
1667  flags = (fu16_t)va_arg(ap, unsigned int);
1668  creationtime = va_arg(ap, fu32_t);
1669  maxmsglen = (fu16_t)va_arg(ap, unsigned int);
1670  unknown_d2 = (fu16_t)va_arg(ap, unsigned int);
1671  unknown_d5 = (fu16_t)va_arg(ap, unsigned int);
1672  maxvisiblemsglen = (fu16_t)va_arg(ap, unsigned int);
1673  va_end(ap);
1674
1675  owl_function_debugmsg("In faimtest_chat_infoupdate");
1676  /*
1677  printf("chat: %s:  info update:\n", croomname);
1678  printf("chat: %s:  \tRoominfo: {%04x, %s, %04x}\n", croomname, roominfo->exchange, roominfo->name, roominfo->instance);
1679  printf("chat: %s:  \tRoomname: %s\n", croomname, roomname);
1680  printf("chat: %s:  \tRoomdesc: %s\n", croomname, roomdesc);
1681  printf("chat: %s:  \tOccupants: (%d)\n", croomname, usercount);
1682
1683  for (i = 0; i < usercount; i++)
1684    printf("chat: %s:  \t\t%s\n", croomname, userinfo[i].sn);
1685 
1686  owl_function_debugmsg("chat: %s:  \tRoom flags: 0x%04x (%s%s%s%s)\n",
1687         croomname, flags,
1688         (flags & AIM_CHATROOM_FLAG_EVILABLE) ? "Evilable, " : "",
1689         (flags & AIM_CHATROOM_FLAG_NAV_ONLY) ? "Nav Only, " : "",
1690         (flags & AIM_CHATROOM_FLAG_INSTANCING_ALLOWED) ? "Instancing allowed, " : "",
1691         (flags & AIM_CHATROOM_FLAG_OCCUPANT_PEEK_ALLOWED) ? "Occupant peek allowed, " : "");
1692  printf("chat: %s:  \tCreation time: %lu (time_t)\n", croomname, creationtime);
1693  printf("chat: %s:  \tUnknown_d2: 0x%04x\n", croomname, unknown_d2);
1694  printf("chat: %s:  \tUnknown_d5: 0x%02x\n", croomname, unknown_d5);
1695  printf("chat: %s:  \tMax message length: %d bytes\n", croomname, maxmsglen);
1696  printf("chat: %s:  \tMax visible message length: %d bytes\n", croomname, maxvisiblemsglen);
1697  */
1698 
1699  return(1);
1700}
1701
1702static int faimtest_chat_incomingmsg(aim_session_t *sess, aim_frame_t *fr, ...)
1703{
1704  va_list ap;
1705  aim_userinfo_t *userinfo;
1706  const char *msg;
1707  char tmpbuf[1152];
1708 
1709  va_start(ap, fr);
1710  userinfo = va_arg(ap, aim_userinfo_t *);     
1711  msg = va_arg(ap, const char *);
1712  va_end(ap);
1713
1714  owl_function_debugmsg("in faimtest_chat_incomingmsg");
1715
1716  /*
1717  printf("chat: %s: incoming msg from %s: %s\n", aim_chat_getname(fr->conn), userinfo->sn, msg);
1718  */
1719 
1720  /*
1721   * Do an echo for testing purposes.  But not for ourselves ("oops!")
1722   */
1723  if (strcmp(userinfo->sn, sess->sn) != 0) {
1724    /* sprintf(tmpbuf, "(%s said \"%s\")", userinfo->sn, msg); */
1725    aim_chat_send_im(sess, fr->conn, 0, tmpbuf, strlen(tmpbuf));
1726  }
1727 
1728  return 1;
1729}
1730
1731static int conninitdone_chat(aim_session_t *sess, aim_frame_t *fr, ...)
1732{
1733  owl_function_debugmsg("faimtest_conninitdone_chat:");
1734
1735  aim_conn_addhandler(sess, fr->conn, 0x000e, 0x0001, faimtest_parse_genericerr, 0);
1736  aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERJOIN, faimtest_chat_join, 0);
1737  aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERLEAVE, faimtest_chat_leave, 0);
1738  aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_ROOMINFOUPDATE, faimtest_chat_infoupdate, 0);
1739  aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_INCOMINGMSG, faimtest_chat_incomingmsg, 0);
1740 
1741  aim_clientready(sess, fr->conn);
1742 
1743  owl_function_debugmsg("Chat ready");
1744
1745  /*
1746    chatcon = find_oscar_chat_by_conn(gc, fr->conn);
1747    chatcon->id = id;
1748    chatcon->cnv = serv_got_joined_chat(gc, id++, chatcon->show);
1749  */
1750  return(1);
1751}
1752
1753void chatnav_redirect(aim_session_t *sess, struct aim_redirect_data *redir)
1754{
1755  aim_conn_t *tstconn;
1756
1757  owl_function_debugmsg("in faimtest_chatnav_redirect");
1758 
1759  tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHATNAV, redir->ip);
1760  if (!tstconn || (tstconn->status & AIM_CONN_STATUS_RESOLVERR)) {
1761    /* printf("unable to connect to chat(nav) server\n"); */
1762    if (tstconn)
1763      aim_conn_kill(sess, &tstconn);
1764    return;
1765  }
1766 
1767  aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
1768  aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, conninitdone_chat, 0);
1769  aim_sendcookie(sess, tstconn, redir->cookielen, redir->cookie);
1770  /* printf("chatnav: connected\n"); */
1771  return;
1772}
1773
1774/* XXX this needs instance too */
1775void chat_redirect(aim_session_t *sess, struct aim_redirect_data *redir)
1776{
1777  aim_conn_t *tstconn;
1778
1779  owl_function_debugmsg("in chat_redirect");
1780 
1781  tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHAT, redir->ip);
1782  if (!tstconn || (tstconn->status & AIM_CONN_STATUS_RESOLVERR)) {
1783    /* printf("unable to connect to chat server\n"); */
1784    if (tstconn) aim_conn_kill(sess, &tstconn);
1785    return; 
1786  }             
1787  /* printf("chat: connected to %s instance %d on exchange %d\n", redir->chat.room, redir->chat.instance, redir->chat.exchange); */
1788 
1789  /*
1790   * We must do this to attach the stored name to the connection!
1791   */
1792  aim_chat_attachname(tstconn, redir->chat.exchange, redir->chat.room, redir->chat.instance);
1793  aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
1794  aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, conninitdone_chat, 0);
1795  aim_sendcookie(sess, tstconn, redir->cookielen, redir->cookie);
1796  return;       
1797}
1798
1799void owl_process_aim(void)
1800{
1801  if (owl_global_is_doaimevents(&g)) {
1802    owl_aim_process_events();
1803  }
1804}
Note: See TracBrowser for help on using the repository browser.