rsalz@uunet.uu.net (Rich Salz) (03/07/89)
Submitted-by: Kevin Sweet <sweet@scubed.arpa> Posting-number: Volume 18, Issue 2 Archive-name: mq Replacements for mailq and from: mq - selectively display the mail queue. options exist to list mail from or to a particular site, list mail exclusive of a particular site, and list mail without the truncation of long pathnames. from - makes `from' output look somewhat like `Mail' "header" output in that it prints out a minimalistic pathname to the sender and the subject line. It catches subject titles that `Mail' some- times misses like news articles saved in mbox format. I have listed the machine/OS combinations (BSD/SysV) that I have successfully compiled and run the programs in the Makefile. One comment, however. No checking is done with respect to what other programs (or users) are doing to the mail queue files and mailboxes. (I have received segmentation faults _occasionally_ when, I assume, `sendmail' is deleting a file that `mq' wants to read. I'm a scientific programmer that did this for "fun" and don't know what to do about this situation. `From' seems to be pretty resilient, though.) Kevin Sweet -- Kevin Sweet ----------------------------------------- sweet@scubed.arpa S-CUBED, 3398 Carmel Mountain, San Diego, CA 92121-1095, (619)587-8499 (home) 12205 Carmel Vista 242, San Diego, CA 92130-2237, (619)259-9338 UUCP/ARPA: [ames,att,harvard,rutgers,ucsd,uunet]scubed!sweet DECNET: SDSC::"SWEET@S3VAX.SPAN" , 1.312::SWEET #---cut here---cut here---cut here---cut here---cut here---cut here--- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # README # Makefile # mq.c # from.c # from.1 # mq.8 # echo shar: extracting "README" '(1426 characters)' if test -f README then echo shar: will not over-write existing file "README" else sed 's/^XX//' << \SHAR_EOF > README XXReplacements for mailq and from: XX XXmq - selectively display the mail queue. XX options exist to list mail from or to a particular site, list XX mail exclusive of a particular site, and list mail without the XX truncation of long pathnames. XX XXfrom - makes `from' output look somewhat like `Mail' "header" output XX in that it prints out a minimalistic pathname to the sender and XX the subject line. It catches subject titles that `Mail' some- XX times misses like news articles saved in mbox format. XX XXI have listed the machine/OS combinations (BSD/SysV) that I have XXsuccessfully compiled and run the programs in the Makefile. XX XXOne comment, however. No checking is done with respect to what other XXprograms (or users) are doing to the mail queue files and mailboxes. XX(I have received segmentation faults _occasionally_ when, I assume, XX `sendmail' is deleting a file that `mq' wants to read. I'm a scientific XX programmer that did this for "fun" and don't know what to do about this XX situation. `From' seems to be pretty resilient, though.) XX XXKevin Sweet, 22 April 1988 XX-- XXKevin Sweet ----------------------------------------- sweet@scubed.arpa XXS-CUBED, 3398 Carmel Mountain, San Diego, CA 92121-1095, (619)587-8499 XX(home) 12205 Carmel Vista 242, San Diego, CA 92130-2237, (619)259-9338 XXUUCP/ARPA: [ames,att,harvard,rutgers,ucsd,uunet]scubed!sweet XXDECNET: SDSC::"SWEET@S3VAX.SPAN" , 1.312::SWEET SHAR_EOF if test 1426 -ne "`wc -c < README`" then echo shar: error transmitting "README" '(should have been 1426 characters)' fi fi # end of overwriting check echo shar: extracting "Makefile" '(1345 characters)' if test -f Makefile then echo shar: will not over-write existing file "Makefile" else sed 's/^XX//' << \SHAR_EOF > Makefile XX# `C' compiler void compatibility XXVOID='-DVOID=(void)' XX XX# BSD compatibility XX# kelvin.arpa: Celerity C1230/C1260 UNIX 3.4.78 XX# scubed.arpa: Ultrix V2.0-1 XX# s3sun.arpa: Sun UNIX 4.2 Release 3.0 XX# s3dawn.scubed.arpa: Sun UNIX 4.2 Release 3.4 XX XX## SysV compatitibilty XX## space.scubed.arpa: Ridge 32/3200 running RX/V 1.1 (V.2) XX## sdcc15.ucsd.edu: UNIX System V Release 2.1.1v4 AT&T 3B20 XX#NDIR= -I/usr/local XX#LIBNDIR= -L/usr/local/lib -lndir XX## if the default set-up for the directory files doesn't work, XX## `$man directory' should tell you where the appropriate files are XX## located on your system (if they are there at all). Comment out the XX## above two lines and adjust $(LIBNDIR) below as well as changing the XX## include line in mq.c to the appropriate value. XX##LIBNDIR= -L/usr/ucb.lib -lucb XX#OS= -DSYSV $(NDIR) XX XX# system mailbox directory (the trailing slash is needed) and XX# system mail queue directory (no trailing slash!) XXMAIL= '-DMAILDIR="/usr/spool/mail/"' '-DMQUEUE="/usr/spool/mqueue"' XX XXCFLAGS= -O $(OS) $(VOID) $(MAIL) XX XXall: mq from XX XXmq: mq.o XX cc -o mq mq.o $(LIBNDIR) XX XXfrom: from.o XX cc -o from from.o XX XXclean: Makefile XX @rm -f core mq.o from.o XX XXclobber: clean XX @rm -f mq from mq.shar XX XXcleanse: clean shar XX @rm -f mq from mq.c from.c mq.8 from.1 README Makefile XX XXshar: Makefile XX shar README Makefile mq.c from.c from.1 mq.8 > mq.shar SHAR_EOF if test 1345 -ne "`wc -c < Makefile`" then echo shar: error transmitting "Makefile" '(should have been 1345 characters)' fi fi # end of overwriting check echo shar: extracting "mq.c" '(9946 characters)' if test -f mq.c then echo shar: will not over-write existing file "mq.c" else sed 's/^XX//' << \SHAR_EOF > mq.c XX/* program for selectively displaying the mail queue. XX * XX * usage: XX * mq [-w] [-n] [-v] [-f [name]] [-t [name]] [-d name] XX * XX * caveats/comments: XX * -> 1) no checking is done w.r.t. what other programs are doing XX * to the mail queue files. XX * 2) items in the queue without a control file are ignored and XX * not counted. XX * 3) one might also want to sort by priority. XX * XX * author: XX * Kevin Sweet ---------------------------------- sweet@scubed.arpa XX * S-CUBED, 3398 Carmel Mountain, San Diego, CA 92121-1095 XX * (home) 12205 Carmel Vista 242, San Diego, CA 92130-2237 XX * ------- [ames,att,harvard,rutgers,ucsd,uunet]scubed!sweet ------ XX * XX * This work is copyright 1988 by Kevin Sweet. Permission is granted XX * to modify and distribute this work under the provision that the XX * author is informed of any non-cosmetic changes to the code and that XX * the author's name remain part of the documentaion. XX */ XX XX#ifndef VOID XX# define VOID XX#endif XX#include <sys/types.h> XX#include <sys/stat.h> XX#ifdef SYSV XX# include <string.h> XX# define index strchr XX# define rindex strrchr XX# include <ndir.h> /* see Makefile... */ XX#else /* SYSV */ XX# include <strings.h> XX# include <sys/dir.h> XX#endif XX#include <stdio.h> XX#include <ctype.h> XX XXint order(); XXextern int free(), qsort(); XXextern long atol(); XXextern char *ctime(), *getenv(), *malloc(); XXstatic int gethelp(); XX XX#define FALSE 0 XX#define LSIZE 256 XX#define MALLOC(a) (char *) malloc( (unsigned) sizeof(char) * \ XX ((a) + 1) ) XX#define NUMQ 128 XX/* #define SORT_BY_ID /**/ XX#define SORT_BY_TIME /**/ XX#define SWITCHAR '-' XX#define TRUE 1 XX XXstruct mqueue { XX long l; /* location in directory stream */ XX long t; /* time entered queue */ XX char q[8]; /* queue id */ XX}; XXtypedef unsigned short int BOOLEAN; XX XXmain(argc, argv) XXint argc; XXchar *argv[]; XX{ XX BOOLEAN DONT, FROM, NUMBER, TO, VERBOSE, WIDE; XX DIR *dp; XX FILE *fp; XX char dont[80], from[80], line[LSIZE], to[80]; XX register char *cp, *fg, *message, *qdir, *user; XX register int i, icnt, ldont, lfrom, lto, mcnt, qcnt, qdlen; XX register long size; XX struct direct *dirp; XX struct mqueue qinfo[NUMQ]; XX struct stat sbuf; XX XX /* find the print options XX */ XX#ifdef SYSV XX user = getenv("LOGNAME"); XX#else XX user = getenv("USER"); XX#endif XX DONT = FROM = NUMBER = TO = VERBOSE = WIDE = FALSE; XX for (i = 1, cp = argv[1]; i < argc; i++, cp = argv[i]) XX if (cp[0] == SWITCHAR) XX switch (cp[1]) { XX case 'h': case 'H': XX gethelp(argv[0], 0); XX case 'n': case 'N': XX NUMBER = TRUE; XX break; XX case 'w': case 'W': XX WIDE = TRUE; XX break; XX case 'v': case 'V': XX VERBOSE = TRUE; XX break; XX case 'f': case 'F': XX FROM = TRUE; XX if (cp[2]) XX sprintf(from, "%.79s", &argv[i][2]); XX else XX if (i != argc-1 && argv[i+1][0] != SWITCHAR) { XX sprintf(from, "%.79s", argv[i+1]); XX i++; XX } XX else XX sprintf(from, "%.79s", user); XX lfrom = strlen(from); XX break; XX case 't': case 'T': XX TO = TRUE; XX if (cp[2]) XX sprintf(to, "%.79s", &argv[i][2]); XX else XX if (i != argc-1 && argv[i+1][0] != SWITCHAR) { XX sprintf(to, "%.79s", argv[i+1]); XX i++; XX } XX else XX sprintf(to, "%.79s", user); XX lto = strlen(to); XX break; XX case 'd': case 'D': XX DONT = TRUE; XX if (cp[2]) XX sprintf(dont, "%.79s", &argv[i][2]); XX else XX if (i != argc-1 && argv[i+1][0] != SWITCHAR) { XX sprintf(dont, "%.79s", argv[i+1]); XX i++; XX } XX else XX sprintf(dont, "%c", '\0'); XX ldont = strlen(dont); XX if (!ldont) DONT = FALSE; XX break; XX default: XX printf("invalid option '%c': ", cp[1]); XX gethelp(argv[0], -1); XX } /* end switch */ XX else XX { XX gethelp(argv[0], 0); XX } /* end for/if */ XX XX /* find the mqueue directory. XX */ XX qcnt = 0; XX#ifndef DEBUG XX if ( !(fp = fopen("/usr/lib/sendmail.cf", "r")) ) { XX printf("fatal error: "); XX printf("unable to read /usr/lib/sendmail.cf\n"); XX gethelp(argv[0], 1); XX } XX while ((fg = fgets(line, LSIZE, fp)) != (char *) NULL) { XX if (strncmp(fg, "OQ", 2)) continue; XX fg[strlen(line)-1] = '\0'; XX fg += 2; XX qcnt++; XX qdlen = strlen(fg) + 1; XX qdir = MALLOC(qdlen); XX strncpy(qdir, fg, qdlen - 1); XX break; XX } XX fclose(fp); XX#endif /* DEBUG */ XX if (!qcnt) { XX qdlen = strlen(MQUEUE) + 1; XX qdir = MALLOC(qdlen); XX strncpy(qdir, MQUEUE, qdlen - 1); XX } XX XX /* find queue files in the mqueue directory: XX * save the location in the directory stream, the queue id and XX * the time for each vaild (non-zero length) queue control file. XX */ XX if ( !(dp = opendir(qdir)) ) { XX printf("fatal error: "); XX printf("unable to open directory %s\n", qdir); XX gethelp(argv[0], 2); XX } XX mcnt = qcnt = 0; XX for (dirp = readdir(dp); dirp != (struct direct *) NULL; XX dirp = readdir(dp)) XX if (!strncmp(dirp->d_name, "qf", 2)) { XX /* XX * open the file and test it for validity XX */ XX cp = MALLOC(qdlen + 1 + strlen(dirp->d_name)); XX sprintf(cp, "%s/%s", qdir, dirp->d_name); XX fp = fopen(cp, "r"); XX VOID stat(cp, &sbuf); XX VOID free(cp); XX if (!fp) continue; XX if (!sbuf.st_size) { XX fclose(fp); XX continue; XX } XX /* XX * do book-keeping XX */ XX icnt = 0; XX mcnt++; XX if (qcnt < NUMQ) XX /* XX * check to see if we are supposed to print the entry XX */ XX while ( fg = fgets(line, LSIZE, fp) ) { XX fg[strlen(line)-1] = '\0'; XX if (*fg == 'S') { XX if (FROM) { XX for (; *fg; *fg++) XX if (!strncmp(fg, from, lfrom)) XX icnt |= 0x001; XX } else XX icnt |= 0x001; XX } else XX if (*fg == 'R') { XX if (TO) { XX for (; *fg; *fg++) XX if (!strncmp(fg, to, lto)) XX icnt |= 0x002; XX } else XX icnt |= 0x002; XX if (DONT) { XX for (; *fg; *fg++) XX if (!strncmp(fg, dont, ldont)) XX icnt |= 0x004; XX } XX } XX } /* end while loop */ XX XX if ( (icnt & 0x004) || XX !(icnt & 0x002) || XX !(icnt & 0x001) ) { XX /* XX * either DONT was specified _and_ we found XX * the dont field in the Receiver field, XX * or TO was specified _and_ we did not find XX * the to field in the Receiver field, XX * or FROM was specified _and_ we did not find XX * the from field in the Sender field; XX * or we have exceeded the array dimension for XX * holding queue information. XX */ XX fclose(fp); XX continue; XX } XX /* XX * save the location in the directory stream XX */ XX qinfo[qcnt].l = telldir(dp); XX /* XX * save the queue id XX */ XX sprintf(qinfo[qcnt].q, "%.7s", XX index(dirp->d_name, 'f')+1); XX /* XX * save the queue time XX */ XX VOID fseek(fp, 0L, 0); XX while ((fg = fgets(line, LSIZE, fp)) && *fg != 'D') XX if (*fg == 'T') qinfo[qcnt].t = atol(&line[1]); XX /* XX * increment the valid queue file counter XX */ XX qcnt++; XX fclose(fp); XX } XX closedir(dp); XX XX /* print the requisite header XX */ XX if (!qcnt) { XX if (!mcnt) printf("Mail queue is empty\n"); XX else { XX printf("Mail Queue (%d request%c", XX mcnt, mcnt > 1 ? 's' : '\0'); XX printf(", none %s)\n", XX NUMBER == TRUE ? "applied" : "printed"); XX } XX exit(0); XX } XX printf("%sMail Queue (%d request%c", NUMBER == TRUE ? "" : XX ( VERBOSE == TRUE ? " " : "\t\t" ), XX mcnt, mcnt > 1 ? 's' : '\0'); XX if (qcnt != mcnt) XX printf(", only %d %s", qcnt, XX NUMBER == TRUE ? "applied" : "printed"); XX printf(")\n"); XX XX if (NUMBER) exit(0); XX XX if (VERBOSE == FALSE) XX printf("%s%s\n", "--QID-- --Size-- -----Q-Time----- ", XX "------------Sender/Recipient-----------------"); XX XX /* sort the queue files XX */ XX VOID qsort(qinfo, qcnt, sizeof(struct mqueue), order); XX XX /* loop through the valid queue files: XX */ XX for (icnt = 0; icnt < qcnt; icnt++) { XX cp = MALLOC(qdlen + 2 + strlen(qinfo[icnt].q)); XX sprintf(cp, "%s/qf%s", qdir, qinfo[icnt].q); XX fp = fopen(cp, "r"); XX VOID free(cp); XX XX /* read in everything up to the first header line XX */ XX mcnt = 0; XX while ( fg = fgets(line, LSIZE, fp) ) { XX XX /* get rid of the trailing newline XX */ XX fg[strlen(line)-1] = '\0'; XX XX /* get the size of the data file (long) XX */ XX if (*fg == 'D') { XX cp = MALLOC(qdlen + strlen(fg)); XX sprintf(cp, "%s/%s", qdir, &line[1]); XX VOID stat(cp, &sbuf); XX size = (long) sbuf.st_size; XX VOID free(cp); XX } else XX /* XX * get the error message (char *) XX */ XX if (*fg == 'M') { XX message = MALLOC(strlen(fg)); XX sprintf(message, "%s", &line[1]); XX mcnt++; XX } else XX /* XX * get the sender (char *) XX */ XX if (*fg == 'S') { XX/* XX * print out what we have so far XX */ XXif (VERBOSE) { XX if (WIDE) printf("from: %s\n", &line[1]); XX else printf("from: %.73s\n", &line[1]); XX} else { XX printf("%-7.7s %8ld %.16s ", XX qinfo[icnt].q, size, ctime(&qinfo[icnt].t)); XX if (WIDE) { XX printf("%s\n", &line[1]); XX if (mcnt) printf("\t\t\t\t (%s)\n", message); XX } else { XX printf("%.45s\n", &line[1]); XX if (mcnt) printf("\t\t\t\t (%.43s)\n", message); XX } XX} XX size = 0L; XX if (mcnt) VOID free(message); XX } else XX /* XX * get the recipients (char *) XX */ XX if (*fg == 'R') { XX /* XX * print out the rest XX */ XX if (VERBOSE) { XX printf(" to: "); XX if (WIDE) XX printf("%s\n", &line[1]); XX else XX printf("%.69s\n", &line[1]); XX } else { XX printf("\t\t\t\t "); XX if (WIDE) XX printf("%s\n", &line[1]); XX else XX printf("%.45s\n", &line[1]); XX } XX } XX XX } /* end fp loop */ XX fclose(fp); XX XX if (VERBOSE) printf(" in queue since: %.16s\n", XX ctime(&qinfo[icnt].t)); XX XX } /* end valid queue file loop */ XX XX exit(0); XX} XX XX/* qsort comparison function. XX */ XXint XXorder(e1, e2) XXstruct mqueue *e1; XXstruct mqueue *e2; XX{ XX#ifdef SORT_BY_TIME XX if (e1->t < e2->t) return(-1); XX else if (e1->t > e2->t) return(1); XX else return(0); XX#endif XX#ifdef SORT_BY_ID XX return(strcmp(e1->q, e2->q)); XX#endif XX} XX XX/* the help/usage message XX */ XXstatic XXint XXgethelp(program, exit_status) XXchar *program; XXint exit_status; XX{ XX register char *name; XX XX name = rindex(program, '/'); XX if (name) *name++; XX else { XX name = rindex(program, '\\'); XX if (name) *name++; XX else name = program; XX } XX printf("usage: %s [-w] [-n] [-v]", name); XX printf(" [-f [name]] [-t [name]] [-d name]\n"); XX exit(exit_status); XX} XX SHAR_EOF if test 9946 -ne "`wc -c < mq.c`" then echo shar: error transmitting "mq.c" '(should have been 9946 characters)' fi fi # end of overwriting check echo shar: extracting "from.c" '(6741 characters)' if test -f from.c then echo shar: will not over-write existing file "from.c" else sed 's/^XX//' << \SHAR_EOF > from.c XX/* XX * usage: XX * from [-f] [file] [-d] [-w] [-s sender] [-u user] XX * XX * caveats/comments: XX * no checking is done w.r.t. what other programs are doing to the XX * mailboxes. XX * XX * author: XX * Kevin Sweet ---------------------------------- sweet@scubed.arpa XX * S-CUBED, 3398 Carmel Mountain, San Diego, CA 92121-1095 XX * (home) 12205 Carmel Vista 242, San Diego, CA 92130-2237 XX * ------- [ames,att,harvard,rutgers,ucsd,uunet]scubed!sweet ------ XX * XX * This work is copyright 1988 by Kevin Sweet. Permission is granted XX * to modify and distribute this work under the provision that the XX * author is informed of any non-cosmetic changes to the code and that XX * the author's name remain part of the documentaion. XX */ XX XX#ifdef SYSV XX# define MAXPATHLEN 1024 XX# include <string.h> XX# define index strchr XX# define rindex strrchr XX#else XX# include <sys/param.h> XX# include <strings.h> XX#endif XX#include <stdio.h> XX XXextern char *getenv(); XXstatic char *getmbox(); XXstatic int gethelp(); XX XX#define FORWARD 0 XX#define LSIZE 256 XX#define NUMQ 256 XX#define SWITCHAR '-' XX XXstruct mbox { XX char from[LSIZE]; XX char subject[LSIZE]; XX}; XX XXmain(argc, argv) XXint argc; XXchar *argv[]; XX{ XX FILE *fp; XX char line[LSIZE], mbox[MAXPATHLEN], path[LSIZE], sender[LSIZE]; XX register char *bang, *cp; XX register int DATE, SENDER, WIDE, XX from, i, j, left, mcnt, subject; XX struct mbox mail[NUMQ]; XX XX /* find the mail file to list along with any options XX */ XX strcpy(mbox, "\0"); XX DATE = SENDER = WIDE = 0; XX for (i = 1, cp = argv[1]; i < argc; i++, cp = argv[i]) { XX XX if (cp[0] == SWITCHAR) XX switch (cp[1]) { XX case 'h': case 'H': XX gethelp(argv[0], 0); XX case 'd': case 'D': XX DATE = 1; XX break; XX case 'w': case 'W': XX WIDE ++; XX if (cp[2] == 'w' || cp[2] == 'W') WIDE++; XX break; XX case 'f': case 'F': XX if (cp[2]) XX strncpy(mbox, &argv[i][2], MAXPATHLEN); XX else XX if (i != argc-1 && argv[i+1][0] != SWITCHAR) { XX strncpy(mbox, argv[i+1], MAXPATHLEN); XX i++; XX } XX else XX strncpy(mbox, getmbox(), MAXPATHLEN); XX break; XX case 's': case 'S': XX if (cp[2]) XX strncpy(sender, &argv[i][2], LSIZE); XX else XX if (i != argc-1 && argv[i+1][0] != SWITCHAR) { XX strncpy(sender, argv[i+1], LSIZE); XX i++; XX } XX else XX#ifdef SYSV XX strncpy(sender, getenv("LOGNAME"), LSIZE); XX#else XX strncpy(sender, getenv("USER"), LSIZE); XX#endif XX SENDER = strlen(sender); XX break; XX case 'u': case 'U': XX if (cp[2]) { XX strncpy(mbox, MAILDIR, MAXPATHLEN); XX strncat(mbox, &argv[i][2], XX MAXPATHLEN - strlen(mbox)); XX } XX else XX if (i != argc-1 || argv[i+1][0] != SWITCHAR) { XX strncpy(mbox, MAILDIR, MAXPATHLEN); XX strncat(mbox, argv[i+1], XX MAXPATHLEN - strlen(mbox)); XX i++; XX } XX else XX strcpy(mbox, "\0"); XX break; XX default: XX printf("invalid option '%c': ", cp[1]); XX gethelp(argv[0], -1); XX } /* end if/switch */ XX else XX strncpy(mbox, argv[i], MAXPATHLEN); XX XX } /* end for */ XX XX /* use the system mailbox if there are no arguments or if XX * there are any (fatal) errors XX */ XX if (!strlen(mbox)) { XX strncpy(mbox, MAILDIR, MAXPATHLEN); XX#ifdef SYSV XX strncat(mbox, getenv("LOGNAME"), XX#else XX strncat(mbox, getenv("USER"), XX#endif XX MAXPATHLEN - strlen(mbox)); XX } XX XX /* if we can't open the mailbox, exit quitely XX */ XX fp = fopen(mbox, "r"); XX if (!fp) exit(1); XX XX /* read in the sender and subject of each letter XX */ XX mcnt = -1; XX while ( cp = fgets(line, LSIZE, fp) ) { XX cp[strlen(line)-1] = '\0'; XX if (!strncmp(line, "From ", 5)) { XX if (mcnt >= 0 && !strlen(mail[mcnt].from)) XX strcpy(mail[mcnt].from, path); XX strcpy(path, index(line, ' ')+1); XX if (!DATE) { XX cp = index(path, ' '); XX if (cp) cp[0] = '\0'; XX } XX if (SENDER) { XX from = 1; XX subject = 1; XX cp = path; XX j = 0; XX for (; *cp; *cp++) XX if (!strncmp(cp, sender, SENDER)) j++; XX } else XX j = 1; XX if (j) { XX mcnt++; XX from = 0; XX subject = 0; XX } XX } else XX if (!from && ( !strncmp(line, "From: ", 6) || XX !strncmp(line+1, "From: ", 6) )) { XX if (!FORWARD) from = 1; XX if (DATE || WIDE > 1) { XX strcpy(mail[mcnt].from, path); XX continue; XX } XX cp = index(line, '<'); XX if (cp) *cp++; XX else cp = index(line, ' ')+1; XX strcpy(mail[mcnt].from, cp); XX cp = index(mail[mcnt].from, '>'); XX if (!cp) cp = index(mail[mcnt].from, ' '); XX if (cp) cp[0] = '\0'; XX } else XX if (!subject && !strncmp(line, "Subject: ", 9)) { XX if (!FORWARD) subject = 1; XX strcpy(mail[mcnt].subject, index(line, ' ')+1); XX if (DATE && !WIDE) XX strcpy(mail[mcnt].subject, "\0"); XX } XX } XX if (!strlen(mail[mcnt].from)) strcpy(mail[mcnt].from, path); XX XX /* display each entry: XX * if this isn't a wide list, use the shortest available name XX * for the sender and make sure that the subject does not XX * wrap 80 columns XX */ XX for (i = 0; i <= mcnt; i++) { XX cp = index(mail[i].from, '!'); XX bang = rindex(mail[i].from, '!'); XX if (!DATE && WIDE < 2) { XX if (!bang || !strcmp(cp, bang)) XX cp = mail[i].from; XX else XX { XX cp++; XX while (strcmp(index(cp, '!'), bang)) { XX cp = index(cp, '!'); XX cp++; XX } /* end while */ XX } XX } else XX cp = mail[i].from; XX left = 71 - (int) strlen(cp); XX printf("From %s", cp); XX if (DATE && !WIDE) putchar('\n'); XX else XX if (strlen(mail[i].subject)) { XX printf(", "); XX if (!WIDE) { XX putchar('"'); XX cp = mail[i].subject; XX for (j = 0; j < left; j++) XX if (*cp) putchar(*cp++); XX printf("\"\n"); XX } else XX printf("\"%s\"\n", mail[i].subject); XX } XX else XX printf(", (no subject)\n"); XX } XX XX fclose(fp); XX} XX XXstatic XXchar * XXgetmbox() XX{ XX FILE *fp; XX char line[LSIZE], mailrc[MAXPATHLEN], mbox[MAXPATHLEN]; XX register char *cp; XX XX /* find out where to look for mail startup file XX */ XX strncpy(mailrc, getenv("HOME"), MAXPATHLEN); XX strncat(mailrc, "/.mailrc", MAXPATHLEN - strlen(mailrc)); XX if (getenv("MAILRC")) XX strncpy(mailrc, getenv("MAILRC"), MAXPATHLEN); XX XX /* find out where to look for the default mailbox XX */ XX strncpy(mbox, getenv("HOME"), MAXPATHLEN); XX strncat(mbox, "/mbox", MAXPATHLEN - strlen(mbox)); XX fp = fopen(mailrc, "r"); XX if (fp) { XX while ( cp = fgets(line, LSIZE, fp) ) { XX cp[strlen(line)-1] = '\0'; XX if (strncmp(line, "set MBOX=", 9)) continue; XX cp += 9; XX strncpy(mbox, cp, MAXPATHLEN); XX break; XX } XX fclose(fp); XX } XX if (getenv("MBOX")) XX strncpy(mbox, getenv("MBOX"), MAXPATHLEN); XX XX return(mbox); XX} XX XX/* the help/usage message XX */ XXstatic XXint XXgethelp(program, exit_status) XXchar *program; XXint exit_status; XX{ XX register char *name; XX XX name = rindex(program, '/'); XX if (name) *name++; XX else { XX name = rindex(program, '\\'); XX if (name) *name++; XX else name = program; XX } XX printf("usage: %s [-f] [file] ", name); XX printf("[-d] [-w] [-s sender] [-u user]\n"); XX exit(exit_status); XX} XX SHAR_EOF if test 6741 -ne "`wc -c < from.c`" then echo shar: error transmitting "from.c" '(should have been 6741 characters)' fi fi # end of overwriting check echo shar: extracting "from.1" '(2208 characters)' if test -f from.1 then echo shar: will not over-write existing file "from.1" else sed 's/^XX//' << \SHAR_EOF > from.1 XX.de KS XX.if t .B \\$1 \\$2 XX.if n .I \\$1 \\$2 XX.. XX.de UL XX.if t \\$1\l'|0\(ul'\\$2 XX.if n .I \\$1 \\$2 XX.. XX.de Sh XX.PP XX\fB\\$1\fR XX.PP XX.. XX.TH FROM 1L local "22 April 1988" XX.SH NAME XXfrom \- list sender and subject of mail XX.SH SYNTAX XX.B from XX[\fB\-f\fR] XX[\fBfile\fR] XX[\fB\-d\fR] XX[\fB\-w\fR] XX[\fB\-s\fR [sender]] XX[\fB\-u\fR user] XX.SH DESCRIPTION XX.I From XXlists an abbreviated name for the sender of each letter in the XXspecified mail file XX.KS file XX(which XX.UL may XXbe preceded or prepended on the command line by \fB\-f\fR) XXalong with the subject of the letter so that both sets of information XXcan fit into 80 columns of standard output. XX.Sh Options XXWith no options, \fIfrom\fR lists the mail in the user's system mailbox. XX.TP 1i XX.B \-f XXIf XX.KS file XXis not specified, then mail in the file \fImbox\fR in XXthe user's home directory is listed (see ENVIRONMENT section for XXfurther details). XXOtherwise, mail in the mailbox XX.I file XXis listed. XX.TP XX.B \-h XXPrint the \fIfrom\fR syntax. XX.TP XX.B \-d XXThe complete return path and the date received are displayed. XX(This duplicates \fI/usr/ucb/from\fR.) XX.TP XX.B \-w XXThe \fB\-w\fR option is similar to that for \fIps\fR on BSD systems. XXSelecting \fB\-w\fR displays each entry in long form (in this case, XXa minimalist sender's address and the full subject); XXwhereas, \fB\-ww\fR displays each entry in unabridged form (i.e., the XXfull subject and the complete return path for the sender are listed). XX.TP XX.BR \-s " sender" XXOnly mail from \fIsender\fR is listed. \fISender\fR defaults to XX$LOGNAME on System V and to $USER on BSD systems. XX.TP XX.BR \-u " user" XXMail in \fIuser\fR's system mailbox is listed. XX.SH ENVIRONMENT XX.I From XXuses the following environment variables: XX.TP 1.375i XXHOME XXThe user's home (default login) directory. XX.TP XXUSER/LOGNAME XXThe user's user (login) name. XX.PP XXIf the environment variable MAILRC is set, XX.I from XXwill check the mail startup file specified by $MAILRC instead of XX\fI$HOME/.mailrc\fR. XXIf the environment variable MBOX is set, XX.I from XXwill recognize the default mailbox specified by $MBOX rather than XXthat specified in the mail startup file XXor XX\fI$HOME/mbox\fR. XX.SH "SEE ALSO" XX.ta 12n XXBSD \- \fIMail\fR(1) XX.br XXSystem V \- \fImailx\fR(1) XX.SH AUTHOR XXKevin Sweet SHAR_EOF if test 2208 -ne "`wc -c < from.1`" then echo shar: error transmitting "from.1" '(should have been 2208 characters)' fi fi # end of overwriting check echo shar: extracting "mq.8" '(1850 characters)' if test -f mq.8 then echo shar: will not over-write existing file "mq.8" else sed 's/^XX//' << \SHAR_EOF > mq.8 XX.de KS XX.if t .B \\$1 \\$2 XX.if n .I \\$1 \\$2 XX.. XX.de UL XX.if t \\$1\l'|0\(ul'\\$2 XX.if n \\$1 \\$2 XX.. XX.de Sh XX.PP XX\fB\\$1\fR XX.PP XX.. XX.TH MQ 8L local "22 April 1988" XX.SH NAME XXmq \- print the contents of the mail queue XX.SH SYNTAX XX.B mq XX[\fB\-w\fR] XX[\fB\-n\fR] XX[\fB\-v\fR] XX[\fB\-f\fR [name]] XX[\fB\-t\fR [name]] XX[\fB\-d\fR name] XX.SH DESCRIPTION XXBy default, XX.I mq XXlists the contents of the mail queue in the same format as XX.I sendmail XXwhen invoked as \fImailq\fR except that XXitems in the queue without a control file are not displayed by \fImq\fR. XXThat is, XXit displays an error message (if any), the queue identification code, XXfile size, queue time, sender, and recipient(s) for each entry in the XXqueue XXso that the result can fit into 80 columns of standard output. XX.Sh Options XX.TP 1i XX.B \-f XX\fBfrom\fR. XXIf XX.KS name XXis specified, \fImq\fR lists only messages with XX.KS name XXin the `sender' field. Otherwise, \fImq\fR will list only messages XXwith the user's login name (as given by the environment variable XXLOGNAME on System V and by USER on BSD systems) in the `sender' field. XX.TP XX.B \-t XX\fBto\fR. XXIf XX.KS name XXis specified, \fImq\fR lists only messages with XX.KS name XXin the `recipient' field. Otherwise, \fImq\fR will list only messages XXwith $USER/$LOGNAME in the `recipient' field. XX.TP XX.BR \-d " name" XX\fBdon't\fR. XXList all messages that XX.UL "do not" XXcontain the string XX.KS name XXin the `recipient' field. XX.TP XX.B \-h XX\fBhelp\fR. XXPrint the \fImq\fR syntax. XX.TP XX.B \-w XX\fBwide\fR. XX.I Mq XXwill not truncate `sender' and `recipient' fields on output. XX.TP XX.B \-n XX\fBnumber\fR. XXList only a count of the selected files in the mail queue. XX.TP XX.B \-v XX\fBverbose\fR. XXDisplay the contents of the mail queue listing the sender, XXrecipient(s) and queue time in noncolumnar format. XX.SH FILES XX/usr/lib/sendmail.cf XX.SH "SEE ALSO" XX\fIsendmail\fR(8) XX.SH AUTHOR XXKevin Sweet SHAR_EOF if test 1850 -ne "`wc -c < mq.8`" then echo shar: error transmitting "mq.8" '(should have been 1850 characters)' fi fi # end of overwriting check # # End of shell archive exit 0 -- -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.