wswietse@eutrc3.UUCP (Wietse Venema) (04/20/88)
comp.sources.misc: Volume 3, Issue 6 Submitted-By: "Wietse Venema" <wswietse@eutrc3.UUCP> Archive-Name: pcmail/Part5 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 5 (of 8)." # Contents: ascf.c comm.h deskutil.c invoke.c kpres.c logs.c path.h # sendwork.c spoolfil.c srctoman.sh switcher.c unalias.c # Wrapped by wietse@eutwc1 on Wed Apr 20 16:45:27 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f ascf.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"ascf.c\" else echo shar: Extracting \"ascf.c\" \(4105 characters\) sed "s/^X//" >ascf.c <<'END_OF_ascf.c' X/*++ X/* NAME X/* ascf 3 X/* SUMMARY X/* stdio-like ascii filter X/* PROJECT X/* pc-mail X/* PACKAGE X/* ascii filtering X/* SYNOPSIS X/* FILE *ascopen(name,mode) X/* char *name; X/* char *mode; X/* X/* int ascget(fp) X/* FILE *fp; X/* X/* int ascclose(fp) X/* FILE *fp; X/* DESCRIPTION X/* The functions in this module provide filtered stream i/o for X/* textfiles produced by word processors. Their calling sequence X/* has been modelled after the standard i/o library routines. X/* X/* ascopen() is the analogon of fopen(3), ascget() returns the next X/* character in the filtered input stream, and ascclose() closes X/* the stream. ascget() is a macro. X/* X/* The following mappings are done: cr/lf, cr, lf, lf/cr are X/* replaced by newline; all high bits are stripped off; wordstar X/* hyphens are converted to normal hyphens. Except for tabs, X/* all control characters are suppressed in the output. X/* In order to avoid problems in mailers, a newline X/* character is appended to the last line of each file. X/* SEE ALSO X/* stdio(3) standard i/o library interface. X/* DIAGNOSTICS X/* ascopen() returns a null pointer on failure; ascget() returns X/* the value EOF when the end of a stream is reached. ascclose() X/* returns whatever fclose() returns. X/* BUGS X/* Actually works with wordstar or clean ascii files only. X/* No character pushback. X/* Although allowed by ascopen(), the "w" file open mode is X/* of no use. X/* AUTHOR(S) X/* W.Z. Venema X/* Eindhoven University of Technology X/* Department of Mathematics and Computer Science X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands X/* CREATION DATE X/* Mon Jul 6 16:03:41 GMT+1:00 1987 X/* LAST MODIFICATION X/* Mon Apr 4 23:34:46 MET 1988 X/* VERSION/RELEASE X/* 1.4 X/*--*/ X X#include <ctype.h> X X#include "defs.h" X#include "ascf.h" X X/* some systems do not define _NFILE in stdio.h */ X X#ifndef _NFILE X# include <sys/param.h> /* maybe we are a sun */ X# ifdef NOFILE X# define _NFILE NOFILE X# else X"ERROR: cannot get max nr of open files" X# endif X#endif X X#define CTRL(x) ((x)^0100) /* ASCII control characters */ X X#ifdef MSDOS X#include <fcntl.h> /* to turn cr/lf mapping off */ X#endif X Xpublic Asc asc[_NFILE]; /* one filter structure per file */ X X/* ascopen - open stream, initialize intermediate buffer */ X Xpublic FILE *ascopen(file,mode) Xchar *file,*mode; X{ X register FILE *fp; X X if (fp = fopen(file,mode)) { /* if file is accessable */ X register Asc *ap = asc+fileno(fp); X if (ap->buf = malloc(BUFSIZ)) { /* if buffer available */ X ap->cnt = 0; /* init buffer count */ X ap->nlf = 0; /* no newline appended yet */ X#ifdef O_BINARY X setmode(fileno(fp),O_BINARY); X#endif X } else { X fclose(fp); /* no room for that buffer */ X fp = 0; X } X } X return(fp); X} X X/* ascclose - release intermediate buffer and close the stream */ X Xpublic int ascclose(fp) Xregister FILE *fp; X{ X free(asc[fileno(fp)].buf); X return(fclose(fp)); X} X X/* ascbuf - ascii filter, make new buffer of text */ X Xpublic int ascbuf(fp) XFILE *fp; X{ X register Asc *ap = asc+fileno(fp); /* intermediate buffer access */ X register char *cp = ap->buf; /* init write pointer */ X register int c; /* single-character input buffer */ X int d; /* look-ahead character */ X X while (cp < ap->buf+BUFSIZ && X (c = getc(fp)) != EOF && (c &= 0177) != CTRL('Z')) { X if (c == ' ' || isprint(c) || c == '\t') { X *cp++ = c; /* accept character */ X } else if ((c == '\r' && ((d = getc(fp)) == '\n' || (ungetc(d,fp),1))) X || (c == '\n' && ((d = getc(fp)) == '\r' || (ungetc(d,fp),1)))) { X *cp++ = '\n'; /* terminate line */ X } else if (c == CTRL('_')) { X *cp++ = '-'; /* wordstar hyphen */ X } else { X continue; /* ignore other characters */ X } X } X if (ap->cnt = cp-ap->buf) { /* anything in the buffer? */ X ap->ptr = ap->buf; /* yes, set read pointer */ X return(ascget(fp)); /* and return first character */ X } else if (ap->nlf == 0) { /* make sure file ends with \n */ X return(ap->nlf = '\n'); /* append newline first */ X } else { /* now we're really done */ X return(EOF); /* that's it. */ X } X} END_OF_ascf.c if test 4105 -ne `wc -c <ascf.c`; then echo shar: \"ascf.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f comm.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"comm.h\" else echo shar: Extracting \"comm.h\" \(1967 characters\) sed "s/^X//" >comm.h <<'END_OF_comm.h' X/*++ X/* NAME X/* comm 5 X/* SUMMARY X/* cico systems parameters X/* PROJECT X/* pc-mail X/* PACKAGE X/* cico X/* SYNOPSIS X/* #include "params.h" X/* #include "comm.h" X/* DESCRIPTION X/* .nf X X/* /* roles and other behavioural codes */ X X#define MASTER 1 /* who sends files */ X#define SLAVE 2 /* who receives files */ X#define DONE 3 /* no more files */ X X#define YES 'Y' X#define NO 'N' X X/* /* communications parameters (see params.h) */ X X#define COMM_LINE (comm[P_PORT].strval) X#define COMM_RATE (comm[P_BAUD].strval) X#define DIAL_SEQUENCE (comm[P_DIAL].strval) X#define LOGIN_NAME (comm[P_LOGIN].strval) X#define DISC_SEQUENCE (comm[P_DISC].strval) X X/* /* related info */ X Xextern int ttfd; /* comm. port */ Xextern Info *comm; /* comm. info */ Xextern char *password; /* password */ Xextern char rmthost[]; /* remote system name */ X X/* /* functions that use the above */ X Xextern char *rmtname(); /* make remote spool-file name */ Xextern char *locname(); /* make local spool-file name */ X X/* /* protocol function pointers */ X Xextern int (*Read)(); /* protocol read */ Xextern int (*Write)(); /* protocol write */ Xextern int (*Close)(); /* protocol close */ X X/* /* use these at your own risk */ X X#define MSGBUF 4096 /* message buffer size */ X Xextern char msgin[MSGBUF]; /* message receive buffer */ Xextern char msgout[MSGBUF]; /* message send buffer */ X X/* /* message i/o functions */ X Xextern int isok(); /* do request; get yes or no */ Xextern char *talk(); /* send message */ Xextern char *hear(); /* receive message */ X/* SEE ALSO X/* comm(3) implementation module X/* AUTHOR(S) X/* W.Z. Venema X/* Eindhoven University of Technology X/* Department of Mathematics and Computer Science X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands X/* CREATION DATE X/* Sun Apr 12 13:52:39 GMT+1:00 1987 X/* LAST MODIFICATION X/* Mon Apr 4 23:36:42 MET 1988 X/* VERSION/RELEASE X/* 1.3 X/*--*/ END_OF_comm.h if test 1967 -ne `wc -c <comm.h`; then echo shar: \"comm.h\" unpacked with wrong size! fi # end of overwriting check fi if test -f deskutil.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"deskutil.c\" else echo shar: Extracting \"deskutil.c\" \(4943 characters\) sed "s/^X//" >deskutil.c <<'END_OF_deskutil.c' X/*++ X/* NAME X/* deskutil 3 X/* SUMMARY X/* utility functions X/* PROJECT X/* pc-mail X/* PACKAGE X/* mailsh X/* SYNOPSIS X/* #include "mailsh.h" X/* X/* void patience() X/* X/* int when() X/* X/* int delete() X/* X/* int unspool() X/* X/* int print() X/* X/* int save() X/* X/* char *tstamp(ltime) X/* long *ltime() X/* DESCRIPTION X/* tstamp() converts absolute time to a string. If called with X/* recent time argument (less than 100 days ago) the string will X/* be of the form "Sun Apr 17 12:50", otherwise "Sun Apr 17 1988". X/* X/* delete() gives the user another chance before a message is deleted. X/* X/* unspool() actually deletes a message. As a side effect it destroys X/* the current mail box display so that the next display will X/* reflect the actual status of the spool directory. X/* The affected message and meta file names are taken from the X/* global "message" and "commant" string variables. X/* X/* print() copies a pager file to the printer. X/* X/* save() asks where the pager file should be saved. X/* X/* when() should be called after the user has entered a mail destination X/* address. It informs the user that messages are not sent right away, X/* but after selection of the Network option in the main menu. X/* X/* patience() prints a 'one moment please' message in the middle X/* screen window. As a side effect, the current pager file is set X/* to none. X/* FILES X/* mail header files in the spool directory X/* SEE ALSO X/* pager(3), pager(5), kbdinp(3) X/* AUTHOR(S) X/* W.Z. Venema X/* Eindhoven University of Technology X/* Department of Mathematics and Computer Science X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands X/* CREATION DATE X/* Tue May 12 15:35:20 GMT+1:00 1987 X/* LAST MODIFICATION X/* Mon Apr 4 23:38:26 MET 1988 X/* VERSION/RELEASE X/* 1.3 X/*--*/ X X#include <errno.h> X X#include "defs.h" X#include "pager.h" X#include "mailsh.h" X#include "screen.h" X#include "status.h" X Xhidden int save_desk(); X X/* patience - say this will take some time */ X Xpublic void patience() X{ X static char *m_wait[] = { X "", X "One moment please...", X 0, X }; X X register File *pp = open_pager(); /* create pager file */ X X mesg_pager(pp,m_wait); /* write pager file */ X ds_pager(); /* show om middle window */ X close_pager(pp); /* forget pager file */ X} X X/* delete - user wants to delete a message; ask for confirmation */ X Xpublic int delete() X{ X static Screen screen[] = { X ESCCR, "Enter", unspool,int_error, X 0, 0, 0, X "Press ESC to cancel. Confirm with ENTER", X }; X X return(kbdinp(screen)|S_REDRAW); X} X X/* unspool - actually delete a message; force mail box display rebuild */ X Xpublic int unspool() X{ X if (((chmod(message,0666) || unlink(message)) && errno != ENOENT) X || ((chmod(comment,0666) || unlink(comment)) && errno != ENOENT)) { X errdisp(E_UNLINK); /* notify user of problem */ X return(S_REDRAW); /* say screen has changed */ X } else { X junk_desk(); /* say mail box has changed */ X return(S_BREAK); /* no more work to do */ X } X} X X/* print - print pager display on default printer */ X Xpublic int print() X{ X return(pr_pager() ? (errdisp(E_PRINTERR),S_REDRAW) : 0); X} X X/* save - ask where pager display should be copied to */ X Xpublic int save() X{ X static Screen screen[] = { X STRING, 0, save_desk,int_error, X 0, 0, 0, X "Press ESC to cancel. Save to file:", X }; X X kbdinp(screen); /* prompt for file name, then copy */ X return(S_REDRAW); /* force screen repaint */ X} X X/* save_desk - copy pager file to ordinary file */ X Xhidden int save_desk(to) Xchar *to; X{ X if (cp_pager(to)) { /* if file copy failed */ X unlink(to); /* remove that file */ X errdisp(E_WRITERR); /* notify the user */ X return(S_BREAK|S_REDRAW); /* redisplay, terminate caller */ X } else { X junk_file(); /* say file display maybe outdated */ X return(S_BREAK); /* terminate caller */ X } X} X X/* when - say when mail will actually be sent */ X Xpublic int when() X{ X static char *msg[] = { X "", X "To send messages through the network, use the Network", X "option in the main menu.", X 0, X }; X File *pp = open_pager(); /* open new pager file */ X X mesg_pager(pp,msg); /* fill pager file */ X ds_pager(); /* display the file */ X close_pager(pp); /* forget pager file */ X return(0); /* don't care value */ X} X X/* tstamp - time format as produced by the ls(1) command */ X Xpublic char *tstamp(ltime) Xlong *ltime; X{ X static char buf[25]; X X /* X * Output from asctime() is of the form X * "Sun Apr 17 13:34:35 1988" X * Depending on how recent the time in question is, we X * supress the time or year field. X */ X X (void) strcpy(buf,asctime(localtime(ltime))); X if (time((long *)0)-*ltime > 60L*60L*24L*100L) { X buf[24] = '\0'; /* remove the \n */ X (void) strcpy(buf+11,buf+19); /* old file, show year */ X } else X buf[16] = '\0'; /* recent, show time */ X return(buf); X} END_OF_deskutil.c if test 4943 -ne `wc -c <deskutil.c`; then echo shar: \"deskutil.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f invoke.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"invoke.c\" else echo shar: Extracting \"invoke.c\" \(4946 characters\) sed "s/^X//" >invoke.c <<'END_OF_invoke.c' X/*++ X/* NAME X/* invoke 3 X/* SUMMARY X/* system-dependent process control stuff X/* PROJECT X/* pc-mail X/* PACKAGE X/* mailsh X/* SYNOPSIS X/* #include "status.h" X/* X/* int invokelp(arg0,arg1,...) X/* char *arg0,*arg1,... X/* X/* int invokevp(argv) X/* char **argv; X/* X/* int onexit(command) X/* char *command; X/* DESCRIPTION X/* invokelp() creates a child process to execute a command. X/* arg0, arg1,... is a null-terminated list of string pointers, X/* the first being the name of the program. Use is made X/* of the search path to locate the program in arg0. X/* X/* invokevp() is similar to invokelp; the difference is that X/* argv is an array of pointers to arguments. X/* X/* onexit() executes a command, thereby terminating the current process. X/* DIAGNOSTICS X/* invokelp(), invokevp() return the exit status of the child process, X/* E_SYSFAIL if there were insufficient resources, and X/* E_NOPROG if the program in arg0 or argv[0] could not be found. X/* X/* onexit() return -1 if there were problems. X/* BUGS X/* The invokexx() functions should not be used if the command needs to X/* be handled by a command-language processor (e.g. shell built-ins, X/* or i/o redirection). X/* AUTHOR(S) X/* W.Z. Venema X/* Eindhoven University of Technology X/* Department of Mathematics and Computer Science X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands X/* CREATION DATE X/* Sun Apr 5 15:27:37 GMT+1:00 1987 X/* LAST MODIFICATION X/* Wed Apr 6 00:19:56 MET 1988 X/* VERSION/RELEASE X/* 1.4 X/*--*/ X X#include <errno.h> X#include "defs.h" X#include "status.h" X X#ifdef MSDOS X#include <process.h> X#endif X X/* invokelp - create child process to execute command */ X X/* VARARGS2 */ X Xpublic int invokelp(arg0,arg1,arg2,arg3,arg4) Xchar *arg0,*arg1,*arg2,*arg3,*arg4; X{ X /* X * On unix systems we fork a process and overlay the child with X * the desired program. X * This means we get -1 if the fork did not succeed, otherwise X * the exit status if the child process. The code is a bit elaborate X * since we want to handle various error conditions. X */ X#ifdef unix X register int pid; X X if ((pid = fork()) < 0) { /* fork off a process */ X return(E_SYSFAIL); /* resources exhausted */ X } else if (pid == 0) { /* this is the child process */ X execlp(arg0,arg0,arg1,arg2,arg3,arg4);/* try to replace it */ X _exit(errno == ENOENT ? E_NOPROG : E_SYSFAIL); /* sorry, failed */ X /* NOTREACHED */ X } else { X int xstat,wstat; /* wait till above child terminates */ X while ((wstat = wait(&xstat)) != -1 && wstat != pid) X /* void */ ; X if (wstat == -1) { X return(E_SYSFAIL); /* oops: no child! */ X } else if (xstat&0377) { X return(E_UNKNOWN); /* child was killed */ X } else { X return(xstat>>8); /* child died naturally */ X } X /* NOTREACHED */ X } X#endif X X /* X * On MS-DOS systems we try to avoid the command.com shell because X * it always returns a zero status code. X */ X#ifdef MSDOS X int stat; X char *p; X X if ((stat = spawnlp(P_WAIT,arg0,arg0,arg1,arg2,arg3,arg4)) < 0 X && errno == ENOENT X && (strcmp(p = arg0+strlen(arg0)-4,".bat") == 0 || strcmp(p,".BAT") == 0)) X stat = spawnlp(P_WAIT,"command","command","/c",arg0,arg1,arg2,arg3,arg4); X return(stat >= 0 ? stat : (errno == ENOENT ? E_NOPROG : E_SYSFAIL)); X#endif X} X X/* invokelp - create child process to execute command */ X Xpublic int invokevp(argv) Xchar **argv; X{ X /* X * On unix systems we fork a process and overlay the child with X * the desired program. X * This means we get -1 if the fork did not succeed, otherwise X * the exit status if the child process. The code is a bit elaborate X * since we want to handle various error conditions. X */ X#ifdef unix X register int pid; X X if ((pid = fork()) < 0) { /* fork off a process */ X return(E_SYSFAIL); /* resources exhausted */ X } else if (pid == 0) { /* this is the child process */ X execvp(*argv,argv); /* try to replace it */ X _exit(errno == ENOENT ? E_NOPROG : E_SYSFAIL); /* sorry, failed */ X /* NOTREACHED */ X } else { X int xstat,wstat; /* wait till above child terminates */ X while ((wstat = wait(&xstat)) != -1 && wstat != pid) X /* void */ ; X if (wstat == -1) { X return(E_SYSFAIL); /* oops: no child! */ X } else if (xstat&0377) { X return(E_UNKNOWN); /* child was killed */ X } else { X return(xstat>>8); /* child died naturally */ X } X /* NOTREACHED */ X } X#endif X X /* X * On MS-DOS systems we try to avoid the command.com shell because X * it always returns a zero status code. X */ X#ifdef MSDOS X int stat; X X return((stat = spawnvp(P_WAIT,*argv,argv)) >= 0 ? X stat : (errno == ENOENT ? E_NOPROG : E_SYSFAIL)); X#endif X} X X/* onexit - exec another command */ X Xint onexit(command) Xchar *command; X{ X if (command && *command) { X#ifdef unix X return(execlp("/bin/sh","sh","-c",command)); X#endif X X#ifdef MSDOS X return(system(command)); X#endif X } X} END_OF_invoke.c if test 4946 -ne `wc -c <invoke.c`; then echo shar: \"invoke.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f kpres.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"kpres.c\" else echo shar: Extracting \"kpres.c\" \(4951 characters\) sed "s/^X//" >kpres.c <<'END_OF_kpres.c' X/*++ X/* NAME X/* kpres X/* SUMMARY X/* k-protocol presentation layer X/* PACKAGE X/* uucp across thenet X/* SYNOPSIS X/* #include "kp.h" X/* X/* kopen(fd) X/* int fd; X/* X/* kwrite(fd,buf,len) X/* int fd,len; X/* char *buf; X/* X/* kread(fd,buf,len) X/* int fd,len; X/* char *buf; X/* X/* kclose(fd) X/* int fd; X/* DESCRIPTION X/* This section contains functions that imitate standard unix X/* unbuffered i/o facilities. A status code of FAIL is returned when X/* the network partner wants to terminate the protocol, or when the X/* the transmission error rate is excessive. X/* X/* Eight-bit data bytes are transported as harmless six-bit data bytes X/* in the ASCII range 32 through 95. This introduces an overhead of 33%. X/* For textfiles, this is hardly worse than kermit (typical overhead X/* 10 %). For binary files the overhead is much less than with kermit X/* (typical overhead 60%). X/* X/* Kopen() sets up the terminal characteristics of the specified file X/* descriptors (no echo, raw, tandem). Always returns zero status. X/* X/* Kwrite() attempts to send the bytes in buf. A zero-length buffer X/* should be written to indicate an end-of-file condition. Return status: X/* the number of bytes requested, or FAIL. X/* X/* Kread() attempts to read the requested number of bytes. Status code: X/* the number of bytes actually read, or FAIL. A read of zero bytes X/* normally indicates an end-of-file condition (see kwrite). X/* X/* Kclose() sends a protocol abort sequence to the network partner. X/* This function should be called to terminate the k protocol driver X/* at the other end, or to confirm reception of a protocol abort sequence. X/* Kclose always returns zero exit status. X/* X/* The function kfail() is called by the strategy layer functions to X/* indicate protocol failure or termination. X/* FUNCTIONS AND MACROS X/* kwproto, krproto, kclsproto X/* BUGS X/* Zero byte read/writes are a clumsy way to handle end-of-files. X/* They have been implemented for the sake of compatibility with uucico. X/* AUTHOR(S) X/* Wietse Venema X/* Eindhoven University of Technology X/* Department of Mathematics and Computer Science X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands X/* CREATION DATE X/* Mon Feb 3 11:14:13 MET 1986 X/* LAST MODIFICATION X/* Mon Apr 4 23:43:28 MET 1988 X/* VERSION/RELEASE X/* 1.3 X/*--*/ X X#ifdef unix X# ifdef SIII X# include <termio.h> X# else X# include <sgtty.h> X# endif X#endif X#include <setjmp.h> X#include "kp.h" X Xstatic jmp_buf Failbuf; X Xkfail() X{ X longjmp(Failbuf,TRUE); X} X Xkopen(fd) Xint fd; X{ X#ifdef unix X# ifdef SIII X struct termio ttymode; X X ioctl(fd,TCGETA,&ttymode); X ttymode.c_iflag = IXOFF|IXON|ISTRIP; X ttymode.c_cc[VMIN] = 1; X ttymode.c_cc[VTIME] = 0; X ioctl(fd,TCSETA,&ttymode); X# else X struct sgttyb ttymode; X X gtty(fd,&ttymode); X ttymode.sg_flags |= (TANDEM|RAW); X ttymode.sg_flags &= ~(ECHO|CBREAK); X stty(fd,&ttymode); X# endif X#else X xioctl(1); X#endif X return 0; X} X Xkwrite(fd,buf,len) Xint fd; Xregister char *buf; Xregister int len; X{ X static char packbuf[MAXPACKSIZ]; X static char *packptr = packbuf; X register int c,i,rest,shift; X X /* set error trap */ X X if (setjmp(Failbuf)) X return FAIL; X X /* if 'end of data' send null packet */ X X if (len <= 0) { X kwproto(fd,NULLP,0); X return 0; X X /* expand 3 eight-bit bytes to four six-bit bytes */ X X } else { X for (rest = shift = i = 0; i < len; shift = (shift+STEP)%OUT,i++) { X X c = *buf++ & 0377; /* No sign extension */ X *packptr++ = tosix(rest|(c << shift)); /* Assemble byte */ X rest = (c >> (OUT-shift)); /* Save unused bits */ X X if (shift == (OUT-STEP)) { /* At byte boundary? */ X *packptr++ = tosix(rest); /* Make 'fourth' byte */ X rest = 0; /* No unused bits now */ X if (packptr-packbuf > PACKSIZ-4) { /* Check packet size */ X kwproto(fd,packbuf,packptr-packbuf); X packptr = packbuf; X } X } X } X if (shift) { /* Any bits left? */ X *packptr++ = tosix(rest); /* Put them there */ X } X if (packptr > packbuf) { /* Flush buffer */ X kwproto(fd,packbuf,packptr-packbuf); /* Ship it off */ X packptr = packbuf; X } X return i; X } X} X Xkread(fd,buf,len) Xint fd; Xchar *buf; Xint len; X{ X static char packbuf[MAXPACKSIZ] = ""; X static char *packptr = packbuf; X static int packsiz = 0; X register int i,c; X static int shift,rest; X X /* set error trap */ X X if (setjmp(Failbuf)) X return FAIL; X X /* read packet if buffer is empty */ X X if (packsiz <= 0) { X krproto(fd,packptr = packbuf,&packsiz); X rest = shift = 0; X } X X /* unpack (remainder of) buffer; return 0 if empty packet received */ X X for (i = 0; (i < len) && packsiz--; shift = (shift+STEP)%IN) X { X c = unsix(*packptr++); X if (shift) X buf[i++] = (rest | (c << (IN-shift))); X rest = (c >> shift); X } X return i; X} X Xkclose(fd) Xint fd; X{ X /* not here - pass job to the lower layer that understands packet types */ X X kclsproto(fd); X return 0; X} X X END_OF_kpres.c if test 4951 -ne `wc -c <kpres.c`; then echo shar: \"kpres.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f logs.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"logs.c\" else echo shar: Extracting \"logs.c\" \(4714 characters\) sed "s/^X//" >logs.c <<'END_OF_logs.c' X/*++ X/* NAME X/* logs 3 X/* SUMMARY X/* error logging, status reports, debugging X/* PROJECT X/* pc-mail X/* PACKAGE X/* cico X/* SYNOPSIS X/* void dbg(fmt[,args]); X/* char *fmt; X/* X/* int open_log(); X/* X/* void log(fmt[,args]); X/* char *fmt; X/* X/* void trap(code,fmt[,args]); X/* char *fmt; X/* DESCRIPTION X/* All functions in this module do some form of logging, and accept X/* printf-like format strings with %s, %c, and %S, %C. The latter X/* two cause output mapping of arbitrary byte values to printable codes. X/* X/* dbg() formats its arguments and writes the result to the standard X/* output. X/* X/* open_log() tries to open the logfile for writing. It returns X/* a status E_WRITERR if the file could not be opened or created. X/* X/* log() writes status info to the log file. If debugging is enabled, X/* the message is also written to the standard output. X/* X/* trap() writes a message to the log file and performs a longjmp call X/* (systrap) with the status as given in the code parameter. If X/* debugging is enabled, the message is also written to the standard X/* output. X/* FUNCTIONS AND MACROS X/* longjmp() X/* FILES X/* LOGFILE status reports X/* BUGS X/* Logfile info may be lost if the program terminates abnormally. X/* We do not open/close the with each log() call since that would X/* slow down performance on floppy-based systems dramatically. X/* AUTHOR(S) X/* W.Z. Venema X/* Eindhoven University of Technology X/* Department of Mathematics and Computer Science X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands X/* CREATION DATE X/* Thu Mar 26 17:45:19 GMT+1:00 1987 X/* LAST MODIFICATION X/* Mon Apr 4 23:44:00 MET 1988 X/* VERSION/RELEASE X/* 1.3 X/*--*/ X X#include <setjmp.h> X#include <ctype.h> X#include <varargs.h> X#include "defs.h" X#include "logs.h" X#include "path.h" X#include "status.h" X X#define dbgout stdout /* where debugging output should go */ X Xhidden FILE *logfp = NULL; /* log file file pointer */ Xhidden char *visible(); /* map characters to readable codes */ Xhidden void dprintf(); /* special-purpose formatting function */ X X/* dbg - write debugging info to the debugging output */ X X/* VARARGS1 */ X Xpublic void dbg(fmt,va_alist) Xregister char *fmt; Xva_dcl X{ X va_list s; X X va_start(s); X dprintf(dbgout,fmt,s); X va_end(s); X} X X/* open_log - check the logfile can be written */ X Xpublic int open_log() X{ X if (logfp == NULL && (logfp = fopen(logfile(),"a")) == NULL) X return(E_WRITERR); X else X return(0); X} X X/* log - write status info to the log file */ X X/* VARARGS1 */ X Xpublic void log(fmt,va_alist) Xregister char *fmt; Xva_dcl X{ X va_list s; X X /* log file should be open! */ X X if (logfp == NULL) X exit(E_CONFUSED); X X /* write status record to log file */ X X va_start(s); X dprintf(logfp,fmt,s); X putc('\n',logfp); X va_end(s); X X /* if debugging on, write also to debugging output */ X X if (dflag) { X va_start(s); X dprintf(dbgout,fmt,s); X putc('\n',dbgout); X va_end(s); X } X} X X/* trap - exception handler */ X X/* VARARGS2 */ X Xpublic void trap(code,fmt,va_alist) Xint code; Xchar *fmt; Xva_dcl X{ X va_list s; X X /* write exception record to log file */ X X va_start(s); X dprintf(logfp,fmt,s); X putc('\n',logfp); X va_end(s); X X /* if debugging on, write also to debugging output */ X X if (dflag) { X va_start(s); X dprintf(dbgout,fmt,s); X putc('\n',logfp); X va_end(s); X } X longjmp(systrap,code); X} X X/* visible - turn arbitrary character into something visible */ X Xstatic char *visible(c) Xregister int c; X{ X static char buf[5]; X X switch(c&=0377) { X default: X sprintf(buf,isascii(c) && isprint(c) ? "%c" : "\\%03o",c); X return(buf); X case ' ': X return("\\s"); X case '\b': X return("\\b"); X case '\t': X return("\\t"); X case '\r': X return("\\r"); X case '\n': X return("\\n"); X case '\f': X return("\\f"); X case '\\': X return("\\\\"); X } X} X X/* dprintf - handle %s, %c, %S and %C format requests */ X Xstatic void dprintf(fp,fmt,s) Xregister FILE *fp; Xregister char *fmt; Xva_list s; X{ X register int c; X X for (/* void */; c = *fmt; fmt++) { X if (c != '%') { X putc(c,fp); X } else if ((c = *++fmt) == 'S') { /* %S: translated */ X register char *cp = va_arg(s,char *); X while(*cp) X fputs(visible(*cp++&0377),fp); X } else if (c == 'C') { /* %C: translated */ X fputs(visible(va_arg(s,int)),fp); X } else if (c == 's') { /* %s: string, as is */ X fputs(va_arg(s,char *),fp); X } else if (c == 'c') { /* %c: char, as is */ X putc(va_arg(s,int),fp); X } else if (c == '%') { /* real % character */ X putc(c,fp); X } X } X} END_OF_logs.c if test 4714 -ne `wc -c <logs.c`; then echo shar: \"logs.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f path.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"path.h\" else echo shar: Extracting \"path.h\" \(4342 characters\) sed "s/^X//" >path.h <<'END_OF_path.h' X/*++ X/* NAME X/* path X/* SUMMARY X/* system-dependent file name definitions X/* PROJECT X/* pc-mail X/* PACKAGE X/* general X/* SYNOPSIS X/* #include "path.h" X/* DESCRIPTION X/* File-system dependent definitions should be changed here. X/* .nf X X/* /* the minmal number of open files we think we need */ X X#define MINFILES 10 X X/* /* system-dependent defaults */ X X#ifdef unix X#define THISDIR "." /* current directory */ X#define DEFSPOOL "./spool" /* default spool directory */ X#define DEFEDIT "vi" /* default editor */ X#ifdef SIII X#define DEFPRINT "lp" /* printer spooler */ X#else X#define DEFPRINT "lpr" /* printer spooler */ X#endif X#define MAILFILE "mail.msg" /* temporary message file */ X#define TMPALIAS "tmp.alias" /* temp alias file */ X#define NULLDEV "/dev/null" /* bit dump */ X#endif X X#ifdef MSDOS X#define THISDIR "." /* current directory */ X#define DEFSPOOL "\\spool" /* spool directory */ X#define DEFEDIT "edlin" /* default editor */ X#define DEFPRINT "PRN" /* default printer */ X#define MAILFILE "mail.msg" /* temp message file */ X#define TMPALIAS "alias.tmp" /* temp alias file */ X#define NULLDEV "NUL" /* bit dump */ X#endif X X/* /* system-dependent function calls for file & printer access */ X X#ifdef unix X#define propen() popen(mailprn,"w") /* open printe stream */ X#define prclose(p) pclose(p) /* close print stream */ X#define fspool(file) strcons("%s/%s",maildir,file) X#endif X X#ifdef MSDOS X#define propen() fopen(mailprn,"a") /* open print stream */ X#define prclose(p) (putc('\014',p),fclose(p)) /* close print stream */ X#define fspool(file) strcons("%s\\%s",maildir,file) X#endif X X/* /* system-independent file names */ X X#define SMAIL "smail" /* queues a mail message */ X#define CICO "cico" /* file transfer program */ X#define RMAIL "rmail" /* extract originator address */ X X/* /* X* The spool directory is used for storage of all files manipulated X* by the mail programs. Message files should always have a meta file X* with information about the destination or origin of a message file. X* X* Message/meta file names are of the form <letter><sequence number>. X* Corresponding message/meta files have the same sequene number. X* The following definitions are for the <letter> part of spool files. X*/ X X#define LOGFILE "LOGFILE" /* transaction logs */ X X#define NEWPFX "n" /* received message */ X#define HDRPFX "h" /* originator of new mail */ X#define OLDPFX "o" /* originator of old mail */ X X#define MSGPFX "d" /* message ready to be sent */ X#define XQTPFX "x" /* its destination */ X X#define EDTPFX "e" /* message being worked on */ X#define COMPFX "c" /* its description */ X X#define SETPFX "s" /* system parameter file */ X X#define ALIPFX "a" /* alias data base */ X X#define SPLFMT "%s%05d" /* spool-file name format */ X X/* /* X* The following macros provide convenient access of spool files, so we X* don't have to remember the spool file name format and prefix stuff. X*/ X X#define sendmail(file,to) spoolfil(file,to,MSGPFX,XQTPFX) X#define workon(fname,meta) spoolfil(fname,meta,EDTPFX,COMPFX) X X#define parm_file() fspool(strcons(SPLFMT,SETPFX,0)) X#define aliases() fspool(strcons(SPLFMT,ALIPFX,0)) X#define logfile() fspool(LOGFILE) X X#define meta_file(type,id) fspool(strcons(SPLFMT,type,id)) X#define mesg_file(type,id) fspool(strcons(SPLFMT,type,id)) X X#define work_meta(id) fspool(strcons(SPLFMT,COMPFX,id)) X#define work_mesg(id) fspool(strcons(SPLFMT,EDTPFX,id)) X X#define in_mesg(id) fspool(strcons(SPLFMT,NEWPFX,id)) X#define in_meta(id) fspool(strcons(SPLFMT,OLDPFX,id)) X X#define new_mesg(id) fspool(strcons(SPLFMT,NEWPFX,id)) X#define new_meta(id) fspool(strcons(SPLFMT,HDRPFX,id)) X X#define out_mesg(id) fspool(strcons(SPLFMT,MSGPFX,id)) X#define out_meta(id) fspool(strcons(SPLFMT,XQTPFX,id)) X X/* /* stuff taken from the environment */ X Xextern char *editor; /* path to editor */ Xextern char *maildir; /* spool directory */ Xextern char *mailprn; /* how to print */ Xextern char *mailcmd; /* do this on exit */ X Xextern int pathinit(); /* get path info from environment */ X/* AUTHOR(S) X/* W.Z. Venema X/* Eindhoven University of Technology X/* Department of Mathematics and Computer Science X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands X/* CREATION DATE X/* Sun Apr 5 13:23:45 GMT+1:00 1987 X/* LAST MODIFICATION X/* Wed Apr 6 00:21:29 MET 1988 X/* VERSION/RELEASE X/* 1.4 X/*--*/ END_OF_path.h if test 4342 -ne `wc -c <path.h`; then echo shar: \"path.h\" unpacked with wrong size! fi # end of overwriting check fi if test -f sendwork.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"sendwork.c\" else echo shar: Extracting \"sendwork.c\" \(4326 characters\) sed "s/^X//" >sendwork.c <<'END_OF_sendwork.c' X/*++ X/* NAME X/* sendwork 3 X/* SUMMARY X/* send local work to remote system X/* PROJECT X/* pc-mail X/* PACKAGE X/* cico X/* SYNOPSIS X/* #include "work.h" X/* X/* void sendwork(wrk) X/* work *wrk; X/* DESCRIPTION X/* sendwork converts names and contents of local work files, X/* sends them to the remote system and deletes the files after X/* successfull transfer. X/* X/* In particular, it generates appropriate "From " lines at the X/* beginning of an outgoing mail message. X/* FUNCTIONS AND MACROS X/* rmtname() X/* SEE ALSO X/* scanwork(3) locates work in the spool directory X/* rmtname(3) rules for remote file name construction X/* DIAGNOSTICS X/* sendwork() returns via longjmp(systrap,errorcode) in case X/* of unrecoverable problems. X/* X/* The error codes are: E_CONFUSED (unexpected work type), X/* E_LOST (timed out), E_READERR (file read error). X/* AUTHOR(S) X/* W.Z. Venema X/* Eindhoven University of Technology X/* Department of Mathematics and Computer Science X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands X/* CREATION DATE X/* Thu Mar 26 11:32:23 GMT+1:00 1987 X/* LAST MODIFICATION X/* Wed Apr 6 00:22:23 MET 1988 X/* VERSION/RELEASE X/* 1.4 X/*--*/ X X#include <time.h> X#include "defs.h" X#include "work.h" X#include "logs.h" X#include "status.h" X#include "params.h" X#include "comm.h" X Xextern struct tm *localtime(); /* std C library */ X X/* X* A pc-mail system can connect to the UNIX net in at least two modes: X* X* 1. As a real UUCP node, with it's own node name. This node name will X* have to appear in the "From " lines of outgoing mail. A consequence X* is that the pc mail node name should be known in mailer routing tables. X* Obviously this implies some administrative work when a pc mail node X* is added to the net or taken out of operation. X* X* 2. As an ordinary user. The program lets the UNIX host believe that X* mail messages come from an ordinary user. Recipients of mail will X* not be able to see that the mail came from the pc. Only the UNIX host X* knows it should forward mail for unixhost!xyz to the pc-mail node. X* This approach has the advantage that adding/deleting pc-mail nodes X* is simpler. X*/ X X#ifdef UUCP_NODE /* case 1 */ X# define U_USER "root" /* use current user's name */ X# define U_HOST LOGIN_NAME /* use pc host name */ X#else /* case 2 */ X# define U_USER LOGIN_NAME /* use remote login name */ X# define U_HOST rmthost /* use remote host name */ X#endif X X/* sendwork - adapt file contents for remote host */ X Xpublic sendwork(wrk) Xwork *wrk; X{ X register char *date; X long secs; X X switch (wrk->type) { X X /* X * Local D files contain the mail message, nothing more, nothing less. X * We add a "From " line with originator/date/system. X * Otherwise, D files can be sent as is. X */ X X case 'D': X secs = time((long *)0); X (date = asctime(localtime(&secs)))[24] = '\0'; X say(strcons("From %s %s remote from %s\n",U_USER,date,U_HOST)); X send_file(wrk->fp); X break; X X /* X * Local X files contain the destination network address only. X * Therefore we must mock up some extra info to make the X * remote uuxqt program happy. X */ X X case 'X': X say(strcons("U %s %s\n",U_USER,U_HOST)); /* U user system */ X say(strcons("F %s\n",rmtname('D',wrk->tail))); /* F D.rmtsysGnumber */ X say(strcons("I %s\n",rmtname('D',wrk->tail))); /* I D.rmtsysGnumber */ X say("C rmail "); /* C rmail */ X send_file(wrk->fp); /* send destination */ X break; X X default: X trap(E_CONFUSED,"INTERNAL ERROR (unexpected work type: %c)",wrk->type); X } X} X X/* say - write string to host */ X Xhidden say(str) Xchar *str; X{ X if (CALL(Write)(ttfd,str,strlen(str)) < 0) X trap(E_LOST,"FAILED (link lost)"); X} X X/* send_file - do the nitty-gritty of file transfer; traps on all errors */ X Xhidden send_file(fp) Xregister FILE *fp; X{ X register int nread,nwrite = 0; X char buf[BUFSIZ]; X register int rerror; X X while ((nread = fread(buf,sizeof(*buf),sizeof(buf),fp)) > 0 && X (nwrite = CALL(Write)(ttfd,buf,nread)) == nread) X /* empty */; X rerror = ferror(fp); X fclose(fp); X X if (rerror) { X trap(E_READERR,"FILE READ ERROR (%s)",sys_errlist[errno]); X /* NOTREACHED */ X } else if (nwrite < 0 || CALL(Write)(ttfd,buf,0) != 0) { X trap(E_LOST,"FAILED (link lost)"); X /* NOTREACHED */ X } X} END_OF_sendwork.c if test 4326 -ne `wc -c <sendwork.c`; then echo shar: \"sendwork.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f spoolfil.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"spoolfil.c\" else echo shar: Extracting \"spoolfil.c\" \(4020 characters\) sed "s/^X//" >spoolfil.c <<'END_OF_spoolfil.c' X/*++ X/* NAME X/* spoolfil,metafile 3 X/* SUMMARY X/* create message file and meta file X/* PROJECT X/* pc-mail X/* PACKAGE X/* general utilities X/* SYNOPSIS X/* int spoolfil(mesg,meta_info,mesg_prefix,meta_prefix) X/* char *mesg; X/* char *meta_info; X/* char *mesg_prefix; X/* char *meta_prefix; X/* X/* int metafile(string,path) X/* char *string; X/* char *path; X/* DESCRIPTION X/* spoolfil() creates a message, meta file pair in the spool X/* directory. X/* X/* "mesg" should be null-terminated string with the name of an existing X/* file. The contents of that file are filtered to produce a X/* clean ASCII file. X/* X/* "meta-info" is a string with additional information that is X/* written to a meta file (usually name of mail recipient, mail X/* originator or a comment describing the contents of the message file). X/* X/* "mesg_prefix," "meta_prefix" are strings that will be used for building X/* names for files in the spool directory. X/* X/* metafile() creates a file, writes a string to it and terminates X/* the file with a newline character. This function is typically used X/* to create a file with meta information (mail originator, message X/* summary etc.). X/* FUNCTIONS AND MACROS X/* ascopen(), ascget(), ascclose(), newseqno() X/* DIAGNOSTICS X/* A nonzero return value indicates an error condition (see status.h) X/* SEE ALSO X/* status(5) return values X/* ascf(3) ASCII filter X/* BUGS X/* Wordprocessor control codes etc will be lost when spoolfil copies X/* a file. X/* AUTHOR(S) X/* W.Z. Venema X/* Eindhoven University of Technology X/* Department of Mathematics and Computer Science X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands X/* CREATION DATE X/* Mon May 18 18:45:10 GMT+1:00 1987 X/* LAST MODIFICATION X/* Mon Apr 4 23:50:14 MET 1988 X/* VERSION/RELEASE X/* 1.3 X/*--*/ X X#include "defs.h" X#include "path.h" X#include "ascf.h" X#include "status.h" X X/* metafile - create a one-liner file */ X Xpublic int metafile(string,file) Xchar *string; Xchar *file; X{ X register FILE *fp; X X if ((fp = fopen(file,"w")) == 0) { X return(E_WRITERR); X } else if (fprintf(fp,"%s\n",string),ferror(fp)) { X fclose(fp); X return(E_WRITERR); X } else { X fclose(fp); X return(0); X } X} X X/* spoolfil - make arbitrary spool file */ X Xpublic int spoolfil(fname,meta,msgpfx,auxpfx) Xchar *fname; Xchar *meta; Xchar *msgpfx; Xchar *auxpfx; X{ X register int newid = newseqno(); /* new message id */ X register int stat; /* some status */ X char *msgpath; /* new message file */ X char *auxpath; /* new meta file */ X X msgpath = mesg_file(msgpfx,newid); /* message file path */ X auxpath = meta_file(auxpfx,newid); /* meta file path */ X X /* copy disk file to spool file, check for errors */ X X if (stat = copyfile(fname,msgpath)) { /* read/write error */ X unlink(msgpath); /* delete msg file */ X return(stat); /* notify caller */ X X /* create file for meta information, check for errors */ X X } else if (stat = metafile(meta,auxpath)) { /* metafile error */ X unlink(msgpath); /* delete msg file */ X unlink(auxpath); /* delete meta file */ X return(stat); /* notify caller */ X X /* when nothing went wrong */ X X } else { X chmod(msgpath,0444); /* message read-only */ X chmod(auxpath,0444); /* metafile read-only */ X return(0); /* own error handling */ X } X} X X/* copyfile - copy a file and filter it */ X Xpublic int copyfile(from,to) Xchar *from; Xchar *to; X{ X register FILE *in,*out; /* file pointers */ X int rerr,werr; /* error status */ X X if ((in = ascopen(from,"r")) == 0) { /* cannot read ?? */ X return(E_READERR); X } else if ((out = fopen(to,"w")) == 0) { /* cannot write */ X ascclose(in); X return(E_WRITERR); X } else { X register int c; X while ((c = ascget(in)) != EOF) /* ASCII filter */ X putc(c,out); X rerr = ferror(in); /* check read status */ X werr = ferror(out); /* check write status */ X ascclose(in); X fclose(out); X if (rerr) { X return(E_READERR); X } else if (werr) { X return(E_WRITERR); X } else { X return(0); X } X } X} END_OF_spoolfil.c if test 4020 -ne `wc -c <spoolfil.c`; then echo shar: \"spoolfil.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f srctoman.sh -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"srctoman.sh\" else echo shar: Extracting \"srctoman.sh\" \(4444 characters\) sed "s/^X//" >srctoman.sh <<'END_OF_srctoman.sh' X: srctoman - see comment below X X: process arguments X Xwhile : Xdo X case $1 in X [0-9]) SECT=$1;; X -) LANG=$1; B='[#:]';; X -awk) LANG=$1; B='#';; X -c) LANG=$1; B='\/\*';; X -f) LANG=$1; B='[Cc]';; X -mk) LANG=$1; B='#';; X -n|-t) LANG=$1; B='\\"';; X -p) LANG=$1; B='{';; X -r) LANG=$1; B='#';; X -C) LANG=$1; B=$2; shift;; X -*) ERROR="unknown option: $1"; break;; X "") ERROR="missing file argument"; break;; X *) break;; X esac X shift Xdone X X: check error status X Xcase $ERROR in X"") ;; X *) echo "$0: $ERROR" 1>&2 X echo "usage: $0 [-|-awk|-c|-f|-mk|-n|-p|-t|-r] [section] file(s)" 1>&2; exit 1;; Xesac X X: set up for file suffix processing X Xcase $LANG in X"") sh='[:#]'; r='#'; rh=$r; awk='#'; mk='#'; X c='\/\*'; h=$c; y=$c; l=$c; X f='[Cc]'; fh=$f; p='{'; ph=$p; X ms='\\"'; nr=$ms; mn=$ms; man=$ms; Xesac X X: extract comments X Xfor i in $* Xdo X case $LANG in X "") eval B\="\$`expr $i : '^.*\.\([^.]*\)$'`" X test "$B" || { echo "$0: unknown suffix: $i; assuming c" 1>&2; B=$c; } X esac X sed ' X /^'"$B"'++/,/^'"$B"'--/!d X /^'"$B"'++/d X /^'"$B"'--/d X s/[ ]*$// X /^'"$B"' \([A-Z]\)/{ X s//\1/ X /^NAME/{ X N X s/^.*\n'"$B"'[ ]*// X h X y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/ X s/^.*$/.TH & '"$SECT"'\ X.ad\ X.fi\ X.SH NAME/ X p X g X s/ [0-9]$// X a\ X\\- X p X d X } X /^SUMMARY/d X /^DESCRIPTION/s//.SH &\ X.ad\ X.fi/ X /^BUGS/s//.SH &\ X.ad\ X.fi/ X /^DIAGNOSTICS/s//.SH &\ X.ad\ X.fi/ X /^[A-Z][A-Z][A-Z][^a-z]*$/s//.SH &\ X.na\ X.nf/ X p X d X } X s/^'"$B"'[ ]*// X s/^[ ]*$// X' $i Xdone X Xexit X X:++ X: NAME X: srctoman 1 X: SUMMARY X: extract manual page from source file comment X: PACKAGE X: source file maintentance tools X: SYNOPSIS X: srctoman [-|-awk|-c|-f|-mk|-m|-n|-p|-t|-r] [section] file(s) X: DESCRIPTION X: Srctoman converts comments in various programming languages to X: UNIX-style manual pages. X: The command processes comments in the style of newsource(1); X: its standard output is suitable for formatting with nroff(1) or X: troff(1) using the "-man" macro package. X: Typically, srctoman is integrated with make(1) scripts. X: X: Source files are processed in the indicated order; if no X: files argument the command produces no output. X: X: The source file language can be specified through a command-line X: option, or can be implied by the filename suffix. X: The expected start-of-comment symbol is shown in the last column. X: X: .nf X option language comment X X - shell [:#] X -awk awk # X -c c /* X -f fortran [Cc] X -mk make # X -n nroff \\" X -p pascal { X -t troff \\" X -r ratfor # X -C any language next argument X: .fi X: X: .nf X suffix language comment X X .awk awk # X .c c /* X .f fortran [Cc] X .fh fortran [Cc] X .h c /* X .l lex /* X .man nroff,troff \\" X .mk make # X .me nroff,troff \\" X .ms nroff,troff \\" X .nr nroff,troff \\" X .p pascal { X .ph pascal { X .r ratfor # X .rh ratfor # X .sh shell [:#] X .y yacc /* X: .fi X: X: The required format of comments is discussed below, where SOC X: stands for the start-of-comment symbol of the language being used. X: X: 1) Start of manual: SOC, followed by `++'. X: X: 2) Section heading: SOC, blank, section name in upper case. X: X: 3) New paragraph: empty line or line with SOC only. X: X: 4) All other text: SOC and subsequent blanks or tabs are removed. X: Lines that do not start with SOC are left unchanged (useful for X: inclusion of program text). X: X: 5) End of manual: SOC, followed by `--'. X: An end-of-comment may follow if the source file language requires this. X: X: The following manual sections receive a special treatment: X: NAME and SUMMARY should appear at the beginning and in X: this order; DESCRIPTION, DIAGNOSTICS and BUGS will be X: right-margin adjusted. X: Other sections may be added freely without confusing srctoman. X: COMMANDS X: sh(1), sed(1), expr(1) X: SEE ALSO X: newsource(1), modsource(1), xman(1) X: The earlier commands new(1), mod(1), mkman(1) and dssman(1) X: by Ruud Zwart and Ben Noordzij (Erasmus University, Rotterdam) X: DIAGNOSTICS X: The program complains if an unknown language is specified X: or if the language cannot be deduced from the file suffix. X: AUTHOR(S) X: W.Z. Venema X: Eindhoven University of Technology X: Department of Mathematics and Computer Science X: Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands X: CREATION DATE X: Fri Jan 17 22:59:27 MET 1986 X: LAST MODIFICATION X: Thu Mar 10 20:08:15 MET 1988 X: VERSION/RELEASE X: 1.20 X:-- X X END_OF_srctoman.sh if test 4444 -ne `wc -c <srctoman.sh`; then echo shar: \"srctoman.sh\" unpacked with wrong size! fi chmod +x srctoman.sh # end of overwriting check fi if test -f switcher.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"switcher.c\" else echo shar: Extracting \"switcher.c\" \(4041 characters\) sed "s/^X//" >switcher.c <<'END_OF_switcher.c' X/*++ X/* NAME X/* switcher 3 X/* SUMMARY X/* master/slave protocol control switcher X/* PROJECT X/* pc-mail X/* PACKAGE X/* cico X/* SYNOPSIS X/* int switcher(role) X/* int role; X/* DESCRIPTION X/* switcher() takes care of the high-level protocol on top of X/* the packet protocol. X/* X/* The system is in one of two roles: MASTER or SLAVE. In MASTER X/* mode (initial mode of the caller) a system scans its local X/* spool directory for work until no more is found, and then X/* sends a H (hangup) request. The slave will respond with HY X/* if it has no work, otherwise it will respond with HN and X/* the two systems switch roles. X/* X/* Work can be of the form of S (send) requests or R (receive) X/* requests. The slave responds with SY (RY) or SN (RN), depending on X/* whether it is willing to process the request. The recipient X/* of a message sends a CY or CN message, depending on whether X/* transmission was successfull. X/* X/* Only H(angup) and S(end) requests are implemented here. This is X/* for security reasons. Thus, the only way to exchange data is X/* through electronic mail. X/* FUNCTIONS AND MACROS X/* isok, talk(), hear(), trap(), scanwork(), sendwork() X/* rmtwork(), getwork() X/* DIAGNOSTICS X/* Various nonzero status codes are returned in case of problems. X/* AUTHOR(S) X/* W.Z. Venema X/* Eindhoven University of Technology X/* Department of Mathematics and Computer Science X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands X/* CREATION DATE X/* Fri Mar 27 21:49:16 GMT+1:00 1987 X/* LAST MODIFICATION X/* Wed Apr 6 00:23:14 MET 1988 X/* VERSION/RELEASE X/* 1.4 X/*--*/ X X#include <setjmp.h> X#include "defs.h" X#include "work.h" X#include "params.h" X#include "comm.h" X#include "logs.h" X#include "status.h" X X/* switcher - handles master/slave role swicthing until all work is done */ X Xpublic switcher(role) Xregister int role; X{ X int *savetrap = systrap; X jmp_buf mytrap; X int status; X X if (status = setjmp(systrap = mytrap)) { X systrap = savetrap; /* get here on fatal errors */ X return(status); X } X X /* switch roles until both ends out of work */ X X while (role != DONE) { X switch (role) { X case MASTER: X role = master(); X break; X case SLAVE: X role = slave(); X break; X default: X trap(E_CONFUSED,"INTERNAL ERROR (unexpected role: %d)",role); X } X } X systrap = savetrap; /* get here if no fatal errors */ X return(0); X} X X/* master - process local work; when done, switch roles or finish */ X Xhidden int master() X{ X register work *wrk; X register char *resp; X X while (wrk = scanwork()) { /* scan for work */ X log("REQUEST (%s)",wrk->rqst); X if (wrk->fp == 0) { /* check file exists */ X log("CAN'T READ DATA (%s)",sys_errlist[errno]); X } else if (isok(wrk->rqst) == NO) { /* check xfer allowed */ X log("PERMISSION (DENIED)"); X } else { /* adapt + send data */ X sendwork(wrk); X log("REQUESTED (%s)",resp = hear()); X if (strcmp(resp,"CY")) /* check sucessfull */ X trap(E_REJECT,"FAILED"); /* completion */ X chmod(wrk->path,0666); /* delete workfile */ X unlink(wrk->path); /* only if all well */ X } X } X X /* switch roles or finish if slave has no work */ X X return(isok("H") == YES ? (talk("HY"),DONE) : SLAVE); X} X X/* slave - process remote work; accept H and S requests only */ X Xhidden int slave() X{ X register char *cmnd; X register work *wrk; X X for (;;) { X switch ((cmnd = hear())[0]) { X case 'S': /* master wants to send */ X log("REQUESTED (%s)",cmnd); /* log the request */ X wrk = rmtwork(cmnd); /* parse the request */ X talk("SY"); /* say ok */ X getwork(wrk); /* receive work */ X talk("CY"); /* we never copy */ X log("COPY (SUCCEEDED)"); X break; X case 'H': /* master is out of work */ X return(scanwork() ? (talk("HN"),MASTER) : (talk("HY"),DONE)); X default: X talk(strcons("%cN",cmnd[0])); /* refuse other type of work */ X break; X } X } X} END_OF_switcher.c if test 4041 -ne `wc -c <switcher.c`; then echo shar: \"switcher.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f unalias.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"unalias.c\" else echo shar: Extracting \"unalias.c\" \(4581 characters\) sed "s/^X//" >unalias.c <<'END_OF_unalias.c' X/*++ X/* NAME X/* unalias 3 X/* SUMMARY X/* alias processing X/* PROJECT X/* pc-mail X/* PACKAGE X/* smail X/* SYNOPSIS X/* char **unalias(namevec) X/* char **namevec; X/* DESCRIPTION X/* unalias() takes an array of string pointers and returns a vector X/* with string pointers to their alias expansions. The resulting X/* vector is in static memory. X/* X/* After alias expansion, all addresses are sorted and duplicate X/* names are eliminated. The algorithms for alias expansion and X/* duplicate elimination are case-insensitive. X/* X/* unalias() accesses the alias data base through the ascf ASCII X/* filter. X/* DIAGNOSTICS X/* unalias() returns a null pointer in case of memory-allocation problems. X/* X/* unalias() terminates prematurely when the alias expansion has X/* produced BUFSIZ recipients. This provides some defense against X/* cycles in the alias data base. It is up to the caller to X/* recognize this condition. X/* BUGS X/* The overflow/cycle detection algorithm is inelegant. X/* FILES X/* Alias data base in spool directory X/* AUTHOR(S) X/* W.Z. Venema X/* Eindhoven University of Technology X/* Department of Mathematics and Computer Science X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands X/* CREATION DATE X/* Wed Apr 6 20:21:35 MET 1988 X/* LAST MODIFICATION X/* Wed Apr 6 20:21:35 MET 1988 X/* VERSION/RELEASE X/* 1.0 X/*--*/ X X#include "defs.h" X#include "hsearch.h" X#include "path.h" X#include "ascf.h" X X/* forward declarations */ X Xhidden int hash_alias(); Xhidden void sort_alias(); Xhidden void uniq_alias(); Xhidden char **find_alias(); X X/* unalias - replace aliases by their equivalents */ X Xpublic char **unalias(names) Xchar **names; X{ X static int dohash = 1; /* hash table not yet made */ X static char *recp[BUFSIZ+1]; /* the result of alias expansion */ X char **stop = recp+BUFSIZ; /* overflow limit */ X X if (dohash && (dohash = hash_alias())) /* build the hash table */ X return(0); X if (stop > find_alias(names,recp,stop)) { /* build vector of addresses */ X sort_alias(recp); /* sort the recp list */ X uniq_alias(recp); /* squeeze out identical addresses */ X } X return(recp); X} X X/* hash_alias - copy alias data base to hash table */ X Xhidden int hash_alias() X{ X register FILE *fp; X char buf[BUFSIZ]; X X /* initialize the hash table */ X X if (hcreate(BUFSIZ) == 0) X return(-1); X X /* X * Lines in the alias data base are of the form X * X * <left-hand part> <right-hand part> X * X * where the l.h. part is an alias, and the r.h. part one or more X * words. Of course, those words can be aliases. The order in which X * aliases are defined is not important. The alias data base is used X * only after it has been loaded into memory. X * X * Each l.h. part is used as the key for finding the r.h. part in the X * hash table. The r.h. part is stored as a vector of pointers to strings. X */ X X if (fp = ascopen(aliases(),"r")) { /* read through ASCII filter */ X while (fgets(buf,BUFSIZ,fp)) { /* read alias entry */ X register char **cpp; X ENTRY e; X if ((cpp = strvec(buf,", \t\r\n")) == 0) /* split alias entry */ X return(-1); X if ((e.key = *cpp) /* left-hand part exists */ X && (e.data = (char *) (cpp+1)) /* right-hand part exists */ X && (hsearch(e,ENTER) == 0)) /* enter hash table */ X return(-1); X } X ascclose(fp); X } X return(0); X} X X/* find_alias - recursively expand aliases */ X Xhidden char **find_alias(from,to,stop) Xchar **from; Xregister char **to; Xregister char **stop; X{ X register char **cpp; X register ENTRY *sp; X X /* recursively replace aliases, but don't crash in case of cycles */ X X for (cpp = from; *cpp && (to < stop); cpp++) { X ENTRY e; X e.key = *cpp; X if (sp = hsearch(e,FIND)) { X to = find_alias((char **)sp->data,to,stop); X } else { X *to++ = *cpp; X } X } X *to = 0; X return(to); X} X X/* Istrcmp - interface between qsort and istrcmp */ X Xhidden int Istrcmp(p1,p2) Xchar **p1,**p2; X{ X return(istrcmp(*p1,*p2)); X} X X/* sort_alias - sort the addresses after alias substitutions */ X Xhidden void sort_alias(to) Xchar **to; X{ X register char **cpp; X int istrcmp(); X X /* find out length of the list */ X X for (cpp = to; *cpp; cpp++) X /* void */ ; X X /* sort the list */ X X qsort((char *)to,cpp-to,sizeof(*to),Istrcmp); X} X X/* uniq_alias - collapse sequences of identical addresses */ X Xhidden void uniq_alias(to) Xchar **to; X{ X register char **in = to; X register char **out = to; X X while (*out = *in) { X while (*++in && istrcmp(*out,*in) == 0) { X /* void */ ; X } X ++out; X } X} END_OF_unalias.c if test 4581 -ne `wc -c <unalias.c`; then echo shar: \"unalias.c\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 5 \(of 8\). cp /dev/null ark5isdone MISSING="" for I in 1 2 3 4 5 6 7 8 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 8 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- uucp: mcvax!eutrc3!wswietse | Eindhoven University of Technology bitnet: wswietse@heithe5 | Dept. of Mathematics and Computer Science surf: tuerc5::wswietse | Eindhoven, The Netherlands.