xref: /original-bsd/usr.bin/uucp/uux/uux.c (revision 4345ed8c)
12e47aecaSbostic /*-
2*4345ed8cSbostic  * Copyright (c) 1988, 1993
3*4345ed8cSbostic  *	The Regents of the University of California.  All rights reserved.
42e47aecaSbostic  *
52e47aecaSbostic  * %sccs.include.proprietary.c%
62e47aecaSbostic  */
72e47aecaSbostic 
8237dc26bSsam #ifndef lint
9*4345ed8cSbostic static char copyright[] =
10*4345ed8cSbostic "@(#) Copyright (c) 1988, 1993\n\
11*4345ed8cSbostic 	The Regents of the University of California.  All rights reserved.\n";
122e47aecaSbostic #endif /* not lint */
132e47aecaSbostic 
142e47aecaSbostic #ifndef lint
15*4345ed8cSbostic static char sccsid[] = "@(#)uux.c	8.1 (Berkeley) 06/06/93";
162e47aecaSbostic #endif /* not lint */
17237dc26bSsam 
18237dc26bSsam #include "uucp.h"
19ec043261Srick #include <sys/stat.h>
205678f928Srick #include <sysexits.h>
21237dc26bSsam 
22237dc26bSsam #define NOSYSPART 0
23237dc26bSsam #define HASSYSPART 1
24237dc26bSsam 
2554be4067Sbloom #define LQUOTE	'('
2654be4067Sbloom #define RQUOTE ')'
2754be4067Sbloom 
28237dc26bSsam #define APPCMD(d) {\
29598ee396Sbloom register char *p; for (p = d; *p != '\0';)\
30598ee396Sbloom 	{*cmdp++ = *p++;\
31598ee396Sbloom 		if(cmdp>(sizeof(cmd)+&cmd[0])){\
32598ee396Sbloom 			fprintf(stderr,"argument list too long\n");\
335678f928Srick 			cleanup(EX_SOFTWARE);\
34598ee396Sbloom 		}\
35598ee396Sbloom 	}\
36598ee396Sbloom 	*cmdp++ = ' '; *cmdp = '\0';}
37237dc26bSsam 
38237dc26bSsam #define GENSEND(f, a, b, c, d, e) {\
39138b24ebSralph 	fprintf(f, "S %s %s %s -%s %s 0666\n", a, b, c, d, e); }
40138b24ebSralph #define GENRCV(f, a, b, c) {fprintf(f, "R %s %s %s - \n", a, b, c);}
41237dc26bSsam 
4254be4067Sbloom struct timeb Now;
4354be4067Sbloom 
main(argc,argv)44237dc26bSsam main(argc, argv)
4559945304Srick int argc;
4659945304Srick char **argv;
47237dc26bSsam {
48237dc26bSsam 	char cfile[NAMESIZE];	/* send commands for files from here */
49237dc26bSsam 	char dfile[NAMESIZE];	/* used for all data files from here */
50237dc26bSsam 	char rxfile[NAMESIZE];	/* to be sent to xqt file (X. ...) */
51237dc26bSsam 	char tfile[NAMESIZE];	/* temporary file name */
52237dc26bSsam 	char tcfile[NAMESIZE];	/* temporary file name */
53237dc26bSsam 	char t2file[NAMESIZE];	/* temporary file name */
54237dc26bSsam 	int cflag = 0;		/*  commands in C. file flag  */
55237dc26bSsam 	int rflag = 0;		/*  C. files for receiving flag  */
56138b24ebSralph #ifdef DONTCOPY
57138b24ebSralph 	int Copy = 0;		/* Don't Copy spool files */
58138b24ebSralph #else !DONTCOPY
59237dc26bSsam 	int Copy = 1;		/* Copy spool files */
60138b24ebSralph #endif !DONTCOPY
61138b24ebSralph 	int Linkit = 0;		/* Try link before copy */
62598ee396Sbloom 	char buf[2*BUFSIZ];
63598ee396Sbloom 	char inargs[2*BUFSIZ];
64237dc26bSsam 	int pipein = 0;
65237dc26bSsam 	int startjob = 1;
66237dc26bSsam 	char Grade = 'A';
67ec043261Srick 	long Gradedelta = 100000000L;	/* "huge number" */
68ec043261Srick 	long size = 0L;
69237dc26bSsam 	char path[MAXFULLNAME];
70598ee396Sbloom 	char cmd[2*BUFSIZ];
71237dc26bSsam 	char *ap, *cmdp;
72598ee396Sbloom 	char prm[2*BUFSIZ];
73baec781eSbloom 	char syspart[MAXBASENAME+1], rest[MAXFULLNAME];
74baec781eSbloom 	char Xsys[MAXBASENAME+1], local[MAXBASENAME+1];
75dc4ef50dSralph 	char *xsys = Xsys;
76237dc26bSsam 	FILE *fprx, *fpc, *fpd, *fp;
77237dc26bSsam 	extern char *getprm(), *lastpart();
78237dc26bSsam 	extern FILE *ufopen();
7959945304Srick 	int uid, ret, c;
80237dc26bSsam 	char redir = '\0';
81237dc26bSsam 	int nonoti = 0;
82237dc26bSsam 	int nonzero = 0;
83138b24ebSralph 	int link_failed;
84138b24ebSralph 	char *ReturnTo = NULL;
85138b24ebSralph 	extern int LocalOnly;
8659945304Srick 	extern char *optarg;
8759945304Srick 	extern int optind;
88237dc26bSsam 
89237dc26bSsam 	strcpy(Progname, "uux");
90237dc26bSsam 	uucpname(Myname);
91237dc26bSsam 	umask(WFMASK);
92237dc26bSsam 	Ofn = 1;
93237dc26bSsam 	Ifn = 0;
94138b24ebSralph #ifdef	VMS
95138b24ebSralph 	arg_fix(argc, argv);
96138b24ebSralph #endif
9705805a94Sbostic 	while (((c = getopt(argc, argv, "-prclCg:x:nzLa:")) != EOF) ||
9805805a94Sbostic 	    (optind < argc && (c = *argv[optind]) == '-' && ++optind))
9959945304Srick 		switch (c) {
1006fe915a8Sbostic 		case '-':
1016fe915a8Sbostic 			/* FALLTHROUGH */
102237dc26bSsam 		case 'p':
103237dc26bSsam 			pipein = 1;
104237dc26bSsam 			break;
105237dc26bSsam 		case 'r':
106237dc26bSsam 			startjob = 0;
107237dc26bSsam 			break;
108237dc26bSsam 		case 'c':
109138b24ebSralph 			Copy = 0;
110138b24ebSralph 			Linkit = 0;
111138b24ebSralph 			break;
112237dc26bSsam 		case 'l':
113237dc26bSsam 			Copy = 0;
114138b24ebSralph 			Linkit = 1;
115138b24ebSralph 			break;
116138b24ebSralph 		case 'C':
117138b24ebSralph 			Copy = 1;
118138b24ebSralph 			Linkit = 0;
119237dc26bSsam 			break;
120237dc26bSsam 		case 'g':
12159945304Srick 			Grade = *optarg;
12259945304Srick 			Gradedelta = atol(optarg+1);
123237dc26bSsam 			break;
124237dc26bSsam 		case 'x':
125138b24ebSralph 			chkdebug();
12659945304Srick 			Debug = atoi(optarg);
127237dc26bSsam 			if (Debug <= 0)
128237dc26bSsam 				Debug = 1;
129237dc26bSsam 			break;
130237dc26bSsam 		case 'n':
131237dc26bSsam 			nonoti = 1;
132237dc26bSsam 			break;
133237dc26bSsam 		case 'z':
134237dc26bSsam 			nonzero = 1;
135237dc26bSsam 			break;
136138b24ebSralph 		case 'L':
137138b24ebSralph 			LocalOnly++;
138138b24ebSralph 			break;
139138b24ebSralph 		case 'a':
14059945304Srick 			ReturnTo = optarg;
141baec781eSbloom 			if (prefix(Myname, ReturnTo) && ReturnTo[strlen(Myname)]				== '!')
142baec781eSbloom 				ReturnTo = index(ReturnTo, '!') + 1;
143138b24ebSralph 			break;
14459945304Srick 		case '?':
145237dc26bSsam 		default:
146237dc26bSsam 			break;
147237dc26bSsam 		}
14859945304Srick 
149baec781eSbloom 	ap = getwd(Wrkdir);
150baec781eSbloom 	if (ap == 0) {
151138b24ebSralph 		fprintf(stderr, "can't get working directory; will try to continue\n");
152138b24ebSralph 		strcpy(Wrkdir, "/UNKNOWN");
153138b24ebSralph 	}
154237dc26bSsam 
155237dc26bSsam 	DEBUG(4, "\n\n** %s **\n", "START");
156237dc26bSsam 
157237dc26bSsam 	inargs[0] = '\0';
15859945304Srick 	while (optind < argc) {
15959945304Srick 		DEBUG(4, "arg - %s:", argv[optind]);
160237dc26bSsam 		strcat(inargs, " ");
16159945304Srick 		strcat(inargs, argv[optind++]);
162237dc26bSsam 	}
163237dc26bSsam 	DEBUG(4, "arg - %s\n", inargs);
16459945304Srick 	if (subchdir(Spool) < 0) {
16559945304Srick 		syslog(LOG_WARNING, "chdir(%s) failed: %m", Spool);
16659945304Srick 		cleanup(1);
16759945304Srick 	}
168237dc26bSsam 	uid = getuid();
169ec043261Srick 	if (guinfo(uid, User, path) != SUCCESS) {
17059945304Srick 		syslog(LOG_WARNING, "Can't find username for uid %d", uid);
171ec043261Srick 		DEBUG(1, "Using username", "uucp");
172ec043261Srick 		strcpy(User, "uucp");
173ec043261Srick 	}
174237dc26bSsam 
175baec781eSbloom 	strncpy(local, Myname, MAXBASENAME);
176237dc26bSsam 	cmdp = cmd;
177237dc26bSsam 	*cmdp = '\0';
178237dc26bSsam 	gename(DATAPRE, local, 'X', rxfile);
179237dc26bSsam 	fprx = ufopen(rxfile, "w");
18059945304Srick 	if (fprx == NULL) {
18159945304Srick 		syslog(LOG_WARNING, "fopen(%s) failed: %m", rxfile);
18259945304Srick 		cleanup(1);
18359945304Srick 	}
184237dc26bSsam 	gename(DATAPRE, local, 'T', tcfile);
185237dc26bSsam 	fpc = ufopen(tcfile, "w");
18659945304Srick 	if (fpc == NULL) {
18759945304Srick 		syslog(LOG_WARNING, "fopen(%s) failed: %m", tcfile);
18859945304Srick 		cleanup(1);
18959945304Srick 	}
190237dc26bSsam 	fprintf(fprx, "%c %s %s\n", X_USER, User, local);
191237dc26bSsam 	if (nonoti)
192237dc26bSsam 		fprintf(fprx, "%c\n", X_NONOTI);
193237dc26bSsam 	if (nonzero)
194237dc26bSsam 		fprintf(fprx, "%c\n", X_NONZERO);
195138b24ebSralph 	if (ReturnTo == NULL || *ReturnTo == '\0')
196138b24ebSralph 		ReturnTo = User;
197138b24ebSralph 	fprintf(fprx, "%c %s\n", X_RETURNTO, ReturnTo);
198237dc26bSsam 
199237dc26bSsam 	/* find remote system name */
200237dc26bSsam 	ap = inargs;
201237dc26bSsam 	xsys[0] = '\0';
202237dc26bSsam 	while ((ap = getprm(ap, prm)) != NULL) {
203237dc26bSsam 		if (prm[0] == '>' || prm[0] == '<') {
204237dc26bSsam 			ap = getprm(ap, prm);
205237dc26bSsam 			continue;
206237dc26bSsam 		}
207237dc26bSsam 
208237dc26bSsam 		split(prm, xsys, rest);
209237dc26bSsam 		break;
210237dc26bSsam 	}
211237dc26bSsam 	if (xsys[0] == '\0')
212237dc26bSsam 		strcpy(xsys, local);
213dc4ef50dSralph 	if (versys(&xsys) != 0) {
214237dc26bSsam 		/*  bad system name  */
215237dc26bSsam 		fprintf(stderr, "bad system name: %s\n", xsys);
216237dc26bSsam 		fclose(fprx);
217237dc26bSsam 		fclose(fpc);
2185678f928Srick 		cleanup(EX_NOHOST);
219237dc26bSsam 	}
220237dc26bSsam 
22154be4067Sbloom 	strncpy(Rmtname, xsys, MAXBASENAME);
22254be4067Sbloom 	DEBUG(4, "xsys %s\n", xsys);
22354be4067Sbloom 
224237dc26bSsam 	if (pipein) {
225237dc26bSsam 		gename(DATAPRE, local, 'B', dfile);
226237dc26bSsam 		fpd = ufopen(dfile, "w");
22759945304Srick 		if (fpd == NULL) {
22859945304Srick 			syslog(LOG_WARNING, "fopen(%s) failed: %m", dfile);
22959945304Srick 			cleanup(1);
23059945304Srick 		}
231237dc26bSsam 		while (!feof(stdin)) {
232237dc26bSsam 			ret = fread(buf, 1, BUFSIZ, stdin);
233237dc26bSsam 			fwrite(buf, 1, ret, fpd);
234598ee396Sbloom 			if (ferror(stdin)) {
235598ee396Sbloom 				perror("stdin");
2365678f928Srick 				cleanup(EX_IOERR);
237598ee396Sbloom 			}
238598ee396Sbloom 			if (ferror(fpd)) {
239598ee396Sbloom 				perror(dfile);
2405678f928Srick 				cleanup(EX_IOERR);
241598ee396Sbloom 			}
242ec043261Srick 			size += ret;
243237dc26bSsam 		}
244237dc26bSsam 		fclose(fpd);
245138b24ebSralph 		strcpy(tfile, dfile);
246237dc26bSsam 		if (strcmp(local, xsys) != SAME) {
24754be4067Sbloom 			register int Len = strlen(local);
24854be4067Sbloom 			if (Len > SYSNSIZE)
24954be4067Sbloom 				Len = SYSNSIZE;
25054be4067Sbloom 			tfile[Len + 2] = 'S';
251138b24ebSralph 			GENSEND(fpc, dfile, tfile, User, "", dfile);
252237dc26bSsam 			cflag++;
253237dc26bSsam 		}
254138b24ebSralph 		fprintf(fprx, "%c %s\n", X_RQDFILE, tfile);
255138b24ebSralph 		fprintf(fprx, "%c %s\n", X_STDIN, tfile);
256237dc26bSsam 	}
257237dc26bSsam 	/* parse command */
258237dc26bSsam 	ap = inargs;
259237dc26bSsam 	while ((ap = getprm(ap, prm)) != NULL) {
260237dc26bSsam 		DEBUG(4, "prm - %s\n", prm);
261237dc26bSsam 		if (prm[0] == '>' || prm[0] == '<') {
262237dc26bSsam 			redir = prm[0];
263237dc26bSsam 			continue;
264237dc26bSsam 		}
265237dc26bSsam 
266237dc26bSsam 		if (prm[0] == ';') {
267237dc26bSsam 			APPCMD(prm);
268237dc26bSsam 			continue;
269237dc26bSsam 		}
270237dc26bSsam 
271237dc26bSsam 		if (prm[0] == '|' || prm[0] == '^') {
272237dc26bSsam 			if (cmdp != cmd)
273237dc26bSsam 				APPCMD(prm);
274237dc26bSsam 			continue;
275237dc26bSsam 		}
276237dc26bSsam 
277237dc26bSsam 		/* process command or file or option */
278237dc26bSsam 		ret = split(prm, syspart, rest);
279237dc26bSsam 		DEBUG(4, "s - %s, ", syspart);
280237dc26bSsam 		DEBUG(4, "r - %s, ", rest);
281237dc26bSsam 		DEBUG(4, "ret - %d\n", ret);
282237dc26bSsam 		if (syspart[0] == '\0')
283237dc26bSsam 			strcpy(syspart, local);
284237dc26bSsam 
285237dc26bSsam 		if (cmdp == cmd && redir == '\0') {
286237dc26bSsam 			/* command */
287237dc26bSsam 			APPCMD(rest);
288237dc26bSsam 			continue;
289237dc26bSsam 		}
290237dc26bSsam 
291237dc26bSsam 		/* process file or option */
292237dc26bSsam 		DEBUG(4, "file s- %s, ", syspart);
293237dc26bSsam 		DEBUG(4, "local - %s\n", local);
294237dc26bSsam 		/* process file */
295237dc26bSsam 		if (redir == '>') {
296237dc26bSsam 			if (rest[0] != '~')
297237dc26bSsam 				if (ckexpf(rest))
2985678f928Srick 					cleanup(EX_CANTCREAT);
299237dc26bSsam 			fprintf(fprx, "%c %s %s\n", X_STDOUT, rest,
300237dc26bSsam 			 syspart);
301237dc26bSsam 			redir = '\0';
302237dc26bSsam 			continue;
303237dc26bSsam 		}
304237dc26bSsam 
305237dc26bSsam 		if (ret == NOSYSPART && redir == '\0') {
306237dc26bSsam 			/* option */
307237dc26bSsam 			APPCMD(rest);
308237dc26bSsam 			continue;
309237dc26bSsam 		}
310237dc26bSsam 
311ec043261Srick 		if (rest[0] != '\0') {
312ec043261Srick 			struct stat stbuf;
313ec043261Srick 			if (stat(rest, &stbuf) < 0)
314ec043261Srick 				DEBUG(4, "Can't stat %s\n", rest);
315ec043261Srick 			else
316ec043261Srick 				size += stbuf.st_size;
317ec043261Srick 			DEBUG(4, "size = %ld\n", size);
318ec043261Srick 		}
319ec043261Srick 
320237dc26bSsam 		if (strcmp(xsys, local) == SAME
321237dc26bSsam 		 && strcmp(xsys, syspart) == SAME) {
322237dc26bSsam 			if (ckexpf(rest))
3235678f928Srick 				cleanup(EX_CANTCREAT);
324237dc26bSsam 			if (redir == '<')
325237dc26bSsam 				fprintf(fprx, "%c %s\n", X_STDIN, rest);
326237dc26bSsam 			else
327237dc26bSsam 				APPCMD(rest);
328237dc26bSsam 			redir = '\0';
329237dc26bSsam 			continue;
330237dc26bSsam 		}
331237dc26bSsam 
332237dc26bSsam 		if (strcmp(syspart, local) == SAME) {
333237dc26bSsam 			/*  generate send file */
334237dc26bSsam 			if (ckexpf(rest))
3355678f928Srick 				cleanup(EX_CANTCREAT);
336237dc26bSsam 			gename(DATAPRE, local, 'A', dfile);
337237dc26bSsam 			DEBUG(4, "rest %s\n", rest);
338237dc26bSsam 			if ((chkpth(User, "", rest) || anyread(rest)) != 0) {
339237dc26bSsam 				fprintf(stderr, "permission denied %s\n", rest);
3405678f928Srick 				cleanup(EX_NOINPUT);
341237dc26bSsam 			}
342138b24ebSralph 			link_failed = 0;
343138b24ebSralph 			if (Linkit) {
344138b24ebSralph 				if (link(subfile(rest), subfile(dfile)) != 0)
345138b24ebSralph 					link_failed++;
346138b24ebSralph 				else
347138b24ebSralph 					GENSEND(fpc, rest, dfile, User, "", dfile);
348138b24ebSralph 			}
349138b24ebSralph 			if (Copy || link_failed) {
350237dc26bSsam 				if (xcp(rest, dfile) != 0) {
351237dc26bSsam 					fprintf(stderr, "can't copy %s to %s\n", rest, dfile);
3525678f928Srick 					cleanup(EX_NOINPUT);
353237dc26bSsam 				}
354237dc26bSsam 				GENSEND(fpc, rest, dfile, User, "", dfile);
355237dc26bSsam 			}
356138b24ebSralph 			if (!Copy && !Linkit) {
357237dc26bSsam 				GENSEND(fpc, rest, dfile, User, "c", "D.0");
358237dc26bSsam 			}
359237dc26bSsam 			cflag++;
360237dc26bSsam 			if (redir == '<') {
361237dc26bSsam 				fprintf(fprx, "%c %s\n", X_STDIN, dfile);
362237dc26bSsam 				fprintf(fprx, "%c %s\n", X_RQDFILE, dfile);
363dc4ef50dSralph 			} else {
364237dc26bSsam 				APPCMD(lastpart(rest));
365237dc26bSsam 				fprintf(fprx, "%c %s %s\n", X_RQDFILE,
366237dc26bSsam 				 dfile, lastpart(rest));
367237dc26bSsam 			}
368237dc26bSsam 			redir = '\0';
369237dc26bSsam 			continue;
370237dc26bSsam 		}
371237dc26bSsam 
372237dc26bSsam 		if (strcmp(local, xsys) == SAME) {
373237dc26bSsam 			/*  generate local receive  */
374237dc26bSsam 			gename(CMDPRE, syspart, 'R', tfile);
375237dc26bSsam 			strcpy(dfile, tfile);
376237dc26bSsam 			dfile[0] = DATAPRE;
377237dc26bSsam 			fp = ufopen(tfile, "w");
37859945304Srick 			if (fp == NULL) {
37959945304Srick 				syslog(LOG_WARNING, "fopen(%s) failed: %m",
38059945304Srick 					tfile);
38159945304Srick 				cleanup(1);
38259945304Srick 			}
383237dc26bSsam 			if (ckexpf(rest))
3845678f928Srick 				cleanup(EX_CANTCREAT);
385237dc26bSsam 			GENRCV(fp, rest, dfile, User);
386237dc26bSsam 			fclose(fp);
387237dc26bSsam 			rflag++;
388237dc26bSsam 			if (rest[0] != '~')
389237dc26bSsam 				if (ckexpf(rest))
3905678f928Srick 					cleanup(EX_CANTCREAT);
391237dc26bSsam 			if (redir == '<') {
392237dc26bSsam 				fprintf(fprx, "%c %s\n", X_RQDFILE, dfile);
393237dc26bSsam 				fprintf(fprx, "%c %s\n", X_STDIN, dfile);
394dc4ef50dSralph 			} else {
395237dc26bSsam 				fprintf(fprx, "%c %s %s\n", X_RQDFILE, dfile,
396237dc26bSsam 				  lastpart(rest));
397237dc26bSsam 				APPCMD(lastpart(rest));
398237dc26bSsam 			}
399237dc26bSsam 
400237dc26bSsam 			redir = '\0';
401237dc26bSsam 			continue;
402237dc26bSsam 		}
403237dc26bSsam 
404237dc26bSsam 		if (strcmp(syspart, xsys) != SAME) {
405237dc26bSsam 			/* generate remote receives */
406237dc26bSsam 			gename(DATAPRE, syspart, 'R', dfile);
407237dc26bSsam 			strcpy(tfile, dfile);
408237dc26bSsam 			tfile[0] = CMDPRE;
409237dc26bSsam 			fpd = ufopen(dfile, "w");
41059945304Srick 			if (fpd == NULL) {
41159945304Srick 				syslog(LOG_WARNING, "fopen(%s) failed: %m",
41259945304Srick 					dfile);
41359945304Srick 				cleanup(1);
41459945304Srick 			}
415237dc26bSsam 			gename(DATAPRE, local, 'T', t2file);
416237dc26bSsam 			GENRCV(fpd, rest, t2file, User);
417237dc26bSsam 			fclose(fpd);
418237dc26bSsam 			GENSEND(fpc, dfile, tfile, User, "", dfile);
419237dc26bSsam 			cflag++;
420237dc26bSsam 			if (redir == '<') {
421237dc26bSsam 				fprintf(fprx, "%c %s\n", X_RQDFILE, t2file);
422237dc26bSsam 				fprintf(fprx, "%c %s\n", X_STDIN, t2file);
423dc4ef50dSralph 			} else {
424237dc26bSsam 				fprintf(fprx, "%c %s %s\n", X_RQDFILE, t2file,
425237dc26bSsam 				  lastpart(rest));
426237dc26bSsam 				APPCMD(lastpart(rest));
427237dc26bSsam 			}
428237dc26bSsam 			redir = '\0';
429237dc26bSsam 			continue;
430237dc26bSsam 		}
431237dc26bSsam 
432237dc26bSsam 		/* file on remote system */
433237dc26bSsam 		if (rest[0] != '~')
434237dc26bSsam 			if (ckexpf(rest))
4355678f928Srick 				cleanup(EX_CANTCREAT);
436237dc26bSsam 		if (redir == '<')
437237dc26bSsam 			fprintf(fprx, "%c %s\n", X_STDIN, rest);
438237dc26bSsam 		else
439237dc26bSsam 			APPCMD(rest);
440237dc26bSsam 		redir = '\0';
441237dc26bSsam 		continue;
442237dc26bSsam 
443237dc26bSsam 	}
444138b24ebSralph 	/*
445138b24ebSralph 	 * clean up trailing ' ' in command.
446138b24ebSralph 	 */
447138b24ebSralph 	if (cmdp > cmd && cmdp[0] == '\0' && cmdp[-1] == ' ')
448138b24ebSralph 		*--cmdp = '\0';
449138b24ebSralph 	/* block multi-hop uux, which doesn't work */
450138b24ebSralph 	for (ap = cmd; *ap && *ap != ' '; ap++)
451138b24ebSralph 		if (*ap == '!') {
452138b24ebSralph 			fprintf(stderr, "uux handles only adjacent sites.\n");
453138b24ebSralph 			fprintf(stderr, "Try uusend for multi-hop delivery.\n");
4545678f928Srick 			cleanup(EX_USAGE);
455138b24ebSralph 		}
456237dc26bSsam 
457237dc26bSsam 	fprintf(fprx, "%c %s\n", X_CMD, cmd);
458598ee396Sbloom 	if (ferror(fprx)) {
459598ee396Sbloom 		logent(cmd, "COULD NOT QUEUE XQT");
4605678f928Srick 		cleanup(EX_IOERR);
461598ee396Sbloom 	} else
462237dc26bSsam 		logent(cmd, "XQT QUE'D");
463237dc26bSsam 	fclose(fprx);
464237dc26bSsam 
465ec043261Srick 	if (size > 0 && Gradedelta > 0) {
466ec043261Srick 		DEBUG (4, "Grade changed from %c ", Grade);
467ec043261Srick 		Grade += size/Gradedelta;
468ec043261Srick 		if (Grade > 'z')
469ec043261Srick 			Grade = 'z';
470ec043261Srick 		DEBUG(4, "to %c\n", Grade);
471ec043261Srick 	}
472138b24ebSralph 	gename(XQTPRE, local, Grade, tfile);
473237dc26bSsam 	if (strcmp(xsys, local) == SAME) {
474237dc26bSsam 		/* rti!trt: xmv() works across filesystems, link(II) doesnt */
475237dc26bSsam 		xmv(rxfile, tfile);
476237dc26bSsam 		if (startjob)
477237dc26bSsam 			if (rflag)
478237dc26bSsam 				xuucico(xsys);
479237dc26bSsam 			else
480237dc26bSsam 				xuuxqt();
481237dc26bSsam 	}
482237dc26bSsam 	else {
483237dc26bSsam 		GENSEND(fpc, rxfile, tfile, User, "", rxfile);
484237dc26bSsam 		cflag++;
485237dc26bSsam 	}
486237dc26bSsam 
487598ee396Sbloom 	if (ferror(fpc))
4885678f928Srick 		cleanup(EX_IOERR);
489237dc26bSsam 	fclose(fpc);
490237dc26bSsam 	if (cflag) {
491237dc26bSsam 		gename(CMDPRE, xsys, Grade, cfile);
492237dc26bSsam 		/* rti!trt: use xmv() rather than link(II) */
493237dc26bSsam 		xmv(tcfile, cfile);
494237dc26bSsam 		if (startjob)
495237dc26bSsam 			xuucico(xsys);
496237dc26bSsam 		cleanup(0);
497237dc26bSsam 	}
498237dc26bSsam 	else
499237dc26bSsam 		unlink(subfile(tcfile));
500dc4ef50dSralph 	exit(0);
501237dc26bSsam }
502237dc26bSsam 
503237dc26bSsam #define FTABSIZE 30
504237dc26bSsam char Fname[FTABSIZE][NAMESIZE];
505237dc26bSsam int Fnamect = 0;
506237dc26bSsam 
507138b24ebSralph /*
508138b24ebSralph  *	cleanup and unlink if error
509237dc26bSsam  *
510237dc26bSsam  *	return - none - do exit()
511237dc26bSsam  */
512237dc26bSsam 
cleanup(code)513237dc26bSsam cleanup(code)
514237dc26bSsam int code;
515237dc26bSsam {
516237dc26bSsam 	int i;
517237dc26bSsam 
518237dc26bSsam 	logcls();
519237dc26bSsam 	rmlock(CNULL);
520237dc26bSsam 	if (code) {
521237dc26bSsam 		for (i = 0; i < Fnamect; i++)
522237dc26bSsam 			unlink(subfile(Fname[i]));
523237dc26bSsam 		fprintf(stderr, "uux failed. code %d\n", code);
524237dc26bSsam 	}
525237dc26bSsam 	DEBUG(1, "exit code %d\n", code);
526237dc26bSsam 	exit(code);
527237dc26bSsam }
528237dc26bSsam 
529138b24ebSralph /*
530138b24ebSralph  *	open file and record name
531237dc26bSsam  *
532237dc26bSsam  *	return file pointer.
533237dc26bSsam  */
534237dc26bSsam 
ufopen(file,mode)535237dc26bSsam FILE *ufopen(file, mode)
536237dc26bSsam char *file, *mode;
537237dc26bSsam {
538237dc26bSsam 	if (Fnamect < FTABSIZE)
539237dc26bSsam 		strcpy(Fname[Fnamect++], file);
540237dc26bSsam 	else
541237dc26bSsam 		logent("Fname", "TABLE OVERFLOW");
542138b24ebSralph 	return fopen(subfile(file), mode);
543237dc26bSsam }
544138b24ebSralph #ifdef	VMS
545138b24ebSralph /*
546138b24ebSralph  * EUNICE bug:
547138b24ebSralph  *	quotes are not stripped from DCL.  Do it here.
548138b24ebSralph  *	Note if we are running under Unix shell we don't
549138b24ebSralph  *	do the right thing.
550138b24ebSralph  */
arg_fix(argc,argv)551138b24ebSralph arg_fix(argc, argv)
552138b24ebSralph char **argv;
553138b24ebSralph {
554138b24ebSralph 	register char *cp, *tp;
555138b24ebSralph 
556138b24ebSralph 	for (; argc > 0; --argc, argv++) {
557138b24ebSralph 		cp = *argv;
558138b24ebSralph 		if (cp == (char *)0 || *cp++ != '"')
559138b24ebSralph 			continue;
560138b24ebSralph 		tp = cp;
561138b24ebSralph 		while (*tp++) ;
562138b24ebSralph 		tp -= 2;
563138b24ebSralph 		if (*tp == '"') {
564138b24ebSralph 			*tp = '\0';
565138b24ebSralph 			*argv = cp;
566138b24ebSralph 		}
567138b24ebSralph 	}
568138b24ebSralph }
569138b24ebSralph #endif VMS
57054be4067Sbloom 
57154be4067Sbloom /*
57254be4067Sbloom  *	split into system and file part
57354be4067Sbloom  *
57454be4067Sbloom  *	return codes:
57554be4067Sbloom  *		NOSYSPART
57654be4067Sbloom  *		HASSYSPART
57754be4067Sbloom  */
57854be4067Sbloom 
split(name,sys,rest)57954be4067Sbloom split(name, sys, rest)
58054be4067Sbloom register char *name, *rest;
58154be4067Sbloom char *sys;
58254be4067Sbloom {
58354be4067Sbloom 	register char *c;
58454be4067Sbloom 
58554be4067Sbloom 	if (*name == LQUOTE) {
58654be4067Sbloom 		if ((c = index(name + 1, RQUOTE)) != NULL) {
58754be4067Sbloom 		/* strip off quotes */
58854be4067Sbloom 			name++;
58954be4067Sbloom 			while (c != name)
59054be4067Sbloom 				*rest++ = *name++;
59154be4067Sbloom 			*rest = '\0';
59254be4067Sbloom 			*sys = '\0';
59354be4067Sbloom 			return NOSYSPART;
59454be4067Sbloom 		}
59554be4067Sbloom 	}
59654be4067Sbloom 
59754be4067Sbloom 	if ((c = index(name, '!')) == NULL) {
59854be4067Sbloom 		strcpy(rest, name);
59954be4067Sbloom 		*sys = '\0';
60054be4067Sbloom 		return NOSYSPART;
60154be4067Sbloom 	}
60254be4067Sbloom 
60354be4067Sbloom 	*c++ = '\0';
60454be4067Sbloom 	strncpy(sys, name, MAXBASENAME);
60554be4067Sbloom 	sys[MAXBASENAME] = '\0';
60654be4067Sbloom 
60754be4067Sbloom 	strcpy(rest, c);
60854be4067Sbloom 	return HASSYSPART;
60954be4067Sbloom }
610