/src/binutils-gdb/binutils/filemode.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* filemode.c -- make a string describing file modes |
2 | | Copyright (C) 1985-2023 Free Software Foundation, Inc. |
3 | | |
4 | | This program is free software; you can redistribute it and/or modify |
5 | | it under the terms of the GNU General Public License as published by |
6 | | the Free Software Foundation; either version 3, or (at your option) |
7 | | any later version. |
8 | | |
9 | | This program is distributed in the hope that it will be useful, |
10 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | | GNU General Public License for more details. |
13 | | |
14 | | You should have received a copy of the GNU General Public License |
15 | | along with this program; if not, write to the Free Software |
16 | | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA |
17 | | 02110-1301, USA. */ |
18 | | |
19 | | #include "sysdep.h" |
20 | | #include "bfd.h" |
21 | | #include "bucomm.h" |
22 | | |
23 | | static char ftypelet (unsigned long); |
24 | | static void setst (unsigned long, char *); |
25 | | |
26 | | /* filemodestring - fill in string STR with an ls-style ASCII |
27 | | representation of the st_mode field of file stats block STATP. |
28 | | 10 characters are stored in STR; no terminating null is added. |
29 | | The characters stored in STR are: |
30 | | |
31 | | 0 File type. 'd' for directory, 'c' for character |
32 | | special, 'b' for block special, 'm' for multiplex, |
33 | | 'l' for symbolic link, 's' for socket, 'p' for fifo, |
34 | | '-' for any other file type |
35 | | |
36 | | 1 'r' if the owner may read, '-' otherwise. |
37 | | |
38 | | 2 'w' if the owner may write, '-' otherwise. |
39 | | |
40 | | 3 'x' if the owner may execute, 's' if the file is |
41 | | set-user-id, '-' otherwise. |
42 | | 'S' if the file is set-user-id, but the execute |
43 | | bit isn't set. |
44 | | |
45 | | 4 'r' if group members may read, '-' otherwise. |
46 | | |
47 | | 5 'w' if group members may write, '-' otherwise. |
48 | | |
49 | | 6 'x' if group members may execute, 's' if the file is |
50 | | set-group-id, '-' otherwise. |
51 | | 'S' if it is set-group-id but not executable. |
52 | | |
53 | | 7 'r' if any user may read, '-' otherwise. |
54 | | |
55 | | 8 'w' if any user may write, '-' otherwise. |
56 | | |
57 | | 9 'x' if any user may execute, 't' if the file is "sticky" |
58 | | (will be retained in swap space after execution), '-' |
59 | | otherwise. |
60 | | 'T' if the file is sticky but not executable. */ |
61 | | |
62 | | /* Get definitions for the file permission bits. */ |
63 | | |
64 | | #ifndef S_IRWXU |
65 | | #define S_IRWXU 0700 |
66 | | #endif |
67 | | #ifndef S_IRUSR |
68 | | #define S_IRUSR 0400 |
69 | | #endif |
70 | | #ifndef S_IWUSR |
71 | | #define S_IWUSR 0200 |
72 | | #endif |
73 | | #ifndef S_IXUSR |
74 | | #define S_IXUSR 0100 |
75 | | #endif |
76 | | |
77 | | #ifndef S_IRWXG |
78 | | #define S_IRWXG 0070 |
79 | | #endif |
80 | | #ifndef S_IRGRP |
81 | | #define S_IRGRP 0040 |
82 | | #endif |
83 | | #ifndef S_IWGRP |
84 | | #define S_IWGRP 0020 |
85 | | #endif |
86 | | #ifndef S_IXGRP |
87 | | #define S_IXGRP 0010 |
88 | | #endif |
89 | | |
90 | | #ifndef S_IRWXO |
91 | | #define S_IRWXO 0007 |
92 | | #endif |
93 | | #ifndef S_IROTH |
94 | | #define S_IROTH 0004 |
95 | | #endif |
96 | | #ifndef S_IWOTH |
97 | | #define S_IWOTH 0002 |
98 | | #endif |
99 | | #ifndef S_IXOTH |
100 | | #define S_IXOTH 0001 |
101 | | #endif |
102 | | |
103 | | /* Like filemodestring, but only the relevant part of the `struct stat' |
104 | | is given as an argument. */ |
105 | | |
106 | | void |
107 | | mode_string (unsigned long mode, char *str) |
108 | 27 | { |
109 | 27 | str[0] = ftypelet ((unsigned long) mode); |
110 | 27 | str[1] = (mode & S_IRUSR) != 0 ? 'r' : '-'; |
111 | 27 | str[2] = (mode & S_IWUSR) != 0 ? 'w' : '-'; |
112 | 27 | str[3] = (mode & S_IXUSR) != 0 ? 'x' : '-'; |
113 | 27 | str[4] = (mode & S_IRGRP) != 0 ? 'r' : '-'; |
114 | 27 | str[5] = (mode & S_IWGRP) != 0 ? 'w' : '-'; |
115 | 27 | str[6] = (mode & S_IXGRP) != 0 ? 'x' : '-'; |
116 | 27 | str[7] = (mode & S_IROTH) != 0 ? 'r' : '-'; |
117 | 27 | str[8] = (mode & S_IWOTH) != 0 ? 'w' : '-'; |
118 | 27 | str[9] = (mode & S_IXOTH) != 0 ? 'x' : '-'; |
119 | 27 | setst ((unsigned long) mode, str); |
120 | 27 | } |
121 | | |
122 | | /* Return a character indicating the type of file described by |
123 | | file mode BITS: |
124 | | 'd' for directories |
125 | | 'b' for block special files |
126 | | 'c' for character special files |
127 | | 'm' for multiplexer files |
128 | | 'l' for symbolic links |
129 | | 's' for sockets |
130 | | 'p' for fifos |
131 | | '-' for any other file type. */ |
132 | | |
133 | | #ifndef S_ISDIR |
134 | | #ifdef S_IFDIR |
135 | | #define S_ISDIR(i) (((i) & S_IFMT) == S_IFDIR) |
136 | | #else /* ! defined (S_IFDIR) */ |
137 | | #define S_ISDIR(i) (((i) & 0170000) == 040000) |
138 | | #endif /* ! defined (S_IFDIR) */ |
139 | | #endif /* ! defined (S_ISDIR) */ |
140 | | |
141 | | #ifndef S_ISBLK |
142 | | #ifdef S_IFBLK |
143 | | #define S_ISBLK(i) (((i) & S_IFMT) == S_IFBLK) |
144 | | #else /* ! defined (S_IFBLK) */ |
145 | | #define S_ISBLK(i) 0 |
146 | | #endif /* ! defined (S_IFBLK) */ |
147 | | #endif /* ! defined (S_ISBLK) */ |
148 | | |
149 | | #ifndef S_ISCHR |
150 | | #ifdef S_IFCHR |
151 | | #define S_ISCHR(i) (((i) & S_IFMT) == S_IFCHR) |
152 | | #else /* ! defined (S_IFCHR) */ |
153 | | #define S_ISCHR(i) 0 |
154 | | #endif /* ! defined (S_IFCHR) */ |
155 | | #endif /* ! defined (S_ISCHR) */ |
156 | | |
157 | | #ifndef S_ISFIFO |
158 | | #ifdef S_IFIFO |
159 | | #define S_ISFIFO(i) (((i) & S_IFMT) == S_IFIFO) |
160 | | #else /* ! defined (S_IFIFO) */ |
161 | | #define S_ISFIFO(i) 0 |
162 | | #endif /* ! defined (S_IFIFO) */ |
163 | | #endif /* ! defined (S_ISFIFO) */ |
164 | | |
165 | | #ifndef S_ISSOCK |
166 | | #ifdef S_IFSOCK |
167 | | #define S_ISSOCK(i) (((i) & S_IFMT) == S_IFSOCK) |
168 | | #else /* ! defined (S_IFSOCK) */ |
169 | | #define S_ISSOCK(i) 0 |
170 | | #endif /* ! defined (S_IFSOCK) */ |
171 | | #endif /* ! defined (S_ISSOCK) */ |
172 | | |
173 | | #ifndef S_ISLNK |
174 | | #ifdef S_IFLNK |
175 | | #define S_ISLNK(i) (((i) & S_IFMT) == S_IFLNK) |
176 | | #else /* ! defined (S_IFLNK) */ |
177 | | #define S_ISLNK(i) 0 |
178 | | #endif /* ! defined (S_IFLNK) */ |
179 | | #endif /* ! defined (S_ISLNK) */ |
180 | | |
181 | | static char |
182 | | ftypelet (unsigned long bits) |
183 | 27 | { |
184 | 27 | if (S_ISDIR (bits)) |
185 | 0 | return 'd'; |
186 | 27 | if (S_ISLNK (bits)) |
187 | 0 | return 'l'; |
188 | 27 | if (S_ISBLK (bits)) |
189 | 0 | return 'b'; |
190 | 27 | if (S_ISCHR (bits)) |
191 | 0 | return 'c'; |
192 | 27 | if (S_ISSOCK (bits)) |
193 | 0 | return 's'; |
194 | 27 | if (S_ISFIFO (bits)) |
195 | 0 | return 'p'; |
196 | | |
197 | 27 | #ifdef S_IFMT |
198 | | #ifdef S_IFMPC |
199 | | if ((bits & S_IFMT) == S_IFMPC |
200 | | || (bits & S_IFMT) == S_IFMPB) |
201 | | return 'm'; |
202 | | #endif |
203 | | #ifdef S_IFNWK |
204 | | if ((bits & S_IFMT) == S_IFNWK) |
205 | | return 'n'; |
206 | | #endif |
207 | 27 | #endif |
208 | | |
209 | 27 | return '-'; |
210 | 27 | } |
211 | | |
212 | | /* Set the 's' and 't' flags in file attributes string CHARS, |
213 | | according to the file mode BITS. */ |
214 | | |
215 | | static void |
216 | | setst (unsigned long bits ATTRIBUTE_UNUSED, char *chars ATTRIBUTE_UNUSED) |
217 | 27 | { |
218 | 27 | #ifdef S_ISUID |
219 | 27 | if (bits & S_ISUID) |
220 | 0 | { |
221 | 0 | if (chars[3] != 'x') |
222 | | /* Set-uid, but not executable by owner. */ |
223 | 0 | chars[3] = 'S'; |
224 | 0 | else |
225 | 0 | chars[3] = 's'; |
226 | 0 | } |
227 | 27 | #endif |
228 | 27 | #ifdef S_ISGID |
229 | 27 | if (bits & S_ISGID) |
230 | 1 | { |
231 | 1 | if (chars[6] != 'x') |
232 | | /* Set-gid, but not executable by group. */ |
233 | 0 | chars[6] = 'S'; |
234 | 1 | else |
235 | 1 | chars[6] = 's'; |
236 | 1 | } |
237 | 27 | #endif |
238 | 27 | #ifdef S_ISVTX |
239 | 27 | if (bits & S_ISVTX) |
240 | 1 | { |
241 | 1 | if (chars[9] != 'x') |
242 | | /* Sticky, but not executable by others. */ |
243 | 1 | chars[9] = 'T'; |
244 | 0 | else |
245 | 0 | chars[9] = 't'; |
246 | 1 | } |
247 | 27 | #endif |
248 | 27 | } |