Index: aim.c
===================================================================
--- aim.c	(revision a0a517919ef86311a49f1e5652564bf3c3408ef0)
+++ aim.c	(revision 8c464045b522be5c95316873a192212a54f657aa)
@@ -62,5 +62,4 @@
 void addcb_bos(aim_session_t *sess, aim_conn_t *bosconn);
 static int conninitdone_bos(aim_session_t *sess, aim_frame_t *fr, ...);
-int login(aim_session_t *sess, const char *sn, const char *passwd);
 static int conninitdone_admin(aim_session_t *sess, aim_frame_t *fr, ...);
 int logout(aim_session_t *sess);
@@ -79,5 +78,5 @@
 static int getaimdata(aim_session_t *sess, unsigned char **bufret, int *buflenret, unsigned long offset, unsigned long len, const char *modname);
 static int faimtest_memrequest(aim_session_t *sess, aim_frame_t *fr, ...);
-static void printuserflags(fu16_t flags);
+/* static void printuserflags(fu16_t flags); */
 static int faimtest_parse_userinfo(aim_session_t *sess, aim_frame_t *fr, ...);
 static int faimtest_handlecmd(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, const char *tmpstr);
@@ -105,4 +104,14 @@
 static int offlinemsgdone(aim_session_t *sess, aim_frame_t *fr, ...);
 
+static int faimtest_ssi_parseerr     (aim_session_t *, aim_frame_t *, ...);
+static int faimtest_ssi_parserights  (aim_session_t *, aim_frame_t *, ...);
+static int faimtest_ssi_parselist    (aim_session_t *, aim_frame_t *, ...);
+static int faimtest_ssi_parseack     (aim_session_t *, aim_frame_t *, ...);
+static int faimtest_ssi_authgiven    (aim_session_t *, aim_frame_t *, ...);
+static int faimtest_ssi_authrequest  (aim_session_t *, aim_frame_t *, ...);
+static int faimtest_ssi_authreply    (aim_session_t *, aim_frame_t *, ...);
+static int faimtest_ssi_gotadded     (aim_session_t *, aim_frame_t *, ...);
+
+
 void chatnav_redirect(aim_session_t *sess, struct aim_redirect_data *redir);
 void chat_redirect(aim_session_t *sess, struct aim_redirect_data *redir);
@@ -112,7 +121,11 @@
 void owl_aim_init(void)
 {
-  aim_session_init(owl_global_get_aimsess(&g), AIM_SESS_FLAGS_NONBLOCKCONNECT, 0);
+  /* aim_session_init(owl_global_get_aimsess(&g), AIM_SESS_FLAGS_NONBLOCKCONNECT, 0); */
+
+  /*
+  aim_session_init(owl_global_get_aimsess(&g), TRUE, 0);
   aim_setdebuggingcb(owl_global_get_aimsess(&g), faimtest_debugcb);
-
+  aim_tx_setenqueue(owl_global_get_aimsess(&g), AIM_TX_IMMEDIATE, NULL);
+  */
   /* an experiment to expose idle time */
   /* aim_ssi_setpresence(owl_global_get_aimsess(&g), 0x00000400); */
@@ -122,7 +135,14 @@
 int owl_aim_login(char *screenname, char *password)
 {
-  int ret;
   struct owlfaim_priv *priv;
-
+  aim_conn_t *conn;
+  aim_session_t *sess;
+
+  sess=owl_global_get_aimsess(&g);
+
+  aim_session_init(sess, TRUE, 0);
+  aim_setdebuggingcb(sess, faimtest_debugcb);
+  aim_tx_setenqueue(sess, AIM_TX_IMMEDIATE, NULL);
+  
   /* this will leak, I know and just don't care right now */
   priv=owl_malloc(sizeof(struct owlfaim_priv));
@@ -131,19 +151,48 @@
   priv->screenname = owl_strdup(screenname);
   priv->password = owl_strdup(password);
-  priv->server = "login.oscar.aol.com";
-  owl_global_get_aimsess(&g)->aux_data = priv;
-
-  aim_tx_setenqueue(owl_global_get_aimsess(&g), AIM_TX_IMMEDIATE, NULL);
-  
-  /* request a login */
-  ret=login(owl_global_get_aimsess(&g), priv->screenname, priv->password);
-  if (ret) {
+  priv->server = owl_strdup(FAIM_LOGIN_SERVER);
+  sess->aux_data = priv;
+
+  conn=aim_newconn(sess, AIM_CONN_TYPE_AUTH, priv->server ? priv->server : FAIM_LOGIN_SERVER);
+  /*  conn=aim_newconn(sess, AIM_CONN_TYPE_AUTH, NULL); */
+  if (!conn) {
+    owl_function_error("owl_aim_login: connection error during AIM login\n");
     owl_global_set_aimnologgedin(&g);
     owl_global_set_no_doaimevents(&g);
+    return (-1);
+  }
+
+  /*
+  else if (conn->fd == -1) {
+    if (conn->status & AIM_CONN_STATUS_RESOLVERR) {
+      owl_function_error("owl_aim_login: could not resolve authorize name");
+    } else if (conn->status & AIM_CONN_STATUS_CONNERR) {
+      owl_function_error("owl_aim_login: could not connect to authorizer");
+    } else {
+      owl_function_error("owl_aim_login: unknown connection error");
+    }
+    owl_global_set_aimnologgedin(&g);
+    owl_global_set_no_doaimevents(&g);
+    aim_conn_kill(sess, &conn);
     return(-1);
   }
-
+  */
+
+    
+  aim_conn_addhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_FLAPVER, faimtest_flapversion, 0);
+  aim_conn_addhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
+
+  aim_conn_addhandler(sess, conn, AIM_CB_FAM_ATH, AIM_CB_ATH_AUTHRESPONSE, faimtest_parse_login, 0);
+  aim_conn_addhandler(sess, conn, AIM_CB_FAM_ATH, AIM_CB_ATH_LOGINRESPONSE, faimtest_parse_authresp, 0);
+  /* aim_conn_addhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, gaim_connerr, 0); */
+  /* aim_conn_addhandler(sess, conn, 0x0017, 0x0007, gaim_parse_login, 0); */
+  /* aim_conn_addhandler(sess, conn, 0x0017, 0x0003, gaim_parse_auth_resp, 0); */
+    
   /* start processing AIM events */
   owl_global_set_doaimevents(&g);
+  /* conn->status |= AIM_CONN_STATUS_INPROGRESS; */
+  owl_function_debugmsg("owl_aim_login: sending login request for %s", screenname);
+  aim_request_login(sess, conn, screenname);
+  owl_function_debugmsg("owl_aim_login: connecting");
 
   return(0);
@@ -237,8 +286,10 @@
   /* there is a max away message lentgh we should check against */
 
+  /*
   aim_bos_setprofile(owl_global_get_aimsess(&g),
 		     owl_global_get_bosconn(&g),
 		     NULL, NULL, 0, "us-ascii", msg, 
 		     strlen(msg), 0);
+  */
   return(0);
 }
@@ -364,5 +415,5 @@
   va_end(ap);
 
-  owl_function_debugmsg("doing faimtest_parse_login");
+  owl_function_debugmsg("faimtest_parse_login: %s %s %s", priv->screenname, priv->password, key);
 
   aim_send_login(sess, fr->conn, priv->screenname, priv->password, &info, key);
@@ -504,4 +555,16 @@
   aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSGCOMPLETE, offlinemsgdone, 0);
 
+  /*
+  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_ERROR,              faimtest_ssi_parseerr, 0);
+  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RIGHTSINFO,         faimtest_ssi_parserights, 0);
+  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_LIST,               faimtest_ssi_parselist, 0);
+  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_NOLIST,             faimtest_ssi_parselist, 0);
+  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_SRVACK,             faimtest_ssi_parseack, 0);
+  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RECVAUTH,           faimtest_ssi_authgiven, 0);
+  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RECVAUTHREQ,        faimtest_ssi_authrequest, 0);
+  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RECVAUTHREP,        faimtest_ssi_authreply, 0);
+  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_ADDED,              faimtest_ssi_gotadded, 0);
+  */
+
   return;
 }
@@ -510,65 +573,22 @@
 {
   owl_function_debugmsg("doing coninitdone_bos");
+
+
   aim_reqpersonalinfo(sess, fr->conn);
-
   aim_ssi_reqrights(sess);
   aim_ssi_reqdata(sess);
-
-  aim_bos_reqlocaterights(sess, fr->conn);
-  aim_bos_reqbuddyrights(sess, fr->conn);
+  aim_locate_reqrights(sess);
+  aim_buddylist_reqrights(sess, fr->conn);
+
   aim_im_reqparams(sess);
-  aim_bos_reqrights(sess, fr->conn); /* XXX - Don't call this with ssi? */
-
-  /* aim_bos_setprofile(owl_global_get_aimsess(&g), fr->conn, NULL, NULL, 0, NULL, NULL, 0, AIM_CAPS_EMPTY); */
-
-#ifdef NOSSI
-  /*
+  /* aim_bos_reqrights(sess, fr->conn); */ /* XXX - Don't call this with ssi */
+
+  owl_function_debugmsg("conninitdone_bos: requesting rights");
+  aim_bos_reqrights(sess, fr->conn); /* XXX - Don't call this with ssi */
   aim_bos_setgroupperm(sess, fr->conn, AIM_FLAG_ALLUSERS);
   aim_bos_setprivacyflags(sess, fr->conn, AIM_PRIVFLAGS_ALLOWIDLE | AIM_PRIVFLAGS_ALLOWMEMBERSINCE);
-  */
-#endif
 
   return(1);
 }
-
-int login(aim_session_t *sess, const char *sn, const char *passwd)
-{
-  struct owlfaim_priv *priv = (struct owlfaim_priv *)sess->aux_data;
-  aim_conn_t *authconn;
-
-  if (sn) priv->screenname = strdup(sn);
-  if (passwd) priv->password = strdup(passwd);
-  if (priv->proxy) aim_setupproxy(sess, priv->proxy, priv->proxyusername, priv->proxypass);
-
-  if (!priv->screenname || !priv->password) {
-    owl_function_error("Internal error: aim login called without screenname or password");
-    return(-1);
-  }
-
-  if (!(authconn = aim_newconn(sess, AIM_CONN_TYPE_AUTH, priv->server ? priv->server : FAIM_LOGIN_SERVER))) {
-    owl_function_error("Internal error: connection error during AIM login\n");
-    return (-1);
-  } else if (authconn->fd == -1) {
-    if (authconn->status & AIM_CONN_STATUS_RESOLVERR) {
-      owl_function_error("AIM: could not resolve authorize name");
-    } else if (authconn->status & AIM_CONN_STATUS_CONNERR) {
-      owl_function_error("AIM: could not connect to authorizer");
-    }
-    aim_conn_kill(sess, &authconn);
-    return(-1);
-  }
-
-  aim_conn_addhandler(sess, authconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_FLAPVER, faimtest_flapversion, 0);
-  aim_conn_addhandler(sess, authconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
-  aim_conn_addhandler(sess, authconn, 0x0017, 0x0007, faimtest_parse_login, 0);
-  aim_conn_addhandler(sess, authconn, 0x0017, 0x0003, faimtest_parse_authresp, 0);
-
-  /* If the connection is in progress, this will just be queued */
-  aim_request_login(sess, authconn, priv->screenname);
-  owl_function_debugmsg("AIM login request sent for %s", priv->screenname);
-
-  return(0);
-}
-
 
 static int conninitdone_admin(aim_session_t *sess, aim_frame_t *fr, ...)
@@ -607,5 +627,5 @@
   va_end(ap);
   
-  /* printf("connerr: Code 0x%04x: %s\n", code, msg); */
+  owl_function_error("faimtest_parse_connerr: Code 0x%04x: %s\n", code, msg);
   aim_conn_kill(sess, &fr->conn); /* this will break the main loop */
   
@@ -623,6 +643,7 @@
   status = va_arg(ap, int); /* status code of confirmation request */
   va_end(ap);
-  
-  /* printf("account confirmation returned status 0x%04x (%s)\n", status, (status==0x0000)?"email sent":"unknown"); */
+
+  /* owl_function_debugmsg("faimtest_accountconfirm: Code 0x%04x: %s\n", code, msg); */
+  owl_function_debugmsg("faimtest_accountconfirm: account confirmation returned status 0x%04x (%s)\n", status, (status==0x0000)?"email sent":"unknown");
   
   return 1;
@@ -645,7 +666,7 @@
   va_end(ap);
   
-  /* printf("info%s: perms = %d, type = %x, length = %d, val = %s\n", change?" change":"", perms, type, length, str?val:"(not string)"); */
-  
-  return 1;
+  owl_function_debugmsg("faimtest_infochange: info%s: perms = %d, type = %x, length = %d, val = %s", change?" change":"", perms, type, length, str?val:"(not string)");
+  
+  return(1);
 }
 
@@ -666,5 +687,5 @@
     tstconn = aim_newconn(sess, AIM_CONN_TYPE_AUTH, redir->ip);
     if (!tstconn || (tstconn->status & AIM_CONN_STATUS_RESOLVERR)) {
-      /* printf("unable to reconnect with authorizer\n"); */
+      owl_function_error("faimtest_handleredirect: unable to reconnect with authorizer");
     } else {
       aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_FLAPVER, faimtest_flapversion, 0);
@@ -676,5 +697,5 @@
       /* Send the cookie to the Auth */
       aim_sendcookie(sess, tstconn, redir->cookielen, redir->cookie);
-      /* printf("sent cookie to authorizer host\n"); */
+      owl_function_debugmsg("faimtest_handleredirect: sent cookie to authorizer host");
     }
   } else if (redir->group == 0x000d) {  /* ChatNav */
@@ -683,5 +704,5 @@
     chat_redirect(sess, redir);
   } else {
-    /* printf("uh oh... got redirect for unknown service 0x%04x!!\n", redir->group); */
+    owl_function_debugmsg("faimtest_handleredirect: uh oh... got redirect for unknown service 0x%04x!!", redir->group);
   }
   va_end(ap);
@@ -698,5 +719,6 @@
   va_end(ap);
   
-  /* printf("ICBM Parameters: maxchannel = %d, default flags = 0x%08lx, max msg len = %d, max sender evil = %f, max reciever evil = %f, min msg interval = %ld\n", params->maxchan, params->flags, params->maxmsglen, ((float)params->maxsenderwarn)/10.0, ((float)params->maxrecverwarn)/10.0, params->minmsginterval); */
+  owl_function_debugmsg("faimtest_icbmparaminfo: ICBM Parameters: maxchannel = %d, default flags = 0x%08lx, max msg len = %d, max sender evil = %f, max reciever evil = %f, min msg interval = %ld",
+		       params->maxchan, params->flags, params->maxmsglen, ((float)params->maxsenderwarn)/10.0, ((float)params->maxrecverwarn)/10.0, params->minmsginterval);
      
   /*
@@ -724,6 +746,5 @@
   va_end(ap);
   
-  /* printf("buddy list rights: Max buddies = %d / Max watchers = %d\n", maxbuddies, maxwatchers); */
-  owl_function_debugmsg("in faimtest_parse_buddyrights");
+  owl_function_debugmsg("faimtest_parse_buddyrights: Max buddies = %d / Max watchers = %d\n", maxbuddies, maxwatchers);
   
   /* aim_ssi_reqrights(sess, fr->conn); */
@@ -743,5 +764,5 @@
   va_end(ap);
   
-  /* printf("BOS rights: Max permit = %d / Max deny = %d\n", maxpermits, maxdenies); */
+  owl_function_debugmsg("faimtest_bosrights: Max permit = %d / Max deny = %d\n", maxpermits, maxdenies);
   aim_clientready(sess, fr->conn);
   owl_function_debugmsg("officially connected to BOS.");
@@ -759,7 +780,5 @@
   va_end(ap);
 
-  owl_function_debugmsg("in faimtest_parse_locrights");
-
-  /* printf("locate rights: max signature length = %d\n", maxsiglen); */
+  owl_function_debugmsg("faimtest_locrights: rights: max signature length = %d\n", maxsiglen);
   
   return(1);
@@ -776,5 +795,5 @@
   va_end(ap);
 
-  /* printf("minimum report interval: %d (seconds?)\n", interval); */
+  owl_function_debugmsg("faimtest_reportinterval: %d (seconds?)\n", interval);
 
   if (!priv->connected) {
@@ -792,5 +811,5 @@
   fu16_t id;
   va_list ap;
-  /* static int codeslen = 5;
+  static int codeslen = 5;
   static char *codes[] = {
     "Unknown",
@@ -800,14 +819,11 @@
     "Top o' the world!"
   };
-  */
-
-  return 1;
-  
+
   va_start(ap, fr);
   id = va_arg(ap, int);
   msg = va_arg(ap, char *);
   va_end(ap);
-  
-  /* printf("motd: %s (%d / %s)\n", msg, id, (id < codeslen)?codes[id]:"unknown"); */
+
+  owl_function_debugmsg("faimtest_parse_motd: %s (%d / %s)\n", msg?msg:"nomsg", id, (id < codeslen)?codes[id]:"unknown");
   
   return 1;
@@ -887,5 +903,5 @@
     
     free(filename); /* not needed */
-    printf("memrequest: recieved invalid request for 0x%08lx bytes at 0x%08lx (file %s)\n", len, offset, modname);
+    owl_function_error("getaimdata memrequest: recieved invalid request for 0x%08lx bytes at 0x%08lx (file %s)\n", len, offset, modname);
     i = 8;
     if (modname) {
@@ -978,5 +994,5 @@
     free(buf);
   } else {
-    /* printf("memrequest: unable to use AIM binary (\"%s/%s\"), sending defaults...\n", priv->aimbinarypath, modname); */
+    owl_function_debugmsg("faimtest_memrequest: unable to use AIM binary (\"%s/%s\"), sending defaults...\n", priv->aimbinarypath, modname);
     aim_sendmemblock(sess, fr->conn, offset, len, NULL, AIM_SENDMEMBLOCK_FLAG_ISREQUEST);
   }
@@ -984,28 +1000,20 @@
 }
 
+/*
 static void printuserflags(fu16_t flags)
 {
-
-  if (flags & AIM_FLAG_UNCONFIRMED)
-    printf("UNCONFIRMED ");
-  if (flags & AIM_FLAG_ADMINISTRATOR)
-    printf("ADMINISTRATOR ");
-  if (flags & AIM_FLAG_AOL)
-    printf("AOL ");
-  if (flags & AIM_FLAG_OSCAR_PAY)
-    printf("OSCAR_PAY ");
-  if (flags & AIM_FLAG_FREE)
-    printf("FREE ");
-  if (flags & AIM_FLAG_AWAY)
-    printf("AWAY ");
-  if (flags & AIM_FLAG_ICQ)
-    printf("ICQ ");
-  if (flags & AIM_FLAG_WIRELESS)
-    printf("WIRELESS ");
-  if (flags & AIM_FLAG_ACTIVEBUDDY)
-    printf("ACTIVEBUDDY ");
+  if (flags & AIM_FLAG_UNCONFIRMED) printf("UNCONFIRMED ");
+  if (flags & AIM_FLAG_ADMINISTRATOR) printf("ADMINISTRATOR ");
+  if (flags & AIM_FLAG_AOL) printf("AOL ");
+  if (flags & AIM_FLAG_OSCAR_PAY) printf("OSCAR_PAY ");
+  if (flags & AIM_FLAG_FREE) printf("FREE ");
+  if (flags & AIM_FLAG_AWAY) printf("AWAY ");
+  if (flags & AIM_FLAG_ICQ) printf("ICQ ");
+  if (flags & AIM_FLAG_WIRELESS) printf("WIRELESS ");
+  if (flags & AIM_FLAG_ACTIVEBUDDY) printf("ACTIVEBUDDY ");
   
   return;
 }
+*/
 
 static int faimtest_parse_userinfo(aim_session_t *sess, aim_frame_t *fr, ...)
@@ -1046,5 +1054,6 @@
   printf("userinfo: capabilities = %s = 0x%08lx\n", (userinfo->present & AIM_USERINFO_PRESENT_CAPABILITIES) ? "present" : "not present", userinfo->capabilities);
   */
-  
+
+  /*
   if (inforeq == AIM_GETINFO_GENERALINFO) {
     owl_function_debugmsg("userinfo: profile_encoding: %s\n", prof_encoding ? prof_encoding : "[none]");
@@ -1058,5 +1067,5 @@
     owl_function_debugmsg("userinfo: unknown info request\n");
   }
-  
+  */
   return(1);
 }
@@ -1362,4 +1371,5 @@
   }
 
+  owl_function_debugmsg("faimtest_parse_incoming_im_chan1: message from: %s", userinfo->sn?userinfo->sn:"");
   /* create a message, and put it on the message queue */
   stripmsg=owl_text_htmlstrip(realmsg);
@@ -1379,6 +1389,6 @@
 
   return(1);
-  
-  /* printf("icbm: message: %s\n", realmsg); */
+
+  owl_function_debugmsg("faimtest_parse_incoming_im_chan1: icbm: message: %s\n", realmsg);
   
   if (args->icbmflags & AIM_IMFLAGS_MULTIPART) {
@@ -1386,11 +1396,11 @@
     int z;
 
-    /* printf("icbm: multipart: this message has %d parts\n", args->mpmsg.numparts); */
+    owl_function_debugmsg("faimtest_parse_incoming_im_chan1: icbm: multipart: this message has %d parts\n", args->mpmsg.numparts);
     
     for (sec = args->mpmsg.parts, z = 0; sec; sec = sec->next, z++) {
       if ((sec->charset == 0x0000) || (sec->charset == 0x0003) || (sec->charset == 0xffff)) {
-	/* printf("icbm: multipart:   part %d: charset 0x%04x, subset 0x%04x, msg = %s\n", z, sec->charset, sec->charsubset, sec->data); */
+	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);
       } else {
-	/* printf("icbm: multipart:   part %d: charset 0x%04x, subset 0x%04x, binary or UNICODE data\n", z, sec->charset, sec->charsubset); */
+	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);
       }
     }
@@ -1399,5 +1409,5 @@
   if (args->icbmflags & AIM_IMFLAGS_HASICON) {
     /* aim_send_im(sess, userinfo->sn, AIM_IMFLAGS_BUDDYREQ, "You have an icon"); */
-    /* printf("icbm: their icon: iconstamp = %ld, iconlen = 0x%08lx, iconsum = 0x%04x\n", args->iconstamp, args->iconlen, args->iconsum); */
+    owl_function_debugmsg("faimtest_parse_incoming_im_chan1: icbm: their icon: iconstamp = %ld, iconlen = 0x%08lx, iconsum = 0x%04x\n", args->iconstamp, args->iconlen, args->iconsum);
   }
 
@@ -1445,7 +1455,7 @@
   
   if (args->reqclass == AIM_CAPS_SENDFILE) {
-    /* printf("send file!\n"); */
+    owl_function_debugmsg("faimtest_parse_incoming_im_chan2: send file!");
   } else if (args->reqclass == AIM_CAPS_CHAT) {
-    owl_function_debugmsg("chat invite: %s, %i, %i", args->info.chat.roominfo.name, args->info.chat.roominfo.exchange, args->info.chat.roominfo.instance);
+    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);
     /*
     printf("chat invitation: room name = %s\n", args->info.chat.roominfo.name);
@@ -1458,9 +1468,11 @@
     /* aim_chat_join(sess, conn, args->info.chat.roominfo.exchange, args->info.chat.roominfo.name, args->info.chat.roominfo.instance); */
   } else if (args->reqclass == AIM_CAPS_BUDDYICON) {
-    /* printf("Buddy Icon from %s, length = %lu\n", userinfo->sn, args->info.icon.length); */
+    owl_function_debugmsg("faimtest_parse_incoming_im_chan2: Buddy Icon from %s, length = %lu\n",
+			  userinfo->sn, args->info.icon.length);
   } else if (args->reqclass == AIM_CAPS_ICQRTF) {
-    /* printf("RTF message from %s: (fgcolor = 0x%08lx, bgcolor = 0x%08lx) %s\n", userinfo->sn, args->info.rtfmsg.fgcolor, args->info.rtfmsg.bgcolor, args->info.rtfmsg.rtfmsg); */
+    owl_function_debugmsg("faimtest_parse_incoming_im_chan2: RTF message from %s: (fgcolor = 0x%08lx, bgcolor = 0x%08lx) %s\n",
+			  userinfo->sn, args->info.rtfmsg.fgcolor, args->info.rtfmsg.bgcolor, args->info.rtfmsg.rtfmsg);
   } else {
-    /* printf("icbm: unknown reqclass (%d)\n", args->reqclass); */
+    owl_function_debugmsg("faimtest_parse_incoming_im_chan2: icbm: unknown reqclass (%d)\n", args->reqclass);
   }
   return 1;
@@ -1487,8 +1499,8 @@
     ret = faimtest_parse_incoming_im_chan2(sess, fr->conn, userinfo, args);
   } else {
-    /* printf("unsupported channel 0x%04x\n", channel); */
-  }
-  va_end(ap);
-  /* printf("icbm: done with ICBM handling (ret = %d)\n", ret); */
+    owl_function_debugmsg("faimtest_parse_incoming_im: unsupported channel 0x%04x\n", channel);
+  }
+  va_end(ap);
+  owl_function_debugmsg("faimtest_parse_incoming_im: done with ICBM handling (ret = %d)\n", ret);
   return 1;
 }
@@ -1511,5 +1523,5 @@
 
   if (userinfo->present & AIM_USERINFO_PRESENT_IDLE) {
-    /*  */
+    owl_function_debugmsg("faimtest_parseoncoming: in empty part of userinfo present and present idle");
   }
 
@@ -1645,5 +1657,4 @@
 static int faimtest_parse_misses(aim_session_t *sess, aim_frame_t *fr, ...)
 {
-  /*
   static char *missedreasons[] = {
     "Invalid (0)",
@@ -1653,5 +1664,5 @@
     "Evil Receiver"
   };
-  static int missedreasonslen = 5; */
+  static int missedreasonslen = 5;
   
   va_list ap;
@@ -1666,5 +1677,5 @@
   va_end(ap);
   
-  /* printf("missed %d messages from %s on channel %d (reason %d: %s)\n", nummissed, userinfo->sn, chan, reason, (reason<missedreasonslen)?missedreasons[reason]:"unknown"); */
+  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");
   
   return 1;
@@ -1685,5 +1696,5 @@
   va_end(ap);
   
-  /* printf("msgack: 0x%04x / %s\n", type, sn); */
+  owl_function_debugmsg("faimtest_parse_msgack: 0x%04x / %s\n", type, sn);
   
   return 1;
@@ -1692,5 +1703,4 @@
 static int faimtest_parse_ratechange(aim_session_t *sess, aim_frame_t *fr, ...)
 {
-  /*
   static char *codes[5] = {
     "invalid",
@@ -1700,5 +1710,4 @@
     "limit cleared"
   };
-  */
   va_list ap;
   fu16_t code, rateclass;
@@ -1733,13 +1742,11 @@
   va_end(ap);
   
-  /*
-  printf("rate %s (rate class 0x%04x): curavg = %ld, maxavg = %ld, alert at %ld, clear warning at %ld, limit at %ld, disconnect at %ld (window size = %ld)\n",
-	 (code < 5)?codes[code]:"invalid",
-	 rateclass,
-	 currentavg, maxavg,
-	 alert, clear,
-	 limit, disconnect,
-	 windowsize);
-  */
+  owl_function_debugmsg("faimtest_parse_ratechange: rate %s (rate class 0x%04x): curavg = %ld, maxavg = %ld, alert at %ld, clear warning at %ld, limit at %ld, disconnect at %ld (window size = %ld)",
+			(code < 5)?codes[code]:"invalid",
+			rateclass,
+			currentavg, maxavg,
+			alert, clear,
+			limit, disconnect,
+			windowsize);
   return 1;
 }
@@ -1764,5 +1771,5 @@
    * ten.
    */
-  /* printf("evil level change: new value = %2.1f%% (caused by %s)\n", ((float)newevil)/10, (userinfo && strlen(userinfo->sn))?userinfo->sn:"anonymous"); */
+  owl_function_debugmsg("faimtest_parse_evilnotify: new value = %2.1f%% (caused by %s)\n", ((float)newevil)/10, (userinfo && strlen(userinfo->sn))?userinfo->sn:"anonymous");
   
   return 1;
@@ -1773,6 +1780,5 @@
   va_list ap;
   char *address, *SNs;
-  int num;
-  /* int i; */
+  int num, i;
   
   va_start(ap, fr);
@@ -1782,10 +1788,9 @@
   va_end(ap);
   
-  /* printf("E-Mail Search Results for %s: ", address);
-  
-  for(i = 0; i < num; i++)
-    printf("%s, ", &SNs[i*(MAXSNLEN+1)]);
-  printf("\n");
-  */
+  owl_function_debugmsg("faimtest_parse_searchreply: E-Mail Search Results for %s: ", address);
+  
+  for(i = 0; i < num; i++) {
+    owl_function_debugmsg("  %s", &SNs[i*(MAXSNLEN+1)]);
+  }
   
   return 1;
@@ -1801,5 +1806,5 @@
   va_end(ap);
   
-  /* printf("E-Mail Search Results for %s: No Results or Invalid Email\n", address); */
+  owl_function_debugmsg("faimtest_parse_searcherror: E-Mail Search Results for %s: No Results or Invalid Email\n", address);
   
   return 1;
@@ -1820,5 +1825,5 @@
   va_end(ap);
   
-  /* printf("popup: (%dx%x:%d) %s (%s)\n", width, height, delay, msg, url); */
+  owl_function_debugmsg("handlepopup: (%dx%x:%d) %s (%s)\n", width, height, delay, msg, url);
   
   return 1;
@@ -1843,12 +1848,12 @@
   va_end(ap);
   
-  /* printf("migration in progress -- new BOS is %s -- disconnecting\n", bosip); */
+  owl_function_debugmsg("migrate: migration in progress -- new BOS is %s -- disconnecting", bosip);
   aim_conn_kill(sess, &fr->conn);
   
   if (!(bosconn = aim_newconn(sess, AIM_CONN_TYPE_BOS, bosip))) {
-    /* printf("migrate: could not connect to BOS: internal error\n"); */
+    owl_function_debugmsg("migrate: could not connect to BOS: internal error");
     return 1;
   } else if (bosconn->status & AIM_CONN_STATUS_CONNERR) {	
-    /* printf("migrate: could not connect to BOS\n"); */
+    owl_function_debugmsg("migrate: could not connect to BOS");
     aim_conn_kill(sess, &bosconn);
     return 1;
@@ -1857,5 +1862,5 @@
   /* Login will happen all over again. */
   addcb_bos(sess, bosconn);
-  /* aim_sendcookie(sess, bosconn, cookie); */
+  /* aim_sendcookie(sess, bosconn, cookie); */ /********/
   return 1;
 }
@@ -1863,5 +1868,5 @@
 static int ssirights(aim_session_t *sess, aim_frame_t *fr, ...)
 {
-  /* printf("got SSI rights, requesting data\n"); */
+  owl_function_debugmsg("ssirights: got SSI rights, requesting data\n");
   /* aim_ssi_reqdata(sess, fr->conn, 0, 0x0000); */
   aim_ssi_reqdata(sess);
@@ -1878,5 +1883,5 @@
   struct aim_ssi_item *list;
   struct aim_ssi_item *curitem;
-  /* struct aim_ssi_item *l; */
+  struct aim_ssi_item *l;
   
   va_start(ap, fr);
@@ -1887,11 +1892,12 @@
   va_end(ap);
   
-  /* printf("got SSI data: (0x%02x, %d items, %ld)\n", fmtver, itemcount, stamp); */
+  owl_function_debugmsg("ssiddata: got SSI data (0x%02x, %d items, %ld)", fmtver, itemcount, stamp);
+  /*
   for (curitem=sess->ssi.local; curitem; curitem=curitem->next) {
-    /* for (l = list; l; l = l->next) { */
-    /* printf("\t0x%04x (%s) - 0x%04x/0x%04x\n", l->type, l->name, l->gid, l->bid); */
-    /* printf("I would have printed data here!\n"); */
-  }
-  
+    for (l = list; l; l = l->next) {
+      owl_function_debugmsg("\t0x%04x (%s) - 0x%04x/0x%04x", l->type, l->name, l->gid, l->bid);
+    }
+  }
+  */
   aim_ssi_enable(sess);
   
@@ -1901,5 +1907,5 @@
 static int ssidatanochange(aim_session_t *sess, aim_frame_t *fr, ...)
 {
-  /* printf("server says we have the latest SSI data already\n"); */
+  owl_function_debugmsg("ssidatanochange: server says we have the latest SSI data already");
   /* aim_ssi_enable(sess, fr->conn); */
   aim_ssi_enable(sess);
@@ -1917,7 +1923,7 @@
   
   if (msg->type == 0x0001) {
-    /* printf("offline message from %ld at %d/%d/%d %02d:%02d : %s\n", msg->sender, msg->year, msg->month, msg->day, msg->hour, msg->minute, msg->msg); */
+    owl_function_debugmsg("offlinemsg: from %ld at %d/%d/%d %02d:%02d : %s", msg->sender, msg->year, msg->month, msg->day, msg->hour, msg->minute, msg->msg);
   } else {
-    /* printf("unknown offline message type 0x%04x\n", msg->type); */
+    owl_function_debugmsg("unknown offline message type 0x%04x", msg->type);
   }
   return 1;
@@ -1927,4 +1933,5 @@
 {
   /* Tell the server to delete them. */
+  owl_function_debugmsg("offlinemsg done: ");
   aim_icq_ackofflinemsgs(sess);
   return 1;
@@ -1933,5 +1940,4 @@
 
 /******************** chat.c **************************/
-
 
 static int faimtest_chat_join(aim_session_t *sess, aim_frame_t *fr, ...)
@@ -2201,68 +2207,449 @@
 
 
-/****************************************/
-
-/*
-static int gaim_parse_oncoming(aim_session_t *sess, aim_frame_t *fr, ...) {
-        struct gaim_connection *gc = sess->aux_data;
-        struct oscar_data *od = gc->proto_data;
-        aim_userinfo_t *info;
-        time_t time_idle = 0, signon = 0;
-        int type = 0;
-        int caps = 0;
-        char *tmp;
-
-        va_list ap;
-        va_start(ap, fr);
-        info = va_arg(ap, aim_userinfo_t *);
-        va_end(ap);
-
-        if (info->present & AIM_USERINFO_PRESENT_CAPABILITIES)
-                caps = info->capabilities;
-        if (info->flags & AIM_FLAG_ACTIVEBUDDY)
-                type |= UC_AB;
-
-        if ((!od->icq) && (info->present & AIM_USERINFO_PRESENT_FLAGS)) {
-                        if (info->flags & AIM_FLAG_UNCONFIRMED)
-                                type |= UC_UNCONFIRMED;
-                        if (info->flags & AIM_FLAG_ADMINISTRATOR)
-                                type |= UC_ADMIN;
-                        if (info->flags & AIM_FLAG_AOL)
-                                type |= UC_AOL;
-                        if (info->flags & AIM_FLAG_FREE)
-                                type |= UC_NORMAL;
-                        if (info->flags & AIM_FLAG_AWAY)
-                                type |= UC_UNAVAILABLE;
-                        if (info->flags & AIM_FLAG_WIRELESS)
-                                type |= UC_WIRELESS;
-        }
-        if (info->present & AIM_USERINFO_PRESENT_ICQEXTSTATUS) {
-                type = (info->icqinfo.status << 16);
-                if (!(info->icqinfo.status & AIM_ICQ_STATE_CHAT) &&
-                      (info->icqinfo.status != AIM_ICQ_STATE_NORMAL)) {
-                        type |= UC_UNAVAILABLE;
-                }
-        }
-
-        if (caps & AIM_CAPS_ICQ)
-                caps ^= AIM_CAPS_ICQ;
-
-        if (info->present & AIM_USERINFO_PRESENT_IDLE) {
-                time(&time_idle);
-                time_idle -= info->idletime*60;
-        }
-
-        if (info->present & AIM_USERINFO_PRESENT_SESSIONLEN)
-                signon = time(NULL) - info->sessionlen;
-
-        tmp = g_strdup(normalize(gc->username));
-        if (!strcmp(tmp, normalize(info->sn)))
-                g_snprintf(gc->displayname, sizeof(gc->displayname), "%s", info->sn);
-        g_free(tmp);
-
-        serv_got_update(gc, info->sn, 1, info->warnlevel/10, signon,
-                        time_idle, type, caps);
-
-        return 1;
-}
-*/
+/**********************************************************************************/
+
+
+static int faimtest_ssi_rerequestdata(aim_session_t *sess, aim_frame_t *fr, ...)
+{
+  aim_ssi_reqdata(sess);
+  return(0);
+}
+
+static int faimtest_ssi_parseerr(aim_session_t *sess, aim_frame_t *fr, ...)
+{
+  /* GaimConnection *gc = sess->aux_data; */
+  /*	OscarData *od = gc->proto_data; */
+  va_list ap;
+  fu16_t reason;
+
+  va_start(ap, fr);
+  reason = (fu16_t)va_arg(ap, unsigned int);
+  va_end(ap);
+
+  owl_function_debugmsg("faimtest_ssi_parseerr: ssi: SNAC error %hu", reason);
+
+  if (reason == 0x0005) {
+    owl_function_error("faimtest_ssi_parseerr: unable to retrieve buddy list");
+  }
+
+  /* Activate SSI */
+  /* Sending the enable causes other people to be able to see you, and you to see them */
+  /* Make sure your privacy setting/invisibility is set how you want it before this! */
+  owl_function_debugmsg("faimtest_ssi_parseerr: ssi: activating server-stored buddy list");
+  aim_ssi_enable(sess);
+  
+  return(1);
+}
+
+static int faimtest_ssi_parserights(aim_session_t *sess, aim_frame_t *fr, ...)
+{
+  /* GaimConnection *gc = sess->aux_data; */
+  /* OscarData *od = (OscarData *)gc->proto_data; */
+  int numtypes, i;
+  fu16_t *maxitems;
+  va_list ap;
+
+  va_start(ap, fr);
+  numtypes = va_arg(ap, int);
+  maxitems = va_arg(ap, fu16_t *);
+  va_end(ap);
+
+  owl_function_debugmsg("faimtest_ssi_parserights: ");
+  for (i=0; i<numtypes; i++) {
+    owl_function_debugmsg(" max type 0x%04x=%hd,", i, maxitems[i]);
+  }
+
+  /*
+  if (numtypes >= 0) od->rights.maxbuddies = maxitems[0];
+  if (numtypes >= 1) od->rights.maxgroups = maxitems[1];
+  if (numtypes >= 2) od->rights.maxpermits = maxitems[2];
+  if (numtypes >= 3) od->rights.maxdenies = maxitems[3];
+  */
+  
+  return(1);
+}
+
+#if 0
+static int faimtest_ssi_parselist(aim_session_t *sess, aim_frame_t *fr, ...)
+{
+  /* GaimConnection *gc = sess->aux_data; */
+  /* GaimAccount *account = gaim_connection_get_account(gc); */
+  /* OscarData *od = (OscarData *)gc->proto_data; */
+  struct aim_ssi_item *curitem;
+  int tmp;
+  int export = FALSE;
+  /* XXX - use these?
+     va_list ap;
+     
+     va_start(ap, fr);
+     fmtver = (fu16_t)va_arg(ap, int);
+     numitems = (fu16_t)va_arg(ap, int);
+     items = va_arg(ap, struct aim_ssi_item);
+     timestamp = va_arg(ap, fu32_t);
+     va_end(ap); */
+  
+  owl_function_debugmsg("faimtest_ssi_parselist: syncing local list and server list");
+
+  /* Clean the buddy list */
+  aim_ssi_cleanlist(sess);
+
+  /* Add from server list to local list */
+  for (curitem=sess->ssi.local; curitem; curitem=curitem->next) {
+    if ((curitem->name == NULL) || (g_utf8_validate(curitem->name, -1, NULL)))
+      switch (curitem->type) {
+      case 0x0000: { /* Buddy */
+	if (curitem->name) {
+	  char *gname = aim_ssi_itemlist_findparentname(sess->ssi.local, curitem->name);
+	  char *gname_utf8 = gname ? gaim_utf8_try_convert(gname) : NULL;
+	  char *alias = aim_ssi_getalias(sess->ssi.local, gname, curitem->name);
+	  char *alias_utf8 = alias ? gaim_utf8_try_convert(alias) : NULL;
+	  GaimBuddy *buddy = gaim_find_buddy(gc->account, curitem->name);
+	  /* Should gname be freed here? -- elb */
+	  /* Not with the current code, but that might be cleaner -- med */
+	  free(alias);
+	  if (buddy) {
+	    /* Get server stored alias */
+	    if (alias_utf8) {
+	      g_free(buddy->alias);
+	      buddy->alias = g_strdup(alias_utf8);
+	    }
+	  } else {
+	    GaimGroup *g;
+	    buddy = gaim_buddy_new(gc->account, curitem->name, alias_utf8);
+	    
+	    if (!(g = gaim_find_group(gname_utf8 ? gname_utf8 : _("Orphans")))) {
+	      g = gaim_group_new(gname_utf8 ? gname_utf8 : _("Orphans"));
+	      gaim_blist_add_group(g, NULL);
+	    }
+	    
+	    gaim_debug(GAIM_DEBUG_INFO, "oscar",
+		       "ssi: adding buddy %s to group %s to local list\n", curitem->name, gname_utf8 ? gname_utf8 : _("Orphans"));
+	    gaim_blist_add_buddy(buddy, NULL, g, NULL);
+	    export = TRUE;
+	  }
+	  g_free(gname_utf8);
+	  g_free(alias_utf8);
+	}
+      } break;
+      
+      case 0x0001: { /* Group */
+	/* Shouldn't add empty groups */
+      } break;
+      
+      case 0x0002: { /* Permit buddy */
+	if (curitem->name) {
+	  /* if (!find_permdeny_by_name(gc->permit, curitem->name)) { AAA */
+	  GSList *list;
+	  for (list=account->permit; (list && aim_sncmp(curitem->name, list->data)); list=list->next);
+	  if (!list) {
+	    gaim_debug(GAIM_DEBUG_INFO, "oscar",
+		       "ssi: adding permit buddy %s to local list\n", curitem->name);
+	    gaim_privacy_permit_add(account, curitem->name, TRUE);
+	    export = TRUE;
+	  }
+	}
+      } break;
+      
+      case 0x0003: { /* Deny buddy */
+	if (curitem->name) {
+	  GSList *list;
+	  for (list=account->deny; (list && aim_sncmp(curitem->name, list->data)); list=list->next);
+	  if (!list) {
+	    gaim_debug(GAIM_DEBUG_INFO, "oscar",
+		       "ssi: adding deny buddy %s to local list\n", curitem->name);
+	    gaim_privacy_deny_add(account, curitem->name, TRUE);
+	    export = TRUE;
+	  }
+	}
+      } break;
+      
+      case 0x0004: { /* Permit/deny setting */
+	if (curitem->data) {
+	  fu8_t permdeny;
+	  if ((permdeny = aim_ssi_getpermdeny(sess->ssi.local)) && (permdeny != account->perm_deny)) {
+	    gaim_debug(GAIM_DEBUG_INFO, "oscar",
+		       "ssi: changing permdeny from %d to %hhu\n", account->perm_deny, permdeny);
+	    account->perm_deny = permdeny;
+	    if (od->icq && account->perm_deny == 0x03) {
+	      serv_set_away(gc, "Invisible", "");
+	    }
+	    export = TRUE;
+	  }
+	}
+      } break;
+      
+      case 0x0005: { /* Presence setting */
+	/* We don't want to change Gaim's setting because it applies to all accounts */
+      } break;
+      } /* End of switch on curitem->type */
+  } /* End of for loop */
+  
+  /* If changes were made, then flush buddy list to file */
+  if (export)
+    gaim_blist_save();
+  
+  { /* Add from local list to server list */
+    GaimBlistNode *gnode, *cnode, *bnode;
+    GaimGroup *group;
+    GaimBuddy *buddy;
+    GaimBuddyList *blist;
+    GSList *cur;
+    
+    /* Buddies */
+    if ((blist = gaim_get_blist()))
+      for (gnode = blist->root; gnode; gnode = gnode->next) {
+	if(!GAIM_BLIST_NODE_IS_GROUP(gnode))
+	  continue;
+	group = (GaimGroup *)gnode;
+	for (cnode = gnode->child; cnode; cnode = cnode->next) {
+	  if(!GAIM_BLIST_NODE_IS_CONTACT(cnode))
+	    continue;
+	  for (bnode = cnode->child; bnode; bnode = bnode->next) {
+	    if(!GAIM_BLIST_NODE_IS_BUDDY(bnode))
+	      continue;
+	    buddy = (GaimBuddy *)bnode;
+	    if (buddy->account == gc->account) {
+	      const char *servernick = gaim_buddy_get_setting(buddy, "servernick");
+	      if (servernick)
+		serv_got_alias(gc, buddy->name, servernick);
+	      
+	      if (aim_ssi_itemlist_exists(sess->ssi.local, buddy->name)) {
+		/* Store local alias on server */
+		char *alias = aim_ssi_getalias(sess->ssi.local, group->name, buddy->name);
+		if (!alias && buddy->alias && strlen(buddy->alias))
+		  aim_ssi_aliasbuddy(sess, group->name, buddy->name, buddy->alias);
+		free(alias);
+	      } else {
+		gaim_debug(GAIM_DEBUG_INFO, "oscar",
+			   "ssi: adding buddy %s from local list to server list\n", buddy->name);
+		aim_ssi_addbuddy(sess, buddy->name, group->name, gaim_get_buddy_alias_only(buddy), NULL, NULL, 0);
+	      }
+	    }
+	  }
+	}
+      }
+    
+    /* Permit list */
+    if (gc->account->permit) {
+      for (cur=gc->account->permit; cur; cur=cur->next)
+	if (!aim_ssi_itemlist_finditem(sess->ssi.local, NULL, cur->data, AIM_SSI_TYPE_PERMIT)) {
+	  gaim_debug(GAIM_DEBUG_INFO, "oscar",
+		     "ssi: adding permit %s from local list to server list\n", (char *)cur->data);
+	  aim_ssi_addpermit(sess, cur->data);
+	}
+    }
+    
+    /* Deny list */
+    if (gc->account->deny) {
+      for (cur=gc->account->deny; cur; cur=cur->next)
+	if (!aim_ssi_itemlist_finditem(sess->ssi.local, NULL, cur->data, AIM_SSI_TYPE_DENY)) {
+	  gaim_debug(GAIM_DEBUG_INFO, "oscar",
+		     "ssi: adding deny %s from local list to server list\n", (char *)cur->data);
+	  aim_ssi_adddeny(sess, cur->data);
+	}
+    }
+    /* Presence settings (idle time visibility) */
+    if ((tmp = aim_ssi_getpresence(sess->ssi.local)) != 0xFFFFFFFF)
+      if (!(tmp & 0x400))
+	aim_ssi_setpresence(sess, tmp | 0x400);
+  } /* end adding buddies from local list to server list */
+  
+  /* Set our ICQ status */
+  if  (od->icq && !gc->away) {
+    aim_setextstatus(sess, AIM_ICQ_STATE_NORMAL);
+  }
+  
+  /* Activate SSI */
+  /* Sending the enable causes other people to be able to see you, and you to see them */
+  /* Make sure your privacy setting/invisibility is set how you want it before this! */
+  gaim_debug(GAIM_DEBUG_INFO, "oscar", "ssi: activating server-stored buddy list\n");
+  aim_ssi_enable(sess);
+  
+  return 1;
+}
+
+static int gaim_ssi_parseack(aim_session_t *sess, aim_frame_t *fr, ...)
+{
+  GaimConnection *gc = sess->aux_data;
+  va_list ap;
+  struct aim_ssi_tmp *retval;
+  
+  va_start(ap, fr);
+  retval = va_arg(ap, struct aim_ssi_tmp *);
+  va_end(ap);
+  
+  while (retval) {
+    gaim_debug(GAIM_DEBUG_MISC, "oscar",
+	       "ssi: status is 0x%04hx for a 0x%04hx action with name %s\n", retval->ack,  retval->action, retval->item ? (retval->item->name ? retval->item->name : "no name") : "no item");
+    
+    if (retval->ack != 0xffff)
+      switch (retval->ack) {
+      case 0x0000: { /* added successfully */
+      } break;
+      
+      case 0x000c: { /* you are over the limit, the cheat is to the limit, come on fhqwhgads */
+	gchar *buf;
+	buf = g_strdup_printf(_("Could not add the buddy %s because you have too many buddies in your buddy list.  Please remove one and try again."), (retval->name ? retval->name : _("(no name)")));
+	gaim_notify_error(gc, NULL, _("Unable To Add"), buf);
+	g_free(buf);
+      }
+	
+      case 0x000e: { /* buddy requires authorization */
+	if ((retval->action == AIM_CB_SSI_ADD) && (retval->name))
+	  gaim_auth_sendrequest(gc, retval->name);
+      } break;
+      
+      default: { /* La la la */
+	gchar *buf;
+	gaim_debug(GAIM_DEBUG_ERROR, "oscar", "ssi: Action 0x%04hx was unsuccessful with error 0x%04hx\n", retval->action, retval->ack);
+	buf = g_strdup_printf(_("Could not add the buddy %s for an unknown reason.  The most common reason for this is that you have the maximum number of allowed buddies in your buddy list."), (retval->name ? retval->name : _("(no name)")));
+	gaim_notify_error(gc, NULL, _("Unable To Add"), buf);
+	g_free(buf);
+	/* XXX - Should remove buddy from local list */
+      } break;
+      }
+    
+    retval = retval->next;
+  }
+  
+  return 1;
+}
+
+static int gaim_ssi_authgiven(aim_session_t *sess, aim_frame_t *fr, ...)
+{
+  GaimConnection *gc = sess->aux_data;
+  va_list ap;
+  char *sn, *msg;
+  gchar *dialog_msg, *nombre;
+  struct name_data *data;
+  GaimBuddy *buddy;
+  
+  va_start(ap, fr);
+  sn = va_arg(ap, char *);
+  msg = va_arg(ap, char *);
+  va_end(ap);
+  
+  gaim_debug(GAIM_DEBUG_INFO, "oscar",
+	     "ssi: %s has given you permission to add him to your buddy list\n", sn);
+  
+  buddy = gaim_find_buddy(gc->account, sn);
+  if (buddy && (gaim_get_buddy_alias_only(buddy)))
+    nombre = g_strdup_printf("%s (%s)", sn, gaim_get_buddy_alias_only(buddy));
+  else
+    nombre = g_strdup(sn);
+  
+  dialog_msg = g_strdup_printf(_("The user %s has given you permission to add you to their buddy list.  Do you want to add them?"), nombre);
+  data = g_new(struct name_data, 1);
+  data->gc = gc;
+  data->name = g_strdup(sn);
+  data->nick = NULL;
+  
+  gaim_request_yes_no(gc, NULL, _("Authorization Given"), dialog_msg,
+		      0, data,
+		      G_CALLBACK(gaim_icq_buddyadd),
+		      G_CALLBACK(oscar_free_name_data));
+  
+  g_free(dialog_msg);
+  g_free(nombre);
+  
+  return 1;
+}
+
+static int gaim_ssi_authrequest(aim_session_t *sess, aim_frame_t *fr, ...)
+{
+  GaimConnection *gc = sess->aux_data;
+  va_list ap;
+  char *sn, *msg;
+  gchar *dialog_msg, *nombre;
+  struct name_data *data;
+  GaimBuddy *buddy;
+  
+  va_start(ap, fr);
+  sn = va_arg(ap, char *);
+  msg = va_arg(ap, char *);
+  va_end(ap);
+  
+  gaim_debug(GAIM_DEBUG_INFO, "oscar",
+	     "ssi: received authorization request from %s\n", sn);
+  
+  buddy = gaim_find_buddy(gc->account, sn);
+  if (buddy && (gaim_get_buddy_alias_only(buddy)))
+    nombre = g_strdup_printf("%s (%s)", sn, gaim_get_buddy_alias_only(buddy));
+  else
+    nombre = g_strdup(sn);
+  
+  dialog_msg = g_strdup_printf(_("The user %s wants to add you to their buddy list for the following reason:\n%s"), nombre, msg ? msg : _("No reason given."));
+  data = g_new(struct name_data, 1);
+  data->gc = gc;
+  data->name = g_strdup(sn);
+  data->nick = NULL;
+  
+  gaim_request_action(gc, NULL, _("Authorization Request"), dialog_msg,
+		      0, data, 2,
+		      _("Authorize"), G_CALLBACK(gaim_auth_grant),
+		      _("Deny"), G_CALLBACK(gaim_auth_dontgrant_msgprompt));
+  
+  g_free(dialog_msg);
+  g_free(nombre);
+  
+  return 1;
+}
+
+static int gaim_ssi_authreply(aim_session_t *sess, aim_frame_t *fr, ...)
+{
+  GaimConnection *gc = sess->aux_data;
+  va_list ap;
+  char *sn, *msg;
+  gchar *dialog_msg, *nombre;
+  fu8_t reply;
+  GaimBuddy *buddy;
+  
+  va_start(ap, fr);
+  sn = va_arg(ap, char *);
+  reply = (fu8_t)va_arg(ap, int);
+  msg = va_arg(ap, char *);
+  va_end(ap);
+  
+  gaim_debug(GAIM_DEBUG_INFO, "oscar",
+	     "ssi: received authorization reply from %s.  Reply is 0x%04hhx\n", sn, reply);
+  
+  buddy = gaim_find_buddy(gc->account, sn);
+  if (buddy && (gaim_get_buddy_alias_only(buddy)))
+    nombre = g_strdup_printf("%s (%s)", sn, gaim_get_buddy_alias_only(buddy));
+  else
+    nombre = g_strdup(sn);
+  
+  if (reply) {
+    /* Granted */
+    dialog_msg = g_strdup_printf(_("The user %s has granted your request to add them to your buddy list."), nombre);
+    gaim_notify_info(gc, NULL, _("Authorization Granted"), dialog_msg);
+  } else {
+    /* Denied */
+    dialog_msg = g_strdup_printf(_("The user %s has denied your request to add them to your buddy list for the following reason:\n%s"), nombre, msg ? msg : _("No reason given."));
+    gaim_notify_info(gc, NULL, _("Authorization Denied"), dialog_msg);
+  }
+  g_free(dialog_msg);
+  g_free(nombre);
+  
+  return 1;
+}
+
+static int gaim_ssi_gotadded(aim_session_t *sess, aim_frame_t *fr, ...)
+{
+  GaimConnection *gc = sess->aux_data;
+  va_list ap;
+  char *sn;
+  GaimBuddy *buddy;
+  
+  va_start(ap, fr);
+  sn = va_arg(ap, char *);
+  va_end(ap);
+  
+  buddy = gaim_find_buddy(gc->account, sn);
+  gaim_debug(GAIM_DEBUG_INFO, "oscar",
+	     "ssi: %s added you to their buddy list\n", sn);
+  gaim_account_notify_added(gc->account, NULL, sn, (buddy ? gaim_get_buddy_alias_only(buddy) : NULL), NULL);
+  
+  return 1;
+}
+#endif
