home *** CD-ROM | disk | FTP | other *** search
/ Amiga GigaPD 3 / Amiga_GigaPD_v3_2of3.iso / amicdrom / main.c < prev    next >
C/C++ Source or Header  |  1994-03-15  |  16KB  |  586 lines

  1. /* main.c:
  2.  *
  3.  * Interactive test program for the ISO- and Rock-Ridge-support
  4.  * routines.
  5.  *
  6.  * ----------------------------------------------------------------------
  7.  * This code is (C) Copyright 1993 by Frank Munkert.
  8.  * All rights reserved.
  9.  * This software may be freely distributed and redistributed for
  10.  * non-commercial purposes, provided this notice is included.
  11.  */
  12.  
  13. #include <stdlib.h>
  14. #include <stdio.h>
  15. #include <string.h>
  16.  
  17. #include <dos/var.h>
  18. #include <clib/dos_protos.h>
  19.  
  20. #include "cdrom.h"
  21. #include "iso9660.h"
  22. #include "rock.h"
  23.  
  24. CDROM *cd = NULL;
  25. char g_the_device[80];
  26. int g_the_unit;
  27. int g_trackdisk = 0;
  28. int g_fastmem = 0;
  29.  
  30. void Cleanup (void)
  31. {
  32.   if (cd)
  33.     Cleanup_CDROM (cd);
  34. }
  35.  
  36. void Usage (void)
  37. {
  38.   fprintf (stderr,
  39.     "Usage: cdrom command [parameters]\n"
  40.     "Commands:\n"
  41.     "  c name        Show contents of file 'name'\n"
  42.     "  d dir         Show contents of directory 'dir' (use ISO names)\n"
  43.     "  e dir         Show contents of directory 'dir' (use Rock Ridge names)\n"
  44.     "  f dir name    Change to directory 'dir' and try to find object 'name'\n"
  45.     "  i             Check which protocol is used\n"
  46.     "  o name        Try to open object 'name'\n"
  47.     "  p             Read top-level path table\n"
  48.     "  r             Read contents of root directory\n"
  49.     "  s num         Read sector number 'num'\n"
  50.     "  t name        Try to open parent of object 'name'\n"
  51.     "  v             Read primary volume descriptor\n"
  52.     "  z             Send test unit ready command\n"
  53.     "Use \":\" as the name of the root directory\n"
  54.     );
  55.   exit (1);
  56. }
  57.  
  58. char *MKSTR (char *p_in, int p_length, char *p_out)
  59. {
  60.   char *res = p_out;
  61.   int len = p_length;
  62.   int i;
  63.   
  64.   while (len && p_in[len-1] == ' ')
  65.     len--;
  66.  
  67.   for (i=0; i<len; i++)
  68.     *p_out++ = *p_in++;
  69.     
  70.   *p_out = 0;
  71.   
  72.   return res;
  73. }
  74.  
  75. void Show_Flags (unsigned char p_flags)
  76. {
  77.   if (p_flags & 1)
  78.     printf ("existence ");
  79.   if (p_flags & 2)
  80.     printf ("directory ");
  81.   if (p_flags & 4)
  82.     printf ("associated ");
  83.   if (p_flags & 8)
  84.     printf ("record ");
  85.   if (p_flags & 16)
  86.     printf ("protection ");
  87.   if (p_flags & 128)
  88.     printf ("multi-extent ");
  89. }
  90.  
  91. void Show_Directory_Record (directory_record *p_dir)
  92. {
  93.   char buf[256];
  94.  
  95.   printf ("Extended Attr Record Length: %d\n", (int) p_dir->ext_attr_length);
  96.   printf ("Location of Extent:          %lu\n", p_dir->extent_loc_m);
  97.   printf ("Data Length:                 %lu\n", p_dir->data_length_m);
  98.   printf ("Recording Date and Time:     %02d.%02d.19%02d %02d:%02d:%02d %+d\n",
  99.         (int) p_dir->day, (int) p_dir->month, (int) p_dir->year,
  100.       (int) p_dir->hour, (int) p_dir->minute, (int) p_dir->second,
  101.       (int) p_dir->tz);
  102.   printf ("Flags:                       %d (", (int) p_dir->flags);
  103.   Show_Flags (p_dir->flags);
  104.   printf (")\n");
  105.   printf ("File Unit Size:              %d\n", (int) p_dir->file_unit_size);
  106.   printf ("Gap Size:                    %d\n", (int) p_dir->gap_size);
  107.   printf ("Volume Sequence Number:      %hu\n", p_dir->sequence_m);
  108.   printf ("File Identifier:             ");
  109.   if (p_dir->file_id[0] == 0)
  110.     printf ("(00)\n");
  111.   else if (p_dir->file_id[0] == 1)
  112.     printf ("(01)\n");
  113.   else
  114.     printf ("%s\n", MKSTR (p_dir->file_id, p_dir->file_id_length, buf));
  115. }
  116.  
  117. void Show_Primary_Volume_Descriptor (CDROM *p_cd)
  118. {
  119.   prim_vol_desc *pvd;
  120.   char buf[129];
  121.   
  122.   if (!Read_Sector (p_cd, 16)) {
  123.     fprintf (stderr, "cannot read sector 16\n");
  124.     exit (1);
  125.   }
  126.  
  127.   pvd = (prim_vol_desc *) p_cd->buffer;
  128.   printf ("Volume Descriptor Type:          %d\n", (int) pvd->type);
  129.   printf ("Standard Identifier:             %s\n", pvd->id);
  130.   printf ("Volume Descriptor Version:       %d\n", (int) pvd->version);
  131.   printf ("System Identifier:               %s\n", MKSTR (pvd->system_id,32,buf));
  132.   printf ("Volume Identifier:               %s\n", MKSTR (pvd->volume_id,32,buf));
  133.   printf ("Volume Space Size:               %lu\n", pvd->space_size_m);
  134.   printf ("Volume Set Size:                 %hu\n", pvd->set_size_m);
  135.   printf ("Volume Sequence Number:          %hu\n", pvd->sequence_m);
  136.   printf ("Logical Block Size:              %hu\n", pvd->block_size_m);
  137.   printf ("Path Table Size:                 %lu\n", pvd->path_size_m);
  138.   printf ("Location of Occ of M Path Table: %lu\n", pvd->m_table); 
  139.   printf ("Location of Occ of Opt M Path T: %lu\n", pvd->opt_m_table);
  140.   printf ("Volume Set Identifier:           %s\n",
  141.                       MKSTR (pvd->volume_set_id,128,buf));  
  142.   printf ("Publisher Identifier:            %s\n",
  143.                       MKSTR (pvd->publisher_id,128,buf)); 
  144.   printf ("Data Preparer Identifier:        %s\n",
  145.                       MKSTR (pvd->data_preparer,128,buf));
  146.   printf ("Application Identifier:          %s\n",
  147.                       MKSTR (pvd->application_id,128,buf));
  148.   printf ("Copyright File Identifier:       %s\n",
  149.                       MKSTR (pvd->copyright,37,buf));
  150.   printf ("Abstract File Identifier:        %s\n",
  151.                       MKSTR (pvd->abstract_file_id,37,buf));
  152.   printf ("Bibliographic File Identifier:   %s\n",
  153.                       MKSTR (pvd->bibliographic_id,37,buf));
  154.   printf ("File Structure Version:          %d\n",
  155.                       (int) pvd->file_structure_version);
  156.   printf ("ROOT DIRECTORY RECORD:\n");
  157.   Show_Directory_Record (&pvd->root);
  158. }
  159.  
  160. void Show_Path_Table (CDROM *p_cd, unsigned long p_size, unsigned long p_location)
  161. {
  162.   unsigned long cnt = 0;
  163.   int len;
  164.   int scsi_pos = 0;
  165.   int todo;
  166.   char buf[256];
  167.   path_table_record *ptr = (path_table_record *) buf;
  168.  
  169.   printf ("Ext Attr RecLen  Location   Parent Dir Num    Identifier\n"
  170.           "---------------  --------   --------------    ----------\n");
  171.  
  172.   if (!Read_Sector (p_cd, p_location)) {
  173.     fprintf (stderr, "cannot read sector %lu\n", p_location);
  174.     exit (1);
  175.   }
  176.  
  177.   while (cnt < p_size) {
  178.     len = p_cd->buffer[scsi_pos] + 8;
  179.     if (len & 1)
  180.       len++;
  181.  
  182.     if (len + scsi_pos <= 2048) {
  183.       memcpy (buf, p_cd->buffer + scsi_pos, len);
  184.       todo = 0;
  185.       scsi_pos += len;
  186.     } else {
  187.       memcpy (buf, p_cd->buffer + scsi_pos, 2048 - scsi_pos);
  188.       todo = len - (2048 - scsi_pos);
  189.       scsi_pos = 2048;
  190.     }
  191.  
  192.     if (scsi_pos == 2048) {
  193.       p_location++;
  194.       if (!Read_Sector (p_cd, p_location)) {
  195.         fprintf (stderr, "cannot read sector %lu\n", p_location);
  196.         exit (1);
  197.       }
  198.       scsi_pos = 0;
  199.       if (todo) {
  200.         memcpy (buf + (len - todo), p_cd->buffer, todo);
  201.         scsi_pos = todo;
  202.       }
  203.     }
  204.  
  205.     cnt += len;
  206.     
  207.     printf ("%-17d%-11lu%-18hu",
  208.             (int) ptr->ext_attr_length,
  209.         ptr->location,
  210.         ptr->parent);
  211.     if (ptr->id[0] == 0)
  212.       printf ("(00)\n");
  213.     else if (ptr->id[0] == 1)
  214.       printf ("(01)\n");
  215.     else {
  216.       fwrite (ptr->id, ptr->id_length, 1, stdout);
  217.       printf ("\n");
  218.     }
  219.   }
  220. }
  221.  
  222. void Show_Top_Level_Path_Table (CDROM *p_cd)
  223. {
  224.   prim_vol_desc *pvd;
  225.   
  226.   if (!Read_Sector (p_cd, 16)) {
  227.     fprintf (stderr, "cannot read sector 16\n");
  228.     exit (1);
  229.   }
  230.  
  231.   pvd = (prim_vol_desc *) p_cd->buffer;
  232.   
  233.   Show_Path_Table (p_cd, pvd->path_size_m, pvd->m_table);
  234.  
  235. }
  236.  
  237. void Show_Directory (CDROM *p_cd, unsigned long p_location, unsigned long p_length)
  238. {
  239.   int cnt = 0;
  240.   int pos = 0;
  241.   
  242.   if (!Read_Sector (p_cd, p_location)) {
  243.     fprintf (stderr, "cannot read sector %lu\n", p_location);
  244.     exit (1);
  245.   }
  246.  
  247.   while (cnt < p_length) {
  248.     directory_record *dir = (directory_record *) (p_cd->buffer + pos);
  249.     
  250.     if (dir->length == 0)
  251.       break;
  252.     Show_Directory_Record (dir);
  253.     cnt += dir->length;
  254.     pos += dir->length;
  255.     if (cnt < p_length) {
  256.       printf ("------------------------------------------------------------\n");
  257.       if (pos >= 2048) {
  258.         if (!Read_Sector (p_cd, ++p_location)) {
  259.           fprintf (stderr, "cannot read sector %lu\n", p_location);
  260.           exit (1);
  261.         }
  262.         pos = 0;
  263.       }
  264.     }
  265.   }
  266. }
  267.  
  268. void Show_Root_Directory (CDROM *p_cd)
  269. {
  270.   prim_vol_desc *pvd;
  271.   
  272.   if (!Read_Sector (p_cd, 16)) {
  273.     fprintf (stderr, "cannot read sector 16\n");
  274.     exit (1);
  275.   }
  276.  
  277.   pvd = (prim_vol_desc *) p_cd->buffer;
  278.  
  279.   Show_Directory (p_cd, pvd->root.extent_loc_m, pvd->root.data_length_m);
  280. }
  281.  
  282. void Check_Protocol (CDROM *p_cd)
  283. {
  284.   VOLUME *vol;
  285.  
  286.   if (!(vol = Open_Volume (p_cd, 0))) {
  287.     fprintf (stderr, "cannot open volume; iso_errno = %d\n", iso_errno);
  288.     exit (1);
  289.   }
  290.   
  291.   if (Uses_Rock_Ridge_Protocol (vol)) {
  292.     printf ("Rock Ridge Protocol, skip length = %d\n", vol->skip);
  293.   } else
  294.     printf ("ISO-9660 protocol\n");
  295.  
  296.   Close_Volume (vol);
  297. }
  298.  
  299. void Try_To_Open (CDROM *p_cd, char *p_directory, char *p_name)
  300. {
  301.   VOLUME *vol;
  302.   CDROM_OBJ *top = NULL;
  303.   CDROM_OBJ *home;
  304.   CDROM_OBJ *obj;
  305.   CDROM_OBJ *parent;
  306.  
  307.   if (!(vol = Open_Volume (p_cd, 1))) {
  308.     fprintf (stderr, "cannot open volume; iso_errno = %d\n", iso_errno);
  309.     exit (1);
  310.   }
  311.  
  312.   if (p_directory && p_directory != (char *) -1) {
  313.     if (!(top = Open_Top_Level_Directory (vol))) {
  314.       fprintf (stderr, "cannot open top level directory\n");
  315.       Close_Volume (vol);
  316.       exit (1);
  317.     }
  318.     
  319.     if (!(home = Open_Object (top, p_directory))) {
  320.       fprintf (stderr, "cannot open top level directory\n");
  321.       Close_Object (top);
  322.       Close_Volume (vol);
  323.       exit (1);
  324.     }
  325.   } else {
  326.     if (!(home = Open_Top_Level_Directory (vol))) {
  327.       fprintf (stderr, "cannot open home directory;"
  328.                        " iso_errno = %d\n", iso_errno);
  329.       Close_Volume (vol);
  330.       exit (1);
  331.     }
  332.   }
  333.  
  334.   if (obj = Open_Object (home, p_name)) {
  335.     CDROM_INFO info;
  336.     printf ("%s '%s' found, location = %lu\n",
  337.             obj->directory_f ? "Directory" : "File",
  338.             p_name, obj->dir_record->extent_loc_m);
  339.     if (CDROM_Info (obj, &info)) {
  340.       printf ("INFO Name = ");
  341.       fwrite (info.name, info.name_length, 1, stdout);
  342.       printf ("\n");
  343.     } else
  344.       printf ("CANNOT FIND INFO FOR OBJECT!\n");
  345.     if (p_directory == (char *) -1) {
  346.       parent = Find_Parent (obj);
  347.       if (parent) {
  348.         printf ("parent found, location = %lu\n",
  349.             parent->dir_record->extent_loc_m);
  350.         Close_Object (parent);
  351.       } else
  352.         printf ("parent not found, iso_errno = %d\n", iso_errno);
  353.     }
  354.     Close_Object (obj);
  355.   } else {
  356.     if (iso_errno == ISOERR_NOT_FOUND)
  357.       printf ("Object '%s' not found\n", p_name);
  358.     else
  359.       printf ("Object '%s': iso_errno = %d\n", iso_errno);
  360.   }
  361.  
  362.   if (top)
  363.     Close_Object (top);
  364.   Close_Object (home);
  365.   Close_Volume (vol);
  366. }
  367.  
  368. void Show_File_Contents (CDROM *p_cd, char *p_name)
  369. {
  370.   VOLUME *vol;
  371.   CDROM_OBJ *home;
  372.   CDROM_OBJ *obj;
  373. #define THEBUFSIZE 5000
  374.   char buffer[THEBUFSIZE];
  375.   int cnt;
  376.  
  377.   if (!(vol = Open_Volume (p_cd, 1))) {
  378.     fprintf (stderr, "cannot open volume; iso_errno = %d\n", iso_errno);
  379.     exit (1);
  380.   }
  381.  
  382.   if (!(home = Open_Top_Level_Directory (vol))) {
  383.     fprintf (stderr, "cannot open top level directory;"
  384.                      " iso_errno = %d\n", iso_errno);
  385.     Close_Volume (vol);
  386.     exit (1);
  387.   }
  388.  
  389.   if (obj = Open_Object (home, p_name)) {
  390.     for (;;) {
  391.       cnt = Read_From_File (obj, buffer, THEBUFSIZE);
  392.       if (cnt == -1) {
  393.         fprintf (stderr, "cannot read from file!\n");
  394.     break;
  395.       }
  396.       if (cnt == 0)
  397.         break;
  398.       fwrite (buffer, cnt, 1, stdout);
  399.     }
  400.  
  401.     Close_Object (obj);
  402.   } else {
  403.     fprintf (stderr, "Object '%s': iso_errno = %d\n", p_name, iso_errno);
  404.   }
  405.  
  406.   Close_Object (home);
  407.   Close_Volume (vol);
  408.   
  409. }
  410.  
  411. void Show_Dir_Contents (CDROM *p_cd, char *p_name, int p_rock_ridge)
  412. {
  413.   VOLUME *vol;
  414.   CDROM_OBJ *home;
  415.   CDROM_OBJ *obj;
  416.   CDROM_INFO info;
  417.   int cnt;
  418.   char buf[200];
  419.   int len;
  420.  
  421.   if (!(vol = Open_Volume (p_cd, p_rock_ridge))) {
  422.     fprintf (stderr, "cannot open volume; iso_errno = %d\n", iso_errno);
  423.     exit (1);
  424.   }
  425.  
  426.   if (!(home = Open_Top_Level_Directory (vol))) {
  427.     fprintf (stderr, "cannot open top level directory;"
  428.                      " iso_errno = %d\n", iso_errno);
  429.     Close_Volume (vol);
  430.     exit (1);
  431.   }
  432.  
  433.   if (obj = Open_Object (home, p_name)) {
  434.     unsigned long offset = 0;
  435.     
  436.     while (Examine_Next (obj, &info, &offset)) {
  437.       fwrite (info.name, info.name_length, 1, stdout);
  438.       printf ("\n");
  439.     }
  440.  
  441.     Close_Object (obj);
  442.   } else {
  443.     fprintf (stderr, "Object '%s': iso_errno = %d\n", p_name, iso_errno);
  444.   }
  445.  
  446.   Close_Object (home);
  447.   Close_Volume (vol);
  448.   
  449. }
  450.  
  451. void Send_Test_Unit_Ready (CDROM *p_cd)
  452. {
  453.   printf ("result = %d\n", Test_Unit_Ready (p_cd));
  454. }
  455.  
  456. void Show_Sector (CDROM *p_cd, int p_sector)
  457. {
  458.   int i, j;
  459.   int off = 0;
  460.   
  461.   if (p_sector < 0)
  462.     return;
  463.   
  464.   if (!Read_Sector (p_cd, p_sector)) {
  465.     fprintf (stderr, "cannot read sector %d\n", p_sector);
  466.     exit (1);
  467.   }
  468.   
  469.   for (i=0; i<128; i++) {
  470.     printf ("%03x0: ", i);
  471.     for (j=0; j<16; j++)
  472.       printf ("%02x ", (int) p_cd->buffer[off++]);
  473.     off -= 16;
  474.     putchar (' ');
  475.     for (j=0; j<16; j++) {
  476.       char c = p_cd->buffer[off++];
  477.       if (32<=c && c<=127)
  478.         putchar (c);
  479.       else
  480.         putchar ('.');
  481.     }
  482.     putchar ('\n');
  483.   }
  484. }
  485.  
  486. int Get_Device_And_Unit (void)
  487. {
  488.   int len;
  489.   char buf[10];
  490.   
  491.   len = GetVar ((UBYTE *) "CDROM_DEVICE", (UBYTE *) g_the_device,
  492.           sizeof (g_the_device), 0);
  493.   if (len < 0)
  494.     return 0;
  495.   if (len >= sizeof (g_the_device)) {
  496.     fprintf (stderr, "CDROM_DEVICE too long\n");
  497.     exit (1);
  498.   }
  499.   g_the_device[len] = 0;
  500.   
  501.   len = GetVar ((UBYTE *) "CDROM_UNIT", (UBYTE *) buf,
  502.           sizeof (buf), 0);
  503.   if (len < 0)
  504.     return 0;
  505.   if (len >= sizeof (buf)) {
  506.     fprintf (stderr, "CDROM_UNIT too long\n");
  507.     exit (1);
  508.   }
  509.   buf[len] = 0;
  510.   g_the_unit = atoi (buf);
  511.   
  512.   if (GetVar ((UBYTE *) "CDROM_TRACKDISK", (UBYTE *) buf,
  513.       sizeof (buf), 0) > 0) {
  514.     fprintf (stderr, "using trackdisk\n");
  515.     g_trackdisk = 1;
  516.   }
  517.  
  518.   if (GetVar ((UBYTE *) "CDROM_FASTMEM", (UBYTE *) buf,
  519.       sizeof (buf), 0) > 0) {
  520.     fprintf (stderr, "using fastmem\n");
  521.     g_fastmem = 1;
  522.   }
  523.  
  524.   return 1;
  525. }
  526.  
  527. void main (int argc, char *argv[])
  528. {
  529.   atexit (Cleanup);
  530.  
  531.   if (argc < 2)
  532.     Usage ();
  533.  
  534.   if (!Get_Device_And_Unit ()) {
  535.     fprintf (stderr,
  536.       "Please the following environment variables:\n"
  537.       "  CDROM_DEVICE    name of SCSI device\n"
  538.       "  CDROM_UNIT      unit number of CDROM drive\n"
  539.       "e.g.\n"
  540.       "  setenv CDROM_DEVICE scsi.device\n"
  541.       "  setenv CDROM_UNIT 2\n"
  542.       "Set the variable CDROM_TRACKDISK to any value if you\n"
  543.       "want to use trackdisk calls instead of SCSI-direct calls\n"
  544.       "Set the variable CDROM_FASTMEM to any value if you\n"
  545.       "want to use fast memory for SCSI buffers (does not work\n"
  546.       "with all SCSI devices!)\n"
  547.       );
  548.     exit (1);
  549.   }
  550.  
  551.   cd = Open_CDROM (g_the_device, g_the_unit, g_trackdisk, g_fastmem);
  552.   if (!cd) {
  553.     fprintf (stderr, "cannot open CDROM\n");
  554.     exit (1);
  555.   }
  556.  
  557.   if (argv[1][0] == 'c' && argc == 3)
  558.     Show_File_Contents (cd, argv[2]);
  559.   else if (argv[1][0] == 'd' && argc == 3)
  560.     Show_Dir_Contents (cd, argv[2], 0);
  561.   else if (argv[1][0] == 'e' && argc == 3)
  562.     Show_Dir_Contents (cd, argv[2], 1);
  563.   else if (argv[1][0] == 'f' && argc == 4)
  564.     Try_To_Open (cd, argv[2], argv[3]);
  565.   else if (argv[1][0] == 'i')
  566.     Check_Protocol (cd);
  567.   else if (argv[1][0] == 'o' && argc == 3)
  568.     Try_To_Open (cd, NULL, argv[2]);
  569.   else if (argv[1][0] == 'p')
  570.     Show_Top_Level_Path_Table (cd);
  571.   else if (argv[1][0] == 'r')
  572.     Show_Root_Directory (cd);
  573.   else if (argv[1][0] == 's' && argc == 3)
  574.     Show_Sector (cd, atoi (argv[2]));
  575.   else if (argv[1][0] == 't' && argc == 3)
  576.     Try_To_Open (cd, (char *) -1, argv[2]);
  577.   else if (argv[1][0] == 'v')
  578.     Show_Primary_Volume_Descriptor (cd);
  579.   else if (argv[1][0] == 'z')
  580.     Send_Test_Unit_Ready (cd);
  581.   else
  582.     Usage ();
  583.  
  584.   exit (0);
  585. }
  586.