Annotation of 40BSD/cmd/berknet/sub.c, revision 1.1.1.1

1.1       root        1: /*
                      2:        sub.c
                      3: 
                      4:        support procedures
                      5: 
                      6:        the following procedures end up reading the passwd file
                      7:        or the passwdf file and are to be avoided.
                      8: 
                      9:        getpwuid(uid)
                     10:        getpwnam(sn)
                     11:        PwdCurrent()
                     12:        getenv("HOME")          maybe if hget, hgethome don't work
                     13:        SnFromUid(uid)          maybe if hashed passwd stuff doesn't work
                     14:        SnCurrent()             maybe if getlogin fails calls SnFromUid(uid)
                     15:        getpwf()
                     16:        passwdent(uid,sn)
                     17: */
                     18: 
                     19: # include "defs.h"
                     20: # include "config.h"
                     21: 
                     22: /* global variables */
                     23: int debugflg = DBV;    /* debug flag */
                     24: char local = LOCAL;    /* the machine we're on */
                     25: struct userinfo status;
                     26: 
                     27: char netcmd[]  =       NETCMD;
                     28: char resfile[] =       RESFILE;
                     29: char senddir[] =       SENDDIR;
                     30: char Bsh[] =           BINSH;
                     31: 
                     32: char shomedir[100];
                     33: 
                     34: /*
                     35:        passwdent()
                     36: 
                     37:        Read the password file looking for current user's entry.
                     38:        Fill in the status structure.
                     39:        Has the (dangerous) side effect of giving a value to getenv("HOME").
                     40: */
                     41: passwdent()
                     42: {
                     43:        register char *u;
                     44:        register struct passwd *pwd;
                     45:        pwd = PwdCurrent();
                     46:        if(pwd == NULL){
                     47:                err("Bad uid/username\n");
                     48:                return;
                     49:        }
                     50:        strcpy(status.localname,pwd->pw_name);
                     51:        status.muid = guid(pwd->pw_uid,pwd->pw_gid);
                     52:        status.mgid = pwd->pw_gid;
                     53:        if(isdigit(pwd->pw_gecos[0]))status.jobno = atoi(pwd->pw_gecos);
                     54:        else status.jobno = 32767;
                     55:        strcpy(status.dir,pwd->pw_dir);
                     56:        strcpy(shomedir,pwd->pw_dir);           /* side effect */
                     57:        u = pwd->pw_shell;
                     58:        if(u[0] == 0 || strcmp(u,"/bin/sbash") == 0)u= Bsh;
                     59:        strcpy(status.loginshell,u);
                     60:        }
                     61: /*
                     62:        promptlogin(mchto)
                     63: 
                     64:        ask user for login and passwd on mchto.
                     65:        make sure status.localname has a value before calling
                     66:        this.  One way is to call passwdent().
                     67: */
                     68: promptlogin(mchto)
                     69:        char mchto;
                     70: {
                     71:        char buf[BUFSIZ], mch;
                     72:        FILE *wf;
                     73:        int c;
                     74:        if(status.mpasswd[0] == 0 || status.login[0] == 0 || status.force){
                     75:                wf = fopen("/dev/tty","r");
                     76:                if(wf != NULL){
                     77:                        if(status.login[0]==0 || status.force){
                     78:                                fprintf(stderr,"Name (%s:%s): ",longname(mchto),
                     79:                                        status.localname);
                     80:                                if(fgets(buf, BUFSIZ, wf) != buf){
                     81:                                        perror("fgets");
                     82:                                        exit(EX_OSERR);
                     83:                                        }
                     84:                                c = strlen(buf);
                     85:                                buf[c > 0 ? c-1 : 0] = 0;
                     86:                                if(c > 10){
                     87:                                        err("Login name too long.\n");
                     88:                                        exit(EX_USAGE);
                     89:                                        }
                     90:                                if(FMemberSCh(buf,' ')){
                     91:                                        err("Login names don't have blanks in them.\n");
                     92:                                        exit(EX_USAGE);
                     93:                                        }
                     94:                                if(buf[0] == 0)strcpy(buf,status.localname);
                     95:                                mch = MchSFromAddr(status.login,buf);
                     96:                                if(mch != local && mch != mchto){
                     97:                                        err(
                     98:                                "Must specify login name on %s machine\n",
                     99:                                                longname(mchto));
                    100:                                        exit(EX_USAGE);
                    101:                                }
                    102:                        }
                    103:                        if(strcmp(status.login,"network") != 0
                    104:                                && (status.mpasswd[0]== 0 || status.force)){
                    105:                                sprintf(buf,"Password (%s:%s):",
                    106:                                        longname(mchto), status.login);
                    107:                                strcpy(status.mpasswd,getpass(buf));
                    108:                                }
                    109:                        fclose(wf);
                    110:                        }
                    111:                }
                    112:        if(status.login[0] == 0) strcpy(status.login,status.localname);
                    113:        if(status.mpasswd[0] == 0)strcpy(status.mpasswd,"\"\"");
                    114:        status.force = 0;
                    115:        }
                    116: 
                    117: #define        tst(a,b)        (*mode == 'r'? (b) : (a))
                    118: #define        RDR     0
                    119: #define        WTR     1
                    120: static int     popen_pid[20];
                    121: 
                    122: /* return a file descriptor suitable for writing, send to 
                    123:   user toaddress from fromaddress,
                    124:   if cautious != 0 then don't do any forwarding
                    125:   hopcnt is passed thru the mail program.
                    126:          normal value is 0
                    127:   */
                    128: FILE *
                    129: mailopen(toaddress, fromaddress, cautious, hopcnt)
                    130: char *toaddress, *fromaddress;
                    131: int cautious, hopcnt;
                    132: {
                    133:        char    cmd[100];
                    134:        char    *mode = "w";
                    135:        int p[2];
                    136:        register myside, hisside, pid;
                    137:        char shopcnt[20];
                    138: 
                    139:        if(pipe(p) < 0)
                    140:                return NULL;
                    141:        myside = tst(p[WTR], p[RDR]);
                    142:        hisside = tst(p[RDR], p[WTR]);
                    143:        while((pid = fork()) == -1)sleep(2);
                    144:        if(pid == 0) {
                    145:                /* myside and hisside reverse roles in child */
                    146:                close(myside);
                    147:                /*
                    148:                dup2(hisside, tst(0, 1));
                    149:                */
                    150:                close(0);
                    151:                dup(hisside);
                    152:                close(hisside);
                    153:                sprintf(shopcnt,"%d",hopcnt);
                    154:                if(fromaddress != NULL){
                    155:                        /* by convention, MAILFWD1 may forward this mail
                    156:                           and response messages shouldn't be forwarded */
                    157:                        if(!cautious && !FMemberSCh(toaddress,'/')){
                    158: # ifdef DELIVERM
                    159:                                mexecl("/etc/delivermail",
                    160:                                        "delivermail", "-ee", "-r", fromaddress,
                    161:                                        "-h",shopcnt, toaddress, 0);
                    162: # endif
                    163:                                mexecl(MAILFWD1, "mail","-r",fromaddress,
                    164:                                        "-h",shopcnt,toaddress,0);
                    165:                        }
                    166:                        mexecl(SYSMAIL2, "mail","-d","-r",fromaddress,
                    167:                                "-h", shopcnt,toaddress,0);
                    168:                } else {
                    169:                        if(!cautious && !FMemberSCh(toaddress,'/')){
                    170: # ifdef DELIVERM
                    171:                                mexecl("/etc/delivermail",
                    172:                                        "delivermail", "-ee", "-h", shopcnt,
                    173:                                        toaddress, 0);
                    174: # endif
                    175:                                mexecl(MAILFWD1, "mail","-h", shopcnt,
                    176:                                        toaddress,0);
                    177:                        }
                    178:                        mexecl(SYSMAIL2, "mail","-d","-h", shopcnt,toaddress,0);
                    179:                }
                    180:                perror(SYSMAIL2);
                    181:                exit(EX_UNAVAILABLE);
                    182:        }
                    183:        if(pid == -1)
                    184:                return NULL;
                    185:        popen_pid[myside] = pid;
                    186:        close(hisside);
                    187:        return(fdopen(myside, mode));
                    188: }
                    189: 
                    190: mailclose(ptr)
                    191: FILE *ptr;
                    192: {
                    193:        register f, r, (*hstat)(), (*istat)(), (*qstat)();
                    194:        int status;
                    195: 
                    196:        f = fileno(ptr);
                    197:        fclose(ptr);
                    198:        istat = signal(SIGINT, SIG_IGN);
                    199:        qstat = signal(SIGQUIT, SIG_IGN);
                    200:        hstat = signal(SIGHUP, SIG_IGN);
                    201:        while((r = wait(&status)) != popen_pid[f] && r != -1)
                    202:                ;
                    203:        if(r == -1)
                    204:                status = -1;
                    205:        signal(SIGINT, istat);
                    206:        signal(SIGQUIT, qstat);
                    207:        signal(SIGHUP, hstat);
                    208:        return(status);
                    209: }
                    210:        
                    211: /* determine through machine */
                    212: gothru(from,to){
                    213:        register int i;
                    214:        switch(from){
                    215: # ifdef RAND
                    216:        case 'a':       i = configA[to-'a']; break;
                    217:        case 'b':       i = configB[to-'a']; break;
                    218:        case 'c':       i = configC[to-'a']; break;
                    219: # endif
                    220: # ifdef NOSC
                    221:        case 'a':       i = configA[to-'a']; break;
                    222:        case 'c':       i = configC[to-'a']; break;
                    223:        case 'm':       i = configM[to-'a']; break;
                    224: # endif
                    225: # ifdef BERKELEY
                    226:        /* for Berkeley */
                    227:        case 'a':       i = configA[to-'a']; break;
                    228:        case 'b':       i = configB[to-'a']; break;
                    229:        case 'c':       i = configC[to-'a']; break;
                    230:        case 'd':       i = configD[to-'a']; break;
                    231:        case 'e':       i = configE[to-'a']; break;
                    232:        case 'f':       i = configF[to-'a']; break;
                    233:        case 'i':       i = configI[to-'a']; break;
                    234:        case 'j':       i = configJ[to-'a']; break;
                    235:        case 'k':       i = configK[to-'a']; break;
                    236:        case 'l':       i = configL[to-'a']; break;
                    237:        case 'm':       i = configM[to-'a']; break;
                    238:        case 'o':       i = configO[to-'a']; break;
                    239:        case 'q':       i = configQ[to-'a']; break;
                    240:        case 'r':       i = configR[to-'a']; break;
                    241:        case 's':       i = configS[to-'a']; break;
                    242:        case 't':       i = configT[to-'a']; break;
                    243:        case 'v':       i = configV[to-'a']; break;
                    244:        case 'x':       i = configX[to-'a']; break;
                    245:        case 'y':       i = configY[to-'a']; break;
                    246:        case 'z':       i = configZ[to-'a']; break;
                    247: # endif
                    248:        default:        i = 0; break;
                    249:        }
                    250:        return(i);
                    251:        }
                    252: /*
                    253:        harg(string,pargc,pargv)
                    254: 
                    255:        A curious procedure which takes a pointer to an argc, and a 
                    256:        pointer to an argv, and parses them so that the
                    257:        argument following the flag is copied into string.
                    258:        pargv[0] must be the flag argument.
                    259:        handles both
                    260:                -my
                    261:        and
                    262:                -m y
                    263:        for the net command.
                    264: */
                    265: harg(ans,pargc,pargv)
                    266:   char *ans,*pargc,***pargv;{
                    267:        if((*pargv)[0][2])              /* no space */
                    268:                strcpy(ans,(*pargv)[0] + 2);
                    269:        else {                          /* space, get next arg */
                    270:                strcpy(ans,(*pargv)[1]);
                    271:                (*pargc)--;
                    272:                (*pargv)++;
                    273:                }
                    274:        }
                    275: 
                    276: /* prints out commands before executing them */
                    277: /*VARARGS0*/
                    278: mexecl(s)
                    279:   char *s;{
                    280:        int *p = (int *)&s;
                    281:        register int i;
                    282:        if(debugflg){
                    283:                for(i=0; p[i]; i++)err("%s ",p[i]);
                    284:                putc('\n',stderr);
                    285:                }
                    286:        execl(p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7],p[8],p[9],p[10],p[11],
                    287:        p[12],p[13],p[14],p[15],0);
                    288:        }
                    289: /* prints out commands before executing them */
                    290: mexecv(s,p)
                    291:   register char *s, **p;{
                    292:        register int i;
                    293:        if(debugflg){
                    294:                err("%s ",s);
                    295:                for(i=0; p[i]; i++)err("%s ",p[i]);
                    296:                putc('\n',stderr);
                    297:                }
                    298:        execv(s,p);
                    299:        }
                    300: 
                    301: /*VARARGS0*/
                    302: /* fills in -l - -p from commands like rcp */
                    303: /* must be called with at least two arguments */
                    304: kexecl(s)
                    305:   char *s;     {
                    306:        char *a[20], i = 2, j = 2;
                    307:        char **p = (char **)&s;
                    308:        a[0] = p[0];
                    309:        a[1] = p[1];
                    310:        if(status.login[0]){
                    311:                a[i++] = "-l";
                    312:                a[i++] = status.login;
                    313:                }
                    314:        if(status.mpasswd[0]){
                    315:                a[i++] = "-p";
                    316:                a[i++] = status.mpasswd;
                    317:                }
                    318:        if(status.nonotify)a[i++] = "-b";
                    319:        if(status.force)   a[i++] = "-f";
                    320:        if(status.quiet)   a[i++] = "-q";
                    321:        if(status.nowrite) a[i++] = "-n";
                    322:        while(p[j])a[i++] = p[j++];
                    323:        a[i] = 0;
                    324:        mexecl(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10],a[11],
                    325:        a[12],a[13],a[14],a[15],0);
                    326:        }
                    327: 
                    328: /*
                    329:        MchSFromAddr(sn,addr)
                    330: 
                    331:        take an address of the form "mach:username"
                    332:        and return mch as the 1 char code of "mach" and
                    333:        in sn put "username".
                    334:        If addr has no colon in it, return mch==local, sn==addr.
                    335:        Return 0 for mch if host unknown.
                    336: */
                    337: MchSFromAddr(sn,addr)
                    338:        char *sn, *addr;
                    339: {
                    340:        char fcolon = 0, *s, mch, stemp[BUFSIZ];
                    341: 
                    342:        /* assume addr is a local address */
                    343: 
                    344:        strcpy(stemp,addr);
                    345:        s = stemp;
                    346:        while(*s){
                    347:                if(*s == ':'){
                    348:                        fcolon = 1;
                    349:                        *s++ = 0;
                    350:                        break;
                    351:                }
                    352:                s++;
                    353:        }
                    354:        if(fcolon != 1){
                    355:                /* sn better be the right size for addr */
                    356:                mch = local;
                    357:                strcpy(sn,addr);
                    358:                return(mch);
                    359:        }
                    360: 
                    361:        /* addr has a colon in it, s pts to name */
                    362:        mch = lookup(stemp);
                    363:        strcpy(sn,s);
                    364:        return(mch);
                    365: }
                    366: 
                    367: 
                    368: /* returns a single character for machine S */
                    369: /* returns 0 for unknown host */
                    370: lookup(s)
                    371:   register char *s; {
                    372:        register struct tt *t;
                    373:        if(strlen(s) == 1)return(isupper(*s) ? tolower(*s) : *s);
                    374:        for(t = table; t->bigname; t++)
                    375:                if(streql(s,t->bigname) == 0)return(t->lname);
                    376:        return(0);
                    377:        }
                    378: 
                    379: /* returns a long name (string) for single character machine c */
                    380: char *longname(c)
                    381:   register char c;
                    382:        {
                    383:        register struct tt *t;
                    384:        if(c == 0)return("UNKNOWN");
                    385:        for(t = table; t->bigname; t++)
                    386:                if(c == t->lname)return(t->bigname);
                    387:        return("UNKNOWN");
                    388:        }
                    389: /*
                    390:        FMemberSCh(s,ch)
                    391: 
                    392:        return 1 if ch is a character in string s.
                    393:        0 otherwise.
                    394: */
                    395: FMemberSCh(s,ch)
                    396:        register char *s, ch; 
                    397: {
                    398:        while(*s)if(*s++ == ch)return(1);
                    399:        return(0);
                    400: }
                    401: 
                    402: /* return a static string with the form "X hrs X mins X secs" */
                    403: /* t is # of secs */
                    404: char *comptime(t)
                    405:   long t; {
                    406:        static char str[30];
                    407:        char buf[20];
                    408:        long w;
                    409:        str[0] = 0;
                    410:        w = t/3600L;
                    411:        if(w > 0L){
                    412:                sprintf(buf,"%ld hr ",w);
                    413:                strcat(str,buf);
                    414:                }
                    415:        t = t % 3600L;
                    416:        w = t/60L;
                    417:        if(w > 0L){
                    418:                sprintf(buf,"%ld min ",w);
                    419:                strcat(str,buf);
                    420:                }
                    421:        t = t % 60L;
                    422:        sprintf(buf,"%ld sec",t);
                    423:        strcat(str,buf);
                    424:        return(str);
                    425:        }
                    426: /*
                    427:        parseparmlist(string)
                    428: 
                    429:        parses variable parameter lists in string,
                    430:        as defined in genparmlist in net.c
                    431: */
                    432: parseparmlist(parmlist)
                    433:        char *parmlist;
                    434: {
                    435:        while(*parmlist && *parmlist != '(')parmlist++;
                    436: }
                    437: 
                    438: /* just like strcmp except upper- and lower-case are ignored */
                    439: streql(s1,s2)
                    440:   char *s1, *s2; {
                    441:        char a,b;
                    442:        while(*s1 && *s2){
                    443:                a = isupper(*s1) ? tolower(*s1) : *s1;
                    444:                b = isupper(*s2) ? tolower(*s2) : *s2;
                    445:                if(a < b)return(-1);
                    446:                if(a > b)return(1);
                    447:                s1++, s2++;
                    448:                }
                    449:        if(*s2)return(-1);
                    450:        if(*s1)return(1);
                    451:        return(0);
                    452:        }
                    453: /* VARARGS0 */
                    454: err(s,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r) {
                    455:        fprintf(stderr,s,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r);
                    456:        }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.