|
|
1.1 root 1: /*
2: * The uucp command.
3: * Copyright Mark Williams Company Lake Bluff IL 1989.
4: * All rights reserved.
5: */
6:
7: #include <stdio.h>
8: #include <sys/stat.h>
9: #include <ctype.h>
10: #include <access.h>
11: #include <signal.h>
12: #include "dcp.h"
13:
14: #define DEFGRADE 'a'
15:
16: extern int getopt();
17: extern int optind;
18: extern char *optarg;
19: extern char *index(/* char *string, char c */);
20: extern char *rindex(/* char *string, char c */);
21: extern char *mktemp(/* char *template */);
22: extern FILE *fopen();
23: extern char *getwd();
24: char *build_full_path();
25: char *uucpname(), *whoami();
26: char *filesite(/* char *filename */), *filepath(/* char *filename */);
27: char *myfilepath();
28: char *basename(/* char *filename */);
29: char tempname[] = "/usr/spool/uucp/TM.XXXXXX";
30: char luser [32]; /* local user name */
31: char notifyusr [32]; /* user to be notified */
32:
33: char *rmtname = NULL;
34:
35: static char spoolname [BUFSIZ];
36: static char fsname [BUFSIZ]; /* full spool pathname */
37: static char dirname [BUFSIZ]; /* full spool pathname */
38: static char fullfrompath [BUFSIZ];
39: static char fulltopath [BUFSIZ];
40: static char fromsite [32];
41: static char tosite [32];
42: static char options [32];
43: char thissite[SITELEN];
44: char cmd[64]; /* remote command name */
45: FILE *commandfile; /* the "C." spool command file */
46: char commandsite [40]; /* site in command file name */
47: char grade = DEFGRADE; /* transfer grade */
48: char spdir [40] = SPOOLDIR; /* spool directory */
49:
50: int nocicoflg = 0; /* "don't run uucico" flag */
51: int called_uux = 0;
52: int mkdirflg = 1;
53: int nocopyflg = 1;
54: int copyflg = 0;
55: int mailflg = 0;
56: int notifyflg = 0;
57: int debugflg = 0;
58: int debugdir = 0;
59: char *toptr, *fromptr; /* pointers to from and to arguments */
60: char *topath, *frompath; /* file pathname part of source/dest */
61: char topathbuf[BUFSIZ];
62: char frompathbuf[BUFSIZ];
63: char *tositeptr, *fromsiteptr;
64: char argbuf[BUFSIZ];
65: char argbuf1[BUFSIZ];
66: char argbuf2[BUFSIZ];
67:
68: int sending, receiving;
69: struct stat statbuf;
70: int seqno;
71:
72: main(argc, argv)
73: int argc;
74: char *argv[];
75: {
76: int ch;
77: int argx;
78:
79: commandfile = NULL;
80: strcpy(commandsite, "<?>");
81: strcpy(thissite, uucpname());
82: if (strlen(thissite) == 0) {
83: fprintf(stderr, "uucp: can't get my own uucpname\n");
84: exit(1);
85: }
86: strcpy(luser, whoami());
87: strcpy(notifyusr, luser);
88: if (debugflg > 0)
89: fprintf(stderr, "I yam %s.\n", luser);
90: while( (ch=getopt(argc, argv, "dfcCmrg:s:x:n:vV")) != EOF ) {
91: switch(ch) {
92: case 'r':
93: nocicoflg = 1;
94: break;
95: case 's':
96: debugdir = 1;
97: fprintf(stderr, "-s option is %s.\n", optarg);
98: strcpy(spdir, optarg);
99: break;
100: case 'x':
101: debugflg = atoi(optarg);
102: fprintf(stderr, "Debug level is %d\n", debugflg);
103: fprintf(stderr, "uucp Version %s\n", VERSION);
104: break;
105: case 'g':
106: if (isalnum(optarg[0]) && '\0' == optarg[1])
107: grade = optarg[0];
108: else {
109: fprintf(stderr,
110: "uucp: %s: illegal grade\n", optarg);
111: usage();
112: }
113: break;
114: case 'd':
115: mkdirflg = 1;
116: break;
117: case 'f':
118: mkdirflg = 0;
119: break;
120: case 'c':
121: copyflg = 0;
122: nocopyflg = 1;
123: break;
124: case 'C':
125: copyflg = 1;
126: nocopyflg = 0;
127: break;
128: case 'm':
129: mailflg = 1;
130: break;
131: case 'n':
132: notifyflg = 1;
133: strcpy (notifyusr, optarg);
134: if (debugflg > 5)
135: fprintf(stderr, "notify user %s upon rcpt\n",notifyusr);
136: break;
137: case 'v':
138: case 'V':
139: fatal("uucp: Version %s", VERSION);
140: default:
141: fprintf(stderr, "uucp: Option character of %c\n", ch);
142: usage();
143: }
144: }
145: toptr = argv[argc - 1];
146: if (debugflg > 4) {
147: fprintf(stderr, "argc is now %d\n", argc);
148: fprintf(stderr, "therefore, last argument is %s.\n", toptr);
149: }
150: if ((argc - optind) < 2)
151: usage();
152: if (optind >= argc)
153: usage();
154: for (argx = optind; argx < argc - 1; argx ++ )
155: uucp(argv[argx], toptr);
156: if (commandfile != NULL)
157: finish_commandfile();
158: if (nocicoflg || called_uux)
159: return 0;
160: else
161: exec_cico(commandsite);
162: exit(0);
163: }
164:
165: uucp(fromptr, toptr)
166: char *fromptr;
167: char *toptr;
168: {
169: if (debugflg > 1)
170: fprintf(stderr, "uucp from %s to %s\n", fromptr, toptr);
171: sending = 0;
172: receiving = 0;
173: topath = toptr;
174: if ((tositeptr = filesite(toptr)) != NULL) {
175: sending = 1;
176: strcpy(topathbuf, filepath(toptr));
177: topath = topathbuf;
178: if (!knowhost(tositeptr)) {
179: fprintf(stderr,
180: "uucp: destination site %s unknown\n", tositeptr);
181: exit(1);
182: }
183: }
184: strcpy(tosite, tositeptr); tositeptr = tosite;
185: frompath = fromptr;
186: if ((fromsiteptr = filesite(fromptr)) != NULL) {
187: receiving = 1;
188: frompath = filepath(fromptr);
189: if (!knowhost(fromsiteptr)) {
190: fprintf(stderr,
191: "uucp: from site %s unknown\n", fromsiteptr);
192: exit(1);
193: }
194: }
195: strcpy(fromsite, fromsiteptr); fromsiteptr = fromsite;
196: if (strlen(fromsite) == 0 && strlen(tosite) == 0) {
197: if (debugflg > 1) {
198: fprintf(stderr, "Need to issue a cp right here\n");
199: fprintf(stderr, "cp %s %s\n", frompath, topath);
200: }
201: sprintf(argbuf, "cp %s %s", frompath, topath);
202: system(argbuf);
203: return;
204: }
205: strcpy(frompathbuf, frompath);
206: if (debugflg > 1)
207: fprintf(stderr,
208: "We are copying from site %s file %s to site %s file %s.\n",
209: fromsiteptr, frompathbuf, tositeptr, topath);
210: if (sending && receiving) {
211: if (strcmp (tosite, fromsite) == 0) {
212: sprintf(topathbuf, "(%s)", filepath(toptr));
213: strcpy(frompathbuf, fromptr);
214: sprintf(frompathbuf, "(%s)", filepath(frompathbuf));
215: } else {
216: sprintf(topathbuf, "(%s!%s)", thissite, toptr);
217: sprintf(frompathbuf, "(%s)", frompath);
218: }
219: return uuxit(fromsiteptr, frompathbuf, topathbuf);
220: } else if (complex(toptr)) {
221: sprintf(frompathbuf, "!%s", fromptr);
222: sprintf(topathbuf, "(%s)", filepath(toptr)); /* strip off first */
223: if (debugflg > 3)
224: fprintf(stderr, "complex to; %s, %s, %s\n",
225: tositeptr, frompathbuf, topathbuf);
226: return uuxit(tositeptr, frompathbuf, topathbuf);
227: } else if (complex(fromptr)) {
228: sprintf(topathbuf, "(%s!%s)", thissite, toptr);
229: sprintf(frompathbuf, "(%s)", frompath);
230: if (debugflg > 3)
231: fprintf(stderr, "complex fromptr: %s, %s, %s\n",
232: fromsiteptr, frompathbuf, topathbuf);
233: return uuxit(fromsiteptr, frompathbuf, topathbuf);
234: } else {
235: if (sending)
236: return send_file();
237: if (receiving) {
238: if (metacharacters(frompathbuf)) {
239: sprintf(topathbuf, "(%s!%s)", thissite, toptr);
240: return
241: uuxit(fromsiteptr, frompathbuf, topathbuf);
242: } else
243: return receive_file();
244: }
245: }
246: }
247:
248: encode_options()
249: {
250: strcpy(options, "-");
251: if (mkdirflg)
252: strcat (options, "d");
253: if (nocopyflg)
254: strcat(options, "c");
255: if (copyflg)
256: strcat(options, "C");
257: if (notifyflg)
258: strcat(options, "n");
259: if (mailflg)
260: strcat(options, "m");
261: }
262:
263: /*
264: * send one file.
265: * Return 1 if queuing was successful,
266: * 0 if any error.
267: */
268: int
269: send_file()
270: {
271: FILE *sourcefp, *datafp;
272: int c;
273: register int (*intfun)(), (*quitfun)();
274:
275: encode_options();
276: strcpy(fullfrompath, build_full_path(frompath));
277: if (stat(fullfrompath, &statbuf) == -1) {
278: fprintf(stderr, "uucp: Cannot stat %s.\n", fullfrompath);
279: return 0;
280: }
281: if (debugflg > 4)
282: fprintf(stderr,
283: "Send: frompath is %s, full is %s.\n", frompath, fullfrompath);
284: if (getcommandfile(tositeptr))
285: return 0;
286:
287: intfun = signal(SIGINT, SIG_IGN);
288: quitfun = signal(SIGQUIT, SIG_IGN);
289: seqno = getseq(tositeptr);
290: if (nocopyflg)
291: strcpy(spoolname, "D.0");
292: else {
293: sprintf(spoolname, "D.%s%c%04d", tositeptr, grade, seqno);
294: if (debugflg > 3) {
295: fprintf(stderr, "data file built is %s\n", spoolname);
296: fprintf(stderr,"mode: %o.\n",statbuf.st_mode & ~S_IFMT);
297: }
298: }
299: fprintf(commandfile, "S %s %s %s %s %s %o %s\n",
300: fullfrompath, topath, luser, options, spoolname,
301: statbuf.st_mode & ~S_IFMT, notifyusr);
302: if (nocopyflg == 0) {
303: sprintf(dirname, "%s/%s", spdir, tositeptr);
304: if (debugflg > 2)
305: fprintf(stderr, "Gotta copy\n");
306: sprintf(fsname, "%s/%s/%s", spdir, tositeptr, spoolname);
307: if ((!ckdir(dirname)) || (datafp = fopen(fsname, "w")) == NULL)
308: return cantopen("datafile", fsname);
309: if ((sourcefp = fopen(fullfrompath, "r")) == NULL)
310: return cantopen("fromfile", fullfrompath);
311: chmod(fsname, 0600);
312: while ((c = getc(sourcefp)) != EOF)
313: putc(c, datafp);
314: fclose(datafp);
315: fclose(sourcefp);
316: } else
317: strcpy(fsname, fullfrompath);
318: signal(SIGINT, intfun);
319: signal(SIGQUIT, quitfun);
320: return 1;
321: }
322:
323: cantopen(kind, which)
324: char *kind;
325: char *which;
326: {
327: fprintf(stderr, "uucp: Cannot open %s (%s)\n", which, kind);
328: return 1;
329: }
330:
331: /*
332: * receive_file
333: * Return 1 if queuing successful,
334: * 0 if not.
335: */
336: receive_file()
337: {
338: if (debugflg > 2)
339: fprintf(stderr, "Receive file\n");
340: copyflg = nocopyflg = notifyflg = 0;
341: encode_options();
342: strcpy(fulltopath, build_full_path(topath));
343: if (getcommandfile(fromsiteptr))
344: return 0;
345: seqno = getseq(fromsiteptr);
346: fprintf(commandfile, "R %s %s %s %s dummy\n",
347: frompathbuf, fulltopath, luser, options);
348: return 1;
349: }
350:
351: /*
352: * Handle send and receive forms of command.
353: * Command of the form "uucp a!b c!d".
354: * Send it off via uux to do at another location.
355: * of the form "c!uucp b <mysite>!c!d".
356: */
357: uuxit(cmdsite, from, to)
358: char *cmdsite;
359: char *from;
360: char *to;
361: {
362: int argx;
363: char *argv[30];
364: char debugdirm[64];
365: char debugbuf[64];
366: int waitstat;
367:
368: if (debugflg > 2)
369: fprintf(stderr, "uuxit(%s, %s, %s)\n",
370: cmdsite, from, to);
371: argx = 0;
372: argv[argx++] = "memeUUX";
373: if (debugflg > 0) {
374: sprintf(debugbuf, "-x%d", debugflg);
375: argv[argx++] = debugbuf;
376: }
377: /* if (nocicoflg) */ /* always turn off -r for intermediate site */
378: argv [argx++] = "-r";
379: if (debugdir) {
380: sprintf(debugdirm, "-S%s", spdir);
381: argv [argx++] = debugdirm;
382: }
383: sprintf(argbuf, "%s!uucp", cmdsite);
384: argv[argx++] = argbuf;
385: argv[argx++] = "-C";
386: if (mkdirflg)
387: argv[argx++] = "-d";
388: if (notifyflg) {
389: sprintf(argbuf1, "-n%s ", notifyusr);
390: argv[argx++] = argbuf1;
391: }
392: argv[argx++] = from;
393: sprintf(argbuf2, "%s", to);
394: argv[argx++] = argbuf2;
395: argv[argx++] = NULL;
396: if (debugflg > 3) {
397: argx = 0;
398: while (argv [argx] != NULL)
399: fprintf(stderr, "%s ", argv[argx++]);
400: fprintf(stderr, "\n");
401: }
402: if (fork() == 0 ) {
403: execvp("uux", argv);
404: exit(1);
405: } else
406: wait (&waitstat);
407: called_uux = 1;
408: return waitstat;
409: }
410:
411: getcommandfile(forwhich)
412: char *forwhich;
413: {
414: if (commandfile != NULL) {
415: if (strcmp(forwhich, commandsite) != 0)
416: finish_commandfile();
417: }
418: if (commandfile == NULL) {
419: if ((commandfile = fopen(mktemp(tempname), "w")) == NULL) {
420: fprintf(stderr, "uucp: can't open ");
421: perror(tempname);
422: return 1;
423: }
424: strcpy(commandsite, forwhich);
425: }
426: return 0;
427: }
428:
429: finish_commandfile()
430: {
431: static char buf[BUFSIZ];
432:
433: sprintf(buf, "%s/%s", spdir, commandsite);
434: if (!ckdir(buf)) {
435: fprintf(stderr, "Unable to make directory \"%s\"\n", buf);
436: exit(1);
437: }
438: sprintf(buf, "%s/%s/C.%.6s%c%04d",
439: spdir, commandsite, commandsite, grade, seqno);
440: if (debugflg > 1)
441: fprintf(stderr, "command file name is %s.\n", buf);
442: if (link(tempname, buf) == 0)
443: unlink(tempname);
444: else {
445: fprintf(stderr, "uucp: couldn't rename commandfile\n");
446: exit(1);
447: }
448: fclose (commandfile);
449: commandfile = NULL;
450: }
451:
452: char *filesite(name)
453: char *name;
454: {
455: static char site[SITELEN];
456: char *p;
457:
458: strcpy(site, name);
459: if ((p = index(site, '!')) == NULL)
460: return NULL;
461: *p = '\0';
462: return site;
463: }
464:
465: char *filepath(name)
466: char *name;
467: {
468: char *p;
469: static char site[SITELEN];
470: strcpy(site, name);
471: p = index(site, '!');
472: if (p == NULL)
473: return NULL;
474: return p + 1;
475: }
476:
477: char *basename(name)
478: char *name;
479: {
480: char *p;
481: if (NULL == (p = rindex(name, '/')))
482: return name;
483: else
484: return p + 1;
485: }
486:
487: char *
488: build_full_path(localpath)
489: char *localpath;
490: {
491: static char buf[BUFSIZ];
492: char *p;
493: if ((*localpath != '/') && (*localpath != '~')) {
494: strcpy(buf, p = getwd());
495: if (p == NULL) {
496: fprintf(stderr, "uucp: Unable to do getpwd\n");
497: exit(1);
498: }
499: strcat(buf, "/");
500: strcat(buf, localpath);
501: } else
502: strcpy(buf, localpath);
503: return buf;
504: }
505:
506: usage()
507: {
508: fatal("\n\
509: Usage: uucp [-dcmr] [-g grade] [-s dir] [-xnum] <fn> <fn> ... \n\
510: ");
511: }
512:
513: /*
514: * Return 1 if there are shell type metacharacters in the argument.
515: * Zero otherwise.
516: */
517: metacharacters(strin)
518: char *strin;
519: {
520: char *first;
521:
522: if (index(strin, '*') != NULL)
523: return 1;
524: if (index(strin, '?') != NULL)
525: return 1;
526: if (((first = index(strin, '[')) != NULL) && (index(first, ']') != NULL))
527: return 1;
528: return 0;
529: }
530:
531: complex(pathname)
532: char *pathname;
533: {
534: char *cp;
535:
536: if ((cp = index(pathname, '!')) != NULL) {
537: if (index (cp + 1, '!') != NULL)
538: return 1; /* more than one ! */
539: }
540: return 0;
541: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.