Annotation of 43BSD/old/berknet/netdaemon.c, revision 1.1.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.