Annotation of 43BSDReno/old/berknet/netdaemon.c, revision 1.1

1.1     ! root        1: static char sccsid[] = "@(#)netdaemon.c        4.5     (Berkeley)      10/13/82";
        !             2: 
        !             3: /* sccs id variable */
        !             4: static char *netdaemon_sid = "@(#)netdaemon.c  1.10";
        !             5: 
        !             6: /*
        !             7: 
        !             8:        The daemon program that runs the network.
        !             9: 
        !            10: Usage:
        !            11:        netdaemon -m mach [-r readfd] [-w writefd] [-d] [-h]
        !            12:                [-os] [-or] [-ou num] [-p len] [-8] [-l]
        !            13: 
        !            14: Must be started by root.
        !            15: Options:
        !            16:        -d              turn debugging on
        !            17:        -h              use high-speed link (not implemented yet)
        !            18:        -l              don't use net line discipline, even if available
        !            19:        -m mach         remote machine is mach (required)
        !            20:        -os             only send
        !            21:        -or             only receive
        !            22:        -ou num         only send things with uid = num
        !            23:        -p num          length of packet
        !            24:        -r num          if simulute w/pipes, read from num
        !            25:        -w num          if simulate w/pipes, write on num
        !            26: */
        !            27: 
        !            28: # include "defs.h"
        !            29: /* take a time, adjust to be in PST, and divide by no of secs in a day */
        !            30: /* adjust by 10 mins, and day is considered to begin at 3AM */
        !            31: /* (6*3600 = 21600) + 17400 = 39000 */
        !            32: /* number of seconds in a day, usually 86400L */
        !            33: # define nsecday 86400L
        !            34: /* number of days since time began */
        !            35: # define numdays(S) ((S - 39000L)/nsecday)
        !            36: /* set my priority to normal */
        !            37: # define RENICE0() { if (getuid() == 0) { nice(-40); nice(20); nice(0); } }
        !            38: 
        !            39: /* global variables */
        !            40: extern char **environ;
        !            41: struct dumpstruc dump;
        !            42: struct bstruct btable[];
        !            43: struct daemonparms netd;
        !            44: struct userinfo status;
        !            45: 
        !            46: /* local variables */
        !            47: static long length;
        !            48: static DIR *dir;
        !            49: /* static char sheader[] =             "ABCDE"; */
        !            50: static char tempfile[]=        TEMPFILE;
        !            51: static char publogfile[]=      PUBLOGFILE;
        !            52: static struct stat statbuf;
        !            53: int handlekill();
        !            54: static char frommach;
        !            55: long linechars();
        !            56: 
        !            57: main(argc,argv)
        !            58:   char **argv; {
        !            59:        register int i;
        !            60:        long ltime,t;
        !            61:        char buf[100];
        !            62: 
        !            63:        nice(-1);
        !            64:        if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
        !            65:                signal(SIGHUP, handlekill);
        !            66:        if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
        !            67:                signal(SIGQUIT, handlekill);
        !            68:        if (signal(SIGINT, SIG_IGN) != SIG_IGN)
        !            69:                signal(SIGINT, handlekill);
        !            70:        if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
        !            71:                signal(SIGTERM, handlekill);
        !            72:        debugflg = DBV;
        !            73:        setupdaemon(argc,argv);
        !            74:        /* now running alone as a daemon */
        !            75:                /*
        !            76:                for(i=0; i<15; i++)close(i);
        !            77:                signal(SIGHUP,SIG_IGN);
        !            78:                signal(SIGQUIT,SIG_IGN);
        !            79:                signal(SIGINT,SIG_IGN);
        !            80:                */
        !            81:        /* set the umask to a reasonable value */
        !            82:        umask( 022 );
        !            83:        senddir[strlen(senddir)-1] = remote;            /* choose dir */
        !            84:        if(chdir(senddir) < 0){
        !            85:                perror(senddir);
        !            86:                exit(EX_OSFILE);
        !            87:                }
        !            88:        dir = opendir(senddir);
        !            89:        if(dir == NULL){
        !            90:                perror(senddir);
        !            91:                exit(EX_OSFILE);
        !            92:                }
        !            93:        mktemp(tempfile);
        !            94:        tempfile[strlen(tempfile) - 7] = remote;
        !            95:        ltime = gettime();
        !            96:        if(ltime == 0L)
        !            97:                fprintf(stderr,"The network says 'The clock is set wrong.'\n");
        !            98:        sprintf(buf,"net restarted to %s %d %s",longname(remote),
        !            99:                getpid(),ctime(&ltime));
        !           100:        dump.longtime = ltime;
        !           101:        dump.lastndays = numdays(ltime);
        !           102:        addtolog(remote,buf);
        !           103:        addtopublic(buf);
        !           104:        fprintf(stderr,buf);
        !           105:        if(!debugflg)fclose(stderr);
        !           106:        sendpurge();
        !           107:        mainloop();
        !           108:        /* never returns */
        !           109: }
        !           110: /* the main loop of the daemon, alternatively rcv then send, if poss.*/
        !           111: mainloop(){
        !           112:        register int i;
        !           113: 
        !           114:        for(;;){        /* begin reading file */
        !           115:                debug("daemon %c %d\n",remote,getpid());
        !           116:                /* first receive */
        !           117:                if(netd.dp_sndorcv >= 0){       /* if we can receive */
        !           118:                        i = netrcv();
        !           119:                        if(i == -1)dump.nabnormal++;
        !           120:                }
        !           121:                /* now look to send */
        !           122:                if(netd.dp_sndorcv <= 0)        /* if we can send */
        !           123:                        netsend();
        !           124:                /* print out statistics if the right time */
        !           125:                printstat();
        !           126:                dump.nloop++;
        !           127:        }
        !           128: }
        !           129:        /* this code is a little strange because some machines
        !           130:           seem to have trouble having the date set, and time()
        !           131:           returns 0 until somebody remembers to set the date */
        !           132: printstat(){
        !           133:        long thisndays, thistime;
        !           134:        thistime = gettime();
        !           135:        thisndays = numdays(thistime);
        !           136:        if(dump.longtime == 0L){
        !           137:                dump.longtime = thistime;
        !           138:                dump.lastndays = thisndays;
        !           139:                return;
        !           140:                }
        !           141:        if(thisndays == dump.lastndays + 1L) dumpit(thistime);
        !           142:        dump.lastndays = thisndays;
        !           143: }
        !           144: /* look for files to send */
        !           145: netsend(){
        !           146:        static long lasttime = 0;
        !           147:        static char nleft = 1;
        !           148:        long lFileLen,diff;
        !           149:        double drate;
        !           150:        register int uid,uidBest;
        !           151:        char *sdate,*sn,*swait;
        !           152:        long ot,nt,filesize;
        !           153:        register int i;
        !           154:        char stemp[20];
        !           155:        static char jname[FNS];
        !           156:        register struct direct *dp;
        !           157: 
        !           158:        debug("ck send");
        !           159:        if(stat(senddir,&statbuf) < 0){
        !           160:                error("%s %s",senddir,sys_errlist[errno]);
        !           161:                return;
        !           162:                }
        !           163:        if(statbuf.st_mtime == lasttime && nleft == 0)return;   /* no need to search */
        !           164:        lasttime = statbuf.st_mtime;
        !           165:        rewinddir(dir);
        !           166:        lFileLen = 10000000L;
        !           167:        nleft = 0;
        !           168:        while((dp = readdir(dir)) != NULL){
        !           169:                if(dp->d_name[0] != 'c'
        !           170:                   || dp->d_name[1] != 'f'
        !           171:                   || dp->d_name[2] != remote
        !           172:                   || stat(dp->d_name,&statbuf) < 0
        !           173:                   || statbuf.st_mode == 0)
        !           174:                        continue;
        !           175:                dp->d_name[0] = 'd';
        !           176:                if(stat(dp->d_name,&statbuf) < 0 || statbuf.st_mode == 0)
        !           177:                        continue;
        !           178:                uid = guid(statbuf.st_uid,statbuf.st_gid);
        !           179:                if(netd.dp_onlyuid != 0 && uid != netd.dp_onlyuid && uid != SUPERUSER
        !           180:                        && uid != NUID)continue;
        !           181:                nleft++;
        !           182:                filesize = getsize(&statbuf);
        !           183: #ifndef DONTHOLDBIG
        !           184:                if( (filesize > MAXDAYFILE) && day() ) {
        !           185:                        if( !debugflg )
        !           186:                                continue;
        !           187:                        else
        !           188:                                debug("sending large file %s\n", dp->d_name );
        !           189:                }
        !           190: #endif DONTHOLDBIG
        !           191:                if(lFileLen > filesize){
        !           192:                        lFileLen = filesize;
        !           193:                        strcpy(jname,dp->d_name);
        !           194:                        uidBest = uid;
        !           195:                }
        !           196: # ifdef MAXSENDQ
        !           197:                if(nleft > MAXSENDQ)break;
        !           198: # endif MAXSENDQ
        !           199:        }
        !           200:        if(lFileLen == 10000000L)return;
        !           201:        strcpy(stemp,jname);
        !           202:        stemp[0] = 'c';
        !           203:        sn = SnFromUid(uidBest);
        !           204:        if(sn == NULL){
        !           205:                addtolog(remote,"Unknown userid %d\n",uidBest);
        !           206:                addtolog(remote,"Removing %s\n",stemp);
        !           207:                unlink(stemp);
        !           208:                return;
        !           209:        }
        !           210:        addtolog(remote,"^S %s %c: %s ",sn,remote,jname+2);
        !           211:        ot = gettime();
        !           212:        if(send(jname) == 0)return;
        !           213:        nt = gettime();
        !           214:        filesize = getsize(&statbuf);
        !           215:        unlink(jname);
        !           216:        unlink(stemp);
        !           217:        diff = nt - ot;
        !           218:        if(diff < 1)diff = 1;           /* avoid dividing by zero */
        !           219:        sdate = ctime(&nt)+4;
        !           220:        sdate[strlen(sdate) -9] = 0;
        !           221:        swait = comptime(ot - statbuf.st_mtime);
        !           222:        jname[3] = jname[2];
        !           223: # ifndef NOFP
        !           224:        drate = (double)filesize / (double)diff;
        !           225:        addtolog(remote,"^T%c(%s, %ldb, %ldsec, %4.1fb/sec, w %s)\n",
        !           226:                remote,sdate,filesize, diff,drate, swait);
        !           227: # else NOFP
        !           228:        addtolog(remote,"^T%c(%s, %ldb, %ldsec, w %s)\n",
        !           229:                remote,sdate,filesize, diff,swait);
        !           230: # endif NOFP
        !           231:        addtopublic("%s: sent %-8s to %s (%s, %ld b, wait %s)\n",
        !           232:                sdate,sn,longname(remote),jname+3,filesize,swait);
        !           233:        dump.nsend++;
        !           234:        dump.bytetot += filesize;
        !           235:        dump.elaptot += diff;
        !           236:        }
        !           237: 
        !           238: /*
        !           239:    day() returns 1 if the time is between 6AM and 12PM
        !           240: */
        !           241: day()
        !           242: {
        !           243:        int hour;
        !           244:        long t;
        !           245:        char *ctime();
        !           246: 
        !           247:        time( &t );
        !           248:        sscanf( ctime( &t ), "%*s%*s%*s%2d", &hour );
        !           249:        if( (hour>=0) && (hour<6) )
        !           250:                return( 0 );            /* night */
        !           251:        else
        !           252:                return( 1 );            /* day */
        !           253: }
        !           254: 
        !           255: send(jname)
        !           256:        char *jname;
        !           257: {      /* push those bytes */
        !           258:        /* returns 0 if send fails, 1 otherwise */
        !           259:        register int n;
        !           260:        int i;
        !           261:        long lsize;
        !           262:        char mbuf[20], buf[MAXNBUF];
        !           263:        register char *p;
        !           264:        register FILE *jfile;
        !           265: 
        !           266:        debug("send %s",jname);
        !           267:        if(stat(jname,&statbuf) < 0)goto sfail;
        !           268:        lsize = getsize(&statbuf);
        !           269:        if(lsize < MINSIZE){            /* all files are at least this long */
        !           270:                unlink(jname);
        !           271:                jname[0] = 'c';
        !           272:                unlink(jname);
        !           273:                return(1);
        !           274:                }
        !           275:        jfile = fopen(jname,"r");
        !           276:        if(jfile == NULL)goto sfail;
        !           277:        /*
        !           278:        strcpy(mbuf,sheader);
        !           279:        i = strlen(sheader);
        !           280:        p = (char *)&lsize;
        !           281:        lsize = fixuplong(lsize);
        !           282:        mbuf[i] = *p++;
        !           283:        mbuf[i+1] = *p++;
        !           284:        mbuf[i+2] = *p++;
        !           285:        mbuf[i+3] = *p++;
        !           286:        i = i + 4;
        !           287:        sendreset();
        !           288:        */
        !           289:        initseqno();
        !           290:        sprintf(mbuf,"|%08ld|",lsize);
        !           291:        i = 10;
        !           292:        if(xwrite(mbuf,i) == WRITEFAIL)goto bwrite;
        !           293:        while((n=read(fileno(jfile),buf,MAXNBUF)) > 0)
        !           294:                if(xwrite(buf,n) == WRITEFAIL)goto bwrite;
        !           295:        fclose(jfile);
        !           296:        debug("end send");
        !           297:        return(1);
        !           298: bwrite:
        !           299:        dump.nsendfail++;
        !           300:        fclose(jfile);
        !           301:        addtolog(remote,"^F%c\n",remote);
        !           302:        return(0);
        !           303: sfail:
        !           304:        error("%s: %s",jname,sys_errlist[errno]);
        !           305:        dump.nsendfail++;
        !           306:        return(0);
        !           307:        }
        !           308: netrcv(){
        !           309:        /* returns -2 in normal fail, -1 in abnormal fail, >= 0 otherwise */
        !           310:        char sin;
        !           311:        char mgetc(), *s;
        !           312:        register int n;
        !           313:        char c;
        !           314:        int i, dummy, pid;
        !           315:        unsigned rcode;
        !           316:        long otime,olength,diff,rcvfinish,nt;
        !           317:        double r;
        !           318:        char hbuf[20], buf[MAXNBUF];
        !           319:        register FILE *temp;
        !           320:        static struct header hd;
        !           321: 
        !           322:        initseqno();
        !           323:        /*
        !           324:        n = nread(hbuf,strlen(sheader));
        !           325:        if(n == BROKENREAD)return(-2);
        !           326:        if(n != strlen(sheader) || strcmp(sheader,hbuf) != 0){
        !           327:                error("wrong head %d %s",n,hbuf);
        !           328:                return(-1);
        !           329:                }
        !           330:        n = nread(&length,4);
        !           331:        length = fixuplong(length);
        !           332:        */
        !           333:        n = nread(hbuf,10);
        !           334:        if(n == BROKENREAD)return(-2);
        !           335:        if(n != 10){
        !           336:                error("bad length nread %d",n);
        !           337:                return(-1);
        !           338:                }
        !           339:        hbuf[10] = 0;
        !           340:        if(hbuf[0] != '|' || hbuf[9] != '|'){
        !           341:                error("poor format %s",hbuf);
        !           342:                return(-1);
        !           343:                }
        !           344:        hbuf[9] = 0;
        !           345:        length = atol(hbuf+1);
        !           346:        if(length < 0 || length > 100000000L){
        !           347:                error("bad length %ld",length);
        !           348:                return(-1);
        !           349:                }
        !           350:        dump.braw = 4;
        !           351:        olength = length;
        !           352:        otime = gettime();
        !           353:        debug("length = %ld\n",length);
        !           354: 
        !           355: /* 
        !           356:        begin parsing header
        !           357: 
        !           358:        from local to remote (requests)
        !           359:        code    net option      reason
        !           360:        q                       normal request
        !           361:        y       -y              simply skips login check (used by netlpr)
        !           362: 
        !           363:        from remote to local
        !           364:        code    net option      reason
        !           365:        w       -w              message to be written/mailed back
        !           366:        s       -z              normal response
        !           367: */
        !           368: 
        !           369:        i = readhd(&hd);
        !           370:        if(i == -3)goto forw;                   /* being forwarded thru us */
        !           371:        if(i != 0)return(i);
        !           372: 
        !           373:        strcpy(status.login, hd.hd_snto);
        !           374:        strcpy(status.localname,hd.hd_snfrom);
        !           375: 
        !           376:        demask(hd.hd_spasswd);
        !           377: 
        !           378:        s = hd.hd_scmdvirt;
        !           379:        while(*s && *s != ' ')s++;
        !           380:        c = *s;
        !           381:        *s = 0;
        !           382:        if(strcmp(hd.hd_scmdvirt,"netlpr") == 0)dump.nnetlpr++;
        !           383:        else if(strcmp(hd.hd_scmdvirt,"netmail") == 0)dump.nnetmail++;
        !           384:        else if(strcmp(hd.hd_scmdvirt,"mail") == 0)dump.nsmail++;
        !           385:        else if(strcmp(hd.hd_scmdvirt,"netcp") == 0)dump.nnetcp++;
        !           386:        else if(strcmp(hd.hd_scmdvirt,"response") == 0)dump.nresp++;
        !           387:        else dump.nnet++;
        !           388:        *s = c;
        !           389: 
        !           390:        printhd(&hd);
        !           391: 
        !           392:        /* any chars left are data */
        !           393: forw:
        !           394:        sin = 0;
        !           395:        if(length > 0){ /* make a temp input file */
        !           396:                increment(tempfile);
        !           397:                temp = fopen(tempfile,"w");
        !           398:                if(temp == NULL){
        !           399:                        error("%s %s",tempfile,sys_errlist[errno]);
        !           400:                        return(-1);
        !           401:                        }
        !           402:                chmod(tempfile,0600);
        !           403:                if(hd.hd_mchto != local){
        !           404:                        fprintf(temp,"%c :%c :",hd.hd_code,hd.hd_mchto);
        !           405:                        fflush(temp);
        !           406:                }
        !           407:                /* this is the loop to read in all the data */
        !           408:                while((n = mread(buf,MAXNBUF)) > 0)
        !           409:                        if(write(fileno(temp),buf,n) != n){
        !           410:                                error("%s %s",tempfile,sys_errlist[errno]);
        !           411:                                fclose(temp);
        !           412:                                unlink(tempfile);
        !           413:                                return(-1);
        !           414:                                };
        !           415:                fclose(temp);
        !           416:                if(n == BROKENREAD || length > 0){
        !           417:                        unlink(tempfile);
        !           418:                        return(-2);
        !           419:                        }
        !           420:                sin = 1;
        !           421:                if(hd.hd_mchto != local){
        !           422:                        diff = gettime() - otime;
        !           423:                        if(diff < 1)diff = 1;   /* avoid dividing by 0 */
        !           424: # ifndef NOFP
        !           425:                        r = olength;
        !           426:                        r = r/diff;
        !           427:                        addtolog(remote,"^P(to %c, %ldb, %ldsec, %4.1fb/sec)\n",
        !           428:                                hd.hd_mchto,olength,diff,r);
        !           429: # else NOFP
        !           430:                        addtolog(remote,"^P(to %c, %ldb, %ldsec)\n",
        !           431:                                hd.hd_mchto,olength,diff);
        !           432: # endif NOFP
        !           433:                        dump.npass++;
        !           434:                        dump.bytetot += olength;
        !           435:                        dump.elaptot += diff;
        !           436:                        while((pid = fork()) == -1)sleep(2);
        !           437:                        if(pid == 0){
        !           438:                                RENICE0();
        !           439: #ifdef CCV7
        !           440:                                /* make sure the spawned child has it's own
        !           441:                                        group process to avoid the nasty
        !           442:                                        "try again" message
        !           443:                                */
        !           444:                                setpgrp();
        !           445: #endif CCV7
        !           446:                                execl(netcmd,"net","-x","-m",longname(hd.hd_mchto),
        !           447:                                        "-s",tempfile,0);
        !           448:                                error("%s: %s",netcmd,sys_errlist[errno]);
        !           449:                                exit(EX_UNAVAILABLE);
        !           450:                                }
        !           451:                        wait(&rcode);
        !           452:                        unlink(tempfile);
        !           453:                        rcode >>= 8;
        !           454:                        if(rcode != 0)
        !           455:                                error("pass-thru rcode %d", rcode);
        !           456:                        debug("passthru to %c code %c rcode %d",
        !           457:                                hd.hd_mchto,hd.hd_code,rcode);
        !           458:                        return(1);
        !           459:                        }
        !           460:                }
        !           461:        if(length > 0){error("file too short"); return(-1); }
        !           462:        rcvfinish = gettime();
        !           463: 
        !           464:        while((pid = fork()) == -1)sleep(2);
        !           465:        if(pid > 0){
        !           466:                wait(&dummy);
        !           467:                return(1);      /* normal return */
        !           468:        }
        !           469:        /* this is a child, who will go ahead and execute the command */
        !           470:        /* running uid=0 at this point */
        !           471:        RENICE0();
        !           472:        /* nice(0 set back to 0 */
        !           473: #ifdef CCV7
        !           474:        /* separate group process */
        !           475:        setpgrp();
        !           476: #endif CCV7
        !           477: 
        !           478:        while((pid = fork()) == -1)sleep(2);
        !           479:        if(pid != 0)exit(EX_OK);
        !           480: 
        !           481:        /* child process which forks and waits */
        !           482:        mktemp(resfile);
        !           483:        while((pid = fork()) == -1)sleep(2);
        !           484:        if(pid == 0){
        !           485:                /* child */
        !           486:                strcpy(status.loginshell,Bsh);
        !           487:                frommach = hd.hd_mchfrom;
        !           488:                n = check(&hd,(hd.hd_code == 'q'));
        !           489:                if(!n)errormsg(TRUE,&hd,NULL,
        !           490:                        "Bad remote login/password '%s'",hd.hd_snto);
        !           491:                temp = fopen(resfile,"w");
        !           492:                if(temp == NULL)
        !           493:                        errormsg(TRUE,&hd,NULL,
        !           494:                        "Create file %s: %s",resfile,sys_errlist[errno]);
        !           495:                fclose(temp);
        !           496:                chmod(resfile,0600);
        !           497:                mchown(resfile,status.muid,status.mgid);
        !           498:                if(sin)
        !           499:                        mchown(tempfile,status.muid,status.mgid);
        !           500:                else tempfile[0] = 0;
        !           501:                setgid(status.mgid);
        !           502:                setuid(status.muid);
        !           503:                /* after this point our gid, uid is the target user's */
        !           504:                excmd(&hd,resfile,tempfile);
        !           505:        }
        !           506:        /* parent */
        !           507:        wait(&rcode);
        !           508:        rcode = (((rcode&077400) >>8) &0177);
        !           509:        /*
        !           510:        fclose(stdin);
        !           511:        fclose(stdout);
        !           512:        fclose(stderr);
        !           513:        */
        !           514:        if(sin)unlink(tempfile);
        !           515:        /* 
        !           516:           now send something back to the sender 
        !           517:           unless this was a response (file or message)
        !           518:        */
        !           519:        if((hd.hd_code == 'q' || hd.hd_code == 'y')
        !           520:        && (hd.hd_srespfile[0] || !hd.hd_fnonotify))
        !           521:                sndresponse(&hd,rcode);
        !           522:        unlink(resfile);
        !           523:        s = ctime(&rcvfinish);
        !           524:        s += 4;
        !           525:        s[strlen(s) -8] = 0;
        !           526:        diff = rcvfinish - otime;
        !           527:        if(diff < 1)diff = 1;           /* avoid dividing by zero */
        !           528:        dump.bytetot += olength;
        !           529:        dump.elaptot += diff;
        !           530:        sprintf(buf,"%s rcv  %c:%-8s (%s)",
        !           531:                s,hd.hd_mchfrom,hd.hd_snfrom,hd.hd_snto);
        !           532:        addtolog(remote,"%s C: %s\n",buf,hd.hd_scmdvirt);
        !           533:        addtopublic("%s R: %d C: %s\n",buf,rcode,hd.hd_scmdvirt);
        !           534:        nt = rcvfinish - hd.hd_ltimesent;
        !           535:        buf[0] = 0;
        !           536:        if(nt > 0L)sprintf(buf," took (%s)",comptime(nt));
        !           537: # ifndef NOFP
        !           538:        r = olength;
        !           539:        r = r/diff;
        !           540:        addtolog(remote,"\t\tR: %d%s %ldb %ldsec %4.1fb/sec\n",
        !           541:                rcode,buf,olength,diff,r);
        !           542:        r = dump.braw;
        !           543:        r = r/diff;
        !           544:        addtolog(remote,"\t\t%4.1frb/sec %4.1f%% use\n",r,(r/linechars())*100L);
        !           545: # else NOFP
        !           546:        addtolog(remote,"\t\tR: %d%s %ldb %ldsec\n",
        !           547:                rcode,buf,olength,diff);
        !           548: # endif NOFP
        !           549:        exit(EX_OK);
        !           550:        /*UNREACHED*/
        !           551:        }
        !           552: long linechars(){
        !           553:        if(netd.dp_inspeed == 13)return(960L);
        !           554:        else return(120L);
        !           555:        }
        !           556: /* 
        !           557:        execute the user's command
        !           558:        this procedure is executed with uid, gid of the user
        !           559: */
        !           560: excmd(phd,tempresfile,tempinfile)
        !           561:        register struct header *phd;
        !           562:        char *tempresfile, *tempinfile;
        !           563: {
        !           564:        FILE *fd;
        !           565:        int i, uid;
        !           566:        register char *s, c;
        !           567: 
        !           568:        uid = getuid();
        !           569:        uid = uidmask(uid);
        !           570:        status.muid = uidmask(status.muid);
        !           571:        if(uid != status.muid)error("setuid fails");
        !           572:        debug("uid: %u, gid: %u\n",uid,status.mgid);
        !           573:        /* check for allowed root commands, for security reasons */
        !           574:        if(uid == SUPERUSER){
        !           575:                s = phd->hd_scmdact;
        !           576:                while(*s && *s != ' ')s++;
        !           577:                c = *s;
        !           578:                *s = 0;
        !           579:                /* these are the only commands root may execute */
        !           580:                if(strcmp(phd->hd_scmdact,"cat")                != 0
        !           581:                && strcmp(phd->hd_scmdact,MWRITECMD)            != 0
        !           582:                && strcmp(phd->hd_scmdact,"/bin/cat")           != 0
        !           583:                && strcmp(phd->hd_scmdact,"netrm")              != 0
        !           584:                && strcmp(phd->hd_scmdact,"/usr/lib/tq")        != 0
        !           585:                && strcmp(phd->hd_scmdact,"/usr/cc/lib/tq")     != 0
        !           586:                && strcmp(phd->hd_scmdact,"/usr/lib/rtrrm")     != 0
        !           587:                && strcmp(phd->hd_scmdact,"/usr/cc/lib/rtrrm")  != 0
        !           588:                && strcmp(phd->hd_scmdact,"lpr")                != 0)
        !           589:                        errormsg(TRUE,phd,tempresfile,
        !           590:                                "Not allowed to execute '%s' as root",
        !           591:                                phd->hd_scmdact);
        !           592:                *s = c;
        !           593:                }
        !           594:        if(chdir(status.dir) < 0)
        !           595:                errormsg(TRUE,phd,tempresfile,
        !           596:                        "chdir %s: %s",status.dir,sys_errlist[errno]);
        !           597:        setenv(status.dir);     /* set up v7 environment */
        !           598:        if(tempinfile[0])mreopen(TRUE,phd,tempresfile,tempinfile,"r",stdin);
        !           599:        else if(phd->hd_sinfile[0])mreopen(TRUE,phd,tempresfile,phd->hd_sinfile,"r",stdin);
        !           600:        else mreopen(TRUE,phd,tempresfile,"/dev/null","r",stdin);
        !           601:        if(phd->hd_code == 's' && phd->hd_soutfile[0]){
        !           602:                if(stat(phd->hd_soutfile,&statbuf) < 0
        !           603:                   || getsize(&statbuf) != 0)
        !           604:                        errormsg(FALSE,phd,tempresfile,"Bad result file '%s'",phd->hd_soutfile);
        !           605:                mreopen(TRUE,phd,tempresfile,phd->hd_soutfile,"w",stdout);
        !           606:                }
        !           607:        else if(phd->hd_soutfile[0]){
        !           608:                fd = fopen(phd->hd_soutfile,"w");
        !           609:                if(fd == NULL)
        !           610:                        errormsg(TRUE,phd,tempresfile,"Open file %s: %s",
        !           611:                                phd->hd_soutfile,sys_errlist[errno]);
        !           612:                fclose(fd);
        !           613:                mreopen(TRUE,phd,tempresfile,phd->hd_soutfile,"w",stdout);
        !           614:                }
        !           615:        else mreopen(TRUE,phd,tempresfile,tempresfile,"a",stdout);
        !           616:        debug("exec '%s'\n",phd->hd_scmdact);
        !           617:        if(debugflg == 0){
        !           618:                /* cheat */
        !           619:                close(2);
        !           620:                dup(1);
        !           621:                /*
        !           622:                mreopen(TRUE,phd,tempresfile,tempresfile,"a",stderr);
        !           623:                */
        !           624:                }
        !           625:        for(i=3;i<15;i++)close(i);
        !           626:        if(strcmp(phd->hd_scmdact,"cat") == 0
        !           627:        || strcmp(phd->hd_scmdact,"/bin/cat") == 0)excat();
        !           628:        do {
        !           629:                mexecl(status.loginshell,"sh","-c",phd->hd_scmdact,0);
        !           630:                sleep(2);
        !           631:                } while(errno == ETXTBSY);
        !           632:        perror(status.loginshell);
        !           633:        exit(EX_UNAVAILABLE);
        !           634: }
        !           635: /* 
        !           636:        send back a response
        !           637: 
        !           638:        if errormsg was called the resfile should be unlinked,
        !           639:        to avoid two messages being sent there
        !           640: */
        !           641: sndresponse(phd,rcode)
        !           642: unsigned rcode;
        !           643: struct header *phd;
        !           644: {
        !           645:        char cmdstr[BUFSIZ], buf[BUFSIZ];
        !           646:        int dummy;
        !           647:        long maxfile = MAXFILELARGE;
        !           648:        /* send response back if a response file
        !           649:        was given or if mail/write is allowed */
        !           650:        if(stat(resfile,&statbuf) < 0){
        !           651:                error("%s %s",resfile,sys_errlist[errno]);
        !           652:                return;
        !           653:                }
        !           654:        if(getsize(&statbuf) >= maxfile){
        !           655:                errormsg(TRUE,phd,"Result file too large - not sent");
        !           656:                return;
        !           657:                }
        !           658:        if(getsize(&statbuf) == 0){
        !           659:                /* response file specified, no output generated */
        !           660:                if(phd->hd_srespfile[0] != 0)return;
        !           661:                /* quiet option - no output and a rcode of 0 */
        !           662:                if(rcode == 0 && phd->hd_fquiet)return;
        !           663:        }
        !           664:        /* use both old and new mwrite parm lists */
        !           665: 
        !           666:        if(phd->hd_srespfile[0])
        !           667:                sprintf(cmdstr,"-o %s cat",phd->hd_srespfile);
        !           668:        else sprintf(cmdstr,
        !           669: "%s %s %s %lo %c %s \"'%s'\" %ld -t %s -f %s -x %ld -c \"'%s'\" -y %s -e %ld -r %d",
        !           670:        MWRITECMD, phd->hd_snfrom,phd->hd_sttyname,phd->hd_lttytime,
        !           671:        phd->hd_mchto,phd->hd_snto, phd->hd_scmdvirt,phd->hd_ltimesent-TIMEBASE,
        !           672:        phd->hd_addrfrom, phd->hd_addrto, phd->hd_lttytime,
        !           673:        phd->hd_scmdvirt, phd->hd_sttyname, phd->hd_ltimesent-TIMEBASE, rcode);
        !           674: 
        !           675:        sprintf(buf,"%s -m%c -z -b -l %s -s %s -c response %s",
        !           676:                netcmd,phd->hd_mchfrom,phd->hd_snfrom,resfile,cmdstr);
        !           677:        dummy = system(buf);            /* execute command buf */
        !           678: }
        !           679:        
        !           680: /*
        !           681: 
        !           682:        excat
        !           683:        does nothing more than copy standard input to standard
        !           684:        output, like the cat command, but reports write errors.
        !           685:        Uses getc and putc rather than fwrite and fread because
        !           686:        the latter call getc and putc.
        !           687: */
        !           688: excat(){
        !           689:        register int n;
        !           690:        char buf[BUFSIZ];
        !           691: 
        !           692:        errno = 0;
        !           693:        while((n = read(0,buf,BUFSIZ)) > 0){
        !           694:                if(write(1,buf,n) != n){
        !           695:                        perror("filecat: stdout");
        !           696:                        exit(EX_OSFILE);
        !           697:                        }
        !           698:                }
        !           699:        if(errno){
        !           700:                perror("filecat: stdin");
        !           701:                exit(EX_OSFILE);
        !           702:        }
        !           703:        exit(EX_OK);
        !           704: }
        !           705: /* returns errors for netrcv() */
        !           706: static readhd(phd)
        !           707: register struct header *phd;
        !           708: {
        !           709:        char cflag, sbuf[BUFSIZ], parmlist[PARMLIST], *cptr;
        !           710:        int i, code;
        !           711:        code = mgetc();
        !           712:        phd->hd_mchto = mgetc();
        !           713:        if(code != 'q' && code != 'y' && code != 'w' && code != 's'){
        !           714:                error("bad code");
        !           715:                return(-1);
        !           716:                }
        !           717:        phd->hd_code = code;
        !           718:        for(i = 0; i < MAXINX; i++)
        !           719:                if(phd->hd_mchto == inxtoch(i)) break;
        !           720:        if(i >= MAXINX){
        !           721:                error("bad phd->hd_mchto");
        !           722:                return(-1);
        !           723:                }
        !           724:        if(phd->hd_mchto != local)return(-3);   /* being forwarded through us */
        !           725:        phd->hd_mchfrom = mgetc();
        !           726:        phd->hd_vmajor = mgetc();
        !           727:        phd->hd_vminor = mgetc();
        !           728:        i = 0;
        !           729:        i += mgets(phd->hd_snto,NS);
        !           730:        i += mgets(phd->hd_spasswd,20);
        !           731:        i += mgets(phd->hd_sinfile,FNS);
        !           732:        i += mgets(phd->hd_soutfile,FNS);
        !           733:        i += mgets(phd->hd_srespfile,FNS);
        !           734:        i += mgets(phd->hd_snfrom,NS);
        !           735: 
        !           736:        /* addrfrom is the person who sent this to us,
        !           737:           addrto is the person who received the command, i.e.
        !           738:           addrto is on this machine */
        !           739:        if(phd->hd_snfrom[0] == 0)strcpy(phd->hd_snfrom,"root");
        !           740:        sprintf(phd->hd_addrfrom,  "%s:%s",longname(phd->hd_mchfrom),phd->hd_snfrom);
        !           741:        sprintf(phd->hd_addrto,    "%s:%s",longname(phd->hd_mchto),phd->hd_snto);
        !           742: 
        !           743:        i += mgets(phd->hd_sttyname,20);
        !           744:        if(phd->hd_sttyname[0] == 0)strcpy(phd->hd_sttyname,"/dev/ttyx");
        !           745:        cflag = mgetc();
        !           746:        if(!phd->hd_mchfrom || !phd->hd_code || !cflag || !phd->hd_vmajor || !phd->hd_vminor){
        !           747:                error("mgetc fails");
        !           748:                return(-1);
        !           749:                }
        !           750: 
        !           751:        cflag -= 'a';
        !           752:        phd->hd_fnonotify = (cflag & F_NONOTIFY);
        !           753:        phd->hd_fquiet = (cflag & F_QUIET);
        !           754: 
        !           755:        phd->hd_vmajor -= 'a';
        !           756:        phd->hd_vminor -= 'a';
        !           757: 
        !           758:        i += mgets(sbuf,BUFSIZ);
        !           759:        phd->hd_lttytime = 0;
        !           760:        sscanf(sbuf,"%lo",&phd->hd_lttytime);
        !           761: 
        !           762:        i += mgets(parmlist,PARMLIST);
        !           763: #ifdef CRN
        !           764:        cptr = parmlist;
        !           765:        while( *cptr != '(' )
        !           766:                cptr++;
        !           767:        *cptr = '\0';
        !           768:        strcpy( phd->hd_ijobno, parmlist );
        !           769:        *cptr = '(';
        !           770: #else CRN
        !           771:        strcpy( phd->hd_ijobno, "XYZZ" );
        !           772: #endif CRN
        !           773:        /* keep variable parameter list in crn slot */
        !           774:        parseparmlist(parmlist);
        !           775: 
        !           776:        i += mgets(sbuf,BUFSIZ);                /* time sent */
        !           777:        sscanf(sbuf,"%ld",&phd->hd_ltimesent);
        !           778:        phd->hd_ltimesent += TIMEBASE;
        !           779:        i += mgetcmd(phd->hd_scmdact);
        !           780:        i += mgetcmd(phd->hd_scmdvirt);
        !           781:        if(i != 0){error("mgets fails"); return(-1);}
        !           782:        if(phd->hd_scmdvirt[0] == 0)strcpy(phd->hd_scmdvirt,phd->hd_scmdact);
        !           783:        return(0);
        !           784: }
        !           785: /* 
        !           786:    check() -- verify login name and password
        !           787:    phd    = login,passwd
        !           788:    fverify  = 1 if password must check
        !           789:    Returns 1 if password is ok, 0 if not.
        !           790: */
        !           791: check(phd,fverify)     /* 1 if OK, 0 if not */
        !           792: register struct header *phd;
        !           793: int fverify;
        !           794: {
        !           795:        char *sencpasswd, *u, *nullstr = "";
        !           796:        struct passwd *pwd;
        !           797: #ifdef CRN
        !           798:        struct gecos *gcos;
        !           799: #endif CRN
        !           800:        if(phd->hd_snto[0] == 0)return(!fverify);
        !           801:        debug("check: phd->hd_snto = %s\n", phd->hd_snto );
        !           802:        if(!goodacctname(phd->hd_snto))return(!fverify);
        !           803:        pwd = getpwnam(phd->hd_snto);
        !           804:        debug("got pwd=%d, pwd->pw_passwd = %s\n",pwd, pwd->pw_passwd);
        !           805:        if(pwd == NULL)return(!fverify);
        !           806:        if(*phd->hd_spasswd)sencpasswd = crypt(phd->hd_spasswd,pwd->pw_passwd);
        !           807:        else sencpasswd = nullstr;
        !           808:        debug("check: passwd(rcvd)=%s, passwd(file) = %s, passwd(encrypt)=%s\n", phd->hd_spasswd, pwd->pw_passwd, sencpasswd );
        !           809: 
        !           810:        status.muid = guid(pwd->pw_uid,pwd->pw_gid);
        !           811:        status.mgid = pwd->pw_gid;
        !           812: #ifdef CRN
        !           813:        if( (gcos=pwgecos( pwd->pw_gecos )) == NULL )
        !           814:                strcpy( status.jobno, MAGICCRN );
        !           815:        else 
        !           816:                strcpy( status.jobno, gcos->gc_crn );
        !           817: #else CRN
        !           818:        strcpy( status.jobno, "XYZZ");
        !           819: #endif CRN
        !           820:        strcpy(status.dir,pwd->pw_dir);
        !           821:        strcpy(status.loginshell,pwd->pw_shell);
        !           822:        u = status.loginshell;
        !           823:        if(u[0] == 0 || strcmp("/bin/sbash",u) == 0)strcpy(u,Bsh);
        !           824: 
        !           825:        getpwdf(pwd);
        !           826:        /* ignore network passwd */
        !           827:        /* acct is not a pair, acct is not "network", passwd is incorrect,
        !           828:        and verification is requested => passwd not ok */
        !           829:        if(!facctpaircheck(phd) && strcmp(phd->hd_snto,"network") != 0
        !           830:        && strcmp(pwd->pw_passwd,sencpasswd) != 0 && fverify)
        !           831:                return(0);
        !           832:        return(1);      /* otherwise passwd ok */
        !           833:        }
        !           834: mread(b,n)
        !           835:   register int n; {
        !           836:        if(length <= 0)return(0);
        !           837:        if(length < n)n = length;
        !           838:        n = nread(b,n);
        !           839:        if(n != BROKENREAD)length -= n;
        !           840:        return(n);
        !           841:        }
        !           842: char mgetc(){                  /* returns 0 if fail */
        !           843:        register char c;
        !           844:        register int n;
        !           845:        char buf[3];
        !           846:        if((n=nread(buf,3)) == BROKENREAD)return(0);
        !           847:        if(n != 3){error("bad read %d",n); return(0); }
        !           848:        c = buf[0];
        !           849:        if(buf[1] != ' ' && buf[1] != ':'){error("Bad char %c",buf[1]); return(0); }
        !           850:        length -= 3;
        !           851:        if(length < 0){error("length wrong2 %ld",length); return(0); }
        !           852:        return(c);
        !           853:        }
        !           854: /* read in string over the network wire */
        !           855: /* put string in s, max length is maxlen */
        !           856: mgets(s,maxlen)                        /* returns 0 if ok, 1 if not */
        !           857:   int maxlen;
        !           858:   register char *s; {
        !           859:        register char *q;
        !           860:        register int n;
        !           861:        char c;
        !           862:        q = s;
        !           863:        for(;;) {
        !           864:                if((n=nread(&c,1)) == BROKENREAD){
        !           865:                        *s = 0;
        !           866:                        error("mgets %s",s);
        !           867:                        return(1);
        !           868:                        }
        !           869:                if(n == 0)break;
        !           870:                if(c == '\\'){
        !           871:                        if((n=nread(&c,1)) == BROKENREAD){
        !           872:                                *s = 0;
        !           873:                                error("mgets %s",s);
        !           874:                                return(1);
        !           875:                                }
        !           876:                        if(n == 0)break;
        !           877:                        }
        !           878:                if(c == ' ')break;
        !           879:                if(maxlen-- > 0) *s++ = c;
        !           880:                }
        !           881:        *s = 0;
        !           882:        if(nread(&c,1) == BROKENREAD){
        !           883:                error("mgets %s",s);
        !           884:                return(1);
        !           885:                }
        !           886:        length -= (s - q + 2);
        !           887:        if(length < 0){error("length wrong1 %ld %s",length,q); return(-1); }
        !           888:        if(maxlen < 0)
        !           889:                error("mgets - string too long");
        !           890:        return(0);
        !           891:        }
        !           892: mgetcmd(s)                     /* returns 0 if succeed, 1 otherwise */
        !           893:   char *s; {
        !           894:        int i,n;
        !           895:        char c;
        !           896:        i = 0;
        !           897:        for(;;){
        !           898:                if((n=nread(&c,1)) == BROKENREAD){
        !           899:                        s[i] = 0;
        !           900:                        error("mgetcmd %s",s);
        !           901:                        return(1);
        !           902:                        }
        !           903:                if(n <= 0 || c == '\n')break;
        !           904:                if(c == '\\'){
        !           905:                        if(nread(&c,1) == BROKENREAD){
        !           906:                                s[i] = 0;
        !           907:                                error("mgetcmd %s",s);
        !           908:                                return(1);
        !           909:                                }
        !           910:                        length--;
        !           911:                        }
        !           912:                s[i++] = c;
        !           913:                length--;
        !           914:                }
        !           915:        s[i] = 0;
        !           916:        length--;
        !           917:        return(0);
        !           918:        }
        !           919: increment(s)
        !           920:  char *s; {
        !           921:        int i;
        !           922:        char *p;
        !           923:        i = strlen(s) - 1;
        !           924:        while(s[i] == '9')i--;
        !           925:        if(s[i] < '0' || s[i] > '9'){
        !           926:                p = s+i+1;
        !           927:                while(*p)*p++ = '0';
        !           928:                return;
        !           929:                }
        !           930:        (s[i])++;
        !           931:        i++;
        !           932:        while(s[i])s[i++] = '0';
        !           933:        return;
        !           934:        }
        !           935: /* gather 24-hour stats and  mail to STATADDR */
        !           936: /* should also gather stats on # error msgs */
        !           937: dumpit(currt)
        !           938:   long currt; {
        !           939:        register struct dumpstruc *p = &dump;
        !           940:        register int ntot;
        !           941:        long elapt;
        !           942:        double cputime,utime,stime,bs,rawbs;
        !           943:        char *sstartt;
        !           944:        FILE *fdm;
        !           945:        char froma[30];
        !           946:        struct tms tbf;
        !           947: 
        !           948:        /* if STATADDR is a file, the mail program this call will
        !           949:           ultimately execute must be able to deal with it,
        !           950:           and the remote mail program must be able to write on the
        !           951:           file, i.e. mode 666 */
        !           952:        sprintf(froma,"%s=>",longname(local));
        !           953:        strcat(froma,longname(remote));
        !           954:        fdm = mailopen(STATADDR,froma,1,0);
        !           955:        if(fdm == NULL)return;
        !           956: 
        !           957:        /* calculate times */
        !           958:        elapt = currt - dump.longtime;
        !           959:        ntot = p->nnetcp + p->nnetmail + p->nsmail + p->nnetlpr
        !           960:                + p->nresp + p->nnet;
        !           961:        sstartt = ctime(&dump.longtime) + 4;
        !           962:        sstartt[strlen(sstartt) - 9] = 0;
        !           963: 
        !           964:        times(&tbf);
        !           965: # ifndef NOFP
        !           966:        utime = tbf.tms_utime + tbf.tms_cutime;
        !           967:        stime = tbf.tms_stime + tbf.tms_cstime;
        !           968:        cputime = utime + stime;
        !           969:        if(elapt > 0)cputime = (cputime/elapt) * 100.0;
        !           970:        else cputime = 0.0;
        !           971:        utime = utime/60.0;
        !           972:        stime = stime/60.0;
        !           973:        cputime = cputime/60.0;
        !           974:        bs = p->bytetot;
        !           975:        if(p->elaptot > 0)bs = bs /p->elaptot;
        !           976:        else bs = 0.0;
        !           977: # endif NOFP
        !           978: 
        !           979:        /* print out the statistics */
        !           980:        fprintf(fdm,"Subject: %s, %s, time %s\n",
        !           981:                froma,sstartt, comptime(elapt));
        !           982:        fprintf(fdm,"Command summary:\n");
        !           983:        fprintf(fdm,"\t# sent %d\t# pass_thru %d\t# rcv %d:\t# netcp %d\n",
        !           984:                p->nsend,p->npass,ntot,p->nnetcp);
        !           985:        fprintf(fdm,"\t# netlpr %d\t# netmail %d\t# sendbmail %d\t# resp %d\n",
        !           986:                p->nnetlpr,p->nnetmail,p->nsmail,p->nresp);
        !           987:        fprintf(fdm,"Protocol summary:\n");
        !           988:        fprintf(fdm,"\t# pk_sent %d\t# pk_rcv %d\t# b_sent %ld\t# b_rcv %ld\n",
        !           989:                p->npacksent,p->npackrcv,p->nbytesent, p->nbytercv);
        !           990:        fprintf(fdm,
        !           991:                "\t# send_fails %d\t# retrans %d\t# abn %d\t\t# cksum_errs %d\n",
        !           992:                p->nsendfail,p->nretrans, p->nabnormal,p->ncksum);
        !           993: # ifndef NOFP
        !           994:        fprintf(fdm,"Load:\tuser %4.1f\tsys %4.1f\tpct %5.2f\trate %6.1f\n",
        !           995:                utime,stime,cputime,bs);
        !           996:        rawbs = p->brawtot*100L;
        !           997:        rawbs = rawbs / linechars();
        !           998:        fprintf(fdm,"\trawbytes %ld\tuse %4.1f\n", p->brawtot,rawbs);
        !           999: # endif NOFP
        !          1000:        mailclose(fdm);
        !          1001: 
        !          1002:        /* reset counters */
        !          1003:        p->nbytesent = p->nbytercv = p->elaptot = p->bytetot = 0L;
        !          1004:        p->nretrans = p->nloop = p->nabnormal = p->ncksum = 0;
        !          1005:        p->npacksent = p->npackrcv = p->nnetcp = p->nnetmail = 0;
        !          1006:        p->nsmail = p->nnetlpr = p->nnet = p->npass = 0;
        !          1007:        p->nsend = p->nsendfail = 0;
        !          1008:        dump.longtime = currt;
        !          1009:        }
        !          1010: /* returns 1 if n is ok, 0 if not */
        !          1011: goodacctname(n)
        !          1012:   char *n; {
        !          1013:        int i;
        !          1014:        i = -1;
        !          1015:        while(btable[++i].bname)
        !          1016:                if(strcmp(btable[i].bname,n) == 0 &&
        !          1017:                        local == btable[i].bmach)return(0);
        !          1018:        return(1);
        !          1019:        }
        !          1020: demask(s)
        !          1021:   register char *s; {
        !          1022: /*
        !          1023:        static char buf[20];
        !          1024:        char skey[30];
        !          1025:        makeuukey(skey,status.login,local);
        !          1026:        strcpy(s,nbsdecrypt(s,skey,buf));
        !          1027: */
        !          1028:        while(*s){
        !          1029:                *s &= 0177;             /* strip quote bites */
        !          1030:                *s++ ^= 040;            /* invert upper-lower */
        !          1031:                }
        !          1032:        }
        !          1033: /*VARARGS0*/
        !          1034: mreopen(fsendtofmach,phd,sfn,a,b,c){
        !          1035: /* simply handles errors by giving error msg */
        !          1036:        if(freopen(a,b,c) == NULL)
        !          1037:                errormsg(fsendtofmach,phd,sfn,"%s: %s",a,sys_errlist[errno]);
        !          1038: }
        !          1039: /* 
        !          1040:        addtopub(string, args)
        !          1041: 
        !          1042:        add a message to the public logfile /usr/net/logfile.
        !          1043:        note that the file must be writeable by everyone
        !          1044:        if error messages from the netrcv subroutine
        !          1045:        such as chdir errors are to be noticed.
        !          1046: */
        !          1047: /*VARARGS0*/
        !          1048: addtopublic(s,a,b,c,d,e,f,g,h,i,j,k,l,m,n)
        !          1049: char *s;
        !          1050: {
        !          1051:        static FILE *log = NULL;
        !          1052:        if(log == NULL){
        !          1053:                if(stat(publogfile,&statbuf) < 0)return;
        !          1054:                log = fopen(publogfile,"a");
        !          1055:                if(log == NULL)return;
        !          1056:                }
        !          1057:        fseek(log,0L,2);
        !          1058:        fprintf(log,s,a,b,c,d,e,f,g,h,i,j,k,l,m,n);
        !          1059:        fflush(log);
        !          1060:        }
        !          1061: /* set up a dummy environment for v7 /bin/sh */
        !          1062: setenv(home)
        !          1063:   char *home; {
        !          1064:        static char *env[3],benv[2][50];
        !          1065:        env[0] = benv[0];
        !          1066:        env[1] = benv[1];
        !          1067: #ifdef CCV7
        !          1068:        strcpy( env[0], "PATH=:.:/usr/cc/bin:/usr/ucb/bin" );
        !          1069: #else CCV7
        !          1070:        strcpy(env[0],"PATH=:/bin:/usr/bin");
        !          1071: #endif CCV7
        !          1072:        sprintf(env[1],"HOME=%s",home);
        !          1073:        env[2] = 0;
        !          1074:        environ = env;
        !          1075:        }
        !          1076: /* 
        !          1077:        errormsg(fsendtofmach,phd,sfn,"string",arg(s))
        !          1078:        
        !          1079:        Sends error message to user.
        !          1080:        If fsendtofmach=TRUE, send to phd->hd_mchfrom, otherwise
        !          1081:        send to phd->hd_mchto.
        !          1082:        Also, if error occured during return of a "response",
        !          1083:        send to local machine.
        !          1084: 
        !          1085:        Note that errormsg can be called by the netrcv subroutine
        !          1086:        after the setuid() call to the specific user, so the 
        !          1087:        user must be able to get off an error msg back to him,
        !          1088:        and to write in the two log files.
        !          1089:        Can't use -w,-x,-y,-z for the net cmd because must be root for those.
        !          1090: 
        !          1091:        If sfn != NULL, then unlink sfn before exiting.
        !          1092: */
        !          1093: /*VARARGS0*/
        !          1094: errormsg(fsendtofmach,phd,sfn,s,a,b,c,d,e,f,g,h)
        !          1095: char fsendtofmach;                             
        !          1096: struct header *phd;
        !          1097: char *sfn,*s;
        !          1098: {
        !          1099:        int rcode;
        !          1100:        char errstr[BUFSIZ], cmdstr[BUFSIZ], rcmd[BUFSIZ];
        !          1101:        char toadd[FNS], fromadd[FNS], mchto, mchfrom;
        !          1102:        char snto[FNS], snfrom[FNS];
        !          1103: 
        !          1104:        if(phd->hd_sttyname[0] == 0)strcpy(phd->hd_sttyname,"/dev/ttyx");
        !          1105:        /* will send to toadd, from fromadd */
        !          1106:        if(!fsendtofmach || strcmp(phd->hd_scmdvirt,"response") == 0){
        !          1107:                /* send to tomach mach, thus send to toaddr. */
        !          1108:                /* if this is an error during a response, send to local mach. */
        !          1109:                strcpy(toadd,  phd->hd_addrto);
        !          1110:                strcpy(fromadd,phd->hd_addrfrom);
        !          1111:        }
        !          1112:        else {          /* send to remote mach, thus send back to addrfrom*/
        !          1113:                strcpy(toadd,  phd->hd_addrfrom);
        !          1114:                strcpy(fromadd,phd->hd_addrto);
        !          1115:        }
        !          1116:        sprintf(errstr,"Error: ");
        !          1117:        sprintf(cmdstr,s,a,b,c,d,e,f,g,h);
        !          1118:        strcat(errstr,cmdstr);
        !          1119:        strcat(errstr,"\n");
        !          1120:        addtolog(remote,errstr);
        !          1121:        addtopublic(errstr);
        !          1122: 
        !          1123:        mchto =   MchSFromAddr(snto,toadd); 
        !          1124:        mchfrom = MchSFromAddr(snfrom,fromadd);
        !          1125: 
        !          1126:        sprintf(rcmd,
        !          1127: "%s %s %s %lo %c %s \"'%s'\" %ld -t %s -f %s -x %ld -y %s -c \"'%s'\" -e %ld",
        !          1128:        MWRITECMD, snto, phd->hd_sttyname, phd->hd_lttytime, 
        !          1129:        local, snfrom,phd->hd_scmdvirt, phd->hd_ltimesent-TIMEBASE,
        !          1130:        toadd, fromadd, phd->hd_lttytime, phd->hd_sttyname, phd->hd_scmdvirt,
        !          1131:        phd->hd_ltimesent-TIMEBASE);
        !          1132: 
        !          1133:        if(mchto == local)
        !          1134:                sprintf(cmdstr, "echo \"%s\" | %s", errstr,rcmd);
        !          1135:        else 
        !          1136:                sprintf(cmdstr,
        !          1137:                "echo \"%s\" | %s -m%c -b -c errormessage -l network - %s",
        !          1138:                        errstr,netcmd,mchto,rcmd);
        !          1139:        rcode = system(cmdstr);
        !          1140:        debug( "errormsg: cmdstr = %s\n", cmdstr );
        !          1141:        debug( "errormsg: rcode = %d\n", rcode );
        !          1142:        if(sfn != NULL)unlink(sfn);
        !          1143:        exit(EX_USAGE);
        !          1144:        }
        !          1145: handlekill(){  /* SIGTERM signal */
        !          1146:        long t;
        !          1147:        /*
        !          1148:        t = gettime();
        !          1149:        dumpit(t);
        !          1150:        */
        !          1151: # ifdef NETLDISC
        !          1152:        /* turn off net line discipline if possible */
        !          1153:        netd.dp_linedis = 0;
        !          1154:        ioctl(netd.dp_linefd,TIOCSETD,&netd.dp_linedis);
        !          1155:        close(netd.dp_linefd);
        !          1156:        printf("Network line discipline turned off.\n");
        !          1157: # endif NETLDISC
        !          1158:        exit(EX_OK);    /* kill myself */
        !          1159:        }
        !          1160: 
        !          1161: /* check a request to see if it is an acct pair */
        !          1162: /* returns 1 if it is, 0 if not */
        !          1163: static facctpaircheck(phd)
        !          1164: register struct header *phd;
        !          1165: {
        !          1166:        return(0);
        !          1167: }
        !          1168: 

unix.superglobalmegacorp.com

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