xbuffy-3.3.bl.3.orig/0000755000175000017500000000000010413454202012471 5ustar brlbrlxbuffy-3.3.bl.3.orig/xbuffy.c0000644000175000017500000012103006546412470014152 0ustar brlbrl/******************************************************************************* Copyright (c) 1994,1995 William Pemberton (wfp5p@virginia.edu) The X Consortium, and any party obtaining a copy of these files from the X Consortium, directly or indirectly, is granted, free of charge, a full and unrestricted irrevocable, world-wide, paid up, royalty-free, nonexclusive right and license to deal in this software and documentation files (the "Software"), including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons who receive copies from any such party to do so. This license includes without limitation a license to do the foregoing actions under any patents of the party supplying this software to the X Consortium. *******************************************************************************/ /* xbuffy - Bill's version of the multiple mailbox biff Author: Bill Pemberton, wfp5p@virginia.edu This is a modified version of xmultibiff 2.0 by: John Reardon, Midnight Networks, badger@midnight.com, 1993. */ #include #include #include #include #include #include #include #include #ifndef SUN #include #include #endif /* SYSV */ #include "xbuffy.h" #ifndef USE_MOTIF #include #include #include #include #include #include #include #else #include #include #include #include /* #define XtNbackground XmNbackground #define XtNforeground XmNforeground #define XtNwidth XmNwidth #define XtNheight XmNheight #define XtNlabel XmNvalue */ #endif #ifdef USE_LED #include #endif #include "xbuffy.xbm" #ifdef WFP_DEBUG #include "/home/wfp5p/bin/debug_include/malloc.h" #endif void CheckBox(); void TimerBreakPopup(); int CountUnixMail(); void ParseMailPath(); int makeBoxTitle(); void initBox(); Pixel convertColor(); void ButtonDownHandler(); void ButtonUpHandler(); void BreakPopup(); void ExecuteCommand(); void setBoxColor(); void PopupHeader(); char *EliminatePath(); void UpdateBoxNumber(); /** globals **/ char versionString[MAX_STRING]; char *programName; Widget toplevel; Widget *header; ApplicationData_t data; XtAppContext app; DynObject DynBoxObj; BoxInfo_t *boxInfo; int *headerUp; int nBoxes = 0; int envPolltime = 0; int envPriority = 0; int envHeadertime = 0; int NNTPinit = 0; int maxBoxSize = 0; FILE *NNTP_fIn, *NNTP_fOut; extern char **environ; XtResource resources[] = { {"mailboxes", "Mailboxes", XtRString, sizeof(String), XtOffset(ApplicationData_t *, mailBoxes), XtRString, 0}, {"nobeep", "Nobeep", XtRBoolean, sizeof(int), XtOffset(ApplicationData_t *, nobeep), XtRString, "FALSE"}, {"horiz", "Horiz", XtRBoolean, sizeof(int), XtOffset(ApplicationData_t *, horiz), XtRString, "FALSE"}, {"command", "Command", XtRString, sizeof(String), XtOffset(ApplicationData_t *, command), XtRString, 0}, {"names", "Names", XtRBoolean, sizeof(int), XtOffset(ApplicationData_t *, longNames), XtRString, "FALSE"}, {"shortnames", "Shortnames", XtRBoolean, sizeof(int), XtOffset(ApplicationData_t *, shortNames), XtRString, "FALSE"}, {"polltime", "Polltime", XtRString, sizeof(String), XtOffset(ApplicationData_t *, pollTime), XtRString, "60"}, {"priority", "Priority", XtRString, sizeof(String), XtOffset(ApplicationData_t *, priority), XtRString, "15"}, {"headertime", "Headertime", XtRString, sizeof(String), XtOffset(ApplicationData_t *, headerTime), XtRString, 0}, {"orig", "Orig", XtRBoolean, sizeof(int), XtOffset(ApplicationData_t *, origMode), XtRString, "FALSE"}, {"audiocmd", "Audiocmd", XtRString, sizeof(String), XtOffset(ApplicationData_t *, audioCmd), XtRString, 0}, {"boxfile", "Boxfile", XtRString, sizeof(String), XtOffset(ApplicationData_t *, boxFile), XtRString, 0}, {"center", "Center", XtRBoolean, sizeof(int), XtOffset(ApplicationData_t *, center), XtRString, "FALSE"}, {"fill", "Fill", XtRBoolean, sizeof(int), XtOffset(ApplicationData_t *, fill), XtRString, "FALSE"}, {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), XtOffset(ApplicationData_t *, fg), XtRString, XtDefaultForeground}, {XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel), XtOffset(ApplicationData_t *, bg), XtRString, XtDefaultBackground}, #ifdef USE_NNTP {"newsboxes", "Newsboxes", XtRString, sizeof(String), XtOffset(ApplicationData_t *, newsBoxes), XtRString, 0}, #endif /* USE_NNTP */ }; XrmOptionDescRec options[] = { {"-nobeep", "*nobeep", XrmoptionNoArg, "TRUE"}, {"-center", "*center", XrmoptionNoArg, "TRUE"}, {"-fill", "*fill", XrmoptionNoArg, "TRUE"}, {"-horiz", "*horiz", XrmoptionNoArg, "TRUE"}, {"-names", "*names", XrmoptionNoArg, "TRUE"}, {"-shortnames", "*shortnames", XrmoptionNoArg, "TRUE"}, {"-acmd", "*audiocmd", XrmoptionSepArg, 0}, {"-poll", "*polltime", XrmoptionSepArg, 0}, {"-priority", "*priority", XrmoptionSepArg, 0}, {"-header", "*headertime", XrmoptionSepArg, 0}, {"-orig", "*orig", XrmoptionNoArg, "TRUE"}, {"-boxfile", "*boxfile", XrmoptionSepArg, 0}, {"-command", "*command", XrmoptionSepArg, 0}, }; void CheckBox(i) int i; { int num = 0; Arg args[5]; int nargs; static BoxInfo_t *tempNews = 0; BoxInfo_t *currentBox; int found; static char *mailHeader = NULL; int headerSize; Boolean beenTouched; Boolean isIcon = FALSE; currentBox = &boxInfo[i]; #ifdef USE_NNTP if (boxInfo[i].type == NNTPBOX) { num = CountNNTP(currentBox, NULL, &beenTouched); } #endif /* USE_NNTP */ if ((boxInfo[i].type == MAILBOX) || (boxInfo[i].type == MAILDIR) || (boxInfo[i].type == MHDIR)) { num = CountUnixMail(currentBox, NULL, &beenTouched); } nargs = 0; XtSetArg(args[nargs], XtNiconic, &isIcon); if ((num > currentBox->n) || ((!currentBox->origMode) && ((num != currentBox->n) || (beenTouched)))) { if ((currentBox->headerTime != 0) && (!isIcon) && (num > 0)) { PopupHeader(currentBox->w, currentBox->boxNum, 0, 0); } if ((!currentBox->nobeep) && (num > 0)) { if (currentBox->audioCmd != NULL) { system(currentBox->audioCmd); } else { XBell(XtDisplay(currentBox->w), 0); } } } if (currentBox->n != num) { currentBox->n = num; UpdateBoxNumber(currentBox); } XtAppAddTimeOut(app, (currentBox->pollTime * 1000), CheckBox, (XtPointer) i); } void setBoxColor(box,status) BoxInfo_t *box; int status; { Arg args[5]; int nargs; nargs = 0; if (status) { XtSetArg(args[nargs], XtNbackground, box->fg); nargs++; XtSetArg(args[nargs], XtNforeground, box->bg); nargs++; } else { XtSetArg(args[nargs], XtNbackground, box->bg); nargs++; XtSetArg(args[nargs], XtNforeground, box->fg); nargs++; } XtSetValues(box->w, args, nargs); } void UpdateBoxNumber(box) BoxInfo_t *box; { char amt[MAX_STRING]; char fmtString[MAX_STRING]; char *ptr; int offset; Arg args[5]; int nargs; #ifdef USE_MOTIF XmString label; #endif #ifdef USE_LED if (box->led != -1) { char l[17]; if (box->n > 0) { if (box->pid > 1) { if (!kill(box->pid, SIGINT)) waitpid(box->pid, NULL, 0); /* else perror("Failing to kill led"); */ } switch (box->pid = fork()) { case -1: perror("Fork failure"); break; case 0: sprintf(amt, "%d", box->n); sprintf(l, "%d", box->led); if (execlp("led", "led", l, amt, (char*)NULL) == -1) { fprintf(stderr, "Error executing led\n"); _exit(1); } default: } } else { if (box->pid > 1) if (!kill(box->pid, SIGINT)) { waitpid(box->pid, NULL, 0); box->pid = 0; } else perror("Failing to kill led"); } } #endif if (box->boxTitle != NULL) { sprintf(amt, "%s: %d", box->boxTitle, box->n); } else { sprintf(amt, "%d", box->n); } memset(fmtString, ' ',MAX_STRING); if (data.center) /* center implies fill */ { offset = ((maxBoxSize+4) - NEWstrlen(amt))/2; if (offset < 0) offset = 0; if (offset > MAX_STRING) offset = 0; ptr = fmtString+ offset; strcpy(ptr,amt); ptr = fmtString+NEWstrlen(fmtString); *ptr = ' '; *(ptr+offset+1-(offset%2))='\0'; } else if (data.fill) { offset = maxBoxSize+4-NEWstrlen(amt); if (offset < 0) offset = 0; strcpy(fmtString,amt); ptr = fmtString+NEWstrlen(fmtString); while (offset-- >0) *ptr++ = ' '; *ptr = '\0'; } else { strcpy(fmtString, amt); } nargs = 0; if (!box->origMode) { if (box->n > 0) { setBoxColor(box,1); } else { setBoxColor(box,0); } } #ifdef USE_MOTIF label = XmStringCreateSimple(amt); XtSetArg(args[nargs], XmNlabelString, label); nargs++; #else XtSetArg(args[nargs], XtNlabel, fmtString); nargs++; #endif XtSetValues(box->w, args, nargs); #ifdef USE_MOTIF XmStringFree(label); #endif } #ifdef USE_MOTIF static void dimension_text(char *hdrPtr, int *rows, int *cols) { int curwidth; *rows = 0; *cols = 0; curwidth = 0; while (*hdrPtr != '\0') { if (*hdrPtr == '\n') { (*rows)++; if (curwidth > *cols) *cols = curwidth; curwidth = 0; } else curwidth++; hdrPtr++; } } #endif /* event handlers that decides what to do with button clicks */ void ButtonDownHandler(w, i, event, cont) Widget w; int *i; XEvent *event; Boolean *cont; { if (event->xbutton.button == 1) { PopupHeader(w, *i, event, cont); } /* don't do anything else for other button clicks */ } void ButtonUpHandler(w, i, event, cont) Widget w; int *i; XEvent *event; Boolean *cont; { if (event->xbutton.button == 1) { BreakPopup(w, *i, event, cont); } else if (event->xbutton.button == 2) { ExecuteCommand(w, *i, event, cont); } else if (event->xbutton.button == 3) { BoxInfo_t *currentBox; currentBox = &boxInfo[*i]; setBoxColor(currentBox,0); #ifdef USE_LED if (currentBox->led != -1) if (currentBox->pid > 1) if (!kill(currentBox->pid, SIGINT)) { waitpid(currentBox->pid, NULL, 0); currentBox->pid = 0; } else perror("Failing to kill led"); #endif } } void PopupHeader(w, i, event, cont) Widget w; int i; XEvent *event; Boolean *cont; { Arg args[5]; int nargs; Widget tmpCommand; Position biff_x, biff_y, root_x, root_y; static XtIntervalId timerID; static int rootH = 0; static int rootW = 0; int number = 0; static Boolean firstTime = TRUE; static DynObject mailHeaders; static char *hdrPtr; Dimension headerW, headerH; BoxInfo_t *currentBox; Boolean beenTouched; #ifdef USE_MOTIF int rows, cols; #endif currentBox = &boxInfo[i]; if (rootH == 0) { rootH = DisplayHeight(XtDisplay(w), DefaultScreen(XtDisplay(w))); rootW = DisplayWidth(XtDisplay(w), DefaultScreen(XtDisplay(w))); } if ((!firstTime) && (DynSize(mailHeaders) != 0)) { DynDestroy(mailHeaders); } firstTime = FALSE; mailHeaders = DynCreate(sizeof(char), MAX_STRING); #ifdef DEBUG DynDebug(mailHeaders, 1); DynParanoid(mailHeaders, 1); #endif #ifdef USE_NNTP /* check to see if there is any news before proceeding */ if (boxInfo[i].type == NNTPBOX) { number = CountNNTP(&boxInfo[i], mailHeaders, &beenTouched); DynAdd(mailHeaders, "\0"); hdrPtr = (char *) DynGet(mailHeaders, 0); } #endif /* update the number on the box (in case there are new articles) */ if ((currentBox->type == MAILBOX) || (currentBox->type == MAILDIR) || (currentBox->type == MHDIR)) { number = CountUnixMail(currentBox, mailHeaders, &beenTouched); DynAdd(mailHeaders, "\0"); hdrPtr = (char *) DynGet(mailHeaders, 0); } /* if the number is different, update it */ currentBox->n = number; UpdateBoxNumber(&boxInfo[i]); /* if the number is zero, there's no header, so leave */ if (boxInfo[i].n == 0) { return; } /* if its already up, pop it down, because we must update it */ if (headerUp[i] == TRUE) { XtRemoveTimeOut(timerID); BreakPopup(0, i, 0, 0); } /* Calculate Relative position -> Root absolute position */ nargs = 0; XtSetArg(args[nargs], XtNwidth, &biff_x); nargs++; XtSetArg(args[nargs], XtNheight, &biff_y); nargs++; XtGetValues(w, args, nargs); XtTranslateCoords(w, biff_x, biff_y, &root_x, &root_y); header[i] = XtCreatePopupShell(currentBox->boxTitle, transientShellWidgetClass, currentBox->w, 0, 0); nargs = 0; #ifndef USE_MOTIF XtSetArg(args[nargs], XtNlabel, hdrPtr); nargs++; XtSetArg(args[nargs], XtNhighlightThickness, 0); nargs++; tmpCommand = XtCreateManagedWidget("popup", commandWidgetClass, header[i], args, nargs); XtAddCallback(tmpCommand, XtNcallback, BreakPopup, (XtPointer) i); #else dimension_text((char *) hdrPtr, &rows, &cols); XtSetArg(args[nargs], XmNvalue, hdrPtr); nargs++; XtSetArg(args[nargs], XmNeditMode, XmMULTI_LINE_EDIT); nargs++; XtSetArg(args[nargs], XmNeditable, False); nargs++; XtSetArg(args[nargs], XmNrows, (short) rows); nargs++; XtSetArg(args[nargs], XmNcolumns, (short) cols); nargs++; tmpCommand = XmCreateText(header[i], "popup", args, nargs); XtManageChild(tmpCommand); XtAddCallback(tmpCommand, XmNactivateCallback, BreakPopup, (XtPointer) i); #endif if (!XtIsRealized(header[i])) { XtRealizeWidget(header[i]); } /* see where we should put this thing so its on the screen */ /* i.e. make sure we can see it */ nargs = 0; XtSetArg(args[nargs], XtNwidth, &headerW); nargs++; XtSetArg(args[nargs], XtNheight, &headerH); nargs++; XtGetValues(header[i], args, nargs); if (((int) root_x + (int) headerW) >= (rootW - 20)) { root_x = (Position) rootW - ((Position) headerW + 5); } if (((int) root_y + (int) headerH) >= (rootH - 20)) { root_y = (Position) rootH - ((Position) headerH + 40); } nargs = 0; XtSetArg(args[nargs], XtNx, root_x); nargs++; XtSetArg(args[nargs], XtNy, root_y); nargs++; XtSetValues(header[i], args, nargs); XtPopup(header[i], XtGrabNone); headerUp[i] = TRUE; /* free alloc'ed string */ /* register a routine to pop it down if it was invoked from a routine */ if (event == 0) { timerID = XtAppAddTimeOut(app, (currentBox->headerTime * 1000), TimerBreakPopup, (XtPointer) i); } } void TimerBreakPopup(i) int i; { BreakPopup(0, i, 0, 0); } void BreakPopup(w, i, event, cont) Widget w; int i; XEvent *event; Boolean *cont; { if (headerUp[i] != TRUE) { return; } XtPopdown(header[i]); XtDestroyWidget(header[i]); headerUp[i] = FALSE; } void ExecuteCommand(w, i, event, cont) Widget w; int i; XEvent *event; Boolean *cont; { BoxInfo_t *currentBox; currentBox = &boxInfo[i]; #ifdef USE_LED if (currentBox->led != -1) if (currentBox->pid > 1) if (!kill(currentBox->pid, SIGINT)) { waitpid(currentBox->pid, NULL, 0); currentBox->pid = 0; } else perror("Failing to kill led"); #endif if (currentBox->command != NULL) { system(currentBox->command); } } int isLocked(mbox) char *mbox; { /* right now this is a REAL stupid function, it just looks for a .lock file */ char *lockfile; int retVal; lockfile = (char *) malloc( (NEWstrlen(mbox)+15)*sizeof(char)); strcpy(lockfile, mbox); strcat(lockfile, ".lock"); retVal = exists(lockfile); free(lockfile); return(retVal); } int CountMBoxMail(mailBox, headerString) BoxInfo_t *mailBox; DynObject headerString; { FILE *fp = 0; char buffer[MAX_STRING]; char From[MAX_STRING], Subject[MAX_STRING]; register int count = 0; int status = UNKNOWN; register Boolean in_header = FALSE; fp = fopen(mailBox->box, "r"); if (fp == NULL) return 0; From[0] = Subject[0] = '\0'; while (fgets(buffer, MAX_STRING - 2, fp) != 0) { long CL = 0L; int has_CL = FALSE; buffer[MAX_STRING - 1] = '\0'; /* just in case */ if ((strchr(buffer, '\n') == NULL) && (!feof(fp))) { int c; while ((c = getc(fp)) != EOF && c != '\n'); /* keep reading */ } if ((!in_header) && (real_from(buffer))) { has_CL = FALSE; in_header = TRUE; status = NEW_MSG; } else if (in_header) { if (header_cmp(buffer, "From", NULL)) { strcpy(From, buffer); } if (header_cmp(buffer, "Content-Length", NULL)) { has_CL = TRUE; CL = atol(buffer+15); } if (header_cmp(buffer, "Subject", NULL)) { strcpy(Subject, buffer); } if (header_cmp(buffer, "Status", NULL)) { remove_header_keyword(buffer); if (*buffer == 'N') status = NEW_MSG; else status = READ_MSG; } else if (buffer[0] == LINEFEED) { #ifdef USE_CONTENT_LENGTH if (has_CL) fseek(fp,CL,SEEK_CUR); #endif in_header = FALSE; if ((status == NEW_MSG) || (mailBox->origMode)) { count++; if (headerString != NULL) { if (NEWstrlen(From) != 0) DynInsert(headerString, ((DynHigh(headerString) > 0) ? (DynSize(headerString)) : 0), From, NEWstrlen(From)); if (NEWstrlen(Subject) != 0) DynInsert(headerString, ((DynHigh(headerString) > 0) ? (DynSize(headerString)) : 0), Subject, NEWstrlen(Subject)); } } From[0] = Subject[0] = '\0'; } } } fclose(fp); return count; } int CountDirMail(mailBox, headerString) BoxInfo_t *mailBox; DynObject headerString; { DIR *dp = 0; FILE *fp = 0; char buffer[MAX_STRING]; char From[MAX_STRING], Subject[MAX_STRING]; char path[_POSIX_PATH_MAX]; int status; register Boolean found = FALSE; register Boolean mailfile = TRUE; struct dirent *de; register int count = 0; if (mailBox->type == MAILDIR) { sprintf(path, "%s/new", mailBox->box); } else { strcpy(path,mailBox->box); } dp = opendir(path); if (dp == NULL) return 0; while ((de = readdir (dp)) != NULL) { mailfile = TRUE; if (mailBox->type == MHDIR) { char *p; p = de->d_name; while (*p && mailfile) { if (!isdigit (*p)) mailfile = FALSE; p++; } } else if (mailBox->type == MAILDIR) { if (*de->d_name == '.') mailfile = FALSE; } if (mailfile) { if (mailBox->type == MAILDIR) count++; if (headerString != NULL || mailBox->type == MHDIR) { /* Ok, we need to get the From: and Subject: lines */ From[0] = Subject[0] = '\0'; found = FALSE; status = NEW_MSG; if (mailBox->type == MAILDIR) { sprintf(path, "%s/new/%s",mailBox->box,de->d_name); } else { sprintf(path, "%s/%s",mailBox->box,de->d_name); } fp = fopen(path, "r"); if (fp != NULL) { while (!found && fgets(buffer, MAX_STRING - 2, fp) != 0) { long CL; int has_CL; buffer[MAX_STRING - 1] = '\0'; /* just in case */ if ((strchr(buffer, '\n') == NULL) && (!feof(fp))) { /* read to end of line */ int c; while ((c = getc(fp)) != EOF && c != '\n'); /* keep reading */ } if (headerString != NULL && header_cmp(buffer, "From", NULL)) { strcpy(From, buffer); } else if (headerString != NULL && header_cmp(buffer, "Subject", NULL)) { strcpy(Subject, buffer); } else if (mailBox->type == MHDIR && header_cmp(buffer, "Status", NULL)) { remove_header_keyword(buffer); if (*buffer == 'N') status = NEW_MSG; else status = READ_MSG; } else if (buffer[0] == LINEFEED && (mailBox->type == MAILDIR || status == NEW_MSG)) { if (mailBox->type == MHDIR) count++; if (strlen(From) != 0) DynInsert(headerString, ((DynHigh(headerString) > 0) ? (DynSize(headerString)) : 0), From, strlen(From)); if (strlen(Subject) != 0) DynInsert(headerString, ((DynHigh(headerString) > 0) ? (DynSize(headerString)) : 0), Subject, strlen(Subject)); found = TRUE; } } fclose(fp); } } } } closedir(dp); return count; } int CountUnixMail(mailBox, headerString, beenTouched) BoxInfo_t *mailBox; DynObject headerString; Boolean *beenTouched; { struct stat f_stat; struct timeval t[2]; register int count = 0; char path[_POSIX_PATH_MAX]; *beenTouched = FALSE; if (mailBox->type == MAILBOX) { if (isLocked(mailBox->box)) return (mailBox->n); } if (mailBox->type == MAILDIR) { sprintf(path,"%s/new",mailBox->box); } else { strcpy(path,mailBox->box); } if (stat(path, &f_stat)) { mailBox->st_size = 0; mailBox->box_mtime = 0; return (0); } if ((f_stat.st_size != mailBox->st_size) || (f_stat.st_mtime > mailBox->box_mtime)) { mailBox->st_size = f_stat.st_size; mailBox->box_mtime = f_stat.st_mtime; *beenTouched = TRUE; } if ((!*beenTouched) && (headerString == NULL)) return (mailBox->n); switch (mailBox->type) { case MAILBOX: count = CountMBoxMail(mailBox, headerString); break; case MAILDIR: case MHDIR: count = CountDirMail(mailBox, headerString); break; } /* Restore access time of mailbox. */ t[0].tv_sec = f_stat.st_atime; t[0].tv_usec = 0; t[1].tv_sec = f_stat.st_mtime; t[1].tv_usec = 0; utimes(mailBox->box, t); return count; } Pixel convertColor(colorname, defValue) char *colorname; Pixel defValue; { XrmValue namein, pixelout; namein.addr = colorname; namein.size = NEWstrlen(colorname) + 1; pixelout.size = 0; XtConvert(toplevel, XtRString, &namein, XtRPixel, &pixelout); if (pixelout.size == 0) /* it failed */ return(defValue); else return(*(Pixel *)pixelout.addr); } #ifdef USE_LED void initBox(box, BoxType, pollTime, headerTime, BoxNameType, command, audioCmd, title, origMode, nobeep, bgName, fgName, led) #else void initBox(box, BoxType, pollTime, headerTime, BoxNameType, command, audioCmd, title, origMode, nobeep, bgName, fgName) #endif char *box; BoxType_t BoxType; int pollTime; int headerTime; BoxNameType_t BoxNameType; char *command; char *audioCmd; char *title; Boolean origMode; Boolean nobeep; char *bgName; char *fgName; #ifdef USE_LED int led; #endif { BoxInfo_t tempBox; int boxSize; char *ptr; /* get rid of trailing whitespace in box */ ptr = box + NEWstrlen(box) - 1; while (isspace(*ptr)) *ptr-- = '\0'; #ifdef DEBUG fprintf(stderr, "Init Box = *%s*\n", box); fprintf(stderr, "nboxes = %i\n", nBoxes); fprintf(stderr, "type = %i\n", BoxType); fprintf(stderr, "command = *%s*\n", command); fprintf(stderr, "audio = *%s*\n", audioCmd); fprintf(stderr, "boxTitle = *%s*\n", title); fprintf(stderr, "pollTime = %i headerTime = %i\n", pollTime, headerTime); fprintf(stderr, "nobeep = %i origMode = %i \n", nobeep, origMode); fprintf(stderr, "nametype = %i\n\n", BoxNameType); #endif tempBox.box = NEWstrdup(box); tempBox.type = BoxType; tempBox.boxNum = nBoxes; if (BoxType == NNTPBOX) { tempBox.articles = DynCreate(sizeof(Articles_t), 2); #ifdef DEBUG /* DynDebug(tempBox.articles, 1); DynParanoid(tempBox.articles, 1);*/ #endif } else if (BoxType == MAILBOX) { struct stat st; char tmp[_POSIX_PATH_MAX]; if (stat (box, &st) != -1) { if (S_ISDIR (st.st_mode)) { /* check for maildir mailbox */ sprintf(tmp, "%s/cur", box); if (stat (tmp, &st) == 0 && S_ISDIR (st.st_mode)) { tempBox.type = MAILDIR; } else { /* check for mh mailbox */ sprintf(tmp, "%s/.mh_sequences", box); if (access (tmp, F_OK) == 0) { tempBox.type = MHDIR; } else { sprintf(tmp, "%s/.xmhcache", box); if (access (tmp, F_OK) == 0) { tempBox.type = MHDIR; } } } } } } if ((pollTime <= 0) || (pollTime >= 3600)) tempBox.pollTime = envPolltime; else tempBox.pollTime = pollTime; if ((tempBox.type == NNTPBOX) && (tempBox.pollTime < 180)) tempBox.pollTime = 180; if ((headerTime < 0) || (headerTime >= 60)) tempBox.headerTime = envHeadertime; else tempBox.headerTime = headerTime; tempBox.BoxNameType = BoxNameType; tempBox.boxTitle = NEWstrdup(title); if (tempBox.BoxNameType == UNDEF) { if (data.shortNames) tempBox.BoxNameType = SHORT; if (data.longNames) tempBox.BoxNameType = LONG; } boxSize = makeBoxTitle(&tempBox); if (boxSize > maxBoxSize) maxBoxSize = boxSize; tempBox.command = NEWstrdup(command); tempBox.audioCmd = NEWstrdup(audioCmd); tempBox.origMode = origMode; tempBox.nobeep = nobeep; if (bgName != NULL) tempBox.bg = convertColor(bgName,data.bg); else tempBox.bg = data.bg; if (fgName != NULL) tempBox.fg = convertColor(fgName,data.fg); else tempBox.fg = data.fg; #ifdef USE_LED if (led < 1 || led > 3) tempBox.led = -1; else tempBox.led = led; #endif tempBox.box_mtime = tempBox.st_size = 0; DynAdd(DynBoxObj, &tempBox); boxInfo = (BoxInfo_t *) DynGet(DynBoxObj, 0); nBoxes++; } void ParseMailPath() { char *mailPath = 0; char *boxes = 0; char *str = 0; /* get mail path */ if ((mailPath = getenv("MAILPATH")) != 0) { boxes = mailPath; } else if ((mailPath = getenv("MAIL")) != 0) { boxes = mailPath; } else if (data.mailBoxes != 0) { boxes = data.mailBoxes; } else { return; } str = (char *) strtok(boxes, ":, "); while (str != NULL) { #ifdef USE_LED initBox(NEWstrdup(str), MAILBOX, envPolltime, envHeadertime, UNDEF, data.command, data.audioCmd, NULL, data.origMode, data.nobeep,NULL,NULL,-1); #else initBox(NEWstrdup(str), MAILBOX, envPolltime, envHeadertime, UNDEF, data.command, data.audioCmd, NULL, data.origMode, data.nobeep,NULL,NULL); #endif str = (char *) strtok(NULL, ":, "); } } char *EliminatePath(path) char *path; { char *file = 0; file = (char *) strrchr(path, '/'); file = (file ? ++file : path); return (file); } #ifdef USE_NNTP void ParseNewsPath() { char *newsPath = 0; char *boxes = 0; char *str = 0; /* get nntp path */ if ((newsPath = getenv("NEWSPATH")) != 0) { boxes = newsPath; } else if (data.newsBoxes != 0) { boxes = data.newsBoxes; } else { return; } str = strtok(boxes, ":, "); while (str != NULL) { initBox(NEWstrdup(str), NNTPBOX, envPolltime, envHeadertime, UNDEF, data.command, data.audioCmd, NULL, data.origMode, data.nobeep, NULL,NULL); str = strtok(NULL, ":, "); } } #endif /* USE_NNTP */ /* the the icon if it is not already loaded */ void LoadIcon(w) Widget w; { Display *display = XtDisplay(w); int screen; Pixmap icon_pixmap = (Pixmap) 0; Arg arg; screen = DefaultScreen(display); /* User sets iconPixmap resource, converter does the right thing.. */ XtSetArg(arg, XtNiconPixmap, &icon_pixmap); XtGetValues(w, &arg, 1); if (icon_pixmap == (Pixmap) 0) { XtSetArg(arg, XtNiconPixmap, XCreateBitmapFromData(display, RootWindow(display, screen), xbuffy_bits, xbuffy_width, xbuffy_height)); XtSetValues(w, &arg, 1); } } int makeBoxTitle(currentBox) BoxInfo_t *currentBox; { char line[MAX_STRING]; line[0] = '\0'; if ((currentBox->type == MAILBOX) || (currentBox->type == MAILDIR) || (currentBox->type == MHDIR)) { switch (currentBox->BoxNameType) { case SHORT: strcpy(line, EliminatePath(currentBox->box)); break; case LONG: strcpy(line, currentBox->box); break; case NONE: case USR: case UNDEF: break; } if (line[0] != '\0') currentBox->boxTitle = NEWstrdup(line); } else { switch (currentBox->BoxNameType) { case SHORT: case LONG: strcpy(line, currentBox->box); break; case NONE: case USR: case UNDEF: break; } if (line[0] != '\0') currentBox->boxTitle = NEWstrdup(line); } if ( currentBox->boxTitle != NULL) return(NEWstrlen(currentBox->boxTitle)); else return(0); } void Usage() { printf("Usage: %s [toolkit options] [options] ...\n\n", programName); printf("Options are:\n"); printf(" -help print this message\n"); printf(" -version print the version number\n"); printf(" -poll how often to poll the file(s); default: 60\n"); printf(" -header popup header when mail is received\n"); printf(" (use '0' for mouse press only)\n"); printf(" -acmd command for audio instead of \n"); printf(" -boxfile filename containing names of mailboxes\n"); printf(" -horiz place the boxes horizontally; default: vertical\n"); printf(" -nobeep don't ring bell when mail is received\n"); printf(" -names display full path of mail files in the boxes\n"); printf(" -shortnames display names of mail files in the boxes\n"); printf(" -center center the names of the boxes\n"); printf(" -fill make all the boxes the same size\n"); printf(" -orig original mode - display all messages in the boxes\n"); printf(" -command system command to execute when middle button is pushed\n"); printf(" -mail specify a mailbox(s) to watch\n"); #ifdef USE_NNTP printf(" -news specify a newsgroup(s) to watch\n"); #endif /* USE_NNTP */ printf("\n"); printf("If there are any files specified on the command line, it will\n"); printf("monitor those mail files, otherwise it will use your MAILPATH\n"); printf("environment variable.\n"); printf("\n"); } int main(argc, argv) int argc; char *argv[]; { #ifdef USE_MOTIF static String fallback_resources[] = { "*.popup.translations: :Activate()", "*XmPushButton.translations: #override \ :Arm()\n\ :Disarm()", (String) NULL }; #endif static Boolean mailArgs; Widget form; int i; char *check; char name[MAX_STRING]; Arg args[5]; int nargs; int pid; #ifdef DEBUG char pause_string[10]; /* gets(pause_string);*/ #endif /* initialize program name and version string */ programName = EliminatePath(argv[0]); sprintf(versionString, "%s v%s", programName, VERSION); mailArgs = TRUE; nBoxes = 0; DynBoxObj = DynCreate(sizeof(BoxInfo_t), 1); #ifdef DEBUG DynDebug(DynBoxObj, 1); DynParanoid(DynBoxObj, 1); #endif boxInfo = (BoxInfo_t *) DynGet(DynBoxObj, 0); nargs = 0; XtSetArg(args[nargs], XtNallowShellResize, TRUE); nargs++; #ifdef USE_MOTIF toplevel = XtAppInitialize(&app, X_RESOURCE_CLASS, options, XtNumber(options), &argc, argv, fallback_resources, args, nargs); #else toplevel = XtAppInitialize(&app, X_RESOURCE_CLASS, options, XtNumber(options), &argc, argv, 0, args, nargs); #endif XtGetApplicationResources(toplevel, &data, resources, XtNumber(resources), 0, 0); /* initialize some values */ if (data.pollTime != NULL) envPolltime = atoi(data.pollTime); if ((data.pollTime == NULL) && ((check = getenv("MAILCHECK")) != 0)) { if ((envPolltime = atoi(check)) < 0) { fprintf(stderr, "MAILCHECK has illegal value\n"); } } if ((envPolltime <= 0) || (envPolltime >= 3600)) envPolltime = 60; if (data.priority != NULL) envPriority = atoi(data.priority); if ((envPriority < 0) || (envPriority >= 20)) envPriority = 15; if (data.headerTime != NULL) envHeadertime = atoi(data.headerTime); if (envHeadertime <= 0) envHeadertime = 0; if (envHeadertime >= 60) envHeadertime = 60; argc--; ++argv; while (argc) { if (strcmp("-help", *argv) == 0) { Usage(); exit(0); } else if (strcmp("-version", *argv) == 0) { printf("%s\n", versionString); exit(0); } else if (strcmp("-news", *argv) == 0) { #ifndef USE_NNTP fprintf(stderr, "program not compiled with -DUSE_NNTP ignoring %s\n", *argv); #else mailArgs = FALSE; #endif /* !USE_NNTP */ } else if (strcmp("-mail", *argv) == 0) { mailArgs = TRUE; } else { if (*argv[0] == '-') { fprintf(stderr, "Bad option: %s\n\n", *argv); Usage(); exit(-1); } if (mailArgs) { #ifdef USE_LED initBox(NEWstrdup(*argv), MAILBOX, envPolltime, envHeadertime, UNDEF, data.command, data.audioCmd, NULL, data.origMode, data.nobeep,NULL,NULL,-1); #else initBox(NEWstrdup(*argv), MAILBOX, envPolltime, envHeadertime, UNDEF, data.command, data.audioCmd, NULL, data.origMode, data.nobeep,NULL,NULL); #endif } #ifdef USE_NNTP else { #ifdef USE_LED initBox(NEWstrdup(*argv), NNTPBOX, envPolltime, envHeadertime, UNDEF, data.command, data.audioCmd, NULL, data.origMode, data.nobeep,NULL,NULL,-1); #else initBox(NEWstrdup(*argv), NNTPBOX, envPolltime, envHeadertime, UNDEF, data.command, data.audioCmd, NULL, data.origMode, data.nobeep,NULL,NULL); #endif } #endif /* USE_NNTP */ } argc--; ++argv; } if ((data.boxFile != 0) && (nBoxes == 0)) { readBoxfile(data.boxFile); } if (nBoxes == 0) { ParseMailPath(); #ifdef USE_NNTP ParseNewsPath(); #endif /* USE_NNTP */ } /* if there are still no boxes, what's the point? */ if (nBoxes == 0) { fprintf(stderr, "nothing to watch is specified\n"); fprintf(stderr, "check $MAILPATH / XBuffy.mailboxes\n"); #ifdef USE_NNTP fprintf(stderr, "check $NEWSPATH / XBuffy.newsboxes\n"); #endif /* USE_NNTP */ Usage(); exit(-1); } LoadIcon(toplevel); nargs = 0; #ifndef USE_MOTIF if (data.horiz) { XtSetArg(args[nargs], XtNorientation, XtorientHorizontal); nargs++; } form = XtCreateManagedWidget("box", boxWidgetClass, toplevel, args, nargs); /* form = XtCreateManagedWidget("box", panedWidgetClass, toplevel, args, nargs);*/ #else if (data.horiz) { XtSetArg(args[nargs], XmNorientation, XmHORIZONTAL); nargs++; XtSetArg(args[nargs], XmNpacking, XmPACK_COLUMN); nargs++; } else { XtSetArg(args[nargs], XmNorientation, XmVERTICAL); nargs++; XtSetArg(args[nargs], XmNpacking, XmPACK_TIGHT); nargs++; } XtSetArg(args[nargs], XmNisAligned, True); nargs++; XtSetArg(args[nargs], XmNentryVerticalAlignment, XmALIGNMENT_CENTER); nargs++; form = XmCreateRowColumn(toplevel, "box", args, nargs); XtManageChild(form); #endif if ((header = (Widget *) malloc(nBoxes * sizeof(Widget))) == 0) { fprintf(stderr, "Can't malloc header widgets\n"); exit(-1); } if ((headerUp = (int *) malloc(nBoxes * sizeof(int))) == 0) { fprintf(stderr, "Can't malloc header flags\n"); exit(-1); } for (i = 0; i < nBoxes; i++) { Boolean dummy; headerUp[i] = FALSE; if ((boxInfo[i].type == MAILBOX) || (boxInfo[i].type == MAILDIR) || (boxInfo[i].type == MHDIR)) boxInfo[i].n = CountUnixMail(&boxInfo[i], NULL, &dummy); #ifdef USE_NNTP if (boxInfo[i].type == NNTPBOX) boxInfo[i].n = CountNNTP(&boxInfo[i], NULL, &dummy); #endif sprintf(name, "box%d", i); #ifndef USE_MOTIF nargs = 0; XtSetArg(args[nargs], XtNleft, XtChainLeft); nargs++; XtSetArg(args[nargs], XtNright, XtChainLeft); nargs++; XtSetArg(args[nargs], XtNresizable, True); nargs++; /*7!*/ XtSetArg(args[nargs], XtNshowGrip, False); nargs++; XtSetArg(args[nargs], XtNallowResize, True); nargs++; boxInfo[i].w = XtCreateManagedWidget(name, commandWidgetClass, form, args, nargs); XtAddEventHandler(boxInfo[i].w, ButtonPressMask, True, ButtonDownHandler, &boxInfo[i].boxNum); XtAddEventHandler(boxInfo[i].w, ButtonReleaseMask, True, ButtonUpHandler, &boxInfo[i].boxNum); #else nargs = 0; XtSetArg(args[nargs], XmNresizable, TRUE); nargs++; boxInfo[i].w = XmCreatePushButton(form, name, args, nargs); XtManageChild(boxInfo[i].w); XtAddEventHandler(boxInfo[i].w, ButtonPressMask, True, ButtonDownHandler, &boxInfo[i].boxNum); XtAddEventHandler(boxInfo[i].w, ButtonReleaseMask, True, ButtonUpHandler, &boxInfo[i].boxNum); #endif UpdateBoxNumber(&boxInfo[i]); CheckBox(i); } #ifdef DEBUG fprintf(stderr, "bg = %i, fg = %i maxSize = %i\n", data.bg, data.fg,maxBoxSize); for (i = 0; i < nBoxes; i++) { fprintf(stderr, "box = %s\n", boxInfo[i].box); fprintf(stderr, "pollTime = %i\n", boxInfo[i].pollTime); fprintf(stderr, "headerTime = %i\n", boxInfo[i].headerTime); fprintf(stderr, "origMode = %i\n", boxInfo[i].origMode); fprintf(stderr, "nobeep = %i\n", boxInfo[i].nobeep); #ifdef USE_LED fprintf(stderr, "led = %i\n", boxInfo[i].led); #endif fprintf(stderr, "command = %s\n", boxInfo[i].command); fprintf(stderr, "nameType = %i\n", boxInfo[i].BoxNameType); } #endif XtRealizeWidget(toplevel); #ifndef DEBUG #ifdef HAVE_SETPRIORITY if (setpriority(PRIO_PROCESS, 0, envPriority) == -1) perror("Proirity change Failed"); #endif /* put ourself in the background */ switch (pid = fork()) { case 0: XtAppMainLoop(app); /* in child do the stuff */ break; case -1: perror("Fork failure"); XtAppMainLoop(app); /* fork failed - carry on in the parent instead */ break; default: exit(0); /* ok its going we can stop now */ break; } #else XtAppMainLoop(app); #endif return 0; } xbuffy-3.3.bl.3.orig/README0000644000175000017500000000565006473242266013377 0ustar brlbrl XBuffy 08/20/97 Xbuffy was written by Bill Pemberton (wfp5p@virginia.edu) and was based on Xmultibiff by John Reardon. Xmultibiff can be found at ftp.midnight.com. I was looking for a replacement for XBiff. I use the filter program (it comes with elm) to separate my mail into several different mailboxes. I looked at a lot of replacements for XBiff until I found Xmultibiff. Xmultibiff was very promising, but it didn't do quite what I wanted it to do, so I modified it to create XBuffy. Basically, XBuffy (and Xmultibiff) is a XBiff-type program with a lot of new options. With XBuffy you can watch multiple mailboxes. When new mail arrives, you can have a pop up window showing the From: and Subject: lines. You can also set it up to launch your favorite mail reader when you click on a box. Currently. xbuffy is only capable of watching mailboxes with the standard mailbox format (messages separated with a From line). This version also incorporates a new feature which will let you monitor newsgroups in the same way you monitor mailboxes. It parses your .newsrc and uses NNTP to monitor any given group or groups. It will keep constant track of how many unread articles are in a specified newsgroup(s). Also, when new articles come in, it will pop up the From and Subject lines of the article just like it pops them up for mailboxes. Note that this feature won't be able to see new incoming articles if you are using a version of NNTP prior to 1.5.11t5 (the problem is with the NNTP server, not Xbuffy). Xbuffy uses the Athena Widget library and the libDyn package (libDyn is included here). To build: % xmkmf -a % make If the make fails there are a few changes you may have to change for some platforms. Look at the file config.h and change anything that is appropriate. To learn of the usefulness of multiple mailboxes and incoming mail processing, check out procmail written by S.R. van den Berg. It can be used to sort your incoming mail into separate files, start programs when mail arrives, and a host of other things. A recent version can be gotten from ftp.informatik.rwth-aachen.de (137.226.112.172) in pub/unix/procmail.tar.Z. Some mailers (including elm) cause a problem with xbuffy. When you read a mail message, a Status: header is added to the message to show that the message has been read. Many mailers will only add this header to message in your real mailbox. This means that xbuffy can not tell if you've read mail in other folders. Some mailers have configuration options that force it to add Status: headers, some (like elm) don't. I've made a patch to elm to create a mode that DOES add Status: headers. This is known as Magic mode. Contact me if you want more information about the changes to elm. Xbuffy has been tested on SunOS 4.1.3 Solaris 2.5 Linux 2.X AIX 3.2.X AIX 4.X Irix 4.X Irix 5.X Please e-mail all added features (and any problems you may have) to wfp5p@virginia.EDU. xbuffy-3.3.bl.3.orig/xbuffy.h0000644000175000017500000000635206546405643014174 0ustar brlbrl/******************************************************************************* Copyright (c) 1994,1995 William Pemberton (wfp5p@virginia.edu) The X Consortium, and any party obtaining a copy of these files from the X Consortium, directly or indirectly, is granted, free of charge, a full and unrestricted irrevocable, world-wide, paid up, royalty-free, nonexclusive right and license to deal in this software and documentation files (the "Software"), including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons who receive copies from any such party to do so. This license includes without limitation a license to do the foregoing actions under any patents of the party supplying this software to the X Consortium. *******************************************************************************/ #ifndef _XBUFFY_H_ #define _XBUFFY_H_ #include #include #include "libdyn/dyn.h" #ifndef HAVE_BCOPY #define bcopy(x,y,z) memcpy(y,x,z) #define bzero(S,len) memset(S,0,len) #endif #define MAX_STRING 256 #define NEW_MSG 1 #define OLD_MSG 2 #define READ_MSG 4 #define UNKNOWN 8 #define LINEFEED (char) 10 #define X_RESOURCE_CLASS "XBuffy" enum BoxType_e { MAILBOX = 0, MAILDIR, MHDIR, NNTPBOX, }; typedef enum BoxType_e BoxType_t; enum BoxNameType_e {NONE = 0, SHORT, LONG, USR, UNDEF}; typedef enum BoxNameType_e BoxNameType_t; struct articles_s { long firstNum; long lastNum; }; typedef struct articles_s Articles_t; struct BoxInfo_s{ Widget w; int boxNum; /* the box number */ char *box; /* the box filename or newsgroup */ BoxType_t type; /* the box type (mail, news, etc) */ DynObject articles; /* for newsgroups, the read pairs */ time_t box_mtime; /* last time read */ off_t st_size; /* size of file on last read */ int n; /* the number of messages in the box */ char *command; char *audioCmd; char *boxTitle; int last; int pollTime; int headerTime; int nobeep; int origMode; char *bgName, *fgName; /* these are only used in the boxfile function */ Pixel bg,fg; BoxNameType_t BoxNameType; #ifdef USE_LED short led; /* led number */ int pid; /* led flasher pid */ #endif }; typedef struct BoxInfo_s BoxInfo_t; struct ApplicationData_s { char *mailBoxes; #ifdef USE_NNTP char *newsBoxes; #endif /* USE_NNTP */ Boolean horiz; Boolean shortNames; Boolean longNames; Boolean origMode; Boolean nobeep; Boolean center; Boolean fill; char *pollTime; char *headerTime; char *audioCmd; char *command; char *boxFile; char *priority; Pixel bg, fg; }; typedef struct ApplicationData_s ApplicationData_t; #ifdef _AIX #include #define exists(fname) (access(fname, E_ACC) == 0) #define canChange(fname) (accessx(fname, (R_ACC | W_ACC), ACC_SELF) == 0) #else #define exists(fname) (access(fname, F_OK) == 0) #define canChange(fname) (access(fname, (R_OK | W_OK)) == 0) #endif #define NEWstrlen(s) (s == NULL ? 0 : strlen(s)) #define NEWstrdup(s) (s == NULL ? NULL : strdup(s)) extern char *header_cmp(); #endif /* _XBUFFY_H_ */ xbuffy-3.3.bl.3.orig/xbuffy.man0000644000175000017500000002150306546414245014511 0ustar brlbrl.TH XBUFFY 1 01/31/95 .uc 4.2 .SH NAME xbuffy \- yet another biff for the X Window System .SH SYNOPSIS .B xbuffy [X toolkit options] [-help] [-version] [-horiz] [-poll \fIseconds\fR] [-header \fIseconds\fR] [-acmd \fIsound file\fR] [-nobeep] [-names] [-orig] [-priority \fIpriority\fR] [-command \fIcommand\fR] [-shortnames] [-mail ] [-news ] .SH DESCRIPTION Xbuffy is based on Xmultibiff by John Reardon. Xbuffy keeps track of multiple mailboxes. You can either specify mailbox files on the command line, in a Xresources file, in a text configuration file, or set your MAILPATH environment variable (a colon separated list of files). It will display the number of new messages in each mail file in a box. You can clear the reverse video in a box by clicking on the box with Button 3. Another key feature of xbuffy is that it will use NNTP to watch newsgroups in the same way it watches mailboxes. You can also specify newsgroups on the command line, in Xresources, in a text configuration file (the same file can specify both mailboxes and newsboxes), or set your NEWSPATH environment variable using the same format as the MAILPATH environment variable. By specifying certain command line options and/or Xresources, xbuffy can show the From and Subject lines in each box. It can also invoke shell commands on button clicks. Each box can be configured differently by using a \fIboxfile.\fR In general, it is a very extensible biff. Read on for details on what it can do. .SH OPTIONS The following options are recognized: .TP 10 .B -help Print a brief help message and exit .TP .B -version Print the current version and exit .TP .B -poll \fIsecs\fR How often the mailbox files are polled for new mail. If this is not specified, it will use the \fBMAILCHECK\fR environment variable. (default: 60) .TP .B -header \fIsecs\fR This will display the \fBFrom:\fR and \fBSubject:\fR lines from incoming mail messages in a popup window when button 1 is pressed in the box label. The mail header will also popup automatically for the amount of time indicated in \fIsecs\fR when new mail arrives. If \fIsecs\fR is 0, the mail header will not pop up when new mail arrives. Clicking in the popup window when mail arrives (if the argument is non-zero) will instantly popdown the window. This feature was borrowed from xpbiff. .TP .B -fill Makes all the boxes the same size. .TP .B -center Centers the name of the box in the box. This option turns on the fill option. .TP .B -acmd \fIsound command\fR This will run a command instead of ringing the bell when new mail arrives. For example, you could "cat meow >/dev/audio". This option could also be used to automatically open a mail reader when new mail arrives. .TP .B -horiz This will line up the boxes horizontally (default: vertical) .TP .B -nobeep This will disable the beep (or sound command) when new mail arrives .TP .B -boxfile \fIfilename\fR The name of a file containing configuration information for the boxes. The boxfile is an alternative way of specifying what to watch. The boxfile also allows each box to have different polltime, headertime, etc. .TP .B -origMode This will show all messages in each mailbox. It has no effect on news groups. .TP .B -names Will display the full pathname of all the mailboxes it is watching. .TP .B -shortnames Will display the file names of all the mailboxes it is watching. .TP .B -priority \fIpriority\fR Nice level at which xbuffy and its child processes will run. .TP .B -command \fIcommand\fR This is the default command that is to be executed when Button 2 is pressed on a box. .TP .B X Options Standard X windows options (e.g. -fn, -display, etc.) .SH ENVIRONMENT The names and purpose of the some of the following environment variables were borrowed from Bash, the GNU Shell. .TP 5 .B MAILCHECK This specifies the amount of seconds to wait in between polling for mail. .TP .B MAILPATH This is a colon separated list of files to check for mail. .TP .B NEWSPATH This is a colon separated list of newsgroups to monitor. .TP .B NNTPSERVER This is the name of the NNTP server to use for news boxes. .SH X DEFAULTS The application class is XBuffy. Almost all the arguments above can be set in the X resource database, allowing for one-time configuration and eliminating long command lines. The environment variables described above take precedence over any X resources that are specified. Also, any command line arguments take precedence over both X resources and environment variables. .SH BOXFILE FORMAT The boxfile contains configuration information for each box. Any line that begins with '#' is considered a comment and is ignored. The definition of a box begins with the keyword \fIbox\fR followed by the filename or newsgroup for that box. All subsequent lines are then used to configure that box until either another \fIbox\fR command or the end of file. Note that these options are NOT case sensitive. The following are settable on a per box basis by using the \fIboxfile\fR option (note that the boxfile may also be set in the Xresources with the resource Xbuffy.boxfile: ). When using a \fIboxfile\fR, only the \fIbox\fR line is required. All options that are not given in the boxfile will default to the command line (or built in) value. .TP 10 .B box \fIfile name\fR The filename or newsgroup for this box. This also marks the beginning of a box definition. .TP .B title \fIbox title\fR The title that you want for this box. This will override the shortname or longname option. .TP .B mailbox Specify that the box is a mailbox (a file). If neither mailbox or newsbox is specified, mailbox is the default. .TP .B newsbox Specify that the box is a newsbox (a NNTP newsgroup). .TP .B origMode origMode will make Xbuffy try to act like Xmultibiff and count ALL messages instead of just NEW message. .TP .B newMode newMode will make Xbuffy count only new messages (this is the default). .TP .B nobeep This will disable the beep (or sound command) when new mail arrives in the specified mailbox to be counted. .TP .B beep This will enable the beep (or sound) when new mail arrives in the specified mailbox to be counted. .TP .B shortname This will cause the specified box to be prefaced with the filename. .TP .B longname This will cause the specified box to be prefaced with a full path name. .TP .B audio \fIcommand string\fR Set to the command string to be used automatically when new mail arrives. .TP .B polltime \fIsecs\fR Set to the time (in seconds) in between polling the box. .TP .B headertime \fIsecs\fR Set to the time (in seconds) to display the header when new things arrive. .TP .B command \fIcommand string\fR Specifies a UNIX shell command to be executed by \fBsh\fR when the middle mouse button is pushed in a box. Take care to escape characters correctly. .TP .B led \fInum\fR Specifies a keyboard led to flash when new mail arrives. This is a number between 1 and 3. (1 - NumLock, 2 - CapsLock or 3 - ScrollLock). .B NOTE: This is only available on LINUX and only if compiled with --enable-led .TP 0 The following resources are settable on a per application basis in the Xresources: .TP 10 .B horiz Set to TRUE or FALSE. Same as the -horiz option. .TP .B mailboxes Set to a colon separated list of mailboxes (files). This is the same as specifying files on the command line. .TP .B newsboxes Set to a colon separated list of news groups. This is the same as specifying files on the command line. .SH EXAMPLES The following examples demonstrate how to configure xbuffy to do the same thing from both the command-line and X resources. Although, for maximum flexibility on a per-box basis, I suggest using a boxfile. The following example will watch 2 mailboxes in a home directory: .nf \fI% xbuffy -mail ~/box1 ~/box2 &\fR .fi boxfile: .nf box ~/box1 box ~/box2 .fi The following example will watch a mailbox and a newsgroup: .nf \fI% xbuffy -mail /usr/spool/mail/you -news comp.windows.x &\fR .fi boxfile: .nf box /usr/spool/mail/you box comp.windows.x newsbox .fi .SH GRATITUDE Thanks to John Reardon for writing the original Xmultibiff and Xmultibiff 2.0. Xbuffy is a modified version of Xmultibiff 2.0 (although the code is looking less and less similar everyday). .SH BUGS Sometimes buffy detects a change in the mailbox and reports new mail before the mail is finished being delivered. This can (will) be fixed when buffy learns hows to deal with file locking. There is a bug with the NNTP stuff that isn't really Buffy's fault. Most versions of the NNTP server will not dynamically update the high message number (you must disconnect from the server and re-connect to get a new high message). If your server is running one of these versions of NNTP then you will not get told of new articles in your newsboxes. .SH AUTHOR xbuffy: Bill Pemberton, wfp5p@virginia.EDU .TP xmultibiff: John Reardon, Midnight Networks Inc., badger@midnight.com xbuffy-3.3.bl.3.orig/xbuffy.xbm0000644000175000017500000000632106473242266014526 0ustar brlbrl#define xbuffy_width 64 #define xbuffy_height 64 static char xbuffy_bits[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x51, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xf5, 0xa1, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xfa, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x21, 0x66, 0x3e, 0x33, 0x9f, 0x6f, 0x06, 0xfb, 0x51, 0x6e, 0x66, 0x33, 0x83, 0x61, 0x06, 0xf7, 0x21, 0x18, 0x3e, 0x33, 0x8f, 0x87, 0x01, 0xfb, 0x51, 0x76, 0x66, 0x33, 0x83, 0x81, 0x01, 0xf7, 0x21, 0x66, 0x3e, 0x3f, 0x83, 0x81, 0x01, 0xfb, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0xa1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xd1, 0xff, 0x7f, 0xff, 0xe1, 0xc0, 0xff, 0xf7, 0xa1, 0xff, 0x3f, 0xfe, 0x40, 0x80, 0xff, 0xfb, 0x51, 0x55, 0x15, 0x7c, 0x00, 0x00, 0x55, 0xf5, 0xa1, 0xaa, 0x0a, 0x38, 0x20, 0x80, 0xab, 0xfa, 0xf9, 0xff, 0x07, 0x30, 0x10, 0xc0, 0xff, 0xff, 0xfd, 0xff, 0x03, 0x60, 0x48, 0xe2, 0xff, 0xff, 0xff, 0xff, 0x21, 0xc0, 0x24, 0xf1, 0xff, 0xff, 0x01, 0x80, 0x40, 0x80, 0x93, 0xf8, 0x00, 0x80, 0x01, 0x40, 0x90, 0x00, 0x4b, 0x7c, 0x00, 0x80, 0x01, 0x40, 0x24, 0x01, 0x26, 0x3e, 0x00, 0x80, 0x01, 0x80, 0x48, 0x02, 0x1c, 0x1f, 0x00, 0x80, 0x01, 0x00, 0x91, 0x00, 0x98, 0x0f, 0x00, 0x80, 0x01, 0x00, 0x22, 0x09, 0xf2, 0x07, 0x00, 0x80, 0x01, 0x00, 0x44, 0x12, 0xe7, 0x03, 0x00, 0x80, 0x01, 0x00, 0x08, 0xa4, 0xcf, 0x01, 0x00, 0x80, 0x01, 0x00, 0x10, 0x09, 0xc7, 0x00, 0x00, 0x80, 0x01, 0x00, 0x20, 0x02, 0xa2, 0x00, 0x00, 0x80, 0x01, 0x00, 0x40, 0x04, 0xd0, 0x01, 0x04, 0x80, 0x01, 0x00, 0x80, 0x00, 0xa8, 0x03, 0x0a, 0x80, 0x01, 0x00, 0x00, 0x01, 0x74, 0x07, 0x11, 0x80, 0x01, 0x00, 0x00, 0x02, 0x7a, 0x8e, 0x20, 0x80, 0x01, 0x00, 0x00, 0x04, 0x7d, 0x44, 0x46, 0x80, 0x01, 0x00, 0x00, 0x88, 0x3a, 0x28, 0x8f, 0x80, 0x01, 0x00, 0x00, 0x50, 0x05, 0x10, 0x07, 0x81, 0xe1, 0xff, 0xff, 0xb3, 0x02, 0x08, 0x02, 0x82, 0x21, 0x00, 0x00, 0x6a, 0x01, 0x04, 0x00, 0x84, 0x21, 0x00, 0xe0, 0xc6, 0x00, 0x02, 0x00, 0x8e, 0x21, 0x00, 0xe0, 0x02, 0x08, 0x01, 0x10, 0x9f, 0x21, 0x00, 0xe0, 0x01, 0x84, 0x20, 0x89, 0xbf, 0x21, 0x00, 0x80, 0x00, 0x42, 0x90, 0xc4, 0xff, 0x21, 0xff, 0x00, 0x01, 0x29, 0x48, 0xe2, 0xbf, 0x21, 0x00, 0x00, 0x82, 0x14, 0x24, 0xf0, 0x9f, 0x21, 0xdf, 0x03, 0x46, 0x0a, 0x92, 0xf8, 0x8f, 0x21, 0x00, 0x00, 0x0e, 0x05, 0x49, 0xfc, 0x87, 0x21, 0xff, 0x07, 0x9e, 0x08, 0x24, 0xfe, 0x83, 0x21, 0x00, 0x00, 0x2e, 0x18, 0x10, 0xff, 0x81, 0xe1, 0xff, 0xff, 0x4f, 0x3c, 0x88, 0xff, 0x80, 0x81, 0x5f, 0x55, 0x8f, 0x7e, 0xc0, 0x7f, 0x80, 0x81, 0xbf, 0xaa, 0x0f, 0xff, 0xe0, 0x3f, 0x80, 0x01, 0x10, 0x00, 0x03, 0x3e, 0xf1, 0x1f, 0x80, 0x01, 0x10, 0x00, 0x03, 0x1c, 0xfa, 0x0f, 0x80, 0x01, 0x10, 0x00, 0x03, 0x08, 0xfc, 0x07, 0x80, 0x01, 0x50, 0x05, 0x03, 0x00, 0xf8, 0x03, 0x80, 0x01, 0x50, 0x05, 0x03, 0x00, 0xf0, 0x01, 0x80, 0x01, 0x50, 0x05, 0x03, 0x00, 0xe0, 0x00, 0x80, 0x01, 0x50, 0x05, 0x03, 0x00, 0x40, 0x00, 0x80, 0x01, 0x50, 0x01, 0x03, 0x00, 0x00, 0x00, 0x80, 0x01, 0x50, 0x01, 0x03, 0x00, 0x00, 0x00, 0x80, 0x01, 0x50, 0x00, 0x03, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; xbuffy-3.3.bl.3.orig/boxfile.fmt0000644000175000017500000000027206546405643014653 0ustar brlbrlbox /usr/spool/mail/wfp5p title Sometitle command Somecommand audio Somestring mailbox | newsbox origMode | newMode beep | nobeep shortname | longname headertime 10 polltime 30 led -1 xbuffy-3.3.bl.3.orig/boxfile.sample0000644000175000017500000000101306546405643015340 0ustar brlbrl# Spool directory box /usr/spool/mail/wfp5p title mail command xterm -sb -title "mail" -e "elm"& beep polltime 45 newMode headertime 10 led 2 box /home/wfp5p/.Mail/pepband title Pep Band beep command xterm -sb -title "Pep Band" -e elm -Mf /home/wfp5p/.Mail/pepband& polltime 45 newMode headertime 10 led 3 box /home/wfp5p/.Mail/sonic-life-l title Sonic Life command xterm -sb -title "Sonic Life" -e elm -Mf /home/wfp5p/.Mail/sonic-life-l& beep polltime 120 newMode #box uva.general #newsbox #beep #polltime 30 #newMode xbuffy-3.3.bl.3.orig/XBuffy.ad0000644000175000017500000000033306546405643014222 0ustar brlbrl! ! Application Defaults file for XBuffy ! XBuffy*nobeep: FALSE XBuffy*horiz: FALSE XBuffy*names: FALSE XBuffy*shortnames: TRUE XBuffy*polltime: 30 XBuffy*priority: 15 XBuffy*headertime: 10 XBuffy*background: #cccccc xbuffy-3.3.bl.3.orig/boxfile.c0000644000175000017500000001652606546407323014315 0ustar brlbrl/******************************************************************************* Copyright (c) 1994,1995 William Pemberton (wfp5p@virginia.edu) The X Consortium, and any party obtaining a copy of these files from the X Consortium, directly or indirectly, is granted, free of charge, a full and unrestricted irrevocable, world-wide, paid up, royalty-free, nonexclusive right and license to deal in this software and documentation files (the "Software"), including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons who receive copies from any such party to do so. This license includes without limitation a license to do the foregoing actions under any patents of the party supplying this software to the X Consortium. *******************************************************************************/ #include #include #include #include "xbuffy.h" #define cmpTok(tok,str,tokVal) {if ( strcmp(tok,str) == 0) return(tokVal);} extern ApplicationData_t data; static char *tokens[20] = { "box", "title", "command", "audio", "mailbox", "newsbox", "origmode", "newmode", "beep", "nobeep", "last", "headertime", "polltime", "shortname", "longname", "background", "foreground", #ifdef USE_LED "led", #endif NULL }; enum TokType { UNK_T = 0, BOX_T, TITLE_T, COMMAND_T, AUDIO_T, MAILBOX_T, NEWSBOX_T, ORIGMODE_T, NEWMODE_T, BEEP_T, NOBEEP_T, LAST_T, HEADER_T, POLL_T, SHORT_T, LONG_T, BG_T, FG_T #ifdef USE_LED , LED_T #endif }; typedef enum TokType TokenType; TokenType token(line, next) char *line; char *next; { char tok[30]; char *p1; int x; p1 = line; x = 0; while ((*p1 != '\0') && (isspace(*p1))) p1++; while ((*p1 != '\0') && (!isspace(*p1)) && (x < 29)) { tok[x++] = (isupper(*p1) ? tolower(*p1) : *p1); p1++; } tok[x] = '\0'; while ((*p1 != '\0') && (isspace(*p1))) p1++; strcpy(next, p1); if (NEWstrlen(next)) next[NEWstrlen(next) - 1] = '\0'; /* strip the newline */ for (x = 0; tokens[x] != NULL; x++) { if (strcmp(tok, tokens[x]) == 0) return (x + 1); } return (UNK_T); } void clearBox(tempBox) BoxInfo_t *tempBox; { if (tempBox->box != NULL) { free(tempBox->box); tempBox->box = NULL; } if (tempBox->command != NULL) { free(tempBox->command); tempBox->command = NULL; } if (tempBox->audioCmd != NULL) { free(tempBox->audioCmd); tempBox->audioCmd = NULL; } if (tempBox->boxTitle != NULL) { free(tempBox->boxTitle); tempBox->boxTitle = NULL; } if (tempBox->bgName != NULL) { free(tempBox->bgName); tempBox->bgName = NULL; } if (tempBox->fgName != NULL) { free(tempBox->fgName); tempBox->fgName = NULL; } tempBox->type = 0; tempBox->last = 0; tempBox->headerTime = tempBox->nobeep = tempBox->origMode = 0; tempBox->pollTime = tempBox->headerTime = -1; #ifdef USE_LED tempBox->pid = 0; tempBox->led = -1; #endif tempBox->BoxNameType = UNDEF; } char *parseTwiddle(str) char *str; { static char retVal[MAX_STRING]; char *ptr, *res; char *home; ptr = str; res = retVal; while (*ptr != '\0') { if (*ptr == '~') { home = (char *) getenv("HOME"); strcpy(res, home); res += NEWstrlen(home); } else *(res++) = *ptr; ++ptr; } *res = '\0'; return (retVal); } char *parseEnv(str) char *str; { static char retVal[MAX_STRING]; char envStr[MAX_STRING]; char *ptr,*res; char *envValue,*envPtr; ptr = str; envPtr = envStr; res = retVal; while (*ptr != '\0') { if (*ptr == '{') { ptr++; while ( (*ptr != '\0') && (*ptr != '}') ) { *envPtr = *ptr; ptr++; envPtr++; } if (*ptr == '}') ptr++; *envPtr = '\0'; envValue = (char *)getenv(envStr); strcpy(res,envValue); res+=NEWstrlen(envValue); } else { *(res++) = *ptr; ++ptr; } } *res = '\0'; return(retVal); } #ifdef TESTBOX char *showNull(w) char *w; { if (w == NULL) return ("NULL"); else return (w); } void dumpBox(tempBox) BoxInfo_t tempBox; { printf("Dumping Box = *%s*\n", tempBox.box); printf("type = %i\n", tempBox.type); printf("command = *%s*\n", showNull(tempBox.command)); printf("audio = *%s*\n", showNull(tempBox.audioCmd)); printf("boxTitle = *%s*\n", showNull(tempBox.boxTitle)); printf("pollTime = %i headerTime = %i\n", tempBox.pollTime, tempBox.headerTime); printf("nobeep = %i origMode = %i \n", tempBox.nobeep, tempBox.origMode); printf("nametype = %i\n\n", tempBox.BoxNameType); } #endif void readBoxfile(boxFile) char *boxFile; { BoxInfo_t tempBox; FILE *boxes; char line[MAX_STRING]; int inBox; char next[MAX_STRING]; tempBox.bgName = tempBox.fgName = tempBox.box = tempBox.command = tempBox.audioCmd = tempBox.boxTitle = NULL; #ifdef USE_LED tempBox.led = -1; #endif clearBox(&tempBox); if ((boxes = fopen(boxFile, "r")) == 0) { fprintf(stderr, "Could not open boxfile %s\n", boxFile); return; } inBox = 0; while (fgets(line, MAX_STRING - 2, boxes) != 0) { line[MAX_STRING - 1] = '\0'; /* just in case */ if (line[0] == '#') /* it's a comment */ continue; switch (token(line, next)) { case BOX_T: if (inBox) { #ifndef TESTBOX initBox(tempBox.box, tempBox.type, tempBox.pollTime, tempBox.headerTime, tempBox.BoxNameType, tempBox.command, tempBox.audioCmd, tempBox.boxTitle, tempBox.origMode, tempBox.nobeep, tempBox.bgName, tempBox.fgName # ifdef USE_LED , tempBox.led # endif ); #else dumpBox(tempBox); #endif clearBox(&tempBox); } tempBox.box = (char *) strdup(parseTwiddle(parseEnv(next))); inBox = TRUE; break; case TITLE_T: tempBox.boxTitle = (char *) strdup(next); tempBox.BoxNameType = USR; break; case COMMAND_T: tempBox.command = (char *) strdup(next); break; case AUDIO_T: tempBox.audioCmd = (char *) strdup(next); break; case MAILBOX_T: tempBox.type = MAILBOX; break; case NEWSBOX_T: tempBox.type = NNTPBOX; break; case ORIGMODE_T: tempBox.origMode = TRUE; break; case NEWMODE_T: tempBox.origMode = FALSE; break; case BEEP_T: tempBox.nobeep = FALSE; break; case NOBEEP_T: tempBox.nobeep = TRUE; break; case LAST_T: tempBox.last = atoi(next); break; case HEADER_T: tempBox.headerTime = atoi(next); break; case POLL_T: tempBox.pollTime = atoi(next); break; case SHORT_T: tempBox.BoxNameType = SHORT; break; case LONG_T: tempBox.BoxNameType = LONG; break; case BG_T: tempBox.bgName = (char *) strdup(next); break; case FG_T: tempBox.fgName = (char *) strdup(next); break; #ifdef USE_LED case LED_T: tempBox.led = atoi(next); break; #endif default: break; } } /* while */ if (inBox) #ifndef TESTBOX initBox(tempBox.box, tempBox.type, tempBox.pollTime, tempBox.headerTime, tempBox.BoxNameType, tempBox.command, tempBox.audioCmd, tempBox.boxTitle, tempBox.origMode, tempBox.nobeep, tempBox.bgName, tempBox.fgName # ifdef USE_LED , tempBox.led # endif ); #else dumpBox(tempBox); #endif fclose(boxes); } #ifdef TESTBOX main() { readBoxfile("boxfile.sample"); } #endif xbuffy-3.3.bl.3.orig/nntp.c0000644000175000017500000002075306546405643013644 0ustar brlbrl/******************************************************************************* Copyright (c) 1994,1995 William Pemberton (wfp5p@virginia.edu) The X Consortium, and any party obtaining a copy of these files from the X Consortium, directly or indirectly, is granted, free of charge, a full and unrestricted irrevocable, world-wide, paid up, royalty-free, nonexclusive right and license to deal in this software and documentation files (the "Software"), including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons who receive copies from any such party to do so. This license includes without limitation a license to do the foregoing actions under any patents of the party supplying this software to the X Consortium. *******************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include "xbuffy.h" #define CR (13) #define LF LINEFEED #define NEWLINE LF #define CHUNK_SIZE (1024L) #define MAX_LINE (1024) #ifdef TESTNEWS FILE *NNTP_fIn, *NNTP_fOut; int NNTPinit = 0; #else extern FILE *NNTP_fIn, *NNTP_fOut; extern int NNTPinit; #endif void Fatal(va_alist) { char *fmt; extern int errno; va_list p; va_start(p); fmt = va_arg(p, char *); vfprintf(stderr, fmt, p); fputc('\n', stderr); if (errno) perror("System error"); va_end(p); exit(1); } void fputeol(FILE * NNTP_fOut) { fputc(CR, NNTP_fOut); fputc(LF, NNTP_fOut); fflush(NNTP_fOut); } void initNNTP() { char line[1024]; int err; int sock; char *serverName; struct sockaddr_in server; struct hostent *hp; sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) Fatal("socket failed"); server.sin_family = AF_INET; server.sin_port = htons(119); /* NNTP */ serverName = getenv("NNTPSERVER"); if (serverName == NULL) #ifdef NNTP_SERVER serverName = NNTP_SERVER; #else Fatal("Please set $NNTPSERVER to an appropriate news server."); #endif hp = gethostbyname(serverName); if (hp == 0) Fatal("gethostbyname failed"); bcopy(*hp->h_addr_list, (char *) &server.sin_addr, hp->h_length); err = connect(sock, (struct sockaddr*)&server, sizeof(server)); if (err) Fatal("connect failed"); if (!(NNTP_fIn = fdopen(sock, "r"))) Fatal("fdopen(sock,\"r\") failed"); if (!(NNTP_fOut = fdopen(sock, "w"))) Fatal("fdopen(sock,\"w\") failed"); /* get header line */ fgets(line, sizeof(line), NNTP_fIn); if (atoi(line) != 200) Fatal("initial line unexpected: %s", line); NNTPinit = 1; } int getHeaders(long Article, char **from, char **subject) { char line[CHUNK_SIZE]; char *q; int x; fprintf(NNTP_fOut, "head %ld", Article); fputeol(NNTP_fOut); if (fgets(line, sizeof(line) - 1, NNTP_fIn) == 0) Fatal("getHeaders: premature EOF"); if ((x = atoi(line)) != 221) { if (x == 423) /* then the article just don't exist */ return (0); else Fatal("getHeaders: got a bad value: %s", line); } while ((line[0] != '.') && (line[1] != NEWLINE)) { /* retrieve line */ if (fgets(line, sizeof(line) - 1, NNTP_fIn) == 0) Fatal("ReadBlock: premature EOF"); /* look for CR LF at the end of the line then replace it with NEWLINE */ q = line + NEWstrlen(line) - 1; #ifdef DEBUG if (q[0] != LF) Fatal("ReadBlock: didn't find LF at end-of-line:\n%s", line); if (q[-1] != CR) Fatal("ReadBlock: didn't see CR near end-of-line:\n%s", line); #endif q[-1] = NEWLINE; if (strincmp(line, "From:", 5) == 0) *from = strdup(line); if (strincmp(line, "Subject:", 8) == 0) *subject = strdup(line); } return (1); } static char *getNewsrc() { static char fname[512]; sprintf(fname, "%s/.newsrc", getenv("HOME")); return (fname); } void readNewsrcEntry(newsBox, firstArt, lastArt) BoxInfo_t *newsBox; long firstArt; long lastArt; { FILE *newsrc; Boolean done = FALSE; char line[MAX_LINE]; static Articles_t tempArt; newsrc = fopen(getNewsrc(), "r"); if (newsrc == NULL) Fatal("Can't open .newsrc\n"); while (DynSize(newsBox->articles)) DynDelete(newsBox->articles, DynHigh(newsBox->articles)); while ((!done) && (fgets(line, MAX_LINE - 1, newsrc) != 0)) { char *tmp; char *backp; if (strincmp(line, newsBox->box, NEWstrlen(newsBox->box)) != 0) continue; tmp = line + NEWstrlen(newsBox->box); while ((!isdigit(*tmp)) && (*tmp != '\n')) tmp++; backp = tmp; while (*tmp != '\n') { /* First number */ while (isdigit(*tmp)) { tmp++; } tempArt.firstNum = atol(backp); backp = tmp; /* Is that it or is there another? */ if (*tmp == ',') { tempArt.lastNum = tempArt.firstNum; tmp++; backp++; } else if (*tmp == '\n') { tempArt.lastNum = tempArt.firstNum; } /* There IS more */ else { tmp++; backp++; while (isdigit(*tmp)) { tmp++; } tempArt.lastNum = atol(backp); backp = tmp; if (*tmp != '\n') { tmp++, backp++; } } if (tempArt.lastNum > firstArt) { if (tempArt.firstNum < firstArt) tempArt.firstNum = firstArt; DynAdd(newsBox->articles, &tempArt); } } } fclose(newsrc); tempArt.firstNum = tempArt.lastNum = lastArt + 1; DynAdd(newsBox->articles, &tempArt); } int insideBox(x, firstNum, lastNum) long x; long firstNum; long lastNum; { return ((x >= firstNum) && (x <= lastNum)); } int CountNNTP(newsBox, headerString, beenTouched) BoxInfo_t *newsBox; DynObject headerString; Boolean *beenTouched; { int sock, err, len; char line[1024]; long ipaddr; char *from; char *subject; long firstScanArticle; long firstArticle; long lastArticle; long retVal; long count; long numberArticles; long x; int index; struct stat f_stat; Articles_t *artP; if (!NNTPinit) initNNTP(); *beenTouched = FALSE; count = 0; /* send dummy group selection */ /* fputs("group news.answers", NNTP_fOut); fputeol(NNTP_fOut); */ /* get return line */ /* fgets(line, sizeof(line), NNTP_fIn); if (atoi(line) != 211) Fatal("unexpected response to group line: %s", line);*/ /* send group selection */ sprintf(line, "group %s", newsBox->box); fputs(line, NNTP_fOut); fputeol(NNTP_fOut); #ifdef DEBUG printf("countNNTP: send %s\n",line); #endif /* get return line */ fgets(line, sizeof(line), NNTP_fIn); if (atoi(line) != 211) Fatal("unexpected response to group line: %s", line); if (4 != sscanf(line, "%ld %ld %ld %ld", &retVal, &numberArticles, &firstArticle, &lastArticle)) Fatal("couldn't parse group line: %s", line); #ifdef DEBUG printf("countNNTP: read %s\n",line); #endif stat(getNewsrc(), &f_stat); if ((f_stat.st_size != newsBox->st_size) || (f_stat.st_mtime > newsBox->box_mtime)) { newsBox->st_size = f_stat.st_size; newsBox->box_mtime = f_stat.st_mtime; *beenTouched = TRUE; } readNewsrcEntry(newsBox, firstArticle, lastArticle); #ifdef DEBUG len = DynLow(newsBox->articles); while (len <= DynHigh(newsBox->articles)) { artP = (Articles_t *) DynGet(newsBox->articles, len); printf("Pair %ld %ld\n", artP->firstNum, artP->lastNum); len++; } #endif artP = (Articles_t *) DynGet(newsBox->articles, 0); index = 0; x = firstArticle; while (x <= lastArticle) { if (!insideBox(x, artP[index].firstNum, artP[index].lastNum)) { from = subject = NULL; if (getHeaders(x, &from, &subject)) { count++; if (headerString != NULL) { from[NEWstrlen(from) - 1] = subject[NEWstrlen(subject) - 1] = '\0'; DynInsert(headerString, ((DynHigh(headerString) > 0) ? (DynHigh(headerString) + 1) : 0), from, NEWstrlen(from)); DynInsert(headerString, ((DynHigh(headerString) > 0) ? (DynHigh(headerString) + 1) : 0), subject, NEWstrlen(subject)); } free(from); free(subject); } } else { x = artP[index].lastNum; index++; } x++; } return (count); } #ifdef TESTNEWS void main() { BoxInfo_t tempBox; Boolean dummy; tempBox.articles = DynCreate(sizeof(Articles_t), 2); while (1) { DynObject headers; char *hdrPtr; headers = DynCreate(sizeof(char), MAX_STRING); tempBox.box = "uva.general"; printf("There are %i articles\n", CountNNTP(&tempBox, NULL, &dummy)); CountNNTP(&tempBox, headers, &dummy); DynAdd(headers, '\0'); hdrPtr = (char *) DynGet(headers, 0); printf("\n*********************\n%s\n", hdrPtr); printf("done\n"); sleep(20); } } #endif xbuffy-3.3.bl.3.orig/CHANGES0000644000175000017500000000402306473242266013503 0ustar brlbrlChanges from Xbuffy 3.2 to Xbuffy 3.3 ------------------------------------------------------- Fixed a bug with the boxfile code (thanks to kalt@ensta.fr (Christophe Kalt)). Changes from Xbuffy 3.1 to Xbuffy 3.2 ------------------------------------------------------- Button 3 will now reset the box colors. The box name (if you are using boxfiles) can now contain environment variables. This is currently only done for the box parameter. To use an environment variable, put it in {} (for example: box /usr/spool/{USER} Now trys to look for lock files. Right now it only knows about .lock . Added the ability to use Content-Length: headers. Options to center and/or make all boxes the same size (this the the -center and -fill options). Changes from Xbuffy 3.0 to Xbuffy 3.1 ------------------------------------------------------- Fixed a few minor bugs (such as a portion of the mailbox title getting hacked off). Made some changes so it will compile on Solaris. I know of 1 person that got it to run successfully using gcc. Changes from Xbuffy 2.2 to Xbuffy 3.0 ------------------------------------------------------- Changes to get xbuffy into the X11R6 contrib. Got rid of the elm patch (for the R6 contrib, the patch can be gotten by anonymous ftp to ftp.virginia.edu:/pub/elm.diffs.gz). Changes from Xbuffy 2.1 to Xbuffy 2.2 ------------------------------------------------------- Changed when initNNTP gets called so that xbuffy will start displaying something sooner. Added patchlevel.h to make moderators happy. Added a local strdup for systems that don't have strdup (like Ultrix). (thanks to John Stoffel Added the ability for user control of the nice level. (thanks to Juan D. Martin ) Whitespace on the end of box names now gets removed. Changed the elm patch a little bit. Changes from Xbuffy 2.0 to Xbuffy 2.1 ------------------------------------------------------- Added define for linux Added htons call in nntp.c (from smpatel@xi.dorm.umd.edu) Fixed the -news parameter xbuffy-3.3.bl.3.orig/libdyn/0000755000175000017500000000000010413454420013754 5ustar brlbrlxbuffy-3.3.bl.3.orig/libdyn/README0000644000175000017500000000273706473242266014663 0ustar brlbrllibdyn.a -- Release 1.0 A C Dynamic Object is an array that takes care of resizing itself as elements are added and deleted from it. It can be of any type for which sizeof is defined and for which an address of a variable of that type can be passed to a function. To build libdyn.a, simply type "make depend all" (if you don't have the program makedepend, of course, leave out the "depend" part). If your system's bcopy() cannot handle overlapping regions, you'll need to write one that can. (Left as an excercise for the reader..) The library should compile and work without modification on a vast number of systems. It only uses 5 external functions: malloc, realloc, free, bcopy, and fprintf (to stderr). Of these, only bcopy should need to be changed for other systems (such as MS-DOS) and it could probably be done with a -D flag to the compiler. The test/demo program is built by "make all". This program produces the library's debugging output (to stderr) as well as some of its own output (to stdout). The library has been tested (with test.c) on a VAX VSII, VAXstation 3100, DECstation 3100, and IBM RT all running BSD4.3 (except for the DECstation, which was running Ultrix V2.1). An earlier version of this library was posted to alt.sources. This version contains one new function (DynInsert) and slightly cleaner code, but no bugfixes (no bugs were found). Author: Barr3y Jaspan, Student Information Processing Board (SIPB) and MIT-Project Athena, bjaspan@athena.mit.edu, 1990 xbuffy-3.3.bl.3.orig/libdyn/dyn.10000644000175000017500000001160106473242266014645 0ustar brlbrl.TH DYN 3M "15 March 1990" .SH NAME dyn \- the C Dynamic Object library .SH DESCRIPTION A C Dynamic Object is an array that takes care of resizing itself as you add and delete elements from it. It can be of any type for which sizeof is defined and for which an address of a variable of that type can be passed to a function. The library containing the functions described below is called .IR libdyn.a , and the necessary declarations to use them are in .RI < dyn.h >. .PP A DynObject is actually a structure that contains an array and a couple of integers to maintain necessary state information. When a Dyn function is said to operate on "the object" or "the array", it is operating on the array stored in the structure while at the same time updating internal state information. .SH LIST OF FUNCTIONS .nf DynObject DynCreate(size, increment) int size, increment; .fi .PP .IR Requires : .I size and .I increment are greater than zero. .PP .IR Effects : Creates a new DynObject that will store elements of size .I size and will allocate memory in blocks large enough to hold exactly .I increment elements. For example, if you are storing 8-byte double precision numbers and .I increment is 5, each 5th element you add to the object will cause it to request 40 more bytes (8 * 5) from the operating system. If .I increment is zero, a default value is used (currently 100). This is the only time the programmer deals with a dynamic object's memory allocation. .PP .IR Returns : .B DynCreate returns the new DynObject, or NULL if there is insufficient memory. .PP .nf int DynDestroy(obj) DynObject obj; .fi .PP .IR Modifies : obj .PP .IR Effects : Frees all memory associated with .IR obj . The results of calling any Dyn function on a destroyed object are undefined (except for DynCreate, which resets the object). .PP .IR Returns : .B DynDestroy returns DYN_OK. .PP .nf int DynAdd(obj, el) DynObject obj; DynPtr el; .fi .PP .IR Modifies : obj .PP .IR Effects : Adds the element pointed to by .I el to the object .IR obj , resizing the object if necessary. The new element becomes the last element in obj's array. .PP .IR Returns : .B DynAdd returns DYN_OK on success or DYN_NOMEM if there is insufficient memory. .PP .nf int DynInsert(obj, index, els, num) DynObject obj; DynPtr els; int index, num; .fi .PP .IR Modifies : obj .PP .IR Effects : Inserts the array of .I num elements, pointed to by .IR els, into the object .I obj starting at the array location .IR index , resizing the object if necessary. Order is preserved; if you have the array "1 2 3 4 5" and insert "10 11 12" at the third position, you will have the array "1 2 10 11 12 3 4 5". .PP .IR Returns : .B DynInsert returns DYN_BADINDEX if .I index is not between 0 and .BR DynSize ( obj ) ; DYN_BADVALUE if .I num is less than 1; DYN_NOMEM if there is insufficient memory. .PP .nf int DynGet(obj, index) DynObject obj; int index; .fi .PP .IR Effects : Returns the address of the element .I index in the array of .IR obj . This pointer can be treated as a normal array of the type specified to .BR DynCreate . The order of elements in this array is the order in which they were added to the object. The returned pointer is guaranteed to be valid only until obj is modified. .PP .IR Returns : .B DynGet returns NULL if .I index is larger than the number of elements in the array of less than zero. .PP .nf int DynDelete(obj, index) DynObject obj; int index; .fi .PP .IR Modifies : obj .PP .IR Effects : The element .I index is deleted from the object .IR obj . Note that the element is actually removed permanently from the array. If you have the array "1 2 3 4 5" and delete the third element, you will have the array "1 2 4 5". The order of elements in not affected. .PP .IR Returns : .B DynDelete will return DYN_OK on success or DYN_BADINDEX if the element .I index does not exist in the array or is less than zero. .PP .nf int DynSize(obj) DynObject obj; .fi .PP .IR Effects : Returns the number of elements in the object .IR obj . .PP .nf int DynHigh(obj) DynObject obj; .fi .PP .IR Effects : Returns the index of the highest element in the object .IR obj . In this version, .B DynHigh is macro that expands to .B DynSize - 1. .PP .nf int DynLow(obj) DynObject obj; .fi .PP .IR Effects : Returns the index of the lowest element in the object .IR obj . In this version, .B DynLow is macro that expands to 0. .PP .nf int DynDebug(obj, state) DynObject obj; int state; .fi .PP .IR Modifies : obj .PP .IR Effects : Sets the debugging state of .I obj to .I state and prints a message on stderr saying what state debugging was set to. Any non-zero value for .I state turns debugging ``on''. When debugging is on, all Dyn functions will produce (hopefully useful) output describing what is going on on stderr. .PP .IR Returns : .B DynDebug returns DYN_OK. .SH AUTHOR Barr3y Jaspan, Student Information Processing Board (SIPB) and MIT-Project Athena, bjaspan@athena.mit.edu xbuffy-3.3.bl.3.orig/libdyn/dyn_append.c0000644000175000017500000000211406473242266016255 0ustar brlbrl/* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the source code for the function DynAppend(). * * There are no restrictions on this code; however, if you make any * changes, I request that you document them so that I do not get * credit or blame for your modifications. * * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) * and MIT-Project Athena, 1989. */ #include #include "dynP.h" int DynAppend(obj, els, num) DynObjectP obj; DynPtr els; int num; { if (obj->debug) fprintf(stderr, "dyn: append: Writing %d bytes from %d to %d + %d\n", obj->el_size*num, els, obj->array, obj->num_el*obj->el_size); if (obj->size < obj->num_el + num) { int num_incs, ret; num_incs = ((obj->num_el + num - obj->size) / obj->inc) + 1; if ((ret = _DynRealloc(obj, num_incs)) != DYN_OK) return ret; } bcopy(els, obj->array + obj->num_el*obj->el_size, obj->el_size*num); obj->num_el += num; if (obj->debug) fprintf(stderr, "dyn: append: done.\n"); return DYN_OK; } xbuffy-3.3.bl.3.orig/libdyn/dyn_create.c0000644000175000017500000000205306473242266016253 0ustar brlbrl/* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the source code for the functions DynCreate() and * DynDestroy(). * * There are no restrictions on this code; however, if you make any * changes, I request that you document them so that I do not get * credit or blame for your modifications. * * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) * and MIT-Project Athena, 1989. */ #include #include "dynP.h" #ifndef DEFAULT_INC #define DEFAULT_INC 100 #endif static int default_increment = DEFAULT_INC; DynObjectP DynCreate(el_size, inc) int el_size, inc; { DynObjectP obj; obj = (DynObjectP) malloc(sizeof(DynObjectRecP)); if (obj == NULL) return NULL; obj->array = (DynPtr) malloc(0); obj->el_size = el_size; obj->num_el = obj->size = 0; obj->debug = obj->paranoid = 0; obj->inc = (!! inc) ? inc : default_increment; return obj; } int DynDestroy(obj) DynObjectP obj; { free(obj->array); free(obj); return DYN_OK; } xbuffy-3.3.bl.3.orig/libdyn/dyn_debug.c0000644000175000017500000000117706473242266016104 0ustar brlbrl/* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the source code for the function DynDebug(). * * There are no restrictions on this code; however, if you make any * changes, I request that you document them so that I do not get * credit or blame for your modifications. * * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) * and MIT-Project Athena, 1989. */ #include #include "dynP.h" int DynDebug(obj, state) DynObjectP obj; char state; { obj->debug = state; fprintf(stderr, "dyn: debug: Debug state set to %d.\n", state); return DYN_OK; } xbuffy-3.3.bl.3.orig/libdyn/dyn_delete.c0000644000175000017500000000361106473242266016253 0ustar brlbrl/* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the source code for the function DynDelete(). * * There are no restrictions on this code; however, if you make any * changes, I request that you document them so that I do not get * credit or blame for your modifications. * * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) * and MIT-Project Athena, 1989. */ #include #include "dynP.h" int DynDelete(obj, index) DynObjectP obj; int index; { if (index < 0) { if (obj->debug) fprintf(stderr, "dyn: delete: bad index %d\n", index); return DYN_BADINDEX; } if (index >= obj->num_el) { if (obj->debug) fprintf(stderr, "dyn: delete: Highest index is %d.\n", obj->num_el); return DYN_BADINDEX; } if (index == obj->num_el-1) { if (obj->paranoid) { if (obj->debug) fprintf(stderr, "dyn: delete: last element, zeroing.\n"); bzero(obj->array + index*obj->el_size, obj->el_size); } else { if (obj->debug) fprintf(stderr, "dyn: delete: last element, punting.\n"); } } else { if (obj->debug) fprintf(stderr, "dyn: delete: copying %d bytes from %d + %d to + %d.\n", obj->el_size*(obj->num_el - index), obj->array, (index+1)*obj->el_size, index*obj->el_size); bcopy(obj->array + (index+1)*obj->el_size, obj->array + index*obj->el_size, obj->el_size*(obj->num_el - index)); if (obj->paranoid) { if (obj->debug) fprintf(stderr, "dyn: delete: zeroing %d bytes from %d + %d\n", obj->el_size, obj->array, obj->el_size*(obj->num_el - 1)); bzero(obj->array + obj->el_size*(obj->num_el - 1), obj->el_size); } } --obj->num_el; if (obj->debug) fprintf(stderr, "dyn: delete: done.\n"); return DYN_OK; } xbuffy-3.3.bl.3.orig/libdyn/dyn_header.c0000644000175000017500000000063606473242266016245 0ustar brlbrl/* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the source code for the function xxx. * * There are no restrictions on this code; however, if you make any * changes, I request that you document them so that I do not get * credit or blame for your modifications. * * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) * and MIT-Project Athena, 1989. */ xbuffy-3.3.bl.3.orig/libdyn/dyn_insert.c0000644000175000017500000000314106473242266016313 0ustar brlbrl/* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the source code for the function DynInsert(). * * There are no restrictions on this code; however, if you make any * changes, I request that you document them so that I do not get * credit or blame for your modifications. * * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) * and MIT-Project Athena, 1989. */ #include #include "dynP.h" int DynInsert(obj, index, els, num) DynObjectP obj; DynPtr els; int index, num; { int ret; if (index < 0 || index > obj->num_el) { if (obj->debug) fprintf(stderr, "dyn: insert: index %d is not in [0,%d]\n", index, obj->num_el); return DYN_BADINDEX; } if (num < 1) { if (obj->debug) fprintf(stderr, "dyn: insert: cannot insert %d elements\n", num); return DYN_BADVALUE; } if (obj->debug) fprintf(stderr,"dyn: insert: Moving %d bytes from %d + %d to + %d\n", (obj->num_el-index)*obj->el_size, obj->array, obj->el_size*index, obj->el_size*(index+num)); if ((ret = _DynResize(obj, obj->num_el + num)) != DYN_OK) return ret; bcopy(obj->array + index, obj->array + (index + num), (obj->num_el-index)*obj->el_size); if (obj->debug) fprintf(stderr, "dyn: insert: Copying %d bytes from %d to %d + %d\n", obj->el_size*num, els, obj->array, obj->el_size*index); bcopy(els, obj->array + obj->el_size*index, obj->el_size*num); obj->num_el += num; if (obj->debug) fprintf(stderr, "dyn: insert: done.\n"); return DYN_OK; } xbuffy-3.3.bl.3.orig/libdyn/dyn_paranoid.c0000644000175000017500000000123006473242266016601 0ustar brlbrl/* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the source code for the function DynDebug(). * * There are no restrictions on this code; however, if you make any * changes, I request that you document them so that I do not get * credit or blame for your modifications. * * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) * and MIT-Project Athena, 1989. */ #include #include "dynP.h" int DynParanoid(obj, state) DynObjectP obj; char state; { obj->paranoid = state; if (obj->debug) fprintf(stderr, "dyn: paranoid: Paranoia set to %d.\n", state); return DYN_OK; } xbuffy-3.3.bl.3.orig/libdyn/dyn_put.c0000644000175000017500000000347206473242266015626 0ustar brlbrl/* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the source code for the functions DynGet() and DynAdd(). * * There are no restrictions on this code; however, if you make any * changes, I request that you document them so that I do not get * credit or blame for your modifications. * * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) * and MIT-Project Athena, 1989. */ #include #include "dynP.h" static int DynPut(); DynPtr DynGet(obj, num) DynObjectP obj; int num; { if (num < 0) { if (obj->debug) fprintf(stderr, "dyn: get: bad index %d\n", num); return NULL; } if (num >= obj->num_el) { if (obj->debug) fprintf(stderr, "dyn: get: highest element is %d.\n", obj->num_el); return NULL; } if (obj->debug) fprintf(stderr, "dyn: get: Returning address %d + %d.\n", obj->array, obj->el_size*num); return (DynPtr) obj->array + obj->el_size*num; } int DynAdd(obj, el) DynObjectP obj; DynPtr el; { int ret; ret = DynPut(obj, el, obj->num_el); if (ret != DYN_OK) return ret; ++obj->num_el; return ret; } /* * This function is not exported because if index is large enough to * cause two or more increments to be allocated the rep invariant * is not preserved. */ static int DynPut(obj, el, index) DynObjectP obj; DynPtr el; int index; { int ret; if (obj->debug) fprintf(stderr, "dyn: put: Writing %d bytes from %d to %d + %d\n", obj->el_size, el, obj->array, index*obj->el_size); if ((ret = _DynResize(obj, index)) != DYN_OK) return ret; bcopy(el, obj->array + index*obj->el_size, obj->el_size); if (obj->debug) fprintf(stderr, "dyn: put: done.\n"); return DYN_OK; } xbuffy-3.3.bl.3.orig/libdyn/dyn_realloc.c0000644000175000017500000000242406473242266016433 0ustar brlbrl/* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the source code for the internal function _DynRealloc(). * * There are no restrictions on this code; however, if you make any * changes, I request that you document them so that I do not get * credit or blame for your modifications. * * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) * and MIT-Project Athena, 1989. */ #include #include "dynP.h" /* * Ideally, this function should not be called from outside the * library. However, nothing will break if it is. */ int _DynRealloc(obj, num_incs) DynObjectP obj; int num_incs; { DynPtr temp; int new_size_in_bytes; new_size_in_bytes = obj->el_size*(obj->size + obj->inc*num_incs); if (obj->debug) fprintf(stderr, "dyn: alloc: Increasing object by %d bytes (%d incs).\n", obj->el_size*obj->inc*num_incs, num_incs); temp = (DynPtr) realloc(obj->array, new_size_in_bytes); if (temp == NULL) { if (obj->debug) fprintf(stderr, "dyn: alloc: Out of memory.\n"); return DYN_NOMEM; } else { obj->array = temp; obj->size += obj->inc*num_incs; } if (obj->debug) fprintf(stderr, "dyn: alloc: done.\n"); return DYN_OK; } xbuffy-3.3.bl.3.orig/libdyn/dyn_size.c0000644000175000017500000000114706473242266015765 0ustar brlbrl/* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the source code for the function DynSize(). * * There are no restrictions on this code; however, if you make any * changes, I request that you document them so that I do not get * credit or blame for your modifications. * * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) * and MIT-Project Athena, 1989. */ #include #include "dynP.h" int DynSize(obj) DynObjectP obj; { if (obj->debug) fprintf(stderr, "dyn: size: returning size %d.\n", obj->num_el); return obj->num_el; } xbuffy-3.3.bl.3.orig/libdyn/test.c0000644000175000017500000000702306473242266015117 0ustar brlbrl/* * This file is a (rather silly) demonstration of the use of the * C Dynamic Object library. It is a also reasonably thorough test * of the library (except that it only tests it with one data size). * * There are no restrictions on this code; however, if you make any * changes, I request that you document them so that I do not get * credit or blame for your modifications. * * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) * and MIT-Project Athena, 1989. */ #include #include "dyn.h" static char random_string[] = "This is a random string."; static char insert1[] = "This will be put at the beginning."; static char insert2[] = "(parenthetical remark!) "; static char insert3[] = " This follows the random string."; main(argc, argv) int argc; char **argv; { DynObject obj; int i, s; char d, *data; obj = DynCreate(sizeof(char), 8); if (! obj) { fprintf(stderr, "test: create failed.\n"); exit(1); } DynDebug(obj, 1); DynParanoid(obj, 1); if (DynGet(obj, -5) || DynGet(obj, 0) || DynGet(obj, 1000)) { fprintf(stderr, "test: Get did not fail when it should have.\n"); exit(1); } if (DynDelete(obj, -1) != DYN_BADINDEX || DynDelete(obj, 0) != DYN_BADINDEX || DynDelete(obj, 100) != DYN_BADINDEX) { fprintf(stderr, "test: Delete did not fail when it should have.\n"); exit(1); } printf("Size of empty object: %d\n", DynSize(obj)); for (i=0; i<14; i++) { d = (char) i; if (DynAdd(obj, &d) != DYN_OK) { fprintf(stderr, "test: Adding %d failed.\n", i); exit(1); } } if (DynAppend(obj, random_string, strlen(random_string)+1) != DYN_OK) { fprintf(stderr, "test: appending array failed.\n"); exit(1); } if (DynDelete(obj, DynHigh(obj) / 2) != DYN_OK) { fprintf(stderr, "test: deleting element failed.\n"); exit(1); } if (DynDelete(obj, DynHigh(obj) * 2) == DYN_OK) { fprintf(stderr, "test: delete should have failed here.\n"); exit(1); } d = 200; if (DynAdd(obj, &d) != DYN_OK) { fprintf(stderr, "test: Adding %d failed.\n", i); exit(1); } data = (char *) DynGet(obj, 0); s = DynSize(obj); for (i=0; i < s; i++) printf("Element %d is %d.\n", i, (unsigned char) data[i]); data = (char *) DynGet(obj, 13); printf("Element 13 is %d.\n", (unsigned char) *data); data = (char *) DynGet(obj, DynSize(obj)); if (data) { fprintf(stderr, "DynGet did not return NULL when it should have.\n"); exit(1); } printf("This should be the random string: \"%s\"\n", DynGet(obj, 14)); if (DynInsert(obj, -1, "foo", 4) != DYN_BADINDEX || DynInsert(obj, DynSize(obj) + 1, "foo", 4) != DYN_BADINDEX || DynInsert(obj, 0, "foo", -1) != DYN_BADVALUE) { fprintf(stderr, "DynInsert did not fail when it should have.\n"); exit(1); } if (DynInsert(obj, DynSize(obj) - 2, insert3, strlen(insert3) + 1) != DYN_OK) { fprintf(stderr, "DynInsert to end failed.\n"); exit(1); } if (DynInsert(obj, 19, insert2, strlen(insert2)) != DYN_OK) { fprintf(stderr, "DynInsert to middle failed.\n"); exit(1); } if (DynInsert(obj, 0, insert1, strlen(insert1)+1) != DYN_OK) { fprintf(stderr, "DynInsert to start failed.\n"); exit(1); } printf("A new random string: \"%s\"\n", DynGet(obj, 14 + strlen(insert1) + 1)); printf("This was put at the beginning: \"%s\"\n", DynGet(obj, 0)); DynDestroy(obj); return 0; } xbuffy-3.3.bl.3.orig/libdyn/dyn.h0000644000175000017500000000227006473253537014741 0ustar brlbrl/* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the public header file. * * There are no restrictions on this code; however, if you make any * changes, I request that you document them so that I do not get * credit or blame for your modifications. * * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) * and MIT-Project Athena, 1989. */ /* * dyn.h -- header file to be included by programs linking against * libdyn.a. */ #include "config.h" #ifndef HAVE_BCOPY #define bcopy(x,y,z) memcpy(y,x,z) #define bzero(S,len) memset(S,0,len) #endif #ifndef _Dyn_h #define _Dyn_h #ifdef notdef typedef void *DynPtr; #else typedef char *DynPtr; #endif typedef struct _DynObject DynObjectRec, *DynObject; /* Function macros */ #define DynHigh(obj) (DynSize(obj) - 1) #define DynLow(obj) (0) /* Return status codes */ #define DYN_OK -1000 #define DYN_NOMEM -1001 #define DYN_BADINDEX -1002 #define DYN_BADVALUE -1003 /* Function declarations */ DynObject DynCreate(); int DynAdd(), DynDelete(), DynDestroy(), DynDebug(); int DynInsert(), DynParanoid(); DynPtr DynGet(); #endif /* _Dyn_h */ /* DO NOT ADD ANYTHING AFTER THIS #endif */ xbuffy-3.3.bl.3.orig/libdyn/dynP.h0000644000175000017500000000250006473242266015052 0ustar brlbrl/* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the private header file. * * There are no restrictions on this code; however, if you make any * changes, I request that you document them so that I do not get * credit or blame for your modifications. * * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) * and MIT-Project Athena, 1989. */ /* * dynP.h -- private header file included by source files for libdyn.a. */ #ifndef _DynP_h #define _DynP_h #include "dyn.h" /* * Rep invariant: * 1) el_size is the number of bytes per element in the object * 2) num_el is the number of elements currently in the object. It is * one higher than the highest index at which an element lives. * 3) size is the number of elements the object can hold without * resizing. num_el <= index. * 4) inc is a multiple of the number of elements the object grows by * each time it is reallocated. */ typedef struct _DynObject { DynPtr array; int el_size, num_el, size, inc; char debug, paranoid; } DynObjectRecP, *DynObjectP; /* Internal functions */ int _DynRealloc(); #define _DynResize(obj, req) \ ((obj)->size > (req) ? DYN_OK : \ (_DynRealloc((obj), (((req) - (obj)->size) / (obj)->inc) + 1))) #endif /* _DynP_h */ /* DON'T ADD STUFF AFTER THIS #endif */ xbuffy-3.3.bl.3.orig/libdyn/Makefile.in0000644000175000017500000000047006474463164016043 0ustar brlbrl# # A GNU autoconf makefile for xbuffy # OBJS = dyn_create.o dyn_put.o dyn_debug.o dyn_delete.o dyn_size.o \ dyn_append.o dyn_realloc.o dyn_paranoid.o dyn_insert.o HDRS = dyn.h dynP.h VPATH=@srcdir@ @SET_MAKE@ libdyn.a: $(OBJS) ar rc libdyn.a $(OBJS) -ranlib libdyn.a clean: rm -f *.o libdyn.a *~ xbuffy-3.3.bl.3.orig/Makefile.in0000644000175000017500000000371506546406104014556 0ustar brlbrl# # XBuffy Default Makefile for non Imake (GNU Autoconf based) # SHELL=/bin/sh VERSION=@VERSION@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ libdir=@libdir@ mandir=@mandir@ srcdir=@srcdir@ VPATH=@srcdir@ @SET_MAKE@ INSTALL=@INSTALL@ CC=@CC@ XCPPFLAGS=-I. @CPPFLAGS@ CFLAGS=@CFLAGS@ $(XCPPFLAGS) LDFLAGS=@LDFLAGS@ LIBS=@LIBS@ LIBDYN = $(srcdir)/libdyn/libdyn.a OBJS = xbuffy.o boxfile.o realfrom.o getword.o len_next.o move_left.o \ strincmp.o remfirstwd.o header_cmp.o @LIBOBJS@ DOC = README xbuffy.man boxfile.fmt boxfile.sample DEFAULTS = XBuffy.ad HDRS = xbuffy.h xbuffy.xbm CLEANFILES=xbuffy @LED@ *.o *~ all: xbuffy @LED@ xbuffy: $(LIBDYN) $(OBJS) $(CC) -o xbuffy $(OBJS) $(LIBDYN) $(LDFLAGS) $(LIBS) led: led.o $(CC) -o led led.o $(LDFLAGS) $(LIBDYN): (cd libdyn && $(MAKE) CC="$(CC)" CFLAGS="$(CFLAGS) -I..") install: xbuffy @LED@ $(srcdir)/mkinstalldirs $(bindir) -mv -f $(bindir)/xbuffy $(bindir)/xbuffy.old $(INSTALL) -m 755 xbuffy $(bindir) -if [ "@LED@" ]; then \ $(INSTALL) -m 4755 led $(bindir); \ fi $(srcdir)/mkinstalldirs $(mandir)/man1 $(INSTALL) -m 644 $(srcdir)/xbuffy.man $(mandir)/man1/xbuffy.1 -if [ ! -f $(libdir)/X11/app-defaults/XBuffy ]; then \ $(srcdir)/mkinstalldirs $(libdir)/X11/app-defaults; \ $(INSTALL) -m 644 $(srcdir)/XBuffy.ad $(libdir)/X11/app-defaults/XBuffy; \ fi uninstall: rm -f $(bindir)/xbuffy $(mandir)/man1/xbuffy.1 -if [ "@LED@" ]; then \ rm -f $(bindir)/led \ fi -mv -f $(bindir)/xbuffy.old $(bindir)/xbuffy config.h.in: $(srcdir)/acconfig.h autoheader config.h: $(srcdir)/config.h.in ./config.status dep: Makefile mv Makefile Makefile.bak awk -f $(srcdir)/depend.awk < Makefile.bak > Makefile echo '# DO NOT REMOVE THIS LINE' >> Makefile $(CC) -MM $(XCPPFLAGS) $(srcdir)/*.c >> Makefile clean: (cd $(srcdir) && rm -f $(CLEANFILES)) (cd $(srcdir)/libdyn && $(MAKE) $@) distclean: clean (cd $(srcdir) && rm -f config.cache config.log config.status \ Makefile config.h tags) xbuffy-3.3.bl.3.orig/TODO0000644000175000017500000000034606473242266013204 0ustar brlbrlHere's some of the features that I want to add in the future..... - Allow different colors for each box. - Enhance what can be done in the boxfile. - Allow a double column/row format. - Something like xbiffs -file option xbuffy-3.3.bl.3.orig/README.BL0000644000175000017500000001065306546414652013673 0ustar brlbrl Brandon Long blong@fiction.net 6/30/1998 Version: 3.3.bl.3 XBuffy - An Improved X Multibiff ================================ This is xbuffy, an X program designed to watch multiple mail folders for new mail. This version supports mbox/mh/maildir and "nntp" folders. This is a modified version of xbuffy 3.3 by Bill Pemberton (wfp5p@virginia.edu). Note that the rpm xbuffy-3.3-2 contains everything but the debian bugfixes and debian xbuffy-3.3-1 doesn't have the atime and mdir patches. To build, just type: configure make If you want to use nntp, use the --enable-nntp switch. You might want to set a default server by using --enable-nntp=. The environment variable NNTPSERVER will always override the default. Future versions will probably allow you to set the server in the boxfile (after all, how else can you watch multiple news servers?) If you want a "nicer" look, you can try an alternate widget set. Most non-linux people might want to try Motif, use the --with-motif option to configure. If you have an alternative Athena widget set installed, you can use that. Try --with-xaw3d, --with-xaw95 or --with-neXtaw. If you have linked an alternative Athena widget set to the libXaw shared library, you don't need to specify a different set. This version also includes LINUX specific LED blinking support if you compile with --enable-led. This compiles a separate program (led) which must be installed suid root to access the LINUX console driver. Xbuffy will then recognize the boxfile command 'led' to blink one of the led's on the keyboard to announce new mail. LED support was provided by Anders Johansson of Linköping University . The standard thing to do is to create a boxfile (I usually use ~/.xbuffy) and place in it commands to watch your mail folders. ---- .xbuffy ------ box /var/mail/blong title Incoming polltime 5 headertime 0 audio cat /Archive/multimedia/sound/au/glass.au > /dev/audio command xterm -fn 7x13 -title "Mutt Incoming" -e mutt & box ~/Mail/received title Received headertime 0 command xterm -fn 7x13 -title "Mutt Received" -e mutt -f =received & box ~/Mail/mutt title Mutt headertime 0 polltime 15 command xterm -fn 7x13 -title "Mutt Mutt" -e mutt -f =mutt & box comp.mail.elm newsbox polltime 100 command xterm -fn 7x13 -title "Mutt comp.mail.elm" -e mutt -f "[news]comp.mail.elm" & --------------------- Maildir/MH Notes: ------------------ You specify a maildir/mh folder by pointing "box" at the directory which is the folder. Normally, you can pick whether to show only the new messages or all of the messages in the mailbox when you click the left button on the mailbox button. With maildir/mh folders, you only get the new messages regardless of this setting. This version of xbuffy makes the same assumptions that Mutt does about these folders, namely that a Maildir folder is a directory with subdirectories of cur, tmp, and new. An MH folder is a directory with a .xmhcache or .mh_sequences file in it. Version Notes -------------- Version 3.3.bl.3: - Added support for LINUX console LED blinking on new mail from Anders Johansson of Linköping University . - Improvements to configure script for finding weird install places for X and Motif libraries. If this doesn't find yours, you can still specify it with --with-motif=/path/to/motif. Please mail me if you're system has it somewhere else. - Use the debian Xresources (XBuffy.ad), they're nicer Version 3.3.bl.2: - Added support for autoconf configuration to replace Imake - Suggestions/code from Ralf Hildebrandt (R.Hildebrandt@tu-bs.de) - Make main() return an int to keep the Xserver from complaining - some platforms (HP-UX 9.x) don't have utimes(), now use substitute - -center can cause coredump Version 3.3.bl.1: - xbuffy.time.patch by David DeSimone (fox@convex.hp.com) - no longer crashes if mailbox doesn't exist - alignment code bug - don't modify the access-time of mailboxes when checking them to allow other biff's to notice new mail as well - xbuffy.mdir.patch by Brandon Long (blong@fiction.net) - adds support for mh and maildir folders - xbuffy_3.3-1.diff debian patch by Joel Rosdahl - fixes a typo in the NNTP support - Removed a bit of NNTP correctness checking that caused problems - init NNTP boxes the same way you init MAIL boxes xbuffy-3.3.bl.3.orig/configure.in0000644000175000017500000001172606546412700015022 0ustar brlbrldnl Process this file with autoconf to produce a configure script. AC_INIT(xbuffy.h) AC_CONFIG_HEADER(config.h) VERSION=3.3 SUBVERSION=.bl.3 AC_MSG_CHECKING(for prefix) if test x$prefix = xNONE; then xbuffy_cv_prefix=$ac_default_prefix else xbuffy_cv_prefix=$prefix fi AC_MSG_RESULT($xbuffy_cv_prefix) AC_PROG_CC AC_PROG_MAKE_SET AC_PROG_INSTALL AC_DEFINE_UNQUOTED(VERSION, "$VERSION$SUBVERSION") AC_SUBST(VERSION) AC_PATH_XTRA if test -d "$x_includes"; then CPPFLAGS="$CPPFLAGS -I${x_includes}" AC_MSG_RESULT(Found X includes at $x_includes) fi if test -d "$x_libraries"; then LDFLAGS="-L${x_libraries} $LDFLAGS" AC_MSG_RESULT(Found X libraries at $x_libraries) fi dnl AC_CHECK_LIB(ICE, IceOpenConnection, dnl [X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE"],, [$X_EXTRA_LIBS]) LIBS="$LIBS -lXmu -lXt -lX11" dnl Check for -lXext AC_CHECK_LIB(Xext, XShapeQueryExtension, LIBS="-lXext $LIBS",, -lX11 $X_EXTRA_LIBS) XAW=yes AC_ARG_WITH(xaw3d, [ --with-xaw3d[=DIR] use Xaw3d instead of Xaw], [if test $withval != yes; then xbuffy_cv_xaw3d=$withval LDFLAGS="-L${xbuffy_cv_xaw3d}/lib $LDFLAGS" CPPFLAGS="$CPPFLAGS -I${xbuffy_cv_xaw3d}/include" fi LIBS="-lXaw3d $LIBS" XAW=no ]) AC_ARG_WITH(xaw95, [ --with-xaw95[=DIR] use Xaw95 instead of Xaw], [if test $withval != yes; then xbuffy_cv_xaw95=$withval CPPFLAGS="$CPPFLAGS -I${xbuffy_cv_xaw95}/include" LDFLAGS="-L${xbuffy_cv_xaw95}/lib $LDFLAGS" fi LIBS="-lXaw95 $LIBS" XAW=no ]) AC_ARG_WITH(neXtaw, [ --with-neXtaw[=DIR] use neXtaw instead of Xaw], [if test $withval != yes; then xbuffy_cv_nextaw=$withval CPPFLAGS="$CPPFLAGS -I${xbuffy_cv_nextaw}/include" LDFLAGS="-L${xbuffy_cv_nextaw}/lib $LDFLAGS" fi LIBS="-lneXtaw $LIBS" XAW=no ]) xbuffy_cv_motif=no AC_ARG_WITH(motif, [ --with-motif[=DIR] use Motif instead of Xaw], [if test $withval != yes; then xbuffy_cv_motif=$withval fi AC_DEFINE(USE_MOTIF) if test x$xbuffy_cv_motif != xno; then LIBS="-lXm $LIBS" LDFLAGS="-L${xbuffy_cv_motif}/lib $LDFLAGS" CPPFLAGS="$CPPFLAGS -I${xbuffy_cv_motif}/include" XAW=no else motif_includes="`echo $x_includes|sed 's%/[^/][^/]*%%'` /local/Motif*/include /local/include/Motif* /usr/local/Motif*/include /usr/local/include/Motif* /usr/include/Motif* /usr/Motif*/include /usr/local/include /usr/local/X11*/include /usr/include /usr/include/X11* /usr/dt/include" AC_MSG_CHECKING(for location of Motif headers) xbuffy_motif_include= for try in $motif_includes; do if test -f "$try/Xm/Xm.h"; then xbuffy_motif_include=$try fi done if test -n "$xbuffy_motif_include"; then AC_MSG_RESULT($xbuffy_motif_include) motif_libs="`echo $x_libraries|sed 's%/[^/][^/]*$%%'` `echo "$xbuffy_motif_include" | sed s/include/lib/` /local/Motif*/lib /local/lib/Motif* /usr/local/Motif*/lib /usr/local/lib/Motif* /usr/Motif*/lib /usr/lib/Motif* /usr/local/lib /usr/local/X11*/lib /usr/lib /usr/lib/X11* /usr/dt/lib" AC_MSG_CHECKING(for location of Motif libraries) xbuffy_motif_lib= for try in $motif_libs; do if test -f "$try/libXm.a" -o -f "$try/libXm.so" -o -f "$try/libXm.sl"; then xbuffy_motif_lib=$try fi done if test -n "$xbuffy_motif_lib"; then AC_MSG_RESULT($xbuffy_motif_lib) XAW=no CPPFLAGS="$CPPFLAGS -I${xbuffy_motif_include}" LIBS="-lXm $LIBS" LDFLAGS="-L${xbuffy_motif_lib} $LDFLAGS" else AC_MSG_RESULT() fi else AC_MSG_RESULT() fi fi]) dnl Default to Athena libraries if test x$XAW = xyes; then LIBS="-lXaw -lXext -lXmu $LIBS" AC_MSG_RESULT(Defaulting to Athena Widgets) fi xbuffy_led=no AC_ARG_ENABLE(led, [ --enable-led Enable LINUX specific LED support], [if test $enableval = yes; then xbuffy_led=yes fi ]) if test $xbuffy_led = yes; then AC_DEFINE(USE_LED) LED=led AC_SUBST(LED) AC_MSG_RESULT(Enabling LINUX keyboard LED blinking support) else AC_MSG_RESULT(Disabling keyboard LED blinking support) fi xbuffy_nntp_server=no AC_ARG_ENABLE(nntp, [ --enable-nntp[=server] Enable NNTP 'Mailbox' support], [if test x$enableval != xyes; then xbuffy_nntp_server=$enableval fi AC_DEFINE(USE_NNTP) LIBOBJS="$LIBOBJS nntp.o" AC_CHECK_LIB(socket, socket) AC_CHECK_LIB(nsl, gethostbyname) if test x$xbuffy_nntp_server != xno; then AC_DEFINE_UNQUOTED(NNTP_SERVER, "$xbuffy_nntp_server") AC_SUBST(NNTP_SERVER) AC_MSG_RESULT(Using NNTP Server $xbuffy_nntp_server) fi]) xbuffy_cv_length=yes AC_ARG_ENABLE(length, [ --disable-length Do NOT use Content-Length: header], [if test $enableval = no; then xbuffy_cv_length=no; AC_MSG_RESULT(Disabling Content-Length: Header) fi]) if test $xbuffy_cv_length = yes; then AC_DEFINE(USE_CONTENT_LENGTH) fi AC_HEADER_STDC AC_CHECK_FUNCS(setpriority) AC_REPLACE_FUNCS(utimes strdup bcopy) AC_OUTPUT(Makefile libdyn/Makefile) xbuffy-3.3.bl.3.orig/led.c0000644000175000017500000000501606546405643013424 0ustar brlbrl#include #include #include #include #include #define LedModeOff 0 #define LedModeOn 1 #define TERMINATESTR "Program (and child) terminated.\n" #define NUMLOCKLED 1 #define CAPSLOCKLED 2 #define SCROLLLOCKLED 3 #define KEYBOARDDEVICE "/dev/console" typedef enum { CLEAR = 0, SET = 1 } LedMode; void led (int what, LedMode mode); inline void clear_led (int what) { led(what, CLEAR); } inline void set_led (int what) { led(what, SET); } void my_exit (int sig); static int keyboardDevice = 0; int led_num; int main(int argc, char** argv) { int i,num,parent; if (geteuid()) { fprintf(stderr, "led must be run as root!\n"); exit(1); } if (argc!=3) { fprintf(stderr, "led: Wrong number of arguments\n"); exit(1); } led_num=strtol(argv[1], (char **)NULL, 10); num=strtol(argv[2], (char **)NULL, 10); if (num <= 0) exit(0); /* What's the point? */ signal(SIGINT, my_exit); signal(SIGTERM, my_exit); if (! geteuid()) { /* We are running as EUID root - CONSOLE */ if (-1 == (keyboardDevice = open(KEYBOARDDEVICE, O_RDONLY))) { perror(KEYBOARDDEVICE); fprintf(stderr, TERMINATESTR); exit(1); } } while(1) { i = getppid(); /* Check if parent is dead, then go kill your self */ if (i == 1 || kill(i, 0)==(-1)) { exit(0); } for (i = 0; i < num; i++) { set_led(led_num); usleep(100000); clear_led(led_num); usleep(150000); } usleep(500000); } } void my_exit(int sig) { clear_led(led_num); if (keyboardDevice) { /* EUID root - CONSOLE */ close(keyboardDevice); } exit(0); } void led (int led, LedMode mode) { char ledVal; struct { int led_mode; int led; } values; switch (mode) { case SET: values.led_mode = LedModeOn; break; case CLEAR: values.led_mode = LedModeOff; break; } values.led = led; if (ioctl(keyboardDevice, KDGETLED, &ledVal)) { perror("KDGETLED"); exit(1); } switch (led) { case SCROLLLOCKLED: if (mode == SET) ledVal |= LED_SCR; else ledVal &= ~LED_SCR; break; case NUMLOCKLED: if (mode == SET) ledVal |= LED_NUM; else ledVal &= ~LED_NUM; break; case CAPSLOCKLED: if (mode == SET) ledVal |= LED_CAP; else ledVal &= ~LED_CAP; break; default: perror("Invalid led-value"); exit(1); } if (ioctl(keyboardDevice, KDSETLED, ledVal)) { perror ("KDSETLED"); exit(1); } } xbuffy-3.3.bl.3.orig/install-sh0000755000175000017500000001124406473252046014514 0ustar brlbrl#! /bin/sh # # install - install a program, script, or datafile # This comes from X11R5. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" tranformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 xbuffy-3.3.bl.3.orig/mkinstalldirs0000755000175000017500000000133406474233532015315 0ustar brlbrl#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain # $Id: mkinstalldirs,v 1.10 1996/05/03 07:37:52 friedman Exp $ errstatus=0 for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" 1>&2 mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr fi fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here