koreth@ssyx.ucsc.edu (Steven Grimm) (07/30/88)
Submitted-by: koreth@ssyx.ucsc.edu (Steven Grimm) Posting-number: Volume 1, Issue 67 Archive-name: uupc/part03 #!/bin/sh # this is part 3 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # file mail.c continued # CurArch=3 if test ! -r s2_seq_.tmp then echo "Please unpack part 1 first!" exit 1; fi ( read Scheck if test "$Scheck" != $CurArch then echo "Please unpack part $Scheck next!" exit 1; else exit 0; fi ) < s2_seq_.tmp || exit 1 sed 's/^X//' << 'SHAR_EOF' >> mail.c X finis(); X } X n = 0; X for ( i = 0; i < letternum; i++ ) X if ( letters[i].delete == FALSE ) { X copymsg( i, fmailbag, FALSE ); X n++; X } X fclose (fmailbag ); X} X X X/* copy a message X if noheaders true, don't copy header lines X*/ Xcopymsg( n, f, noheaders ) XFILE *f; X{ X long bytes; X char buf[BUFSIZ]; X X fseek( fmailbox, letters[n].adr, 0 ); X bytes = letters[n+1].adr - letters[n].adr; X X while ( bytes > 0 && fgets( buf, BUFSIZ, fmailbox ) ) { X bytes -= strlen( buf ); X X /* write line */ X if ( !noheaders ) X fputs( buf, f ); X X /* reset header */ X if ( noheaders && strcmp( buf, "\n") == SAME ) X noheaders = FALSE; X X } X} X Xpager(n) X{ X long bytes; X char buf[BUFSIZ]; X X fseek( fmailbox, letters[n].adr, 0 ); X bytes = letters[n+1].adr - letters[n].adr; X X pagereset(); X while ( bytes > 0 && fgets( buf, BUFSIZ, fmailbox ) ) { X bytes -= strlen( buf )+1; X if ( pageline( buf ) == TRUE ) X break; X } X X pageline( "\n" ); X} X Xpagereset() X{ X PageCount = 0; X} X Xpageline( s ) Xchar * s; X{ X char c; X X fputs( s, stdout ); X if ( ++PageCount > 24 ) { X PageCount = 0; X c = get_one(); X switch( c ) { X case 'q': X case 'Q': X case '\003': X case 'x': X case 'X': X return( TRUE ); X } X } X return( FALSE ); X} X Xchar *getnext( s, p ) Xregister char **s, *p; X{ X *s = (char *)NULL; X while ( *p == ' ' || *p == '\t' ) X p++; X if ( *p == '\n' || *p == '\0' ) X return( (char *)NULL ); X *s = p; X while ( *p != ' ' && *p != '\t' && *p != '\n' && *p != '\0' ) X *p++; X if ( *p != '\0' ) X *p++ = '\0'; X return(p); X} SHAR_EOF chmod 0600 mail.c || echo "restore of mail.c fails" sed 's/^X//' << 'SHAR_EOF' > mailhost.c && X/* mailhost.c X X*/ X#define MAIN mailmain X#include "host.c" X SHAR_EOF chmod 0600 mailhost.c || echo "restore of mailhost.c fails" sed 's/^X//' << 'SHAR_EOF' > makefile && XDESTDIR=. X XCFLAGS=-g X XUTLOBS= dirsubs.o genv.o ndir.o fgets.o getone.o\ X inoutpth.o shell.o time.o chekname.o XDCPOBS= dcpgpkt.o dcpsys.o dcpxfer.o X XMAILOBS=mailhost.o mail.o lmail.o dmymath.o lib.o libdcp.a libutl.a XUUOBS=uuhost.o uusup.o dcp.o rmail.o dmymath.o lib.o ndir.o libutl.a libdcp.a X Xall: mail.ttp uu.ttp X Xmail.ttp: $(MAILOBS) X $(CC) $(CFLAGS) -o $@ $(MAILOBS) X Xuu.ttp: $(UUOBS) X $(CC) $(CFLAGS) -o $@ $(UUOBS) X Xlibutl.a: $(UTLOBS) X c:\megamax\ar.ttp rv $@ $? Xlibdcp.a: $(DCPOBS) X c:\megamax\ar.ttp rv $@ $? X Xrmail.o: rmail.c pcmail.c Xlmail.o: lmail.c pcmail.c SHAR_EOF chmod 0600 makefile || echo "restore of makefile fails" sed 's/^X//' << 'SHAR_EOF' > mlib.c && X/* mlib.c X X*/ X X#include "local/mlib.c" X SHAR_EOF chmod 0600 mlib.c || echo "restore of mlib.c fails" sed 's/^X//' << 'SHAR_EOF' > ndir.c && X/* X * Program: ndir.c X * Facility: X * Directory reading support for the atari st X */ X X#define DEF_NDIR X X#include <osbind.h> X#include <stdio.h> X#include "ndir.h" X X#ifndef TRUE X#define TRUE (-1) X#define FALSE (0) X#endif X X#define BSLASH '\\' X#define SLASH '/' X XDIR DtaBuff; /* used by GEMDOS for Fsfirst/Fsnext */ Xshort FirstSearch; /* used to first call to readdir */ Xstruct direct dentry; /* portable directory structure */ X XDIR *opendir( filename ) Xchar *filename; X{ X int status; X char *cp1,*cp2; X X Fsetdta( &DtaBuff ); X FirstSearch = TRUE; X X /* X * Copy filename into FilePath buffer and convert forward slashs X * to backward slashes. X * Also make sure path terminates in a back slash X */ X cp1 = DtaBuff.FilePath; X cp2 = filename; X while (*cp2 != '\0') X { X *cp1++ = (*cp2 == SLASH) ? BSLASH : *cp2; X cp2++; X } X if ( *(cp1-1) != BSLASH ) /* enforce trailing back slash */ X { X *cp1++ = BSLASH; X } X *cp1 = '\0'; /* add trailing zero */ X strcat( DtaBuff.FilePath, "*.*" ); X X status = Fsfirst( DtaBuff.FilePath, 0 ); X if ( status != 0 ) return( (DIR *)NULL ); X return( &DtaBuff ); X} X Xstruct direct *readdir( dirp ) XDIR *dirp; X{ X int status; X X if ( FirstSearch ) X { X FirstSearch = FALSE; X dentry.d_ino = 0L; X dentry.d_reclen = 264; X dentry.d_namlen = strlen( dirp->FileName ); X strcpy( dentry.d_name, dirp->FileName ); X return( &dentry ); X } X Fsetdta( dirp ); X if (( status = Fsnext() ) != 0 ) X return( (struct direct *)NULL ); X dentry.d_ino = 0L; X dentry.d_reclen = 264; X dentry.d_namlen = strlen( dirp->FileName ); X strcpy( dentry.d_name, dirp->FileName ); X return( &dentry ); X} X Xvoid closedir( dirp ) XDIR *dirp; X{ X return; X} X X SHAR_EOF chmod 0600 ndir.c || echo "restore of ndir.c fails" sed 's/^X//' << 'SHAR_EOF' > ndir.h && X/* @(#)ndir.h 1.4 4/16/85 */ X/* Modified for the atari st series 5/4/87 */ X#ifndef DEV_BSIZE X#define DEV_BSIZE 512 X#endif X#define DIRBLKSIZ DEV_BSIZE X#define MAXNAMLEN 255 X Xstruct direct { X long d_ino; /* inode number of entry */ X short d_reclen; /* length of this record */ X short d_namlen; /* length of string in d_name */ X char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */ X}; X X/* X * The DIRSIZ macro gives the minimum record length which will hold X * the directory entry. This requires the amount of space in struct direct X * without the d_name field, plus enough space for the name with a terminating X * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary. X */ X X#ifdef DIRSIZ X#undef DIRSIZ X#endif X#define DIRSIZ(dp) \ X ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3)) X X/* X * Definitions for library routines operating on directories. X */ X X/* Structure of a directory entry under GEMDOS */ X Xtypedef struct _dirdesc X { X char Reserved[21]; X char FileAttr; X int CreateTime; X int CreateDate; X long FileSize; X char FileName[14]; X char FilePath[256]; X } DIR; X X#ifndef NULL X#define NULL 0L X#endif X X#ifndef DEF_NDIR Xextern DIR *opendir(); Xextern struct direct *readdir(); Xextern void closedir(); X#endif X SHAR_EOF chmod 0600 ndir.h || echo "restore of ndir.h fails" sed 's/^X//' << 'SHAR_EOF' > pcmail.c && X/* pcmail.c X X X X copyright (C) 1987 Stuart Lynne X X Copying and use of this program are controlled by the terms of the X Free Software Foundations GNU Emacs General Public License. X X X version 0.1 March 31/1987 X X Xpcmail X X pcmail address1 address2 ... < the.message X Xdescription X X An 822 compatible (hopefully) mail delivery system for pc's. X X Designed for delivering mail on a pc based system. It will put X local mail (ie, not @ or ! in address) into files in the default X mail directory. X X If remote it will put into an outgoing mailbag in the default mail X directory. Performs a simple bundling of mail messages into one X file with arguments prepended as To: arg header lines. And adds a X Message-Lines: header which gives the number of lines in the X content part of the message (after the first blank line). X X pcmail john jack jill@xyz.uucp < afile X X To: john X To: jack X To: jill@xyz.uucp X X-Message-Lines: ????? X Content-Length: ????? X X ... X ... X ... X X Content-Length: is used without X- prepended to be compatible with AT&T X Mail bundles. This is not 822 compatible per se, but is allowed. X X It also adds the from From and Date lines. Subject: lines may be inserted X by placing them at the beginning of the message. X X A Unix version should lock the /usr/mail/mailbag file. X X Another program called rpcmail will unbundle the files created by X pcmail and deliver each message to the local rmail. So conceptually X X (pcmail ..... < ...; pcmail .... < ...) | sz -> rz | rpcmail X X would deliver remote messages intact. X Xenvironment variables X X The following evironment variables are used: X X MAILBOX current user's mailbox, "stuart" X NAME current user's name, "Stuart Lynne" X DOMAIN domain of this machine, "slynne.mac.van-bc.can" X MAILDIR where is mail kept, "mpw:mail" X Xcompiling X X Compiled by itself it will operate as a standalone program. If the X compiler option: X X -DNOMAIN X X is used, it will compile as a routine: X X pcmail (argc, argv) X char **argv; X int argc; X X and can be used internally in other programs. X X XCustomization X X PCMAIL mailbag for remote mail X FAKEUUX emulate uux, make appropriate files in SPOOLDIR X X RMAIL rmail X X DEBUG1 first level Debug trace X X X*/ X X#include "dcp.h" X XFILE *FOPEN(); X X#define FORWARD "Forward to" X X X#define SBUFSIZ 124 X XFILE *mailfile; XFILE *tempfile; X Xchar buf[BUFSIZ]; Xchar miscbuff[100]; Xlong int lines = 0; Xlong int bytes = 0; Xlong int sequence = 0; X Xlong tloc; Xchar chartime[26]; /* current time in characters */ Xchar *thetime; X Xchar tfilename[100]; Xchar mfilename[100]; Xchar mailsent[100]; Xchar s_systems[64]; X Xint local = TRUE; X Xchar remotes[BUFSIZ]; X X Xchar uucp[] = "uucp"; X Xchar *fgets(); Xint fputs(); X X#ifdef NOMAIN X X#ifdef RMAIL X#define main rmail X#else X#define main lmail X#endif X X#define exit return X Xextern int debuglevel; X X#else Xint debuglevel; X#endif X X#ifndef RMAIL Xchar Subject[132] = ""; X#endif X Xchar *mcurdir; Xchar s_mcurdir[128]; /* current directory path (save malloc call) */ Xchar * getcwd(); Xint chdir(); X X X Xmain(argc, argv) Xchar *argv[]; X{ X long int position; X register int header = 1; X register int amount; X X register int argcount; X register char **argvec; X int remote; X int s1, s2; X X X X X#ifndef NOMAIN X /* get environment var's */ X HOSTINIT; X loadenv(); X X if (argc <= 1) { X fprintf( stderr, "pcmail usage: pcmail addresses < message\n" ); X exit(1); X } X debuglevel = 99; X X#endif X#ifdef RMAIL X local = FALSE; X#else X local = TRUE; X#endif X X if ( debuglevel > 5 ) { X fprintf( stderr, "pcmail: argc %d ", argc ); X argcount = argc; X argvec = argv; X while (argcount--) { X fprintf( stderr, " \"%s\"", *argvec++ ); X } X fprintf( stderr, "\n" ); X X tloc = time( (long *)NULL ); X thetime = ctime(&tloc); X fprintf( stderr, "thetime: %s\n",thetime ); X } X X#ifdef MSDOS X mcurdir = getcwd( s_mcurdir, sizeof(s_mcurdir) ); X#else X mcurdir = getcwd( s_mcurdir, 0 ); X#endif X chdir( spooldir ); X X /* get sequence number */ X mkfilename( tfilename, confdir, SFILENAME ); X X if ( debuglevel > 4 ) X fprintf( stderr, "pcmail: opening %s\n", tfilename ); /* */ X X tempfile = FOPEN( tfilename, "r", 't' ); X if (tempfile != (FILE *)NULL) { X fscanf( tempfile, "%ld", &sequence ); X fclose( tempfile ); X } X else { X fprintf( stderr, "pcmail: can't find %s file, creating\n", X tfilename ); X sequence = 1; /* start at 1 */ X }; X X /* update sequence number */ X if ( debuglevel > 5 ) X fprintf( stderr, "pcmail: new sequence # %ld\n", sequence ); X X tempfile = FOPEN( tfilename, "w", 't' ); X if (tempfile != (FILE *)NULL) { X fprintf( tempfile, "%ld\n", sequence+1 ); X fclose( tempfile ); X } X X /* open a temporary file */ X /* sprintf( tfilename, TFILENAME, sequence ); */ X sprintf( miscbuff, TFILENAME, sequence ); X mkfilename( tfilename, tempdir, miscbuff ); X X if ( debuglevel > 5 ) X fprintf( stderr, "pcmail: opening %s\n", tfilename ); X X tempfile = FOPEN( tfilename, "w", 'b' ); X if (tempfile == (FILE *)NULL) { X fprintf( stderr, "pcmail: can't open %s\n", tfilename ); X exit(1); X } X X /* copy stdin to tempfile, counting content lines and bytes */ X header = 1; X while (fgets( buf, 512, stdin ) != (char *)NULL) { X if (header != 0) { X if (strlen( buf ) == 1) { X header = 0; X fprintf( tempfile, "\n" ); X continue; X } X else if (strchr( buf, ':' ) == NULL) { X header = 0; X fprintf( tempfile, "\n" ); X } X } X if (header == 0) { X lines++; X bytes += strlen( buf ); X } X fputs( buf, tempfile ); X } X X fclose( tempfile ); X X if ( debuglevel > 4 ) { X fprintf( stderr, "pcmail: stdin copied to tmp %ld %ld\n", X bytes, lines ); X fprintf( stderr, "pcmail: args %d\n", argc ); X } X X /* loop on args, copying to appropriate postbox, X do remote only once X remote checking is done empirically, could be better X */ X remotes[0] = '\0'; X X X#ifndef RMAIL X if ( strcmp( argv[1], "-s" ) == SAME ) { X argv++;argv++; X argc--;argc--; X if ( argc == 0 ) X return( -1 ); X strcpy( Subject, *argv ); X } X#endif X argcount = argc; X argvec = argv; X X while (--argcount > 0) { X argvec++; X if ( debuglevel > 5 ) X fprintf( stderr, "pcmail: arg# %d\ %s\n", X argcount, *argvec ); X X if ( X (strchr( *argvec, '!' ) != SAME) || X (strchr( *argvec, '@' ) != SAME) || X (strchr( *argvec, '%' ) != SAME) X ) { X if ( debuglevel > 5 ) X fprintf( stderr, "pcmail: send to remote\n" ); X X s1 = strlen( remotes ); X s2 = strlen( *argvec ); X X /* can we cram one more address on line */ X if ( s1 > 0 && (s1 + s2 + 1) > 128 ) { X /* dump it then, to bad */ X sendone( argc, argv, remotes, TRUE ); X remotes[0] = '\0'; X } X X /* add *arvgvec to list of remotes */ X strcat( remotes, " " ); X strcat( remotes, *argvec ); X X } X else { X if ( debuglevel > 5 ) X fprintf( stderr, "pcmail: calling sendone %s\n", X *argvec ); X X sendone( argc, argv, *argvec, FALSE ); X } X X } X /* dump remotes if necessary */ X if ( strlen( remotes ) > 0 ) X sendone( argc, argv, remotes, TRUE ); X X#ifndef RMAIL X X mkfilename( mailsent, home, COPYFILE ); X if ( debuglevel > 4 ) X fprintf( stderr, "pcmail: copfile = %s\n", mailsent ); X sendone( argc, argv, mailsent, FALSE ); X X#endif X X unlink( tfilename ); X chdir( mcurdir ); X exit(0); X} X X/* X * Figure out which mail server we should send something to. Scan the X * systems file for the first component of the desired mailpath. If we X * don't find it, revert to the default server. X */ Xservername(address, def, buf) Xchar *address, *def, *buf; X{ X char temp[32], line[256], *bang; X X while (*address == ' ') X address++; X strncpy(temp, address, 31); X temp[31] = '\0'; X X/* Isolate the first component of the mail path */ X bang = index(temp, '!'); X if (bang) X *bang = '\0'; X X if (checkname(temp) == FAILED) X strcpy(buf, def); X else X strcpy(buf, temp); X} X X Xchar fpat1[] = "%c.%.7s%04ld"; Xchar fpat2[] = "S %s %s %s - %s 0666 %s"; X X/* sendone copies file plus headers to appropriate postbox X NB. we do headers here to allow flexibility later, for example X in being able to do bcc, per host service processing etc. X*/ Xsendone( argc, argv, address, remote ) Xchar **argv; Xint argc; Xchar *address; X{ X#ifdef RMAIL X int recflag = 0; /* we have read a "Received:" */ X int fromflag = 0; /* we have copied the "From " */ X#endif X register char *cp; X char maildest[32]; /* system to send to */ X char icfilename[32]; /* local C. copy file */ X char ixfilename[32]; /* local X. xqt file */ X char idfilename[32]; /* local D. data file */ X char rxfilename[32]; /* remote X. xqt file */ X char rdfilename[32]; /* remote D. data file */ X char tmfilename[32]; /* temporary storage */ X#ifdef MSDOS X char cixfilename[32]; /* canonical ixfilename */ X char cidfilename[32]; /* canonical idfilename */ X#endif X if ( remote ) { X /* sprintf all required file names */ X mkfilename(s_systems, confdir, SYSTEMS); X servername(address, mailserv, maildest); X sprintf( tmfilename, fpat1, 'C', maildest, sequence ); X importpath( icfilename, tmfilename ); X#ifdef MSDOS X sprintf( cidfilename, fpat1, 'D', maildest, sequence ); X importpath( idfilename, cidfilename ); X sprintf( cixfilename, fpat1, 'D', nodename, sequence ); X importpath( ixfilename, cixfilename ); X#else X sprintf( tmfilename, fpat1, 'D', maildest, sequence ); X importpath( idfilename, tmfilename ); X sprintf( tmfilename, fpat1, 'D', nodename, sequence ); X importpath( ixfilename, tmfilename ); X#endif X sprintf( rdfilename, fpat1, 'D', nodename, sequence ); X sprintf( rxfilename, fpat1, 'X', nodename, sequence ); X } X else { X /* postbox file name */ X if ( index( address, SEPCHAR ) == (char *)NULL ) X mkfilename( idfilename, maildir, address ); X else X strcpy( idfilename, address ); X } X X if ( debuglevel > 5 ) X fprintf( stderr, "pcmail: sendone: %s\n", idfilename ); X X if ( remote == FALSE ) { X if ( debuglevel > 5 ) X fprintf( stderr, "pcmail: sendone: check for remote\n" ); X /* check for forwarding */ X if ( (mailfile = FOPEN( idfilename, "r", 'b' )) != (FILE *)NULL ) { X cp = fgets( buf, BUFSIZ, mailfile ); X fclose( mailfile ); X if (cp != (char *)NULL) X if (strncmp( buf, FORWARD, 10 ) == 0) { X strcpy( buf, buf+11 ); X return( sendone( argc, argv, buf, FALSE ) ); X } X } X } X X /* open mailfile */ X if ( (mailfile = FOPEN( idfilename, "a", 'b' )) == (FILE *)NULL ) { X fprintf( stdout, "pcmail: cannot append to %s\n", idfilename ); X return( 0 ); X } X X if ( debuglevel > 5 ) X fprintf( stderr, "pcmail: append to mailfile\n" ); X X tloc = time( (long *)NULL ); X thetime = ctime(&tloc); X (void)strcpy(chartime, thetime); /* make our own copy */ X thetime = chartime; /* and work with our own copy */ X thetime[strlen(thetime)-1] = '\0'; X X#ifndef RMAIL X fprintf( mailfile, "From %s %s", mailbox, thetime ); X if ( remote ) X fprintf( mailfile, " remote from %s", nodename ); X fputc( '\012', mailfile ); X fprintf( mailfile, "Received: by %s (pcmail) %s", domain, thetime ); X fputc( '\012', mailfile ); X fprintf( mailfile, "Date: %s", thetime ); X fputc( '\012', mailfile ); X /* add Date:, From: and Message-ID: headers */ X fprintf( mailfile, "From: %s <%s@%s>", name, mailbox, domain ); X fputc( '\012', mailfile ); X fprintf( mailfile, "Message-ID: <%ld@%s>", sequence, domain ); X fputc( '\012', mailfile ); X /* add To: headers */ X while (--argc > 0) { X fprintf( mailfile, "To: %s", *++argv ); X fputc( '\012', mailfile ); X } X if ( strlen( Subject ) > 0 ) { X fprintf( mailfile, "Subject: %s", Subject ); X fputc( '\012', mailfile ); X } X#ifdef PCMAIL X /* add Message-Lines: and Content-Length: headers */ X fprintf( mailfile, "X-Message-Lines: %ld", lines ); X fputc( '\012', mailfile ); X fprintf( mailfile, "Content-Length: %ld", bytes ); X fputc( '\012', mailfile ); X#endif /* PCMAIL */ X#endif /* RMAIL */ X X /* copy tempfile to postbox file */ X if (debuglevel > 4) X fprintf( stderr, "pcmail: copy tempfile %s to %s\n", X tfilename, idfilename ); X tempfile = FOPEN( tfilename, "r", 'b' ); X if ( tempfile == (FILE *)NULL) { X fprintf( stdout, "pcmail: can't re-open %s\n", tfilename ); X return( 0 ); X } X while (fgets( buf, 512, tempfile ) != (char *)NULL) { X/* X * If this is rmail, we want to munge the first "From " line, since there X * will be a "remote from hostname" at the end that we want to prepend to X * the mail path after "From ". Subsequent "From " lines will have a > X * prepended so we don't mess up the mail shell (all "From " lines are X * treated this way if we aren't rmail) X */ X if ( strncmp( buf, "From ", 5 ) == 0 ) X#ifdef RMAIL X if (! fromflag++) X munge_from(buf); X else X#endif X fputc( '>', mailfile ); X/* X * We want to insert our "Received:" line above all the others, if this X * is rmail. There will be some if we're receiving from a remote site X * (i.e., rmail) -- if we aren't, the received line is inserted elsewhere X * anyway so we don't worry about it. X */ X#ifdef RMAIL X if ((! strncmp(buf, "Received:", 9)) && (! recflag++)) X fprintf( mailfile, "Received: by %s (pcmail) %s\n", X domain, thetime ); X#endif X cp = &buf[ strlen(buf)-1 ]; X if ( *cp == '\n' ) X *cp = '\0'; X fputs( buf, mailfile ); X fputc( '\012', mailfile ); X } X X /* close files */ X fclose( mailfile ); X fclose( tempfile ); X X /* all done unless going to remote via uucp */ X /* must create the job control files */ X if ( remote == TRUE ) { X X /* create remote X xqt file */ X mailfile = FOPEN( ixfilename, "w", 'b' ); X if (mailfile == (FILE *)NULL) { X fprintf( stdout, "pcmail: cannot append to %s\n", ixfilename ); X return( 0 ); X } X fprintf( mailfile, "U %s %s", uucp, nodename ); X fputc( '\012', mailfile ); X fprintf( mailfile, "F %s", rdfilename ); X fputc( '\012', mailfile ); X fprintf( mailfile, "I %s", rdfilename ); X fputc( '\012', mailfile ); X fprintf( mailfile, "C rmail %s", address ); X fputc( '\012', mailfile ); X fclose( mailfile ); X X /* create local C copy file */ X mailfile = FOPEN( icfilename, "w", 't' ); X if (mailfile == (FILE *)NULL) { X fprintf( stdout, "pcmail: cannot append to %s\n", icfilename ); X return( 0 ); X } X X#ifdef MSDOS X fprintf( mailfile, fpat2, cidfilename, rdfilename, X uucp, cidfilename, uucp ); X fputc( '\012', mailfile ); X fprintf( mailfile, fpat2, cixfilename, rxfilename, X uucp, cixfilename, uucp ); X fputc( '\012', mailfile ); X#else X fprintf( mailfile, fpat2, idfilename, rdfilename, X uucp, idfilename, uucp ); X fputc( '\012', mailfile ); X fprintf( mailfile, fpat2, ixfilename, rxfilename, X uucp, ixfilename, uucp ); X fputc( '\012', mailfile ); X#endif X fclose( mailfile ); X X } /* if ( remote == TRUE ) */ X X return( 1 ); X} X X/* X * Munge a "From " line. If there is a " remote from hostname" at the X * end of the line, prepend hostname to whatever comes after the "From " X * and get rid of " remote...". Otherwise leave the line alone. Since X * we will be doing only this munge, the resulting From line will never X * be longer than the original, so copying back into the original's X * buffer is okay. X */ Xmunge_from(buf) Xchar *buf; X{ X int rstart, plen; X char path[256], date[256], host[16]; X X if (sscanf(buf, "From %s ", path) != 1) X return; X X plen = strlen(path); X X for (rstart = plen+6; buf[rstart]; rstart++) X if (! strncmp(buf+rstart, " remote from ", 13)) X break; X X if (! buf[rstart]) X return; X X buf[rstart] = 0; X strcpy(date, buf+plen+6); X X strcpy(host, buf+rstart+13); X plen = strlen(host); X if (! plen) X return; X X if (host[plen-1] == '\n') X host[plen-1] = 0; X X sprintf(buf, "From %s!%s%s\n", host, path, date); X} X X X#ifndef AMIGA X#ifdef RMAIL Xrnews(argc, argv) Xint argc; Xchar *argv[]; X{ X struct tm *thetm; X char filename[132]; X char format[128]; X FILE *f; X char buf[BUFSIZ]; X X static int count = 0; X X tloc = time( (long *)NULL ); X thetime = ctime(&tloc); X tloc = time( (long *)NULL ); X X thetm = localtime( &tloc ); X X/* X * Construct a filename to spool news to temporarily. The filename looks X * like DDHHMMSS.CCC, where DD is the day of the month, HH is the hour, X * MM is the minute, SS is the second, and CCC is an increasing sequence X * counter. X */ X sprintf( filename, NEWSDIR, X thetm->tm_mday, X thetm->tm_hour, X thetm->tm_min, X thetm->tm_sec, X count X ); X X count++; X X if ( debuglevel > 5 ) X fprintf( stderr, "rnews: %s\n", filename ); X X if ( (f = FOPEN( filename, "w", 't' )) == (FILE *)NULL ) { X fprintf( stderr, "rnews: can't open %s %d\n", filename, errno ); X return( -1 ); X } X X while ( fgets( buf, BUFSIZ, stdin ) != (char *)NULL ) X fputs( buf, f ); X X fclose( f ); X} X X#endif /* RMAIL */ X#endif /* AMIGA */ X X SHAR_EOF chmod 0600 pcmail.c || echo "restore of pcmail.c fails" sed 's/^X//' << 'SHAR_EOF' > printmsg.c && X#include <stdio.h> X#include <strings.h> Xextern FILE *logfile; Xextern int debuglevel; Xextern int remote; X X#define MASTER 1 X X/* */ X/* X * p r i n t m s g X * X * Print error message on standard output if not remote. X */ X/*VARARGS1*/ Xprintmsg(level, fmt, a1, a2, a3, a4, a5) Xint level; Xchar *fmt; Xchar *a1, *a2, *a3, *a4, *a5; X{ X char msg[256]; X X if ( debuglevel > level ) { X sprintf( msg, fmt, a1, a2, a3, a4, a5 ); X strcat( msg, "\n" ); X if ( remote == MASTER ) X fputs( msg, stdout ); X fputs( msg, logfile ); X } X} X X SHAR_EOF chmod 0600 printmsg.c || echo "restore of printmsg.c fails" sed 's/^X//' << 'SHAR_EOF' > readme.1st && XUUPC/ST version 0.1 "release" notes X X X *** CAVEATS ** X X I'm releasing this very unfinished version of UUPC because I've Xgotten so many requests for it. I make no claims about the cleanliness Xor functionality of this code; it is by no means debugged and is very Xrough in a number of places. In particular: X X- The program only works in originate mode, not answer mode. This means X that your ST can poll other systems, but they can't poll you. X X- Newsfeeds are only minimally supported. The program will take non-batched, X non-compressed articles as input to the "rnews" program and put them in a X spool directory, by default \usr\spool\rnews, with filenames indicating X the date and time that the articles were received. No attempt is made to X sort articles by newsgroup. X X- The mail shell is primitive, to say the least. I have improved on the X functionality of the shell in the original uupc distribution, but it X still lacks many features. X X- Configuration requires modification of a number of source files, which X will be listed later, and knowledge of some UUCP file formats (L.sys). X X All of the above, and many more bugs and deficiencies, will be Xfixed in the (near?) future. I stress again that I'm releasing this Xsource code only because lots of people wanted to see it, not because I Xthink it's anywhere near ready to distribute. X X This code was developed with Laser C; it may or may not compile Xor work under other systems. X X I can't take credit for writing most of the code; read the other Xdocumentation files for its history. I downloaded UUPC from uunet and Xmodified it from there. X X X X *** CONFIGURATION *** X X Several files will have to be modified to configure the program Xfor your site. If you can't get it working, too bad. That sounds harsh, Xbut I have neither the time nor the inclination to answer 20 mail messages Xa day about code that isn't finished yet. More complete documentation will Xbe included with the final release of the code X XGENV.H Most of the items in this file should be self-explanatory; I X have included the defaults from my site. X XHOST.H The primary items of interest here are COPYFILE (which keeps a X copy of outgoing mail) and NEWSDIR, which is the directory to X stash news articles in. COPYFILE is relative to the home X directory specified in GENV.H. X XSYSTEMS This is UUPC's L.sys file; it lives in CONFDIR. I've included my X systems file, sans phone numbers and passwords (don't want to X upset my feeds!). Note that it differs somewhat from the standard X L.sys format; in particular, the "speed" field is the Hayes command X (without AT) to dial out to the target system. X X X I *think* those cover the configuration; the final release will Xautomate configuration, maybe with a GEM shell (but I'm not promising Xanything). I am also porting netnews 3.0 to the ST, so the final release Xwill have a completely functional news system. X This code should be modified to run cleanly under MT C-shell; Xit will hog CPU time like crazy as is. I plan to reorganize the code Xto make porting to other environments easier. X X If you have bug fixes or improvements, please mail them to me. XI'd also like bug reports from people who get the system to compile, but Xplease don't bother me with things like "it doesn't let you edit mail." XSuggestions for new features will have to wait until I'm done with the Xstuff *I* want to see -- I probably have 90% of the suggestions covered Xalready. Questions about how to set up the program are subject to Xdeletion without a reply; see the rationale above. Praise and offers Xof wealth and power will be gladly accepted, however. :] X The code really isn't as bad as I've tried to make it sound; it Xhas been working reliably for me for the past couple of weeks, and only Xcrashes if the host you're connected to does something really weird. X X X -Steven Grimm X Domain: koreth@ssyx.ucsc.edu X UUCP: ...!uunet!ucbvax!ucscc!ssyx!koreth X or (faster): X ...!uunet!ssyx.ucsc.edu!koreth X SHAR_EOF chmod 0600 readme.1st || echo "restore of readme.1st fails" sed 's/^X//' << 'SHAR_EOF' > readme.dcp && Xuupc/dcp June 8, 1987 Stuart Lynne X XFor Beta implementors only. X XThis is the very first release of my version of Richard H. Lambs uucp Xprogram dcp. X XSee README.UUPC for overview of how everything is stitched together. X XSummary of Changes: X X - eliminated references to all protocols except for the 3 window X g protocol X - streamlined dcp and condensed into four files X - moved host dependant stuff to one file uuXXX X - bug fixes to get 3w g protocol to send at full speed X X Xdcp.c - dcp pseudo main, high level stuff Xdcp.h - header file Xdcpxfer.c - file xfer Xdcpsys.c - connection stuff Xdcpgpkt.c - g packet protocol X X XFor more information, bug fixes, more commands etc: X X Stuart.Lynne@van-bc.uucp X 604-937-7532 X X XFixes X XJun 8/87 Added FOPEN and CREAT to recursively create directory X trees if they don't exist when a file is opened for writing X or appending X XJun 8/87 Found bug in getting file name in initial protocol sequence X Need to read more than one packet. X XJul/87 Added Hayes dialer to dcpsys SHAR_EOF chmod 0600 readme.dcp || echo "restore of readme.dcp fails" sed 's/^X//' << 'SHAR_EOF' > readme.inf && XAugust 9, 1987 uupc Questions and Answers uupc Development X X XThe following is some commonly asked questions about uupc and, of Xcourse, the answers to these questions. X X X 1. What does "uupc" stands for? X X It is an acronym for "UUcp for PC's", but it is also a pun on X uucp, which is in turn an acronym for "Unix to Unix CoPy". X X 2. What does uupc do? X X It gives a personal computer the capability to become a X "node" in the UUCP (or a similar) network and exchange X information such as electronic mail and USENET news with X other computers on that network. X X 3. What personal computers does uupc runs on? X X Currently it is available for the Apple Macintosh, Atari ST, X Commodore Amiga, and IBM PC (and compatibles) with DOS. More X computers and operating systems will be able run uupc in the X near future. (IBM PC with MINIX is a likely next candidate.) X X 4. Does uupc require me to leave my computer on all day to wait X for incoming mail? X X No. Most people only use uupc to call up their neighbouring X system to send and/or pickup mail at times convenient to X them. Outgoing mail are also spooled to disk and do not need X to be send immediately to your neighbouring system after it X is composed. X X However, uupc can also be set up on a personal computer to X wait for incoming call continuously and act as a "mail-hub" X to relay messages for other systems if you choose. X X 5. What do I need to have to get uupc up and running on one of X the above personal computers? X X You need a neighbouring system to communicate with. This X system can be either a UNIX system, another personal computer X running uupc, or any other system that can talk UUCP's 'g' X protocol. X X You would also need to have the appropriate C compiler for X your personal computer if you have received only the source X for uupc. X X 6. Is the source to uupc publicly available? X X Yes. It was posted to the USENET newsgroup comp.sources.misc X in August 1987 and is available from (at least) any site X which archives this newsgroup. If you have trouble locating X a copy of the uupc sources, please drop uupc Development a X note through one of the e-mail addresses listed at the end of X this file. X X 7. What does the uupc software consists of? X X It consists of two programs, uupc and pcmail. uupc is an automated X files transfer program, similar to /usr/lib/uucico in UUCP, X and mail is a mailer user-interface, like mail(1) in UNIX. X X 8. What are the typical use of these programs? X X uu is used to accept incoming file relayed to you through X your neighbouring machine and deliver outgoing file to your X neighbouring machine for forwarding to other machines. In X most cases these "files" contain electronic messages which X are to be used with the mail program. X X pcmail is used to read incoming mail delivered by uu, and X compose outgoing mail for delivery with uu. However, it can X also be used to transfer files to/from other systems that is X reachable through electronic mail. X X 9. What do I need to do to get uupc running on my personal X computer? X X You would need to obtain the binaries of uupc for your X computer by either compiling the uupc sources on your machine X or obtaining the uupc binaries from someone who has a copy. X X You would also need to arrange to have your neighbouring X system to recognize your system as one of their neighbouring X systems in the network. The procedures for this varies, you X should contact the people who manage your neighbouring system X for about details. X X10. Does uupc supports more than one neighbouring systems? X X Yes, it can support multiple neighbouring systems. The mail X software will currently always route outgoing mail through X one of these systems, but a future version of this software X will allow multiple forwarding machines for outgoing mail. X X11. Is uupc the same program on all systems it runs on, or is it X actually a different program for each of the systems? X X It is the same program across all systems, with the exception X of the system-dependent code, which is different from system X to system. X X The user-interface and command line options for uupc are also X uniform across all the systems it runs on, so there is no X need to learn a new program when you use uupc on a different X computer. The uniform user-interface also makes it easier to X use uupc on different computers at the same time. X X12. If I don't like the mail program's simple user-interface, are X there any alternatives? X X Since a mailbox can be easily converted to a simple text X file, alternative mailer can be easily written to accomodate X different needs. At the very least, you will be able to use X your favorite text-editor to read your incoming message and X compose your outgoing message. X X Future release of uupc will include mailers for the different X systems which will take advantage of special features only X availabe on the systems they run on (e.g. window and mouse). X X13. What if I want to port uupc to another personal computer not X presently support by uupc? X X First you should read the file UUPORT.INF, which should be X available from the same source you obtained this file from. X If you cannot locate a copy of this file, then please send a X request for it to uucp Development at one of the e-mail X addresses listed at the end of this file. X X After you have read the above file and decided that you still X want to do a port of uupc to a new machine/operating systems, X please drop uupc Development a note at one of the the e-mail X addresses listed at the end of this file. This way we will X at least be able to save each other from duplicated efforts. X Who knows? We might even have a version for ready for your X system when you call to tell us that you are about to begin X your port. X X14. Who/what is the "UUPC Development Team"? X X The original software (dcp) was done by Richard H. Lamb. X Modified to run on the Mac by Stuart Lynne. X Atari ST by Lawrence Harris. X Amiga by Jeff Lydiatt. X IBM PC by Samual Lam X VMS (not available yet) Lawrence Harris X X15. What is the copyright status and distribution policy of uupc? X X The dcp portions of uupc are Copyright (c) Richard H. Lamb. X Modifications Copyright (c) Stuart Lynne X Mail, PCMail Copyright (c) Stuart Lynne X Mac software Copyright (c) Stuart Lynne X Amiga software Copyright (c) Jeff Lydiatt X Atari software Copyright (c) Lawrence Harris X IBM software Copyright (c) Sam Lam X XIn general we are promoting the use of this software on a "public domain" Xbasis. You can use for your own use, and can give copies of the source Xcode to anyone, provided you provide this information to them. X X X16. If I have more questions, comments, or suggestions about X uupc, where should I send them? X X Please send them all to us at uupc Development at one of the X e-mail addresses listed below. We also welcome any bug fixes X and improved/new code for uupc that you might want to share. X X Xuupc Development can be reached at the following e-mail address: X X uupc@van-bc.UUCP X XThis is routed to the uupc mailing list and a local news group for Xdiscussion of uupc software. X XTo join the mailing list send a request to: X X uupc-request@van-bvc.uucp X X X X17. Can I get Binary Versions of uupc mailed to me. X XYes and no. X XNo we cannot email binaries to you at this time. X XYes, if you send a self addressed / stamped (international coupon) mailer Xwith appropriate diskettes (2) we will attempt to return them to you with Xthe appropriate version of the software. X XWe plan to make a binary posting to the appropriate Usenet comp.binary Xnewsgroups in the late fall, or early next year when the software is Xa bit more functional, better documented and easier to install and Xoperate without the source. X XMail your disks to: X X UUPC Request X C/O Stuart Lynne X 225B Evergreen Drive X Port Moody, BC, X Canada, V3H 1S1 X X X-- X{ihnp4!alberta!ubc-vision,uunet}!van-bc!Stuart.Lynne Vancouver,BC,604-937-7532 X SHAR_EOF chmod 0600 readme.inf || echo "restore of readme.inf fails" sed 's/^X//' << 'SHAR_EOF' > readme.por && Xuupc Porting Information August 3, 1987 uupc Development X X XThis writeup is aimed at programmers intending to port uupc to Xmachines and operating systems which it don't currently run on. XIf you only want to install uupc on a system where a uupc port Xexists, this writeup might also provide some insights to the Xinternal working of uupc and make the installation of uupc on Xyour machine a more interesting task. X XSince I did part of the IBM-PC/MS-DOS port for uupc, what I will Xdescribe here is actually closely related to the structure of Xthis particular port. (I also did part of the port of uupc's Xmailer to AIX (SVR1) on the RT-PC.) What is shown here is *by no Xmean* the only way things could be done, it's just some tips and Xhints that I can think of after doing one-and-a-half port of Xuupc. X XThe purpose of this writeup is to try to make the life of Xprogrammers doing uupc ports for other machines/operating systems Xeasier. However, the best sources of information on how new Xports should be done is still by reading the system-dependent Xcode of the existing uupc ports. (This is how I learnt how to do Xmy ports.) It would also be useful to have a listing of the Xsystem-dependent code of the IBM-PC/DOS port handy while reading Xthis writeup. X X XTo compile uupc, the C compiler and linker on your system must be Xable to differentiate between upper and lower cases in external Xnames. X XThe C run-time support on your system should use '\n' as line Xseparator for *text* files. If your system uses other sequences Xor methods to delimit text file lines, the C run-time support Xmust perform the appropriate translation functions for mapping in Xboth directions when a file is opened in text mode. X XIn order to port uupc to a new machine/operating system, you have Xto come up with a new version of six system-dependent files in Xthe the "local" directory. The names of these six files in the Xlocal directory are host.h, host.c, mlib.c, ulib.c, ndir.h and Xndir.c. X XNote that theses files could in turn #include other *.c and *.h Xfiles if you wish to separate the system-dependent code into more Xsmall files. The important thing here is that they must Xcollectively provide the same set of routines, global variables, Xand environment to the common code. X XWhat should be contained in these six files are describe below: X X Xhost.h - Host dependent file virtual #included everywhere else. X X Almost every file in both the common and host-dependent code X include this header file. So it should contains all the X #includes, #defines, and externs that everybody would need. X X Parts of the uupc common code assume Berkeley-style index() X and rindex(), so if your system supports only SysV-style X strchr() and strrchr(), they need to mapped using #define X here. X X Declarations for "library" routines in host.c, mlib.c and X ulib.c should also be make here to made them known to the rest X of the world. However, declaractions for the directory X scanning routines should be put into ndir.h instead. X X If your system requires that text file and binary fiies be X opened differently, you should map the name 'FILEMODE' into X 'filemode' with a #define here. Otherwise, 'FILEMODE' should X be mapped to the null string. X X Xhost.c - Generic main program and library routines for both parts. X X This file includes a generic main program that simply starts X up and call the procedure MAIN. More importantly, the X definition of all the library routines that are needed by both SHAR_EOF echo "End of part 3, continue with part 4" echo "4" > s2_seq_.tmp exit 0