| 1 |
/* filemode.c -- make a string describing file modes |
/* filemode.c -- make a string describing file modes |
| 2 |
Copyright (C) 1985, 1990, 1993, 1998-2000, 2004 Free Software Foundation, Inc. |
|
| 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 |
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 |
it under the terms of the GNU General Public License as published by |
| 21 |
# include <config.h> |
# include <config.h> |
| 22 |
#endif |
#endif |
| 23 |
|
|
|
#include <sys/types.h> |
|
|
#include <sys/stat.h> |
|
|
|
|
| 24 |
#include "filemode.h" |
#include "filemode.h" |
| 25 |
|
|
| 26 |
#include "stat-macros.h" |
#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 |
/* Set the 's' and 't' flags in file attributes string CHARS, |
#if ! HAVE_DECL_STRMODE |
|
according to the file mode BITS. */ |
|
|
|
|
|
static void |
|
|
setst (mode_t bits, char *chars) |
|
|
{ |
|
|
if (bits & S_ISUID) |
|
|
{ |
|
|
if (chars[3] != 'x') |
|
|
/* Set-uid, but not executable by owner. */ |
|
|
chars[3] = 'S'; |
|
|
else |
|
|
chars[3] = 's'; |
|
|
} |
|
|
if (bits & S_ISGID) |
|
|
{ |
|
|
if (chars[6] != 'x') |
|
|
/* Set-gid, but not executable by group. */ |
|
|
chars[6] = 'S'; |
|
|
else |
|
|
chars[6] = 's'; |
|
|
} |
|
|
if (bits & S_ISVTX) |
|
|
{ |
|
|
if (chars[9] != 'x') |
|
|
/* Sticky, but not executable by others. */ |
|
|
chars[9] = 'T'; |
|
|
else |
|
|
chars[9] = 't'; |
|
|
} |
|
|
} |
|
| 40 |
|
|
| 41 |
/* Return a character indicating the type of file described by |
/* Return a character indicating the type of file described by |
| 42 |
file mode BITS: |
file mode BITS: |
| 43 |
'd' for directories |
'-' regular file |
| 44 |
'D' for doors |
'b' block special file |
| 45 |
'b' for block special files |
'c' character special file |
| 46 |
'c' for character special files |
'C' high performance ("contiguous data") file |
| 47 |
'n' for network special files |
'd' directory |
| 48 |
'm' for multiplexor files |
'D' door |
| 49 |
'M' for an off-line (regular) file |
'l' symbolic link |
| 50 |
'l' for symbolic links |
'm' multiplexed file (7th edition Unix; obsolete) |
| 51 |
's' for sockets |
'n' network special file (HP-UX) |
| 52 |
'p' for fifos |
'p' fifo (named pipe) |
| 53 |
'C' for contigous data files |
'P' port |
| 54 |
'-' for regular files |
's' socket |
| 55 |
'?' for any other file type. */ |
'w' whiteout (4.4BSD) |
| 56 |
|
'?' some other file type */ |
| 57 |
|
|
| 58 |
static char |
static char |
| 59 |
ftypelet (mode_t bits) |
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)) |
if (S_ISBLK (bits)) |
| 69 |
return 'b'; |
return 'b'; |
| 70 |
if (S_ISCHR (bits)) |
if (S_ISCHR (bits)) |
| 71 |
return 'c'; |
return 'c'; |
|
if (S_ISDIR (bits)) |
|
|
return 'd'; |
|
|
if (S_ISREG (bits)) |
|
|
return '-'; |
|
|
if (S_ISFIFO (bits)) |
|
|
return 'p'; |
|
| 72 |
if (S_ISLNK (bits)) |
if (S_ISLNK (bits)) |
| 73 |
return 'l'; |
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)) |
if (S_ISSOCK (bits)) |
| 79 |
return 's'; |
return 's'; |
| 80 |
if (S_ISMPC (bits)) |
|
| 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'; |
return 'm'; |
| 88 |
if (S_ISNWK (bits)) |
if (S_ISNWK (bits)) |
| 89 |
return 'n'; |
return 'n'; |
| 90 |
if (S_ISDOOR (bits)) |
if (S_ISPORT (bits)) |
| 91 |
return 'D'; |
return 'P'; |
| 92 |
if (S_ISCTG (bits)) |
if (S_ISWHT (bits)) |
| 93 |
return 'C'; |
return 'w'; |
| 94 |
|
|
|
/* The following two tests are for Cray DMF (Data Migration |
|
|
Facility), which is a HSM file system. A migrated file has a |
|
|
`st_dm_mode' that is different from the normal `st_mode', so any |
|
|
tests for migrated files should use the former. */ |
|
|
|
|
|
if (S_ISOFD (bits)) |
|
|
/* off line, with data */ |
|
|
return 'M'; |
|
|
/* off line, with no data */ |
|
|
if (S_ISOFL (bits)) |
|
|
return 'M'; |
|
| 95 |
return '?'; |
return '?'; |
| 96 |
} |
} |
| 97 |
|
|
| 98 |
/* Like filemodestring, but only the relevant part of the `struct stat' |
/* Like filemodestring, but rely only on MODE. */ |
|
is given as an argument. */ |
|
| 99 |
|
|
| 100 |
void |
void |
| 101 |
mode_string (mode_t mode, char *str) |
strmode (mode_t mode, char *str) |
| 102 |
{ |
{ |
| 103 |
str[0] = ftypelet (mode); |
str[0] = ftypelet (mode); |
| 104 |
str[1] = mode & S_IRUSR ? 'r' : '-'; |
str[1] = mode & S_IRUSR ? 'r' : '-'; |
| 105 |
str[2] = mode & S_IWUSR ? 'w' : '-'; |
str[2] = mode & S_IWUSR ? 'w' : '-'; |
| 106 |
str[3] = mode & S_IXUSR ? 'x' : '-'; |
str[3] = (mode & S_ISUID |
| 107 |
|
? (mode & S_IXUSR ? 's' : 'S') |
| 108 |
|
: (mode & S_IXUSR ? 'x' : '-')); |
| 109 |
str[4] = mode & S_IRGRP ? 'r' : '-'; |
str[4] = mode & S_IRGRP ? 'r' : '-'; |
| 110 |
str[5] = mode & S_IWGRP ? 'w' : '-'; |
str[5] = mode & S_IWGRP ? 'w' : '-'; |
| 111 |
str[6] = mode & S_IXGRP ? 'x' : '-'; |
str[6] = (mode & S_ISGID |
| 112 |
|
? (mode & S_IXGRP ? 's' : 'S') |
| 113 |
|
: (mode & S_IXGRP ? 'x' : '-')); |
| 114 |
str[7] = mode & S_IROTH ? 'r' : '-'; |
str[7] = mode & S_IROTH ? 'r' : '-'; |
| 115 |
str[8] = mode & S_IWOTH ? 'w' : '-'; |
str[8] = mode & S_IWOTH ? 'w' : '-'; |
| 116 |
str[9] = mode & S_IXOTH ? 'x' : '-'; |
str[9] = (mode & S_ISVTX |
| 117 |
setst (mode, str); |
? (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 |
/* filemodestring - fill in string STR with an ls-style ASCII |
| 126 |
representation of the st_mode field of file stats block STATP. |
representation of the st_mode field of file stats block STATP. |
| 127 |
10 characters are stored in STR; no terminating null is added. |
12 characters are stored in STR. |
| 128 |
The characters stored in STR are: |
The characters stored in STR are: |
| 129 |
|
|
| 130 |
0 File type. 'd' for directory, 'c' for character |
0 File type, as in ftypelet above, except that other letters are used |
| 131 |
special, 'b' for block special, 'm' for multiplex, |
for files whose type cannot be determined solely from st_mode: |
| 132 |
'l' for symbolic link, 's' for socket, 'p' for fifo, |
|
| 133 |
'-' for regular, '?' for any other file type |
'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. |
1 'r' if the owner may read, '-' otherwise. |
| 140 |
|
|
| 160 |
9 'x' if any user may execute, 't' if the file is "sticky" |
9 'x' if any user may execute, 't' if the file is "sticky" |
| 161 |
(will be retained in swap space after execution), '-' |
(will be retained in swap space after execution), '-' |
| 162 |
otherwise. |
otherwise. |
| 163 |
'T' if the file is sticky but not executable. */ |
'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 |
void |
| 171 |
filemodestring (struct stat *statp, char *str) |
filemodestring (struct stat const *statp, char *str) |
| 172 |
{ |
{ |
| 173 |
mode_string (statp->st_mode, str); |
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 |
} |
} |