(root)/
binutils-2.41/
binutils/
filemode.c
       1  /* filemode.c -- make a string describing file modes
       2     Copyright (C) 1985-2023 Free Software Foundation, Inc.
       3  
       4     This program is free software; you can redistribute it and/or modify
       5     it under the terms of the GNU General Public License as published by
       6     the Free Software Foundation; either version 3, or (at your option)
       7     any later version.
       8  
       9     This program is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12     GNU General Public License for more details.
      13  
      14     You should have received a copy of the GNU General Public License
      15     along with this program; if not, write to the Free Software
      16     Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
      17     02110-1301, USA.  */
      18  
      19  #include "sysdep.h"
      20  #include "bfd.h"
      21  #include "bucomm.h"
      22  
      23  static char ftypelet (unsigned long);
      24  static void setst (unsigned long, char *);
      25  
      26  /* filemodestring - fill in string STR with an ls-style ASCII
      27     representation of the st_mode field of file stats block STATP.
      28     10 characters are stored in STR; no terminating null is added.
      29     The characters stored in STR are:
      30  
      31     0	File type.  'd' for directory, 'c' for character
      32  	special, 'b' for block special, 'm' for multiplex,
      33  	'l' for symbolic link, 's' for socket, 'p' for fifo,
      34  	'-' for any other file type
      35  
      36     1	'r' if the owner may read, '-' otherwise.
      37  
      38     2	'w' if the owner may write, '-' otherwise.
      39  
      40     3	'x' if the owner may execute, 's' if the file is
      41  	set-user-id, '-' otherwise.
      42  	'S' if the file is set-user-id, but the execute
      43  	bit isn't set.
      44  
      45     4	'r' if group members may read, '-' otherwise.
      46  
      47     5	'w' if group members may write, '-' otherwise.
      48  
      49     6	'x' if group members may execute, 's' if the file is
      50  	set-group-id, '-' otherwise.
      51  	'S' if it is set-group-id but not executable.
      52  
      53     7	'r' if any user may read, '-' otherwise.
      54  
      55     8	'w' if any user may write, '-' otherwise.
      56  
      57     9	'x' if any user may execute, 't' if the file is "sticky"
      58  	(will be retained in swap space after execution), '-'
      59  	otherwise.
      60  	'T' if the file is sticky but not executable.  */
      61  
      62  /* Get definitions for the file permission bits.  */
      63  
      64  #ifndef S_IRWXU
      65  #define S_IRWXU 0700
      66  #endif
      67  #ifndef S_IRUSR
      68  #define S_IRUSR 0400
      69  #endif
      70  #ifndef S_IWUSR
      71  #define S_IWUSR 0200
      72  #endif
      73  #ifndef S_IXUSR
      74  #define S_IXUSR 0100
      75  #endif
      76  
      77  #ifndef S_IRWXG
      78  #define S_IRWXG 0070
      79  #endif
      80  #ifndef S_IRGRP
      81  #define S_IRGRP 0040
      82  #endif
      83  #ifndef S_IWGRP
      84  #define S_IWGRP 0020
      85  #endif
      86  #ifndef S_IXGRP
      87  #define S_IXGRP 0010
      88  #endif
      89  
      90  #ifndef S_IRWXO
      91  #define S_IRWXO 0007
      92  #endif
      93  #ifndef S_IROTH
      94  #define S_IROTH 0004
      95  #endif
      96  #ifndef S_IWOTH
      97  #define S_IWOTH 0002
      98  #endif
      99  #ifndef S_IXOTH
     100  #define S_IXOTH 0001
     101  #endif
     102  
     103  /* Like filemodestring, but only the relevant part of the `struct stat'
     104     is given as an argument.  */
     105  
     106  void
     107  mode_string (unsigned long mode, char *str)
     108  {
     109    str[0] = ftypelet ((unsigned long) mode);
     110    str[1] = (mode & S_IRUSR) != 0 ? 'r' : '-';
     111    str[2] = (mode & S_IWUSR) != 0 ? 'w' : '-';
     112    str[3] = (mode & S_IXUSR) != 0 ? 'x' : '-';
     113    str[4] = (mode & S_IRGRP) != 0 ? 'r' : '-';
     114    str[5] = (mode & S_IWGRP) != 0 ? 'w' : '-';
     115    str[6] = (mode & S_IXGRP) != 0 ? 'x' : '-';
     116    str[7] = (mode & S_IROTH) != 0 ? 'r' : '-';
     117    str[8] = (mode & S_IWOTH) != 0 ? 'w' : '-';
     118    str[9] = (mode & S_IXOTH) != 0 ? 'x' : '-';
     119    setst ((unsigned long) mode, str);
     120  }
     121  
     122  /* Return a character indicating the type of file described by
     123     file mode BITS:
     124     'd' for directories
     125     'b' for block special files
     126     'c' for character special files
     127     'm' for multiplexer files
     128     'l' for symbolic links
     129     's' for sockets
     130     'p' for fifos
     131     '-' for any other file type.  */
     132  
     133  #ifndef S_ISDIR
     134  #ifdef S_IFDIR
     135  #define S_ISDIR(i) (((i) & S_IFMT) == S_IFDIR)
     136  #else /* ! defined (S_IFDIR) */
     137  #define S_ISDIR(i) (((i) & 0170000) == 040000)
     138  #endif /* ! defined (S_IFDIR) */
     139  #endif /* ! defined (S_ISDIR) */
     140  
     141  #ifndef S_ISBLK
     142  #ifdef S_IFBLK
     143  #define S_ISBLK(i) (((i) & S_IFMT) == S_IFBLK)
     144  #else /* ! defined (S_IFBLK) */
     145  #define S_ISBLK(i) 0
     146  #endif /* ! defined (S_IFBLK) */
     147  #endif /* ! defined (S_ISBLK) */
     148  
     149  #ifndef S_ISCHR
     150  #ifdef S_IFCHR
     151  #define S_ISCHR(i) (((i) & S_IFMT) == S_IFCHR)
     152  #else /* ! defined (S_IFCHR) */
     153  #define S_ISCHR(i) 0
     154  #endif /* ! defined (S_IFCHR) */
     155  #endif /* ! defined (S_ISCHR) */
     156  
     157  #ifndef S_ISFIFO
     158  #ifdef S_IFIFO
     159  #define S_ISFIFO(i) (((i) & S_IFMT) == S_IFIFO)
     160  #else /* ! defined (S_IFIFO) */
     161  #define S_ISFIFO(i) 0
     162  #endif /* ! defined (S_IFIFO) */
     163  #endif /* ! defined (S_ISFIFO) */
     164  
     165  #ifndef S_ISSOCK
     166  #ifdef S_IFSOCK
     167  #define S_ISSOCK(i) (((i) & S_IFMT) == S_IFSOCK)
     168  #else /* ! defined (S_IFSOCK) */
     169  #define S_ISSOCK(i) 0
     170  #endif /* ! defined (S_IFSOCK) */
     171  #endif /* ! defined (S_ISSOCK) */
     172  
     173  #ifndef S_ISLNK
     174  #ifdef S_IFLNK
     175  #define S_ISLNK(i) (((i) & S_IFMT) == S_IFLNK)
     176  #else /* ! defined (S_IFLNK) */
     177  #define S_ISLNK(i) 0
     178  #endif /* ! defined (S_IFLNK) */
     179  #endif /* ! defined (S_ISLNK) */
     180  
     181  static char
     182  ftypelet (unsigned long bits)
     183  {
     184    if (S_ISDIR (bits))
     185      return 'd';
     186    if (S_ISLNK (bits))
     187      return 'l';
     188    if (S_ISBLK (bits))
     189      return 'b';
     190    if (S_ISCHR (bits))
     191      return 'c';
     192    if (S_ISSOCK (bits))
     193      return 's';
     194    if (S_ISFIFO (bits))
     195      return 'p';
     196  
     197  #ifdef S_IFMT
     198  #ifdef S_IFMPC
     199    if ((bits & S_IFMT) == S_IFMPC
     200        || (bits & S_IFMT) == S_IFMPB)
     201      return 'm';
     202  #endif
     203  #ifdef S_IFNWK
     204    if ((bits & S_IFMT) == S_IFNWK)
     205      return 'n';
     206  #endif
     207  #endif
     208  
     209    return '-';
     210  }
     211  
     212  /* Set the 's' and 't' flags in file attributes string CHARS,
     213     according to the file mode BITS.  */
     214  
     215  static void
     216  setst (unsigned long bits ATTRIBUTE_UNUSED, char *chars ATTRIBUTE_UNUSED)
     217  {
     218  #ifdef S_ISUID
     219    if (bits & S_ISUID)
     220      {
     221        if (chars[3] != 'x')
     222  	/* Set-uid, but not executable by owner.  */
     223  	chars[3] = 'S';
     224        else
     225  	chars[3] = 's';
     226      }
     227  #endif
     228  #ifdef S_ISGID
     229    if (bits & S_ISGID)
     230      {
     231        if (chars[6] != 'x')
     232  	/* Set-gid, but not executable by group.  */
     233  	chars[6] = 'S';
     234        else
     235  	chars[6] = 's';
     236      }
     237  #endif
     238  #ifdef S_ISVTX
     239    if (bits & S_ISVTX)
     240      {
     241        if (chars[9] != 'x')
     242  	/* Sticky, but not executable by others.  */
     243  	chars[9] = 'T';
     244        else
     245  	chars[9] = 't';
     246      }
     247  #endif
     248  }