Index: aim.c
===================================================================
--- aim.c	(revision c5873bee66a6dca24a9439b1a93ec6112e0cb9be)
+++ aim.c	(revision 5e5f08f3fcfd064d18df1008f09c00202a36ffdb)
@@ -7,4 +7,5 @@
 
 struct owlfaim_priv {
+  char *aimbinarypath;
   char *screenname;
   char *password;
@@ -64,4 +65,6 @@
 /* static int reportinterval(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs); */
 static int faimtest_parse_motd(aim_session_t *sess, aim_frame_t *fr, ...);
+static int getaimdata(aim_session_t *sess, unsigned char **bufret, int *buflenret, unsigned long offset, unsigned long len, const char *modname);
+static int faimtest_memrequest(aim_session_t *sess, aim_frame_t *fr, ...);
 /* static void printuserflags(fu16_t flags); */
 static int faimtest_parse_userinfo(aim_session_t *sess, aim_frame_t *fr, ...);
@@ -514,4 +517,6 @@
   va_end(ap);
 
+  owl_function_debugmsg("faimtest_parse_login: %s %s %s", priv->screenname, priv->password, key);
+
   aim_send_login(sess, fr->conn, priv->screenname, priv->password, &info, key);
   
@@ -630,4 +635,5 @@
   aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR,    faimtest_parse_connerr, 0);
   aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_RIGHTSINFO,         faimtest_locrights, 0);
+  aim_conn_addhandler(sess, bosconn, 0x0001,         0x001f,                        faimtest_memrequest, 0);
   aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_ONCOMING,           faimtest_parse_oncoming, 0);
   aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_OFFGOING,           faimtest_parse_offgoing, 0);
@@ -945,4 +951,166 @@
 
 /*
+ * This is a little more complicated than it looks.  The module
+ * name (proto, boscore, etc) may or may not be given.  If it is
+ * not given, then use aim.exe.  If it is given, put ".ocm" on the
+ * end of it.
+ *
+ * Now, if the offset or length requested would cause a read past
+ * the end of the file, then the request is considered invalid.  Invalid
+ * requests are processed specially.  The value hashed is the
+ * the request, put into little-endian (eight bytes: offset followed
+ * by length).  
+ *
+ * Additionally, if the request is valid, the length is mod 4096.  It is
+ * important that the length is checked for validity first before doing
+ * the mod.
+ *
+ * Note to Bosco's Brigade: if you'd like to break this, put the 
+ * module name on an invalid request.
+ *
+ */
+static int getaimdata(aim_session_t *sess, unsigned char **bufret, int *buflenret, unsigned long offset, unsigned long len, const char *modname)
+{
+  struct owlfaim_priv *priv = sess->aux_data;
+  FILE *f;
+  static const char defaultmod[] = "aim.exe";
+  char *filename = NULL;
+  struct stat st;
+  unsigned char *buf;
+  int invalid = 0;
+  
+  if (!bufret || !buflenret)
+    return -1;
+  
+  if (modname) {
+    filename = owl_sprintf("%s/%s.ocm", priv->aimbinarypath, modname);
+  } else {
+    filename = owl_sprintf("%s/%s", priv->aimbinarypath, defaultmod);
+  }
+  
+  if (stat(filename, &st) == -1) {
+    if (!modname) {
+      /* perror("memrequest: stat"); */
+      owl_free(filename);
+      return -1;
+    }
+    invalid = 1;
+  }
+  
+  if (!invalid) {
+    if ((offset > st.st_size) || (len > st.st_size))
+      invalid = 1;
+    else if ((st.st_size - offset) < len)
+      len = st.st_size - offset;
+    else if ((st.st_size - len) < len)
+      len = st.st_size - len;
+  }
+  
+  if (!invalid && len) {
+    len %= 4096;
+  }
+  
+  if (invalid) {
+    int i;
+    
+    owl_free(filename); /* not needed */
+    owl_function_error("getaimdata memrequest: recieved invalid request for 0x%08lx bytes at 0x%08lx (file %s)\n", len, offset, modname);
+    i = 8;
+    if (modname) {
+      i+=strlen(modname);
+    }
+    
+    if (!(buf = owl_malloc(i))) {
+      return -1;
+    }
+    
+    i=0;
+    
+    if (modname) {
+      memcpy(buf, modname, strlen(modname));
+      i+=strlen(modname);
+    }
+    
+    /* Damn endianness. This must be little (LSB first) endian. */
+    buf[i++] = offset & 0xff;
+    buf[i++] = (offset >> 8) & 0xff;
+    buf[i++] = (offset >> 16) & 0xff;
+    buf[i++] = (offset >> 24) & 0xff;
+    buf[i++] = len & 0xff;
+    buf[i++] = (len >> 8) & 0xff;
+    buf[i++] = (len >> 16) & 0xff;
+    buf[i++] = (len >> 24) & 0xff;
+    
+    *bufret = buf;
+    *buflenret = i;
+  } else {
+    if (!(buf = owl_malloc(len))) {
+      owl_free(filename);
+      return -1;
+    }
+    /* printf("memrequest: loading %ld bytes from 0x%08lx in \"%s\"...\n", len, offset, filename); */
+    if (!(f = fopen(filename, "r"))) {
+      /* perror("memrequest: fopen"); */
+      owl_free(filename);
+      owl_free(buf);
+      return -1;
+    }
+    
+    owl_free(filename);
+    
+    if (fseek(f, offset, SEEK_SET) == -1) {
+      /* perror("memrequest: fseek"); */
+      fclose(f);
+      owl_free(buf);
+      return -1;
+    }
+    
+    if (fread(buf, len, 1, f) != 1) {
+      /* perror("memrequest: fread"); */
+      fclose(f);
+      owl_free(buf);
+      return -1;
+    }
+    
+    fclose(f);
+    *bufret = buf;
+    *buflenret = len;
+  }
+  return 0; /* success! */
+}
+
+/*
+ * This will get an offset and a length.  The client should read this
+ * data out of whatever AIM.EXE binary the user has provided (hopefully
+ * it matches the client information thats sent at login) and pass a
+ * buffer back to libfaim so it can hash the data and send it to AOL for
+ * inspection by the client police.
+ */
+static int faimtest_memrequest(aim_session_t *sess, aim_frame_t *fr, ...)
+{
+  struct owlfaim_priv *priv = sess->aux_data;
+  va_list ap;
+  fu32_t offset, len;
+  const char *modname;
+  unsigned char *buf;
+  int buflen;
+  
+  va_start(ap, fr);
+  offset = va_arg(ap, fu32_t);
+  len = va_arg(ap, fu32_t);
+  modname = va_arg(ap, const char *);
+  va_end(ap);
+  
+  if (priv->aimbinarypath && (getaimdata(sess, &buf, &buflen, offset, len, modname) == 0)) {
+    aim_sendmemblock(sess, fr->conn, offset, buflen, buf, AIM_SENDMEMBLOCK_FLAG_ISREQUEST);
+    owl_free(buf);
+  } else {
+    owl_function_debugmsg("faimtest_memrequest: unable to use AIM binary (\"%s/%s\"), sending defaults...\n", priv->aimbinarypath, modname);
+    aim_sendmemblock(sess, fr->conn, offset, len, NULL, AIM_SENDMEMBLOCK_FLAG_ISREQUEST);
+  }
+  return 1;
+}
+
+/*
 static void printuserflags(fu16_t flags)
 {
Index: functions.c
===================================================================
--- functions.c	(revision d12a8c71f5d91653b1bffd9fa566448eb52b5d43)
+++ functions.c	(revision 8bba1aed9c99b38e86fab76c25d3b415be31afdb)
@@ -1177,5 +1177,5 @@
     return;
 
-  file = owl_global_get_debug_file_handle(&g);
+  file = fopen(owl_global_get_debug_file(&g), "a");
   if (!file) /* XXX should report this */
     return;
@@ -1187,5 +1187,5 @@
   vfprintf(file, fmt, ap);
   putc('\n', file);
-  fflush(file);
+  fclose(file);
 
   va_end(ap);
Index: global.c
===================================================================
--- global.c	(revision 26ad412433e18b39230531a2a518a03bffc1d3d4)
+++ global.c	(revision 8bba1aed9c99b38e86fab76c25d3b415be31afdb)
@@ -983,28 +983,2 @@
                                                        filters[i].desc));
 }
-
-FILE *owl_global_get_debug_file_handle(owl_global *g) {
-  static char *open_file = NULL;
-  const char *filename = owl_global_get_debug_file(g);
-  if (g->debug_file == NULL ||
-      (open_file && strcmp(filename, open_file) != 0)) {
-    char *path;
-    int fd;
-
-    if (g->debug_file)
-      fclose(g->debug_file);
-
-    g->debug_file = NULL;
-
-    path = owl_sprintf("%s.%d", filename, getpid());
-    fd = open(path, O_CREAT|O_WRONLY|O_EXCL, 0600);
-    owl_free(path);
-
-    if (fd >= 0)
-      g->debug_file = fdopen(fd, "a");
-
-    owl_free(open_file);
-    open_file = owl_strdup(filename);
-  }
-  return g->debug_file;
-}
Index: owl.c
===================================================================
--- owl.c	(revision 205e1645be4619c39f0963639fd7bfb7b0ec5195)
+++ owl.c	(revision 205e1645be4619c39f0963639fd7bfb7b0ec5195)
@@ -457,4 +457,6 @@
   g.load_initial_subs = opts.load_initial_subs;
 
+  owl_function_debugmsg("startup: Finished parsing arguments");
+
   owl_register_signal_handlers();
   owl_start_curses();
Index: owl.h
===================================================================
--- owl.h	(revision 26ad412433e18b39230531a2a518a03bffc1d3d4)
+++ owl.h	(revision 987cf3f48057443b84ecf140854129cf1a6cbbdc)
@@ -76,5 +76,5 @@
 
 #define OWL_DEBUG 0
-#define OWL_DEBUG_FILE "/var/tmp/barnowl-debug"
+#define OWL_DEBUG_FILE "/var/tmp/owldebug"
 
 #define OWL_CONFIG_DIR "/.owl"             /* this is relative to the user's home directory */
@@ -643,5 +643,4 @@
   int load_initial_subs;
   volatile sig_atomic_t interrupted;
-  FILE *debug_file;
 } owl_global;
 
Index: variable.c
===================================================================
--- variable.c	(revision 26ad412433e18b39230531a2a518a03bffc1d3d4)
+++ variable.c	(revision f6fae8d526ff0525c526bc767e88c386fde4f41b)
@@ -186,6 +186,5 @@
   OWLVAR_PATH( "debug_file" /* %OwlVarStub */, OWL_DEBUG_FILE,
 	       "path for logging debug messages when debugging is enabled",
-	       "This file will be logged to if 'debug' is set to 'on'.\n"
-               "BarnOwl will append a dot and the current process's pid to the filename."),
+	       "This file will be logged to if 'debug' is set to 'on'.\n"),
   
   OWLVAR_PATH( "zsigproc" /* %OwlVarStub:zsigproc */, NULL,
Index: zephyr.c
===================================================================
--- zephyr.c	(revision 8ab1f2801e62b0ef27d25c62c5b64ee194ad3f15)
+++ zephyr.c	(revision 987cf3f48057443b84ecf140854129cf1a6cbbdc)
@@ -179,13 +179,6 @@
 {
 #ifdef HAVE_LIBZEPHYR
-  Code_t code;
-  if(owl_global_is_havezephyr(&g)) {
-    if((code = ZPending()) < 0) {
-      owl_function_debugmsg("Error (%s) in ZPending()\n",
-                            error_message(code));
-      return 0;
-    }
-    return code;
-  }
+  if(owl_global_is_havezephyr(&g))
+    return(ZPending());
 #endif
   return 0;
@@ -1404,14 +1397,9 @@
 #ifdef HAVE_LIBZEPHYR
   ZNotice_t notice;
-  Code_t code;
   owl_message *m=NULL;
 
   while(owl_zephyr_zpending() && zpendcount < OWL_MAX_ZEPHYRGRAMS_TO_PROCESS) {
     if (owl_zephyr_zpending()) {
-      if ((code = ZReceiveNotice(&notice, NULL)) != ZERR_NONE) {
-        owl_function_debugmsg("Error: %s while calling ZReceiveNotice\n",
-                              error_message(code));
-        continue;
-      }
+      ZReceiveNotice(&notice, NULL);
       zpendcount++;
 
