12159047fSniklas /* filemode.c -- make a string describing file modes
2*007c2a45Smiod Copyright 1985, 1990, 1991, 1994, 1995, 1997, 2003
3b55d4692Sfgsch Free Software Foundation, Inc.
42159047fSniklas
52159047fSniklas This program is free software; you can redistribute it and/or modify
62159047fSniklas it under the terms of the GNU General Public License as published by
72159047fSniklas the Free Software Foundation; either version 2, or (at your option)
82159047fSniklas any later version.
92159047fSniklas
102159047fSniklas This program is distributed in the hope that it will be useful,
112159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
122159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
132159047fSniklas GNU General Public License for more details.
142159047fSniklas
152159047fSniklas You should have received a copy of the GNU General Public License
162159047fSniklas along with this program; if not, write to the Free Software
17fddef416Sniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18fddef416Sniklas 02111-1307, USA. */
192159047fSniklas
202159047fSniklas #include "bfd.h"
21fddef416Sniklas #include "bucomm.h"
222159047fSniklas
23*007c2a45Smiod static char ftypelet (unsigned long);
24*007c2a45Smiod static void setst (unsigned long, char *);
252159047fSniklas
262159047fSniklas /* filemodestring - fill in string STR with an ls-style ASCII
272159047fSniklas representation of the st_mode field of file stats block STATP.
282159047fSniklas 10 characters are stored in STR; no terminating null is added.
292159047fSniklas The characters stored in STR are:
302159047fSniklas
312159047fSniklas 0 File type. 'd' for directory, 'c' for character
322159047fSniklas special, 'b' for block special, 'm' for multiplex,
332159047fSniklas 'l' for symbolic link, 's' for socket, 'p' for fifo,
342159047fSniklas '-' for any other file type
352159047fSniklas
362159047fSniklas 1 'r' if the owner may read, '-' otherwise.
372159047fSniklas
382159047fSniklas 2 'w' if the owner may write, '-' otherwise.
392159047fSniklas
402159047fSniklas 3 'x' if the owner may execute, 's' if the file is
412159047fSniklas set-user-id, '-' otherwise.
422159047fSniklas 'S' if the file is set-user-id, but the execute
432159047fSniklas bit isn't set.
442159047fSniklas
452159047fSniklas 4 'r' if group members may read, '-' otherwise.
462159047fSniklas
472159047fSniklas 5 'w' if group members may write, '-' otherwise.
482159047fSniklas
492159047fSniklas 6 'x' if group members may execute, 's' if the file is
502159047fSniklas set-group-id, '-' otherwise.
512159047fSniklas 'S' if it is set-group-id but not executable.
522159047fSniklas
532159047fSniklas 7 'r' if any user may read, '-' otherwise.
542159047fSniklas
552159047fSniklas 8 'w' if any user may write, '-' otherwise.
562159047fSniklas
572159047fSniklas 9 'x' if any user may execute, 't' if the file is "sticky"
582159047fSniklas (will be retained in swap space after execution), '-'
592159047fSniklas otherwise.
602159047fSniklas 'T' if the file is sticky but not executable. */
612159047fSniklas
622159047fSniklas #if 0
632159047fSniklas
642159047fSniklas /* This is not used; only mode_string is used. */
652159047fSniklas
662159047fSniklas void
67*007c2a45Smiod filemodestring (struct stat *statp, char *str)
682159047fSniklas {
692159047fSniklas mode_string ((unsigned long) statp->st_mode, str);
702159047fSniklas }
712159047fSniklas
722159047fSniklas #endif
732159047fSniklas
742159047fSniklas /* Get definitions for the file permission bits. */
752159047fSniklas
762159047fSniklas #ifndef S_IRWXU
772159047fSniklas #define S_IRWXU 0700
782159047fSniklas #endif
792159047fSniklas #ifndef S_IRUSR
802159047fSniklas #define S_IRUSR 0400
812159047fSniklas #endif
822159047fSniklas #ifndef S_IWUSR
832159047fSniklas #define S_IWUSR 0200
842159047fSniklas #endif
852159047fSniklas #ifndef S_IXUSR
862159047fSniklas #define S_IXUSR 0100
872159047fSniklas #endif
882159047fSniklas
892159047fSniklas #ifndef S_IRWXG
902159047fSniklas #define S_IRWXG 0070
912159047fSniklas #endif
922159047fSniklas #ifndef S_IRGRP
932159047fSniklas #define S_IRGRP 0040
942159047fSniklas #endif
952159047fSniklas #ifndef S_IWGRP
962159047fSniklas #define S_IWGRP 0020
972159047fSniklas #endif
982159047fSniklas #ifndef S_IXGRP
992159047fSniklas #define S_IXGRP 0010
1002159047fSniklas #endif
1012159047fSniklas
1022159047fSniklas #ifndef S_IRWXO
1032159047fSniklas #define S_IRWXO 0007
1042159047fSniklas #endif
1052159047fSniklas #ifndef S_IROTH
1062159047fSniklas #define S_IROTH 0004
1072159047fSniklas #endif
1082159047fSniklas #ifndef S_IWOTH
1092159047fSniklas #define S_IWOTH 0002
1102159047fSniklas #endif
1112159047fSniklas #ifndef S_IXOTH
1122159047fSniklas #define S_IXOTH 0001
1132159047fSniklas #endif
1142159047fSniklas
1152159047fSniklas /* Like filemodestring, but only the relevant part of the `struct stat'
1162159047fSniklas is given as an argument. */
1172159047fSniklas
1182159047fSniklas void
mode_string(unsigned long mode,char * str)119*007c2a45Smiod mode_string (unsigned long mode, char *str)
1202159047fSniklas {
1212159047fSniklas str[0] = ftypelet ((unsigned long) mode);
1222159047fSniklas str[1] = (mode & S_IRUSR) != 0 ? 'r' : '-';
1232159047fSniklas str[2] = (mode & S_IWUSR) != 0 ? 'w' : '-';
1242159047fSniklas str[3] = (mode & S_IXUSR) != 0 ? 'x' : '-';
1252159047fSniklas str[4] = (mode & S_IRGRP) != 0 ? 'r' : '-';
1262159047fSniklas str[5] = (mode & S_IWGRP) != 0 ? 'w' : '-';
1272159047fSniklas str[6] = (mode & S_IXGRP) != 0 ? 'x' : '-';
1282159047fSniklas str[7] = (mode & S_IROTH) != 0 ? 'r' : '-';
1292159047fSniklas str[8] = (mode & S_IWOTH) != 0 ? 'w' : '-';
1302159047fSniklas str[9] = (mode & S_IXOTH) != 0 ? 'x' : '-';
1312159047fSniklas setst ((unsigned long) mode, str);
1322159047fSniklas }
1332159047fSniklas
1342159047fSniklas /* Return a character indicating the type of file described by
1352159047fSniklas file mode BITS:
1362159047fSniklas 'd' for directories
1372159047fSniklas 'b' for block special files
1382159047fSniklas 'c' for character special files
139*007c2a45Smiod 'm' for multiplexer files
1402159047fSniklas 'l' for symbolic links
1412159047fSniklas 's' for sockets
1422159047fSniklas 'p' for fifos
1432159047fSniklas '-' for any other file type. */
1442159047fSniklas
1452159047fSniklas #ifndef S_ISDIR
1462159047fSniklas #ifdef S_IFDIR
1472159047fSniklas #define S_ISDIR(i) (((i) & S_IFMT) == S_IFDIR)
1482159047fSniklas #else /* ! defined (S_IFDIR) */
1492159047fSniklas #define S_ISDIR(i) (((i) & 0170000) == 040000)
1502159047fSniklas #endif /* ! defined (S_IFDIR) */
1512159047fSniklas #endif /* ! defined (S_ISDIR) */
1522159047fSniklas
1532159047fSniklas #ifndef S_ISBLK
1542159047fSniklas #ifdef S_IFBLK
1552159047fSniklas #define S_ISBLK(i) (((i) & S_IFMT) == S_IFBLK)
1562159047fSniklas #else /* ! defined (S_IFBLK) */
1572159047fSniklas #define S_ISBLK(i) 0
1582159047fSniklas #endif /* ! defined (S_IFBLK) */
1592159047fSniklas #endif /* ! defined (S_ISBLK) */
1602159047fSniklas
1612159047fSniklas #ifndef S_ISCHR
1622159047fSniklas #ifdef S_IFCHR
1632159047fSniklas #define S_ISCHR(i) (((i) & S_IFMT) == S_IFCHR)
1642159047fSniklas #else /* ! defined (S_IFCHR) */
1652159047fSniklas #define S_ISCHR(i) 0
1662159047fSniklas #endif /* ! defined (S_IFCHR) */
1672159047fSniklas #endif /* ! defined (S_ISCHR) */
1682159047fSniklas
1692159047fSniklas #ifndef S_ISFIFO
1702159047fSniklas #ifdef S_IFIFO
1712159047fSniklas #define S_ISFIFO(i) (((i) & S_IFMT) == S_IFIFO)
1722159047fSniklas #else /* ! defined (S_IFIFO) */
1732159047fSniklas #define S_ISFIFO(i) 0
1742159047fSniklas #endif /* ! defined (S_IFIFO) */
1752159047fSniklas #endif /* ! defined (S_ISFIFO) */
1762159047fSniklas
1772159047fSniklas #ifndef S_ISSOCK
1782159047fSniklas #ifdef S_IFSOCK
1792159047fSniklas #define S_ISSOCK(i) (((i) & S_IFMT) == S_IFSOCK)
1802159047fSniklas #else /* ! defined (S_IFSOCK) */
1812159047fSniklas #define S_ISSOCK(i) 0
1822159047fSniklas #endif /* ! defined (S_IFSOCK) */
1832159047fSniklas #endif /* ! defined (S_ISSOCK) */
1842159047fSniklas
1852159047fSniklas #ifndef S_ISLNK
1862159047fSniklas #ifdef S_IFLNK
1872159047fSniklas #define S_ISLNK(i) (((i) & S_IFMT) == S_IFLNK)
1882159047fSniklas #else /* ! defined (S_IFLNK) */
1892159047fSniklas #define S_ISLNK(i) 0
1902159047fSniklas #endif /* ! defined (S_IFLNK) */
1912159047fSniklas #endif /* ! defined (S_ISLNK) */
1922159047fSniklas
1932159047fSniklas static char
ftypelet(unsigned long bits)194*007c2a45Smiod ftypelet (unsigned long bits)
1952159047fSniklas {
1962159047fSniklas if (S_ISDIR (bits))
1972159047fSniklas return 'd';
1982159047fSniklas if (S_ISLNK (bits))
1992159047fSniklas return 'l';
2002159047fSniklas if (S_ISBLK (bits))
2012159047fSniklas return 'b';
2022159047fSniklas if (S_ISCHR (bits))
2032159047fSniklas return 'c';
2042159047fSniklas if (S_ISSOCK (bits))
2052159047fSniklas return 's';
2062159047fSniklas if (S_ISFIFO (bits))
2072159047fSniklas return 'p';
2082159047fSniklas
2092159047fSniklas #ifdef S_IFMT
2102159047fSniklas #ifdef S_IFMPC
2112159047fSniklas if ((bits & S_IFMT) == S_IFMPC
2122159047fSniklas || (bits & S_IFMT) == S_IFMPB)
2132159047fSniklas return 'm';
2142159047fSniklas #endif
2152159047fSniklas #ifdef S_IFNWK
2162159047fSniklas if ((bits & S_IFMT) == S_IFNWK)
2172159047fSniklas return 'n';
2182159047fSniklas #endif
2192159047fSniklas #endif
2202159047fSniklas
2212159047fSniklas return '-';
2222159047fSniklas }
2232159047fSniklas
2242159047fSniklas /* Set the 's' and 't' flags in file attributes string CHARS,
2252159047fSniklas according to the file mode BITS. */
2262159047fSniklas
2272159047fSniklas static void
setst(unsigned long bits ATTRIBUTE_UNUSED,char * chars ATTRIBUTE_UNUSED)228*007c2a45Smiod setst (unsigned long bits ATTRIBUTE_UNUSED, char *chars ATTRIBUTE_UNUSED)
2292159047fSniklas {
2302159047fSniklas #ifdef S_ISUID
2312159047fSniklas if (bits & S_ISUID)
2322159047fSniklas {
2332159047fSniklas if (chars[3] != 'x')
2342159047fSniklas /* Set-uid, but not executable by owner. */
2352159047fSniklas chars[3] = 'S';
2362159047fSniklas else
2372159047fSniklas chars[3] = 's';
2382159047fSniklas }
2392159047fSniklas #endif
2402159047fSniklas #ifdef S_ISGID
2412159047fSniklas if (bits & S_ISGID)
2422159047fSniklas {
2432159047fSniklas if (chars[6] != 'x')
2442159047fSniklas /* Set-gid, but not executable by group. */
2452159047fSniklas chars[6] = 'S';
2462159047fSniklas else
2472159047fSniklas chars[6] = 's';
2482159047fSniklas }
2492159047fSniklas #endif
2502159047fSniklas #ifdef S_ISVTX
2512159047fSniklas if (bits & S_ISVTX)
2522159047fSniklas {
2532159047fSniklas if (chars[9] != 'x')
2542159047fSniklas /* Sticky, but not executable by others. */
2552159047fSniklas chars[9] = 'T';
2562159047fSniklas else
2572159047fSniklas chars[9] = 't';
2582159047fSniklas }
2592159047fSniklas #endif
2602159047fSniklas }
261