Index: ChangeLog
===================================================================
--- ChangeLog	(revision c04545549e3f0b43646330a258585390a50966cc)
+++ ChangeLog	(revision a352335c16b1820d3683357330a3b984458ac2d0)
@@ -1,16 +1,16 @@
 $Id$
 
-2.0.7-pre-2
-	Don't allow zwrite if zephyr isn't present
+2.0.7
+	Idletimes now appear in the buddylisting
+	Failed AIM logins are now correctly reported
+	Owl will build now without zephyr, enabling it to act as a
+	  standalone AIM client.
 	There is now a zcrypt command
 	Replies to zcrypted messages now work
-	Failed AIM logins are now correctly reported
-	
-2.0.7-pre-1
-	Owl should build now without zephyr, enabling it to act as a
-	  standalone AIM client.
+	Don't allow zwrite if zephyr isn't present
 	Cleaned up some warnings from linux gcc.
 	Fixed bug that can cause response stuff to crash
-	Idletimes now appear in the buddylisting
+	Improved status command
+	Fixed bug in buddy stuff
 	
 2.0.6
Index: aim.c
===================================================================
--- aim.c	(revision c04545549e3f0b43646330a258585390a50966cc)
+++ aim.c	(revision a352335c16b1820d3683357330a3b984458ac2d0)
@@ -147,5 +147,4 @@
   priv->server = "login.oscar.aol.com";
   owl_global_get_aimsess(&g)->aux_data = priv;
-
   
   /* login */
@@ -153,10 +152,24 @@
   if (ret) {
     owl_global_set_aimnologgedin(&g);
-    /* printf("login returned %i\n"); */
+    owl_global_set_no_doaimevents(&g);
     return(-1);
   }
+  owl_global_set_doaimevents(&g);
+  return(0);
+}
+
+/* stuff to run once login has been successful */
+void owl_aim_successful_login(char *screenname)
+{
   owl_global_set_aimloggedin(&g, screenname);
-
-  return(0);
+  owl_global_set_doaimevents(&g); /* this should already be on */
+  owl_function_makemsg("%s logged in", screenname);
+
+  owl_function_debugmsg("Successful AIM login for %s", screenname);
+
+  /* start the ingorelogin timer */
+  owl_timer_reset_newstart(owl_global_get_aim_login_timer(&g),
+			   owl_global_get_aim_ignorelogin_timer(&g));
+
 }
 
@@ -166,11 +179,17 @@
   logout(owl_global_get_aimsess(&g));
   owl_global_set_aimnologgedin(&g);
-}
-
-void owl_aim_login_error(void)
-{
-  owl_function_makemsg("Authentication error on login");
+  owl_global_set_no_doaimevents(&g);
+}
+
+void owl_aim_login_error(char *message)
+{
+  if (message) {
+    owl_function_makemsg(message);
+  } else {
+    owl_function_makemsg("Authentication error on login");
+  }
   owl_function_beep();
   owl_global_set_aimnologgedin(&g);
+  owl_global_set_no_doaimevents(&g);
 }
 
@@ -365,4 +384,5 @@
 
   /* printf("Screen name: %s\n", info->sn); */
+  owl_function_debugmsg("Here with %s", info->sn);
 
   /*
@@ -374,6 +394,23 @@
     printf("Error URL: %s\n", info->errorurl);
     */
-    owl_aim_login_error();
-    /* aim_conn_kill(sess, &fr->conn); */
+    if (info->errorcode==0x05) {
+      /* Incorrect nick/password */
+      owl_aim_login_error("Incorrect nickname or password.");
+    } else if (info->errorcode==0x11) {
+      /* Suspended account */
+      owl_aim_login_error("Your account is currently suspended.");
+    } else if (info->errorcode==0x14) {
+      /* service temporarily unavailable */
+      owl_aim_login_error("The AOL Instant Messenger service is temporarily unavailable.");
+    } else if (info->errorcode==0x18) {
+      /* connecting too frequently */
+      owl_aim_login_error("You have been connecting and disconnecting too frequently. Wait ten minutes and try again. If you continue to try, you will need to wait even longer.");
+    } else if (info->errorcode==0x1c) {
+      /* client too old */
+      owl_aim_login_error("The client version you are using is too old.");
+    } else {
+      owl_aim_login_error(NULL);
+    }
+    aim_conn_kill(sess, &fr->conn);
     return 1;
   }
@@ -395,7 +432,7 @@
     return 1;
   }
+  owl_aim_successful_login(info->sn);
   addcb_bos(sess, bosconn);
   aim_sendcookie(sess, bosconn, info->cookie);
-  owl_function_makemsg("%s logged in", info->sn);
   return 1;
 }
@@ -424,4 +461,6 @@
 int faimtest_conncomplete(aim_session_t *sess, aim_frame_t *fr, ...)
 {
+  /* owl_aim_successful_login(info->sn); */
+
   return 1;
 }
Index: buddylist.c
===================================================================
--- buddylist.c	(revision 5b85d1961e3bc41db16d76039f47ae0030762c90)
+++ buddylist.c	(revision a352335c16b1820d3683357330a3b984458ac2d0)
@@ -10,23 +10,14 @@
 
 /* Deal with an "oncoming" message.  This means recognizing the user
- * has logged in, and sending a message if they were not already
+ * has logged in, and displaying a message if they were not already
  * logged in.
  */
 void owl_buddylist_oncoming(owl_buddylist *b, char *screenname)
 {
-  int i, j, found;
+  int *zero;
   owl_message *m;
-  int *zero;
 
-  found=0;
-  j=owl_list_get_size(&(b->buddies));
-  for (i=0; i<j; i++) {
-    if (!strcasecmp(owl_list_get_element(&(b->buddies), i), screenname)) {
-      found=1;
-      break;
-    }
-  }
+  if (!owl_buddylist_is_buddy_loggedin(b, screenname)) {
 
-  if (!found) {
     /* add the buddy */
     owl_list_append_element(&(b->buddies), owl_strdup(screenname));
@@ -36,9 +27,10 @@
 
     /* do a request for idle time */
-    owl_buddylist_request_idletimes(owl_global_get_buddylist(&g));
+    owl_buddylist_request_idletime(b, screenname);
 	
     /* are we ingoring login messages for a while? */
     if (!owl_timer_is_expired(owl_global_get_aim_login_timer(&g))) return;
 
+    /* if not, create the login message */
     m=owl_malloc(sizeof(owl_message));
     owl_message_create_aim(m,
@@ -49,5 +41,4 @@
 			   1);
     owl_global_messagequeue_addmsg(&g, m);
-
   }
 }
@@ -58,31 +49,23 @@
 void owl_buddylist_offgoing(owl_buddylist *b, char *screenname)
 {
-  int i, j, found;
+  int index;
   owl_message *m;
 
-  found=0;
-  j=owl_list_get_size(&(b->buddies));
-  for (i=0; i<j; i++) {
-    if (!strcasecmp(owl_list_get_element(&(b->buddies), i), screenname)) {
-      found=1;
-      owl_free(owl_list_get_element(&(b->buddies), i));
-      owl_free(owl_list_get_element(&(b->idletimes), i));
-      owl_list_remove_element(&(b->buddies), i);
-      owl_list_remove_element(&(b->idletimes), i);
-      break;
-    }
-  }
+  index=owl_buddylist_get_buddy_index(b, screenname);
+  if (index==-1) return;
 
-  if (found) {
-    m=owl_malloc(sizeof(owl_message));
-    owl_message_create_aim(m,
-			   screenname,
-			   owl_global_get_aim_screenname(&g),
-			   "",
-			   OWL_MESSAGE_DIRECTION_IN,
-			   -1);
+  owl_free(owl_list_get_element(&(b->buddies), index));
+  owl_free(owl_list_get_element(&(b->idletimes), index));
+  owl_list_remove_element(&(b->buddies), index);
+  owl_list_remove_element(&(b->idletimes), index);
 
-    owl_global_messagequeue_addmsg(&g, m);
-  }
+  m=owl_malloc(sizeof(owl_message));
+  owl_message_create_aim(m,
+			 screenname,
+			 owl_global_get_aim_screenname(&g),
+			 "",
+			 OWL_MESSAGE_DIRECTION_IN,
+			 -1);
+  owl_global_messagequeue_addmsg(&g, m);
 }
 
@@ -101,4 +84,15 @@
 }
 
+/* send request to the AIM server to retrieve info on one buddy.  The
+ * AIM callback then fills in the values when the responses are
+ * received.  The buddy must be logged in or no request will be
+ * performed.
+ */
+void owl_buddylist_request_idletime(owl_buddylist *b, char *screenname)
+{
+  if (!owl_buddylist_is_buddy_loggedin(b, screenname)) return;
+  owl_aim_get_idle(screenname);
+}
+
 /* return the number of logged in buddies */
 int owl_buddylist_get_size(owl_buddylist *b)
@@ -110,5 +104,31 @@
 char *owl_buddylist_get_buddy(owl_buddylist *b, int n)
 {
+  if (n > owl_buddylist_get_size(b)-1) return("");
   return(owl_list_get_element(&(b->buddies), n));
+}
+
+/* Return the index of the buddy 'screename' or -1
+ * if the buddy is not logged in.
+ */
+int owl_buddylist_get_buddy_index(owl_buddylist *b, char *screenname)
+{
+  int i, j;
+  
+  j=owl_list_get_size(&(b->buddies));
+  for (i=0; i<j; i++) {
+    if (!strcasecmp(owl_list_get_element(&(b->buddies), i), screenname)) {
+      return(i);
+    }
+  }
+  return(-1);
+}
+
+/* return 1 if the buddy 'screenname' is logged in,
+ * otherwise return 0
+ */
+int owl_buddylist_is_buddy_loggedin(owl_buddylist *b, char *screenname)
+{
+  if (owl_buddylist_get_buddy_index(b, screenname)!=-1) return(1);
+  return(0);
 }
 
@@ -127,16 +147,13 @@
 void owl_buddylist_set_idletime(owl_buddylist *b, char *screenname, int minutes)
 {
-  int i, j, *idle;
+  int index, *idle;
 
-  j=owl_buddylist_get_size(b);
-  for (i=0; i<j; i++) {
-    if (!strcasecmp(owl_list_get_element(&(b->buddies), i), screenname)) {
-      owl_free(owl_list_get_element(&(b->idletimes), i));
-      idle=owl_malloc(sizeof(int));
-      *idle=minutes;
-      owl_list_replace_element(&(b->idletimes), i, idle);
-      return;
-    }
-  }
+  index=owl_buddylist_get_buddy_index(b, screenname);
+  if (index==-1) return;
+
+  owl_free(owl_list_get_element(&(b->idletimes), index));
+  idle=owl_malloc(sizeof(int));
+  *idle=minutes;
+  owl_list_replace_element(&(b->idletimes), index, idle);
 }
 
Index: commands.c
===================================================================
--- commands.c	(revision c04545549e3f0b43646330a258585390a50966cc)
+++ commands.c	(revision a352335c16b1820d3683357330a3b984458ac2d0)
@@ -2130,13 +2130,7 @@
   /* try to login */
   ret=owl_aim_login(argv[1], argv[2]);
-  if (!ret) {
-    /* start the ingorelogin timer */
-    owl_timer_reset_newstart(owl_global_get_aim_login_timer(&g),
-			     owl_global_get_aim_ignorelogin_timer(&g));
-    
-    return(NULL);
-  }
-  
-  owl_function_makemsg("Warning: login for %s failed.\n");
+  if (ret) owl_function_makemsg("Warning: login for %s failed.\n");
+
+  /* this is a test */
   return(NULL);
 }
Index: functions.c
===================================================================
--- functions.c	(revision 3ba3af00ede219be9bf18197463a48d3b5dd9d37)
+++ functions.c	(revision a352335c16b1820d3683357330a3b984458ac2d0)
@@ -1684,11 +1684,23 @@
   time_t start;
   int up, days, hours, minutes;
+  owl_fmtext fm;
+
+  owl_fmtext_init_null(&fm);
 
   start=owl_global_get_starttime(&g);
 
-  sprintf(buff, "Version: %s\n", OWL_VERSION_STRING);
-  sprintf(buff, "%sScreen size: %i lines, %i columns\n", buff, owl_global_get_lines(&g), owl_global_get_cols(&g));
-  sprintf(buff, "%sStartup Arugments: %s\n", buff, owl_global_get_startupargs(&g));
-  sprintf(buff, "%sStartup Time: %s", buff, ctime(&start));
+  owl_fmtext_append_normal(&fm, "Version: ");
+  owl_fmtext_append_normal(&fm, OWL_VERSION_STRING);
+  owl_fmtext_append_normal(&fm, "\n");
+
+  sprintf(buff, "Screen size: %i lines, %i columns\n", owl_global_get_lines(&g), owl_global_get_cols(&g));
+  owl_fmtext_append_normal(&fm, buff);
+
+  owl_fmtext_append_normal(&fm, "Startup Arugments: ");
+  owl_fmtext_append_normal(&fm, owl_global_get_startupargs(&g));
+  owl_fmtext_append_normal(&fm, "\n");
+  sprintf(buff, "Startup Time: %s", ctime(&start));
+  owl_fmtext_append_normal(&fm, buff);
+  
 
   up=owl_global_get_runtime(&g);
@@ -1699,17 +1711,36 @@
   minutes=up/60;
   up-=minutes*60;
-  sprintf(buff, "%sRun Time: %i days %2.2i:%2.2i:%2.2i\n", buff, days, hours, minutes, up);
+  sprintf(buff, "Run Time: %i days %2.2i:%2.2i:%2.2i\n", days, hours, minutes, up);
+  owl_fmtext_append_normal(&fm, buff);
 
   if (owl_global_get_hascolors(&g)) {
-    sprintf(buff, "%sColor: Yes, %i color pairs.\n", buff, owl_global_get_colorpairs(&g));
+    sprintf(buff, "Color: Yes, %i color pairs.\n", owl_global_get_colorpairs(&g));
   } else {
-    strcat(buff, "Color: No.\n");
-  }
-
+    sprintf(buff, "Color: No.\n");
+  }
+  owl_fmtext_append_normal(&fm, buff);
+
+  /*
   sprintf(buff, "%sMemory Malloced: %i\n", buff, owl_global_get_malloced(&g));
   sprintf(buff, "%sMemory Freed: %i\n", buff, owl_global_get_freed(&g));
   sprintf(buff, "%sMemory In Use: %i\n", buff, owl_global_get_meminuse(&g));
-
-  owl_function_popless_text(buff);
+  */
+
+  owl_fmtext_append_normal(&fm, "\n");
+  if (owl_global_is_aimloggedin(&g)) {
+    owl_fmtext_append_normal(&fm, "AIM: logged in as ");
+    owl_fmtext_append_normal(&fm, owl_global_get_aim_screenname(&g));
+    owl_fmtext_append_normal(&fm, "\n");
+  } else {
+    owl_fmtext_append_normal(&fm, "AIM: not logged in\n");
+  }
+  if (owl_global_is_doaimevents(&g)) {
+    owl_fmtext_append_normal(&fm, "AIM: processing events\n ");
+  } else {
+    owl_fmtext_append_normal(&fm, "AIM: not processing events\n ");
+  }
+
+  owl_function_popless_fmtext(&fm);
+  owl_fmtext_free(&fm);
 }
 
Index: global.c
===================================================================
--- global.c	(revision de0333491c0a25f06d19685b9e2e266e07b5187e)
+++ global.c	(revision a352335c16b1820d3683357330a3b984458ac2d0)
@@ -100,4 +100,5 @@
   g->havezephyr=0;
   g->haveaim=0;
+  owl_global_set_no_doaimevents(g);
 }
 
@@ -674,5 +675,8 @@
 char *owl_global_get_aim_screenname(owl_global *g)
 {
-  return (g->aim_screenname);
+  if (owl_global_is_aimloggedin(g)) {
+    return (g->aim_screenname);
+  }
+  return("");
 }
 
@@ -688,4 +692,21 @@
   g->aim_loggedin=0;
 }
+
+int owl_global_is_doaimevents(owl_global *g)
+{
+  if (g->aim_doprocessing) return(1);
+  return(0);
+}
+
+void owl_global_set_doaimevents(owl_global *g)
+{
+  g->aim_doprocessing=1;
+}
+
+void owl_global_set_no_doaimevents(owl_global *g)
+{
+  g->aim_doprocessing=0;
+}
+
 
 aim_session_t *owl_global_get_aimsess(owl_global *g)
Index: owl.c
===================================================================
--- owl.c	(revision de0333491c0a25f06d19685b9e2e266e07b5187e)
+++ owl.c	(revision a352335c16b1820d3683357330a3b984458ac2d0)
@@ -319,12 +319,13 @@
     followlast=owl_global_should_followlast(&g);
     
-    /* If we're logged into AIM, do AIM stuff */
-    if (owl_global_is_aimloggedin(&g)) {
-      owl_function_debugmsg("Doing aim processing");
+    /* Do AIM stuff */
+    if (owl_global_is_doaimevents(&g)) {
       owl_aim_process_events();
 
-      if (owl_timer_is_expired(owl_global_get_aim_buddyinfo_timer(&g))) {
-	owl_buddylist_request_idletimes(owl_global_get_buddylist(&g));
-	owl_timer_reset(owl_global_get_aim_buddyinfo_timer(&g));
+      if (owl_global_is_aimloggedin(&g)) {
+	if (owl_timer_is_expired(owl_global_get_aim_buddyinfo_timer(&g))) {
+	  owl_buddylist_request_idletimes(owl_global_get_buddylist(&g));
+	  owl_timer_reset(owl_global_get_aim_buddyinfo_timer(&g));
+	}
       }
     }
Index: owl.h
===================================================================
--- owl.h	(revision 5b85d1961e3bc41db16d76039f47ae0030762c90)
+++ owl.h	(revision a352335c16b1820d3683357330a3b984458ac2d0)
@@ -21,6 +21,6 @@
 static const char owl_h_fileIdent[] = "$Id$";
 
-#define OWL_VERSION         2.0.7-pre-2
-#define OWL_VERSION_STRING "2.0.7-pre-2"
+#define OWL_VERSION         2.0.7
+#define OWL_VERSION_STRING "2.0.7"
 
 #define OWL_DEBUG 0
@@ -447,4 +447,5 @@
   owl_timer aim_buddyinfo_timer;
   int aim_loggedin;         /* true if currently logged into AIM */
+  int aim_doprocessing;     /* true if we should process AIM events (like pending login) */
   char *aim_screenname;     /* currently logged in AIM screen name */
   owl_buddylist buddylist;  /* list of logged in AIM buddies */
