1 /*
2 Copyright (C) 2003, 2005, 2008, 2011 Rocky Bernstein <rocky@gnu.org>
3 Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19
20 #ifdef HAVE_CONFIG_H
21 # include "config.h"
22 # define __CDIO_CONFIG_H__ 1
23 #endif
24
25 #ifdef HAVE_STRING_H
26 #include <string.h>
27 #endif
28
29 #ifdef HAVE_SYS_STAT_H
30 #include <sys/stat.h>
31 #endif
32
33 /*! String inside frame which identifies XA attributes. Note should
34 come *before* public headers which does a #define of
35 this name.
36 */
37 const char ISO_XA_MARKER_STRING[] = {'C', 'D', '-', 'X', 'A', '0', '0', '1'};
38
39 /* Public headers */
40 #include <cdio/iso9660.h>
41 #include <cdio/util.h>
42 #include <cdio/bytesex.h>
43
44 /* Private headers */
45 #include "cdio_assert.h"
46 #include "filemode.h"
47
48 /** The below variable is trickery to force enum symbol values to be
49 recorded in debug symbol tables. It is used to allow one to refer
50 to the enumeration value names in the typedefs above in a debugger
51 and debugger expressions.
52 */
53 xa_misc_enum_t debugger_xa_misc_enum;
54
55 #define BUF_COUNT 16
56 #define BUF_SIZE 80
57
58 /* Return a pointer to a internal free buffer */
59 static char *
_getbuf(void)60 _getbuf (void)
61 {
62 static char _buf[BUF_COUNT][BUF_SIZE];
63 static int _num = -1;
64
65 _num++;
66 _num %= BUF_COUNT;
67
68 memset (_buf[_num], 0, BUF_SIZE);
69
70 return _buf[_num];
71 }
72
73 /*!
74 Returns a string which interpreting the extended attribute xa_attr.
75 For example:
76 \verbatim
77 d---1xrxrxr
78 ---2--r-r-r
79 -a--1xrxrxr
80 \endverbatim
81
82 A description of the characters in the string follows
83 The 1st character is either "d" if the entry is a directory, or "-" if not.
84 The 2nd character is either "a" if the entry is CDDA (audio), or "-" if not.
85 The 3rd character is either "i" if the entry is interleaved, or "-" if not.
86 The 4th character is either "2" if the entry is mode2 form2 or "-" if not.
87 The 5th character is either "1" if the entry is mode2 form1 or "-" if not.
88 Note that an entry will either be in mode2 form1 or mode form2. That
89 is you will either see "2-" or "-1" in the 4th & 5th positions.
90
91 The 6th and 7th characters refer to permissions for a user while the
92 the 8th and 9th characters refer to permissions for a group while, and
93 the 10th and 11th characters refer to permissions for a others.
94
95 In each of these pairs the first character (6, 8, 10) is "x" if the
96 entry is executable. For a directory this means the directory is
97 allowed to be listed or "searched".
98 The second character of a pair (7, 9, 11) is "r" if the entry is allowed
99 to be read.
100 */
101
102 const char *
iso9660_get_xa_attr_str(uint16_t xa_attr)103 iso9660_get_xa_attr_str (uint16_t xa_attr)
104 {
105 char *result = _getbuf();
106
107 xa_attr = uint16_from_be (xa_attr);
108
109 result[ 0] = (xa_attr & XA_ATTR_DIRECTORY) ? 'd' : '-';
110 result[ 1] = (xa_attr & XA_ATTR_CDDA) ? 'a' : '-';
111 result[ 2] = (xa_attr & XA_ATTR_INTERLEAVED) ? 'i' : '-';
112 result[ 3] = (xa_attr & XA_ATTR_MODE2FORM2) ? '2' : '-';
113 result[ 4] = (xa_attr & XA_ATTR_MODE2FORM1) ? '1' : '-';
114
115 result[ 5] = (xa_attr & XA_PERM_XUSR) ? 'x' : '-';
116 result[ 6] = (xa_attr & XA_PERM_RUSR) ? 'r' : '-';
117
118 result[ 7] = (xa_attr & XA_PERM_XGRP) ? 'x' : '-';
119 result[ 8] = (xa_attr & XA_PERM_RGRP) ? 'r' : '-';
120
121 /* Hack alert: wonder if this should be ROTH and XOTH? */
122 result[ 9] = (xa_attr & XA_PERM_XSYS) ? 'x' : '-';
123 result[10] = (xa_attr & XA_PERM_RSYS) ? 'r' : '-';
124
125 result[11] = '\0';
126
127 return result;
128 }
129
130 iso9660_xa_t *
iso9660_xa_init(iso9660_xa_t * _xa,uint16_t uid,uint16_t gid,uint16_t attr,uint8_t filenum)131 iso9660_xa_init (iso9660_xa_t *_xa, uint16_t uid, uint16_t gid, uint16_t attr,
132 uint8_t filenum)
133 {
134 cdio_assert (_xa != NULL);
135
136 _xa->user_id = uint16_to_be (uid);
137 _xa->group_id = uint16_to_be (gid);
138 _xa->attributes = uint16_to_be (attr);
139
140 _xa->signature[0] = 'X';
141 _xa->signature[1] = 'A';
142
143 _xa->filenum = filenum;
144
145 _xa->reserved[0]
146 = _xa->reserved[1]
147 = _xa->reserved[2]
148 = _xa->reserved[3]
149 = _xa->reserved[4] = 0x00;
150
151 return _xa;
152 }
153
154 void
iso9660_xa_free(iso9660_xa_t * _xa)155 iso9660_xa_free (iso9660_xa_t *_xa)
156 {
157 if (_xa != NULL)
158 free(_xa);
159 }
160
161 /*!
162 Returns POSIX mode bitstring for a given file.
163 */
164 posix_mode_t
iso9660_get_posix_filemode_from_xa(uint16_t i_perms)165 iso9660_get_posix_filemode_from_xa(uint16_t i_perms)
166 {
167 posix_mode_t mode = 0;
168
169 if (i_perms & XA_PERM_RUSR) mode |= S_IRUSR;
170 if (i_perms & XA_PERM_XUSR) mode |= S_IXUSR;
171
172 #ifdef S_IRGRP
173 if (i_perms & XA_PERM_RGRP) mode |= S_IRGRP;
174 #endif
175 #ifdef S_IXGRP
176 if (i_perms & XA_PERM_XGRP) mode |= S_IXGRP;
177 #endif
178
179 #ifdef S_IROTH
180 if (i_perms & XA_PERM_ROTH) mode |= S_IROTH;
181 #endif
182 #ifdef S_IXOTH
183 if (i_perms & XA_PERM_XOTH) mode |= S_IXOTH;
184 #endif
185
186 if (i_perms & XA_ATTR_DIRECTORY) mode |= S_IFDIR;
187
188 return mode;
189 }
190
191