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

  1. /* rock.c:
  2.  *
  3.  * Support for the Rock Ridge filing system.
  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.  * 16-Oct-93   fmu   Adapted to new VOLUME structure.
  14.  */
  15.  
  16. #include <stdlib.h>
  17. #include <string.h>
  18.  
  19. #include <exec/memory.h>
  20. #include <clib/exec_protos.h>
  21. #ifdef AZTEC_C
  22. #include <pragmas/exec_lib.h>
  23. #endif
  24. #ifdef LATTICE
  25. #include <pragmas/exec_pragmas.h>
  26. #endif
  27. #if defined(_DCC) && defined(REGISTERED)
  28. #include <pragmas/exec_pragmas.h>
  29. extern struct Library *SysBase;
  30. #endif
  31.  
  32. #include "rock.h"
  33.  
  34. #define VOL(vol,tag) (((t_iso_vol_info *)(vol->vol_info))->tag)
  35. #define OBJ(obj,tag) (((t_iso_obj_info *)(obj->obj_info))->tag)
  36.  
  37. /* Check whether the given volume uses the Rock Ridge Interchange Protocol.
  38.  * The protocol is identified by the sequence
  39.  *            'S' 'P' 7 1 0xbe 0xef
  40.  * in the system use field of the (00) directory in the root directory of
  41.  * the volume.
  42.  *
  43.  * Returns 1 iff the RR protocol is used; 0 otherwise.
  44.  * If the RR protocol is used, *p_skip will be set to the skip length
  45.  * specified in the SP system use field.
  46.  */
  47.  
  48. t_bool Uses_Rock_Ridge_Protocol (VOLUME *p_volume, int *p_skip)
  49. {
  50.   unsigned long loc = VOL(p_volume,pvd).root.extent_loc_m;
  51.   directory_record *dir;
  52.   int system_use_pos;
  53.   unsigned char *sys;
  54.  
  55.   if (!(dir = Get_Directory_Record (p_volume, loc, 0)))
  56.     return 0;
  57.   
  58.   system_use_pos = 33 + dir->file_id_length;
  59.   if (system_use_pos & 1)
  60.     system_use_pos++;
  61.  
  62.   if (system_use_pos >= dir->length)
  63.     return 0;
  64.  
  65.   sys = (unsigned char *) dir + system_use_pos;
  66.   if (sys[0] == 'S' && sys[1] == 'P' && sys[2] == 7 &&
  67.       sys[3] == 1 && sys[4] == 0xbe && sys[5] == 0xef) {
  68.     *p_skip = sys[6];
  69.     return 1;
  70.   } else
  71.     return 0;
  72. }
  73.  
  74. /* Searches for the system use field with name p_name in the directory record
  75.  * p_dir and fills the buffer p_buf (with length p_buf_len) with the information
  76.  * contained in the system use field.
  77.  *
  78.  * p_index is the ordinal number of the system use field (if more than one
  79.  * system use field with the same name is recorded.) 0=first occurrence,
  80.  * 1=second occurrence, and so on.
  81.  *
  82.  * 1 is returned if the system use field has been found; otherwise 0
  83.  * is returned.
  84.  */
  85.  
  86. int Get_System_Use_Field (VOLUME *p_volume, directory_record *p_dir,
  87.               char *p_name, char *p_buf, int p_buf_len,
  88.               int p_index)
  89. {
  90.   int system_use_pos;
  91.   int slen, len;
  92.   unsigned long length = p_dir->length;
  93.   unsigned char *buf = (unsigned char *) p_dir;
  94.  
  95.   system_use_pos = 33 + p_dir->file_id_length;
  96.   if (system_use_pos & 1)
  97.     system_use_pos++;
  98.   system_use_pos += VOL(p_volume,skip);
  99.  
  100.   /* the system use field must be at least 4 bytes long */
  101.   while (system_use_pos + 3 < length) {
  102.     slen = buf[system_use_pos+2];
  103.     if (buf[system_use_pos] == p_name[0] &&
  104.         buf[system_use_pos+1] == p_name[1]) {
  105.       if (p_index)
  106.         p_index--;
  107.       else {
  108.         len = (slen < p_buf_len) ? slen : p_buf_len;
  109.         memcpy (p_buf, buf + system_use_pos, len);
  110.         return 1;
  111.       }
  112.     }
  113.     /* look for continuation area: */
  114.     if (buf[system_use_pos] == 'C' &&
  115.         buf[system_use_pos+1] == 'E') {
  116.       unsigned long newloc, offset;
  117.       memcpy (&newloc, buf + system_use_pos + 8, 4);
  118.       memcpy (&offset, buf + system_use_pos + 16, 4);
  119.       memcpy (&length, buf + system_use_pos + 24, 4);
  120.       if (!Read_Sector (p_volume->cd, newloc))
  121.         return 0;
  122.       buf = p_volume->cd->buffer;
  123.       system_use_pos = offset;
  124.       continue;
  125.     }
  126.     
  127.     /* look for system use field terminator: */
  128.     if (buf[system_use_pos] == 'S' &&
  129.         buf[system_use_pos+1] == 'T')
  130.       return 0;
  131.  
  132.     system_use_pos += slen;
  133.   }
  134.   return 0;
  135. }
  136.  
  137. /* Determines the Rock Ridge file name of the CDROM object p_obj.
  138.  * The file name will be stored in the buffer p_buf (with length p_buf_len).
  139.  * The file name will NOT be null-terminated. The number of characters in
  140.  * the file name is returned. If there is no Rock Ridge file name for
  141.  * p_obj, then -1 is returned.
  142.  */
  143.  
  144. int Get_RR_File_Name (VOLUME *p_volume, directory_record *p_dir,
  145.               char *p_buf, int p_buf_len)
  146. {
  147.   __unaligned struct nm_system_use_field {
  148.     char      id[2];
  149.     unsigned char length;
  150.     unsigned char version;
  151.     unsigned char flags;
  152.     char          name[210];
  153.   } nm;
  154.   int len, slen;
  155.   int index = 0;
  156.   int total = 0;
  157.  
  158.   for (;;) {
  159.     if (!Get_System_Use_Field (p_volume, p_dir, "NM",
  160.                      (char *) &nm, sizeof (nm), index))
  161.       return -1;
  162.  
  163.     slen = nm.length-5;
  164.     len = (p_buf_len < slen) ? p_buf_len : slen;
  165.     if (len)
  166.       memcpy (p_buf, nm.name, len);
  167.  
  168.     total += len;
  169.     if (!(nm.flags & 1))
  170.       return total;
  171.  
  172.     p_buf += len;
  173.     p_buf_len -= len;
  174.     index++;
  175.   }
  176. }
  177.  
  178.