356 lines
6.4 KiB
C
356 lines
6.4 KiB
C
/*
|
|
* 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));
|
|
}
|