1 | /*
|
---|
2 | * This program is copyright Alec Muffett 1993, portions copyright other authors.
|
---|
3 | * The authors disclaim all responsibility or liability with respect to it's usage
|
---|
4 | * or its effect upon hardware or computer systems.
|
---|
5 | */
|
---|
6 |
|
---|
7 | #include "config.h"
|
---|
8 | #include <string.h>
|
---|
9 | #include <stdlib.h>
|
---|
10 | #ifdef HAVE_ZLIB_H
|
---|
11 | #include <zlib.h>
|
---|
12 | #endif
|
---|
13 | #ifdef HAVE_INTTYPES_H
|
---|
14 | #include <inttypes.h>
|
---|
15 | #endif
|
---|
16 | #include "packer.h"
|
---|
17 |
|
---|
18 | static char vers_id[] = "packlib.c : v2.3p2 Alec Muffett 18 May 1993";
|
---|
19 |
|
---|
20 | #define DEBUG 0
|
---|
21 |
|
---|
22 | /* Structures for processing "broken" 64bit dictionary files */
|
---|
23 |
|
---|
24 | struct pi_header64
|
---|
25 | {
|
---|
26 | uint64_t pih_magic;
|
---|
27 | uint64_t pih_numwords;
|
---|
28 | uint16_t pih_blocklen;
|
---|
29 | uint16_t pih_pad;
|
---|
30 | };
|
---|
31 |
|
---|
32 | typedef struct
|
---|
33 | {
|
---|
34 | FILE *ifp;
|
---|
35 | FILE *dfp;
|
---|
36 | FILE *wfp;
|
---|
37 | uint64_t flags;
|
---|
38 | uint64_t hwms[256];
|
---|
39 | struct pi_header64 header;
|
---|
40 | int count;
|
---|
41 | char data[NUMWORDS][MAXWORDLEN];
|
---|
42 | } PWDICT64;
|
---|
43 |
|
---|
44 |
|
---|
45 | static int
|
---|
46 | _PWIsBroken64(FILE *ifp)
|
---|
47 | {
|
---|
48 | PWDICT64 pdesc64;
|
---|
49 |
|
---|
50 | rewind(ifp);
|
---|
51 | if (!fread((char *) &pdesc64.header, sizeof(pdesc64.header), 1, ifp))
|
---|
52 | {
|
---|
53 | return 0;
|
---|
54 | }
|
---|
55 |
|
---|
56 | return (pdesc64.header.pih_magic == PIH_MAGIC);
|
---|
57 | }
|
---|
58 |
|
---|
59 |
|
---|
60 | PWDICT *
|
---|
61 | PWOpen(prefix, mode)
|
---|
62 | const char *prefix;
|
---|
63 | char *mode;
|
---|
64 | {
|
---|
65 | int use64 = 0;
|
---|
66 | static PWDICT pdesc;
|
---|
67 | static PWDICT64 pdesc64;
|
---|
68 | char iname[STRINGSIZE];
|
---|
69 | char dname[STRINGSIZE];
|
---|
70 | char wname[STRINGSIZE];
|
---|
71 | FILE *dfp;
|
---|
72 | FILE *ifp;
|
---|
73 | FILE *wfp;
|
---|
74 |
|
---|
75 | if (pdesc.header.pih_magic == PIH_MAGIC)
|
---|
76 | {
|
---|
77 | fprintf(stderr, "%s: another dictionary already open\n", prefix);
|
---|
78 | return ((PWDICT *) 0);
|
---|
79 | }
|
---|
80 |
|
---|
81 | memset(&pdesc, '\0', sizeof(pdesc));
|
---|
82 | memset(&pdesc64, '\0', sizeof(pdesc64));
|
---|
83 |
|
---|
84 | snprintf(iname, STRINGSIZE, "%s.pwi", prefix);
|
---|
85 | snprintf(dname, STRINGSIZE, "%s.pwd", prefix);
|
---|
86 | snprintf(wname, STRINGSIZE, "%s.hwm", prefix);
|
---|
87 |
|
---|
88 | if (mode[0] == 'r')
|
---|
89 | {
|
---|
90 | pdesc.flags &= ~PFOR_USEZLIB;
|
---|
91 | /* first try the normal db file */
|
---|
92 | if (!(pdesc.dfp = fopen(dname, mode)))
|
---|
93 | {
|
---|
94 | #ifdef HAVE_ZLIB_H
|
---|
95 | pdesc.flags |= PFOR_USEZLIB;
|
---|
96 | /* try extension .gz */
|
---|
97 | snprintf(dname, STRINGSIZE, "%s.pwd.gz", prefix);
|
---|
98 | if (!(pdesc.dfp = gzopen(dname, mode)))
|
---|
99 | {
|
---|
100 | perror(dname);
|
---|
101 | return ((PWDICT *) 0);
|
---|
102 | }
|
---|
103 | #else
|
---|
104 | perror(dname);
|
---|
105 | return ((PWDICT *) 0);
|
---|
106 | #endif
|
---|
107 | }
|
---|
108 | }
|
---|
109 | else
|
---|
110 | {
|
---|
111 | pdesc.flags &= ~PFOR_USEZLIB;
|
---|
112 | /* write mode: use fopen */
|
---|
113 | if (!(pdesc.dfp = fopen(dname, mode)))
|
---|
114 | {
|
---|
115 | perror(dname);
|
---|
116 | return ((PWDICT *) 0);
|
---|
117 | }
|
---|
118 | }
|
---|
119 |
|
---|
120 | if (!(pdesc.ifp = fopen(iname, mode)))
|
---|
121 | {
|
---|
122 | #ifdef HAVE_ZLIB_H
|
---|
123 | if(pdesc.flags & PFOR_USEZLIB)
|
---|
124 | gzclose(pdesc.dfp);
|
---|
125 | else
|
---|
126 | #endif
|
---|
127 | fclose(pdesc.dfp);
|
---|
128 | perror(iname);
|
---|
129 | return ((PWDICT *) 0);
|
---|
130 | }
|
---|
131 |
|
---|
132 | if ((pdesc.wfp = fopen(wname, mode)))
|
---|
133 | {
|
---|
134 | pdesc.flags |= PFOR_USEHWMS;
|
---|
135 | }
|
---|
136 |
|
---|
137 | ifp = pdesc.ifp;
|
---|
138 | dfp = pdesc.dfp;
|
---|
139 | wfp = pdesc.wfp;
|
---|
140 |
|
---|
141 | if (mode[0] == 'w')
|
---|
142 | {
|
---|
143 | pdesc.flags |= PFOR_WRITE;
|
---|
144 | pdesc.header.pih_magic = PIH_MAGIC;
|
---|
145 | pdesc.header.pih_blocklen = NUMWORDS;
|
---|
146 | pdesc.header.pih_numwords = 0;
|
---|
147 |
|
---|
148 | fwrite((char *) &pdesc.header, sizeof(pdesc.header), 1, ifp);
|
---|
149 | } else
|
---|
150 | {
|
---|
151 | pdesc.flags &= ~PFOR_WRITE;
|
---|
152 |
|
---|
153 | if (!fread((char *) &pdesc.header, sizeof(pdesc.header), 1, ifp))
|
---|
154 | {
|
---|
155 | fprintf(stderr, "%s: error reading header\n", prefix);
|
---|
156 |
|
---|
157 | pdesc.header.pih_magic = 0;
|
---|
158 | fclose(ifp);
|
---|
159 | #ifdef HAVE_ZLIB_H
|
---|
160 | if(pdesc.flags & PFOR_USEZLIB)
|
---|
161 | gzclose(dfp);
|
---|
162 | else
|
---|
163 | #endif
|
---|
164 | fclose(dfp);
|
---|
165 | if(wfp)
|
---|
166 | {
|
---|
167 | fclose(wfp);
|
---|
168 | }
|
---|
169 | return ((PWDICT *) 0);
|
---|
170 | }
|
---|
171 |
|
---|
172 | if ((pdesc.header.pih_magic == 0) || (pdesc.header.pih_numwords == 0))
|
---|
173 | {
|
---|
174 | /* uh-oh. either a broken "64-bit" file or a garbage file. */
|
---|
175 | rewind (ifp);
|
---|
176 | if (!fread((char *) &pdesc64.header, sizeof(pdesc64.header), 1, ifp))
|
---|
177 | {
|
---|
178 | fprintf(stderr, "%s: error reading header\n", prefix);
|
---|
179 |
|
---|
180 | pdesc.header.pih_magic = 0;
|
---|
181 | fclose(ifp);
|
---|
182 | #ifdef HAVE_ZLIB_H
|
---|
183 | if(pdesc.flags & PFOR_USEZLIB)
|
---|
184 | gzclose(dfp);
|
---|
185 | else
|
---|
186 | #endif
|
---|
187 | fclose(dfp);
|
---|
188 | if(wfp)
|
---|
189 | {
|
---|
190 | fclose(wfp);
|
---|
191 | }
|
---|
192 | return ((PWDICT *) 0);
|
---|
193 | }
|
---|
194 | if (pdesc64.header.pih_magic != PIH_MAGIC)
|
---|
195 | {
|
---|
196 | /* nope, not "64-bit" after all */
|
---|
197 | fprintf(stderr, "%s: error reading header\n", prefix);
|
---|
198 |
|
---|
199 | pdesc.header.pih_magic = 0;
|
---|
200 | fclose(ifp);
|
---|
201 | #ifdef HAVE_ZLIB_H
|
---|
202 | if(pdesc.flags & PFOR_USEZLIB)
|
---|
203 | gzclose(dfp);
|
---|
204 | else
|
---|
205 | #endif
|
---|
206 | fclose(dfp);
|
---|
207 |
|
---|
208 | if(wfp)
|
---|
209 | {
|
---|
210 | fclose(wfp);
|
---|
211 | }
|
---|
212 | return ((PWDICT *) 0);
|
---|
213 | }
|
---|
214 | pdesc.header.pih_magic = pdesc64.header.pih_magic;
|
---|
215 | pdesc.header.pih_numwords = pdesc64.header.pih_numwords;
|
---|
216 | pdesc.header.pih_blocklen = pdesc64.header.pih_blocklen;
|
---|
217 | pdesc.header.pih_pad = pdesc64.header.pih_pad;
|
---|
218 | use64 = 1;
|
---|
219 | }
|
---|
220 |
|
---|
221 | if (pdesc.header.pih_magic != PIH_MAGIC)
|
---|
222 | {
|
---|
223 | fprintf(stderr, "%s: magic mismatch\n", prefix);
|
---|
224 |
|
---|
225 | pdesc.header.pih_magic = 0;
|
---|
226 | fclose(ifp);
|
---|
227 | #ifdef HAVE_ZLIB_H
|
---|
228 | if(pdesc.flags & PFOR_USEZLIB)
|
---|
229 | gzclose(dfp);
|
---|
230 | else
|
---|
231 | #endif
|
---|
232 | fclose(dfp);
|
---|
233 |
|
---|
234 | if(wfp)
|
---|
235 | {
|
---|
236 | fclose(wfp);
|
---|
237 | }
|
---|
238 | return ((PWDICT *) 0);
|
---|
239 | }
|
---|
240 |
|
---|
241 | if (pdesc.header.pih_numwords < 1)
|
---|
242 | {
|
---|
243 | fprintf(stderr, "%s: invalid word count\n", prefix);
|
---|
244 |
|
---|
245 | pdesc.header.pih_magic = 0;
|
---|
246 | fclose(ifp);
|
---|
247 | #ifdef HAVE_ZLIB_H
|
---|
248 | if(pdesc.flags & PFOR_USEZLIB)
|
---|
249 | gzclose(dfp);
|
---|
250 | else
|
---|
251 | #endif
|
---|
252 | fclose(dfp);
|
---|
253 | if(wfp)
|
---|
254 | {
|
---|
255 | fclose(wfp);
|
---|
256 | }
|
---|
257 | return ((PWDICT *) 0);
|
---|
258 | }
|
---|
259 |
|
---|
260 | if (pdesc.header.pih_blocklen != NUMWORDS)
|
---|
261 | {
|
---|
262 | fprintf(stderr, "%s: size mismatch\n", prefix);
|
---|
263 |
|
---|
264 | pdesc.header.pih_magic = 0;
|
---|
265 | fclose(ifp);
|
---|
266 | #ifdef HAVE_ZLIB_H
|
---|
267 | if(pdesc.flags & PFOR_USEZLIB)
|
---|
268 | gzclose(dfp);
|
---|
269 | else
|
---|
270 | #endif
|
---|
271 | fclose(dfp);
|
---|
272 | if(wfp)
|
---|
273 | {
|
---|
274 | fclose(wfp);
|
---|
275 | }
|
---|
276 | return ((PWDICT *) 0);
|
---|
277 | }
|
---|
278 |
|
---|
279 | if (pdesc.flags & PFOR_USEHWMS)
|
---|
280 | {
|
---|
281 | int i;
|
---|
282 |
|
---|
283 | if (use64)
|
---|
284 | {
|
---|
285 | if (fread(pdesc64.hwms, 1, sizeof(pdesc64.hwms), wfp) != sizeof(pdesc64.hwms))
|
---|
286 | {
|
---|
287 | pdesc.flags &= ~PFOR_USEHWMS;
|
---|
288 | }
|
---|
289 | for (i = 0; i < sizeof(pdesc.hwms) / sizeof(pdesc.hwms[0]); i++)
|
---|
290 | {
|
---|
291 | pdesc.hwms[i] = pdesc64.hwms[i];
|
---|
292 | }
|
---|
293 | }
|
---|
294 | else if (fread(pdesc.hwms, 1, sizeof(pdesc.hwms), wfp) != sizeof(pdesc.hwms))
|
---|
295 | {
|
---|
296 | pdesc.flags &= ~PFOR_USEHWMS;
|
---|
297 | }
|
---|
298 | #if DEBUG
|
---|
299 | for (i=1; i<=0xff; i++)
|
---|
300 | {
|
---|
301 | printf("hwm[%02x] = %d\n", i, pdesc.hwms[i]);
|
---|
302 | }
|
---|
303 | #endif
|
---|
304 | }
|
---|
305 | }
|
---|
306 |
|
---|
307 | return (&pdesc);
|
---|
308 | }
|
---|
309 |
|
---|
310 | int
|
---|
311 | PWClose(pwp)
|
---|
312 | PWDICT *pwp;
|
---|
313 | {
|
---|
314 | if (pwp->header.pih_magic != PIH_MAGIC)
|
---|
315 | {
|
---|
316 | fprintf(stderr, "PWClose: close magic mismatch\n");
|
---|
317 | return (-1);
|
---|
318 | }
|
---|
319 |
|
---|
320 | if (pwp->flags & PFOR_WRITE)
|
---|
321 | {
|
---|
322 | pwp->flags |= PFOR_FLUSH;
|
---|
323 | PutPW(pwp, (char *) 0); /* flush last index if necess */
|
---|
324 |
|
---|
325 | if (fseek(pwp->ifp, 0L, 0))
|
---|
326 | {
|
---|
327 | fprintf(stderr, "index magic fseek failed\n");
|
---|
328 | return (-1);
|
---|
329 | }
|
---|
330 |
|
---|
331 | if (!fwrite((char *) &pwp->header, sizeof(pwp->header), 1, pwp->ifp))
|
---|
332 | {
|
---|
333 | fprintf(stderr, "index magic fwrite failed\n");
|
---|
334 | return (-1);
|
---|
335 | }
|
---|
336 |
|
---|
337 | if (pwp->flags & PFOR_USEHWMS)
|
---|
338 | {
|
---|
339 | int i;
|
---|
340 | for (i=1; i<=0xff; i++)
|
---|
341 | {
|
---|
342 | if (!pwp->hwms[i])
|
---|
343 | {
|
---|
344 | pwp->hwms[i] = pwp->hwms[i-1];
|
---|
345 | }
|
---|
346 | #if DEBUG
|
---|
347 | printf("hwm[%02x] = %d\n", i, pwp->hwms[i]);
|
---|
348 | #endif
|
---|
349 | }
|
---|
350 | fwrite(pwp->hwms, 1, sizeof(pwp->hwms), pwp->wfp);
|
---|
351 | }
|
---|
352 | }
|
---|
353 |
|
---|
354 | fclose(pwp->ifp);
|
---|
355 | #ifdef HAVE_ZLIB_H
|
---|
356 | if(pwp->flags & PFOR_USEZLIB)
|
---|
357 | gzclose(pwp->dfp);
|
---|
358 | else
|
---|
359 | #endif
|
---|
360 | fclose(pwp->dfp);
|
---|
361 | if(pwp->wfp)
|
---|
362 | {
|
---|
363 | fclose(pwp->wfp);
|
---|
364 | }
|
---|
365 |
|
---|
366 | pwp->header.pih_magic = 0;
|
---|
367 |
|
---|
368 | return (0);
|
---|
369 | }
|
---|
370 |
|
---|
371 | int
|
---|
372 | PutPW(pwp, string)
|
---|
373 | PWDICT *pwp;
|
---|
374 | char *string;
|
---|
375 | {
|
---|
376 | if (!(pwp->flags & PFOR_WRITE))
|
---|
377 | {
|
---|
378 | return (-1);
|
---|
379 | }
|
---|
380 |
|
---|
381 | if (string)
|
---|
382 | {
|
---|
383 | strncpy(pwp->data[pwp->count], string, MAXWORDLEN);
|
---|
384 | pwp->data[pwp->count][MAXWORDLEN - 1] = '\0';
|
---|
385 |
|
---|
386 | pwp->hwms[string[0] & 0xff]= pwp->header.pih_numwords;
|
---|
387 |
|
---|
388 | ++(pwp->count);
|
---|
389 | ++(pwp->header.pih_numwords);
|
---|
390 |
|
---|
391 | } else if (!(pwp->flags & PFOR_FLUSH))
|
---|
392 | {
|
---|
393 | return (-1);
|
---|
394 | }
|
---|
395 |
|
---|
396 | if ((pwp->flags & PFOR_FLUSH) || !(pwp->count % NUMWORDS))
|
---|
397 | {
|
---|
398 | int i;
|
---|
399 | uint32_t datum;
|
---|
400 | register char *ostr;
|
---|
401 |
|
---|
402 | datum = (uint32_t) ftell(pwp->dfp);
|
---|
403 |
|
---|
404 | fwrite((char *) &datum, sizeof(datum), 1, pwp->ifp);
|
---|
405 |
|
---|
406 | fputs(pwp->data[0], pwp->dfp);
|
---|
407 | putc(0, pwp->dfp);
|
---|
408 |
|
---|
409 | ostr = pwp->data[0];
|
---|
410 |
|
---|
411 | for (i = 1; i < NUMWORDS; i++)
|
---|
412 | {
|
---|
413 | register int j;
|
---|
414 | register char *nstr;
|
---|
415 | nstr = pwp->data[i];
|
---|
416 |
|
---|
417 | if (nstr[0])
|
---|
418 | {
|
---|
419 | for (j = 0; ostr[j] && nstr[j] && (ostr[j] == nstr[j]); j++);
|
---|
420 | putc(j & 0xff, pwp->dfp);
|
---|
421 | fputs(nstr + j, pwp->dfp);
|
---|
422 | }
|
---|
423 | putc(0, pwp->dfp);
|
---|
424 |
|
---|
425 | ostr = nstr;
|
---|
426 | }
|
---|
427 |
|
---|
428 | memset(pwp->data, '\0', sizeof(pwp->data));
|
---|
429 | pwp->count = 0;
|
---|
430 | }
|
---|
431 | return (0);
|
---|
432 | }
|
---|
433 |
|
---|
434 | char *
|
---|
435 | GetPW(pwp, number)
|
---|
436 | PWDICT *pwp;
|
---|
437 | uint32_t number;
|
---|
438 | {
|
---|
439 | uint32_t datum;
|
---|
440 | register int i;
|
---|
441 | register char *ostr;
|
---|
442 | register char *nstr;
|
---|
443 | register char *bptr;
|
---|
444 | char buffer[NUMWORDS * MAXWORDLEN];
|
---|
445 | static char data[NUMWORDS][MAXWORDLEN];
|
---|
446 | static uint32_t prevblock = 0xffffffff;
|
---|
447 | uint32_t thisblock;
|
---|
448 |
|
---|
449 | thisblock = number / NUMWORDS;
|
---|
450 |
|
---|
451 | if (prevblock == thisblock)
|
---|
452 | {
|
---|
453 | #if DEBUG
|
---|
454 | fprintf(stderr, "returning (%s)\n", data[number % NUMWORDS]);
|
---|
455 | #endif
|
---|
456 | return (data[number % NUMWORDS]);
|
---|
457 | }
|
---|
458 |
|
---|
459 | if (_PWIsBroken64(pwp->ifp))
|
---|
460 | {
|
---|
461 | uint64_t datum64;
|
---|
462 | if (fseek(pwp->ifp, sizeof(struct pi_header64) + (thisblock * sizeof(uint64_t)), 0))
|
---|
463 | {
|
---|
464 | perror("(index fseek failed)");
|
---|
465 | return ((char *) 0);
|
---|
466 | }
|
---|
467 |
|
---|
468 | if (!fread((char *) &datum64, sizeof(datum64), 1, pwp->ifp))
|
---|
469 | {
|
---|
470 | perror("(index fread failed)");
|
---|
471 | return ((char *) 0);
|
---|
472 | }
|
---|
473 | datum = datum64;
|
---|
474 | } else {
|
---|
475 | if (fseek(pwp->ifp, sizeof(struct pi_header) + (thisblock * sizeof(uint32_t)), 0))
|
---|
476 | {
|
---|
477 | perror("(index fseek failed)");
|
---|
478 | return ((char *) 0);
|
---|
479 | }
|
---|
480 |
|
---|
481 | if (!fread((char *) &datum, sizeof(datum), 1, pwp->ifp))
|
---|
482 | {
|
---|
483 | perror("(index fread failed)");
|
---|
484 | return ((char *) 0);
|
---|
485 | }
|
---|
486 | }
|
---|
487 |
|
---|
488 | int r = 1;
|
---|
489 | #ifdef HAVE_ZLIB_H
|
---|
490 | if (pwp->flags & PFOR_USEZLIB)
|
---|
491 | {
|
---|
492 | r = gzseek(pwp->dfp, datum, 0);
|
---|
493 | if(r >= 0)
|
---|
494 | r = 0;
|
---|
495 | }
|
---|
496 | else
|
---|
497 | #endif
|
---|
498 | r = fseek(pwp->dfp, datum, 0);
|
---|
499 |
|
---|
500 |
|
---|
501 | if (r)
|
---|
502 | {
|
---|
503 | perror("(data fseek failed)");
|
---|
504 | return ((char *) 0);
|
---|
505 | }
|
---|
506 | r = 0;
|
---|
507 |
|
---|
508 | #ifdef HAVE_ZLIB_H
|
---|
509 | if (pwp->flags & PFOR_USEZLIB)
|
---|
510 | {
|
---|
511 | r = gzread(pwp->dfp, buffer, sizeof(buffer));
|
---|
512 | if(r < 0)
|
---|
513 | r = 0;
|
---|
514 | }
|
---|
515 | else
|
---|
516 | #endif
|
---|
517 | r = fread(buffer, 1, sizeof(buffer), pwp->dfp);
|
---|
518 |
|
---|
519 |
|
---|
520 |
|
---|
521 | if (!r)
|
---|
522 | {
|
---|
523 | perror("(data fread failed)");
|
---|
524 | return ((char *) 0);
|
---|
525 | }
|
---|
526 |
|
---|
527 | prevblock = thisblock;
|
---|
528 |
|
---|
529 | bptr = buffer;
|
---|
530 |
|
---|
531 | for (ostr = data[0]; (*(ostr++) = *(bptr++)); /* nothing */ );
|
---|
532 |
|
---|
533 | ostr = data[0];
|
---|
534 |
|
---|
535 | for (i = 1; i < NUMWORDS; i++)
|
---|
536 | {
|
---|
537 | nstr = data[i];
|
---|
538 | strcpy(nstr, ostr);
|
---|
539 |
|
---|
540 | ostr = nstr + *(bptr++);
|
---|
541 | while ((*(ostr++) = *(bptr++)));
|
---|
542 |
|
---|
543 | ostr = nstr;
|
---|
544 | }
|
---|
545 |
|
---|
546 | return (data[number % NUMWORDS]);
|
---|
547 | }
|
---|
548 |
|
---|
549 | unsigned int
|
---|
550 | FindPW(pwp, string)
|
---|
551 | PWDICT *pwp;
|
---|
552 | char *string;
|
---|
553 | {
|
---|
554 | register uint32_t lwm;
|
---|
555 | register uint32_t hwm;
|
---|
556 | register uint32_t middle;
|
---|
557 | register char *this;
|
---|
558 | int idx;
|
---|
559 |
|
---|
560 | #if DEBUG
|
---|
561 | fprintf(stderr, "look for (%s)\n", string);
|
---|
562 | #endif
|
---|
563 |
|
---|
564 | if (pwp->flags & PFOR_USEHWMS)
|
---|
565 | {
|
---|
566 | idx = string[0] & 0xff;
|
---|
567 | lwm = idx ? pwp->hwms[idx - 1] : 0;
|
---|
568 | hwm = pwp->hwms[idx];
|
---|
569 |
|
---|
570 | #if DEBUG
|
---|
571 | fprintf(stderr, "idx = %d\n", idx);
|
---|
572 | fprintf(stderr, "lwm = %d, hwm = %d\n", lwm, hwm);
|
---|
573 | #endif
|
---|
574 | } else
|
---|
575 | {
|
---|
576 | lwm = 0;
|
---|
577 | hwm = PW_WORDS(pwp) - 1;
|
---|
578 | }
|
---|
579 |
|
---|
580 | /* if the high water mark is lower than the low water mark, something is screwed up */
|
---|
581 | if ( hwm < lwm )
|
---|
582 | {
|
---|
583 | lwm = 0;
|
---|
584 | hwm = PW_WORDS(pwp) - 1;
|
---|
585 | }
|
---|
586 |
|
---|
587 | #if DEBUG
|
---|
588 | fprintf(stderr, "---- %lu, %lu ----\n", lwm, hwm);
|
---|
589 | #endif
|
---|
590 |
|
---|
591 | for (;;)
|
---|
592 | {
|
---|
593 | int cmp;
|
---|
594 |
|
---|
595 | middle = lwm + ((hwm - lwm + 1) / 2);
|
---|
596 |
|
---|
597 | #if DEBUG
|
---|
598 | fprintf(stderr, "lwm = %lu, middle = %lu, hwm = %lu\n", lwm, middle, hwm);
|
---|
599 | #endif
|
---|
600 |
|
---|
601 | this = GetPW(pwp, middle);
|
---|
602 | if ( ! this )
|
---|
603 | {
|
---|
604 | #if DEBUG
|
---|
605 | fprintf(stderr, "getpw returned null, returning null in FindPW\n");
|
---|
606 | #endif
|
---|
607 | return(PW_WORDS(pwp));
|
---|
608 | }
|
---|
609 | else
|
---|
610 | {
|
---|
611 | #if DEBUG
|
---|
612 | fprintf(stderr, "comparing %s against found %s\n", string, this);
|
---|
613 | #endif
|
---|
614 | }
|
---|
615 |
|
---|
616 | cmp = strcmp(string, this);
|
---|
617 | if (cmp == 0)
|
---|
618 | {
|
---|
619 | return(middle);
|
---|
620 | }
|
---|
621 |
|
---|
622 | if (middle == hwm)
|
---|
623 | {
|
---|
624 | #if DEBUG
|
---|
625 | fprintf(stderr, "at terminal subdivision, stopping search\n");
|
---|
626 | #endif
|
---|
627 | break;
|
---|
628 | }
|
---|
629 |
|
---|
630 | if (cmp < 0)
|
---|
631 | {
|
---|
632 | hwm = middle;
|
---|
633 | }
|
---|
634 | else if (cmp > 0)
|
---|
635 | {
|
---|
636 | lwm = middle;
|
---|
637 | }
|
---|
638 | }
|
---|
639 |
|
---|
640 | return (PW_WORDS(pwp));
|
---|
641 | }
|
---|