Annotation of 41BSD/cmd/berknet/sub.c, revision 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.