home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / useful / dist / disk / cdrom / amicdrom / generic.c < prev    next >
C/C++ Source or Header  |  1994-04-17  |  9KB  |  403 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.  * 01-Jan-94   fmu   Added multisession support.
  14.  * 29-Nov-93   fmu   New function Block_Size().
  15.  * 15-Nov-93   fmu   Missing return value for 'Location' inserted.
  16.  * 10-Nov-93   fmu   Added HFS/ISO-9660-lookup reversing in Which_Protocol.
  17.  */
  18.  
  19. #include <stdlib.h>
  20. #include <string.h>
  21.  
  22. #include <exec/types.h>
  23. #include <exec/memory.h>
  24. #include <clib/exec_protos.h>
  25. #include <clib/utility_protos.h>
  26. #ifdef AZTEC_C
  27. #include <pragmas/exec_lib.h>
  28. #include <pragmas/utility_lib.h>
  29. #endif
  30. #ifdef LATTICE
  31. #include <pragmas/exec_pragmas.h>
  32. #include <pragmas/utility_pragmas.h>
  33.  
  34. extern struct Library *UtilityBase;
  35. extern struct ExecBase *SysBase;
  36. #endif
  37. #if defined(_DCC) && defined(REGISTERED)
  38. #include <pragmas/exec_pragmas.h>
  39. #include <pragmas/utility_pragmas.h>
  40.  
  41. extern struct Library *UtilityBase;
  42. extern struct Library *SysBase;
  43. #endif
  44.  
  45. #include "cdrom.h"
  46. #include "generic.h"
  47. #include "iso9660.h"
  48. #include "rock.h"
  49. #include "hfs.h"
  50. #include "params.h"
  51.  
  52. #define HAN(vol,func) (*(vol)->handler->func)
  53. #define HANX(vol,func) ((vol)->handler->func)
  54.  
  55. t_bool g_hfs_first = FALSE;
  56.  
  57. /* Strncasecmp works like 'strncmp' but ignores case differences.
  58.  */
  59.  
  60. int Strncasecmp (char *p_str1, char *p_str2, int p_length)
  61. {
  62.   int i;
  63.   int len = 0;
  64.   
  65.   while (len < p_length && *p_str1 && *p_str2) {
  66.     if (i = ToLower (*p_str1++) - ToLower (*p_str2++))
  67.       return i;
  68.     len++;
  69.   }
  70.   return (len == p_length) ? 0 : ToLower (*p_str1) - ToLower (*p_str2);
  71. }
  72.  
  73. /* WhichProtocol - examines which protocol is used.
  74.  *
  75.  * Input Variables:
  76.  *  p_cdrom - CDROM descriptor
  77.  *  p_use_rock_ridge - flag for the ROCKRIDGE startup option
  78.  *
  79.  * Output Variables:
  80.  *  p_skip - skip length for RockRidge disks
  81.  *  p_offset - block offset of last session for multisession disks (ISO only)
  82.  *
  83.  * Result:
  84.  *  PRO_ISO, PRO_HIGH_SIERRA, PRO_RR, PRO_HFS or PRO_UNKNOWN.
  85.  */
  86.  
  87. t_protocol Which_Protocol (CDROM *p_cdrom, t_bool p_use_rock_ridge, int *p_skip,
  88.                t_ulong *p_offset)
  89. {
  90.   if (p_cdrom->drive_type == DRIVE_TOSHIBA_3401) {
  91.     if (Is_XA_Mode_Disk (p_cdrom))
  92.       Mode_Select (p_cdrom, 0x81, 2048);
  93.     else
  94.       Mode_Select (p_cdrom, 0x00, 2048);
  95.   }
  96.  
  97.   if (g_hfs_first && Uses_HFS_Protocol (p_cdrom, p_skip))
  98.     return PRO_HFS;
  99.  
  100.   if (Uses_Iso_Protocol (p_cdrom, p_offset)) {
  101.     if (p_use_rock_ridge) {
  102.       VOLUME tmp_vol; /* temporary volume descriptor */
  103.       t_bool rr;
  104.  
  105.       tmp_vol.cd = p_cdrom;
  106.       tmp_vol.protocol = PRO_ISO;
  107.       Iso_Init_Vol_Info (&tmp_vol, 0, *p_offset);
  108.       rr = Uses_Rock_Ridge_Protocol (&tmp_vol, p_skip);
  109.       HAN (&tmp_vol, close_vol_info) (&tmp_vol);
  110.       return rr ? PRO_ROCK : PRO_ISO;
  111.     } else
  112.       return PRO_ISO;
  113.   }
  114.   
  115.   if (Uses_High_Sierra_Protocol (p_cdrom))
  116.     return PRO_HIGH_SIERRA;
  117.  
  118.   if (!g_hfs_first && Uses_HFS_Protocol (p_cdrom, p_skip))
  119.     return PRO_HFS;
  120.  
  121.   return PRO_UNKNOWN;
  122. }
  123.  
  124. VOLUME *Open_Volume (CDROM *p_cdrom, t_bool p_use_rock_ridge)
  125. {
  126.   VOLUME *res;
  127.   int skip;
  128.   t_ulong offset;
  129.     
  130.   res = AllocMem (sizeof (VOLUME), MEMF_PUBLIC);
  131.   if (!res) {
  132.     iso_errno = ISOERR_NO_MEMORY;
  133.     return NULL;
  134.   }
  135.  
  136.   res->cd = p_cdrom;
  137.   
  138.   res->locks = 0;        /* may be modified by application program */
  139.   res->file_handles = 0; /* may be modified by application program */
  140.  
  141.   res->protocol = Which_Protocol (p_cdrom, p_use_rock_ridge, &skip, &offset);
  142.   if (res->protocol == PRO_UNKNOWN) {
  143.     /* give it a second try: */
  144.     res->protocol = Which_Protocol (p_cdrom, p_use_rock_ridge, &skip, &offset);
  145.   }
  146.  
  147.   switch (res->protocol) {
  148.   case PRO_ROCK:
  149.   case PRO_ISO:
  150.     if (!Iso_Init_Vol_Info (res, skip, offset)) {
  151.       FreeMem (res, sizeof (VOLUME));
  152.       return NULL;
  153.     }
  154.     break;
  155.   case PRO_HFS:
  156.     if (!HFS_Init_Vol_Info (res, skip)) {
  157.       FreeMem (res, sizeof (VOLUME));
  158.       return NULL;
  159.     }
  160.     break;
  161.   default:
  162.     FreeMem (res, sizeof (VOLUME));
  163.     return NULL;
  164.   }
  165.  
  166.   return res;
  167. }
  168.  
  169. void Close_Volume (VOLUME *p_volume)
  170. {
  171.   HAN(p_volume, close_vol_info)(p_volume);
  172.   FreeMem (p_volume, sizeof (VOLUME));
  173. }
  174.  
  175. CDROM_OBJ *Open_Top_Level_Directory (VOLUME *p_volume)
  176. {
  177.   return HAN(p_volume, open_top_level_directory)(p_volume);
  178. }
  179.  
  180. CDROM_OBJ *Open_Object (CDROM_OBJ *p_current_dir, char *p_path_name)
  181. {
  182.   char *cp = p_path_name;
  183.   CDROM_OBJ *obj, *new;
  184.   VOLUME *vol = p_current_dir->volume;
  185.   char *np;
  186.   char name[100];
  187.  
  188.   if (*cp == ':') {
  189.     obj = HAN(vol, open_top_level_directory)(p_current_dir->volume);
  190.     cp++;
  191.   } else {
  192.     obj = Clone_Object (p_current_dir);
  193.     if (!obj) {
  194.       iso_errno = ISOERR_NO_MEMORY;
  195.       return NULL;
  196.     }
  197.     while (*cp == '/') {
  198.       new = HAN(vol, find_parent)(obj);
  199.       if (!new)
  200.         return NULL;
  201.       HAN(vol, close_obj)(obj);
  202.       obj = new;
  203.       cp++;
  204.     }
  205.   }
  206.  
  207.   while (*cp) {
  208.     for (np = name; *cp && *cp != '/'; )
  209.       *np++ = *cp++;
  210.     *np = 0;
  211.  
  212.     if (*cp)
  213.       cp++;
  214.  
  215.     if (new = HAN(vol, open_obj_in_directory)(obj, name)) {
  216.       HAN(vol, close_obj)(obj);
  217.       if (*cp && new->symlink_f) {
  218.     HAN(vol, close_obj)(new);
  219.     iso_errno = ISOERR_IS_SYMLINK;
  220.     return NULL;
  221.       }
  222.       if (*cp && !new->directory_f) {
  223.     HAN(vol, close_obj)(new);
  224.     iso_errno = ISOERR_NOT_FOUND;
  225.     return NULL;
  226.       }
  227.       obj = new;
  228.     } else {
  229.       HAN(vol, close_obj)(obj);
  230.       return NULL;
  231.     }
  232.   }
  233.  
  234.   return obj;
  235. }
  236.  
  237. void Close_Object (CDROM_OBJ *p_object)
  238. {
  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.   return new;
  272. }
  273.  
  274. CDROM_OBJ *Find_Parent (CDROM_OBJ *p_object)
  275. {
  276.   return HAN(p_object->volume, find_parent)(p_object);
  277. }
  278.  
  279. t_bool Is_Top_Level_Object (CDROM_OBJ *p_object)
  280. {
  281.   return HAN(p_object->volume, is_top_level_obj)(p_object);
  282. }
  283.  
  284. t_bool Same_Objects (CDROM_OBJ *p_object1, CDROM_OBJ *p_object2)
  285. {
  286.   if (p_object1->volume != p_object2->volume)
  287.     return 0;
  288.   return HAN(p_object1->volume, same_objects)(p_object1, p_object2);
  289. }
  290.  
  291. t_ulong Volume_Creation_Date (VOLUME *p_volume)
  292. {
  293.   if (!HANX(p_volume, creation_date))
  294.     return 0;
  295.   return HAN(p_volume, creation_date)(p_volume);
  296. }
  297.  
  298. t_ulong Volume_Size (VOLUME *p_volume)
  299. {
  300.   return HAN(p_volume, volume_size)(p_volume);
  301. }
  302.  
  303. t_ulong Block_Size (VOLUME *p_volume)
  304. {
  305.   return HAN(p_volume, block_size)(p_volume);
  306. }
  307.  
  308. void Volume_ID (VOLUME *p_volume, char *p_buffer, int p_buf_length)
  309. {
  310.   HAN(p_volume, volume_id)(p_volume, p_buffer, p_buf_length);
  311. }
  312.  
  313. t_ulong Location (CDROM_OBJ *p_object)
  314. {
  315.   return HAN(p_object->volume, location)(p_object);
  316. }
  317.  
  318. /* Find a position in a file.
  319.  */
  320.  
  321. int Seek_Position (CDROM_OBJ *p_object, long p_offset, int p_mode)
  322. {
  323.   t_ulong new_pos;
  324.   t_ulong max_len = HAN(p_object->volume, file_length)(p_object);
  325.  
  326.   if (p_object->directory_f) {
  327.     iso_errno = ISOERR_BAD_ARGUMENTS;
  328.     return 0;
  329.   }
  330.   
  331.   switch (p_mode) {
  332.   case SEEK_FROM_START:
  333.     if (p_offset < 0 || p_offset > max_len) {
  334.       iso_errno = ISOERR_OFF_BOUNDS;
  335.       return 0;
  336.     }
  337.     new_pos = p_offset;
  338.     break;
  339.   case SEEK_FROM_CURRENT_POS:
  340.     if ((p_offset < 0 && -p_offset > p_object->pos) ||
  341.         (p_offset > 0 && p_object->pos + p_offset > max_len)) {
  342.       iso_errno =