Annotation of 3BSD/cmd/net/netdaemon.c, revision 1.1

1.1     ! root        1: /*
        !             2:        The daemon program that runs the network.
        !             3: 
        !             4:        netdaemon mach readfd writefd
        !             5: 
        !             6:        Must be started by root.
        !             7: */
        !             8: 
        !             9: # include "defs.h"
        !            10: 
        !            11: /* global variables */
        !            12: extern char **environ;
        !            13: short masterseqno, lastseqno;
        !            14: struct dumpstruc dump;
        !            15: struct bstruct btable[];
        !            16: int onlyuid;
        !            17: 
        !            18: /* local variables */
        !            19: static long length;
        !            20: static char nsendfail;
        !            21: static FILE *dir;
        !            22: static char header[] =                 "ABCDE";
        !            23: static char tempfile[]=        TEMPFILE;
        !            24: static char publogfile[]=      PUBLOGFILE;
        !            25: static char dumpfile[]=        DUMPFILE;
        !            26: static char namefile[]=        NAMEFILE;
        !            27: static struct stat statbuf;
        !            28: static struct direct dirbuf;
        !            29: int handlekill();
        !            30: static char frommach;
        !            31: static char buf[BUFSIZ];
        !            32: /* addrfrom is the person who sent this to us,
        !            33:    addrto is the person who received the command, i.e.
        !            34:    addrto is on this machine */
        !            35: static char addrto[BUFSIZ], addrfrom[BUFSIZ];
        !            36: 
        !            37: main(argc,argv)
        !            38:   char **argv; {
        !            39:        register int i;
        !            40:        long ltime,t;
        !            41: 
        !            42:        signal(SIGTRM,handlekill);
        !            43:        debugflg = DBV;
        !            44:        setupdaemon(argc,argv);
        !            45:        /* now running alone as a daemon */
        !            46:                /*
        !            47:                for(i=0; i<15; i++)close(i);
        !            48:                signal(SIGHUP,SIG_IGN);
        !            49:                signal(SIGQUIT,SIG_IGN);
        !            50:                signal(SIGINT,SIG_IGN);
        !            51:                */
        !            52:        senddir[strlen(senddir)-1] = remote;            /* choose dir */
        !            53:        if(chdir(senddir) < 0){
        !            54:                perror(senddir);
        !            55:                exit(1);
        !            56:                }
        !            57:        dir = fopen(senddir,"r");
        !            58:        if(dir == NULL){
        !            59:                perror(senddir);
        !            60:                exit(1);
        !            61:                }
        !            62:        mktemp(tempfile);
        !            63:        tempfile[strlen(tempfile) - 7] = remote;
        !            64:        ltime = gettime();
        !            65:        sprintf(buf,"net restarted to %s %d %s",longname(remote),
        !            66:                getpid(),ctime(&ltime));
        !            67:        dump.longtime = dump.shorttime = ltime;
        !            68:        addtolog(remote,buf);
        !            69:        addtodump(remote,buf);
        !            70:        addtopublic(buf);
        !            71:        fprintf(stderr,buf);
        !            72:        if(!debugflg)fclose(stderr);
        !            73:        sendpurge();
        !            74:        nsendfail = 0;
        !            75:        for(;;){        /* begin reading file */
        !            76:                debug("daemon %c %d\nreceive",remote,getpid());
        !            77:                i = getreset();
        !            78:                dump.waittime = 0L;
        !            79:                if(i == BROKENREAD){
        !            80:                        if(nsendfail < NSEND) netsend();
        !            81:                        else nsendfail++;
        !            82:                        }
        !            83:                else {
        !            84:                        i = netrcv();
        !            85:                        if(i >= 0){
        !            86:                                nsendfail = 0;  /* it sent, it is up */
        !            87:                                dump.waittot += dump.waittime;
        !            88:                                }
        !            89:                        if(i == -1)dump.nabnormal++;
        !            90:                        }
        !            91:                t = gettime();
        !            92:                if(t - dump.shorttime > SAMPL)pload(t);
        !            93:                if(t - dump.longtime > BIGSAMPL)dumpit(t);
        !            94:                dump.nloop++;
        !            95:                /* count up to NSEND, sending, then wait NSEND */
        !            96:                if(nsendfail >= NSEND*2)nsendfail = 0;  
        !            97:                }
        !            98:        }
        !            99: netsend(){
        !           100:        static long lasttime = 0;
        !           101:        static char nleft = 1;
        !           102:        long lFileLen,diff;
        !           103:        double drate;
        !           104:        int uid,uidBest;
        !           105:        char *sdate,*sn,*swait;
        !           106:        long ot,nt,filesize;
        !           107:        register int i;
        !           108:        char stemp[20];
        !           109:        static char jname[FNS];
        !           110: 
        !           111:        debug("ck send");
        !           112:        if(stat(senddir,&statbuf) < 0){
        !           113:                error("%s %s",senddir,sys_errlist[errno]);
        !           114:                return;
        !           115:                }
        !           116:        if(statbuf.st_mtime == lasttime && nleft == 0)return;   /* no need to search */
        !           117:        lasttime = statbuf.st_mtime;
        !           118:        fseek(dir,0L,0);
        !           119:        lFileLen = 10000000L;
        !           120:        nleft = 0;
        !           121:        while(fread(&dirbuf,1,sizeof dirbuf,dir) == sizeof dirbuf){
        !           122:                if(dirbuf.d_ino == 0
        !           123:                   || dirbuf.d_name[0] != 'c'
        !           124:                   || dirbuf.d_name[1] != 'f'
        !           125:                   || dirbuf.d_name[2] != remote
        !           126:                   || stat(dirbuf.d_name,&statbuf) < 0
        !           127:                   || statbuf.st_mode == 0)
        !           128:                        continue;
        !           129:                dirbuf.d_name[0] = 'd';
        !           130:                if(stat(dirbuf.d_name,&statbuf) < 0 || statbuf.st_mode == 0)
        !           131:                        continue;
        !           132:                uid = guid(statbuf.st_uid,statbuf.st_gid);
        !           133:                if(onlyuid != 0 && uid != onlyuid && uid != SUPERUSER)continue;
        !           134:                nleft++;
        !           135:                filesize = getsize(&statbuf);
        !           136:                if(lFileLen > filesize){
        !           137:                        lFileLen = filesize;
        !           138:                        for(i=0; i<DIRSIZ; i++)
        !           139:                                jname[i] = dirbuf.d_name[i];
        !           140:                        uidBest = uid;
        !           141:                }
        !           142:        }
        !           143:        if(lFileLen == 10000000L)return;
        !           144:        strcpy(stemp,jname);
        !           145:        stemp[0] = 'c';
        !           146:        sn = SnFromUid(uidBest);
        !           147:        if(sn == NULL){
        !           148:                addtolog(remote,"Unknown userid %d\n",uidBest);
        !           149:                return;
        !           150:        }
        !           151:        addtolog(remote,"^S %s %c: %s ",sn,remote,jname+2);
        !           152:        ot = gettime();
        !           153:        dump.waittime = 0L;
        !           154:        if(send(jname) == 0)return;
        !           155:        nt = gettime();
        !           156:        dump.waittot += dump.waittime;
        !           157:        filesize = getsize(&statbuf);
        !           158:        unlink(jname);
        !           159:        unlink(stemp);
        !           160:        diff = nt - ot;
        !           161:        if(diff < 1)diff = 1;           /* avoid dividing by zero */
        !           162:        sdate = ctime(&nt)+4;
        !           163:        sdate[strlen(sdate) -9] = 0;
        !           164:        drate = (double)filesize / (double)diff;
        !           165:        swait = comptime(ot - statbuf.st_mtime);
        !           166:        jname[3] = jname[2];
        !           167:        addtolog(remote,"^T%c(%s, %ldb, %ldsec, %4.1fb/sec, w %s)\n",
        !           168:                remote,sdate,filesize, diff,drate, swait);
        !           169:        addtopublic("%s: sent %-8s to %c (%s, %ld b, wait %s)\n",
        !           170:                sdate,sn,remote,jname+3,filesize,swait);
        !           171:        dump.nsend++;
        !           172:        dump.bytetot += filesize;
        !           173:        dump.elaptot += diff;
        !           174:        /* add this users name to /usr/net/usernames */
        !           175:        addtoname(sn);
        !           176:        }
        !           177: send(jname)
        !           178:        char *jname;
        !           179: {      /* push those bytes */
        !           180:        /* returns 0 if send fails, 1 otherwise */
        !           181:        register int n;
        !           182:        int i;
        !           183:        long lsize;
        !           184:        char mbuf[BUFSIZ];
        !           185:        register char *p;
        !           186:        FILE *jfile;
        !           187: 
        !           188:        debug("send %s",jname);
        !           189:        if(stat(jname,&statbuf) < 0)goto sfail;
        !           190:        lsize = getsize(&statbuf);
        !           191:        if(lsize < MINSIZE){            /* all files are at least this long */
        !           192:                unlink(jname);
        !           193:                jname[0] = 'c';
        !           194:                unlink(jname);
        !           195:                return(1);
        !           196:                }
        !           197:        jfile = fopen(jname,"r");
        !           198:        if(jfile == NULL)goto sfail;
        !           199:        strcpy(mbuf,header);
        !           200:        i = strlen(header);
        !           201:        p = (char *)&lsize;
        !           202:        lsize = fixuplong(lsize);
        !           203:        mbuf[i] = *p++;
        !           204:        mbuf[i+1] = *p++;
        !           205:        mbuf[i+2] = *p++;
        !           206:        mbuf[i+3] = *p++;
        !           207:        i = i + 4;
        !           208:        sendreset();
        !           209:        masterseqno = 1;
        !           210:        lastseqno = 0;
        !           211:        if(xwrite(mbuf,1,i) == WRITEFAIL)goto bwrite;
        !           212:        while((n=fread(buf,1,BLOCKSIZE,jfile)) > 0)
        !           213:                if(xwrite(buf,1,n) == WRITEFAIL)goto bwrite;
        !           214:        fclose(jfile);
        !           215:        debug("end send");
        !           216:        nsendfail = 0;
        !           217:        return(1);
        !           218: bwrite:
        !           219:        nsendfail++;
        !           220:        dump.nsendfail++;
        !           221:        fclose(jfile);
        !           222:        addtolog(remote,"^F%c\n",remote);
        !           223:        return(0);
        !           224: sfail:
        !           225:        error("%s: %s",jname,sys_errlist[errno]);
        !           226:        dump.nsendfail++;
        !           227:        return(0);
        !           228:        }
        !           229: netrcv(){
        !           230:        /* returns -2 in normal fail, -1 in abnormal fail, >= 0 otherwise */
        !           231:        char code, sin;
        !           232:        char tmach, fmach;
        !           233:        char mgetc(), cflag, *s;
        !           234:        register int n,i;
        !           235:        char vmajor, vminor, c;
        !           236:        int rcode, dummy, pid, uid;
        !           237:        char buf1[BUFSIZ], cmdstr[BUFSIZ];
        !           238:        static char parmlist[PARMLIST];
        !           239:        long timesent,otime,olength,diff,rcvfinish,nt,maxfile = MAXFILE;
        !           240:        double r;
        !           241:        static char resp[FNS], infile[FNS], outfile[FNS];
        !           242:        static char hbuf[10];
        !           243:        static FILE *temp;
        !           244: 
        !           245:        n = nread(hbuf,1,strlen(header));
        !           246:        if(n == BROKENREAD)return(-2);
        !           247:        if(n != strlen(header) || strcmp(header,hbuf) != 0){
        !           248:                error("wrong head %d %s",n,hbuf);
        !           249:                return(-1);
        !           250:                }
        !           251:        n = nread(&length,1,4);
        !           252:        if(n == BROKENREAD)return(-2);
        !           253:        if(n != 4){
        !           254:                error("bad length nread %d",n);
        !           255:                return(-1);
        !           256:                }
        !           257:        length = fixuplong(length);
        !           258:        olength = length;
        !           259:        otime = gettime();
        !           260:        debug("length = %ld\n",length);
        !           261:        i = 0;
        !           262: 
        !           263: /* 
        !           264:        begin parsing header
        !           265: 
        !           266:        from local to remote (requests)
        !           267:        code    net option      reason
        !           268:        q                       normal request
        !           269:        y       -y              simply skips login check (used by netlpr)
        !           270: 
        !           271:        from remote to local
        !           272:        code    net option      reason
        !           273:        w       -w              message to be written/mailed back
        !           274:        s       -z              normal response
        !           275: */
        !           276: 
        !           277:        code = mgetc();
        !           278:        tmach = mgetc();
        !           279:        if(tmach < 'a' || 'z' < tmach){
        !           280:                error("bad tmach");
        !           281:                return(-1);
        !           282:                }
        !           283:        if(tmach != local)goto forw;    /* being forwarded through us */
        !           284:        fmach = mgetc();
        !           285:        vmajor = mgetc();
        !           286:        vminor = mgetc();
        !           287:        i += mgets(status.login,NS);
        !           288:        i += mgets(status.mpasswd,20);
        !           289:        demask(status.mpasswd);
        !           290:        i += mgets(infile,FNS);
        !           291:        i += mgets(outfile,FNS);
        !           292:        i += mgets(resp,FNS);
        !           293:        i += mgets(status.localname,NS);
        !           294: 
        !           295:        /* addrfrom is the person who sent this to us,
        !           296:           addrto is the person who received the command, i.e.
        !           297:           addrto is on this machine */
        !           298:        if(status.localname[0] == 0)strcpy(status.localname,"root");
        !           299:        sprintf(addrfrom,  "%s:%s",longname(fmach),status.localname);
        !           300:        sprintf(addrto,    "%s:%s",longname(tmach),status.login);
        !           301: 
        !           302:        i += mgets(status.sTtyname,20);
        !           303:        if(status.sTtyname[0] == 0)strcpy(status.sTtyname,"/dev/ttyx");
        !           304:        cflag = mgetc();
        !           305:        if(!fmach || !code || !cflag || !vmajor || !vminor){
        !           306:                error("mgetc fails");
        !           307:                return(-1);
        !           308:                }
        !           309:        cflag -= 'a';
        !           310:        vmajor -= 'a';
        !           311:        vminor -= 'a';
        !           312:        if(vmajor != VMAJOR || vminor != VMINOR){
        !           313:                /*
        !           314:                error("versions dont agree (%d,%d) vs. (%d,%d) remote",
        !           315:                        VMAJOR,VMINOR,vmajor,vminor);
        !           316:                return(-1);
        !           317:                */
        !           318:                }
        !           319:        i += mgets(buf,BUFSIZ);
        !           320:        status.lTtytime = 0;
        !           321:        sscanf(buf,"%lo",&status.lTtytime);
        !           322: 
        !           323:        i += mgets(parmlist,PARMLIST);
        !           324:        status.jobno = atoi(parmlist);
        !           325:        /* keep variable parameter list in jobno slot */
        !           326:        parseparmlist(parmlist);
        !           327: 
        !           328:        i += mgets(buf1,BUFSIZ);                /* time sent */
        !           329:        sscanf(buf1,"%ld",&timesent);
        !           330:        i += mgetcmd(status.sCmdAct);
        !           331:        i += mgetcmd(status.sCmdVirt);
        !           332:        if(i != 0){error("mgets fails"); return(-1);}
        !           333:        if(status.sCmdVirt[0] == 0)strcpy(status.sCmdVirt,status.sCmdAct);
        !           334:        s = status.sCmdVirt;
        !           335:        while(*s && *s != ' ')s++;
        !           336:        c = *s;
        !           337:        *s = 0;
        !           338:        if(strcmp(status.sCmdVirt,"netlpr") == 0)dump.nnetlpr++;
        !           339:        else if(strcmp(status.sCmdVirt,"netmail") == 0)dump.nnetmail++;
        !           340:        else if(strcmp(status.sCmdVirt,"mail") == 0)dump.nsmail++;
        !           341:        else if(strcmp(status.sCmdVirt,"netcp") == 0)dump.nnetcp++;
        !           342:        else if(strcmp(status.sCmdVirt,"response") == 0)dump.nresp++;
        !           343:        else dump.nnet++;
        !           344:        *s = c;
        !           345:        debug("%c %c %c (%c,%c) %s %s %s %s (%s) %s %c %lo %d %s\n",
        !           346:                code,tmach,fmach,vmajor+'a',vminor+'a',status.login,
        !           347:                infile,outfile,resp,status.localname,
        !           348:                status.sTtyname,cflag+'a',status.lTtytime,status.jobno,status.sCmdAct);
        !           349: 
        !           350: 
        !           351:        /* any chars left are data */
        !           352: forw:
        !           353:        sin = 0;
        !           354:        if(length > 0){ /* make a temp input file */
        !           355:                increment(tempfile);
        !           356:                temp = fopen(tempfile,"w");
        !           357:                if(temp == NULL){
        !           358:                        error("%s %s",tempfile,sys_errlist[errno]);
        !           359:                        return(-1);
        !           360:                        }
        !           361:                chmod(tempfile,0600);
        !           362:                if(tmach != local)fprintf(temp,"%c :%c :",code,tmach);
        !           363:                while((n = mread(buf,1,BLOCKSIZE)) > 0)
        !           364:                        if(fwrite(buf,1,n,temp) != n){
        !           365:                                error("%s %s",tempfile,sys_errlist[errno]);
        !           366:                                fclose(temp);
        !           367:                                unlink(tempfile);
        !           368:                                return(-1);
        !           369:                                };
        !           370:                fclose(temp);
        !           371:                if(n == BROKENREAD || length > 0){
        !           372:                        unlink(tempfile);
        !           373:                        return(-2);
        !           374:                        }
        !           375:                sin = 1;
        !           376:                if(tmach != local){
        !           377:                        diff = gettime() - otime;
        !           378:                        if(diff < 1)diff = 1;   /* avoid dividing by 0 */
        !           379:                        r = olength;
        !           380:                        r = r/diff;
        !           381:                        addtolog(remote,"^P(to %c, %ldb, %ldsec, %4.1fb/sec)\n",
        !           382:                                tmach,olength,diff,r);
        !           383:                        dump.npass++;
        !           384:                        dump.bytetot += olength;
        !           385:                        dump.elaptot += diff;
        !           386:                        while((pid = fork()) == -1)sleep(2);
        !           387:                        if(pid == 0){
        !           388:                                execl(netcmd,"net","-x","-m",longname(tmach),
        !           389:                                        "-s",tempfile,buf,0);
        !           390:                                exit(1);
        !           391:                                }
        !           392:                        wait(&dummy);
        !           393:                        unlink(tempfile);
        !           394:                        return(1);
        !           395:                        }
        !           396:                }
        !           397:        if(length > 0){error("file too short"); return(-1); }
        !           398:        rcvfinish = gettime();
        !           399: 
        !           400:        while((pid = fork()) == -1)sleep(2);
        !           401:        if(pid > 0){
        !           402:                wait(&dummy);
        !           403:                return(1);      /* normal return */
        !           404:        }
        !           405: 
        !           406:        while((pid = fork()) == -1)sleep(2);
        !           407:        if(pid != 0)exit(0);
        !           408: 
        !           409:        /* child process which forks and waits */
        !           410:        mktemp(resfile);
        !           411:        while((pid = fork()) == -1)sleep(2);
        !           412:        if(pid == 0){
        !           413:                /* child */
        !           414:                strcpy(status.loginshell,Bsh);
        !           415:                frommach = fmach;
        !           416:                n = check(status.login,status.mpasswd,(code == 'q'));
        !           417:                if(!n)errormsg(fmach,"Bad remote login/password '%s'",status.login);
        !           418:                temp = fopen(resfile,"w");
        !           419:                if(temp == NULL)
        !           420:                        errormsg(fmach,"creat %s %s",resfile,sys_errlist[errno]);
        !           421:                chmod(resfile,0600);
        !           422:                fclose(temp);
        !           423:                mchown(resfile,status.muid,status.mgid);
        !           424:                if(sin)
        !           425:                        mchown(tempfile,status.muid,status.mgid);
        !           426:                setuid(status.muid);
        !           427:                setgid(status.mgid);
        !           428:                uid = getuid();
        !           429:                uid = uidmask(uid);
        !           430:                status.muid = uidmask(status.muid);
        !           431:                if(uid != status.muid)error("setuid fails");
        !           432:                debug("uid: %o\n",uid);
        !           433:                /* check for allowed root commands, for security reasons */
        !           434:                if(uid == SUPERUSER){
        !           435:                        s = status.sCmdAct;
        !           436:                        while(*s && *s != ' ')s++;
        !           437:                        c = *s;
        !           438:                        *s = 0;
        !           439:                        /* these are the only commands root may execute */
        !           440:                        if(strcmp(status.sCmdAct,"cat")            != 0
        !           441:                        && strcmp(status.sCmdAct,CATCMD)           != 0
        !           442:                        && strcmp(status.sCmdAct,FILECAT)          != 0
        !           443:                        && strcmp(status.sCmdAct,MWRITECMD)        != 0
        !           444:                        && strcmp(status.sCmdAct,"/usr/lib/tq")    != 0
        !           445:                        && strcmp(status.sCmdAct,"/usr/lib/rtrrm") != 0
        !           446:                        && strcmp(status.sCmdAct,"lpr")            != 0)
        !           447:                                errormsg(fmach,
        !           448:                                        "Not allowed to execute '%s' as root",
        !           449:                                        status.sCmdAct);
        !           450:                        *s = c;
        !           451:                        }
        !           452:                if(chdir(status.dir) < 0)
        !           453:                        errormsg(fmach,"chdir %s %s",status.dir,sys_errlist[errno]);
        !           454:                setenv(status.dir);     /* set up v7 environment */
        !           455:                if(sin)mreopen(fmach,tempfile,"r",stdin);
        !           456:                else if(infile[0])mreopen(fmach,infile,"r",stdin);
        !           457:                else mreopen(fmach,"/dev/null","r",stdin);
        !           458:                if(code == 's' && outfile[0]){
        !           459:                        if(stat(outfile,&statbuf) < 0
        !           460:                           || getsize(&statbuf) != 0
        !           461:                           || !(statbuf.st_mode&0600))
        !           462:                                errormsg(local,"Bad result file '%s'",outfile);
        !           463:                        mreopen(fmach,outfile,"w",stdout);
        !           464:                        }
        !           465:                else if(outfile[0]){
        !           466:                        temp = fopen(outfile,"w");
        !           467:                        if(temp == NULL)
        !           468:                                errormsg(fmach,"fopen %s %s",outfile,sys_errlist[errno]);
        !           469:                        fclose(temp);
        !           470:                        mreopen(fmach,outfile,"w",stdout);
        !           471:                        }
        !           472:                else mreopen(fmach,resfile,"a",stdout);
        !           473:                debug("exec '%s'\n",status.sCmdAct);
        !           474:                if(debugflg == 0){
        !           475:                        /* cheat */
        !           476:                        close(2);
        !           477:                        dup(1);
        !           478:                        /*
        !           479:                        mreopen(fmach,resfile,"a",stderr);
        !           480:                        */
        !           481:                        }
        !           482:                for(i=3;i<15;i++)close(i);
        !           483:                do {
        !           484:                        mexecl(status.loginshell,"sh","-c",status.sCmdAct,0);
        !           485:                        sleep(2);
        !           486:                        } while(errno == ETXTBSY);
        !           487:                exit(1);
        !           488:                }
        !           489:        /* parent */
        !           490:        wait(&rcode);
        !           491:        rcode >>= 8;
        !           492:        /*
        !           493:        fclose(stdin);
        !           494:        fclose(stdout);
        !           495:        fclose(stderr);
        !           496:        */
        !           497:        if(sin)unlink(tempfile);
        !           498:        /* 
        !           499:           now send something back to the sender 
        !           500:           unless this was a response (file or message)
        !           501:        */
        !           502:        if((code == 'q' || code == 'y') && (resp[0] || !(cflag&F_NONOTIFY))){
        !           503:                /* send response back if a response file
        !           504:                was given or if mail/write is allowed */
        !           505:                /* should give an error message for non-zero return codes */
        !           506:                if(stat(resfile,&statbuf) < 0){
        !           507:                        error("%s %s",resfile,sys_errlist[errno]);
        !           508:                        goto next;
        !           509:                        }
        !           510:                /* allow larger files between the Ingres machines */
        !           511:                if(machtype[local  - 'a'] == M_INGRES
        !           512:                && machtype[remote - 'a'] == M_INGRES)
        !           513:                        maxfile = MAXFILELARGE;
        !           514:                if(getsize(&statbuf) >= maxfile){
        !           515:                        errormsg(fmach,"Result file too large - not sent");
        !           516:                        goto next;
        !           517:                        }
        !           518:                if(getsize(&statbuf) == 0){
        !           519:                        /* response file specified, no output generated */
        !           520:                        if(resp[0] != 0) goto next;
        !           521:                        /* quiet option - no output and a rcode of 0 */
        !           522:                        if(rcode == 0 && (cflag&F_QUIET))goto next;
        !           523:                }
        !           524:                /* use both old and new mwrite parm lists */
        !           525: 
        !           526:                if(resp[0])sprintf(cmdstr,"-o %s %s",resp,CATCMD);
        !           527:                else sprintf(cmdstr,
        !           528: "%s %s %s %lo %c %s \"'%s'\" %ld -t %s -f %s -x %ld -c \"'%s'\" -y %s -e %ld -r %d",
        !           529: MWRITECMD, status.localname,status.sTtyname,status.lTtytime,tmach,status.login, status.sCmdVirt,timesent,
        !           530: addrfrom, addrto, status.lTtytime, status.sCmdVirt, status.sTtyname, timesent, rcode);
        !           531:                sprintf(buf,"%s -m%c -z -b -l %s -s %s -c response %s",
        !           532:                        netcmd,fmach,status.localname,resfile,cmdstr);
        !           533:                dummy = system(buf);            /* execute command buf */
        !           534:                }
        !           535: next:
        !           536:        unlink(resfile);
        !           537:        s = ctime(&rcvfinish);
        !           538:        s += 4;
        !           539:        s[strlen(s) -8] = 0;
        !           540:        diff = rcvfinish - otime;
        !           541:        if(diff < 1)diff = 1;           /* avoid dividing by zero */
        !           542:        r = olength;
        !           543:        r = r/diff;
        !           544:        dump.bytetot += olength;
        !           545:        dump.elaptot += diff;
        !           546:        sprintf(buf,"%s rcv  %c:%-8s (%s)",
        !           547:                s,fmach,status.localname,status.login);
        !           548:        addtolog(remote,"%s C: %s\n",buf,status.sCmdVirt);
        !           549:        addtopublic("%s R: %d C: %s\n",buf,rcode,status.sCmdVirt);
        !           550:        nt = rcvfinish - timesent - TIMEBASE;
        !           551:        buf[0] = 0;
        !           552:        if(nt > 0L)sprintf(buf," took (%s)",comptime(nt));
        !           553:        addtolog(remote,"\t\tR: %d%s %ldb %ldsec %4.1fb/sec\n",
        !           554:                rcode,buf,olength,diff,r);
        !           555:        exit(0);
        !           556:        /*UNREACHED*/
        !           557:        }
        !           558: 
        !           559: /* 
        !           560:    check() -- verify login name and password
        !           561:    snTo    = login,
        !           562:    pass    = passwd,
        !           563:    verify  = 1 if password must check
        !           564:    Returns 1 if password is ok, 0 if not.
        !           565: */
        !           566: check(snTo,pass,verify)        /* 1 if OK, 0 if not */
        !           567:   int verify;
        !           568:   char *snTo, *pass; {
        !           569:        int ver;
        !           570:        char *s, *u, *nullstr = "";
        !           571:        struct passwd *pwd;
        !           572:        ver = (verify == 0);            /* ver is true if password verification
        !           573:                                                was not requested */
        !           574:        if(snTo[0] == 0)return(ver);
        !           575:        if(!goodacctname(snTo))return(ver);
        !           576:        pwd = getpwnam(snTo);
        !           577:        if(pwd == NULL)return(ver);
        !           578: # ifndef NEWPROT
        !           579:        if(machtype[local-'a'] == M_CC && machtype[frommach-'a'] == M_CC)
        !           580:                s = pass;
        !           581:        else
        !           582: # endif
        !           583:        if(*pass)s = crypt(pass,pwd->pw_passwd);
        !           584:        else s = nullstr;
        !           585:        status.muid = guid(pwd->pw_uid,pwd->pw_gid);
        !           586:        status.mgid = pwd->pw_gid;
        !           587:        if(isdigit(pwd->pw_gecos[0]))status.jobno = atoi(pwd->pw_gecos);
        !           588:        else status.jobno = 32767;
        !           589:        strcpy(status.dir,pwd->pw_dir);
        !           590:        strcpy(status.loginshell,pwd->pw_shell);
        !           591:        u = status.loginshell;
        !           592:        if(u[0] == 0 /* || strcmp("sh",u+strlen(u)-2) != 0 */) strcpy(u,Bsh);
        !           593: 
        !           594:        getpwdf(pwd);
        !           595:        /* ignore network passwd */
        !           596:        if(!spacct(status.login,s,status.localname,status.muid,status.mgid)
        !           597:        && strcmp(pwd->pw_passwd,s) && verify)
        !           598:                return(0);
        !           599:        return(1);
        !           600:        }
        !           601: mread(b,i,n)
        !           602:   register int n; {
        !           603:        if(length <= 0)return(0);
        !           604:        if(length < n)n = length;
        !           605:        n = nread(b,i,n);
        !           606:        if(n != BROKENREAD)length -= n;
        !           607:        return(n);
        !           608:        }
        !           609: char mgetc(){                  /* returns 0 if fail */
        !           610:        register char c;
        !           611:        register int n;
        !           612:        char buf[3];
        !           613:        if((n=nread(buf,1,3)) == BROKENREAD)return(0);
        !           614:        if(n != 3){error("bad read %d",n); return(0); }
        !           615:        c = buf[0];
        !           616:        if(buf[1] != ' ' && buf[1] != ':'){error("Bad char %c",buf[1]); return(0); }
        !           617:        length -= 3;
        !           618:        if(length < 0){error("length wrong2 %ld",length); return(0); }
        !           619:        return(c);
        !           620:        }
        !           621: /* read in string over the network wire */
        !           622: /* put string in s, max length is maxlen */
        !           623: mgets(s,maxlen)                        /* returns 0 if ok, 1 if not */
        !           624:   int maxlen;
        !           625:   register char *s; {
        !           626:        register char *q;
        !           627:        register int n;
        !           628:        char c;
        !           629:        q = s;
        !           630:        for(;;) {
        !           631:                if((n=nread(&c,1,1)) == BROKENREAD){
        !           632:                        *s = 0;
        !           633:                        error("mgets %s",s);
        !           634:                        return(1);
        !           635:                        }
        !           636:                if(n == 0)break;
        !           637:                if(c == '\\'){
        !           638:                        if((n=nread(&c,1,1)) == BROKENREAD){
        !           639:                                *s = 0;
        !           640:                                error("mgets %s",s);
        !           641:                                return(1);
        !           642:                                }
        !           643:                        if(n == 0)break;
        !           644:                        }
        !           645:                if(c == ' ')break;
        !           646:                if(maxlen-- > 0) *s++ = c;
        !           647:                }
        !           648:        *s = 0;
        !           649:        if(nread(&c,1,1) == BROKENREAD){
        !           650:                error("mgets %s",s);
        !           651:                return(1);
        !           652:                }
        !           653:        length -= (s - q + 2);
        !           654:        if(length < 0){error("length wrong1 %ld %s",length,q); return(-1); }
        !           655:        if(maxlen < 0)
        !           656:                error("mgets - string too long");
        !           657:        return(0);
        !           658:        }
        !           659: mgetcmd(s)                     /* returns 0 if succeed, 1 otherwise */
        !           660:   char *s; {
        !           661:        int i,n;
        !           662:        char c;
        !           663:        i = 0;
        !           664:        for(;;){
        !           665:                if((n=nread(&c,1,1)) == BROKENREAD){
        !           666:                        s[i] = 0;
        !           667:                        error("mgetcmd %s",s);
        !           668:                        return(1);
        !           669:                        }
        !           670:                if(n <= 0 || c == '\n')break;
        !           671:                if(c == '\\'){
        !           672:                        if(nread(&c,1,1) == BROKENREAD){
        !           673:                                s[i] = 0;
        !           674:                                error("mgetcmd %s",s);
        !           675:                                return(1);
        !           676:                                }
        !           677:                        length--;
        !           678:                        }
        !           679:                s[i++] = c;
        !           680:                length--;
        !           681:                }
        !           682:        s[i] = 0;
        !           683:        length--;
        !           684:        return(0);
        !           685:        }
        !           686: increment(s)
        !           687:  char *s; {
        !           688:        int i;
        !           689:        char *p;
        !           690:        i = strlen(s) - 1;
        !           691:        while(s[i] == '9')i--;
        !           692:        if(s[i] < '0' || s[i] > '9'){
        !           693:                p = s+i+1;
        !           694:                while(*p)*p++ = '0';
        !           695:                return;
        !           696:                }
        !           697:        (s[i])++;
        !           698:        i++;
        !           699:        while(s[i])s[i++] = '0';
        !           700:        return;
        !           701:        }
        !           702: pload(currt)
        !           703: long currt; {
        !           704:        struct tms tbf;
        !           705:        static long out = 0L, ocut = 0L, ost = 0L, ocst = 0L;
        !           706:        long u, s, elapt;
        !           707:        double br,r,ru,rs;
        !           708:        char *str,buf[BUFSIZ];
        !           709:        currt = gettime();
        !           710:        elapt = currt - dump.shorttime;
        !           711:        times(&tbf);
        !           712:        u = tbf.tms_utime-out + tbf.tms_cutime-ocut;
        !           713:        s = tbf.tms_stime-ost + tbf.tms_cstime-ocst;
        !           714:        dump.outime += u;
        !           715:        dump.ostime += s;
        !           716:        r = u + s;
        !           717:        if(elapt > 0)r = (r/elapt)*100.0;
        !           718:        else r = 0.0;
        !           719:        /* adjust to be seconds */
        !           720:        r = r/60.0;
        !           721:        ru = u/60.0;
        !           722:        rs = s/60.0;
        !           723:        str = ctime(&currt);
        !           724:        str[strlen(str) - 5] = 0;
        !           725:        sprintf(buf,"%s (%s):\t%4.1fu\t%4.1fs\t%5.2f\t%s\n",
        !           726:                str,longname(remote),ru,rs,r,comptime(elapt));
        !           727:        addtodump(remote,"%s",buf);
        !           728:        br = dump.bytetot;
        !           729:        if(dump.elaptot > 0)br = br/dump.elaptot;
        !           730:        else br = 0.0;
        !           731:        addtodump(remote, "\tTrans.\t%.6ld bytes\t%4.1f bytes/sec\t%s",
        !           732:                dump.bytetot,br,comptime(dump.elaptot));
        !           733:        addtodump(remote," %s\n",comptime(dump.waittot));
        !           734:        dump.shorttime = currt;
        !           735:        dump.waittot = dump.elaptot = dump.bytetot = 0L;
        !           736:        out = tbf.tms_utime;
        !           737:        ocut = tbf.tms_cutime;
        !           738:        ost = tbf.tms_stime;
        !           739:        ocst = tbf.tms_cstime;
        !           740:        sprintf(buf,"%s %c",NETQSTAT,remote);
        !           741:        system(buf);                            /* gather stats on netq len. */
        !           742:        }
        !           743: /* should also gather stats on # error msgs */
        !           744: dumpit(currt)
        !           745:   long currt; {
        !           746:        register int ntot;
        !           747:        long elapt;
        !           748:        double r,ru,rs;
        !           749:        register struct dumpstruc *p = &dump;
        !           750:        register char *tt;
        !           751:        tt = ctime(&currt);
        !           752:        tt[strlen(tt) - 9] = 0;
        !           753:        elapt = currt - dump.longtime;
        !           754:        r = dump.outime + dump.ostime;
        !           755:        if(elapt > 0)r = (r/elapt) * 100.0;
        !           756:        else r = 0.0;
        !           757:        ru = dump.outime/60.0;
        !           758:        rs = dump.ostime/60.0;
        !           759:        r = r/60.0;
        !           760:        dump.longtime = dump.shorttime;
        !           761:        ntot = p->nnetcp + p->nnetmail + p->nsmail + p->nnetlpr
        !           762:                + p->nresp + p->nnet;
        !           763:        addtodump(remote,"Daily statisics\t(%s):\nSummary:\n",tt);
        !           764:        addtodump(remote,"\t# sent %d\t# pass-thru %d\t# rcv %d:\t# netcp %d\n",
        !           765:                p->nsend,p->npass,ntot,p->nnetcp);
        !           766:        addtodump(remote,"\t# netlpr %d\t# netmail %d\t# sendmail %d\t# resp %d\n",
        !           767:                p->nnetlpr,p->nnetmail,p->nsmail,p->nresp);
        !           768:        addtodump(remote,"Protocol summary:\n");
        !           769:        addtodump(remote,"\t# pk sent %d\t# pk rcv %d\t# b sent %ld\t# b rcv %ld\n",
        !           770:                p->npacksent,p->npackrcv,p->nbytesent, p->nbytercv);
        !           771:        addtodump(remote,
        !           772:                "\t# send fails %d\t# retrans %d\t# abn %d\t\t# cksum errs %d\n",
        !           773:                p->nsendfail,p->nretrans, p->nabnormal,p->ncksum);
        !           774:        addtodump(remote,"Load:\t\t\t\t%4.1fu\t%4.1fs\t%5.2f%%\t%s\n",
        !           775:                ru,rs,r,comptime(elapt));
        !           776:        p->nbytesent = p->nbytercv = p->outime = p->ostime = 0L;
        !           777:        p->nretrans = p->nloop = p->nabnormal = p->ncksum = 0;
        !           778:        p->npacksent = p->npackrcv = p->nnetcp = p->nnetmail = 0;
        !           779:        p->nsmail = p->nnetlpr = p->nnet = p->npass = 0;
        !           780:        p->nsend = p->nsendfail = 0;
        !           781:        }
        !           782: /* returns 1 if n is ok, 0 if not */
        !           783: goodacctname(n)
        !           784:   char *n; {
        !           785:        int i;
        !           786:        i = -1;
        !           787:        while(btable[++i].bname)
        !           788:                if(strcmp(btable[i].bname,n) == 0 &&
        !           789:                        local == btable[i].bmach)return(0);
        !           790:        return(1);
        !           791:        }
        !           792: demask(s)
        !           793:   register char *s; {
        !           794: # ifdef NEWPROT
        !           795:        static char buf[20];
        !           796:        strcpy(s,nbsdecrypt(s,THEKEY,buf));
        !           797: # else
        !           798:        while(*s){
        !           799:                *s &= 0177;             /* strip quote bites */
        !           800:                *s++ ^= 040;            /* invert upper-lower */
        !           801:                }
        !           802: # endif
        !           803:        }
        !           804: /*VARARGS0*/
        !           805: mreopen(f,a,b,c){
        !           806: /* simply handles errors by giving error msg */
        !           807:        if(freopen(a,b,c) == NULL)errormsg(f,"%s: %s",a,sys_errlist[errno]);
        !           808:        }
        !           809: /* 
        !           810:        addtopub(string, args)
        !           811: 
        !           812:        add a message to the public logfile /usr/net/logfile.
        !           813:        note that the file must be writeable by everyone
        !           814:        if error messages from the netrcv subroutine
        !           815:        such as chdir errors are to be noticed.
        !           816: */
        !           817: /*VARARGS0*/
        !           818: addtopublic(s,a,b,c,d,e,f,g,h,i,j,k,l,m,n)
        !           819: char *s;
        !           820: {
        !           821:        static FILE *log = NULL;
        !           822:        if(log == NULL){
        !           823:                if(stat(publogfile,&statbuf) < 0)return;
        !           824:                log = fopen(publogfile,"a");
        !           825:                if(log == NULL)return;
        !           826:                }
        !           827:        fseek(log,0L,2);
        !           828:        fprintf(log,s,a,b,c,d,e,f,g,h,i,j,k,l,m,n);
        !           829:        fflush(log);
        !           830:        }
        !           831: /*VARARGS0*/
        !           832: addtodump(mach,str,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,t,u)
        !           833: char *str;
        !           834: {
        !           835:        static FILE *log = NULL;
        !           836:        dumpfile[strlen(dumpfile)-1] = mach;
        !           837:        if(log == NULL){
        !           838:                if(stat(dumpfile,&statbuf) < 0)return;
        !           839:                log = fopen(dumpfile,"a");
        !           840:                if(log == NULL)return;
        !           841:                }
        !           842:        fseek(log,0L,2);
        !           843:        fprintf(log,str,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,t,u);
        !           844:        fflush(log);
        !           845:        }
        !           846: /* set up a dummy environment for v7 /bin/sh */
        !           847: setenv(home)
        !           848:   char *home; {
        !           849:        static char *env[3],benv[2][50];
        !           850:        env[0] = benv[0];
        !           851:        env[1] = benv[1];
        !           852:        strcpy(env[0],"PATH=:/bin:/usr/bin");
        !           853:        sprintf(env[1],"HOME=%s",home);
        !           854:        env[2] = 0;
        !           855:        environ = env;
        !           856:        }
        !           857: /* errormsg- sends error message to user-
        !           858:    may be on local or remote machine.
        !           859:    Sends to addrfrom if fmach != local,
        !           860:    or to addrto if fmach=local, on the assumption
        !           861:    that addrfrom is where it came from and addrto is where it
        !           862:    was destined on this machine.  The only time fmach=local is
        !           863:    if the result file is screwed up.
        !           864: 
        !           865:    Note that errormsg can be called by the netrcv subroutine
        !           866:    after the setuid() call to the specific user, so the 
        !           867:    user must be able to get off an error msg back to him,
        !           868:    and to write in the two log files.
        !           869:    Can't use -w,-x,-y,-z for the net cmd because must be root for those.
        !           870: */
        !           871: /*VARARGS0*/
        !           872: errormsg(fmach,s,a,b,c,d,e,f,g,h)
        !           873: char *s;
        !           874: {
        !           875:        int rcode;
        !           876:        char errstr[BUFSIZ], cmdstr[BUFSIZ], rcmd[BUFSIZ];
        !           877:        char toadd[FNS], fromadd[FNS], mchto, mchfrom;
        !           878: 
        !           879:        if(fmach < 'a' || 'z' < fmach)fmach = local;
        !           880:        if(status.sTtyname[0] == 0)strcpy(status.sTtyname,"/dev/ttyx");
        !           881:        /* will send to toadd, from fromadd */
        !           882:        if(fmach == local || strcmp(status.sCmdVirt,"response") == 0){
        !           883:                /* send to local mach, thus send to toaddr. */
        !           884:                /* if this is an error during a response, send to local mach. */
        !           885:                strcpy(toadd,  addrto);
        !           886:                strcpy(fromadd,addrfrom);
        !           887:        }
        !           888:        else {          /* send to remote mach, thus send back to addrfrom*/
        !           889:                strcpy(toadd,  addrfrom);
        !           890:                strcpy(fromadd,addrto);
        !           891:        }
        !           892:        sprintf(errstr,"Error: ");
        !           893:        sprintf(cmdstr,s,a,b,c,d,e,f,g,h);
        !           894:        strcat(errstr,cmdstr);
        !           895:        strcat(errstr,"\n");
        !           896:        addtolog(remote,errstr);
        !           897:        addtopublic(errstr);
        !           898: 
        !           899:        mchto =   MchSFromAddr(status.localname,toadd);
        !           900:        mchfrom = MchSFromAddr(status.login,    fromadd);
        !           901: 
        !           902:        sprintf(rcmd,
        !           903: "%s %s %s %lo %c %s \"'%s'\" %ld -t %s -f %s -x %ld -y %s -c \"'%s'\" -e %ld",
        !           904:        MWRITECMD, 
        !           905:        status.localname, status.sTtyname, status.lTtytime, local, status.login,status.sCmdVirt, gettime(),
        !           906:        toadd, fromadd, status.lTtytime, status.sTtyname, status.sCmdVirt, gettime());
        !           907:        if(fmach == local)
        !           908:                sprintf(cmdstr, "echo \"%s\" | %s", errstr,rcmd);
        !           909:        else sprintf(cmdstr,
        !           910:        "echo \"%s\" | %s -m%c -b -c errormessage -l network - %s",
        !           911:                errstr,netcmd,fmach,rcmd);
        !           912:        rcode = system(cmdstr);
        !           913:        exit(1);
        !           914:        }
        !           915: handlekill(){  /* SIGTRM signal */
        !           916:        long t;
        !           917:        addtodump(remote,"Netdaemon terminated.\n");
        !           918:        t = gettime();
        !           919:        pload(t);
        !           920:        dumpit(t);
        !           921:        exit(0);        /* kill myself */
        !           922:        }
        !           923: spacct(log,pass,localname,luid,lgid) /* returns 1 if login ok, 0 if not */
        !           924: char *log,*pass,*localname; {
        !           925:        long lt;
        !           926:        int u,g;
        !           927:        if(strcmp(log,"network") == 0)return(1);
        !           928:        /* experimental */
        !           929: # ifdef SPACCT
        !           930:        if(strcmp(log,localname) == 0 && luid != 0 && lgid == 0
        !           931:        && isdigit(pass[0]) &&  (
        !           932:           strcmp(log,"source") == 0
        !           933:        || strcmp(log,"daemon") == 0)
        !           934:        ){
        !           935:                /* login name is same on both machines, userid is group 0,
        !           936:                non-root, the password is numeric
        !           937:                and the login name is one of a select few */
        !           938:                lt = atol(pass);
        !           939:                u = (lt & 0177777);
        !           940:                g = (lt >> 16);
        !           941:                if((luid == u) && (lgid == g))return(1);
        !           942:                }
        !           943: # endif
        !           944:        return(0);
        !           945:        }
        !           946: /* add the user's name to our name list */
        !           947: /*VARARGS0*/
        !           948: addtoname(name)
        !           949: char *name;
        !           950: {
        !           951:        static FILE *log = NULL;
        !           952:        if(name == NULL ||
        !           953:           name[0] == 0 ||
        !           954:           strcmp(name,"root") == 0 ||
        !           955:           strcmp(name,"network") == 0 ||
        !           956:           strcmp(name,"schmidt") == 0)return;
        !           957:        if(log == NULL){
        !           958:                if(stat(namefile,&statbuf) < 0)return;
        !           959:                log = fopen(namefile,"a");
        !           960:                if(log == NULL)return;
        !           961:                }
        !           962:        fseek(log,0L,2);
        !           963:        fprintf(log,"%s:%s\n",longname(local),name);
        !           964:        fflush(log);
        !           965:        }

unix.superglobalmegacorp.com

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