]> andersk Git - moira.git/blob - regtape/employee.pc
Added a command-line arg, to allow the administrator to load only one
[moira.git] / regtape / employee.pc
1 /* $Header$
2  */
3
4 #include <stdio.h>
5 #include <string.h>
6 #include <ctype.h>
7 #include <sys/time.h>
8 #include <moira.h>
9 #include <moira_site.h>
10 EXEC SQL INCLUDE sqlca;
11
12
13 #define WHO 11859               /* root */
14 #define PROG "emp-tape"
15
16 #define MAX_ID_VALUE    31999
17 #define MIN_ID_VALUE    101
18
19 /* File format is:
20
21 0-8     id number
22 9-38    name
23 39-62   office address
24 63-74   phone1
25 75-86   phone2
26 87-106  dept
27 107-156 title
28 157-186 username
29 187-241 host
30
31 */
32
33 #define LOC_ID 0
34 #define LOC_NAME 9
35 #define LOC_OFFICE 39
36 #define LOC_PHONE 63
37 #define LOC_PHONE2 75
38 #define LOC_DEPT 87
39 #define LOC_TITLE 107
40 #define LOC_USERNAME 157
41 #define LOC_HOST 187
42
43 #define LEN_ID 9
44 #define LEN_NAME 30
45 #define LEN_OFFICE 24
46 #define LEN_PHONE 12
47 #define LEN_PHONE2 12
48 #define LEN_DEPT 20
49 #define LEN_TITLE 50
50 #define LEN_USERNAME 30
51 #define LEN_HOST 55
52
53
54 struct entry {
55     char *name;
56     char *last;
57     char *first;
58     char *middle;
59     char *title;
60     char *class;
61     char *id;
62     char *eid;
63     char *dept;
64     char *address;
65     char *phone;
66     char *phone2;
67     int highid;
68 };
69
70
71 char *whoami;
72 int newfinger = 0;
73
74 #define sqlfail() (sqlca.sqlcode && sqlca.sqlcode != 1403)
75 #define SQL_DUPLICATE -2112
76
77
78 main(argc, argv)
79 int argc;
80 char **argv;
81 {
82     FILE *in;
83     struct entry *e, *get_next_entry();
84     int i, wait = 0;
85     char buf[BUFSIZ], *file = NULL;
86 EXEC SQL BEGIN DECLARE SECTION;
87     char *db="moira";
88 EXEC SQL END DECLARE SECTION;
89
90     whoami = strrchr(argv[0], '/');
91     if (whoami)
92       whoami++;
93     else
94       whoami = argv[0];
95
96     setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
97     setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
98
99     for (i = 1; i < argc; i++) {
100         if (!strcmp(argv[i], "-w"))
101           wait++;
102         else if (!strcmp(argv[i], "-D"))
103           setenv("ING_SET", "set printqry");
104         else if (!strcmp(argv[i], "-n"))
105           newfinger++;
106         else if (file != NULL)
107           fprintf(stderr, "Usage: %s [-w] [-D] [-n] inputfile\n", whoami);
108         else
109           file = argv[i];
110     }
111
112     in = fopen(file, "r");
113     if (in == NULL) {
114         fprintf(stderr, "Unable to open %s for input\n", file);
115         exit(1);
116     }
117
118     initialize_sms_error_table();
119
120     EXEC SQL CONNECT :db IDENTIFIED BY :db;
121     if (sqlca.sqlcode != 0) {
122         dbmserr("opening database", sqlca.sqlcode);
123         exit(1);
124     }
125
126     while (e = get_next_entry(in)) {
127     again:
128         process_entry(e);
129         EXEC SQL COMMIT WORK;
130         if (sqlca.sqlcode != 0) {
131           dbmserr("committing work", sqlca.sqlcode);
132           exit(1);
133         }
134         if (wait) {
135             printf("Next");
136             fflush(stdout);
137             gets(buf);
138         }
139     }
140
141     exit(0);
142 }
143
144
145 char *substr(buf, key)
146 char *buf;
147 char *key;
148 {
149     int l;
150
151     for (l = strlen(key); *buf; buf++)
152       if (!strncmp(buf, key, l))
153         return(buf);
154     return(NULL);
155 }
156
157
158 struct entry *get_next_entry(in)
159 FILE *in;
160 {
161     static struct entry e;
162     static char buf[BUFSIZ], mid[16], eid[16];
163     static char name[LEN_NAME+1], sname[LEN_NAME+1], id[LEN_ID+1];
164     static char office[LEN_OFFICE+1], phone[LEN_PHONE+1], phone2[LEN_PHONE2+1];
165     static char dept[LEN_DEPT+1], title[LEN_TITLE+1], username[LEN_USERNAME+1];
166     static char host[LEN_HOST+1];
167     int ends_sr, ends_jr, ends_iii, ends_iv, ends_ii, ends_v;
168     char *p;
169
170     if (fgets(buf, sizeof(buf), in) == NULL)
171       return((struct entry *)NULL);
172
173     strncpy(id, &buf[LOC_ID], LEN_ID); id[LEN_ID] = 0;
174     strncpy(name, &buf[LOC_NAME], LEN_NAME); name[LEN_NAME] = 0;
175     strncpy(office, &buf[LOC_OFFICE], LEN_OFFICE); office[LEN_OFFICE] = 0;
176     strncpy(phone, &buf[LOC_PHONE], LEN_PHONE); phone[LEN_PHONE] = 0;
177     strncpy(phone2, &buf[LOC_PHONE2], LEN_PHONE2); phone2[LEN_PHONE2] = 0;
178     strncpy(dept, &buf[LOC_DEPT], LEN_DEPT); dept[LEN_DEPT] = 0;
179     strncpy(title, &buf[LOC_TITLE], LEN_TITLE); title[LEN_TITLE] = 0;
180     strncpy(username, &buf[LOC_USERNAME], LEN_USERNAME); username[LEN_USERNAME] = 0;
181     strncpy(host, &buf[LOC_HOST], LEN_HOST); host[LEN_HOST] = 0;
182
183     strcpy(sname, name);
184     e.name = strtrim(sname);
185     p = strchr(name, ',');
186     if (p)
187       *p = 0;
188     e.last = strtrim(name);
189     if (p) {
190         p++;
191         while (isspace(*p))
192           p++;
193         e.first = p;
194         if (p = strchr(e.first, ' ')) {
195             *p = 0;
196             e.first = strtrim(e.first);
197             e.middle = strtrim(p + 1);
198         } else {
199             e.first = strtrim(e.first);
200             e.middle = "";
201         }
202     } else {
203         e.first = "";
204         e.middle = "";
205     }
206     ends_sr = ends_jr = ends_iii = ends_iv = ends_ii = ends_v = 0;
207     LookForSt(e.last);
208     LookForO(e.last);
209     LookForJrAndIII(e.last, &ends_sr, &ends_jr, &ends_iii, &ends_iv,
210                     &ends_ii, &ends_v);
211     LookForJrAndIII(e.first, &ends_sr, &ends_jr, &ends_iii, &ends_iv,
212                     &ends_ii, &ends_v);
213     FixCase(e.last);
214     FixCase(e.first);
215     FixCase(e.middle);
216
217     e.id = id;
218     e.eid = eid;
219     EncryptID(e.eid, e.id, e.first, e.last);
220
221     e.address = strtrim(office);
222     e.phone = strtrim(phone);
223     e.phone2 = strtrim(phone2);
224     e.dept = strtrim(dept);
225     e.title = strtrim(title);
226
227     e.class = "MITS";
228     e.highid = 0;
229     if (substr(e.title, "PROF") || substr(e.title, "LECTURE"))
230         e.class = "FACULTY";
231     if (!strcmp(e.dept, "LINCOLN LAB")) {
232         e.class = "LINCOLN";
233         e.highid = 1;
234     }
235
236     return(&e);
237 }
238
239
240 process_entry(e)
241 struct entry *e;
242 {
243     int changed, nochange, encrypted;
244     char buf[BUFSIZ], *from, *to;
245     EXEC SQL BEGIN DECLARE SECTION;
246     char *first, *last, *middle, *eid, *sid, *name, *title, *phone2, *rdept, *rtitle;
247     char *raddr, *rhphone, *rophone, *prog;
248     char class[9], oaddr[25], ophone[17], dept[128], dfirst[17], dlast[17], dmiddle[17];
249     int id, status, who;
250     EXEC SQL END DECLARE SECTION;
251
252     who = WHO;
253     prog = PROG;
254     first = e->first;
255     if (strlen(first) > 16)
256       first[16] = 0;
257     last = e->last;
258     if (strlen(last) > 16)
259       last[16] = 0;
260     middle = e->middle;
261     eid = e->eid;
262     sid = e->id;
263     id = 0;
264     encrypted = 0;
265
266     /* Get user info */
267     EXEC SQL SELECT users_id, first, last, middle, type, office_addr, office_phone, department, status
268       INTO :id, :dfirst, :dlast, :dmiddle, :class, :oaddr, :ophone, :dept, :status
269       FROM users
270       WHERE clearid = :sid;
271     if (sqlfail()) {
272         if (sqlca.sqlcode == SQL_DUPLICATE) {
273             com_err(whoami, 0, "duplicate ID number %s on user %s %s", sid, first, last);
274             return;
275         } else
276           sqlexit();
277     }
278     if (id == 0) {
279         EXEC SQL SELECT users_id, first, last, middle, type, office_addr, office_phone, department, status
280           INTO :id, :dfirst, :dlast, :dmiddle, :class, :oaddr, :ophone, :dept, :status
281           FROM users
282           WHERE last = :last and first = :first and clearid = :eid;
283         if (sqlfail() && sqlca.sqlcode != SQL_DUPLICATE) {
284               sqlexit();
285         }
286         encrypted++;
287         if (id == 0) {
288             newuser(e);
289             return;
290         }
291     }
292
293     /* Update class/state if necessary.  (Exclude several spacial cases.) */
294     if (strcmp(e->class, strtrim(class)) &&
295         strcmp(class, "STAFF") && strcmp(class, "SIPBMEM") &&
296         strcmp(class, "KNIGHT")) {
297         com_err(whoami, 0, "updating class for %s %s from %s to %s",
298                 first, last, class, e->class);
299         if (status == US_NOT_ALLOWED)
300           status = US_NO_LOGIN_YET;
301         if (status == US_ENROLL_NOT_ALLOWED)
302           status = US_ENROLLED;
303         strcpy(class, e->class);
304         EXEC SQL UPDATE users
305           SET type = NVL(:class,CHR(0)), status = :status, modtime = SYSDATE,
306                 modby = :who, modwith = :prog
307           WHERE users_id = :id;
308         if (sqlca.sqlcode != 0) {
309           dbmserr("updating user", sqlca.sqlcode);
310           exit(1);
311         }
312     }
313
314     /* Update name if necessary */
315     if (strcmp(first, strtrim(dfirst)) ||
316         strcmp(last, strtrim(dlast)) ||
317         strcmp(middle, strtrim(dmiddle))) {
318         com_err(whoami, 0, "updating real name for %s %s", first, last);
319         EXEC SQL UPDATE users
320           SET first = NVL(:first,CHR(0)), last = NVL(:last,CHR(0)),
321           middle = NVL(:middle,CHR(0)), modby = :who, modwith = :prog,
322           modtime = SYSDATE
323           WHERE users_id = :id;
324         if (sqlca.sqlcode != 0) {
325           dbmserr("updating name", sqlca.sqlcode);
326           exit(1);
327         }
328     }
329
330     changed = nochange = 0;
331     if (encrypted) changed++;
332     strcpy(buf, e->address);
333     while (to = strchr(buf, ','))
334       *to = ';';
335     while (to = strchr(buf, ':'))
336       *to = ';';
337     if (newfinger) {
338         if (oaddr[0] == ' ' && buf[0]) {
339             strncpy(oaddr, buf, 16);
340             oaddr[16] = 0;
341             changed++;
342         } else if (strncmp(strtrim(oaddr), buf, 15))
343           nochange++;
344     } else {
345         if (strncmp(strtrim(oaddr), buf, 15))
346           changed++;
347         strncpy(oaddr, buf, 16);
348         oaddr[16] = 0;
349     }
350     from = e->phone;
351     to = buf;
352     while (*from) {
353         if (isdigit(*from))
354           *to++ = *from;
355         from++;
356     }
357     *to = 0;
358     if (newfinger) {
359         if (ophone[0] == ' ') {
360             strncpy(ophone, buf, 16);
361             ophone[16] = 0;
362         } else if (strncmp(strtrim(ophone), buf, 11))
363           nochange++;
364     } else {
365         if (strncmp(strtrim(ophone), buf, 11))
366           changed++;
367         strncpy(ophone, buf, 16);
368         ophone[16] = 0;
369     }
370     FixCase(e->dept);
371     FixCase(e->title);
372     if (newfinger) {
373         if (dept[0] == ' ') {
374             strncpy(dept, e->dept, 12);
375             dept[12] = 0;
376         } else if (strncmp(strtrim(dept), e->dept, 11))
377           nochange++;
378     } else {
379         if (strncmp(strtrim(dept), e->dept, 11))
380           changed++;
381         strncpy(dept, e->dept, 12);
382         dept[12] = 0;
383     }
384     sid = e->id;
385     name = e->name;
386     rdept = e->dept;
387     rtitle = e->title;
388     raddr = e->address;
389     rhphone = e->phone;
390     rophone = e->phone2;
391     if (changed) {
392         com_err(whoami, 0, "updating finger for %s %s", first, last);
393         EXEC SQL UPDATE users
394           SET office_addr = NVL(:oaddr,CHR(0)),
395           office_phone = NVL(:ophone,CHR(0)), department = NVL(:dept,CHR(0)),
396           fmodtime = SYSDATE, fmodby = :who, fmodwith = :prog,
397           xname = NVL(:name,CHR(0)), xdept = NVL(:rdept,CHR(0)),
398           xtitle = NVL(:rtitle,CHR(0)), xaddress = NVL(:raddr,CHR(0)),
399           xphone1 = NVL(:rhphone,CHR(0)), xphone2 = NVL(:rophone,CHR(0)),
400           xmodtime = SYSDATE, clearid = NVL(:sid,CHR(0))
401           WHERE users_id = :id;
402         if (sqlca.sqlcode != 0) {
403           dbmserr(NULL, sqlca.sqlcode);
404           exit(1);
405         }
406     } else {
407         EXEC SQL UPDATE users
408           SET xname = NVL(:name,CHR(0)), xdept = NVL(:rdept,CHR(0)),
409           xtitle = NVL(:rtitle,CHR(0)), xaddress = NVL(:raddr,CHR(0)),
410           xphone1 = NVL(:rhphone,CHR(0)), xphone2 = NVL(:rophone,CHR(0)),
411           xmodtime = SYSDATE, clearid = NVL(:sid,CHR(0))
412           WHERE users_id = :id;
413         if (sqlca.sqlcode != 0) {
414           dbmserr(NULL, sqlca.sqlcode);
415           exit(1);
416         }
417     }
418 }
419
420
421 newuser(e)
422 struct entry *e;
423 {
424     char *from, *to;
425     EXEC SQL BEGIN DECLARE SECTION;
426     int id, uid, st, who;
427     char *last, *first, *class, *middle, login[9], *sid, fullname[65], *prog;
428     char oaddr[81], ophone[17], dept[128], *name, *title, phone2[17];
429     char *rdept, *rhphone, *rophone;
430     EXEC SQL END DECLARE SECTION;
431
432     who = WHO;
433     prog = PROG;
434     strncpy(oaddr, e->address, 16);
435     oaddr[16] = 0;
436     while (to = strchr(oaddr, ','))
437       *to = ';';
438     while (to = strchr(oaddr, ':'))
439       *to = ';';
440     from = e->phone;
441     to = ophone;
442     while (*from) {
443         if (isdigit(*from))
444           *to++ = *from;
445         from++;
446     }
447     *to = 0;
448     FixCase(e->dept);
449     strncpy(dept, e->dept, 12);
450     dept[12] = 0;
451     
452     id = set_next_users_id(0);
453     uid = set_next_uid(e->highid);
454     sprintf(login, "#%d", uid);
455     last = e->last;
456     first = e->first;
457     middle = e->middle;
458     class = e->class;
459     if (*middle)
460       sprintf(fullname, "%s %s %s", first, middle, last);
461     else
462       sprintf(fullname, "%s %s", first, last);
463     st = US_NO_LOGIN_YET;
464
465     sid = e->id;
466     name = e->name;
467     rdept = e->dept;
468     title = e->title;
469     rhphone = e->phone;
470     rophone = e->phone2;
471
472     EXEC SQL INSERT INTO users
473       (login, users_id, unix_uid, shell, last, first, middle, status,
474        clearid, type, modtime, modby, modwith, fullname, office_addr,
475        office_phone, department, fmodtime, fmodby, fmodwith,
476        potype, xname, xdept, xtitle, xaddress, xphone1, xphone2, xmodtime)
477       VALUES (:login, :id, :uid, '/bin/athena/tcsh',
478               NVL(:last,CHR(0)), NVL(:first,CHR(0)), NVL(:middle,CHR(0)),
479               :st, NVL(:sid,CHR(0)), NVL(:class,CHR(0)), SYSDATE, :who, :prog,
480               NVL(:fullname,CHR(0)), NVL(:oaddr,CHR(0)), NVL(:ophone,CHR(0)),
481               NVL(:dept,CHR(0)), SYSDATE, :who, :prog, 'NONE',
482               NVL(:name,CHR(0)), NVL(:rdept,CHR(0)), NVL(:title,CHR(0)),
483               NVL(:oaddr,CHR(0)), NVL(:rhphone,CHR(0)), NVL(:rophone,CHR(0)),
484               SYSDATE);
485     if (sqlca.sqlcode != 0) {
486       dbmserr("adding user", sqlca.sqlcode);
487       exit(1);
488     } else
489       com_err(whoami, 0, "adding user %s %s", e->first, e->last);
490 }
491
492
493 set_next_users_id(limit)
494     int limit;
495 {
496     EXEC SQL BEGIN DECLARE SECTION;
497     int rowcount, flag, value, retval;
498     EXEC SQL END DECLARE SECTION;
499
500     EXEC SQL SELECT value INTO :value FROM numvalues 
501       WHERE name = 'users_id';
502     if (sqlfail()) sqlexit();
503     if (sqlca.sqlerrd[2] != 1) {
504         EXEC SQL ROLLBACK;
505         com_err(whoami, MR_INTERNAL, "values table inconsistancy");
506         exit(1);
507     }
508
509     flag = 0;
510     EXEC SQL SELECT users_id INTO :flag FROM users
511       WHERE users_id = :value;
512     if (sqlfail()) sqlexit();
513     if (sqlca.sqlerrd[2] == 0)
514       flag = 0;
515     while (flag) {
516         value++;
517         if (limit && value > MAX_ID_VALUE)
518             value = MIN_ID_VALUE;
519         flag = 0;
520         EXEC SQL SELECT users_id INTO :flag FROM users 
521           WHERE users_id = :value;
522         if (sqlfail()) sqlexit();
523         if (sqlca.sqlerrd[2] == 0)
524           flag = 0;
525     }
526
527     retval = value++;
528     if (limit && value > MAX_ID_VALUE)
529       value = MIN_ID_VALUE;
530     EXEC SQL UPDATE numvalues SET value = :value
531       WHERE name = 'users_id';
532     if (sqlca.sqlcode != 0) {
533         dbmserr("assigning ID", sqlca.sqlcode);
534         exit(1);
535     }
536     return(retval);
537 }
538
539 set_next_uid(high)
540     int high;
541 {
542     EXEC SQL BEGIN DECLARE SECTION;
543     int rowcount, flag, value, retval;
544     char *name;
545     EXEC SQL END DECLARE SECTION;
546
547     if (high)
548         name = "high_uid";
549     else
550         name = "unix_uid";
551
552     EXEC SQL SELECT value INTO :value FROM numvalues 
553       WHERE name = :name;
554     if (sqlfail()) sqlexit();
555     if (sqlca.sqlerrd[2] != 1) {
556         EXEC SQL ROLLBACK;
557         com_err(whoami, MR_INTERNAL, "values table inconsistancy");
558         exit(1);
559     }
560
561     flag = 0;
562     EXEC SQL SELECT unix_uid INTO :flag FROM users WHERE unix_uid = :value;
563     if (sqlfail()) sqlexit();
564     if (sqlca.sqlerrd[2] == 0)
565       flag = 0;
566     while (flag) {
567         value++;
568         if (!high && value > MAX_ID_VALUE)
569             value = MIN_ID_VALUE;
570         flag = 0;
571         EXEC SQL SELECT unix_uid INTO :flag FROM users WHERE unix_uid = :value;
572         if (sqlfail()) sqlexit();
573         if (sqlca.sqlerrd[2] == 0)
574           flag = 0;
575     }
576
577     retval = value++;
578     if (!high && value > MAX_ID_VALUE)
579       value = MIN_ID_VALUE;
580     EXEC SQL UPDATE numvalues SET value = :value WHERE name = :name;
581     if (sqlca.sqlcode != 0) {
582         dbmserr("assigning ID", sqlca.sqlcode);
583         exit(1);
584     }
585     return(retval);
586 }
587
588
589 sqlexit()
590 {
591     dbmserr(NULL, sqlca.sqlcode);
592     EXEC SQL ROLLBACK WORK;
593     exit(1);
594 }
595
596 dbmserr(char *where, int what)
597 {
598   char err_msg[256];
599   int bufsize=256, msglength=0;
600
601   sqlglm(err_msg, &bufsize, &msglength);
602   err_msg[msglength]=0;
603
604   if(where)
605     com_err(whoami, 0, "DBMS error %swhile %s", err_msg, where);
606   else
607     com_err(whoami, 0, "DBMS error %s", err_msg);
608 }
This page took 0.144723 seconds and 5 git commands to generate.