ag@elgar.UUCP (Keith Gabryelski) (06/16/88)
comp.sources.misc: Volume 3, Issue 57 Submitted-By: "Keith Gabryelski" <ag@elgar.UUCP> Archive-Name: send Here is source code for a send program written under Sco Xenix 2.2.1. Also included is code for fsend (fast send) and its ilk, huh (display last send), and stom (send format to unix mailbox format converter). There should be no problem using this code on any system V machine. This code will not work on a BSD machine. Although it wouldn't be much work to port it. Send me your comments and bug reports/fixes. It's public domain... Your mileage may vary. --- "If green is all there is to be, then green is good enough for me" - ktf [ Keith ] UUCP: {ucsd, cbosgd!crash, sdcsvax!crash, nosc!crash}!elgar!ag [Gabryelski] INET: ag@elgar.cts.com ARPA: elgar!ag@ucsd.edu ---------------------------------------------------------------------------- #! /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 the files: # README # Makefile # send.c # huh.c # stom.c # doc # This archive created: Wed Jun 15 15:43:13 1988 export PATH; PATH=/bin:$PATH if test -f 'README' then echo shar: will not over-write existing file "'README'" else cat << \SHAR_EOF > 'README' To make this package: edit the Makefile -- change $(BINDIR) and $(MANDIR) to something reasonable. make make install Voila' --- [ Keith ] UUCP: {ucsd, cbosgd!crash, sdcsvax!crash, nosc!crash}!elgar!ag [Gabryelski] INET: ag@elgar.cts.com ARPA: elgar!ag@ucsd.edu SHAR_EOF fi # end of overwriting check if test -f 'Makefile' then echo shar: will not over-write existing file "'Makefile'" else cat << \SHAR_EOF > 'Makefile' SHELL=/bin/sh BINDIR = /u/local/bin MANDIR= /usr/man/man.LOCAL all: send huh stom send: send.c cc -O send.c -o send huh: huh.c cc -O huh.c -o huh stom: stom.c cc -O stom.c -o stom shar: shar README Makefile send.c huh.c stom.c doc > send.shar install: -rm -f $(BINDIR)/fs $(BINDIR)/fsend $(BINDIR)/fr $(BINDIR)/freply -rm -f $(BINDIR)/reply $(BINDIR)/shout $(BINDIR)/send cp send huh stom $(BINDIR) ln $(BINDIR)/send $(BINDIR)/fs ln $(BINDIR)/send $(BINDIR)/fsend ln $(BINDIR)/send $(BINDIR)/fr ln $(BINDIR)/send $(BINDIR)/freply ln $(BINDIR)/send $(BINDIR)/reply ln $(BINDIR)/send $(BINDIR)/shout -cp doc/*.C $(MANDIR) lint: lint send.c -o send SHAR_EOF fi # end of overwriting check if test -f 'send.c' then echo shar: will not over-write existing file "'send.c'" else cat << \SHAR_EOF > 'send.c' /* ** send.c ** ** Written by: Keith Gabryelski (ag@elgar.UUCP) ** ** Released into public domain June 14, 1988. ** Please keep this header. */ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <utmp.h> #include <pwd.h> #include <errno.h> extern errno; extern struct passwd *getpwuid(), *getpwnam(); extern FILE *fopen(); extern char *getlogin(), *strrchr(), *ctime(), *malloc(), *realloc(); extern char *ttyname(), *strcpy(), *strncpy(), *strcat(); extern long time(); extern char *sys_errlist[]; extern int sys_nerr; extern void setutent(); #undef TRUE #undef FALSE #define TRUE 1 #define FALSE 0 #define UNUSED -1 #define NORMAL 0 #define FAST 1 #define SENDS_FILENAME "/.sends" /* must have the '/' */ #define DEAD_SEND_FILENAME "/dead.send" /* must have the '/' */ #define MESSAGE_SEPARATOR 0x1F char *puterr(), *get_typed_message(), *cat_message(), *myfgets(); char *get_last_sender(); int reply(), send(), shout(); struct { char *name; /* Command name. */ int (*function)(); /* Function to use. */ int type; /* Parameters. */ char *text; /* First word in header.*/ } command_table[] = { {"fr", reply, FAST, "Reply"}, {"freply", reply, FAST, "Reply"}, {"fs", send, FAST, "Message"}, {"fsend", send, FAST, "Message"}, {"reply", reply, NORMAL, "Reply"}, {"send", send, NORMAL, "Message"}, {"shout", shout, NORMAL, "Shout"}, {NULL, } }; int argc, uid; char **argv, *progname; char login_name[] = " \0", /* eight chars plus nul */ tty_name[] = " \0"; /* twelve chars plus a nul */ char * mymalloc(size) unsigned size; { char *p; if ((p = malloc(size)) == NULL) { (void) fprintf(stderr, "%s: Out of memory.\n", progname); exit(-1); } return p; } char * myrealloc(p, size) char *p; unsigned size; { if (p == NULL) { if ((p = malloc(size)) == NULL) { (void) fprintf(stderr, "%s: Out of memory.\n", progname); exit(-1); } } else if ((p = realloc(p, size)) == NULL) { (void) fprintf(stderr, "%s: Out of memory.\n", progname); exit(-1); } return p; } main(largc, largv) int largc; char **largv; { char *ptr; int i; struct passwd *pt; progname = *largv++; --largc; argv = largv; argc = largc; uid = getuid(); pt = getpwuid(uid); if ((ptr = getlogin()) == NULL) if ((ptr = pt->pw_name) == NULL) ptr = "somebody"; /* can't figure this guy out */ (void) strncpy(login_name, ptr, 8); if ((ptr = ttyname(0)) == NULL) strcpy(tty_name, "tty??"); else strncpy(tty_name, ((ptr= strrchr(ptr, '/')) ? ptr+1 : "tty??"), 12); i = 0; while (command_table[i].name != NULL) if (strcmp(progname, command_table[i].name)) ++i; else break; if (command_table[i].name == NULL) send(NORMAL, "Message"); else (*command_table[i].function)(command_table[i].type, command_table[i].text); exit(0); } /* ** reply -- ** Reply to a previously sent message. This routine uses the ** (from) user name of the last message sent as the user to ** send a message to. */ reply(type, text) int type; char *text; { char **send_to_list = (char **)mymalloc(0); char *message; /* ** make send_to_list initially have one element -- NULL. ** ** Even though only one user is ever gonna get a message, ** I still use the add_to_list() routine. */ send_to_list = (char **)myrealloc(send_to_list, sizeof(char *)); send_to_list[0] = NULL; add_to_list(&send_to_list, get_last_sender()); message = get_typed_message(); send_message(send_to_list, message, type, text); } /* ** send - generic send-a-message-to-one-or-more-users routine. ** ** ** */ send(type, text) int type; char *text; { char **send_to_list = (char **)mymalloc(0); char *message; /* ** make send_to_list initially have one element -- NULL. ** */ send_to_list = (char **)myrealloc(send_to_list, sizeof(char *)); send_to_list[0] = NULL; if (argc < 1) { fprintf(stderr, "%s: usage: %s user1, [user2,] [...,] [message]\n", progname, progname); exit(-1); } while (*argv != NULL) { --argc; if ((*argv)[strlen(*argv)-1] == ',') { (*argv)[strlen(*argv)-1] = '\0'; add_to_list(&send_to_list, *argv++); } else { add_to_list(&send_to_list, *argv++); break; } } message = get_typed_message(); send_message(send_to_list, message, type, text); } /* ** shout -- Send a message to all logged in users. ** ** */ shout(type, text) int type; char *text; { char **send_to_list = (char **)mymalloc(0); char *message; struct utmp *getutent(), *ut; /* ** make send_to_list initially have one element -- NULL. ** */ send_to_list = (char **)myrealloc(send_to_list, sizeof(char *)); send_to_list[0] = NULL; setutent(); while ((ut = getutent()) != (struct utmp *)NULL) if (ut->ut_type == USER_PROCESS) add_to_list(&send_to_list, ut->ut_line); message = get_typed_message(); send_message(send_to_list, message, type, text); } /* ** get_typed_message() -- ** Get arguments for a message of the command line ** and take input from stdin if the last argument ** is "-" or no message was given on the command ** line. */ char * get_typed_message() { char *buffer = mymalloc(1); int old_argc; *buffer = '\0'; old_argc = argc; while (argc > 0 && !(argc == 1 && !strcmp(*argv, "-"))) { buffer = cat_message(buffer, *argv++); buffer = cat_message(buffer, " "); --argc; } if (argc || !old_argc) { char *line = mymalloc(BUFSIZ); while ((line = myfgets(line, BUFSIZ, stdin)) != NULL) buffer = cat_message(buffer, line); } /* ** That extra <cr> or ' '. ack... */ if (buffer[strlen(buffer)-1] == '\n' || buffer[strlen(buffer)-1] == ' ') buffer[strlen(buffer)-1] = '\0'; return buffer; } char * myfgets(buffer, size, stream) char *buffer; int size; FILE *stream; { int c, length = 0; while ((c = getc(stream)) != EOF && c != '\n' && (length-1) < size) if (c >= ' ') buffer[length++] = c; if (c == '\n') buffer[length++] = c; buffer[length++] = '\0'; return c == EOF ? NULL : buffer; } char * cat_message(buffer, line) char *buffer, *line; { buffer = myrealloc(buffer, strlen(buffer) + strlen(line) + 1); strcat(buffer, line); return buffer; } char * get_last_sender() { char *ptr, *sends_filename = mymalloc(0); char dummy[50]; static char name[50]; int c, n; struct passwd *pt; FILE *fp; pt = getpwuid(uid); if ((ptr = pt->pw_dir) != NULL) { sends_filename = myrealloc(sends_filename, strlen(ptr) + sizeof(SENDS_FILENAME) + 1); strcpy(sends_filename, ptr); strcat(sends_filename, SENDS_FILENAME); if ((fp = fopen(sends_filename, "r")) == (FILE *)NULL) { fprintf(stderr, "%s: No reply possible, can't open %s (%s).\n", progname, sends_filename, puterr(errno)); exit(-1); } *name = '\0'; while (fscanf(fp, "[%s %s %s (%s", dummy, dummy, dummy, name) == 4) while ((c = getc(fp)) != MESSAGE_SEPARATOR && c != EOF) ; fclose(fp); if (name[strlen(name)-1] == ')') name[strlen(name)-1] = '\0'; if (*name == '\0') { fprintf(stderr, "%s: no sends.\n", progname); exit(-1); } } else { fprintf(stderr, "%s: No reply possible, no home directory.\n", progname); exit(-1); } return name; } send_message(user_list, message, type, text) char **user_list, *message; int type; char *text; { char *date_text, *ptr, *sends_filename = mymalloc(0); char **sent_to_list = (char **)mymalloc(0); char **sends_list = (char **)mymalloc(0); int sendit = TRUE, sent = FALSE, failed = FALSE, need_crlf = FALSE; long clock[1]; struct utmp *getutent(), *ut; struct passwd *pt; struct stat stbuf; FILE *fp; static char device[] = "/dev/ \0"; /* setup null sent_to_list */ sent_to_list = (char **)myrealloc(sent_to_list, sizeof(char *)); sent_to_list[0] = NULL; sends_list = (char **)myrealloc(sends_list, sizeof(char *)); sends_list[0] = NULL; /* get the date without a terminating <cr> */ clock[0] = time((long *)0); date_text = ctime(clock); date_text[24] = '\0'; /* find user/tty in utmp */ while (*user_list != NULL) { setutent(); sendit = UNUSED; sent = FALSE; while ((ut = getutent()) != (struct utmp *)NULL) { if ((ut->ut_type == USER_PROCESS) && ((!strncmp(ut->ut_user, *user_list, 8)) || (!strncmp(ut->ut_line, *user_list, 12)))) { sendit = TRUE; if (add_to_list(&sent_to_list, ut->ut_line)) { sent = TRUE; break; } strncpy(device+5, ut->ut_line, 12); if (uid != 0) { if (stat(device, &stbuf) == -1) { fprintf(stderr, "%s: Couldn't stat %s (%s).\n", progname, device, puterr(errno)); sendit = FALSE; failed = TRUE; } else if (!stbuf.st_mode&2) { fprintf(stderr, "[%s/%s]: Is not receiving sends.\n", ut->ut_user, ut->ut_line); sendit = FALSE; failed = TRUE; } } /* open device and send the message */ if (sendit) { if ((fp = fopen(device, "w")) == (FILE *)NULL) fprintf(stderr, "%s: could not open %s (%s).\n", progname, device, puterr(errno)); else { if (type&FAST) fprintf(fp, "\007\n[%s/%s: %s]\n", login_name, tty_name, message); else fprintf(fp, "\007\n[%s from %s (%s) %s]\n%s\n", text, login_name, tty_name, date_text, message); printf("[%s/%s] ", ut->ut_user, ut->ut_line); need_crlf = sent = TRUE; fclose(fp); /* write send to ~user/.sends file */ if (!add_to_list(&sends_list, ut->ut_user)) { pt = getpwnam(ut->ut_user); if ((ptr = pt->pw_dir) != NULL) { sends_filename = myrealloc(sends_filename, strlen(ptr) + sizeof(SENDS_FILENAME) + 1); strcpy(sends_filename, ptr); strcat(sends_filename, SENDS_FILENAME); if ((fp = fopen(sends_filename, "a+")) != (FILE *)NULL) fprintf(fp, "[%s from %s (%s) %s]\n%s\n%c", text, login_name, tty_name, date_text, message, MESSAGE_SEPARATOR); fclose(fp); } } } } } } if (!sent) { failed = TRUE; if (sendit == UNUSED) { /* ** Decide what the user tried to type in. Was it a user ** who isn't logged in or maybe a tty device that no user ** is logged on to or maybe a mistyped username. */ if ((pt = getpwuid(*user_list)) == (struct passwd *)NULL) { int status; strncpy(device+5, *user_list, 12); status = stat(device, &stbuf); if (status == -1 || !stbuf.st_mode&S_IFCHR) fprintf(stderr, "%s: no user %s.\n", progname, *user_list); else fprintf(stderr, "%s: no user logged on device %s.\n", progname, *user_list); } else fprintf(stderr, "%s: %s not logged in.\n", progname, *user_list); } } ++user_list; } if (failed) { char *dead_filename = malloc(0); pt = getpwuid(uid); if ((ptr = pt->pw_dir) == NULL) { dead_filename = myrealloc(dead_filename, sizeof("/tmp/") + sizeof(login_name) + sizeof(DEAD_SEND_FILENAME) + 1); strcpy(dead_filename, "/tmp/"); strcat(dead_filename, login_name); strcat(dead_filename, DEAD_SEND_FILENAME); } else { dead_filename = myrealloc(dead_filename, strlen(ptr) + sizeof(DEAD_SEND_FILENAME) + 1); strcpy(dead_filename, ptr); strcat(dead_filename, DEAD_SEND_FILENAME); } if ((fp = fopen(dead_filename, "a+")) != (FILE *)NULL) { fprintf(fp, "[%s from %s (%s) %s]\n%s\n%c", text, login_name, tty_name, date_text, message, MESSAGE_SEPARATOR); fprintf(stderr, "%s: message copied to %s.\n", progname, dead_filename); } fclose(fp); free(dead_filename); } if (need_crlf) putchar('\n'); free(sends_filename); } add_to_list(list, name) char ***list, *name; { register int i; for (i = 0; (*list)[i] != NULL; ++i) if (!strcmp((*list)[i], name)) return TRUE; *list = (char **)myrealloc(*list, sizeof(char *) * (i + 2)); (*list)[i] = mymalloc(strlen(name)+1); strcpy((*list)[i], name); (*list)[i+1] = NULL; return FALSE; } /* ** **free_list(list) **char **list; **{ ** register int i; ** ** for (i = 0; list[i] != NULL; ++i) ** free(list[i]); ** ** free(list); **} */ char * puterr(error) int error; { static char qwerty[42]; (void) sprintf(qwerty, "Unknown error %d", error); return ((unsigned)error >= sys_nerr) ? qwerty : sys_errlist[error]; } SHAR_EOF fi # end of overwriting check if test -f 'huh.c' then echo shar: will not over-write existing file "'huh.c'" else cat << \SHAR_EOF > 'huh.c' /* ** huh.c -- ** What was that last send? ** ** Written by: Keith Gabryelski (ag@elgar.UUCP) ** ** Released into public domain June 14, 1988. ** Please keep this header. */ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <pwd.h> #include <errno.h> extern errno; extern FILE *fopen(); extern struct passwd *getpwuid(), *getpwnam(); extern char *sys_errlist[], *malloc(), *realloc(); extern int sys_nerr; #undef TRUE #undef FALSE #define TRUE 1 #define FALSE 0 #define SENDS_FILENAME "/.sends" /* must have the '/' */ #define MESSAGE_SEPARATOR 0x1F char *puterr(), *mymalloc(), *myrealloc(); char *progname; int sflag = FALSE; char * mymalloc(size) unsigned size; { char *p; if ((p = malloc(size)) == NULL) { (void) fprintf(stderr, "%s: Out of memory.\n", progname); exit(-1); } return p; } char * myrealloc(p, size) char *p; unsigned size; { if (p == NULL) { if ((p = malloc(size)) == NULL) { (void) fprintf(stderr, "%s: Out of memory.\n", progname); exit(-1); } } else if ((p = realloc(p, size)) == NULL) { (void) fprintf(stderr, "%s: Out of memory.\n", progname); exit(-1); } return p; } main(argc, argv) int argc; char **argv; { char *ptr, *sends_filename = mymalloc(0); int amount = 1, n, c; long *seek_list = (long *)mymalloc(0); struct passwd *pt; FILE *fp; progname = *argv++; --argc; if (**argv == '-') if (!strcmp(*argv, "-s")) { sflag = TRUE; *++argv; --argc; } else { fprintf(stderr, "%s: invalid switch given.\n", progname); usage(); } if (argc > 2) usage(); if (argc) { amount = atoi(*argv++); --argc; } if (amount < 1) { fprintf(stderr, "%s: invalid amount.\n", progname); usage(); } if (argc) { if ((pt = getpwnam(*argv)) == (struct passwd *)NULL) { fprintf(stderr, "%s: invalid user name '%s'.\n", progname, *argv); exit(-1); } } else pt = getpwuid(getuid()); if ((ptr = pt->pw_dir) == NULL) { fprintf(stderr, "%s: couldn't find a home directory.\n", progname); exit(-1); } sends_filename = myrealloc(sends_filename, strlen(ptr) + sizeof(SENDS_FILENAME) + 1); strcpy(sends_filename, ptr); strcat(sends_filename, SENDS_FILENAME); if ((fp = fopen(sends_filename, "r")) == (FILE *)NULL) { if (errno == ENOENT) { fprintf(stderr, "No sends.\n"); exit(0); } else { fprintf(stderr, "%s: couldn't open sends file %s (%s).\n", progname, sends_filename, puterr(errno)); exit(-1); } } /* setup null sent_to_list */ seek_list = (long *)myrealloc(seek_list, sizeof(long)); seek_list[0] = -1; do { n = add_to_list(&seek_list, ftell(fp)); while((c = getc(fp)) != MESSAGE_SEPARATOR && c != EOF) ; } while (c != EOF); if (n == 1) fprintf(stderr, "No sends.\n"); else { if (n-1 < amount) amount = 0; else amount = n - amount - 1; fseek(fp, seek_list[amount], 0); do { while ((c = getc(fp)) != MESSAGE_SEPARATOR && c != EOF) putchar(c); if (sflag && c == MESSAGE_SEPARATOR) putchar(MESSAGE_SEPARATOR); } while (c != EOF); } fclose(fp); exit(0); } usage() { fprintf(stderr, "%s: usage %s [-s] [amount] [username]\n", progname, progname); exit(-1); } add_to_list(list, element) long **list, element; { register int i; for (i = 0; (*list)[i] != -1; ++i) ; *list = (long *)myrealloc(*list, sizeof(long) * (i + 2)); (*list)[i] = element; (*list)[i+1] = -1; return i+1; } char * puterr(error) int error; { static char qwerty[42]; (void) sprintf(qwerty, "Unknown error %d", error); return ((unsigned)error >= sys_nerr) ? qwerty : sys_errlist[error]; } SHAR_EOF fi # end of overwriting check if test -f 'stom.c' then echo shar: will not over-write existing file "'stom.c'" else cat << \SHAR_EOF > 'stom.c' /* ** stom.c -- ** Convert a .sends formatted message into a Unix mailbox ** format. ** ** Written by: Keith Gabryelski (ag@elgar.UUCP) ** ** Released into public domain June 14, 1988. ** Please keep this header. */ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <pwd.h> #include <errno.h> extern errno; extern FILE *fopen(); extern struct passwd *getpwuid(), *getpwnam(); extern char *sys_errlist[], *malloc(), *realloc(); extern int sys_nerr; #undef TRUE #undef FALSE #define TRUE 1 #define FALSE 0 #define SENDS_FILENAME "/.sends" /* must have the '/' */ #define MESSAGE_SEPARATOR 0x1F char *puterr(), *mymalloc(), *myrealloc(); char *progname; main(argc, argv) int argc; char **argv; { FILE *fp; progname = *argv++; --argc; if (argc < 1) convert(stdin); else while (argc--) { if ((fp = fopen(*argv, "r")) == NULL) fprintf(stderr, "%s: can't access file %s (%s).\n", progname, *argv, puterr(errno)); else convert(fp); *++argv; } exit(0); } convert(stream) FILE *stream; { char text[20], user_name[10], date[28]; char *dp; int c; while (fscanf(stream, "[%s from %s ", text, user_name) == 2) { /* ** ignore tty. */ while ((c = getc(stream)) != ')') ; /* ** get date. */ dp = date; while ((c = getc(stream)) != ']') *dp++ = c; *dp = '\0'; printf("From %s%s\nSubject: A %s\n", user_name, date, text); /* ** And the message itself. */ while ((c = getc(stream)) != MESSAGE_SEPARATOR) putchar(c); } } char * puterr(error) int error; { static char qwerty[42]; (void) sprintf(qwerty, "Unknown error %d", error); return ((unsigned)error >= sys_nerr) ? qwerty : sys_errlist[error]; } SHAR_EOF fi # end of overwriting check if test ! -d 'doc' then mkdir 'doc' fi cd 'doc' if test -f 'send.C' then echo shar: will not over-write existing file "'send.C'" else cat << \SHAR_EOF > 'send.C' .TH SEND C .SH NAME send, fsend, fs, reply, freply, fr, shout \- send a message to one or more users on the system. .SH SYNOPSIS .B send user1[, user2][, user3][,... ][message] .B fsend user1[, user2][, user3][,... ][message] .B fs user1[, user2][, user3][,... ][message] .B reply [message] .B freply [message] .B fr [message] .B shout [message] .SH DESCRIPTION Send (and its counterparts) display messages on a specified user (or users) terminal(s). Send (and fsend) take a comma separated list of usernames (or tty devices) to send the message to. If a message is given on the command line, it may be continued (via stdin) by putting a dash as the last argument on the command line. If no message is specified, stdin will be used. Reply will use the username of the last person to send you a message as the recipient of the current message. Fsend and freply use shorter headers to cutdown on message output. They work exactly like their counterparts (send and reply) in all other respects. Shout will send a message to all users on the system. Not for regular use. As a message is sent to user, it is also written to a save file called ".sends" in the recipients home directory. This file must exist and should be 622 mode for it to be updated correctly. This file is typically cleared on logout. Fs and fr are finger savers for fsend and freply. .SH FILES ~USERNAME/.sends - Sends save file. ~/dead.send - Save file for failed sends. .SH SEE ALSO huh(C), stom(C) .SH AUTHOR .RS .PP Keith M. Gabryelski (ag@elgar.UUCP) .RE SHAR_EOF fi # end of overwriting check if test -f 'huh.C' then echo shar: will not over-write existing file "'huh.C'" else cat << \SHAR_EOF > 'huh.C' .TH HUH C .SH NAME huh \- Display last send. .SH SYNOPSIS .B huh [-s] [amount] [username] .SH DESCRIPTION Huh will display the last .B amount (default; 1) send message(s) from the user .B username (default; your own) .sends file. -s is used to format the output of huh(C) into something stom(C) can use as input. .SH FILES ~USERNAME/.sends - Sends save file. .SH SEE ALSO send(C), stom(C) .SH AUTHOR .RS .PP Keith M. Gabryelski (ag@elgar.UUCP) .RE SHAR_EOF fi # end of overwriting check if test -f 'stom.C' then echo shar: will not over-write existing file "'stom.C'" else cat << \SHAR_EOF > 'stom.C' .TH STOM C .SH NAME stom \- convert a .sends formatted file to a unix mailbox format. .SH SYNOPSIS .B stom [file1] [file2] [file3] [...] .SH DESCRIPTION Stom converts a .sends formatted file into a unix mailbox format. If no arguments are given stom will use stdin. This is useful when used in conjuction with huh(C) to reply via mail to a send. .RS huh -s | stom > mailbox .PP mail -f mailbox .RE .SH SEE ALSO huh(C), send(C) .SH AUTHOR .RS .PP Keith M. Gabryelski (ag@elgar.UUCP) .RE SHAR_EOF fi # end of overwriting check cd .. # End of shell archive exit 0 -- "If green is all there is to be, then green is good enough for me" - ktf [ Keith ] UUCP: {ucsd, cbosgd!crash, sdcsvax!crash, nosc!crash}!elgar!ag [Gabryelski] INET: ag@elgar.cts.com ARPA: elgar!ag@ucsd.edu