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