]> andersk Git - moira.git/blob - gen/aliases.qc
61244a8897bb16c56ce1f1df78643efe325899b5
[moira.git] / gen / aliases.qc
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
8  *      mail alias entries
9  */
10
11
12 #include <stdio.h>
13 #include <sms.h>
14 #include <sms_app.h>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <sys/time.h>
18
19
20 #define ML_WID  72
21 #define AL_MAX_WID 896
22
23 char *divide = "########################################################################";
24 extern int errno;
25 char *ingres_date_and_time();
26
27
28 main(argc, argv)
29 int argc;
30 char **argv;
31 {
32     long tm = time(NULL);
33     FILE *out= stdout;
34     struct stat sb;
35 ##  int error, flag1, flag2, flag3;
36 ##  char *filetime;
37
38 ##  ingres sms
39
40     if (argc == 2) {
41         if (stat(argv[1], &sb) == 0) {
42             filetime = ingres_date_and_time(sb.st_mtime);
43 ##          retrieve (flag1 = int4(interval("min",tblstats.modtime - filetime)))
44 ##              where tblstats.table = "list"
45 ##          retrieve (flag2 = int4(interval("min",tblstats.modtime - filetime)))
46 ##              where tblstats.table = "members"
47 ##          retrieve (flag3 = int4(interval("min",tblstats.modtime - filetime)))
48 ##              where tblstats.table = "users"
49             if (flag1 < 0 && flag2 < 0 && flag3 < 0) {
50                 fprintf(stderr, "File %s does not need to be rebuilt.\n",
51                         argv[1]);
52                 exit(0);
53             }
54         }
55         if ((out = fopen(argv[1], "w")) == NULL) {
56             fprintf(stderr, "unable to open %s for output\n", argv[1]);
57             exit(errno);
58         }
59     } else if (argc != 1) {
60         fprintf(stderr, "usage: %s [outfile]\n", argv[0]);
61         exit(-1);
62     }
63
64 ##  set lockmode session where readlock = nolock
65
66     
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
70     do_mlists(out);
71     do_poboxes(out);
72     do_aliases(out);
73
74     fprintf(out, "\n%s\n# End of aliases file\n%s\n", divide, divide);
75
76 ##  inquire_equel(error = "errorno")
77     if (error)  {
78         fprintf(out, "Ingres error %d\n", error);
79         exit(error);
80     }
81
82 ##  exit
83
84     if (fclose(out)) {
85         perror("close failed");
86         exit(errno);
87     }
88     exit(0);
89 }
90
91
92 /* Extract mailing lists.  First dump all real mailing lists.  While doing
93  * this, make a list of all mailing list IDs and all sub-list IDs.  Next,
94  * as long as there are sub-lists that aren't mailing lists, extract them
95  * and add them to the list of mailing lists.  If further sublists are 
96  * encountered, repeat...
97  */
98
99 int lwid, bol;
100
101 do_mlists(out)
102 FILE *out;
103 ##{
104 ##  char name[257], desc[257], own_type[9], owner_name[33];
105 ##  int id, own_id, member_id;
106     struct save_queue *sq, *sq_create();
107
108     sq = sq_create();
109     fprintf(out, "\n%s\n# Mailing lists\n%s\n", divide, divide);
110
111 ##  range of l is list
112 ##  retrieve (id = l.list_id) where l.maillist != 0 {
113       sq_save_unique_data(sq, id);
114 ##  }
115
116 ##  range of m is members
117 ##  range of u is users
118 ##  range of s is strings
119     while (sq_get_data(sq, &id)) {
120 ##      repeat retrieve (name= l.#name, desc = l.#desc,
121 ##                own_type = l.acl_type, own_id = l.acl_id)
122 ##              where l.list_id = @id
123         trim(name);
124         trim(desc);
125         trim(own_type);
126         put_fill(out, desc);
127         if (!strcmp(own_type, "LIST")) {
128 ##          repeat retrieve (owner_name = l.#name) where l.list_id = @own_id
129             trim(owner_name);
130             fprintf(out, "owner-%s: %s\n", name, owner_name);
131             sq_save_unique_data(sq, own_id);
132         } else if (!strcmp(own_type, "USER")) {
133 ##          repeat retrieve (owner_name = u.#login) where u.users_id = @own_id
134             trim(owner_name);
135             fprintf(out, "owner-%s: %s\n", name, owner_name);
136         }
137         fprintf(out, "%s: ", name);
138         lwid = strlen(name) + 2;
139         bol = 1;
140 ##      repeat retrieve (name = u.#login) where u.users_id = m.#member_id and
141 ##              m.list_id = @id and m.member_type = "USER" {
142             do_member(out, name);
143 ##      }
144 ##      repeat retrieve (name = l.#name, member_id = m.#member_id)
145 ##              where l.list_id = m.#member_id and
146 ##                    m.list_id = @id and m.member_type = "LIST" {
147             do_member(out, name);
148             sq_save_unique_data(sq, member_id);
149 ##      }
150 ##      repeat retrieve (name = s.#string) where s.string_id = m.#member_id and
151 ##              m.list_id = @id and m.member_type = "STRING" {
152             do_member(out, name);
153 ##      }
154         fprintf(out, "\n\n");
155     }
156
157     sq_destroy(sq);
158 ##}
159
160
161 /* print out strings separated by commas, doing line breaks as appropriate */
162
163 do_member(out, s)
164 FILE *out;
165 register char *s;
166 {
167     register wwid;
168     static int awid;
169     static int cont = 1;
170
171     trim(s);
172     wwid = strlen(s);
173
174     if (awid + wwid + 2 > AL_MAX_WID) {
175         fprintf(out, ",\n\tcontinuation-%d\ncontinuation-%d: ", cont, cont);
176         cont++;
177         awid = lwid = bol = 17;
178     }
179
180     if (bol) {
181         lwid += wwid;
182         awid = lwid;
183         fprintf(out, "%s", s);
184         bol = 0;
185         return;
186     }
187     if (lwid + wwid + 2 > ML_WID) {
188         fprintf(out, ",\n\t%s", s);
189         awid = lwid + wwid + 2;
190         lwid = wwid + 8;
191         return;
192     }
193     lwid += wwid + 2;
194     fprintf(out, ", %s", s);
195 }
196
197
198 /* Extract user poboxes.  First do POP boxes, where the name matches the
199  * login name and the machine name is in the pop_id.  Then do SMTP boxes,
200  * where the expansion is stored in the strings table.  The remaining boxes
201  * are of type NONE and should be skipped.
202  */
203
204 do_poboxes(out)
205 FILE *out;
206 ##{
207 ##  char login[9], name[33], box[129];
208
209     fprintf(out, "\n%s\n# User Poboxes\n%s\n", divide, divide);
210
211 ##  range of u is users
212 ##  range of m is machine
213 ##  retrieve (login = u.#login, name = m.#name)
214 ##      where u.potype = "POP" and m.mach_id = u.pop_id {
215       trim(login, name);
216       fprintf(out, "%s: %s@%s\n", login, login, name);
217 ##  }
218
219     fprintf(out, "\n# User Forwarding\n");
220
221 ##  range of s is strings
222 ##  retrieve (login = u.#login, box = s.#string)
223 ##      where u.potype = "SMTP" and u.box_id = s.string_id {
224       trim(login);
225       trim(box);
226       fprintf(out, "%s: %s\n", login, box);
227 ##  }
228
229 ##}
230
231
232 do_aliases(out)
233 FILE *out;
234 ##{
235 ##  char name[33], trans[129];
236
237     fprintf(out, "\n%s\n# Aliases\n%s\n", divide, divide);
238
239 ##  range of a is alias
240 ##  retrieve (name = a.#name, trans = a.#trans) where a.type = "MAIL" {
241         trim(name);
242         trim(trans);
243         fprintf(out, "%s: %s\n", name, trans);
244 ##  }
245 ##}
246
247
248 put_fill(aliases, string)
249 FILE *aliases;
250 register char *string;
251 {
252     register char *c;
253     register int lwid;
254     register int wwid;
255
256     if (*string == 0) return;
257     fputs("#  ", aliases);
258     lwid = 3;
259
260     while (1) {
261         while (*string && *string == ' ') string++;
262         c = (char *)index(string, ' ');
263         if (c == 0) {
264             wwid = strlen(string);
265         } else {
266             wwid = c - string;
267             *c = 0;
268         }
269
270         if ((lwid + wwid) > ML_WID) {
271             fputs("\n#  ", aliases);
272             lwid = 3;
273             fputs(string, aliases);
274         } else {
275             fputs(string, aliases);
276         }
277
278         if (c == (char *)0) break;
279         /* add a space after the word */
280         (void) fputc(' ', aliases);
281         wwid++;
282         lwid += wwid;
283         string += wwid;
284         /* add another if after a period */
285         if (*--c == '.') {
286             (void) fputc(' ', aliases);
287             lwid++;
288         }
289     }
290
291     (void) fputc('\n', aliases);
292 }
This page took 0.065655 seconds and 3 git commands to generate.