#include <strings.h>
#include <ctype.h>
#include <sys/time.h>
-#include <sms.h>
-#include <sms_app.h>
+#include <moira.h>
+#include <moira_site.h>
+EXEC SQL INCLUDE sqlca;
+#define WHO 11859 /* root */
+#define PROG "stu-tape"
+
+#define MAX_ID_VALUE 31999
+#define MIN_ID_VALUE 101
+
/* File format is:
0-29 name
#define LOC_DORM_ROOM 110
#define LOC_CITY 125
#define LOC_STATE 145
-#define LOC_DORM_PHONE 159
-#define LOC_MIT_PHONE1 243
+#define LOC_DPHONE 155
+#define LOC_MPHONE 243
-#define LEN_NAME 29
+#define LEN_NAME 30
#define LEN_ID 9
-#define LEN_COURSE 3
-#define LEN_YEAR 23
-#define LEN_ADDRESS 29
-#define LEN_DORM_ROOM 14
-#define LEN_CITY 28
-#define LEN_STATE 12
-#define LEN_DPHONE 9
-#define LEN_MPHONE 9
+#define LEN_COURSE 5
+#define LEN_YEAR 25
+#define LEN_ADDRESS 30
+#define LEN_DORM_ROOM 15
+#define LEN_CITY 20
+#define LEN_STATE 10
+#define LEN_DPHONE 12
+#define LEN_MPHONE 12
struct entry {
+ char *name;
char *last;
char *first;
char *middle;
char *dphone;
char *mphone;
char *class;
- char **argv;
- char **finger;
};
char *whoami;
+int newfinger = 0;
+#define SQL_DUPLICATE -40100
+#define SQL_DEADLOCK -49900
+#define sqlfail() (sqlca.sqlcode && sqlca.sqlcode != 100)
main(argc, argv)
int argc;
{
FILE *in;
struct entry *e, *get_next_entry();
- int status, wait = 0;
- char buf[BUFSIZ];
+ int i, wait = 0;
+ char buf[BUFSIZ], *file = NULL;
whoami = rindex(argv[0], '/');
if (whoami)
else
whoami = argv[0];
- if (argc > 2)
- wait++;
+ for (i = 1; i < argc; i++) {
+ if (!strcmp(argv[i], "-w"))
+ wait++;
+ else if (!strcmp(argv[i], "-D"))
+ setenv("ING_SET", "set printqry");
+ else if (!strcmp(argv[i], "-n"))
+ newfinger++;
+ else if (file != NULL)
+ fprintf(stderr, "Usage: %s [-w] [-D] [-n] inputfile\n", whoami);
+ else
+ file = argv[i];
+ }
- in = fopen(argv[1], "r");
+ in = fopen(file, "r");
if (in == NULL) {
- fprintf(stderr, "Unable to open %s for input\n", argv[1]);
+ fprintf(stderr, "Unable to open %s for input\n", file);
exit(1);
}
- if (status = sms_connect("")) {
- com_err(whoami, status, " connecting to Moira");
- exit(1);
- }
- if (status = sms_auth(whoami)) {
- com_err(whoami, status, " authenticating");
+ setlinebuf(stdout);
+ setlinebuf(stderr);
+ initialize_sms_error_table();
+
+ EXEC SQL CONNECT moira;
+ if (sqlca.sqlcode != 0) {
+ com_err(whoami, 0, "ingres error %d", sqlca.sqlcode);
exit(1);
}
+
while (e = get_next_entry(in)) {
+ again:
process_entry(e);
+ EXEC SQL COMMIT WORK;
+ if (sqlca.sqlcode != 0) {
+ if (sqlca.sqlcode == SQL_DEADLOCK) {
+ com_err(whoami, MR_DEADLOCK, "commiting work");
+ goto again;
+ } else {
+ com_err(whoami, 0, "ingres error %d", sqlca.sqlcode);
+ exit(1);
+ }
+ }
if (wait) {
printf("Next");
fflush(stdout);
}
}
- sms_disconnect();
exit(0);
}
{
static struct entry e;
static char buf[BUFSIZ], eid[16], classbuf[10], titlebuf[12];
- static int year = 0;
- int ends_jr, ends_iii, ends_iv;
+ static char name[LEN_NAME+1], id[LEN_ID+1], course[LEN_COURSE+1];
+ static char year[LEN_YEAR+1], address[LEN_ADDRESS+1];
+ static char dorm_room[LEN_DORM_ROOM+1], city[LEN_CITY+1];
+ static char state[LEN_STATE+1], dphone[LEN_DPHONE+1], mphone[LEN_MPHONE+1];
+ static char sname[LEN_NAME+1], title[128];
+ static int nyear = 0;
+ int ends_jr, ends_iii, ends_iv, ends_sr, ends_ii, ends_v;
char *p;
- if (year == 0) {
+ if (nyear == 0) {
struct tm *tm;
struct timeval tv;
gettimeofday(&tv, NULL);
tm = localtime(&tv.tv_sec);
- year = tm->tm_year;
+ nyear = tm->tm_year;
if (tm->tm_mon > 5)
- year++;
+ nyear++;
}
- fgets(buf, sizeof(buf), in);
- buf[LEN_NAME] = 0;
- p = index(&buf[LOC_NAME], ',');
+ if (fgets(buf, sizeof(buf), in) == NULL)
+ return((struct entry *)NULL);
+
+ strncpy(name, &buf[LOC_NAME], LEN_NAME); name[LEN_NAME] = 0;
+ strncpy(id, &buf[LOC_ID], LEN_ID); id[LEN_ID] = 0;
+ strncpy(course, &buf[LOC_COURSE], LEN_COURSE); course[LEN_COURSE] = 0;
+ strncpy(year, &buf[LOC_YEAR], LEN_YEAR); year[LEN_YEAR] = 0;
+ strncpy(address, &buf[LOC_ADDRESS], LEN_ADDRESS); address[LEN_ADDRESS] = 0;
+ strncpy(dorm_room, &buf[LOC_DORM_ROOM], LEN_DORM_ROOM); dorm_room[LEN_DORM_ROOM] = 0;
+ strncpy(city, &buf[LOC_CITY], LEN_CITY); city[LEN_CITY] = 0;
+ strncpy(state, &buf[LOC_STATE], LEN_STATE); state[LEN_STATE] = 0;
+ strncpy(dphone, &buf[LOC_DPHONE], LEN_DPHONE); dphone[LEN_DPHONE] = 0;
+ strncpy(mphone, &buf[LOC_MPHONE], LEN_MPHONE); mphone[LEN_MPHONE] = 0;
+
+ strcpy(sname, name);
+ e.name = strtrim(sname);
+ p = index(name, ',');
if (p)
*p = 0;
- e.last = strtrim(&buf[LOC_NAME]);
+ e.last = strtrim(name);
if (p) {
- e.first = p + 2;
+ p++;
+ while (isspace(*p))
+ p++;
+ e.first = p;
if (p = index(e.first, ' ')) {
*p = 0;
+ e.first = strtrim(e.first);
e.middle = strtrim(p + 1);
- } else
- e.middle = "";
- } else
- e.first = "";
- e.first = strtrim(e.first);
- ends_jr = ends_iii = ends_iv = 0;
+ } else {
+ e.first = strtrim(e.first);
+ e.middle = "";
+ }
+ } else {
+ e.first = "";
+ e.middle = "";
+ }
+ ends_jr = ends_iii = ends_iv = ends_sr = ends_ii = ends_v = 0;
LookForSt(e.last);
LookForO(e.last);
- LookForJrAndIII(e.last, &ends_jr, &ends_iii, &ends_iv);
- LookForJrAndIII(e.first, &ends_jr, &ends_iii, &ends_iv);
+ LookForJrAndIII(e.last, &ends_sr, &ends_jr, &ends_iii, &ends_iv,
+ &ends_ii, &ends_v);
+ LookForJrAndIII(e.first, &ends_sr, &ends_jr, &ends_iii, &ends_iv,
+ &ends_ii, &ends_v);
FixCase(e.last);
FixCase(e.first);
FixCase(e.middle);
- e.title = titlebuf;
- titlebuf[0] = 0;
- AppendJrOrIII(titlebuf, &ends_jr, &ends_iii, &ends_iv);
- e.id = &buf[LOC_ID];
+ e.id = id;
e.id[LEN_ID] = 0;
e.eid = eid;
EncryptID(e.eid, e.id, e.first, e.last);
- e.course = &buf[LOC_COURSE];
- e.course[LEN_COURSE] = 0;
- e.year = &buf[LOC_YEAR];
- e.year[LEN_YEAR] = 0;
- if (e.year[0] == 'G')
- e.class = "G";
- else {
+ e.year = strtrim(year);
+ e.title = title;
+ if (e.year[0] == 'G') {
+ e.class = "G";
+ sprintf(title, "Grad Student");
+ } else {
e.class = classbuf;
- sprintf(classbuf, "%d", year + 4 - atoi(e.year) + 1900);
- }
- e.address = &buf[LOC_ADDRESS];
- e.address[LEN_ADDRESS] = 0;
- e.dorm = &buf[LOC_DORM_ROOM];
- e.dorm[LEN_DORM_ROOM] = 0;
- e.city = &buf[LOC_CITY];
- e.city[LEN_CITY] = 0;
- e.state = &buf[LOC_STATE];
- e.state[LEN_STATE] = 0;
- e.dphone = &buf[LOC_DORM_PHONE];
- e.dphone[LEN_DPHONE] = 0;
- e.mphone = &buf[LOC_MIT_PHONE1];
- e.mphone[LEN_MPHONE] = 0;
- return(&e);
-}
-
-
-char **copy_argv(argc, argv)
-int argc;
-char **argv;
-{
- char **ret;
-
- ret = (char **) malloc((argc + 1) * sizeof(char *));
- ret[argc] = NULL;
- while (argc-- > 0)
- ret[argc] = strsave(argv[argc]);
- return(ret);
-}
-
-
-free_argv(argv)
-char **argv;
-{
- char **p;
-
- for (p = argv; *p; p++)
- free(p);
- free(argv);
-}
-
-
-getusers(argc, argv, e)
-int argc;
-char **argv;
-struct entry *e;
-{
- if (!strcmp(e->eid, argv[U_MITID])) {
- e->argv = copy_argv(argc, argv);
- return(SMS_ABORT);
- }
-#ifdef DEBUG
- com_err(whoami, 0, "comparing %s and %s", e->eid, argv[U_MITID]);
-#endif
- return(SMS_CONT);
-}
-
-
-getfinger(argc, argv, e)
-int argc;
-char **argv;
-struct entry *e;
-{
- e->finger = copy_argv(argc, argv);
- return(SMS_ABORT);
-}
-
+ sprintf(classbuf, "%d", nyear + 4 - atoi(e.year) + 1900);
+ sprintf(title, "Undergrad (class of %s)", classbuf);
+ }
-scream()
-{
- com_err(whoami, 0, "Programmer botch!");
+ e.course = strtrim(course);
+ e.address = strtrim(address);
+ e.dorm = strtrim(dorm_room);
+ e.city = strtrim(city);
+ e.state = strtrim(state);
+ e.dphone = strtrim(dphone);
+ e.mphone = strtrim(mphone);
+ return(&e);
}
process_entry(e)
struct entry *e;
{
- int status, changed;
- char *argv[U_END], buf[BUFSIZ], *from, *to;
-
- argv[0] = e->first;
- argv[1] = e->last;
- e->argv = NULL;
- status = sms_query("get_user_by_name", 2, argv, getusers, e);
- if (status == SMS_NO_MATCH || e->argv == NULL) {
- newuser(argv, e);
- return;
- } else if (status != SMS_SUCCESS) {
- com_err(whoami, status, "looking for user");
- return;
- }
- if (strcmp(e->class, e->argv[U_CLASS])) {
- com_err(whoami, 0, "updating class for user %s", e->argv[U_NAME]);
- argv[U_NAME] = e->argv[U_NAME];
- argv[U_NAME+1] = e->argv[U_NAME];
- argv[U_UID+1] = e->argv[U_UID];
- argv[U_SHELL+1] = e->argv[U_SHELL];
- argv[U_LAST+1] = e->argv[U_LAST];
- argv[U_FIRST+1] = e->argv[U_FIRST];
- argv[U_MIDDLE+1] = e->argv[U_MIDDLE];
- argv[U_STATE+1] = e->argv[U_STATE];
- argv[U_MITID+1] = e->argv[U_MITID];
- argv[U_CLASS+1] = e->class;
- status = sms_query("update_user", 10, argv, scream, NULL);
- if (status) {
- com_err(whoami, status, "updating user");
- free_argv(e->argv);
+ int changed, nochange, encrypted;
+ char buf[BUFSIZ], *from, *to;
+ EXEC SQL BEGIN DECLARE SECTION;
+ char *first, *last, *middle, *eid, *title, *sid, *name, *rname, *rdept, *rtitle;
+ char *rophone, *rhphone, *prog;
+ char class[9], haddr[128], hphone[33], ophone[33], dept[33], raddr[128];
+ char dfirst[17], dlast[17], dmiddle[17];
+ int id, status, who;
+ EXEC SQL END DECLARE SECTION;
+
+ who = WHO;
+ prog = PROG;
+ first = e->first;
+ if (strlen(first) > 16)
+ first[16] = 0;
+ last = e->last;
+ if (strlen(last) > 16)
+ last[16] = 0;
+ middle = e->middle;
+ eid = e->eid;
+ sid = e->id;
+ id = 0;
+ encrypted = 0;
+
+ /* Get user info */
+ EXEC SQL REPEATED SELECT users_id, first, last, middle, type, home_addr, home_phone, office_phone, status, department
+ INTO :id, :dfirst, :dlast, :dmiddle, :class, :haddr, :hphone, :ophone, :status, :dept
+ FROM users
+ WHERE clearid = :sid;
+ if (sqlfail()) {
+ if (sqlca.sqlcode == SQL_DUPLICATE) {
+ com_err(whoami, 0, "duplicate ID number %s on user %s %s", sid, first, last);
return;
+ } else if (sqlca.sqlcode == SQL_DEADLOCK) {
+ com_err(whoami, MR_DEADLOCK, "looking up user %s", sid);
+ EXEC SQL ROLLBACK;
+ return process_entry(e);
+ } else
+ sqlexit();
+ }
+ if (id == 0) {
+ EXEC SQL REPEATED SELECT users_id, first, last, middle, type, home_addr, home_phone, office_phone, status, department
+ INTO :id, :dfirst, :dlast, :dmiddle, :class, :haddr, :hphone, :ophone, :status, :dept
+ FROM users
+ WHERE last = :last and first = :first and clearid = :eid;
+ if (sqlfail()) {
+ if (sqlca.sqlcode == SQL_DEADLOCK) {
+ com_err(whoami, MR_DEADLOCK, "looking up user %s", sid);
+ EXEC SQL ROLLBACK;
+ return process_entry(e);
+ } else if (sqlca.sqlcode != SQL_DUPLICATE)
+ sqlexit();
+ }
+ encrypted++;
+ if (id == 0) {
+ newuser(e);
+ return;
+ }
+ }
+
+ /* See if class changed: if it's different, and the value in the database
+ * is not STAFF or SIPB, then update the database. Since they were on the
+ * students tape, make the account usable.
+ */
+ if (strcmp(e->class, strtrim(class)) &&
+ strcmp(class, "STAFF") && strcmp(class, "SIPB")) {
+ com_err(whoami, 0, "updating class for user %s %s from %s to %s",
+ first, last, class, e->class);
+ if (status == US_NOT_ALLOWED) status = US_NO_LOGIN_YET;
+ if (status == US_ENROLL_NOT_ALLOWED) status = US_ENROLLED;
+ strcpy(class, e->class);
+ EXEC SQL REPEATED UPDATE users
+ SET type = :class, status = :status, modtime = 'now',
+ modby = :who, modwith = :prog
+ WHERE users_id = :id;
+ if (sqlca.sqlcode != 0) {
+ com_err(whoami, 0, "ingres error %d", sqlca.sqlcode);
+ exit(1);
}
}
- if (status = sms_query("get_finger_by_login", 1, e->argv, getfinger, e)) {
- com_err(whoami, status, "getting finger info for %s", e->argv[U_NAME]);
- free_argv(e->argv);
- return;
+
+ /* Update name if necessary */
+ if (strcmp(first, strtrim(dfirst)) ||
+ strcmp(last, strtrim(dlast)) ||
+ strcmp(middle, strtrim(dmiddle))) {
+ com_err(whoami, 0, "updating real name for %s %s", first, last);
+ EXEC SQL UPDATE users
+ SET first = :first, last = :last, middle = :middle,
+ modby = :who, modwith = :prog, modtime = 'now'
+ WHERE users_id = :id;
+ if (sqlca.sqlcode != 0) {
+ com_err(whoami, 0, "ingres error %d", sqlca.sqlcode);
+ exit(1);
+ }
}
- changed = 0;
- strcpy(buf, strtrim(e->address));
+
+ /* Deal with updating the finger info if necessary */
+ changed = nochange = 0;
+ if (encrypted) changed++;
+ strcpy(buf, e->address);
if (*e->dorm) {
strcat(buf, " ");
- strcat(buf, strtrim(e->dorm));
+ strcat(buf, e->dorm);
}
if (*e->city) {
strcat(buf, " ");
- strcat(buf, strtrim(e->city));
+ strcat(buf, e->city);
}
+ FixCase(buf);
if (*e->state) {
strcat(buf, " ");
- strcat(buf, strtrim(e->state));
+ strcat(buf, e->state);
}
- if (strncmp(e->finger[F_HOME_ADDR], buf, 80)) {
- changed++;
- free(e->finger[F_HOME_ADDR]);
- e->finger[F_HOME_ADDR] = strsave(buf);
+ while (to = index(buf, ','))
+ *to = ';';
+ while (to = index(buf, ':'))
+ *to = ';';
+ if (newfinger) {
+ if (haddr[0] == ' ') {
+ strncpy(haddr, buf, 80);
+ haddr[80] = 0;
+ changed++;
+ } else if (strncmp(strtrim(haddr), buf, 80))
+ nochange++;
+ } else {
+ if (strncmp(strtrim(haddr), buf, 80))
+ changed++;
+ strncpy(haddr, buf, 80);
+ haddr[80] = 0;
}
from = e->dphone;
to = buf;
from++;
}
*to = 0;
- if (strncmp(e->finger[F_HOME_PHONE], buf, 16)) {
- changed++;
- free(e->finger[F_HOME_PHONE]);
- e->finger[F_HOME_PHONE] = strsave(buf);
+ if (newfinger) {
+ if (hphone[0] == ' ') {
+ strncpy(hphone, buf, 16);
+ hphone[16] = 0;
+ } else if (strncmp(strtrim(hphone), buf, 16))
+ nochange++;
+ } else {
+ if (strncmp(strtrim(hphone), buf, 16))
+ changed++;
+ strncpy(hphone, buf, 16);
+ hphone[16] = 0;
}
from = e->mphone;
to = buf;
from++;
}
*to = 0;
- if (strncmp(e->finger[F_OFFICE_PHONE], buf, 12)) {
- changed++;
- free(e->finger[F_OFFICE_PHONE]);
- e->finger[F_OFFICE_PHONE] = strsave(buf);
+ if (newfinger) {
+ if (ophone[0] == ' ') {
+ strncpy(ophone, buf, 12);
+ ophone[12] = 0;
+ } else if (strncmp(strtrim(ophone), buf, 12))
+ nochange++;
+ } else {
+ if (strncmp(strtrim(ophone), buf, 12))
+ changed++;
+ strncpy(ophone, buf, 12);
+ ophone[12] = 0;
}
- e->course = strtrim(e->course);
- if (strncmp(e->finger[F_MIT_DEPT], e->course, 12)) {
- changed++;
- free(e->finger[F_MIT_DEPT]);
- e->finger[F_MIT_DEPT] = strsave(e->course);
+ e->course = e->course;
+ if (newfinger) {
+ if (dept[0] == ' ') {
+ strncpy(dept, e->course, 12);
+ dept[12] = 0;
+ } else if (strncmp(strtrim(dept), e->course, 11))
+ nochange++;
+ } else {
+ if (strncmp(strtrim(dept), e->course, 11))
+ changed++;
+ strncpy(dept, e->course, 12);
+ dept[12] = 0;
+ }
+ sid = e->id;
+ name = e->name;
+ rdept = e->course;
+ rtitle = e->title;
+ rophone = e->mphone;
+ rhphone = e->dphone;
+ strcpy(raddr, e->address);
+ if (*e->dorm) {
+ strcat(raddr, " ");
+ strcat(raddr, e->dorm);
+ }
+ strcat(raddr, "|");
+ if (*e->city) {
+ strcat(raddr, e->city);
+ FixCase(raddr);
+ if (*e->state) {
+ strcat(raddr, " ");
+ if (isupper(e->state[0]) && isupper(e->state[1]) &&
+ isdigit(e->state[2]) && isdigit(e->state[3]) &&
+ isdigit(e->state[4]) && isdigit(e->state[5]) &&
+ isdigit(e->state[6])) {
+ sprintf(buf, "%c%c %s", e->state[0],e->state[1],
+ &(e->state[2]));
+ strcat(raddr, buf);
+ } else
+ strcat(raddr, e->state);
+ }
+ } else {
+ FixCase(raddr);
+ strcat(raddr, "MIT INTERDEPARTMENTAL MAIL");
}
if (changed) {
- com_err(whoami, 0, "updating finger for %s", e->argv[U_NAME]);
- status = sms_query("update_finger_by_login", 9, e->finger,
- scream, NULL);
- if (status)
- com_err(whoami, status, " while updating finger info");
- }
- free_argv(e->argv);
- free_argv(e->finger);
+ com_err(whoami, 0, "updating finger for %s %s", first, last);
+ EXEC SQL REPEATED UPDATE users
+ SET home_addr = :haddr, home_phone = :hphone,
+ office_phone = :ophone, department = :dept,
+ fmodtime = 'now', fmodby = :who, fmodwith = :prog,
+ xname = :name, xdept = :rdept, xtitle = :rtitle,
+ xaddress = :raddr, xphone1 = :rhphone, xphone2 = :rophone,
+ xmodtime = date('now'), clearid = :sid
+ WHERE users_id = :id;
+ if (sqlca.sqlcode != 0) {
+ if (sqlca.sqlcode == SQL_DEADLOCK) {
+ com_err(whoami, MR_DEADLOCK, "updating user %s", sid);
+ EXEC SQL ROLLBACK;
+ return process_entry(e);
+ } else {
+ com_err(whoami, 0, "ingres error %d", sqlca.sqlcode);
+ exit(1);
+ }
+ }
+ } else {
+ EXEC SQL REPEATED UPDATE users
+ SET xname = :name, xdept = :rdept, xtitle = :rtitle,
+ xaddress = :raddr, xphone1 = :rhphone, xphone2 = :rophone,
+ xmodtime = date('now'), clearid = :sid
+ WHERE users_id = :id;
+ if (sqlca.sqlcode != 0) {
+ if (sqlca.sqlcode == SQL_DEADLOCK) {
+ com_err(whoami, MR_DEADLOCK, "updating user %s", sid);
+ EXEC SQL ROLLBACK;
+ return process_entry(e);
+ } else {
+ com_err(whoami, 0, "ingres error %d", sqlca.sqlcode);
+ exit(1);
+ }
+ }
+ }
}
-newuser(argv, e)
-char **argv;
+
+newuser(e)
struct entry *e;
{
- int status;
-
- argv[U_NAME] = UNIQUE_LOGIN;
- argv[U_UID] = UNIQUE_UID;
- argv[U_SHELL] = "/bin/csh";
- argv[U_LAST] = e->last;
- argv[U_FIRST] = e->first;
- argv[U_MIDDLE] = e->middle;
- argv[U_STATE] = "0";
- argv[U_MITID] = e->eid;
- argv[U_CLASS] = e->class;
- com_err(whoami, 0, "adding user %s %s", e->first, e->last);
- status = sms_query("add_user", 9, argv, scream, NULL);
- if (status) {
- com_err(whoami, status, "adding user");
+ char buf[512], *from, *to;
+ EXEC SQL BEGIN DECLARE SECTION;
+ int id, uid, who;
+ char *last, *first, *class, *middle, login[9], *sid, fullname[65], *prog;
+ char haddr[81], hphone[17], ophone[13], dept[24], *title, raddr[81], *name;
+ EXEC SQL END DECLARE SECTION;
+
+ who = WHO;
+ prog = PROG;
+ strcpy(buf, e->address);
+ if (*e->dorm) {
+ strcat(buf, " ");
+ strcat(buf, e->dorm);
+ }
+ if (*e->city) {
+ strcat(buf, " ");
+ strcat(buf, e->city);
+ }
+ if (*e->state) {
+ strcat(buf, " ");
+ strcat(buf, e->state);
+ }
+ strncpy(haddr, buf, 80);
+ from = e->dphone;
+ to = buf;
+ while (*from) {
+ if (isdigit(*from))
+ *to++ = *from;
+ from++;
+ }
+ *to = 0;
+ strncpy(hphone, buf, 16);
+ from = e->mphone;
+ to = buf;
+ while (*from) {
+ if (isdigit(*from))
+ *to++ = *from;
+ from++;
+ }
+ *to = 0;
+ strncpy(ophone, buf, 12);
+ strncpy(dept, e->course, 12);
+
+ id = set_next_users_id(0);
+ uid = set_next_uid(1);
+ sprintf(login, "#%d", uid);
+ last = e->last;
+ first = e->first;
+ middle = e->middle;
+ sid = e->id;
+ class = e->class;
+ title = e->title;
+ if (*middle)
+ sprintf(fullname, "%s %s %s", first, middle, last);
+ else
+ sprintf(fullname, "%s %s", first, last);
+ name = e->name;
+ strcpy(raddr, e->address);
+ if (*e->dorm) {
+ strcat(raddr, " ");
+ strcat(raddr, e->dorm);
+ }
+ strcat(raddr, "|");
+ if (*e->city) {
+ strcat(raddr, e->city);
+ FixCase(raddr);
+ if (*e->state) {
+ strcat(raddr, " ");
+ if (isupper(e->state[0]) && isupper(e->state[1]) &&
+ isdigit(e->state[2]) && isdigit(e->state[3]) &&
+ isdigit(e->state[4]) && isdigit(e->state[5]) &&
+ isdigit(e->state[6])) {
+ sprintf(buf, "%c%c %s", e->state[0],e->state[1],
+ &(e->state[2]));
+ strcat(raddr, buf);
+ } else
+ strcat(raddr, e->state);
+ }
+ } else {
+ FixCase(raddr);
+ strcat(raddr, "MIT INTERDEPARTMENTAL MAIL");
+ }
+ EXEC SQL REPEATED INSERT INTO users
+ (login, users_id, uid, shell, last, first, middle, status,
+ clearid, type, modtime, modby, modwith, fullname, home_addr,
+ home_phone, office_phone, department, fmodtime, fmodby, fmodwith,
+ potype, xname, xdept, xtitle, xaddress, xphone1, xphone2, xmodtime)
+ VALUES (:login, :id, :uid, '/bin/csh', :last, :first, :middle, 0,
+ :sid, :class, 'now', :who, :prog, :fullname, :haddr, :hphone,
+ :ophone, :dept, 'now', :who, :prog, 'NONE', :name, :dept,
+ :title, :raddr, :hphone, :ophone, date('now'));
+ if (sqlca.sqlcode != 0) {
+ if (sqlca.sqlcode == SQL_DEADLOCK) {
+ com_err(whoami, MR_DEADLOCK, "adding user %s", sid);
+ EXEC SQL ROLLBACK;
+ return newuser(e);
+ } else {
+ com_err(whoami, 0, "ingres error %d", sqlca.sqlcode);
+ exit(1);
+ }
+ } else
+ com_err(whoami, 0, "adding user %s %s", e->first, e->last);
+}
+
+
+
+set_next_users_id(limit)
+ int limit;
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ int rowcount, flag, value, retval;
+ EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL REPEATED SELECT value INTO :value FROM numvalues
+ WHERE name = 'users_id';
+ if (sqlfail()) sqlexit();
+ if (sqlca.sqlerrd[2] != 1) {
+ EXEC SQL ROLLBACK;
+ com_err(whoami, MR_INTERNAL, "values table inconsistancy");
+ exit(1);
+ }
+
+ flag = 0;
+ EXEC SQL REPEATED SELECT users_id INTO :flag FROM users
+ WHERE users_id = :value;
+ if (sqlfail()) sqlexit();
+ if (sqlca.sqlerrd[2] == 0)
+ flag = 0;
+ while (flag) {
+ value++;
+ if (limit && value > MAX_ID_VALUE)
+ value = MIN_ID_VALUE;
+ flag = 0;
+ EXEC SQL REPEATED SELECT users_id INTO :flag FROM users
+ WHERE users_id = :value;
+ if (sqlfail()) sqlexit();
+ if (sqlca.sqlerrd[2] == 0)
+ flag = 0;
+ }
+
+ retval = value++;
+ if (limit && value > MAX_ID_VALUE)
+ value = MIN_ID_VALUE;
+ EXEC SQL REPEATED UPDATE numvalues SET value = :value
+ WHERE name = 'users_id';
+ if (sqlca.sqlcode != 0) {
+ com_err(whoami, 0, "ingres error %d", sqlca.sqlcode);
+ exit(1);
}
+ return(retval);
+}
+
+set_next_uid(limit)
+ int limit;
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ int rowcount, flag, value, retval;
+ EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL REPEATED SELECT value INTO :value FROM numvalues
+ WHERE name = 'uid';
+ if (sqlfail()) sqlexit();
+ if (sqlca.sqlerrd[2] != 1) {
+ EXEC SQL ROLLBACK;
+ com_err(whoami, MR_INTERNAL, "values table inconsistancy");
+ exit(1);
+ }
+
+ flag = 0;
+ EXEC SQL REPEATED SELECT uid INTO :flag FROM users WHERE uid = :value;
+ if (sqlfail()) sqlexit();
+ if (sqlca.sqlerrd[2] == 0)
+ flag = 0;
+ while (flag) {
+ value++;
+ if (limit && value > MAX_ID_VALUE)
+ value = MIN_ID_VALUE;
+ flag = 0;
+ EXEC SQL REPEATED SELECT uid INTO :flag FROM users WHERE uid = :value;
+ if (sqlfail()) sqlexit();
+ if (sqlca.sqlerrd[2] == 0)
+ flag = 0;
+ }
+
+ retval = value++;
+ if (limit && value > MAX_ID_VALUE)
+ value = MIN_ID_VALUE;
+ EXEC SQL REPEATED UPDATE numvalues SET value = :value WHERE name = 'uid';
+ if (sqlca.sqlcode != 0) {
+ com_err(whoami, 0, "ingres error %d", sqlca.sqlcode);
+ exit(1);
+ }
+ return(retval);
+}
+
+
+sqlexit()
+{
+ if (sqlca.sqlcode == SQL_DEADLOCK)
+ com_err(whoami, MR_DEADLOCK, "unrecoverable ingres error %d",
+ sqlca.sqlcode);
+ else
+ com_err(whoami, 0, "ingres error %d", sqlca.sqlcode);
+ EXEC SQL ROLLBACK WORK;
+ exit(1);
}