(kill-comment): Fixed by rewriting it with syntax-tables rather than regexps
[emacs.git] / src / filemode.c
blobd804e94d73c632f36c593bfd3d6def088f31f2d9
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 USA. */
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
23 #include <sys/types.h>
24 #include <sys/stat.h>
26 #if !S_IRUSR
27 # if S_IREAD
28 # define S_IRUSR S_IREAD
29 # else
30 # define S_IRUSR 00400
31 # endif
32 #endif
34 #if !S_IWUSR
35 # if S_IWRITE
36 # define S_IWUSR S_IWRITE
37 # else
38 # define S_IWUSR 00200
39 # endif
40 #endif
42 #if !S_IXUSR
43 # if S_IEXEC
44 # define S_IXUSR S_IEXEC
45 # else
46 # define S_IXUSR 00100
47 # endif
48 #endif
50 #ifdef STAT_MACROS_BROKEN
51 #undef S_ISBLK
52 #undef S_ISCHR
53 #undef S_ISDIR
54 #undef S_ISFIFO
55 #undef S_ISLNK
56 #undef S_ISMPB
57 #undef S_ISMPC
58 #undef S_ISNWK
59 #undef S_ISREG
60 #undef S_ISSOCK
61 #endif /* STAT_MACROS_BROKEN. */
63 #if !defined(S_ISBLK) && defined(S_IFBLK)
64 #define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
65 #endif
66 #if !defined(S_ISCHR) && defined(S_IFCHR)
67 #define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
68 #endif
69 #if !defined(S_ISDIR) && defined(S_IFDIR)
70 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
71 #endif
72 #if !defined(S_ISREG) && defined(S_IFREG)
73 #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
74 #endif
75 #if !defined(S_ISFIFO) && defined(S_IFIFO)
76 #define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
77 #endif
78 #if !defined(S_ISLNK) && defined(S_IFLNK)
79 #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
80 #endif
81 #if !defined(S_ISSOCK) && defined(S_IFSOCK)
82 #define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
83 #endif
84 #if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */
85 #define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
86 #define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
87 #endif
88 #if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */
89 #define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
90 #endif
92 void mode_string ();
93 static char ftypelet ();
94 static void rwx ();
95 static void setst ();
97 /* filemodestring - fill in string STR with an ls-style ASCII
98 representation of the st_mode field of file stats block STATP.
99 10 characters are stored in STR; no terminating null is added.
100 The characters stored in STR are:
102 0 File type. 'd' for directory, 'c' for character
103 special, 'b' for block special, 'm' for multiplex,
104 'l' for symbolic link, 's' for socket, 'p' for fifo,
105 '-' for regular, '?' for any other file type
107 1 'r' if the owner may read, '-' otherwise.
109 2 'w' if the owner may write, '-' otherwise.
111 3 'x' if the owner may execute, 's' if the file is
112 set-user-id, '-' otherwise.
113 'S' if the file is set-user-id, but the execute
114 bit isn't set.
116 4 'r' if group members may read, '-' otherwise.
118 5 'w' if group members may write, '-' otherwise.
120 6 'x' if group members may execute, 's' if the file is
121 set-group-id, '-' otherwise.
122 'S' if it is set-group-id but not executable.
124 7 'r' if any user may read, '-' otherwise.
126 8 'w' if any user may write, '-' otherwise.
128 9 'x' if any user may execute, 't' if the file is "sticky"
129 (will be retained in swap space after execution), '-'
130 otherwise.
131 'T' if the file is sticky but not executable. */
133 void
134 filemodestring (statp, str)
135 struct stat *statp;
136 char *str;
138 mode_string (statp->st_mode, str);
141 /* Like filemodestring, but only the relevant part of the `struct stat'
142 is given as an argument. */
144 void
145 mode_string (mode, str)
146 unsigned short mode;
147 char *str;
149 str[0] = ftypelet ((long) mode);
150 rwx ((mode & 0700) << 0, &str[1]);
151 rwx ((mode & 0070) << 3, &str[4]);
152 rwx ((mode & 0007) << 6, &str[7]);
153 setst (mode, str);
156 /* Return a character indicating the type of file described by
157 file mode BITS:
158 'd' for directories
159 'b' for block special files
160 'c' for character special files
161 'm' for multiplexor files
162 'l' for symbolic links
163 's' for sockets
164 'p' for fifos
165 '-' for regular files
166 '?' for any other file type. */
168 static char
169 ftypelet (bits)
170 long bits;
172 #ifdef S_ISBLK
173 if (S_ISBLK (bits))
174 return 'b';
175 #endif
176 if (S_ISCHR (bits))
177 return 'c';
178 if (S_ISDIR (bits))
179 return 'd';
180 if (S_ISREG (bits))
181 return '-';
182 #ifdef S_ISFIFO
183 if (S_ISFIFO (bits))
184 return 'p';
185 #endif
186 #ifdef S_ISLNK
187 if (S_ISLNK (bits))
188 return 'l';
189 #endif
190 #ifdef S_ISSOCK
191 if (S_ISSOCK (bits))
192 return 's';
193 #endif
194 #ifdef S_ISMPC
195 if (S_ISMPC (bits))
196 return 'm';
197 #endif
198 #ifdef S_ISNWK
199 if (S_ISNWK (bits))
200 return 'n';
201 #endif
202 return '?';
205 /* Look at read, write, and execute bits in BITS and set
206 flags in CHARS accordingly. */
208 static void
209 rwx (bits, chars)
210 unsigned short bits;
211 char *chars;
213 chars[0] = (bits & S_IRUSR) ? 'r' : '-';
214 chars[1] = (bits & S_IWUSR) ? 'w' : '-';
215 chars[2] = (bits & S_IXUSR) ? 'x' : '-';
218 /* Set the 's' and 't' flags in file attributes string CHARS,
219 according to the file mode BITS. */
221 static void
222 setst (bits, chars)
223 unsigned short bits;
224 char *chars;
226 #ifdef S_ISUID
227 if (bits & S_ISUID)
229 if (chars[3] != 'x')
230 /* Set-uid, but not executable by owner. */
231 chars[3] = 'S';
232 else
233 chars[3] = 's';
235 #endif
236 #ifdef S_ISGID
237 if (bits & S_ISGID)
239 if (chars[6] != 'x')
240 /* Set-gid, but not executable by group. */
241 chars[6] = 'S';
242 else
243 chars[6] = 's';
245 #endif
246 #ifdef S_ISVTX
247 if (bits & S_ISVTX)
249 if (chars[9] != 'x')
250 /* Sticky, but not executable by others. */
251 chars[9] = 'T';
252 else
253 chars[9] = 't';
255 #endif