/*************************************************************************
*                                unpList                                 *
*                                                                        *
* With this program you can see what different files are crunched with.  *
*                                                                        *
*************************************************************************/

// First we include a lot of things

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <exec/types.h>
#include <dos/rdargs.h>
#include <dos/dosextens.h>
#include <libraries/unpack.h>

#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/unpack.h>


// Global Variables
struct  Library *UnpackBase;
struct  UnpackInfo *cinfo=NULL;
struct  RDArgs *rda=NULL;
BPTR    oldlock;


#ifdef LATTICE
void __regargs _CXBRK(void)               // Catch CTRL-C Handling
{
  fprintf(stderr,"*** User breaked\n");   // Print out break message
  CurrentDir(oldlock);                    // and clean up after us
  upFreeCInfo(cinfo);
  CloseLibrary(UnpackBase);
  FreeArgs(rda);
  exit(0);                                // then we exit our program.
}
#endif


// Prototypes
void ScanDir(struct UnpackInfo *ui, BPTR mylock);
void TestFile(struct UnpackInfo *info, char *name);
void PrintName(char *name);


// Main program
void main (void)
{
extern  struct ExecBase *SysBase;
struct  FileInfoBlock fib;
struct  Process *mytask;

LONG    arguments[1] = {0};
BPTR    dirlock;

char   *name;
int     i=0;

  if( ((struct Library*) DOSBase)->lib_Version < 37 )
  {
      fprintf(stderr,"unpList requires at least Kickstart 2.04!\n");
      exit(0);
  }

  if (rda = ReadArgs("FILE=DIR/M",arguments,NULL))
  {
    if (UnpackBase = OpenLibrary("unpack.library",42L))
    {
      if (cinfo = upAllocCInfo())
      {
        printf("unpList 1.0 (2/10-1995) by Thomas Neumann\n\n");
        mytask = (struct Process *)FindTask(NULL);
        oldlock = mytask->pr_CurrentDir;

        if (arguments[0] == NULL) // If no arguments are given, scan
        {                         // current directory.
          dirlock = (oldlock);
          ScanDir(cinfo, dirlock);
        }
        else
        {
          // It this complex or what? :)
          while ((name = (char *)((LONG *)arguments[0])[i++]))
          {
            // Lock given name
            if ((dirlock = Lock(name, ACCESS_READ)) != NULL)
            {
              Examine(dirlock, &fib);
              if (fib.fib_DirEntryType > 0)
                ScanDir(cinfo, dirlock);    // It's a directory
              else
                TestFile(cinfo, name);      // It's a file
              UnLock(dirlock);
            }
            else
              TestFile(cinfo, name);        // Couldn't lock
          }
        }
        upFreeCInfo(cinfo);
      }
      CloseLibrary(UnpackBase);
    }
    else
      fprintf(stderr,"You need the unpack.library version 42 or higher\n");

  FreeArgs(rda);
  }
  else
    PrintFault(IoErr(),NULL);
}


void ScanDir (struct UnpackInfo *ui, BPTR mylock)
{
struct FileInfoBlock fib;

  oldlock = CurrentDir(mylock);         // Set current directory

  if (Examine(mylock, &fib))
    while (ExNext(mylock, &fib))        // Test all files in directory
    {
      if (fib.fib_DirEntryType < 0)
        TestFile(ui, fib.fib_FileName); // We got a file
      else
      {
        PrintName(fib.fib_FileName);    // Print out directory name
        printf(" (DIR)\n");
      }
    }

  CurrentDir(oldlock);                  // Set current directory back
}


void TestFile (struct UnpackInfo *info, char *name)
{
  PrintName(name);

  if (upDetermineFile(info,name))
    printf("%6ld %s\n",info->ui_CrunchLen,info->ui_CruncherName);
  else
    printf("%6ld %s\n",info->ui_CrunchLen,info->ui_ErrorMsg);
}


void PrintName(char *name)
{
int j,k;

  printf("%s",name);
  if ((k = 30-strlen(name)) < 0)
    k=1;

  for (j=0;j<k;j++)
    printf(" ");
}
