#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libraries/dos.h>
#include <exec/memory.h>
#include <proto/dos.h>
#include <proto/exec.h>

unsigned long int TotBytes;
unsigned long int TotDirs;
unsigned long int TotFiles;
char GlobalFileName[512];

BOOL DoSizeCheck(BPTR);

int CXBRK() {return(0);}
int chkabort() {return(0);}

void main(argc,argv)
int argc;
char *argv[];
{
   BPTR mylock;

   TotBytes=0;
   TotDirs=0;
   TotFiles=0;

   printf("sc - size check by Jean-François Stenuit\n");
   if (argc!=2)
   {
      printf("Usage : sc filename|dirname\n");
      exit(0);
   };
   if (argv[1][strlen(argv[1])-1]=='/')
      argv[1][strlen(argv[1])-1]=0;
   if ((mylock=Lock(argv[1],ACCESS_READ))==0)
   {
      printf("Unable to lock %s, DOS error code %d.\n",argv[1],IoErr());
      exit(0);
   };
   strcpy(GlobalFileName,argv[1]);
   if (DoSizeCheck(mylock)==FALSE)
      printf("Recursive routine failed\n");
   else
      printf("%s contains %d files and %d subdirs, summing %d bytes.\n",
              argv[1],    TotFiles,    TotDirs,            TotBytes);
   UnLock(mylock);
   exit(0);
}

BOOL DoSizeCheck(ALock)
BPTR ALock;
{
   register struct FileInfoBlock *myFIB;
   register BPTR NewLock;
   register short int i;
   register char tmp;

   if ((myFIB=(struct FileInfoBlock *)
        AllocMem(sizeof(struct FileInfoBlock),MEMF_PUBLIC))==0)
      return(FALSE);
   if (Examine(ALock,myFIB)==FALSE)
   {
      FreeMem((APTR)myFIB,sizeof(struct FileInfoBlock));
      return(FALSE);
   };
   if (myFIB->fib_DirEntryType<0)
   /* A file : just add its size to total */
   {
      TotBytes+=myFIB->fib_Size;
      TotFiles++;
      FreeMem((APTR)myFIB,sizeof(struct FileInfoBlock));
      return(TRUE);
   }
   else
   /* A subdir : check the whole contents */
   {
      for(;;)
      {
         if (ExNext(ALock,myFIB)==FALSE)
         {
            FreeMem((APTR)myFIB,sizeof(struct FileInfoBlock));
            if (IoErr()==ERROR_NO_MORE_ENTRIES)
               return(TRUE);
            else
               return(FALSE);
         }
         else
         {
            if (myFIB->fib_DirEntryType<0)
            {
               TotBytes+=myFIB->fib_Size;
               TotFiles++;
            }
            else
            {
               TotDirs++;
               if (GlobalFileName[strlen(GlobalFileName)-1]!=':')
                  strcat(GlobalFileName,"/");
               strcat(GlobalFileName,myFIB->fib_FileName);
               NewLock=Lock(GlobalFileName,ACCESS_READ);
               if (DoSizeCheck(NewLock)==FALSE)
               {
                  UnLock(NewLock);
                  FreeMem((APTR)myFIB,sizeof(struct FileInfoBlock));
                  return(FALSE);
               };
               for (i=strlen(GlobalFileName);
                            ((tmp=GlobalFileName[i])!='/')&&(tmp!=':');
                             i--)
                  GlobalFileName[i]=0;
               if (GlobalFileName[i]!=':')
                  GlobalFileName[i]=0;
               UnLock(NewLock);
            };
         };
      };
   };
}
