Annotation of 3BSD/cmd/net/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: int debugflg = DBV;    /* debug flag */
                     23: char local = LOCAL;    /* the machine we're on */
                     24: 
                     25: char netcmd[]  =       NETCMD;
                     26: char resfile[] =       RESFILE;
                     27: char senddir[] =       SENDDIR;
                     28: char Bsh[] =           BINSH;
                     29: 
                     30: char shomedir[BUFSIZ];
                     31: 
                     32: /*
                     33:        passwdent()
                     34: 
                     35:        Read the password file looking for current user's entry.
                     36:        Fill in the status structure.
                     37:        Has the (dangerous) side effect of giving a value to getenv("HOME").
                     38: */
                     39: passwdent()
                     40: {
                     41:        register char *u;
                     42:        register struct passwd *pwd;
                     43:        pwd = PwdCurrent();
                     44:        if(pwd == NULL){
                     45:                err("Bad uid/username\n");
                     46:                return;
                     47:        }
                     48:        strcpy(status.localname,pwd->pw_name);
                     49:        status.muid = guid(pwd->pw_uid,pwd->pw_gid);
                     50:        status.mgid = pwd->pw_gid;
                     51:        if(isdigit(pwd->pw_gecos[0]))status.jobno = atoi(pwd->pw_gecos);
                     52:        else status.jobno = 32767;
                     53:        strcpy(status.dir,pwd->pw_dir);
                     54:        strcpy(shomedir,pwd->pw_dir);           /* side effect */
                     55:        u = pwd->pw_shell;
                     56:        if(u[0] == 0)u= Bsh;
                     57:        strcpy(status.loginshell,u);
                     58:        }
                     59: /*
                     60:        promptlogin(mchto)
                     61: 
                     62:        ask user for login and passwd on mchto.
                     63:        make sure status.localname has a value before calling
                     64:        this.  One way is to call passwdent(), another is to
                     65:        strcpy(status.localname,SnCurrent()).
                     66: */
                     67: promptlogin(mchto)
                     68:        char mchto;
                     69: {
                     70:        char buf[BUFSIZ], mch;
                     71:        FILE *wf;
                     72:        int c;
                     73:        if(status.mpasswd[0] == 0 || status.login[0] == 0 || status.force){
                     74:                wf = fopen("/dev/tty","r");
                     75:                if(wf != NULL){
                     76:                        if(status.login[0]==0 || status.force){
                     77:                                printf("Name (%s:%s): ",longname(mchto),
                     78:                                        status.localname);
                     79:                                if(fgets(buf, BUFSIZ, wf) != buf){
                     80:                                        perror("fgets");
                     81:                                        exit(1);
                     82:                                        }
                     83:                                c = strlen(buf);
                     84:                                buf[c > 0 ? c-1 : 0] = 0;
                     85:                                if(c > 10){
                     86:                                        err("Login name too long.\n");
                     87:                                        exit(1);
                     88:                                        }
                     89:                                if(FMemberSCh(buf,' ')){
                     90:                                        err("Login names don't have blanks in them.\n");
                     91:                                        exit(1);
                     92:                                        }
                     93:                                if(buf[0] == 0)strcpy(buf,status.localname);
                     94:                                mch = MchSFromAddr(status.login,buf);
                     95:                                if(mch != local && mch != mchto){
                     96:                                        err(
                     97:                                "Must specify login name on %s machine\n",
                     98:                                                longname(mchto));
                     99:                                        exit(1);
                    100:                                }
                    101:                        }
                    102:                        if(strcmp(status.login,"network") != 0
                    103:                                && (status.mpasswd[0]== 0 || status.force)){
                    104:                                sprintf(buf,"Password (%s:%s):",
                    105:                                        longname(mchto), status.login);
                    106:                                strcpy(status.mpasswd,getpass(buf));
                    107:                                }
                    108:                        fclose(wf);
                    109:                        }
                    110:                }
                    111:        if(status.login[0] == 0) strcpy(status.login,status.localname);
                    112:        if(status.mpasswd[0] == 0)strcpy(status.mpasswd,"\"\"");
                    113:        status.force = 0;
                    114:        }
                    115:        
                    116: /* determine through machine */
                    117: gothru(from,to){
                    118:        register int i;
                    119:        switch(from){
                    120:        case 'a':       i = configA[to-'a']; break;
                    121:        case 'b':       i = configB[to-'a']; break;
                    122:        case 'c':       i = configC[to-'a']; break;
                    123:        case 'd':       i = configD[to-'a']; break;
                    124:        case 'e':       i = configE[to-'a']; break;
                    125:        case 'f':       i = configF[to-'a']; break;
                    126:        case 'i':       i = configI[to-'a']; break;
                    127:        case 'j':       i = configJ[to-'a']; break;
                    128:        case 'm':       i = configM[to-'a']; break;
                    129:        case 'o':       i = configO[to-'a']; break;
                    130:        case 'q':       i = configQ[to-'a']; break;
                    131:        case 's':       i = configS[to-'a']; break;
                    132:        case 'v':       i = configV[to-'a']; break;
                    133:        case 'y':       i = configY[to-'a']; break;
                    134:        case 'z':       i = configZ[to-'a']; break;
                    135:        default:        i = 0; break;
                    136:        }
                    137:        return(i);
                    138:        }
                    139: /*
                    140:        harg(string,pargc,pargv)
                    141: 
                    142:        A curious procedure which takes a pointer to an argc, and a 
                    143:        pointer to an argv, and parses them so that the
                    144:        argument following the flag is copied into string.
                    145:        pargv[0] must be the flag argument.
                    146:        handles both
                    147:                -my
                    148:        and
                    149:                -m y
                    150:        for the net command.
                    151: */
                    152: harg(ans,pargc,pargv)
                    153:   char *ans,*pargc,***pargv;{
                    154:        if((*pargv)[0][2])              /* no space */
                    155:                strcpy(ans,(*pargv)[0] + 2);
                    156:        else {                          /* space, get next arg */
                    157:                strcpy(ans,(*pargv)[1]);
                    158:                (*pargc)--;
                    159:                (*pargv)++;
                    160:                }
                    161:        }
                    162: 
                    163: /* prints out commands before executing them */
                    164: /*VARARGS0*/
                    165: mexecl(s)
                    166:   char *s;{
                    167:        int *p = (int *)&s;
                    168:        register int i;
                    169:        if(debugflg){
                    170:                for(i=0; p[i]; i++)err("%s ",p[i]);
                    171:                putc('\n',stderr);
                    172:                }
                    173:        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],
                    174:        p[12],p[13],p[14],p[15],0);
                    175:        perror(p[0]);
                    176:        }
                    177: /* prints out commands before executing them */
                    178: mexecv(s,p)
                    179:   register char *s, **p;{
                    180:        register int i;
                    181:        if(debugflg){
                    182:                err("%s ",s);
                    183:                for(i=0; p[i]; i++)err("%s ",p[i]);
                    184:                putc('\n',stderr);
                    185:                }
                    186:        execv(s,p);
                    187:        perror(s);
                    188:        }
                    189: 
                    190: /*VARARGS0*/
                    191: /* fills in -l - -p from commands like rcp */
                    192: /* must be called with at least two arguments */
                    193: kexecl(s)
                    194:   char *s;     {
                    195:        char *a[20], i = 2, j = 2;
                    196:        char **p = (char **)&s;
                    197:        a[0] = p[0];
                    198:        a[1] = p[1];
                    199:        if(status.login[0]){
                    200:                a[i++] = "-l";
                    201:                a[i++] = status.login;
                    202:                }
                    203:        if(status.mpasswd[0]){
                    204:                a[i++] = "-p";
                    205:                a[i++] = status.mpasswd;
                    206:                }
                    207:        if(status.nonotify)a[i++] = "-b";
                    208:        if(status.force)   a[i++] = "-f";
                    209:        if(status.quiet)   a[i++] = "-q";
                    210:        if(status.nowrite) a[i++] = "-n";
                    211:        while(p[j])a[i++] = p[j++];
                    212:        a[i] = 0;
                    213:        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],
                    214:        a[12],a[13],a[14],a[15],0);
                    215:        }
                    216: 
                    217: /*
                    218:        MchSFromAddr(sn,addr)
                    219: 
                    220:        take an address of the form "mach:username"
                    221:        and return mch as the 1 char code of "mach" and
                    222:        in sn put "username".
                    223:        If addr has no colon in it, return mch==local, sn==addr.
                    224: */
                    225: MchSFromAddr(sn,addr)
                    226:        char *sn, *addr;
                    227: {
                    228:        char fcolon = 0, *s, mch, stemp[BUFSIZ];
                    229: 
                    230:        /* assume addr is a local address */
                    231: 
                    232:        strcpy(stemp,addr);
                    233:        s = stemp;
                    234:        while(*s){
                    235:                if(*s == ':'){
                    236:                        fcolon = 1;
                    237:                        *s++ = 0;
                    238:                        break;
                    239:                }
                    240:                s++;
                    241:        }
                    242:        if(fcolon != 1){
                    243:                /* sn better be the right size for addr */
                    244:                mch = local;
                    245:                strcpy(sn,addr);
                    246:                return(mch);
                    247:        }
                    248: 
                    249:        /* addr has a colon in it, s pts to name */
                    250:        mch = lookup(stemp);
                    251:        strcpy(sn,s);
                    252:        return(mch);
                    253: }
                    254: 
                    255: 
                    256: /* returns a single character for machine S */
                    257: lookup(s)
                    258:   register char *s; {
                    259:        register struct tt *t;
                    260:        if(strlen(s) == 1)return(isupper(*s) ? tolower(*s) : *s);
                    261:        for(t = table; t->bigname; t++)
                    262:                if(streql(s,t->bigname) == 0)return(t->lname);
                    263:        return(0);
                    264:        }
                    265: 
                    266: /* returns a long name (string) for single character machine c */
                    267: char *longname(c)
                    268:   register char c;
                    269:        {
                    270:        register struct tt *t;
                    271:        if(c == 0)return("UNKNOWN");
                    272:        for(t = table; t->bigname; t++)
                    273:                if(c == t->lname)return(t->bigname);
                    274:        return("UNKNOWN");
                    275:        }
                    276: /*VARARGS0*/
                    277: debug(s,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,t)
                    278: char *s; {
                    279:        if(debugflg){
                    280:                printf(s,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,t);
                    281:                putchar('\n');
                    282:                }
                    283:        }
                    284: 
                    285: /*
                    286:        FMemberSCh(s,ch)
                    287: 
                    288:        return 1 if ch is a character in string s.
                    289:        0 otherwise.
                    290: */
                    291: FMemberSCh(s,ch)
                    292:        register char *s, ch; 
                    293: {
                    294:        while(*s)if(*s++ == ch)return(1);
                    295:        return(0);
                    296: }
                    297: 
                    298: /* return a static string with the form "X hrs X mins X secs" */
                    299: /* t is # of secs */
                    300: char *comptime(t)
                    301:   long t; {
                    302:        static char str[30];
                    303:        char buf[20];
                    304:        long w;
                    305:        str[0] = 0;
                    306:        w = t/3600L;
                    307:        if(w > 0L){
                    308:                sprintf(buf,"%ld hr ",w);
                    309:                strcat(str,buf);
                    310:                }
                    311:        t = t % 3600L;
                    312:        w = t/60L;
                    313:        if(w > 0L){
                    314:                sprintf(buf,"%ld min ",w);
                    315:                strcat(str,buf);
                    316:                }
                    317:        t = t % 60L;
                    318:        sprintf(buf,"%ld sec",t);
                    319:        strcat(str,buf);
                    320:        return(str);
                    321:        }
                    322: /*
                    323:        parseparmlist(string)
                    324: 
                    325:        parses variable parameter lists in string,
                    326:        as defined in genparmlist in net.c
                    327: */
                    328: parseparmlist(parmlist)
                    329:        char *parmlist;
                    330: {
                    331:        while(*parmlist && *parmlist != '(')parmlist++;
                    332: }
                    333: 
                    334: /*
                    335:        PwdCurrent()
                    336: 
                    337:        Read the password file and return pwd to
                    338:        entry for current user.
                    339:        Return NULL if error.
                    340: 
                    341:        This code is a little screwed up because of the conventions
                    342:        regarding the state of the utmp file after someone su's--
                    343:        either to root or to another person.
                    344:        The final decision was to return getpwuid(getuid) if
                    345:        the machine has one login name per userid,
                    346:        and if there are multiple login names per userid, to
                    347:        search the passwd file for the getlogin() name and return
                    348:        the passwd file entry for that.
                    349:        If there is no utmp entry, just use the userid.
                    350:        This means that people who su on machine with multiple
                    351:        user-id's will get the passwd entry for the account recorded
                    352:        in the utmp file, not their current userid.
                    353: */
                    354: struct passwd *
                    355: PwdCurrent()
                    356: {
                    357:        register struct passwd *pwd;
                    358:        register char *sn;
                    359: 
                    360: # ifdef MULTNAMS
                    361:        sn = getlogin();
                    362:        if(sn != NULL && sn[0] != 0 && sn[0] != ' '){
                    363:                pwd = getpwnam(sn);
                    364:                if(pwd != NULL)return(pwd);
                    365:        }
                    366: # endif
                    367: 
                    368:        return(getpwuid(uidmask(getuid())));
                    369: }
                    370: /*
                    371:        SnCurrent()
                    372: 
                    373:        Return the name of the current user.
                    374:        If not in the /etc/utmp file, will read the passwd file.
                    375:        Returns NULL if error.
                    376:        Note that detached processes on V7 have getlogin() return
                    377:        a pointer to a null string, not NULL.
                    378: */
                    379: char *SnCurrent()
                    380: {
                    381:        static char snBuf[NS];
                    382:        register char *sn;
                    383: 
                    384:        sn = getlogin();
                    385:        if(sn == NULL || sn[0] == 0 || sn[0] == ' ')
                    386:                sn = SnFromUid(getuid());
                    387:        if(sn != NULL){
                    388:                strcpy(snBuf,sn);
                    389:                sn = snBuf;
                    390:        }
                    391:        return(sn);
                    392: }
                    393: /* just like strcmp except upper- and lower-case are ignored */
                    394: streql(s1,s2)
                    395:   char *s1, *s2; {
                    396:        char a,b;
                    397:        while(*s1 && *s2){
                    398:                a = isupper(*s1) ? tolower(*s1) : *s1;
                    399:                b = isupper(*s2) ? tolower(*s2) : *s2;
                    400:                if(a < b)return(-1);
                    401:                if(a > b)return(1);
                    402:                s1++, s2++;
                    403:                }
                    404:        if(*s2)return(-1);
                    405:        if(*s1)return(1);
                    406:        return(0);
                    407:        }
                    408: /* VARARGS0 */
                    409: err(s,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r) {
                    410:        fprintf(stderr,s,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r);
                    411:        }

unix.superglobalmegacorp.com

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