.
[coreutils.git] / lib / filemode.c
blob91373de34bd513e8e2c57394edf087105588cec3
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 Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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
202 #ifdef S_ISOFD
203 /* Cray migrated dmf file. */
204 if (S_ISOFD (bits))
205 return 'M';
206 #endif
207 #ifdef S_ISOFL
208 /* Cray migrated dmf file. */
209 if (S_ISOFL (bits))
210 return 'M';
211 #endif
212 return '?';
215 /* Look at read, write, and execute bits in BITS and set
216 flags in CHARS accordingly. */
218 static void
219 rwx (bits, chars)
220 unsigned short bits;
221 char *chars;
223 chars[0] = (bits & S_IRUSR) ? 'r' : '-';
224 chars[1] = (bits & S_IWUSR) ? 'w' : '-';
225 chars[2] = (bits & S_IXUSR) ? 'x' : '-';
228 /* Set the 's' and 't' flags in file attributes string CHARS,
229 according to the file mode BITS. */
231 static void
232 setst (bits, chars)
233 unsigned short bits;
234 char *chars;
236 #ifdef S_ISUID
237 if (bits & S_ISUID)
239 if (chars[3] != 'x')
240 /* Set-uid, but not executable by owner. */
241 chars[3] = 'S';
242 else
243 chars[3] = 's';
245 #endif
246 #ifdef S_ISGID
247 if (bits & S_ISGID)
249 if (chars[6] != 'x')
250 /* Set-gid, but not executable by group. */
251 chars[6] = 'S';
252 else
253 chars[6] = 's';
255 #endif
256 #ifdef S_ISVTX
257 if (bits & S_ISVTX)
259 if (chars[9] != 'x')
260 /* Sticky, but not executable by others. */
261 chars[9] = 'T';
262 else
263 chars[9] = 't';
265 #endif