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