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

Defined functions

getfname defined in line 314; used 4 times
index defined in line 302; used 3 times
main defined in line 67; never used
mkdir defined in line 332; used 1 times

Defined variables

UULIB defined in line 55; used 2 times
  • in line 227(2)
UUPUB defined in line 58; used 4 times
cmdbuf defined in line 44; used 5 times
destname defined in line 54; used 34 times
dnbuf defined in line 43; used 15 times
excl defined in line 51; used 4 times
f defined in line 64; used 8 times
fflg defined in line 61; used 8 times
filename defined in line 59; used 6 times
mode defined in line 41; used 7 times
nextsys defined in line 42; used 3 times
rflg defined in line 45; used 2 times
rsend defined in line 39; used 2 times
sccsid defined in line 2; never used
sl defined in line 52; used 10 times
sourcename defined in line 53; used 4 times
stbuf defined in line 49; used 5 times
user defined in line 47; used 6 times

Defined macros

NULL defined in line 300; used 11 times
RECOVER defined in line 30; used 9 times
Last modified: 1983-07-03
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1433
Valid CSS Valid XHTML 1.0 Strict