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