]>
diplodocus.org Git - nmh/blob - uip/aliasbr.c
3 * aliasbr.c -- new aliasing mechanism
5 * This code is Copyright (c) 2002, by the authors of nmh. See the
6 * COPYRIGHT file in the root directory of the nmh distribution for
7 * complete copyright information.
11 #include <h/aliasbr.h>
12 #include <h/addrsbr.h>
20 struct aka
*akahead
= NULL
;
21 struct aka
*akatail
= NULL
;
23 struct home
*homehead
= NULL
;
24 struct home
*hometail
= NULL
;
32 char *akresult (struct aka
*);
33 char *akvalue (char *);
36 static char *akval (struct aka
*, char *);
37 static int aleq (char *, char *);
38 static char *scanp (unsigned char *);
39 static char *getp (char *);
40 static char *seekp (char *, char *, char **);
41 static int addfile (struct aka
*, char *);
42 static int addgroup (struct aka
*, char *);
43 static int addmember (struct aka
*, char *);
44 static int addall (struct aka
*);
45 static char *getalias (char *);
46 static void add_aka (struct aka
*, char *);
47 static struct aka
*akalloc (char *);
48 static struct home
*hmalloc (struct passwd
*);
51 /* Do mh alias substitution on 's' and return the results. */
61 v
= akval (akahead
, s
);
76 akresult (struct aka
*ak
)
78 register char *cp
= NULL
, *dp
, *pp
;
79 register struct adr
*ad
;
81 for (ad
= ak
->ak_addr
; ad
; ad
= ad
->ad_next
) {
82 pp
= ad
->ad_local
? akval (ak
->ak_next
, ad
->ad_text
)
83 : getcpy (ad
->ad_text
);
87 cp
= concat (cp
, ",", pp
, NULL
);
96 akvis
= ak
->ak_visible
;
102 akval (struct aka
*ak
, char *s
)
107 for (; ak
; ak
= ak
->ak_next
) {
108 if (aleq (s
, ak
->ak_name
)) {
109 return akresult (ak
);
110 } else if (strchr (s
, ':')) {
111 /* The first address in a blind list will contain the
112 alias name, so try to match, but just with just the
113 address (not including the list name). If there's a
114 match, then replace the alias part with its
117 char *name
= getname (s
);
121 /* s is of the form "Blind list: address". If address
122 is an alias, expand it. */
123 struct mailname
*mp
= getm (name
, NULL
, 0, AD_NAME
, NULL
);
125 if (mp
&& mp
->m_ingrp
) {
126 char *gname
= add (mp
->m_gname
, NULL
);
128 if (gname
&& aleq (name
, ak
->ak_name
)) {
130 cp
= concat (gname
, akresult (ak
), NULL
);
138 /* Need to flush getname after use. */
139 while (getname ("")) continue;
152 aleq (char *string
, char *aliasent
)
156 while ((c
= *string
++))
157 if (*aliasent
== '*')
160 if ((c
| 040) != (*aliasent
| 040))
165 return (*aliasent
== 0 || *aliasent
== '*');
173 register char *bp
, *cp
, *pp
;
175 register struct aka
*ak
= NULL
;
179 && (strncmp (file
, "./", 2) && strncmp (file
, "../", 3)))
180 file
= etcpath (file
);
181 if ((fp
= fopen (file
, "r")) == NULL
) {
186 while (vfgets (fp
, &ap
) == OK
) {
188 switch (*(pp
= scanp (bp
))) {
189 case '<': /* recurse a level */
190 if (!*(cp
= getp (pp
+ 1))) {
191 akerrst
= "'<' without alias-file";
195 if ((i
= alias (cp
)) != AK_OK
) {
200 case ':': /* comment */
208 if (!*(cp
= seekp (pp
, &lc
, &ap
))) {
212 if (!(ak
= akalloc (cp
))) {
230 switch (*(pp
= scanp (ap
))) {
235 case '<': /* read values from file */
236 if (!*(cp
= getp (pp
+ 1))) {
240 if (!addfile (ak
, cp
)) {
246 case '=': /* UNIX group */
247 if (!*(cp
= getp (pp
+ 1))) {
251 if (!addgroup (ak
, cp
)) {
257 case '+': /* UNIX group members */
258 if (!*(cp
= getp (pp
+ 1))) {
262 if (!addmember (ak
, cp
)) {
268 case '*': /* Everyone */
273 while ((cp
= getalias (pp
)))
287 static char buffer
[BUFSIZ
];
291 snprintf (buffer
, sizeof(buffer
), "unable to read '%s'", akerrst
);
295 snprintf (buffer
, sizeof(buffer
), "error in line '%s'", akerrst
);
299 snprintf (buffer
, sizeof(buffer
), "out of memory while on '%s'", akerrst
);
303 snprintf (buffer
, sizeof(buffer
), "no such group as '%s'", akerrst
);
307 snprintf (buffer
, sizeof(buffer
), "unknown error (%d)", i
);
316 scanp (unsigned char *p
)
327 register unsigned char *cp
= scanp (p
);
330 while (!isspace (*cp
) && *cp
)
339 seekp (char *p
, char *c
, char **a
)
341 register unsigned char *cp
;
344 while (!isspace (*cp
) && *cp
&& *cp
!= ':' && *cp
!= ';')
355 addfile (struct aka
*ak
, char *file
)
361 if (!(fp
= fopen (etcpath (file
), "r"))) {
366 while (fgets (buffer
, sizeof buffer
, fp
))
367 while ((cp
= getalias (buffer
)))
376 addgroup (struct aka
*ak
, char *grp
)
379 register struct group
*gr
= getgrnam (grp
);
380 register struct home
*hm
= NULL
;
383 gr
= getgrgid (atoi (grp
));
389 while ((gp
= *gr
->gr_mem
++))
392 for (hm
= homehead
; hm
; hm
= hm
->h_next
)
393 if (!strcmp (hm
->h_name
, gp
)) {
394 add_aka (ak
, hm
->h_name
);
397 if ((pw
= getpwnam(gp
)))
409 addmember (struct aka
*ak
, char *grp
)
412 register struct group
*gr
= getgrnam (grp
);
413 register struct home
*hm
= NULL
;
428 for (hm
= homehead
; hm
; hm
= hm
->h_next
)
429 if (hm
->h_gid
== gid
)
430 add_aka (ak
, hm
->h_name
);
437 addall (struct aka
*ak
)
439 int noshell
= NoShell
== NULL
|| *NoShell
== 0;
440 register struct home
*hm
;
447 for (hm
= homehead
; hm
; hm
= hm
->h_next
)
448 if ((int) hm
->h_uid
> Everyone
449 && (noshell
|| strcmp (hm
->h_shell
, NoShell
)))
450 add_aka (ak
, hm
->h_name
);
452 return homehead
!= NULL
;
457 getalias (char *addrs
)
459 register unsigned char *pp
, *qp
;
460 static char *cp
= NULL
;
468 /* Remove leading any space from the address. */
469 for (pp
= cp
; isspace (*pp
); pp
++)
473 /* Find the end of the address. */
474 for (qp
= pp
; *qp
!= 0 && *qp
!= ','; qp
++)
476 /* Set cp to point to the remainder of the addresses. */
479 for (cp
= qp
, qp
--; qp
> pp
; qp
--)
492 add_aka (struct aka
*ak
, char *pp
)
494 register struct adr
*ad
, *ld
;
496 for (ad
= ak
->ak_addr
, ld
= NULL
; ad
; ld
= ad
, ad
= ad
->ad_next
)
497 if (!strcmp (pp
, ad
->ad_text
))
500 ad
= (struct adr
*) mh_xmalloc (sizeof(*ad
));
501 ad
->ad_text
= getcpy (pp
);
502 ad
->ad_local
= strchr(pp
, '@') == NULL
&& strchr(pp
, '!') == NULL
;
514 register struct passwd
*pw
;
519 /* if the list has yet to be initialized */
520 /* zap the list, and rebuild from scratch */
527 while ((pw
= getpwent ()))
539 register struct aka
*p
;
541 p
= (struct aka
*) mh_xmalloc (sizeof(*p
));
543 p
->ak_name
= getcpy (id
);
548 akatail
->ak_next
= p
;
558 hmalloc (struct passwd
*pw
)
560 register struct home
*p
;
562 p
= (struct home
*) mh_xmalloc (sizeof(*p
));
564 p
->h_name
= getcpy (pw
->pw_name
);
565 p
->h_uid
= pw
->pw_uid
;
566 p
->h_gid
= pw
->pw_gid
;
567 p
->h_home
= getcpy (pw
->pw_dir
);
568 p
->h_shell
= getcpy (pw
->pw_shell
);
571 if (hometail
!= NULL
)
572 hometail
->h_next
= p
;
573 if (homehead
== NULL
)