]> andersk Git - moira.git/blame - gen/mailhub.qc
removed references to admin; fixed up depend
[moira.git] / gen / mailhub.qc
CommitLineData
63812b62 1/* $Header$
2 *
3 * This generates the /usr/lib/aliases file for the mailhub, and an additional
4 * information file for helper programs that send back error messages.
5 *
6 * (c) Copyright 1988 by the Massachusetts Institute of Technology.
7 * For copying and distribution information, please see the file
8 * <mit-copyright.h>.
9 */
10
11#include <mit-copyright.h>
12#include <stdio.h>
13#include <string.h>
14#include <ctype.h>
15#include <sms.h>
16#include <sms_app.h>
17#include <sys/types.h>
18#include <sys/stat.h>
19#include <sys/time.h>
20
21extern int errno;
22char *whoami = "aliases.gen";
23char *ingres_date_and_time();
24char *divide = "################################################################\n";
25
26
27main(argc, argv)
28int argc;
29char **argv;
30{
31 long tm = time(NULL);
32 FILE *out= stdout;
33 char filename[64], *targetfile;
34 struct stat sb;
35## int flag;
36## char *filetime;
37 int ingerr();
38
39 IIseterr(ingerr);
40## ingres sms
41## set lockmode session where level = table
42
43 if (argc == 2) {
44 if (stat(argv[1], &sb) == 0) {
45 filetime = ingres_date_and_time(sb.st_mtime);
46## retrieve (flag = int4(interval("min",tblstats.modtime - filetime)))
47## where tblstats.table = "users"
48 if (flag < 0) {
49 fprintf(stderr, "File %s does not need to be rebuilt.\n",
50 argv[1]);
51 exit(SMS_NO_CHANGE);
52 }
53 }
54 targetfile = argv[1];
55 sprintf(filename, "%s~", targetfile);
56 if ((out = fopen(filename, "w")) == NULL) {
57 fprintf(stderr, "unable to open %s for output\n", filename);
58 exit(SMS_OCONFIG);
59 }
60 } else if (argc != 1) {
61 fprintf(stderr, "usage: %s [outfile]\n", argv[0]);
62 exit(SMS_ARGS);
63 }
64
65 fprintf(out, "%s\n# Aliases File Extract of %s", divide, ctime(&tm));
66 fprintf(out, "# This file is automatically generated, do not edit it directly.\n%s\n\n", divide);
67
68## begin transaction
69 get_info();
70## end transaction
71## exit
72
73 fprintf(stderr, "Sorting Info\n");
74 sort_info();
75
76 fprintf(stderr, "Dumping information\n");
77 do_people(out);
78
79 fprintf(out, "\n%s\n# End of aliases file\n", divide);
80
81 if (fclose(out)) {
82 perror("close failed");
83 exit(SMS_CCONFIG);
84 }
85
86 if (argc == 2)
87 fix_file(targetfile);
88 exit(SMS_SUCCESS);
89}
90
91
92/*
93 * ingerr: (supposedly) called when Ingres indicates an error.
94 * I have not yet been able to get this to work to intercept a
95 * database open error.
96 */
97#define INGRES_DEADLOCK 4700
98
99static int ingerr(num)
100 int *num;
101{
102 char buf[256];
103 int ingres_errno;
104
105 switch (*num) {
106 case INGRES_DEADLOCK:
107 ingres_errno = SMS_DEADLOCK;
108 break;
109 default:
110 ingres_errno = SMS_INGRES_ERR;
111 }
112 com_err(whoami, SMS_INGRES_ERR, " code %d\n", *num);
113 critical_alert("DCM", "Alias build encountered INGRES ERROR %d", *num);
114 exit(ingres_errno);
115}
116
117struct hash *users, *machines, *strings, *names;
118struct user {
119 char *login;
120 unsigned short status;
121 char *first;
122 char *last;
123 char mi;
124 char *fullname;
125 char *addr;
126 char *pobox;
127 int id;
128};
129#define MAXIDS 10
130struct names {
131 char *name;
132 struct names *next;
133 int ids[MAXIDS];
134 short count;
135};
136
137
138get_info()
139##{
140## int id, pid, bid, stat, cnt;
141## char name[129], type[9], fname[17], mname[17], lname[17], year[9];
142## char dept[13], oaddr[17], ophone[13], buf[257], haddr[17], hphone[13];
143 char *s, *depttmp, *savedat(), *office_addr, *office_phone;
144 register struct user *u;
145
146 /* get locks */
147## retrieve (buf = users.modtime) where users.users_id = 0
148
149 cnt = 0;
150 machines = create_hash(1000);
151## retrieve (id = machine.mach_id, name = machine.#name) {
152 if (s = index(name, '.'))
153 *s = 0;
154 sprintf(buf, "%s.LOCAL", name);
155 hash_store(machines, id, strsave(buf));
156 cnt++;
157## }
158 fprintf(stderr, "Loaded %d machines\n", cnt);
159
160 cnt = 0;
161 strings = create_hash(2000);
162## retrieve (id = strings.string_id, name = strings.string) {
163 hash_store(strings, id, strsave(strtrim(name)));
164 cnt++;
165## }
166 fprintf(stderr, "Loaded %d strings\n", cnt);
167
168 cnt = 0;
169 users = create_hash(15000);
170## range of u is users
171## retrieve (id = u.users_id, name = u.login, stat = u.status,
172## fname = u.first, mname = u.middle, lname = u.last,
173## year = u.mit_year, dept = u.mit_dept,
174## oaddr = u.office_addr, ophone = u.office_phone,
175## haddr = u.home_addr, hphone = u.home_phone,
176## type = u.potype, pid = u.pop_id, bid = u.box_id) {
177 u = (struct user *) malloc(sizeof(struct user));
178 u->status = stat;
179 u->login = strsave(strtrim(name));
180 u->first = strsave(strtrim(fname));
181 u->last = strsave(strtrim(lname));
182 if (mname[0] != ' ')
183 u->mi = mname[0];
184 else
185 u->mi = 0;
186 if (atoi(year) > 1900)
187 depttmp = "Undergraduate";
188 else
189 depttmp = strtrim(dept);
190 sprintf(buf, "%s, %s %c; ID: %s; Dept: %s %s",
191 u->last, u->first, u->mi ? u->mi : ' ',
192 u->login, depttmp, strtrim(year));
193 u->fullname = strsave(buf);
194
195 office_addr = strtrim(oaddr);
196 if (*office_addr == 0) {
197 office_addr = strtrim(haddr);
198 }
199 office_phone = strtrim(ophone);
200 if (*office_phone == 0) {
201 office_phone = strtrim(hphone);
202 }
203
204 if (*office_addr) {
205 sprintf(buf, "%s; %s",
206 office_addr, office_phone);
207 u->addr = strsave(buf);
208 } else
209 u->addr = NULL;
210
211 u->id = 0;
212 u->pobox = (char *) NULL;
213 if (stat != 3) {
214 if (type[0] == 'P') {
215 if (s = hash_lookup(machines, pid)) {
216 sprintf(buf, "%s@%s", strtrim(name), s);
217 u->pobox = strsave(buf);
218 } else {
219 fprintf(stderr,
220 "User %s's pobox is on a missing machine!\n",
221 u->login);
222 }
223 } else if (type[0] == 'S') {
224 if ((u->pobox = hash_lookup(strings, bid)) == NULL)
225 fprintf(stderr,
226 "User %s's pobox string is missing!\n",
227 u->login);
228 }
229 }
230 hash_store(users, id, u);
231 cnt++;
232## }
233 fprintf(stderr, "Loaded %d users\n", cnt);
234##}
235
236
237char *savedat(s)
238register char *s;
239{
240 char buf[256];
241 register char *ss = &buf[0];
242 char *lastchar = NULL;
243
244 while (isspace(*s))
245 s++;
246 if (*s == 0)
247 return("");
248
249 for (; *s; s++) {
250 if (isspace(*s)) {
251 *ss++ = '_';
252 } else if (islower(*s)) {
253 *ss++ = toupper(*s);
254 lastchar = ss;
255 } else {
256 *ss++ = *s;
257 lastchar = ss;
258 }
259 }
260 if (lastchar)
261 *lastchar = 0;
262 *ss = 0;
263 if ((ss = (char *) malloc(strlen(buf)+1)) == NULL) {
264 fprintf(stderr, "ran out of memory saving data\n");
265 exit(1);
266 }
267 strcpy(ss, buf);
268 return(ss);
269}
270
271
272void insert_names(id, u, dummy)
273int id;
274struct user *u;
275int dummy;
276{
277 char buffer[256];
278
279 if (u->status != 0 && u->status != 4)
280 insert_name(u->login, id);
281 insert_name(u->last, id);
282 sprintf(buffer, "%s_%s", u->first, u->last);
283 insert_name(buffer, id);
284 if (u->mi) {
285 sprintf(buffer, "%s_%c_%s", u->first, u->mi, u->last);
286 insert_name(buffer, id);
287 }
288}
289
290int incount = 0;
291
292insert_name(s, id)
293char *s;
294int id;
295{
296 int code;
297 register struct names *ns;
298 register int count;
299 register struct idblock *ra;
300
301 incount++;
302 code = hashstr(s);
303 ns = (struct names *) hash_lookup(names, code);
304 if (ns == NULL) {
305 if ((ns = (struct names *) malloc(sizeof(struct names))) == NULL) {
306 fprintf(stderr, "ran out of memory inserting name (sorting)\n");
307 exit(1);
308 }
309 ns->name = strsave(s);
310 ns->count = 1;
311 ns->ids[0] = id;
312 hash_store(names, code, ns);
313 return;
314 }
315 if (strcasecmp(ns->name, s)) {
316 while (ns->next) {
317 ns = ns->next;
318 if (!strcasecmp(ns->name, s))
319 goto foundns;
320 }
321 if ((ns->next = (struct names *)malloc(sizeof(struct names))) == NULL) {
322 fprintf(stderr, "ran out of memory insterting name (sorting)\n");
323 exit(1);
324 }
325 ns = ns->next;
326 ns->name = strsave(s);
327 ns->count = 1;
328 ns->ids[0] = id;
329 hash_store(names, code, ns);
330 return;
331 }
332 foundns:
333 if (ns->count < MAXIDS - 1) {
334 ns->ids[ns->count++] = id;
335 return;
336 }
337 ns->count++;
338}
339
340
341int hashstr(s)
342register char *s;
343{
344 register int result;
345 register int c;
346
347 for (result = 0; *s; s++) {
348 if (isupper(*s))
349 c = tolower(*s);
350 else
351 c = *s;
352/* result = result * 31 + *s; */
353 result = (result << 5) - result + c - 'a';
354 }
355 return(result < 0 ? -result : result);
356}
357
358
359sort_info()
360{
361 names = create_hash(10000);
362 hash_step(users, insert_names, NULL);
363 fprintf(stderr, "Inserted %d names\n", incount);
364}
365
366
367static long offset;
368static FILE *msgs;
369
370output_data(dummy, nms, out)
371int dummy;
372struct names *nms;
373FILE *out;
374{
375 register struct names *ns;
376 register struct user *u;
377 int i;
378
379 incount++;
380 for (ns = nms; ns; ns = ns->next) {
381 if (strlen(ns->name) < 2)
382 continue;
383 if (ns->count == 1) {
384 u = (struct user *) hash_lookup(users, ns->ids[0]);
385 if (u->pobox) {
386 fprintf(out, "%s: %s\n", ns->name, u->pobox);
387 continue;
388 }
389 if (u->id == 0) {
390 u->id = offset;
391 if (*u->addr) {
392 fprintf(msgs, "%s\n %s\n\001", u->fullname, u->addr);
393 offset += strlen(u->fullname) + strlen(u->addr) + 5;
394 } else {
395 fprintf(msgs, "%s\n\001", u->fullname);
396 offset += strlen(u->fullname) + 2;
397 }
398 }
399 fprintf(out, "%s: +%d+@no_po_box\n", ns->name, u->id);
400 } else if (ns->count < 10) {
401 fprintf(out, "%s: +%d+@ambiguous\n", ns->name, offset);
402 for (i = 0; i < ns->count; i++) {
403 u = (struct user *) hash_lookup(users, ns->ids[i]);
404 fprintf(msgs, "%s\n", u->fullname);
405 offset += strlen(u->fullname) + 1;
406 }
407 fputs("\001", msgs);
408 offset++;
409 } else {
410 fprintf(out, "%s: +%d+@too_many\n", ns->name, ns->count);
411 }
412 }
413}
414
415
416do_people(out)
417FILE *out;
418{
419 incount = 0;
420 msgs = fopen("aliases.strings", "w");
421 fputs(msgs, "\001");
422 offset = 1;
423
424 hash_step(names, output_data, out);
425 fputs("\n", msgs);
426 fclose(msgs);
427 fprintf(stderr, "Output %d entries\n", incount);
428}
This page took 0.099588 seconds and 5 git commands to generate.