File:  [MW Coherent from dump] / coherent / a / usr / bob / uusrc / dcp / dcp.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed May 29 04:56:34 2019 UTC (7 years ago) by root
Branches: MarkWilliams, MAIN
CVS tags: relic, HEAD
coherent

/*
 * dcp.c 
 *
 * revised edition of dcp -- "dcp" a uucp clone
 *
 * copyright (c) richard h. lamb 1985, 1986, 1987 
 * changes copyright (c) stuart lynne may/1987 
 * changes copyright (c) peter housel nov/1988
 * changes (massive) copyright (c) 1989-1991 by Mark Williams Company
 *
 * this program implements a uucico type file transfer and remote execution
 * type protocol. 
 *
 * Usage:  uucico [-xn] [-r0]		   slave mode
 * 	   uucico [-xn] [-r1] -{sS}host    call host
 * 	   uucico [-xn] [-r1] -{sS}all	   call all known hosts
 * 	   uucico [-xn] [-r1] -{c}all	   call all known hosts with queued files
 * 	   uucico [-xn] -r1		   call uutouch queued hosts
 */

#include <sys/types.h>
#include <time.h>
#include <signal.h>
#include "dcp.h"
#include "perm.h"
#include "alarm.h"

int	pktsize;		/* packet size for pro */
char	xfromfile[BUFSIZ];	/* source of copy */
char	xtofile[BUFSIZ];	/* destination of copy */
char	*clinep[10];		/* pointer to fields from line from C. file */
char	cline [BUFSIZ];		/* line from C. file			*/

char *fromfilep, *tofilep, *usernamep, *optionp, *spoolfilep, *modep, *notifyp;

int	nclinep;		/* number tokens in cline		*/
long	bytecount;		/* transfer byte count	*/

int	size;			/* nbytes in buff */
char proto[5];			/* list of protocols */
int	bad_count;
int	total_errors;
unsigned int checksum();

/*
 *  Global Variables
 */

int	checkfirst = 0;		/* check spooldir before calling	*/
int	abort_cico = 0;		/* Indicates Process Abort Signalled	*/
int	sysended = 0;		/* Indicates sysend() was called	*/
int	processid;		/* Current Process Id (uucico)		*/
int	fpfd = -1;		/* File Decriptor used for send&receive	*/
int	role = SLAVE;		/* Our role, either MASTER or SLAVE	*/
char	*sysname = NULL;	/* Command line -[sS]sysname argument	*/
char	*rmtname = NULL;	/* Remote System being processed now	*/
char	*logname = NULL;	/* In SLAVE mode, the login name	*/
int	forcecall = 0;		/* Ignore L.sys spec for time to call	*/
int	terminatelevel = 0;	/* Indicates return code for one call	*/
char	cfile[CTLFLEN];		/* Current C.* Control Work File Name	*/
FILE	*cfp = NULL;		/* FILE Pointer for C.* files		*/
char	*nodename;		/* UUCP node name (or MYNAME, perhaps)	*/
char	*version;		/* Version Character String		*/
int	stripflg = 0;		/* Flag to strip chars to 7bits on read */

/*
 *  Extern Function Declarations
 */

extern	int catchhup(), catchquit(), catchterm(), catchsegv();
extern	char *getenv();

/*
 *  Local Variables
 */

static char	state;			/* system state */

main(argc, argv)
int argc;
char *argv[];
{
	time_t now;
	static char buf[16];

	sprintf(buf, "%.14s%s", VERSION,
#if SGTTY
		"S");
#elif TERMIO
		"T");
#elif BBS
		"SB");
#endif
	version = &buf[0];

	while(--argc) {
		if (**++argv != '-')
			usage();
		switch(argv[0][1]) {
		case 'x':
			debuglevel = atoi(&argv[0][2]);  break;
		case 'c':
			checkfirst = 1;
			role = MASTER;
			sysname = &argv[0][2];
			break;
		case 'S':
			forcecall = 1;
		case 's':
			role = MASTER;
			sysname = &argv[0][2];  break;
		case 'r':
			role = atoi(&argv[0][2]);  break;
		case 'v':
		case 'V':
			fatal("uucico: Version %s", version);
		default:
			usage();  break;
		}
	}
	if ( ((role!=MASTER) && ((role!=SLAVE) || (sysname!=NULL))) ||
	     ((role==MASTER) && (sysname==NULL)) )
		usage();

	open_debug("uucico", role==SLAVE);
	if ( debuglevel && !lsys_access() ) {
		printmsg(M_LOG, "unauthorized debuglevel; reset to zero.");
		debuglevel = 0;
	}
	processid = getpid();
	timedout  = 0;
	INITALRM();
	signal(SIGINT,  SIG_IGN);
	signal(SIGHUP,  catchhup);
	signal(SIGQUIT, catchquit);
	signal(SIGTERM, catchterm);
	signal(SIGSEGV, catchsegv);

	if (role == MASTER) {
		time(&now);
		printmsg(M_CALL,
			"System Name \"%s\", debug=%d (%.24s) (V%s)",
			sysname, debuglevel, ctime(&now), version);
		lsys_open();
		state = 'I';
		while(!abort_cico) {
			printmsg(M_DEBUG, "Mstate = %c", state);
			switch(state) {
			case 'I':
				terminatelevel = 0;
				if ( (state=getsystem()) != 'S' )
					rmtname = NULL;
				break;
			case 'S':

		/* If our check first flag is NOT set, then we call regardless
		 * of if there files pending for transfer from this site.
		 * If our check flag is set, then we only call when a file is
		 * pending for transfer.
		*/
				if(checkfirst == 0){
					state = callup();
					break;
				}
				if((checkfirst != 0) && (scandir() == 'S')){
					state = callup();
				}
				else{
					state = 'Y';
					plog(M_CALL,"Attempting to call, checking for queued files.");
					plog(M_CALL,"No Files pending");
				}
				break;

			case 'P':
				perm_get(rmtname, NULL);
				nodename = myname();
				fixline();
				state = startup();
				break;
			case 'D':
				if ( (state=master()) != 'A' )
					break;
			case 'A':
				terminatelevel++;
			case 'Y':
				state = sysend();  break;
			}
			if (state == 'A')
				break;
		}
		lsys_close();
	} else {
		state = '0';
		while(!abort_cico) {
			printmsg(M_DEBUG, "Sstate = %c", state);
			switch(state) {
			case '0':
				state = initline() ? 'I': 'Y';
				break;
			case 'I':
				if ( (logname=getenv("USER")) == NULL )
					fatal("Can't getenv USER");
				time(&now);
				printmsg(M_CALL,
				    "Logname \"%s\", debug=%d (%.24s) (V%s)",
				     logname, debuglevel, ctime(&now), version);
				perm_get(NULL, logname);
				nodename = myname();
				state = startup();
				break;
			case 'R':
				if ( (state=slave()) != 'A' )
					break;
			case 'A':
				terminatelevel++;
			case 'Y':
				state = sysend();
				break;
			}
			if (state == 'A')
				break;
		}
	}
	if ( !sysended )
		sysend();
	exec_xqt();
	exit(0);
}

/*
 * master
 */
master()
{
	state = 'I';
	while(!abort_cico) {
		printmsg(M_CONVERSE, "Top level state (master mode) %c", state);
		switch(state) {
		case 'I':	state = sinit();			break;
		case 'B':	state = scandir();			break;
		case 'S':	state = sendf();			break;
		case 'Q':	state = sbreak();			break;
		case 'G':	state = recvf();			break;
		case 'C':	state = 'Y';				break;
		case 'Y':	state = endp();				break;
		case 'P':			return ('Y');
		case 'A':			return ('A');
		default:			return ('A');
		}
	}
	return('A');
}

/*
 * slave
 */
slave()
{
	state = 'I';
	while(!abort_cico) {
		printmsg(M_CONVERSE, "Top level state (slave mode) %c", state);
		switch(state) {
		case 'I':	state = rinit();			break;
		case 'F':	state = recvf();			break;
		case 'C':	state = schkdir();			break;
		case 'T':	state = 'B';				break;
		case 'B':	state = scandir();			break;
		case 'S':	state = sendf();			break;
		case 'Q':	state = sbreak();			break;
		case 'G':			return ('Y');
		case 'Y':	state = endp();				break;
		case 'P':			return ('Y');
		case 'A':			return ('A');
		default:			return ('A');
		}
	}
	return('A');
}

/*
 * r e c v f
 *
 * This is the state table switcher for receiving files. 
 */

recvf()
{
	state = 'F';			/* Receive-Init is the start state */
	while(!abort_cico) {
		printmsg(M_DEBUG, " recvf state: %c", state);
		switch(state) {	
		case 'F':	state = rmtcmd();	break;	/* Rcv File */
		case 'J':	state = rdata();	break;	/* Rcv Data */
		case 'D':	state = sdata();	break;
		case 'Z':	state = seof();		break;
		case 'C':		return ('C');	/* Complete state */
		case 'A':		return ('Y');	/* Abort state */
		default:		return ('Y');	/* Abort state */
		}
	}
	return('A');
}


/*
 * s e n d f
 *
 * Sendsw is the state table switcher for sending files. It loops until either
 * it finishes, or an error is encountered.  The routines called by sendsw
 * are responsible for changing the state. 
 * -
 * This routine is more properly called the command file reader.
 * It needs to dispatch to sfile and rfile based upon decoding of records in
 * the C.<> file.
 *
 */
sendf()
{
	fpfd = -1;			/* reset file getter/opener */
	state = 'F';			/* Send initiate is the start state */
	while(!abort_cico) {		/* Do this as long as necessary */
		printmsg(M_DEBUG, "sendf state: %c", state);
		switch(state) {
		case 'F':	state = cdotcmd();	break;	/* Send-File */
		case 'J':	state = rdata();	break;
		case 'D':	state = sdata();	break;	/* Send-Data */
		case 'Z':	state = seof();		break;	/* Send-EoF */
		case 'B':		return ('B');		/* Complete */
		case 'A':		return ('Y');		/* Abort */
		default:		return ('Y');	/* Unknown, fail */
		}
	}
	return('A');
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.