|
|
1.1 root 1: /* aliasbr.c - new aliasing mechanism */
2:
3: #include "../h/mh.h"
4: #include "../h/aliasbr.h"
5: #include <ctype.h>
6: #include <grp.h>
7: #include <pwd.h>
8: #include <stdio.h>
9:
10:
11: static int akvis;
12: static char *akerrst;
13:
14: struct aka *akahead = NULL;
15: struct aka *akatail = NULL;
16:
17: struct home *homehead = NULL;
18: struct home *hometail = NULL;
19:
20: char *scanp (), *getp (), *seekp (), *akval (), *getalias ();
21: struct aka *akalloc ();
22: struct home *hmalloc ();
23:
24:
25: struct passwd *getpwent ();
26: struct group *getgrnam (), *getgrgid ();
27:
28: /* */
29:
30: char *akvalue (s)
31: register char *s;
32: {
33: register char *v;
34:
35: if (akahead == NULL)
36: (void) alias (AliasFile);
37:
38: akvis = -1;
39: v = akval (akahead, s);
40: if (akvis == -1)
41: akvis = 0;
42: return v;
43: }
44:
45:
46: int akvisible () {
47: return akvis;
48: }
49:
50: /* */
51:
52: char *akresult (ak)
53: register struct aka *ak;
54: {
55: register char *cp = NULL,
56: *dp,
57: *pp;
58: register struct adr *ad;
59:
60: for (ad = ak -> ak_addr; ad; ad = ad -> ad_next) {
61: pp = ad -> ad_local ? akval (ak -> ak_next, ad -> ad_text)
62: : getcpy (ad -> ad_text);
63:
64: if (dp = cp) {
65: cp = concat (cp, ",", pp, NULLCP);
66: free (dp);
67: free (pp);
68: }
69: else
70: cp = pp;
71: }
72:
73: if (akvis == -1)
74: akvis = ak -> ak_visible;
75: return cp;
76: }
77:
78:
79: static char *akval (ak, s)
80: register struct aka *ak;
81: register char *s;
82: {
83: for (; ak; ak = ak -> ak_next)
84: if (aleq (s, ak -> ak_name))
85: return akresult (ak);
86:
87: return getcpy (s);
88: }
89:
90:
91: static int aleq (string, aliasent)
92: register char *string,
93: *aliasent;
94: {
95: register char c;
96:
97: while (c = *string++)
98: if (*aliasent == '*')
99: return 1;
100: else
101: if ((c | 040) != (*aliasent | 040))
102: return 0;
103: else
104: aliasent++;
105:
106: return (*aliasent == NULL || *aliasent == '*');
107: }
108:
109: /* */
110:
111: int alias (file)
112: register char *file;
113: {
114: int i;
115: register char *bp,
116: *cp,
117: *pp;
118: char lc,
119: *ap;
120: register struct aka *ak = NULL;
121: register FILE *fp;
122:
123: if (*file != '/' && *file != '.')
124: file = libpath (file);
125: if ((fp = fopen (file, "r")) == NULL) {
126: akerrst = file;
127: return AK_NOFILE;
128: }
129:
130: while (vfgets (fp, &ap) == OK) {
131: bp = ap;
132: switch (*(pp = scanp (bp))) {
133: case '<': /* recurse a level */
134: if (!*(cp = getp (pp + 1))) {
135: akerrst = "'<' without alias-file";
136: (void) fclose (fp);
137: return AK_ERROR;
138: }
139: if ((i = alias (cp) != AK_OK)) {
140: (void) fclose (fp);
141: return i;
142: }
143:
144: case ':': /* comment */
145: case ';':
146: case NULL:
147: continue;
148: }
149:
150: akerrst = bp;
151: if (!*(cp = seekp (pp, &lc, &ap))) {
152: (void) fclose (fp);
153: return AK_ERROR;
154: }
155: if (!(ak = akalloc (cp))) {
156: (void) fclose (fp);
157: return AK_LIMIT;
158: }
159: switch (lc) {
160: case ':':
161: ak -> ak_visible = 0;
162: break;
163:
164: case ';':
165: ak -> ak_visible = 1;
166: break;
167:
168: default:
169: (void) fclose (fp);
170: return AK_ERROR;
171: }
172:
173: switch (*(pp = scanp (ap))) {
174: case NULL: /* EOL */
175: (void) fclose (fp);
176: return AK_ERROR;
177:
178: case '<': /* read values from file */
179: if (!*(cp = getp (pp + 1))) {
180: (void) fclose (fp);
181: return AK_ERROR;
182: }
183: if (!addfile (ak, cp)) {
184: (void) fclose (fp);
185: return AK_NOFILE;
186: }
187: break;
188:
189: case '=': /* UNIX group */
190: if (!*(cp = getp (pp + 1))) {
191: (void) fclose (fp);
192: return AK_ERROR;
193: }
194: if (!addgroup (ak, cp)) {
195: (void) fclose (fp);
196: return AK_NOGROUP;
197: }
198: break;
199:
200: case '+': /* UNIX group members */
201: if (!*(cp = getp (pp + 1))) {
202: (void) fclose (fp);
203: return AK_ERROR;
204: }
205: if (!addmember (ak, cp)) {
206: (void) fclose (fp);
207: return AK_NOGROUP;
208: }
209: break;
210:
211: case '*': /* Everyone */
212: (void) addall (ak);
213: break;
214:
215: default: /* list */
216: while (cp = getalias (pp))
217: add_aka (ak, cp);
218: break;
219: }
220: }
221:
222: (void) fclose (fp);
223: return AK_OK;
224: }
225:
226: /* */
227:
228: char *akerror (i)
229: int i;
230: {
231: static char buffer[BUFSIZ];
232:
233: switch (i) {
234: case AK_NOFILE:
235: (void) sprintf (buffer, "unable to read '%s'", akerrst);
236: break;
237:
238: case AK_ERROR:
239: (void) sprintf (buffer, "error in line '%s'", akerrst);
240: break;
241:
242: case AK_LIMIT:
243: (void) sprintf (buffer, "out of memory while on '%s'", akerrst);
244: break;
245:
246: case AK_NOGROUP:
247: (void) sprintf (buffer, "no such group as '%s'", akerrst);
248: break;
249:
250: default:
251: (void) sprintf (buffer, "unknown error (%d)", i);
252: break;
253: }
254:
255: return buffer;
256: }
257:
258: /* */
259:
260: static char *scanp (p)
261: register char *p;
262: {
263: while (isspace (*p))
264: p++;
265: return p;
266: }
267:
268:
269: static char *getp (p)
270: register char *p;
271: {
272: register char *cp = scanp (p);
273:
274: p = cp;
275: while (!isspace (*cp) && *cp)
276: cp++;
277: *cp = NULL;
278:
279: return p;
280: }
281:
282:
283: static char *seekp (p, c, a)
284: register char *p,
285: *c,
286: **a;
287: {
288: register char *cp = scanp (p);
289:
290: p = cp;
291: while (!isspace (*cp) && *cp && *cp != ':' && *cp != ';')
292: cp++;
293: *c = *cp;
294: *cp++ = NULL;
295: *a = cp;
296:
297: return p;
298: }
299:
300: /* */
301:
302: static int addfile (ak, file)
303: register struct aka *ak;
304: register char *file;
305: {
306: register char *cp;
307: char buffer[BUFSIZ];
308: register FILE *fp;
309:
310: if ((fp = fopen (libpath (file), "r")) == NULL) {
311: akerrst = file;
312: return NULL;
313: }
314:
315: while (fgets (buffer, sizeof buffer, fp) != NULL)
316: while (cp = getalias (buffer))
317: add_aka (ak, cp);
318:
319: (void) fclose (fp);
320: return 1;
321: }
322:
323: /* */
324:
325: static int addgroup (ak, grp)
326: register struct aka *ak;
327: register char *grp;
328: {
329: register char *gp;
330: register struct group *gr = getgrnam (grp);
331: register struct home *hm = NULL;
332:
333: if (!gr)
334: gr = getgrgid (atoi (grp));
335: if (!gr) {
336: akerrst = grp;
337: return NULL;
338: }
339:
340: if (homehead == NULL)
341: init_pw ();
342:
343: while (gp = *gr -> gr_mem++)
344: for (hm = homehead; hm; hm = hm -> h_next)
345: if (!strcmp (hm -> h_name, gp)) {
346: add_aka (ak, hm -> h_name);
347: break;
348: }
349:
350: return 1;
351: }
352:
353: /* */
354:
355: static int addmember (ak, grp)
356: register struct aka *ak;
357: register char *grp;
358: {
359: int gid;
360: register struct group *gr = getgrnam (grp);
361: register struct home *hm = NULL;
362:
363: if (gr)
364: gid = gr -> gr_gid;
365: else {
366: gid = atoi (grp);
367: gr = getgrgid (gid);
368: }
369: if (!gr) {
370: akerrst = grp;
371: return NULL;
372: }
373:
374: if (homehead == NULL)
375: init_pw ();
376:
377: for (hm = homehead; hm; hm = hm -> h_next)
378: if (hm -> h_gid == gid)
379: add_aka (ak, hm -> h_name);
380:
381: return 1;
382: }
383:
384: /* */
385:
386: static int addall (ak)
387: register struct aka *ak;
388: {
389: int noshell = NoShell == NULLCP || *NoShell == NULL;
390: register struct home *hm;
391:
392: if (homehead == NULL)
393: init_pw ();
394: if (Everyone < 0)
395: Everyone = EVERYONE;
396:
397: for (hm = homehead; hm; hm = hm -> h_next)
398: if (hm -> h_uid > Everyone
399: && (noshell || strcmp (hm -> h_shell, NoShell)))
400: add_aka (ak, hm -> h_name);
401:
402: return homehead != NULL;
403: }
404:
405: /* */
406:
407: static char *getalias (addrs)
408: register char *addrs;
409: {
410: register char *pp,
411: *qp;
412: static char *cp = NULL;
413:
414: if (cp == NULL)
415: cp = addrs;
416: else
417: if (*cp == NULL)
418: return (cp = NULL);
419:
420: for (pp = cp; isspace (*pp); pp++)
421: continue;
422: if (*pp == NULL)
423: return (cp = NULL);
424: for (qp = pp; *qp != NULL && *qp != ','; qp++)
425: continue;
426: if (*qp == ',')
427: *qp++ = NULL;
428: for (cp = qp, qp--; qp > pp; qp--)
429: if (*qp != NULL)
430: if (isspace (*qp))
431: *qp = NULL;
432: else
433: break;
434:
435: return pp;
436: }
437:
438: /* */
439:
440: static add_aka (ak, pp)
441: register struct aka *ak;
442: register char *pp;
443: {
444: register struct adr *ad,
445: *ld;
446:
447: for (ad = ak -> ak_addr, ld = NULL; ad; ld = ad, ad = ad -> ad_next)
448: if (!strcmp (pp, ad -> ad_text))
449: return;
450:
451: ad = (struct adr *) malloc (sizeof *ad);
452: if (ad == NULL)
453: return;
454: ad -> ad_text = getcpy (pp);
455: ad -> ad_local = index (pp, '@') == NULL && index (pp, '!') == NULL;
456: ad -> ad_next = NULL;
457: if (ak -> ak_addr)
458: ld -> ad_next = ad;
459: else
460: ak -> ak_addr = ad;
461: }
462:
463:
464: init_pw () {
465: register struct passwd *pw;
466:
467: (void) setpwent ();
468:
469: while (pw = getpwent ())
470: if (!hmalloc (pw))
471: break;
472:
473: (void) endpwent ();
474: }
475:
476: /* */
477:
478: static struct aka *akalloc (id)
479: register char *id;
480: {
481: register struct aka *p = (struct aka *) malloc (sizeof *p);
482:
483: if (!p)
484: return NULL;
485:
486: p -> ak_name = getcpy (id);
487: p -> ak_visible = 0;
488: p -> ak_addr = NULL;
489: p -> ak_next = NULL;
490: if (akatail != NULL)
491: akatail -> ak_next = p;
492: if (akahead == NULL)
493: akahead = p;
494: akatail = p;
495:
496: return p;
497: }
498:
499:
500: static struct home *hmalloc (pw)
501: struct passwd *pw;
502: {
503: register struct home *p = (struct home *) malloc (sizeof *p);
504:
505: if (!p)
506: return NULL;
507:
508: p -> h_name = getcpy (pw -> pw_name);
509: p -> h_uid = pw -> pw_uid;
510: p -> h_gid = pw -> pw_gid;
511: p -> h_home = getcpy (pw -> pw_dir);
512: p -> h_shell = getcpy (pw -> pw_shell);
513: #ifdef BSD42
514: p -> h_ngrps = 0;
515: #endif BSD42
516: p -> h_next = NULL;
517: if (hometail != NULL)
518: hometail -> h_next = p;
519: if (homehead == NULL)
520: homehead = p;
521: hometail = p;
522:
523: return p;
524: }
525:
526: /* */
527:
528: #ifndef MMDFMTS
529: struct home *seek_home (name)
530: register char *name;
531: {
532: register struct home *hp;
533:
534: if (homehead == NULL)
535: init_pw ();
536:
537: for (hp = homehead; hp; hp = hp -> h_next)
538: if (uleq (name, hp -> h_name))
539: return hp;
540:
541: return NULL;
542: }
543: #endif MMDFMTS
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.