1 /*
2     Copyright (C) 2003-2008, 2012-2013, 2017
3                   Rocky Bernstein <rocky@gnu.org>
4     Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
5 
6     See also iso9660.h by Eric Youngdale (1993).
7 
8     Copyright 1993 Yggdrasil Computing, Incorporated
9 
10     This program is free software: you can redistribute it and/or modify
11     it under the terms of the GNU General Public License as published by
12     the Free Software Foundation, either version 3 of the License, or
13     (at your option) any later version.
14 
15     This program is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18     GNU General Public License for more details.
19 
20     You should have received a copy of the GNU General Public License
21     along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23 /*!
24  * \file iso9660.h
25  *
26  * \brief The top-level interface header for libiso9660: the ISO-9660
27  * filesystem library; applications include this.
28  *
29  * See also the ISO-9660 specification. The freely available European
30  * equivalant standard is called ECMA-119.
31 */
32 
33 
34 #ifndef CDIO_ISO9660_H_
35 #define CDIO_ISO9660_H_
36 
37 #include <time.h>
38 
39 #include <cdio/cdio.h>
40 #include <cdio/ds.h>
41 #include <cdio/posix.h>
42 
43 /** \brief ISO 9660 Integer and Character types
44 
45 These are described in the section 7 of the ISO 9660 (or ECMA 119)
46 specification.
47 */
48 
49 typedef uint8_t  iso711_t; /*! See section 7.1.1 */
50 typedef int8_t   iso712_t; /*! See section 7.1.2 */
51 typedef uint16_t iso721_t; /*! See section 7.2.1 */
52 typedef uint16_t iso722_t; /*! See section 7.2.2 */
53 typedef uint32_t iso723_t; /*! See section 7.2.3 */
54 typedef uint32_t iso731_t; /*! See section 7.3.1 */
55 typedef uint32_t iso732_t; /*! See section 7.3.2 */
56 typedef uint64_t iso733_t; /*! See section 7.3.3 */
57 
58 typedef char     achar_t;  /*! See section 7.4.1 */
59 typedef char     dchar_t;  /*! See section 7.4.1 */
60 
61 #ifndef EMPTY_ARRAY_SIZE
62 #define EMPTY_ARRAY_SIZE 0
63 #endif
64 
65 #include <cdio/types.h>
66 #include <cdio/xa.h>
67 
68 #ifdef ISODCL
69 #undef ISODCL
70 #endif
71 /* This part borrowed from the bsd386 isofs */
72 #define ISODCL(from, to)        ((to) - (from) + 1)
73 
74 #define MIN_TRACK_SIZE 4*75
75 #define MIN_ISO_SIZE MIN_TRACK_SIZE
76 
77 /*! The below isn't really an enumeration one would really use in a
78     program; things are done this way so that in a debugger one can to
79     refer to the enumeration value names such as in a debugger
80     expression and get something. With the more common a \#define
81     mechanism, the name/value assocation is lost at run time.
82   */
83 extern enum iso_enum1_s {
84   ISO_PVD_SECTOR      =   16, /**< Sector of Primary Volume Descriptor. */
85   ISO_EVD_SECTOR      =   17, /**< Sector of End Volume Descriptor. */
86   LEN_ISONAME         =   31, /**< Size in bytes of the filename
87                                  portion + null byte. */
88   ISO_MAX_SYSTEM_ID   =   32, /**< Maximum number of characters in a system
89                                  id. */
90   MAX_ISONAME         =   37, /**< Size in bytes of the filename
91                                  portion + null byte. */
92   ISO_MAX_PREPARER_ID =  128, /**< Maximum number of characters in a
93                                  preparer id. */
94   MAX_ISOPATHNAME     =  255, /**< Maximum number of characters in the
95                                  entire ISO 9660 filename. */
96   ISO_BLOCKSIZE       = 2048  /**< Number of bytes in an ISO 9660 block. */
97 
98 } iso_enums1;
99 
100 /*! An enumeration for some of the ISO_* \#defines below. This isn't
101     really an enumeration one would really use in a program it is here
102     to be helpful in debuggers where wants just to refer to the
103     ISO_*_ names and get something.
104   */
105 
106 /*! ISO 9660 directory flags. */
107 extern enum iso_flag_enum_s {
108   ISO_FILE            =   0,   /**<  Not really a flag...                */
109   ISO_EXISTENCE       =   1,   /**< Do not make existence known (hidden) */
110   ISO_DIRECTORY       =   2,   /**< This file is a directory             */
111   ISO_ASSOCIATED      =   4,   /**< This file is an associated file      */
112   ISO_RECORD          =   8,   /**< Record format in extended attr. != 0 */
113   ISO_PROTECTION      =  16,   /**< No read/execute perm. in ext. attr.  */
114   ISO_DRESERVED1      =  32,   /**<, Reserved bit 5                      */
115   ISO_DRESERVED2      =  64,   /**<, Reserved bit 6                      */
116   ISO_MULTIEXTENT     = 128,   /**< Not final entry of a mult. ext. file */
117 } iso_flag_enums;
118 
119 /*! Volume descriptor types */
120 extern enum iso_vd_enum_s {
121   ISO_VD_BOOT_RECORD   =  0,  /**< CD is bootable */
122   ISO_VD_PRIMARY       =  1,  /**< Is in any ISO-9660 */
123   ISO_VD_SUPPLEMENTARY =  2,  /**< Used by Joliet, for example */
124   ISO_VD_PARITION      =  3,  /**< Indicates a partition of a CD */
125   ISO_VD_END           = 255
126 } iso_vd_enums;
127 
128 
129 /*!
130    An ISO filename is:
131    <em>abcd</em>.<em>eee</em> ->
132    <em>filename</em>.<em>ext</em>;<em>version#</em>
133 
134     For ISO-9660 Level 1, the maximum needed string length is:
135 
136 @code
137          30 chars (filename + ext)
138     +     2 chars ('.' + ';')
139     +     5 chars (strlen("32767"))
140     +     1 null byte
141    ================================
142     =    38 chars
143 @endcode
144 
145 */
146 
147 /*! \brief Maximum number of characters in a publisher id. */
148 #define ISO_MAX_PUBLISHER_ID 128
149 
150 /*! \brief Maximum number of characters in an application id. */
151 #define ISO_MAX_APPLICATION_ID 128
152 
153 /*! \brief Maximum number of characters in a volume id. */
154 #define ISO_MAX_VOLUME_ID 32
155 
156 /*! \brief Maximum number of characters in a volume-set id. */
157 #define ISO_MAX_VOLUMESET_ID 128
158 
159 /*! String inside frame which identifies an ISO 9660 filesystem. This
160     string is the "id" field of an iso9660_pvd_t or an iso9660_svd_t.
161 */
162 extern const char ISO_STANDARD_ID[sizeof("CD001")-1];
163 
164 #define ISO_STANDARD_ID      "CD001"
165 
166 #ifdef __cplusplus
167 extern "C" {
168 #endif /* __cplusplus */
169 
170 typedef enum strncpy_pad_check {
171   ISO9660_NOCHECK = 0,
172   ISO9660_7BIT,
173   ISO9660_ACHARS,
174   ISO9660_DCHARS
175 } strncpy_pad_check_t;
176 
177 PRAGMA_BEGIN_PACKED
178 
179 /*!
180   \brief ISO-9660 shorter-format time structure. See ECMA 9.1.5.
181 
182   @see iso9660_dtime
183  */
184 struct  iso9660_dtime_s {
185   iso711_t      dt_year;   /**< Number of years since 1900 */
186   iso711_t      dt_month;  /**< Has value in range 1..12. Note starts
187                               at 1, not 0 like a tm struct. */
188   iso711_t      dt_day;    /**< Day of the month from 1 to 31 */
189   iso711_t      dt_hour;   /**< Hour of the day from 0 to 23 */
190   iso711_t      dt_minute; /**< Minute of the hour from 0 to 59 */
191   iso711_t      dt_second; /**< Second of the minute from 0 to 59 */
192   iso712_t      dt_gmtoff; /**< GMT values -48 .. + 52 in 15 minute
193                               intervals */
194 } GNUC_PACKED;
195 
196 typedef struct iso9660_dtime_s  iso9660_dtime_t;
197 
198 /*!
199   \brief ISO-9660 longer-format time structure.
200 
201   Section 8.4.26.1 of ECMA 119. All values are encoded as character
202   arrays, eg. '1', '9', '5', '5' for the year 1955 (no null terminated
203   byte).
204 
205   @see iso9660_ltime
206  */
207 struct  iso9660_ltime_s {
208   char   lt_year        [ISODCL(   1,   4)];   /**< Add 1900 to value
209                                                     for the Julian
210                                                     year */
211   char   lt_month       [ISODCL(   5,   6)];   /**< Has value in range
212                                                   1..12. Note starts
213                                                   at 1, not 0 like a
214                                                   tm struct. */
215   char   lt_day         [ISODCL(   7,   8)];   /**< Day of month: 1..31 */
216   char   lt_hour        [ISODCL(   9,   10)];  /**< hour: 0..23 */
217   char   lt_minute      [ISODCL(  11,   12)];  /**< minute: 0..59 */
218   char   lt_second      [ISODCL(  13,   14)];  /**< second: 0..59 */
219   char   lt_hsecond     [ISODCL(  15,   16)];  /**< The value is in
220                                                   units of 1/100's of
221                                                   a second */
222   iso712_t lt_gmtoff;  /**< Offset from Greenwich Mean Time in number
223                           of 15 min intervals from -48 (West) to +52
224                           (East) recorded according to 7.1.2 numerical
225                           value */
226 } GNUC_PACKED;
227 
228 typedef struct iso9660_ltime_s  iso9660_ltime_t;
229 typedef struct iso9660_dir_s    iso9660_dir_t;
230 typedef struct iso9660_stat_s   iso9660_stat_t;
231 
232 #include <cdio/rock.h>
233 
234 /*! \brief Format of an ISO-9660 directory record
235 
236  Section 9.1 of ECMA 119.
237 
238  This structure may have an odd length depending on how many
239  characters there are in the filename!  Some compilers (e.g. on
240  Sun3/mc68020) pad the structures to an even length.  For this reason,
241  we cannot use sizeof (struct iso_path_table) or sizeof (struct
242  iso_directory_record) to compute on disk sizes.  Instead, we use
243  offsetof(..., name) and add the name size.  See mkisofs.h of the
244  cdrtools package.
245 
246   @see iso9660_stat
247 */
248 struct iso9660_dir_s {
249   iso711_t         length;            /*! Length of Directory record (9.1.1) */
250   iso711_t         xa_length;         /*! XA length if XA is used. Otherwise
251                                           zero. (9.1.2)  */
252   iso733_t         extent;            /*! LBA of first local block allocated
253                                           to the extent */
254   iso733_t         size;              /*! data length of File Section. This
255                                           does not include the length of
256                                           any XA Records. (9.1.2) */
257   iso9660_dtime_t  recording_time;    /*! Recording date and time (9.1.3) */
258   uint8_t          file_flags;        /*! If no XA then zero. If a directory,
259                                         then bits 2,3 and 7 are zero.
260                                         (9.1.6) */
261   iso711_t         file_unit_size;    /*! File Unit size for the File
262                                         Section if the File Section
263                                         is recorded in interleaved
264                                         mode. Otherwise zero. (9.1.7) */
265   iso711_t         interleave_gap;    /*! Interleave Gap size for the
266                                         File Section if the File
267                                         Section is interleaved. Otherwise
268                                         zero. (9.1.8) */
269   iso723_t volume_sequence_number;    /*! Ordinal number of the volume
270                                           in the Volume Set on which
271                                           the Extent described by this
272                                           Directory Record is
273                                           recorded. (9.1.9) */
274 /*! MSVC compilers cannot handle a zero sized array in the middle
275     of a struct, and iso9660_dir_s is reused within iso9660_pvd_s.
276     Therefore, instead of defining:
277        iso711_t filename_len;
278        char     filename[];
279     we leverage the fact that iso711_t and char are the same size
280     and use an union. The only gotcha is that the actual string
281     payload of filename.str[] starts at 1, not 0. */
282   union {
283     iso711_t        len;
284     char            str[1];
285   } filename;
286 } GNUC_PACKED;
287 
288 /*!
289   \brief ISO-9660 Primary Volume Descriptor.
290  */
291 struct iso9660_pvd_s {
292   iso711_t         type;                         /**< ISO_VD_PRIMARY - 1 */
293   char             id[5];                        /**< ISO_STANDARD_ID "CD001"
294                                                   */
295   iso711_t         version;                      /**< value 1 for ECMA 119 */
296   char             unused1[1];                   /**< unused - value 0 */
297   achar_t          system_id[ISO_MAX_SYSTEM_ID]; /**< each char is an achar */
298   dchar_t          volume_id[ISO_MAX_VOLUME_ID]; /**< each char is a dchar */
299   uint8_t          unused2[8];                   /**< unused - value 0 */
300   iso733_t         volume_space_size;            /**< total number of
301                                                     sectors */
302   uint8_t          unused3[32];                  /**< unused - value 0 */
303   iso723_t         volume_set_size;              /**< often 1 */
304   iso723_t         volume_sequence_number;       /**< often 1 */
305   iso723_t         logical_block_size;           /**< sector size, e.g. 2048 */
306   iso733_t         path_table_size;              /**< bytes in path table */
307   iso731_t         type_l_path_table;            /**< first sector of L Path
308                                                       Table */
309   iso731_t         opt_type_l_path_table;        /**< first sector of optional
310                                                     L Path Table */
311   iso732_t         type_m_path_table;            /**< first sector of M Path
312                                                     table */
313   iso732_t         opt_type_m_path_table;        /**< first sector of optional
314                                                     M Path table */
315   iso9660_dir_t    root_directory_record;        /**< See 8.4.18 and
316                                                     section 9.1 of
317                                                     ISO 9660 spec. */
318   char             root_directory_filename;      /**< Is '\\0' or root
319                                                   directory. Also pads previous
320                                                   field to 34 bytes */
321   dchar_t          volume_set_id[ISO_MAX_VOLUMESET_ID]; /**< Volume Set of
322                                                            which the volume is
323                                                            a member. See
324                                                         section 8.4.19 */
325   achar_t          publisher_id[ISO_MAX_PUBLISHER_ID];  /**< Publisher of
326                                                          volume. If the first
327                                                          character is '_' 0x5F,
328                                                          the remaining bytes
329                                                          specify a file
330                                                          containing the user.
331                                                          If all bytes are " "
332                                                          (0x20) no publisher
333                                                          is specified. See
334                                                          section 8.4.20 of
335                                                          ECMA 119 */
336   achar_t          preparer_id[ISO_MAX_PREPARER_ID]; /**< preparer of
337                                                          volume. If the first
338                                                          character is '_' 0x5F,
339                                                          the remaining bytes
340                                                          specify a file
341                                                          containing the user.
342                                                          If all bytes are " "
343                                                          (0x20) no preparer
344                                                          is specified.
345                                                          See section 8.4.21
346                                                          of ECMA 119 */
347   achar_t          application_id[ISO_MAX_APPLICATION_ID]; /**< application
348                                                          use to create the
349                                                          volume. If the first
350                                                          character is '_' 0x5F,
351                                                          the remaining bytes
352                                                          specify a file
353                                                          containing the user.
354                                                          If all bytes are " "
355                                                          (0x20) no application
356                                                          is specified.
357                                                          See section of 8.4.22
358                                                          of ECMA 119 */
359   dchar_t          copyright_file_id[37];     /**< Name of file for
360                                                  copyright info. If
361                                                  all bytes are " "
362                                                  (0x20), then no file
363                                                  is identified.  See
364                                                  section 8.4.23 of ECMA 119
365                                                  9660 spec. */
366   dchar_t          abstract_file_id[37];      /**< See section 8.4.24 of
367                                                  ECMA 119. */
368   dchar_t          bibliographic_file_id[37]; /**< See section 7.5 of
369                                                  ISO 9660 spec. */
370   iso9660_ltime_t  creation_date;             /**< date and time of volume
371                                                  creation. See section 8.4.26.1
372                                                  of the ISO 9660 spec. */
373   iso9660_ltime_t  modification_date;         /**< date and time of the most
374                                                  recent modification.
375                                                  See section 8.4.27 of the
376                                                  ISO 9660 spec. */
377   iso9660_ltime_t  expiration_date;           /**< date and time when volume
378                                                  expires. See section 8.4.28
379                                                  of the ISO 9660 spec. */
380   iso9660_ltime_t  effective_date;            /**< date and time when volume
381                                                  is effective. See section
382                                                  8.4.29 of the ISO 9660
383                                                  spec. */
384   iso711_t         file_structure_version;    /**< value 1 for ECMA 119 */
385   uint8_t           unused4[1];                /**< unused - value 0 */
386   char             application_data[512];     /**< Application can put
387                                                  whatever it wants here. */
388   uint8_t          unused5[653];              /**< Unused - value 0 */
389 } GNUC_PACKED;
390 
391 typedef struct iso9660_pvd_s  iso9660_pvd_t;
392 
393 /*!
394   \brief ISO-9660 Supplementary Volume Descriptor.
395 
396   This is used for Joliet Extentions and is almost the same as the
397   the primary descriptor but two unused fields, "unused1" and "unused3
398   become "flags and "escape_sequences" respectively.
399 */
400 struct iso9660_svd_s {
401   iso711_t         type;                         /**< ISO_VD_SUPPLEMENTARY - 2
402                                                   */
403   char             id[5];                        /**< ISO_STANDARD_ID "CD001"
404                                                   */
405   iso711_t         version;                      /**< value 1 */
406   char             flags;                        /**< Section 8.5.3 */
407   achar_t          system_id[ISO_MAX_SYSTEM_ID]; /**< Section 8.5.4; each char
408                                                     is an achar */
409   dchar_t          volume_id[ISO_MAX_VOLUME_ID]; /**< Section 8.5.5; each char
410                                                     is a dchar */
411   char             unused2[8];
412   iso733_t         volume_space_size;            /**< total number of
413                                                     sectors */
414   char             escape_sequences[32];         /**< Section 8.5.6 */
415   iso723_t         volume_set_size;              /**< often 1 */
416   iso723_t         volume_sequence_number;       /**< often 1 */
417   iso723_t         logical_block_size;           /**< sector size, e.g. 2048 */
418   iso733_t         path_table_size;              /**< 8.5.7; bytes in path
419                                                     table */
420   iso731_t         type_l_path_table;            /**< 8.5.8; first sector of
421                                                     little-endian path table */
422   iso731_t         opt_type_l_path_table;        /**< 8.5.9; first sector of
423                                                     optional little-endian
424                                                     path table */
425   iso732_t         type_m_path_table;            /**< 8.5.10; first sector of
426                                                     big-endian path table */
427   iso732_t         opt_type_m_path_table;        /**< 8.5.11; first sector of
428                                                     optional big-endian path
429                                                     table */
430   iso9660_dir_t    root_directory_record;        /**< See section 8.5.12 and
431                                                     9.1 of ISO 9660 spec. */
432   char             root_directory_filename;      /**< Is '\\0' or root
433                                                   directory. Also pads previous
434                                                   field to 34 bytes */
435   dchar_t          volume_set_id[ISO_MAX_VOLUMESET_ID];    /**< 8.5.13;
436                                                               dchars */
437   achar_t          publisher_id[ISO_MAX_PUBLISHER_ID]; /**<
438                                                           Publisher of volume.
439                                                           If the first char-
440                                                           aracter is '_' 0x5F,
441                                                           the remaining bytes
442                                                           specify a file
443                                                           containing the user.
444                                                           If all bytes are " "
445                                                           (0x20) no publisher
446                                                           is specified. See
447                                                           section 8.5.14 of
448                                                           ECMA 119 */
449   achar_t          preparer_id[ISO_MAX_PREPARER_ID]; /**<
450                                                         Data preparer of
451                                                         volume. If the first
452                                                         character is '_' 0x5F,
453                                                         the remaining bytes
454                                                         specify a file
455                                                         containing the user.
456                                                         If all bytes are " "
457                                                         (0x20) no preparer
458                                                         is specified.
459                                                         See section 8.5.15
460                                                         of ECMA 119 */
461   achar_t          application_id[ISO_MAX_APPLICATION_ID]; /**< application
462                                                          use to create the
463                                                          volume. If the first
464                                                          character is '_' 0x5F,
465                                                          the remaining bytes
466                                                          specify a file
467                                                          containing the user.
468                                                          If all bytes are " "
469                                                          (0x20) no application
470                                                          is specified.
471                                                          See section of 8.5.16
472                                                          of ECMA 119 */
473   dchar_t          copyright_file_id[37];     /**< Name of file for
474                                                  copyright info. If
475                                                  all bytes are " "
476                                                  (0x20), then no file
477                                                  is identified.  See
478                                                  section 8.5.17 of ECMA 119
479                                                  9660 spec. */
480   dchar_t          abstract_file_id[37];      /**< See section 8.5.18 of
481                                                  ECMA 119. */
482   dchar_t          bibliographic_file_id[37]; /**< See section 8.5.19 of
483                                                  ECMA 119. */
484   iso9660_ltime_t  creation_date;             /**< date and time of volume
485                                                  creation. See section 8.4.26.1
486                                                  of the ECMA 119 spec. */
487   iso9660_ltime_t  modification_date;         /**< date and time of the most
488                                                  recent modification.
489                                                  See section 8.4.27 of the
490                                                  ECMA 119 spec. */
491   iso9660_ltime_t  expiration_date;           /**< date and time when volume
492                                                  expires. See section 8.4.28
493                                                  of the ECMA 119 spec. */
494   iso9660_ltime_t  effective_date;            /**< date and time when volume
495                                                  is effective. See section
496                                                  8.4.29 of the ECMA 119
497                                                  spec. */
498   iso711_t         file_structure_version;    /**< value 1 for ECMA 119 */
499   uint8_t           unused4[1];                /**< unused - value 0 */
500   char             application_data[512];     /**< 8.5.20 Application can put
501                                                  whatever it wants here. */
502   uint8_t          unused5[653];              /**< Unused - value 0 */
503 } GNUC_PACKED;
504 
505 typedef struct iso9660_svd_s  iso9660_svd_t;
506 
507 PRAGMA_END_PACKED
508 
509 /*! \brief A data type for a list of ISO9660
510   statbuf file pointers returned from the various
511   Cdio iso9660 readdir routines.
512  */
513 typedef CdioList_t CdioISO9660FileList_t;
514 
515 /*! \brief A data type for a list of ISO9660
516   statbuf drectory pointer returned from the variious
517   Cdio iso9660 readdir routines.
518  */
519 typedef CdioList_t CdioISO9660DirList_t;
520 
521 /*! \brief Unix stat-like version of iso9660_dir
522 
523    The iso9660_stat structure is not part of the ISO-9660
524    specification. We use it for our to communicate information
525    in a C-library friendly way, e.g struct tm time structures and
526    a C-style filename string.
527 
528    @see iso9660_dir
529 */
530 struct iso9660_stat_s { /* big endian!! */
531 
532  iso_rock_statbuf_t rr;              /**< Rock Ridge-specific fields  */
533 
534   struct tm          tm;              /**< time on entry - FIXME merge with
535                                          one of entries above, like ctime? */
536   lsn_t              lsn;             /**< start logical sector number */
537   uint32_t           size;            /**< total size in bytes */
538   uint32_t           secsize;         /**< number of sectors allocated */
539   iso9660_xa_t       xa;              /**< XA attributes */
540   enum { _STAT_FILE = 1, _STAT_DIR = 2 } type;
541   bool               b_xa;
542   char         filename[EMPTY_ARRAY_SIZE]; /**< filename */
543 };
544 
545 /** A mask used in iso9660_ifs_read_vd which allows what kinds
546     of extensions we allow, eg. Joliet, Rock Ridge, etc. */
547 typedef uint8_t iso_extension_mask_t;
548 
549 /*! An enumeration for some of the ISO_EXTENSION_* \#defines below. This isn't
550     really an enumeration one would really use in a program it is here
551     to be helpful in debuggers where wants just to refer to the
552     ISO_EXTENSION_*_ names and get something.
553   */
554 extern enum iso_extension_enum_s {
555   ISO_EXTENSION_JOLIET_LEVEL1 = 0x01,
556   ISO_EXTENSION_JOLIET_LEVEL2 = 0x02,
557   ISO_EXTENSION_JOLIET_LEVEL3 = 0x04,
558   ISO_EXTENSION_ROCK_RIDGE    = 0x08,
559   ISO_EXTENSION_HIGH_SIERRA   = 0x10
560 } iso_extension_enums;
561 
562 
563 #define ISO_EXTENSION_ALL           0xFF
564 #define ISO_EXTENSION_NONE          0x00
565 #define ISO_EXTENSION_JOLIET     \
566   (ISO_EXTENSION_JOLIET_LEVEL1 | \
567    ISO_EXTENSION_JOLIET_LEVEL2 | \
568    ISO_EXTENSION_JOLIET_LEVEL3 )
569 
570 
571 /** This is an opaque structure. */
572 typedef struct _iso9660_s iso9660_t;
573 
574   /*! Close previously opened ISO 9660 image and free resources
575     associated with the image. Call this when done using using an ISO
576     9660 image.
577 
578     @param p_iso the ISO-9660 file image to get data from
579 
580     @return true is unconditionally returned. If there was an error
581     false would be returned. Resources associated with p_iso are
582     freed.
583   */
584   bool iso9660_close (iso9660_t * p_iso);
585 
586 
587   /*!
588     Open an ISO 9660 image for reading. Maybe in the future we will have
589     a mode. NULL is returned on error.
590 
591     @param psz_path full path of ISO9660 file.
592 
593 
594     @return a IS9660 structure  is unconditionally returned. The caller
595     should call iso9660_close() when done.
596   */
597   iso9660_t *iso9660_open (const char *psz_path /*flags, mode */);
598 
599   /*!
600     Open an ISO 9660 image for reading allowing various ISO 9660
601     extensions.  Maybe in the future we will have a mode. NULL is
602     returned on error.
603 
604     @see iso9660_open_fuzzy
605   */
606   iso9660_t *iso9660_open_ext (const char *psz_path,
607                                iso_extension_mask_t iso_extension_mask);
608 
609   /*! Open an ISO 9660 image for "fuzzy" reading. This means that we
610     will try to guess various internal offset based on internal
611     checks. This may be useful when trying to read an ISO 9660 image
612     contained in a file format that libiso9660 doesn't know natively
613     (or knows imperfectly.)
614 
615     Some tolerence allowed for positioning the ISO 9660 image. We scan
616     for STANDARD_ID and use that to set the eventual offset to adjust
617     by (as long as that is <= i_fuzz).
618 
619     Maybe in the future we will have a mode. NULL is returned on error.
620 
621     @see iso9660_open, @see iso9660_fuzzy_ext
622   */
623   iso9660_t *iso9660_open_fuzzy (const char *psz_path /*flags, mode */,
624                                  uint16_t i_fuzz);
625 
626   /*!
627     Open an ISO 9660 image for reading with some tolerence for positioning
628     of the ISO9660 image. We scan for ISO_STANDARD_ID and use that to set
629     the eventual offset to adjust by (as long as that is <= i_fuzz).
630 
631     Maybe in the future we will have a mode. NULL is returned on error.
632 
633     @see iso9660_open_ext @see iso9660_open_fuzzy
634   */
635   iso9660_t *iso9660_open_fuzzy_ext (const char *psz_path,
636                                      iso_extension_mask_t iso_extension_mask,
637                                      uint16_t i_fuzz
638                                      /*flags, mode */);
639 
640   /*!
641     Read the Super block of an ISO 9660 image but determine framesize
642     and datastart and a possible additional offset. Generally here we are
643     not reading an ISO 9660 image but a CD-Image which contains an ISO 9660
644     filesystem.
645   */
646   bool iso9660_ifs_fuzzy_read_superblock (iso9660_t *p_iso,
647                                           iso_extension_mask_t iso_extension_mask,
648                                           uint16_t i_fuzz);
649 
650   /*!
651     Seek to a position and then read i_size blocks.
652 
653     @param p_iso the ISO-9660 file image to get data from
654 
655     @param ptr place to put returned data. It should be able to store
656     a least i_size bytes
657 
658     @param start location to start reading from
659 
660     @param i_size number of blocks to read. Each block is ISO_BLOCKSIZE bytes
661     long.
662 
663     @return number of bytes (not blocks) read
664 
665   */
666   long int iso9660_iso_seek_read (const iso9660_t *p_iso, /*out*/ void *ptr,
667                                   lsn_t start, long int i_size);
668 
669   /*!
670     Read the Primary Volume Descriptor for a CD.
671     True is returned if read, and false if there was an error.
672   */
673   bool iso9660_fs_read_pvd ( const CdIo_t *p_cdio,
674                              /*out*/ iso9660_pvd_t *p_pvd );
675 
676   /*!
677     Read the Primary Volume Descriptor for an ISO 9660 image.
678     True is returned if read, and false if there was an error.
679   */
680   bool iso9660_ifs_read_pvd (const iso9660_t *p_iso,
681                              /*out*/ iso9660_pvd_t *p_pvd);
682 
683   /*!
684     Read the Super block of an ISO 9660 image. This is the
685     Primary Volume Descriptor (PVD) and perhaps a Supplemental Volume
686     Descriptor if (Joliet) extensions are acceptable.
687   */
688   bool iso9660_fs_read_superblock (CdIo_t *p_cdio,
689                                    iso_extension_mask_t iso_extension_mask);
690 
691   /*!
692     Read the Super block of an ISO 9660 image. This is the
693     Primary Volume Descriptor (PVD) and perhaps a Supplemental Volume
694     Descriptor if (Joliet) extensions are acceptable.
695   */
696   bool iso9660_ifs_read_superblock (iso9660_t *p_iso,
697                                     iso_extension_mask_t iso_extension_mask);
698 
699 
700 /*====================================================
701   Time conversion
702  ====================================================*/
703 
704   /*!
705     Set time in format used in ISO 9660 directory index record
706     from a Unix time structure.
707   */
708   void iso9660_set_dtime (const struct tm *tm,
709                           /*out*/ iso9660_dtime_t *idr_date);
710 
711 
712   /*!
713     Set time in format used in ISO 9660 directory index record
714     from a Unix time structure. timezone is given as an offset
715     correction in minutes.
716   */
717   void iso9660_set_dtime_with_timezone (const struct tm *p_tm,
718                                         int timezone,
719                                         /*out*/ iso9660_dtime_t *p_idr_date);
720 
721   /*!
722     Set "long" time in format used in ISO 9660 primary volume descriptor
723     from a Unix time structure. */
724   void iso9660_set_ltime (const struct tm *_tm,
725                           /*out*/ iso9660_ltime_t *p_pvd_date);
726 
727   /*!
728     Set "long" time in format used in ISO 9660 primary volume descriptor
729     from a Unix time structure. */
730   void iso9660_set_ltime_with_timezone (const struct tm *_tm,
731                                         int timezone,
732                                         /*out*/ iso9660_ltime_t *p_pvd_date);
733 
734   /*!
735     Get Unix time structure from format use in an ISO 9660 directory index
736     record. Even though tm_wday and tm_yday fields are not explicitly in
737     idr_date, they are calculated from the other fields.
738 
739     If tm is to reflect the localtime, set "b_localtime" true, otherwise
740     tm will reported in GMT.
741   */
742   bool iso9660_get_dtime (const iso9660_dtime_t *idr_date, bool b_localtime,
743                           /*out*/ struct tm *tm);
744 
745 
746   /*!
747     Get "long" time in format used in ISO 9660 primary volume descriptor
748     from a Unix time structure.
749   */
750   bool iso9660_get_ltime (const iso9660_ltime_t *p_ldate,
751                           /*out*/ struct tm *p_tm);
752 
753   /*====================================================
754     Character Classification and String Manipulation
755     ====================================================*/
756   /*!
757     Return true if c is a DCHAR - a character that can appear in an an
758     ISO-9600 level 1 directory name. These are the ASCII capital
759     letters A-Z, the digits 0-9 and an underscore.
760   */
761   bool iso9660_is_dchar (int c);
762 
763   /*!
764     Return true if c is an ACHAR -
765     These are the DCHAR's plus some ASCII symbols including the space
766     symbol.
767   */
768   bool iso9660_is_achar (int c);
769 
770   /*!
771     Convert an ISO-9660 file name which is in the format usually stored
772     in a ISO 9660 directory entry into what's usually listed as the
773     file name in a listing.  Lowercase name, and remove trailing ;1's
774     or .;1's and turn the other ;'s into version numbers.
775 
776     @param psz_oldname the ISO-9660 filename to be translated.
777     @param psz_newname returned string. The caller allocates this and
778     it should be at least the size of psz_oldname.
779     @return length of the translated string is returned.
780   */
781   int iso9660_name_translate(const char *psz_oldname,
782                              /*out*/ char *psz_newname);
783 
784   /*!
785     Convert an ISO-9660 file name which is in the format usually stored
786     in a ISO 9660 directory entry into what's usually listed as the
787     file name in a listing.  Lowercase name if no Joliet Extension
788     interpretation. Remove trailing ;1's or .;1's and turn the other
789     ;'s into version numbers.
790 
791     @param psz_oldname the ISO-9660 filename to be translated.
792     @param psz_newname returned string. The caller allocates this and
793     it should be at least the size of psz_oldname.
794     @param i_joliet_level 0 if not using Joliet Extension. Otherwise the
795     Joliet level.
796     @return length of the translated string is returned. It will be no greater
797     than the length of psz_oldname.
798   */
799   int iso9660_name_translate_ext(const char *psz_oldname, char *psz_newname,
800                                  uint8_t i_joliet_level);
801 
802   /*!
803     Pad string src with spaces to size len and copy this to dst. If
804     len is less than the length of src, dst will be truncated to the
805     first len characters of src.
806 
807     src can also be scanned to see if it contains only ACHARs, DCHARs,
808     7-bit ASCII chars depending on the enumeration _check.
809 
810     In addition to getting changed, dst is the return value.
811     Note: this string might not be NULL terminated.
812   */
813   char *iso9660_strncpy_pad(char dst[], const char src[], size_t len,
814                             enum strncpy_pad_check _check);
815 
816   /*=====================================================================
817     File and Directory Names
818     ======================================================================*/
819 
820   /*!
821     Check that psz_path is a valid ISO-9660 directory name.
822 
823     A valid directory name should not start out with a slash (/),
824     dot (.) or null byte, should be less than 37 characters long,
825     have no more than 8 characters in a directory component
826     which is separated by a /, and consist of only DCHARs.
827 
828     True is returned if psz_path is valid.
829   */
830   bool iso9660_dirname_valid_p (const char psz_path[]);
831 
832   /*!
833     Take psz_path and a version number and turn that into a ISO-9660
834     pathname.  (That's just the pathname followd by ";" and the version
835     number. For example, mydir/file.ext -> MYDIR/FILE.EXT;1 for version
836     1. The resulting ISO-9660 pathname is returned.
837   */
838   char *iso9660_pathname_isofy (const char psz_path[], uint16_t i_version);
839 
840   /*!
841     Check that psz_path is a valid ISO-9660 pathname.
842 
843     A valid pathname contains a valid directory name, if one appears and
844     the filename portion should be no more than 8 characters for the
845     file prefix and 3 characters in the extension (or portion after a
846     dot). There should be exactly one dot somewhere in the filename
847     portion and the filename should be composed of only DCHARs.
848 
849     True is returned if psz_path is valid.
850   */
851   bool iso9660_pathname_valid_p (const char psz_path[]);
852 
853 /*=====================================================================
854   directory tree
855 ======================================================================*/
856 
857 void
858 iso9660_dir_init_new (void *dir, uint32_t self, uint32_t ssize,
859                       uint32_t parent, uint32_t psize,
860                       const time_t *dir_time);
861 
862 void
863 iso9660_dir_init_new_su (void *dir, uint32_t self, uint32_t ssize,
864                          const void *ssu_data, unsigned int ssu_size,
865                          uint32_t parent, uint32_t psize,
866                          const void *psu_data, unsigned int psu_size,
867                          const time_t *dir_time);
868 
869 void
870 iso9660_dir_add_entry_su (void *dir, const char filename[], uint32_t extent,
871                           uint32_t size, uint8_t file_flags,
872                           const void *su_data,
873                           unsigned int su_size, const time_t *entry_time);
874 
875 unsigned int
876 iso9660_dir_calc_record_size (unsigned int namelen, unsigned int su_len);
877 
878 /*!
879    Given a directory pointer, find the filesystem entry that contains
880    lsn and return information about it.
881 
882    @param p_cdio the CD object to read from
883 
884    @return stat_t of entry if we found lsn, or NULL otherwise.
885    Caller must free return value using iso9660_stat_free().
886  */
887 #define iso9660_fs_find_lsn  iso9660_find_fs_lsn
888 iso9660_stat_t *iso9660_fs_find_lsn(CdIo_t *p_cdio, lsn_t i_lsn);
889 
890 
891 /*!
892    Given a directory pointer, find the filesystem entry that contains
893    LSN and return information about it.
894 
895    @param p_cdio the ISO-9660 file image to get data from.
896 
897    @param i_lsn the LSN to find
898 
899    @param ppsz_full_filename the place to store the name of the path that has LSN.
900    On entry this should point to NULL. If not, the value will be freed.
901    On exit a value is malloc'd and the caller is responsible for
902    freeing the result.
903 
904    @return stat_t of entry if we found lsn, or NULL otherwise.
905    Caller must free return value using iso9660_stat_free().
906  */
907 iso9660_stat_t *iso9660_fs_find_lsn_with_path(CdIo_t *p_cdio, lsn_t i_lsn,
908                                               /*out*/ char **ppsz_full_filename);
909 
910 /*!
911    Given a directory pointer, find the filesystem entry that contains
912    lsn and return information about it.
913 
914    @param p_iso the ISO-9660 file image to get data from.
915 
916    @param i_lsn the LSN to find
917 
918    @return stat_t of entry if we found lsn, or NULL otherwise.
919    Caller must free return value using iso9660_stat_free().
920  */
921 iso9660_stat_t *iso9660_ifs_find_lsn(iso9660_t *p_iso, lsn_t i_lsn);
922 
923 
924 /*!
925    Given a directory pointer, find the filesystem entry that contains
926    lsn and return information about it.
927 
928    @param p_iso pointer to iso_t
929 
930    @param i_lsn LSN to find
931 
932    @param ppsz_path  full path of lsn filename. On entry *ppsz_path should be
933    NULL. On return it will be allocated an point to the full path of the
934    file at lsn or NULL if the lsn is not found. You should deallocate
935    *ppsz_path when you are done using it.
936 
937    @return stat_t of entry if we found lsn, or NULL otherwise.
938    Caller must free return value using iso9660_stat_free().
939  */
940 iso9660_stat_t *iso9660_ifs_find_lsn_with_path(iso9660_t *p_iso,
941                                                lsn_t i_lsn,
942                                                /*out*/ char **ppsz_path);
943 
944 /*!
945   Free the passed iso9660_stat_t structure.
946 
947   @param p_stat iso9660 stat buffer to free.
948 
949  */
950 void iso9660_stat_free(iso9660_stat_t *p_stat);
951 
952 /*!
953   Return file status for psz_path. NULL is returned on error.
954 
955   @param p_cdio the CD object to read from
956 
957   @param psz_path filename path to look up and get information about
958 
959   @return ISO 9660 file information. The caller must free the returned
960   result using iso9660_stat_free().
961 
962 
963   Important note:
964 
965   You make get different results looking up "/" versus "/." and the
966   latter may give more complete information. "/" will take information
967   from the PVD only, whereas "/." will force a directory read of "/" and
968   find "." and in that Rock-Ridge information might be found which fills
969   in more stat information. Ideally iso9660_fs_stat should be fixed.
970   Patches anyone?
971  */
972 iso9660_stat_t *iso9660_fs_stat (CdIo_t *p_cdio, const char psz_path[]);
973 
974 
975 /*!
976   Return file status for path name psz_path. NULL is returned on error.
977   pathname version numbers in the ISO 9660 name are dropped, i.e. ;1
978   is removed and if level 1 ISO-9660 names are lowercased.
979 
980   @param p_cdio the CD object to read from
981 
982   @param psz_path filename path to look up and get information about
983 
984   @return ISO 9660 file information.  The caller must free the
985   returned result using iso9660_stat_free().
986 
987  */
988 iso9660_stat_t *iso9660_fs_stat_translate (CdIo_t *p_cdio,
989                                            const char psz_path[]);
990 /*!
991 
992   @param p_iso the ISO-9660 file image to get data from
993 
994   @param psz_path path the look up
995 
996   @return file status for pathname. NULL is returned on error.
997   The caller must free the returned result using iso9660_stat_free().
998  */
999 iso9660_stat_t *iso9660_ifs_stat (iso9660_t *p_iso, const char psz_path[]);
1000 
1001 
1002 /*!
1003   @param p_iso the ISO-9660 file image to get data from
1004 
1005   @param psz_path filename path translate
1006 
1007   @return file status for path name psz_path. NULL is returned on
1008   error.  pathname version numbers in the ISO 9660 name are dropped,
1009   i.e. ;1 is removed and if level 1 ISO-9660 names are lowercased.
1010   The caller must free the returned result using iso9660_stat_free().
1011  */
1012 iso9660_stat_t *iso9660_ifs_stat_translate (iso9660_t *p_iso,
1013                                             const char psz_path[]);
1014 
1015 
1016 /*!
1017   Create a new data structure to hold a list of
1018   ISO9660 statbuf-entry pointers for the files inside
1019   a directory.
1020 
1021   @return allocated list. Free with iso9660_filelist_free()
1022 */
1023 CdioISO9660FileList_t * iso9660_filelist_new(void);
1024 
1025 
1026 /*!
1027   Create a new data structure to hold a list of
1028   ISO9660 statbuf entries for directory
1029   pointers for the files inside a directory.
1030 
1031   @return allocated list. Free with iso9660_dirlist_free()
1032 */
1033 CdioISO9660DirList_t * iso9660_dirlist_new(void);
1034 
1035 
1036 
1037 /*!
1038   Free the passed CdioISOC9660FileList_t structure.
1039 */
1040 void iso9660_filelist_free(CdioISO9660FileList_t *p_filelist);
1041 
1042 
1043 /*!
1044   Free the passed CdioISOC9660Dirlist_t structure.
1045 */
1046 void iso9660_dirlist_free(CdioISO9660DirList_t *p_filelist);
1047 
1048 
1049 /*!
1050   Read psz_path (a directory) and return a list of iso9660_stat_t
1051   pointers for the files inside that directory.
1052 
1053   @param p_cdio the CD object to read from
1054 
1055   @param psz_path path the read the directory from.
1056 
1057   @return file status for psz_path. The caller must free the
1058   The caller must free the returned result using iso9660_stat_free().
1059 */
1060 CdioList_t * iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[]);
1061 
1062 /*!
1063   Read psz_path (a directory) and return a list of iso9660_stat_t
1064   pointers for the files inside that directory.
1065 
1066   @param p_iso the ISO-9660 file image to get data from
1067 
1068   @param psz_path path the read the directory from.
1069 
1070   @return file status for psz_path. The caller must free the
1071   The caller must free the returned result using iso9660_stat_free().
1072 */
1073 CdioList_t * iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[]);
1074 
1075 /*!
1076   Return the PVD's application ID.
1077 
1078   @param p_pvd the PVD to get data from
1079 
1080   @return  the application id.
1081   NULL is returned if there is some problem in getting this.
1082   The caller must free the resturned result using free() if
1083   not null.
1084 */
1085 char * iso9660_get_application_id(iso9660_pvd_t *p_pvd);
1086 
1087 /*!
1088   Return the PVD's application ID.
1089 
1090   @param p_iso the ISO-9660 file image to get data from
1091 
1092   @param p_psz_app_id the application id set on success.
1093 
1094   NULL is returned if there is some problem in getting this.
1095   The caller must free the resturned result using free() if
1096   not null.
1097 */
1098 bool iso9660_ifs_get_application_id(iso9660_t *p_iso,
1099                                     /*out*/ cdio_utf8_t **p_psz_app_id);
1100 
1101 /*!
1102   Return the Joliet level recognized for p_iso.
1103 */
1104 uint8_t iso9660_ifs_get_joliet_level(iso9660_t *p_iso);
1105 
1106 uint8_t iso9660_get_dir_len(const iso9660_dir_t *p_idr);
1107 
1108 #ifdef FIXME
1109 uint8_t iso9660_get_dir_size(const iso9660_dir_t *p_idr);
1110 
1111 lsn_t iso9660_get_dir_extent(const iso9660_dir_t *p_idr);
1112 #endif
1113 
1114   /*!
1115     Return the directory name stored in the iso9660_dir_t
1116 
1117     A string is allocated: the caller must deallocate. This routine
1118     can return NULL if memory allocation fails.
1119   */
1120   char * iso9660_dir_to_name (const iso9660_dir_t *p_iso9660_dir);
1121 
1122   /*!
1123     Returns a POSIX mode for a given p_iso_dirent.
1124   */
1125   mode_t iso9660_get_posix_filemode(const iso9660_stat_t *p_iso_dirent);
1126 
1127   /*!
1128     Return a string containing the preparer id with trailing
1129     blanks removed.
1130   */
1131   char *iso9660_get_preparer_id(const iso9660_pvd_t *p_pvd);
1132 
1133   /*!
1134     Get the preparer ID.  psz_preparer_id is set to NULL if there
1135     is some problem in getting this and false is returned.
1136   */
1137   bool iso9660_ifs_get_preparer_id(iso9660_t *p_iso,
1138                                    /*out*/ cdio_utf8_t **p_psz_preparer_id);
1139 
1140   /*!
1141     Return a string containing the PVD's publisher id with trailing
1142     blanks removed.
1143   */
1144   char *iso9660_get_publisher_id(const iso9660_pvd_t *p_pvd);
1145 
1146   /*!
1147     Get the publisher ID.  psz_publisher_id is set to NULL if there
1148     is some problem in getting this and false is returned.
1149   */
1150   bool iso9660_ifs_get_publisher_id(iso9660_t *p_iso,
1151                                     /*out*/ cdio_utf8_t **p_psz_publisher_id);
1152 
1153   uint8_t iso9660_get_pvd_type(const iso9660_pvd_t *p_pvd);
1154 
1155   const char * iso9660_get_pvd_id(const iso9660_pvd_t *p_pvd);
1156 
1157   int iso9660_get_pvd_space_size(const iso9660_pvd_t *p_pvd);
1158 
1159   int iso9660_get_pvd_block_size(const iso9660_pvd_t *p_pvd) ;
1160 
1161   /*! Return the primary volume id version number (of pvd).
1162     If there is an error 0 is returned.
1163   */
1164   int iso9660_get_pvd_version(const iso9660_pvd_t *pvd) ;
1165 
1166   /*!
1167     Return a string containing the PVD's system id with trailing
1168     blanks removed.
1169   */
1170   char *iso9660_get_system_id(const iso9660_pvd_t *p_pvd);
1171 
1172   /*!
1173     Return "yup" if any file has Rock-Ridge extensions. Warning: this can
1174     be time consuming. On an ISO 9600 image with lots of files but no Rock-Ridge
1175     extensions, the entire directory structure will be scanned up to u_file_limit.
1176 
1177     @param p_iso the ISO-9660 file image to get data from
1178 
1179     @param u_file_limit the maximimum number of (non-rock-ridge) files
1180     to consider before giving up and returning "dunno".
1181 
1182     "dunno" can also be returned if there was some error encountered
1183     such as not being able to allocate memory in processing.
1184 
1185   */
1186   bool_3way_t iso9660_have_rr(iso9660_t *p_iso, uint64_t u_file_limit);
1187 
1188   /*!
1189     Get the system ID.  psz_system_id is set to NULL if there
1190     is some problem in getting this and false is returned.
1191   */
1192   bool iso9660_ifs_get_system_id(iso9660_t *p_iso,
1193                                  /*out*/ cdio_utf8_t **p_psz_system_id);
1194 
1195 
1196   /*! Return the LSN of the root directory for pvd.
1197     If there is an error CDIO_INVALID_LSN is returned.
1198   */
1199   lsn_t iso9660_get_root_lsn(const iso9660_pvd_t *p_pvd);
1200 
1201   /*!
1202     Get the volume ID in the PVD.  psz_volume_id is set to NULL if there
1203     is some problem in getting this and false is returned.
1204   */
1205   char *iso9660_get_volume_id(const iso9660_pvd_t *p_pvd);
1206 
1207   /*!
1208     Get the volume ID in the PVD.  psz_volume_id is set to NULL if there
1209     is some problem in getting this and false is returned.
1210   */
1211   bool iso9660_ifs_get_volume_id(iso9660_t *p_iso,
1212                                  /*out*/ cdio_utf8_t **p_psz_volume_id);
1213 
1214   /*!
1215     Return the volumeset ID in the PVD.
1216     NULL is returned if there is some problem in getting this.
1217   */
1218   char *iso9660_get_volumeset_id(const iso9660_pvd_t *p_pvd);
1219 
1220   /*!
1221     Get the volumeset ID.  psz_systemset_id is set to NULL if there
1222     is some problem in getting this and false is returned.
1223   */
1224   bool iso9660_ifs_get_volumeset_id(iso9660_t *p_iso,
1225                                     /*out*/ cdio_utf8_t **p_psz_volumeset_id);
1226 
1227   /* pathtable */
1228 
1229   /*! Zero's out pathable. Do this first. */
1230   void iso9660_pathtable_init (void *pt);
1231 
1232   unsigned int iso9660_pathtable_get_size (const void *pt);
1233 
1234   uint16_t iso9660_pathtable_l_add_entry (void *pt, const char name[],
1235                                           uint32_t extent, uint16_t parent);
1236 
1237   uint16_t iso9660_pathtable_m_add_entry (void *pt, const char name[],
1238                                           uint32_t extent, uint16_t parent);
1239 
1240   /**=====================================================================
1241      Volume Descriptors
1242      ======================================================================*/
1243 
1244   void iso9660_set_pvd (void *pd, const char volume_id[],
1245                         const char application_id[],
1246                         const char publisher_id[], const char preparer_id[],
1247                         uint32_t iso_size, const void *root_dir,
1248                         uint32_t path_table_l_extent,
1249                         uint32_t path_table_m_extent,
1250                         uint32_t path_table_size, const time_t *pvd_time);
1251 
1252   void iso9660_set_evd (void *pd);
1253 
1254   /*!
1255     Return true if ISO 9660 image has extended attrributes (XA).
1256   */
1257   bool iso9660_ifs_is_xa (const iso9660_t * p_iso);
1258 
1259 
1260 #ifndef DO_NOT_WANT_COMPATIBILITY
1261 /** For compatibility with < 0.77 */
1262 #define iso9660_isdchar       iso9660_is_dchar
1263 #define iso9660_isachar       iso9660_is_achar
1264 #endif /*DO_NOT_WANT_COMPATIBILITY*/
1265 
1266 #ifdef __cplusplus
1267 }
1268 #endif /* __cplusplus */
1269 
1270 #undef ISODCL
1271 #endif /* CDIO_ISO9660_H_ */
1272 
1273 /*
1274  * Local variables:
1275  *  c-file-style: "gnu"
1276  *  tab-width: 8
1277  *  indent-tabs-mode: nil
1278  * End:
1279  */
1280