debian/0000775000000000000000000000000011642632105007170 5ustar debian/README.debian0000664000000000000000000000211011460253752011270 0ustar SECURITY INFO: Xlassie processes mail server passwords, which means that there are security implication to its use. You need to avoid having passwords present in ways other users can observe. One way to avoid this is to invoke it as ssh-askpass "POP Password" | xlassie -password ask ... The script /usr/share/doc/xlassie/examples/xlassie-auto shows another reasonably secure yet convenient way to invoke xlassie, assuming you trust your file system's security. With either of these, you remain vulnerable to someone touching your console for a second to run a program that pokes through xlassie's memory image, grovels out the password, and sends it to the evildoer. Aside from this, POP-3 is not a secure protocol, so network sniffing can reveal the clear text password. To defeat this, at boot time I set up an stunnel connection between localhost and the POP-3 server. Then xlassie can connect to localhost instead of the real mail server. USAGE HINTS You might need to use the -nokde option when under wmaker. It seems to pick up hints for both. At least, this is what I do. debian/patches/0000755000000000000000000000000011642632105010615 5ustar debian/patches/debian-changes0000644000000000000000000021327311642632105013400 0ustar Description: TODO: Put a short summary on the line above and replace this paragraph with a longer explanation of this change. Complete the meta-information with other relevant fields (see below for details). To make it easier, the information below has been extracted from the changelog. Adjust it or drop it. . xlassie (1.8-21) unstable; urgency=low . * bump standards version (debian/control) * dh --parallel * dh 8 * use updated upstream Makefile (debian/rules) * single-debian-patch source option Author: Barak A. Pearlmutter --- The information above should follow the Patch Tagging Guidelines, please checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here are templates for supplementary fields that you might want to add: Origin: , Bug: Bug-Debian: http://bugs.debian.org/ Bug-Ubuntu: https://launchpad.net/bugs/ Forwarded: Reviewed-By: Last-Update: --- 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/xlassie.c +++ xlassie-1.8/xlassie.c @@ -1,5 +1,7 @@ /* Copyright (C) 1998 Trent Piepho * (C) 1999-2001 Trent Piepho + * Updates (C) 2004 Barak A. Pearlmutter + * Nadim Shaikli * * 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 @@ -17,848 +19,1247 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include #include #include +#include #include + #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; + +/* Alloc and limit string lengths for potential security reasons */ +char opt_spool[256]; +char opt_username[32]; +char opt_password[32]; +char opt_mailcommand[256]; +char opt_clickcommand[256]; + +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, opt_spool}, + {"mailcommand", "mailcmd", False, False, opt_mailcommand}, + {"clickcommand", "clickcmd", False, False, opt_clickcommand}, + {"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, opt_username}, + {"password", "password", False, False, opt_password}, + {"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 \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 Set app name\n"); - printf(" -bg Background color [%s]\n",BgColor); - printf(" -fg 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 Check mail every 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 to execute on new mail arrival\n"); - printf(" -fn Font for the new mail count\n"); - printf(" -display X server to connect to\n"); - printf(" -shape Use a shaped window\n"); - printf(" -file File to use for mail spool or maildir directory\n"); - printf(" -command Command to execute when clicked on\n"); -#ifdef POP3 - printf(" -pop3 Connect to pop3 server rather than local mail spool\n"); - printf(" -apop3 Like -pop3, but uses a diferent method.\n"); - printf(" Use when -pop3 doesn't find the correct number\n"); - printf(" -imap Use the IMAP protocol instead of pop3\n"); - printf(" -username Username for pop3/imap server\n" - " if different from local username\n"); - printf(" -password 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;iold) { + 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 Set application class name (default: %s)\n", optList[NAME].value); + printf(" -bg Background color (default: %s)\n", optList[BACKGROUND].value); + printf(" -fg Foreground color (default: %s)\n", optList[FOREGROUND].value); + printf(" -hilight [] Use a different foreground color when there\n" + " is non-zero mail (default: %s)\n", optList[HIGHLIGHT].value); + printf(" -update Check mail every 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 [] Light-up keyboard LED if mail exists\n"); + printf(" (default: %d)\n", atoi(optList[LED].value)); + printf(" -fn Font for the new mail count\n"); + printf(" -display X server to connect to\n"); + printf(" -geometry Window geometry\n"); + printf(" -shape Use a shaped window\n"); + printf(" -spool File to use for mail spool or maildir directory\n"); + printf(" -mailcommand Command to execute on new mail arrival\n"); + printf(" -clickcommand Command to execute when clicked upon\n"); + printf(" (default: %s)\n", optList[CLICKCOMMAND].value); + printf(" -offset Mail display count offset (for debugging)\n"); +#ifdef HAVE_POP3 + printf(" -pop3 Connect to pop3 server rather than local mail spool\n"); + printf(" -apop3 Like -pop3, but uses a different method.\n"); + printf(" Use when -pop3 doesn't find the correct number\n"); + printf(" -imap Use the IMAP protocol instead of pop3\n"); + printf(" -imapfolder Use this folder instead of INBOX\n"); + printf(" -username Username for pop3/imap server,\n" + " when different from local username\n"); + printf(" -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() +{ + int i; - 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); - }; + printf("Mail account password: "); + fgets(optList[PASSWORD].value, sizeof(opt_password), stdin); + i = strlen(optList[PASSWORD].value)-1; + if(optList[PASSWORD].value[i] == '\n') + optList[PASSWORD].value[i] = '\0'; } -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; + strcpy(optList[SPOOL].value, optarg); + break; + case 13: + optList[MAILCOMMAND].isSet = True; + strcpy(optList[MAILCOMMAND].value, optarg); + break; + case 14: + optList[CLICKCOMMAND].isSet = True; + strcpy(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; + strcpy(optList[SPOOL].value, optarg); + break; + case 17: + optList[APOP3].isSet = True; + optList[SPOOL].isSet = True; + strcpy(optList[SPOOL].value, optarg); + break; + case 18: + optList[IMAP].isSet = True; + optList[SPOOL].isSet = True; + strcpy(optList[SPOOL].value, optarg); + break; + case 19: + optList[FOLDERNAME].isSet = True; + strcpy(optList[FOLDERNAME].value, optarg); + break; + case 20: + optList[USERNAME].isSet = True; + strcpy(optList[USERNAME].value, optarg); + break; + case 21: + optList[PASSWORD].isSet = True; + strcpy(optList[PASSWORD].value, 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) { + sprintf(optList[SPOOL].value, "/var/spool/mail/%s", + pwd->pw_name); + } else { + strcpy(optList[SPOOL].value, mail); + } + + /* Set some defaults requiring external struct accesses */ + strcpy(optList[CLICKCOMMAND].value, COMMAND); + strcpy(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;iread=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;id_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(); + } } --- 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 --- /dev/null +++ xlassie-1.8/xlassie.h2m @@ -0,0 +1,163 @@ +Include file for help2man man page +$Id: xlassie.h2m,v 1.3 2004-11-25 12:33:56 bap Exp $ + +[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 '-command' (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-up 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 . +.br +Modified by +.br + - Barak A. Pearlmutter +.br + - Nadim Shaikli . --- 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/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/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 --- 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/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: debian/patches/series0000644000000000000000000000001711642632105012030 0ustar debian-changes debian/source/0000775000000000000000000000000011642631563010477 5ustar debian/source/format0000664000000000000000000000001411460253752011703 0ustar 3.0 (quilt) debian/control0000664000000000000000000000150111642631621010572 0ustar Source: xlassie Section: x11 Priority: optional Maintainer: Barak A. Pearlmutter Standards-Version: 3.9.2 Build-Depends: help2man, debhelper (>= 8), libx11-dev, libxt-dev, libxext-dev, x11proto-core-dev Homepage: http://www.speakeasy.org/%7Exyzzy/xlassie/ Vcs-Git: git://git.debian.org/git/collab-maint/xlassie.git Vcs-Browser: http://git.debian.org/?p=collab-maint/xlassie.git Package: xlassie Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Dockable mail notifier w/ message count & POP3/APOP/IMAP support Enhanced pending mail notifier. Displays the number of waiting messages. Supports local mail spool and POP3/APOP3/IMAP mail servers. Can run a command when clicked upon. Uses plain xlib, so memory footprint is tiny. Can operate as plain app or WindowMaker/KDE dock applet. debian/examples0000664000000000000000000000002411460253752010732 0ustar debian/xlassie-auto debian/changelog0000664000000000000000000001253111642632020011040 0ustar xlassie (1.8-21) unstable; urgency=low * bump standards version (debian/control) * dh --parallel * dh 8 * use updated upstream Makefile (debian/rules) * single-debian-patch source option -- Barak A. Pearlmutter Tue, 04 Oct 2011 17:28:00 +0100 xlassie (1.8-20) unstable; urgency=low * bump deb standards * Switch to dpkg-source 3.0 (quilt) format -- Barak A. Pearlmutter Thu, 25 Mar 2010 18:56:42 +0000 xlassie (1.8-19) unstable; urgency=low * correct some minor typos and an inconsequential lintian issue -- Barak A. Pearlmutter Wed, 20 Jan 2010 18:39:01 +0100 xlassie (1.8-18) unstable; urgency=low * rev deb policy * fancier, and lintian clean, debian/rules -- Barak A. Pearlmutter Fri, 25 Sep 2009 16:00:22 -0400 xlassie (1.8-17) unstable; urgency=low * lintian issues, rev deb policy, rev dh -- Barak A. Pearlmutter Tue, 19 Aug 2008 12:28:14 +0100 xlassie (1.8-16) unstable; urgency=low * debian house keeping (menu section changes, build dependency changes) * Add homepage field to debian/control -- Barak A. Pearlmutter Wed, 30 Jan 2008 12:10:14 +0000 xlassie (1.8-15) unstable; urgency=low * factor out stripping vs installing in Makefile (closes: #438302) -- Barak A. Pearlmutter Thu, 16 Aug 2007 16:16:40 +0100 xlassie (1.8-14) unstable; urgency=low * add debian/watch file * use exponential notation when message count exceeds 99 -- Barak A. Pearlmutter Tue, 12 Sep 2006 16:23:14 +0100 xlassie (1.8-13) unstable; urgency=low * imap folder option patch from Benjamin Bayart (closes: #381457) -- Barak A. Pearlmutter Fri, 4 Aug 2006 18:31:40 +0100 xlassie (1.8-12) unstable; urgency=low * fix mail dir bug, thanks to Dan Aloni -- Barak A. Pearlmutter Thu, 1 Jun 2006 13:07:07 +0100 xlassie (1.8-11) unstable; urgency=low * missing libxt-dev build dependency (closes: #347005) -- Barak A. Pearlmutter Tue, 17 Jan 2006 11:21:01 +0000 xlassie (1.8-10) unstable; urgency=low * account for broken (apart) xlibs (closes: #347005) -- Barak A. Pearlmutter Mon, 9 Jan 2006 11:12:44 +0000 xlassie (1.8-9) unstable; urgency=low * versioned debhelper build dependency * mail count offset option, for debugging * use GNU getopt() for non-X option parsing * rework previously blecherous font search code * also patch from Nadim Shaikli including: * added Xresource abilities; can set all options (closes: #282548) * document Xresources in man pages * rename options -file to -spool and -command to -clickcommand * fix the update interval logic for pop/imap * various minor improvements for consistency and readability -- Barak A. Pearlmutter Thu, 25 Nov 2004 12:35:16 +0000 xlassie (1.8-8) unstable; urgency=low * policy rev * patch from Nadim Shaikli (closes: #280804) including: * count>99 overflowed window; now displays "F" (closes: #265155) * added/documented -led option to toggle keyboard LED upon mail reception * added gracefully quit by pressing 'q' on window * minor typo/location changes in help and manpage for consistency * man page improvements (reworked to use help2man --include) -- Barak A. Pearlmutter Fri, 12 Nov 2004 12:24:56 -0700 xlassie (1.8-7) unstable; urgency=low * document -geometry option in -help option * fix -verbose option bug (printed noise regardless) -- Barak A. Pearlmutter Thu, 5 Aug 2004 19:13:10 -0500 xlassie (1.8-6) unstable; urgency=low * tone down verbosity -- Barak A. Pearlmutter Mon, 3 Mar 2003 20:57:25 +0000 xlassie (1.8-5) unstable; urgency=low * add option to re-count mail upon click, as default * add --verbose option -- Barak A. Pearlmutter Fri, 28 Feb 2003 00:49:10 +0000 xlassie (1.8-4) unstable; urgency=low * update debian infrastructure * stop setting /usr/doc link -- Barak A. Pearlmutter Sat, 8 Feb 2003 14:45:43 +0000 xlassie (1.8-3) unstable; urgency=low * switch dependency order (closes: #170241) -- Barak Pearlmutter Thu, 21 Nov 2002 23:26:50 -0700 xlassie (1.8-2) unstable; urgency=low * text-only mods, no change to any functionality (closes: #166358) -- Barak Pearlmutter Sun, 27 Oct 2002 22:10:27 -0700 xlassie (1.8-1) unstable; urgency=low * integrate upstream mods -- Barak Pearlmutter Tue, 26 Feb 2002 15:16:10 -0700 xlassie (1.7-3) unstable; urgency=low * fiddle with default fonts (closes: #102613) * add README.debian with discussion of security (addresses #102612) -- Barak Pearlmutter Thu, 12 Jul 2001 16:00:49 -0600 xlassie (1.7-2) unstable; urgency=low * rephrase description * add build dependencies (closes: #98142) -- Barak Pearlmutter Mon, 21 May 2001 00:16:16 -0600 xlassie (1.7-1) unstable; urgency=low * invoke help2man * add --help and --version switches * Generalize font specs. * New upstream release. -- Barak Pearlmutter Wed, 16 May 2001 01:10:55 -0600 xlassie (1.5-1) unstable; urgency=low * Initial release. -- Barak A. Pearlmutter Mon, 10 Jul 2000 14:33:50 -0700 debian/copyright0000664000000000000000000000105511460253752011131 0ustar This package was debianized by Barak Pearlmutter on Mon, 10 Jul 2000 14:33:50 -0700. Downloaded from http://www.speakeasy.org/~xyzzy/download/xlassie-1.8.tar.gz on 26-Feb-2002. Author: Trent Piepho http://www.speakeasy.org/%7Exyzzy/ Copyright: Copyright (C) 1998 Trent Piepho You are free to distribute this software under the terms of the GNU General Public License, version 2. On Debian systems, the complete text of this license can be found in /usr/share/common-licenses/GPL-2. debian/compat0000664000000000000000000000000211476735253010403 0ustar 8 debian/menu0000664000000000000000000000017111460253752010063 0ustar ?package(xlassie):needs="X11" section="Applications/Network/Communication"\ title="xlassie" command="/usr/bin/xlassie" debian/xlassie-auto0000775000000000000000000000044211460253752011541 0ustar #!/bin/sh # This is a tiny little script suitable for invocation within an X # startup script such as GNUstep/Library/WindowMaker/autostart cat ~/personal/pop-mail-password \ | xlassie -pop3 localhost -password ask -offline \ -fg black -hilight red \ -bell -update 60 -nokde debian/xlassie-remote-loop0000775000000000000000000000053111460253752013032 0ustar #!/bin/sh -f if [ $# = 0 -o x$1 = x-h ]; then p=$(basename $0) echo "Usage: $p host [remote xlassie options]" echo " runs xlassie on remote host via ssh, restarting upon exit" exit 1 fi h=$1 shift while true; do ssh -n -X ${h} xlassie "$@" echo -n "remote xlassie terminated ..." sleep 10 echo " restarting" done debian/rules0000775000000000000000000000014311476735253010263 0ustar #!/usr/bin/make -f %: dh $@ --parallel override_dh_auto_install: dh_auto_install -- prefix=/usr debian/watch0000664000000000000000000000031311460253752010223 0ustar # Watch control file. # Run uscan(1) to check for upstream updates and more. version=3 http://www.speakeasy.org/%7Exyzzy/xlassie/ \ http://www.speakeasy.org/~xyzzy/download/xlassie-([\d\.]*)\.tar\.gz