/*
 * DeleteTool.c   V1.0
 *
 * Trashcan tool for ToolManager
 *
 * (c) 1991 by Stefan Becker
 *
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <workbench/icon.h>
#include <workbench/startup.h>
#include <dos/exall.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#include <clib/icon_protos.h>
#include <clib/intuition_protos.h>

/* Global data */
char Version[]="$VER: DeleteTool 1.0 (10.10.1991)";
char About[]="DeleteTool V1.0 (10.10.1991)\nŠ 1991 Stefan Becker\n"\
             "This program is freely distributable\n"\
             "It eats all files you drop on it!";
struct Library *IconBase;
char Template[]="QUIET/S,NAMES/M";
struct {
        ULONG quiet;
        char  **names;
       } def={FALSE,NULL};
struct EasyStruct SafetyES={sizeof(struct EasyStruct),0,"DeleteTool",
                            "Warning: You cannot get\nback what you delete!",
                            "Ok|Cancel"};
struct EasyStruct AboutES={sizeof(struct EasyStruct),0,"About",About,"OK"};

/* Recursive directory scan */
static void ScanDirectory(BPTR dl)
{
 struct ExAllControl *eac;
 struct ExAllData *eadata;
 BPTR ofl;
 BOOL more;

 /* Get memory for ExAllControl */
 if (!(eac=AllocDosObject(DOS_EXALLCONTROL,NULL))) goto sde1;

 /* Get memory for ExAllControl */
 if (!(eadata=malloc(10*sizeof(struct ExAllData)))) goto sde2;

 /* Initialize ExAllControl */
 eac->eac_LastKey=0;
 eac->eac_MatchString=NULL; /* Delete all files except "*.info" */
 eac->eac_MatchFunc=NULL;

 /* Scan directory */
 ofl=CurrentDir(dl);
 do
  {
   register struct ExAllData *ead;

   /* Get directory entries */
   more=ExAll(dl,eadata,10*sizeof(struct ExAllData),ED_TYPE,eac);

   /* Check result */
   if (!more && (IoErr()!=ERROR_NO_MORE_ENTRIES)) /* Error occured */
    break;

   /* Finished? */
   if (eac->eac_Entries==0)
    continue;

   /* Examine results */
   ead=eadata;
   do
    {
     LONG len;

     /* Directory? */
     if (ead->ed_Type>=0)
      {
       BPTR fl=Lock(ead->ed_Name,SHARED_LOCK);

       /* Recursion */
       if (fl)
        {
         ScanDirectory(fl);
         UnLock(fl);
        }
      }

     /* File or icon? */
     len=strlen(ead->ed_Name);
     if ((len>4) && !stricmp(ead->ed_Name+len-5,".info"))
      {
       /* Icon */
       SetProtection(ead->ed_Name,0);
       ead->ed_Name[len-5]='\0';      /* remove the ".info" */
       DeleteDiskObject(ead->ed_Name);
      }
     else
      {
       /* File */
       char *cp;

       SetProtection(ead->ed_Name,0);
       if (DeleteFile(ead->ed_Name) && (cp=malloc(len+6)))
        {
         BPTR fl;

         /* Create icon name */
         strcpy(cp,ead->ed_Name);
         strcat(cp,".info");

         /* No icon? Create it! */
         if (fl=Lock(cp,SHARED_LOCK))
          UnLock(fl);
         else
          {
           BPTR fh=Open(cp,MODE_NEWFILE);
           if (fh) Close(fh);
          }

         /* Delete icon */
         SetProtection(cp,0);
         DeleteDiskObject(ead->ed_Name);
         free(cp);
        }
      }

     /* Next entry */
     ead=ead->ed_Next;
    }
   while (ead);
  }
 while (more);

 CurrentDir(ofl);

 /* Free all resources */
 free(eadata);
sde2: FreeDosObject(DOS_EXALLCONTROL,eac);
sde1: return;
}

/* Requester function */
BOOL PopUpRequester(struct EasyStruct *es)
{
 struct Screen *pubsc;
 struct Window *w=NULL;
 BOOL rc;

 /* Get Window pointer */
 if (pubsc=LockPubScreen("Workbench"))
  w=pubsc->FirstWindow;

 /* Pop up requester */
 rc=EasyRequest(w,es,NULL,"");

 /* Unlock screen */
 if (pubsc) UnlockPubScreen(NULL,pubsc);

 return(rc);
}

/* CLI entry point */
void main(int argc, char **argv)
{
 struct RDArgs *rda;
 struct FileInfoBlock *fib;
 char **name;

 /* Open icon.library V37: DeleteDiskObject() is new for V37!!! */
 if (!(IconBase=OpenLibrary(ICONNAME,37))) goto me1;

 /* Read command line arguments */
 rda=ReadArgs(Template,(LONG *) &def,NULL);

 /* Get memory for FIB */
 if (!(fib=calloc(sizeof(struct FileInfoBlock),1))) goto me2;

 /* Any objects to delete? */
 if (name=def.names)
  {
   /* Yes. Should we open a safety requester? */
   if (!def.quiet && !PopUpRequester(&SafetyES)) goto me3;

   /* Delete objects */
   while (*name)
    {
     BPTR fl;
     char *cp;
     ULONG len;
     BOOL deleted;

     /* Init variables */
     cp=*name;
     len=strlen(cp)-1;
     deleted=TRUE;

     /* File or Directory? */
     if (fl=Lock(cp,SHARED_LOCK))
      if (Examine(fl,fib))
       {
        /* Directory? */
        if (fib->fib_DirEntryType>=0)
         ScanDirectory(fl); /* Delete all files in directory */

        /* Remove trailing '/' */
        if (cp[len]=='/') cp[len]='\0';

        /* Delete file */
        UnLock(fl);
        SetProtection(cp,0);
        if (!DeleteFile(cp)) deleted=FALSE;
       }
      else UnLock(fl);

     /* Delete icon */
     if (deleted && (cp=malloc(len+7)))
      {
       /* Create icon file name */
       strcpy(cp,*name);
       strcat(cp,".info");

       /* No icon? Create it! */
       if (fl=Lock(cp,SHARED_LOCK))
        UnLock(fl);
       else
        {
         BPTR fh=Open(cp,MODE_NEWFILE);
         if (fh) Close(fh);
        }

       /* Delete icon */
       SetProtection(cp,0);
       DeleteDiskObject(*name);
       free(cp);
      }

     /* Next argument */
     name++;
    }
  }
 else /* Pop up about requester */
  PopUpRequester(&AboutES);

 /* Exit program */
me3: free(fib);
me2: if (rda) FreeArgs(rda);
     CloseLibrary(IconBase);
me1: exit(0);
}
