.
[coreutils.git] / lib / filemode.c
blob20c65c4b06e239a9640414d6abfaec76d6ff0005
1 /* filemode.c -- make a string describing file modes
2 Copyright (C) 1985, 1990, 1993 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
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
22 #include <sys/types.h>
23 #include <sys/stat.h>
25 #if !S_IRUSR
26 # if S_IREAD
27 # define S_IRUSR S_IREAD
28 # else
29 # define S_IRUSR 00400
30 # endif
31 #endif
33 #if !S_IWUSR
34 # if S_IWRITE
35 # define S_IWUSR S_IWRITE
36 # else
37 # define S_IWUSR 00200
38 # endif
39 #endif
41 #if !S_IXUSR
42 # if S_IEXEC
43 # define S_IXUSR S_IEXEC
44 # else
45 # define S_IXUSR 00100
46 # endif
47 #endif
49 #ifdef STAT_MACROS_BROKEN
50 #undef S_ISBLK
51 #undef S_ISCHR
52 #undef S_ISDIR
53 #undef S_ISFIFO
54 #undef S_ISLNK
55 #undef S_ISMPB
56 #undef S_ISMPC
57 #undef S_ISNWK
58 #undef S_ISREG
59 #undef S_ISSOCK
60 #endif /* STAT_MACROS_BROKEN. */
62 #if !defined(S_ISBLK) && defined(S_IFBLK)
63 #define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
64 #endif
65 #if !defined(S_ISCHR) && defined(S_IFCHR)
66 #define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
67 #endif
68 #if !defined(S_ISDIR) && defined(S_IFDIR)
69 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
70 #endif
71 #if !defined(S_ISREG) && defined(S_IFREG)
72 #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
73 #endif
74 #if !defined(S_ISFIFO) && defined(S_IFIFO)
75 #define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
76 #endif
77 #if !defined(S_ISLNK) && defined(S_IFLNK)
78 #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
79 #endif
80 #if !defined(S_ISSOCK) && defined(S_IFSOCK)
81 #define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
82 #endif
83 #if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */
84 #define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
85 #define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
86 #endif
87 #if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */
88 #define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
89 #endif
91 void mode_string ();
92 static char ftypelet ();
93 static void rwx ();
94 static void setst ();
96 /* filemodestring - fill in string STR with an ls-style ASCII
97 representation of the st_mode field of file stats block STATP.
98 10 characters are stored in STR; no terminating null is added.
99 The characters stored in STR are:
101 0 File type. 'd' for directory, 'c' for character
102 special, 'b' for block special, 'm' for multiplex,
103 'l' for symbolic link, 's' for socket, 'p' for fifo,
104 '-' for regular, '?' for any other file type
106 1 'r' if the owner may read, '-' otherwise.
108 2 'w' if the owner may write, '-' otherwise.
110 3 'x' if the owner may execute, 's' if the file is
111 set-user-id, '-' otherwise.
112 'S' if the file is set-user-id, but the execute
113 bit isn't set.
115 4 'r' if group members may read, '-' otherwise.
117 5 'w' if group members may write, '-' otherwise.
119 6 'x' if group members may execute, 's' if the file is
120 set-group-id, '-' otherwise.
121 'S' if it is set-group-id but not executable.
123 7 'r' if any user may read, '-' otherwise.
125 8 'w' if any user may write, '-' otherwise.
127 9 'x' if any user may execute, 't' if the file is "sticky"
128 (will be retained in swap space after execution), '-'
129 otherwise.
130 'T' if the file is sticky but not executable. */
132 void
133 filemodestring (statp, str)
134 struct stat *statp;
135 char *str;
137 mode_string (statp->st_mode, str);
140 /* Like filemodestring, but only the relevant part of the `struct stat'
141 is given as an argument. */
143 void
144 mode_string (mode, str)
145 unsigned short mode;
146 char *str;
148 str[0] = ftypelet ((long) mode);
149 rwx ((mode & 0700) << 0, &str[1]);
150 rwx ((mode & 0070) << 3, &str[4]);
151 rwx ((mode & 0007) << 6, &str[7]);
152 setst (mode, str);
155 /* Return a character indicating the type of file described by
156 file mode BITS:
157 'd' for directories
158 'b' for block special files
159 'c' for character special files
160 'm' for multiplexor files
161 'l' for symbolic links
162 's' for sockets
163 'p' for fifos
164 '-' for regular files
165 '?' for any other file type. */
167 static char
168 ftypelet (bits)
169 long bits;
171 #ifdef S_ISBLK
172 if (S_ISBLK (bits))
173 return 'b';
174 #endif
175 if (S_ISCHR (bits))
176 return 'c';
177 if (S_ISDIR (bits))
178 return 'd';
179 if (S_ISREG (bits))
180 return '-';
181 #ifdef S_ISFIFO
182 if (S_ISFIFO (bits))
183 return 'p';
184 #endif
185 #ifdef S_ISLNK
186 if (S_ISLNK (bits))
187 return 'l';
188 #endif
189 #ifdef S_ISSOCK
190 if (S_ISSOCK (bits))
191 return 's';
192 #endif
193 #ifdef S_ISMPC
194 if (S_ISMPC (bits))
195 return 'm';
196 #endif
197 #ifdef S_ISNWK
198 if (S_ISNWK (bits))
199 return 'n';
200 #endif
201 return '?';
204 /* Look at read, write, and execute bits in BITS and set
205 flags in CHARS accordingly. */
207 static void
208 rwx (bits, chars)
209 unsigned short bits;
210 char *chars;
212 chars[0] = (bits & S_IRUSR) ? 'r' : '-';
213 chars[1] = (bits & S_IWUSR) ? 'w' : '-';
214 chars[2] = (bits & S_IXUSR) ? 'x' : '-';
217 /* Set the 's' and 't' flags in file attributes string CHARS,
218 according to the file mode BITS. */
220 static void
221 setst (bits, chars)
222 unsigned short bits;
223 char *chars;
225 #ifdef S_ISUID
226 if (bits & S_ISUID)
228 if (chars[3] != 'x')
229 /* Set-uid, but not executable by owner. */
230 chars[3] = 'S';
231 else
232 chars[3] = 's';
234 #endif
235 #ifdef S_ISGID
236 if (bits & S_ISGID)
238 if (chars[6] != 'x')
239 /* Set-gid, but not executable by group. */
240 chars[6] = 'S';
241 else
242 chars[6] = 's';
244 #endif
245 #ifdef S_ISVTX
246 if (bits & S_ISVTX)
248 if (chars[9] != 'x')
249 /* Sticky, but not executable by others. */
250 chars[9] = 'T';
251 else
252 chars[9] = 't';
254 #endif