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