This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / binutils / filemode.c
1 /* filemode.c -- make a string describing file modes
2    Copyright (C) 1985, 1990 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 1, 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 #include <sys/types.h>
19 #include <sys/stat.h>
20
21 void mode_string ();
22 static char ftypelet ();
23 static void rwx ();
24 static void setst ();
25
26 /* filemodestring - fill in string STR with an ls-style ASCII
27    representation of the st_mode field of file stats block STATP.
28    10 characters are stored in STR; no terminating null is added.
29    The characters stored in STR are:
30
31    0    File type.  'd' for directory, 'c' for character
32         special, 'b' for block special, 'm' for multiplex,
33         'l' for symbolic link, 's' for socket, 'p' for fifo,
34         '-' for any other file type
35
36    1    'r' if the owner may read, '-' otherwise.
37
38    2    'w' if the owner may write, '-' otherwise.
39
40    3    'x' if the owner may execute, 's' if the file is
41         set-user-id, '-' otherwise.
42         'S' if the file is set-user-id, but the execute
43         bit isn't set.
44
45    4    'r' if group members may read, '-' otherwise.
46
47    5    'w' if group members may write, '-' otherwise.
48
49    6    'x' if group members may execute, 's' if the file is
50         set-group-id, '-' otherwise.
51         'S' if it is set-group-id but not executable.
52
53    7    'r' if any user may read, '-' otherwise.
54
55    8    'w' if any user may write, '-' otherwise.
56
57    9    'x' if any user may execute, 't' if the file is "sticky"
58         (will be retained in swap space after execution), '-'
59         otherwise.
60         'T' if the file is sticky but not executable. */
61
62 void
63 filemodestring (statp, str)
64      struct stat *statp;
65      char *str;
66 {
67   mode_string (statp->st_mode, str);
68 }
69
70 /* Like filemodestring, but only the relevant part of the `struct stat'
71    is given as an argument. */
72
73 void
74 mode_string (mode, str)
75      unsigned short mode;
76      char *str;
77 {
78   str[0] = ftypelet (mode);
79   rwx ((mode & 0700) << 0, &str[1]);
80   rwx ((mode & 0070) << 3, &str[4]);
81   rwx ((mode & 0007) << 6, &str[7]);
82   setst (mode, str);
83 }
84
85 /* Return a character indicating the type of file described by
86    file mode BITS:
87    'd' for directories
88    'b' for block special files
89    'c' for character special files
90    'm' for multiplexor files
91    'l' for symbolic links
92    's' for sockets
93    'p' for fifos
94    '-' for any other file type. */
95
96 static char
97 ftypelet (bits)
98      unsigned short bits;
99 {
100   switch (bits & S_IFMT)
101     {
102     default:
103       return '-';
104     case S_IFDIR:
105       return 'd';
106 #ifdef S_IFLNK
107     case S_IFLNK:
108       return 'l';
109 #endif
110 #ifdef S_IFCHR
111     case S_IFCHR:
112       return 'c';
113 #endif
114 #ifdef S_IFBLK
115     case S_IFBLK:
116       return 'b';
117 #endif
118 #ifdef S_IFMPC
119     case S_IFMPC:
120     case S_IFMPB:
121       return 'm';
122 #endif
123 #ifdef S_IFSOCK
124     case S_IFSOCK:
125       return 's';
126 #endif
127 #ifdef S_IFIFO
128 #if S_IFIFO != S_IFSOCK
129     case S_IFIFO:
130       return 'p';
131 #endif
132 #endif
133 #ifdef S_IFNWK                  /* HP-UX */
134     case S_IFNWK:
135       return 'n';
136 #endif
137     }
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 (bits, chars)
145      unsigned short bits;
146      char *chars;
147 {
148   chars[0] = (bits & S_IREAD) ? 'r' : '-';
149   chars[1] = (bits & S_IWRITE) ? 'w' : '-';
150   chars[2] = (bits & S_IEXEC) ? 'x' : '-';
151 }
152
153 /* Set the 's' and 't' flags in file attributes string CHARS,
154    according to the file mode BITS. */
155
156 static void
157 setst (bits, chars)
158      unsigned short bits;
159      char *chars;
160 {
161 #ifdef S_ISUID
162   if (bits & S_ISUID)
163     {
164       if (chars[3] != 'x')
165         /* Set-uid, but not executable by owner. */
166         chars[3] = 'S';
167       else
168         chars[3] = 's';
169     }
170 #endif
171 #ifdef S_ISGID
172   if (bits & S_ISGID)
173     {
174       if (chars[6] != 'x')
175         /* Set-gid, but not executable by group. */
176         chars[6] = 'S';
177       else
178         chars[6] = 's';
179     }
180 #endif
181 #ifdef S_ISVTX
182   if (bits & S_ISVTX)
183     {
184       if (chars[9] != 'x')
185         /* Sticky, but not executable by others. */
186         chars[9] = 'T';
187       else
188         chars[9] = 't';
189     }
190 #endif
191 }
192
193