]> andersk Git - libfaim.git/commitdiff
- Sat Jun 24 00:44:24 UTC 2000
authormid <mid>
Sat, 24 Jun 2000 02:01:31 +0000 (02:01 +0000)
committermid <mid>
Sat, 24 Jun 2000 02:01:31 +0000 (02:01 +0000)
   - Support zero-type TLVs in aim_extractinfo()
     - AOL now ocassionally throws extra zeros in so in order to break
         clients.  Aparently zero-type TLVs are a special case -- if the
         type is zero, then _there is no length_ field.  AOL are geniuses.
     - Note that you only get these if you send a bad client string, such
         as the top one in faimtest.  If you #if 0 that one out and use the
         second one, you'll be fine.  (Unless you just want to see the message
         for yourself.  Its nifty. (FREE!))
   - ICBM parser now uses aim_extractuserinfo() so that it can benefit
       from the above changes, as well as clean up the whole "is it the
       first or the second one of this type?" issue
     - This also fixes the changes AOL made in away messages.
   = Fixed a possible buffer overflow when AOL changes the max sn length
   - Increased MAXSNLEN to 32 (they appear to be valid)
     - If you start getting messages from someone called "AOL Instant
        Messenger", see comment one, paragraph two.
   - aim_select() now returns a -1 if there are no connections open
   - Connections are now killed completely if there is a major error on them
   - faimtest now calls aim_logoff() on connection error

CHANGES
aim_conn.c
aim_im.c
aim_info.c
aim_rxqueue.c
aim_txqueue.c
faim/aim.h
utils/faimtest/faimtest.c

diff --git a/CHANGES b/CHANGES
index c9f7d2826c1b0877473224adf2345897b7d0de90..9a47d4a39760ddb422f64dcd87f717caa8354f53 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,27 @@
 
 No release numbers
 ------------------
+ - Sat Jun 24 00:44:24 UTC 2000
+   - Support zero-type TLVs in aim_extractinfo()
+     - AOL now ocassionally throws extra zeros in so in order to break
+         clients.  Aparently zero-type TLVs are a special case -- if the
+         type is zero, then _there is no length_ field.  AOL are geniuses.
+     - Note that you only get these if you send a bad client string, such
+         as the top one in faimtest.  If you #if 0 that one out and use the
+         second one, you'll be fine.  (Unless you just want to see the message
+         for yourself.  Its nifty. (FREE!))
+   - ICBM parser now uses aim_extractuserinfo() so that it can benefit
+       from the above changes, as well as clean up the whole "is it the 
+       first or the second one of this type?" issue
+     - This also fixes the changes AOL made in away messages.
+   = Fixed a possible buffer overflow when AOL changes the max sn length
+   - Increased MAXSNLEN to 32 (they appear to be valid)
+     - If you start getting messages from someone called "AOL Instant
+        Messenger", see comment one, paragraph two.
+   - aim_select() now returns a -1 if there are no connections open
+   - Connections are now killed completely if there is a major error on them
+   - faimtest now calls aim_logoff() on connection error
+
  - Fri Jun 23 22:38:47 UTC 2000
    - Adds start of adverts support
    - Adds aim_bos_nop().  You may want to send this occassionally
index 061409f74b78a672d39eda164e2f76b21683c18f..2e1c35fd57df188d2c84baa57f58b54027084bca 100644 (file)
@@ -80,6 +80,9 @@ void aim_conn_kill(struct aim_session_t *sess, struct aim_conn_t **deadconn)
   }
   faim_mutex_unlock(&sess->connlistlock);
 
+  /* XXX: do we need this for txqueue too? */
+  aim_rxqueue_cleanbyconn(sess, *deadconn);
+
   aim_conn_close(*deadconn);
   free(*deadconn);
   deadconn = NULL;
@@ -255,7 +258,8 @@ struct aim_conn_t *aim_select(struct aim_session_t *sess,
   faim_mutex_lock(&sess->connlistlock);
   if (sess->connlist == NULL) {
     faim_mutex_unlock(&sess->connlistlock);
-    return 0;
+    *status = -1;
+    return NULL;
   }
   faim_mutex_unlock(&sess->connlistlock);
 
index c380cc772746904ac145414e39c24d0871b6242f..f82ecfa23bc521e7e3fd604314b97f83c7f131c3 100644 (file)
--- a/aim_im.c
+++ b/aim_im.c
@@ -276,27 +276,26 @@ int aim_parse_incoming_im_middle(struct aim_session_t *sess,
     }
 
   /*
-   * Source screen name.
-   */
-  memcpy(userinfo.sn, command->data+i+1, (int)command->data[i]);
-  userinfo.sn[(int)command->data[i]] = '\0';
-  i += 1 + (int)command->data[i];
-
-  /*
-   * Warning Level
-   */
-  userinfo.warnlevel = aimutil_get16(command->data+i); /* guess */
-  i += 2;
-
-  /*
-   * Number of TLVs that follow.  Not needed.
+   * Extract the standard user info block.
+   *
+   * Note that although this contains TLVs that appear contiguous
+   * with the TLVs read below, they are two different pieces.  The
+   * userinfo block contains the number of TLVs that contain user
+   * information, the rest are not even though there is no seperation.
+   * aim_extractuserinfo() returns the number of bytes used by the
+   * userinfo tlvs, so you can start reading the rest of them right
+   * afterward.  
+   *
+   * That also means that TLV types can be duplicated between the
+   * userinfo block and the rest of the message, however there should
+   * never be two TLVs of the same type in one block.
+   * 
    */
-  wastebits = aimutil_get16(command->data+i);
-  i += 2;
+  i += aim_extractuserinfo(command->data+i, &userinfo);
   
   /*
-   * Read block of TLVs.  All further data is derived
-   * from what is parsed here.
+   * Read block of TLVs (not including the userinfo data).  All 
+   * further data is derived from what is parsed here.
    */
   tlvlist = aim_readtlvchain(command->data+i, command->commandlen-i);
 
@@ -314,55 +313,26 @@ int aim_parse_incoming_im_middle(struct aim_session_t *sess,
            
       /*
        * Check Autoresponse status.  If it is an autoresponse,
-       * it will contain a second type 0x0004 TLV, with zero length.
+       * it will contain a type 0x0004 TLV, with zero length.
        */
-      if (aim_gettlv(tlvlist, 0x0004, 2))
+      if (aim_gettlv(tlvlist, 0x0004, 1))
        icbmflags |= AIM_IMFLAGS_AWAY;
       
       /*
        * Check Ack Request status.
        */
-      if (aim_gettlv(tlvlist, 0x0003, 2))
+      if (aim_gettlv(tlvlist, 0x0003, 1))
        icbmflags |= AIM_IMFLAGS_ACK;
       
-      /*
-       * Extract the various pieces of the userinfo struct.
-       */
-      /* Class. */
-      if ((tmptlv = aim_gettlv(tlvlist, 0x0001, 1)))
-       userinfo.class = aimutil_get16(tmptlv->value);
-      /* Member-since date. */
-      if ((tmptlv = aim_gettlv(tlvlist, 0x0002, 1)))
-       {
-         /* If this is larger than 4, its probably the message block, skip */
-         if (tmptlv->length <= 4)
-           userinfo.membersince = aimutil_get32(tmptlv->value);
-       }
-      /* On-since date */
-      if ((tmptlv = aim_gettlv(tlvlist, 0x0003, 1)))
-       userinfo.onlinesince = aimutil_get32(tmptlv->value);
-      /* Idle-time */
-      if ((tmptlv = aim_gettlv(tlvlist, 0x0004, 1)))
-       userinfo.idletime = aimutil_get16(tmptlv->value);
-      /* Session Length (AIM) */
-      if ((tmptlv = aim_gettlv(tlvlist, 0x000f, 1)))
-       userinfo.sessionlen = aimutil_get16(tmptlv->value);
-      /* Session Length (AOL) */
-      if ((tmptlv = aim_gettlv(tlvlist, 0x0010, 1)))
-       userinfo.sessionlen = aimutil_get16(tmptlv->value);
-      
       /*
        * Message block.
-       *
-       * XXX: Will the msgblock always be the second 0x0002? 
        */
       msgblocktlv = aim_gettlv(tlvlist, 0x0002, 1);
-      if (!msgblocktlv || !msgblocktlv->value)
-       {
-         printf("faim: icbm: major error! no message block TLV found!\n");
-         aim_freetlvchain(&tlvlist);
-         return 1;
-       }
+      if (!msgblocktlv || !msgblocktlv->value) {
+       printf("faim: icbm: major error! no message block TLV found!\n");
+       aim_freetlvchain(&tlvlist);
+       return 1;
+      }
       
       /*
        * Extracting the message from the unknown cruft.
@@ -438,22 +408,6 @@ int aim_parse_incoming_im_middle(struct aim_session_t *sess,
       unsigned short reqclass = 0;
       unsigned short status = 0;
       
-      /* Class. */
-      if ((tmptlv = aim_gettlv(tlvlist, 0x0001, 1)))
-       userinfo.class = aimutil_get16(tmptlv->value);
-      /* On-since date */
-      if ((tmptlv = aim_gettlv(tlvlist, 0x0003, 1)))
-       userinfo.onlinesince = aimutil_get32(tmptlv->value);
-      /* Idle-time */
-      if ((tmptlv = aim_gettlv(tlvlist, 0x0004, 1)))
-       userinfo.idletime = aimutil_get16(tmptlv->value);
-      /* Session Length (AIM) */
-      if ((tmptlv = aim_gettlv(tlvlist, 0x000f, 1)))
-       userinfo.sessionlen = aimutil_get16(tmptlv->value);
-      /* Session Length (AOL) */
-      if ((tmptlv = aim_gettlv(tlvlist, 0x0010, 1)))
-       userinfo.sessionlen = aimutil_get16(tmptlv->value);
-
       /*
        * There's another block of TLVs embedded in the type 5 here. 
        */
index 88f07fce626843887ee6978f32ea09d66d4aad8e..8015916a0b72362c1339e67f58743a6d3c310882 100644 (file)
@@ -159,6 +159,7 @@ int aim_extractuserinfo(u_char *buf, struct aim_userinfo_s *outinfo)
   int curtlv = 0;
   int tlv1 = 0;
   u_short curtype;
+  int lastvalid;
 
 
   if (!buf || !outinfo)
@@ -171,8 +172,13 @@ int aim_extractuserinfo(u_char *buf, struct aim_userinfo_s *outinfo)
    * Screen name.    Stored as an unterminated string prepended
    *                 with an unsigned byte containing its length.
    */
-  memcpy(outinfo->sn, &(buf[i+1]), buf[i]);
-  outinfo->sn[(int)buf[i]] = '\0';
+  if (buf[i] < MAXSNLEN) {
+    memcpy(outinfo->sn, &(buf[i+1]), buf[i]);
+    outinfo->sn[(int)buf[i]] = '\0';
+  } else {
+    memcpy(outinfo->sn, &(buf[i+1]), MAXSNLEN-1);
+    outinfo->sn[MAXSNLEN] = '\0';
+  }
   i = 1 + (int)buf[i];
 
   /*
@@ -191,163 +197,177 @@ int aim_extractuserinfo(u_char *buf, struct aim_userinfo_s *outinfo)
   /* 
    * Parse out the Type-Length-Value triples as they're found.
    */
-  while (curtlv < tlvcnt)
-    {
-      curtype = aimutil_get16(&buf[i]);
-      switch (curtype)
-       {
-         /*
-          * Type = 0x0001: Member Class.   
-          * 
-          * Specified as any of the following bitwise ORed together:
-          *      0x0001  Trial (user less than 60days)
-          *      0x0002  Unknown bit 2
-          *      0x0004  AOL Main Service user
-          *      0x0008  Unknown bit 4
-          *      0x0010  Free (AIM) user 
-          *      0x0020  Away
-          *
-          * In some odd cases, we can end up with more
-          * than one of these.  We only want the first,
-          * as the others may not be something we want.
-          *
-          */
-       case 0x0001:
-         if (tlv1) /* use only the first */
-           break;
-         outinfo->class = aimutil_get16(&buf[i+4]);
-         tlv1++;
-         break;
-         
-         /*
-          * Type = 0x0002: Member-Since date. 
-          *
-          * The time/date that the user originally
-          * registered for the service, stored in 
-          * time_t format
-          */
-       case 0x0002: 
-         outinfo->membersince = aimutil_get32(&buf[i+4]);
-         break;
-         
-         /*
-          * Type = 0x0003: On-Since date.
-          *
-          * The time/date that the user started 
-          * their current session, stored in time_t
-          * format.
-          */
-       case 0x0003:
-         outinfo->onlinesince = aimutil_get32(&buf[i+4]);
-         break;
-
-         /*
-          * Type = 0x0004: Idle time.
-          *
-          * Number of seconds since the user
-          * actively used the service.
-          */
-       case 0x0004:
-         outinfo->idletime = aimutil_get16(&buf[i+4]);
-         break;
-
-         /*
-          * Type = 0x000d
-          *
-          * Capability information.  Not real sure of
-          * actual decoding.  See comment on aim_bos_setprofile()
-          * in aim_misc.c about the capability block, its the same.
-          *
-          */
-       case 0x000d:
-         {
-           int len;
-           len = aimutil_get16(buf+i+2);
-           if (!len)
-             break;
-           
-           outinfo->capabilities = aim_getcap(buf+i+4, len);
-         }
-         break;
+  while (curtlv < tlvcnt) {
+    lastvalid = 1;
+    curtype = aimutil_get16(&buf[i]);
+    switch (curtype) {
+      /*
+       * Type = 0x0000: Invalid
+       *
+       * AOL has been trying to throw these in just to break us.
+       * They're real nice guys over there at AOL.  
+       *
+       * Just skip the two zero bytes and continue on. (This doesn't
+       * count towards tlvcnt!)
+       */
+    case 0x0000:
+      lastvalid = 0;
+      i += 2;
+      break;
 
-         /*
-          * Type = 0x000e
-          *
-          * Unknown.  Always of zero length, and always only
-          * on AOL users.
-          *
-          * Ignore.
-          *
-          */
-       case 0x000e:
-         break;
-         
-         /*
-          * Type = 0x000f: Session Length. (AIM)
-          * Type = 0x0010: Session Length. (AOL)
-          *
-          * The duration, in seconds, of the user's
-          * current session.
-          *
-          * Which TLV type this comes in depends
-          * on the service the user is using (AIM or AOL).
-          *
-          */
-       case 0x000f:
-       case 0x0010:
-         outinfo->sessionlen = aimutil_get32(&buf[i+4]);
+      /*
+       * Type = 0x0001: Member Class.   
+       * 
+       * Specified as any of the following bitwise ORed together:
+       *      0x0001  Trial (user less than 60days)
+       *      0x0002  Unknown bit 2
+       *      0x0004  AOL Main Service user
+       *      0x0008  Unknown bit 4
+       *      0x0010  Free (AIM) user 
+       *      0x0020  Away
+       *
+       * In some odd cases, we can end up with more
+       * than one of these.  We only want the first,
+       * as the others may not be something we want.
+       *
+       */
+    case 0x0001:
+      if (tlv1) /* use only the first */
+       break;
+      outinfo->class = aimutil_get16(&buf[i+4]);
+      tlv1++;
+      break;
+      
+      /*
+       * Type = 0x0002: Member-Since date. 
+       *
+       * The time/date that the user originally
+       * registered for the service, stored in 
+       * time_t format
+       */
+    case 0x0002: 
+      outinfo->membersince = aimutil_get32(&buf[i+4]);
+      break;
+      
+      /*
+       * Type = 0x0003: On-Since date.
+       *
+       * The time/date that the user started 
+       * their current session, stored in time_t
+       * format.
+       */
+    case 0x0003:
+      outinfo->onlinesince = aimutil_get32(&buf[i+4]);
+      break;
+      
+      /*
+       * Type = 0x0004: Idle time.
+       *
+       * Number of seconds since the user
+       * actively used the service.
+       */
+    case 0x0004:
+      outinfo->idletime = aimutil_get16(&buf[i+4]);
+      break;
+      
+      /*
+       * Type = 0x000d
+       *
+       * Capability information.  Not real sure of
+       * actual decoding.  See comment on aim_bos_setprofile()
+       * in aim_misc.c about the capability block, its the same.
+       *
+       */
+    case 0x000d:
+      {
+       int len;
+       len = aimutil_get16(buf+i+2);
+       if (!len)
          break;
-
-         /*
-          * Reaching here indicates that either AOL has
-          * added yet another TLV for us to deal with, 
-          * or the parsing has gone Terribly Wrong.
-          *
-          * Either way, inform the owner and attempt
-          * recovery.
-          *
-          */
-       default:
+       
+       outinfo->capabilities = aim_getcap(buf+i+4, len);
+      }
+      break;
+      
+      /*
+       * Type = 0x000e
+       *
+       * Unknown.  Always of zero length, and always only
+       * on AOL users.
+       *
+       * Ignore.
+       *
+       */
+    case 0x000e:
+      break;
+      
+      /*
+       * Type = 0x000f: Session Length. (AIM)
+       * Type = 0x0010: Session Length. (AOL)
+       *
+       * The duration, in seconds, of the user's
+       * current session.
+       *
+       * Which TLV type this comes in depends
+       * on the service the user is using (AIM or AOL).
+       *
+       */
+    case 0x000f:
+    case 0x0010:
+      outinfo->sessionlen = aimutil_get32(&buf[i+4]);
+      break;
+      
+      /*
+       * Reaching here indicates that either AOL has
+       * added yet another TLV for us to deal with, 
+       * or the parsing has gone Terribly Wrong.
+       *
+       * Either way, inform the owner and attempt
+       * recovery.
+       *
+       */
+    default:
+      {
+       int len,z = 0, y = 0, x = 0;
+       char tmpstr[80];
+       printf("faim: userinfo: **warning: unexpected TLV:\n");
+       printf("faim: userinfo:   sn    =%s\n", outinfo->sn);
+       printf("faim: userinfo:   curtlv=0x%04x\n", curtlv);
+       printf("faim: userinfo:   type  =0x%04x\n",aimutil_get16(&buf[i]));
+       printf("faim: userinfo:   length=0x%04x\n", len = aimutil_get16(&buf[i+2]));
+       printf("faim: userinfo:   data: \n");
+       while (z<len)
          {
-           int len,z = 0, y = 0, x = 0;
-           char tmpstr[80];
-           printf("faim: userinfo: **warning: unexpected TLV:\n");
-           printf("faim: userinfo:   sn    =%s\n", outinfo->sn);
-           printf("faim: userinfo:   curtlv=0x%04x\n", curtlv);
-           printf("faim: userinfo:   type  =0x%04x\n",aimutil_get16(&buf[i]));
-           printf("faim: userinfo:   length=0x%04x\n", len = aimutil_get16(&buf[i+2]));
-           printf("faim: userinfo:   data: \n");
-           while (z<len)
+           x = sprintf(tmpstr, "faim: userinfo:      ");
+           for (y = 0; y < 8; y++)
              {
-               x = sprintf(tmpstr, "faim: userinfo:      ");
-               for (y = 0; y < 8; y++)
+               if (z<len)
                  {
-                   if (z<len)
-                     {
-                       sprintf(tmpstr+x, "%02x ", buf[i+4+z]);
-                       z++;
-                       x += 3;
-                     }
-                   else
-                     break;
+                   sprintf(tmpstr+x, "%02x ", buf[i+4+z]);
+                   z++;
+                   x += 3;
                  }
-               printf("%s\n", tmpstr);
+               else
+                 break;
              }
+           printf("%s\n", tmpstr);
          }
-         break;
-       }  
-      /*
-       * No matter what, TLV triplets should always look like this:
-       *
-       *   u_short type;
-       *   u_short length;
-       *   u_char  data[length];
-       *
-       */
-      i += (2 + 2 + aimutil_get16(&buf[i+2]));
-      
+      }
+      break;
+    }  
+    /*
+     * No matter what, TLV triplets should always look like this:
+     *
+     *   u_short type;
+     *   u_short length;
+     *   u_char  data[length];
+     *
+     */
+    if (lastvalid) {
+      i += (2 + 2 + aimutil_get16(&buf[i+2]));            
       curtlv++;
     }
+  }
   
   return i;
 }
index 003c1a20fc8413f81c588636c367c6f3897dd801..763f8ecc8fd748a7790e6c3838fa84dacf8cdbf5 100644 (file)
@@ -40,7 +40,7 @@ int aim_get_command(struct aim_session_t *sess, struct aim_conn_t *conn)
    */
   faim_mutex_lock(&conn->active);
   if (read(conn->fd, generic, 6) < 6){
-    aim_conn_close(conn);
+    aim_conn_kill(sess, &conn);
     faim_mutex_unlock(&conn->active);
     return -1;
   }
@@ -89,7 +89,7 @@ int aim_get_command(struct aim_session_t *sess, struct aim_conn_t *conn)
   if (read(conn->fd, newrx->data, newrx->commandlen) < newrx->commandlen){
     free(newrx->data);
     free(newrx);
-    aim_conn_close(conn);
+    aim_conn_kill(sess, &conn);
     faim_mutex_unlock(&conn->active);
     return -1;
   }
@@ -259,3 +259,21 @@ void aim_purge_rxqueue(struct aim_session_t *sess)
 
   return;
 }
+
+/*
+ * Since aim_get_command will aim_conn_kill dead connections, we need
+ * to clean up the rxqueue of unprocessed connections on that socket.
+ *
+ * XXX: this is something that was handled better in the old connection
+ * handling method, but eh.
+ */
+void aim_rxqueue_cleanbyconn(struct aim_session_t *sess, struct aim_conn_t *conn)
+{
+  struct command_rx_struct *currx;
+
+  for (currx = sess->queue_incoming; currx; currx = currx->next) {
+    if ((!currx->handled) && (currx->conn == conn))
+      currx->handled = 1;
+  }    
+  return;
+}
index 619137d7b5b3c046be1e8d63ceff4a1600e08a6e..7c2da33f34ab2fc44893764abde2ba53eb179c81 100644 (file)
@@ -138,7 +138,7 @@ int aim_tx_enqueue__immediate(struct aim_session_t *sess, struct command_tx_stru
   newpacket->lock = 1; /* lock */
   newpacket->sent = 0; /* not sent yet */
 
-  aim_tx_sendframe(newpacket);
+  aim_tx_sendframe(sess, newpacket);
 
   if (newpacket->data)
     free(newpacket->data);
@@ -225,7 +225,7 @@ int aim_tx_printqueue(struct aim_session_t *sess)
  *    9) Step to next struct in list and go back to 1.
  *
  */
-int aim_tx_sendframe(struct command_tx_struct *cur)
+int aim_tx_sendframe(struct aim_session_t *sess, struct command_tx_struct *cur)
 {
   int buflen = 0;
   unsigned char *curPacket;
@@ -288,9 +288,9 @@ int aim_tx_sendframe(struct command_tx_struct *cur)
   faim_mutex_lock(&cur->conn->active);
   if ( (u_int)write(cur->conn->fd, curPacket, buflen) != buflen) {
     faim_mutex_unlock(&cur->conn->active);
-    printf("\nWARNING: Error in sending packet -- will try again next time\n\n");
-    cur->sent = 0; /* mark it unsent */
-    return 0; /* bail out -- continuable error */
+    cur->sent = 1;
+    aim_conn_kill(sess, &cur->conn);
+    return 0; /* bail out */
   }
 
   if ((cur->hdrtype == AIM_FRAMETYPE_OFT) && cur->commandlen) {
@@ -352,7 +352,7 @@ int aim_tx_flushqueue(struct aim_session_t *sess)
        sleep((cur->conn->lastactivity + cur->conn->forcedlatency) - time(NULL));
       }
 
-      if (aim_tx_sendframe(cur) == -1)
+      if (aim_tx_sendframe(sess, cur) == -1)
        break;
     }
   }
index 331f9f18000f2e4b8f970b0e5bec0e3fe5165b74..855a778af29c5da878bad6f23e60917994ed4a42 100644 (file)
 
 /* 
  * Current Maximum Length for Screen Names (not including NULL) 
+ *
+ * Currently only names up to 16 characters can be registered
+ * however it is aparently legal for them to be larger.
  */
-#define MAXSNLEN 16
+#define MAXSNLEN 32
 
 /*
  * Current Maximum Length for Instant Messages
@@ -370,7 +373,7 @@ unsigned long aim_sendredirect(struct aim_session_t *sess,
                               char *ip,
                               char *cookie);
 void aim_purge_rxqueue(struct aim_session_t *);
-
+void aim_rxqueue_cleanbyconn(struct aim_session_t *sess, struct aim_conn_t *conn);
 
 int aim_parse_unknown(struct aim_session_t *, struct command_rx_struct *command, ...);
 int aim_parse_missed_im(struct aim_session_t *, struct command_rx_struct *, ...);
@@ -381,7 +384,7 @@ struct command_tx_struct *aim_tx_new(unsigned short framing, int chan, struct ai
 int aim_tx_enqueue__queuebased(struct aim_session_t *, struct command_tx_struct *);
 int aim_tx_enqueue__immediate(struct aim_session_t *, struct command_tx_struct *);
 #define aim_tx_enqueue(x, y) ((*(x->tx_enqueue))(x, y))
-int aim_tx_sendframe(struct command_tx_struct *cur);
+int aim_tx_sendframe(struct aim_session_t *sess, struct command_tx_struct *cur);
 u_int aim_get_next_txseqnum(struct aim_conn_t *);
 int aim_tx_flushqueue(struct aim_session_t *);
 int aim_tx_printqueue(struct aim_session_t *);
index 8dac7132bb991a9810ee399dd4a12ab040ff6570..4763eda445d512982b0500b291f5c7ef44526871 100644 (file)
@@ -81,9 +81,9 @@ int main(void)
 {
   struct aim_session_t aimsess;
   struct aim_conn_t *authconn = NULL, *waitingconn = NULL;
-  int keepgoing = 1, stayconnected = 1;
+  int keepgoing = 1;
 
-#if 1
+#if 0
   /* Use something like this for AIM */
   struct client_info_s info = {"Boo", 2, 1, 0, "us", "en"};
 #else
@@ -92,8 +92,6 @@ int main(void)
 #endif
   int selstat = 0;
 
-  aim_session_init(&aimsess);
-
   if ( !(screenname = getenv("SCREENNAME")) ||
        !(password = getenv("PASSWORD")))
     {
@@ -103,11 +101,8 @@ int main(void)
 
   server = getenv("AUTHSERVER");
 
-  /*
-   * (I used a goto-based loop here because n wanted quick proof
-   *  that reconnecting without restarting was actually possible...)
-   */
- enter:
+  aim_session_init(&aimsess);
+
   authconn = aim_newconn(&aimsess, AIM_CONN_TYPE_AUTH, server?server:FAIM_LOGIN_SERVER);
 
   if (authconn == NULL) {
@@ -120,27 +115,27 @@ int main(void)
       fprintf(stderr, "faimtest: could not connect to authorizer\n");
     aim_conn_kill(&aimsess, &authconn);
     return -1;
-  } else {
+  }
 #ifdef SNACLOGIN
-    /* new login code -- not default -- pending new password encryption algo */
-    aim_conn_addhandler(&aimsess, authconn, 0x0017, 0x0007, faimtest_parse_login, 0);
-    aim_conn_addhandler(&aimsess, authconn, 0x0017, 0x0003, faimtest_parse_authresp, 0);
+  /* new login code -- not default -- pending new password encryption algo */
+  aim_conn_addhandler(&aimsess, authconn, 0x0017, 0x0007, faimtest_parse_login, 0);
+  aim_conn_addhandler(&aimsess, authconn, 0x0017, 0x0003, faimtest_parse_authresp, 0);
     
-    aim_sendconnack(&aimsess, authconn);
-    aim_request_login(&aimsess, authconn, FAIMTEST_SCREENNAME);
+  aim_sendconnack(&aimsess, authconn);
+  aim_request_login(&aimsess, authconn, FAIMTEST_SCREENNAME);
 #else
-    aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_AUTHSUCCESS, faimtest_parse_authresp, 0);
-    aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_GEN, AIM_CB_GEN_SERVERREADY, faimtest_authsvrready, 0);
-    aim_send_login(&aimsess, authconn, screenname, password, &info);
+  aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_AUTHSUCCESS, faimtest_parse_authresp, 0);
+  aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_GEN, AIM_CB_GEN_SERVERREADY, faimtest_authsvrready, 0);
+  aim_send_login(&aimsess, authconn, screenname, password, &info);
 #endif
-  }
+  printf("faimtest: login sent\n");
 
   while (keepgoing) {
     waitingconn = aim_select(&aimsess, NULL, &selstat);
 
     switch(selstat) {
     case -1: /* error */
-      keepgoing = 0;
+      keepgoing = 0; /* fall through and hit the aim_logoff() */
       break;
 
     case 0: /* no events pending */
@@ -153,6 +148,7 @@ int main(void)
     case 2: /* incoming data pending */
       if (aim_get_command(&aimsess, waitingconn) < 0) {
          printf("\afaimtest: connection error!\n");
+         keepgoing = 0; /* fall through and hit the aim_logoff() */
       } else
        aim_rxdispatch(&aimsess);
       break;
@@ -168,12 +164,6 @@ int main(void)
   /* close up all connections, dead or no */
   aim_logoff(&aimsess); 
 
-  if (stayconnected) {
-      printf("\nTrying to reconnect in 2 seconds...\n");
-      sleep(2);
-      goto enter;
-   }
-
   /* Get out */
   exit(0);
 }
@@ -979,6 +969,7 @@ int faimtest_parse_connerr(struct aim_session_t *sess, struct command_rx_struct
   va_end(ap);
 
   printf("faimtest: connerr: Code 0x%04x: %s\n", code, msg);
+  aim_conn_kill(sess, &command->conn); /* this will break the main loop */
 
   return 1;
 }
This page took 0.511 seconds and 5 git commands to generate.