Index: functions.c
===================================================================
--- functions.c	(revision 5934b875fdd473a2de68eb58d5c7ccec7e602a82)
+++ functions.c	(revision f25812b2029878bb898c301ce9e06adee69692cf)
@@ -3410,52 +3410,35 @@
   int i, j;
   owl_list anyone;
-  owl_message *m;
   owl_zbuddylist *zbl;
+  GList **zaldlist;
+  GList *zaldptr;
+  ZAsyncLocateData_t *zald;
   const char *user;
-  ZLocations_t location[200];
-  int numlocs, ret;
 
   if (!owl_global_is_havezephyr(&g)) return;
-
-  zbl=owl_global_get_zephyr_buddylist(&g);
+  owl_global_set_pseudologin_notify(&g, notify);
+  zbl = owl_global_get_zephyr_buddylist(&g);
+  zaldlist = owl_global_get_zaldlist(&g);
+
+  /* Clear the existing ZALDs first. */
+  zaldptr = g_list_first(*zaldlist);
+  while (zaldptr) {
+    ZFreeALD(zaldptr->data);
+    owl_free(zaldptr->data);
+    zaldptr = g_list_next(zaldptr);
+  }
+  g_list_free(*zaldlist);
+  *zaldlist = NULL;
 
   owl_list_create(&anyone);
-  ret=owl_zephyr_get_anyone_list(&anyone, NULL);
-
-  j=owl_list_get_size(&anyone);
-  for (i=0; i<j; i++) {
-    user=owl_list_get_element(&anyone, i);
-    ret=ZLocateUser(zstr(user), &numlocs, ZAUTH);
-    if (ret!=ZERR_NONE) {
-      owl_function_error("Error getting location for %s", user);
-      continue;
-    }
-    numlocs=200;
-    ret=ZGetLocations(location, &numlocs);
-    if (ret==0) {
-      if ((numlocs>0) && !owl_zbuddylist_contains_user(zbl, user)) {
-	/* Send a PSEUDO LOGIN! */
-	if (notify) {
-	  m=owl_malloc(sizeof(owl_message));
-	  owl_message_create_pseudo_zlogin(m, 0, user, location[0].host, location[0].time, location[0].tty);
-	  owl_global_messagequeue_addmsg(&g, m);
-	}
-	owl_zbuddylist_adduser(zbl, user);
-	owl_function_debugmsg("owl_function_zephyr_buddy_check: login for %s ", user);
-      } else if ((numlocs==0) && owl_zbuddylist_contains_user(zbl, user)) {
-	/* I don't think this ever happens (if there are 0 locations we should get an error from
-	 * ZGetLocations)
-	 */
-	owl_function_error("owl_function_zephyr_buddy_check: exceptional case logout for %s ",user);
-      }
-    } else if ((ret==ZERR_NOLOCATIONS) && owl_zbuddylist_contains_user(zbl, user)) {
-      /* Send a PSEUDO LOGOUT! */
-      if (notify) {
-	m=owl_malloc(sizeof(owl_message));
-	owl_message_create_pseudo_zlogin(m, 1, user, "", "", "");
-	owl_global_messagequeue_addmsg(&g, m);
-      }
-      owl_zbuddylist_deluser(zbl, user);
-      owl_function_debugmsg("owl_function_zephyr_buddy_check: logout for %s ",user);
+  owl_zephyr_get_anyone_list(&anyone, NULL);
+  j = owl_list_get_size(&anyone);
+  for (i = 0; i < j; i++) {
+    user = owl_list_get_element(&anyone, i);
+    zald = owl_malloc(sizeof(ZAsyncLocateData_t));
+    if (ZRequestLocations(zstr(user), zald, UNACKED, ZAUTH) == ZERR_NONE) {
+      *zaldlist = g_list_append(*zaldlist, zald);
+    } else {
+      owl_free(zald);
     }
   }
Index: global.c
===================================================================
--- global.c	(revision 59ab8dd786d5bd5660425148c60e9f2a11a0d81d)
+++ global.c	(revision f25812b2029878bb898c301ce9e06adee69692cf)
@@ -110,4 +110,7 @@
   owl_zbuddylist_create(&(g->zbuddies));
 
+  g->zaldlist = NULL;
+  g->pseudologin_notify = 0;
+
   owl_obarray_init(&(g->obarray));
 
@@ -963,4 +966,19 @@
 }
 
+GList **owl_global_get_zaldlist(owl_global *g)
+{
+  return &(g->zaldlist);
+}
+
+int owl_global_get_pseudologin_notify(owl_global *g)
+{
+  return g->pseudologin_notify;
+}
+
+void owl_global_set_pseudologin_notify(owl_global *g, int notify)
+{
+  g->pseudologin_notify = notify;
+}
+
 struct termios *owl_global_get_startup_tio(owl_global *g)
 {
Index: owl.h
===================================================================
--- owl.h	(revision 03c5bddef12e63f0cf2dacca911a8830b13d76e9)
+++ owl.h	(revision f25812b2029878bb898c301ce9e06adee69692cf)
@@ -604,4 +604,6 @@
   owl_zbuddylist zbuddies;
   owl_timer zephyr_buddycheck_timer;
+  GList *zaldlist;
+  int pseudologin_notify;
   struct termios startup_tio;
   owl_obarray obarray;
Index: zephyr.c
===================================================================
--- zephyr.c	(revision c230bc1b418cbace9d748df62640c26a59aa1622)
+++ zephyr.c	(revision f25812b2029878bb898c301ce9e06adee69692cf)
@@ -1299,4 +1299,69 @@
 }
 
+#ifdef HAVE_LIBZEPHYR
+void owl_zephyr_process_pseudologin(ZNotice_t *n)
+{
+  owl_message *m;
+  owl_zbuddylist *zbl;
+  GList **zaldlist;
+  GList *zaldptr;
+  ZAsyncLocateData_t *zald = NULL;
+  ZLocations_t location;
+  int numlocs, ret, notify;
+
+  /* Find a ZALD to match this notice. */
+  zaldlist = owl_global_get_zaldlist(&g);
+  zaldptr = g_list_first(*zaldlist);
+  while (zaldptr) {
+    if (ZCompareALDPred(n, zaldptr->data)) {
+      zald = zaldptr->data;
+      *zaldlist = g_list_remove(*zaldlist, zaldptr->data);
+      break;
+    }
+    zaldptr = g_list_next(zaldptr);
+  }
+  if (zald) {
+    /* Deal with notice. */
+    notify = owl_global_get_pseudologin_notify(&g);
+    zbl = owl_global_get_zephyr_buddylist(&g);
+    ret = ZParseLocations(n, zald, &numlocs, NULL);
+    if (ret == ZERR_NONE) {
+      if (numlocs > 0 && !owl_zbuddylist_contains_user(zbl, zald->user)) {
+        if (notify) {
+          numlocs = 1;
+          ret = ZGetLocations(&location, &numlocs);
+          if (ret == ZERR_NONE) {
+            /* Send a PSEUDO LOGIN! */
+            m = owl_malloc(sizeof(owl_message));
+            owl_message_create_pseudo_zlogin(m, 0, zald->user,
+                                             location.host,
+                                             location.time,
+                                             location.tty);
+            owl_global_messagequeue_addmsg(&g, m);
+          }
+          owl_zbuddylist_adduser(zbl, zald->user);
+          owl_function_debugmsg("owl_function_zephyr_buddy_check: login for %s ", zald->user);
+        }
+      } else if (numlocs == 0 && owl_zbuddylist_contains_user(zbl, zald->user)) {
+        /* Send a PSEUDO LOGOUT! */
+        if (notify) {
+          m = owl_malloc(sizeof(owl_message));
+          owl_message_create_pseudo_zlogin(m, 1, zald->user, "", "", "");
+          owl_global_messagequeue_addmsg(&g, m);
+        }
+        owl_zbuddylist_deluser(zbl, zald->user);
+        owl_function_debugmsg("owl_function_zephyr_buddy_check: logout for %s ", zald->user);
+      }
+    }
+    ZFreeALD(zald);
+    owl_free(zald);
+  }
+}
+#else
+void owl_zephyr_process_pseudologin(void *n)
+{
+}
+#endif
+
 /*
  * Process zephyrgrams from libzephyr's queue. To prevent starvation,
@@ -1333,4 +1398,11 @@
       }
 
+      /* if it is a LOCATE message, it's for pseudologins. */
+      if (strcmp(notice.z_opcode, LOCATE_LOCATE) == 0) {
+        owl_zephyr_process_pseudologin(&notice);
+        ZFreeNotice(&notice);
+        continue;
+      }
+
       /* create the new message */
       m=owl_malloc(sizeof(owl_message));
