#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define DIR_SIZE 1024

//The atari directory entry structure
struct _Atari_DIR
{
   char Flag_Byte;
   int File_Len;
   int Start_Sector;
   char Filename[8];
   char Ext[3];
};

// used for debug
void showpos(FILE *stream)
{
   fpos_t pos;

   /* display the current file pointer
      position of a stream */
  fgetpos(stream, &pos);
   printf("File position: %ld\n", pos);
}

void main(int argc, char **argv)
{
   if (argc<2) {puts("usage: extract image_filename"); exit(0);}
   FILE *fin = fopen(argv[1],"rb");
   if (fin == NULL) {puts("invalid file name"); exit(0);}
   // get Atari directory
   _Atari_DIR *dir;
   dir = (_Atari_DIR *) malloc(64*sizeof(_Atari_DIR));
   long start_dir = long(0x168)*128L;

   if (fseek(fin,start_dir,SEEK_SET))
      {puts("could not find Atari directory");exit(0);}
//   showpos(fin);

   int num = fread(dir,sizeof(_Atari_DIR),64,fin);
   if (num != 64)
      {printf("file length read %d\n",num); puts("could not read directory");exit(0);}
   char str[13], buf[128];
   for (int dir_index = 0;dir_index<64;dir_index++)
   {
     if (dir[dir_index].Flag_Byte&0x7f)
     {
   // build file name
	strncpy(&str[0],dir[dir_index].Filename,8);
	strncpy(&str[9],dir[dir_index].Ext,3);
	str[8]  = '.';
	str[12] = '\0';
   printf("writing file: %s \n",str);
   // open the Atari filename for write to the IBM harddrive
	FILE *fout = fopen(str,"wb");

   // get starting sector
	int sector = dir[dir_index].Start_Sector;
   // loop to read all of the sectors for this file
	for (int i=dir[dir_index].File_Len; i>0; i--)
	{
	   // point to current sector
	   fseek(fin,long(sector-1)*128L,SEEK_SET);
	   // read the current sector
	   fread(buf,1,128,fin);
	   // write the current sector to disk
	   fwrite(buf,1,(buf[127]&0x7f),fout);
	   // get next sector
	   sector = ((buf[125]&0x3)<<8)+buf[126];
	}
	fclose(fout);
     }
   }
   fclose(fin);

}