]>
Commit | Line | Data |
---|---|---|
27e6dc94 | 1 | /* |
2 | * $Source$ | |
3 | * $Author$ | |
4 | * $Header$ | |
5 | */ | |
6 | ||
7 | #ifndef lint | |
8 | static char *rcsid_rafnu_c = "$Header$"; | |
9 | ||
10 | #endif lint | |
11 | ||
12 | ||
13 | /* ReadAndFixNextUser reads in a student record line in the format | |
14 | * of the registrar's tape and hacks on the info to make it conform | |
15 | * to athenareg's standards. For example, the line | |
16 | ||
17 | 123321123 ALBERGHETTI III JOANNA MARIA 97 | |
18 | ||
19 | * gets processed into: | |
20 | * | |
21 | * --> | |
22 | * {nil, nil, nil, nil, | |
23 | * last -> "Alberghetti", | |
24 | * first -> "Joanna III", | |
25 | * mid_init -> "M", | |
26 | * nil, | |
27 | * crypt_ssn -> "aj7.NBbasJbn8" ; encrypted with salt "aj" | |
28 | * year -> "97", | |
29 | * nil} | |
30 | * | |
31 | */ | |
32 | ||
33 | #include <stdio.h> | |
34 | #include <ctype.h> | |
98a7b0ee | 35 | #ifdef USE_CRYPT_H |
36 | #include <crypt.h> | |
37 | #else | |
38 | #include <unistd.h> | |
39 | #endif | |
27e6dc94 | 40 | |
41 | #define LAST_LEN 15 | |
42 | #define FIRST_LEN 15 | |
43 | #define FULL_NAME_LEN 31 | |
44 | ||
45 | #define REG_TAPE_LINE_LEN 77 | |
46 | #define SSN_OFFSET 0 | |
47 | #define SSN_ILEN 9 | |
48 | #define LAST_NAME_OFFSET 10 | |
49 | #define LAST_NAME_MAX_ILEN 39 | |
50 | #define FIRST_NAME_OFFSET 49 | |
51 | #define FIRST_NAME_MAX_ILEN 25 | |
52 | #define MIT_YEAR_OFFSET 74 | |
53 | #define MIT_YEAR_ILEN 2 | |
54 | ||
55 | #define BUFSIZE 1024 | |
56 | ||
57 | int | |
58 | ReadAndFixNextUser(s, querc, querv) | |
59 | FILE *s; | |
60 | int querc; | |
61 | char **querv; | |
62 | ||
63 | { | |
64 | char ibuf[BUFSIZE]; /* input line buffer */ | |
65 | static lno = 0; /* line number */ | |
66 | int len; /* line length */ | |
67 | char issn[SSN_ILEN + 1]; | |
68 | char ilnm[LAST_NAME_MAX_ILEN + 1]; | |
69 | char ifnm[FIRST_NAME_MAX_ILEN + 1 + 6]; /* extra for ", Jr.", et al */ | |
70 | char iyr[MIT_YEAR_ILEN + 1]; | |
f8062548 | 71 | int ends_sr = 0; /* 1 if name ends in "SR" or "SR." */ |
27e6dc94 | 72 | int ends_jr = 0; /* 1 if name ends in "JR" or "JR." */ |
73 | int ends_iii = 0; /* 1 if name ends in "III" */ | |
74 | int ends_iv = 0; /* 1 if name ends in "IV" */ | |
75 | char salt[2]; | |
76 | register char *p; | |
27e6dc94 | 77 | |
78 | for (;;) { /* ... well, at least until we get a good | |
79 | * input line */ | |
80 | if (fgets(ibuf, BUFSIZE, s) == NULL) { | |
81 | fprintf(stderr, "Reached EOF after line %d.\n", lno); | |
82 | return (EOF); /* reached EOF */ | |
83 | } | |
84 | /* | |
85 | * POTENTIAL BUG!!! fgets will not remove \n from input stream | |
86 | * May need to manually get that character off | |
87 | */ | |
88 | lno++; | |
89 | ||
90 | if ((len = strlen(ibuf)) != REG_TAPE_LINE_LEN) { | |
91 | fprintf(stderr, "bad length\n"); | |
92 | goto complain_and_continue; | |
93 | } | |
94 | ||
95 | /* grab and check input SSN */ | |
96 | ||
97 | issn[SSN_ILEN] = '\0'; | |
98 | (void) strncpy(issn, ibuf + SSN_OFFSET, SSN_ILEN); | |
99 | for (p = issn; *p; p++) { | |
100 | if (!isdigit(*p)) { | |
101 | fprintf(stderr, "bad char \"%c\"\n", *p); | |
102 | goto complain_and_continue; | |
103 | } | |
104 | } | |
105 | ||
106 | /* check for blank before last name */ | |
107 | ||
108 | if (!isspace(ibuf[LAST_NAME_OFFSET - 1])) { | |
109 | fprintf(stderr, "not space \"%c\"\n", ibuf[LAST_NAME_OFFSET - 1]); | |
110 | goto complain_and_continue; | |
111 | } | |
112 | ||
113 | /* grab input last name */ | |
114 | ||
115 | ilnm[LAST_NAME_MAX_ILEN] = '\0'; | |
116 | (void) strncpy(ilnm, ibuf + LAST_NAME_OFFSET, LAST_NAME_MAX_ILEN); | |
117 | for (p = ilnm; *p; p++) { | |
118 | if (!isalpha(*p) && *p != '-' && *p != ' ' && | |
119 | *p != '.' && *p != '\'') { | |
120 | fprintf(stderr, "bad char in name \"%c\"\n", *p); | |
121 | goto complain_and_continue; | |
122 | } | |
123 | } | |
124 | ||
125 | /* grab input first name */ | |
126 | ||
127 | ifnm[FIRST_NAME_MAX_ILEN] = '\0'; | |
128 | (void) strncpy(ifnm, ibuf + FIRST_NAME_OFFSET, FIRST_NAME_MAX_ILEN); | |
129 | ||
130 | for (p = ifnm; *p; p++) { | |
131 | if (!isalpha(*p) && *p != '-' && *p != ' ' && *p != '.') { | |
132 | fprintf(stderr, "bad char in fname \"%c\"\n", *p); | |
133 | goto complain_and_continue; | |
134 | } | |
135 | } | |
136 | ||
137 | /* grab MIT year */ | |
138 | ||
139 | iyr[MIT_YEAR_ILEN] = '\0'; | |
140 | (void) strncpy(iyr, ibuf + MIT_YEAR_OFFSET, MIT_YEAR_ILEN); | |
141 | if (strcmp(iyr, "GG") && strcmp(iyr, "90") && strcmp(iyr, "88") | |
142 | && strcmp(iyr, "89") && strcmp(iyr, "91")) { | |
143 | fprintf(stderr, "bad year \"%s\"\n", iyr); | |
144 | goto complain_and_continue; | |
145 | } | |
146 | ||
147 | /* Okay, got everything, now hack on it */ | |
148 | ||
149 | /* Last name ... */ | |
150 | ||
151 | TrimTrailingSpace(ilnm); | |
f8062548 | 152 | LookForJrAndIII(ilnm, &ends_sr, &ends_jr, &ends_iii, &ends_iv); |
27e6dc94 | 153 | LookForSt(ilnm); |
154 | LookForO(ilnm); | |
155 | FixCase(ilnm); | |
156 | (void) strncpy(querv[4], ilnm, LAST_LEN); | |
157 | ||
158 | /* First name & middle initial ... */ | |
159 | ||
160 | TrimTrailingSpace(ifnm); | |
f8062548 | 161 | LookForJrAndIII(ifnm, &ends_sr, &ends_jr, &ends_iii, &ends_iv); |
27e6dc94 | 162 | |
163 | GetMidInit(ifnm, querv[6]); | |
164 | FixCase(ifnm); | |
165 | (void) strncpy(querv[5], ifnm, FIRST_LEN); | |
166 | ||
167 | ||
168 | /* okay, finish up first name */ | |
f8062548 | 169 | AppendJrOrIII(ifnm, &ends_sr, &ends_jr, &ends_iii, &ends_iv); |
27e6dc94 | 170 | |
171 | /* MIT Year ... */ | |
172 | ||
173 | if (!strcmp(iyr, "GG")) { | |
174 | (void) strcpy(querv[9], "G\0"); | |
175 | } | |
176 | else { | |
177 | (void) strcpy(querv[9], iyr); | |
178 | } | |
179 | ||
180 | /* MIT-ID (Social Security Number) ... */ | |
181 | ||
182 | salt[0] = tolower(*ilnm); | |
183 | salt[1] = tolower(*ifnm); | |
184 | (void) strcpy(querv[8], crypt(issn + 2, salt)); /* last 7 digits only */ | |
185 | (void) strcat(querv[8], "\0"); | |
186 | /* That's all, folks */ | |
187 | ||
188 | ||
189 | return (lno); | |
190 | ||
191 | complain_and_continue: | |
192 | fprintf(stderr, "\007ERROR on input line no. %d, len %d:\n", | |
193 | lno, len); | |
194 | fprintf(stderr, "%s\n", ibuf); | |
195 | } | |
196 | } | |
197 | ||
198 | TrimTrailingSpace(ip) | |
199 | register char *ip; | |
200 | { | |
201 | register char *p; | |
202 | ||
203 | for (p = ip + strlen(ip) - 1; p >= ip && isspace(*p); p--) { | |
204 | *p = '\0'; | |
205 | } | |
206 | } | |
207 | ||
208 | GetMidInit(nm, mi) | |
209 | register char *nm; /* truncate at first space, if any such */ | |
210 | register char *mi; /* set to first char after first space, if | |
211 | * any such */ | |
212 | { | |
213 | while (*nm && !isspace(*nm)) { | |
214 | nm++; | |
215 | } | |
216 | if (*nm) { | |
217 | *nm++ = '\0'; | |
218 | } | |
219 | while (*nm && isspace(*nm)) { | |
220 | nm++; | |
221 | } | |
222 | if (*nm) { | |
223 | *mi++ = *nm; | |
224 | } | |
225 | *mi = '\0'; | |
226 | } | |
227 | ||
f8062548 | 228 | AppendJrOrIII(nm, phas_sr, phas_jr, phas_iii, phas_iv) |
27e6dc94 | 229 | register char *nm; |
f8062548 | 230 | register int *phas_sr; |
27e6dc94 | 231 | register int *phas_jr; |
232 | register int *phas_iii; | |
233 | register int *phas_iv; | |
234 | { | |
f8062548 | 235 | if (*phas_sr) { |
236 | (void) strcat(nm, ", Sr."); | |
237 | } | |
238 | else if (*phas_jr) { | |
27e6dc94 | 239 | (void) strcat(nm, ", Jr."); |
240 | } | |
241 | else if (*phas_iii) { | |
242 | (void) strcat(nm, " III"); | |
243 | } | |
244 | else if (*phas_iv) { | |
245 | (void) strcat(nm, " IV"); | |
246 | } | |
247 | } | |
248 | ||
249 | FixCase(p) | |
250 | register char *p; | |
251 | { | |
252 | register int cflag; /* convert to lcase, unless at start or | |
253 | * following */ | |
254 | ||
255 | /* a space or punctuation mark (e.g., '-') */ | |
256 | ||
257 | for (cflag = 0; *p; p++) { | |
258 | if (cflag && isupper(*p)) { | |
259 | *p = tolower(*p); | |
260 | } | |
261 | else if (isspace(*p) || ispunct(*p)) { | |
262 | cflag = 0; | |
263 | } | |
264 | else { | |
265 | cflag = 1; | |
266 | } | |
267 | } | |
268 | } | |
269 | ||
f8062548 | 270 | LookForJrAndIII(nm, pends_sr, pends_jr, pends_iii, pends_iv) |
27e6dc94 | 271 | register char *nm; |
f8062548 | 272 | register int *pends_sr; |
27e6dc94 | 273 | register int *pends_jr; |
274 | register int *pends_iii; | |
275 | register int *pends_iv; | |
276 | { | |
277 | register int len = strlen(nm); | |
278 | ||
f8062548 | 279 | if (len >= 4 && !strcmp(nm + len - 3, " SR")) { |
280 | *pends_sr = 1; | |
281 | nm[len - 3] = '\0'; | |
282 | } | |
283 | else if (len >= 4 && !strcmp(nm + len - 3, " JR")) { | |
27e6dc94 | 284 | *pends_jr = 1; |
285 | nm[len - 3] = '\0'; | |
286 | } | |
287 | else if (len >= 4 && !strcmp(nm + len - 3, " IV")) { | |
288 | *pends_iv = 1; | |
289 | nm[len - 3] = '\0'; | |
290 | } | |
f8062548 | 291 | else if (len >= 5 && !strcmp(nm + len - 4, " SR.")) { |
292 | *pends_sr = 1; | |
293 | nm[len - 4] = '\0'; | |
294 | } | |
27e6dc94 | 295 | else if (len >= 5 && !strcmp(nm + len - 4, " JR.")) { |
296 | *pends_jr = 1; | |
297 | nm[len - 4] = '\0'; | |
298 | } | |
299 | else if (len >= 5 && !strcmp(nm + len - 4, " III")) { | |
300 | *pends_iii = 1; | |
301 | nm[len - 4] = '\0'; | |
302 | } | |
303 | } | |
304 | ||
305 | LookForSt(nm) /* ST PIERRE, etc. */ | |
306 | register char *nm; | |
307 | { | |
308 | char temp[256]; | |
309 | ||
310 | if (!strcmp(nm, "ST ")) { | |
311 | (void) strcpy(temp, nm + 3); | |
312 | (void) strcpy(nm, "ST. "); | |
313 | (void) strcat(nm, temp); | |
314 | } | |
315 | } | |
316 | ||
317 | LookForO(nm) /* O BRIEN, etc. */ | |
318 | register char *nm; | |
319 | { | |
320 | if (!strcmp(nm, "O ") && isalpha(nm[2])) { | |
321 | nm[1] = '\''; | |
322 | } | |
323 | } |