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