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