home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 5 / FreshFish_July-August1994.bin / bbs / disk / amicdrom-1.11.lha / AmiCDROM-1.11 / generic.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-23  |  9.0 KB  |  384 lines

  1. /* generic.c:
  2.  *
  3.  * Generic interface to the protocol handlers.
  4.  *
  5.  * ----------------------------------------------------------------------
  6.  * This code is (C) Copyright 1993,1994 by Frank Munkert.
  7.  * All rights reserved.
  8.  * This software may be freely distributed and redistributed for
  9.  * non-commercial purposes, provided this notice is included.
  10.  * ----------------------------------------------------------------------
  11.  * History:
  12.  * 
  13.  * 22-May-94   fmu   Performance improvement for lock+filehandle processing.
  14.  * 01-Jan-94   fmu   Added multisession support.
  15.  * 29-Nov-93   fmu   New function Block_Size().
  16.  * 15-Nov-93   fmu   Missing return value for 'Location' inserted.
  17.  * 10-Nov-93   fmu   Added HFS/ISO-9660-lookup reversing in Which_Protocol.
  18.  */
  19.  
  20. #include <stdlib.h>
  21. #include <string.h>
  22.  
  23. #include <exec/types.h>
  24. #include <exec/memory.h>
  25. #include <clib/exec_protos.h>
  26. #include <clib/utility_protos.h>
  27. #ifdef AZTEC_C
  28. #include <pragmas/exec_lib.h>
  29. #include <pragmas/utility_lib.h>
  30. #endif
  31. #ifdef LATTICE
  32. #include <pragmas/exec_pragmas.h>
  33. #include <pragmas/utility_pragmas.h>
  34.  
  35. extern struct Library *UtilityBase;
  36. extern struct ExecBase *SysBase;
  37. #endif
  38. #if defined(_DCC) && defined(REGISTERED)
  39. #include <pragmas/exec_pragmas.h>
  40. #include <pragmas/utility_pragmas.h>
  41.  
  42. extern struct Library *UtilityBase;
  43. extern struct Library *SysBase;
  44. #endif
  45.  
  46. #include "cdrom.h"
  47. #include "generic.h"
  48. #include "iso9660.h"
  49. #include "rock.h"
  50. #include "hfs.h"
  51. #include "params.h"
  52.  
  53. #define HAN(vol,func) (*(vol)->handler->func)
  54. #define HANX(vol,func) ((vol)->handler->func)
  55.  
  56. t_bool g_hfs_first = FALSE;
  57.  
  58. /* Strncasecmp works like 'strncmp' but ignores case differences.
  59.  */
  60.  
  61. int Strncasecmp (char *p_str1, char *p_str2, int p_length)
  62. {
  63.   int i;
  64.   int len = 0;
  65.   
  66.   while (len < p_length && *p_str1 && *p_str2) {
  67.     if (i = ToLower (*p_str1++) - ToLower (*p_str2++))
  68.       return i;
  69.     len++;
  70.   }
  71.   return (len == p_length) ? 0 : ToLower (*p_str1) - ToLower (*p_str2);
  72. }
  73.  
  74. /* WhichProtocol - examines which protocol is used.
  75.  *
  76.  * Input Variables:
  77.  *  p_cdrom - CDROM descriptor
  78.  *  p_use_rock_ridge - flag for the ROCKRIDGE startup option
  79.  *
  80.  * Output Variables:
  81.  *  p_skip - skip length for RockRidge disks
  82.  *  p_offset - block offset of last session for multisession disks (ISO only)
  83.  *
  84.  * Result:
  85.  *  PRO_ISO, PRO_HIGH_SIERRA, PRO_RR, PRO_HFS or PRO_UNKNOWN.
  86.  */
  87.  
  88. t_protocol Which_Protocol (CDROM *p_cdrom, t_bool p_use_rock_ridge, int *p_skip,
  89.                t_ulong *p_offset)
  90. {
  91.   if (p_cdrom->model == MODEL_TOSHIBA_3401) {
  92.     if (Is_XA_Mode_Disk (p_cdrom))
  93.       Mode_Select (p_cdrom, 0x81, 2048);
  94.     else
  95.       Mode_Select (p_cdrom, 0x00, 2048);
  96.   }
  97.  
  98.   if (g_hfs_first && Uses_HFS_Protocol (p_cdrom, p_skip))
  99.     return PRO_HFS;
  100.  
  101.   if (Uses_Iso_Protocol (p_cdrom, p_offset)) {
  102.     if (p_use_rock_ridge) {
  103.       VOLUME tmp_vol; /* temporary volume descriptor */
  104.       t_bool rr;
  105.  
  106.       tmp_vol.cd = p_cdrom;
  107.       tmp_vol.protocol = PRO_ISO;
  108.       Iso_Init_Vol_Info (&tmp_vol, 0, *p_offset);
  109.       rr = Uses_Rock_Ridge_Protocol (&tmp_vol, p_skip);
  110.       HAN (&tmp_vol, close_vol_info) (&tmp_vol);
  111.       return rr ? PRO_ROCK : PRO_ISO;
  112.     } else
  113.       return PRO_ISO;
  114.   }
  115.   
  116.   if (Uses_High_Sierra_Protocol (p_cdrom))
  117.     return PRO_HIGH_SIERRA;
  118.  
  119.   if (!g_hfs_first && Uses_HFS_Protocol (p_cdrom, p_skip))
  120.     return PRO_HFS;
  121.  
  122.   return PRO_UNKNOWN;
  123. }
  124.  
  125. VOLUME *Open_Volume (CDROM *p_cdrom, t_bool p_use_rock_ridge)
  126. {
  127.   VOLUME *res;
  128.   int skip;
  129.   t_ulong offset;
  130.     
  131.   res = AllocMem (sizeof (VOLUME), MEMF_PUBLIC);
  132.   if (!res) {
  133.     iso_errno = ISOERR_NO_MEMORY;
  134.     return NULL;
  135.   }
  136.  
  137.   res->cd = p_cdrom;
  138.   
  139.   res->locks = 0;        /* may be modified by application program */
  140.   res->file_handles = 0; /* may be modified by application program */
  141.  
  142.   res->protocol = Which_Protocol (p_cdrom, p_use_rock_ridge, &skip, &offset);
  143.   if (res->protocol == PRO_UNKNOWN) {
  144.     /* give it a second try: */
  145.     res->protocol = Which_Protocol (p_cdrom, p_use_rock_ridge, &skip, &offset);
  146.   }
  147.  
  148.   switch (res->protocol) {
  149.   case PRO_ROCK:
  150.   case PRO_ISO:
  151.     if (!Iso_Init_Vol_Info (res, skip, offset)) {
  152.       FreeMem (res, sizeof (VOLUME));
  153.       return NULL;
  154.     }
  155.     break;
  156.   case PRO_HFS:
  157.     if (!HFS_Init_Vol_Info (res, skip)) {
  158.       FreeMem (res, sizeof (VOLUME));
  159.       return NULL;
  160.     }
  161.     break;
  162.   default:
  163.     FreeMem (res, sizeof (VOLUME));
  164.     return NULL;
  165.   }
  166.  
  167.   return res;
  168. }
  169.  
  170. void Close_Volume (VOLUME *p_volume)
  171. {
  172.   HAN(p_volume, close_vol_info)(p_volume);
  173.   FreeMem (p_volume, sizeof (VOLUME));
  174. }
  175.  
  176. CDROM_OBJ *Open_Top_Level_Directory (VOLUME *p_volume)
  177. {
  178.   CDROM_OBJ * result = HAN(p_volume, open_top_level_directory)(p_volume);
  179.   if (result)
  180.     result->pathlist = NULL;
  181.   return result;
  182. }
  183.  
  184. CDROM_OBJ *Open_Object (CDROM_OBJ *p_current_dir, char *p_path_name)
  185. {
  186.   char *cp = p_path_name;
  187.   CDROM_OBJ *obj, *new;
  188.   VOLUME *vol = p_current_dir->volume;
  189.   char *np;
  190.   char name[100];
  191.  
  192.   if (*cp == ':') {
  193.     obj = HAN(vol, open_top_level_directory)(p_current_dir->volume);
  194.     if (obj)
  195.       obj->pathlist = NULL;
  196.     cp++;
  197.   } else {
  198.     obj = Clone_Object (p_current_dir);
  199.     if (!obj) {
  200.       iso_errno = ISOERR_NO_MEMORY;
  201.       return NULL;
  202.     }
  203.     while (*cp == '/') {
  204.       new = HAN(vol, find_parent)(obj);
  205.       if (!new)
  206.         return NULL;
  207.       new->pathlist = Copy_Path_List (obj->pathlist, TRUE);
  208.       Close_Object (obj);
  209.       obj = new;
  210.       cp++;
  211.     }
  212.   }
  213.  
  214.   while (*cp) {
  215.     for (np = name; *cp && *cp != '/'; )
  216.       *np++ = *cp++;
  217.     *np = 0;
  218.  
  219.     if (*cp)
  220.       cp++;
  221.  
  222.     if (new = HAN(vol, open_obj_in_directory)(obj, name)) {
  223.       new->pathlist = Append_Path_List (obj->pathlist, name);
  224.       Close_Object (obj);
  225.       if (*cp && new->symlink_f) {
  226.     HAN(vol, close_obj)(new);
  227.     iso_errno = ISOERR_IS_SYMLINK;
  228.     return NULL;
  229.       }
  230.       if (*cp && !new->directory_f) {
  231.     HAN(vol, close_obj)(new);
  232.     iso_errno = ISOERR_NOT_FOUND;
  233.     return NULL;
  234.       }
  235.       obj = new;
  236.     } else {
  237.       Close_Object (obj);
  238.       return NULL;
  239.     }
  240.   }
  241.  
  242.   return obj;
  243. }
  244.  
  245. void Close_Object (CDROM_OBJ *p_object)
  246. {
  247.   Free_Path_List (p_object->pathlist);
  248.   HAN(p_object->volume, close_obj)(p_object);
  249. }
  250.  
  251. int Read_From_File (CDROM_OBJ *p_file, char *p_buffer, int p_buffer_length)
  252. {
  253.   return HAN(p_file->volume, read_from_file)(p_file, p_buffer, p_buffer_length);
  254. }
  255.  
  256. int CDROM_Info (CDROM_OBJ *p_obj, CDROM_INFO *p_info)
  257. {
  258.   return HAN(p_obj->volume, cdrom_info)(p_obj, p_info);
  259. }
  260.  
  261. t_bool Examine_Next (CDROM_OBJ *p_dir, CDROM_INFO *p_info, unsigned long *p_offset)
  262. {
  263.   return HAN(p_dir->volume, examine_next)(p_dir, p_info, p_offset);
  264. }
  265.  
  266. CDROM_OBJ *Clone_Object (CDROM_OBJ *p_object)
  267. {
  268.   CDROM_OBJ *new = AllocMem (sizeof (CDROM_OBJ), MEMF_PUBLIC);
  269.  
  270.   if (!new)
  271.     return NULL;
  272.  
  273.   memcpy (new, p_object, sizeof (CDROM_OBJ));
  274.   new->obj_info = HAN(p_object->volume,clone_obj_info)(p_object->obj_info);
  275.   if (!new->obj_info) {
  276.     FreeMem (new, sizeof (CDROM_OBJ));
  277.     return NULL;
  278.   }
  279.  
  280.   new->pathlist = Copy_Path_List (p_object->pathlist, FALSE);
  281.  
  282.   return new;
  283. }
  284.  
  285. CDROM_OBJ *Find_Parent (CDROM_OBJ *p_object)
  286. {
  287.   CDROM_OBJ *result = HAN(p_object->volume, find_parent)(p_object);
  288.   if (result)
  289.     result->pathlist = Copy_Path_List (p_object->pathlist, TRUE);
  290.   return result;
  291. }
  292.  
  293. t_bool Is_Top_Level_Object (CDROM_OBJ *p_object)
  294. {
  295.   return HAN(p_object->volume, is_top_level_obj)(p_object);
  296. }
  297.  
  298. t_bool Same_Objects (CDROM_OBJ *p_object1, CDROM_OBJ *p_object2)
  299. {
  300.   if (p_object1->volume != p_object2->volume)
  301.     return 0;
  302.   return HAN(p_object1->volume, same_objects)(p_object1, p_object2);
  303. }
  304.  
  305. t_ulong Volume_Creation_Date (VOLUME *p_volume)
  306. {
  307.   if (!HANX(p_volume, creation_date))
  308.     return 0;
  309.   return HAN(p_volume, creation_date)(p_volume);
  310. }
  311.  
  312. t_ulong Volume_Size (VOLUME *p_volume)
  313. {
  314.   return HAN(p_volume, volume_size)(p_volume);
  315. }
  316.  
  317. t_ulong Block_Size (VOLUME *p_volume)
  318. {
  319.   return HAN(p_volume, block_size)(p_volume);
  320. }
  321.  
  322. void Volume_ID (VOLUME *p_volume, char *p_buffer, int p_buf_length)
  323. {
  324.   HAN(p_volume, volume_id)(p_volume, p_buffer, p_buf_length);
  325. }
  326.  
  327. t_ulong Location (CDROM_OBJ *p_object)
  328. {
  329.   return HAN(p_object->volume, location)(p_object);
  330. }
  331.  
  332. /* Find a position in a file.
  333.  */
  334.  
  335. int Seek_Position (CDROM_OBJ *p_object, long p_offset, int p_mode)
  336. {
  337.   t_ulong new_pos;
  338.   t_ulong max_len = HAN(p_object->volume, file_length)(p_object);
  339.  
  340.   if (p_object->directory_f) {
  341.     iso_errno = ISOERR_BAD_ARGUMENTS;
  342.     return 0;
  343.   }
  344.   
  345.   switch (p_mode) {
  346.   case SEEK_FROM_START:
  347.     if (p_offset < 0 || p_offset > max_len) {
  348.       iso_errno = ISOERR_OFF_BOUNDS;
  349.       return 0;
  350.     }
  351.     new_pos = p_offset;
  352.     break;
  353.   case SEEK_FROM_CURRENT_POS:
  354.     if ((p_offset < 0 && -p_offset > p_object->pos) ||
  355.         (p_offset > 0 && p_object->pos + p_offset > max_len)) {
  356.       iso_errno = ISOERR_OFF_BOUNDS;
  357.       return 0;
  358.     }
  359.     new_pos = p_object->pos + p_offset;
  360.     break;
  361.   case SEEK_FROM_END:
  362.     if (p_offset > 0 || -p_offset > max_len) {
  363.       iso_errno = ISOERR_OFF_BOUNDS;
  364.       return 0;
  365.     }
  366.     new_pos = max_len + p_offset;
  367.     break;
  368.   default:
  369.     iso_errno = ISOERR_BAD_ARGUMENTS;
  370.     return 0;    
  371.   }
  372.   p_object->pos = new_pos;
  373.   return 1;
  374. }
  375.  
  376. /* Find path name of an object:
  377.  *
  378.  */
  379.  
  380. int Full_Path_Name (CDROM_OBJ *p_obj, char *p_buf, int p_buf_length)
  381. {
  382.   return Path_Name_From_Path_List (p_obj->pathlist, p_buf, p_buf_length);
  383. }
  384.