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