[comp.sources.atari.st] v01i067: uupc -- UUCP clone

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