/***************************************************************************
 *                                                                         *
 *   READPFN.C                                                             *
 *                                                                         *
 *   Copyright (c) 1996 Galacticomm, Inc.    All Rights Reserved.          *
 *                                                                         *
 *   This function reads a compiled profanity list into memory.  The       *
 *   caller must provide the buffer to be read into.                       *
 *                                                                         *
 *                                           - J. Alvrus    2/29/96        *
 *                                                                         *
 ***************************************************************************/

#include "gcommlib.h"

extern CHAR *profList[26];

// THIS IS TEMPORARY SO IT CAN COMPILE
#define PFN_MAXALC 256
#define RDPFN_OK		0
#define RDPFN_INVALID	1
#define RDPFN_OVERFLOW	2
#define RDPFN_FOPEN		3
#define RDPFN_EOF		4
// END OF TEMPORARY SHIT 

INT                                //   error code                         
readpfn(                           // read profanity data file             
const CHAR *filnam,                //   profanity data file path+name      
CHAR **pfnbuf)                     //   ptr to pfn list buffer (or NULL)   
{
     CHAR *tmpList[26];
     CHAR *c;
     INT i;
     USHORT *offsets;
     FILE *fp;
     Cffblk fb;
     CHAR *tmpbuf;

     if (!fnd1st(&fb,(CHAR *)filnam,0)) {
          return(RDPFN_FOPEN);
     }
     if (fb.ff_fsize > PFN_MAXALC) {
          return(RDPFN_INVALID);
     }
     if (fb.ff_fsize < 26*sizeof(USHORT)) {
          return(RDPFN_OVERFLOW);
     }
     if ((fp=fopen(filnam,FOPRB)) == NULL) {
          return(RDPFN_FOPEN);
     }
     tmpbuf=(CHAR *)alcmem((size_t)fb.ff_fsize);
     if (fread(tmpbuf,1,fb.ff_fsize,fp) != fb.ff_fsize) {
          fclose(fp);
          free(tmpbuf);
          return(RDPFN_EOF);
     }
     offsets=(USHORT *)tmpbuf;
     if (offsets[0] != 0) {
          fclose(fp);
          free(tmpbuf);
          return(RDPFN_INVALID);
     }
     if (tmpbuf[fb.ff_fsize-1] != '\0') {  // null termination for 'z' entry
          fclose(fp);
          free(tmpbuf);
          return(RDPFN_INVALID);
     }
     for (i=0 ; i < 26 ; i++) {
          if (offsets[i] < fb.ff_fsize-(26*sizeof(USHORT))) {
               tmpList[i]=&tmpbuf[offsets[i]+(26*sizeof(USHORT))];
          }
          else {
               fclose(fp);
               free(tmpbuf);
               return(RDPFN_OVERFLOW);
          }
          if (i > 0) {
               if (tmpList[i] <= tmpList[i-1]) {
                    fclose(fp);
                    free(tmpbuf);
                    return(RDPFN_INVALID);
               }
               if (*(tmpList[i]-1) != '\0') { // null term. for 'a'-'y' entries
                    fclose(fp);
                    free(tmpbuf);
                    return(RDPFN_INVALID);
               }
          }
     }
     for (i=0 ; i < 26 ; i++) {
          c=tmpList[i];
          for ( ; *c != '\0' ; c++) {
               if (*c > 3 && !islower(*c)) {
                    fclose(fp);
                    free(tmpbuf);
                    return(RDPFN_INVALID);
               }
          }
     }
     memmove(profList,tmpList,sizeof(profList));
     if (pfnbuf != NULL) {
          *pfnbuf=tmpbuf;
     }
     return(RDPFN_OK);
}