home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 2: PC / frozenfish_august_1995.bin / bbs / d09xx / d0935.lha / AmiCDROM / generic.c < prev    next >
C/C++ Source or Header  |  1993-12-20  |  8KB  |  340 lines

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