1 /*
2     Copyright (C) 2005, 2006 2008, 2012 Rocky Bernstein <rocky@gnu.org>
3 
4     See also rock.c by Eric Youngdale (1993) from GNU/Linux
5     This is Copyright 1993 Yggdrasil Computing, Incorporated
6 
7     This program is free software: you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation, either version 3 of the License, or
10     (at your option) any later version.
11 
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License
18     along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20 /*!
21    \file rock.h
22    \brief Things related to the Rock Ridge Interchange Protocol (RRIP)
23 
24    Applications will probably not include this directly but via
25    the iso9660.h header.
26 */
27 
28 
29 #ifndef CDIO_ROCK_H_
30 #define CDIO_ROCK_H_
31 
32 #include <cdio/types.h>
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif /* __cplusplus */
37 
38 /*! An enumeration for some of the ISO_ROCK_* \#defines below. This isn't
39   really an enumeration one would really use in a program it is to
40   be helpful in debuggers where wants just to refer to the ISO_ROCK_*
41   names and get something.
42 */
43 extern enum iso_rock_enums {
44   ISO_ROCK_IRUSR  = 000400,   /**< read permission (owner) */
45   ISO_ROCK_IWUSR  = 000200,   /**< write permission (owner) */
46   ISO_ROCK_IXUSR  = 000100,   /**< execute permission (owner) */
47   ISO_ROCK_IRGRP  = 000040,   /**< read permission (group) */
48   ISO_ROCK_IWGRP  = 000020,   /**< write permission (group) */
49   ISO_ROCK_IXGRP  = 000010,   /**< execute permission (group) */
50   ISO_ROCK_IROTH  = 000004,   /**< read permission (other) */
51   ISO_ROCK_IWOTH  = 000002,   /**< write permission (other) */
52   ISO_ROCK_IXOTH  = 000001,   /**< execute permission (other) */
53 
54   ISO_ROCK_ISUID  = 004000,   /**< set user ID on execution */
55   ISO_ROCK_ISGID  = 002000,   /**< set group ID on execution */
56   ISO_ROCK_ISVTX  = 001000,   /**< save swapped text even after use */
57 
58   ISO_ROCK_ISSOCK = 0140000,  /**< socket */
59   ISO_ROCK_ISLNK  = 0120000,  /**< symbolic link */
60   ISO_ROCK_ISREG  = 0100000,  /**< regular */
61   ISO_ROCK_ISBLK  = 060000,   /**< block special */
62   ISO_ROCK_ISCHR  = 020000,   /**< character special */
63   ISO_ROCK_ISDIR  = 040000,   /**< directory */
64   ISO_ROCK_ISFIFO = 010000    /**< pipe or FIFO */
65 } iso_rock_enums;
66 
67 #define ISO_ROCK_IRUSR    000400  /** read permission (owner) */
68 #define ISO_ROCK_IWUSR    000200  /** write permission (owner) */
69 #define ISO_ROCK_IXUSR    000100  /** execute permission (owner) */
70 #define ISO_ROCK_IRGRP    000040  /** read permission (group) */
71 #define ISO_ROCK_IWGRP    000020  /** write permission (group) */
72 #define ISO_ROCK_IXGRP    000010  /** execute permission (group) */
73 #define ISO_ROCK_IROTH    000004  /** read permission (other) */
74 #define ISO_ROCK_IWOTH    000002  /** write permission (other) */
75 #define ISO_ROCK_IXOTH    000001  /** execute permission (other) */
76 
77 #define ISO_ROCK_ISUID    004000  /** set user ID on execution */
78 #define ISO_ROCK_ISGID    002000  /** set group ID on execution */
79 #define ISO_ROCK_ISVTX    001000  /** save swapped text even after use */
80 
81 #define ISO_ROCK_ISSOCK  0140000  /** socket */
82 #define ISO_ROCK_ISLNK   0120000  /** symbolic link */
83 #define ISO_ROCK_ISREG   0100000  /** regular */
84 #define ISO_ROCK_ISBLK    060000  /** block special */
85 #define ISO_ROCK_ISCHR    020000  /** character special */
86 #define ISO_ROCK_ISDIR    040000  /** directory */
87 #define ISO_ROCK_ISFIFO   010000  /** pipe or FIFO */
88 
89 /** Enforced file locking (shared w/set group ID) */
90 #define ISO_ROCK_ENFMT ISO_ROCK_ISGID
91 
92 PRAGMA_BEGIN_PACKED
93 
94 /*! The next two structs are used by the system-use-sharing protocol
95    (SUSP), in which the Rock Ridge extensions are embedded.  It is
96    quite possible that other extensions are present on the disk, and
97    this is fine as long as they all use SUSP. */
98 
99 /*! system-use-sharing protocol */
100 typedef struct iso_su_sp_s{
101   unsigned char magic[2];
102   uint8_t       skip;
103 } GNUC_PACKED iso_su_sp_t;
104 
105 /*! system-use extension record */
106 typedef struct iso_su_er_s {
107   iso711_t      len_id;  /**< Identifier length. Value 10?. */
108   unsigned char len_des;
109   unsigned char len_src;
110   iso711_t      ext_ver; /**< Extension version. Value 1? */
111   char data[EMPTY_ARRAY_SIZE];
112 } GNUC_PACKED iso_su_er_t;
113 
114 typedef struct iso_su_ce_s {
115   char extent[8];
116   char offset[8];
117   char size[8];
118 } iso_su_ce_t;
119 
120 /*! POSIX file attributes, PX. See Rock Ridge Section 4.1.2 */
121 typedef struct iso_rock_px_s {
122   iso733_t st_mode;       /*! file mode permissions; same as st_mode
123                             of POSIX:5.6.1 */
124   iso733_t st_nlinks;     /*! number of links to file; same as st_nlinks
125                             of POSIX:5.6.1 */
126   iso733_t st_uid;        /*! user id owner of file; same as st_uid
127                             of POSIX:5.6.1 */
128   iso733_t st_gid;        /*! group id of file; same as st_gid of
129                             of POSIX:5.6.1 */
130 } GNUC_PACKED iso_rock_px_t ;
131 
132 /*! POSIX device number, PN. A PN is mandatory if the file type
133   recorded in the "PX" File Mode field for a Directory Record
134   indicates a character or block device (ISO_ROCK_ISCHR |
135   ISO_ROCK_ISBLK).  This entry is ignored for other (non-Direcotry)
136   file types. No more than one "PN" is recorded in the System Use Area
137   of a Directory Record.
138 
139   See Rock Ridge Section 4.1.2 */
140 typedef struct iso_rock_pn_s {
141   iso733_t dev_high;     /**< high-order 32 bits of the 64 bit device number.
142                             7.2.3 encoded */
143   iso733_t dev_low;      /**< low-order 32 bits of the 64 bit device number.
144                             7.2.3 encoded */
145 } GNUC_PACKED iso_rock_pn_t ;
146 
147 /*! These are the bits and their meanings for flags in the SL structure. */
148 typedef enum {
149   ISO_ROCK_SL_CONTINUE = 1,
150   ISO_ROCK_SL_CURRENT  = 2,
151   ISO_ROCK_SL_PARENT   = 4,
152   ISO_ROCK_SL_ROOT     = 8
153 } iso_rock_sl_flag_t;
154 
155 #define ISO_ROCK_SL_CONTINUE 1
156 #define ISO_ROCK_SL_CURRENT  2
157 #define ISO_ROCK_SL_PARENT   4
158 #define ISO_ROCK_SL_ROOT     8
159 
160 typedef struct iso_rock_sl_part_s {
161   uint8_t flags;
162   uint8_t len;
163   char text[EMPTY_ARRAY_SIZE];
164 } GNUC_PACKED iso_rock_sl_part_t ;
165 
166 /*! Symbolic link. See Rock Ridge Section 4.1.3 */
167 typedef struct iso_rock_sl_s {
168   unsigned char flags;
169   iso_rock_sl_part_t link;
170 } GNUC_PACKED iso_rock_sl_t ;
171 
172 /*! Alternate name. See Rock Ridge Section 4.1.4 */
173 
174 /*! These are the bits and their meanings for flags in the NM structure. */
175 typedef enum {
176   ISO_ROCK_NM_CONTINUE = 1,
177   ISO_ROCK_NM_CURRENT  = 2,
178   ISO_ROCK_NM_PARENT   = 4,
179 } iso_rock_nm_flag_t;
180 
181 #define ISO_ROCK_NM_CONTINUE 1
182 #define ISO_ROCK_NM_CURRENT  2
183 #define ISO_ROCK_NM_PARENT   4
184 
185 
186 typedef struct iso_rock_nm_s {
187   unsigned char flags;
188   char name[EMPTY_ARRAY_SIZE];
189 } GNUC_PACKED iso_rock_nm_t ;
190 
191 /*! Child link. See Section 4.1.5.1 */
192 typedef struct iso_rock_cl_s {
193   char location[1];
194 } GNUC_PACKED iso_rock_cl_t ;
195 
196 /*! Parent link. See Section 4.1.5.2 */
197 typedef struct iso_rock_pl_s {
198   char location[1];
199 } GNUC_PACKED iso_rock_pl_t ;
200 
201 /*! These are the bits and their meanings for flags in the TF structure. */
202 typedef enum {
203   ISO_ROCK_TF_CREATE     =  1,
204   ISO_ROCK_TF_MODIFY     =  2,
205   ISO_ROCK_TF_ACCESS     =  4,
206   ISO_ROCK_TF_ATTRIBUTES =  8,
207   ISO_ROCK_TF_BACKUP     =  16,
208   ISO_ROCK_TF_EXPIRATION =  32,
209   ISO_ROCK_TF_EFFECTIVE  =  64,
210   ISO_ROCK_TF_LONG_FORM  = 128
211 } iso_rock_tf_flag_t;
212 
213 /* These are the bits and their meanings for flags in the TF structure. */
214 #define ISO_ROCK_TF_CREATE      1
215 #define ISO_ROCK_TF_MODIFY      2
216 #define ISO_ROCK_TF_ACCESS      4
217 #define ISO_ROCK_TF_ATTRIBUTES  8
218 #define ISO_ROCK_TF_BACKUP     16
219 #define ISO_ROCK_TF_EXPIRATION 32
220 #define ISO_ROCK_TF_EFFECTIVE  64
221 #define ISO_ROCK_TF_LONG_FORM 128
222 
223 /*! Time stamp(s) for a file. See Rock Ridge Section 4.1.6 */
224 typedef struct iso_rock_tf_s {
225   uint8_t flags; /**< See ISO_ROCK_TF_* bits above. */
226   uint8_t time_bytes[EMPTY_ARRAY_SIZE]; /**< A homogenious array of
227                                            iso9660_ltime_t or
228                                            iso9660_dtime_t entries
229                                            depending on flags &
230                                            ISO_ROCK_TF_LONG_FORM. Lacking
231                                            a better method, we store
232                                            this as an array of bytes
233                                            and a cast to the
234                                            appropriate type will have
235                                            to be made before
236                                            extraction.  */
237 } GNUC_PACKED iso_rock_tf_t ;
238 
239 /*! File data in sparse format. See Rock Ridge Section 4.1.7 */
240 typedef struct iso_rock_sf_s {
241   iso733_t virtual_size_high; /**< high-order 32 bits of virtual size */
242   iso733_t virtual_size_low;  /**< low-order 32 bits of virtual size */
243   uint8_t   table_depth;
244 } GNUC_PACKED iso_rock_sf_t ;
245 
246 typedef struct iso_extension_record_s {
247   char signature[2];   /**< signature word; either 'SP', 'CE', 'ER', 'RR',
248                           'PX', 'PN', 'SL', 'NM', 'CL', 'PL', 'TF', or
249                           'ZF' */
250   iso711_t len;        /**< length of system-user area - 44 for PX
251                           20 for PN, 5+strlen(text) for SL, 21 for
252                           SF, etc. */
253   iso711_t version;    /**< version number - value 1 */
254   union {
255     iso_su_sp_t    SP;  /**< system-use-sharing protocol - not
256                           strictly part of Rock Ridge */
257     iso_su_er_t    ER;  /**< system-use extension packet - not
258                            strictly part of Rock Ridge */
259     iso_su_ce_t    CE;  /**< system-use -  strictly part of Rock Ridge */
260     iso_rock_px_t  PX;  /**< Rock Ridge POSIX file attributes */
261     iso_rock_pn_t  PN;  /**< Rock Ridge POSIX device number */
262     iso_rock_sl_t  SL;  /**< Rock Ridge symbolic link */
263     iso_rock_nm_t  NM;  /**< Rock Ridge alternate name */
264     iso_rock_cl_t  CL;  /**< Rock Ridge child link */
265     iso_rock_pl_t  PL;  /**< Rock Ridge parent link */
266     iso_rock_tf_t  TF;  /**< Rock Ridge timestamp(s) for a file */
267   } u;
268 } GNUC_PACKED iso_extension_record_t;
269 
270 typedef struct iso_rock_time_s {
271   bool          b_used;     /**< If true, field has been set and  is valid.
272                                Otherwise remaning fields are meaningless. */
273   bool          b_longdate;  /**< If true date format is a iso9660_ltime_t.
274                                Otherwise date is iso9660_dtime_t */
275   union
276   {
277     iso9660_ltime_t ltime;
278     iso9660_dtime_t dtime;
279   } t;
280 } GNUC_PACKED iso_rock_time_t;
281 
282 typedef struct iso_rock_statbuf_s {
283   bool_3way_t   b3_rock;              /**< has Rock Ridge extension.
284                                          If "yep", then the fields
285                                          are used.
286                                       */
287   posix_mode_t  st_mode;              /**< protection */
288   posix_nlink_t st_nlinks;            /**< number of hard links */
289   posix_uid_t   st_uid;               /**< user ID of owner */
290   posix_gid_t   st_gid;               /**< group ID of owner */
291   uint8_t       s_rock_offset;
292   int           i_symlink;            /**< size of psz_symlink */
293   int           i_symlink_max;        /**< max allocated to psz_symlink */
294   char         *psz_symlink;          /**< if symbolic link, name
295                                          of pointed to file.  */
296   iso_rock_time_t create;             /**< create time See ISO 9660:9.5.4. */
297   iso_rock_time_t modify;             /**< time of last modification
298                                          ISO 9660:9.5.5. st_mtime field of
299                                          POSIX:5.6.1. */
300   iso_rock_time_t access;             /**< time of last file access st_atime
301                                          field of POSIX:5.6.1. */
302   iso_rock_time_t attributes;         /**< time of last attribute change.
303                                          st_ctime field of POSIX:5.6.1. */
304   iso_rock_time_t backup;             /**< time of last backup. */
305   iso_rock_time_t expiration;         /**< time of expiration; See ISO
306                                          9660:9.5.6. */
307   iso_rock_time_t effective;          /**< Effective time; See ISO 9660:9.5.7.
308                                        */
309   uint32_t i_rdev;                    /**< the upper 16-bits is major device
310                                          number, the lower 16-bits is the
311                                          minor device number */
312 
313 } iso_rock_statbuf_t;
314 
315 PRAGMA_END_PACKED
316 
317 /*! return length of name field; 0: not found, -1: to be ignored */
318 int get_rock_ridge_filename(iso9660_dir_t * de, /*out*/ char * retname,
319                             /*out*/ iso9660_stat_t *p_stat);
320 
321   int parse_rock_ridge_stat(iso9660_dir_t *de, /*out*/ iso9660_stat_t *p_stat);
322 
323   /*!
324     Returns POSIX mode bitstring for a given file.
325   */
326   mode_t
327   iso9660_get_posix_filemode_from_rock(const iso_rock_statbuf_t *rr);
328 
329 /*!
330   Returns a string which interpreting the POSIX mode st_mode.
331   For example:
332   \verbatim
333   drwxrws---
334   -rw---Sr--
335   lrwxrwxrwx
336   \endverbatim
337 
338   A description of the characters in the string follows
339   The 1st character is either "d" if the entry is a directory, "l" is
340   a symbolic link or "-" if neither.
341 
342   The 2nd to 4th characters refer to permissions for a user while the
343   the 5th to 7th characters refer to permissions for a group while, and
344   the 8th to 10h characters refer to permissions for everyone.
345 
346   In each of these triplets the first character (2, 5, 8) is "r" if
347   the entry is allowed to be read.
348 
349   The second character of a triplet (3, 6, 9) is "w" if the entry is
350   allowed to be written.
351 
352   The third character of a triplet (4, 7, 10) is "x" if the entry is
353   executable but not user (for character 4) or group (for characters
354   6) settable and "s" if the item has the corresponding user/group set.
355 
356   For a directory having an executable property on ("x" or "s") means
357   the directory is allowed to be listed or "searched". If the execute
358   property is not allowed for a group or user but the corresponding
359   group/user is set "S" indicates this. If none of these properties
360   holds the "-" indicates this.
361 */
362 const char *iso9660_get_rock_attr_str(posix_mode_t st_mode);
363 
364 /** These variables are not used, but are defined to facilatate debugging
365     by letting us use enumerations values (which also correspond to
366     \#define's inside a debugged program.
367  */
368 extern iso_rock_nm_flag_t iso_rock_nm_flag;
369 extern iso_rock_sl_flag_t iso_rock_sl_flag;
370 extern iso_rock_tf_flag_t iso_rock_tf_flag;
371 
372 #ifdef __cplusplus
373 }
374 #endif /* __cplusplus */
375 
376 #endif /* CDIO_ROCK_H_ */
377 
378 /*
379  * Local variables:
380  *  c-file-style: "gnu"
381  *  tab-width: 8
382  *  indent-tabs-mode: nil
383  * End:
384  */
385