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