# 2.11BSD#431 - /usr/src/usr.bin/uucp/uusend.c

##### Functions

    getfname          X
    index             X
    main              X
    makedir           X

##### Variables

    UULIB             X
    UUPUB             X
    cmdbuf            X
    destname          X
    dnbuf             X
    excl              X
    f                 X
    fflg              X
    filename          X
    mode              X
    nextsys           X
    rflg              X
    rsend             X
    sl                X
    sourcename        X
    stbuf             X
    user              X

##### Macros

    NULL              X
    RECOVER           X

       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

- in line 68, 150, 206, 254

index defined in line 306; used 3 times

- in line 44, 155, 186

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

- in line 209, 252-257(3)

cmdbuf defined in line 52; used 5 times

- in line 168-176(4), 256

destname defined in line 62; used 35 times

- in line 132, 155-162(3), 172-174(2), 181-186(3), 192, 201-204(2), 227-269(22), 276

dnbuf defined in line 51; used 13 times

- in line 209-231(11), 255-257(2)

excl defined in line 59; used 4 times

- in line 155-162(4)

f defined in line 72; used 8 times

- in line 116, 148-150(3), 172, 211, 242, 266

fflg defined in line 69; used 8 times

- in line 115, 148-151(2), 188, 207-210(2), 240, 265

filename defined in line 67; used 6 times

- in line 206, 213, 254-256(3), 268

mode defined in line 49; used 10 times

- in line 106-107(2), 163-165(2), 172, 275-276(2), 337-339(2), 357

nextsys defined in line 50; used 3 times

- in line 160, 172-174(2)

rflg defined in line 53; used 2 times

- in line 111, 172

rsend defined in line 47; used 2 times

- in line 101, 138

sccsid defined in line 2; never used
sl defined in line 60; used 10 times

- in line 186-199(7), 206, 218, 225

sourcename defined in line 61; used 4 times

- in line 131-134(2), 143, 150

stbuf defined in line 57; used 5 times

- in line 164-165(2), 238-239(2), 260

user defined in line 55; used 6 times

- in line 201-202(2), 216, 223, 258-259(2)

#### Defined macros

NULL defined in line 304; used 11 times

- in line 87, 144, 188, 195, 202-206(2), 249, 258, 269, 314, 327

RECOVER defined in line 37; used 12 times

- in line 65, 71, 113, 187, 194, 205, 220, 229, 237, 251, 271, 317

Last modified: 1996-10-24 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1302 |