Logo
~Apps~
~Projects~
~Contact~

catalog.c

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include <sys/stat.h>
00005 #include <sys/types.h>
00006 
00007 #include "dos33.h"
00008 
00009 
00010 typedef struct dfilestruct
00011 {
00012  struct dfilestruct *next;
00013  u8 catalog_track;
00014  u8 catalog_sector;
00015  u8 catalog_index; // 0..6
00016  u8 filetype;
00017  char ft;
00018  char filename[32];
00019  u8 first_tsl_track;
00020  u8 first_tsl_sector;
00021  int bits;
00022 } __attribute__((packed))DFILE;
00023 
00024 
00025 #define TRACKS_PER_DISK 0x23
00026 #define SECTORS_PER_TRACK 0x10
00027 #define BYTES_PER_SECTOR 0x100
00028 #define TWO_BYTES_TO_SHORT(__x,__y) ((((int)__y)<<8)+__x)
00029 #define DISK_SEEK(__track,__sector) fseek(fil,((__track*SECTORS_PER_TRACK)+__sector)*BYTES_PER_SECTOR,SEEK_SET)
00030 
00031 #define DEBUGFILENAME 1
00032 
00033 
00034 DFILE *dfilebase = NULL;
00035 
00036 
00039 
00040 int dump_vtol(struct dos33_vtol *vtoc)
00041 {
00042  {
00043  printf("VTOC\n");
00044  printf("\tFour: %x\n", vtoc -> four);
00045  printf("\tT/S of first catalog sector: %x %x\n", vtoc -> catalog_track, vtoc -> catalog_sector);
00046  printf("\tDOS Version 3.%x\n", vtoc -> dos_version);
00047  printf("\tVolume Number %d\n", vtoc -> volume);
00048  printf("\tMax num T/S pairs in each S of T/S list: %d ($%x)\n", vtoc -> ts_pairs, vtoc -> ts_pairs);
00049  printf("\tLast track where sectors are allocated: %d ($%x)\n", vtoc -> last_track, vtoc -> last_track);
00050  printf("\tDirection of allocation: %s ($%x)\n", vtoc -> allocation_direction == 0xff ? "OUT" : "IN", vtoc -> allocation_direction);
00051  printf("\tNum of tracks per disk: %d ($%x)\n", vtoc -> tracks_per_disk, vtoc -> tracks_per_disk);
00052  printf("\tNum of sectors per track: %d ($%x)\n", vtoc -> sectors_per_track, vtoc -> sectors_per_track);
00053  printf("\tNum of bytes per sector: %d ($%x)\n", vtoc -> bytes_per_sector, vtoc -> bytes_per_sector);
00054  }
00055  return 0;
00056 }
00057 
00058 
00061 
00062 int dump_catalog(struct dos33_catalog_sector *catalog)
00063 {
00064  int i;
00065  int j;
00066  char temp_string[0x20];
00067 
00068  {
00069  printf("Catalog:\n");
00070  printf("\tNext track: 0x%x\n", catalog -> next_track);
00071  printf("\tNext sector: 0x%x\n", catalog -> next_sector);
00072  for (i = 0; i < 7; i++)
00073  {
00074         for (j = 0; j < 0x1e; j++)
00075         {
00076  temp_string[j] = catalog -> files[i].file_name[j] & 0x7f;
00077         }
00078         temp_string[0x1d] = 0;
00079         printf("\t%i: 0x%x/0x%x 0%x %s size 0x%x\n", 
00080                 i, 
00081  catalog -> files[i].first_tsl_track, 
00082  catalog -> files[i].first_tsl_sector, 
00083  catalog -> files[i].file_type, 
00084  temp_string, 
00085  catalog -> files[i].num_sectors);
00086  }
00087  }
00088  return 0;
00089 }
00090 
00091 
00094 
00095 int dump_tsl(struct dos33_ts_list *tsl)
00096 {
00097  int i;
00098 
00099  {
00100  printf("TSL\n");
00101  printf("\tNext: %x/%x\n", tsl -> next.track, tsl -> next.sector);
00102  printf("\tDepth: %i\n", tsl -> current_sectors_deep);
00103  for (i = 0; i < 122; i++)
00104  {
00105         printf("\t0x%2x: 0x%x/0x%x\n", i, tsl -> data_location[i].track, 
00106  tsl -> data_location[i].sector);
00107  }
00108  }
00109  return 0;
00110 }
00111 
00112 
00115 
00116 void verify_filename(char *s)
00117 {
00118         int i;
00119 
00120         for (i = 0; i < strlen(s); i++)
00121         {
00122                 switch (s[i])
00123                 {
00124                 case '/':
00125                         s[i] = '_';
00126                 }
00127         }
00128 }
00129 
00130 
00133 
00134 void extract_file(FILE *fil,DFILE *df,char *filename)
00135 {
00136         FILE *fil2;
00137         struct dos33_catalog_sector catalog;
00138         struct dos33_ts_list tsl;
00139         int file_to_get = df -> catalog_index;
00140         int catalog_sector;
00141         int catalog_track;
00142         int i;
00143         unsigned char data[256];
00144         unsigned char temp_track;
00145         unsigned char temp_sector;
00146 
00147         fil2 = fopen(filename, "wb");
00148         catalog_track = df -> catalog_track;
00149         catalog_sector = df -> catalog_sector;
00150 
00151 //printf(" ct %d cs %d index %d\n",catalog_track,catalog_sector,file_to_get);
00152         DISK_SEEK(catalog_track, catalog_sector);
00153         fread(&catalog, 256, 1, fil);
00154         temp_track = catalog.files[file_to_get].first_tsl_track;
00155         temp_sector = catalog.files[file_to_get].first_tsl_sector;
00156 
00157         do
00158         {
00159 //printf(" TSL @ read track %d read sector %d\n",temp_track,temp_sector);
00160                 DISK_SEEK(temp_track, temp_sector);
00161                 fread(&tsl, 256, 1, fil);
00162 //              dump_tsl(&tsl);
00163 
00164                 // check for file size?
00165 
00166 //printf(" * reading %d sectors\n",catalog.files[file_to_get].num_sectors);
00167                 for (i = 0; i < 122; i++) // catalog.files[file_to_get].num_sectors; i++)
00168                 {
00169                         if (!tsl.data_location[i].track && !tsl.data_location[i].sector)
00170                         {
00171                                 fseek(fil2, 256, SEEK_CUR);
00172                         }
00173                         else
00174                         {
00175                                 DISK_SEEK(tsl.data_location[i].track, tsl.data_location[i].sector);
00176                                 fread(&data, 256, 1, fil);
00177                                 fwrite(&data, 256, 1, fil2);
00178                         }
00179                 }
00180                 if (tsl.next.track != temp_track || tsl.next.sector != temp_sector)
00181                 {
00182                         temp_track = tsl.next.track;
00183                         temp_sector = tsl.next.sector;
00184                 }
00185                 else
00186                 {
00187                         temp_track = 0;
00188                         temp_sector = 0;
00189                 }
00190         } while (temp_track != 0);
00191         fclose(fil2);
00192         i = 0644;
00193         if (df -> bits & 1)
00194                 i += 0100;
00195         if (df -> bits & 2)
00196                 i += 010;
00197         if (df -> bits & 4)
00198                 i += 01;
00199         chmod(filename, i);
00200 }
00201 
00202 
00205 
00206 int main(int argc, char **argv)
00207 {
00208         FILE *fil;
00209         DFILE           *df;
00210         DFILE           *tmpdf;
00211         struct dos33_vtol vtoc;
00212         struct dos33_catalog_sector catalog;
00213         int i;
00214         int j;
00215         int catalog_sector;
00216         int catalog_track;
00217         int loop;
00218         int x;
00219         unsigned char   data[256];
00220         char dirname[256];
00221 
00222         if (argc < 2)
00223         {
00224                 printf("Usage %s <image name [*.dsk]>\n", argv[0]);
00225                 return -1;
00226         }
00227 
00228         for (loop = 1; loop < argc; loop++)
00229         {
00230                 fil = fopen(argv[loop], "rb");
00231                 if (fil == NULL)
00232                 {
00233                         printf("Could not open %s!\n", argv[loop]);
00234                         return -1;
00235                 }
00236                 printf("Disk image: %s\n",argv[loop]);
00237 
00238                 // READ VTOC
00239                 DISK_SEEK(0x11, 0x00);
00240                 fread(&vtoc, 256, 1, fil);
00241 
00242                 // Read catalog
00243                 catalog_track = vtoc.catalog_track;
00244                 catalog_sector = vtoc.catalog_sector;
00245 
00246                 while (catalog_track || catalog_sector)
00247                 {
00248                         if (catalog_track > 39 || catalog_sector > 15)
00249                         {
00250                                 printf("Is this really a dos 3.3 disk?\n");
00251                                 dfilebase = NULL;
00252                                 break;
00253                         }
00254 
00255                         // read catalog sector
00256                         DISK_SEEK(catalog_track, catalog_sector);
00257                         fread(&catalog, 256, 1, fil);
00258 
00259                         for (i = 0; i < 7; i++)
00260                         {
00261                                 if (!*catalog.files[i].file_name)
00262                                 {
00263                                         break;
00264                                 }
00265                                 if (catalog.files[i].first_tsl_track == 255) // deleted
00266                                 {
00267                                         break;
00268                                 }
00269                                 df = (DFILE *)malloc(sizeof(DFILE));
00270                                 df -> catalog_track = catalog_track;
00271                                 df -> catalog_sector = catalog_sector;
00272                                 df -> catalog_index = i;
00273                                 df -> filetype = catalog.files[i].file_type;
00274                                 df -> ft = 0;
00275                                 *df -> filename = 0;
00276                                 df -> first_tsl_track = catalog.files[i].first_tsl_track;
00277                                 df -> first_tsl_sector = catalog.files[i].first_tsl_sector;
00278                                 df -> next = dfilebase;
00279                                 dfilebase = df;
00280                                 if (catalog.files[i].file_type >= 0x80)
00281                                 {
00282                                         printf("*");
00283                                 }
00284                                 else
00285                                 {
00286                                         printf(" ");
00287                                 }
00288                                 switch (catalog.files[i].file_type & 0x7f)
00289                                 {
00290 // bits 0 .. 7 = tiabsrab
00291                                 case 0:
00292                                         df -> ft = 'T';
00293                                         printf("T");
00294                                         df -> bits = 0;
00295                                         break;
00296                                 case 1:
00297                                         df -> ft = 'I';
00298                                         printf("I");
00299                                         df -> bits = 1;
00300                                         break;
00301                                 case 2:
00302                                         df -> ft = 'A';
00303                                         printf("A");
00304                                         df -> bits = 2;
00305                                         break;
00306                                 case 4:
00307                                         df -> ft = 'B';
00308                                         printf("B");
00309                                         df -> bits = 3;
00310                                         break;
00311                                 case 8:
00312                                         df -> ft = 'S';
00313                                         printf("S");
00314                                         df -> bits = 4;
00315                                         break;
00316                                 case 0x10:
00317                                         df -> ft = 'R';
00318                                         printf("R");
00319                                         df -> bits = 5;
00320                                         break;
00321                                 case 0x20:
00322                                         df -> ft = 'A';
00323                                         printf("A");
00324                                         df -> bits = 6;
00325                                         break;
00326                                 case 0x40:
00327                                         df -> ft = 'B';
00328                                         printf("B");
00329                                         df -> bits = 7;
00330                                         break;
00331                                 default:
00332                                         printf(" *** unknown file type 0x%02x ***\n", catalog.files[i].file_type & 0x7f);
00333                                         printf("Is this really a dos 3.3 disk?\n");
00334                                         dfilebase = NULL;
00335                                         catalog.next_track = catalog.next_sector = 0;
00336                                         break;
00337                                 } // switch()
00338 
00339                                 printf(" %3d ", catalog.files[i].num_sectors);
00340                                 for (j = 0; j < 0x1e - DEBUGFILENAME; j++)
00341                                 {
00342                                         printf("%c", catalog.files[i].file_name[j] & 0x7f);
00343                                         df -> filename[j] = catalog.files[i].file_name[j] & 0x7f;
00344                                 }
00345                                 df -> filename[j] = 0;
00346                                 printf("\n");
00347                                 while (df -> filename[strlen(df -> filename) - 1] == ' ')
00348                                 {
00349                                         df -> filename[strlen(df -> filename) - 1] = 0;
00350                                 }
00351                         }
00352                         catalog_track = catalog.next_track;
00353                         catalog_sector = catalog.next_sector;
00354                 }
00355 
00356                 // get files
00357                 if (dfilebase)
00358                 {
00359                         strcpy(dirname,argv[loop]);
00360                         x = -1;
00361                         for (i = 0; i < strlen(dirname); i++)
00362                                 if (dirname[i] == '.')
00363                                         x = i;
00364                         if (x > -1)
00365                                 dirname[x] = 0;
00366                         mkdir(dirname, 0755);
00367                 }
00368                 for (df = dfilebase; df; df = tmpdf)
00369                 {
00370                         if (*df -> filename)
00371                         {
00372                                 verify_filename(df -> filename);
00373                                 sprintf(data,"%s/%s",dirname,df -> filename);
00374                                 extract_file(fil, df, data);
00375                         }
00376                         tmpdf = df -> next;
00377                         free(df);
00378                 }
00379                 dfilebase = NULL;
00380 
00381                 fclose(fil);
00382         } // for (loop)
00383         return 0;
00384 }
00385 
Page, code, and content Copyright (C) 2005 by Anders Hedström
Generated on Mon Aug 29 20:21:47 2005 for C++ Sockets by  doxygen 1.4.4