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