3 * aliasbr.c -- new aliasing mechanism
16 struct aka *akahead = NULL;
17 struct aka *akatail = NULL;
19 struct home *homehead = NULL;
20 struct home *hometail = NULL;
28 char *akresult (struct aka *);
29 char *akvalue (char *);
32 static char *akval (struct aka *, char *);
33 static int aleq (char *, char *);
34 static char *scanp (char *);
35 static char *getp (char *);
36 static char *seekp (char *, char *, char **);
37 static int addfile (struct aka *, char *);
38 static int addgroup (struct aka *, char *);
39 static int addmember (struct aka *, char *);
40 static int addall (struct aka *);
41 static char *getalias (char *);
42 static void add_aka (struct aka *, char *);
43 static struct aka *akalloc (char *);
44 static struct home *hmalloc (struct passwd *);
46 struct home *seek_home (char *);
59 v = akval (akahead, s);
74 akresult (struct aka *ak)
76 register char *cp = NULL, *dp, *pp;
77 register struct adr *ad;
79 for (ad = ak->ak_addr; ad; ad = ad->ad_next) {
80 pp = ad->ad_local ? akval (ak->ak_next, ad->ad_text)
81 : getcpy (ad->ad_text);
85 cp = concat (cp, ",", pp, NULL);
94 akvis = ak->ak_visible;
100 akval (struct aka *ak, char *s)
105 for (; ak; ak = ak->ak_next)
106 if (aleq (s, ak->ak_name))
107 return akresult (ak);
114 aleq (char *string, char *aliasent)
118 while ((c = *string++))
119 if (*aliasent == '*')
122 if ((c | 040) != (*aliasent | 040))
127 return (*aliasent == 0 || *aliasent == '*');
135 register char *bp, *cp, *pp;
137 register struct aka *ak = NULL;
141 && (strncmp (file, "./", 2) && strncmp (file, "../", 3)))
142 file = etcpath (file);
143 if ((fp = fopen (file, "r")) == NULL) {
148 while (vfgets (fp, &ap) == OK) {
150 switch (*(pp = scanp (bp))) {
151 case '<': /* recurse a level */
152 if (!*(cp = getp (pp + 1))) {
153 akerrst = "'<' without alias-file";
157 if ((i = alias (cp)) != AK_OK) {
162 case ':': /* comment */
170 if (!*(cp = seekp (pp, &lc, &ap))) {
174 if (!(ak = akalloc (cp))) {
192 switch (*(pp = scanp (ap))) {
197 case '<': /* read values from file */
198 if (!*(cp = getp (pp + 1))) {
202 if (!addfile (ak, cp)) {
208 case '=': /* UNIX group */
209 if (!*(cp = getp (pp + 1))) {
213 if (!addgroup (ak, cp)) {
219 case '+': /* UNIX group members */
220 if (!*(cp = getp (pp + 1))) {
224 if (!addmember (ak, cp)) {
230 case '*': /* Everyone */
235 while ((cp = getalias (pp)))
249 static char buffer[BUFSIZ];
253 snprintf (buffer, sizeof(buffer), "unable to read '%s'", akerrst);
257 snprintf (buffer, sizeof(buffer), "error in line '%s'", akerrst);
261 snprintf (buffer, sizeof(buffer), "out of memory while on '%s'", akerrst);
265 snprintf (buffer, sizeof(buffer), "no such group as '%s'", akerrst);
269 snprintf (buffer, sizeof(buffer), "unknown error (%d)", i);
289 register char *cp = scanp (p);
292 while (!isspace (*cp) && *cp)
301 seekp (char *p, char *c, char **a)
306 while (!isspace (*cp) && *cp && *cp != ':' && *cp != ';')
317 addfile (struct aka *ak, char *file)
323 if (!(fp = fopen (etcpath (file), "r"))) {
328 while (fgets (buffer, sizeof buffer, fp))
329 while ((cp = getalias (buffer)))
338 addgroup (struct aka *ak, char *grp)
341 register struct group *gr = getgrnam (grp);
342 register struct home *hm = NULL;
345 gr = getgrgid (atoi (grp));
352 if (homehead == NULL)
356 while ((gp = *gr->gr_mem++))
361 for (hm = homehead; hm; hm = hm->h_next)
362 if (!strcmp (hm->h_name, gp)) {
363 add_aka (ak, hm->h_name);
367 if ((pw = getpwnam(gp)))
380 addmember (struct aka *ak, char *grp)
383 register struct group *gr = getgrnam (grp);
384 register struct home *hm = NULL;
398 if (homehead == NULL)
402 for (hm = homehead; hm; hm = hm->h_next)
403 if (hm->h_gid == gid)
404 add_aka (ak, hm->h_name);
411 addall (struct aka *ak)
413 int noshell = NoShell == NULL || *NoShell == 0;
414 register struct home *hm;
417 if (homehead == NULL)
423 for (hm = homehead; hm; hm = hm->h_next)
424 if (hm->h_uid > Everyone
425 && (noshell || strcmp (hm->h_shell, NoShell)))
426 add_aka (ak, hm->h_name);
428 return homehead != NULL;
433 getalias (char *addrs)
435 register char *pp, *qp;
436 static char *cp = NULL;
444 for (pp = cp; isspace (*pp); pp++)
448 for (qp = pp; *qp != 0 && *qp != ','; qp++)
452 for (cp = qp, qp--; qp > pp; qp--)
465 add_aka (struct aka *ak, char *pp)
467 register struct adr *ad, *ld;
469 for (ad = ak->ak_addr, ld = NULL; ad; ld = ad, ad = ad->ad_next)
470 if (!strcmp (pp, ad->ad_text))
473 ad = (struct adr *) malloc (sizeof(*ad));
476 ad->ad_text = getcpy (pp);
477 ad->ad_local = strchr(pp, '@') == NULL && strchr(pp, '!') == NULL;
489 register struct passwd *pw;
495 /* if the list has yet to be initialized */
496 /* zap the list, and rebuild from scratch */
504 while ((pw = getpwent ()))
518 register struct aka *p;
520 if (!(p = (struct aka *) malloc (sizeof(*p))))
523 p->ak_name = getcpy (id);
528 akatail->ak_next = p;
538 hmalloc (struct passwd *pw)
540 register struct home *p;
542 if (!(p = (struct home *) malloc (sizeof(*p))))
545 p->h_name = getcpy (pw->pw_name);
546 p->h_uid = pw->pw_uid;
547 p->h_gid = pw->pw_gid;
548 p->h_home = getcpy (pw->pw_dir);
549 p->h_shell = getcpy (pw->pw_shell);
552 if (hometail != NULL)
553 hometail->h_next = p;
554 if (homehead == NULL)
564 seek_home (char *name)
566 register struct home *hp;
573 if (homehead == NULL)
577 for (hp = homehead; hp; hp = hp->h_next)
578 if (!strcasecmp (name, hp->h_name))
583 * The only place where there might be problems.
584 * This assumes that ALL usernames are kept in lowercase.
586 for (c = name, c1 = lname; *c && (c1 - lname < sizeof(lname) - 1); c++, c1++) {
587 if (isalpha(*c) && isupper(*c))
593 if ((pw = getpwnam(lname)))