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