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: }

Defined functions

addtopublic defined in line 1048; used 4 times
check defined in line 791; used 1 times
day defined in line 241; used 1 times
demask defined in line 1020; used 1 times
dumpit defined in line 937; used 1 times
errormsg defined in line 1094; used 8 times
excat defined in line 688; used 1 times
excmd defined in line 560; used 1 times
facctpaircheck defined in line 1163; used 1 times
goodacctname defined in line 1011; used 1 times
handlekill defined in line 1145; used 5 times
increment defined in line 919; used 1 times
linechars defined in line 552; used 3 times
main defined in line 57; never used
mainloop defined in line 111; used 1 times
mgetc defined in line 842; used 7 times
mgetcmd defined in line 892; used 2 times
mgets defined in line 856; used 10 times
mread defined in line 834; used 1 times
mreopen defined in line 1034; used 6 times
netrcv defined in line 308; used 1 times
netsend defined in line 145; used 1 times
printstat defined in line 132; used 1 times
readhd defined in line 706; used 1 times
send defined in line 255; used 1 times
setenv defined in line 1062; used 1 times
sndresponse defined in line 641; used 1 times

Defined variables

btable defined in line 42; used 3 times
dump defined in line 41; used 31 times
frommach defined in line 54; used 1 times
length defined in line 47; used 22 times
netd defined in line 43; used 9 times
netdaemon_sid defined in line 4; never used
publogfile defined in line 51; used 2 times
sccsid defined in line 1; never used
statbuf defined in line 52; used 20 times
status defined in line 44; used 26 times
tempfile defined in line 50; used 16 times

Defined macros

RENICE0 defined in line 37; used 2 times
nsecday defined in line 33; used 1 times
  • in line 35
numdays defined in line 35; used 2 times
Last modified: 1982-10-13
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3591
Valid CSS Valid XHTML 1.0 Strict