Index: .gitignore
===================================================================
--- .gitignore	(revision 1703f7231e2822e81916109bafcfebee606f7beb)
+++ .gitignore	(revision 42ad91716a0f429f02385235acffa71546e28caa)
@@ -4,5 +4,4 @@
 *~
 .#*
-.*.swp
 .deps
 META.yml
Index: Makefile.am
===================================================================
--- Makefile.am	(revision b373d4433450dc226e49ae0d4eda3542c4a42904)
+++ Makefile.am	(revision 42ad91716a0f429f02385235acffa71546e28caa)
@@ -20,8 +20,9 @@
 perl_tester_SOURCES = $(BASE_SRCS) \
      owl.h owl_perl.h config.h \
+     libzcrypt.a \
      $(GEN_C) $(GEN_H) \
      perl_tester.c
 
-perl_tester_LDADD = libfaim/libfaim.a
+perl_tester_LDADD = libfaim/libfaim.a libzcrypt.a
 
 TESTS=runtests.sh
@@ -42,6 +43,4 @@
 GEN_H = owl_prototypes.h
 
-TYPEMAP = typemap
-
 BUILT_SOURCES = $(GEN_C) $(GEN_H)
 
@@ -55,6 +54,6 @@
 proto: owl_prototypes.h
 
-perlglue.c: perlglue.xs $(TYPEMAP)
-	$(AM_V_GEN)perl $(XSUBPPDIR)/xsubpp $(XSUBPPFLAGS) -prototypes perlglue.xs -typemap $(TYPEMAP) > perlglue.c
+perlglue.c: perlglue.xs
+	$(AM_V_GEN)perl $(XSUBPPDIR)/xsubpp $(XSUBPPFLAGS) -prototypes perlglue.xs > perlglue.c
 
 varstubs.c: stubgen.pl variable.c
Index: aim.c
===================================================================
--- aim.c	(revision 1fdca1ba004d56eb347146421fd728b822931f1d)
+++ aim.c	(revision c79a04782cf599c7fdc305dbe33acb4b8842c771)
@@ -249,62 +249,22 @@
 }
 
-/*
- * I got these constants by skimming libfaim/im.c
- *
- * "UNICODE" actually means "UCS-2BE".
- */
-#define AIM_CHARSET_ISO_8859_1         0x0003
-#define AIM_CHARSET_UNICODE            0x0002
-
-int owl_aim_do_send(const char *to, const char *msg, int flags) /* noproto */
+int owl_aim_send_im(const char *to, const char *msg)
 {
   int ret;
-  char *encoded;
-  struct aim_sendimext_args args;
-    gsize len;
-
-  encoded = g_convert(msg, -1, "ISO-8859-1", "UTF-8", NULL, &len, NULL);
-  if (encoded) {
-    owl_function_debugmsg("Encoded outgoing AIM as ISO-8859-1");
-    args.charset = AIM_CHARSET_ISO_8859_1;
-    args.charsubset = 0;
-    args.flags = AIM_IMFLAGS_ISO_8859_1;
-  } else {
-    owl_function_debugmsg("Encoding outgoing IM as UCS-2BE");
-    encoded = g_convert(msg, -1, "UCS-2BE", "UTF-8", NULL, &len, NULL);
-    if (!encoded) {
-      /*
-       * TODO: Strip or HTML-encode characters, or figure out how to
-       * send in a differen charset.
-       */
-      owl_function_error("Unable to encode outgoing AIM message in UCS-2");
-      return 1;
-    }
-
-    args.charset = AIM_CHARSET_UNICODE;
-    args.charsubset = 0;
-    args.flags = AIM_IMFLAGS_UNICODE;
-  }
-
-  args.destsn = to;
-  args.msg = encoded;
-  args.msglen = len;
-  args.flags |= flags;
-
-  ret=aim_im_sendch1_ext(owl_global_get_aimsess(&g), &args);
-
-  owl_free(encoded);
-
+
+  ret=aim_im_sendch1(owl_global_get_aimsess(&g), to, 0, msg);
+    
+  /* I don't know how to check for an error yet */
   return(ret);
 }
 
-int owl_aim_send_im(const char *to, const char *msg)
-{
-  return owl_aim_do_send(to, msg, 0);
-}
-
 int owl_aim_send_awaymsg(const char *to, const char *msg)
 {
-  return owl_aim_do_send(to, msg, AIM_IMFLAGS_AWAY);
+  int ret;
+
+  ret=aim_im_sendch1(owl_global_get_aimsess(&g), to, AIM_IMFLAGS_AWAY, msg);
+
+  /* I don't know how to check for an error yet */
+  return(ret);
 }
 
@@ -1189,20 +1149,80 @@
   owl_message *m;
   char *stripmsg, *nz_screenname, *wrapmsg;
-  char *realmsg = NULL;
-
-  if (!args->msg) {
-    realmsg = owl_strdup("");
-  } else if (args->icbmflags & AIM_IMFLAGS_UNICODE) {
-    realmsg = g_convert(args->msg, args->msglen, "UTF-8", "UCS-2BE",
-                        NULL, NULL, NULL);
-  } else if(args->icbmflags & AIM_IMFLAGS_ISO_8859_1) {
-    realmsg = g_convert(args->msg, args->msglen, "UTF-8", "ISO-8859-1",
-                        NULL, NULL, NULL);
+  char realmsg[8192+1] = "";
+  /* int clienttype = AIM_CLIENTTYPE_UNKNOWN; */
+
+  /* clienttype = aim_fingerprintclient(args->features, args->featureslen); */
+
+  /*
+  printf("icbm: sn = \"%s\"\n", userinfo->sn);
+  printf("icbm: probable client type: %d\n", clienttype);
+  printf("icbm: warnlevel = %f\n", aim_userinfo_warnlevel(userinfo));
+  printf("icbm: flags = 0x%04x = ", userinfo->flags);
+  printuserflags(userinfo->flags);
+  printf("\n");
+  */
+
+  /*
+  printf("icbm: membersince = %lu\n", userinfo->membersince);
+  printf("icbm: onlinesince = %lu\n", userinfo->onlinesince);
+  printf("icbm: idletime = 0x%04x\n", userinfo->idletime);
+  printf("icbm: capabilities = %s = 0x%08lx\n", (userinfo->present & AIM_USERINFO_PRESENT_CAPABILITIES) ? "present" : "not present", userinfo->capabilities);
+  */
+
+  /*
+  printf("icbm: icbmflags = ");
+  if (args->icbmflags & AIM_IMFLAGS_AWAY) printf("away ");
+  if (args->icbmflags & AIM_IMFLAGS_ACK) printf("ackrequest ");
+  if (args->icbmflags & AIM_IMFLAGS_OFFLINE) printf("offline ");
+  if (args->icbmflags & AIM_IMFLAGS_BUDDYREQ) printf("buddyreq ");
+  if (args->icbmflags & AIM_IMFLAGS_HASICON) printf("hasicon ");
+  printf("\n");
+  */
+
+  /*
+  if (args->icbmflags & AIM_IMFLAGS_CUSTOMCHARSET) {
+  printf("icbm: encoding flags = {%04x, %04x}\n", args->charset, args->charsubset);
+  }
+  */
+  
+  /*
+   * Quickly convert it to eight bit format, replacing non-ASCII UNICODE 
+   * characters with their equivelent HTML entity.
+   */
+  if (args->icbmflags & AIM_IMFLAGS_UNICODE) {
+    int i;
+    
+    for (i=0; i<args->msglen; i+=2) {
+      fu16_t uni;
+
+      uni = ((args->msg[i] & 0xff) << 8) | (args->msg[i+1] & 0xff);
+      if ((uni < 128) || ((uni >= 160) && (uni <= 255))) { /* ISO 8859-1 */
+	snprintf(realmsg+strlen(realmsg), sizeof(realmsg)-strlen(realmsg), "%c", uni);
+      } else { /* something else, do UNICODE entity */
+	snprintf(realmsg+strlen(realmsg), sizeof(realmsg)-strlen(realmsg), "&#%04x;", uni);
+      }
+    }
   } else {
-    realmsg = owl_strdup(args->msg);
-  }
-
-  if (!realmsg) {
-    realmsg = owl_strdup("[Error decoding incoming IM]");
+    /*
+     * For non-UNICODE encodings (ASCII and ISO 8859-1), there is 
+     * no need to do anything special here.  Most 
+     * terminals/whatever will be able to display such characters 
+     * unmodified.
+     *
+     * Beware that PC-ASCII 128 through 159 are _not_ actually 
+     * defined in ASCII or ISO 8859-1, and you should send them as 
+     * UNICODE.  WinAIM will send these characters in a UNICODE 
+     * message, so you need to do so as well.
+     *
+     * You may not think it necessary to handle UNICODE messages.  
+     * You're probably wrong.  For one thing, Microsoft "Smart
+     * Quotes" will be sent by WinAIM as UNICODE (not HTML UNICODE,
+     * but real UNICODE). If you don't parse UNICODE at all, your 
+     * users will get a blank message instead of the message 
+     * containing Smart Quotes.
+     *
+     */
+    if (args->msg && args->msglen)
+      strncpy(realmsg, args->msg, sizeof(realmsg));
   }
 
@@ -1249,6 +1269,19 @@
   }
 
-  owl_free(realmsg);
-
+  /*
+  if (realmsg) {
+    int i = 0;
+    while (realmsg[i] == '<') {
+      if (realmsg[i] == '<') {
+	while (realmsg[i] != '>')
+	  i++;
+	i++;
+      }
+    }
+    tmpstr = realmsg+i;
+    faimtest_handlecmd(sess, conn, userinfo, tmpstr);
+  }
+  */
+  
   return(1);
 }
Index: commands.c
===================================================================
--- commands.c	(revision 5ade618c57cac0be3d8abfc5ec361c636937bb78)
+++ commands.c	(revision 61de0850fedd7ac9f03bd5642d1ea9fc10d970e9)
@@ -861,5 +861,5 @@
   OWLCMD_VOID_CTX("edit:history-next", owl_command_edit_history_next, 
 		  OWL_CTX_EDIT,
-		  "replaces the text with the next history",
+		  "replaces the text with the previous history",
 		  "", ""),
 
Index: editwin.c
===================================================================
--- editwin.c	(revision 6c171f190998142df485a1f93b4ef7bad5a8ea57)
+++ editwin.c	(revision 2184001c40142118127a6101aeb6da9357898928)
@@ -326,13 +326,19 @@
 static void oe_release_excursion(owl_editwin *e, oe_excursion *x)
 {
-  oe_excursion **px;
+  oe_excursion *p;
 
   x->valid = 0;
-  for (px = &e->excursions; *px != NULL; px = &(*px)->next)
-    if (*px == x) {
-      *px = x->next;
-      return;
-    }
-  abort();
+  if (e->excursions == NULL)
+    /* XXX huh. */ ;
+  else if (e->excursions == x)
+    e->excursions = x->next;
+  else {
+    for (p = e->excursions; p->next != NULL; p = p->next)
+      if (p->next == x) {
+	p->next = p->next->next;
+	break;
+      }
+    /* and if we ran off the end? XXX */
+  }
 }
 
@@ -1252,4 +1258,6 @@
 
   if (!g_unichar_iscntrl(c) || c == '\n' || c== '\t' ) {
+    memset(tmp, 0, 7);
+
     if (c == '\n' && e->style == OWL_EDITWIN_STYLE_ONELINE) {
       return;
@@ -1294,5 +1302,5 @@
       return; /* our work here is done */
 
-    tmp[g_unichar_to_utf8(c, tmp)] = '\0';
+    g_unichar_to_utf8(c, tmp);
     owl_editwin_replace(e, 0, tmp);
   }
Index: fmtext.c
===================================================================
--- fmtext.c	(revision 6c171f190998142df485a1f93b4ef7bad5a8ea57)
+++ fmtext.c	(revision f119757ac31f8512736f47ad09423377daa09f80)
@@ -57,13 +57,19 @@
 
   /* Set attributes */
-  if (a)
-    strncat(f->textbuff, attrbuff,
-	    g_unichar_to_utf8(OWL_FMTEXT_UC_ATTR | attr, attrbuff));
-  if (fg)
-    strncat(f->textbuff, attrbuff,
-	    g_unichar_to_utf8(OWL_FMTEXT_UC_FGCOLOR | fgcolor, attrbuff));
-  if (bg)
-    strncat(f->textbuff, attrbuff,
-	    g_unichar_to_utf8(OWL_FMTEXT_UC_BGCOLOR | bgcolor, attrbuff));
+  if (a) {
+    memset(attrbuff,0,6);
+    g_unichar_to_utf8(OWL_FMTEXT_UC_ATTR | attr, attrbuff);
+    strcat(f->textbuff, attrbuff);      
+  }
+  if (fg) {
+    memset(attrbuff,0,6);
+    g_unichar_to_utf8(OWL_FMTEXT_UC_FGCOLOR | fgcolor, attrbuff);
+    strcat(f->textbuff, attrbuff);      
+  }
+  if (bg) {
+    memset(attrbuff,0,6);
+    g_unichar_to_utf8(OWL_FMTEXT_UC_BGCOLOR | bgcolor, attrbuff);
+    strcat(f->textbuff, attrbuff);      
+  }
   
   strcat(f->textbuff, text);
@@ -196,13 +202,19 @@
   _owl_fmtext_realloc(f, newlen);
 
-  if (a)
-    strncat(f->textbuff, attrbuff,
-	    g_unichar_to_utf8(OWL_FMTEXT_UC_ATTR | attr, attrbuff));
-  if (fg)
-    strncat(f->textbuff, attrbuff,
-	    g_unichar_to_utf8(OWL_FMTEXT_UC_FGCOLOR | fgcolor, attrbuff));
-  if (bg)
-    strncat(f->textbuff, attrbuff,
-	    g_unichar_to_utf8(OWL_FMTEXT_UC_BGCOLOR | bgcolor, attrbuff));
+  if (a) {
+    memset(attrbuff,0,6);
+    g_unichar_to_utf8(OWL_FMTEXT_UC_ATTR | attr, attrbuff);
+    strcat(f->textbuff, attrbuff);      
+  }
+  if (fg) {
+    memset(attrbuff,0,6);
+    g_unichar_to_utf8(OWL_FMTEXT_UC_FGCOLOR | fgcolor, attrbuff);
+    strcat(f->textbuff, attrbuff);      
+  }
+  if (bg) {
+    memset(attrbuff,0,6);
+    g_unichar_to_utf8(OWL_FMTEXT_UC_BGCOLOR | bgcolor, attrbuff);
+    strcat(f->textbuff, attrbuff);      
+  }
 
   strncat(f->textbuff, in->textbuff+start, stop-start+1);
@@ -303,8 +315,4 @@
 	int start, end;
 	while (owl_regex_compare(owl_global_get_search_re(&g), s, &start, &end) == 0) {
-	  /* Prevent an infinite loop matching the empty string. */
-	  if (end == 0)
-	    break;
-
 	  /* Found search string, highlight it. */
 
Index: functions.c
===================================================================
--- functions.c	(revision dca3b27c476353ad24df77afcfcd5fbf685e836d)
+++ functions.c	(revision 340c3e79617a8c1179a58118a0f7adbb87fc40d4)
@@ -1941,6 +1941,5 @@
 {
   owl_fmtext fm;
-  char *ptr;
-  char *result;
+  char *ptr, buff[LINE];
   int i;
 
@@ -1948,8 +1947,7 @@
 
   for (i=0; i<argc; i++) {
-    ptr = long_zuser(argv[i]);
-    result = owl_zephyr_zlocate(ptr, auth);
-    owl_fmtext_append_normal(&fm, result);
-    owl_free(result);
+    ptr=long_zuser(argv[i]);
+    owl_zephyr_zlocate(ptr, buff, auth);
+    owl_fmtext_append_normal(&fm, buff);
     owl_free(ptr);
   }
Index: perl/lib/BarnOwl.pm
===================================================================
--- perl/lib/BarnOwl.pm	(revision 77c87b2b8f0028eea432fb75a14183ed321f5f1c)
+++ perl/lib/BarnOwl.pm	(revision de3f6412cb0dc1b4e1044541558395c4c1fd807c)
@@ -435,13 +435,17 @@
 sub default_zephyr_signature
 {
-  my $zsig = getvar('zsig');
-  if (!$zsig && (my $zsigproc = getvar('zsigproc'))) {
-    $zsig = `$zsigproc`;
-  } elsif (!defined($zsig = get_zephyr_variable('zwrite-signature'))) {
-    $zsig = ((getpwuid($<))[6]);
-    $zsig =~ s/,.*//;
+  if (my $zsig = getvar('zsig')) {
+    return $zsig;
   }
-  chomp($zsig);
-  return $zsig;
+  if (my $zsigproc = getvar('zsigproc')) {
+    return `$zsigproc`;
+  }
+  my $zwrite_signature = get_zephyr_variable('zwrite-signature');
+  if (defined($zwrite_signature)) {
+    return $zwrite_signature;
+  }
+  my $name = ((getpwuid($<))[6]);
+  $name =~ s/,.*//;
+  return $name;
 }
 
Index: perl/modules/IRC/lib/BarnOwl/Module/IRC.pm
===================================================================
--- perl/modules/IRC/lib/BarnOwl/Module/IRC.pm	(revision 0c4a190dd56c6e2fcdf3a8fd077cade98620946d)
+++ perl/modules/IRC/lib/BarnOwl/Module/IRC.pm	(revision ecee82f6b16f57700264fae58d35a924920f1e8e)
@@ -399,8 +399,8 @@
     $body =~ tr/\n\r/  /;
     if ($body =~ /^\/me (.*)/) {
-        $conn->conn->me($to, Encode::encode('utf-8', $1));
+        $conn->conn->me($to, $1);
         $body = '* '.$conn->nick.' '.$1;
     } else {
-        $conn->conn->privmsg($to, Encode::encode('utf-8', $body));
+        $conn->conn->privmsg($to, $body);
     }
     my $msg = BarnOwl::Message->new(
Index: perl/modules/Jabber/lib/BarnOwl/Module/Jabber.pm
===================================================================
--- perl/modules/Jabber/lib/BarnOwl/Module/Jabber.pm	(revision 26cde205cd3bb7efbb854fcbb1984776650a4a7f)
+++ perl/modules/Jabber/lib/BarnOwl/Module/Jabber.pm	(revision 5118b3217a9478ce3deb0a9b7299f98b554fa075)
@@ -321,5 +321,5 @@
               . "add <jid>     Adds <jid> to your roster.\n\n"
               . "unsub <jid>   Unsubscribe from <jid>'s presence.\n\n"
-              . "remove <jid>  Removes <jid> from your roster. (implicit unsub)\n\n"
+              . "remove <jid>  Removes <jid> to your roster. (implicit unsub)\n\n"
               . "auth <jid>    Authorizes <jid> to subscribe to your presence.\n\n"
               . "deauth <jid>  De-authorizes <jid>'s subscription to your presence.\n\n"
Index: perl_tester.c
===================================================================
--- perl_tester.c	(revision 737b8f16912a0ac4905cb24609e3980fc2378717)
+++ perl_tester.c	(revision 42ad91716a0f429f02385235acffa71546e28caa)
@@ -32,5 +32,4 @@
   perl_free(my_perl);
   PERL_SYS_TERM();
-  return 0;
 }
 
Index: perlglue.xs
===================================================================
--- perlglue.xs	(revision 5791bf749e1cf8fcf653cee9840ad05eedd577ad)
+++ perlglue.xs	(revision 9e5b5fdef1dac8b4eeaeaf49810ab65f616de7c0)
@@ -9,6 +9,4 @@
 
 #define SV_IS_CODEREF(sv) (SvROK((sv)) && SvTYPE(SvRV((sv))) == SVt_PVCV)
-
-typedef char utf8;
 
 	/*************************************************************
@@ -31,5 +29,5 @@
 MODULE = BarnOwl		PACKAGE = BarnOwl
 
-const utf8 *
+const char *
 command(cmd, ...)
 	const char *cmd
@@ -79,5 +77,5 @@
 		RETVAL
 
-const utf8 *
+const char *
 zephyr_getrealm()
 	CODE:
@@ -86,5 +84,5 @@
 		RETVAL
 
-const utf8 *
+const char *
 zephyr_getsender()
 	CODE:
@@ -102,5 +100,5 @@
 		i = owl_zwrite_create_and_send_from_line(cmd, msg);
 
-const utf8 *
+const char *
 ztext_stylestrip(ztext)
 	const char *ztext
@@ -115,5 +113,5 @@
 		if (rv) owl_free(rv);
 
-const utf8 *
+const char *
 zephyr_smartstrip_user(in)
 	const char *in
@@ -130,5 +128,5 @@
 		owl_free(rv);
 
-const utf8 *
+const char *
 zephyr_getsubs()
 	PREINIT:
@@ -142,6 +140,5 @@
 		if (rv) owl_free(rv);
 
-void
-queue_message(msg)
+void queue_message(msg) 
 	SV *msg
 	PREINIT:
@@ -158,6 +155,5 @@
 	}
 
-void
-admin_message(header, body)
+void admin_message(header, body) 
 	const char *header
 	const char *body
@@ -167,6 +163,5 @@
 	}
 
-void
-start_question(line, callback)
+void start_question(line, callback)
 	const char *line
 	SV *callback
@@ -183,6 +178,5 @@
 	}
 
-void
-start_password(line, callback)
+void start_password(line, callback)
 	const char *line
 	SV *callback
@@ -199,6 +193,5 @@
 	}
 
-void
-start_edit_win(line, callback)
+void start_edit_win(line, callback)
 	const char *line
 	SV *callback
@@ -316,5 +309,5 @@
 	}
 
-const utf8 *
+const char *
 wordwrap(in, cols)
 	const char *in
@@ -328,6 +321,5 @@
 		RETVAL
 	CLEANUP:
-		if (rv)
-			owl_free(rv);
+		if (rv) owl_free(rv);
 
 void
@@ -432,5 +424,5 @@
 		RETVAL
 
-const utf8 *
+const char *
 skiptokens(str, n)
 	const char *str;
@@ -572,5 +564,5 @@
 		RETVAL
 
-const utf8 *
+const char *
 get_region()
 	PREINIT:
Index: unicode.t
===================================================================
--- t/unicode.t	(revision 09ff1eb7370de312e8c2eff74221cfb974dc1df7)
+++ 	(revision )
@@ -1,16 +1,0 @@
-#!/usr/bin/env perl
-use strict;
-use warnings;
-use utf8;
-use Encode;
-
-BEGIN { bootstrap BarnOwl; };
-
-use Test::More qw(no_plan);
-
-my $unicode = "“hello”";
-
-ok(Encode::is_utf8($unicode));
-ok(Encode::is_utf8(BarnOwl::wordwrap($unicode, 100)));
-
-is(BarnOwl::wordwrap($unicode, 100), $unicode);
Index: pemap
===================================================================
--- typemap	(revision 39e81f799239d76e4d42870e6aabcb35d6e2c059)
+++ 	(revision )
@@ -1,8 +1,0 @@
-TYPEMAP
-utf8 *         T_PV_UTF8
-const utf8 *   T_PV_UTF8
-
-OUTPUT
-T_PV_UTF8
-        sv_setpv((SV*)$arg, $var);
-        SvUTF8_on((SV*)$arg);
Index: zephyr.c
===================================================================
--- zephyr.c	(revision dca3b27c476353ad24df77afcfcd5fbf685e836d)
+++ zephyr.c	(revision c79a04782cf599c7fdc305dbe33acb4b8842c771)
@@ -911,5 +911,5 @@
 #endif
 
-char *owl_zephyr_zlocate(const char *user, int auth)
+void owl_zephyr_zlocate(const char *user, char *out, int auth)
 {
 #ifdef HAVE_LIBZEPHYR
@@ -918,32 +918,29 @@
   ZLocations_t locations;
   char *myuser;
-  char *p, *result;
-
+  
+  strcpy(out, "");
   ZResetAuthentication();
-  ret = ZLocateUser(zstr(user), &numlocs, auth ? ZAUTH : ZNOAUTH);
-  if (ret != ZERR_NONE)
-    return owl_sprintf("Error locating user %s: %s\n",
-		       user, error_message(ret));
-
-  myuser = short_zuser(user);
-  if (numlocs == 0) {
-    result = owl_sprintf("%s: Hidden or not logged in\n", myuser);
-  } else {
-    result = owl_strdup("");
-    for (; numlocs; numlocs--) {
-      ZGetLocations(&locations, &one);
-      p = owl_sprintf("%s%s: %s\t%s\t%s\n",
-			  result, myuser,
-			  locations.host ? locations.host : "?",
-			  locations.tty ? locations.tty : "?",
-			  locations.time ? locations.time : "?");
-      owl_free(result);
-      result = p;
-    }
-  }
-
-  return result;
-#else
-  return owl_strdup("");
+  ret=ZLocateUser(zstr(user),&numlocs,auth?ZAUTH:ZNOAUTH);
+  if (ret != ZERR_NONE) {
+    sprintf(out, "Error locating user %s\n", user);
+    return;
+  }
+
+  if (numlocs==0) {
+    myuser=short_zuser(user);
+    sprintf(out, "%s: Hidden or not logged in\n", myuser);
+    owl_free(myuser);
+    return;
+  }
+    
+  for (;numlocs;numlocs--) {
+    ZGetLocations(&locations,&one);
+    myuser=short_zuser(user);
+    sprintf(out + strlen(out), "%s: %s\t%s\t%s\n", myuser,
+	    locations.host ? locations.host : "?",
+	    locations.tty ? locations.tty : "?",
+	    locations.time ? locations.time : "?");
+    owl_free(myuser);
+  }
 #endif
 }
