|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)uusend.c 5.1 (Berkeley) 7/2/83"; ! 3: #endif ! 4: ! 5: /* ! 6: * uusend: primitive operation to allow uucp like copy of binary files ! 7: * but handle indirection over systems. ! 8: * ! 9: * usage: uusend [-r] [-m ooo] localfile sysname1!sysname2!...!destfile ! 10: * uusend [-r] [-m ooo] - sysname1!sysname2!...!destfile ! 11: * ! 12: * Author: Mark Horton, May 1980. ! 13: * ! 14: * "-r" switch added. Has same effect as "-r" in uux. 11/82 CCW ! 15: * ! 16: * Error recovery (a la uucp) added & ifdefs for ruusend (as in rmail). ! 17: * Checks for illegal access to /usr/lib/uucp. ! 18: * February 1983 Christopher Woodbury ! 19: * Fixed mode set[ug]id loophole. 4/8/83 CCW ! 20: * ! 21: * Add '-f' to make uusend syntax more similar to UUCP. "destname" ! 22: * can now be a directory. June 1983 CCW ! 23: */ ! 24: ! 25: #include <stdio.h> ! 26: #include <pwd.h> ! 27: #include <sys/types.h> ! 28: #include <sys/stat.h> ! 29: ! 30: #define RECOVER ! 31: ! 32: FILE *in, *out; ! 33: FILE *dout; ! 34: ! 35: FILE *popen(); ! 36: char *index(), *strcpy(); ! 37: ! 38: #ifdef RUUSEND ! 39: int rsend; ! 40: #endif ! 41: int mode = -1; /* mode to chmod new file to */ ! 42: char *nextsys; /* next system in the chain */ ! 43: char dnbuf[200]; /* buffer for result of ~user/file */ ! 44: char cmdbuf[256]; /* buffer to build uux command in */ ! 45: char *rflg = ""; /* default value of rflg ccw -- 1 Nov '82 */ ! 46: ! 47: struct passwd *user; /* entry in /etc/passwd for ~user */ ! 48: struct passwd *getpwnam(); ! 49: struct stat stbuf; ! 50: ! 51: char *excl; /* location of first ! in destname */ ! 52: char *sl; /* location of first / in destname */ ! 53: char *sourcename; /* argv[1] */ ! 54: char *destname; /* argv[2] */ ! 55: char *UULIB = "/usr/lib/uucp"; /* UUCP lib directory */ ! 56: ! 57: #ifdef RECOVER ! 58: char *UUPUB = "/usr/spool/uucppublic/"; /* public UUCP directory */ ! 59: char *filename; /* file name from end of destname */ ! 60: char *getfname(); /* routine to get filename from destname */ ! 61: int fflg; ! 62: char f[100]; /* name of default output file */ ! 63: #else ! 64: char *f = ""; /* so we waste a little space */ ! 65: #endif ! 66: ! 67: main(argc, argv) ! 68: int argc; ! 69: char **argv; ! 70: { ! 71: register int c; ! 72: long count = 0; ! 73: ! 74: #ifdef DEBUG ! 75: long t; ! 76: dout = fopen(DEBUG, "a"); ! 77: if (dout == NULL) { ! 78: printf("Cannot append to %s\n", DEBUG); ! 79: exit(1); ! 80: } ! 81: freopen(DEBUG, "a", stdout); ! 82: /*xxx ! 83: freopen(DEBUG, "a", stderr); ! 84: xxx*/ ! 85: chmod(DEBUG, 0666); ! 86: fprintf(dout, "\nuusend run: "); ! 87: for (c=0; c<argc; c++) ! 88: fprintf(dout, "%s ", argv[c]); ! 89: time(&t); ! 90: fprintf(dout, "%s", ctime(&t)); ! 91: #endif ! 92: ! 93: #ifdef RUUSEND ! 94: if(argv[0][0] == 'r') ! 95: rsend++; ! 96: #endif ! 97: while (argc > 1 && argv[1][0] == '-' && argv[1][1]) { ! 98: switch(argv[1][1]) { ! 99: case 'm': ! 100: sscanf(argv[2], "%o", &mode); ! 101: mode &= 0777; /* fix set[ug]id loophole */ ! 102: argc--; argv++; ! 103: break; ! 104: case 'r': /* -r flag for uux */ ! 105: rflg = "-r "; ! 106: break; ! 107: #ifdef RECOVER ! 108: case 'f': ! 109: fflg++; ! 110: strcpy(f, argv[1]); ! 111: break; ! 112: #endif ! 113: default: ! 114: fprintf(stderr, "Bad flag: %s\n", argv[1]); ! 115: break; ! 116: } ! 117: argc--; argv++; ! 118: } ! 119: ! 120: if (argc != 3) { ! 121: fprintf(stderr, "Usage: uusend [-m ooo] [-r] -/file sys!sys!..!rfile\n"); ! 122: exit(1); ! 123: } ! 124: ! 125: sourcename = argv[1]; ! 126: destname = argv[2]; ! 127: ! 128: if (sourcename[0] == '-') ! 129: in = stdin; ! 130: else { ! 131: #ifdef RUUSEND ! 132: if (rsend) { ! 133: fprintf(stderr, "illegal input\n"); ! 134: exit(2); ! 135: } ! 136: #endif ! 137: in = fopen(sourcename, "r"); ! 138: if (in == NULL) { ! 139: perror(argv[1]); ! 140: exit(2); ! 141: } ! 142: if (!fflg || f[2] == '\0') { ! 143: strcpy(f, "-f"); ! 144: strcat(f, getfname(sourcename)); ! 145: fflg++; ! 146: } ! 147: } ! 148: ! 149: excl = index(destname, '!'); ! 150: if (excl) { ! 151: /* ! 152: * destname is on a remote system. ! 153: */ ! 154: nextsys = destname; ! 155: *excl++ = 0; ! 156: destname = excl; ! 157: if (mode < 0) { ! 158: fstat(fileno(in), &stbuf); ! 159: mode = stbuf.st_mode & 0777; ! 160: } ! 161: #ifdef RUUSEND ! 162: sprintf(cmdbuf,"uux %s- \"%s!ruusend %s -m %o - (%s)\"", ! 163: #else ! 164: sprintf(cmdbuf, "uux %s- \"%s!uusend %s -m %o - (%s)\"", ! 165: #endif ! 166: rflg, nextsys, f, mode, destname); ! 167: #ifdef DEBUG ! 168: fprintf(dout, "remote: nextsys='%s', destname='%s', cmd='%s'\n", nextsys, destname, cmdbuf); ! 169: #endif ! 170: out = popen(cmdbuf, "w"); ! 171: } else { ! 172: /* ! 173: * destname is local. ! 174: */ ! 175: if (destname[0] == '~') { ! 176: #ifdef DEBUG ! 177: fprintf(dout, "before ~: '%s'\n", destname); ! 178: fflush(dout); ! 179: #endif ! 180: sl = index(destname, '/'); ! 181: #ifdef RECOVER ! 182: if (sl == NULL && !fflg) { ! 183: fprintf(stderr, "Illegal ~user\n"); ! 184: exit(3); ! 185: } ! 186: for (sl = destname; *sl != '\0'; sl++) ! 187: ; /* boy, is this a hack! */ ! 188: #else ! 189: if (sl == NULL) { ! 190: fprintf(stderr, "Illegal ~user\n"); ! 191: exit(3); ! 192: } ! 193: *sl++ = 0; ! 194: #endif ! 195: user = getpwnam(destname+1); ! 196: if (user == NULL) { ! 197: fprintf(stderr, "No such user as %s\n", ! 198: destname); ! 199: #ifdef RECOVER ! 200: if ((filename =getfname(sl)) == NULL && ! 201: !fflg) ! 202: exit(4); ! 203: strcpy(dnbuf, UUPUB); ! 204: if (fflg) ! 205: strcat(dnbuf, &f[2]); ! 206: else ! 207: strcat(dnbuf, filename); ! 208: } ! 209: else { ! 210: strcpy(dnbuf, user->pw_dir); ! 211: strcat(dnbuf, "/"); ! 212: strcat(dnbuf, sl); ! 213: } ! 214: #else ! 215: exit(4); ! 216: } ! 217: strcpy(dnbuf, user->pw_dir); ! 218: strcat(dnbuf, "/"); ! 219: strcat(dnbuf, sl); ! 220: #endif ! 221: destname = dnbuf; ! 222: } ! 223: #ifdef RECOVER ! 224: else ! 225: destname = strcpy(dnbuf, destname); ! 226: #endif ! 227: if(strncmp(UULIB, destname, strlen(UULIB)) == 0) { ! 228: fprintf(stderr, "illegal file: %s", destname); ! 229: exit(4); ! 230: } ! 231: #ifdef RECOVER ! 232: if (stat(destname, &stbuf) == 0 && ! 233: (stbuf.st_mode & S_IFMT) == S_IFDIR && ! 234: fflg) { ! 235: strcat(dnbuf, "/"); ! 236: strcat(dnbuf, &f[2]); ! 237: } ! 238: #endif ! 239: out = fopen(destname, "w"); ! 240: #ifdef DEBUG ! 241: fprintf(dout, "local, file='%s'\n", destname); ! 242: #endif ! 243: if (out == NULL) { ! 244: perror(destname); ! 245: #ifdef RECOVER ! 246: if (strncmp(destname,UUPUB,strlen(UUPUB)) == 0) ! 247: exit(5); /* forget it! */ ! 248: filename = getfname(destname); ! 249: if (destname == dnbuf) /* cmdbuf is scratch */ ! 250: filename = strcpy(cmdbuf, filename); ! 251: destname = strcpy(dnbuf, UUPUB); ! 252: if (user != NULL) { ! 253: strcat(destname, user->pw_name); ! 254: if (stat(destname, &stbuf) == -1) { ! 255: mkdir(destname); ! 256: chmod(destname, 0777); ! 257: } ! 258: strcat(destname, "/"); ! 259: } ! 260: #ifdef RECOVER ! 261: if (fflg) ! 262: strcat(destname, &f[2]); ! 263: else ! 264: strcat(destname, filename); ! 265: #endif ! 266: if ((out = fopen(destname, "w")) == NULL) ! 267: exit(5); /* all for naught! */ ! 268: #else ! 269: exit(5); ! 270: #endif ! 271: } ! 272: if (mode > 0) ! 273: chmod(destname, mode); /* don't bother to check it */ ! 274: } ! 275: ! 276: /* ! 277: * Now, in any case, copy from in to out. ! 278: */ ! 279: ! 280: while ((c=getc(in)) != EOF) { ! 281: putc(c, out); ! 282: count++; ! 283: } ! 284: #ifdef DEBUG ! 285: fprintf(dout, "count %ld bytes\n", count); ! 286: fclose(dout); ! 287: #endif ! 288: ! 289: fclose(in); ! 290: fclose(out); /* really should pclose in that case */ ! 291: exit(0); ! 292: } ! 293: ! 294: /* ! 295: * Return the ptr in sp at which the character c appears; ! 296: * NULL if not found. Included so I don't have to fight the ! 297: * index/strchr battle. ! 298: */ ! 299: ! 300: #define NULL 0 ! 301: ! 302: char * ! 303: index(sp, c) ! 304: register char *sp, c; ! 305: { ! 306: do { ! 307: if (*sp == c) ! 308: return(sp); ! 309: } while (*sp++); ! 310: return(NULL); ! 311: } ! 312: ! 313: #ifdef RECOVER ! 314: char * ! 315: getfname(p) ! 316: register char *p; ! 317: { ! 318: register char *s; ! 319: s = p; ! 320: while (*p != '\0') ! 321: p++; ! 322: if (p == s) ! 323: return (NULL); ! 324: for (;p != s; p--) ! 325: if (*p == '/') { ! 326: p++; ! 327: break; ! 328: } ! 329: return (p); ! 330: } ! 331: ! 332: mkdir(dirname) ! 333: char *dirname; ! 334: { ! 335: register int pid; ! 336: int retcode, status; ! 337: switch ((pid = fork())) { ! 338: case -1: /* error */ ! 339: return (-1); ! 340: break; ! 341: case 0: /* child */ ! 342: umask(0); ! 343: execl("/bin/mkdir", "mkdir", dirname, 0); ! 344: exit(1); ! 345: break; ! 346: default: /* parent */ ! 347: while ((retcode=wait(&status)) != pid && retcode != -1) ! 348: ; ! 349: if (retcode == -1) ! 350: return (-1); ! 351: else ! 352: return (status); ! 353: break; ! 354: } ! 355: } ! 356: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.