.
[gnulib.git] / lib / filemode.c
blob5e909dfca422769450ec14a5c3053ff5eadf90ef
1 /* filemode.c -- make a string describing file modes
2 Copyright (C) 1985, 1990, 1993, 1998-2000 Free Software Foundation, Inc.
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 2, or (at your option)
7 any later version.
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.
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 Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 #if HAVE_CONFIG_H
19 # include <config.h>
20 #endif
22 #include <sys/types.h>
23 #include <sys/stat.h>
25 #include "filemode.h"
27 #if !S_IRUSR
28 # if S_IREAD
29 # define S_IRUSR S_IREAD
30 # else
31 # define S_IRUSR 00400
32 # endif
33 #endif
35 #if !S_IWUSR
36 # if S_IWRITE
37 # define S_IWUSR S_IWRITE
38 # else
39 # define S_IWUSR 00200
40 # endif
41 #endif
43 #if !S_IXUSR
44 # if S_IEXEC
45 # define S_IXUSR S_IEXEC
46 # else
47 # define S_IXUSR 00100
48 # endif
49 #endif
51 #if !S_IRGRP
52 # define S_IRGRP (S_IRUSR >> 3)
53 #endif
54 #if !S_IWGRP
55 # define S_IWGRP (S_IWUSR >> 3)
56 #endif
57 #if !S_IXGRP
58 # define S_IXGRP (S_IXUSR >> 3)
59 #endif
60 #if !S_IROTH
61 # define S_IROTH (S_IRUSR >> 6)
62 #endif
63 #if !S_IWOTH
64 # define S_IWOTH (S_IWUSR >> 6)
65 #endif
66 #if !S_IXOTH
67 # define S_IXOTH (S_IXUSR >> 6)
68 #endif
70 #ifdef STAT_MACROS_BROKEN
71 # undef S_ISBLK
72 # undef S_ISCHR
73 # undef S_ISDIR
74 # undef S_ISFIFO
75 # undef S_ISLNK
76 # undef S_ISMPB
77 # undef S_ISMPC
78 # undef S_ISNWK
79 # undef S_ISREG
80 # undef S_ISSOCK
81 #endif /* STAT_MACROS_BROKEN. */
83 #if !defined S_ISBLK && defined S_IFBLK
84 # define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
85 #endif
86 #if !defined S_ISCHR && defined S_IFCHR
87 # define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
88 #endif
89 #if !defined S_ISDIR && defined S_IFDIR
90 # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
91 #endif
92 #if !defined S_ISREG && defined S_IFREG
93 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
94 #endif
95 #if !defined S_ISFIFO && defined S_IFIFO
96 # define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
97 #endif
98 #if !defined S_ISLNK && defined S_IFLNK
99 # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
100 #endif
101 #if !defined S_ISSOCK && defined S_IFSOCK
102 # define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
103 #endif
104 #if !defined S_ISMPB && defined S_IFMPB /* V7 */
105 # define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
106 # define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
107 #endif
108 #if !defined S_ISNWK && defined S_IFNWK /* HP/UX */
109 # define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
110 #endif
111 #if !defined S_ISDOOR && defined S_IFDOOR /* Solaris 2.5 and up */
112 # define S_ISDOOR(m) (((m) & S_IFMT) == S_IFDOOR)
113 #endif
114 #if !defined S_ISCTG && defined S_IFCTG /* MassComp */
115 # define S_ISCTG(m) (((m) & S_IFMT) == S_IFCTG)
116 #endif
120 /* Set the 's' and 't' flags in file attributes string CHARS,
121 according to the file mode BITS. */
123 static void
124 setst (mode_t bits, char *chars)
126 #ifdef S_ISUID
127 if (bits & S_ISUID)
129 if (chars[3] != 'x')
130 /* Set-uid, but not executable by owner. */
131 chars[3] = 'S';
132 else
133 chars[3] = 's';
135 #endif
136 #ifdef S_ISGID
137 if (bits & S_ISGID)
139 if (chars[6] != 'x')
140 /* Set-gid, but not executable by group. */
141 chars[6] = 'S';
142 else
143 chars[6] = 's';
145 #endif
146 #ifdef S_ISVTX
147 if (bits & S_ISVTX)
149 if (chars[9] != 'x')
150 /* Sticky, but not executable by others. */
151 chars[9] = 'T';
152 else
153 chars[9] = 't';
155 #endif
158 /* Return a character indicating the type of file described by
159 file mode BITS:
160 'd' for directories
161 'D' for doors
162 'b' for block special files
163 'c' for character special files
164 'n' for network special files
165 'm' for multiplexor files
166 'M' for an off-line (regular) file
167 'l' for symbolic links
168 's' for sockets
169 'p' for fifos
170 'C' for contigous data files
171 '-' for regular files
172 '?' for any other file type. */
174 static char
175 ftypelet (mode_t bits)
177 #ifdef S_ISBLK
178 if (S_ISBLK (bits))
179 return 'b';
180 #endif
181 if (S_ISCHR (bits))
182 return 'c';
183 if (S_ISDIR (bits))
184 return 'd';
185 if (S_ISREG (bits))
186 return '-';
187 #ifdef S_ISFIFO
188 if (S_ISFIFO (bits))
189 return 'p';
190 #endif
191 #ifdef S_ISLNK
192 if (S_ISLNK (bits))
193 return 'l';
194 #endif
195 #ifdef S_ISSOCK
196 if (S_ISSOCK (bits))
197 return 's';
198 #endif
199 #ifdef S_ISMPC
200 if (S_ISMPC (bits))
201 return 'm';
202 #endif
203 #ifdef S_ISNWK
204 if (S_ISNWK (bits))
205 return 'n';
206 #endif
207 #ifdef S_ISDOOR
208 if (S_ISDOOR (bits))
209 return 'D';
210 #endif
211 #ifdef S_ISCTG
212 if (S_ISCTG (bits))
213 return 'C';
214 #endif
216 /* The following two tests are for Cray DMF (Data Migration
217 Facility), which is a HSM file system. A migrated file has a
218 `st_dm_mode' that is different from the normal `st_mode', so any
219 tests for migrated files should use the former. */
221 #ifdef S_ISOFD
222 if (S_ISOFD (bits))
223 /* off line, with data */
224 return 'M';
225 #endif
226 #ifdef S_ISOFL
227 /* off line, with no data */
228 if (S_ISOFL (bits))
229 return 'M';
230 #endif
231 return '?';
234 /* Like filemodestring, but only the relevant part of the `struct stat'
235 is given as an argument. */
237 void
238 mode_string (mode_t mode, char *str)
240 str[0] = ftypelet (mode);
241 str[1] = mode & S_IRUSR ? 'r' : '-';
242 str[2] = mode & S_IWUSR ? 'w' : '-';
243 str[3] = mode & S_IXUSR ? 'x' : '-';
244 str[4] = mode & S_IRGRP ? 'r' : '-';
245 str[5] = mode & S_IWGRP ? 'w' : '-';
246 str[6] = mode & S_IXGRP ? 'x' : '-';
247 str[7] = mode & S_IROTH ? 'r' : '-';
248 str[8] = mode & S_IWOTH ? 'w' : '-';
249 str[9] = mode & S_IXOTH ? 'x' : '-';
250 setst (mode, str);
253 /* filemodestring - fill in string STR with an ls-style ASCII
254 representation of the st_mode field of file stats block STATP.
255 10 characters are stored in STR; no terminating null is added.
256 The characters stored in STR are:
258 0 File type. 'd' for directory, 'c' for character
259 special, 'b' for block special, 'm' for multiplex,
260 'l' for symbolic link, 's' for socket, 'p' for fifo,
261 '-' for regular, '?' for any other file type
263 1 'r' if the owner may read, '-' otherwise.
265 2 'w' if the owner may write, '-' otherwise.
267 3 'x' if the owner may execute, 's' if the file is
268 set-user-id, '-' otherwise.
269 'S' if the file is set-user-id, but the execute
270 bit isn't set.
272 4 'r' if group members may read, '-' otherwise.
274 5 'w' if group members may write, '-' otherwise.
276 6 'x' if group members may execute, 's' if the file is
277 set-group-id, '-' otherwise.
278 'S' if it is set-group-id but not executable.
280 7 'r' if any user may read, '-' otherwise.
282 8 'w' if any user may write, '-' otherwise.
284 9 'x' if any user may execute, 't' if the file is "sticky"
285 (will be retained in swap space after execution), '-'
286 otherwise.
287 'T' if the file is sticky but not executable. */
289 void
290 filemodestring (struct stat *statp, char *str)
292 mode_string (statp->st_mode, str);