#include <libraries/dos.h>
#include <exec/memory.h>
#include "mb.h"
/*
 *  Directory access routines.
 */


/*
 *  A directory item looks like this:
struct FileInfoBlock {
   LONG fib_DiskKey;
   LONG fib_DirEntryType;
   char fib_FileName[108];
   LONG fib_Protection;
   LONG fib_EntryType;
   LONG fib_Size;
   LONG fib_NumBlocks;
   struct DateStamp fib_Date;
   char fib_Comment[80];
   char padding[36];
};
 */

typedef struct FileInfoBlock FCB;
extern char tmpstr[];
extern short debug;
static int olddta;
static FCB *fcb = 0;
static  struct InfoData *ID = 0L;
char wcstring[100];

/*
 *  Open directory, return first item.
 */
extern long Examine(),Lock(),ExNext();
diropen(cp, p, dirdef)
char   *cp;
DIRDEF *dirdef;
DIRENT *p;
{
   long  result,Info();
   extern char *AllocMem();
   if(fcb == 0) {
      fcb = (FCB *)AllocMem((long)sizeof(*fcb),
                                   (long)MEMF_PUBLIC|MEMF_CLEAR);
   }
   if(ID == 0) {
      ID = (struct InfoData *)AllocMem((long)sizeof(*ID),
                                   (long)MEMF_PUBLIC|MEMF_CLEAR);
   }

/*
 *  Get the first directory entry.
 */
   dirdef->lock = Lock(cp,ACCESS_READ);
   if(dirdef->lock == 0L) {
      p->size = -1;
      return (false);
   }
   if(Info(dirdef->lock,ID) == 0L) {
      /* If Info fails then the named file/device is NOT a disk */
      dirdef->size = 0L;
      dirdef->free = 0L;
      return(false);
   }
   else {
      dirdef->size =
              ((ID->id_BytesPerBlock*ID->id_NumBlocksUsed + 1023L) / 1024L);
      dirdef->free =
              ((ID->id_BytesPerBlock * ID->id_NumBlocks + 1023L) / 1024L)
                  - dirdef->size;
   }
   /* Examine this name to find out what it is - it MUST be a directory */
   if((result = Examine(dirdef->lock,fcb)) == 0L) {
      UnLock(dirdef->lock);
      p->size = -1;
      return (false);
   }
   if(fcb->fib_DirEntryType < 0) {  /* It's a file! That's WRONG! */
      UnLock(dirdef->lock);
      p->size = -1;
      return (false);
   }
   if(dirnext(p,dirdef))return(false);
   if(dodir(p)) return (true);
   return (false);
}
freefcb()
{
   if(fcb)FreeMem(fcb,(long)sizeof(*fcb));
   if(ID)FreeMem(ID,(long)sizeof(*ID));
}
/*
 *  Return first and succeeding filenames in the directory.
 *  And if a wildcard is specified only return the matching
 *  names.
 */

dirnext(p, dirdef)
DIRENT *p;
DIRDEF *dirdef;
{
   /* search for next filename in the directory */
   while(true) {
      if(ExNext(dirdef->lock,fcb) == 0L) {
         p->size    = -1;
         UnLock(dirdef->lock);
         return(1);
      }
      if (dodir(p)) {
         return(0);
      }
   }
}

dodir(p)
DIRENT *p;
{
   /* wcmatch checks wcstring against fcb->fib_FileName
      If the wildcard is null then everything matches it and
      wcmatch returns a true, otherwise it returns true only
      if the wcstring and filename match
   */
   if(wcmatch(&fcb->fib_FileName[0],&wcstring[0]) == 0)return(false);
   strcpy(p->name,&fcb->fib_FileName[0]);
   if(fcb->fib_DirEntryType >= 0) {  /*It's a directory */
      if(!match(p->name, "/")) {
         return (false);
      }
      if(port->mode & (local | sysop)) {
         strcat(p->name, "/");
      }
      else {
         return (false);
      }
   }
   /* return the size in Kb rounded up */
   p->size = (fcb->fib_Size+01777)>>10;
   return (true);
}

/*
 *  Modified form of getdir from original mbfile.c
 *  The amiga searches directories for wildcards in
 *  a different way than does the IBM. SO set it up
 *  for a wildcard match for the amiga.
 *
 */
extern DIRPATH *dphd;
DIRPATH *setdir(p)
char *p;
{
   register DIRPATH *dp;
   register char *cp,*pp;
   cp = p;
   pp = &wcstring[0];
   *pp = 0;
   for(dp = dphd; dp isnt NULL; dp = dp->next)
      if (dp->id is port->opt2)  {
         strcpy(port->line, dp->path);
         while(*cp)*pp++ = *cp++;
         *pp = 0;
         return dp;
      }
   port->msg = mndir;
   return NULL;
}
/* Check filename in *a against a possibly null wildcard string in *b */
wcmatch(a,b)
char *a,*b;
{
   register char *p,*q;
   p = a;
   q = b;
   /* If the wildcard is null then everything matches */
   if(*q == 0)return(1);
   if(*q == '*') {
      /* Leading wildcard * in the pattern */
      while(*p)p++;
      while(*q)q++;
      p--;
      q--;
      while(*q != '*') {
         if(toupper(*p) == toupper(*q)) {
            p--;
            q--;
            continue;
         }
         break;
      }
      if(*q == '*')return(1);
      return(0);
   }
   while(*p && *q && (*q != '*')) {
      if(toupper(*p) == toupper(*q)) {
         p++;
         q++;
         continue;
      }
      break;
   }
   if((*p == 0) && (*q == 0))return(1);
   if(*q == '*')return(1);
   return(0);
}
