X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Ffilemode.c;h=0f6641ace6a364bdc488a5dc2643f97e4c93bec7;hb=d4d84c1d916f5bff3bb72be92e9d1383a25077c1;hp=5e909dfca422769450ec14a5c3053ff5eadf90ef;hpb=8a7c83d56c059e5a4a41e0f3cf06497a254e96d4;p=gnulib.git diff --git a/lib/filemode.c b/lib/filemode.c index 5e909dfca..0f6641ace 100644 --- a/lib/filemode.c +++ b/lib/filemode.c @@ -1,10 +1,12 @@ /* filemode.c -- make a string describing file modes - Copyright (C) 1985, 1990, 1993, 1998-2000 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify + Copyright (C) 1985, 1990, 1993, 1998-2000, 2004, 2006, 2009-2011 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 2, or (at your option) - any later version. + 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 @@ -12,282 +14,167 @@ 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, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#if HAVE_CONFIG_H -# include -#endif + along with this program. If not, see . */ -#include -#include +#include #include "filemode.h" -#if !S_IRUSR -# if S_IREAD -# define S_IRUSR S_IREAD -# else -# define S_IRUSR 00400 -# endif -#endif - -#if !S_IWUSR -# if S_IWRITE -# define S_IWUSR S_IWRITE -# else -# define S_IWUSR 00200 -# endif -#endif - -#if !S_IXUSR -# if S_IEXEC -# define S_IXUSR S_IEXEC -# else -# define S_IXUSR 00100 -# endif -#endif - -#if !S_IRGRP -# define S_IRGRP (S_IRUSR >> 3) -#endif -#if !S_IWGRP -# define S_IWGRP (S_IWUSR >> 3) -#endif -#if !S_IXGRP -# define S_IXGRP (S_IXUSR >> 3) -#endif -#if !S_IROTH -# define S_IROTH (S_IRUSR >> 6) -#endif -#if !S_IWOTH -# define S_IWOTH (S_IWUSR >> 6) -#endif -#if !S_IXOTH -# define S_IXOTH (S_IXUSR >> 6) -#endif - -#ifdef STAT_MACROS_BROKEN -# undef S_ISBLK -# undef S_ISCHR -# undef S_ISDIR -# undef S_ISFIFO -# undef S_ISLNK -# undef S_ISMPB -# undef S_ISMPC -# undef S_ISNWK -# undef S_ISREG -# undef S_ISSOCK -#endif /* STAT_MACROS_BROKEN. */ - -#if !defined S_ISBLK && defined S_IFBLK -# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) -#endif -#if !defined S_ISCHR && defined S_IFCHR -# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) -#endif -#if !defined S_ISDIR && defined S_IFDIR -# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +/* 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 !defined S_ISREG && defined S_IFREG -# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#endif -#if !defined S_ISFIFO && defined S_IFIFO -# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) -#endif -#if !defined S_ISLNK && defined S_IFLNK -# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) -#endif -#if !defined S_ISSOCK && defined S_IFSOCK -# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) -#endif -#if !defined S_ISMPB && defined S_IFMPB /* V7 */ -# define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB) -# define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC) -#endif -#if !defined S_ISNWK && defined S_IFNWK /* HP/UX */ -# define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK) -#endif -#if !defined S_ISDOOR && defined S_IFDOOR /* Solaris 2.5 and up */ -# define S_ISDOOR(m) (((m) & S_IFMT) == S_IFDOOR) -#endif -#if !defined S_ISCTG && defined S_IFCTG /* MassComp */ -# define S_ISCTG(m) (((m) & S_IFMT) == S_IFCTG) -#endif - - -/* Set the 's' and 't' flags in file attributes string CHARS, - according to the file mode BITS. */ - -static void -setst (mode_t bits, char *chars) -{ -#ifdef S_ISUID - if (bits & S_ISUID) - { - if (chars[3] != 'x') - /* Set-uid, but not executable by owner. */ - chars[3] = 'S'; - else - chars[3] = 's'; - } -#endif -#ifdef S_ISGID - if (bits & S_ISGID) - { - if (chars[6] != 'x') - /* Set-gid, but not executable by group. */ - chars[6] = 'S'; - else - chars[6] = 's'; - } -#endif -#ifdef S_ISVTX - if (bits & S_ISVTX) - { - if (chars[9] != 'x') - /* Sticky, but not executable by others. */ - chars[9] = 'T'; - else - chars[9] = 't'; - } -#endif -} +#if ! HAVE_DECL_STRMODE /* Return a character indicating the type of file described by file mode BITS: - 'd' for directories - 'D' for doors - 'b' for block special files - 'c' for character special files - 'n' for network special files - 'm' for multiplexor files - 'M' for an off-line (regular) file - 'l' for symbolic links - 's' for sockets - 'p' for fifos - 'C' for contigous data files - '-' for regular files - '?' for any other file type. */ + '-' 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) { -#ifdef S_ISBLK + /* 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'; -#endif if (S_ISCHR (bits)) return 'c'; - if (S_ISDIR (bits)) - return 'd'; - if (S_ISREG (bits)) - return '-'; -#ifdef S_ISFIFO - if (S_ISFIFO (bits)) - return 'p'; -#endif -#ifdef S_ISLNK if (S_ISLNK (bits)) return 'l'; -#endif -#ifdef S_ISSOCK + if (S_ISFIFO (bits)) + return 'p'; + + /* Other file types (though not letters) standardized by POSIX. */ if (S_ISSOCK (bits)) return 's'; -#endif -#ifdef S_ISMPC - if (S_ISMPC (bits)) + + /* Nonstandard file types. */ + if (S_ISCTG (bits)) + return 'C'; + if (S_ISDOOR (bits)) + return 'D'; + if (S_ISMPB (bits) || S_ISMPC (bits)) return 'm'; -#endif -#ifdef S_ISNWK if (S_ISNWK (bits)) return 'n'; -#endif -#ifdef S_ISDOOR - if (S_ISDOOR (bits)) - return 'D'; -#endif -#ifdef S_ISCTG - if (S_ISCTG (bits)) - return 'C'; -#endif - - /* 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_ISPORT (bits)) + return 'P'; + if (S_ISWHT (bits)) + return 'w'; -#ifdef S_ISOFD - if (S_ISOFD (bits)) - /* off line, with data */ - return 'M'; -#endif -#ifdef S_ISOFL - /* off line, with no data */ - if (S_ISOFL (bits)) - return 'M'; -#endif return '?'; } -/* Like filemodestring, but only the relevant part of the `struct stat' - is given as an argument. */ +/* Like filemodestring, but rely only on MODE. */ void -mode_string (mode_t mode, char *str) +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_IXUSR ? 'x' : '-'; + 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_IXGRP ? 'x' : '-'; + 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_IXOTH ? 'x' : '-'; - setst (mode, str); + 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. - 10 characters are stored in STR; no terminating null is added. + 12 characters are stored in STR. The characters stored in STR are: - 0 File type. 'd' for directory, 'c' for character - special, 'b' for block special, 'm' for multiplex, - 'l' for symbolic link, 's' for socket, 'p' for fifo, - '-' for regular, '?' for any other file type + 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. - 1 'r' if the owner may read, '-' 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. - 2 'w' if the owner may write, '-' otherwise. + 4 'r' if group members may read, '-' 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. + 5 'w' if group members may write, '-' otherwise. - 4 'r' if group members may read, '-' 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. - 5 'w' if group members may write, '-' otherwise. + 7 'r' if any user may read, '-' 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. + 8 'w' if any user may write, '-' otherwise. - 7 'r' if any user may read, '-' 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. - 8 'w' if any user may write, '-' otherwise. + 10 ' ' for compatibility with 4.4BSD strmode, + since this interface does not support ACLs. - 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. */ + 11 '\0'. */ void -filemodestring (struct stat *statp, char *str) +filemodestring (struct stat const *statp, char *str) { - mode_string (statp->st_mode, 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'; }