TOC plugin (AIM and ICQ)

"A. Craig West" <[email protected]> Tue, 6 Apr 2004 02:57:12 -0400 (EDT)
Newsgroups gmane.network.everybuddy.devel
Message-ID <[email protected]>
I've been doing a lot of re-organization in the toc code, and it seems to be
working now, although I really need to test with ICQ, all of my testing so
far is with AIM. But here are my diffs from the trunk (including some minor
fixes for yahoo)
The TOC changes mostly help make connecting and disconnecting more
deterministic. Now, it occasionally gets stuck trying to connect, but this is
no longer critical, just disconnect and reconnect seems to work. Be nic to
know why the connection doesn't always go through, though...

----------------- Patch Begins ------------------------
Index: core/plugins/yahoo/yahoo.c
===================================================================
--- core/plugins/yahoo/yahoo.c	(revision 334)
+++ core/plugins/yahoo/yahoo.c	(working copy)
@@ -148,6 +148,7 @@
   if (lad->id != -1)
   {
     yahoo_logoff(lad->id);
+    lad->id = -1;
   }
 }
 
@@ -169,6 +170,7 @@
     {
       /* connect to the server */
       login(la);
+      return; /* so we don't do this processing twice */
     }
 
     if (!strcmp(state, "Online"))
Index: core/plugins/toc/toc.c
===================================================================
--- core/plugins/toc/toc.c	(revision 334)
+++ core/plugins/toc/toc.c	(working copy)
@@ -35,6 +35,9 @@
 
 int eb_toc_init(void);
 int eb_toc_finish(void);
+void eb_toc_login(eb_local_account * ela);
+void eb_toc_logout(eb_local_account * ela);
+void eb_toc_disconnect (toc_conn * conn);
 
 eb_plugin_info toc_LTX_plugin_info={"AIM/ICQ via TOC", "Torrey Searle's libtoc", "Who knows?", "Who cares?", eb_toc_init, eb_toc_finish};
 
@@ -94,85 +97,128 @@
 void eb_toc_set_state(eb_local_account * ela, char * state)
 {
   eb_toc_lad * lad=GET_LAD(ela);
+  char * st_str = NULL;
 
-  if(!strcmp(state, "Online") || !strcmp(state, "Away"))
+  if(!strcmp(state, "Offline"))
   {
-    if(ela->connected)
+    eb_toc_logout(ela);
+    return;
+  }
+  else
+  {
+    /* Check if we are connected yet */
+    if (!ela->connected)
     {
-      if(ela->ready && state[0]=='A' && !lad->away)
+      /* connect to the server */
+      eb_toc_login(ela);
+    }
+    else if (ela->ready)
+    {
+      /* Only set the away message if the connection is ready */
+
+      if(!strcmp(state, "Online"))
       {
-        toc_set_away(lad->conn, "This user is away.");
-        lad->away=1;
-        free(ela->status_string);
-        ela->status_string=strdup("Away");
+	if (lad->away)
+	{
+	  toc_set_away(lad->conn, NULL);
+	  lad->away = 0;
+	}
       }
+      else
+      {
+	/* when changing the away message, need to change to not away first */
+        if (lad->away)
+	{
+	  toc_set_away(lad->conn, NULL);
+	}
+	else
+	{
+	  lad->away = 1;
+	}
 
-      if(ela->ready && state[0]=='O' && lad->away)
-      {
-        toc_set_away(lad->conn, NULL);
-        lad->away=0;
-        free(ela->status_string);
-        ela->status_string=strdup("Online");
+	if(!strcmp(state, "Away"))
+	{
+	  toc_set_away(lad->conn, "This user is away.");
+	}
+	else
+	{
+	  toc_set_away(lad->conn, state);
+	}
       }
 
+      free(ela->status_string);
+      ela->status_string = strdup(state);
       eb_local_account_update(ela);
-      return;
     }
+  }
+}
 
-    ela->connected=1;
-    eb_local_account_update(ela);
+void eb_toc_login(eb_local_account * ela)
+{
+  eb_toc_lad * lad = GET_LAD(ela);
 
-    lad->conn=toc_signon(ela->handle, eb_get_value(ela->config_key, "password"),
-      eb_get_value(ela->config_key, "toc/server"), atoi(eb_get_value(ela->config_key, "toc/port")),
-      eb_get_value(ela->config_key, "user_info"));
+  if (atoi(eb_get_value(ela->config_key, "excl_soa")))
+  { return; }
 
-    if(lad->conn==NULL)
-    {
-      eb_show_error("Could not log into TOC server. Check your preferences and try again.", "Connection failed");
-      ela->connected=0;
-      eb_local_account_update(ela);
-      return;
-    }
+  ela->connected = 1;
+  ela->ready = 0;
+  eb_local_account_update(ela);
 
-    lad->fd_tag=eb_input_add(lad->conn->fd, EB_INPUT_READ|EB_INPUT_EXCEPTION, eb_toc_callback, lad->conn);
+  if (lad->conn != NULL)
+  {
+    eb_toc_disconnect(lad->conn);
+  }
 
-    lad->conn->account=ela;
+  lad->conn = toc_signon(ela->handle, eb_get_value(ela->config_key, "password"),
+    eb_get_value(ela->config_key, "toc/server"), atoi(eb_get_value(ela->config_key, "toc/port")),
+    eb_get_value(ela->config_key, "user_info"));
 
-    ela->ready=1;
-    if(state[0]=='A')
-    {
-      toc_set_away(lad->conn, "This user is away");
-      lad->away=1;
-      free(ela->status_string);
-      ela->status_string=strdup("Away");
-    } else {
-      free(ela->status_string);
-      ela->status_string=strdup("Online");
-    }
+  if (lad->conn == NULL)
+  {
+    eb_show_error("Could not log into TOC server. Check your preferences and try again.", "Connection failed");
+    ela->connected = 0;
     eb_local_account_update(ela);
     return;
   }
 
-  if(!strcmp(state, "Offline"))
-  {
-    if(!ela->connected) { return; }
+  lad->conn->account = ela;
 
-    toc_signoff(lad->conn);
-    eb_local_account_update(ela);
-  }
-}
+  lad->fd_tag = eb_input_add(lad->conn->fd, EB_INPUT_READ|EB_INPUT_EXCEPTION, eb_toc_callback, lad->conn);
 
-void eb_toc_login(eb_local_account * ela)
-{
-  if(atoi(eb_get_value(ela->config_key, "excl_soa")))
-  { return; }
-
+  ela->ready = 1;
   eb_toc_set_state(ela, "Online");
 }
 
 void eb_toc_logout(eb_local_account * ela)
 {
-  eb_toc_set_state(ela, "Offline");
+  EList * en;
+  eb_toc_lad * lad = GET_LAD(ela);
+
+  if (!ela->connected)
+    return;
+
+  for (en = ela->buddies; en != NULL; en = en->next)
+  {
+    eb_account * acc = (eb_account *)en->data;
+    if (acc->status != EB_ACCOUNT_OFFLINE)
+    {
+      free(acc->status_string);
+      acc->status_string = strdup("Offline");
+      acc->status = EB_ACCOUNT_OFFLINE;
+      eb_buddy_update_status(acc);
+      eb_buddy_logout(acc);
+    }
+  }
+
+  free(ela->status_string);
+  ela->status_string = strdup("Offline");
+  ela->ready = ela->connected = 0;
+  eb_local_account_update(ela);
+  if (lad->conn != NULL)
+  {
+    eb_toc_disconnect(lad->conn);
+  }
+  lad->away=0;
 }
 
 void eb_toc_setup_local_account(eb_local_account * ela)
@@ -273,33 +319,12 @@
 
 void eb_toc_set_away(eb_local_account * ela, char * short_msg, char * long_msg)
 {
-  eb_toc_lad * lad=GET_LAD(ela);
-
-  if(lad->away)
-  { toc_set_away(lad->conn, NULL); }
-
-  toc_set_away(lad->conn, long_msg);
-
-  free(ela->status_string);
-  ela->status_string=strdup("Away");
-  eb_local_account_update(ela);
-
-  lad->away=1;
+  eb_toc_set_state(ela, long_msg);
 }
 
 void eb_toc_unset_away(eb_local_account * ela)
 {
-  eb_toc_lad * lad=GET_LAD(ela);
-
-  if(lad->away)
-  {
-    toc_set_away(lad->conn, NULL);
-    lad->away=0;
-
-    free(ela->status_string);
-    ela->status_string=strdup("Online");
-    eb_local_account_update(ela);
-  }
+  eb_toc_set_state(ela, "Online");
 }
 
 void eb_toc_join_group_chat(eb_local_account * ela, char * name)
@@ -427,54 +452,84 @@
 void eb_toc_update_user_status (toc_conn * conn, char * user, int online, time_t idle, int evil, int unavailable )
 {
   eb_local_account * ela=GET_ELA(conn);
-  eb_account * acc=eb_toc_get_account(ela, user);
+  eb_account * acc;
   char buf[64];
-  char buf2[32];
+  char buf2[64];
+  int do_login = 0;
+  int do_logout = 0;
 
-  if(acc==NULL)
+  if (ela == NULL)
   {
     printf("Martian buddy update (%s)\n", user);
     return;
   }
 
-  if(acc->status!=EB_ACCOUNT_OFFLINE && !online)
-  { eb_buddy_logout(acc); return; }
+  acc = eb_toc_get_account(ela, user);
+  if (acc == NULL)
+  {
+    acc = eb_add_account_plus("Unknown", user, ela, user);
+  }
 
-  if(acc->status==EB_ACCOUNT_OFFLINE && online)
-  { eb_buddy_login(acc); }
+  if (acc->status == EB_ACCOUNT_OFFLINE)
+  {
+    do_login = 1;
+  }
 
-  buf[0]='\0';
-  if(idle>0)
+  free(acc->status_string);
+  if (online)
   {
-    int mins=(time(NULL)-idle)/60;
-    buf[0]='(';
-    buf[1]='\0';
+    if (unavailable)
+    {
+      acc->status = EB_ACCOUNT_AWAY;
+      sprintf(buf, "Away");
+    }
+    else
+    {
+      acc->status = EB_ACCOUNT_ONLINE;
+      sprintf(buf, "");
+    }
 
-    if(mins/(60*24))
+    if (idle > 0)
     {
-      sprintf(buf2, "%d:", mins/(60*24));
+      int mins = (time(NULL) - idle) / 60;
+      strcat(buf, "(");
+
+      if (mins / (60 * 24))
+      {
+	sprintf(buf2, "%d:", mins / (60 * 24));
+	strcat(buf, buf2);
+	mins %= (60 * 24);
+      }
+
+      sprintf(buf2, "%d:%02d)", mins / 60, mins % 60);
       strcat(buf, buf2);
-      mins%=(60*24);
     }
 
-    sprintf(buf2, "%d:%02d)", mins/60, mins%60);
-    strcat(buf, buf2);
+    if (evil)
+    {
+      sprintf(buf2, " [%d%%]", evil);
+      strcat(buf, buf2);
+    }
+
+    acc->status_string = strdup(buf);
   }
+  else
+  {
+    acc->status = EB_ACCOUNT_OFFLINE;
+    acc->status_string = strdup("Offline");
+    do_login = 0;
+    do_logout = 1;
+  }
 
-  if(evil)
+  if (do_login)
   {
-    char buf2[32];
-    sprintf(buf2, " [%d%%]", evil);
-    strcat(buf, buf2);
+    eb_buddy_login(acc);
   }
-
-  if(unavailable)
-  { acc->status=EB_ACCOUNT_AWAY; } else { acc->status=EB_ACCOUNT_ONLINE; }
-
-  free(acc->status_string);
-  acc->status_string=strdup(buf);
-
   eb_buddy_update_status(acc);
+  if (do_logout)
+  {
+    eb_buddy_logout(acc);
+  }
 }
 
 void eb_toc_error_message(char * message)
@@ -485,36 +540,28 @@
 void eb_toc_disconnect (toc_conn * conn)
 {
   eb_local_account * ela=GET_ELA(conn);
+  eb_toc_lad * lad;
   EList * n;
 
-  if(ela==NULL) { return; }
+  if (conn == NULL)
+    return;
 
-  if(ela->connected)
+  if (ela == NULL)
   {
-    ela->connected=0;
-    toc_signoff(conn);
   } else {
-    printf("I'm going all loopy...\n");
-  }
+    lad=GET_LAD(ela);
 
-  GET_LAD(ela)->away=0;
+    lad->conn = NULL; /* Make sure that logout doesn't try to call us */
 
-  ela->connected=0;
-  ela->ready=0;
-  GET_LAD(ela)->conn=NULL;
-  free(ela->status_string);
-  ela->status_string=strdup("Offline");
-  eb_input_remove(GET_LAD(ela)->fd_tag);
-
-  for(n=ela->buddies; n!=NULL; n=n->next)
-  {
-    eb_account * a=(eb_account *)n->data;
-
-    if(a->status!=EB_ACCOUNT_OFFLINE)
-    { eb_buddy_logout(a); }
+    if(ela->connected)
+    {
+      eb_toc_logout(ela);
+    }
+    eb_input_remove(lad->fd_tag);
   }
 
-  eb_local_account_update(ela);
+  toc_signoff(conn);
+  free(conn);
 }
 
 void eb_toc_join_ack (toc_conn * conn, char * id, char * name)
----------------- Patch Ends ------------------------

-- 
Craig West         Ph: (416) 666-1645	|  It's not a bug,
[email protected]              	|  It's a feature...