Annotation of 43BSDReno/old/berknet/sub.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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