]> andersk Git - moira.git/blob - regtape/students.pc
add INSTALL=@INSTALL@
[moira.git] / regtape / students.pc
1 /* $Id$
2  *
3  * Load data into Moira from Registrar's 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>.
8  */
9
10 #include <mit-copyright.h>
11 #include <moira.h>
12 #include <moira_site.h>
13 #include <moira_schema.h>
14
15 #include <ctype.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <time.h>
20
21 EXEC SQL INCLUDE sqlca;
22 extern void sqlglm(char *, unsigned int *, unsigned int *);
23
24 RCSID("$Header$");
25
26 #define WHO 11859               /* root */
27 #define PROG "stu-tape"
28
29 #define MAX_ID_VALUE    31999
30 #define MIN_ID_VALUE    101
31
32 /* File format is:
33
34 0-29    name
35 30-38   id number
36 50-54   school code
37 55-79   year
38 80-109  address
39 110-124 room
40 125-144 city
41 145-158 state
42 159-168 dorm phone
43 169-212 home address
44 213-232 home city
45 243-251 mit phone (?)
46 */
47
48 #define LOC_NAME 0
49 #define LOC_ID 30
50 #define LOC_COURSE 50
51 #define LOC_YEAR 55
52 #define LOC_ADDRESS 80
53 #define LOC_DORM_ROOM 110
54 #define LOC_CITY 125
55 #define LOC_STATE 145
56 #define LOC_DPHONE 155
57 #define LOC_MPHONE 243
58
59 #define LEN_NAME 30
60 #define LEN_ID 9
61 #define LEN_COURSE 5
62 #define LEN_YEAR 25
63 #define LEN_ADDRESS 30
64 #define LEN_DORM_ROOM 15
65 #define LEN_CITY 20
66 #define LEN_STATE 10
67 #define LEN_DPHONE 12
68 #define LEN_MPHONE 12
69
70 struct entry {
71   char *name;
72   char *last;
73   char *first;
74   char *middle;
75   char *title;
76   char *id;
77   char *eid;
78   char *course;
79   char *year;
80   char *address;
81   char *dorm;
82   char *city;
83   char *state;
84   char *dphone;
85   char *mphone;
86   char *class;
87 };
88
89 char *whoami;
90 int newfinger = 0;
91
92 struct entry *get_next_entry(FILE *in);
93 void process_entry(struct entry *e);
94 void newuser(struct entry *e);
95 int set_next_users_id(int limit);
96 int set_next_uid(int limit);
97 void sqlexit(void);
98 void dbmserr(char *where, int what);
99
100 #define SQL_DUPLICATE -2112
101 #define sqlfail() (sqlca.sqlcode && sqlca.sqlcode != 1403)
102
103 int main(int argc, char **argv)
104 {
105   FILE *in;
106   struct entry *e;
107   int i, wait = 0;
108   char buf[80], *file = NULL;
109   EXEC SQL BEGIN DECLARE SECTION;
110   char *db = "moira";
111   EXEC SQL END DECLARE SECTION;
112
113   whoami = strrchr(argv[0], '/');
114   if (whoami)
115     whoami++;
116   else
117     whoami = argv[0];
118
119   setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
120   setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
121
122   for (i = 1; i < argc; i++)
123     {
124       if (!strcmp(argv[i], "-w"))
125         wait++;
126       else if (!strcmp(argv[i], "-n"))
127         newfinger++;
128       else if (file)
129         fprintf(stderr, "Usage: %s [-w] [-D] [-n] inputfile\n", whoami);
130       else
131         file = argv[i];
132     }
133
134   in = fopen(file, "r");
135   if (!in)
136     {
137       fprintf(stderr, "Unable to open %s for input\n", file);
138       exit(1);
139     }
140
141   initialize_sms_error_table();
142
143   EXEC SQL CONNECT :db IDENTIFIED BY :db;
144   if (sqlca.sqlcode)
145     {
146       dbmserr("connecting", sqlca.sqlcode);
147       exit(1);
148     }
149
150   while ((e = get_next_entry(in)))
151     {
152       process_entry(e);
153       EXEC SQL COMMIT WORK;
154       if (sqlca.sqlcode)
155         {
156           dbmserr("committing work", sqlca.sqlcode);
157           exit(1);
158         }
159       if (wait)
160         {
161           printf("Next");
162           fflush(stdout);
163           fgets(buf, sizeof(buf), stdin);
164         }
165     }
166
167   exit(0);
168 }
169
170
171 struct entry *get_next_entry(FILE *in)
172 {
173   static struct entry e;
174   static char buf[BUFSIZ], eid[16], classbuf[10];
175   static char name[LEN_NAME + 1], id[LEN_ID + 1], course[LEN_COURSE + 1];
176   static char year[LEN_YEAR + 1], address[LEN_ADDRESS + 1];
177   static char dorm_room[LEN_DORM_ROOM + 1], city[LEN_CITY + 1];
178   static char state[LEN_STATE + 1], dphone[LEN_DPHONE + 1];
179   static char mphone[LEN_MPHONE + 1], sname[LEN_NAME + 1], title[128];
180   static int nyear = 0;
181   int ends_jr, ends_iii, ends_iv, ends_sr, ends_ii, ends_v;
182   char *p;
183
184   if (nyear == 0)
185     {
186       struct tm *tm;
187       struct timeval tv;
188
189       gettimeofday(&tv, NULL);
190       tm = localtime(&tv.tv_sec);
191       nyear = tm->tm_year;
192       if (tm->tm_mon > 5)
193         nyear++;
194     }
195
196   if (!fgets(buf, sizeof(buf), in))
197     return NULL;
198
199   strncpy(name, &buf[LOC_NAME], LEN_NAME);
200   name[LEN_NAME] = '\0';
201   strncpy(id, &buf[LOC_ID], LEN_ID);
202   id[LEN_ID] = '\0';
203   strncpy(course, &buf[LOC_COURSE], LEN_COURSE);
204   course[LEN_COURSE] = '\0';
205   strncpy(year, &buf[LOC_YEAR], LEN_YEAR);
206   year[LEN_YEAR] = '\0';
207   strncpy(address, &buf[LOC_ADDRESS], LEN_ADDRESS);
208   address[LEN_ADDRESS] = '\0';
209   strncpy(dorm_room, &buf[LOC_DORM_ROOM], LEN_DORM_ROOM);
210   dorm_room[LEN_DORM_ROOM] = '\0';
211   strncpy(city, &buf[LOC_CITY], LEN_CITY);
212   city[LEN_CITY] = '\0';
213   strncpy(state, &buf[LOC_STATE], LEN_STATE);
214   state[LEN_STATE] = '\0';
215   strncpy(dphone, &buf[LOC_DPHONE], LEN_DPHONE);
216   dphone[LEN_DPHONE] = '\0';
217   strncpy(mphone, &buf[LOC_MPHONE], LEN_MPHONE);
218   mphone[LEN_MPHONE] = '\0';
219
220   strcpy(sname, name);
221   e.name = strtrim(sname);
222   p = strchr(name, ',');
223   if (p)
224     *p = '\0';
225   e.last = strtrim(name);
226   if (p)
227     {
228       p++;
229       while (isspace(*p))
230         p++;
231       e.first = p;
232       if ((p = strchr(e.first, ' ')))
233         {
234           *p = '\0';
235           e.first = strtrim(e.first);
236           e.middle = strtrim(p + 1);
237         }
238       else
239         {
240           e.first = strtrim(e.first);
241           e.middle = "";
242         }
243     }
244   else
245     {
246       e.first = "";
247       e.middle = "";
248     }
249   ends_jr = ends_iii = ends_iv = ends_sr = ends_ii = ends_v = 0;
250   LookForSt(e.last);
251   LookForO(e.last);
252   LookForJrAndIII(e.last, &ends_sr, &ends_jr, &ends_iii, &ends_iv,
253                   &ends_ii, &ends_v);
254   LookForJrAndIII(e.first, &ends_sr, &ends_jr, &ends_iii, &ends_iv,
255                   &ends_ii, &ends_v);
256   FixCase(e.last);
257   FixCase(e.first);
258   FixCase(e.middle);
259
260   e.id = id;
261   e.id[LEN_ID] = '\0';
262   e.eid = eid;
263   EncryptID(e.eid, e.id, e.first, e.last);
264
265   e.year = strtrim(year);
266   e.title = title;
267   if (e.year[0] == 'G')
268     {
269       e.class = "G";
270       sprintf(title, "Grad Student");
271     }
272   else
273     {
274       e.class = classbuf;
275       sprintf(classbuf, "%d", nyear + 4 - atoi(e.year) + 1900);
276       sprintf(title, "Undergrad (class of %s)", classbuf);
277     }
278
279   e.course = strtrim(course);
280   e.address = strtrim(address);
281   e.dorm = strtrim(dorm_room);
282   e.city = strtrim(city);
283   e.state = strtrim(state);
284   e.dphone = strtrim(dphone);
285   e.mphone = strtrim(mphone);
286   return &e;
287 }
288
289
290 void process_entry(struct entry *e)
291 {
292   int changed, nochange, encrypted;
293   char buf[MAX_FIELD_WIDTH], *from, *to;
294   EXEC SQL BEGIN DECLARE SECTION;
295   char *first, *last, *middle, *eid, *sid, *name, *rdept;
296   char *rtitle, *rophone, *rhphone, *prog;
297   char class[USERS_TYPE_SIZE], haddr[USERS_HOME_ADDR_SIZE];
298   char hphone[USERS_HOME_PHONE_SIZE], ophone[USERS_OFFICE_PHONE_SIZE];
299   char dept[USERS_DEPARTMENT_SIZE], raddr[USERS_XADDRESS_SIZE];
300   char dfirst[USERS_FIRST_SIZE], dlast[USERS_LAST_SIZE];
301   char dmiddle[USERS_MIDDLE_SIZE];
302   int id, status, who;
303   EXEC SQL END DECLARE SECTION;
304
305   who = WHO;
306   prog = PROG;
307   first = e->first;
308   if (strlen(first) > USERS_FIRST_SIZE - 1)
309     first[USERS_FIRST_SIZE - 1] = '\0';
310   last = e->last;
311   if (strlen(last) > USERS_LAST_SIZE - 1)
312     last[USERS_LAST_SIZE - 1] = '\0';
313   middle = e->middle;
314   if (strlen(middle) > USERS_MIDDLE_SIZE - 1)
315     middle[USERS_MIDDLE_SIZE - 1] = '\0';
316   eid = e->eid;
317   sid = e->id;
318   id = 0;
319   encrypted = 0;
320
321   /* Get user info */
322   EXEC SQL SELECT users_id, first, last, middle, type, home_addr, home_phone,
323     office_phone, status, department
324     INTO :id, :dfirst, :dlast, :dmiddle, :class, :haddr, :hphone,
325     :ophone, :status, :dept
326     FROM users
327     WHERE clearid = :sid;
328   if (sqlfail())
329     {
330       if (sqlca.sqlcode == SQL_DUPLICATE)
331         {
332           com_err(whoami, 0, "duplicate ID number %s on user %s %s",
333                   sid, first, last);
334           return;
335         }
336       else
337         sqlexit();
338     }
339   if (id == 0)
340     {
341       EXEC SQL SELECT users_id, first, last, middle, type, home_addr,
342         home_phone, office_phone, status, department
343         INTO :id, :dfirst, :dlast, :dmiddle, :class, :haddr,
344         :hphone, :ophone, :status, :dept
345         FROM users
346         WHERE last = :last and first = :first and clearid = :eid;
347       if (sqlfail())
348         sqlexit();
349       encrypted++;
350       if (id == 0)
351         {
352           newuser(e);
353           return;
354         }
355     }
356
357   /* See if class changed: if it's different, and the value in the database
358    * is not STAFF or SIPBMEM, and the value from the tape is actually
359    * meaningful, then update the database.  Since they were on the
360    * students tape, make the account usable.
361    */
362   if (strcmp(e->class, strtrim(class)) &&
363       strcmp(class, "STAFF") && strcmp(class, "SIPBMEM") &&
364       e->year[0])
365     {
366       com_err(whoami, 0, "updating class for user %s %s from %s to %s",
367               first, last, class, e->class);
368       if (status == US_NOT_ALLOWED)
369         status = US_NO_LOGIN_YET;
370       if (status == US_ENROLL_NOT_ALLOWED)
371         status = US_ENROLLED;
372       strcpy(class, e->class);
373       EXEC SQL UPDATE users
374         SET type = NVL(:class, CHR(0)), status = :status, modtime = SYSDATE,
375         modby = :who, modwith = :prog
376         WHERE users_id = :id;
377       if (sqlca.sqlcode)
378         {
379           dbmserr("updating class", sqlca.sqlcode);
380           exit(1);
381         }
382     }
383
384   /* Update name if necessary */
385   if (strcmp(first, strtrim(dfirst)) ||
386       strcmp(last, strtrim(dlast)) ||
387       strcmp(middle, strtrim(dmiddle)))
388     {
389       com_err(whoami, 0, "updating real name for %s %s", first, last);
390       EXEC SQL UPDATE users
391         SET first = NVL(:first, CHR(0)), last = NVL(:last, CHR(0)),
392         middle = NVL(:middle, CHR(0)), modby = :who, modwith = :prog,
393         modtime = SYSDATE
394         WHERE users_id = :id;
395       if (sqlca.sqlcode != 0)
396         {
397           dbmserr("updating name", sqlca.sqlcode);
398           exit(1);
399         }
400     }
401
402   /* Deal with updating the finger info if necessary */
403   changed = nochange = 0;
404   if (encrypted)
405     changed++;
406   strcpy(buf, e->address);
407   if (*e->dorm)
408     {
409       strcat(buf, " ");
410       strcat(buf, e->dorm);
411     }
412   if (*e->city)
413     {
414       strcat(buf, " ");
415       strcat(buf, e->city);
416     }
417   FixCase(buf);
418   if (*e->state)
419     {
420       strcat(buf, " ");
421       strcat(buf, e->state);
422     }
423   while ((to = strchr(buf, ',')))
424     *to = ';';
425   while ((to = strchr(buf, ':')))
426     *to = ';';
427   if (newfinger)
428     {
429       if (haddr[0] == ' ')
430         {
431           strncpy(haddr, buf, USERS_HOME_ADDR_SIZE - 1);
432           haddr[USERS_HOME_ADDR_SIZE - 1] = '\0';
433           changed++;
434         }
435       else if (strncmp(strtrim(haddr), buf, USERS_HOME_ADDR_SIZE - 1))
436         nochange++;
437     }
438   else
439     {
440       if (strncmp(strtrim(haddr), buf, USERS_HOME_ADDR_SIZE - 1))
441         changed++;
442       strncpy(haddr, buf, USERS_HOME_ADDR_SIZE - 1);
443       haddr[USERS_HOME_ADDR_SIZE - 1] = '\0';
444     }
445   from = e->dphone;
446   to = buf;
447   while (*from)
448     {
449       if (isdigit(*from))
450         *to++ = *from;
451       from++;
452     }
453   *to = '\0';
454   if (newfinger)
455     {
456       if (hphone[0] == ' ')
457         {
458           strncpy(hphone, buf, USERS_HOME_PHONE_SIZE - 1);
459           hphone[USERS_HOME_PHONE_SIZE - 1] = '\0';
460         }
461       else if (strncmp(strtrim(hphone), buf, USERS_HOME_PHONE_SIZE - 1))
462         nochange++;
463     }
464   else
465     {
466       if (strncmp(strtrim(hphone), buf, USERS_HOME_PHONE_SIZE - 1))
467         changed++;
468       strncpy(hphone, buf, USERS_HOME_PHONE_SIZE - 1);
469       hphone[USERS_HOME_PHONE_SIZE - 1] = '\0';
470     }
471   from = e->mphone;
472   to = buf;
473   while (*from)
474     {
475       if (isdigit(*from))
476         *to++ = *from;
477       from++;
478     }
479   *to = '\0';
480   if (newfinger)
481     {
482       if (ophone[0] == ' ')
483         {
484           strncpy(ophone, buf, USERS_OFFICE_PHONE_SIZE - 1);
485           ophone[USERS_OFFICE_PHONE_SIZE - 1] = '\0';
486         }
487       else if (strncmp(strtrim(ophone), buf, USERS_OFFICE_PHONE_SIZE - 1))
488         nochange++;
489     }
490   else
491     {
492       if (strncmp(strtrim(ophone), buf, USERS_OFFICE_PHONE_SIZE - 1))
493         changed++;
494       strncpy(ophone, buf, USERS_OFFICE_PHONE_SIZE - 1);
495       ophone[USERS_OFFICE_PHONE_SIZE - 1] = '\0';
496     }
497   e->course = e->course;
498   if (newfinger)
499     {
500       if (dept[0] == ' ')
501         {
502           strncpy(dept, e->course, USERS_DEPARTMENT_SIZE - 1);
503           dept[USERS_DEPARTMENT_SIZE - 1] = '\0';
504         }
505       else if (strncmp(strtrim(dept), e->course, USERS_DEPARTMENT_SIZE - 1))
506         nochange++;
507     }
508   else
509     {
510       if (strncmp(strtrim(dept), e->course, USERS_DEPARTMENT_SIZE - 1))
511         changed++;
512       strncpy(dept, e->course, USERS_DEPARTMENT_SIZE - 1);
513       dept[USERS_DEPARTMENT_SIZE - 1] = '\0';
514     }
515   sid = e->id;
516   name = e->name;
517   rdept = e->course;
518   rtitle = e->title;
519   rophone = e->mphone;
520   rhphone = e->dphone;
521   strcpy(raddr, e->address);
522   if (*e->dorm)
523     {
524       strcat(raddr, " ");
525       strcat(raddr, e->dorm);
526     }
527   strcat(raddr, "|");
528   if (*e->city)
529     {
530       strcat(raddr, e->city);
531       FixCase(raddr);
532       if (*e->state)
533         {
534           strcat(raddr, " ");
535           if (isupper(e->state[0]) && isupper(e->state[1]) &&
536               isdigit(e->state[2]) && isdigit(e->state[3]) &&
537               isdigit(e->state[4]) && isdigit(e->state[5]) &&
538               isdigit(e->state[6]))
539             {
540               sprintf(buf, "%c%c  %s", e->state[0], e->state[1],
541                       &(e->state[2]));
542               strcat(raddr, buf);
543             }
544           else
545             strcat(raddr, e->state);
546         }
547     }
548   else
549     {
550       FixCase(raddr);
551       strcat(raddr, "MIT INTERDEPARTMENTAL MAIL");
552     }
553   if (changed)
554     {
555       com_err(whoami, 0, "updating finger for %s %s", first, last);
556       EXEC SQL UPDATE users
557         SET home_addr = NVL(:haddr, CHR(0)), home_phone = NVL(:hphone, CHR(0)),
558         office_phone = NVL(:ophone, CHR(0)), department = NVL(:dept, CHR(0)),
559         fmodtime = SYSDATE, fmodby = :who, fmodwith = :prog,
560         xname = NVL(:name, CHR(0)), xdept = NVL(:rdept, CHR(0)),
561         xtitle = NVL(:rtitle, CHR(0)), xaddress = NVL(:raddr, CHR(0)),
562         xphone1 = NVL(:rhphone, CHR(0)), xphone2 = NVL(:rophone, CHR(0)),
563         xmodtime = SYSDATE, clearid = NVL(:sid, CHR(0))
564         WHERE users_id = :id;
565       if (sqlca.sqlcode)
566         {
567           dbmserr(NULL, sqlca.sqlcode);
568           exit(1);
569         }
570     }
571   else
572     {
573       EXEC SQL UPDATE users
574         SET xname = NVL(:name, CHR(0)), xdept = NVL(:rdept, CHR(0)),
575         xtitle = NVL(:rtitle, CHR(0)), xaddress = NVL(:raddr, CHR(0)),
576         xphone1 = NVL(:rhphone, CHR(0)), xphone2 = NVL(:rophone, CHR(0)),
577         xmodtime = SYSDATE, clearid = NVL(:sid, CHR(0))
578         WHERE users_id = :id;
579       if (sqlca.sqlcode)
580         {
581           dbmserr(NULL, sqlca.sqlcode);
582           exit(1);
583         }
584     }
585 }
586
587 void newuser(struct entry *e)
588 {
589   char buf[512], *from, *to;
590   EXEC SQL BEGIN DECLARE SECTION;
591   int id, uid, who;
592   char *last, *first, *class, *middle, login[USERS_LOGIN_SIZE], *sid;
593   char fullname[USERS_FULLNAME_SIZE], *prog;
594   char haddr[USERS_HOME_ADDR_SIZE], hphone[USERS_HOME_PHONE_SIZE];
595   char ophone[USERS_OFFICE_PHONE_SIZE], dept[USERS_DEPARTMENT_SIZE];
596   char *title, raddr[USERS_XADDRESS_SIZE], *name;
597   EXEC SQL END DECLARE SECTION;
598
599   who = WHO;
600   prog = PROG;
601   strcpy(buf, e->address);
602   if (*e->dorm)
603     {
604       strcat(buf, " ");
605       strcat(buf, e->dorm);
606     }
607   if (*e->city)
608     {
609       strcat(buf, " ");
610       strcat(buf, e->city);
611     }
612   if (*e->state)
613     {
614       strcat(buf, " ");
615       strcat(buf, e->state);
616     }
617   strncpy(haddr, buf, USERS_HOME_ADDR_SIZE - 1);
618   haddr[USERS_HOME_ADDR_SIZE - 1] = '\0';
619   from = e->dphone;
620   to = buf;
621   while (*from)
622     {
623       if (isdigit(*from))
624         *to++ = *from;
625       from++;
626     }
627   *to = '\0';
628   strncpy(hphone, buf, USERS_HOME_PHONE_SIZE - 1);
629   hphone[USERS_HOME_PHONE_SIZE - 1] = '\0';
630   from = e->mphone;
631   to = buf;
632   while (*from)
633     {
634       if (isdigit(*from))
635         *to++ = *from;
636       from++;
637     }
638   *to = '\0';
639   strncpy(ophone, buf, USERS_OFFICE_PHONE_SIZE - 1);
640   ophone[USERS_OFFICE_PHONE_SIZE - 1] = '\0';
641   strncpy(dept, e->course, USERS_DEPARTMENT_SIZE - 1);
642   dept[USERS_DEPARTMENT_SIZE - 1] = '\0';
643
644   id = set_next_users_id(0);
645   uid = set_next_uid(1);
646   sprintf(login, "#%d", uid);
647   last = e->last;
648   first = e->first;
649   middle = e->middle;
650   sid = e->id;
651   class = e->class;
652   title = e->title;
653   if (*middle)
654     sprintf(fullname, "%s %s %s", first, middle, last);
655   else
656     sprintf(fullname, "%s %s", first, last);
657   name = e->name;
658   strcpy(raddr, e->address);
659   if (*e->dorm)
660     {
661       strcat(raddr, " ");
662       strcat(raddr, e->dorm);
663     }
664   strcat(raddr, "|");
665   if (*e->city)
666     {
667       strcat(raddr, e->city);
668       FixCase(raddr);
669       if (*e->state)
670         {
671           strcat(raddr, " ");
672           if (isupper(e->state[0]) && isupper(e->state[1]) &&
673               isdigit(e->state[2]) && isdigit(e->state[3]) &&
674               isdigit(e->state[4]) && isdigit(e->state[5]) &&
675               isdigit(e->state[6]))
676             {
677               sprintf(buf, "%c%c  %s", e->state[0], e->state[1],
678                       &(e->state[2]));
679               strcat(raddr, buf);
680             }
681           else
682             strcat(raddr, e->state);
683         }
684     }
685   else
686     {
687       FixCase(raddr);
688       strcat(raddr, "MIT INTERDEPARTMENTAL MAIL");
689     }
690   EXEC SQL INSERT INTO users
691     (login, users_id, unix_uid, shell, last, first, middle, status,
692      clearid, type, modtime, modby, modwith, fullname, home_addr,
693      home_phone, office_phone, department, fmodtime, fmodby, fmodwith,
694      potype, xname, xdept, xtitle, xaddress, xphone1, xphone2, xmodtime)
695     VALUES (:login, :id, :uid, '/bin/athena/tcsh', NVL(:last, CHR(0)),
696             NVL(:first, CHR(0)), NVL(:middle, CHR(0)), 0, NVL(:sid, CHR(0)),
697             NVL(:class, CHR(0)), SYSDATE, :who, :prog, NVL(:fullname, CHR(0)),
698             NVL(:haddr, CHR(0)), NVL(:hphone, CHR(0)), NVL(:ophone, CHR(0)),
699             NVL(:dept, CHR(0)), SYSDATE, :who, :prog, 'NONE',
700             NVL(:name, CHR(0)), NVL(:dept, CHR(0)), NVL(:title, CHR(0)),
701             NVL(:raddr, CHR(0)), NVL(:hphone, CHR(0)), NVL(:ophone, CHR(0)),
702             SYSDATE);
703   if (sqlca.sqlcode)
704     {
705       dbmserr("adding user", sqlca.sqlcode);
706       exit(1);
707     }
708   else
709     com_err(whoami, 0, "adding user %s %s", e->first, e->last);
710 }
711
712
713 int set_next_users_id(int limit)
714 {
715   EXEC SQL BEGIN DECLARE SECTION;
716   int flag, value, retval;
717   EXEC SQL END DECLARE SECTION;
718
719   EXEC SQL SELECT value INTO :value FROM numvalues
720     WHERE name = 'users_id';
721   if (sqlfail())
722     sqlexit();
723   if (sqlca.sqlerrd[2] != 1)
724     {
725       EXEC SQL ROLLBACK;
726       com_err(whoami, MR_INTERNAL, "values table inconsistancy");
727       exit(1);
728     }
729
730   flag = 0;
731   EXEC SQL SELECT users_id INTO :flag FROM users
732     WHERE users_id = :value;
733   if (sqlfail())
734     sqlexit();
735   if (sqlca.sqlerrd[2] == 0)
736     flag = 0;
737   while (flag)
738     {
739       value++;
740       if (limit && value > MAX_ID_VALUE)
741         value = MIN_ID_VALUE;
742       flag = 0;
743       EXEC SQL SELECT users_id INTO :flag FROM users
744         WHERE users_id = :value;
745       if (sqlfail())
746         sqlexit();
747       if (sqlca.sqlerrd[2] == 0)
748         flag = 0;
749     }
750
751   retval = value++;
752   if (limit && value > MAX_ID_VALUE)
753     value = MIN_ID_VALUE;
754   EXEC SQL UPDATE numvalues SET value = :value
755     WHERE name = 'users_id';
756   if (sqlca.sqlcode)
757     {
758       dbmserr("updating numvalues", sqlca.sqlcode);
759       exit(1);
760     }
761   return retval;
762 }
763
764 int set_next_uid(int limit)
765 {
766   EXEC SQL BEGIN DECLARE SECTION;
767   int flag, value, retval;
768   EXEC SQL END DECLARE SECTION;
769
770   EXEC SQL SELECT value INTO :value FROM numvalues
771     WHERE name = 'unix_uid';
772   if (sqlfail())
773     sqlexit();
774   if (sqlca.sqlerrd[2] != 1)
775     {
776       EXEC SQL ROLLBACK;
777       com_err(whoami, MR_INTERNAL, "values table inconsistancy");
778       exit(1);
779     }
780
781   flag = 0;
782   EXEC SQL SELECT unix_uid INTO :flag FROM users WHERE unix_uid = :value;
783   if (sqlfail())
784     sqlexit();
785   if (sqlca.sqlerrd[2] == 0)
786     flag = 0;
787   while (flag)
788     {
789       value++;
790       if (limit && value > MAX_ID_VALUE)
791         value = MIN_ID_VALUE;
792       flag = 0;
793       EXEC SQL SELECT unix_uid INTO :flag FROM users WHERE unix_uid = :value;
794       if (sqlfail())
795         sqlexit();
796       if (sqlca.sqlerrd[2] == 0)
797         flag = 0;
798     }
799
800   retval = value++;
801   if (limit && value > MAX_ID_VALUE)
802     value = MIN_ID_VALUE;
803   EXEC SQL UPDATE numvalues SET value = :value WHERE name = 'unix_uid';
804   if (sqlca.sqlcode)
805     {
806       dbmserr("updating numvalues", sqlca.sqlcode);
807       exit(1);
808     }
809   return retval;
810 }
811
812
813 void sqlexit(void)
814 {
815   dbmserr(NULL, sqlca.sqlcode);
816   EXEC SQL ROLLBACK WORK;
817   exit(1);
818 }
819
820 void dbmserr(char *where, int what)
821 {
822   char err_msg[256];
823   int bufsize = 256, msglength = 0;
824
825   sqlglm(err_msg, &bufsize, &msglength);
826   err_msg[msglength] = '\0';
827
828   if (where)
829     com_err(whoami, 0, "DBMS error %swhile %s", err_msg, where);
830   else
831     com_err(whoami, 0, "DBMS error %s", err_msg);
832 }
This page took 2.228214 seconds and 5 git commands to generate.