Description: Autogenerated patch header for a single-debian-patch file.
 The delta against upstream is either kept as a single patch, or maintained
 in some VCS, and exported as a single patch instead of more manageable
 atomic patches.
Forwarded: not-needed

---
--- xlassie-1.8.orig/Makefile
+++ xlassie-1.8/Makefile
@@ -1,21 +1,29 @@
-LIBS = -L/usr/X11R6/lib -lXext -lX11
-CFLAGS = -O2 -fomit-frame-pointer -pipe -Wall
-#CFLAGS = -g -pipe
+CC ?= gcc
+CFLAGS ?= -O2 -g -Wall
+LOADLIBES ?= -lXext -lX11 -lXt
+LDFLAGS ?= -L/usr/X11R6/lib
+
+prefix?=/usr/local
+mandir?=$(prefix)/share/man
+bindir?=$(prefix)/bin
+
+INSTALL ?= install
+INSTALL_PROGRAM ?= $(INSTALL) --mode a+rx,ug+w
+INSTALL_DIR ?= mkdir --parent
 
 # Use this for solaris
-#LIBS = -L/usr/openwin/lib -lsocket -lnsl -lresolv -lXext -lX11
 #CFLAGS = -O2 -pipe -Wall
+#LOADLIBES = -lsocket -lnsl -lresolv -lXext -lX11
+#LDFLAGS = -L/usr/openwin/lib
 
 all: xlassie
 
 xlassie: xlassie.o socket.o
-	gcc $(CFLAGS) -o xlassie xlassie.o socket.o $(LIBS)
+xlassie.o: defaults.h
+socket.o: defaults.h
 
-xlassie.o: xlassie.c defaults.h
-	gcc $(CFLAGS) -c xlassie.c
-
-socket.o: socket.c defaults.h
-	gcc $(CFLAGS) -c socket.c
+xlassie.1x: xlassie xlassie.h2m
+	help2man --include xlassie.h2m --section=1x --no-info --output xlassie.1x ./xlassie
 
 dist: clean
 	@(dir=`pwd`; name=`basename $$dir`; \
@@ -23,4 +31,15 @@ dist: clean
 	cd .. ; tar -zcf $$name/$$name.tar.gz --exclude $$name/$$name.tar.gz $$name )
 
 clean:
-	-rm -f *.o xlassie
+	-rm -f *.o xlassie xlassie.1x
+
+install: xlassie xlassie.1x
+	$(INSTALL_DIR) $(DESTDIR)$(bindir)
+	$(INSTALL_PROGRAM) xlassie $(DESTDIR)$(bindir)/
+	$(INSTALL_DIR) $(DESTDIR)$(mandir)/man1
+	$(INSTALL) xlassie.1x $(DESTDIR)$(mandir)/man1/
+
+install-strip:
+	$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) --strip' install
+
+.PHONY: all clean dist install
--- xlassie-1.8.orig/README
+++ xlassie-1.8/README
@@ -52,15 +52,15 @@ dock the window in the panel.
 
     --------------------------------------------------------------
 
-	-command
+	-clickcommand
 
 Lets you specify a command to be executed when the window is clicked on.  The
 default command is specified in defaults.h.  You should inclose the command in
 quotes if it's longer than one word.  You will also probably want to stick an
 & on the end so the command runs in the background.  Example usage:
 
-xlassie -command "xterm -e pine &"
-xlassie -command "fetchpop -r &"
+xlassie -clickcommand "xterm -e pine &"
+xlassie -clickcommand "fetchpop -r &"
 
     --------------------------------------------------------------
 
--- xlassie-1.8.orig/defaults.h
+++ xlassie-1.8/defaults.h
@@ -12,7 +12,7 @@
  * argument will be overwritten so it doesn't show up in a "ps".  Even if you
  * compile in POP3 support, it is still possible to use a local mail spool. */
 
-#define POP3
+#define HAVE_POP3
 
 /****************************************************************************/
 
@@ -26,8 +26,8 @@
 /* Interval between checks for new mail, the default is 5 seconds for a local
  * file and 60 seconds for a POP3 server */
 
-#define INTERVAL_POP3	60   /* POP3 default */
-#define INTERVAL_SPOOL	5	/* Spool file default */
+#define INTERVAL_SPOOL	"5"	/* Spool file default */
+#define INTERVAL_REMOTE	"60"	/* POP3 default */
 
 /****************************************************************************/
 
@@ -37,7 +37,7 @@
  * completes. */
 
 /* run pine in an xterm */
-#define COMMAND	"rxvt +sb -T pine -e pine &"
+/* #define COMMAND	"rxvt +sb -T pine -e pine &" */
 
 /* start kmail */
 /* #define COMMAND "kmail &" */
@@ -48,22 +48,28 @@
 /* fetch pop mail, then run pine */
 /* #define COMMAND "(fetchpop -r ; rxvt -e pine) &" */
 
+/* Don't actually fetch mail, just check mailbox count */
+#define COMMAND "CHECK_MAILBOX"
+
 /****************************************************************************/
 
-/* Default font for the display.  You can use xfontsel to try and find some
- * nice fonts on your system.  I would suggest using a scalable font. */
+/* Default font for the display.  You can use xfontsel or gfontview to try and
+ * find some nice font on your system.  I would suggest a scalable font. */
 
 /* Some people don't have the utopia font, but they should, it's one of the
- * standard fonts that come with X. */
+ * standard fonts that come with ghostscript.   If desperate just use a wildcard.  */
 #define FONTNAME "-*-utopia-medium-r-normal--40-*-*-*-*-*-iso8859-1"
 #define KDEFONT	 "-*-utopia-medium-r-normal--25-*-*-*-*-*-iso8859-1"
 #define WMFONT   "-*-utopia-medium-r-normal--56-*-*-*-*-*-iso8859-1"
 
-
-/* These fonts will get used as back ups, in case the first font doesn't work. 
+/* These fonts will get used as back ups, in case the first font doesn't work.
  * They will just be tried in order, and if none of them are found, then
  * xlassie will fail to run.  */
 
+#define FONTNAME0 "-*-helvetica-medium-r-normal--40-*-*-*-*-*-iso8859-1"
+#define KDEFONT0  "-*-helvetica-medium-r-normal--25-*-*-*-*-*-iso8859-1"
+#define WMFONT0   "-*-helvetica-medium-r-normal--56-*-*-*-*-*-iso8859-1"
+
 /* The URW helvetica scalable font, common with Linux distros as the part of
  * the urw-fonts or ghostscript-fonts packages */
 #define FONTNAME1 "-urw-helvetica-medium-r-normal--40-*-*-*-*-*-iso8859-1"
@@ -80,4 +86,7 @@
 #define KDEFONT3  "-adobe-times-medium-r-normal--25-*-*-*-*-*-iso8859-1"
 #define WMFONT3   "-adobe-times-medium-r-normal--34-*-*-*-*-*-iso8859-1"
 
-/****************************************************************************/
+/* This should work! */
+#define FONTNAME4	"-*-*-medium-r-normal--40-*-*-*-*-*-iso8859-1"
+#define KDEFONT4	"-*-*-medium-r-normal--25-*-*-*-*-*-iso8859-1"
+#define WMFONT4		"-*-*-medium-r-normal--56-*-*-*-*-*-iso8859-1"
--- xlassie-1.8.orig/socket.c
+++ xlassie-1.8/socket.c
@@ -25,7 +25,7 @@
 #include "defaults.h"
 
 
-#ifdef POP3
+#ifdef HAVE_POP3
 
 int sock_connect(char *hostname,int port)
 {
@@ -58,3 +58,7 @@ int sock_connect(char *hostname,int port
 }
 
 #endif
+
+// Local Variables:
+//  tab-width: 4
+// End:
--- xlassie-1.8.orig/todo
+++ xlassie-1.8/todo
@@ -1,4 +1,2 @@
-1. write man page
-2. use X resources
-3. #ifdef shape stuff
-4. use gnome dock app protocol
+1. #ifdef shape stuff
+2. use gnome dock app protocol
--- xlassie-1.8.orig/xlassie.c
+++ xlassie-1.8/xlassie.c
@@ -1,5 +1,7 @@
 /* Copyright (C) 1998 Trent Piepho  <xyzzy@u.washington.edu>
  *           (C) 1999-2001 Trent Piepho  <xyzzy@speakeasy.org>
+ *   Updates (C) 2004 Barak A. Pearlmutter <barak@cs.nuim.ie>
+ *                    Nadim Shaikli <nadim@arabeyes.org>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -14,851 +16,1256 @@
  * with this program; if not, write to the Free Software Foundation, Inc., 675
  * Mass Ave, Cambridge, MA 02139, USA.  */
 
+#define _GNU_SOURCE
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <getopt.h>
 #include <dirent.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <signal.h>
 #include <time.h>
 #include <pwd.h>
+#include <stdarg.h>
 #include <errno.h>
+#include <termios.h>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 #include <X11/Xos.h>
 #include <X11/Xatom.h>
+#include <X11/keysym.h>
 #include <X11/extensions/shape.h>
+
 #include "defaults.h"
 
-#define VERSION "1.8"
+#define VERSION         "1.8"
+#define APL_CLASS       "XBiff"		/* class name to check as well */
+#define APL_SUBCLASS    "xlassie"	/* application class name */
 
 /* X related globals */
 Display *dpy;
 Window win;
 GC gc;
-XFontStruct *font;
+XFontStruct *font = 0;
 int Ascent=33,Descent=0;
 int Width=55,Height=33;
 XColor FgXColor,HiXColor;
 Pixmap ShapeMask;			/* shape stuff */
-GC ShapeGC;					/* shape stuff */
-int MaskWidth,MaskHeight;	/* shape stuff */
+GC ShapeGC;				/* shape stuff */
+int MaskWidth,MaskHeight;		/* shape stuff */
 Atom DeleteWindow;			/* Atom of delete window message */
 Atom KWMDockWindow;			/* Atom for KWM hint */
 
 /* app-default related globals */
-char *FgColor="Black",*BgColor="White",*HiColor="Red";
-char *FontName=NULL;
-char *DisplayName=NULL;
-char *AppName;
+char *DisplayName = NULL;
+int Options = 0;
 int Number;
-int Interval=INTERVAL_SPOOL;
-char SpoolFile[256];
-char Command[256];
-char Username[32];
-char Password[32];
-char NewMailCommand[256];
-char *Geometry=NULL;
-int Options=0;
-#define BELL_MODE		0x0001
-#define COMMAND_MODE	0x0002
-#define SHAPED_WINDOW	0x0004
-#define HILIGHT_MAIL	0x0008
-#define OFFLINE			0x0010
-#define USE_POP3		0x0020
-#define USE_APOP3		0x0040
-#define USE_IMAP		0x0080
-#define USE_MAILDIR		0x0100
-#define WM_MODE			0x0200
-#define KDE1_MODE		0x0400
-#define KDE2_MODE		0x0800
-#define NOKDE			0x1000
-#define	NOWM			0x2000
-
-char *BackupFonts[3][4] = {{ FONTNAME, FONTNAME1, FONTNAME2, FONTNAME3 }, 
-						   { KDEFONT, KDEFONT1, KDEFONT2, KDEFONT3 },
-						   { WMFONT, WMFONT1, WMFONT2, WMFONT3 } };
+int Count_offset = 0;
+
+char *BackupFonts[][7] = {
+  { FONTNAME, FONTNAME0, FONTNAME1, FONTNAME2, FONTNAME3, FONTNAME4, 0 },
+  { KDEFONT, KDEFONT0, KDEFONT1, KDEFONT2, KDEFONT3, KDEFONT4, 0 },
+  { WMFONT, WMFONT0, WMFONT1, WMFONT2, WMFONT3, WMFONT4, 0 }};
 
 void usage();
+void close_display();
+void update_led(int toggle);
 void update();
 void handler(int);
-void parse_options(int argc,char *argv[]);
+void parse_cmdline(int argc,char *argv[]);
 void init(int argc,char *argv[]);
 int count_mail();
-int count_mail_mbox();
 
-void update()
+/* Local sub-options */
+#define VERBOSE         (1<<0)
+#define USE_MAILDIR     (1<<1)
+#define KDE2_MODE       (1<<2)
+
+/* List out all the various options used */
+/* This enumerated list and the array of stuctures 'optList' __MUST__
+ * always be in sycn and must have a one-to-one correspondance.
+ */
+enum optOptions
+  {
+    NAME,
+    BACKGROUND,
+    FOREGROUND,
+    HIGHLIGHT,
+    UPDATE,
+    BELL,
+    LED,
+    FONT,
+    GEOMETRY,
+    SHAPE,
+    SPOOL,
+    MAILCOMMAND,
+    CLICKCOMMAND,
+    POP3,
+    APOP3,
+    IMAP,
+    FOLDERNAME,
+    USERNAME,
+    PASSWORD,
+    OFFLINE,
+    WMAKER,
+    KDE,
+    NOKDE,
+    NOWMAKER
+  };
+
+typedef struct
 {
-	static int old_number=-1;
-	char str[32];
-	static int oldw=-1,oldh=-1;
-	int w,h;
-
-	if(Options&OFFLINE && Number==-1)  {
-		strcpy(str,"X");
-	} else {
-		sprintf(str,"%d",Number);
-	}
+  const char        *label;         /* label/long name */
+  const char        *name;          /* alternate/short name */
+  const int         isBool;         /* entry is a boolean function */
+  int               isSet;          /* indicate if set */
+  char              *value;         /* specified value/setting */
+} optStruct;
+
+// This array and 'optOptions' __MUST__ always be in sync
+optStruct optList[] =
+  {
+    {"name", "name",			False,	False, APL_SUBCLASS},
+    {"background", "bg",		False,	False, "White"},
+    {"foreground", "fg",		False,	False, "Black"},
+    {"highlight", "hilight",		False,	False, "Red"},
+    {"update", "update",		False,	False, INTERVAL_SPOOL},
+    {"bell", "bell",			True,	False, NULL},
+    {"led", "led",			False,	False, "1"},
+    {"font", "fn",			False,	False, NULL},
+    {"geometry", "geometry",		False,	False, NULL},
+    {"shape", "shape",			True,	False, NULL},
+    {"spool", "spool",			False,	False, ""},
+    {"mailcommand", "mailcmd",		False,	False, ""},
+    {"clickcommand", "clickcmd",	False,	False, COMMAND},
+    {"pop3", "pop3",			False,	False, INTERVAL_SPOOL},
+    {"apop3", "apop3",			False,	False, INTERVAL_SPOOL},
+    {"imap", "imap",			False,	False, INTERVAL_SPOOL},
+    {"imapfolder", "imapfolder",	False,	False, "INBOX"},
+    {"username", "username",		False,	False, NULL},
+    {"password", "password",		False,	False, ""},
+    {"offline", "offline",		True,	False, NULL},
+    {"wmaker", "wmaker",		True,	False, NULL},
+    {"kde", "kde",			True,	False, NULL},
+    {"nokde", "nokde",			True,	False, NULL},
+    {"nowmaker", "nowmaker",		True,	False, NULL},
+  };
+
+
+/* ---------- *
+ * -* Code *- *
+ * ---------- */
+
+void verbose(char *fmt, ...)
+{
+  va_list ap;
+  if (! (Options&VERBOSE)) return;
+  va_start(ap, fmt);
+  vfprintf(stderr, fmt, ap);
+  va_end(ap);
+  fprintf(stderr, "\n");
+  fflush(stderr);
+}
 
-	w = (Width-XTextWidth(font,str,strlen(str)))/2;
-	h = (Height+Ascent-Descent)/2;
+/*
+ * Grab the .Xdefault resources (if any) for this application
+ */
+void parse_xdefaults(Display *display, const char *app_name)
+{
+  int	entry;
 
-	if(Options&SHAPED_WINDOW)  {
-		if(Number!=old_number || oldw!=w || oldh!=h)  {
-			old_number=Number; oldw=w; oldh=h;
-			/* these next 3 lines clear the pixmap, is there a cleaner way? */
-			XSetFunction(dpy,ShapeGC,GXclear);
-			XFillRectangle(dpy,ShapeMask,ShapeGC,0,0,MaskWidth,MaskHeight);
-			XSetFunction(dpy,ShapeGC,GXset);
-			XDrawString(dpy,ShapeMask,ShapeGC,0,Ascent,str,strlen(str));
-			XShapeCombineMask(dpy, win, ShapeBounding, 
-				w, h-Ascent, ShapeMask, ShapeSet);
-		};
-	} else {
-		XClearWindow(dpy,win);
+  for (entry = 0; entry < (sizeof(optList) / sizeof(optList[0])); entry++)
+    {
+      char		*def1, *def2;
+      const char	*e_label	= optList[entry].label;
+      const char	*e_name		= optList[entry].name;
+
+      /* previously set somehow - sanity check */
+      if (e_label == NULL || optList[entry].isSet != False)
+	{
+	  verbose("Xdefaults - (%2d) = %s [externally set] = %s",
+		  entry, optList[entry].label, optList[entry].value);
+	  continue;
 	}
 
-	if(Options&HILIGHT_MAIL)  {
-		XSetForeground(dpy,gc,Number?HiXColor.pixel:FgXColor.pixel);
+      /* Get both long and short name settings */
+      def1 = XGetDefault(display, app_name, e_label);
+      def2 = XGetDefault(display, app_name, e_name);
+
+      if ((def1 == NULL) && (def2 == NULL))
+	{
+	  def1 = XGetDefault(display, APL_SUBCLASS, e_label);
+	  def2 = XGetDefault(display, APL_SUBCLASS, e_name);
+	  if ((def1 == NULL) && (def2 == NULL))
+	    {
+	      def1 = XGetDefault(display, APL_CLASS, e_label);
+	      def2 = XGetDefault(display, APL_CLASS, e_name);
+	    }
 	}
 
-	XDrawString(dpy,win,gc,w,h,str,strlen(str));
+      /* Short name settings are OK */
+      if ((def1 == NULL) && def2)
+	def1 = def2;
+
+      /* Set the ultimate value to use */
+      if (def1)
+	{
+	  if (optList[entry].isBool)
+	    {
+	      if ((strcasecmp(def1, "TRUE") == 0)	||
+		  (strcasecmp(def1, "YES") == 0)	||
+		  (strcasecmp(def1, "ON") == 0)	||
+		  (strcasecmp(def1, "1") == 0))
+		{
+		  optList[entry].isSet = 1;
+		  optList[entry].value = "1";
+		}
+	      else
+		{
+		  optList[entry].isSet = 0;
+		  optList[entry].value = "0";
+		}
+	    }
+	  else
+	    {
+	      optList[entry].isSet = 1;
+	      optList[entry].value = def1;
+	    }
+	}
+      /* Optionally note what was read from the .Xdefaults file */
+      verbose("Xdefaults - (%2d) - %s = %s",
+	      entry, optList[entry].label, optList[entry].value);
+    }
 }
 
-void handler(int nothing)
+/*
+ * Do some clean-up prior to closing display
+ */
+void close_display()
 {
-	int old;
-
-	old = Number;
-	count_mail();
-	if(old==Number) return;
-	update();
-	if(Number>old)  {
-		if(Options&BELL_MODE)  XBell(dpy,100);
-		if(Options&COMMAND_MODE) {
-			char str[256];
-			sprintf(str, NewMailCommand, Number);
-			system(str);
-		}
-	}
-	XFlush(dpy);
+  verbose("Setting LED to OFF");
+  update_led(False);
+  XCloseDisplay(dpy);
 }
 
-void font_height(void)
+/*
+ * Toggle specified LED based on availability of email
+ * unless instructed to turn it off verbosely
+ */
+void update_led (int toggle)
 {
-	int foo,bar,baz;
-	XCharStruct extents;
+  XKeyboardControl control;
+  verbose("Updating LED: %d", toggle);
 
-	XTextExtents(font,"0123456789",10,&foo,&bar,&baz,&extents);
-	Ascent=extents.ascent;
-	Descent=extents.descent;
+  /* At most 32 LEDs numbered from one are supported.  No standard
+     interpretation of LEDs is defined or specified anywhere.
+  */
+  control.led = atoi(optList[LED].value);
+  if ((Number > 0) && toggle)
+    control.led_mode = LedModeOn;
+  else
+    control.led_mode = LedModeOff;
+  XChangeKeyboardControl(dpy, KBLed | KBLedMode, &control);
 }
 
-void usage(void)
+// Calculate log base 10 of an integer, rounded down
+int ilog10(unsigned int x)
 {
-	printf("XLassie V" VERSION "\tby Trent Piepho <xyzzy@speakeasy.org>\n");
-	printf("\thttp://www.speakeasy.org/~xyzzy/xlassie/\n");
-	printf("Usage: xlassie [-h] | [-options]\n");
-	printf("where options include:\n");
-	printf("    -h,  -help              Print usage\n");
-	printf("    -v,  -version           Print version\n");
-	printf("    -name <name>            Set app name\n");
-	printf("    -bg <color>             Background color [%s]\n",BgColor);
-	printf("    -fg <color>             Foreground color [%s]\n",FgColor);
-	printf("    -hilight [color]        Use a different foreground color when there\n"
-		   "                                is non-zero mail [%s]\n", HiColor);
-	printf("    -update <number>        Check mail every <number> seconds\n"
-	       "                                default %d sec local, %d sec remote\n", INTERVAL_SPOOL, INTERVAL_POP3);
-	printf("    -bell                   Ring bell when count increases from zero\n");
-	printf("    -mailcommand <command>  Command to execute on new mail arrival\n");
-	printf("    -fn <fontname>          Font for the new mail count\n");
-	printf("    -display <displayname>  X server to connect to\n");
-	printf("    -shape                  Use a shaped window\n");
-	printf("    -file <filename>        File to use for mail spool or maildir directory\n");
-	printf("    -command <command>      Command to execute when clicked on\n");
-#ifdef POP3
-	printf("    -pop3 <server>          Connect to pop3 server rather than local mail spool\n");
-	printf("    -apop3 <server>         Like -pop3, but uses a diferent method.\n");
-	printf("                                Use when -pop3 doesn't find the correct number\n");
-	printf("    -imap <server>          Use the IMAP protocol instead of pop3\n");
-	printf("    -username <name>        Username for pop3/imap server\n"
-		   "                                if different from local username\n");
-	printf("    -password <word>        Password to use on pop3/imap server\n");
-	printf("                                Use the password 'ask' to get prompted for\n"
-		   "                                the password on stdin.\n");
-	printf("    -offline                Don't exit when the server is unreachable\n");
-#endif
-	printf("    -wmaker                 Do stuff to get swallowed into the WindowMaker dock\n");
-	printf("    -kde                    Do stuff to get swallowed into the KDE dock\n");
-	printf("                                Normally KDE or WindowMaker is autodetected\n"
-		   "                                and you don't need to use the above options\n");
-	printf("    -nokde, -nowmaker       Don't do the stuff to get swallowed\n");
+  int i;
+  if (x==0) return -1;
+  for (i=0; x>9; x/=10, i+=1)
+    ;
+  return i;
 }
 
-void ask_password()
+void update()
 {
-	int i;
+  static int old_number=-1;
+  char str[32];
+  static int oldw=-1,oldh=-1;
+  int w,h;
+
+  verbose("updating window");
+
+  if(optList[OFFLINE].isSet && Number==-1)  {
+    strcpy(str,"X");
+  } else {
+    int number = Number+Count_offset;
+    // Since the code doesn't resize the count properly, email
+    // counts with more than 99 messages results in weird looking
+    // displays.  A short-term solution (this should be fixed by
+    // properly resizing the total message count to fit in the
+    // area proscribed) is just to give a Full indicator.
+    if (number > 99) {
+      // Use "e2" for 100-999, ie numbers of the form d.ddde2, etc.
+      // We make no provisions for an inbox with over 10^10 messages.
+      verbose("count %d exceeds two digits", number);
+      sprintf(str,"e%d",ilog10(number));
+    } else {
+      sprintf(str,"%d",number);
+    }
+  }
+
+  w = (Width-XTextWidth(font,str,strlen(str)))/2;
+  h = (Height+Ascent-Descent)/2;
+
+  if(optList[SHAPE].isSet) {
+    if(Number!=old_number || oldw!=w || oldh!=h)  {
+      old_number=Number; oldw=w; oldh=h;
+      /* these next 3 lines clear the pixmap, is there a cleaner way? */
+      XSetFunction(dpy,ShapeGC,GXclear);
+      XFillRectangle(dpy,ShapeMask,ShapeGC,0,0,MaskWidth,MaskHeight);
+      XSetFunction(dpy,ShapeGC,GXset);
+      XDrawString(dpy,ShapeMask,ShapeGC,0,Ascent,str,strlen(str));
+      XShapeCombineMask(dpy, win, ShapeBounding,
+			w, h-Ascent, ShapeMask, ShapeSet);
+    };
+  } else {
+    XClearWindow(dpy,win);
+  }
+
+  if(optList[HIGHLIGHT].isSet) {
+    XSetForeground(dpy, gc,
+		   (Number+Count_offset) ? HiXColor.pixel : FgXColor.pixel);
+  }
 
-	printf("Mail account password: ");
-	fgets(Password, 32, stdin);
-	i = strlen(Password)-1;
-	if(Password[i]=='\n') Password[i]='\0';
-}
-
-void parse_options(int argc,char *argv[])
-{
-	int i;
-	int intervalused=0;
-
-	for(i=1;i<argc;i++)  {
-		if(!strcmp(argv[i],"-fg"))  {
-			if(++i==argc)  { usage(); exit(2); };
-			FgColor=argv[i];
-		} else if(!strcmp(argv[i],"-bg"))  {
-			if(++i==argc)  { usage(); exit(2); };
-			BgColor=argv[i];
-		} else if(!strcmp(argv[i],"-update"))  {
-			if(++i==argc)  { usage(); exit(2); };
-			Interval=atoi(argv[i]);
-			intervalused=1;
-		} else if(!strcmp(argv[i],"-bell"))  {
-			Options|=BELL_MODE;
-		} else if(!strcmp(argv[i],"-shape"))  {
-			Options|=SHAPED_WINDOW;
-		} else if(!strcmp(argv[i],"-fn") || !strcmp(argv[i],"-font"))  {
-			if(++i==argc)  { usage(); exit(2); };
-			FontName=argv[i];
-		} else if(!strcmp(argv[i],"-display"))  {
-			if(++i==argc)  { usage(); exit(2); };
-			DisplayName=argv[i];
-		} else if(!strcmp(argv[i],"-file"))  {
-			if(++i==argc)  { usage(); exit(2); };
-			strcpy(SpoolFile,argv[i]);
-		} else if(!strcmp(argv[i],"-hilight"))  {
-			Options|=HILIGHT_MAIL;
-			if(i+1!=argc && argv[i+1][0]!='-') HiColor=argv[++i];
-		} else if(!strcmp(argv[i],"-command"))  {
-			if(++i==argc)  { usage(); exit(2); };
-			strcpy(Command,argv[i]);
-		} else if(!strcmp(argv[i],"-geometry"))  {
-			if(++i==argc)  { usage(); exit(2); };
-			Geometry=argv[i];
-		} else if(!strcmp(argv[i],"-name")) {
-			if(++i==argc)  { usage(); exit(2); };
-			AppName=argv[i];
-#ifdef POP3
-		} else if(!strcmp(argv[i],"-pop3"))  {
-			if(++i==argc)  { usage(); exit(2); };
-			strcpy(SpoolFile,argv[i]);
-			Options|=USE_POP3;
-			if(!intervalused) Interval=INTERVAL_POP3;
-		} else if(!strcmp(argv[i],"-apop3"))  {
-			if(++i==argc)  { usage(); exit(2); };
-			strcpy(SpoolFile,argv[i]);
-			Options|=USE_APOP3;
-			if(!intervalused) Interval=INTERVAL_POP3;
-		} else if(!strcmp(argv[i],"-imap"))  {
-			if(++i==argc)  { usage(); exit(2); };
-			strcpy(SpoolFile,argv[i]);
-			Options|=USE_IMAP;
-			if(!intervalused) Interval=INTERVAL_POP3;
-		} else if(!strcmp(argv[i],"-username"))  {
-			if(++i==argc)  { usage(); exit(2); };
-			strcpy(Username,argv[i]);
-		} else if(!strcmp(argv[i],"-password"))  {
-			if(++i==argc)  { usage(); exit(2); };
-			strcpy(Password,argv[i]);
-			memset(argv[i],0,strlen(argv[i]));
-			if(!strcmp(Password,"ask"))  ask_password();
-		} else if(!strcmp(argv[i],"-offline"))  {
-			Options|=OFFLINE;
-#endif
-		} else if(!strcmp(argv[i],"-wmaker"))  {
-			Options|=WM_MODE;
-		} else if(!strcmp(argv[i],"-kde")) {
-			Options|=KDE1_MODE|KDE2_MODE;
-		} else if(!strcmp(argv[i],"-nokde")) {
-			Options|=NOKDE;
-		} else if(!strcmp(argv[i],"-nowmaker")) {
-			Options|=NOWM;
-		} else if(!strcmp(argv[i],"-mailcommand")) {
-			Options|=COMMAND_MODE;
-			if(++i==argc)  { usage(); exit(2); };
-			strcpy(NewMailCommand, argv[i]);
-		} else if(!strcmp(argv[i],"-h") || !strcmp(argv[i],"-help"))  {
-			usage(); exit(0);
-		} else if(!strcmp(argv[i],"-v") || !strcmp(argv[i],"-version"))  {
-			printf("XLassie " VERSION "\n"); exit(0);
-		} else {
-			fprintf(stderr,"Unknown option %s\n",argv[i]);
-			fprintf(stderr,"Use -h for help\n");
-			exit(2);
-		};
-	};
+  XDrawString(dpy,win,gc,w,h,str,strlen(str));
+
+  if(optList[LED].isSet) update_led(True);
 }
 
-void init(int argc,char *argv[])
+void handler(int signum)
 {
-	int screen;
-	XWMHints *wmh;
-	XSizeHints *xsh;
-	XClassHint *classh;
-	XColor color,tmp;
-	Window icon=0;
-	int x,y,g;
-
-	parse_options(argc,argv);
-
-	dpy=XOpenDisplay(DisplayName);
-	if(dpy==NULL)  {
-		fprintf(stderr,"Error: Can't open display: %s\n",DisplayName);
-		exit(1);
-	}
-	screen=DefaultScreen(dpy);
-	DeleteWindow = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
+  int old;
 
-	if(!(Options&NOKDE)) {
-		/* Turn on KDE mode if we find the KWM docking hint atom */
-		KWMDockWindow = XInternAtom(dpy, "KWM_DOCKWINDOW", True);
-		if(KWMDockWindow!=None)  {
-			Options |= KDE1_MODE;
-		} else  { 
-			/* Looks like KWM_DOCKWINDOW wasn't the magic word.  Try the KDE2,
-			   "NET" method and see if that works.  */
-			KWMDockWindow = XInternAtom(dpy, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR",
-			                            True);
-			if(KWMDockWindow!=None)  {
-				Options |= KDE2_MODE;
-			}
-		}
-	}
-	if(!(Options&NOWM)) {
-		/* Find a window maker atom... */
-		Atom a = XInternAtom(dpy, "_WINDOWMAKER_WM_PROTOCOLS", True);
-		if(a!=None) {
-			Options |= WM_MODE;
-			Options |= SHAPED_WINDOW;
-		}
-	}
+  /* Intercept Ctrl-C's and kill commands */
+  if ((signum == SIGINT) || (signum == SIGTERM))
+    {
+      /* Clean-up and exit */
+      verbose("SIGINT handler");
+      close_display();
+      exit(errno);
+    }
+
+  old = Number;
+  verbose("SIGALRM handler");
+  count_mail();
+  verbose("new count %d, old %d", Number, old);
+  if(old==Number) {
+    return;
+  }
+  update();
+  if(Number>old)  {
+    if(optList[BELL].isSet) XBell(dpy,100);
+    if(optList[MAILCOMMAND].isSet) {
+      char str[256];
+      sprintf(str, optList[MAILCOMMAND].value, Number);
+      system(str);
+    }
+  }
+  XFlush(dpy);
+}
 
-	xsh=XAllocSizeHints();
-	wmh=XAllocWMHints();
-	classh=XAllocClassHint();
-
-	/* Try and find a font */
-	if((Options&KDE2_MODE) || (Options&KDE1_MODE)) y=1;
-	else if(Options&WM_MODE) y=2; else y=0;
-
-	if(FontName == NULL) { FontName = BackupFonts[y][0]; x=1; }
-	else { x = 0; }
-
-	font=XLoadQueryFont(dpy, FontName);
-	for(;x<4 && font==NULL;x++) {
-		fprintf(stderr, "Font \"%s\" not found\n", FontName);
-		FontName = BackupFonts[y][x];
-		fprintf(stderr, " trying \"%s\"\n", FontName);
-		font=XLoadQueryFont(dpy, FontName);
-	}
-	if(font==NULL) {
-		fprintf(stderr, "Can't find any fonts, I give up!\n");
-		exit(1);
-	}
+void font_height(void)
+{
+  int foo,bar,baz;
+  XCharStruct extents;
 
-	font_height();
-	Height=Ascent+Descent;
-	Width=XTextWidth(font,"88",2);
-	xsh->flags = PSize; xsh->width = Width; xsh->height = Height;
-/*	printf("%d x %d\n", Width, Height);*/
-
-	g=XWMGeometry(dpy,screen,Geometry,NULL,0,xsh,&x,&y,&Width,&Height,&g);
-	if(g&XValue)  { xsh->x=x; xsh->flags|=USPosition; };
-	if(g&YValue)  { xsh->y=y; xsh->flags|=USPosition; };
-	if(g&WidthValue)  {xsh->width=Width; xsh->flags|=USSize; 
-	} else            {Width = xsh->width; };
-	if(g&HeightValue)  {xsh->height=Height; xsh->flags|=USSize;
-	} else            {Height = xsh->height; };
+  XTextExtents(font,"0123456789",10,&foo,&bar,&baz,&extents);
+  Ascent=extents.ascent;
+  Descent=extents.descent;
+}
 
-/*	printf("%dx%d+%d+%d\n",Width,Height,x,y);
-	printf("%s%s%s%s\n",
-		(xsh->flags&USPosition)?"USPosition ":"",
-		(xsh->flags&PPosition)?"PPosition ":"",
-		(xsh->flags&USSize)?"USSize ":"",
-		(xsh->flags&PSize)?"PSize ":""); */
-
-	win=XCreateSimpleWindow(dpy,RootWindow(dpy,screen),x,y,Width,Height,0,
-		BlackPixel(dpy,screen),WhitePixel(dpy,screen));
-
-	wmh->initial_state=NormalState;
-	wmh->input=False;
-	wmh->window_group = win;
-	wmh->flags = StateHint | InputHint | WindowGroupHint;
-	classh->res_name = (AppName==NULL)?"xlassie":AppName;
-	classh->res_class = "XBiff";
-
-	if(Options&WM_MODE) {
-		/* WindowMaker stuff */
-		icon=XCreateSimpleWindow(dpy,RootWindow(dpy,screen),x,y,Width,Height,
-				 0, BlackPixel(dpy,screen), WhitePixel(dpy,screen));
-		wmh->initial_state=WithdrawnState;
-		wmh->icon_window=icon;
-		wmh->flags |= IconWindowHint;
-		XSetClassHint(dpy, icon, classh);
-		XSelectInput(dpy, icon, ExposureMask|ButtonPressMask|StructureNotifyMask);
-	}
-	XmbSetWMProperties(dpy, win, "xlassie", "xlassie", argv, argc,
-					   xsh, wmh, classh);
-	XSetWMProtocols(dpy, win, &DeleteWindow, 1);
-	XSelectInput(dpy, win, ExposureMask|ButtonPressMask|StructureNotifyMask);
-
-	if(Options&KDE1_MODE) {
-		unsigned char data = 1;
-		if(KWMDockWindow==None)  {
-			fprintf(stderr, "KDE1 mode isn't going to work, skipping\n");
-		} else {
-			XChangeProperty(dpy, win, KWMDockWindow, KWMDockWindow, 8, 
-							PropModeReplace, &data, 1);
-		}
-	}
-	if(Options&KDE2_MODE) {
-		if(KWMDockWindow==None)  {
-			fprintf(stderr, "KDE2 mode isn't going to work, skipping\n");
-		} else {
-			XChangeProperty(dpy, win, KWMDockWindow, XA_WINDOW, 32, 
-							PropModeReplace, (void*)&win, 1);
-		}
-	}
+void version(void)
+{
+  printf("xlassie " VERSION "\n");
+}
 
-	XMapWindow(dpy, win);
-	if(Options&WM_MODE) win = icon;		/* Use the icon window from now on */
+void usage(void)
+{
+  version();
+  printf("Usage: xlassie [options]\n");
+  printf("Options:\n");
+  printf("    -h,  -help              Print usage and exit\n");
+  printf("    -v,  -version           Print version and exit\n");
+  printf("    -V,  -verbose           Chatter on about this and that\n");
+  printf("    -name <name>            Set application class name (default: %s)\n", optList[NAME].value);
+  printf("    -bg <color>             Background color (default: %s)\n", optList[BACKGROUND].value);
+  printf("    -fg <color>             Foreground color (default: %s)\n", optList[FOREGROUND].value);
+  printf("    -hilight [<color>]      Use a different foreground color when there\n"
+	 "                                is non-zero mail (default: %s)\n", optList[HIGHLIGHT].value);
+  printf("    -update <number>        Check mail every <number> seconds\n"
+	 "                                (default: %s sec local, %s sec remote)\n", INTERVAL_SPOOL, INTERVAL_REMOTE);
+  printf("    -bell                   Ring bell when count increases from zero\n");
+  printf("    -led [<number>]         Light-up keyboard LED <number> if mail exists\n");
+  printf("                                (default: %d)\n", atoi(optList[LED].value));
+  printf("    -fn <fontname>          Font for the new mail count\n");
+  printf("    -display <displayname>  X server to connect to\n");
+  printf("    -geometry <geometry>    Window geometry\n");
+  printf("    -shape                  Use a shaped window\n");
+  printf("    -spool <filename>        File to use for mail spool or maildir directory\n");
+  printf("    -mailcommand <command>  Command to execute on new mail arrival\n");
+  printf("    -clickcommand <command> Command to execute when clicked upon\n");
+  printf("                                (default: %s)\n", optList[CLICKCOMMAND].value);
+  printf("    -offset <number>        Mail display count offset (for debugging)\n");
+#ifdef HAVE_POP3
+  printf("    -pop3 <server>          Connect to pop3 server rather than local mail spool\n");
+  printf("    -apop3 <server>         Like -pop3, but uses a different method.\n");
+  printf("                                Use when -pop3 doesn't find the correct number\n");
+  printf("    -imap <server>          Use the IMAP protocol instead of pop3\n");
+  printf("    -imapfolder <folder>    Use this folder instead of INBOX\n");
+  printf("    -username <name>        Username for pop3/imap server,\n"
+	 "                                when different from local username\n");
+  printf("    -password <password>    Password to use on pop3/imap server.\n");
+  printf("                                Use the password 'ask' to be prompted for\n"
+	 "                                the password on stdin.\n");
+  printf("    -offline                Don't exit when the server is unreachable\n");
+#endif
+  printf("    -wmaker, -kde           Do stuff to get swallowed into the WindowMaker\n");
+  printf("                                or KDE dock.  Normally unneeded: WindowMaker\n"
+	 "                                and KDE should be autodetected.\n");
+  printf("    -nokde, -nowmaker       Don't do the stuff to get swallowed\n");
+}
 
-	gc=XCreateGC(dpy,win,0,NULL);
+void ask_password()
+{
+  size_t i = 4;
+  struct termios saved;
+  int got = tcgetattr(0, &saved);
+  if (got != -1) {
+    struct termios noecho = saved;
+    noecho.c_lflag &= ~ECHO;
+    tcsetattr(0, TCSADRAIN, &noecho);
+  }
+
+  printf("Mail account password: ");
+  fflush(stdout);
+  i = getline(&optList[PASSWORD].value, &i, stdin);
+  if(optList[PASSWORD].value[i - 1] == '\n') {
+    putchar('\n');
+    optList[PASSWORD].value[i - 1] = '\0';
+  }
 
-	XAllocNamedColor(dpy,DefaultColormap(dpy,screen),FgColor,&color,&tmp);
-	XSetForeground(dpy,gc,color.pixel); FgXColor=color;
-	XAllocNamedColor(dpy,DefaultColormap(dpy,screen),BgColor,&color,&tmp);
-	XSetBackground(dpy,gc,color.pixel);
-	XSetWindowBackground(dpy,win,color.pixel);
-	if(Options&HILIGHT_MAIL)  XAllocNamedColor(dpy,DefaultColormap(dpy,screen),
-												HiColor,&HiXColor,&tmp);
-	XSetFont(dpy,gc,font->fid);
-
-	if(Options&SHAPED_WINDOW)  {
-		MaskWidth = Width; MaskHeight = Height;
-		ShapeMask = XCreatePixmap(dpy,win,MaskWidth,MaskHeight,1);
-		ShapeGC = XCreateGC(dpy,ShapeMask,0,NULL);
-		XSetFont(dpy,ShapeGC,font->fid);
-	};
+  if (got != -1)
+    tcsetattr(0, TCSADRAIN, &saved);
 }
 
-int check_spool()
+void parse_cmdline(int argc, char *argv[])
 {
-	struct stat st;
-	char str[PATH_MAX];
+  while (1) {
+    static struct option long_options[] = {
+      {"help",			no_argument,		NULL, 'h'},
+      {"version",		no_argument,		NULL, 'v'},
+      {"verbose",		no_argument,		NULL, 'V'},
+      {"name",			required_argument,	NULL, 1},
+      {"bg",			required_argument,	NULL, 2},
+      {"fg",			required_argument,	NULL, 3},
+      {"hilight",		optional_argument,	NULL, 4},
+      {"update",		required_argument,	NULL, 5},
+      {"bell",			no_argument,		NULL, 6},
+      {"led",			optional_argument,	NULL, 7},
+      {"fn",			required_argument,	NULL, 8},
+      {"font",			required_argument,	NULL, 8},
+      {"display",		required_argument,	NULL, 9},
+      {"geometry",		required_argument,	NULL, 10},
+      {"shape",			no_argument,		NULL, 11},
+      {"spool",			required_argument,	NULL, 12},
+      {"mailcommand",		required_argument,	NULL, 13},
+      {"clickcommand",		required_argument,	NULL, 14},
+      {"offset",		required_argument,	NULL, 15},
+#ifdef HAVE_POP3
+      {"pop3",			required_argument,	NULL, 16},
+      {"apop3",			required_argument,	NULL, 17},
+      {"imap",			required_argument,	NULL, 18},
+      {"imapfolder",		required_argument,	NULL, 19},
+      {"username",		required_argument,	NULL, 20},
+      {"password",		required_argument,	NULL, 21},
+      {"offline",		no_argument,		NULL, 22},
+#endif
+      {"wmaker",		no_argument,		NULL, 23},
+      {"kde",			no_argument,		NULL, 24},
+      {"nokde",			no_argument,		NULL, 25},
+      {"nowmaker",		no_argument,		NULL, 26},
+      {NULL, 0, NULL, 0}
+    };
+
+    int option_index = 0;
+    int c = getopt_long_only (argc, argv, "hvV",
+			      long_options, &option_index);
+    if (c == -1) break;
+    switch (c)
+      {
+      case 0:
+	printf ("option %s", long_options[option_index].name);
+	if (optarg) printf (" with arg %s", optarg);
+	printf ("\n");
+	break;
+      case 'h': usage(); exit(0); break;
+      case 'v': version(); exit(0); break;
+      case 'V': Options |= VERBOSE; break;
+      case 1:
+	optList[NAME].isSet = True;
+	optList[NAME].value = optarg;
+	break;
+      case 2:
+	optList[BACKGROUND].isSet = True;
+	optList[BACKGROUND].value = optarg;
+	break;
+      case 3:
+	optList[FOREGROUND].isSet = True;
+	optList[FOREGROUND].value = optarg;
+	break;
+      case 4:
+	optList[HIGHLIGHT].isSet = True;
+	if (optarg) optList[HIGHLIGHT].value = optarg;
+	break;
+      case 5:
+	optList[UPDATE].isSet = True;
+	optList[UPDATE].value = optarg;
+	break;
+      case 6: optList[BELL].isSet = True; break;
+      case 7:
+	optList[LED].isSet = True;
+	if(optarg) optList[LED].value = optarg;
+	break;
+      case 8:
+	optList[FONT].isSet = True;
+	optList[FONT].value = optarg;
+	break;
+      case 9: DisplayName = optarg; break;
+      case 10:
+	optList[GEOMETRY].isSet = True;
+	optList[GEOMETRY].value = optarg;
+	break;
+      case 11: optList[SHAPE].isSet = True; break;
+      case 12:
+	optList[SPOOL].isSet = True;
+	optList[SPOOL].value = optarg;
+	break;
+      case 13:
+	optList[MAILCOMMAND].isSet = True;
+	optList[MAILCOMMAND].value = optarg;
+	break;
+      case 14:
+	optList[CLICKCOMMAND].isSet = True;
+	optList[CLICKCOMMAND].value = optarg;
+	break;
+      case 15: Count_offset = atoi(optarg); break;
+
+#ifdef HAVE_POP3
+      case 16:
+	optList[POP3].isSet = True;
+	optList[SPOOL].isSet = True;
+	optList[SPOOL].value = optarg;
+	break;
+      case 17:
+	optList[APOP3].isSet = True;
+	optList[SPOOL].isSet = True;
+	optList[SPOOL].value = optarg;
+	break;
+      case 18:
+	optList[IMAP].isSet = True;
+	optList[SPOOL].isSet = True;
+	optList[SPOOL].value = optarg;
+	break;
+      case 19:
+	optList[FOLDERNAME].isSet = True;
+	optList[FOLDERNAME].value = optarg;
+	break;
+      case 20:
+	optList[USERNAME].isSet = True;
+	optList[USERNAME].value = optarg;
+	break;
+      case 21:
+	optList[PASSWORD].isSet = True;
+	optList[PASSWORD].value = strdup(optarg);
+	/* Overwrite password argument (for 'ps' scanning) */
+	memset(optarg, 0, strlen(optarg));
+	break;
+      case 22: optList[OFFLINE].isSet = True; break;
+#endif
+      case 23: optList[WMAKER].isSet = True; break;
+      case 24:
+	optList[KDE].isSet = True;
+	Options |= KDE2_MODE;
+	break;
+      case 25: optList[NOKDE].isSet = True; break;
+      case 26: optList[NOWMAKER].isSet = True; break;
+      }
+  }
 
-	if(Options&(USE_POP3|USE_APOP3|USE_IMAP)) return 0;
-	if(stat(SpoolFile, &st)) {
-		perror("stat");
-		fprintf(stderr, "Can't seem to find your mail file/directory: '%s'\n",
-		        SpoolFile);
-		exit(errno);
-	}
+  if(!strcmp(optList[PASSWORD].value, "ask"))
+    ask_password();
+}
 
-	if(S_ISDIR(st.st_mode)) {
-		Options|=USE_MAILDIR;
+void init(int argc,char *argv[])
+{
+  int screen;
+  XWMHints *wmh;
+  XSizeHints *xsh;
+  XClassHint *classh;
+  XColor color,tmp;
+  Window icon=0;
+  int x,y,g;
+
+  /* Get any command-line options, these trump the .Xdefaults */
+  parse_cmdline(argc, argv);
+
+  dpy=XOpenDisplay(DisplayName);
+  if(dpy==NULL)  {
+    fprintf(stderr,"error: Can't open display: %s\n",DisplayName);
+    exit(1);
+  }
+  screen=DefaultScreen(dpy);
+  DeleteWindow = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
+
+  /* Get the .Xdefault resources and populate our settings */
+  parse_xdefaults(dpy, optList[NAME].value);
+
+  if( !(optList[NOKDE].isSet) ) {
+    // Look for KDE1 stuff
+    KWMDockWindow = XInternAtom(dpy, "KWM_DOCKWINDOW", True);
+    if (KWMDockWindow != None)  {
+      verbose("found KDE1 stuff, switching on KDE1 mode");
+      optList[KDE].isSet = True;
+    }
+  }
+
+  if( !(optList[NOKDE].isSet) ) {
+    // Look for KDE2 "NET" method
+    KWMDockWindow = XInternAtom(dpy, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR",
+				True);
+    if (KWMDockWindow != None)  {
+      verbose("found KDE2 stuff, switching on KDE2 mode");
+      Options |= KDE2_MODE;
+    }
+  }
+
+  if( !(optList[NOWMAKER].isSet) ) {
+    // Look for a window maker atom
+    Atom a = XInternAtom(dpy, "_WINDOWMAKER_WM_PROTOCOLS", True);
+    if (a != None) {
+      verbose("found WMaker atom, switching on WM mode");
+      optList[WMAKER].isSet = True;
+      optList[SHAPE].isSet = True;
+    }
+  }
+
+  xsh=XAllocSizeHints();
+  wmh=XAllocWMHints();
+  classh=XAllocClassHint();
+
+  // This font finding stuff is rather icky.
+  // It would be better to find a font *after* deciding
+  // which mode will actually work.  Font finding should
+  // be in a subroutine (!), so it could be re-invoked
+  // when a mode switch is needed.
+
+  if (optList[FONT].isSet) {
+    // User specified font
+    font = XLoadQueryFont(dpy, optList[FONT].value);
+    if (!font) {
+      fprintf(stderr, "warning: user-specified font not available: %s\n",
+	      optList[FONT].value);
+    }
+  }
+
+  if (!font) {
+    // Need to find a font
+
+    if (optList[WMAKER].isSet)
+      y=2; // WMaker
+    else if ((optList[KDE].isSet) || (Options & KDE2_MODE))
+      y=1; // KDE
+    else
+      y=0; // not docked
+
+    verbose("font list %d", y);
+
+    for (x=0; !font; x++) {
+      optList[FONT].value = BackupFonts[y][x];
+      if ( !optList[FONT].value ) {
+	fprintf(stderr, "error: no available font\n");
+	exit(1);
+      }
+      verbose("considering font %s", optList[FONT].value);
+      font = XLoadQueryFont(dpy, optList[FONT].value);
+    }
+    verbose("found good font");
+  }
+
+  font_height();
+  Height=Ascent+Descent;
+  Width=XTextWidth(font,"88",2);
+  xsh->flags = PSize; xsh->width = Width; xsh->height = Height;
+  verbose("display region: %d x %d", Width, Height);
+
+  g = XWMGeometry(dpy,screen,optList[GEOMETRY].value,NULL,0,xsh,
+		  &x,&y,&Width,&Height,&g);
+  if(g&XValue)  { xsh->x = x; xsh->flags |= USPosition; };
+  if(g&YValue)  { xsh->y = y; xsh->flags |= USPosition; };
+  if(g&WidthValue)  {xsh->width = Width; xsh->flags |= USSize;
+  } else            {Width = xsh->width; };
+  if(g&HeightValue)  {xsh->height = Height; xsh->flags |= USSize;
+  } else             {Height = xsh->height; };
 
-		/* Check for the subdir "new" and use it if it exists */
-		strcpy(str, SpoolFile);
-		strcat(str, (str[strlen(str)-1]=='/')?"new":"/new");
-		if(!stat(str, &st) && S_ISDIR(st.st_mode)) {
-			strcpy(SpoolFile, str);
-		}
-	}
-	return 1;
+  /*	printf("%dx%d+%d+%d\n",Width,Height,x,y);
+	printf("%s%s%s%s\n",
+	(xsh->flags&USPosition)?"USPosition ":"",
+	(xsh->flags&PPosition)?"PPosition ":"",
+	(xsh->flags&USSize)?"USSize ":"",
+	(xsh->flags&PSize)?"PSize ":"");
+  */
+
+  win=XCreateSimpleWindow(dpy,RootWindow(dpy,screen),x,y,Width,Height,0,
+			  BlackPixel(dpy,screen),WhitePixel(dpy,screen));
+
+  wmh->initial_state = NormalState;
+  wmh->input = False;
+  wmh->window_group = win;
+  wmh->flags = StateHint | WindowGroupHint;
+  classh->res_name = optList[NAME].value;
+  classh->res_class = APL_CLASS;
+
+  if(optList[WMAKER].isSet) {
+    verbose("using WMaker mode");
+    icon=XCreateSimpleWindow(dpy,RootWindow(dpy,screen),x,y,Width,Height,
+			     0,BlackPixel(dpy,screen),WhitePixel(dpy,screen));
+    wmh->initial_state=WithdrawnState;
+    wmh->icon_window=icon;
+    wmh->flags |= IconWindowHint;
+    XSetClassHint(dpy, icon, classh);
+    XSelectInput(dpy, icon,
+		 ExposureMask
+		 | ButtonPressMask
+		 | KeyPressMask
+		 | StructureNotifyMask);
+  }
+
+  XmbSetWMProperties(dpy, win, "xlassie", "xlassie", argv, argc,
+		     xsh, wmh, classh);
+  XSetWMProtocols(dpy, win, &DeleteWindow, 1);
+  XSelectInput(dpy, win,
+	       ExposureMask
+	       | ButtonPressMask
+	       | KeyPressMask
+	       | StructureNotifyMask);
+  XFlush(dpy);
+
+  if(optList[KDE].isSet) {
+    unsigned char data = 1;
+    verbose("using KDE1 mode");
+    if (KWMDockWindow == None) {
+      verbose("KDE1 mode isn't going to work, skipping");
+    } else {
+      XChangeProperty(dpy, win, KWMDockWindow, KWMDockWindow, 8,
+		      PropModeReplace, &data, 1);
+    }
+  }
+
+  if (Options & KDE2_MODE) {
+    verbose("using KDE2 mode");
+    if (KWMDockWindow == None) {
+      verbose("KDE2 mode isn't going to work, skipping");
+    } else {
+      XChangeProperty(dpy, win, KWMDockWindow, XA_WINDOW, 32,
+		      PropModeReplace, (void*)&win, 1);
+    }
+  }
+
+  XMapWindow(dpy, win);
+
+  if(optList[WMAKER].isSet) win = icon;	// Use the icon window from now on
+
+  gc = XCreateGC(dpy,win,0,NULL);
+  XAllocNamedColor(dpy,DefaultColormap(dpy,screen),
+		   optList[FOREGROUND].value,&color,&tmp);
+  XSetForeground(dpy,gc,color.pixel); FgXColor=color;
+  XAllocNamedColor(dpy,DefaultColormap(dpy,screen),
+		   optList[BACKGROUND].value,&color,&tmp);
+  XSetBackground(dpy,gc,color.pixel);
+  XSetWindowBackground(dpy,win,color.pixel);
+  if(optList[HIGHLIGHT].isSet)
+    XAllocNamedColor(dpy,DefaultColormap(dpy,screen),
+		     optList[HIGHLIGHT].value,&HiXColor,&tmp);
+  XSetFont(dpy,gc,font->fid);
+
+  if(optList[SHAPE].isSet) {
+    verbose("using shaped window");
+    MaskWidth = Width; MaskHeight = Height;
+    ShapeMask = XCreatePixmap(dpy,win,MaskWidth,MaskHeight,1);
+    ShapeGC = XCreateGC(dpy,ShapeMask,0,NULL);
+    XSetFont(dpy,ShapeGC,font->fid);
+  };
 }
 
-int main(int argc,char *argv[])
+int check_spool()
 {
-	XEvent xev;
-	Atom WM_PROTOCOLS;
-	struct itimerval itv;
-	struct sigaction sig;
-	struct passwd* pwd;
-	char *mail;
-
-	pwd = getpwuid(getuid());
-	mail= getenv("MAIL");
-	if(mail==NULL) {
-		sprintf(SpoolFile,"/var/spool/mail/%s", pwd->pw_name);
-	} else {
-		strcpy(SpoolFile, mail);
-	}
-	strcpy(Username,pwd->pw_name);
-	strcpy(Command, COMMAND);
+  struct stat st;
+  char str[PATH_MAX];
 
-	init(argc,argv);
-	check_spool();
+  if(optList[POP3].isSet || optList[APOP3].isSet || optList[IMAP].isSet)
+    return 0;
 
-	WM_PROTOCOLS = XInternAtom(dpy, "WM_PROTOCOLS", False);
+  if(stat(optList[SPOOL].value, &st)) {
+    perror("stat");
+    fprintf(stderr, "error: mail file/directory not found '%s'\n",
+	    optList[SPOOL].value);
+    exit(1);
+  }
+
+  if(S_ISDIR(st.st_mode)) {
+    Options|=USE_MAILDIR;
+
+    /* Check for the subdir "new" and use it if it exists */
+    strcpy(str, optList[SPOOL].value);
+    strcat(str, (str[strlen(str)-1]=='/')?"new":"/new");
+    if(!stat(str, &st) && S_ISDIR(st.st_mode)) {
+      strcpy(optList[SPOOL].value, str);
+    }
+  }
+  return 1;
+}
 
-#ifdef OFFLINE_DEFAULT
-	Options|=OFFLINE;
+int main(int argc,char *argv[])
+{
+  XEvent xev;
+  Atom WM_PROTOCOLS;
+  struct itimerval itv;
+  struct sigaction sig;
+  struct passwd* pwd;
+  char *mail;
+
+  pwd = getpwuid(getuid());
+  mail= getenv("MAIL");
+  if(mail==NULL) {
+    asprintf(&optList[SPOOL].value, "/var/spool/mail/%s",
+	    pwd->pw_name);
+  } else {
+    optList[SPOOL].value = mail;
+  }
+
+  /* Set some defaults requiring external struct accesses */
+  optList[USERNAME].value = pwd->pw_name;
+
+  init(argc,argv);
+  check_spool();
+
+  WM_PROTOCOLS = XInternAtom(dpy, "WM_PROTOCOLS", False);
+
+#ifdef HAVE_POP3
+# ifdef OFFLINE_DEFAULT
+  Options|=OFFLINE;
+# endif
 #endif
 
-	count_mail();
+  count_mail();
 
-	if(Options&BELL_MODE && Number) XBell(dpy,100);
+  if(optList[BELL].isSet && Number) XBell(dpy,100);
 
-	sig.sa_handler=handler;
-	sigemptyset(&sig.sa_mask);
-	sig.sa_flags=SA_RESTART;
-	sigaction(SIGALRM,&sig,NULL);
-	itv.it_interval.tv_sec=Interval; itv.it_interval.tv_usec=0;
-	itv.it_value = itv.it_interval;
-	setitimer(ITIMER_REAL,&itv,NULL);
-
-	for(;;)  {
-		XNextEvent(dpy,&xev);
-		switch(xev.type)  {
-		case Expose:
-			while(XCheckTypedEvent(dpy,Expose,&xev));
-			update();
-			break;
-		case ButtonPress:
-			system(Command);
-			break;
-		case ConfigureNotify:
-			Width = xev.xconfigure.width;
-			Height = xev.xconfigure.height;
-			update();
-			break;
-		case ClientMessage:
-			if(xev.xclient.message_type == WM_PROTOCOLS)  {
-				if(xev.xclient.data.l[0] == DeleteWindow) {
-					XCloseDisplay(dpy);
-					exit(0);
-				};
-			};
-			break;
-		case DestroyNotify:
-			XCloseDisplay(dpy);
-			exit(0);
-		default:
-		};
+  sig.sa_handler=handler;
+  sigemptyset(&sig.sa_mask);
+  sig.sa_flags=SA_RESTART;
+  sigaction(SIGALRM,&sig,NULL);
+  sigaction(SIGINT,&sig,NULL);
+  sigaction(SIGTERM,&sig,NULL);
+#ifdef HAVE_POP3
+  if ((optList[POP3].isSet  ||
+       optList[APOP3].isSet ||
+       optList[IMAP].isSet) && (!(optList[UPDATE].isSet)))
+    itv.it_interval.tv_sec = atoi(INTERVAL_REMOTE);
+  else
+#endif
+    itv.it_interval.tv_sec = atoi(optList[UPDATE].value);
+  itv.it_interval.tv_usec = 0;
+  itv.it_value = itv.it_interval;
+  setitimer(ITIMER_REAL,&itv,NULL);
+
+  for(;;)  {
+    XNextEvent(dpy,&xev);
+    switch(xev.type)  {
+    case Expose:
+      while(XCheckTypedEvent(dpy,Expose,&xev));
+      update();
+      break;
+    case ButtonPress:
+      verbose("button click!");
+      if (strcmp(optList[CLICKCOMMAND].value,
+		 "CHECK_MAILBOX") != 0) {
+	verbose("calling click command");
+	system(optList[CLICKCOMMAND].value);
+      } else {
+	verbose("raising SIGALRM");
+	raise(SIGALRM);
+      }
+      break;
+    case KeyPress:
+      if (XLookupKeysym(&xev.xkey, 0) == XK_q) {
+	verbose("quit: keypress q");
+	close_display();
+	exit(0);
+      }
+      break;
+    case ConfigureNotify:
+      Width = xev.xconfigure.width;
+      Height = xev.xconfigure.height;
+      update();
+      break;
+    case ClientMessage:
+      if(xev.xclient.message_type == WM_PROTOCOLS)  {
+	if(xev.xclient.data.l[0] == DeleteWindow) {
+	  verbose("quit: DeleteWindow");
+	  close_display();
+	  exit(0);
 	};
+      };
+      break;
+    case DestroyNotify:
+      verbose("quit: DestroyNotify");
+      close_display();
+      exit(0);
+    default:
+      verbose("warning: unknown xev.type %d", xev.type);
+    };
+  };
 }
 
-#ifdef POP3
+#ifdef HAVE_POP3
 int sock_connect(char *,int);
 
 FILE *pop_login()
 {
-	int fd;
-	FILE *f;
-	char buf[256];
-
-	fd=sock_connect(SpoolFile,110);
-	if(fd==-1)  {
-		if(Options&OFFLINE)  {
-			Number=-1; return NULL;
-		} else {
-			fprintf(stderr,"Error connecting to POP3 server %s\n",SpoolFile);
-			exit(1);
-		};
-	};
-
-	f=fdopen(fd,"r+");
-
-	fgets(buf,256,f);
+  int fd;
+  FILE *f;
+  char buf[256];
+
+  fd=sock_connect(optList[SPOOL].value, 110);
+  if(fd==-1)  {
+    if(optList[OFFLINE].isSet) {
+      Number=-1; return NULL;
+    } else {
+      fprintf(stderr, "error: cannot connect to POP3 server %s\n",
+	      optList[SPOOL].value);
+      exit(1);
+    };
+  };
+
+  f=fdopen(fd,"r+");
+
+  fgets(buf,256,f);
+
+  fflush(f); fprintf(f,"USER %s\r\n", optList[USERNAME].value);
+  fflush(f); fgets(buf,256,f);
+
+  if(buf[0]!='+')  {
+    fprintf(stderr,"warning: server rejected username\n");
+    fprintf(f,"QUIT\r\n");fclose(f);
+    return NULL;
+  };
+  fflush(f); fprintf(f,"PASS %s\r\n", optList[PASSWORD].value);
+  fflush(f); fgets(buf,256,f);
+  if(buf[0]!='+')  {
+    fprintf(stderr,"warning: server rejected password\n");
+    fprintf(stderr," server resposne: %s",buf);
+    fprintf(f,"QUIT\r\n");fclose(f);
+    return NULL;
+  };
 
-	fflush(f); fprintf(f,"USER %s\r\n",Username);
-	fflush(f); fgets(buf,256,f);
-
-	if(buf[0]!='+')  {
-		fprintf(stderr,"Server doesn't like your name!\n");
-		fprintf(f,"QUIT\r\n");fclose(f);
-		return NULL;
-	};
-	fflush(f); fprintf(f,"PASS %s\r\n",Password);
-	fflush(f); fgets(buf,256,f);
-	if(buf[0]!='+')  {
-		fprintf(stderr,"Server doesn't like your password!\n");
-		fprintf(stderr,"It said %s",buf);
-		fprintf(f,"QUIT\r\n");fclose(f);
-		return NULL;
-	};
-
-	return(f);
+  return(f);
 }
 
 FILE *imap_login()
 {
-	int fd;
-	FILE *f;
-	char buf[128];
-
-	fd=sock_connect(SpoolFile, 143);
-	if(fd==-1)  {
-		if(Options&OFFLINE)  {
-			Number=-1; return NULL;
-		} else {
-			fprintf(stderr, "Error connecting to IMAP server %s\n", SpoolFile);
-			exit(1);
-		};
-	};
-
-	f=fdopen(fd, "r+");
+  int fd;
+  FILE *f;
+  char buf[128];
+
+  fd=sock_connect(optList[SPOOL].value, 143);
+  if(fd==-1)  {
+    if(optList[OFFLINE].isSet) {
+      Number=-1; return NULL;
+    } else {
+      fprintf(stderr, "error: cannot connect to IMAP server %s\n",
+	      optList[SPOOL].value);
+      exit(1);
+    };
+  };
+
+  f=fdopen(fd, "r+");
+
+  fgets(buf, 127, f);
+  fflush(f); fprintf(f, "a001 LOGIN %s \"%s\"\r\n",
+		     optList[USERNAME].value, optList[PASSWORD].value);
+  fflush(f); fgets(buf, 127, f);
+
+  if(buf[5]!='O')  {       /* Looking for "a001 OK" */
+    fprintf(stderr, "warning: server rejected name and/or password.\n");
+    fprintf(f, "a002 LOGOUT\r\n"); fclose(f);
+    return NULL;
+  };
 
-	fgets(buf, 127, f);
-	fflush(f); fprintf(f, "a001 LOGIN %s \"%s\"\r\n", Username, Password);
-	fflush(f); fgets(buf, 127, f);
-
-	if(buf[5]!='O')  {       /* Looking for "a001 OK" */
-		fprintf(stderr, "Server doesn't like your name and/or password!\n");
-		fprintf(f, "a002 LOGOUT\r\n"); fclose(f);
-		return NULL;
-	};
-
-	return f;
+  return f;
 }
 
 int count_mail_pop()
 {
-	FILE *f;
-	char buf[256];
-	int total,read;
-
-	f = pop_login();
-	if(f==NULL) return -1;
-
-	fflush(f); fprintf(f,"STAT\r\n");
-	fflush(f); fgets(buf,256,f);
-	sscanf(buf,"+OK %d",&total);
-	fflush(f); fprintf(f,"LAST\r\n");
-	fflush(f); fgets(buf,256,f);
-	sscanf(buf,"+OK %d",&read);
-	Number=total-read;
+  FILE *f;
+  char buf[256];
+  int total,read;
+
+  f = pop_login();
+  if(f==NULL) return -1;
+
+  fflush(f); fprintf(f,"STAT\r\n");
+  fflush(f); fgets(buf,256,f);
+  sscanf(buf,"+OK %d",&total);
+  fflush(f); fprintf(f,"LAST\r\n");
+  fflush(f); fgets(buf,256,f);
+  sscanf(buf,"+OK %d",&read);
+  Number=total-read;
 
-	fprintf(f,"QUIT\r\n");
-	fclose(f);
+  fprintf(f,"QUIT\r\n");
+  fclose(f);
 
-	return 1;
+  return 1;
 }
 
 struct msg {
-	int size;
-	int read;
+  int size;
+  int read;
 };
 
 struct msg *get_list(FILE *f,int *nout)
 {
-	char buf[256];
-	struct msg *l;
-	int i,n;
-
-	fflush(f); fprintf(f,"STAT\r\n");
-	fflush(f); fgets(buf,256,f);
-	sscanf(buf,"+OK %d",&n);
-
-	l=malloc(sizeof(struct msg)*n);
-	fflush(f); fprintf(f,"LIST\r\n");
-	fflush(f); fgets(buf,256,f);
-	if(strncmp(buf,"+OK",3))  {
-		fprintf(stderr,"Can't get list?\n");
-		return NULL;
-	};
+  char buf[256];
+  struct msg *l;
+  int i,n;
+
+  fflush(f); fprintf(f,"STAT\r\n");
+  fflush(f); fgets(buf,256,f);
+  sscanf(buf,"+OK %d",&n);
+
+  l=malloc(sizeof(struct msg)*n);
+  fflush(f); fprintf(f,"LIST\r\n");
+  fflush(f); fgets(buf,256,f);
+  if(strncmp(buf,"+OK",3))  {
+    fprintf(stderr, "warning: can't get list.\n");
+    return NULL;
+  };
+
+  for(i=0;i<n;i++)  {
+    fgets(buf,256,f);
+    sscanf(buf,"%*d %d",&l[i].size);
+  };
+  fgets(buf,256,f);
+  if(buf[0]!='.')  {
+    fprintf(stderr,"warning: too many messages.\n");
+    return NULL;
+  };
 
-	for(i=0;i<n;i++)  {
-		fgets(buf,256,f);
-		sscanf(buf,"%*d %d",&l[i].size);
-	};
-	fgets(buf,256,f);
-	if(buf[0]!='.')  {
-		fprintf(stderr,"To many messages?\n");
-		return NULL;
-	};
-
-	*nout=n;
-	return l;
+  *nout=n;
+  return l;
 }
 
 void get_header(FILE *f,struct msg *l,int i)
 {
-	char buf[256];
-	
-	fflush(f); fprintf(f,"TOP %d 1\r\n",i+1);
-	fflush(f); fgets(buf,256,f);
-	if(strncmp(buf,"+OK",3))  {
-		fprintf(stderr,"TOP failed!\n");
-		fprintf(stderr,"Returned %s\n",buf);
-		return;
-	};
-	l->read=0;
-	for(;;)  {
-		fgets(buf,256,f);
-		if(!strcmp(buf,".\r\n"))  break;
-		if(!strncmp(buf,"Status: R",9))
-			l->read=1;
-	};
-	/* fprintf(stderr,"msg %d %s\n",i+1,l->read?"read":"unread"); */
+  char buf[256];
+
+  fflush(f); fprintf(f,"TOP %d 1\r\n",i+1);
+  fflush(f); fgets(buf,256,f);
+  if(strncmp(buf,"+OK",3))  {
+    fprintf(stderr, "warning: TOP failed.\n");
+    fprintf(stderr,"   server returned: %s\n",buf);
+    return;
+  };
+  l->read=0;
+  for(;;)  {
+    fgets(buf,256,f);
+    if(!strcmp(buf,".\r\n"))  break;
+    if(!strncmp(buf,"Status: R",9))
+      l->read=1;
+  };
+  /* fprintf(stderr,"msg %d %s\n",i+1,l->read?"read":"unread"); */
 }
 
 int count_mail_pop_2()
 {
-	FILE *f;
-	int i,j,n2;
-	int total=0;
-	static struct msg *l1=NULL,*l2;
-	static int n;
-
-	f = pop_login();
-	if(f==NULL) return -1;
-
-	if(l1==NULL)  {  /* get initial list */
-		l1=get_list(f,&n);
-		if(l1==NULL) return -1;
-		for(i=0;i<n;i++) {
-			get_header(f,l1+i,i);
-			if(!l1[i].read) total++;
-		};
-		Number=total; 
-		return 1;
-	};
+  FILE *f;
+  int i,j,n2;
+  int total=0;
+  static struct msg *l1=NULL,*l2;
+  static int n;
+
+  f = pop_login();
+  if(f==NULL) return -1;
+
+  if(l1==NULL)  {  /* get initial list */
+    l1=get_list(f,&n);
+    if(l1==NULL) return -1;
+    for(i=0;i<n;i++) {
+      get_header(f,l1+i,i);
+      if(!l1[i].read) total++;
+    };
+    Number=total;
+    return 1;
+  };
+
+  l2=get_list(f,&n2);
+
+  /* compare lists, retreive new messages */
+  for(i=0,j=0;i<n && j<n2;i++,j++)  {
+    /*		fprintf(stderr,"Old list %d size %d %c, new list %d size %d\n",
+		i+1,l1[i].size,l1[i].read?'R':'U', j+1,l2[j].size);
+    */
+    if(l1[i].size != l2[j].size) break;
+    if(!l1[i].read)  {
+      get_header(f,l2+j,j);
+    } else {
+      l2[j].read=1;
+    };
+  };
+  for(;j<n2;j++) get_header(f,l2+j,j);
+
+  fclose(f);
+
+  free(l1); l1=l2; l2=NULL; n=n2;
+  for(i=0;i<n;i++)  if(!l1[i].read) total++;
+  Number=total;
 
-	l2=get_list(f,&n2);
-
-	/* compare lists, retreive new messages */
-	for(i=0,j=0;i<n && j<n2;i++,j++)  {
-/*		fprintf(stderr,"Old list %d size %d %c, new list %d size %d\n",
-		               i+1,l1[i].size,l1[i].read?'R':'U', j+1,l2[j].size); */
-		if(l1[i].size != l2[j].size) break;
-		if(!l1[i].read)  {
-			get_header(f,l2+j,j);
-		} else {
-			l2[j].read=1;
-		};
-	};
-	for(;j<n2;j++) get_header(f,l2+j,j);
-
-	fclose(f);
-
-	free(l1); l1=l2; l2=NULL; n=n2;
-	for(i=0;i<n;i++)  if(!l1[i].read) total++;
-	Number=total;
-
-	return 1;
+  return 1;
 }
 
 int count_mail_imap()
 {
-	FILE *f;
-	char buf[128];
-	int total=0;
-
-	f = imap_login();
-	if(f==NULL) return -1;
-
-	fflush(f); fprintf(f, "a003 STATUS INBOX (UNSEEN)\r\n");
-	fflush(f); fgets(buf, 127, f);
-	if(!sscanf(buf, "* STATUS INBOX (UNSEEN %d)", &total) &&
-	   !sscanf(buf, "* STATUS \"INBOX\" (UNSEEN %d)", &total)) {
-		fprintf(stderr, "Couldn't understand response from server\n");
-		fprintf(stderr, "%s", buf);
-		return 0;
-	}
+  FILE *f;
+  char srch1[128];
+  char srch2[128];
+  char buf[128];
+  int total=0;
+
+  f = imap_login();
+  if(f==NULL) return -1;
+
+  verbose("To server: a003 STATUS %s (UNSEEN)\r\n", optList[FOLDERNAME].value);
+  fflush(f); fprintf(f, "a003 STATUS %s (UNSEEN)\r\n", optList[FOLDERNAME].value);
+  fflush(f); fgets(buf, 127, f);
+  sprintf(srch1,"* STATUS %s (UNSEEN %%d)", optList[FOLDERNAME].value);
+  sprintf(srch2,"* STATUS \"%s\" (UNSEEN %%d)", optList[FOLDERNAME].value);
+  if(!sscanf(buf, srch1, &total) &&
+     !sscanf(buf, srch2, &total)) {
+    fprintf(stderr, "warning: unexpected response from server\n");
+    fprintf(stderr, " while searching either: %s\n", srch1);
+    fprintf(stderr, " or: %s\n", srch2);
+    fprintf(stderr, " response was: %s", buf);
+    return 0;
+  }
 
-	Number = total;
+  Number = total;
 
-	fclose(f);
+  fclose(f);
 
-	return 1;
+  return 1;
 }
 #endif
 
 int count_mail_mbox()
 {
-	static time_t mtime=0;
-	static off_t size=0;
-	struct stat st;
-	int isread=0;
-	FILE *spool;
-	char buf[256];
-
-	spool = fopen(SpoolFile,"r");
-	if(spool==NULL)  {
-		fprintf(stderr,"Trying to open spoolfile %s\n",SpoolFile);
-		perror("xlassie");
-		XCloseDisplay(dpy);
-		exit(errno);
-	};
-
-	if(fstat(fileno(spool),&st)) {
-		perror("fstat");
-		XCloseDisplay(dpy);
-		exit(errno);
-	};
-	/* check to see if file was changed */
-	if(st.st_mtime != mtime || st.st_size != size)  {  
-		mtime = st.st_mtime;
-		size = st.st_size;
-		Number = 0;
-		while(fgets(buf, 256, spool)) {
-			if(!strncmp(buf, "From ", 5))  {
-				Number++; isread=0;
-			} else if(!strncmp(buf, "Status: R", 9))  {
-				if(!isread) { Number--; isread=1; };
-			};
-		};
-	}
-	fclose(spool);
+  static time_t mtime=0;
+  static off_t size=0;
+  struct stat st;
+  int isread=0;
+  FILE *spool;
+  char buf[256];
+
+  spool = fopen(optList[SPOOL].value, "r");
+  if(spool==NULL)  {
+    perror("xlassie");
+    fprintf(stderr,"error: failed to open spoolfile '%s'\n",
+	    optList[SPOOL].value);
+    close_display();
+    exit(errno);
+  };
+
+  if(fstat(fileno(spool),&st)) {
+    perror("fstat");
+    fprintf(stderr,"error: failed to stat spoolfile '%s'\n",
+	    optList[SPOOL].value);
+    close_display();
+    exit(errno);
+  };
+  /* check to see if file was changed */
+  if(st.st_mtime != mtime || st.st_size != size)  {
+    mtime = st.st_mtime;
+    size = st.st_size;
+    Number = 0;
+    while(fgets(buf, 256, spool)) {
+      if(!strncmp(buf, "From ", 5))  {
+	Number++; isread=0;
+      } else if(!strncmp(buf, "Status: R", 9))  {
+	if(!isread) { Number--; isread=1; };
+      };
+    };
+  }
+  fclose(spool);
 
-	return 1;
+  return 1;
 }
 
+// In the distant future xlassie could be modified to use the Linux
+// system call for requesting notification when a directory has an
+// entry added or removed or modified.
+
+// Or, could just use scandir(3) instead of doing this all manually.
+
 int count_mail_maildir()
 {
-	static time_t mtime=0;
-	struct stat st;
-	DIR *dir;
-	struct dirent *de;
-
-	if(stat(SpoolFile, &st)) {
-		perror("stat");
-		fprintf(stderr, "Can't access incomming mail directory '%s'\n", 
-		        SpoolFile);
-		XCloseDisplay(dpy);
-		exit(errno);
-	}
-
-	if(st.st_mtime != mtime) {
-		mtime = st.st_mtime;
-		if((dir = opendir(SpoolFile)) == NULL) {
-			perror("opendir");
-			XCloseDisplay(dpy);
-			exit(errno);
-		}
-		Number = 0;
-		while((de = readdir(dir)) != NULL) {
-			if(de->d_name[0] != '.') Number++;
-		}
-		closedir(dir);
-	}
-	return 1;
+  static time_t mtime=0;
+  struct stat st;
+  DIR *dir;
+  struct dirent *de;
+
+  if(stat(optList[SPOOL].value, &st)) {
+    perror("stat");
+    fprintf(stderr, "error: unable to access mail directory '%s'\n",
+	    optList[SPOOL].value);
+    close_display();
+    exit(errno);
+  }
+
+  if(st.st_mtime != mtime) {
+    mtime = st.st_mtime;
+    if ( !(dir = opendir(optList[SPOOL].value)) ) {
+      perror("opendir");
+      fprintf(stderr, "error: unable to access mail directory '%s'\n",
+	      optList[SPOOL].value);
+      close_display();
+      exit(errno);
+    }
+    Number = 0;
+    while( (de = readdir(dir)) != NULL ) {
+      if (de->d_name[0] != '.') Number++;
+    }
+    closedir(dir);
+  }
+  return 1;
 }
 
 int count_mail()
 {
-	if(Options&USE_MAILDIR) {
-		return count_mail_maildir();
-#ifdef POP3
-	} else if(Options&USE_APOP3)  {
-		return count_mail_pop_2();
-	} else if(Options&USE_POP3)  {
-		return count_mail_pop();
-	} else if(Options&USE_IMAP) {
-		return count_mail_imap();
+  verbose("about to count mail");
+
+  if(Options&USE_MAILDIR) {
+    return count_mail_maildir();
+#ifdef HAVE_POP3
+  } else if(optList[APOP3].isSet)  {
+    return count_mail_pop_2();
+  } else if(optList[POP3].isSet)  {
+    return count_mail_pop();
+  } else if(optList[IMAP].isSet) {
+    return count_mail_imap();
 #endif
-	} else {
-		return count_mail_mbox();
-	}
+  } else {
+    return count_mail_mbox();
+  }
 }
--- /dev/null
+++ xlassie-1.8/xlassie.h2m
@@ -0,0 +1,163 @@
+Include file for help2man man page
+
+[name]
+xlassie \- mailbox counter for X
+
+
+[description]
+The \fIxlassie\fR program is a replacement for the standard X mail
+notification tool, XBiff. It has several useful enhancements over XBiff.
+.in +2
+.sp
+\fB*\fP Counts the number of new messages you have
+.br
+\fB*\fP Can query remote mail on a POP3 server or on an IMAP server
+.br
+\fB*\fP Can count local mail with an mbox or a maildir style spool
+.br
+\fB*\fP Uses less memory than XBiff (or any other X mail checker)
+.br
+\fB*\fP Can run a command when clicked on, and/or when new mail arrives
+.br
+\fB*\fP Can toggle an LED indicating availability of mail
+.br
+\fB*\fP Supports both the KDE and the WindowMaker applet protocols
+.br
+\fB*\fP Runs as a standard X application
+.PP
+When the count is 0 (no mail) it is displayed in a less obtrusive
+color.  When mail arrives a beep is emitted, and the updated unread
+message count is displayed.
+.PP
+When xlassie is running, the following interactive commands are available:
+.PP
+.in +4
+.nf
+\fBq\fP             \fBQuit\fP gracefully.
+\fBmouse click\fP   Spawn 'clickcommand' (if any), otherwise update mail
+count.
+
+
+[X resources]
+
+When reading X resources, two class names \fBxlassie\fR and \fBxbiff\fR
+are recognized (in that order) unless the \fB\-name\fR is used.  The class
+name \fBxbiff\fR allows resources common to both xbiff and xlassie to
+be easily configured, while the class name \fBxlassie\fR allows resources
+unique to this program.  If no resources are specified, suitable defaults
+will be used.  Command-line arguments can be used to override resource
+settings.  The following resources are allowed (e.g, "xlassie.RESOURCE"):
+.TP
+\fBname:\fR \fIname\fR
+Use the specified name as a class name for this application
+(default: xlassie).
+.TP
+\fBbackground:\fR \fIcolor\fR
+Use the specified color as this application's background color.
+The 'bg' resource is also recognized (default: White).
+.TP
+\fBforeground:\fR \fIcolor\fR
+Use the specified color as this application's foreground color.
+The 'fg' resource is also recognized (default: Black).
+.TP
+\fBhightlight:\fR \fIcolor\fR
+Use the specified color as this application's foreground color when there
+is non-zero mail. The 'hilight' resource is also recognized (default: Red).
+.TP
+\fBupdate:\fR \fInumber\fR
+Use the specified number to note how many seconds should be used to check
+mail every (default: 5 seconds local, 60 seconds remote).
+.TP
+\fBbell:\fR \fIboolean\fR
+Use the specified boolean value to affect the ringing of the system bell
+when mail is received (default: False).
+.TP
+\fBled:\fR \fInumber\fR
+Use the specified number to light the LED specified if mail exists
+(default: 1).
+.TP
+\fBfont:\fR \fIfontname\fR
+Use the specified fontname as the application's font. The 'fn' resource
+is also recognized.
+.TP
+\fBgeometry:\fR \fIgeometry\fR
+Use the specified X window geometry.
+.TP
+\fBshape:\fR \fIboolean\fR
+Use the specified boolean value to affect shaped window creation
+(default: False).
+.TP
+\fBspool:\fR \fIfilename\fR
+Use the specified filename as the mail spool or maildir directory.
+.TP
+\fBmailcommand:\fR \fIcommand\fR
+Use the specified command to execute on new mail arrival. The 'mailcmd'
+resource is also recognized. If you have a %d in the command, it will
+get replaced with the number of new messages.  Remember to put quotes
+around the command if it's longer than one word.  If you want the
+command to run the background, put a '&' at the end.
+.TP
+\fBclickcommand:\fR \fIcommand\fR
+Use the specified command to execute when application is clicked on.
+The 'clickcmd' resource is also recognized (default: CHECK_MAILBOX).
+.TP
+\fBpop3:\fR \fIserver\fR
+Use the specified pop3 server rather than local mail spool.
+.TP
+\fBapop3:\fR \fIserver\fR
+Use the specified pop3 server rather than local mail spool but while using
+a different access method.  This option is useful when \fB\-pop3\fR doesn't
+find the correct number.
+.TP
+\fBimap:\fR \fIserver\fR
+Use the specified imap server rather than local mail spool.
+.TP
+\fBusername:\fR \fIname\fR
+Use the specified login name for pop3/imap server access when different
+from local username.
+.TP
+\fBpassword:\fR \fIpassword\fR
+Use the specified login password for pop3/imap server access.
+.TP
+\fBoffline:\fR \fIboolean\fR
+Use the specified boolean value to affect whether access is continued in
+the case a remote server is unreachable (default: False).
+.TP
+\fBwmaker:\fR \fIboolean\fR
+Use the specified boolean value to affect the ability to get swallowed into
+a WindowMaker dock (default: False).
+.TP
+\fBkde:\fR \fIboolean\fR
+Use the specified boolean value to affect the ability to get swallowed into
+a KDE dock (default: False).
+.TP
+\fBnokde:\fR \fIboolean\fR
+Use the specified boolean value to affect the inability to get swallowed into
+a KDE dock (default: False).
+.TP
+\fBnowmaker:\fR \fIboolean\fR
+Use the specified boolean value to affect the inability to get swallowed into
+a WindowMaker dock (default: False).
+
+
+[environment]
+If set \fBMAIL\fR is the mail spool or maildir directory to use,
+unless otherwise specified on the command line.
+
+
+[copyright]
+Copyright (c) 1998-2001, Trent Piepho.
+.br
+Copyright of modifications held by their respective authors.
+.PP
+Licensed under the GNU General Public License v2 (GPL).
+
+
+[author]
+Original XLassie by Trent Piepho <xyzzy@speakeasy.org>.
+.br
+Modified by
+.br
+ - Barak A. Pearlmutter <barak@cs.may.ie>
+.br
+ - Nadim Shaikli <nadim@arabeyes.org>.
--- xlassie-1.8.orig/xlassie.lsm
+++ xlassie-1.8/xlassie.lsm
@@ -1,7 +1,7 @@
 Begin3
 Title:          XLassie
-Version:        1.8
-Entered-date:	29MAY01
+Version:        1.5
+Entered-date:	13JAN00
 Description:    XLassie is an enhanced version of XBiff.  Support for POP3 or
 		IMAP mailservers, ability to run a command when clicked on,
 		written in straight xlib so memory usage is less, and it
@@ -11,7 +11,7 @@ Keywords:       mail notification biff x
 Author:         xyzzy@speakeasy.org (Trent Piepho)
 Maintained-by:  xyzzy@speakeasy.org (Trent Piepho)
 Primary-site:   ftp.u.washington.edu /public/xyzzy
-		19kB xlassie-1.8.tar.gz
+		17kB xlassie-1.5.tar.gz
 Alternate-site: sunsite.unc.edu /pub/Linux/X11/xapps
 Platforms:	X11
 Copying-policy: GPL
--- xlassie-1.8.orig/xlassie.spec
+++ xlassie-1.8/xlassie.spec
@@ -16,24 +16,27 @@ BuildRoot:	/tmp/xlassie
 %description
 XLassie is an enhanced version of XBiff.  Support for POP3 mailservers,
 ability to run a command when clicked on, written in straight xlib so memory
-usage is less, and it doesn't just tell you _if_ you have new mail, but how
-many new messages you have.  Extra support to operate as a KDE or WindowMaker 
+usage is less, and it not only tells you _if_ you have new mail, but how
+many new messages you have.  Extra support to operate as a KDE or WindowMaker
 dock applet, in addition to plain old X11 mode.
 
 %prep
 %setup
 
 %build
-make CFLAGS="$RPM_OPT_FLAGS"
+make CFLAGS="$RPM_OPT_FLAGS" xlassie xlassie.1x
 
 %install
 rm -rf $RPM_BUILD_ROOT
 install -d -m 755 $RPM_BUILD_ROOT/usr/X11R6/bin
 install -s -m 755 xlassie $RPM_BUILD_ROOT/usr/X11R6/bin
+install -d -m 755 $RPM_BUILD_ROOT/usr/X11R6/man/man1
+install -s -m 755 xlassie.1x $RPM_BUILD_ROOT/usr/X11R6/man/man1
 
 %files
 %attr(-, root, root) %doc README xlassie.lsm
 %attr(-, root, root) /usr/X11R6/bin/xlassie
+%attr(-, root, root) /usr/X11R6/man/man1/xlassie.1x
 
 %clean
 rm -rf $RPM_BUILD_ROOT
