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

Defined functions

getfname defined in line 318; used 4 times
index defined in line 306; used 3 times
main defined in line 75; never used
makedir defined in line 337; never used

Defined variables

UULIB defined in line 63; used 2 times
  • in line 233(2)
UUPUB defined in line 66; used 4 times
cmdbuf defined in line 52; used 5 times
destname defined in line 62; used 35 times
dnbuf defined in line 51; used 13 times
excl defined in line 59; used 4 times
f defined in line 72; used 8 times
fflg defined in line 69; used 8 times
filename defined in line 67; used 6 times
mode defined in line 49; used 10 times
nextsys defined in line 50; used 3 times
rflg defined in line 53; used 2 times
rsend defined in line 47; used 2 times
sccsid defined in line 2; never used
sl defined in line 60; used 10 times
sourcename defined in line 61; used 4 times
stbuf defined in line 57; used 5 times
user defined in line 55; used 6 times

Defined macros

NULL defined in line 304; used 11 times
RECOVER defined in line 37; used 12 times
Last modified: 1996-10-24
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 210
Valid CSS Valid XHTML 1.0 Strict