#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <conio.h>

typedef struct {
	char name[56];
  unsigned long offset, length;
} dirrec;  //64 bytes per entry

dirrec dir[500];   //32000 bytes, prolly
char buf[10000];

unsigned long dir_start, num_ents;

void main(int argc, char *argv[])
{
	FILE *in, *f;
  long l;
  int i, i1, i2, i3, i4;
  char s[80], c;

  strcpy(s,"G:\\QUAKE\\ID1.PAK");
  if (argc>1)
  	strcpy(s,argv[1]);
  in=fopen(s,"rb");
  if (!in)
  {
  	printf("Error opening \"%s\"",s);
    return;
  }
  fread((void *)s, 4, 1, in); //"PACK"
  fread((void *)&dir_start, 4, 1, in);
  fread((void *)&num_ents, 4, 1, in);
  num_ents/=64L;
	fseek(in,dir_start,SEEK_SET);

  if (num_ents>=500L)
  {
  	printf("Too many entries!\n");
    fclose(in);
    return;
  }

  fread((void *)dir, sizeof(dirrec), num_ents, in);

  i=0;
  while (1)
  {
  	printf("%d: \"%s\"\n",i,dir[i].name);
    printf("Length: %ld\n",dir[i].length);
    printf("\nWhat? ");
    c=toupper(getche());
    printf("\n\n");
    switch(c)
    {
    	case '[':
      case '-':
      	if (i==0)
        	i=num_ents-1;
        else
        	i--;
        break;
      case ']':
      case '+':
      case '=':
      	i++;
        if (i==num_ents)
        	i=0;
        break;
      case 's':
      case 'S':
      	for (i1=strlen(dir[i].name)-1; i1>0; i1--)
        	if (dir[i].name[i1]=='/')
          	break;
        i1++;
        if (!strchr(dir[i].name,'/'))
        	i1=0;
        strcpy(s,&dir[i].name[i1]);
        printf("Saving \"%s\"...\n",s);
        f=fopen(s,"wb");
        if (!f)
        {
        	printf("Error opening \"%s\"!\n",s);
          break;
        }
        fseek(in,dir[i].offset,SEEK_SET);
        i4=dir[i].length/9999;
        if (dir[i].length%9999)
        	i4++;
	      for (i2=0;i2<i4;i2++)
	      {
        	fread((void *)buf,1,9999,in);
          l=dir[i].length - (long)i2 * 9999L;
          if (l>9999L)
          	l=9999;
          i3=l;
          fwrite((void *)buf,1,i3,f);
        }
        fclose(f);
      	break;
      case 'q':
      case 'Q':
      case 27:
      	fclose(in);
      	return;
      case '?':
      	printf("[/-: Previous entry\n");
        printf("]/+: Next entry\n");
        printf(" S : Save entry to file\n");
        printf(" Q : Quit\n");
        break;
    }
  }
}