|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)uux.c 5.14 (Berkeley) 10/27/88";
3: #endif
4:
5: #include "uucp.h"
6: #include <sys/stat.h>
7: #include <sysexits.h>
8:
9: #define NOSYSPART 0
10: #define HASSYSPART 1
11:
12: #define LQUOTE '('
13: #define RQUOTE ')'
14:
15: #define APPCMD(d) {\
16: register char *p; for (p = d; *p != '\0';)\
17: {*cmdp++ = *p++;\
18: if(cmdp>(sizeof(cmd)+&cmd[0])){\
19: fprintf(stderr,"argument list too long\n");\
20: cleanup(EX_SOFTWARE);\
21: }\
22: }\
23: *cmdp++ = ' '; *cmdp = '\0';}
24:
25: #define GENSEND(f, a, b, c, d, e) {\
26: fprintf(f, "S %s %s %s -%s %s 0666\n", a, b, c, d, e); }
27: #define GENRCV(f, a, b, c) {fprintf(f, "R %s %s %s - \n", a, b, c);}
28:
29: struct timeb Now;
30:
31: main(argc, argv)
32: int argc;
33: char **argv;
34: {
35: char cfile[NAMESIZE]; /* send commands for files from here */
36: char dfile[NAMESIZE]; /* used for all data files from here */
37: char rxfile[NAMESIZE]; /* to be sent to xqt file (X. ...) */
38: char tfile[NAMESIZE]; /* temporary file name */
39: char tcfile[NAMESIZE]; /* temporary file name */
40: char t2file[NAMESIZE]; /* temporary file name */
41: int cflag = 0; /* commands in C. file flag */
42: int rflag = 0; /* C. files for receiving flag */
43: #ifdef DONTCOPY
44: int Copy = 0; /* Don't Copy spool files */
45: #else !DONTCOPY
46: int Copy = 1; /* Copy spool files */
47: #endif !DONTCOPY
48: int Linkit = 0; /* Try link before copy */
49: char buf[2*BUFSIZ];
50: char inargs[2*BUFSIZ];
51: int pipein = 0;
52: int startjob = 1;
53: char Grade = 'A';
54: long Gradedelta = 100000000L; /* "huge number" */
55: long size = 0L;
56: char path[MAXFULLNAME];
57: char cmd[2*BUFSIZ];
58: char *ap, *cmdp;
59: char prm[2*BUFSIZ];
60: char syspart[MAXBASENAME+1], rest[MAXFULLNAME];
61: char Xsys[MAXBASENAME+1], local[MAXBASENAME+1];
62: char *xsys = Xsys;
63: FILE *fprx, *fpc, *fpd, *fp;
64: extern char *getprm(), *lastpart();
65: extern FILE *ufopen();
66: int uid, ret, c;
67: char redir = '\0';
68: int nonoti = 0;
69: int nonzero = 0;
70: int link_failed;
71: char *ReturnTo = NULL;
72: extern int LocalOnly;
73: extern char *optarg;
74: extern int optind;
75:
76: strcpy(Progname, "uux");
77: uucpname(Myname);
78: umask(WFMASK);
79: Ofn = 1;
80: Ifn = 0;
81: #ifdef VMS
82: arg_fix(argc, argv);
83: #endif
84: while (((c = getopt(argc, argv, "-prclCg:x:nzLa:")) != EOF) ||
85: (optind < argc && (c = *argv[optind]) == '-' && ++optind))
86: switch (c) {
87: case '-':
88: /* FALLTHROUGH */
89: case 'p':
90: pipein = 1;
91: break;
92: case 'r':
93: startjob = 0;
94: break;
95: case 'c':
96: Copy = 0;
97: Linkit = 0;
98: break;
99: case 'l':
100: Copy = 0;
101: Linkit = 1;
102: break;
103: case 'C':
104: Copy = 1;
105: Linkit = 0;
106: break;
107: case 'g':
108: Grade = *optarg;
109: Gradedelta = atol(optarg+1);
110: break;
111: case 'x':
112: chkdebug();
113: Debug = atoi(optarg);
114: if (Debug <= 0)
115: Debug = 1;
116: break;
117: case 'n':
118: nonoti = 1;
119: break;
120: case 'z':
121: nonzero = 1;
122: break;
123: case 'L':
124: LocalOnly++;
125: break;
126: case 'a':
127: ReturnTo = optarg;
128: if (prefix(Myname, ReturnTo) && ReturnTo[strlen(Myname)] == '!')
129: ReturnTo = index(ReturnTo, '!') + 1;
130: break;
131: case '?':
132: default:
133: break;
134: }
135:
136: ap = getwd(Wrkdir);
137: if (ap == 0) {
138: fprintf(stderr, "can't get working directory; will try to continue\n");
139: strcpy(Wrkdir, "/UNKNOWN");
140: }
141:
142: DEBUG(4, "\n\n** %s **\n", "START");
143:
144: inargs[0] = '\0';
145: while (optind < argc) {
146: DEBUG(4, "arg - %s:", argv[optind]);
147: strcat(inargs, " ");
148: strcat(inargs, argv[optind++]);
149: }
150: DEBUG(4, "arg - %s\n", inargs);
151: if (subchdir(Spool) < 0) {
152: syslog(LOG_WARNING, "chdir(%s) failed: %m", Spool);
153: cleanup(1);
154: }
155: uid = getuid();
156: if (guinfo(uid, User, path) != SUCCESS) {
157: syslog(LOG_WARNING, "Can't find username for uid %d", uid);
158: DEBUG(1, "Using username", "uucp");
159: strcpy(User, "uucp");
160: }
161:
162: strncpy(local, Myname, MAXBASENAME);
163: cmdp = cmd;
164: *cmdp = '\0';
165: gename(DATAPRE, local, 'X', rxfile);
166: fprx = ufopen(rxfile, "w");
167: if (fprx == NULL) {
168: syslog(LOG_WARNING, "fopen(%s) failed: %m", rxfile);
169: cleanup(1);
170: }
171: gename(DATAPRE, local, 'T', tcfile);
172: fpc = ufopen(tcfile, "w");
173: if (fpc == NULL) {
174: syslog(LOG_WARNING, "fopen(%s) failed: %m", tcfile);
175: cleanup(1);
176: }
177: fprintf(fprx, "%c %s %s\n", X_USER, User, local);
178: if (nonoti)
179: fprintf(fprx, "%c\n", X_NONOTI);
180: if (nonzero)
181: fprintf(fprx, "%c\n", X_NONZERO);
182: if (ReturnTo == NULL || *ReturnTo == '\0')
183: ReturnTo = User;
184: fprintf(fprx, "%c %s\n", X_RETURNTO, ReturnTo);
185:
186: /* find remote system name */
187: ap = inargs;
188: xsys[0] = '\0';
189: while ((ap = getprm(ap, prm)) != NULL) {
190: if (prm[0] == '>' || prm[0] == '<') {
191: ap = getprm(ap, prm);
192: continue;
193: }
194:
195: split(prm, xsys, rest);
196: break;
197: }
198: if (xsys[0] == '\0')
199: strcpy(xsys, local);
200: if (versys(&xsys) != 0) {
201: /* bad system name */
202: fprintf(stderr, "bad system name: %s\n", xsys);
203: fclose(fprx);
204: fclose(fpc);
205: cleanup(EX_NOHOST);
206: }
207:
208: strncpy(Rmtname, xsys, MAXBASENAME);
209: DEBUG(4, "xsys %s\n", xsys);
210:
211: if (pipein) {
212: gename(DATAPRE, local, 'B', dfile);
213: fpd = ufopen(dfile, "w");
214: if (fpd == NULL) {
215: syslog(LOG_WARNING, "fopen(%s) failed: %m", dfile);
216: cleanup(1);
217: }
218: while (!feof(stdin)) {
219: ret = fread(buf, 1, BUFSIZ, stdin);
220: fwrite(buf, 1, ret, fpd);
221: if (ferror(stdin)) {
222: perror("stdin");
223: cleanup(EX_IOERR);
224: }
225: if (ferror(fpd)) {
226: perror(dfile);
227: cleanup(EX_IOERR);
228: }
229: size += ret;
230: }
231: fclose(fpd);
232: strcpy(tfile, dfile);
233: if (strcmp(local, xsys) != SAME) {
234: register int Len = strlen(local);
235: if (Len > SYSNSIZE)
236: Len = SYSNSIZE;
237: tfile[Len + 2] = 'S';
238: GENSEND(fpc, dfile, tfile, User, "", dfile);
239: cflag++;
240: }
241: fprintf(fprx, "%c %s\n", X_RQDFILE, tfile);
242: fprintf(fprx, "%c %s\n", X_STDIN, tfile);
243: }
244: /* parse command */
245: ap = inargs;
246: while ((ap = getprm(ap, prm)) != NULL) {
247: DEBUG(4, "prm - %s\n", prm);
248: if (prm[0] == '>' || prm[0] == '<') {
249: redir = prm[0];
250: continue;
251: }
252:
253: if (prm[0] == ';') {
254: APPCMD(prm);
255: continue;
256: }
257:
258: if (prm[0] == '|' || prm[0] == '^') {
259: if (cmdp != cmd)
260: APPCMD(prm);
261: continue;
262: }
263:
264: /* process command or file or option */
265: ret = split(prm, syspart, rest);
266: DEBUG(4, "s - %s, ", syspart);
267: DEBUG(4, "r - %s, ", rest);
268: DEBUG(4, "ret - %d\n", ret);
269: if (syspart[0] == '\0')
270: strcpy(syspart, local);
271:
272: if (cmdp == cmd && redir == '\0') {
273: /* command */
274: APPCMD(rest);
275: continue;
276: }
277:
278: /* process file or option */
279: DEBUG(4, "file s- %s, ", syspart);
280: DEBUG(4, "local - %s\n", local);
281: /* process file */
282: if (redir == '>') {
283: if (rest[0] != '~')
284: if (ckexpf(rest))
285: cleanup(EX_CANTCREAT);
286: fprintf(fprx, "%c %s %s\n", X_STDOUT, rest,
287: syspart);
288: redir = '\0';
289: continue;
290: }
291:
292: if (ret == NOSYSPART && redir == '\0') {
293: /* option */
294: APPCMD(rest);
295: continue;
296: }
297:
298: if (rest[0] != '\0') {
299: struct stat stbuf;
300: if (stat(rest, &stbuf) < 0)
301: DEBUG(4, "Can't stat %s\n", rest);
302: else
303: size += stbuf.st_size;
304: DEBUG(4, "size = %ld\n", size);
305: }
306:
307: if (strcmp(xsys, local) == SAME
308: && strcmp(xsys, syspart) == SAME) {
309: if (ckexpf(rest))
310: cleanup(EX_CANTCREAT);
311: if (redir == '<')
312: fprintf(fprx, "%c %s\n", X_STDIN, rest);
313: else
314: APPCMD(rest);
315: redir = '\0';
316: continue;
317: }
318:
319: if (strcmp(syspart, local) == SAME) {
320: /* generate send file */
321: if (ckexpf(rest))
322: cleanup(EX_CANTCREAT);
323: gename(DATAPRE, local, 'A', dfile);
324: DEBUG(4, "rest %s\n", rest);
325: if ((chkpth(User, "", rest) || anyread(rest)) != 0) {
326: fprintf(stderr, "permission denied %s\n", rest);
327: cleanup(EX_NOINPUT);
328: }
329: link_failed = 0;
330: if (Linkit) {
331: if (link(subfile(rest), subfile(dfile)) != 0)
332: link_failed++;
333: else
334: GENSEND(fpc, rest, dfile, User, "", dfile);
335: }
336: if (Copy || link_failed) {
337: if (xcp(rest, dfile) != 0) {
338: fprintf(stderr, "can't copy %s to %s\n", rest, dfile);
339: cleanup(EX_NOINPUT);
340: }
341: GENSEND(fpc, rest, dfile, User, "", dfile);
342: }
343: if (!Copy && !Linkit) {
344: GENSEND(fpc, rest, dfile, User, "c", "D.0");
345: }
346: cflag++;
347: if (redir == '<') {
348: fprintf(fprx, "%c %s\n", X_STDIN, dfile);
349: fprintf(fprx, "%c %s\n", X_RQDFILE, dfile);
350: } else {
351: APPCMD(lastpart(rest));
352: fprintf(fprx, "%c %s %s\n", X_RQDFILE,
353: dfile, lastpart(rest));
354: }
355: redir = '\0';
356: continue;
357: }
358:
359: if (strcmp(local, xsys) == SAME) {
360: /* generate local receive */
361: gename(CMDPRE, syspart, 'R', tfile);
362: strcpy(dfile, tfile);
363: dfile[0] = DATAPRE;
364: fp = ufopen(tfile, "w");
365: if (fp == NULL) {
366: syslog(LOG_WARNING, "fopen(%s) failed: %m",
367: tfile);
368: cleanup(1);
369: }
370: if (ckexpf(rest))
371: cleanup(EX_CANTCREAT);
372: GENRCV(fp, rest, dfile, User);
373: fclose(fp);
374: rflag++;
375: if (rest[0] != '~')
376: if (ckexpf(rest))
377: cleanup(EX_CANTCREAT);
378: if (redir == '<') {
379: fprintf(fprx, "%c %s\n", X_RQDFILE, dfile);
380: fprintf(fprx, "%c %s\n", X_STDIN, dfile);
381: } else {
382: fprintf(fprx, "%c %s %s\n", X_RQDFILE, dfile,
383: lastpart(rest));
384: APPCMD(lastpart(rest));
385: }
386:
387: redir = '\0';
388: continue;
389: }
390:
391: if (strcmp(syspart, xsys) != SAME) {
392: /* generate remote receives */
393: gename(DATAPRE, syspart, 'R', dfile);
394: strcpy(tfile, dfile);
395: tfile[0] = CMDPRE;
396: fpd = ufopen(dfile, "w");
397: if (fpd == NULL) {
398: syslog(LOG_WARNING, "fopen(%s) failed: %m",
399: dfile);
400: cleanup(1);
401: }
402: gename(DATAPRE, local, 'T', t2file);
403: GENRCV(fpd, rest, t2file, User);
404: fclose(fpd);
405: GENSEND(fpc, dfile, tfile, User, "", dfile);
406: cflag++;
407: if (redir == '<') {
408: fprintf(fprx, "%c %s\n", X_RQDFILE, t2file);
409: fprintf(fprx, "%c %s\n", X_STDIN, t2file);
410: } else {
411: fprintf(fprx, "%c %s %s\n", X_RQDFILE, t2file,
412: lastpart(rest));
413: APPCMD(lastpart(rest));
414: }
415: redir = '\0';
416: continue;
417: }
418:
419: /* file on remote system */
420: if (rest[0] != '~')
421: if (ckexpf(rest))
422: cleanup(EX_CANTCREAT);
423: if (redir == '<')
424: fprintf(fprx, "%c %s\n", X_STDIN, rest);
425: else
426: APPCMD(rest);
427: redir = '\0';
428: continue;
429:
430: }
431: /*
432: * clean up trailing ' ' in command.
433: */
434: if (cmdp > cmd && cmdp[0] == '\0' && cmdp[-1] == ' ')
435: *--cmdp = '\0';
436: /* block multi-hop uux, which doesn't work */
437: for (ap = cmd; *ap && *ap != ' '; ap++)
438: if (*ap == '!') {
439: fprintf(stderr, "uux handles only adjacent sites.\n");
440: fprintf(stderr, "Try uusend for multi-hop delivery.\n");
441: cleanup(EX_USAGE);
442: }
443:
444: fprintf(fprx, "%c %s\n", X_CMD, cmd);
445: if (ferror(fprx)) {
446: logent(cmd, "COULD NOT QUEUE XQT");
447: cleanup(EX_IOERR);
448: } else
449: logent(cmd, "XQT QUE'D");
450: fclose(fprx);
451:
452: if (size > 0 && Gradedelta > 0) {
453: DEBUG (4, "Grade changed from %c ", Grade);
454: Grade += size/Gradedelta;
455: if (Grade > 'z')
456: Grade = 'z';
457: DEBUG(4, "to %c\n", Grade);
458: }
459: gename(XQTPRE, local, Grade, tfile);
460: if (strcmp(xsys, local) == SAME) {
461: /* rti!trt: xmv() works across filesystems, link(II) doesnt */
462: xmv(rxfile, tfile);
463: if (startjob)
464: if (rflag)
465: xuucico(xsys);
466: else
467: xuuxqt();
468: }
469: else {
470: GENSEND(fpc, rxfile, tfile, User, "", rxfile);
471: cflag++;
472: }
473:
474: if (ferror(fpc))
475: cleanup(EX_IOERR);
476: fclose(fpc);
477: if (cflag) {
478: gename(CMDPRE, xsys, Grade, cfile);
479: /* rti!trt: use xmv() rather than link(II) */
480: xmv(tcfile, cfile);
481: if (startjob)
482: xuucico(xsys);
483: cleanup(0);
484: }
485: else
486: unlink(subfile(tcfile));
487: exit(0);
488: }
489:
490: #define FTABSIZE 30
491: char Fname[FTABSIZE][NAMESIZE];
492: int Fnamect = 0;
493:
494: /*
495: * cleanup and unlink if error
496: *
497: * return - none - do exit()
498: */
499:
500: cleanup(code)
501: int code;
502: {
503: int i;
504:
505: logcls();
506: rmlock(CNULL);
507: if (code) {
508: for (i = 0; i < Fnamect; i++)
509: unlink(subfile(Fname[i]));
510: fprintf(stderr, "uux failed. code %d\n", code);
511: }
512: DEBUG(1, "exit code %d\n", code);
513: exit(code);
514: }
515:
516: /*
517: * open file and record name
518: *
519: * return file pointer.
520: */
521:
522: FILE *ufopen(file, mode)
523: char *file, *mode;
524: {
525: if (Fnamect < FTABSIZE)
526: strcpy(Fname[Fnamect++], file);
527: else
528: logent("Fname", "TABLE OVERFLOW");
529: return fopen(subfile(file), mode);
530: }
531: #ifdef VMS
532: /*
533: * EUNICE bug:
534: * quotes are not stripped from DCL. Do it here.
535: * Note if we are running under Unix shell we don't
536: * do the right thing.
537: */
538: arg_fix(argc, argv)
539: char **argv;
540: {
541: register char *cp, *tp;
542:
543: for (; argc > 0; --argc, argv++) {
544: cp = *argv;
545: if (cp == (char *)0 || *cp++ != '"')
546: continue;
547: tp = cp;
548: while (*tp++) ;
549: tp -= 2;
550: if (*tp == '"') {
551: *tp = '\0';
552: *argv = cp;
553: }
554: }
555: }
556: #endif VMS
557:
558: /*
559: * split into system and file part
560: *
561: * return codes:
562: * NOSYSPART
563: * HASSYSPART
564: */
565:
566: split(name, sys, rest)
567: register char *name, *rest;
568: char *sys;
569: {
570: register char *c;
571:
572: if (*name == LQUOTE) {
573: if ((c = index(name + 1, RQUOTE)) != NULL) {
574: /* strip off quotes */
575: name++;
576: while (c != name)
577: *rest++ = *name++;
578: *rest = '\0';
579: *sys = '\0';
580: return NOSYSPART;
581: }
582: }
583:
584: if ((c = index(name, '!')) == NULL) {
585: strcpy(rest, name);
586: *sys = '\0';
587: return NOSYSPART;
588: }
589:
590: *c++ = '\0';
591: strncpy(sys, name, MAXBASENAME);
592: sys[MAXBASENAME] = '\0';
593:
594: strcpy(rest, c);
595: return HASSYSPART;
596: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.