]> andersk Git - moira.git/blame - regtape/employee.pc
second code style cleanup: void/void * usage, proper #includes. try to
[moira.git] / regtape / employee.pc
CommitLineData
7ac48069 1/* $Id$
2 *
3 * Load data into Moira from Personnel Office data file
4 *
5 * Copyright (C) 1990-1998 by the Massachusetts Institute of Technology
6 * For copying and distribution information, please see the file
7 * <mit-copyright.h>.
469f80df 8 */
9
7ac48069 10#include <mit-copyright.h>
932028de 11#include <moira.h>
12#include <moira_site.h>
7ac48069 13
14#include <ctype.h>
15#include <stdio.h>
16#include <string.h>
17
02cd9ede 18EXEC SQL INCLUDE sqlca;
7ac48069 19extern void sqlglm(char *, unsigned int *, unsigned int *);
469f80df 20
7ac48069 21RCSID("$Header$");
469f80df 22
02cd9ede 23#define WHO 11859 /* root */
24#define PROG "emp-tape"
469f80df 25
397e9044 26#define MAX_ID_VALUE 31999
469f80df 27#define MIN_ID_VALUE 101
28
29/* File format is:
30
310-8 id number
329-38 name
3339-62 office address
3463-74 phone1
3575-86 phone2
3687-106 dept
37107-156 title
38157-186 username
39187-241 host
40
41*/
42
43#define LOC_ID 0
44#define LOC_NAME 9
45#define LOC_OFFICE 39
46#define LOC_PHONE 63
47#define LOC_PHONE2 75
48#define LOC_DEPT 87
49#define LOC_TITLE 107
50#define LOC_USERNAME 157
51#define LOC_HOST 187
52
53#define LEN_ID 9
a6e9fead 54#define LEN_NAME 30
55#define LEN_OFFICE 24
469f80df 56#define LEN_PHONE 12
57#define LEN_PHONE2 12
a6e9fead 58#define LEN_DEPT 20
59#define LEN_TITLE 50
60#define LEN_USERNAME 30
469f80df 61#define LEN_HOST 55
62
63
64struct entry {
5eaef520 65 char *name;
66 char *last;
67 char *first;
68 char *middle;
69 char *title;
70 char *class;
71 char *id;
72 char *eid;
73 char *dept;
74 char *address;
75 char *phone;
76 char *phone2;
77 int highid;
469f80df 78};
79
7ac48069 80struct entry *get_next_entry(FILE *in);
81void process_entry(struct entry *e);
82void newuser(struct entry *e);
83int set_next_users_id(int limit);
84int set_next_uid(int high);
85void sqlexit(void);
86void dbmserr(char *where, int what);
469f80df 87
88char *whoami;
89int newfinger = 0;
90
9f5e5c05 91#define sqlfail() (sqlca.sqlcode && sqlca.sqlcode != 1403)
bd22473a 92#define SQL_DUPLICATE -2112
3e77c6a3 93
469f80df 94
5eaef520 95int main(int argc, char **argv)
02cd9ede 96{
5eaef520 97 FILE *in;
7ac48069 98 struct entry *e;
5eaef520 99 int i, wait = 0;
100 char buf[BUFSIZ], *file = NULL;
101 EXEC SQL BEGIN DECLARE SECTION;
102 char *db = "moira";
103 EXEC SQL END DECLARE SECTION;
104
105 whoami = strrchr(argv[0], '/');
106 if (whoami)
107 whoami++;
108 else
109 whoami = argv[0];
110
111 setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
112 setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
113
114 for (i = 1; i < argc; i++)
115 {
116 if (!strcmp(argv[i], "-w"))
117 wait++;
5eaef520 118 else if (!strcmp(argv[i], "-n"))
119 newfinger++;
120 else if (file)
121 fprintf(stderr, "Usage: %s [-w] [-D] [-n] inputfile\n", whoami);
122 else
123 file = argv[i];
469f80df 124 }
125
5eaef520 126 in = fopen(file, "r");
127 if (!in)
128 {
129 fprintf(stderr, "Unable to open %s for input\n", file);
130 exit(1);
469f80df 131 }
132
5eaef520 133 initialize_sms_error_table();
325821e4 134
5eaef520 135 EXEC SQL CONNECT :db IDENTIFIED BY :db;
136 if (sqlca.sqlcode)
137 {
138 dbmserr("opening database", sqlca.sqlcode);
139 exit(1);
3e77c6a3 140 }
469f80df 141
5eaef520 142 while ((e = get_next_entry(in)))
143 {
5eaef520 144 process_entry(e);
145 EXEC SQL COMMIT WORK;
146 if (sqlca.sqlcode)
147 {
9f5e5c05 148 dbmserr("committing work", sqlca.sqlcode);
149 exit(1);
3e77c6a3 150 }
5eaef520 151 if (wait)
152 {
153 printf("Next");
154 fflush(stdout);
155 gets(buf);
469f80df 156 }
157 }
158
5eaef520 159 exit(0);
02cd9ede 160}
469f80df 161
5eaef520 162struct entry *get_next_entry(FILE *in)
469f80df 163{
5eaef520 164 static struct entry e;
7ac48069 165 static char buf[BUFSIZ], eid[16];
5eaef520 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))
a6e9fead 205 p++;
5eaef520 206 e.first = p;
7ac48069 207 if ((p = strchr(e.first, ' ')))
5eaef520 208 {
209 *p = '\0';
210 e.first = strtrim(e.first);
211 e.middle = strtrim(p + 1);
a6e9fead 212 }
5eaef520 213 else
214 {
215 e.first = strtrim(e.first);
216 e.middle = "";
217 }
218 }
219 else
220 {
221 e.first = "";
222 e.middle = "";
a6e9fead 223 }
5eaef520 224 ends_sr = ends_jr = ends_iii = ends_iv = ends_ii = ends_v = 0;
225 LookForSt(e.last);
226 LookForO(e.last);
7ac48069 227 LookForJrAndIII(e.last, &ends_jr, &ends_sr, &ends_ii, &ends_iii,
228 &ends_iv, &ends_v);
229 LookForJrAndIII(e.first, &ends_jr, &ends_sr, &ends_ii, &ends_iii,
230 &ends_iv, &ends_v);
5eaef520 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;
7ac48069 247 if (strstr(e.title, "PROF") || strstr(e.title, "LECTURE"))
5eaef520 248 e.class = "FACULTY";
249 if (!strcmp(e.dept, "LINCOLN LAB"))
250 {
251 e.class = "LINCOLN";
252 e.highid = 1;
64b4c6b1 253 }
469f80df 254
5eaef520 255 return &e;
469f80df 256}
257
7ac48069 258void process_entry(struct entry *e)
02cd9ede 259{
5eaef520 260 int changed, nochange, encrypted;
261 char buf[BUFSIZ], *from, *to;
262 EXEC SQL BEGIN DECLARE SECTION;
7ac48069 263 char *first, *last, *middle, *eid, *sid, *name, *rdept;
5eaef520 264 char *rtitle, *raddr, *rhphone, *rophone, *prog;
265 char class[9], oaddr[25], ophone[17], dept[128];
266 char dfirst[17], dlast[17], dmiddle[17];
267 int id, status, who;
268 EXEC SQL END DECLARE SECTION;
269
270 who = WHO;
271 prog = PROG;
272 first = e->first;
273 if (strlen(first) > 16)
274 first[16] = '\0';
275 last = e->last;
276 if (strlen(last) > 16)
277 last[16] = '\0';
278 middle = e->middle;
279 eid = e->eid;
280 sid = e->id;
281 id = 0;
282 encrypted = 0;
283
284 /* Get user info */
285 EXEC SQL SELECT users_id, first, last, middle, type, office_addr,
286 office_phone, department, status
287 INTO :id, :dfirst, :dlast, :dmiddle, :class, :oaddr,
288 :ophone, :dept, :status
289 FROM users
290 WHERE clearid = :sid;
291 if (sqlfail())
292 {
293 if (sqlca.sqlcode == SQL_DUPLICATE)
294 {
295 com_err(whoami, 0, "duplicate ID number %s on user %s %s",
296 sid, first, last);
297 return;
298 }
299 else
300 sqlexit();
3e77c6a3 301 }
5eaef520 302 if (id == 0)
303 {
304 EXEC SQL SELECT users_id, first, last, middle, type, office_addr,
305 office_phone, department, status
306 INTO :id, :dfirst, :dlast, :dmiddle, :class, :oaddr,
307 :ophone, :dept, :status
308 FROM users
309 WHERE last = :last and first = :first and clearid = :eid;
310 if (sqlfail() && sqlca.sqlcode != SQL_DUPLICATE)
311 sqlexit();
312 encrypted++;
313 if (id == 0)
314 {
315 newuser(e);
316 return;
325821e4 317 }
469f80df 318 }
325821e4 319
5eaef520 320 /* Update class/state if necessary. (Exclude several spacial cases.) */
321 if (strcmp(e->class, strtrim(class)) &&
322 strcmp(class, "STAFF") && strcmp(class, "SIPBMEM") &&
323 strcmp(class, "KNIGHT"))
324 {
325 com_err(whoami, 0, "updating class for %s %s from %s to %s",
326 first, last, class, e->class);
327 if (status == US_NOT_ALLOWED)
328 status = US_NO_LOGIN_YET;
329 if (status == US_ENROLL_NOT_ALLOWED)
330 status = US_ENROLLED;
331 strcpy(class, e->class);
332 EXEC SQL UPDATE users
333 SET type = NVL(:class, CHR(0)), status = :status, modtime = SYSDATE,
334 modby = :who, modwith = :prog
335 WHERE users_id = :id;
336 if (sqlca.sqlcode)
337 {
9f5e5c05 338 dbmserr("updating user", sqlca.sqlcode);
339 exit(1);
3e77c6a3 340 }
341 }
342
5eaef520 343 /* Update name if necessary */
344 if (strcmp(first, strtrim(dfirst)) ||
345 strcmp(last, strtrim(dlast)) ||
346 strcmp(middle, strtrim(dmiddle)))
347 {
348 com_err(whoami, 0, "updating real name for %s %s", first, last);
349 EXEC SQL UPDATE users
350 SET first = NVL(:first, CHR(0)), last = NVL(:last, CHR(0)),
351 middle = NVL(:middle, CHR(0)), modby = :who, modwith = :prog,
352 modtime = SYSDATE
353 WHERE users_id = :id;
354 if (sqlca.sqlcode)
355 {
9f5e5c05 356 dbmserr("updating name", sqlca.sqlcode);
357 exit(1);
3e77c6a3 358 }
469f80df 359 }
325821e4 360
5eaef520 361 changed = nochange = 0;
362 if (encrypted)
363 changed++;
364 strcpy(buf, e->address);
365 while ((to = strchr(buf, ',')))
366 *to = ';';
367 while ((to = strchr(buf, ':')))
368 *to = ';';
369 if (newfinger)
370 {
371 if (oaddr[0] == ' ' && buf[0])
372 {
373 strncpy(oaddr, buf, 16);
374 oaddr[16] = '\0';
469f80df 375 changed++;
5eaef520 376 }
377 else if (strncmp(strtrim(oaddr), buf, 15))
378 nochange++;
469f80df 379 }
5eaef520 380 else
381 {
382 if (strncmp(strtrim(oaddr), buf, 15))
383 changed++;
384 strncpy(oaddr, buf, 16);
385 oaddr[16] = '\0';
469f80df 386 }
5eaef520 387 from = e->phone;
388 to = buf;
389 while (*from)
390 {
391 if (isdigit(*from))
392 *to++ = *from;
393 from++;
469f80df 394 }
5eaef520 395 *to = '\0';
396 if (newfinger)
397 {
398 if (ophone[0] == ' ')
399 {
400 strncpy(ophone, buf, 16);
401 ophone[16] = '\0';
402 }
403 else if (strncmp(strtrim(ophone), buf, 11))
404 nochange++;
405 }
406 else
407 {
408 if (strncmp(strtrim(ophone), buf, 11))
409 changed++;
410 strncpy(ophone, buf, 16);
411 ophone[16] = '\0';
469f80df 412 }
5eaef520 413 FixCase(e->dept);
414 FixCase(e->title);
415 if (newfinger)
416 {
417 if (dept[0] == ' ')
418 {
419 strncpy(dept, e->dept, 12);
420 dept[12] = '\0';
421 }
422 else if (strncmp(strtrim(dept), e->dept, 11))
423 nochange++;
424 }
425 else
426 {
427 if (strncmp(strtrim(dept), e->dept, 11))
428 changed++;
429 strncpy(dept, e->dept, 12);
430 dept[12] = '\0';
431 }
432 sid = e->id;
433 name = e->name;
434 rdept = e->dept;
435 rtitle = e->title;
436 raddr = e->address;
437 rhphone = e->phone;
438 rophone = e->phone2;
439 if (changed)
440 {
441 com_err(whoami, 0, "updating finger for %s %s", first, last);
442 EXEC SQL UPDATE users
443 SET office_addr = NVL(:oaddr, CHR(0)),
444 office_phone = NVL(:ophone, CHR(0)), department = NVL(:dept, CHR(0)),
445 fmodtime = SYSDATE, fmodby = :who, fmodwith = :prog,
446 xname = NVL(:name, CHR(0)), xdept = NVL(:rdept, CHR(0)),
447 xtitle = NVL(:rtitle, CHR(0)), xaddress = NVL(:raddr, CHR(0)),
448 xphone1 = NVL(:rhphone, CHR(0)), xphone2 = NVL(:rophone, CHR(0)),
449 xmodtime = SYSDATE, clearid = NVL(:sid, CHR(0))
450 WHERE users_id = :id;
451 if (sqlca.sqlcode)
452 {
9f5e5c05 453 dbmserr(NULL, sqlca.sqlcode);
454 exit(1);
3e77c6a3 455 }
5eaef520 456 }
457 else
458 {
459 EXEC SQL UPDATE users
460 SET xname = NVL(:name, CHR(0)), xdept = NVL(:rdept, CHR(0)),
461 xtitle = NVL(:rtitle, CHR(0)), xaddress = NVL(:raddr, CHR(0)),
462 xphone1 = NVL(:rhphone, CHR(0)), xphone2 = NVL(:rophone, CHR(0)),
463 xmodtime = SYSDATE, clearid = NVL(:sid, CHR(0))
464 WHERE users_id = :id;
465 if (sqlca.sqlcode)
466 {
9f5e5c05 467 dbmserr(NULL, sqlca.sqlcode);
468 exit(1);
3e77c6a3 469 }
a6e9fead 470 }
02cd9ede 471}
469f80df 472
473
7ac48069 474void newuser(struct entry *e)
02cd9ede 475{
5eaef520 476 char *from, *to;
477 EXEC SQL BEGIN DECLARE SECTION;
478 int id, uid, st, who;
479 char *last, *first, *class, *middle, login[9], *sid, fullname[65], *prog;
7ac48069 480 char oaddr[81], ophone[17], dept[128], *name, *title;
5eaef520 481 char *rdept, *rhphone, *rophone;
482 EXEC SQL END DECLARE SECTION;
483
484 who = WHO;
485 prog = PROG;
486 strncpy(oaddr, e->address, 16);
487 oaddr[16] = '\0';
488 while ((to = strchr(oaddr, ',')))
489 *to = ';';
490 while ((to = strchr(oaddr, ':')))
491 *to = ';';
492 from = e->phone;
493 to = ophone;
494 while (*from)
495 {
496 if (isdigit(*from))
497 *to++ = *from;
498 from++;
469f80df 499 }
5eaef520 500 *to = '\0';
501 FixCase(e->dept);
502 strncpy(dept, e->dept, 12);
503 dept[12] = '\0';
504
505 id = set_next_users_id(0);
506 uid = set_next_uid(e->highid);
507 sprintf(login, "#%d", uid);
508 last = e->last;
509 first = e->first;
510 middle = e->middle;
511 class = e->class;
512 if (*middle)
513 sprintf(fullname, "%s %s %s", first, middle, last);
514 else
515 sprintf(fullname, "%s %s", first, last);
516 st = US_NO_LOGIN_YET;
517
518 sid = e->id;
519 name = e->name;
520 rdept = e->dept;
521 title = e->title;
522 rhphone = e->phone;
523 rophone = e->phone2;
524
525 EXEC SQL INSERT INTO users
526 (login, users_id, unix_uid, shell, last, first, middle, status,
527 clearid, type, modtime, modby, modwith, fullname, office_addr,
528 office_phone, department, fmodtime, fmodby, fmodwith,
529 potype, xname, xdept, xtitle, xaddress, xphone1, xphone2, xmodtime)
530 VALUES (:login, :id, :uid, '/bin/athena/tcsh',
531 NVL(:last, CHR(0)), NVL(:first, CHR(0)), NVL(:middle, CHR(0)),
532 :st, NVL(:sid, CHR(0)), NVL(:class, CHR(0)), SYSDATE, :who, :prog,
533 NVL(:fullname, CHR(0)), NVL(:oaddr, CHR(0)), NVL(:ophone, CHR(0)),
534 NVL(:dept, CHR(0)), SYSDATE, :who, :prog, 'NONE',
535 NVL(:name, CHR(0)), NVL(:rdept, CHR(0)), NVL(:title, CHR(0)),
536 NVL(:oaddr, CHR(0)), NVL(:rhphone, CHR(0)), NVL(:rophone, CHR(0)),
537 SYSDATE);
538 if (sqlca.sqlcode)
539 {
9f5e5c05 540 dbmserr("adding user", sqlca.sqlcode);
541 exit(1);
5eaef520 542 }
543 else
544 com_err(whoami, 0, "adding user %s %s", e->first, e->last);
02cd9ede 545}
469f80df 546
547
7ac48069 548int set_next_users_id(int limit)
02cd9ede 549{
5eaef520 550 EXEC SQL BEGIN DECLARE SECTION;
7ac48069 551 int flag, value, retval;
5eaef520 552 EXEC SQL END DECLARE SECTION;
553
554 EXEC SQL SELECT value INTO :value FROM numvalues
555 WHERE name = 'users_id';
556 if (sqlfail())
557 sqlexit();
558 if (sqlca.sqlerrd[2] != 1)
559 {
560 EXEC SQL ROLLBACK;
561 com_err(whoami, MR_INTERNAL, "values table inconsistancy");
562 exit(1);
3e77c6a3 563 }
564
5eaef520 565 flag = 0;
566 EXEC SQL SELECT users_id INTO :flag FROM users
567 WHERE users_id = :value;
568 if (sqlfail())
569 sqlexit();
570 if (sqlca.sqlerrd[2] == 0)
3e77c6a3 571 flag = 0;
5eaef520 572 while (flag)
573 {
574 value++;
575 if (limit && value > MAX_ID_VALUE)
576 value = MIN_ID_VALUE;
3e77c6a3 577 flag = 0;
5eaef520 578 EXEC SQL SELECT users_id INTO :flag FROM users
579 WHERE users_id = :value;
580 if (sqlfail())
581 sqlexit();
582 if (sqlca.sqlerrd[2] == 0)
3e77c6a3 583 flag = 0;
3e77c6a3 584 }
585
5eaef520 586 retval = value++;
587 if (limit && value > MAX_ID_VALUE)
588 value = MIN_ID_VALUE;
589 EXEC SQL UPDATE numvalues SET value = :value
590 WHERE name = 'users_id';
591 if (sqlca.sqlcode)
592 {
593 dbmserr("assigning ID", sqlca.sqlcode);
594 exit(1);
3e77c6a3 595 }
5eaef520 596 return retval;
3e77c6a3 597}
598
7ac48069 599int set_next_uid(int high)
3e77c6a3 600{
5eaef520 601 EXEC SQL BEGIN DECLARE SECTION;
7ac48069 602 int flag, value, retval;
5eaef520 603 char *name;
604 EXEC SQL END DECLARE SECTION;
605
606 if (high)
607 name = "high_uid";
608 else
609 name = "unix_uid";
610
611 EXEC SQL SELECT value INTO :value FROM numvalues
612 WHERE name = :name;
613 if (sqlfail())
614 sqlexit();
615 if (sqlca.sqlerrd[2] != 1)
616 {
617 EXEC SQL ROLLBACK;
618 com_err(whoami, MR_INTERNAL, "values table inconsistancy");
619 exit(1);
469f80df 620 }
621
5eaef520 622 flag = 0;
623 EXEC SQL SELECT unix_uid INTO :flag FROM users WHERE unix_uid = :value;
624 if (sqlfail())
625 sqlexit();
626 if (sqlca.sqlerrd[2] == 0)
02cd9ede 627 flag = 0;
5eaef520 628 while (flag)
629 {
630 value++;
631 if (!high && value > MAX_ID_VALUE)
632 value = MIN_ID_VALUE;
02cd9ede 633 flag = 0;
5eaef520 634 EXEC SQL SELECT unix_uid INTO :flag FROM users WHERE unix_uid = :value;
635 if (sqlfail())
636 sqlexit();
637 if (sqlca.sqlerrd[2] == 0)
02cd9ede 638 flag = 0;
469f80df 639 }
640
5eaef520 641 retval = value++;
642 if (!high && value > MAX_ID_VALUE)
643 value = MIN_ID_VALUE;
644 EXEC SQL UPDATE numvalues SET value = :value WHERE name = :name;
645 if (sqlca.sqlcode)
646 {
647 dbmserr("assigning ID", sqlca.sqlcode);
648 exit(1);
3e77c6a3 649 }
5eaef520 650 return retval;
3e77c6a3 651}
652
653
7ac48069 654void sqlexit(void)
3e77c6a3 655{
5eaef520 656 dbmserr(NULL, sqlca.sqlcode);
657 EXEC SQL ROLLBACK WORK;
658 exit(1);
02cd9ede 659}
9f5e5c05 660
7ac48069 661void dbmserr(char *where, int what)
9f5e5c05 662{
663 char err_msg[256];
5eaef520 664 int bufsize = 256, msglength = 0;
9f5e5c05 665
666 sqlglm(err_msg, &bufsize, &msglength);
5eaef520 667 err_msg[msglength] = '\0';
9f5e5c05 668
5eaef520 669 if (where)
9f5e5c05 670 com_err(whoami, 0, "DBMS error %swhile %s", err_msg, where);
671 else
672 com_err(whoami, 0, "DBMS error %s", err_msg);
673}
This page took 0.173052 seconds and 5 git commands to generate.