]> andersk Git - moira.git/blame - gen/aliases.qc
Initial revision
[moira.git] / gen / aliases.qc
CommitLineData
67796c83 1/* $Header$
2 *
3 * This generates the /usr/lib/aliases mail aliases file for the mailhub.
4 * The aliases file will contain:
5 * user pobox entries
6 * maillist expansions
7 * sublists of maillists
67796c83 8 */
9
10
11#include <stdio.h>
39b94410 12#include <string.h>
67796c83 13#include <sms.h>
14#include <sms_app.h>
5076cbb9 15#include <sys/types.h>
16#include <sys/stat.h>
17#include <sys/time.h>
18
67796c83 19
20#define ML_WID 72
21#define AL_MAX_WID 896
22
23char *divide = "########################################################################";
24extern int errno;
5076cbb9 25char *ingres_date_and_time();
67796c83 26
27
28main(argc, argv)
29int argc;
30char **argv;
31{
32 long tm = time(NULL);
33 FILE *out= stdout;
39b94410 34 char filename[64], *targetfile;
5076cbb9 35 struct stat sb;
39b94410 36## int flag1, flag2, flag3;
5076cbb9 37## char *filetime;
38
39## ingres sms
67796c83 40
41 if (argc == 2) {
5076cbb9 42 if (stat(argv[1], &sb) == 0) {
43 filetime = ingres_date_and_time(sb.st_mtime);
44## retrieve (flag1 = int4(interval("min",tblstats.modtime - filetime)))
45## where tblstats.table = "list"
46## retrieve (flag2 = int4(interval("min",tblstats.modtime - filetime)))
47## where tblstats.table = "members"
48## retrieve (flag3 = int4(interval("min",tblstats.modtime - filetime)))
49## where tblstats.table = "users"
50 if (flag1 < 0 && flag2 < 0 && flag3 < 0) {
51 fprintf(stderr, "File %s does not need to be rebuilt.\n",
52 argv[1]);
39b94410 53 exit(SMS_NO_CHANGE);
5076cbb9 54 }
55 }
39b94410 56 targetfile = argv[1];
57 sprintf(filename, "%s~", targetfile);
58 if ((out = fopen(filename, "w")) == NULL) {
59 fprintf(stderr, "unable to open %s for output\n", filename);
60 exit(SMS_OCONFIG);
67796c83 61 }
62 } else if (argc != 1) {
63 fprintf(stderr, "usage: %s [outfile]\n", argv[0]);
39b94410 64 exit(SMS_ARGS);
67796c83 65 }
66
67796c83 67 fprintf(out, "%s\n# Aliases File Extract of %s", divide, ctime(&tm));
68 fprintf(out, "# This file is automatically generated, do not edit it directly.\n%s\n\n", divide);
69
39b94410 70## begin transaction
71 get_info();
72## end transaction
73## exit
74
75 fprintf(stderr, "Dumping information\n");
67796c83 76 do_mlists(out);
77 do_poboxes(out);
67796c83 78
79 fprintf(out, "\n%s\n# End of aliases file\n%s\n", divide, divide);
80
67796c83 81
82 if (fclose(out)) {
83 perror("close failed");
39b94410 84 exit(SMS_CCONFIG);
67796c83 85 }
39b94410 86
87 if (argc == 2)
88 fix_file(targetfile);
89 exit(SMS_SUCCESS);
67796c83 90}
91
92
39b94410 93struct hash *users, *machines, *strings, *lists;
94struct user {
95 char login[9];
96 char *pobox;
97};
98struct member {
99 struct member *next;
100 char *name;
101 int list_id;
102};
103struct list {
104 char name[33];
105 char maillist;
106 char acl_t;
107 char description[256];
108 int acl_id;
109 struct member *m;
110};
111
112
113get_info()
114##{
115## int id, maillistp, acl, pid, bid, mid;
116## char name[129], type[9], buf[257];
117 char *s;
118 register struct user *u;
119 register struct list *l;
120 register struct member *m;
121
122 fprintf(stderr, "Loading machines\n");
123 machines = create_hash(1000);
124## retrieve (id = machine.mach_id, name = machine.#name) {
125 if (s = index(name, '.'))
126 *s = 0;
127 sprintf(buf, "%s.LOCAL", name);
128 hash_store(machines, id, strsave(buf));
129## }
130
131 fprintf(stderr, "Loading strings\n");
132 strings = create_hash(2000);
133## retrieve (id = strings.string_id, name = strings.string) {
134 hash_store(strings, id, strsave(strtrim(name)));
135## }
136
137 fprintf(stderr, "Loading users\n");
138 users = create_hash(15000);
139## range of u is users
140## retrieve (id = u.users_id, name = u.login, type = u.potype,
141## pid = u.pop_id, bid = u.box_id) where u.status = 1 {
142 u = (struct user *) malloc(sizeof(struct user));
143 strcpy(u->login, strtrim(name));
144 u->pobox = (char *) NULL;
145 if (type[0] == 'P') {
146 if (s = hash_lookup(machines, pid)) {
147 sprintf(buf, "%s@%s", name, s);
148 u->pobox = strsave(buf);
149 } else {
150 fprintf(stderr, "User %s's pobox is on a missing machine!\n",
151 u->login);
152 }
153 } else if (type[0] == 'S') {
154 if ((u->pobox = hash_lookup(strings, bid)) == NULL)
155 fprintf(stderr, "User %s's pobox string is missing!\n", u->login);
156 }
157 hash_store(users, id, u);
158## }
159
160 fprintf(stderr, "Loading lists\n");
161 lists = create_hash(15000);
162## range of l is list
163## retrieve (id = l.list_id, name = l.#name, maillistp = l.maillist,
164## buf = l.desc, type = l.acl_type, acl = l.acl_id)
165## where l.active != 0 {
166 l = (struct list *) malloc(sizeof(struct list));
167 strcpy(l->name, strtrim(name));
168 l->maillist = maillistp;
169 strcpy(l->description, strtrim(buf));
170 l->acl_t = type[0];
171 l->acl_id = acl;
172 l->m = (struct member *) NULL;
173 hash_store(lists, id, l);
174## }
175
176
177 fprintf(stderr, "Loading members\n");
178## range of m is members
179## retrieve (id = m.list_id, type = m.member_type, mid = m.member_id) {
180 if (l = (struct list *) hash_lookup(lists, id)) {
181 m = (struct member *) malloc(sizeof(struct member));
182 m->name = (char *) NULL;
183 if (type[0] == 'U') {
184 m->list_id = 0;
185 if (u = (struct user *) hash_lookup(users, mid))
186 m->name = u->login;
187 } else if (type[0] == 'L') {
188 m->list_id = mid;
189 if (l = (struct list *) hash_lookup(lists, mid))
190 m->name = l->name;
191 } else if (type[0] == 'S') {
192 m->list_id = 0;
193 if (s = hash_lookup(strings, mid))
194 m->name = s;
195 }
196 if (m->name != (char *) NULL) {
197 m->next = l->m;
198 l->m = m;
199 }
200 }
201## }
202##}
203
204
205void save_mlist(id, l, sq)
206int id;
207struct list *l;
208struct save_queue *sq;
209{
210 if (l->maillist)
211 sq_save_unique_data(sq, id);
212}
213
214
215/* Determine if a list, given by list_id, is a user group.
216 * We really need to figure out a way to do this right.
217 */
218
219int user_group(id)
220int id;
221{
222 return(0);
223}
224
225
226/* Extract mailing lists. Make a list of all mailinglists, then
227 * process them, adding any sub-lists or acl lists to the list of lists
228 * to be processed. If further sublists are encountered, repeat...
67796c83 229 */
230
231int lwid, bol;
232
233do_mlists(out)
234FILE *out;
39b94410 235{
236 register struct list *l;
237 struct list *l1;
238 register struct member *m;
239 struct user *u;
240 register struct save_queue *sq;
241 struct save_queue *sq_create();
242 int id;
67796c83 243
244 sq = sq_create();
245 fprintf(out, "\n%s\n# Mailing lists\n%s\n", divide, divide);
246
39b94410 247 hash_step(lists, save_mlist, sq);
67796c83 248
67796c83 249 while (sq_get_data(sq, &id)) {
39b94410 250 l = (struct list *) hash_lookup(lists, id);
251 if (l->m && /* there's at least one member */
252 l->m->next == NULL && /* there's only one member */
253 !strcmp(l->name, l->m->name)) /* the member is same as list */
254 continue;
255 put_fill(out, l->description);
256 if (l->acl_t == 'L') {
257 if (l1 = (struct list *) hash_lookup(lists, l->acl_id)) {
258 fprintf(out, "owner-%s: %s\n", l->name, l1->name);
259 if (!user_group(l->acl_id))
260 sq_save_unique_data(sq, l->acl_id);
261 }
262 } else if (l->acl_t == 'U') {
263 if (u = (struct user *) hash_lookup(users, l->acl_id))
264 fprintf(out, "owner-%s: %s\n", l->name, u->login);
67796c83 265 }
39b94410 266 fprintf(out, "%s: ", l->name);
267 lwid = strlen(l->name) + 2;
67796c83 268 bol = 1;
39b94410 269 for (m = l->m; m; m = m->next) {
270 if (m->list_id != 0 && user_group(m->list_id))
271 sq_save_unique_data(sq, m->list_id);
272 do_member(out, m->name);
273 }
67796c83 274 fprintf(out, "\n\n");
275 }
276
277 sq_destroy(sq);
39b94410 278}
67796c83 279
280
281/* print out strings separated by commas, doing line breaks as appropriate */
282
283do_member(out, s)
284FILE *out;
285register char *s;
286{
287 register wwid;
288 static int awid;
289 static int cont = 1;
290
39b94410 291 strtrim(s);
67796c83 292 wwid = strlen(s);
293
294 if (awid + wwid + 2 > AL_MAX_WID) {
295 fprintf(out, ",\n\tcontinuation-%d\ncontinuation-%d: ", cont, cont);
296 cont++;
297 awid = lwid = bol = 17;
298 }
299
300 if (bol) {
301 lwid += wwid;
302 awid = lwid;
303 fprintf(out, "%s", s);
304 bol = 0;
305 return;
306 }
307 if (lwid + wwid + 2 > ML_WID) {
308 fprintf(out, ",\n\t%s", s);
309 awid = lwid + wwid + 2;
310 lwid = wwid + 8;
311 return;
312 }
313 lwid += wwid + 2;
314 fprintf(out, ", %s", s);
315}
316
39b94410 317do_pobox(id, u, out)
318int id;
319register struct user *u;
320FILE *out;
321{
322 if (u->pobox)
323 fprintf(out, "%s: %s\n", u->login, u->pobox);
324}
325
67796c83 326
39b94410 327/* Do user poboxes. Just step through the users table, and print any
328 * we extracted earlier.
67796c83 329 */
330
331do_poboxes(out)
332FILE *out;
39b94410 333{
334 register char *p;
335 char *index();
67796c83 336
337 fprintf(out, "\n%s\n# User Poboxes\n%s\n", divide, divide);
338
39b94410 339 hash_step(users, do_pobox, out);
340}
67796c83 341
342
343put_fill(aliases, string)
344FILE *aliases;
345register char *string;
346{
347 register char *c;
348 register int lwid;
349 register int wwid;
350
351 if (*string == 0) return;
352 fputs("# ", aliases);
353 lwid = 3;
354
355 while (1) {
356 while (*string && *string == ' ') string++;
357 c = (char *)index(string, ' ');
358 if (c == 0) {
359 wwid = strlen(string);
360 } else {
361 wwid = c - string;
362 *c = 0;
363 }
364
365 if ((lwid + wwid) > ML_WID) {
366 fputs("\n# ", aliases);
367 lwid = 3;
368 fputs(string, aliases);
369 } else {
370 fputs(string, aliases);
371 }
372
373 if (c == (char *)0) break;
374 /* add a space after the word */
375 (void) fputc(' ', aliases);
376 wwid++;
377 lwid += wwid;
378 string += wwid;
379 /* add another if after a period */
380 if (*--c == '.') {
381 (void) fputc(' ', aliases);
382 lwid++;
383 }
384 }
385
386 (void) fputc('\n', aliases);
387}
This page took 0.108211 seconds and 5 git commands to generate.