#include <stdio.h>
#include <stdlib.h>

/*
From zaphod.mps.ohio-state.edu!sol.ctr.columbia.edu!cunixf.cc.columbia.edu
!cs.columbia.edu!cooper Tue Jan 29 22:07:18 EST 1991


This C program will take a file of GL format and dissolve it into its
components.  It is not guaranteed, of course.  it also produces a file
listing all the files it creates, so you can re-assemble them using a
program that follows.
You may want to modify this to use command-line arguments.
*/

/* Directory entry in GL file */
#if 0
struct s_entry {
  long bignum;
  char name[13];
}
#endif

/* We don't use it, since some C's make it more than 17 bytes... */

main()
{
  short top;  /* size of directory */
  unsigned char *entry;  /* list of directory entries */
  char glfile[100], listfile[100];
  FILE *fp,  /* gl file */
       *listfp;  /* list of files in directory */
  FILE *newfp;   /* opened for each extracted file */
  int num_ents = 0;  /* number of files to extract */
  int i;
  long rsize;  /* Size of current file */
  char buff[1024];
  /* For referencing fileds in entry table: */
  long *bignum;
  unsigned char *name;

  /* Open required files */

  printf("GL file to open? "); scanf("%s",glfile);
  printf("list file? "); scanf("%s",listfile);

  fp = fopen(glfile,"r");
  if (fp == NULL)
    {
      printf("couldn't open file %s\n", glfile);
      exit(-1);
    }
  listfp = fopen(listfile,"w");
  if (listfp == NULL)
    {
      fclose(fp);
      printf("couldn't open list file %s\n", listfile);
      exit(-1);
    }

  /* Allocate space for directory */
  fread(&top,2,1,fp);
  entry = (unsigned char *)malloc(top);

  /* Read in directory */
  fread(entry,top,1,fp);
  num_ents = top/17 - 1;

  /* Create file list */
  for (name = entry+4, i = 0; i < num_ents; i++, name+=17)
    fprintf(listfp, "%s\n", name);
  fclose(listfp);

  /* Get file size */
  /* Put it in last (zeroed) directory entry, for easy algorithm */
  fseek(fp, 0L, 2);
  bignum = (long *)&entry[num_ents*17];
  *bignum = ftell(fp);

  /* Go to first file */
  bignum = (long *)entry;
  fseek(fp, *bignum, 0);

  /* Extract each file */
  for (name = entry+4, i = 0; i < num_ents;
       i++, name+=17, bignum = (long *)(name-4))
    {
      newfp = fopen(name, "w");
      /* File size if address of next file (or end) minus this address */
      rsize = *(long *)((char *)bignum + 17) - *bignum;

      /* Copy file, one "block" at a time */
      while(rsize > sizeof(buff))
	{
	  fread(buff, sizeof(buff), 1, fp);
	  fwrite(buff, sizeof(buff), 1, newfp);
	  rsize -= sizeof(buff);
	}
      fread(buff, rsize, 1, fp);
      fwrite(buff, rsize, 1, newfp);
      fclose(newfp);
    }
fclose(fp);
free(entry);
}

