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