changeset 338:9d258a0aa560

[gaim-migrate @ 348] Whoa, all kinds of things happened here. The applet looks better. The preferences dialog changes based on your compile-time options (oscar, gnome). Whispering works again. libfaim got updated; it can almost do RVOUS stuff, and hopefully soon can make requests too. The applet doesn't need to have its sounds go through GNOME, although it still can. There is code to facilitate SOCKS5 support (all that needs to be done is to actually write the code to communicate with the proxy server). committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Tue, 06 Jun 2000 09:55:30 +0000
parents f5b199e20d12
children 4c500ceeeb0f
files ChangeLog configure.in libfaim/CHANGES libfaim/Makefile.am libfaim/aim_chat.c libfaim/aim_conn.c libfaim/aim_im.c libfaim/aim_logoff.c libfaim/aim_msgcookie.c libfaim/aim_rxqueue.c libfaim/faim/aim.h src/about.c src/aim.c src/away.c src/buddy.c src/buddy_chat.c src/dialogs.c src/gaim.h src/gaimrc.c src/gnome_applet_mgr.c src/gnome_applet_mgr.h src/oscar.c src/prefs.c src/proxy.c src/proxy.h src/server.c src/sound.c
diffstat 27 files changed, 716 insertions(+), 454 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue Jun 06 09:36:12 2000 +0000
+++ b/ChangeLog	Tue Jun 06 09:55:30 2000 +0000
@@ -3,6 +3,10 @@
 version 0.9.19:
 	* Oscar can sign in to ICQ now
 	* Graphical Smiley Faces
+	* Applet got a bit of a makeover (inside & out)
+	* Applet sounds not necessarily through GNOME
+	* Compile-time options affect Preferences dialog
+	* Whispering works (does anyone even use this?)
 
 version 0.9.18 (06/02/2000):
 	* Logging in works better for oscar
--- a/configure.in	Tue Jun 06 09:36:12 2000 +0000
+++ b/configure.in	Tue Jun 06 09:55:30 2000 +0000
@@ -48,7 +48,7 @@
 fi
 
 if test "$enable_oscar" = yes ; then
-	GAIM_CFLAGS="$GAIM_CFLAGS -DUSE_OSCAR -I../libfaim"
+	GAIM_CFLAGS="$GAIM_CFLAGS -DUSE_OSCAR -I../libfaim/faim"
         GAIM_LDADD="$GAIM_LDADD -L../libfaim -lfaim"
         LIBFAIM_DO="libfaim.a"
 fi
--- a/libfaim/CHANGES	Tue Jun 06 09:36:12 2000 +0000
+++ b/libfaim/CHANGES	Tue Jun 06 09:55:30 2000 +0000
@@ -1,6 +1,38 @@
 
 No release numbers
 ------------------
+ - Tue Jun  6 01:36:48 UTC 2000
+   - Inverted gethostbyname2() check.  Not sure how that ended up 
+       in that state.
+   - Added some of the initial framework to support file transfers
+   - Added in a few checks for that
+     - Can currently parse and send a denial message.
+   - Added cookie caching.  (Sorry, I just like saying that.)
+   - Rearranged channel 2 ICBM parsing (detects the different
+       rendezvous types better and hopefully accuratly).
+   - Killed the connection array.  Now a list.  (Suits the
+       upcoming features better.)  --- REQUIRES CLIENT CHANGES...
+     - In most cases, you need to change aim_conn_close() calls
+         to aim_conn_kill().  This will free them as well as 
+         close them.  If you don't do this, you'll pollute the
+         connection list and leak memory.
+   - Possibly a few other minor things (some cleanups to faimtest for one)
+
+ - Fri Jun  2 23:27:28 UTC 2000
+   - Cleaned up aim_send_login slightly
+   - Added aimicq_encode_password to support the new hash
+       values required for logging in with ICQ
+   - Removed crash when email and/or reg status aren't
+       in the auth response (they're not in ICQ responses)
+   - So now as long as you specify a client version of 
+       4.30.3141 in the client info, and your ICQ number
+       as your screen name, you can login to ICQ via libfaim
+       and use it just like an AIM account.
+   - Added AIM_CB_SPECIAL_CONNERR callback for recieving 
+       messages such as disconnect reasonses ("you logged
+       on from a different machine", etc).
+   - Added faimtest's userinfo handler to support away messages
+
  - Fri Jun  2 15:57:27 UTC 2000
    - Add creation time, maxmsglen, and various unknowns to chat info
      update callback.
--- a/libfaim/Makefile.am	Tue Jun 06 09:36:12 2000 +0000
+++ b/libfaim/Makefile.am	Tue Jun 06 09:55:30 2000 +0000
@@ -5,15 +5,25 @@
 EXTRA_DIST = faim/aim.h faim/aim_cbtypes.h faim/faimconfig.h README \
 		README.gaim CHANGES CHANGES.gaim COPYING BUGS
 
-#libfaim_a_SOURCES = aim_chatnav.c aim_info.c aim_rxhandlers.c \
-#                    aim_tlv.c aim_auth.c aim_conn.c aim_login.c \
-#                    aim_rxqueue.c aim_txqueue.c aim_buddylist.c \
-#                    aim_global.c aim_logoff.c aim_search.c aim_util.c \
-#                    aim_chat.c aim_im.c aim_misc.c aim_snac.c
-libfaim_a_SOURCES = aim_auth.c aim_buddylist.c aim_chat.c aim_chatnav.c \
-		    aim_conn.c aim_im.c aim_info.c aim_login.c aim_logoff.c \
-		    aim_meta.c aim_misc.c aim_rxhandlers.c aim_rxqueue.c \
-		    aim_search.c aim_snac.c aim_tlv.c aim_txqueue.c aim_util.c
+libfaim_a_SOURCES = 	aim_auth.c 		\
+			aim_buddylist.c		\
+			aim_chat.c		\
+			aim_chatnav.c		\
+			aim_conn.c		\
+			aim_im.c		\
+			aim_info.c		\
+			aim_login.c		\
+			aim_logoff.c		\
+			aim_meta.c		\
+			aim_misc.c		\
+			aim_msgcookie.c		\
+			aim_rxhandlers.c	\
+			aim_rxqueue.c		\
+			aim_search.c		\
+			aim_snac.c		\
+			aim_tlv.c		\
+			aim_txqueue.c		\
+			aim_util.c
 
 CFLAGS += $(GAIM_CFLAGS) -I../src -DAIM_BUILDDATE=\"`date +%Y%m%d`\" -DAIM_BUILDTIME=\"`date +%H%M%S`\"
 
--- a/libfaim/aim_chat.c	Tue Jun 06 09:36:12 2000 +0000
+++ b/libfaim/aim_chat.c	Tue Jun 06 09:55:30 2000 +0000
@@ -19,20 +19,18 @@
 
 struct aim_conn_t *aim_chat_getconn(struct aim_session_t *sess, char *name)
 {
-  int i;
+  struct aim_conn_t *cur;
+  
+  faim_mutex_lock(&sess->connlistlock);
+  for (cur = sess->connlist; cur; cur = cur->next) {
+    if (cur->type != AIM_CONN_TYPE_CHAT)
+      continue;
+    if (strcmp((char *)cur->priv, name) == 0)
+      break;
+  }
+  faim_mutex_unlock(&sess->connlistlock);
 
-  for (i=0;i<AIM_CONN_MAX;i++)
-    {
-      if (sess->conns[i].type == AIM_CONN_TYPE_CHAT)
-	{
-	  if (sess->conns[i].priv)
-	    if (!strcmp((char *)sess->conns[i].priv, name))
-	      {
-		return &sess->conns[i];
-	      }
-	}
-    }
-  return NULL;
+  return cur;
 }
 
 int aim_chat_attachname(struct aim_conn_t *conn, char *roomname)
@@ -542,21 +540,14 @@
 
 int aim_chat_leaveroom(struct aim_session_t *sess, char *name)
 {
-  int i;
+  struct aim_conn_t *conn;
 
-  for (i=0;i<AIM_CONN_MAX;i++)
-    {
-      if (sess->conns[i].type == AIM_CONN_TYPE_CHAT)
-	{
-	  if (sess->conns[i].priv)
-	    if (!strcmp((char *)sess->conns[i].priv, name))
-	      {
-		aim_conn_close(&sess->conns[i]);
-		return 0;
-	      }
-	}
-    }
-  return -1;
+  if ((conn = aim_chat_getconn(sess, name)))
+    aim_conn_kill(sess, &conn);
+
+  if (!conn)
+    return -1;
+  return 0;
 }
 
 /*
--- a/libfaim/aim_conn.c	Tue Jun 06 09:36:12 2000 +0000
+++ b/libfaim/aim_conn.c	Tue Jun 06 09:55:30 2000 +0000
@@ -8,21 +8,83 @@
 
 #include <faim/aim.h> 
 
+/*
+ * Clears out connection list, killing remaining connections.
+ */
 void aim_connrst(struct aim_session_t *sess)
 {
-  int i;
-  for (i = 0; i < AIM_CONN_MAX; i++) {
-    aim_conn_close(&sess->conns[i]);
+  faim_mutex_init(&sess->connlistlock, NULL);
+  if (sess->connlist) {
+    struct aim_conn_t *cur = sess->connlist, *tmp;
+
+    while(cur) {
+      tmp = cur->next;
+      aim_conn_close(cur);
+      free(cur);
+      cur = tmp;
+    }
   }
+  sess->connlist = NULL;
+  return;
 }
 
+/*
+ * Gets a new connection structure.
+ */
 struct aim_conn_t *aim_conn_getnext(struct aim_session_t *sess)
 {
-  int i;
-  for (i=0;i<AIM_CONN_MAX;i++)
-    if (sess->conns[i].fd == -1)
-      return &(sess->conns[i]);
-  return NULL;
+  struct aim_conn_t *newconn, *cur;
+
+  if (!(newconn = malloc(sizeof(struct aim_conn_t)))) 	
+    return NULL;
+
+  memset(newconn, 0, sizeof(struct aim_conn_t));
+  aim_conn_close(newconn);
+  newconn->next = NULL;
+
+  faim_mutex_lock(&sess->connlistlock);
+  if (sess->connlist == NULL)
+    sess->connlist = newconn;
+  else {
+    for (cur = sess->connlist; cur->next; cur = cur->next)
+      ;
+    cur->next = newconn;
+  }
+  faim_mutex_unlock(&sess->connlistlock);
+
+  return newconn;
+}
+
+void aim_conn_kill(struct aim_session_t *sess, struct aim_conn_t **deadconn)
+{
+  struct aim_conn_t *cur;
+
+  if (!deadconn || !*deadconn)	
+    return;
+
+  faim_mutex_lock(&sess->connlistlock);
+  if (sess->connlist == NULL)
+    ;
+  else if (sess->connlist->next == NULL) {
+    if (sess->connlist == *deadconn)
+      sess->connlist = NULL;
+  } else {
+    cur = sess->connlist;
+    while (cur->next) {
+      if (cur->next == *deadconn) {
+	cur->next = cur->next->next;
+	break;
+      }
+      cur = cur->next;
+    }
+  }
+  faim_mutex_unlock(&sess->connlistlock);
+
+  aim_conn_close(*deadconn);
+  free(*deadconn);
+  deadconn = NULL;
+
+  return;
 }
 
 void aim_conn_close(struct aim_conn_t *deadconn)
@@ -47,11 +109,15 @@
 struct aim_conn_t *aim_getconn_type(struct aim_session_t *sess,
 				    int type)
 {
-  int i;
-  for (i=0; i<AIM_CONN_MAX; i++)
-    if (sess->conns[i].type == type)
-      return &(sess->conns[i]);
-  return NULL;
+  struct aim_conn_t *cur;
+
+  faim_mutex_lock(&sess->connlistlock);
+  for (cur = sess->connlist; cur; cur = cur->next) {
+    if (cur->type == type)
+      break;
+  }
+  faim_mutex_unlock(&sess->connlistlock);
+  return cur;
 }
 
 /*
@@ -73,15 +139,18 @@
   u_short port = FAIM_LOGIN_PORT;
   char *host = NULL;
   int i=0;
-  
+
   if ((connstruct=aim_conn_getnext(sess))==NULL)
     return NULL;
 
+  faim_mutex_lock(&connstruct->active);
+  
   connstruct->type = type;
 
   if (!dest) { /* just allocate a struct */
     connstruct->fd = -1;
     connstruct->status = 0;
+    faim_mutex_unlock(&connstruct->active);
     return connstruct;
   }
 
@@ -104,11 +173,12 @@
   strncpy(host, dest, i);
   host[i] = '\0';
 
-  hp = gethostbyname2(host, AF_INET);
+  hp = gethostbyname(host);
   free(host);
 
   if (hp == NULL) {
     connstruct->status = (h_errno | AIM_CONN_STATUS_RESOLVERR);
+    faim_mutex_unlock(&connstruct->active);
     return connstruct;
   }
 
@@ -122,29 +192,40 @@
   if(ret < 0) {
     connstruct->fd = -1;
     connstruct->status = (errno | AIM_CONN_STATUS_CONNERR);
+    faim_mutex_unlock(&connstruct->active);
     return connstruct;
   }
   
+  faim_mutex_unlock(&connstruct->active);
+
   return connstruct;
 }
 
 int aim_conngetmaxfd(struct aim_session_t *sess)
 {
-  int i,j;
+  int j = 0;
+  struct aim_conn_t *cur;
 
-  for (i=0,j=0;i<AIM_CONN_MAX;i++)
-    if(sess->conns[i].fd > j)
-      j = sess->conns[i].fd;
+  faim_mutex_lock(&sess->connlistlock);
+  for (cur = sess->connlist; cur; cur = cur->next) {
+    if (cur->fd > j)
+      j = cur->fd;
+  }
+  faim_mutex_unlock(&sess->connlistlock);
+
   return j;
 }
 
 int aim_countconn(struct aim_session_t *sess)
 {
-  int i,cnt;
+  int cnt = 0;
+  struct aim_conn_t *cur;
 
-  for (i=0,cnt=0;i<AIM_CONN_MAX;i++)
-    if (sess->conns[i].fd > -1)
-      cnt++;
+  faim_mutex_lock(&sess->connlistlock);
+  for (cur = sess->connlist; cur; cur = cur->next)
+    cnt++;
+  faim_mutex_unlock(&sess->connlistlock);
+
   return cnt;
 }
 
@@ -160,15 +241,23 @@
  *    1  outgoing data pending (NULL returned)
  *    2  incoming data pending (connection with pending data returned)
  *
+ * XXX: we could probably stand to do a little courser locking here.
+ *
  */ 
 struct aim_conn_t *aim_select(struct aim_session_t *sess,
 			      struct timeval *timeout, int *status)
 {
+  struct aim_conn_t *cur;
   fd_set fds;
+  int maxfd = 0;
   int i;
 
-  if (aim_countconn(sess) <= 0)
+  faim_mutex_lock(&sess->connlistlock);
+  if (sess->connlist == NULL) {
+    faim_mutex_unlock(&sess->connlistlock);
     return 0;
+  }
+  faim_mutex_unlock(&sess->connlistlock);
 
   /* 
    * If we have data waiting to be sent, return immediatly
@@ -179,24 +268,28 @@
   } 
 
   FD_ZERO(&fds);
-  
-  for(i=0;i<AIM_CONN_MAX;i++)
-    if (sess->conns[i].fd>-1)
-      FD_SET(sess->conns[i].fd, &fds);
-  
-  if ((i = select(aim_conngetmaxfd(sess)+1, &fds, NULL, NULL, timeout))>=1) {
-    int j;
-    for (j=0;j<AIM_CONN_MAX;j++) {
-	if (sess->conns[j].fd > -1) {
-	    if ((FD_ISSET(sess->conns[j].fd, &fds))) {
-	      *status = 2;
-	      return &(sess->conns[j]);  /* return the first waiting struct */
-	    }
-	  }	
-	}	
-    /* should never get here */
+  maxfd = 0;
+
+  faim_mutex_lock(&sess->connlistlock);
+  for (cur = sess->connlist; cur; cur = cur->next) {
+    FD_SET(cur->fd, &fds);
+    if (cur->fd > maxfd)
+      maxfd = cur->fd;
+  }
+  faim_mutex_unlock(&sess->connlistlock);
+
+  if ((i = select(maxfd+1, &fds, NULL, NULL, timeout))>=1) {
+    faim_mutex_lock(&sess->connlistlock);
+    for (cur = sess->connlist; cur; cur = cur->next) {
+      if (FD_ISSET(cur->fd, &fds)) {
+	*status = 2;
+	faim_mutex_unlock(&sess->connlistlock);
+	return cur;
+      }
+    }
   }
 
+  faim_mutex_unlock(&sess->connlistlock);
   *status = i; /* may be 0 or -1 */
   return NULL;  /* no waiting or error, return */
 }
@@ -205,25 +298,31 @@
 {
   if (conn)
     return (conn->status & 0x0001);
-  else
-    return -1;
+  return -1;
 }
 
 int aim_conn_setstatus(struct aim_conn_t *conn, int status)
 {
-  if (conn)
-    return (conn->status ^= status);
-  else
+  int val;
+
+  if (!conn)
     return -1;
+  
+  faim_mutex_lock(&conn->active);
+  val = conn->status ^= status;
+  faim_mutex_unlock(&conn->active);
+  return val;
 }
 
 int aim_conn_setlatency(struct aim_conn_t *conn, int newval)
 {
   if (!conn)
     return -1;
-  
+
+  faim_mutex_lock(&conn->active);
   conn->forcedlatency = newval;
   conn->lastactivity = 0; /* reset this just to make sure */
+  faim_mutex_unlock(&conn->active);
 
   return 0;
 }
@@ -233,15 +332,8 @@
   if (!sess)
     return;
 
-  memset(sess->logininfo.screen_name, 0x00, MAXSNLEN);
-  sess->logininfo.BOSIP = NULL;
-  memset(sess->logininfo.cookie, 0x00, AIM_COOKIELEN);
-  sess->logininfo.email = NULL;
-  sess->logininfo.regstatus = 0x00;
-
-  memset(sess->conns, 0, sizeof(struct aim_conn_t)*AIM_CONN_MAX);
+  memset(sess, 0, sizeof(struct aim_session_t));
   aim_connrst(sess);
-
   sess->queue_outgoing = NULL;
   sess->queue_incoming = NULL;
   sess->pendingjoin = NULL;
--- a/libfaim/aim_im.c	Tue Jun 06 09:36:12 2000 +0000
+++ b/libfaim/aim_im.c	Tue Jun 06 09:55:30 2000 +0000
@@ -350,10 +350,11 @@
     }
   else if (channel == 0x0002)
     {	
-      int rendtype;
       struct aim_tlv_t *block1;
       struct aim_tlvlist_t *list2;
       struct aim_tlv_t *tmptlv;
+      struct aim_tlv_t *miscinfo;
+      unsigned short reqclass = 0;
       int a;
       
       /* Class. */
@@ -376,8 +377,11 @@
        * There's another block of TLVs embedded in the type 5 here. 
        */
       block1 = aim_gettlv(tlvlist, 0x0005, 1);
-      if (!block1)
+      if (!block1) {
+	printf("faim: no tlv 0x0005 in rendezvous transaction!\n");
+	aim_freetlvchain(&tlvlist);
 	return 1; /* major problem */
+      }
 
       a = 0x1a; /* skip -- not sure what this information is! */
 
@@ -387,77 +391,187 @@
        * Its probably just an accepted invitation or something.
        *  
        */
-      if (block1->length <= 0x1a)
-	{
+      if (block1->length <= 0x1a) {
+	aim_freetlvchain(&tlvlist);
+	return 1;
+      }
+
+      list2 = aim_readtlvchain(block1->value+a, block1->length-a);
+
+      if (!(miscinfo = aim_gettlv(list2, 0x2711, 1))) {
+	struct aim_msgcookie_t *cook;
+
+	if ((cook = aim_uncachecookie(sess, cookie)) == NULL) {
+	  printf("faim: no 0x2711 info TLV in rendezvous and its not in cache!\n");
+	  aim_freetlvchain(&list2);
 	  aim_freetlvchain(&tlvlist);
 	  return 1;
 	}
 
-      list2 = aim_readtlvchain(block1->value+a, block1->length-a);
+	if (cook->type == 1) {
+	  struct aim_filetransfer_t *ft;
+
+	  if (cook->data) {
+	    struct aim_tlv_t *errortlv;
+	    int errorcode = -1;
+
+	    ft = (struct aim_filetransfer_t *)cook->data;
 
-      if (aim_gettlv(list2, 0x0004, 1) /* start connection */ ||  
-	  aim_gettlv(list2, 0x000b, 1) /* close conncetion */)
-	{
-	  rendtype = 1; /* voice request */
+	    if ((errortlv = aim_gettlv(list2, 0x000b, 1))) {
+	      errorcode = aimutil_get16(errortlv->value);
+	    }
+	    printf("faim: transfer from %s (%s) for %s cancelled (error code %d)\n", ft->sender, ft->ip, ft->filename, errorcode);
+	    free(cook->data);
+	  } else {
+	    printf("faim: not data attached to file transfer\n");
+	  }
+
+	} else {
+	  printf("faim: unknown cookie cache type %d\n", cook->type);
+	}
+
+	free(cook);
+	return 1;
+      }
+
 
-	  /*
-	   * Call client.
-	   */
-	  userfunc = aim_callhandler(command->conn, 0x0004, 0x0007);
-	  if (userfunc)
-	    i = userfunc(sess, 
-			 command, 
-			 channel, 
-			 rendtype,
-			 &userinfo);
-	  else 
-	    i = 0;
+      /*
+       * Parse the first two bytes of the 0x2711 TLV.  
+       *
+       * This can be interpretted in a couple ways.  
+       *
+       * It could be said that its a service type or some such and
+       * that voice is 0, file transfer is 1, and chat is 4 (and 5).
+       *
+       * Or it could be said that its an exchange value.  Exchanges
+       * four and five are for chat, voice is on exchange zero and
+       * file transfer is done on exchange 1.  
+       *
+       * It should work out the same no how its thought of.
+       *
+       */
+      reqclass = aimutil_get16(miscinfo->value+0);
+   
+      switch (reqclass) {	
+      case AIM_RENDEZVOUS_VOICE: {
+
+	/* XXX: implement all this */
+
+	/*
+	 * Call client.
+	 */
+	userfunc = aim_callhandler(command->conn, 0x0004, 0x0007);
+	if (userfunc || (i = 0)) {
+	  i = userfunc(sess, 
+		       command, 
+		       channel, 
+		       reqclass,
+		       &userinfo);
 	}
-      else
-	{
-	  struct aim_chat_roominfo roominfo;
-	  char *msg=NULL,*encoding=NULL,*lang=NULL;
+	break;
+      }
+      case AIM_RENDEZVOUS_FILETRANSFER: {
+	char ip[30];
+	char *desc = NULL;
+	struct aim_msgcookie_t cachedcook;
+	struct aim_filetransfer_t *ft;
+
+	memset(ip, 0, sizeof(ip));
+	
+	if (aim_gettlv(list2, 0x0003, 1) && aim_gettlv(list2, 0x0003, 1)) {
+	  struct aim_tlv_t *iptlv, *porttlv;
+	  
+	  iptlv = aim_gettlv(list2, 0x0003, 1);
+	  porttlv = aim_gettlv(list2, 0x0005, 1);
 
-	  rendtype = 0; /* chat invite */
-	  if (aim_gettlv(list2, 0x2711, 1))
-	    {
-	      struct aim_tlv_t *nametlv;
-	      
-	      nametlv = aim_gettlv(list2, 0x2711, 1);
-	      aim_chat_readroominfo(nametlv->value, &roominfo);
-	    }
+	  snprintf(ip, sizeof(ip)-1, "%d.%d.%d.%d:%d", 
+		  aimutil_get8(iptlv->value+0),
+		  aimutil_get8(iptlv->value+1),
+		  aimutil_get8(iptlv->value+2),
+		  aimutil_get8(iptlv->value+3),
+		  aimutil_get16(porttlv->value));
+	}
+
+	if (aim_gettlv(list2, 0x000c, 1)) {
+	  desc = aim_gettlv_str(list2, 0x000c, 1);
+	}
+
+	printf("faim: rend: file transfer request from %s for %s: %s (%s)\n",
+	       userinfo.sn,
+	       miscinfo->value+8,
+	       desc, 
+	       ip);
+	
+	memcpy(cachedcook.cookie, cookie, 8);
+	memcpy(cachedcook.extended, block1->value+10, 16);
+	
+	ft = malloc(sizeof(struct aim_filetransfer_t));
+	strncpy(ft->sender, userinfo.sn, sizeof(ft->sender));
+	strncpy(ft->ip, ip, sizeof(ft->ip));
+	ft->filename = strdup(miscinfo->value+8);
+	cachedcook.type = 1; 
+	cachedcook.data = ft;
+
+	if (aim_cachecookie(sess, &cachedcook) != 0)
+	  printf("faim: ERROR caching message cookie\n");
+	
+	
+	aim_denytransfer(sess, command->conn, ft->sender, cookie, 0);
+
+	free(desc);
+	
+	i = 1;
+	break;
+      }
+      case AIM_RENDEZVOUS_FILETRANSFER_GET: {
+	printf("faim: file get request (unsupported)\n");
+	i = 1;
+	break;
+      }
+      case AIM_RENDEZVOUS_CHAT_EX3:
+      case AIM_RENDEZVOUS_CHAT_EX4:
+      case AIM_RENDEZVOUS_CHAT_EX5: {
+	struct aim_chat_roominfo roominfo;
+	char *msg=NULL,*encoding=NULL,*lang=NULL;
+
+	aim_chat_readroominfo(miscinfo->value, &roominfo);
+		  
+	if (aim_gettlv(list2, 0x000c, 1))
+	  msg = aim_gettlv_str(list2, 0x000c, 1);
 	  
-	  if (aim_gettlv(list2, 0x000c, 1))
-	    msg = aim_gettlv_str(list2, 0x000c, 1);
+	if (aim_gettlv(list2, 0x000d, 1))
+	  encoding = aim_gettlv_str(list2, 0x000d, 1);
 	  
-	  if (aim_gettlv(list2, 0x000d, 1))
-	    encoding = aim_gettlv_str(list2, 0x000d, 1);
-	  
-	  if (aim_gettlv(list2, 0x000e, 1))
-	    lang = aim_gettlv_str(list2, 0x000e, 1);
+	if (aim_gettlv(list2, 0x000e, 1))
+	  lang = aim_gettlv_str(list2, 0x000e, 1);
       
-	  /*
-	   * Call client.
-	   */
-	  userfunc = aim_callhandler(command->conn, 0x0004, 0x0007);
-	  if (userfunc)
-	    i = userfunc(sess, 
-			 command, 
-			 channel, 
-			 rendtype,
-			 &userinfo, 
-			 &roominfo, 
-			 msg, 
-			 encoding?encoding+1:NULL, 
-			 lang?lang+1:NULL);
-	  else 
-	    i = 0;
-      
+	/*
+	 * Call client.
+	 */
+	userfunc = aim_callhandler(command->conn, 0x0004, 0x0007);
+	if (userfunc || (i = 0))
+	  i = userfunc(sess, 
+		       command, 
+		       channel, 
+		       reqclass, /* == roominfo->exchange */
+		       &userinfo, 
+		       &roominfo, 
+		       msg, 
+		       encoding?encoding+1:NULL, 
+		       lang?lang+1:NULL);
 	  free(roominfo.name);
 	  free(msg);
 	  free(encoding);
 	  free(lang);
-	}
+	  break;
+      }
+      default: {
+	printf("faim: rendezvous: unknown rend class 0x%04x\n", reqclass);
+	i = 1;
+	break;
+      }
+      } /* switch */
+
       aim_freetlvchain(&list2);
     }
 
@@ -471,6 +585,41 @@
 }
 
 /*
+ * Possible codes:
+ *    AIM_TRANSFER_DENY_NOTSUPPORTED -- "client does not support"
+ *    AIM_TRANSFER_DENY_DECLINE -- "client has declined transfer"
+ *    AIM_TRANSFER_DENY_NOTACCEPTING -- "client is not accepting transfers"
+ * 
+ */
+u_long aim_denytransfer(struct aim_session_t *sess,
+			struct aim_conn_t *conn, 
+			char *sender,
+			char *cookie, 
+			unsigned short code)
+{
+  struct command_tx_struct *newpacket;
+  int curbyte, i;
+
+  if(!(newpacket = aim_tx_new(0x0002, conn, 10+8+2+1+strlen(sender)+6)))
+    return -1;
+
+  newpacket->lock = 1;
+
+  curbyte = aim_putsnac(newpacket->data, 0x0004, 0x000b, 0x0000, sess->snac_nextid);
+  for (i = 0; i < 8; i++)
+    curbyte += aimutil_put8(newpacket->data+curbyte, cookie[i]);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002);
+  curbyte += aimutil_put8(newpacket->data+curbyte, strlen(sender));
+  curbyte += aimutil_putstr(newpacket->data+curbyte, sender, strlen(sender));
+  curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0003, code);
+
+  newpacket->lock = 0;
+  aim_tx_enqueue(sess, newpacket);
+
+  return (sess->snac_nextid++);
+}
+
+/*
  * Not real sure what this does, nor does anyone I've talk to.
  *
  * Didn't use to send it.  But now I think it might be a good
--- a/libfaim/aim_logoff.c	Tue Jun 06 09:36:12 2000 +0000
+++ b/libfaim/aim_logoff.c	Tue Jun 06 09:55:30 2000 +0000
@@ -14,13 +14,6 @@
  */
 int aim_logoff(struct aim_session_t *sess)
 {
-  int i = AIM_CONN_MAX-1;
-  while (i > -1)
-    {
-      if (sess->conns[i].fd>-1)
-	aim_conn_close(&(sess->conns[i]));
-      i--;
-    }
   aim_connrst(sess);  /* in case we want to connect again */
 
   return 0;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libfaim/aim_msgcookie.c	Tue Jun 06 09:55:30 2000 +0000
@@ -0,0 +1,99 @@
+
+/*
+ *
+ *
+ */
+
+#include <faim/aim.h>
+
+int aim_cachecookie(struct aim_session_t *sess,
+		    struct aim_msgcookie_t *cookie)
+{
+  struct aim_msgcookie_t *newcook = NULL, *cur = NULL;
+  
+  if (!cookie)
+    return -1;
+
+  if (!(newcook = malloc(sizeof(struct aim_msgcookie_t))))
+    return -1;
+  memcpy(newcook, cookie, sizeof(struct aim_msgcookie_t));
+  newcook->addtime = time(NULL);
+  newcook->next = NULL;
+
+  cur = sess->msgcookies;
+  
+  if (cur == NULL) {
+    sess->msgcookies = newcook;
+    return 0;
+  }
+  while (cur->next != NULL)
+    cur = cur->next;
+  cur->next = newcook;
+
+  return 0;
+}
+
+struct aim_msgcookie_t *aim_uncachecookie(struct aim_session_t *sess, 
+					  char *cookie)
+{
+  struct aim_msgcookie_t *cur;
+
+  if (!cookie)
+    return NULL;
+
+  if (!sess->msgcookies)
+    return NULL;
+
+  if (memcmp(sess->msgcookies->cookie, cookie, 8) == 0) {
+    cur = sess->msgcookies;
+    sess->msgcookies = cur->next;
+    return cur;
+  } 
+
+  cur = sess->msgcookies;
+  while (cur->next) {
+    if (memcmp(cur->next->cookie, cookie, 8) == 0) {
+      struct aim_msgcookie_t *tmp;
+      
+      tmp = cur->next;
+      cur->next = cur->next->next;
+      return tmp;
+    }
+    cur = cur->next;
+  }
+  return NULL;
+}
+
+/*
+ */
+int aim_purgecookies(struct aim_session_t *sess)
+{
+  int maxage = 5*60;
+  struct aim_msgcookie_t *cur;
+  struct aim_msgcookie_t *remed = NULL;
+  time_t curtime;
+ 
+  cur = sess->msgcookies;
+  
+  curtime = time(&curtime);
+ 
+  while (cur) {
+    if ( (cur) && (((cur->addtime) + maxage) < curtime)) {
+#if DEBUG > 1
+      printf("aimmsgcookie: WARNING purged obsolete message cookie %x%x%x%x %x%x%x%x\n",
+	     cur->cookie[0], cur->cookie[1], cur->cookie[2], cur->cookie[3],
+	     cur->cookie[4], cur->cookie[5], cur->cookie[6], cur->cookie[7]);
+#endif
+      remed = aim_uncachecookie(sess, cur->cookie);
+      if (remed) {
+	if (remed->data)
+	  free(remed->data);
+	free(remed);
+      }
+    }
+    cur = cur->next;
+  }
+  
+  return 0;
+}
+
--- a/libfaim/aim_rxqueue.c	Tue Jun 06 09:36:12 2000 +0000
+++ b/libfaim/aim_rxqueue.c	Tue Jun 06 09:55:30 2000 +0000
@@ -24,6 +24,13 @@
     return 0;
 
   /*
+   * Rendezvous (client-client) connections do not speak
+   * FLAP, so this function will break on them.
+   */
+  if (conn->type > 0x01000)
+    return 0;
+
+  /*
    * Read FLAP header.  Six bytes:
    *    
    *   0 char  -- Always 0x2a
--- a/libfaim/faim/aim.h	Tue Jun 06 09:36:12 2000 +0000
+++ b/libfaim/faim/aim.h	Tue Jun 06 09:55:30 2000 +0000
@@ -52,9 +52,9 @@
 #define strlen(x) (int)strlen(x)  /* win32 has a unsigned size_t */
 #endif
 
-#if defined(_WIN32) || (defined(mach) && defined(__APPLE__)) 
-#define gethostbyname2(x,y) gethostbyname(x) /* revert to IPv4 */
-#endif 
+#if defined(mach) && defined(__APPLE__)
+#define gethostbyname(x) gethostbyname2(x, AF_INET) 
+#endif
 
 /* 
  * Current Maximum Length for Screen Names (not including NULL) 
@@ -144,6 +144,7 @@
 #define AIM_CONN_TYPE_BOS           0x0002
 #define AIM_CONN_TYPE_CHAT          0x000e
 #define AIM_CONN_TYPE_CHATNAV       0x000d
+#define AIM_CONN_TYPE_RENDEZVOUS    0x0101 /* these do not speak OSCAR! */
 
 /*
  * Status values returned from aim_conn_new().  ORed together.
@@ -164,6 +165,7 @@
   struct aim_rxcblist_t *handlerlist;
   faim_mutex_t active; /* lock around read/writes */
   faim_mutex_t seqnum_lock; /* lock around ->seqnum changes */
+  struct aim_conn_t *next;
 };
 
 /* struct for incoming commands */
@@ -218,7 +220,8 @@
   /* 
    * Connection information
    */
-  struct aim_conn_t conns[AIM_CONN_MAX];
+  struct aim_conn_t *connlist;
+  faim_mutex_t connlistlock;
   
   /* 
    * TX/RX queues 
@@ -245,6 +248,8 @@
    **/
   struct aim_snac_t *outstanding_snacs;
   u_long snac_nextid;
+
+  struct aim_msgcookie_t *msgcookies;
 };
 
 
@@ -316,6 +321,7 @@
 
 int aim_logoff(struct aim_session_t *);
 
+void aim_conn_kill(struct aim_session_t *sess, struct aim_conn_t **deadconn);
 
 typedef int (*rxcallback_t)(struct aim_session_t *, struct command_rx_struct *, ...);
 int aim_register_callbacks(rxcallback_t *);
@@ -457,6 +463,36 @@
 #define AIM_GETINFO_GENERALINFO 0x00001
 #define AIM_GETINFO_AWAYMESSAGE 0x00003
 
+#define AIM_RENDEZVOUS_VOICE 0x0000
+#define AIM_RENDEZVOUS_FILETRANSFER 0x0001
+#define AIM_RENDEZVOUS_CHAT_EX3 0x0003
+#define AIM_RENDEZVOUS_CHAT_EX4 0x0004
+#define AIM_RENDEZVOUS_CHAT_EX5 0x0005
+#define AIM_RENDEZVOUS_FILETRANSFER_GET 0x0012
+
+struct aim_msgcookie_t {
+  unsigned char cookie[8];
+  unsigned char extended[16];
+  int type;
+  void *data;
+  time_t addtime;
+  struct aim_msgcookie_t *next;
+};
+
+struct aim_filetransfer_t {
+  char sender[MAXSNLEN];	
+  char ip[30];
+  char *filename;
+};
+int aim_cachecookie(struct aim_session_t *sess, struct aim_msgcookie_t *cookie);
+struct aim_msgcookie_t *aim_uncachecookie(struct aim_session_t *sess, char *cookie);
+int aim_purgecookies(struct aim_session_t *sess);
+
+#define AIM_TRANSFER_DENY_NOTSUPPORTED 0x0000
+#define AIM_TRANSFER_DENY_DECLINE 0x0001
+#define AIM_TRANSFER_DENY_NOTACCEPTING 0x0002
+u_long aim_denytransfer(struct aim_session_t *sess, struct aim_conn_t *conn, char *sender, char *cookie, unsigned short code);
+
 u_long aim_getinfo(struct aim_session_t *, struct aim_conn_t *, const char *, unsigned short);
 int aim_extractuserinfo(u_char *, struct aim_userinfo_s *);
 int aim_parse_userinfo_middle(struct aim_session_t *, struct command_rx_struct *);
--- a/src/about.c	Tue Jun 06 09:36:12 2000 +0000
+++ b/src/about.c	Tue Jun 06 09:55:30 2000 +0000
@@ -19,10 +19,6 @@
  *
  */
 
-#ifdef USE_APPLET
-#include <gnome.h>
-#include <applet-widget.h>
-#endif /* USE_APPLET */
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
--- a/src/aim.c	Tue Jun 06 09:36:12 2000 +0000
+++ b/src/aim.c	Tue Jun 06 09:55:30 2000 +0000
@@ -66,6 +66,7 @@
 char toc_addy[16];
 char *quad_addr = NULL;
 
+gboolean running = FALSE; /* whether or not we're currently trying to sign on */
 
 void cancel_logon(void)
 {
@@ -119,7 +120,6 @@
 }
 
 char g_screenname[ 64 ];	/* gotta be enough */
-gboolean running = FALSE;
 
 void dologin(GtkWidget *widget, GtkWidget *w)
 {
@@ -183,11 +183,6 @@
 #ifdef USE_APPLET
 	 applet_widget_unregister_callback(APPLET_WIDGET(applet),"signon");
 	 applet_widget_register_callback(APPLET_WIDGET(applet),
-			 "buddy",
-			 _("Buddy List"),
-			 (AppletCallbackFunc)createOnlinePopup,
-			 NULL);
-	 applet_widget_register_callback(APPLET_WIDGET(applet),
 			 "signoff",
 			 _("Signoff"),
 			 signoff,
@@ -477,7 +472,7 @@
 int main(int argc, char *argv[])
 {
 #ifdef USE_APPLET
-        InitAppletMgr( argc, argv );
+        init_applet_mgr(argc, argv);
 #elif defined USE_THEMES         
         gnome_init("GAIM",NULL,argc,argv);
 #else
--- a/src/away.c	Tue Jun 06 09:36:12 2000 +0000
+++ b/src/away.c	Tue Jun 06 09:55:30 2000 +0000
@@ -50,15 +50,7 @@
 void do_im_back(GtkWidget *w, GtkWidget *x)
 {
 #ifdef USE_APPLET
-  if(!blist) applet_widget_unregister_callback(APPLET_WIDGET(applet),"buddy");
   applet_widget_unregister_callback(APPLET_WIDGET(applet),"away");
-	if(!blist) {
-	        applet_widget_register_callback(APPLET_WIDGET(applet),
-        	        "buddy",
-                	_("Buddy List"),
-      		        (AppletCallbackFunc)createOnlinePopup,
-                	NULL);
-	}
   MRI_user_status = online;
   insert_applet_away();
 #endif /* USE_APPLET */
@@ -100,13 +92,7 @@
         struct conversation *c;
 
 #ifdef USE_APPLET
-        if(!blist) applet_widget_unregister_callback(APPLET_WIDGET(applet),"buddy");
 	remove_applet_away();
-        if(!blist) applet_widget_register_callback(APPLET_WIDGET(applet),
-                                                   "buddy",
-                                                   _("Buddy List"),
-                                                   (AppletCallbackFunc)createOnlinePopup,
-                                                   NULL);
         applet_widget_register_callback(APPLET_WIDGET(applet),
                                         "away",
                                         _("Back"),
--- a/src/buddy.c	Tue Jun 06 09:36:12 2000 +0000
+++ b/src/buddy.c	Tue Jun 06 09:55:30 2000 +0000
@@ -275,11 +275,6 @@
 gint applet_destroy_buddy( GtkWidget *widget, GdkEvent *event,gpointer *data ) {
 	set_applet_draw_closed();
 	gnome_buddy_hide();
-	applet_widget_register_callback(APPLET_WIDGET(applet),
-			"buddy",
-			_("Buddy List"),
-			(AppletCallbackFunc)createOnlinePopup,
-			NULL);
 	return (TRUE);
 }
 
@@ -348,7 +343,6 @@
         set_applet_draw_closed();
         applet_widget_unregister_callback(APPLET_WIDGET(applet),"signoff");
 	remove_applet_away();
-	applet_widget_unregister_callback(APPLET_WIDGET(applet),"buddy");
         applet_widget_register_callback(APPLET_WIDGET(applet),
                 "signon",
                 _("Signon"),
@@ -469,6 +463,8 @@
 			show_ee_dialog(1);
 		else if (!strcasecmp("flynorange", normalize(b->name)))
 			show_ee_dialog(2);
+		else if (!strcasecmp("ewarmenhoven", normalize(b->name)))
+			show_ee_dialog(3);
 
 	} else {
 		
--- a/src/buddy_chat.c	Tue Jun 06 09:36:12 2000 +0000
+++ b/src/buddy_chat.c	Tue Jun 06 09:55:30 2000 +0000
@@ -273,7 +273,7 @@
 	GList *selected;
 	char *who;
 
-	strncpy(buf, gtk_entry_get_text(GTK_ENTRY(b->entry)), sizeof(buf)/2);
+	strncpy(buf, gtk_editable_get_chars(GTK_EDITABLE(b->entry), 0, -1), sizeof(buf)/2);
 	if (!strlen(buf))
 		return;
 
@@ -288,7 +288,7 @@
 	if (!who)
 		return;
 
-	gtk_entry_set_text(GTK_ENTRY(b->entry), "");
+	gtk_editable_delete_text(GTK_EDITABLE(b->entry), 0, -1);
 
         escape_text(buf);
         serv_chat_whisper(b->id, who, buf);
--- a/src/dialogs.c	Tue Jun 06 09:36:12 2000 +0000
+++ b/src/dialogs.c	Tue Jun 06 09:55:30 2000 +0000
@@ -584,8 +584,10 @@
 		label = gtk_label_new("Amazing!  Simply Amazing!");
 	else if (ee == 1)
 		label = gtk_label_new("Pimpin\' Penguin Style! *Waddle Waddle*");
+	else if (ee == 2)
+		label = gtk_label_new("You should be me.  I'm so cute!");
 	else
-		label = gtk_label_new("You should be me.  I'm so cute!");
+		label = gtk_label_new("Now that's what I like!");
 
 	gtk_widget_show(label);
 	gtk_widget_show(ok);
--- a/src/gaim.h	Tue Jun 06 09:36:12 2000 +0000
+++ b/src/gaim.h	Tue Jun 06 09:55:30 2000 +0000
@@ -103,10 +103,8 @@
         GtkWidget *aim_port_entry;
         GtkWidget *login_host_entry;
         GtkWidget *login_port_entry;
-        GtkWidget *http_proxy_host_entry;
-        GtkWidget *http_proxy_port_entry;
-        GtkWidget *socks_proxy_host_entry;
-        GtkWidget *socks_proxy_port_entry;
+        GtkWidget *proxy_host_entry;
+        GtkWidget *proxy_port_entry;
 
 };
 
@@ -350,7 +348,7 @@
 #define TYPE_SIGNOFF   4
 #define TYPE_KEEPALIVE 5
 
-#define REVISION "gaim:$Revision: 347 $"
+#define REVISION "gaim:$Revision: 348 $"
 #define FLAPON "FLAPON\r\n\r\n"
 
 #define ROAST "Tic/Toc"
@@ -448,6 +446,7 @@
 #define OPT_SOUND_FIRST_RCV      0x00000010
 #define OPT_SOUND_WHEN_AWAY      0x00000020
 #define OPT_SOUND_SILENT_SIGNON  0x00000040
+#define OPT_SOUND_THROUGH_GNOME  0x00000080
 
 
 extern int font_options;
--- a/src/gaimrc.c	Tue Jun 06 09:36:12 2000 +0000
+++ b/src/gaimrc.c	Tue Jun 06 09:55:30 2000 +0000
@@ -32,10 +32,6 @@
 #include "gaim.h"
 #include "proxy.h"
 
-#ifdef USE_APPLET
-#include "gnome_applet_mgr.h"
-#endif
-
 /* for people like myself, who are too lazy to add an away msg :) */
 #define BORING_DEFAULT_AWAY_MSG "sorry, i ran out for a while. bbl"
 
--- a/src/gnome_applet_mgr.c	Tue Jun 06 09:36:12 2000 +0000
+++ b/src/gnome_applet_mgr.c	Tue Jun 06 09:55:30 2000 +0000
@@ -44,7 +44,7 @@
 gchar GAIM_GNOME_ONLINE_ICON[255] = GAIM_GNOME_PENGUIN_ONLINE;
 
 GtkWidget *applet;
-GtkWidget *button;
+GtkWidget *appletframe;
 GtkWidget *status_label;
 
 GtkWidget *icon;
@@ -213,7 +213,6 @@
 	}	
 	build_edit_tree();
 	build_permit_tree();
-	applet_widget_unregister_callback(APPLET_WIDGET(applet),"buddy");
 	
 }
 
@@ -230,21 +229,8 @@
 ****************************************************************/
 
 void applet_show_login(AppletWidget *widget, gpointer data) {
+	/* FIXME : this is so pointless */
         show_login();
-	/*
-        applet_widget_unregister_callback(APPLET_WIDGET(applet),"signon");
-        applet_widget_register_callback(APPLET_WIDGET(applet),
-                "signoff",
-                _("Signoff"),
-                signoff,
-                NULL);
-	insert_applet_away();
-        applet_widget_register_callback(APPLET_WIDGET(applet),
-                "buddy",
-                _("Buddy List"),
-                (AppletCallbackFunc)createOnlinePopup,
-                NULL);
-	*/
 }
 
 void insert_applet_away() {
@@ -369,9 +355,9 @@
     GtkAllocation result;
     GNOME_Panel_OrientType orient = applet_widget_get_panel_orient( APPLET_WIDGET(applet) );
     pad = 5;
-    gdk_window_get_position( gtk_widget_get_parent_window( button  ),&x,&y );
+    gdk_window_get_position(gtk_widget_get_parent_window(appletframe), &x, &y);
     buddy_req = gnome_buddy_get_dimentions();
-    applet_req = button->requisition;
+    applet_req = appletframe->requisition;
    switch( orient ){
    	case ORIENT_UP:
    		result.x=x;
@@ -452,7 +438,9 @@
 	closeOnlinePopup();
 }
 
-void AppletClicked( GtkWidget *sender, gpointer data ){
+void AppletClicked( GtkWidget *sender, GdkEventButton *ev, gpointer data ){
+	if (!ev || ev->button != 1 || ev->type != GDK_BUTTON_PRESS)
+		return;
         
 	if( applet_draw_open ){
 	  	switch( MRI_user_status ){
@@ -498,94 +486,13 @@
 }
 
 
-#ifdef HAVE_PANEL_SIZE      
-/***************************************************************
-**
-** Code for panel resizing
-**
-****************************************************************/
-static void applet_change_size(GtkWidget *w, PanelSizeType o, gpointer data) {
-        switch(o) {
-                case SIZE_TINY: 
-                /*24x24*/ 
-                	gtk_widget_set_usize( button, 24,24 );
-        
-			/*load offline icon*/
-			load_applet_icon( GAIM_GNOME_OFFLINE_ICON, 
-							 24, 24, &icon_offline_pm, &icon_offline_bm );
- 
- 			/*load connecting icon*/
- 			load_applet_icon( GAIM_GNOME_CONNECT_ICON, 
-							 24, 24, &icon_connect_pm, &icon_connect_bm );
-							 
-			/*load online icon*/
-			load_applet_icon( GAIM_GNOME_ONLINE_ICON, 
-							 24, 24, &icon_online_pm, &icon_online_bm );
-                break;
-                 
-                case SIZE_STANDARD: 
-                /*48x48*/      
-        		gtk_widget_set_usize( button, 48,48 );
-        
-			/*load offline icon*/
-			load_applet_icon( GAIM_GNOME_OFFLINE_ICON, 
-							 32, 34, &icon_offline_pm, &icon_offline_bm );
- 
- 			/*load connecting icon*/
- 			load_applet_icon( GAIM_GNOME_CONNECT_ICON, 
-							 32, 34, &icon_connect_pm, &icon_connect_bm );
-							 
-			/*load online icon*/
-			load_applet_icon( GAIM_GNOME_ONLINE_ICON, 
-							 32, 34, &icon_online_pm, &icon_online_bm );
-     	        break;
-                
-                case SIZE_LARGE: 
-                /*64x64*/
-                	gtk_widget_set_usize( button, 64, 64 );
-        
-			/*load offline icon*/
-			load_applet_icon( GAIM_GNOME_OFFLINE_ICON, 
-							 55, 55, &icon_offline_pm, &icon_offline_bm );
- 
- 			/*load connecting icon*/
- 			load_applet_icon( GAIM_GNOME_CONNECT_ICON, 
-							 55, 55, &icon_connect_pm, &icon_connect_bm );
-							 
-			/*load online icon*/
-			load_applet_icon( GAIM_GNOME_ONLINE_ICON, 
-							 55, 55, &icon_online_pm, &icon_online_bm );
-     	        break;
-                
-                case SIZE_HUGE: 
-                /*80x80*/
-                	gtk_widget_set_usize( button, 80, 80 );
-        
-			/*load offline icon*/
-			load_applet_icon( GAIM_GNOME_OFFLINE_ICON, 
-							 70, 70, &icon_offline_pm, &icon_offline_bm );
- 
- 			/*load connecting icon*/
- 			load_applet_icon( GAIM_GNOME_CONNECT_ICON, 
-							 70, 70, &icon_connect_pm, &icon_connect_bm );
-							 
-			/*load online icon*/
-			load_applet_icon( GAIM_GNOME_ONLINE_ICON, 
-							 70, 70, &icon_online_pm, &icon_online_bm );
-     	 
-                break;
-        }
-}
-#endif /*HAVE_PANEL_SIZE*/
-
-
 /***************************************************************
 **
 ** Initialize GNOME stuff
 **
 ****************************************************************/
 
-gint InitAppletMgr( int argc, char *argv[] ){
+gint init_applet_mgr(int argc, char *argv[]) {
 	GtkWidget *vbox;
 	
 	GtkStyle *label_style;
@@ -600,24 +507,25 @@
         
         applet=applet_widget_new("gaim_applet");
         if(!applet) g_error(_("Can't create GAIM applet!"));
-        
-        button=gtk_button_new();
+	gtk_widget_set_events(applet, gtk_widget_get_events(applet) |
+				GDK_BUTTON_PRESS_MASK);
+
+        appletframe = gtk_frame_new(NULL);
         
-        
-        gtk_widget_set_usize( button, 48,48 );
+        gtk_widget_set_usize(appletframe, 48, 48);
         
 	
 	/*load offline icon*/
-	load_applet_icon( GAIM_GNOME_OFFLINE_ICON, 
-							 32, 32, &icon_offline_pm, &icon_offline_bm );
+	load_applet_icon( GAIM_GNOME_OFFLINE_ICON, 32, 32,
+			&icon_offline_pm, &icon_offline_bm );
  
  	/*load connecting icon*/
- 	load_applet_icon( GAIM_GNOME_CONNECT_ICON, 
-							 32, 32, &icon_connect_pm, &icon_connect_bm );
+ 	load_applet_icon( GAIM_GNOME_CONNECT_ICON, 32, 32,
+			&icon_connect_pm, &icon_connect_bm );
 							 
 	/*load online icon*/
-	load_applet_icon( GAIM_GNOME_ONLINE_ICON, 
-							 32, 32, &icon_online_pm, &icon_online_bm );
+	load_applet_icon( GAIM_GNOME_ONLINE_ICON, 32, 32,
+			&icon_online_pm, &icon_online_bm );
  	
  	/*icon_away and icon_msg_pennding need to be implemented*/		
 		
@@ -644,20 +552,14 @@
 		debug_print(debug_buff);
 	}
 	
-#ifdef  HAVE_PANEL_SIZE 
-        	gtk_signal_connect(GTK_OBJECT(applet),"change_size",
-                           GTK_SIGNAL_FUNC(applet_change_size),
-                           NULL);
-#endif /*HAVE_PANEL_SIZE*/      
-	
 	gtk_box_pack_start(GTK_BOX(vbox), status_label, FALSE, TRUE, 0);
 	
-	gtk_container_add( GTK_CONTAINER(button), vbox );
-	applet_widget_add(APPLET_WIDGET(applet), button);
+	gtk_container_add( GTK_CONTAINER(appletframe), vbox );
+	applet_widget_add(APPLET_WIDGET(applet), appletframe);
 	
 	gtk_widget_show( status_label );
 	gtk_widget_show( vbox );
-	gtk_widget_show( button );
+	gtk_widget_show( appletframe );
 	        
 	applet_widget_set_tooltip(APPLET_WIDGET(applet),"GAIM");
 
@@ -668,7 +570,7 @@
 					      applet_show_about,
 					      NULL);
 					      
-	gtk_signal_connect( GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC( AppletClicked), NULL);
+	gtk_signal_connect( GTK_OBJECT(applet), "button_press_event", GTK_SIGNAL_FUNC( AppletClicked), NULL);
 
         gtk_widget_show(icon);
         gtk_widget_show(applet);
--- a/src/gnome_applet_mgr.h	Tue Jun 06 09:36:12 2000 +0000
+++ b/src/gnome_applet_mgr.h	Tue Jun 06 09:55:30 2000 +0000
@@ -62,25 +62,15 @@
 #define GAIM_GNOME_PENGUIN_CONNECT "gaim/gnome/penguin-connect.png"
 #define GAIM_GNOME_PENGUIN_ONLINE "gaim/gnome/penguin-online.png"
 
-gint InitAppletMgr();                                              /* Initializes and creates applet */
-
-void setUserState( enum gaim_user_states state );    /* Set the state the user is in (Online, Offline, etc.) */
+gint init_applet_mgr();
 
-void setTotalBuddies( gint num );						    /* For future use to display the total number of buddies within the applet */
-
-void setNumBuddiesOnline( gint num );					/* For future use to display the total number of buddies currently online, within the applet */ 
-
-enum gaim_user_states getUserState();					/* Returns the current state the user is in */
+void setUserState( enum gaim_user_states state );
+enum gaim_user_states getUserState();
 
-gint getTotalBuddies();											/* Returns the total number of buddys set by setTotalBuddies */
-
-gint getNumBuddiesOnline();									/* Returns the total number of buddys set by setNumBuddiesOnline */
+void AppletCancelLogon(); /* Used to cancel a logon and reset the applet */ 
 
-void AppletCancelLogon();                                   /* Used to cancel a logon and reset the applet	*/ 
-
-void set_applet_draw_open();								/* Indicates that the code has a window open that can be controlled by clicking on the applet */
-
-void set_applet_draw_closed();								/* indicates that the code has closed the window that is controled by clicking on the applet */
+void set_applet_draw_open();
+void set_applet_draw_closed();
 
 void insert_applet_away();
 void remove_applet_away();
--- a/src/oscar.c	Tue Jun 06 09:36:12 2000 +0000
+++ b/src/oscar.c	Tue Jun 06 09:55:30 2000 +0000
@@ -35,7 +35,7 @@
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include "gaim.h"
-#include <faim/aim.h>
+#include <aim.h>
 #include "gnome_applet_mgr.h"
 
 static int inpa = -1;
@@ -78,6 +78,8 @@
 static int gaim_chat_info_update (struct aim_session_t *, struct command_rx_struct *, ...);
 static int gaim_chat_incoming_msg(struct aim_session_t *, struct command_rx_struct *, ...);
 
+extern void auth_failed();
+
 static void oscar_callback(gpointer data, gint source,
 				GdkInputCondition condition) {
 	struct aim_conn_t *conn = (struct aim_conn_t *)data;
@@ -87,6 +89,7 @@
 		hide_login_progress("Disconnected.");
 		aim_logoff(gaim_sess);
 		gdk_input_remove(inpa);
+		auth_failed();
 		return;
 	}
 	if (condition & GDK_INPUT_READ) {
@@ -95,6 +98,7 @@
 			signoff();
 			hide_login_progress("Disconnected.");
 			aim_logoff(gaim_sess);
+			auth_failed();
 			gdk_input_remove(inpa);
 		} else {
 			aim_rxdispatch(gaim_sess);
@@ -192,8 +196,6 @@
 	debug_print("Signed off.\n");
 }
 
-extern void auth_failed();
-
 int gaim_parse_auth_resp(struct aim_session_t *sess,
 			 struct command_rx_struct *command, ...) {
 	struct aim_conn_t *bosconn = NULL;
@@ -225,7 +227,7 @@
 		set_state(STATE_OFFLINE);
 		hide_login_progress("Authentication Failed");
 		gdk_input_remove(inpa);
-		aim_conn_close(command->conn);
+		aim_conn_kill(sess, &command->conn);
 		auth_failed();
 		return 0;
 	}
@@ -236,7 +238,7 @@
 	sprintf(debug_buff, "Closing auth connection...\n");
 	debug_print(debug_buff);
 	gdk_input_remove(inpa);
-	aim_conn_close(command->conn);
+	aim_conn_kill(sess, &command->conn);
 
 	bosconn = aim_newconn(sess, AIM_CONN_TYPE_BOS, sess->logininfo.BOSIP);
 	if (bosconn == NULL) {
@@ -245,6 +247,7 @@
 #endif
 		set_state(STATE_OFFLINE);
 		hide_login_progress("Internal Error");
+		auth_failed();
 		return -1;
 	} else if (bosconn->status != 0) {
 #ifdef USE_APPLET
@@ -252,6 +255,7 @@
 #endif
 		set_state(STATE_OFFLINE);
 		hide_login_progress("Could Not Connect");
+		auth_failed();
 		return -1;
 	}
 
@@ -550,13 +554,14 @@
 					     roominfo->instance,
 					     userinfo->sn,
 					     msg);
-		} else if (rendtype == 1) {
-			/* voice chat */
+		} else if (rendtype == AIM_RENDEZVOUS_FILETRANSFER) {
+			/* libfaim won't tell us that we got this just yet */
+		} else if (rendtype == AIM_RENDEZVOUS_FILETRANSFER_GET) {
+			/* nor will it tell us this. but it's still there */
 		} else {
 			sprintf(debug_buff, "Unknown rendtype %d\n", rendtype);
 			debug_print(debug_buff);
 		}
-		/* libfaim doesn't do file transfer yet, from what i can tell */
 	}
 
 	return 1;
@@ -684,7 +689,7 @@
 				i++;
 			}
 			}
-			aim_conn_close(command->conn);
+			aim_conn_kill(sess, &command->conn);
 			break;
 		default:
 			va_end(ap);
--- a/src/prefs.c	Tue Jun 06 09:36:12 2000 +0000
+++ b/src/prefs.c	Tue Jun 06 09:55:30 2000 +0000
@@ -213,12 +213,9 @@
 {
 	g_snprintf(aim_host, sizeof(aim_host), "%s", gtk_entry_get_text(GTK_ENTRY(pd->aim_host_entry)));
 	sscanf(gtk_entry_get_text(GTK_ENTRY(pd->aim_port_entry)), "%d", &aim_port);
-	if (proxy_type == PROXY_HTTP) {
-		g_snprintf(proxy_host, sizeof(proxy_host), "%s", gtk_entry_get_text(GTK_ENTRY(pd->http_proxy_host_entry)));
-		sscanf(gtk_entry_get_text(GTK_ENTRY(pd->http_proxy_port_entry)), "%d", &proxy_port);
-	} else if (proxy_type == PROXY_SOCKS) {
-		g_snprintf(proxy_host, sizeof(proxy_host), "%s", gtk_entry_get_text(GTK_ENTRY(pd->socks_proxy_host_entry)));
-		sscanf(gtk_entry_get_text(GTK_ENTRY(pd->socks_proxy_port_entry)), "%d", &proxy_port);
+	if (proxy_type != PROXY_NONE) {
+		g_snprintf(proxy_host, sizeof(proxy_host), "%s", gtk_entry_get_text(GTK_ENTRY(pd->proxy_host_entry)));
+		sscanf(gtk_entry_get_text(GTK_ENTRY(pd->proxy_port_entry)), "%d", &proxy_port);
 	}
 
 	g_snprintf(login_host, sizeof(login_host), "%s", gtk_entry_get_text(GTK_ENTRY(pd->login_host_entry)));
@@ -256,33 +253,16 @@
 static void set_connect(GtkWidget *w, int *data)
 {
 	proxy_type = (int)data;
-	if (proxy_type == PROXY_HTTP) {
-                if (pd->http_proxy_host_entry)
-                        gtk_widget_set_sensitive(pd->http_proxy_host_entry, TRUE);
-		if (pd->http_proxy_port_entry)
-			gtk_widget_set_sensitive(pd->http_proxy_port_entry, TRUE);
-		if (pd->socks_proxy_host_entry)
-			gtk_widget_set_sensitive(pd->socks_proxy_host_entry, FALSE);
-		if (pd->socks_proxy_port_entry)
-			gtk_widget_set_sensitive(pd->socks_proxy_port_entry, FALSE);
-	} else if (proxy_type == PROXY_SOCKS) {
-		if (pd->socks_proxy_host_entry)
-			gtk_widget_set_sensitive(pd->socks_proxy_host_entry, TRUE);
-		if (pd->socks_proxy_port_entry)
-			gtk_widget_set_sensitive(pd->socks_proxy_port_entry, TRUE);
-                if (pd->http_proxy_host_entry)
-                        gtk_widget_set_sensitive(pd->http_proxy_host_entry, FALSE);
-		if (pd->http_proxy_port_entry)
-			gtk_widget_set_sensitive(pd->http_proxy_port_entry, FALSE);
+	if (proxy_type != PROXY_NONE) {
+                if (pd->proxy_host_entry)
+                        gtk_widget_set_sensitive(pd->proxy_host_entry, TRUE);
+		if (pd->proxy_port_entry)
+			gtk_widget_set_sensitive(pd->proxy_port_entry, TRUE);
 	} else {
-                if (pd->http_proxy_host_entry)
-                        gtk_widget_set_sensitive(pd->http_proxy_host_entry, FALSE);
-		if (pd->http_proxy_port_entry)
-			gtk_widget_set_sensitive(pd->http_proxy_port_entry, FALSE);
-		if (pd->socks_proxy_host_entry)
-			gtk_widget_set_sensitive(pd->socks_proxy_host_entry, FALSE);
-		if (pd->socks_proxy_port_entry)
-			gtk_widget_set_sensitive(pd->socks_proxy_port_entry, FALSE);
+                if (pd->proxy_host_entry)
+                        gtk_widget_set_sensitive(pd->proxy_host_entry, FALSE);
+		if (pd->proxy_port_entry)
+			gtk_widget_set_sensitive(pd->proxy_port_entry, FALSE);
 	}
         
         save_prefs();
@@ -330,6 +310,7 @@
 	GtkWidget *fontbox;
 	GtkWidget *fontframe;
 	GtkWidget *appbox;
+	GtkWidget *appletbox;
 	GtkWidget *away_topbox;
 	GtkWidget *away_botbox;
 	GtkWidget *add_away;
@@ -342,7 +323,13 @@
 	GtkWidget *appearance_page;
 	GtkWidget *chat_page;
         GtkWidget *browser_page;
+#ifndef USE_OSCAR /* sorry, since we don't control the comm we can't set
+		     the connection */
         GtkWidget *connection_page;
+#endif
+#ifdef USE_APPLET
+	GtkWidget *applet_page;
+#endif
         GtkWidget *label;
         GtkWidget *browseropt;
         GtkWidget *connectopt;
@@ -396,15 +383,11 @@
 	gaim_button("Auto-login", &general_options, OPT_GEN_AUTO_LOGIN, genbox);
 	gaim_button("Log All Conversations", &general_options, OPT_GEN_LOG_ALL, genbox);
 	gaim_button("Strip HTML from log files", &general_options, OPT_GEN_STRIP_HTML, genbox);
-#ifdef USE_APPLET
-	gaim_button("Automatically Show Buddy List", &general_options, OPT_GEN_APP_BUDDY_SHOW, genbox);
-#endif
 	gaim_button("Raise windows when message recieved", &general_options, OPT_GEN_POPUP_WINDOWS, genbox);
         gaim_button("Send URLs as links", &general_options, OPT_GEN_SEND_LINKS, genbox);
 	gaim_button("Show Lag-O-Meter", &general_options, OPT_GEN_SHOW_LAGMETER, genbox);
         gaim_button("Save some window size/positions", &general_options, OPT_GEN_SAVED_WINDOWS, genbox);
         gaim_button("Ignore new conversations when away", &general_options, OPT_GEN_DISCARD_WHEN_AWAY, genbox);
-/*	gaim_button("Automagically check for new releases", &general_options, OPT_GEN_CHECK_VERSIONS, genbox); */
 	gaim_button("Automagically highlight misspelled words", &general_options, OPT_GEN_CHECK_SPELLING, genbox);
 	if (!dw && (general_options & OPT_GEN_DEBUG))
 		general_options = general_options ^ OPT_GEN_DEBUG;
@@ -441,8 +424,30 @@
 
         gtk_signal_connect_object( GTK_OBJECT(debugbutton), "clicked", GTK_SIGNAL_FUNC(show_debug), NULL);
 
+
+	/* Applet */
+#ifdef USE_APPLET
+
+	applet_page = gtk_vbox_new(FALSE, 0);
+	label = gtk_label_new("Applet");
+	gtk_widget_show(label);
+	gtk_notebook_append_page(GTK_NOTEBOOK(notebook), applet_page, label);
+
+        appletbox = gtk_vbox_new(FALSE, 5);
+        gtk_box_pack_start(GTK_BOX(applet_page), appletbox, TRUE, TRUE, 5);
+
+	gaim_button("Automatically Show Buddy List", &general_options, OPT_GEN_APP_BUDDY_SHOW, appletbox);
+	gaim_button("Sounds go through GNOME", &sound_options, OPT_SOUND_THROUGH_GNOME, appletbox);
+
+	gtk_widget_show(appletbox);
+	gtk_widget_show(applet_page);
+
+#endif
+	
+
         /* Connection */
         
+#ifndef USE_OSCAR
         connection_page = gtk_vbox_new(FALSE, 0);
         label = gtk_label_new("Connection");
         gtk_widget_show(label);
@@ -507,33 +512,19 @@
                 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(connectopt), TRUE);
 
 
-	hbox = gtk_hbox_new(FALSE, 0);
-	label = gtk_label_new("Proxy Host:");
-	gtk_widget_show(label);
-	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
-        pd->http_proxy_host_entry = gtk_entry_new();
-        gtk_widget_show(pd->http_proxy_host_entry);
-	gtk_box_pack_start(GTK_BOX(hbox), pd->http_proxy_host_entry, FALSE, FALSE, 0);
-
-	label = gtk_label_new("Port:");
-	gtk_widget_show(label);
-	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
-        pd->http_proxy_port_entry = gtk_entry_new();
-        gtk_widget_show(pd->http_proxy_port_entry);
-	gtk_box_pack_start(GTK_BOX(hbox), pd->http_proxy_port_entry, FALSE, FALSE, 0);
-	gtk_widget_show(hbox);
-	
-	gtk_box_pack_start(GTK_BOX(connection_page), hbox, FALSE, FALSE, 0);
-	gtk_entry_set_text(GTK_ENTRY(pd->http_proxy_host_entry), proxy_host);
-
-	g_snprintf(buffer, sizeof(buffer), "%d", proxy_port);
-	gtk_entry_set_text(GTK_ENTRY(pd->http_proxy_port_entry), buffer);
-
         connectopt = gtk_radio_button_new_with_label(gtk_radio_button_group(GTK_RADIO_BUTTON(connectopt)), "SOCKS v4 Proxy");
         gtk_box_pack_start(GTK_BOX(connection_page), connectopt, FALSE, FALSE, 0);
-        gtk_signal_connect(GTK_OBJECT(connectopt), "clicked", GTK_SIGNAL_FUNC(set_connect), (void *)PROXY_SOCKS);
+        gtk_signal_connect(GTK_OBJECT(connectopt), "clicked", GTK_SIGNAL_FUNC(set_connect), (void *)PROXY_SOCKS4);
 	gtk_widget_show(connectopt);
-	if (proxy_type == PROXY_SOCKS)
+	if (proxy_type == PROXY_SOCKS4)
+                gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(connectopt), TRUE);
+
+
+        connectopt = gtk_radio_button_new_with_label(gtk_radio_button_group(GTK_RADIO_BUTTON(connectopt)), "SOCKS v5 Proxy (DOES NOT WORK!)");
+        gtk_box_pack_start(GTK_BOX(connection_page), connectopt, FALSE, FALSE, 0);
+        gtk_signal_connect(GTK_OBJECT(connectopt), "clicked", GTK_SIGNAL_FUNC(set_connect), (void *)PROXY_SOCKS5);
+	gtk_widget_show(connectopt);
+	if (proxy_type == PROXY_SOCKS5)
                 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(connectopt), TRUE);
 
 
@@ -541,55 +532,38 @@
 	label = gtk_label_new("Proxy Host:");
 	gtk_widget_show(label);
 	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
-        pd->socks_proxy_host_entry = gtk_entry_new();
-        gtk_widget_show(pd->socks_proxy_host_entry);
-	gtk_box_pack_start(GTK_BOX(hbox), pd->socks_proxy_host_entry, FALSE, FALSE, 0);
+        pd->proxy_host_entry = gtk_entry_new();
+        gtk_widget_show(pd->proxy_host_entry);
+	gtk_box_pack_start(GTK_BOX(hbox), pd->proxy_host_entry, FALSE, FALSE, 0);
 
 	label = gtk_label_new("Port:");
 	gtk_widget_show(label);
 	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
-        pd->socks_proxy_port_entry = gtk_entry_new();
-        gtk_widget_show(pd->socks_proxy_port_entry);
-	gtk_box_pack_start(GTK_BOX(hbox), pd->socks_proxy_port_entry, FALSE, FALSE, 0);
+        pd->proxy_port_entry = gtk_entry_new();
+        gtk_widget_show(pd->proxy_port_entry);
+	gtk_box_pack_start(GTK_BOX(hbox), pd->proxy_port_entry, FALSE, FALSE, 0);
 	gtk_widget_show(hbox);
 	
 	gtk_box_pack_start(GTK_BOX(connection_page), hbox, FALSE, FALSE, 0);
-	gtk_entry_set_text(GTK_ENTRY(pd->socks_proxy_host_entry), proxy_host);
+	gtk_entry_set_text(GTK_ENTRY(pd->proxy_host_entry), proxy_host);
 
 	g_snprintf(buffer, sizeof(buffer), "%d", proxy_port);
-	gtk_entry_set_text(GTK_ENTRY(pd->socks_proxy_port_entry), buffer);
+	gtk_entry_set_text(GTK_ENTRY(pd->proxy_port_entry), buffer);
 
 
 	gtk_widget_show(connection_page);
 
 
-	if (proxy_type == PROXY_HTTP) {
-                if (pd->http_proxy_host_entry)
-                        gtk_widget_set_sensitive(pd->http_proxy_host_entry, TRUE);
-		if (pd->http_proxy_port_entry)
-			gtk_widget_set_sensitive(pd->http_proxy_port_entry, TRUE);
-		if (pd->socks_proxy_host_entry)
-			gtk_widget_set_sensitive(pd->socks_proxy_host_entry, FALSE);
-		if (pd->socks_proxy_port_entry)
-			gtk_widget_set_sensitive(pd->socks_proxy_port_entry, FALSE);
-	} else if (proxy_type == PROXY_SOCKS) {
-		if (pd->socks_proxy_host_entry)
-			gtk_widget_set_sensitive(pd->socks_proxy_host_entry, TRUE);
-		if (pd->socks_proxy_port_entry)
-			gtk_widget_set_sensitive(pd->socks_proxy_port_entry, TRUE);
-                if (pd->http_proxy_host_entry)
-                        gtk_widget_set_sensitive(pd->http_proxy_host_entry, FALSE);
-		if (pd->http_proxy_port_entry)
-			gtk_widget_set_sensitive(pd->http_proxy_port_entry, FALSE);
+	if (proxy_type != PROXY_NONE) {
+                if (pd->proxy_host_entry)
+                        gtk_widget_set_sensitive(pd->proxy_host_entry, TRUE);
+		if (pd->proxy_port_entry)
+			gtk_widget_set_sensitive(pd->proxy_port_entry, TRUE);
 	} else {
-                if (pd->http_proxy_host_entry)
-                        gtk_widget_set_sensitive(pd->http_proxy_host_entry, FALSE);
-		if (pd->http_proxy_port_entry)
-			gtk_widget_set_sensitive(pd->http_proxy_port_entry, FALSE);
-		if (pd->socks_proxy_host_entry)
-			gtk_widget_set_sensitive(pd->socks_proxy_host_entry, FALSE);
-		if (pd->socks_proxy_port_entry)
-			gtk_widget_set_sensitive(pd->socks_proxy_port_entry, FALSE);
+                if (pd->proxy_host_entry)
+                        gtk_widget_set_sensitive(pd->proxy_host_entry, FALSE);
+		if (pd->proxy_port_entry)
+			gtk_widget_set_sensitive(pd->proxy_port_entry, FALSE);
 	}
 
 	
@@ -598,11 +572,11 @@
         gtk_signal_connect(GTK_OBJECT(pd->aim_port_entry), "focus_out_event", GTK_SIGNAL_FUNC(connection_key_pressed), NULL);
 	gtk_signal_connect(GTK_OBJECT(pd->login_host_entry), "focus_out_event", GTK_SIGNAL_FUNC(connection_key_pressed), NULL);
 	gtk_signal_connect(GTK_OBJECT(pd->login_port_entry), "focus_out_event", GTK_SIGNAL_FUNC(connection_key_pressed), NULL);
-	gtk_signal_connect(GTK_OBJECT(pd->socks_proxy_host_entry), "focus_out_event", GTK_SIGNAL_FUNC(connection_key_pressed), NULL);
-        gtk_signal_connect(GTK_OBJECT(pd->socks_proxy_port_entry), "focus_out_event", GTK_SIGNAL_FUNC(connection_key_pressed), NULL);
-	gtk_signal_connect(GTK_OBJECT(pd->socks_proxy_host_entry), "focus_out_event", GTK_SIGNAL_FUNC(connection_key_pressed), NULL);
-        gtk_signal_connect(GTK_OBJECT(pd->socks_proxy_port_entry), "focus_out_event", GTK_SIGNAL_FUNC(connection_key_pressed), NULL);
+	gtk_signal_connect(GTK_OBJECT(pd->proxy_host_entry), "focus_out_event", GTK_SIGNAL_FUNC(connection_key_pressed), NULL);
+        gtk_signal_connect(GTK_OBJECT(pd->proxy_port_entry), "focus_out_event", GTK_SIGNAL_FUNC(connection_key_pressed), NULL);
 
+
+#endif /* USE_OSCAR */
 	
 	/* Away */
 	
--- a/src/proxy.c	Tue Jun 06 09:36:12 2000 +0000
+++ b/src/proxy.c	Tue Jun 06 09:55:30 2000 +0000
@@ -174,7 +174,7 @@
 	        
                 return ret;
                 break;
-        case PROXY_SOCKS: /* Socks v4 proxy (? I'm not a proxy hacker) */
+        case PROXY_SOCKS4: /* Socks v4 proxy (? I'm not a proxy hacker) */
 		/* this is going to be a cross between the HTTP proxy code
 		 * above and the TiK proxy code, translated from tcl->C */
 		{
@@ -228,6 +228,9 @@
 		}
 		return ret;
                 break;
+	case PROXY_SOCKS5:
+		return -1;
+		break;
         default:
                 fprintf(stderr,"Unknown proxy type : %d.\n",proxy_type);
                 break;
--- a/src/proxy.h	Tue Jun 06 09:36:12 2000 +0000
+++ b/src/proxy.h	Tue Jun 06 09:55:30 2000 +0000
@@ -33,7 +33,8 @@
 
 #define PROXY_NONE 0
 #define PROXY_HTTP 1
-#define PROXY_SOCKS 2		/* Not Implemented !! */
+#define PROXY_SOCKS4 2
+#define PROXY_SOCKS5 3
 
 /* masking gethostbyname function */
 extern struct hostent * proxy_gethostbyname(char *host) ;
--- a/src/server.c	Tue Jun 06 09:36:12 2000 +0000
+++ b/src/server.c	Tue Jun 06 09:55:30 2000 +0000
@@ -28,7 +28,7 @@
 #include <unistd.h>
 #include <gtk/gtk.h>
 #ifdef USE_OSCAR
-#include <faim/aim.h>
+#include <aim.h>
 extern int gaim_caps;
 #endif
 #include "gaim.h"
@@ -575,7 +575,7 @@
         g_snprintf(buf2, sizeof(buf2), "toc_chat_whisper %d %s \"%s\"", id, who, message);
         sflap_send(buf2, -1, TYPE_DATA);
 #else
-	do_error_dialog("Sorry, Oscar doesn't whisper. Send an IM.",
+	do_error_dialog("Sorry, Oscar doesn't whisper. Send an IM. (The last message was not received.)",
 			"Gaim - Chat");
 #endif
 }
--- a/src/sound.c	Tue Jun 06 09:36:12 2000 +0000
+++ b/src/sound.c	Tue Jun 06 09:55:30 2000 +0000
@@ -261,7 +261,6 @@
 }
 
 extern int logins_not_muted;
-#ifndef USE_APPLET
 
 void play_sound(int sound)
 {
@@ -294,12 +293,17 @@
        }
 }
 
-#else /* USE_APPLET */
+#ifdef USE_APPLET
 
 #include <gnome.h>
-void play_sound(int sound)
+void applet_play_sound(int sound)
 {
 
+	if (!(sound_options & OPT_SOUND_THROUGH_GNOME)) {
+		play_sound(sound);
+		return;
+	}
+
 	switch(sound) {
 	case BUDDY_ARRIVE:
 		if ((sound_options & OPT_SOUND_LOGIN) && logins_not_muted)