3 * This generates the /usr/lib/aliases mail aliases file for the mailhub.
4 * The aliases file will contain:
7 * sublists of maillists
15 #include <sys/types.h>
21 #define AL_MAX_WID 896
23 char *divide = "########################################################################";
25 char *whoami = "aliases.gen";
26 char *ingres_date_and_time();
35 char filename[64], *targetfile;
37 ## int flag1, flag2, flag3;
45 if (stat(argv[1], &sb) == 0) {
46 filetime = ingres_date_and_time(sb.st_mtime);
47 ## retrieve (flag1 = int4(interval("min",tblstats.modtime - filetime)))
48 ## where tblstats.table = "list"
49 ## retrieve (flag2 = int4(interval("min",tblstats.modtime - filetime)))
50 ## where tblstats.table = "members"
51 ## retrieve (flag3 = int4(interval("min",tblstats.modtime - filetime)))
52 ## where tblstats.table = "users"
53 if (flag1 < 0 && flag2 < 0 && flag3 < 0) {
54 fprintf(stderr, "File %s does not need to be rebuilt.\n",
60 sprintf(filename, "%s~", targetfile);
61 if ((out = fopen(filename, "w")) == NULL) {
62 fprintf(stderr, "unable to open %s for output\n", filename);
65 } else if (argc != 1) {
66 fprintf(stderr, "usage: %s [outfile]\n", argv[0]);
70 fprintf(out, "%s\n# Aliases File Extract of %s", divide, ctime(&tm));
71 fprintf(out, "# This file is automatically generated, do not edit it directly.\n%s\n\n", divide);
78 fprintf(stderr, "Dumping information\n");
82 fprintf(out, "\n%s\n# End of aliases file\n%s\n", divide, divide);
86 perror("close failed");
97 * ingerr: (supposedly) called when Ingres indicates an error.
98 * I have not yet been able to get this to work to intercept a
99 * database open error.
101 #define INGRES_DEADLOCK 4700
103 static int ingerr(num)
110 case INGRES_DEADLOCK:
111 ingres_errno = SMS_DEADLOCK;
114 ingres_errno = SMS_INGRES_ERR;
116 com_err(whoami, SMS_INGRES_ERR, " code %d\n", *num);
117 critical_alert("DCM", "Alias build encountered INGRES ERROR %d", *num);
122 struct hash *users, *machines, *strings, *lists;
136 char description[256];
144 ## int id, maillistp, acl, pid, bid, mid;
145 ## char name[129], type[9], buf[257];
147 register struct user *u;
148 register struct list *l;
149 register struct member *m;
150 register struct list *memberlist;
152 fprintf(stderr, "Loading machines\n");
153 machines = create_hash(1000);
154 ## retrieve (id = machine.mach_id, name = machine.#name) {
155 if (s = index(name, '.'))
157 sprintf(buf, "%s.LOCAL", name);
158 hash_store(machines, id, strsave(buf));
161 fprintf(stderr, "Loading strings\n");
162 strings = create_hash(2000);
163 ## retrieve (id = strings.string_id, name = strings.string) {
164 hash_store(strings, id, strsave(strtrim(name)));
167 fprintf(stderr, "Loading users\n");
168 users = create_hash(15000);
169 ## range of u is users
170 ## retrieve (id = u.users_id, name = u.login, type = u.potype,
171 ## pid = u.pop_id, bid = u.box_id) where u.status = 1 {
172 u = (struct user *) malloc(sizeof(struct user));
173 strcpy(u->login, strtrim(name));
174 u->pobox = (char *) NULL;
175 if (type[0] == 'P') {
176 if (s = hash_lookup(machines, pid)) {
177 sprintf(buf, "%s@%s", name, s);
178 u->pobox = strsave(buf);
180 fprintf(stderr, "User %s's pobox is on a missing machine!\n",
183 } else if (type[0] == 'S') {
184 if ((u->pobox = hash_lookup(strings, bid)) == NULL)
185 fprintf(stderr, "User %s's pobox string is missing!\n", u->login);
187 hash_store(users, id, u);
190 fprintf(stderr, "Loading lists\n");
191 lists = create_hash(15000);
192 ## range of l is list
193 ## retrieve (id = l.list_id, name = l.#name, maillistp = l.maillist,
194 ## buf = l.desc, type = l.acl_type, acl = l.acl_id)
195 ## where l.active != 0 {
196 l = (struct list *) malloc(sizeof(struct list));
197 strcpy(l->name, strtrim(name));
198 l->maillist = maillistp;
199 strcpy(l->description, strtrim(buf));
202 l->m = (struct member *) NULL;
203 hash_store(lists, id, l);
207 fprintf(stderr, "Loading members\n");
208 ## range of m is members
209 ## retrieve (id = m.list_id, type = m.member_type, mid = m.member_id) {
210 if (l = (struct list *) hash_lookup(lists, id)) {
211 m = (struct member *) malloc(sizeof(struct member));
212 m->name = (char *) NULL;
213 if (type[0] == 'U') {
215 if (u = (struct user *) hash_lookup(users, mid))
217 } else if (type[0] == 'L') {
219 if (memberlist = (struct list *) hash_lookup(lists, mid))
220 m->name = memberlist->name;
221 } else if (type[0] == 'S') {
223 if (s = hash_lookup(strings, mid))
226 if (m->name != (char *) NULL) {
235 void save_mlist(id, l, sq)
238 struct save_queue *sq;
241 sq_save_unique_data(sq, id);
245 /* Extract mailing lists. Make a list of all mailinglists, then
246 * process them, adding any sub-lists or acl lists to the list of lists
247 * to be processed. If further sublists are encountered, repeat...
255 register struct list *l;
257 register struct member *m;
259 register struct save_queue *sq;
260 struct save_queue *sq_create();
264 fprintf(out, "\n%s\n# Mailing lists\n%s\n", divide, divide);
266 hash_step(lists, save_mlist, sq);
268 while (sq_get_data(sq, &id)) {
269 l = (struct list *) hash_lookup(lists, id);
270 if (l->m && /* there's at least one member */
271 l->m->next == NULL && /* there's only one member */
272 !strcmp(l->name, l->m->name)) /* the member is same as list */
274 put_fill(out, l->description);
275 if (l->acl_t == 'L') {
276 if (l1 = (struct list *) hash_lookup(lists, l->acl_id)) {
277 fprintf(out, "owner-%s: %s\n", l->name, l1->name);
278 sq_save_unique_data(sq, l->acl_id);
280 } else if (l->acl_t == 'U') {
281 if (u = (struct user *) hash_lookup(users, l->acl_id))
282 fprintf(out, "owner-%s: %s\n", l->name, u->login);
284 fprintf(out, "%s: ", l->name);
285 lwid = strlen(l->name) + 2;
287 for (m = l->m; m; m = m->next) {
289 sq_save_unique_data(sq, m->list_id);
290 do_member(out, m->name);
292 fprintf(out, "\n\n");
295 /* Removed for speed, since this take 10 minutes to free, and we don't
296 * really need the memory reclaimed.
301 /* print out strings separated by commas, doing line breaks as appropriate */
313 if (!bol && awid + wwid + 2 > AL_MAX_WID) {
314 fprintf(out, ",\n\tcontinuation-%d\ncontinuation-%d: ", cont, cont);
316 awid = lwid = bol = 17;
322 fprintf(out, "%s", s);
326 if (lwid + wwid + 2 > ML_WID) {
327 fprintf(out, ",\n\t%s", s);
328 awid += lwid + wwid + 2;
333 fprintf(out, ", %s", s);
338 register struct user *u;
342 fprintf(out, "%s: %s\n", u->login, u->pobox);
346 /* Do user poboxes. Just step through the users table, and print any
347 * we extracted earlier.
356 fprintf(out, "\n%s\n# User Poboxes\n%s\n", divide, divide);
358 hash_step(users, do_pobox, out);
362 put_fill(aliases, string)
364 register char *string;
370 if (*string == 0) return;
371 fputs("# ", aliases);
375 while (*string && *string == ' ') string++;
376 c = (char *)index(string, ' ');
378 wwid = strlen(string);
384 if ((lwid + wwid) > ML_WID) {
385 fputs("\n# ", aliases);
387 fputs(string, aliases);
389 fputs(string, aliases);
392 if (c == (char *)0) break;
393 /* add a space after the word */
394 (void) fputc(' ', aliases);
398 /* add another if after a period */
400 (void) fputc(' ', aliases);
405 (void) fputc('\n', aliases);