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