Merge from coreutils.
[gnulib.git] / lib / filemode.c
1 /* filemode.c -- make a string describing file modes
2
3    Copyright (C) 1985, 1990, 1993, 1998-2000, 2004, 2006 Free Software
4    Foundation, Inc.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2, or (at your option)
9    any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software Foundation,
18    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
19
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23
24 #include "filemode.h"
25
26 #include "stat-macros.h"
27
28 /* The following is for Cray DMF (Data Migration Facility), which is a
29    HSM file system.  A migrated file has a `st_dm_mode' that is
30    different from the normal `st_mode', so any tests for migrated
31    files should use the former.  */
32 #if HAVE_ST_DM_MODE
33 # define IS_MIGRATED_FILE(statp) \
34     (S_ISOFD (statp->st_dm_mode) || S_ISOFL (statp->st_dm_mode))
35 #else
36 # define IS_MIGRATED_FILE(statp) 0
37 #endif
38
39 #if ! HAVE_DECL_STRMODE
40
41 /* Return a character indicating the type of file described by
42    file mode BITS:
43    '-' regular file
44    'b' block special file
45    'c' character special file
46    'C' high performance ("contiguous data") file
47    'd' directory
48    'D' door
49    'l' symbolic link
50    'm' multiplexed file (7th edition Unix; obsolete)
51    'n' network special file (HP-UX)
52    'p' fifo (named pipe)
53    'P' port
54    's' socket
55    'w' whiteout (4.4BSD)
56    '?' some other file type  */
57
58 static char
59 ftypelet (mode_t bits)
60 {
61   /* These are the most common, so test for them first.  */
62   if (S_ISREG (bits))
63     return '-';
64   if (S_ISDIR (bits))
65     return 'd';
66
67   /* Other letters standardized by POSIX 1003.1-2004.  */
68   if (S_ISBLK (bits))
69     return 'b';
70   if (S_ISCHR (bits))
71     return 'c';
72   if (S_ISLNK (bits))
73     return 'l';
74   if (S_ISFIFO (bits))
75     return 'p';
76
77   /* Other file types (though not letters) standardized by POSIX.  */
78   if (S_ISSOCK (bits))
79     return 's';
80
81   /* Nonstandard file types.  */
82   if (S_ISCTG (bits))
83     return 'C';
84   if (S_ISDOOR (bits))
85     return 'D';
86   if (S_ISMPB (bits) || S_ISMPC (bits))
87     return 'm';
88   if (S_ISNWK (bits))
89     return 'n';
90   if (S_ISPORT (bits))
91     return 'P';
92   if (S_ISWHT (bits))
93     return 'w';
94
95   return '?';
96 }
97
98 /* Like filemodestring, but rely only on MODE.  */
99
100 void
101 strmode (mode_t mode, char *str)
102 {
103   str[0] = ftypelet (mode);
104   str[1] = mode & S_IRUSR ? 'r' : '-';
105   str[2] = mode & S_IWUSR ? 'w' : '-';
106   str[3] = (mode & S_ISUID
107             ? (mode & S_IXUSR ? 's' : 'S')
108             : (mode & S_IXUSR ? 'x' : '-'));
109   str[4] = mode & S_IRGRP ? 'r' : '-';
110   str[5] = mode & S_IWGRP ? 'w' : '-';
111   str[6] = (mode & S_ISGID
112             ? (mode & S_IXGRP ? 's' : 'S')
113             : (mode & S_IXGRP ? 'x' : '-'));
114   str[7] = mode & S_IROTH ? 'r' : '-';
115   str[8] = mode & S_IWOTH ? 'w' : '-';
116   str[9] = (mode & S_ISVTX
117             ? (mode & S_IXOTH ? 't' : 'T')
118             : (mode & S_IXOTH ? 'x' : '-'));
119   str[10] = ' ';
120   str[11] = '\0';
121 }
122
123 #endif /* ! HAVE_DECL_STRMODE */
124
125 /* filemodestring - fill in string STR with an ls-style ASCII
126    representation of the st_mode field of file stats block STATP.
127    12 characters are stored in STR.
128    The characters stored in STR are:
129
130    0    File type, as in ftypelet above, except that other letters are used
131         for files whose type cannot be determined solely from st_mode:
132
133             'F' semaphore
134             'M' migrated file (Cray DMF)
135             'Q' message queue
136             'S' shared memory object
137             'T' typed memory object
138
139    1    'r' if the owner may read, '-' otherwise.
140
141    2    'w' if the owner may write, '-' otherwise.
142
143    3    'x' if the owner may execute, 's' if the file is
144         set-user-id, '-' otherwise.
145         'S' if the file is set-user-id, but the execute
146         bit isn't set.
147
148    4    'r' if group members may read, '-' otherwise.
149
150    5    'w' if group members may write, '-' otherwise.
151
152    6    'x' if group members may execute, 's' if the file is
153         set-group-id, '-' otherwise.
154         'S' if it is set-group-id but not executable.
155
156    7    'r' if any user may read, '-' otherwise.
157
158    8    'w' if any user may write, '-' otherwise.
159
160    9    'x' if any user may execute, 't' if the file is "sticky"
161         (will be retained in swap space after execution), '-'
162         otherwise.
163         'T' if the file is sticky but not executable.
164
165    10   ' ' for compatibility with 4.4BSD strmode,
166         since this interface does not support ACLs.
167
168    11   '\0'.  */
169
170 void
171 filemodestring (struct stat const *statp, char *str)
172 {
173   strmode (statp->st_mode, str);
174
175   if (S_TYPEISSEM (statp))
176     str[0] = 'F';
177   else if (IS_MIGRATED_FILE (statp))
178     str[0] = 'M';
179   else if (S_TYPEISMQ (statp))
180     str[0] = 'Q';
181   else if (S_TYPEISSHM (statp))
182     str[0] = 'S';
183   else if (S_TYPEISTMO (statp))
184     str[0] = 'T';
185 }