]> andersk Git - moira.git/blame_incremental - regtape/employee.pc
New version which includes enrolled, half-enrolled, and half-registered
[moira.git] / regtape / employee.pc
... / ...
CommitLineData
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>
10EXEC 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
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
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
54struct 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 char *email;
68};
69
70
71char *whoami;
72int newfinger = 0;
73
74#define sqlfail() (sqlca.sqlcode && sqlca.sqlcode != 1403)
75#define SQL_DUPLICATE 1422
76
77
78main(argc, argv)
79int argc;
80char **argv;
81{
82 FILE *in;
83 struct entry *e, *get_next_entry();
84 int i, wait = 0;
85 char buf[BUFSIZ], *file = NULL;
86EXEC SQL BEGIN DECLARE SECTION;
87 char *db="moira";
88EXEC 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
145char *substr(buf, key)
146char *buf;
147char *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
158struct entry *get_next_entry(in)
159FILE *in;
160{
161 static struct entry e;
162 static char buf[BUFSIZ], mid[16], eid[16], email[256];
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 if (substr(e.title, "PROF") || substr(e.title, "LECTURE"))
229 e.class = "FACULTY";
230
231 strcpy(email, strtrim(username));
232 if (host[0] == '@')
233 strncat(email, strtrim(host));
234 e.email = email;
235
236 return(&e);
237}
238
239
240process_entry(e)
241struct 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 /* Don't process Lincoln Labs */
253 if (!strncmp(e->address, "LL", 2))
254 return;
255
256 who = WHO;
257 prog = PROG;
258 first = e->first;
259 if (strlen(first) > 16)
260 first[16] = 0;
261 last = e->last;
262 if (strlen(last) > 16)
263 last[16] = 0;
264 middle = e->middle;
265 eid = e->eid;
266 sid = e->id;
267 id = 0;
268 encrypted = 0;
269
270 /* Get user info */
271 EXEC SQL SELECT users_id, first, last, middle, type, office_addr, office_phone, department, status
272 INTO :id, :dfirst, :dlast, :dmiddle, :class, :oaddr, :ophone, :dept, :status
273 FROM users
274 WHERE clearid = :sid;
275 if (sqlfail()) {
276 if (sqlca.sqlcode == SQL_DUPLICATE) {
277 com_err(whoami, 0, "duplicate ID number %s on user %s %s", sid, first, last);
278 return;
279 } else
280 sqlexit();
281 }
282 if (id == 0) {
283 EXEC SQL SELECT users_id, first, last, middle, type, office_addr, office_phone, department, status
284 INTO :id, :dfirst, :dlast, :dmiddle, :class, :oaddr, :ophone, :dept, :status
285 FROM users
286 WHERE last = :last and first = :first and clearid = :eid;
287 if (sqlfail() && sqlca.sqlcode != SQL_DUPLICATE) {
288 sqlexit();
289 }
290 encrypted++;
291 if (id == 0) {
292 newuser(e);
293 return;
294 }
295 }
296
297 /* Update class/state if necessary. (Exclude several spacial cases.) */
298 if (strcmp(e->class, strtrim(class)) &&
299 strcmp(class, "STAFF") && strcmp(class, "SIPBMEM") &&
300 strcmp(class, "KNIGHT")) {
301 com_err(whoami, 0, "updating class for %s %s from %s to %s",
302 first, last, class, e->class);
303 if (status == US_NOT_ALLOWED)
304 status = US_NO_LOGIN_YET;
305 if (status == US_ENROLL_NOT_ALLOWED)
306 status = US_ENROLLED;
307 strcpy(class, e->class);
308 EXEC SQL UPDATE users
309 SET type = NVL(:class,CHR(0)), status = :status, modtime = SYSDATE,
310 modby = :who, modwith = :prog
311 WHERE users_id = :id;
312 if (sqlca.sqlcode != 0) {
313 dbmserr("updating user", sqlca.sqlcode);
314 exit(1);
315 }
316 }
317
318 /* Update name if necessary */
319 if (strcmp(first, strtrim(dfirst)) ||
320 strcmp(last, strtrim(dlast)) ||
321 strcmp(middle, strtrim(dmiddle))) {
322 com_err(whoami, 0, "updating real name for %s %s", first, last);
323 EXEC SQL UPDATE users
324 SET first = NVL(:first,CHR(0)), last = NVL(:last,CHR(0)),
325 middle = NVL(:middle,CHR(0)), modby = :who, modwith = :prog,
326 modtime = SYSDATE
327 WHERE users_id = :id;
328 if (sqlca.sqlcode != 0) {
329 dbmserr("updating name", sqlca.sqlcode);
330 exit(1);
331 }
332 }
333
334 changed = nochange = 0;
335 if (encrypted) changed++;
336 strcpy(buf, e->address);
337 while (to = strchr(buf, ','))
338 *to = ';';
339 while (to = strchr(buf, ':'))
340 *to = ';';
341 if (newfinger) {
342 if (oaddr[0] == ' ' && buf[0]) {
343 strncpy(oaddr, buf, 16);
344 oaddr[16] = 0;
345 changed++;
346 } else if (strncmp(strtrim(oaddr), buf, 15))
347 nochange++;
348 } else {
349 if (strncmp(strtrim(oaddr), buf, 15))
350 changed++;
351 strncpy(oaddr, buf, 16);
352 oaddr[16] = 0;
353 }
354 from = e->phone;
355 to = buf;
356 while (*from) {
357 if (isdigit(*from))
358 *to++ = *from;
359 from++;
360 }
361 *to = 0;
362 if (newfinger) {
363 if (ophone[0] == ' ') {
364 strncpy(ophone, buf, 16);
365 ophone[16] = 0;
366 } else if (strncmp(strtrim(ophone), buf, 11))
367 nochange++;
368 } else {
369 if (strncmp(strtrim(ophone), buf, 11))
370 changed++;
371 strncpy(ophone, buf, 16);
372 ophone[16] = 0;
373 }
374 FixCase(e->dept);
375 FixCase(e->title);
376 if (newfinger) {
377 if (dept[0] == ' ') {
378 strncpy(dept, e->dept, 12);
379 dept[12] = 0;
380 } else if (strncmp(strtrim(dept), e->dept, 11))
381 nochange++;
382 } else {
383 if (strncmp(strtrim(dept), e->dept, 11))
384 changed++;
385 strncpy(dept, e->dept, 12);
386 dept[12] = 0;
387 }
388 sid = e->id;
389 name = e->name;
390 rdept = e->dept;
391 rtitle = e->title;
392 raddr = e->address;
393 rhphone = e->phone;
394 rophone = e->phone2;
395 if (changed) {
396 com_err(whoami, 0, "updating finger for %s %s", first, last);
397 EXEC SQL UPDATE users
398 SET office_addr = NVL(:oaddr,CHR(0)),
399 office_phone = NVL(:ophone,CHR(0)), department = NVL(:dept,CHR(0)),
400 fmodtime = SYSDATE, fmodby = :who, fmodwith = :prog,
401 xname = NVL(:name,CHR(0)), xdept = NVL(:rdept,CHR(0)),
402 xtitle = NVL(:rtitle,CHR(0)), xaddress = NVL(:raddr,CHR(0)),
403 xphone1 = NVL(:rhphone,CHR(0)), xphone2 = NVL(:rophone,CHR(0)),
404 xmodtime = SYSDATE, clearid = NVL(:sid,CHR(0))
405 WHERE users_id = :id;
406 if (sqlca.sqlcode != 0) {
407 dbmserr(NULL, sqlca.sqlcode);
408 exit(1);
409 }
410 } else {
411 EXEC SQL UPDATE users
412 SET xname = NVL(:name,CHR(0)), xdept = NVL(:rdept,CHR(0)),
413 xtitle = NVL(:rtitle,CHR(0)), xaddress = NVL(:raddr,CHR(0)),
414 xphone1 = NVL(:rhphone,CHR(0)), xphone2 = NVL(:rophone,CHR(0)),
415 xmodtime = SYSDATE, clearid = NVL(:sid,CHR(0))
416 WHERE users_id = :id;
417 if (sqlca.sqlcode != 0) {
418 dbmserr(NULL, sqlca.sqlcode);
419 exit(1);
420 }
421 }
422}
423
424
425newuser(e)
426struct entry *e;
427{
428 char *from, *to;
429 EXEC SQL BEGIN DECLARE SECTION;
430 int id, uid, st, who;
431 char *last, *first, *class, *middle, login[9], *sid, fullname[65], *prog;
432 char oaddr[81], ophone[17], dept[128], *name, *title, phone2[17];
433 char *rdept, *rhphone, *rophone;
434 EXEC SQL END DECLARE SECTION;
435
436 who = WHO;
437 prog = PROG;
438 strncpy(oaddr, e->address, 16);
439 oaddr[16] = 0;
440 while (to = strchr(oaddr, ','))
441 *to = ';';
442 while (to = strchr(oaddr, ':'))
443 *to = ';';
444 from = e->phone;
445 to = ophone;
446 while (*from) {
447 if (isdigit(*from))
448 *to++ = *from;
449 from++;
450 }
451 *to = 0;
452 FixCase(e->dept);
453 strncpy(dept, e->dept, 12);
454 dept[12] = 0;
455
456 id = set_next_users_id(0);
457 uid = set_next_uid(1);
458 sprintf(login, "#%d", uid);
459 last = e->last;
460 first = e->first;
461 middle = e->middle;
462 class = e->class;
463 if (*middle)
464 sprintf(fullname, "%s %s %s", first, middle, last);
465 else
466 sprintf(fullname, "%s %s", first, last);
467 st = US_NO_LOGIN_YET;
468
469 sid = e->id;
470 name = e->name;
471 rdept = e->dept;
472 title = e->title;
473 rhphone = e->phone;
474 rophone = e->phone2;
475
476 EXEC SQL INSERT INTO users
477 (login, users_id, unix_uid, shell, last, first, middle, status,
478 clearid, type, modtime, modby, modwith, fullname, office_addr,
479 office_phone, department, fmodtime, fmodby, fmodwith,
480 potype, xname, xdept, xtitle, xaddress, xphone1, xphone2, xmodtime)
481 VALUES (:login, :id, :uid, '/bin/athena/tcsh',
482 NVL(:last,CHR(0)), NVL(:first,CHR(0)), NVL(:middle,CHR(0)),
483 :st, NVL(:sid,CHR(0)), NVL(:class,CHR(0)), SYSDATE, :who, :prog,
484 NVL(:fullname,CHR(0)), NVL(:oaddr,CHR(0)), NVL(:ophone,CHR(0)),
485 NVL(:dept,CHR(0)), SYSDATE, :who, :prog, 'NONE',
486 NVL(:name,CHR(0)), NVL(:rdept,CHR(0)), NVL(:title,CHR(0)),
487 NVL(:oaddr,CHR(0)), NVL(:rhphone,CHR(0)), NVL(:rophone,CHR(0)),
488 SYSDATE);
489 if (sqlca.sqlcode != 0) {
490 dbmserr("adding user", sqlca.sqlcode);
491 exit(1);
492 } else
493 com_err(whoami, 0, "adding user %s %s", e->first, e->last);
494}
495
496
497set_next_users_id(limit)
498 int limit;
499{
500 EXEC SQL BEGIN DECLARE SECTION;
501 int rowcount, flag, value, retval;
502 EXEC SQL END DECLARE SECTION;
503
504 EXEC SQL SELECT value INTO :value FROM numvalues
505 WHERE name = 'users_id';
506 if (sqlfail()) sqlexit();
507 if (sqlca.sqlerrd[2] != 1) {
508 EXEC SQL ROLLBACK;
509 com_err(whoami, MR_INTERNAL, "values table inconsistancy");
510 exit(1);
511 }
512
513 flag = 0;
514 EXEC SQL SELECT users_id INTO :flag FROM users
515 WHERE users_id = :value;
516 if (sqlfail()) sqlexit();
517 if (sqlca.sqlerrd[2] == 0)
518 flag = 0;
519 while (flag) {
520 value++;
521 if (limit && value > MAX_ID_VALUE)
522 value = MIN_ID_VALUE;
523 flag = 0;
524 EXEC SQL SELECT users_id INTO :flag FROM users
525 WHERE users_id = :value;
526 if (sqlfail()) sqlexit();
527 if (sqlca.sqlerrd[2] == 0)
528 flag = 0;
529 }
530
531 retval = value++;
532 if (limit && value > MAX_ID_VALUE)
533 value = MIN_ID_VALUE;
534 EXEC SQL UPDATE numvalues SET value = :value
535 WHERE name = 'users_id';
536 if (sqlca.sqlcode != 0) {
537 dbmserr("assigning ID", sqlca.sqlcode);
538 exit(1);
539 }
540 return(retval);
541}
542
543set_next_uid(limit)
544 int limit;
545{
546 EXEC SQL BEGIN DECLARE SECTION;
547 int rowcount, flag, value, retval;
548 EXEC SQL END DECLARE SECTION;
549
550 EXEC SQL SELECT value INTO :value FROM numvalues
551 WHERE name = 'unix_uid';
552 if (sqlfail()) sqlexit();
553 if (sqlca.sqlerrd[2] != 1) {
554 EXEC SQL ROLLBACK;
555 com_err(whoami, MR_INTERNAL, "values table inconsistancy");
556 exit(1);
557 }
558
559 flag = 0;
560 EXEC SQL SELECT unix_uid INTO :flag FROM users WHERE unix_uid = :value;
561 if (sqlfail()) sqlexit();
562 if (sqlca.sqlerrd[2] == 0)
563 flag = 0;
564 while (flag) {
565 value++;
566 if (limit && value > MAX_ID_VALUE)
567 value = MIN_ID_VALUE;
568 flag = 0;
569 EXEC SQL SELECT unix_uid INTO :flag FROM users WHERE unix_uid = :value;
570 if (sqlfail()) sqlexit();
571 if (sqlca.sqlerrd[2] == 0)
572 flag = 0;
573 }
574
575 retval = value++;
576 if (limit && value > MAX_ID_VALUE)
577 value = MIN_ID_VALUE;
578 EXEC SQL UPDATE numvalues SET value = :value WHERE name = 'unix_uid';
579 if (sqlca.sqlcode != 0) {
580 dbmserr("assigning ID", sqlca.sqlcode);
581 exit(1);
582 }
583 return(retval);
584}
585
586
587sqlexit()
588{
589 dbmserr(NULL, sqlca.sqlcode);
590 EXEC SQL ROLLBACK WORK;
591 exit(1);
592}
593
594dbmserr(char *where, int what)
595{
596 char err_msg[256];
597 int bufsize=256, msglength=0;
598
599 sqlglm(err_msg, &bufsize, &msglength);
600 err_msg[msglength]=0;
601
602 if(where)
603 com_err(whoami, 0, "DBMS error %swhile %s", err_msg, where);
604 else
605 com_err(whoami, 0, "DBMS error %s", err_msg);
606}
This page took 0.037913 seconds and 5 git commands to generate.