]>
diplodocus.org Git - nmh/blob - uip/aliasbr.c
84967deaab123c87fc8de880e8253708f1457ee1
2 * aliasbr.c -- new aliasing mechanism
4 * This code is Copyright (c) 2002, by the authors of nmh. See the
5 * COPYRIGHT file in the root directory of the nmh distribution for
6 * complete copyright information.
10 #include <h/aliasbr.h>
11 #include <h/addrsbr.h>
19 struct aka
*akahead
= NULL
;
20 struct aka
*akatail
= NULL
;
22 struct home
*homehead
= NULL
;
23 struct home
*hometail
= NULL
;
31 char *akresult (struct aka
*);
32 char *akvalue (char *);
35 static char *akval (struct aka
*, char *);
36 static int aleq (char *, char *);
37 static char *scanp (char *);
38 static char *getp (char *);
39 static char *seekp (char *, char *, char **);
40 static int addfile (struct aka
*, char *);
41 static int addgroup (struct aka
*, char *);
42 static int addmember (struct aka
*, char *);
43 static char *getalias (char *);
44 static void add_aka (struct aka
*, char *);
45 static struct aka
*akalloc (char *);
46 static struct home
*hmalloc (struct passwd
*);
49 /* Do mh alias substitution on 's' and return the results. */
59 v
= akval (akahead
, s
);
74 akresult (struct aka
*ak
)
76 char *cp
= NULL
, *dp
, *pp
;
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 /* It'd be tempting to check for a trailing semicolon and remove
106 it. But that would break the EXMH alias parser on what would
107 then be valid expressions:
108 http://lists.gnu.org/archive/html/nmh-workers/2012-10/msg00039.html
111 for (; ak
; ak
= ak
->ak_next
) {
112 if (aleq (s
, ak
->ak_name
)) {
113 return akresult (ak
);
116 if (strchr (s
, ':')) {
117 /* The first address in a blind list will contain the
118 alias name, so try to match, but just with just the
119 address (not including the list name). If there's a
120 match, then replace the alias part with its
123 char *name
= getname (s
);
127 /* s is of the form "Blind list: address". If address
128 is an alias, expand it. */
129 struct mailname
*mp
= getm (name
, NULL
, 0, NULL
, 0);
131 if (mp
&& mp
->m_ingrp
) {
132 char *gname
= add (mp
->m_gname
, NULL
);
134 /* FIXME: gname must be true; add() never returns NULL.
135 * Is some other test required? */
136 if (gname
&& aleq (name
, ak
->ak_name
)) {
138 cp
= concat (gname
, akresult (ak
), NULL
);
146 /* Need to flush getname after use. */
147 while (getname ("")) continue;
155 return mh_xstrdup(s
);
160 aleq (char *string
, char *aliasent
)
164 while ((c
= *string
++)) {
165 if (*aliasent
== '*')
167 if (tolower((unsigned char)c
) != tolower((unsigned char)*aliasent
))
172 return (*aliasent
== 0 || *aliasent
== '*');
182 struct aka
*ak
= NULL
;
186 && !has_prefix(file
, "./") && !has_prefix(file
, "../"))
187 file
= etcpath (file
);
188 if ((fp
= fopen (file
, "r")) == NULL
) {
193 while (vfgets (fp
, &ap
) == OK
) {
195 switch (*(pp
= scanp (bp
))) {
196 case '<': /* recurse a level */
197 if (!*(cp
= getp (pp
+ 1))) {
198 akerrst
= "'<' without alias-file";
202 if ((i
= alias (cp
)) != AK_OK
) {
207 case ':': /* comment */
215 if (!*(cp
= seekp (pp
, &lc
, &ap
))) {
219 if (!(ak
= akalloc (cp
))) {
237 switch (*(pp
= scanp (ap
))) {
242 case '<': /* read values from file */
243 if (!*(cp
= getp (pp
+ 1))) {
247 if (!addfile (ak
, cp
)) {
253 case '=': /* UNIX group */
254 if (!*(cp
= getp (pp
+ 1))) {
258 if (!addgroup (ak
, cp
)) {
264 case '+': /* UNIX group members */
265 if (!*(cp
= getp (pp
+ 1))) {
269 if (!addmember (ak
, cp
)) {
276 while ((cp
= getalias (pp
)))
290 static char buffer
[BUFSIZ
];
294 snprintf (buffer
, sizeof(buffer
), "unable to read '%s'", akerrst
);
298 snprintf (buffer
, sizeof(buffer
), "error in line '%s'", akerrst
);
302 snprintf (buffer
, sizeof(buffer
), "out of memory while on '%s'", akerrst
);
306 snprintf (buffer
, sizeof(buffer
), "no such group as '%s'", akerrst
);
310 snprintf (buffer
, sizeof(buffer
), "unknown error (%d)", i
);
321 while (isspace ((unsigned char) *p
))
330 char *cp
= scanp (p
);
333 while (!isspace ((unsigned char) *cp
) && *cp
)
342 seekp (char *p
, char *c
, char **a
)
347 while (!isspace ((unsigned char) *cp
) && *cp
&& *cp
!= ':' && *cp
!= ';')
358 addfile (struct aka
*ak
, char *file
)
364 if (!(fp
= fopen (etcpath (file
), "r"))) {
369 while (fgets (buffer
, sizeof buffer
, fp
))
370 while ((cp
= getalias (buffer
)))
379 addgroup (struct aka
*ak
, char *grp
)
382 struct group
*gr
= getgrnam (grp
);
383 struct home
*hm
= NULL
;
386 gr
= getgrgid (atoi (grp
));
392 while ((gp
= *gr
->gr_mem
++))
395 for (hm
= homehead
; hm
; hm
= hm
->h_next
)
396 if (!strcmp (hm
->h_name
, gp
)) {
397 add_aka (ak
, hm
->h_name
);
400 if ((pw
= getpwnam(gp
)))
412 addmember (struct aka
*ak
, char *grp
)
415 struct group
*gr
= getgrnam (grp
);
416 struct home
*hm
= NULL
;
431 for (hm
= homehead
; hm
; hm
= hm
->h_next
)
432 if (hm
->h_gid
== gid
)
433 add_aka (ak
, hm
->h_name
);
440 getalias (char *addrs
)
443 static char *cp
= NULL
;
451 /* Remove leading any space from the address. */
452 for (pp
= cp
; isspace ((unsigned char) *pp
); pp
++)
456 /* Find the end of the address. */
457 for (qp
= pp
; *qp
!= 0 && *qp
!= ','; qp
++)
459 /* Set cp to point to the remainder of the addresses. */
462 for (cp
= qp
, qp
--; qp
> pp
; qp
--)
464 if (isspace ((unsigned char) *qp
))
475 add_aka (struct aka
*ak
, char *pp
)
479 for (ad
= ak
->ak_addr
, ld
= NULL
; ad
; ld
= ad
, ad
= ad
->ad_next
)
480 if (!strcmp (pp
, ad
->ad_text
))
484 ad
->ad_text
= mh_xstrdup(pp
);
485 ad
->ad_local
= strchr(pp
, '@') == NULL
&& strchr(pp
, '!') == NULL
;
502 /* if the list has yet to be initialized */
503 /* zap the list, and rebuild from scratch */
510 while ((pw
= getpwent ()))
525 p
->ak_name
= getcpy (id
);
530 akatail
->ak_next
= p
;
540 hmalloc (struct passwd
*pw
)
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
)