/*
* aliasbr.c -- new aliasing mechanism
*
- * $Id$
- *
* This code is Copyright (c) 2002, by the authors of nmh. See the
* COPYRIGHT file in the root directory of the nmh distribution for
* complete copyright information.
#include <h/mh.h>
#include <h/aliasbr.h>
+#include <h/addrsbr.h>
+#include <h/utils.h>
#include <grp.h>
#include <pwd.h>
/*
* prototypes
*/
-int alias (char *);
+int alias (char *);
int akvisible (void);
void init_pw (void);
char *akresult (struct aka *);
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 *);
-#ifndef MMDFMTS
-struct home *seek_home (char *);
-#endif
/* Do mh alias substitution on 's' and return the results. */
char *
akvalue (char *s)
{
- register char *v;
+ char *v;
if (akahead == NULL)
alias (AliasFile);
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)
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);
+
+ 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;
+
+ if (cp) {
+ return cp;
+ }
+ }
+ }
- return getcpy (s);
+ 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 ((c | 040) != (*aliasent | 040))
+ return 0;
+ aliasent++;
+ }
return (*aliasent == 0 || *aliasent == '*');
}
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;
fclose (fp);
return i;
}
-
+ /* FALLTHRU */
case ':': /* comment */
case ';':
case '#':
}
break;
- case '*': /* Everyone */
- addall (ak);
- break;
-
default: /* list */
while ((cp = getalias (pp)))
add_aka (ak, cp);
static char *
scanp (char *p)
{
- while (isspace (*p))
+ while (isspace ((unsigned char) *p))
p++;
return 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;
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;
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;
static int
addgroup (struct aka *ak, char *grp)
{
- register char *gp;
- register struct group *gr = getgrnam (grp);
- register struct home *hm = NULL;
+ char *gp;
+ struct group *gr = getgrnam (grp);
+ struct home *hm = NULL;
if (!gr)
gr = getgrgid (atoi (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;
}
addmember (struct aka *ak, char *grp)
{
gid_t gid;
- register struct group *gr = getgrnam (grp);
- register struct home *hm = NULL;
+ struct group *gr = getgrnam (grp);
+ struct home *hm = NULL;
if (gr)
gid = gr->gr_gid;
return 0;
}
-#ifndef DBMPWD
- if (homehead == NULL)
-#endif /* DBMPWD */
- init_pw ();
+ init_pw ();
for (hm = homehead; hm; hm = hm->h_next)
if (hm->h_gid == gid)
}
-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)
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;
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 *) malloc (sizeof(*ad));
- if (ad == NULL)
- return;
- 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)
void
init_pw (void)
{
- register struct passwd *pw;
-#ifdef DBMPWD
+ struct passwd *pw;
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 */
+ /* if the list has yet to be initialized */
+ /* zap the list, and rebuild from scratch */
+ homehead=NULL;
+ hometail=NULL;
+ init++;
- setpwent ();
+ setpwent ();
- while ((pw = getpwent ()))
- if (!hmalloc (pw))
- break;
+ while ((pw = getpwent ()))
+ if (!hmalloc (pw))
+ break;
- endpwent ();
-#ifdef DBMPWD
+ endpwent ();
}
-#endif /* DBMPWD */
}
static struct aka *
akalloc (char *id)
{
- register struct aka *p;
-
- if (!(p = (struct aka *) malloc (sizeof(*p))))
- return NULL;
+ struct aka *p;
+ NEW(p);
p->ak_name = getcpy (id);
p->ak_visible = 0;
p->ak_addr = NULL;
static struct home *
hmalloc (struct passwd *pw)
{
- register struct home *p;
-
- if (!(p = (struct home *) malloc (sizeof(*p))))
- return NULL;
+ struct home *p;
+ NEW(p);
p->h_name = getcpy (pw->pw_name);
p->h_uid = pw->pw_uid;
p->h_gid = pw->pw_gid;
return p;
}
-
-
-#ifndef MMDFMTS
-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 (!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;
-}
-#endif /* MMDFMTS */