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