| /* filemode.c -- make a string describing file modes |
| |
| Copyright (C) 1985, 1990, 1993, 1998-2000, 2004, 2006, 2009-2020 Free |
| Software Foundation, Inc. |
| |
| This program is free software: you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 3 of the License, or |
| (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program. If not, see <https://www.gnu.org/licenses/>. */ |
| |
| #include <config.h> |
| |
| #include "filemode.h" |
| |
| /* The following is 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 HAVE_ST_DM_MODE |
| # define IS_MIGRATED_FILE(statp) \ |
| (S_ISOFD (statp->st_dm_mode) || S_ISOFL (statp->st_dm_mode)) |
| #else |
| # define IS_MIGRATED_FILE(statp) 0 |
| #endif |
| |
| #if ! HAVE_DECL_STRMODE |
| |
| /* Return a character indicating the type of file described by |
| file mode BITS: |
| '-' regular file |
| 'b' block special file |
| 'c' character special file |
| 'C' high performance ("contiguous data") file |
| 'd' directory |
| 'D' door |
| 'l' symbolic link |
| 'm' multiplexed file (7th edition Unix; obsolete) |
| 'n' network special file (HP-UX) |
| 'p' fifo (named pipe) |
| 'P' port |
| 's' socket |
| 'w' whiteout (4.4BSD) |
| '?' some other file type */ |
| |
| static char |
| ftypelet (mode_t bits) |
| { |
| /* These are the most common, so test for them first. */ |
| if (S_ISREG (bits)) |
| return '-'; |
| if (S_ISDIR (bits)) |
| return 'd'; |
| |
| /* Other letters standardized by POSIX 1003.1-2004. */ |
| if (S_ISBLK (bits)) |
| return 'b'; |
| if (S_ISCHR (bits)) |
| return 'c'; |
| if (S_ISLNK (bits)) |
| return 'l'; |
| if (S_ISFIFO (bits)) |
| return 'p'; |
| |
| /* Other file types (though not letters) standardized by POSIX. */ |
| if (S_ISSOCK (bits)) |
| return 's'; |
| |
| /* Nonstandard file types. */ |
| if (S_ISCTG (bits)) |
| return 'C'; |
| if (S_ISDOOR (bits)) |
| return 'D'; |
| if (S_ISMPB (bits) || S_ISMPC (bits) || S_ISMPX (bits)) |
| return 'm'; |
| if (S_ISNWK (bits)) |
| return 'n'; |
| if (S_ISPORT (bits)) |
| return 'P'; |
| if (S_ISWHT (bits)) |
| return 'w'; |
| |
| return '?'; |
| } |
| |
| /* Like filemodestring, but rely only on MODE. */ |
| |
| void |
| strmode (mode_t mode, char *str) |
| { |
| str[0] = ftypelet (mode); |
| str[1] = mode & S_IRUSR ? 'r' : '-'; |
| str[2] = mode & S_IWUSR ? 'w' : '-'; |
| str[3] = (mode & S_ISUID |
| ? (mode & S_IXUSR ? 's' : 'S') |
| : (mode & S_IXUSR ? 'x' : '-')); |
| str[4] = mode & S_IRGRP ? 'r' : '-'; |
| str[5] = mode & S_IWGRP ? 'w' : '-'; |
| str[6] = (mode & S_ISGID |
| ? (mode & S_IXGRP ? 's' : 'S') |
| : (mode & S_IXGRP ? 'x' : '-')); |
| str[7] = mode & S_IROTH ? 'r' : '-'; |
| str[8] = mode & S_IWOTH ? 'w' : '-'; |
| str[9] = (mode & S_ISVTX |
| ? (mode & S_IXOTH ? 't' : 'T') |
| : (mode & S_IXOTH ? 'x' : '-')); |
| str[10] = ' '; |
| str[11] = '\0'; |
| } |
| |
| #endif /* ! HAVE_DECL_STRMODE */ |
| |
| /* filemodestring - fill in string STR with an ls-style ASCII |
| representation of the st_mode field of file stats block STATP. |
| 12 characters are stored in STR. |
| The characters stored in STR are: |
| |
| 0 File type, as in ftypelet above, except that other letters are used |
| for files whose type cannot be determined solely from st_mode: |
| |
| 'F' semaphore |
| 'M' migrated file (Cray DMF) |
| 'Q' message queue |
| 'S' shared memory object |
| 'T' typed memory object |
| |
| 1 'r' if the owner may read, '-' otherwise. |
| |
| 2 'w' if the owner may write, '-' otherwise. |
| |
| 3 'x' if the owner may execute, 's' if the file is |
| set-user-id, '-' otherwise. |
| 'S' if the file is set-user-id, but the execute |
| bit isn't set. |
| |
| 4 'r' if group members may read, '-' otherwise. |
| |
| 5 'w' if group members may write, '-' otherwise. |
| |
| 6 'x' if group members may execute, 's' if the file is |
| set-group-id, '-' otherwise. |
| 'S' if it is set-group-id but not executable. |
| |
| 7 'r' if any user may read, '-' otherwise. |
| |
| 8 'w' if any user may write, '-' otherwise. |
| |
| 9 'x' if any user may execute, 't' if the file is "sticky" |
| (will be retained in swap space after execution), '-' |
| otherwise. |
| 'T' if the file is sticky but not executable. |
| |
| 10 ' ' for compatibility with 4.4BSD strmode, |
| since this interface does not support ACLs. |
| |
| 11 '\0'. */ |
| |
| void |
| filemodestring (struct stat const *statp, char *str) |
| { |
| strmode (statp->st_mode, str); |
| |
| if (S_TYPEISSEM (statp)) |
| str[0] = 'F'; |
| else if (IS_MIGRATED_FILE (statp)) |
| str[0] = 'M'; |
| else if (S_TYPEISMQ (statp)) |
| str[0] = 'Q'; |
| else if (S_TYPEISSHM (statp)) |
| str[0] = 'S'; |
| else if (S_TYPEISTMO (statp)) |
| str[0] = 'T'; |
| } |