]> diplodocus.org Git - nmh/blob - uip/ali.c
Makefile.am: Add test/inc/test-eom-align to XFAIL_TESTS.
[nmh] / uip / ali.c
1 /* ali.c -- list nmh mail aliases
2 *
3 * This code is Copyright (c) 2002, by the authors of nmh. See the
4 * COPYRIGHT file in the root directory of the nmh distribution for
5 * complete copyright information.
6 */
7
8 #include <h/mh.h>
9 #include <h/addrsbr.h>
10 #include <h/aliasbr.h>
11 #include <h/mts.h>
12 #include <h/utils.h>
13
14 #define ALI_SWITCHES \
15 X("alias aliasfile", 0, ALIASW) \
16 X("noalias", 0, NALIASW) \
17 X("list", 0, LISTSW) \
18 X("nolist", 0, NLISTSW) \
19 X("user", 0, USERSW) \
20 X("nouser", 0, NUSERSW) \
21 X("version", 0, VERSIONSW) \
22 X("help", 0, HELPSW) \
23
24 #define X(sw, minchars, id) id,
25 DEFINE_SWITCH_ENUM(ALI);
26 #undef X
27
28 #define X(sw, minchars, id) { sw, minchars, id },
29 DEFINE_SWITCH_ARRAY(ALI, switches);
30 #undef X
31
32 static int pos = 1;
33
34 extern struct aka *akahead;
35
36 /*
37 * prototypes
38 */
39 static void print_aka (char *, int, int);
40 static void print_usr (char *, int);
41
42
43 int
44 main (int argc, char **argv)
45 {
46 int i, vecp = 0, inverted = 0, list = 0;
47 int noalias = 0;
48 char *cp, **ap, **argp, buf[BUFSIZ];
49 /* Really only need to allocate for argc-1, but must allocate at least 1,
50 so go ahead and allocate for argc char pointers. */
51 char **vec = mh_xmalloc (argc * sizeof (char *)), **arguments;
52 struct aka *ak;
53
54 if (nmh_init(argv[0], 1)) { return 1; }
55
56 mts_init ();
57 arguments = getarguments (invo_name, argc, argv, 1);
58 argp = arguments;
59
60 while ((cp = *argp++)) {
61 if (*cp == '-') {
62 switch (smatch (++cp, switches)) {
63 case AMBIGSW:
64 ambigsw (cp, switches);
65 done (1);
66 case UNKWNSW:
67 adios (NULL, "-%s unknown", cp);
68
69 case HELPSW:
70 snprintf (buf, sizeof(buf), "%s [switches] aliases ...",
71 invo_name);
72 print_help (buf, switches, 1);
73 done (0);
74 case VERSIONSW:
75 print_version (invo_name);
76 done (0);
77
78 case ALIASW:
79 if (!(cp = *argp++) || *cp == '-')
80 adios (NULL, "missing argument to %s", argp[-2]);
81 if ((i = alias (cp)) != AK_OK)
82 adios (NULL, "aliasing error in %s - %s", cp, akerror (i));
83 continue;
84 case NALIASW:
85 noalias++;
86 continue;
87
88 case LISTSW:
89 list++;
90 continue;
91 case NLISTSW:
92 list = 0;
93 continue;
94
95 case USERSW:
96 inverted++;
97 continue;
98 case NUSERSW:
99 inverted = 0;
100 continue;
101 }
102 }
103
104 if (vecp < argc) {
105 vec[vecp++] = cp;
106 } else {
107 /* Should never happen, but try to protect against code changes
108 that could allow it. */
109 adios (NULL, "too many arguments");
110 }
111 }
112
113 if (!noalias) {
114 /* allow Aliasfile: profile entry */
115 if ((cp = context_find ("Aliasfile"))) {
116 char *dp = NULL;
117
118 for (ap = brkstring(dp = mh_xstrdup(cp), " ", "\n"); ap && *ap; ap++)
119 if ((i = alias (*ap)) != AK_OK)
120 adios (NULL, "aliasing error in %s - %s", *ap, akerror (i));
121 mh_xfree(dp);
122 }
123 alias (AliasFile);
124 }
125
126 /*
127 * If -user is specified
128 */
129 if (inverted) {
130 if (vecp == 0)
131 adios (NULL, "usage: %s -user addresses ... (you forgot the addresses)",
132 invo_name);
133
134 for (i = 0; i < vecp; i++)
135 print_usr (vec[i], list);
136 } else {
137 if (vecp) {
138 /* print specified aliases */
139 for (i = 0; i < vecp; i++)
140 print_aka (akvalue (vec[i]), list, 0);
141 } else {
142 /* print them all */
143 for (ak = akahead; ak; ak = ak->ak_next) {
144 char *res;
145
146 printf ("%s: ", ak->ak_name);
147 pos += strlen (ak->ak_name) + 1;
148 res = akresult(ak);
149 print_aka(res, list, pos);
150 free(res);
151 }
152 }
153 }
154
155 free (vec);
156 done (0);
157 return 1;
158 }
159
160 static void
161 print_aka (char *p, int list, int margin)
162 {
163 char c;
164
165 if (p == NULL) {
166 puts("<empty>");
167 return;
168 }
169
170 while ((c = *p++)) {
171 switch (c) {
172 case ',':
173 if (*p) {
174 if (list)
175 printf ("\n%*s", margin, "");
176 else {
177 if (pos >= 68) {
178 printf (",\n ");
179 pos = 2;
180 } else {
181 printf (", ");
182 pos += 2;
183 }
184 }
185 }
186
187 case 0:
188 break;
189
190 default:
191 pos++;
192 putchar (c);
193 }
194 }
195
196 putchar ('\n');
197 pos = 1;
198 }
199
200 static void
201 print_usr (char *s, int list)
202 {
203 char *cp, *pp, *vp;
204 struct aka *ak;
205 struct mailname *mp, *np;
206
207 if ((pp = getname (s)) == NULL)
208 adios (NULL, "no address in \"%s\"", s);
209 if ((mp = getm (pp, NULL, 0, NULL, 0)) == NULL)
210 adios (NULL, "bad address \"%s\"", s);
211 while (getname (""))
212 continue;
213
214 vp = NULL;
215 for (ak = akahead; ak; ak = ak->ak_next) {
216 pp = akresult (ak);
217 while ((cp = getname (pp))) {
218 if ((np = getm (cp, NULL, 0, NULL, 0)) == NULL)
219 continue;
220 if (!strcasecmp (FENDNULL(mp->m_host),
221 FENDNULL(np->m_host)) &&
222 !strcasecmp (FENDNULL(mp->m_mbox),
223 FENDNULL(np->m_mbox))) {
224 vp = vp ? add (ak->ak_name, add (",", vp))
225 : getcpy (ak->ak_name);
226 mnfree (np);
227 while (getname (""))
228 continue;
229 break;
230 }
231 mnfree (np);
232 }
233 }
234 mnfree (mp);
235
236 print_aka (vp ? vp : s, list, 0);
237
238 mh_xfree(vp);
239 }