]> andersk Git - moira.git/blame - regtape/employee.pc
Code style cleanup. (No functional changes)
[moira.git] / regtape / employee.pc
CommitLineData
469f80df 1/* $Header$
2 */
3
4#include <stdio.h>
9f5e5c05 5#include <string.h>
469f80df 6#include <ctype.h>
7#include <sys/time.h>
932028de 8#include <moira.h>
9#include <moira_site.h>
02cd9ede 10EXEC SQL INCLUDE sqlca;
469f80df 11
12
02cd9ede 13#define WHO 11859 /* root */
14#define PROG "emp-tape"
469f80df 15
397e9044 16#define MAX_ID_VALUE 31999
469f80df 17#define MIN_ID_VALUE 101
18
19/* File format is:
20
210-8 id number
229-38 name
2339-62 office address
2463-74 phone1
2575-86 phone2
2687-106 dept
27107-156 title
28157-186 username
29187-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
a6e9fead 44#define LEN_NAME 30
45#define LEN_OFFICE 24
469f80df 46#define LEN_PHONE 12
47#define LEN_PHONE2 12
a6e9fead 48#define LEN_DEPT 20
49#define LEN_TITLE 50
50#define LEN_USERNAME 30
469f80df 51#define LEN_HOST 55
52
53
54struct entry {
5eaef520 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;
469f80df 68};
69
70
71char *whoami;
72int newfinger = 0;
73
9f5e5c05 74#define sqlfail() (sqlca.sqlcode && sqlca.sqlcode != 1403)
bd22473a 75#define SQL_DUPLICATE -2112
3e77c6a3 76
469f80df 77
5eaef520 78int main(int argc, char **argv)
02cd9ede 79{
5eaef520 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];
469f80df 109 }
110
5eaef520 111 in = fopen(file, "r");
112 if (!in)
113 {
114 fprintf(stderr, "Unable to open %s for input\n", file);
115 exit(1);
469f80df 116 }
117
5eaef520 118 initialize_sms_error_table();
325821e4 119
5eaef520 120 EXEC SQL CONNECT :db IDENTIFIED BY :db;
121 if (sqlca.sqlcode)
122 {
123 dbmserr("opening database", sqlca.sqlcode);
124 exit(1);
3e77c6a3 125 }
469f80df 126
5eaef520 127 while ((e = get_next_entry(in)))
128 {
9b2c129e 129 again:
5eaef520 130 process_entry(e);
131 EXEC SQL COMMIT WORK;
132 if (sqlca.sqlcode)
133 {
9f5e5c05 134 dbmserr("committing work", sqlca.sqlcode);
135 exit(1);
3e77c6a3 136 }
5eaef520 137 if (wait)
138 {
139 printf("Next");
140 fflush(stdout);
141 gets(buf);
469f80df 142 }
143 }
144
5eaef520 145 exit(0);
02cd9ede 146}
469f80df 147
148
5eaef520 149char *substr(char *buf, char *key)
469f80df 150{
5eaef520 151 int l;
469f80df 152
5eaef520 153 for (l = strlen(key); *buf; buf++)
154 {
469f80df 155 if (!strncmp(buf, key, l))
5eaef520 156 return buf;
157 }
158 return NULL;
469f80df 159}
160
161
5eaef520 162struct entry *get_next_entry(FILE *in)
469f80df 163{
5eaef520 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))
a6e9fead 205 p++;
5eaef520 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);
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);
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;
64b4c6b1 253 }
469f80df 254
5eaef520 255 return &e;
469f80df 256}
257
258
5eaef520 259process_entry(struct entry *e)
02cd9ede 260{
5eaef520 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();
3e77c6a3 302 }
5eaef520 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;
325821e4 318 }
469f80df 319 }
325821e4 320
5eaef520 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 {
9f5e5c05 339 dbmserr("updating user", sqlca.sqlcode);
340 exit(1);
3e77c6a3 341 }
342 }
343
5eaef520 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 {
9f5e5c05 357 dbmserr("updating name", sqlca.sqlcode);
358 exit(1);
3e77c6a3 359 }
469f80df 360 }
325821e4 361
5eaef520 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';
469f80df 376 changed++;
5eaef520 377 }
378 else if (strncmp(strtrim(oaddr), buf, 15))
379 nochange++;
469f80df 380 }
5eaef520 381 else
382 {
383 if (strncmp(strtrim(oaddr), buf, 15))
384 changed++;
385 strncpy(oaddr, buf, 16);
386 oaddr[16] = '\0';
469f80df 387 }
5eaef520 388 from = e->phone;
389 to = buf;
390 while (*from)
391 {
392 if (isdigit(*from))
393 *to++ = *from;
394 from++;
469f80df 395 }
5eaef520 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';
469f80df 413 }
5eaef520 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 {
9f5e5c05 454 dbmserr(NULL, sqlca.sqlcode);
455 exit(1);
3e77c6a3 456 }
5eaef520 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 {
9f5e5c05 468 dbmserr(NULL, sqlca.sqlcode);
469 exit(1);
3e77c6a3 470 }
a6e9fead 471 }
02cd9ede 472}
469f80df 473
474
5eaef520 475newuser(struct entry *e)
02cd9ede 476{
5eaef520 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++;
469f80df 500 }
5eaef520 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 {
9f5e5c05 541 dbmserr("adding user", sqlca.sqlcode);
542 exit(1);
5eaef520 543 }
544 else
545 com_err(whoami, 0, "adding user %s %s", e->first, e->last);
02cd9ede 546}
469f80df 547
548
5eaef520 549set_next_users_id(int limit)
02cd9ede 550{
5eaef520 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);
3e77c6a3 564 }
565
5eaef520 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)
3e77c6a3 572 flag = 0;
5eaef520 573 while (flag)
574 {
575 value++;
576 if (limit && value > MAX_ID_VALUE)
577 value = MIN_ID_VALUE;
3e77c6a3 578 flag = 0;
5eaef520 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)
3e77c6a3 584 flag = 0;
3e77c6a3 585 }
586
5eaef520 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);
3e77c6a3 596 }
5eaef520 597 return retval;
3e77c6a3 598}
599
5eaef520 600set_next_uid(int high)
3e77c6a3 601{
5eaef520 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);
469f80df 621 }
622
5eaef520 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)
02cd9ede 628 flag = 0;
5eaef520 629 while (flag)
630 {
631 value++;
632 if (!high && value > MAX_ID_VALUE)
633 value = MIN_ID_VALUE;
02cd9ede 634 flag = 0;
5eaef520 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)
02cd9ede 639 flag = 0;
469f80df 640 }
641
5eaef520 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);
3e77c6a3 650 }
5eaef520 651 return retval;
3e77c6a3 652}
653
654
5eaef520 655sqlexit(void)
3e77c6a3 656{
5eaef520 657 dbmserr(NULL, sqlca.sqlcode);
658 EXEC SQL ROLLBACK WORK;
659 exit(1);
02cd9ede 660}
9f5e5c05 661
662dbmserr(char *where, int what)
663{
664 char err_msg[256];
5eaef520 665 int bufsize = 256, msglength = 0;
9f5e5c05 666
667 sqlglm(err_msg, &bufsize, &msglength);
5eaef520 668 err_msg[msglength] = '\0';
9f5e5c05 669
5eaef520 670 if (where)
9f5e5c05 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.186826 seconds and 5 git commands to generate.