xref: /csrg-svn/usr.bin/uucp/uux/uux.c (revision 13695)
1*13695Ssam #ifndef lint
2*13695Ssam static char sccsid[] = "@(#)uux.c	5.1 (Berkeley) 07/02/83";
3*13695Ssam #endif
4*13695Ssam 
5*13695Ssam /*
6*13695Ssam  * Grade option "-g<g>" added. See cbosgd.2611 (Mark Horton)
7*13695Ssam  * no-copy option "-c" added. Suggested by Steve Bellovin
8*13695Ssam  * "-l" is synonym for "-c".
9*13695Ssam  * "X" files use local system name, avoids conflict. Steve Bellovin
10*13695Ssam  */
11*13695Ssam #include "uucp.h"
12*13695Ssam 
13*13695Ssam #define NOSYSPART 0
14*13695Ssam #define HASSYSPART 1
15*13695Ssam 
16*13695Ssam #define APPCMD(d) {\
17*13695Ssam char *p;\
18*13695Ssam for (p = d; *p != '\0';) *cmdp++ = *p++;\
19*13695Ssam *cmdp++ = ' ';\
20*13695Ssam *cmdp = '\0';}
21*13695Ssam 
22*13695Ssam #define GENSEND(f, a, b, c, d, e) {\
23*13695Ssam fprintf(f, "S %s %s %s -%s %s 0666\n", a, b, c, d, e);\
24*13695Ssam }
25*13695Ssam #define GENRCV(f, a, b, c) {\
26*13695Ssam fprintf(f, "R %s %s %s - \n", a, b, c);\
27*13695Ssam }
28*13695Ssam 
29*13695Ssam 
30*13695Ssam /*
31*13695Ssam  *
32*13695Ssam  */
33*13695Ssam 
34*13695Ssam main(argc, argv)
35*13695Ssam char *argv[];
36*13695Ssam {
37*13695Ssam 	char cfile[NAMESIZE];	/* send commands for files from here */
38*13695Ssam 	char dfile[NAMESIZE];	/* used for all data files from here */
39*13695Ssam 	char rxfile[NAMESIZE];	/* to be sent to xqt file (X. ...) */
40*13695Ssam 	char tfile[NAMESIZE];	/* temporary file name */
41*13695Ssam 	char tcfile[NAMESIZE];	/* temporary file name */
42*13695Ssam 	char t2file[NAMESIZE];	/* temporary file name */
43*13695Ssam 	int cflag = 0;		/*  commands in C. file flag  */
44*13695Ssam 	int rflag = 0;		/*  C. files for receiving flag  */
45*13695Ssam 	int Copy = 1;		/* Copy spool files */
46*13695Ssam 	char buf[BUFSIZ];
47*13695Ssam 	char inargs[BUFSIZ];
48*13695Ssam 	int pipein = 0;
49*13695Ssam 	int startjob = 1;
50*13695Ssam 	char Grade = 'A';
51*13695Ssam 	char path[MAXFULLNAME];
52*13695Ssam 	char cmd[BUFSIZ];
53*13695Ssam 	char *ap, *cmdp;
54*13695Ssam 	char prm[BUFSIZ];
55*13695Ssam 	char syspart[8], rest[MAXFULLNAME];
56*13695Ssam 	char xsys[8], local[8];
57*13695Ssam 	FILE *fprx, *fpc, *fpd, *fp;
58*13695Ssam 	extern char *getprm(), *lastpart();
59*13695Ssam 	extern FILE *ufopen();
60*13695Ssam 	int uid, ret;
61*13695Ssam 	char redir = '\0';
62*13695Ssam 	int nonoti = 0;
63*13695Ssam 	int nonzero = 0;
64*13695Ssam 	int orig_uid = getuid();
65*13695Ssam 
66*13695Ssam 	strcpy(Progname, "uux");
67*13695Ssam 	uucpname(Myname);
68*13695Ssam 	umask(WFMASK);
69*13695Ssam 	Ofn = 1;
70*13695Ssam 	Ifn = 0;
71*13695Ssam 	while (argc>1 && argv[1][0] == '-') {
72*13695Ssam 		switch(argv[1][1]){
73*13695Ssam 		case 'p':
74*13695Ssam 		case '\0':
75*13695Ssam 			pipein = 1;
76*13695Ssam 			break;
77*13695Ssam 		case 'r':
78*13695Ssam 			startjob = 0;
79*13695Ssam 			break;
80*13695Ssam 		case 'c':
81*13695Ssam 		case 'l':
82*13695Ssam 			Copy = 0;
83*13695Ssam 			break;
84*13695Ssam 		case 'g':
85*13695Ssam 			Grade = argv[1][2];
86*13695Ssam 			break;
87*13695Ssam 		case 'x':
88*13695Ssam 			chkdebug(orig_uid);
89*13695Ssam 			Debug = atoi(&argv[1][2]);
90*13695Ssam 			if (Debug <= 0)
91*13695Ssam 				Debug = 1;
92*13695Ssam 			break;
93*13695Ssam 		case 'n':
94*13695Ssam 			nonoti = 1;
95*13695Ssam 			break;
96*13695Ssam 		case 'z':
97*13695Ssam 			nonzero = 1;
98*13695Ssam 			break;
99*13695Ssam 		default:
100*13695Ssam 			fprintf(stderr, "unknown flag %s\n", argv[1]);
101*13695Ssam 				break;
102*13695Ssam 		}
103*13695Ssam 		--argc;  argv++;
104*13695Ssam 	}
105*13695Ssam 
106*13695Ssam 	DEBUG(4, "\n\n** %s **\n", "START");
107*13695Ssam 
108*13695Ssam 	inargs[0] = '\0';
109*13695Ssam 	for (argv++; argc > 1; argc--) {
110*13695Ssam 		DEBUG(4, "arg - %s:", *argv);
111*13695Ssam 		strcat(inargs, " ");
112*13695Ssam 		strcat(inargs, *argv++);
113*13695Ssam 	}
114*13695Ssam 	DEBUG(4, "arg - %s\n", inargs);
115*13695Ssam 	ret = gwd(Wrkdir);
116*13695Ssam 	if (ret != 0) {
117*13695Ssam 		fprintf(stderr, "can't get working directory; will try to continue\n");
118*13695Ssam 		strcpy(Wrkdir, "/UNKNOWN");
119*13695Ssam 	}
120*13695Ssam 	subchdir(Spool);
121*13695Ssam 	uid = getuid();
122*13695Ssam 	guinfo(uid, User, path);
123*13695Ssam 
124*13695Ssam 	sprintf(local, "%.7s", Myname);
125*13695Ssam 	cmdp = cmd;
126*13695Ssam 	*cmdp = '\0';
127*13695Ssam 	gename(DATAPRE, local, 'X', rxfile);
128*13695Ssam 	fprx = ufopen(rxfile, "w");
129*13695Ssam 	ASSERT(fprx != NULL, "CAN'T OPEN", rxfile, 0);
130*13695Ssam 	gename(DATAPRE, local, 'T', tcfile);
131*13695Ssam 	fpc = ufopen(tcfile, "w");
132*13695Ssam 	ASSERT(fpc != NULL, "CAN'T OPEN", tcfile, 0);
133*13695Ssam 	fprintf(fprx, "%c %s %s\n", X_USER, User, local);
134*13695Ssam 	if (nonoti)
135*13695Ssam 		fprintf(fprx, "%c\n", X_NONOTI);
136*13695Ssam 	if (nonzero)
137*13695Ssam 		fprintf(fprx, "%c\n", X_NONZERO);
138*13695Ssam 
139*13695Ssam 	/* find remote system name */
140*13695Ssam 	ap = inargs;
141*13695Ssam 	xsys[0] = '\0';
142*13695Ssam 	while ((ap = getprm(ap, prm)) != NULL) {
143*13695Ssam 		if (prm[0] == '>' || prm[0] == '<') {
144*13695Ssam 			ap = getprm(ap, prm);
145*13695Ssam 			continue;
146*13695Ssam 		}
147*13695Ssam 
148*13695Ssam 
149*13695Ssam 		split(prm, xsys, rest);
150*13695Ssam 		break;
151*13695Ssam 	}
152*13695Ssam 	if (xsys[0] == '\0')
153*13695Ssam 		strcpy(xsys, local);
154*13695Ssam 	sprintf(Rmtname, "%.7s", xsys);
155*13695Ssam 	DEBUG(4, "xsys %s\n", xsys);
156*13695Ssam 	if (versys(xsys) != 0) {
157*13695Ssam 		/*  bad system name  */
158*13695Ssam 		fprintf(stderr, "bad system name: %s\n", xsys);
159*13695Ssam 		fclose(fprx);
160*13695Ssam 		fclose(fpc);
161*13695Ssam 		cleanup(EX_NOHOST);
162*13695Ssam 	}
163*13695Ssam 
164*13695Ssam 	if (pipein) {
165*13695Ssam 		gename(DATAPRE, local, 'B', dfile);
166*13695Ssam 		fpd = ufopen(dfile, "w");
167*13695Ssam 		ASSERT(fpd != NULL, "CAN'T OPEN", dfile, 0);
168*13695Ssam 		while (!feof(stdin)) {
169*13695Ssam 			ret = fread(buf, 1, BUFSIZ, stdin);
170*13695Ssam 			fwrite(buf, 1, ret, fpd);
171*13695Ssam 		}
172*13695Ssam 		fclose(fpd);
173*13695Ssam 		if (strcmp(local, xsys) != SAME) {
174*13695Ssam 			GENSEND(fpc, dfile, dfile, User, "", dfile);
175*13695Ssam 			cflag++;
176*13695Ssam 		}
177*13695Ssam 		fprintf(fprx, "%c %s\n", X_RQDFILE, dfile);
178*13695Ssam 		fprintf(fprx, "%c %s\n", X_STDIN, dfile);
179*13695Ssam 	}
180*13695Ssam 	/* parse command */
181*13695Ssam 	ap = inargs;
182*13695Ssam 	while ((ap = getprm(ap, prm)) != NULL) {
183*13695Ssam 		DEBUG(4, "prm - %s\n", prm);
184*13695Ssam 		if (prm[0] == '>' || prm[0] == '<') {
185*13695Ssam 			redir = prm[0];
186*13695Ssam 			continue;
187*13695Ssam 		}
188*13695Ssam 
189*13695Ssam 		if (prm[0] == ';') {
190*13695Ssam 			APPCMD(prm);
191*13695Ssam 			continue;
192*13695Ssam 		}
193*13695Ssam 
194*13695Ssam 		if (prm[0] == '|' || prm[0] == '^') {
195*13695Ssam 			if (cmdp != cmd)
196*13695Ssam 				APPCMD(prm);
197*13695Ssam 			continue;
198*13695Ssam 		}
199*13695Ssam 
200*13695Ssam 		/* process command or file or option */
201*13695Ssam 		ret = split(prm, syspart, rest);
202*13695Ssam 		DEBUG(4, "s - %s, ", syspart);
203*13695Ssam 		DEBUG(4, "r - %s, ", rest);
204*13695Ssam 		DEBUG(4, "ret - %d\n", ret);
205*13695Ssam 		if (syspart[0] == '\0')
206*13695Ssam 			strcpy(syspart, local);
207*13695Ssam 
208*13695Ssam 		if (cmdp == cmd && redir == '\0') {
209*13695Ssam 			/* command */
210*13695Ssam 			APPCMD(rest);
211*13695Ssam 			continue;
212*13695Ssam 		}
213*13695Ssam 
214*13695Ssam 		/* process file or option */
215*13695Ssam 		DEBUG(4, "file s- %s, ", syspart);
216*13695Ssam 		DEBUG(4, "local - %s\n", local);
217*13695Ssam 		/* process file */
218*13695Ssam 		if (redir == '>') {
219*13695Ssam 			if (rest[0] != '~')
220*13695Ssam 				if (ckexpf(rest))
221*13695Ssam 					cleanup(EX_CANTCREAT);
222*13695Ssam 			fprintf(fprx, "%c %s %s\n", X_STDOUT, rest,
223*13695Ssam 			 syspart);
224*13695Ssam 			redir = '\0';
225*13695Ssam 			continue;
226*13695Ssam 		}
227*13695Ssam 
228*13695Ssam 		if (ret == NOSYSPART && redir == '\0') {
229*13695Ssam 			/* option */
230*13695Ssam 			APPCMD(rest);
231*13695Ssam 			continue;
232*13695Ssam 		}
233*13695Ssam 
234*13695Ssam 		if (strcmp(xsys, local) == SAME
235*13695Ssam 		 && strcmp(xsys, syspart) == SAME) {
236*13695Ssam 			if (ckexpf(rest))
237*13695Ssam 				cleanup(EX_CANTCREAT);
238*13695Ssam 			if (redir == '<')
239*13695Ssam 				fprintf(fprx, "%c %s\n", X_STDIN, rest);
240*13695Ssam 			else
241*13695Ssam 				APPCMD(rest);
242*13695Ssam 			redir = '\0';
243*13695Ssam 			continue;
244*13695Ssam 		}
245*13695Ssam 
246*13695Ssam 		if (strcmp(syspart, local) == SAME) {
247*13695Ssam 			/*  generate send file */
248*13695Ssam 			if (ckexpf(rest))
249*13695Ssam 				cleanup(EX_CANTCREAT);
250*13695Ssam 			gename(DATAPRE, local, 'A', dfile);
251*13695Ssam 			DEBUG(4, "rest %s\n", rest);
252*13695Ssam 			if ((chkpth(User, "", rest) || anyread(rest)) != 0) {
253*13695Ssam 				fprintf(stderr, "permission denied %s\n", rest);
254*13695Ssam 				cleanup(EX_NOINPUT);
255*13695Ssam 			}
256*13695Ssam 			if (Copy) {
257*13695Ssam 				if (xcp(rest, dfile) != 0) {
258*13695Ssam 					fprintf(stderr, "can't copy %s to %s\n", rest, dfile);
259*13695Ssam 					cleanup(EX_NOINPUT);
260*13695Ssam 				}
261*13695Ssam 				GENSEND(fpc, rest, dfile, User, "", dfile);
262*13695Ssam 			}
263*13695Ssam 			else {
264*13695Ssam 				GENSEND(fpc, rest, dfile, User, "c", "D.0");
265*13695Ssam 			}
266*13695Ssam 			cflag++;
267*13695Ssam 			if (redir == '<') {
268*13695Ssam 				fprintf(fprx, "%c %s\n", X_STDIN, dfile);
269*13695Ssam 				fprintf(fprx, "%c %s\n", X_RQDFILE, dfile);
270*13695Ssam 			}
271*13695Ssam 			else {
272*13695Ssam 				APPCMD(lastpart(rest));
273*13695Ssam 				fprintf(fprx, "%c %s %s\n", X_RQDFILE,
274*13695Ssam 				 dfile, lastpart(rest));
275*13695Ssam 			}
276*13695Ssam 			redir = '\0';
277*13695Ssam 			continue;
278*13695Ssam 		}
279*13695Ssam 
280*13695Ssam 		if (strcmp(local, xsys) == SAME) {
281*13695Ssam 			/*  generate local receive  */
282*13695Ssam 			gename(CMDPRE, syspart, 'R', tfile);
283*13695Ssam 			strcpy(dfile, tfile);
284*13695Ssam 			dfile[0] = DATAPRE;
285*13695Ssam 			fp = ufopen(tfile, "w");
286*13695Ssam 			ASSERT(fp != NULL, "CAN'T OPEN", tfile, 0);
287*13695Ssam 			if (ckexpf(rest))
288*13695Ssam 				cleanup(EX_CANTCREAT);
289*13695Ssam 			GENRCV(fp, rest, dfile, User);
290*13695Ssam 			fclose(fp);
291*13695Ssam 			rflag++;
292*13695Ssam 			if (rest[0] != '~')
293*13695Ssam 				if (ckexpf(rest))
294*13695Ssam 					cleanup(EX_CANTCREAT);
295*13695Ssam 			if (redir == '<') {
296*13695Ssam 				fprintf(fprx, "%c %s\n", X_RQDFILE, dfile);
297*13695Ssam 				fprintf(fprx, "%c %s\n", X_STDIN, dfile);
298*13695Ssam 			}
299*13695Ssam 			else {
300*13695Ssam 				fprintf(fprx, "%c %s %s\n", X_RQDFILE, dfile,
301*13695Ssam 				  lastpart(rest));
302*13695Ssam 				APPCMD(lastpart(rest));
303*13695Ssam 			}
304*13695Ssam 
305*13695Ssam 			redir = '\0';
306*13695Ssam 			continue;
307*13695Ssam 		}
308*13695Ssam 
309*13695Ssam 		if (strcmp(syspart, xsys) != SAME) {
310*13695Ssam 			/* generate remote receives */
311*13695Ssam 			gename(DATAPRE, syspart, 'R', dfile);
312*13695Ssam 			strcpy(tfile, dfile);
313*13695Ssam 			tfile[0] = CMDPRE;
314*13695Ssam 			fpd = ufopen(dfile, "w");
315*13695Ssam 			ASSERT(fpd != NULL, "CAN'T OPEN", dfile, 0);
316*13695Ssam 			gename(DATAPRE, local, 'T', t2file);
317*13695Ssam 			GENRCV(fpd, rest, t2file, User);
318*13695Ssam 			fclose(fpd);
319*13695Ssam 			GENSEND(fpc, dfile, tfile, User, "", dfile);
320*13695Ssam 			cflag++;
321*13695Ssam 			if (redir == '<') {
322*13695Ssam 				fprintf(fprx, "%c %s\n", X_RQDFILE, t2file);
323*13695Ssam 				fprintf(fprx, "%c %s\n", X_STDIN, t2file);
324*13695Ssam 			}
325*13695Ssam 			else {
326*13695Ssam 				fprintf(fprx, "%c %s %s\n", X_RQDFILE, t2file,
327*13695Ssam 				  lastpart(rest));
328*13695Ssam 				APPCMD(lastpart(rest));
329*13695Ssam 			}
330*13695Ssam 			redir = '\0';
331*13695Ssam 			continue;
332*13695Ssam 		}
333*13695Ssam 
334*13695Ssam 		/* file on remote system */
335*13695Ssam 		if (rest[0] != '~')
336*13695Ssam 			if (ckexpf(rest))
337*13695Ssam 				cleanup(EX_CANTCREAT);
338*13695Ssam 		if (redir == '<')
339*13695Ssam 			fprintf(fprx, "%c %s\n", X_STDIN, rest);
340*13695Ssam 		else
341*13695Ssam 			APPCMD(rest);
342*13695Ssam 		redir = '\0';
343*13695Ssam 		continue;
344*13695Ssam 
345*13695Ssam 	}
346*13695Ssam 
347*13695Ssam 	fprintf(fprx, "%c %s\n", X_CMD, cmd);
348*13695Ssam 	logent(cmd, "XQT QUE'D");
349*13695Ssam 	fclose(fprx);
350*13695Ssam 
351*13695Ssam 	strcpy(tfile, rxfile);
352*13695Ssam 	tfile[0] = XQTPRE;
353*13695Ssam 	if (strcmp(xsys, local) == SAME) {
354*13695Ssam 		/* rti!trt: xmv() works across filesystems, link(II) doesnt */
355*13695Ssam 		xmv(rxfile, tfile);
356*13695Ssam 		if (startjob)
357*13695Ssam 			if (rflag)
358*13695Ssam 				xuucico(xsys);
359*13695Ssam 			else
360*13695Ssam 				xuuxqt();
361*13695Ssam 	}
362*13695Ssam 	else {
363*13695Ssam 		GENSEND(fpc, rxfile, tfile, User, "", rxfile);
364*13695Ssam 		cflag++;
365*13695Ssam 	}
366*13695Ssam 
367*13695Ssam 	fclose(fpc);
368*13695Ssam 	if (cflag) {
369*13695Ssam 		gename(CMDPRE, xsys, Grade, cfile);
370*13695Ssam 		/* rti!trt: use xmv() rather than link(II) */
371*13695Ssam 		xmv(tcfile, cfile);
372*13695Ssam 		if (startjob)
373*13695Ssam 			xuucico(xsys);
374*13695Ssam 		cleanup(0);
375*13695Ssam 	}
376*13695Ssam 	else
377*13695Ssam 		unlink(subfile(tcfile));
378*13695Ssam }
379*13695Ssam 
380*13695Ssam #define FTABSIZE 30
381*13695Ssam char Fname[FTABSIZE][NAMESIZE];
382*13695Ssam int Fnamect = 0;
383*13695Ssam 
384*13695Ssam /***
385*13695Ssam  *	cleanup - cleanup and unlink if error
386*13695Ssam  *
387*13695Ssam  *	return - none - do exit()
388*13695Ssam  */
389*13695Ssam 
390*13695Ssam cleanup(code)
391*13695Ssam int code;
392*13695Ssam {
393*13695Ssam 	int i;
394*13695Ssam 
395*13695Ssam 	logcls();
396*13695Ssam 	rmlock(CNULL);
397*13695Ssam 	if (code) {
398*13695Ssam 		for (i = 0; i < Fnamect; i++)
399*13695Ssam 			unlink(subfile(Fname[i]));
400*13695Ssam 		fprintf(stderr, "uux failed. code %d\n", code);
401*13695Ssam 	}
402*13695Ssam 	DEBUG(1, "exit code %d\n", code);
403*13695Ssam 	exit(code);
404*13695Ssam }
405*13695Ssam 
406*13695Ssam /***
407*13695Ssam  *	ufopen - open file and record name
408*13695Ssam  *
409*13695Ssam  *	return file pointer.
410*13695Ssam  */
411*13695Ssam 
412*13695Ssam FILE *ufopen(file, mode)
413*13695Ssam char *file, *mode;
414*13695Ssam {
415*13695Ssam 	if (Fnamect < FTABSIZE)
416*13695Ssam 		strcpy(Fname[Fnamect++], file);
417*13695Ssam 	else
418*13695Ssam 		logent("Fname", "TABLE OVERFLOW");
419*13695Ssam 	return(fopen(subfile(file), mode));
420*13695Ssam }
421