]> CyberLeo.Net >> Repos - FreeBSD/releng/8.0.git/blob - contrib/cpio/src/filemode.c
Adjust to reflect 8.0-RELEASE.
[FreeBSD/releng/8.0.git] / contrib / cpio / src / filemode.c
1 /* filemode.c -- make a string describing file modes
2    Copyright (C) 1985, 1990, 1993, 2004 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
15    License along with this program; if not, write to the Free
16    Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17    Boston, MA 02110-1301 USA.  */
18 \f
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #include <sys/types.h>
24 #include <sys/stat.h>
25
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
33
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
41
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
49
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.  */
62
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
91
92 /* Return a character indicating the type of file described by
93    file mode BITS:
94    'd' for directories
95    'b' for block special files
96    'c' for character special files
97    'm' for multiplexor files
98    'l' for symbolic links
99    's' for sockets
100    'p' for fifos
101    '-' for regular files
102    '?' for any other file type.  */
103
104 static char
105 ftypelet (long bits)
106 {
107 #ifdef S_ISBLK
108   if (S_ISBLK (bits))
109     return 'b';
110 #endif
111   if (S_ISCHR (bits))
112     return 'c';
113   if (S_ISDIR (bits))
114     return 'd';
115   if (S_ISREG (bits))
116     return '-';
117 #ifdef S_ISFIFO
118   if (S_ISFIFO (bits))
119     return 'p';
120 #endif
121 #ifdef S_ISLNK
122   if (S_ISLNK (bits))
123     return 'l';
124 #endif
125 #ifdef S_ISSOCK
126   if (S_ISSOCK (bits))
127     return 's';
128 #endif
129 #ifdef S_ISMPC
130   if (S_ISMPC (bits))
131     return 'm';
132 #endif
133 #ifdef S_ISNWK
134   if (S_ISNWK (bits))
135     return 'n';
136 #endif
137   return '?';
138 }
139
140 /* Look at read, write, and execute bits in BITS and set
141    flags in CHARS accordingly.  */
142
143 static void
144 rwx (unsigned short bits, char *chars)
145 {
146   chars[0] = (bits & S_IRUSR) ? 'r' : '-';
147   chars[1] = (bits & S_IWUSR) ? 'w' : '-';
148   chars[2] = (bits & S_IXUSR) ? 'x' : '-';
149 }
150
151 /* Set the 's' and 't' flags in file attributes string CHARS,
152    according to the file mode BITS.  */
153
154 static void
155 setst (unsigned short bits, char *chars)
156 {
157 #ifdef S_ISUID
158   if (bits & S_ISUID)
159     {
160       if (chars[3] != 'x')
161         /* Set-uid, but not executable by owner.  */
162         chars[3] = 'S';
163       else
164         chars[3] = 's';
165     }
166 #endif
167 #ifdef S_ISGID
168   if (bits & S_ISGID)
169     {
170       if (chars[6] != 'x')
171         /* Set-gid, but not executable by group.  */
172         chars[6] = 'S';
173       else
174         chars[6] = 's';
175     }
176 #endif
177 #ifdef S_ISVTX
178   if (bits & S_ISVTX)
179     {
180       if (chars[9] != 'x')
181         /* Sticky, but not executable by others.  */
182         chars[9] = 'T';
183       else
184         chars[9] = 't';
185     }
186 #endif
187 }
188
189 /* Like filemodestring (see below), but only the relevant part of the
190    `struct stat' is given as an argument.  */
191
192 void
193 mode_string (unsigned short mode, char *str)
194 {
195   str[0] = ftypelet ((long) mode);
196   rwx ((mode & 0700) << 0, &str[1]);
197   rwx ((mode & 0070) << 3, &str[4]);
198   rwx ((mode & 0007) << 6, &str[7]);
199   setst (mode, str);
200 }
201
202 /* filemodestring - fill in string STR with an ls-style ASCII
203    representation of the st_mode field of file stats block STATP.
204    10 characters are stored in STR; no terminating null is added.
205    The characters stored in STR are:
206
207    0    File type.  'd' for directory, 'c' for character
208         special, 'b' for block special, 'm' for multiplex,
209         'l' for symbolic link, 's' for socket, 'p' for fifo,
210         '-' for regular, '?' for any other file type
211
212    1    'r' if the owner may read, '-' otherwise.
213
214    2    'w' if the owner may write, '-' otherwise.
215
216    3    'x' if the owner may execute, 's' if the file is
217         set-user-id, '-' otherwise.
218         'S' if the file is set-user-id, but the execute
219         bit isn't set.
220
221    4    'r' if group members may read, '-' otherwise.
222
223    5    'w' if group members may write, '-' otherwise.
224
225    6    'x' if group members may execute, 's' if the file is
226         set-group-id, '-' otherwise.
227         'S' if it is set-group-id but not executable.
228
229    7    'r' if any user may read, '-' otherwise.
230
231    8    'w' if any user may write, '-' otherwise.
232
233    9    'x' if any user may execute, 't' if the file is "sticky"
234         (will be retained in swap space after execution), '-'
235         otherwise.
236         'T' if the file is sticky but not executable.  */
237
238 void
239 filemodestring (struct stat *statp, char *str)
240 {
241   mode_string (statp->st_mode, str);
242 }
243