/* * This program is copyright Alec Muffett 1993. The author disclaims all * responsibility or liability with respect to it's usage or its effect * upon hardware or computer systems, and maintains copyright as set out * in the "LICENCE" document which accompanies distributions of Crack v4.0 * and upwards. */ #include "packer.h" static char vers_id[] = "packlib.c : v2.3p2 Alec Muffett 18 May 1993"; PWDICT * PWOpen(prefix, mode) char *prefix; char *mode; { int32 i; static PWDICT pdesc; char iname[STRINGSIZE]; char dname[STRINGSIZE]; char wname[STRINGSIZE]; char buffer[STRINGSIZE]; FILE *dfp; FILE *ifp; FILE *wfp; if (pdesc.header.pih_magic == PIH_MAGIC) { fprintf(stderr, "%s: another dictionary already open\n", prefix); return ((PWDICT *) 0); } memset(&pdesc, '\0', sizeof(pdesc)); sprintf(iname, "%s.pwi", prefix); sprintf(dname, "%s.pwd", prefix); sprintf(wname, "%s.hwm", prefix); if (!(pdesc.dfp = fopen(dname, mode))) { perror(dname); return ((PWDICT *) 0); } if (!(pdesc.ifp = fopen(iname, mode))) { fclose(pdesc.dfp); perror(iname); return ((PWDICT *) 0); } if (pdesc.wfp = fopen(wname, mode)) { pdesc.flags |= PFOR_USEHWMS; } ifp = pdesc.ifp; dfp = pdesc.dfp; wfp = pdesc.wfp; if (mode[0] == 'w') { pdesc.flags |= PFOR_WRITE; pdesc.header.pih_magic = PIH_MAGIC; pdesc.header.pih_blocklen = NUMWORDS; pdesc.header.pih_numwords = 0; fwrite((char *) &pdesc.header, sizeof(pdesc.header), 1, ifp); } else { pdesc.flags &= ~PFOR_WRITE; if (!fread((char *) &pdesc.header, sizeof(pdesc.header), 1, ifp)) { fprintf(stderr, "%s: error reading header\n", prefix); pdesc.header.pih_magic = 0; fclose(ifp); fclose(dfp); return ((PWDICT *) 0); } if (pdesc.header.pih_magic != PIH_MAGIC) { fprintf(stderr, "%s: magic mismatch\n", prefix); pdesc.header.pih_magic = 0; fclose(ifp); fclose(dfp); return ((PWDICT *) 0); } if (pdesc.header.pih_blocklen != NUMWORDS) { fprintf(stderr, "%s: size mismatch\n", prefix); pdesc.header.pih_magic = 0; fclose(ifp); fclose(dfp); return ((PWDICT *) 0); } if (pdesc.flags & PFOR_USEHWMS) { if (fread(pdesc.hwms, 1, sizeof(pdesc.hwms), wfp) != sizeof(pdesc.hwms)) { pdesc.flags &= ~PFOR_USEHWMS; } } } return (&pdesc); } int PWClose(pwp) PWDICT *pwp; { if (pwp->header.pih_magic != PIH_MAGIC) { fprintf(stderr, "PWClose: close magic mismatch\n"); return (-1); } if (pwp->flags & PFOR_WRITE) { pwp->flags |= PFOR_FLUSH; PutPW(pwp, (char *) 0); /* flush last index if necess */ if (fseek(pwp->ifp, 0L, 0)) { fprintf(stderr, "index magic fseek failed\n"); return (-1); } if (!fwrite((char *) &pwp->header, sizeof(pwp->header), 1, pwp->ifp)) { fprintf(stderr, "index magic fwrite failed\n"); return (-1); } if (pwp->flags & PFOR_USEHWMS) { int i; for (i=1; i<=0xff; i++) { if (!pwp->hwms[i]) { pwp->hwms[i] = pwp->hwms[i-1]; } #ifdef DEBUG printf("hwm[%02x] = %d\n", i, pwp->hwms[i]); #endif } fwrite(pwp->hwms, 1, sizeof(pwp->hwms), pwp->wfp); } } fclose(pwp->ifp); fclose(pwp->dfp); pwp->header.pih_magic = 0; return (0); } int PutPW(pwp, string) PWDICT *pwp; char *string; { if (!(pwp->flags & PFOR_WRITE)) { return (-1); } if (string) { strncpy(pwp->data[pwp->count], string, MAXWORDLEN); pwp->data[pwp->count][MAXWORDLEN - 1] = '\0'; pwp->hwms[string[0] & 0xff]= pwp->header.pih_numwords; ++(pwp->count); ++(pwp->header.pih_numwords); } else if (!(pwp->flags & PFOR_FLUSH)) { return (-1); } if ((pwp->flags & PFOR_FLUSH) || !(pwp->count % NUMWORDS)) { int i; int32 datum; register char *ostr; datum = (int32) ftell(pwp->dfp); fwrite((char *) &datum, sizeof(datum), 1, pwp->ifp); fputs(pwp->data[0], pwp->dfp); putc(0, pwp->dfp); ostr = pwp->data[0]; for (i = 1; i < NUMWORDS; i++) { register int j; register char *nstr; nstr = pwp->data[i]; if (nstr[0]) { for (j = 0; ostr[j] && nstr[j] && (ostr[j] == nstr[j]); j++); putc(j & 0xff, pwp->dfp); fputs(nstr + j, pwp->dfp); } putc(0, pwp->dfp); ostr = nstr; } memset(pwp->data, '\0', sizeof(pwp->data)); pwp->count = 0; } return (0); } char * GetPW(pwp, number) PWDICT *pwp; int32 number; { int32 datum; register int i; register char *ostr; register char *nstr; register char *bptr; char buffer[NUMWORDS * MAXWORDLEN]; static char data[NUMWORDS][MAXWORDLEN]; static int32 prevblock = 0xffffffff; int32 thisblock; thisblock = number / NUMWORDS; if (prevblock == thisblock) { return (data[number % NUMWORDS]); } if (fseek(pwp->ifp, sizeof(struct pi_header) + (thisblock * sizeof(int32)), 0)) { perror("(index fseek failed)"); return ((char *) 0); } if (!fread((char *) &datum, sizeof(datum), 1, pwp->ifp)) { perror("(index fread failed)"); return ((char *) 0); } if (fseek(pwp->dfp, datum, 0)) { perror("(data fseek failed)"); return ((char *) 0); } if (!fread(buffer, 1, sizeof(buffer), pwp->dfp)) { perror("(data fread failed)"); return ((char *) 0); } prevblock = thisblock; bptr = buffer; for (ostr = data[0]; *(ostr++) = *(bptr++); /* nothing */ ); ostr = data[0]; for (i = 1; i < NUMWORDS; i++) { nstr = data[i]; strcpy(nstr, ostr); ostr = nstr + *(bptr++); while (*(ostr++) = *(bptr++)); ostr = nstr; } return (data[number % NUMWORDS]); } int32 FindPW(pwp, string) PWDICT *pwp; char *string; { register int32 lwm; register int32 hwm; register int32 middle; register char *this; int idx; if (pwp->flags & PFOR_USEHWMS) { idx = string[0] & 0xff; lwm = idx ? pwp->hwms[idx - 1] : 0; hwm = pwp->hwms[idx]; } else { lwm = 0; hwm = PW_WORDS(pwp) - 1; } #ifdef DEBUG printf("---- %lu, %lu ----\n", lwm, hwm); #endif for (;;) { int cmp; #ifdef DEBUG printf("%lu, %lu\n", lwm, hwm); #endif middle = lwm + ((hwm - lwm + 1) / 2); if (middle == hwm) { break; } this = GetPW(pwp, middle); cmp = strcmp(string, this); /* INLINE ? */ if (cmp < 0) { hwm = middle; } else if (cmp > 0) { lwm = middle; } else { return (middle); } } return (PW_WORDS(pwp)); }