9 #include <moira_site.h>
10 EXEC SQL INCLUDE sqlca;
13 #define WHO 11859 /* root */
14 #define PROG "emp-tape"
16 #define MAX_ID_VALUE 31999
17 #define MIN_ID_VALUE 101
40 #define LOC_USERNAME 157
50 #define LEN_USERNAME 30
74 #define sqlfail() (sqlca.sqlcode && sqlca.sqlcode != 1403)
75 #define SQL_DUPLICATE -2112
78 int main(int argc, char **argv)
81 struct entry *e, *get_next_entry();
83 char buf[BUFSIZ], *file = NULL;
84 EXEC SQL BEGIN DECLARE SECTION;
86 EXEC SQL END DECLARE SECTION;
88 whoami = strrchr(argv[0], '/');
94 setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
95 setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
97 for (i = 1; i < argc; i++)
99 if (!strcmp(argv[i], "-w"))
101 else if (!strcmp(argv[i], "-D"))
102 setenv("ING_SET", "set printqry");
103 else if (!strcmp(argv[i], "-n"))
106 fprintf(stderr, "Usage: %s [-w] [-D] [-n] inputfile\n", whoami);
111 in = fopen(file, "r");
114 fprintf(stderr, "Unable to open %s for input\n", file);
118 initialize_sms_error_table();
120 EXEC SQL CONNECT :db IDENTIFIED BY :db;
123 dbmserr("opening database", sqlca.sqlcode);
127 while ((e = get_next_entry(in)))
131 EXEC SQL COMMIT WORK;
134 dbmserr("committing work", sqlca.sqlcode);
149 char *substr(char *buf, char *key)
153 for (l = strlen(key); *buf; buf++)
155 if (!strncmp(buf, key, l))
162 struct entry *get_next_entry(FILE *in)
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;
173 if (!fgets(buf, sizeof(buf), in))
176 strncpy(id, &buf[LOC_ID], LEN_ID);
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';
196 e.name = strtrim(sname);
197 p = strchr(name, ',');
200 e.last = strtrim(name);
207 if (p = strchr(e.first, ' '))
210 e.first = strtrim(e.first);
211 e.middle = strtrim(p + 1);
215 e.first = strtrim(e.first);
224 ends_sr = ends_jr = ends_iii = ends_iv = ends_ii = ends_v = 0;
227 LookForJrAndIII(e.last, &ends_sr, &ends_jr, &ends_iii, &ends_iv,
229 LookForJrAndIII(e.first, &ends_sr, &ends_jr, &ends_iii, &ends_iv,
237 EncryptID(e.eid, e.id, e.first, e.last);
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);
247 if (substr(e.title, "PROF") || substr(e.title, "LECTURE"))
249 if (!strcmp(e.dept, "LINCOLN LAB"))
259 process_entry(struct entry *e)
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];
269 EXEC SQL END DECLARE SECTION;
274 if (strlen(first) > 16)
277 if (strlen(last) > 16)
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
291 WHERE clearid = :sid;
294 if (sqlca.sqlcode == SQL_DUPLICATE)
296 com_err(whoami, 0, "duplicate ID number %s on user %s %s",
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
310 WHERE last = :last and first = :first and clearid = :eid;
311 if (sqlfail() && sqlca.sqlcode != SQL_DUPLICATE)
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"))
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;
339 dbmserr("updating user", sqlca.sqlcode);
344 /* Update name if necessary */
345 if (strcmp(first, strtrim(dfirst)) ||
346 strcmp(last, strtrim(dlast)) ||
347 strcmp(middle, strtrim(dmiddle)))
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,
354 WHERE users_id = :id;
357 dbmserr("updating name", sqlca.sqlcode);
362 changed = nochange = 0;
365 strcpy(buf, e->address);
366 while ((to = strchr(buf, ',')))
368 while ((to = strchr(buf, ':')))
372 if (oaddr[0] == ' ' && buf[0])
374 strncpy(oaddr, buf, 16);
378 else if (strncmp(strtrim(oaddr), buf, 15))
383 if (strncmp(strtrim(oaddr), buf, 15))
385 strncpy(oaddr, buf, 16);
399 if (ophone[0] == ' ')
401 strncpy(ophone, buf, 16);
404 else if (strncmp(strtrim(ophone), buf, 11))
409 if (strncmp(strtrim(ophone), buf, 11))
411 strncpy(ophone, buf, 16);
420 strncpy(dept, e->dept, 12);
423 else if (strncmp(strtrim(dept), e->dept, 11))
428 if (strncmp(strtrim(dept), e->dept, 11))
430 strncpy(dept, e->dept, 12);
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;
454 dbmserr(NULL, sqlca.sqlcode);
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;
468 dbmserr(NULL, sqlca.sqlcode);
475 newuser(struct entry *e)
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;
487 strncpy(oaddr, e->address, 16);
489 while ((to = strchr(oaddr, ',')))
491 while ((to = strchr(oaddr, ':')))
503 strncpy(dept, e->dept, 12);
506 id = set_next_users_id(0);
507 uid = set_next_uid(e->highid);
508 sprintf(login, "#%d", uid);
514 sprintf(fullname, "%s %s %s", first, middle, last);
516 sprintf(fullname, "%s %s", first, last);
517 st = US_NO_LOGIN_YET;
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)),
541 dbmserr("adding user", sqlca.sqlcode);
545 com_err(whoami, 0, "adding user %s %s", e->first, e->last);
549 set_next_users_id(int limit)
551 EXEC SQL BEGIN DECLARE SECTION;
552 int rowcount, flag, value, retval;
553 EXEC SQL END DECLARE SECTION;
555 EXEC SQL SELECT value INTO :value FROM numvalues
556 WHERE name = 'users_id';
559 if (sqlca.sqlerrd[2] != 1)
562 com_err(whoami, MR_INTERNAL, "values table inconsistancy");
567 EXEC SQL SELECT users_id INTO :flag FROM users
568 WHERE users_id = :value;
571 if (sqlca.sqlerrd[2] == 0)
576 if (limit && value > MAX_ID_VALUE)
577 value = MIN_ID_VALUE;
579 EXEC SQL SELECT users_id INTO :flag FROM users
580 WHERE users_id = :value;
583 if (sqlca.sqlerrd[2] == 0)
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';
594 dbmserr("assigning ID", sqlca.sqlcode);
600 set_next_uid(int high)
602 EXEC SQL BEGIN DECLARE SECTION;
603 int rowcount, flag, value, retval;
605 EXEC SQL END DECLARE SECTION;
612 EXEC SQL SELECT value INTO :value FROM numvalues
616 if (sqlca.sqlerrd[2] != 1)
619 com_err(whoami, MR_INTERNAL, "values table inconsistancy");
624 EXEC SQL SELECT unix_uid INTO :flag FROM users WHERE unix_uid = :value;
627 if (sqlca.sqlerrd[2] == 0)
632 if (!high && value > MAX_ID_VALUE)
633 value = MIN_ID_VALUE;
635 EXEC SQL SELECT unix_uid INTO :flag FROM users WHERE unix_uid = :value;
638 if (sqlca.sqlerrd[2] == 0)
643 if (!high && value > MAX_ID_VALUE)
644 value = MIN_ID_VALUE;
645 EXEC SQL UPDATE numvalues SET value = :value WHERE name = :name;
648 dbmserr("assigning ID", sqlca.sqlcode);
657 dbmserr(NULL, sqlca.sqlcode);
658 EXEC SQL ROLLBACK WORK;
662 dbmserr(char *where, int what)
665 int bufsize = 256, msglength = 0;
667 sqlglm(err_msg, &bufsize, &msglength);
668 err_msg[msglength] = '\0';
671 com_err(whoami, 0, "DBMS error %swhile %s", err_msg, where);
673 com_err(whoami, 0, "DBMS error %s", err_msg);