|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)uucp.c 5.8 (Berkeley) 4/24/88";
3: #endif
4:
5: #include "uucp.h"
6: #include <sys/stat.h>
7: #include "uust.h"
8:
9: /*
10: * uucp command
11: */
12:
13: int Uid;
14: char *Ropt = " ";
15: char Path[100], Optns[10], Ename[MAXBASENAME+1];
16: char Grade = 'n';
17: #ifdef DONTCOPY
18: int Copy = 0;
19: #else !DONTCOPY
20: int Copy = 1;
21: #endif !DONTCOPY
22: char Nuser[32];
23: struct timeb Now;
24:
25: /* variables used to check if talking to more than one system. */
26: int xsflag = -1;
27: char xsys[MAXBASENAME+1];
28:
29: long Nbytes = 0;
30: #define MAXBYTES 50000 /* maximun number of bytes of data per C. file */
31: #define MAXCOUNT 15 /* maximun number of files per C. file */
32:
33: main(argc, argv)
34: int argc;
35: char **argv;
36: {
37: char *sysfile1, *sysfl2;
38: register char *cp;
39: char file1[MAXFULLNAME], file2[MAXFULLNAME];
40: int avoidgwd = 0, c;
41: extern char *optarg;
42: extern int optind;
43:
44: strcpy(Progname, "uucp");
45: uucpname(Myname);
46: umask(WFMASK);
47: Optns[0] = '-';
48: Optns[1] = 'd';
49: #ifdef DONTCOPY
50: Optns[2] = 'c';
51: #else !DONTCOPY
52: Optns[2] = 'C';
53: #endif !DONTCOPY
54: Ename[0] = Nuser[0] = Optns[3] = '\0';
55: while((c = getopt(argc, argv, "aCcdfe:g:mn:rs:x:")) != EOF)
56: switch(c) {
57: case 'a':
58: /* efficiency hack; avoid gwd call */
59: avoidgwd = 1;
60: break;
61: case 'C':
62: Copy = 1;
63: Optns[2] = 'C';
64: break;
65: case 'c':
66: Copy = 0;
67: Optns[2] = 'c';
68: break;
69: case 'd':
70: break;
71: case 'f':
72: Optns[1] = 'f';
73: break;
74: case 'e':
75: strncpy(Ename, optarg, MAXBASENAME);
76: break;
77: case 'g':
78: Grade = *optarg;
79: break;
80: case 'm':
81: strcat(Optns, "m");
82: break;
83: case 'n':
84: sprintf(Nuser, "%.31s", optarg);
85: break;
86: case 'r':
87: Ropt = argv[optind-1];
88: break;
89: case 's':
90: Spool = optarg;
91: break;
92: case 'x':
93: chkdebug();
94: Debug = atoi(optarg);
95: if (Debug <= 0)
96: Debug = 1;
97: fprintf(stderr, "DEBUG %d\n", Debug);
98: break;
99: case '?':
100: default:
101: fprintf(stderr, "unknown flag %s\n", argv[optind-1]);
102: break;
103: }
104:
105: DEBUG(4, "\n\n** %s **\n", "START");
106: if (!avoidgwd) {
107: cp = getwd(Wrkdir);
108: if (cp == NULL) {
109: syslog(LOG_WARNING, "getwd failed");
110: cleanup(1);
111: }
112: }
113: if (subchdir(Spool) < 0) {
114: syslog(LOG_WARNING, "chdir(%s) failed: %m", Spool);
115: cleanup(1);
116: }
117:
118: Uid = getuid();
119: if (guinfo(Uid, User, Path) != SUCCESS) {
120: syslog(LOG_WARNING, "Can't find username for uid %d", Uid);
121: DEBUG(1, "Using username", "uucp");
122: strcpy(User, "uucp");
123: }
124: DEBUG(4, "UID %d, ", Uid);
125: DEBUG(4, "User %s,", User);
126: DEBUG(4, "Ename (%s) ", Ename);
127: DEBUG(4, "PATH %s\n", Path);
128: if (optind > (argc-2)) {
129: fprintf(stderr, "usage: uucp [flags] from... to\n");
130: cleanup(1);
131: }
132:
133:
134: /* set up "to" system and file names */
135: if ((cp = index(argv[--argc], '!')) != NULL) {
136: sysfl2 = argv[argc];
137: *cp = '\0';
138: if (*sysfl2 == '\0')
139: sysfl2 = Myname;
140: else
141: strncpy(Rmtname, sysfl2, MAXBASENAME);
142: if (versys(&sysfl2) != 0) {
143: fprintf(stderr, "bad system name: %s\n", sysfl2);
144: cleanup(1);
145: }
146: if (Rmtname[0] != '\0')
147: strncpy(Rmtname, sysfl2, MAXBASENAME);
148: /* block multi-hop requests immediately */
149: if (index(cp+1, '!') != NULL) {
150: fprintf(stderr, "uucp handles only adjacent sites.\n");
151: fprintf(stderr, "Try uusend for multi-hop delivery.\n");
152: cleanup(1);
153: }
154: strcpy(file2, cp + 1);
155: } else {
156: sysfl2 = Myname;
157: strcpy(file2, argv[argc]);
158: }
159: if (strlen(sysfl2) > MAXBASENAME)
160: sysfl2[MAXBASENAME] = '\0';
161:
162:
163: /* do each from argument */
164: while (optind < argc) {
165: if ((cp = index(argv[optind], '!')) != NULL) {
166: sysfile1 = argv[optind];
167: *cp = '\0';
168: if (strlen(sysfile1) > MAXBASENAME)
169: sysfile1[MAXBASENAME] = '\0';
170: if (*sysfile1 == '\0')
171: sysfile1 = Myname;
172: else
173: strncpy(Rmtname, sysfile1, MAXBASENAME);
174: if (versys(&sysfile1) != 0) {
175: fprintf(stderr, "bad system name: %s\n", sysfile1);
176: cleanup(1);
177: }
178: if (Rmtname[0] != '\0')
179: strncpy(Rmtname, sysfl2, MAXBASENAME);
180: strcpy(file1, cp + 1);
181: } else {
182: sysfile1 = Myname;
183: strcpy(file1, argv[optind]);
184: }
185: DEBUG(4, "file1 - %s\n", file1);
186: copy(sysfile1, file1, sysfl2, file2);
187: optind++;
188: }
189:
190: clscfile();
191: if (*Ropt != '-' && xsflag >= 0)
192: xuucico(xsys);
193: cleanup(0);
194: }
195:
196: cleanup(code)
197: int code;
198: {
199: logcls();
200: rmlock(CNULL);
201: if (code)
202: fprintf(stderr, "uucp failed. code %d\n", code);
203: exit(code);
204: }
205:
206:
207: /*
208: * generate copy files
209: *
210: * return codes 0 | FAIL
211: */
212:
213: copy(s1, f1, s2, f2)
214: register char *s1, *f1, *s2, *f2;
215: {
216: int type, statret;
217: struct stat stbuf, stbuf1;
218: char dfile[NAMESIZE];
219: char file1[MAXFULLNAME], file2[MAXFULLNAME];
220: FILE *cfp, *gtcfile();
221: char opts[100];
222:
223: type = 0;
224: opts[0] = '\0';
225: strcpy(file1, f1);
226: strcpy(file2, f2);
227: if (strcmp(s1, Myname) != SAME)
228: type = 1;
229: if (strcmp(s2, Myname) != SAME)
230: type += 2;
231: if (type & 01)
232: if ((index(f1, '*') != NULL
233: || index(f1, '?') != NULL
234: || index(f1, '[') != NULL))
235: type = 4;
236:
237: switch (type) {
238: case 0:
239: /* all work here */
240: DEBUG(4, "all work here %d\n", type);
241: if (ckexpf(file1))
242: return FAIL;
243: if (ckexpf(file2))
244: return FAIL;
245: if (stat(subfile(file1), &stbuf) != 0) {
246: fprintf(stderr, "can't get file status %s \n copy failed\n",
247: file1);
248: return SUCCESS;
249: }
250: statret = stat(subfile(file2), &stbuf1);
251: if (statret == 0
252: && stbuf.st_ino == stbuf1.st_ino
253: && stbuf.st_dev == stbuf1.st_dev) {
254: fprintf(stderr, "%s %s - same file; can't copy\n", file1, file2);
255: return SUCCESS;
256: }
257: if (chkpth(User, "", file1) != 0
258: || chkperm(file2, index(Optns, 'd'))
259: || chkpth(User, "", file2) != 0) {
260: fprintf(stderr, "permission denied\n");
261: cleanup(1);
262: }
263: if ((stbuf.st_mode & ANYREAD) == 0) {
264: fprintf(stderr, "can't read file (%s) mode (%o)\n",
265: file1, (int)stbuf.st_mode);
266: return FAIL;
267: }
268: if (statret == 0 && (stbuf1.st_mode & ANYWRITE) == 0) {
269: fprintf(stderr, "can't write file (%s) mode (%o)\n",
270: file2, (int)stbuf.st_mode);
271: return FAIL;
272: }
273: xcp(file1, file2);
274: /* With odd umask() might not be able to read it himself */
275: (void) chmod(file2, 0666);
276: logent("WORK HERE", "DONE");
277: return SUCCESS;
278: case 1:
279: /* receive file */
280: DEBUG(4, "receive file - %d\n", type);
281: chsys(s1);
282: if (file1[0] != '~')
283: if (ckexpf(file1))
284: return FAIL;
285: if (ckexpf(file2))
286: return FAIL;
287: if (chkpth(User, "", file2) != 0) {
288: fprintf(stderr, "permission denied\n");
289: return FAIL;
290: }
291: if (Ename[0] != '\0') {
292: /* execute uux - remote uucp */
293: xuux(Ename, s1, file1, s2, file2, opts);
294: return SUCCESS;
295: }
296:
297: cfp = gtcfile(s1);
298: fprintf(cfp, "R %s %s %s %s\n", file1, file2, User, Optns);
299: break;
300: case 2:
301: /* send file */
302: if (ckexpf(file1))
303: return FAIL;
304: if (file2[0] != '~')
305: if (ckexpf(file2))
306: return FAIL;
307: DEBUG(4, "send file - %d\n", type);
308: chsys(s2);
309:
310: if (chkpth(User, "", file1) != 0) {
311: fprintf(stderr, "permission denied %s\n", file1);
312: return FAIL;
313: }
314: if (stat(subfile(file1), &stbuf) != 0) {
315: fprintf(stderr, "can't get status for file %s\n", file1);
316: return FAIL;
317: }
318: if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
319: fprintf(stderr, "directory name illegal - %s\n",
320: file1);
321: return FAIL;
322: }
323: if ((stbuf.st_mode & ANYREAD) == 0) {
324: fprintf(stderr, "can't read file (%s) mode (%o)\n",
325: file1, (int)stbuf.st_mode);
326: return FAIL;
327: }
328: if ((Nuser[0] != '\0') && (index(Optns, 'n') == NULL))
329: strcat(Optns, "n");
330: if (Ename[0] != '\0') {
331: /* execute uux - remote uucp */
332: if (Nuser[0] != '\0')
333: sprintf(opts, "-n%s", Nuser);
334: xuux(Ename, s1, file1, s2, file2, opts);
335: return SUCCESS;
336: }
337: Nbytes += stbuf.st_size;
338: if (Copy) {
339: gename(DATAPRE, Myname, Grade, dfile);
340: if (xcp(file1, dfile) != 0) {
341: fprintf(stderr, "can't copy %s\n", file1);
342: return FAIL;
343: }
344: }
345: else {
346: /* make a dummy D. name */
347: /* cntrl.c knows names < 6 chars are dummy D. files */
348: strcpy(dfile, "D.0");
349: }
350: cfp = gtcfile(s2);
351: fprintf(cfp, "S %s %s %s %s %s %o %s\n", file1, file2,
352: User, Optns, dfile, (int)stbuf.st_mode & 0777, Nuser);
353: break;
354: case 3:
355: case 4:
356: /* send uucp command for execution on s1 */
357: DEBUG(4, "send uucp command - %d\n", type);
358: chsys(s1);
359: if (strcmp(s2, Myname) == SAME) {
360: if (ckexpf(file2))
361: return FAIL;
362: if (chkpth(User, "", file2) != 0) {
363: fprintf(stderr, "permission denied\n");
364: return FAIL;
365: }
366: }
367: if (Ename[0] != '\0') {
368: /* execute uux - remote uucp */
369: xuux(Ename, s1, file1, s2, file2, opts);
370: return SUCCESS;
371: }
372: cfp = gtcfile(s1);
373: fprintf(cfp, "X %s %s!%s %s %s\n", file1, s2, file2, User, Optns);
374: break;
375: }
376: return SUCCESS;
377: }
378:
379: /*
380: * execute uux for remote uucp
381: *
382: * return code - none
383: */
384:
385: xuux(ename, s1, f1, s2, f2, opts)
386: char *ename, *s1, *s2, *f1, *f2, *opts;
387: {
388: char cmd[200];
389:
390: DEBUG(4, "Ropt(%s) ", Ropt);
391: DEBUG(4, "ename(%s) ", ename);
392: DEBUG(4, "s1(%s) ", s1);
393: DEBUG(4, "f1(%s) ", f1);
394: DEBUG(4, "s2(%s) ", s2);
395: DEBUG(4, "f2(%s)\n", f2);
396: sprintf(cmd, "uux %s %s!uucp %s %s!%s \\(%s!%s\\)",
397: Ropt, ename, opts, s1, f1, s2, f2);
398: DEBUG(4, "cmd (%s)\n", cmd);
399: system(cmd);
400: return;
401: }
402:
403: FILE *Cfp = NULL;
404: char Cfile[NAMESIZE];
405:
406: /*
407: * get a Cfile descriptor
408: *
409: * return an open file descriptor
410: */
411:
412: FILE *
413: gtcfile(sys)
414: register char *sys;
415: {
416: static char presys[8] = "";
417: static int cmdcount = 0;
418: register int savemask;
419:
420: if (strcmp(presys, sys) != SAME /* this is !SAME on first call */
421: || Nbytes > MAXBYTES
422: || ++cmdcount > MAXCOUNT) {
423: cmdcount = 1;
424: Nbytes = 0;
425: if (presys[0] != '\0') {
426: clscfile();
427: }
428: gename(CMDPRE, sys, Grade, Cfile);
429: #ifdef VMS
430: savemask = umask(~0600); /* vms must have read permission */
431: #else !VMS
432: savemask = umask(~0200);
433: #endif !VMS
434: Cfp = fopen(subfile(Cfile), "w");
435: umask(savemask);
436: if (Cfp == NULL) {
437: syslog(LOG_WARNING, "fopen(%s) failed: %m",
438: subfile(Cfile));
439: cleanup(1);
440: }
441: strcpy(presys, sys);
442: }
443: return Cfp;
444: }
445:
446: /*
447: * close cfile
448: *
449: * return code - none
450: */
451:
452: clscfile()
453: {
454: if (Cfp == NULL)
455: return;
456: fclose(Cfp);
457: chmod(subfile(Cfile), ~WFMASK & 0777);
458: logent(Cfile, "QUE'D");
459: US_CRS(Cfile);
460: Cfp = NULL;
461: }
462:
463: /*
464: * compile a list of all systems we are referencing
465: */
466: chsys(s1)
467: register char *s1;
468: {
469: if (xsflag < 0)
470: xsflag = 0;
471: else if (xsflag > 0)
472: return;
473:
474: if (xsys[0] == '\0') {
475: strncpy(xsys, s1, MAXBASENAME);
476: return;
477: }
478:
479: if (strncmp(xsys, s1, MAXBASENAME) == SAME)
480: return;
481:
482: xsflag++;
483: xsys[0] = '\0';
484: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.