]>
Commit | Line | Data |
---|---|---|
093c49c9 | 1 | /* $Header$ |
2 | */ | |
3 | ||
4 | #include <stdio.h> | |
5 | #include <strings.h> | |
6 | #include <ctype.h> | |
7 | #include <sys/time.h> | |
8 | #include <sms.h> | |
9 | #include <sms_app.h> | |
10 | ||
11 | ||
12 | /* File format is: | |
13 | ||
14 | 0-29 name | |
15 | 30-38 id number | |
16 | 50-54 school code | |
17 | 55-79 year | |
18 | 80-109 address | |
19 | 110-124 room | |
20 | 125-144 city | |
21 | 145-158 state | |
22 | 159-168 dorm phone | |
23 | 169-212 home address | |
24 | 213-232 home city | |
25 | 243-251 mit phone (?) | |
26 | */ | |
27 | ||
28 | #define LOC_NAME 0 | |
29 | #define LOC_ID 30 | |
30 | #define LOC_COURSE 50 | |
31 | #define LOC_YEAR 55 | |
32 | #define LOC_ADDRESS 80 | |
33 | #define LOC_DORM_ROOM 110 | |
34 | #define LOC_CITY 125 | |
35 | #define LOC_STATE 145 | |
36 | #define LOC_DORM_PHONE 159 | |
37 | #define LOC_MIT_PHONE1 243 | |
38 | ||
39 | #define LEN_NAME 29 | |
40 | #define LEN_ID 9 | |
41 | #define LEN_COURSE 3 | |
42 | #define LEN_YEAR 23 | |
43 | #define LEN_ADDRESS 29 | |
44 | #define LEN_DORM_ROOM 14 | |
45 | #define LEN_CITY 28 | |
46 | #define LEN_STATE 12 | |
47 | #define LEN_DPHONE 9 | |
48 | #define LEN_MPHONE 9 | |
49 | ||
50 | struct entry { | |
51 | char *last; | |
52 | char *first; | |
53 | char *middle; | |
54 | char *title; | |
55 | char *id; | |
56 | char *eid; | |
57 | char *course; | |
58 | char *year; | |
59 | char *address; | |
60 | char *dorm; | |
61 | char *city; | |
62 | char *state; | |
63 | char *dphone; | |
64 | char *mphone; | |
65 | char *class; | |
66 | char **argv; | |
67 | char **finger; | |
68 | }; | |
69 | ||
70 | ||
71 | char *whoami; | |
72 | ||
73 | ||
74 | main(argc, argv) | |
75 | int argc; | |
76 | char **argv; | |
77 | { | |
78 | FILE *in; | |
79 | struct entry *e, *get_next_entry(); | |
80 | int status, wait = 0; | |
81 | char buf[BUFSIZ]; | |
82 | ||
83 | whoami = rindex(argv[0], '/'); | |
84 | if (whoami) | |
85 | whoami++; | |
86 | else | |
87 | whoami = argv[0]; | |
88 | ||
89 | if (argc > 2) | |
90 | wait++; | |
91 | ||
92 | in = fopen(argv[1], "r"); | |
93 | if (in == NULL) { | |
94 | fprintf(stderr, "Unable to open %s for input\n", argv[1]); | |
95 | exit(1); | |
96 | } | |
97 | ||
98 | if (status = sms_connect("")) { | |
99 | com_err(whoami, status, " connecting to Moira"); | |
100 | exit(1); | |
101 | } | |
102 | if (status = sms_auth(whoami)) { | |
103 | com_err(whoami, status, " authenticating"); | |
104 | exit(1); | |
105 | } | |
106 | while (e = get_next_entry(in)) { | |
107 | process_entry(e); | |
108 | if (wait) { | |
109 | printf("Next"); | |
110 | fflush(stdout); | |
111 | gets(buf); | |
112 | } | |
113 | } | |
114 | ||
115 | sms_disconnect(); | |
116 | exit(0); | |
117 | } | |
118 | ||
119 | ||
120 | struct entry *get_next_entry(in) | |
121 | FILE *in; | |
122 | { | |
123 | static struct entry e; | |
124 | static char buf[BUFSIZ], eid[16], classbuf[10], titlebuf[12]; | |
125 | static int year = 0; | |
126 | int ends_jr, ends_iii, ends_iv; | |
127 | char *p; | |
128 | ||
129 | if (year == 0) { | |
130 | struct tm *tm; | |
131 | struct timeval tv; | |
132 | ||
133 | gettimeofday(&tv, NULL); | |
134 | tm = localtime(&tv.tv_sec); | |
135 | year = tm->tm_year; | |
136 | if (tm->tm_mon > 5) | |
137 | year++; | |
138 | } | |
139 | ||
140 | fgets(buf, sizeof(buf), in); | |
141 | buf[LEN_NAME] = 0; | |
142 | p = index(&buf[LOC_NAME], ','); | |
143 | if (p) | |
144 | *p = 0; | |
145 | e.last = strtrim(&buf[LOC_NAME]); | |
146 | if (p) { | |
147 | e.first = p + 2; | |
148 | if (p = index(e.first, ' ')) { | |
149 | *p = 0; | |
150 | e.middle = strtrim(p + 1); | |
151 | } else | |
152 | e.middle = ""; | |
153 | } else | |
154 | e.first = ""; | |
155 | e.first = strtrim(e.first); | |
156 | ends_jr = ends_iii = ends_iv = 0; | |
157 | LookForSt(e.last); | |
158 | LookForO(e.last); | |
159 | LookForJrAndIII(e.last, &ends_jr, &ends_iii, &ends_iv); | |
160 | LookForJrAndIII(e.first, &ends_jr, &ends_iii, &ends_iv); | |
161 | FixCase(e.last); | |
162 | FixCase(e.first); | |
163 | FixCase(e.middle); | |
164 | e.title = titlebuf; | |
165 | titlebuf[0] = 0; | |
166 | AppendJrOrIII(titlebuf, &ends_jr, &ends_iii, &ends_iv); | |
167 | ||
168 | e.id = &buf[LOC_ID]; | |
169 | e.id[LEN_ID] = 0; | |
170 | e.eid = eid; | |
171 | EncryptID(e.eid, e.id, e.first, e.last); | |
172 | ||
173 | e.course = &buf[LOC_COURSE]; | |
174 | e.course[LEN_COURSE] = 0; | |
175 | e.year = &buf[LOC_YEAR]; | |
176 | e.year[LEN_YEAR] = 0; | |
177 | if (e.year[0] == 'G') | |
178 | e.class = "G"; | |
179 | else { | |
180 | e.class = classbuf; | |
181 | sprintf(classbuf, "%d", year + 4 - atoi(e.year) + 1900); | |
182 | } | |
183 | e.address = &buf[LOC_ADDRESS]; | |
184 | e.address[LEN_ADDRESS] = 0; | |
185 | e.dorm = &buf[LOC_DORM_ROOM]; | |
186 | e.dorm[LEN_DORM_ROOM] = 0; | |
187 | e.city = &buf[LOC_CITY]; | |
188 | e.city[LEN_CITY] = 0; | |
189 | e.state = &buf[LOC_STATE]; | |
190 | e.state[LEN_STATE] = 0; | |
191 | e.dphone = &buf[LOC_DORM_PHONE]; | |
192 | e.dphone[LEN_DPHONE] = 0; | |
193 | e.mphone = &buf[LOC_MIT_PHONE1]; | |
194 | e.mphone[LEN_MPHONE] = 0; | |
195 | return(&e); | |
196 | } | |
197 | ||
198 | ||
199 | char **copy_argv(argc, argv) | |
200 | int argc; | |
201 | char **argv; | |
202 | { | |
203 | char **ret; | |
204 | ||
205 | ret = (char **) malloc((argc + 1) * sizeof(char *)); | |
206 | ret[argc] = NULL; | |
207 | while (argc-- > 0) | |
208 | ret[argc] = strsave(argv[argc]); | |
209 | return(ret); | |
210 | } | |
211 | ||
212 | ||
213 | free_argv(argv) | |
214 | char **argv; | |
215 | { | |
216 | char **p; | |
217 | ||
218 | for (p = argv; *p; p++) | |
219 | free(p); | |
220 | free(argv); | |
221 | } | |
222 | ||
223 | ||
224 | getusers(argc, argv, e) | |
225 | int argc; | |
226 | char **argv; | |
227 | struct entry *e; | |
228 | { | |
229 | if (!strcmp(e->eid, argv[U_MITID])) { | |
230 | e->argv = copy_argv(argc, argv); | |
231 | return(SMS_ABORT); | |
232 | } | |
233 | #ifdef DEBUG | |
234 | com_err(whoami, 0, "comparing %s and %s", e->eid, argv[U_MITID]); | |
235 | #endif | |
236 | return(SMS_CONT); | |
237 | } | |
238 | ||
239 | ||
240 | getfinger(argc, argv, e) | |
241 | int argc; | |
242 | char **argv; | |
243 | struct entry *e; | |
244 | { | |
245 | e->finger = copy_argv(argc, argv); | |
246 | return(SMS_ABORT); | |
247 | } | |
248 | ||
249 | ||
250 | scream() | |
251 | { | |
252 | com_err(whoami, 0, "Programmer botch!"); | |
253 | } | |
254 | ||
255 | ||
256 | process_entry(e) | |
257 | struct entry *e; | |
258 | { | |
259 | int status, changed; | |
260 | char *argv[U_END], buf[BUFSIZ], *from, *to; | |
261 | ||
262 | argv[0] = e->first; | |
263 | argv[1] = e->last; | |
264 | e->argv = NULL; | |
265 | status = sms_query("get_user_by_name", 2, argv, getusers, e); | |
266 | if (status == SMS_NO_MATCH || e->argv == NULL) { | |
267 | newuser(argv, e); | |
268 | return; | |
269 | } else if (status != SMS_SUCCESS) { | |
270 | com_err(whoami, status, "looking for user"); | |
271 | return; | |
272 | } | |
273 | if (strcmp(e->class, e->argv[U_CLASS])) { | |
274 | com_err(whoami, 0, "updating class for user %s", e->argv[U_NAME]); | |
275 | argv[U_NAME] = e->argv[U_NAME]; | |
276 | argv[U_NAME+1] = e->argv[U_NAME]; | |
277 | argv[U_UID+1] = e->argv[U_UID]; | |
278 | argv[U_SHELL+1] = e->argv[U_SHELL]; | |
279 | argv[U_LAST+1] = e->argv[U_LAST]; | |
280 | argv[U_FIRST+1] = e->argv[U_FIRST]; | |
281 | argv[U_MIDDLE+1] = e->argv[U_MIDDLE]; | |
282 | argv[U_STATE+1] = e->argv[U_STATE]; | |
283 | argv[U_MITID+1] = e->argv[U_MITID]; | |
284 | argv[U_CLASS+1] = e->class; | |
285 | status = sms_query("update_user", 10, argv, scream, NULL); | |
286 | if (status) { | |
287 | com_err(whoami, status, "updating user"); | |
288 | free_argv(e->argv); | |
289 | return; | |
290 | } | |
291 | } | |
292 | if (status = sms_query("get_finger_by_login", 1, e->argv, getfinger, e)) { | |
293 | com_err(whoami, status, "getting finger info for %s", e->argv[U_NAME]); | |
294 | free_argv(e->argv); | |
295 | return; | |
296 | } | |
297 | changed = 0; | |
298 | strcpy(buf, strtrim(e->address)); | |
299 | if (*e->dorm) { | |
300 | strcat(buf, " "); | |
301 | strcat(buf, strtrim(e->dorm)); | |
302 | } | |
303 | if (*e->city) { | |
304 | strcat(buf, " "); | |
305 | strcat(buf, strtrim(e->city)); | |
306 | } | |
307 | if (*e->state) { | |
308 | strcat(buf, " "); | |
309 | strcat(buf, strtrim(e->state)); | |
310 | } | |
311 | if (strncmp(e->finger[F_HOME_ADDR], buf, 80)) { | |
312 | changed++; | |
313 | free(e->finger[F_HOME_ADDR]); | |
314 | e->finger[F_HOME_ADDR] = strsave(buf); | |
315 | } | |
316 | from = e->dphone; | |
317 | to = buf; | |
318 | while (*from) { | |
319 | if (isdigit(*from)) | |
320 | *to++ = *from; | |
321 | from++; | |
322 | } | |
323 | *to = 0; | |
324 | if (strncmp(e->finger[F_HOME_PHONE], buf, 16)) { | |
325 | changed++; | |
326 | free(e->finger[F_HOME_PHONE]); | |
327 | e->finger[F_HOME_PHONE] = strsave(buf); | |
328 | } | |
329 | from = e->mphone; | |
330 | to = buf; | |
331 | while (*from) { | |
332 | if (isdigit(*from)) | |
333 | *to++ = *from; | |
334 | from++; | |
335 | } | |
336 | *to = 0; | |
337 | if (strncmp(e->finger[F_OFFICE_PHONE], buf, 12)) { | |
338 | changed++; | |
339 | free(e->finger[F_OFFICE_PHONE]); | |
340 | e->finger[F_OFFICE_PHONE] = strsave(buf); | |
341 | } | |
342 | e->course = strtrim(e->course); | |
343 | if (strncmp(e->finger[F_MIT_DEPT], e->course, 12)) { | |
344 | changed++; | |
345 | free(e->finger[F_MIT_DEPT]); | |
346 | e->finger[F_MIT_DEPT] = strsave(e->course); | |
347 | } | |
348 | if (changed) { | |
349 | com_err(whoami, 0, "updating finger for %s", e->argv[U_NAME]); | |
350 | status = sms_query("update_finger_by_login", 9, e->finger, | |
351 | scream, NULL); | |
352 | if (status) | |
353 | com_err(whoami, status, " while updating finger info"); | |
354 | } | |
355 | free_argv(e->argv); | |
356 | free_argv(e->finger); | |
357 | } | |
358 | ||
359 | newuser(argv, e) | |
360 | char **argv; | |
361 | struct entry *e; | |
362 | { | |
363 | int status; | |
364 | ||
365 | argv[U_NAME] = UNIQUE_LOGIN; | |
366 | argv[U_UID] = UNIQUE_UID; | |
367 | argv[U_SHELL] = "/bin/csh"; | |
368 | argv[U_LAST] = e->last; | |
369 | argv[U_FIRST] = e->first; | |
370 | argv[U_MIDDLE] = e->middle; | |
371 | argv[U_STATE] = "0"; | |
372 | argv[U_MITID] = e->eid; | |
373 | argv[U_CLASS] = e->class; | |
374 | com_err(whoami, 0, "adding user %s %s", e->first, e->last); | |
375 | status = sms_query("add_user", 9, argv, scream, NULL); | |
376 | if (status) { | |
377 | com_err(whoami, status, "adding user"); | |
378 | } | |
379 | } |