File:  [MW Coherent from dump] / coherent / a / usr / bob / uusrc / src / uucp.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

/*
 *	The uucp command.
 *	Copyright Mark Williams Company Lake Bluff IL 1989.
 *	All rights reserved.
 */

#include <stdio.h>
#include <sys/stat.h>
#include <ctype.h>
#include <access.h>
#include <signal.h>
#include "dcp.h"

#define DEFGRADE	'a'

extern int getopt();
extern int optind;
extern char *optarg;
extern char *index(/* char *string, char c */);
extern char *rindex(/* char *string, char c */);
extern char *mktemp(/* char *template */);
extern FILE *fopen();
extern	char	*getwd();
char	*build_full_path();
char *uucpname(), *whoami();
char *filesite(/* char *filename */), *filepath(/* char *filename */);
char *myfilepath();
char *basename(/* char *filename */);
char	tempname[] =			"/usr/spool/uucp/TM.XXXXXX";
char	luser [32];			/* local user name */
char	notifyusr [32];			/* user to be notified */

char *rmtname = NULL;

static	char	spoolname [BUFSIZ];
static	char	fsname [BUFSIZ];	/* full spool pathname */
static	char	dirname [BUFSIZ];	/* full spool pathname */
static	char	fullfrompath [BUFSIZ];
static	char	fulltopath [BUFSIZ];
static	char	fromsite [32];
static	char	tosite [32];
static	char	options [32];
char	thissite[SITELEN];
char	cmd[64];			/* remote command name */
FILE	*commandfile;			/* the "C." spool command file */
char	commandsite [40];		/* site in command file name */
char	grade = DEFGRADE;		/* transfer grade */
char	spdir [40] = SPOOLDIR;		/* spool directory */

int	nocicoflg	= 0;		/* "don't run uucico" flag */
int	called_uux	= 0;
int	mkdirflg	= 1;
int	nocopyflg	= 1;
int	copyflg		= 0;
int	mailflg		= 0;
int	notifyflg	= 0;
int	debugflg	= 0;
int	debugdir	= 0;
char	*toptr, *fromptr;		/* pointers to from and to arguments */
char	*topath, *frompath;		/* file pathname part of source/dest */
char	topathbuf[BUFSIZ];
char	frompathbuf[BUFSIZ];
char	*tositeptr, *fromsiteptr;
char	argbuf[BUFSIZ];
char	argbuf1[BUFSIZ];
char	argbuf2[BUFSIZ];

int	sending, receiving;
struct	stat	statbuf;
int	seqno;

main(argc, argv)
int argc; 
char *argv[];
{
	int ch;
	int	argx;

	commandfile = NULL;
	strcpy(commandsite, "<?>");
	strcpy(thissite, uucpname());
	if (strlen(thissite) == 0) {
		fprintf(stderr, "uucp: can't get my own uucpname\n");
		exit(1);
	}
	strcpy(luser, whoami());
	strcpy(notifyusr, luser);
	if (debugflg > 0)
		fprintf(stderr, "I yam %s.\n", luser);
	while( (ch=getopt(argc, argv, "dfcCmrg:s:x:n:vV")) != EOF ) {
		switch(ch) {
		case 'r':
			nocicoflg = 1;
			break;
		case 's':
			debugdir = 1;
			fprintf(stderr, "-s option is %s.\n", optarg);
			strcpy(spdir, optarg);
			break;
		case 'x':
			debugflg = atoi(optarg);
			fprintf(stderr, "Debug level is %d\n", debugflg);
			fprintf(stderr, "uucp Version %s\n", VERSION);
			break;
		case 'g':
			if (isalnum(optarg[0]) && '\0' == optarg[1])
				grade = optarg[0];
			else {
				fprintf(stderr,
					"uucp: %s: illegal grade\n", optarg);
				usage();
			}
			break;
		case 'd':
			mkdirflg = 1;
			break;
		case 'f':
			mkdirflg = 0;
			break;
		case 'c':
			copyflg 	= 0;
			nocopyflg 	= 1;
			break;
		case 'C':
			copyflg 	= 1;
			nocopyflg 	= 0;
			break;
		case 'm':
			mailflg = 1;
			break;
		case 'n':
			notifyflg = 1;
			strcpy (notifyusr, optarg);
			if (debugflg > 5)
			fprintf(stderr, "notify user %s upon rcpt\n",notifyusr);
			break;
		case 'v':
		case 'V':
			fatal("uucp: Version %s", VERSION);
		default:
			fprintf(stderr, "uucp: Option character of %c\n", ch);
			usage();
		}
	}
	toptr = argv[argc - 1];
	if (debugflg > 4) {
		fprintf(stderr, "argc is now %d\n", argc);
		fprintf(stderr, "therefore, last argument is %s.\n", toptr);
	}
	if ((argc - optind) < 2)
		usage();
	if (optind >= argc)
		usage();
	for (argx = optind; argx < argc - 1; argx ++ )
		uucp(argv[argx], toptr);
	if (commandfile != NULL)
		finish_commandfile();
	if (nocicoflg || called_uux)
		return 0;
	else
		exec_cico(commandsite);
	exit(0);
}

uucp(fromptr, toptr)
char	*fromptr;
char	*toptr;
{
	if (debugflg > 1)
		fprintf(stderr, "uucp from %s to %s\n", fromptr, toptr);
	sending = 0;
	receiving = 0;
	topath = toptr;
	if ((tositeptr = filesite(toptr)) != NULL) {
		sending = 1;
		strcpy(topathbuf, filepath(toptr));
		topath = topathbuf;		
		if (!knowhost(tositeptr)) {
			fprintf(stderr,
			"uucp: destination site %s unknown\n", tositeptr);
			exit(1);
		}
	}
	strcpy(tosite, tositeptr);	tositeptr = tosite;
	frompath = fromptr;
	if ((fromsiteptr = filesite(fromptr)) != NULL) {
		receiving = 1;
		frompath = filepath(fromptr);
		if (!knowhost(fromsiteptr)) {
			fprintf(stderr,
			"uucp: from site %s unknown\n", fromsiteptr);
			exit(1);
		}
	}
	strcpy(fromsite, fromsiteptr);	fromsiteptr = fromsite;
	if (strlen(fromsite) == 0 && strlen(tosite) == 0) {
		if (debugflg > 1) {
			fprintf(stderr, "Need to issue a cp right here\n");
			fprintf(stderr, "cp %s %s\n", frompath, topath);
		}
		sprintf(argbuf, "cp %s %s", frompath, topath);
		system(argbuf);
		return;
	}
	strcpy(frompathbuf, frompath);
	if (debugflg > 1)
		fprintf(stderr,
		"We are copying from site %s file %s to site %s file %s.\n",
		fromsiteptr, frompathbuf, tositeptr, topath);
	if (sending && receiving) {
		if (strcmp (tosite, fromsite) == 0) {
			sprintf(topathbuf, "(%s)", filepath(toptr));
			strcpy(frompathbuf, fromptr);
			sprintf(frompathbuf, "(%s)", filepath(frompathbuf));
		} else {
			sprintf(topathbuf, "(%s!%s)", thissite, toptr);
			sprintf(frompathbuf, "(%s)", frompath);
		}
		return uuxit(fromsiteptr, frompathbuf, topathbuf);
	} else if (complex(toptr)) {
		sprintf(frompathbuf, "!%s", fromptr);
		sprintf(topathbuf, "(%s)", filepath(toptr)); /* strip off first */
		if (debugflg > 3) 
			fprintf(stderr, "complex to; %s, %s, %s\n",
				tositeptr, frompathbuf, topathbuf);
		return uuxit(tositeptr, frompathbuf, topathbuf);
	} else if (complex(fromptr)) {
		sprintf(topathbuf, "(%s!%s)", thissite, toptr);
		sprintf(frompathbuf, "(%s)", frompath);
		if (debugflg > 3)
			fprintf(stderr, "complex fromptr: %s, %s, %s\n",
			fromsiteptr, frompathbuf, topathbuf);
		return uuxit(fromsiteptr, frompathbuf, topathbuf);
	} else {
		if (sending)
			return send_file();
		if (receiving) {
			if (metacharacters(frompathbuf)) {
				sprintf(topathbuf, "(%s!%s)", thissite, toptr);
				return
				 uuxit(fromsiteptr, frompathbuf, topathbuf);
			} else
				return receive_file();
		}
	}
}

encode_options()
{
	strcpy(options, "-");
	if (mkdirflg)
		strcat (options, "d");
	if (nocopyflg)
		strcat(options, "c");
	if (copyflg)
		strcat(options, "C");
	if (notifyflg)
		strcat(options, "n");
	if (mailflg)
		strcat(options, "m");
}

/*
 *	send one file.
 *	Return 1 if queuing was successful,
 *	0 if any error.
 */
int
send_file()
{
	FILE	*sourcefp, *datafp;
	int	c;
	register int (*intfun)(), (*quitfun)();

	encode_options();
	strcpy(fullfrompath, build_full_path(frompath));
	if (stat(fullfrompath, &statbuf) == -1) {
		fprintf(stderr, "uucp: Cannot stat %s.\n", fullfrompath);
		return 0;
	}
	if (debugflg > 4)
		fprintf(stderr,
		"Send: frompath is %s, full is %s.\n", frompath, fullfrompath);
	if (getcommandfile(tositeptr))
		return 0;

	intfun = signal(SIGINT, SIG_IGN);
	quitfun = signal(SIGQUIT, SIG_IGN);
	seqno = getseq(tositeptr);
	if (nocopyflg)
		strcpy(spoolname, "D.0");
	else {
		sprintf(spoolname, "D.%s%c%04d", tositeptr, grade, seqno);
		if (debugflg > 3) {
			fprintf(stderr,	"data file built is %s\n", spoolname);
			fprintf(stderr,"mode: %o.\n",statbuf.st_mode & ~S_IFMT);
		}
	}
	fprintf(commandfile, "S %s %s %s %s %s %o %s\n",
		fullfrompath, topath, luser, options, spoolname,
		statbuf.st_mode & ~S_IFMT, notifyusr);
	if (nocopyflg == 0) {
		sprintf(dirname, "%s/%s", spdir, tositeptr);
		if (debugflg > 2) 
			fprintf(stderr, "Gotta copy\n");
		sprintf(fsname, "%s/%s/%s", spdir, tositeptr, spoolname);
		if ((!ckdir(dirname)) || (datafp = fopen(fsname, "w")) == NULL)
			return cantopen("datafile", fsname);
		if ((sourcefp = fopen(fullfrompath, "r")) == NULL) 
			return cantopen("fromfile", fullfrompath);
		chmod(fsname, 0600);
		while ((c = getc(sourcefp)) != EOF)
			putc(c, datafp);
		fclose(datafp);
		fclose(sourcefp);
	} else
		strcpy(fsname, fullfrompath);
	signal(SIGINT, intfun);
	signal(SIGQUIT, quitfun);
	return 1;
}

cantopen(kind, which)
char	*kind;
char	*which;
{
	fprintf(stderr, "uucp: Cannot open %s (%s)\n", which, kind);
	return 1;
}

/*
 *	receive_file
 *	Return 1 if queuing successful,
 *	0 if not.
 */
receive_file()
{
	if (debugflg > 2)
		fprintf(stderr, "Receive file\n");
	copyflg   = nocopyflg = notifyflg = 0;
	encode_options();
	strcpy(fulltopath, build_full_path(topath));
	if (getcommandfile(fromsiteptr))
		return 0;
	seqno = getseq(fromsiteptr);
	fprintf(commandfile, "R %s %s %s %s dummy\n",
		frompathbuf, fulltopath, luser, options);
	return 1;
}

/*
 *	Handle send and receive forms of command.
 *	Command of the form "uucp a!b c!d".
 *	Send it off via uux to do at another location.
 *	of the form "c!uucp b <mysite>!c!d".
 */
uuxit(cmdsite, from, to)
char	*cmdsite;
char	*from;
char	*to;
{
	int	argx;
	char	*argv[30];
	char	debugdirm[64];
	char	debugbuf[64];
	int	waitstat;

	if (debugflg > 2)
		fprintf(stderr, "uuxit(%s, %s, %s)\n",
		cmdsite, from, to);
	argx	= 0;
	argv[argx++] = "memeUUX";
	if (debugflg > 0) {
		sprintf(debugbuf, "-x%d", debugflg);
		argv[argx++] = debugbuf;
	}		
	/* if (nocicoflg) */	/* always turn off -r for intermediate site */
		argv [argx++] = "-r";
	if (debugdir) {
		sprintf(debugdirm, "-S%s", spdir);
		argv [argx++] = debugdirm;
	}
	sprintf(argbuf, "%s!uucp", cmdsite);
	argv[argx++] = argbuf;
	argv[argx++] = "-C";
	if (mkdirflg)
		argv[argx++] = "-d";
	if (notifyflg) {
		sprintf(argbuf1, "-n%s ", notifyusr);
		argv[argx++] = argbuf1;
	}
	argv[argx++] =  from;
	sprintf(argbuf2, "%s", to);
	argv[argx++] = argbuf2;
	argv[argx++] = NULL;
	if (debugflg > 3) {
		argx = 0;
		while (argv [argx] != NULL)
			fprintf(stderr, "%s ", argv[argx++]);
		fprintf(stderr, "\n");
	}
	if (fork() == 0 ) {
		execvp("uux", argv);
		exit(1);
	} else 
		wait (&waitstat);
	called_uux = 1;
	return waitstat;
}

getcommandfile(forwhich)
char	*forwhich;
{
	if (commandfile != NULL) {
		if (strcmp(forwhich, commandsite) != 0)
			finish_commandfile();
	}
	if (commandfile == NULL) {
		if ((commandfile = fopen(mktemp(tempname), "w")) == NULL) {
			fprintf(stderr, "uucp: can't open ");
			perror(tempname);
			return 1;
		}
		strcpy(commandsite, forwhich);
	}
	return 0;
}

finish_commandfile()
{
	static char buf[BUFSIZ];

	sprintf(buf, "%s/%s", spdir, commandsite);
	if (!ckdir(buf)) {
		fprintf(stderr, "Unable to make directory \"%s\"\n", buf);
		exit(1);
	}
	sprintf(buf, "%s/%s/C.%.6s%c%04d",
		 spdir, commandsite, commandsite, grade, seqno);
	if (debugflg > 1)
		fprintf(stderr, "command file name is %s.\n", buf);
	if (link(tempname, buf) == 0)
		unlink(tempname);
	else {
		fprintf(stderr, "uucp: couldn't rename commandfile\n");
		exit(1);
	}
	fclose (commandfile);
	commandfile = NULL;
}

char *filesite(name)
char *name;
{
	static char site[SITELEN];
	char *p;

	strcpy(site, name);
	if ((p = index(site, '!')) == NULL)
		return NULL;
	*p = '\0';
	return site;
}

char *filepath(name)
char *name;
{
	char *p;
	static char site[SITELEN];
	strcpy(site, name);
	p = index(site, '!');
	if (p == NULL) 
		return NULL;
	return p + 1;
}

char *basename(name)
char *name;
{
	char *p;
	if (NULL == (p = rindex(name, '/')))
		return name;
	else
		return p + 1;
}

char	*
build_full_path(localpath)
char	*localpath;
{
	static	char buf[BUFSIZ];
	char	*p;
	if ((*localpath != '/') && (*localpath != '~')) {
		strcpy(buf, p = getwd());
		if (p == NULL) {
			fprintf(stderr, "uucp: Unable to do getpwd\n");
			exit(1);
		}
		strcat(buf, "/");
		strcat(buf, localpath);
	} else
		strcpy(buf, localpath);
	return buf;
}

usage()
{
	fatal("\n\
Usage: uucp [-dcmr] [-g grade] [-s dir] [-xnum] <fn> <fn> ... \n\
");
}

/*
 *	Return 1 if there are shell type metacharacters in the argument.
 *	Zero otherwise.
 */
metacharacters(strin)
char	*strin;
{
	char	*first;

	if (index(strin, '*') != NULL)
		return 1;
	if (index(strin, '?') != NULL)
		return 1;
	if (((first = index(strin, '[')) != NULL) && (index(first, ']') != NULL))
		return 1;
	return 0;
}

complex(pathname)
char	*pathname;
{
	char	*cp;

	if ((cp = index(pathname, '!')) != NULL) {
		if (index (cp + 1, '!') != NULL)
			return 1;	/* more than one ! */
	}
	return 0;
}

unix.superglobalmegacorp.com

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