/*
  Lister Source Code - Released August 9th, 1991
  Copyright 1991 Baf! Technologies
  Written by Kerry Cianos and Geoffrey Faivre-Malloy
  E-mail at : ktc0440c@apsu.bitnet or jjm7609c@apsu.bitnet
*/

/* include our source code */

#include "lister.h"
#include "Output.c"
#include "ListArc.c"
#include "ListArj.c"
#include "ListCpio.c"
#include "ListLharc.c"
#include "ListSit.c"
#include "ListTar.c"
#include "ListZip.c"
#include "ListZoo.c"

char *vers = "$VER: Lister 1.25" ;

main (int argc, char *argv[])
{
  ULONG i;
  BOOL ok;
  int x,count;
  myfunc_p fn[NUMTYPES];

  fn[0] = ListArc;
  fn[1] = ListArj;
  fn[2] = ListCpio;
  fn[3] = ListLharc;
  fn[4] = ListLharc;
  fn[5] = ListSit;
  fn[6] = ListTar;
  fn[7] = ListZip;
  fn[8] = ListZoo;

  if (argc >= 2)
   {
     for (count=1; count < argc;count++)
      {
        i = Detect(argv[count]);
        if ((i & ADD_EXT) || (i & SAME))
         for (x=0; x < NUMTYPES; x++)
          {
            if (i & ADD_EXT)
             {
             if (i & pow2(x)) CheckError(fn[x](x|ADD_EXT,argv[count]));
             }
            else if (i & pow2(x)) CheckError(fn[x](x|SAME,argv[count]));
           }
        else if (i & NOTFOUND)
         {
           for(i=0; i < NUMTYPES; i++)
            {
             ok = fn[i](i|SAME,argv[count]);
             if (ok == TRUE) break;
            }
          if (ok == WRONG_ARCHIVE) CheckError(UNKNOWN);
         }
      }
   }
  else Usage(argv[0]);
  return(0);
}

void Usage(char *name)
{
  printf("\nLister v1.25 -  Copyright 1992 Baf! Technologies\n");
  printf("Email us at : ktc0440c@apsu.bitnet or gf7609c@apsu.bitnet\n\n");
  printf("Usage : %s <filename>\n\n",name);
  exit(0);
}

/*  Converts from MS-DOG time and date to english format
    and places the string into the global time_str */
BOOL MSDog(int time, int date, UBYTE *time_str)
{
  unsigned int yr, mo, day, hr, min, sec;

  yr = (date >> 9 & 0x7f) + 1980;
  mo = date >> 5 & 0x0f;
  day = date & 0x1f;
  hr = time >> 11 & 0x1f;
  min = time >> 5 & 0x3f;
  sec = (time & 0x1f) * 2;

#ifdef CHECKDATE
  if ( (mo < 1) || (mo > 12) || (day < 1) || (day > 31) || (hr < 0) ||
    (hr > 23) || (min < 0) || (min > 59) || (sec < 0) || (sec > 59) ) {
    Error("Corrupted archive!");
    return abort;
    }
#endif

  sprintf(time_str, "%2d-%s-%d %02d:%02d:%02d", day, months[mo-1], yr, hr,
    min, sec);
  return OK;
}

/* This will return an unsigned long integer calculated from the global */
/* buffer used for storage.  Pass the high byte to this routine.        */

ULONG GetLong (UBYTE *b,int temp)
{
  return ((ULONG) (b[temp] << 24) + (ULONG) (b[temp-1] << 16) +
          (ULONG) (b[temp-2] << 8) + (ULONG) b[temp-3]);
}

/* Open the input file */
FILE *OpenFile(ULONG type,UBYTE *infile)
{
  UBYTE filename[256];
  FILE *fp;

  if ((type & (SAME | ADD_EXT)) == SAME)
    sprintf(filename,"%s",infile);
  else sprintf(filename,"%s%s",infile,filetype[type-ADD_EXT]);
  fp = fopen(filename,"rb");
  if (fp == NULL) CheckError(FILE_ERROR);
   else return fp;
}

/* Read x bytes from infile - Do error checking here too */

int
ReadBuf(int x,FILE *fp,UBYTE *b)
{
  int count;
  count = fread(b,x,1,fp);
  if (count == 0)
    { fclose (fp); CheckError(FILE_ERROR); }
  else return (count);
}

/* routine to convert octal stored ascii into numerical form */
int
Convert8(char *str)
{
  int x;

  x = (str[5] - 48) + (str[4] - 48) * 8 + (str[3] - 48) * 64 +
      (str[2] - 48) * 512 + (str[1] - 48) * 4096 + (str[0] - 48) * 32768;
  return (x);
}

ULONG Detect(UBYTE *infile)
{
  int i;
  ULONG type = NOTFOUND;

  for (i = 0; i < NUMTYPES; i++)
    if (strstr(infile,filetype[i]) != NULL)
      return SAME | pow2(i);
  for (i = 0; i < NUMTYPES; i++)
    if (CheckFile(filetype[i],infile))
      type |= ADD_EXT | pow2(i);
  if (type == NOTFOUND && !CheckFile("",infile)) CheckError(NOTFOUND);
  return type;
}

BOOL
CheckFile(char *ext,UBYTE *infile)
{
  char temp[132];
  FILE *fp;

  sprintf(temp,"%s%s",infile,ext);
  if ((fp = fopen (temp,"r")) != NULL)
   {
    fclose(fp);
    return TRUE;
   }
  else return FALSE;
}

ULONG pow2(int i)
{
  ULONG x = 1;
  for (;i != 0; i--)
   x *= 2;
  return x;
}
