|
|
1.1 root 1: /*
2: * processor manager for UNIX systems
3: */
4:
5: #include <dk.h>
6: #include <dkmgr.h>
7: #include <pwd.h>
8: #include <stdio.h>
9: #include <signal.h>
10: #include <sys/ioctl.h>
11: #include <utmp.h>
12: #include <errno.h>
13: #include <sys/types.h>
14: #include <sys/stat.h>
15: #include <sys/param.h>
16: #include <wait.h>
17:
18: #define CTLFILE "/etc/procctl"
19: #define CTL2FILE "/etc/procctl.local"
20: #define UIDFILE "/etc/procuid"
21: #define UID2FILE "/etc/procuid.local"
22: #define LOGLVL 1
23:
24: #define SYSERR 010 /* system error, "something is wrong" */
25: #define BUSY 011 /* destination busy */
26: #define NOCMC 012 /* remote node not answering */
27: #define NODEST 013 /* destination not answering */
28: #define INTERT 014 /* unassigned number */
29: #define REORT 015 /* system overload */
30: #define PERMISSION 017 /* permission denied */
31:
32: /*
33: * format of procctl file entry --
34: *
35: * field 1 - source name, or * for any, of requester for this entry
36: * field 2 - service type requested, character string
37: * field 3 - converted service name for local use in this program
38: * field 4 - parameters, use depends on service type
39: *
40: */
41: struct sprocctl {
42: char * p_sname ; /* source name */
43: char * p_code ; /* service type */
44: char * p_ncode ; /* case stmt type */
45: char * p_param ; /* params for sub-case */
46: } procctl[64] ;
47:
48: /*
49: * format of procuid file entry ---
50: *
51: * field 1 - source name, or * for any, or requester for this entry
52: * field 2 - converted service name requested
53: * field 3 - uid as passed from source nachine, of * for any
54: * field 4 - uid to use locally, or * for same as source
55: */
56: struct sprocuid {
57: char * u_sname ; /* source name */
58: char * u_code ; /* service type */
59: char * u_uid ; /* source provided uid */
60: char * u_nuid ; /* local uid */
61: } procuid[256] ;
62:
63: FILE *fprocctl, *f2procctl, *fprocuid, *f2procuid ; /* file descriptor for control file */
64: long tprocctl, t2procctl, tprocuid, t2procuid ; /* last modification tiume of file */
65: int nprocctl, nprocuid ; /* number of entries read from file */
66: int zprocctl, zprocuid ; /* size of file at last look */
67: char *bprocctl, *bprocuid ; /* where in memory the file lives */
68:
69: /*
70: * defines for a character string "switch" statement
71: * SSWITCH(string) {
72: * SCASE("value")
73: * statements ;
74: * SCASE("value")
75: * statements ;
76: * }
77: */
78: #define SSWITCH(c) SSTR=c;if(0)
79: #define SCASE(c) }else if (strcmp(SSTR,c)==0){
80: char * SSTR ;
81:
82: char *ncode ; /* converted service code */
83: char uid[16] ; /* uid if special */
84: char dkname[32] ; /* system name from /etc/whoami */
85:
86: char *params ; /* parameters for sub-case handling */
87: char parmbuf[512] ; /* for additional parameters */
88: short parmlen ; /* length of additional stuff */
89: char env1[64];
90: extern char **environ ;
91: static char *envinit[] = {
92: env1,
93: 0
94: } ;
95:
96: char *oursrv ; /* pointer to our server name */
97: struct mgrmsg *imsg ; /* pointer to request message from remote */
98: struct passwd *pwent, *pwsearch(); /* password entry */
99: struct passwd *getnam();
100: char pwline[256]; /* line from password file */
101: char *strchr();
102: int proctab[512];
103: void chdies(), rmut() ;
104:
105: char *logfile = "/usr/dk/LOGPROC" ;
106: char logbuf[BUFSIZ];
107: int loglvl = LOGLVL ;
108: FILE *logf ;
109: struct sgttyb term ;
110:
111: extern int getopt(), optind;
112: extern char *optarg;
113: extern char *dkfilename();
114:
115: main(argc, argv)
116: char **argv ;
117: {
118: register short i ;
119: register short fi ;
120: short f2 ;
121: FILE * fip ;
122: extern int dkmgropen ;
123: struct mgrmsg *dkmgr() ;
124: extern int errno, dkp_ld, tty_ld, cdkp_ld, rmesg_ld ;
125: register char *cp, *filename;
126: int msg, tty;
127: int traffic = 2;
128:
129: fi = open("/etc/whoami", 0) ;
130: if (fi < 0) {
131: perror("mgrproc: open /etc/whoami: ") ;
132: exit(1) ;
133: }
134: i = read(fi, dkname, sizeof(dkname)) ;
135: if (i <= 0) {
136: printf("bad read of /etc/whoami\n") ;
137: exit(1) ;
138: }
139: dkname[i] = '\0' ;
140: if ((cp = strchr(dkname, '\n')))
141: *cp = '\0';
142: close(fi) ;
143: oursrv = dkname;
144: while ((i = getopt(argc, argv, "s:t:v:l:")) != EOF) {
145: switch(i) {
146: case 's': /* server */
147: oursrv = optarg;
148: continue;
149:
150: case 't': /* traffic class */
151: traffic = atoi(optarg);
152: continue;
153:
154: case 'v': /* verbosity of logfile comments */
155: loglvl = atoi(optarg);
156: continue;
157:
158: case 'l': /* name of logfile */
159: logfile = optarg;
160: continue;
161:
162: default:
163: exit(1);
164:
165: }
166: }
167: if (i = fork()) {
168: printf("mgrproc: starting server %s on system %s, pid %d\n",
169: oursrv, dkname, i) ;
170: exit(0) ; /* parent exits, child continues */
171: }
172: logf = fopen(logfile, "a") ;
173: if (logf == NULL)
174: printf("cannot open/create log file\n") ;
175: else
176: setbuf(logf, logbuf);
177:
178:
179: signal(SIGINT, SIG_IGN) ;
180: signal(SIGQUIT, SIG_IGN) ;
181: signal(SIGHUP, SIG_IGN) ;
182: signal(SIGTERM, SIG_IGN) ;
183: signal(SIGPIPE, SIG_IGN) ;
184: signal(SIGALRM, SIG_IGN) ;
185: signal(SIGCHLD, chdies) ;
186: pwsearch("root", -1, pwline); /* prime passwd file lookup */
187: loadfiles() ;
188: for (;;) {
189: imsg = dkmgr(oursrv, traffic) ;
190: if (imsg == NULL) {
191: if (errno == EINTR) {
192: # define INULL (int *)NULL
193: while ((i = wait3(INULL, WNOHANG, INULL)) > 0) {
194: register j;
195: for (j=0; j<512; j++)
196: if (proctab[j]==i) {
197: rmut(j);
198: proctab[j] = 0;
199: break;
200: }
201: dolog(3, "CHILD DIES c=%d\n", j) ;
202: }
203: continue ;
204: }
205: perror("mgrproc error in dkmgr: ") ;
206: exit(1) ;
207: }
208: if (imsg->m_service == NULL)
209: imsg->m_service = "(NULL)" ; /* default service */
210: if (imsg->m_uid == NULL)
211: imsg->m_uid = "(NULL)" ;
212: if (imsg->m_source == NULL)
213: imsg->m_source = "(NULL)" ;
214: dolog(1, "REQUEST c=%d, t=%s, UID=%s, from %s\n",
215: imsg->m_chan, imsg->m_service, imsg->m_uid, imsg->m_source) ;
216: for (cp=imsg->m_service; *cp; cp++)
217: if (*cp == '.')
218: *cp = '\0' ;
219: loadfiles() ;
220: for (i=0; i<nprocctl; i++) {
221: if (strcmp(procctl[i].p_code, imsg->m_service) == 0 &&
222: cksource(procctl[i].p_sname, imsg->m_source)) {
223: ncode = procctl[i].p_ncode ;
224: params = procctl[i].p_param ;
225: goto gotit ;
226: }
227: }
228: dolog(0, "ILLEGAL REQUEST chan %d\n", imsg->m_chan) ;
229: dkmgrnak(imsg->m_chan, INTERT) ;
230: continue ;
231:
232: gotit:
233: pwent = NULL;
234: if (strcmp(imsg->m_uid, "(NULL)")) {
235: for (i=0; i<nprocuid; i++) {
236: if (cksource(procuid[i].u_sname, imsg->m_source) &&
237: cksource(procuid[i].u_code, ncode) &&
238: cksource(procuid[i].u_uid, imsg->m_uid)) {
239: if (procuid[i].u_nuid[0] != '*') {
240: dolog(1, "UID %s.%s -> %s\n", imsg->m_source, imsg->m_uid, procuid[i].u_nuid) ;
241: imsg->m_uid = procuid[i].u_nuid ;
242: }
243: goto gotuid ;
244: }
245: }
246: imsg->m_uid = "**BAD**" ;
247: gotuid:
248: pwent = pwsearch(imsg->m_uid, -1, pwline);
249: }
250: if ((i = fork()) > 0) {
251: proctab[imsg->m_chan] = i;
252: continue ;
253: } else if (i < 0) {
254: dolog(0, "ERROR can't fork");
255: dkmgrnak(imsg->m_chan, NODEST);
256: continue;
257: }
258: filename = dkfilename(imsg->m_chan);
259: if (filename == NULL) {
260: dolog(0, "Can't find file for chan %d\n", imsg->m_chan);
261: dkmgrnak(imsg->m_chan, NODEST);
262: exit(1);
263: }
264: f2 = open(filename, 2) ;
265: if (f2 < 0) {
266: dolog(0, "ERROR cannot open %s\n", filename);
267: dkmgrnak(imsg->m_chan, NODEST) ; /* error */
268: exit(1) ;
269: }
270: dolog(7, "DEBUG ncode %s\n", ncode) ;
271: environ = envinit ;
272: sprintf(environ[0], "DKSOURCE=%s.%s", imsg->m_source,
273: imsg->m_uid);
274:
275: SSWITCH(ncode) {
276:
277: SCASE("login")
278: if (dkproto(f2, cdkp_ld) < 0 ||
279: ioctl(f2, FIOPUSHLD, &tty_ld) < 0) {
280: dolog(0, "FAILED PUSHLD %s\n", ncode) ;
281: dkmgrnak(imsg->m_chan, REORT) ;
282: exit(1) ;
283: }
284: dkmgrack(imsg->m_chan) ;
285: setfd(f2) ;
286: execl("/etc/login", "login", 0) ;
287: execl("/bin/login", "login", 0) ;
288: dolog(0, "FAILED EXEC login\n") ;
289: exit(1) ;
290:
291: SCASE("dcon")
292: msg = 0;
293: goto dc;
294:
295: SCASE("mesgdcon")
296: msg = 1;
297:
298: dc:
299: if (dkproto(f2, dkp_ld) < 0) {
300: dolog(0, "FAILED PUSHLD %s\n", ncode) ;
301: dkmgrnak(imsg->m_chan, REORT) ;
302: exit(1) ;
303: }
304: dkmgrack(imsg->m_chan) ;
305: pwent = getnam(imsg->m_uid, f2, pwent) ;
306: if (pwent == NULL) {
307: dolog(0,"FAILED passwd %s\n",imsg->m_uid);
308: exit(1) ;
309: }
310: setfd(f2) ;
311: if (msg)
312: ioctl(0, FIOPUSHLD, &rmesg_ld);
313: else
314: ioctl(0, FIOPUSHLD, &tty_ld);
315: execl("/etc/login", "login", "-p", pwline, 0) ;
316: execl("/bin/login", "login", "-p", pwline, 0) ;
317: dolog(0, "FAILED EXEC login\n") ;
318: exit(1);
319:
320: SCASE("mesgexec")
321: msg = 1;
322: tty = 0;
323: goto ex;
324:
325: SCASE("exec")
326: msg = 0;
327: tty = 0;
328: goto ex;
329:
330: SCASE("ttyexec")
331: msg = 0;
332: tty = 1;
333: ex:
334: if (dkproto(f2, dkp_ld)<0) {
335: dolog(0, "FAILED PUSHLD %s\n", ncode) ;
336: dkmgrnak(imsg->m_chan, REORT) ;
337: exit(1) ;
338: }
339: dkmgrack(imsg->m_chan) ;
340: pwent = getnam(imsg->m_uid, f2, pwent) ;
341: if (pwent == NULL)
342: exit(0) ;
343: setfd(f2) ;
344: if (rparm(0) < 0)
345: exit(0) ;
346: if (msg) {
347: if (ioctl(0, FIOPUSHLD, &rmesg_ld) < 0) {
348: dolog(0, "FAILED PUSHLD(rmesg)\n");
349: exit(1) ;
350: }
351: }
352: if (tty) {
353: if (ioctl(0, FIOPUSHLD, &tty_ld)<0) {
354: dolog(0, "FAILED PUSHLD(tty)\n");
355: exit(1) ;
356: }
357: }
358: execl("/etc/login", "login", "-p", pwline, parmbuf, 0);
359: execl("/bin/login", "login", "-p", pwline, parmbuf, 0);
360: dolog(0, "FAILED EXEC login\n");
361: exit(1) ;
362:
363: SCASE("cmd")
364: /* first param is uid, rest go to sh */
365: dolog(7, "DEBUG cmd %s\n", parmbuf) ;
366: if (dkproto(f2, dkp_ld)<0) {
367: dolog(0, "FAILED PUSHLD %s\n", ncode) ;
368: dkmgrnak(imsg->m_chan, REORT) ;
369: exit(1) ;
370: }
371: cp = params ;
372: while (*cp != ' ' && *cp != '\t' && *cp != '\0')
373: cp++ ;
374: *cp++ = '\0' ;
375: while (*cp == ' ' || *cp == '\t')
376: cp++ ;
377: if (params[0] == '*') {
378: params = imsg->m_uid ;
379: if (pwent == NULL) {
380: dkmgrnak(imsg->m_chan, PERMISSION) ;
381: dolog(1, "FAILED procuid %s.%s\n", imsg->m_source, imsg->m_uid) ;
382: exit(1) ;
383: }
384: }
385: dkmgrack(imsg->m_chan) ;
386: setfd(f2) ;
387: dolog(7, "DEBUG cmd uid %s cmd %s\n", params, cp) ;
388: execl("/etc/login", "login", "-f", params, cp, 0) ;
389: execl("/bin/login", "login", "-f", params, cp, 0) ;
390: dolog(0, "FAILED EXEC login %s\n", cp) ;
391: exit(1) ;
392:
393: }
394: dolog(0, "ILLEGAL CODE %s\n", ncode) ;
395: dkmgrnak(imsg->m_chan, INTERT) ;
396: exit(1) ;
397: }
398: }
399:
400: /* VARARGS2 */
401: dolog(level, fmt, a1, a2, a3, a4, a5)
402: char *fmt;
403: {
404: long clock ;
405: long time() ;
406: char *ctime() ;
407:
408: if (loglvl<level || logf==NULL)
409: return;
410: clock = time(0) ;
411: fseek(logf, 0L, 2);
412: fprintf(logf, "%.15s-%d(%d) ", ctime(&clock)+4, getpid(), loglvl) ;
413: fprintf(logf, fmt, a1, a2, a3, a4, a5);
414: fflush(logf);
415: }
416:
417:
418: /*
419: * Interrupt routine for child death
420: */
421: void
422: chdies()
423: {
424: signal(SIGCHLD, chdies);
425: }
426:
427: /*
428: * delete entry from utmp file
429: */
430: void
431: rmut(i)
432: {
433: register f;
434: register char *line;
435: struct utmp wtmp;
436:
437: line = dkfilename(i);
438: if (line==0)
439: return;
440: line += sizeof("/dev/") - 1;
441: f = open("/etc/utmp", 2);
442: if(f >= 0) {
443: while(read(f, (char *)&wtmp, sizeof(wtmp)) == sizeof(wtmp)) {
444: if (strncmp(wtmp.ut_line, line, sizeof(wtmp.ut_line)))
445: continue;
446: lseek(f, -(long)sizeof(wtmp), 1);
447: strncpy(wtmp.ut_name, "", sizeof(wtmp.ut_name));
448: time(&wtmp.ut_time);
449: write(f, (char *)&wtmp, sizeof(wtmp));
450: }
451: close(f);
452: }
453: f = open("/usr/adm/wtmp", 1);
454: if (f >= 0) {
455: strncpy(wtmp.ut_line, line, sizeof(wtmp.ut_line));
456: strncpy(wtmp.ut_name, "", sizeof(wtmp.ut_name));
457: time(&wtmp.ut_time);
458: lseek(f, (long)0, 2);
459: write(f, (char *)&wtmp, sizeof(wtmp));
460: close(f);
461: }
462: }
463:
464: /*
465: * check a source name against a prototype name
466: * in the control file
467: * return 0 if no match
468: * return 1 if ok match
469: */
470: cksource(ck, src)
471: register char *ck, *src ;
472: {
473:
474: while (*ck == *src) {
475: if (*ck == 0)
476: break ;
477: ck++ ; src++ ;
478: }
479: if (*ck == *src)
480: return 1 ;
481: if (*ck == '*')
482: return 1 ;
483: return 0 ;
484: }
485:
486: struct passwd *
487: getnam(try1, f2, pw)
488: char * try1;
489: register struct passwd *pw ;
490: {
491: register char * cp ;
492:
493: if (pw && pw->pw_uid) {
494: write(f2, "OK", 2) ;
495: return pw ;
496: }
497: write(f2, "NO", 2);
498: while (1) {
499: if (rparm(f2) < 0) {
500: dolog(2, "HANGUP c=%d receiving uid\n", imsg->m_chan) ;
501: exit(1) ;
502: }
503: for (cp = parmbuf; *cp; cp++) {
504: if (*cp == ' ' || *cp == '.' || *cp == ',') {
505: *cp++ = '\0';
506: break ;
507: }
508: }
509: pw = pwsearch(parmbuf, -1, pwline) ;
510: if (pw && (pw->pw_passwd==NULL
511: || strcmp(crypt(cp, pw->pw_passwd), pw->pw_passwd)==0))
512: break;
513: write(f2, "NO", 2) ;
514: }
515: dolog(4, "TRACE UID %s\n", parmbuf) ;
516: write(f2, "OK", 2) ;
517: return pw ;
518: }
519:
520:
521: rparm(f)
522: {
523: register len ;
524: register rlen ;
525: register char *cp ;
526:
527:
528: rlen = sizeof(parmbuf) ;
529: parmlen = 0 ;
530: cp = parmbuf ;
531: while (1) {
532: len = read(f, cp, rlen) ;
533: if (len <= 0)
534: return -1 ;
535: parmlen += len ;
536: rlen -= len ;
537: cp += len - 1 ;
538: if (*cp == '\n' ||
539: *cp == '\r') {
540: *cp = '\0' ;
541: dolog(7, "DEBUG rparam %s\n", parmbuf) ;
542: return 0 ;
543: }
544: cp++ ;
545: }
546: }
547:
548: setfd(f)
549: {
550: int i ;
551:
552: signal(SIGTERM, SIG_DFL) ;
553: signal(SIGPIPE, SIG_DFL) ;
554: signal(SIGQUIT, SIG_DFL) ;
555: signal(SIGINT, SIG_DFL) ;
556: signal(SIGALRM, SIG_DFL) ;
557: signal(SIGHUP, SIG_DFL) ;
558: signal(SIGCHLD, SIG_DFL) ;
559: ioctl(f, TIOCSPGRP, 0) ;
560: close(0) ;
561: close(1) ;
562: close(2) ;
563: close(3) ;
564: dup(f) ;
565: dup(f) ;
566: dup(f) ;
567: dup(f) ;
568: for (i=NSYSFILE; i<9; i++)
569: if (i != fileno(logf))
570: close(i) ;
571: }
572:
573: char * adv(cp)
574: register char *cp ;
575: {
576: while (*cp != '\0' && *cp != '\n' && *cp != ' ' && *cp != '\t') cp++ ;
577: if (*cp == ' ' || *cp == '\t') *cp++ = '\0' ;
578: while (*cp == ' ' || *cp == '\t') cp++ ;
579: return (cp) ;
580: }
581:
582: char * advn(cp)
583: register char *cp ;
584: {
585: while (*cp != '\0' && *cp != '\n') cp++ ;
586: if (*cp == '\n') *cp++ = '\0' ;
587: while (*cp == ' ' || *cp == '\t' || *cp == '\n') cp++ ;
588: return (cp) ;
589: }
590:
591:
592: loadfiles()
593: {
594: struct stat statb ;
595: struct stat statb2 ;
596: register char *cp ;
597: register struct sprocctl *ctlptr ;
598: register struct sprocuid *uidptr ;
599: register i ;
600:
601: if (fprocctl == NULL || f2procctl == NULL) {
602: if (fprocctl == NULL)
603: fprocctl = fopen(CTLFILE, "r") ;
604: if (f2procctl == NULL)
605: f2procctl = fopen(CTL2FILE, "r") ;
606: if (fprocctl == NULL) {
607: fprintf(stderr, "mgrproc, can't open %s\n", CTLFILE) ;
608: nprocctl = 0 ;
609: goto f2 ;
610: }
611: if (f2procctl == NULL) {
612: fprintf(stderr, "mgrproc, can't open %s\n", CTL2FILE) ;
613: nprocctl = 0 ;
614: goto f2 ;
615: }
616: fstat(fileno(fprocctl), &statb) ;
617: fstat(fileno(f2procctl), &statb2) ;
618: } else {
619: fstat(fileno(fprocctl), &statb) ;
620: fstat(fileno(f2procctl), &statb2) ;
621: if (statb.st_mtime == tprocctl && statb2.st_mtime == t2procctl)
622: goto f2 ;
623: }
624: tprocctl = statb.st_mtime ;
625: t2procctl = statb2.st_mtime ;
626: i = statb.st_size + statb2.st_size ;
627: if (i > zprocctl) {
628: if (zprocctl > 0)
629: free(bprocctl) ;
630: bprocctl = (char *)malloc(i+4) ;
631: zprocctl = i ;
632: }
633: rewind(fprocctl) ;
634: rewind(f2procctl) ;
635: fread(bprocctl, statb.st_size, 1, fprocctl) ;
636: if (statb2.st_size)
637: fread(&bprocctl[statb.st_size], statb2.st_size, 1, f2procctl) ;
638: bprocctl[i] = '\0' ;
639: cp = bprocctl ;
640: ctlptr = procctl ;
641: while (*cp) {
642: while (*cp == '#')
643: cp = advn(cp) ;
644: if (*cp == 0)
645: break ;
646: ctlptr->p_sname = cp ;
647: cp = adv(cp) ;
648: ctlptr->p_code = cp ;
649: cp = adv(cp) ;
650: ctlptr->p_ncode = cp ;
651: if (*cp == '*')
652: ctlptr->p_ncode = ctlptr->p_code ;
653: cp = adv(cp) ;
654: ctlptr->p_param = cp ;
655: cp = advn(cp) ;
656: ctlptr++ ;
657: }
658: nprocctl = ctlptr - procctl ;
659: dolog(7, "Reloaded %s; %d entries\n", CTLFILE, nprocctl) ;
660: f2:
661: if (fprocuid == NULL || f2procuid == NULL) {
662: if (fprocuid == NULL)
663: fprocuid = fopen(UIDFILE, "r") ;
664: if (f2procuid == NULL)
665: f2procuid = fopen(UID2FILE, "r") ;
666: if (fprocuid == NULL) {
667: fprintf(stderr, "mgrproc: can't open %s\n", UIDFILE) ;
668: nprocuid = 0 ;
669: return ;
670: }
671: if (f2procuid == NULL) {
672: fprintf(stderr, "mgrproc: can't open %s\n", UID2FILE) ;
673: nprocuid = 0 ;
674: return ;
675: }
676: fstat(fileno(fprocuid), &statb) ;
677: fstat(fileno(f2procuid), &statb2) ;
678: } else {
679: fstat(fileno(fprocuid), &statb) ;
680: fstat(fileno(f2procuid), &statb2) ;
681: if (statb.st_mtime == tprocuid && statb2.st_mtime == t2procuid)
682: return ;
683: }
684: tprocuid = statb.st_mtime ;
685: t2procuid = statb2.st_mtime ;
686: i = statb.st_size + statb2.st_size ;
687: if (i > zprocuid) {
688: if (zprocuid)
689: free(bprocuid) ;
690: bprocuid = (char *)malloc(i+4) ;
691: zprocuid = i ;
692: }
693: rewind(fprocuid) ;
694: rewind(f2procuid) ;
695: fread(bprocuid, statb.st_size, 1, fprocuid) ;
696: fread(&bprocuid[statb.st_size], statb2.st_size, 1, f2procuid) ;
697: bprocuid[i] = '\0' ;
698: cp = bprocuid ;
699: uidptr = procuid ;
700: while (*cp) {
701: while (*cp == '#')
702: cp = advn(cp) ;
703: if (*cp == '\0')
704: break ;
705: uidptr->u_sname = cp ;
706: cp = adv(cp) ;
707: uidptr->u_code = cp ;
708: cp = adv(cp) ;
709: uidptr->u_uid = cp ;
710: cp = adv(cp) ;
711: uidptr->u_nuid = cp ;
712: cp = adv(cp) ;
713: cp = advn(cp) ;
714: uidptr++ ;
715: }
716: nprocuid = uidptr - procuid ;
717: dolog(7, "Reloaded %s; %d entries\n", UIDFILE, nprocuid) ;
718: }
719:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.