X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/d2f12554a254e814dcdafb3828fc0d9936154eef..d0bd505e1a9b0bc2fc107446dcb615bf55c42e81:/uip/aliasbr.c?ds=sidebyside diff --git a/uip/aliasbr.c b/uip/aliasbr.c index af3827ba..489b707b 100644 --- a/uip/aliasbr.c +++ b/uip/aliasbr.c @@ -1,8 +1,4 @@ - -/* - * aliasbr.c -- new aliasing mechanism - * - * $Id$ +/* aliasbr.c -- new aliasing mechanism * * This code is Copyright (c) 2002, by the authors of nmh. See the * COPYRIGHT file in the root directory of the nmh distribution for @@ -11,8 +7,8 @@ #include #include +#include #include -#include #include static int akvis; @@ -21,15 +17,11 @@ static char *akerrst; struct aka *akahead = NULL; struct aka *akatail = NULL; -struct home *homehead = NULL; -struct home *hometail = NULL; - /* * prototypes */ -int alias (char *); +int alias (char *); int akvisible (void); -void init_pw (void); char *akresult (struct aka *); char *akvalue (char *); char *akerror (int); @@ -40,21 +32,16 @@ static char *scanp (char *); static char *getp (char *); static char *seekp (char *, char *, char **); static int addfile (struct aka *, char *); -static int addgroup (struct aka *, char *); -static int addmember (struct aka *, char *); -static int addall (struct aka *); static char *getalias (char *); static void add_aka (struct aka *, char *); static struct aka *akalloc (char *); -static struct home *hmalloc (struct passwd *); -struct home *seek_home (char *); /* Do mh alias substitution on 's' and return the results. */ char * akvalue (char *s) { - register char *v; + char *v; if (akahead == NULL) alias (AliasFile); @@ -77,8 +64,8 @@ akvisible (void) char * akresult (struct aka *ak) { - register char *cp = NULL, *dp, *pp; - register struct adr *ad; + char *cp = NULL, *dp, *pp; + struct adr *ad; for (ad = ak->ak_addr; ad; ad = ad->ad_next) { pp = ad->ad_local ? akval (ak->ak_next, ad->ad_text) @@ -106,27 +93,72 @@ akval (struct aka *ak, char *s) if (!s) return s; /* XXX */ - for (; ak; ak = ak->ak_next) - if (aleq (s, ak->ak_name)) + /* It'd be tempting to check for a trailing semicolon and remove + it. But that would break the EXMH alias parser on what would + then be valid expressions: + http://lists.gnu.org/archive/html/nmh-workers/2012-10/msg00039.html + */ + + for (; ak; ak = ak->ak_next) { + if (aleq (s, ak->ak_name)) { return akresult (ak); + } + + if (strchr (s, ':')) { + /* The first address in a blind list will contain the + alias name, so try to match, but just with just the + address (not including the list name). If there's a + match, then replace the alias part with its + expansion. */ + + char *name = getname (s); + char *cp = NULL; + + if (name) { + /* s is of the form "Blind list: address". If address + is an alias, expand it. */ + struct mailname *mp = getm (name, NULL, 0, NULL, 0); + + if (mp && mp->m_ingrp) { + char *gname = add (mp->m_gname, NULL); + + /* FIXME: gname must be true; add() never returns NULL. + * Is some other test required? */ + if (gname && aleq (name, ak->ak_name)) { + /* Will leak cp. */ + cp = concat (gname, akresult (ak), NULL); + free (gname); + } + } + + mnfree (mp); + } + + /* Need to flush getname after use. */ + while (getname ("")) continue; - return getcpy (s); + if (cp) { + return cp; + } + } + } + + return mh_xstrdup(s); } static int aleq (char *string, char *aliasent) { - register char c; + char c; - while ((c = *string++)) + while ((c = *string++)) { if (*aliasent == '*') return 1; - else - if ((c | 040) != (*aliasent | 040)) - return 0; - else - aliasent++; + if (tolower((unsigned char)c) != tolower((unsigned char)*aliasent)) + return 0; + aliasent++; + } return (*aliasent == 0 || *aliasent == '*'); } @@ -136,13 +168,13 @@ int alias (char *file) { int i; - register char *bp, *cp, *pp; + char *bp, *cp, *pp; char lc, *ap; - register struct aka *ak = NULL; - register FILE *fp; + struct aka *ak = NULL; + FILE *fp; if (*file != '/' - && (strncmp (file, "./", 2) && strncmp (file, "../", 3))) + && !has_prefix(file, "./") && !has_prefix(file, "../")) file = etcpath (file); if ((fp = fopen (file, "r")) == NULL) { akerrst = file; @@ -162,7 +194,7 @@ alias (char *file) fclose (fp); return i; } - + continue; case ':': /* comment */ case ';': case '#': @@ -209,32 +241,6 @@ alias (char *file) } break; - case '=': /* UNIX group */ - if (!*(cp = getp (pp + 1))) { - fclose (fp); - return AK_ERROR; - } - if (!addgroup (ak, cp)) { - fclose (fp); - return AK_NOGROUP; - } - break; - - case '+': /* UNIX group members */ - if (!*(cp = getp (pp + 1))) { - fclose (fp); - return AK_ERROR; - } - if (!addmember (ak, cp)) { - fclose (fp); - return AK_NOGROUP; - } - break; - - case '*': /* Everyone */ - addall (ak); - break; - default: /* list */ while ((cp = getalias (pp))) add_aka (ak, cp); @@ -265,10 +271,6 @@ akerror (int i) snprintf (buffer, sizeof(buffer), "out of memory while on '%s'", akerrst); break; - case AK_NOGROUP: - snprintf (buffer, sizeof(buffer), "no such group as '%s'", akerrst); - break; - default: snprintf (buffer, sizeof(buffer), "unknown error (%d)", i); break; @@ -281,7 +283,7 @@ akerror (int i) static char * scanp (char *p) { - while (isspace (*p)) + while (isspace ((unsigned char) *p)) p++; return p; } @@ -290,10 +292,10 @@ scanp (char *p) static char * getp (char *p) { - register char *cp = scanp (p); + char *cp = scanp (p); p = cp; - while (!isspace (*cp) && *cp) + while (!isspace ((unsigned char) *cp) && *cp) cp++; *cp = 0; @@ -304,10 +306,10 @@ getp (char *p) static char * seekp (char *p, char *c, char **a) { - register char *cp; + char *cp; p = cp = scanp (p); - while (!isspace (*cp) && *cp && *cp != ':' && *cp != ';') + while (!isspace ((unsigned char) *cp) && *cp && *cp != ':' && *cp != ';') cp++; *c = *cp; *cp++ = 0; @@ -320,9 +322,9 @@ seekp (char *p, char *c, char **a) static int addfile (struct aka *ak, char *file) { - register char *cp; + char *cp; char buffer[BUFSIZ]; - register FILE *fp; + FILE *fp; if (!(fp = fopen (etcpath (file), "r"))) { akerrst = file; @@ -338,105 +340,10 @@ addfile (struct aka *ak, char *file) } -static int -addgroup (struct aka *ak, char *grp) -{ - register char *gp; - register struct group *gr = getgrnam (grp); - register struct home *hm = NULL; - - if (!gr) - gr = getgrgid (atoi (grp)); - if (!gr) { - akerrst = grp; - return 0; - } - -#ifndef DBMPWD - if (homehead == NULL) - init_pw (); -#endif /* DBMPWD */ - - while ((gp = *gr->gr_mem++)) -#ifdef DBMPWD - { - struct passwd *pw; -#endif /* DBMPWD */ - for (hm = homehead; hm; hm = hm->h_next) - if (!strcmp (hm->h_name, gp)) { - add_aka (ak, hm->h_name); - break; - } -#ifdef DBMPWD - if ((pw = getpwnam(gp))) - { - hmalloc(pw); - add_aka (ak, gp); - } - } -#endif /* DBMPWD */ - - return 1; -} - - -static int -addmember (struct aka *ak, char *grp) -{ - gid_t gid; - register struct group *gr = getgrnam (grp); - register struct home *hm = NULL; - - if (gr) - gid = gr->gr_gid; - else { - gid = atoi (grp); - gr = getgrgid (gid); - } - if (!gr) { - akerrst = grp; - return 0; - } - -#ifndef DBMPWD - if (homehead == NULL) -#endif /* DBMPWD */ - init_pw (); - - for (hm = homehead; hm; hm = hm->h_next) - if (hm->h_gid == gid) - add_aka (ak, hm->h_name); - - return 1; -} - - -static int -addall (struct aka *ak) -{ - int noshell = NoShell == NULL || *NoShell == 0; - register struct home *hm; - -#ifndef DBMPWD - if (homehead == NULL) -#endif /* DBMPWD */ - init_pw (); - if (Everyone < 0) - Everyone = EVERYONE; - - for (hm = homehead; hm; hm = hm->h_next) - if (hm->h_uid > Everyone - && (noshell || strcmp (hm->h_shell, NoShell))) - add_aka (ak, hm->h_name); - - return homehead != NULL; -} - - static char * getalias (char *addrs) { - register char *pp, *qp; + char *pp, *qp; static char *cp = NULL; if (cp == NULL) @@ -445,17 +352,20 @@ getalias (char *addrs) if (*cp == 0) return (cp = NULL); - for (pp = cp; isspace (*pp); pp++) + /* Remove leading any space from the address. */ + for (pp = cp; isspace ((unsigned char) *pp); pp++) continue; if (*pp == 0) return (cp = NULL); + /* Find the end of the address. */ for (qp = pp; *qp != 0 && *qp != ','; qp++) continue; + /* Set cp to point to the remainder of the addresses. */ if (*qp == ',') *qp++ = 0; for (cp = qp, qp--; qp > pp; qp--) if (*qp != 0) { - if (isspace (*qp)) + if (isspace ((unsigned char) *qp)) *qp = 0; else break; @@ -468,14 +378,14 @@ getalias (char *addrs) static void add_aka (struct aka *ak, char *pp) { - register struct adr *ad, *ld; + struct adr *ad, *ld; for (ad = ak->ak_addr, ld = NULL; ad; ld = ad, ad = ad->ad_next) if (!strcmp (pp, ad->ad_text)) return; - ad = (struct adr *) mh_xmalloc (sizeof(*ad)); - ad->ad_text = getcpy (pp); + NEW(ad); + ad->ad_text = mh_xstrdup(pp); ad->ad_local = strchr(pp, '@') == NULL && strchr(pp, '!') == NULL; ad->ad_next = NULL; if (ak->ak_addr) @@ -485,42 +395,12 @@ add_aka (struct aka *ak, char *pp) } -void -init_pw (void) -{ - register struct passwd *pw; -#ifdef DBMPWD - static int init; - - if (!init) - { - /* if the list has yet to be initialized */ - /* zap the list, and rebuild from scratch */ - homehead=NULL; - hometail=NULL; - init++; -#endif /* DBMPWD */ - - setpwent (); - - while ((pw = getpwent ())) - if (!hmalloc (pw)) - break; - - endpwent (); -#ifdef DBMPWD - } -#endif /* DBMPWD */ -} - - static struct aka * akalloc (char *id) { - register struct aka *p; - - p = (struct aka *) mh_xmalloc (sizeof(*p)); + struct aka *p; + NEW(p); p->ak_name = getcpy (id); p->ak_visible = 0; p->ak_addr = NULL; @@ -533,65 +413,3 @@ akalloc (char *id) return p; } - - -static struct home * -hmalloc (struct passwd *pw) -{ - register struct home *p; - - p = (struct home *) mh_xmalloc (sizeof(*p)); - - p->h_name = getcpy (pw->pw_name); - p->h_uid = pw->pw_uid; - p->h_gid = pw->pw_gid; - p->h_home = getcpy (pw->pw_dir); - p->h_shell = getcpy (pw->pw_shell); - p->h_ngrps = 0; - p->h_next = NULL; - if (hometail != NULL) - hometail->h_next = p; - if (homehead == NULL) - homehead = p; - hometail = p; - - return p; -} - - -struct home * -seek_home (char *name) -{ - register struct home *hp; -#ifdef DBMPWD - struct passwd *pw; - char lname[32]; - char *c,*c1; -#else /* DBMPWD */ - - if (homehead == NULL) - init_pw (); -#endif /* DBMPWD */ - - for (hp = homehead; hp; hp = hp->h_next) - if (!mh_strcasecmp (name, hp->h_name)) - return hp; - -#ifdef DBMPWD - /* - * The only place where there might be problems. - * This assumes that ALL usernames are kept in lowercase. - */ - for (c = name, c1 = lname; *c && (c1 - lname < sizeof(lname) - 1); c++, c1++) { - if (isalpha(*c) && isupper(*c)) - *c1 = tolower (*c); - else - *c1 = *c; - } - *c1 = '\0'; - if ((pw = getpwnam(lname))) - return(hmalloc(pw)); -#endif /* DBMPWD */ - - return NULL; -}