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