upgraded distribution
[findutils.git] / lib / filemode.c
blobc86ee2ff521b2f13cc0ee9880be0fb514b7f6160
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 #ifndef S_IREAD
26 #define S_IREAD S_IRUSR
27 #define S_IWRITE S_IWUSR
28 #define S_IEXEC S_IXUSR
29 #endif
31 #ifdef STAT_MACROS_BROKEN
32 #undef S_ISBLK
33 #undef S_ISCHR
34 #undef S_ISDIR
35 #undef S_ISFIFO
36 #undef S_ISLNK
37 #undef S_ISMPB
38 #undef S_ISMPC
39 #undef S_ISNWK
40 #undef S_ISREG
41 #undef S_ISSOCK
42 #endif /* STAT_MACROS_BROKEN. */
44 #if !defined(S_ISBLK) && defined(S_IFBLK)
45 #define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
46 #endif
47 #if !defined(S_ISCHR) && defined(S_IFCHR)
48 #define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
49 #endif
50 #if !defined(S_ISDIR) && defined(S_IFDIR)
51 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
52 #endif
53 #if !defined(S_ISREG) && defined(S_IFREG)
54 #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
55 #endif
56 #if !defined(S_ISFIFO) && defined(S_IFIFO)
57 #define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
58 #endif
59 #if !defined(S_ISLNK) && defined(S_IFLNK)
60 #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
61 #endif
62 #if !defined(S_ISSOCK) && defined(S_IFSOCK)
63 #define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
64 #endif
65 #if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */
66 #define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
67 #define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
68 #endif
69 #if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */
70 #define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
71 #endif
73 void mode_string ();
74 static char ftypelet ();
75 static void rwx ();
76 static void setst ();
78 /* filemodestring - fill in string STR with an ls-style ASCII
79 representation of the st_mode field of file stats block STATP.
80 10 characters are stored in STR; no terminating null is added.
81 The characters stored in STR are:
83 0 File type. 'd' for directory, 'c' for character
84 special, 'b' for block special, 'm' for multiplex,
85 'l' for symbolic link, 's' for socket, 'p' for fifo,
86 '-' for regular, '?' for any other file type
88 1 'r' if the owner may read, '-' otherwise.
90 2 'w' if the owner may write, '-' otherwise.
92 3 'x' if the owner may execute, 's' if the file is
93 set-user-id, '-' otherwise.
94 'S' if the file is set-user-id, but the execute
95 bit isn't set.
97 4 'r' if group members may read, '-' otherwise.
99 5 'w' if group members may write, '-' otherwise.
101 6 'x' if group members may execute, 's' if the file is
102 set-group-id, '-' otherwise.
103 'S' if it is set-group-id but not executable.
105 7 'r' if any user may read, '-' otherwise.
107 8 'w' if any user may write, '-' otherwise.
109 9 'x' if any user may execute, 't' if the file is "sticky"
110 (will be retained in swap space after execution), '-'
111 otherwise.
112 'T' if the file is sticky but not executable. */
114 void
115 filemodestring (statp, str)
116 struct stat *statp;
117 char *str;
119 mode_string (statp->st_mode, str);
122 /* Like filemodestring, but only the relevant part of the `struct stat'
123 is given as an argument. */
125 void
126 mode_string (mode, str)
127 unsigned short mode;
128 char *str;
130 str[0] = ftypelet ((long) mode);
131 rwx ((mode & 0700) << 0, &str[1]);
132 rwx ((mode & 0070) << 3, &str[4]);
133 rwx ((mode & 0007) << 6, &str[7]);
134 setst (mode, str);
137 /* Return a character indicating the type of file described by
138 file mode BITS:
139 'd' for directories
140 'b' for block special files
141 'c' for character special files
142 'm' for multiplexor files
143 'l' for symbolic links
144 's' for sockets
145 'p' for fifos
146 '-' for regular files
147 '?' for any other file type. */
149 static char
150 ftypelet (bits)
151 long bits;
153 #ifdef S_ISBLK
154 if (S_ISBLK (bits))
155 return 'b';
156 #endif
157 if (S_ISCHR (bits))
158 return 'c';
159 if (S_ISDIR (bits))
160 return 'd';
161 if (S_ISREG (bits))
162 return '-';
163 #ifdef S_ISFIFO
164 if (S_ISFIFO (bits))
165 return 'p';
166 #endif
167 #ifdef S_ISLNK
168 if (S_ISLNK (bits))
169 return 'l';
170 #endif
171 #ifdef S_ISSOCK
172 if (S_ISSOCK (bits))
173 return 's';
174 #endif
175 #ifdef S_ISMPC
176 if (S_ISMPC (bits))
177 return 'm';
178 #endif
179 #ifdef S_ISNWK
180 if (S_ISNWK (bits))
181 return 'n';
182 #endif
183 return '?';
186 /* Look at read, write, and execute bits in BITS and set
187 flags in CHARS accordingly. */
189 static void
190 rwx (bits, chars)
191 unsigned short bits;
192 char *chars;
194 chars[0] = (bits & S_IREAD) ? 'r' : '-';
195 chars[1] = (bits & S_IWRITE) ? 'w' : '-';
196 chars[2] = (bits & S_IEXEC) ? 'x' : '-';
199 /* Set the 's' and 't' flags in file attributes string CHARS,
200 according to the file mode BITS. */
202 static void
203 setst (bits, chars)
204 unsigned short bits;
205 char *chars;
207 #ifdef S_ISUID
208 if (bits & S_ISUID)
210 if (chars[3] != 'x')
211 /* Set-uid, but not executable by owner. */
212 chars[3] = 'S';
213 else
214 chars[3] = 's';
216 #endif
217 #ifdef S_ISGID
218 if (bits & S_ISGID)
220 if (chars[6] != 'x')
221 /* Set-gid, but not executable by group. */
222 chars[6] = 'S';
223 else
224 chars[6] = 's';
226 #endif
227 #ifdef S_ISVTX
228 if (bits & S_ISVTX)
230 if (chars[9] != 'x')
231 /* Sticky, but not executable by others. */
232 chars[9] = 'T';
233 else
234 chars[9] = 't';
236 #endif