1/* 2 * This program is copyright Alec Muffett 1993. The author disclaims all 3 * responsibility or liability with respect to it's usage or its effect 4 * upon hardware or computer systems, and maintains copyright as set out 5 * in the "LICENCE" document which accompanies distributions of Crack v4.0 6 * and upwards. 7 */ 8 9#include "packer.h" 10#include <string.h> 11#include <arpa/inet.h> 12 13static char __unused vers_id[] = "packlib.c : v2.3p2 Alec Muffett 18 May 1993"; 14 15static void PWDictHeaderToHostOrder (struct pi_header* header) 16{ 17 header->pih_magic = ntohl (header->pih_magic); 18 header->pih_numwords = ntohl (header->pih_numwords); 19 header->pih_blocklen = ntohs (header->pih_blocklen); 20} 21 22 23 24static void PWDictHeaderToNetworkOrder (struct pi_header* header) 25{ 26 header->pih_magic = htonl (header->pih_magic); 27 header->pih_numwords = htonl (header->pih_numwords); 28 header->pih_blocklen = htons (header->pih_blocklen); 29} 30 31 32 33static void PWHwmsToHostOrder (int32 *array, size_t max) 34{ 35 size_t i; 36 for (i = 0; i < max; ++i) 37 { 38 array[i] = ntohl (array[i]); 39 } 40} 41 42 43 44static void PWHwmnToNetworkOrder (int32 *array, size_t max) 45{ 46 size_t i; 47 for (i = 0; i < max; ++i) 48 { 49 array[i] = htonl (array[i]); 50 } 51} 52 53 54 55extern int PutPW(PWDICT *pwp, char *string); 56 57PWDICT * 58PWOpen(prefix, mode) 59 char *prefix; 60 char *mode; 61{ 62// int32 i; 63 static PWDICT pdesc; 64 char iname[STRINGSIZE]; 65 char dname[STRINGSIZE]; 66 char wname[STRINGSIZE]; 67// char buffer[STRINGSIZE]; 68 FILE *dfp; 69 FILE *ifp; 70 FILE *wfp; 71 72 if (pdesc.header.pih_magic == PIH_MAGIC) 73 { 74 fprintf(stderr, "%s: another dictionary already open\n", prefix); 75 return ((PWDICT *) 0); 76 } 77 78 memset(&pdesc, '\0', sizeof(pdesc)); 79 80 snprintf(iname, sizeof(iname), "%s.pwi", prefix); 81 snprintf(dname, sizeof(dname), "%s.pwd", prefix); 82 snprintf(wname, sizeof(wname), "%s.hwm", prefix); 83 84 if (!(pdesc.dfp = fopen(dname, mode))) 85 { 86 perror(dname); 87 return ((PWDICT *) 0); 88 } 89 90 if (!(pdesc.ifp = fopen(iname, mode))) 91 { 92 fclose(pdesc.dfp); 93 perror(iname); 94 return ((PWDICT *) 0); 95 } 96 97 if (pdesc.wfp = fopen(wname, mode)) 98 { 99 pdesc.flags |= PFOR_USEHWMS; 100 } 101 102 ifp = pdesc.ifp; 103 dfp = pdesc.dfp; 104 wfp = pdesc.wfp; 105 106 if (mode[0] == 'w') 107 { 108 pdesc.flags |= PFOR_WRITE; 109 pdesc.header.pih_magic = PIH_MAGIC; 110 pdesc.header.pih_blocklen = NUMWORDS; 111 pdesc.header.pih_numwords = 0; 112 113 // convert to "network" byte order 114 PWDictHeaderToNetworkOrder (&pdesc.header); 115 fwrite((char *) &pdesc.header, sizeof(pdesc.header), 1, ifp); 116 PWDictHeaderToHostOrder (&pdesc.header); 117 } else 118 { 119 pdesc.flags &= ~PFOR_WRITE; 120 121 if (!fread((char *) &pdesc.header, sizeof(pdesc.header), 1, ifp)) 122 { 123 fprintf(stderr, "%s: error reading header\n", prefix); 124 125 pdesc.header.pih_magic = 0; 126 fclose(ifp); 127 fclose(dfp); 128 return ((PWDICT *) 0); 129 } 130 131 PWDictHeaderToHostOrder (&pdesc.header); 132 133 if (pdesc.header.pih_magic != PIH_MAGIC) 134 { 135 fprintf(stderr, "%s: magic mismatch\n", prefix); 136 137 pdesc.header.pih_magic = 0; 138 fclose(ifp); 139 fclose(dfp); 140 return ((PWDICT *) 0); 141 } 142 143 if (pdesc.header.pih_blocklen != NUMWORDS) 144 { 145 fprintf(stderr, "%s: size mismatch\n", prefix); 146 147 pdesc.header.pih_magic = 0; 148 fclose(ifp); 149 fclose(dfp); 150 return ((PWDICT *) 0); 151 } 152 153 if (pdesc.flags & PFOR_USEHWMS) 154 { 155 if (fread(pdesc.hwms, 1, sizeof(pdesc.hwms), wfp) != sizeof(pdesc.hwms)) 156 { 157 pdesc.flags &= ~PFOR_USEHWMS; 158 } 159 160 PWHwmsToHostOrder (pdesc.hwms, sizeof (pdesc.hwms) / sizeof (int32)); 161 } 162 } 163 164 return (&pdesc); 165} 166 167int 168PWClose(pwp) 169 PWDICT *pwp; 170{ 171 int result; 172 173 if (pwp->header.pih_magic != PIH_MAGIC) 174 { 175 fprintf(stderr, "PWClose: close magic mismatch\n"); 176 return (-1); 177 } 178 179 if (pwp->flags & PFOR_WRITE) 180 { 181 pwp->flags |= PFOR_FLUSH; 182 PutPW(pwp, (char *) 0); /* flush last index if necess */ 183 184 if (fseek(pwp->ifp, 0L, 0)) 185 { 186 fprintf(stderr, "index magic fseek failed\n"); 187 return (-1); 188 } 189 190 PWDictHeaderToNetworkOrder (&pwp->header); 191 result = fwrite((char *) &pwp->header, sizeof(pwp->header), 1, pwp->ifp); 192 PWDictHeaderToHostOrder (&pwp->header); 193 194 if (!result) 195 { 196 fprintf(stderr, "index magic fwrite failed\n"); 197 return (-1); 198 } 199 200 if (pwp->flags & PFOR_USEHWMS) 201 { 202 int i; 203 for (i=1; i<=0xff; i++) 204 { 205 if (!pwp->hwms[i]) 206 { 207 pwp->hwms[i] = pwp->hwms[i-1]; 208 } 209#ifdef DEBUG 210 printf("hwm[%02x] = %d\n", i, pwp->hwms[i]); 211#endif 212 } 213 214 PWHwmnToNetworkOrder (pwp->hwms, sizeof (pwp->hwms) / sizeof (int32)); 215 fwrite(pwp->hwms, 1, sizeof(pwp->hwms), pwp->wfp); 216 PWHwmsToHostOrder (pwp->hwms, sizeof (pwp->hwms) / sizeof (int32)); 217 } 218 } 219 220 fclose(pwp->ifp); 221 fclose(pwp->dfp); 222 223 pwp->header.pih_magic = 0; 224 225 return (0); 226} 227 228int 229PutPW(pwp, string) 230 PWDICT *pwp; 231 char *string; 232{ 233 if (!(pwp->flags & PFOR_WRITE)) 234 { 235 return (-1); 236 } 237 238 if (string) 239 { 240 strlcpy(pwp->data[pwp->count], string, MAXWORDLEN); 241 242 pwp->hwms[string[0] & 0xff]= pwp->header.pih_numwords; 243 244 ++(pwp->count); 245 ++(pwp->header.pih_numwords); 246 247 } else if (!(pwp->flags & PFOR_FLUSH)) 248 { 249 return (-1); 250 } 251 252 if ((pwp->flags & PFOR_FLUSH) || !(pwp->count % NUMWORDS)) 253 { 254 int i; 255 int32 datum; 256 register char *ostr; 257 258 datum = htonl ((int32) ftell(pwp->dfp)); 259 fwrite((char *) &datum, sizeof(datum), 1, pwp->ifp); 260 261 fputs(pwp->data[0], pwp->dfp); 262 putc(0, pwp->dfp); 263 264 ostr = pwp->data[0]; 265 266 for (i = 1; i < NUMWORDS; i++) 267 { 268 register int j; 269 register char *nstr; 270 nstr = pwp->data[i]; 271 272 if (nstr[0]) 273 { 274 for (j = 0; ostr[j] && nstr[j] && (ostr[j] == nstr[j]); j++); 275 putc(j & 0xff, pwp->dfp); 276 fputs(nstr + j, pwp->dfp); 277 } 278 putc(0, pwp->dfp); 279 280 ostr = nstr; 281 } 282 283 memset(pwp->data, '\0', sizeof(pwp->data)); 284 pwp->count = 0; 285 } 286 return (0); 287} 288 289char * 290GetPW(pwp, number) 291 PWDICT *pwp; 292 int32 number; 293{ 294 int32 datum; 295 register int i; 296 register char *ostr; 297 register char *nstr; 298 register char *bptr; 299 char buffer[NUMWORDS * MAXWORDLEN]; 300 static char data[NUMWORDS][MAXWORDLEN]; 301 static int32 prevblock = 0xffffffff; 302 int32 thisblock; 303 304 thisblock = number / NUMWORDS; 305 306 if (prevblock == thisblock) 307 { 308 return (data[number % NUMWORDS]); 309 } 310 311 if (fseek(pwp->ifp, sizeof(struct pi_header) + (thisblock * sizeof(int32)), 0)) 312 { 313 perror("(index fseek failed)"); 314 return ((char *) 0); 315 } 316 317 if (!fread((char *) &datum, sizeof(datum), 1, pwp->ifp)) 318 { 319 perror("(index fread failed)"); 320 return ((char *) 0); 321 } 322 323 datum = ntohl (datum); 324 325 if (fseek(pwp->dfp, datum, 0)) 326 { 327 perror("(data fseek failed)"); 328 return ((char *) 0); 329 } 330 331 if (!fread(buffer, 1, sizeof(buffer), pwp->dfp)) 332 { 333 perror("(data fread failed)"); 334 return ((char *) 0); 335 } 336 337 prevblock = thisblock; 338 339 bptr = buffer; 340 341 for (ostr = data[0]; *(ostr++) = *(bptr++); /* nothing */ ); 342 343 ostr = data[0]; 344 345 for (i = 1; i < NUMWORDS; i++) 346 { 347 nstr = data[i]; 348 strlcpy(nstr, ostr, MAXWORDLEN); 349 350 ostr = nstr + *(bptr++); 351 while (*(ostr++) = *(bptr++)); 352 353 ostr = nstr; 354 } 355 356 return (data[number % NUMWORDS]); 357} 358 359int32 360FindPW(pwp, string) 361 PWDICT *pwp; 362 char *string; 363{ 364 register int32 lwm; 365 register int32 hwm; 366 register int32 middle; 367 register char *this; 368 int idx; 369 370 if (pwp->flags & PFOR_USEHWMS) 371 { 372 idx = string[0] & 0xff; 373 lwm = idx ? pwp->hwms[idx - 1] : 0; 374 hwm = pwp->hwms[idx]; 375 } else 376 { 377 lwm = 0; 378 hwm = PW_WORDS(pwp) - 1; 379 } 380 381#ifdef DEBUG 382 printf("---- %lu, %lu ----\n", lwm, hwm); 383#endif 384 385 for (;;) 386 { 387 int cmp; 388 389#ifdef DEBUG 390 printf("%lu, %lu\n", lwm, hwm); 391#endif 392 393 middle = lwm + ((hwm - lwm + 1) / 2); 394 395 if (middle == hwm) 396 { 397 break; 398 } 399 400 this = GetPW(pwp, middle); 401 cmp = strcmp(string, this); /* INLINE ? */ 402 403 if (cmp < 0) 404 { 405 hwm = middle; 406 } else if (cmp > 0) 407 { 408 lwm = middle; 409 } else 410 { 411 return (middle); 412 } 413 } 414 415 return (PW_WORDS(pwp)); 416} 417