1: /* 2: * uusend: primitive operation to allow uucp like copy of binary files 3: * but handle indirection over systems. 4: * 5: * usage: uusend [-m ooo] localfile sysname1!sysname2!...!destfile 6: * uusend [-m ooo] - sysname1!sysname2!...!destfile 7: * 8: * Author: Mark Horton, May 1980. 9: */ 10: 11: #include <stdio.h> 12: #include <pwd.h> 13: #include <sys/types.h> 14: #include <sys/stat.h> 15: static char *sccsid = "@(#)uusend.c 1.1"; 16: 17: /* #define DEBUG "/usr/spool/uucp/uusend.log" */ 18: 19: FILE *in, *out; 20: FILE *dout; 21: 22: FILE *popen(); 23: char *index(); 24: 25: int mode = -1; /* mode to chmod new file to */ 26: char nextsys[20]; /* next system in the chain */ 27: char dnbuf[200]; /* buffer for result of ~user/file */ 28: char cmdbuf[256]; /* buffer to build uux command in */ 29: 30: struct passwd *user; /* entry in /etc/passwd for ~user */ 31: struct passwd *getpwnam(); 32: struct stat stbuf; 33: 34: char *excl; /* location of first ! in destname */ 35: char *sl; /* location of first / in destname */ 36: char *sourcename; /* argv[1] */ 37: char *destname; /* argv[2] */ 38: 39: main(argc, argv) 40: int argc; 41: char **argv; 42: { 43: register int c; 44: register int count = 0; 45: 46: #ifdef DEBUG 47: long t; 48: dout = fopen(DEBUG, "a"); 49: if (dout == NULL) { 50: printf("Cannot append to %s\n", DEBUG); 51: exit(1); 52: } 53: freopen(DEBUG, "a", stdout); 54: freopen(DEBUG, "a", stderr); 55: chmod(DEBUG, 0666); 56: fprintf(dout, "\nuusend run: "); 57: for (c=0; c<argc; c++) 58: fprintf(dout, "%s ", argv[c]); 59: time(&t); 60: fprintf(dout, "%s", ctime(&t)); 61: #endif 62: while (argc > 1 && argv[1][0] == '-' && argv[1][1]) { 63: switch(argv[1][1]) { 64: case 'm': 65: sscanf(argv[2], "%o", &mode); 66: argc--; argv++; 67: break; 68: default: 69: fprintf(stderr, "Bad flag: %s\n", argv[1]); 70: break; 71: } 72: argc--; argv++; 73: } 74: 75: if (argc != 3) { 76: fprintf(stderr, "Usage: uusend [-m ooo] -/file sys!sys!..!rfile\n"); 77: exit(1); 78: } 79: 80: sourcename = argv[1]; 81: destname = argv[2]; 82: 83: if (sourcename[0] == '-') 84: in = stdin; 85: else { 86: in = fopen(sourcename, "r"); 87: if (in == NULL) { 88: perror(argv[1]); 89: exit(2); 90: } 91: } 92: 93: excl = index(destname, '!'); 94: if (excl) { 95: /* 96: * destname is on a remote system. 97: */ 98: strncpy(nextsys, destname, excl-destname); 99: nextsys[excl-destname] = 0; 100: destname = excl+1; 101: if (mode < 0) { 102: fstat(fileno(in), &stbuf); 103: mode = stbuf.st_mode & 0777; 104: } 105: sprintf(cmdbuf, "uux - \"%s!uusend -m %o - \(%s\)\"", 106: nextsys, mode, destname); 107: #ifdef DEBUG 108: fprintf(dout, "remote: nextsys='%s', destname='%s', cmd='%s'\n", nextsys, destname, cmdbuf); 109: #endif 110: out = popen(cmdbuf, "w"); 111: } else { 112: /* 113: * destname is local. 114: */ 115: if (destname[0] == '~') { 116: #ifdef DEBUG 117: fprintf(dout, "before ~: '%s'\n", destname); 118: #endif 119: sl = index(destname, '/'); 120: if (sl == NULL) { 121: fprintf(stderr, "Illegal ~user\n"); 122: exit(3); 123: } 124: *sl++ = 0; 125: user = getpwnam(destname+1); 126: if (user == NULL) { 127: fprintf(stderr, "No such user as %s\n", destname); 128: exit(4); 129: } 130: strcpy(dnbuf, user->pw_dir); 131: strcat(dnbuf, "/"); 132: strcat(dnbuf, sl); 133: destname = dnbuf; 134: } 135: out = fopen(destname, "w"); 136: #ifdef DEBUG 137: fprintf(dout, "local, file='%s'\n", destname); 138: #endif 139: if (out == NULL) { 140: perror(destname); 141: exit(5); 142: } 143: if (mode > 0) 144: chmod(destname, mode); /* don't bother to check it */ 145: } 146: 147: /* 148: * Now, in any case, copy from in to out. 149: */ 150: 151: while ((c=getc(in)) != EOF) { 152: putc(c, out); 153: count++; 154: } 155: #ifdef DEBUG 156: fprintf(dout, "count %d bytes\n", count); 157: fclose(dout); 158: #endif 159: 160: fclose(in); 161: fclose(out); /* really should pclose in that case */ 162: exit(0); 163: } 164: 165: /* 166: * Return the ptr in sp at which the character c appears; 167: * NULL if not found. Included so I don't have to fight the 168: * index/strchr battle. 169: */ 170: 171: #define NULL 0 172: 173: char * 174: index(sp, c) 175: register char *sp, c; 176: { 177: do { 178: if (*sp == c) 179: return(sp); 180: } while (*sp++); 181: return(NULL); 182: }