Use `C' to denote so-called `contiguous' files, the same way that tar does.
[gnulib.git] / lib / filemode.c
1 /* filemode.c -- make a string describing file modes
2    Copyright (C) 1985, 1990, 1993, 1998-2000 Free Software Foundation, Inc.
3
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.
8
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.
13
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.  */
17
18 #if HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <sys/types.h>
23 #include <sys/stat.h>
24
25 #include "filemode.h"
26
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
34
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
42
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
50
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
69
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.  */
82
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
117
118
119
120 /* Set the 's' and 't' flags in file attributes string CHARS,
121    according to the file mode BITS.  */
122
123 static void
124 setst (mode_t bits, char *chars)
125 {
126 #ifdef S_ISUID
127   if (bits & S_ISUID)
128     {
129       if (chars[3] != 'x')
130         /* Set-uid, but not executable by owner.  */
131         chars[3] = 'S';
132       else
133         chars[3] = 's';
134     }
135 #endif
136 #ifdef S_ISGID
137   if (bits & S_ISGID)
138     {
139       if (chars[6] != 'x')
140         /* Set-gid, but not executable by group.  */
141         chars[6] = 'S';
142       else
143         chars[6] = 's';
144     }
145 #endif
146 #ifdef S_ISVTX
147   if (bits & S_ISVTX)
148     {
149       if (chars[9] != 'x')
150         /* Sticky, but not executable by others.  */
151         chars[9] = 'T';
152       else
153         chars[9] = 't';
154     }
155 #endif
156 }
157
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.  */
173
174 static char
175 ftypelet (mode_t bits)
176 {
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
215
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.  */
220
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 '?';
232 }
233
234 /* Like filemodestring, but only the relevant part of the `struct stat'
235    is given as an argument.  */
236
237 void
238 mode_string (mode_t mode, char *str)
239 {
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);
251 }
252
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:
257
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
262
263    1    'r' if the owner may read, '-' otherwise.
264
265    2    'w' if the owner may write, '-' otherwise.
266
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.
271
272    4    'r' if group members may read, '-' otherwise.
273
274    5    'w' if group members may write, '-' otherwise.
275
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.
279
280    7    'r' if any user may read, '-' otherwise.
281
282    8    'w' if any user may write, '-' otherwise.
283
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.  */
288
289 void
290 filemodestring (struct stat *statp, char *str)
291 {
292   mode_string (statp->st_mode, str);
293 }