/* List a Tar archive */
BOOL
ListTar(ULONG type,UBYTE *infile)
{
  ULONG tfiles = 0, tcomp = 0, tuncomp = 0, time, uncomp;
  FILE *fp;
  struct TarInfoBlock tar;
  struct tm *tm;
  UBYTE time_str[25];

  /* Open the file up.  Abort if file not found or error occurs */
  fp = OpenFile(type,infile);

  if (!GetHeader(&tar,fp) || !Checksum(&tar)) return WRONG_ARCHIVE;
  fseek(fp,0,SEEK_SET);

  /* Initialize the start of the list */
  InitList(TAR,infile);

  /* Loop until there is a Zero in the first byte of the name */
  while (GetHeader(&tar,fp))
    {
      if (!Checksum(&tar))
        {
          printf("\nChecksum Error in File Header - Aborting\n");
          break;
        }

      /* Read in the uncompressed size */
      sscanf (tar.size,"%8o\n",&uncomp);

      /* Read in date of stored file and put it in string */
      sscanf (tar.mtime,"%12o",&time);
      tm = localtime (&time);

      sprintf (time_str,"%02d-%s-19%d %02d:%02d:%02d",
        tm->tm_mday,months[tm->tm_mon],tm->tm_year,tm->tm_hour,
        tm->tm_min,tm->tm_sec);

      /* Print out statistics read in */
      PrintList(tar.name, uncomp, uncomp,&tfiles,&tcomp,&tuncomp,time_str);

      /* Seek to next header in list */
      fseek (fp,512 - (sizeof tar) + uncomp,SEEK_CUR);
      if ( (uncomp != 0) && ((uncomp % 512) != 0) )
       {
         uncomp = 512 - uncomp % 512;
         fseek (fp,uncomp,SEEK_CUR);
       }
    }

   /* Close the file and print the ending statistics. */
   fclose (fp);
   EndStats(tfiles,tcomp,tuncomp);
   return (TRUE);
}

/* Function to read the tar header structure into memory */
BOOL
GetHeader(struct TarInfoBlock *tar,FILE *fp)
{
  fread (tar->name,1,100,fp);
  if (tar->name[0] == 0)
    return (FALSE);
  fread (tar->mode,1,8,fp);
  fread (tar->uid,1,8,fp);
  fread (tar->gid,1,8,fp);
  fread (tar->size,1,12,fp);
  fread (tar->mtime,1,12,fp);
  fread (tar->chksum,1,8,fp);
  fread (tar->linkflag,1,1,fp);
  fread (tar->linkname,1,100,fp);
  fread (tar->rdev,1,6,fp);
  return (TRUE);
}

BOOL
Checksum (struct TarInfoBlock *tar)
{
  ULONG checksum = 0,ok;
  char *i;

  for (i = tar->name; i <= tar->mtime+11;i++)
    checksum += *i;
  checksum += 8*32;
  for (i = tar->linkflag; i <= tar->rdev+5;i++)
    checksum += *i;
  sscanf(tar->chksum,"%8o",&ok);
  return (ok == checksum);
}
