175fd0b74Schristos /* filemode.c -- make a string describing file modes
2*e992f068Schristos Copyright (C) 1985-2022 Free Software Foundation, Inc.
375fd0b74Schristos
475fd0b74Schristos This program is free software; you can redistribute it and/or modify
575fd0b74Schristos it under the terms of the GNU General Public License as published by
675fd0b74Schristos the Free Software Foundation; either version 3, or (at your option)
775fd0b74Schristos any later version.
875fd0b74Schristos
975fd0b74Schristos This program is distributed in the hope that it will be useful,
1075fd0b74Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
1175fd0b74Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1275fd0b74Schristos GNU General Public License for more details.
1375fd0b74Schristos
1475fd0b74Schristos You should have received a copy of the GNU General Public License
1575fd0b74Schristos along with this program; if not, write to the Free Software
1675fd0b74Schristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
1775fd0b74Schristos 02110-1301, USA. */
1875fd0b74Schristos
1975fd0b74Schristos #include "sysdep.h"
2075fd0b74Schristos #include "bfd.h"
2175fd0b74Schristos #include "bucomm.h"
2275fd0b74Schristos
2375fd0b74Schristos static char ftypelet (unsigned long);
2475fd0b74Schristos static void setst (unsigned long, char *);
2575fd0b74Schristos
2675fd0b74Schristos /* filemodestring - fill in string STR with an ls-style ASCII
2775fd0b74Schristos representation of the st_mode field of file stats block STATP.
2875fd0b74Schristos 10 characters are stored in STR; no terminating null is added.
2975fd0b74Schristos The characters stored in STR are:
3075fd0b74Schristos
3175fd0b74Schristos 0 File type. 'd' for directory, 'c' for character
3275fd0b74Schristos special, 'b' for block special, 'm' for multiplex,
3375fd0b74Schristos 'l' for symbolic link, 's' for socket, 'p' for fifo,
3475fd0b74Schristos '-' for any other file type
3575fd0b74Schristos
3675fd0b74Schristos 1 'r' if the owner may read, '-' otherwise.
3775fd0b74Schristos
3875fd0b74Schristos 2 'w' if the owner may write, '-' otherwise.
3975fd0b74Schristos
4075fd0b74Schristos 3 'x' if the owner may execute, 's' if the file is
4175fd0b74Schristos set-user-id, '-' otherwise.
4275fd0b74Schristos 'S' if the file is set-user-id, but the execute
4375fd0b74Schristos bit isn't set.
4475fd0b74Schristos
4575fd0b74Schristos 4 'r' if group members may read, '-' otherwise.
4675fd0b74Schristos
4775fd0b74Schristos 5 'w' if group members may write, '-' otherwise.
4875fd0b74Schristos
4975fd0b74Schristos 6 'x' if group members may execute, 's' if the file is
5075fd0b74Schristos set-group-id, '-' otherwise.
5175fd0b74Schristos 'S' if it is set-group-id but not executable.
5275fd0b74Schristos
5375fd0b74Schristos 7 'r' if any user may read, '-' otherwise.
5475fd0b74Schristos
5575fd0b74Schristos 8 'w' if any user may write, '-' otherwise.
5675fd0b74Schristos
5775fd0b74Schristos 9 'x' if any user may execute, 't' if the file is "sticky"
5875fd0b74Schristos (will be retained in swap space after execution), '-'
5975fd0b74Schristos otherwise.
6075fd0b74Schristos 'T' if the file is sticky but not executable. */
6175fd0b74Schristos
6275fd0b74Schristos /* Get definitions for the file permission bits. */
6375fd0b74Schristos
6475fd0b74Schristos #ifndef S_IRWXU
6575fd0b74Schristos #define S_IRWXU 0700
6675fd0b74Schristos #endif
6775fd0b74Schristos #ifndef S_IRUSR
6875fd0b74Schristos #define S_IRUSR 0400
6975fd0b74Schristos #endif
7075fd0b74Schristos #ifndef S_IWUSR
7175fd0b74Schristos #define S_IWUSR 0200
7275fd0b74Schristos #endif
7375fd0b74Schristos #ifndef S_IXUSR
7475fd0b74Schristos #define S_IXUSR 0100
7575fd0b74Schristos #endif
7675fd0b74Schristos
7775fd0b74Schristos #ifndef S_IRWXG
7875fd0b74Schristos #define S_IRWXG 0070
7975fd0b74Schristos #endif
8075fd0b74Schristos #ifndef S_IRGRP
8175fd0b74Schristos #define S_IRGRP 0040
8275fd0b74Schristos #endif
8375fd0b74Schristos #ifndef S_IWGRP
8475fd0b74Schristos #define S_IWGRP 0020
8575fd0b74Schristos #endif
8675fd0b74Schristos #ifndef S_IXGRP
8775fd0b74Schristos #define S_IXGRP 0010
8875fd0b74Schristos #endif
8975fd0b74Schristos
9075fd0b74Schristos #ifndef S_IRWXO
9175fd0b74Schristos #define S_IRWXO 0007
9275fd0b74Schristos #endif
9375fd0b74Schristos #ifndef S_IROTH
9475fd0b74Schristos #define S_IROTH 0004
9575fd0b74Schristos #endif
9675fd0b74Schristos #ifndef S_IWOTH
9775fd0b74Schristos #define S_IWOTH 0002
9875fd0b74Schristos #endif
9975fd0b74Schristos #ifndef S_IXOTH
10075fd0b74Schristos #define S_IXOTH 0001
10175fd0b74Schristos #endif
10275fd0b74Schristos
10375fd0b74Schristos /* Like filemodestring, but only the relevant part of the `struct stat'
10475fd0b74Schristos is given as an argument. */
10575fd0b74Schristos
10675fd0b74Schristos void
mode_string(unsigned long mode,char * str)10775fd0b74Schristos mode_string (unsigned long mode, char *str)
10875fd0b74Schristos {
10975fd0b74Schristos str[0] = ftypelet ((unsigned long) mode);
11075fd0b74Schristos str[1] = (mode & S_IRUSR) != 0 ? 'r' : '-';
11175fd0b74Schristos str[2] = (mode & S_IWUSR) != 0 ? 'w' : '-';
11275fd0b74Schristos str[3] = (mode & S_IXUSR) != 0 ? 'x' : '-';
11375fd0b74Schristos str[4] = (mode & S_IRGRP) != 0 ? 'r' : '-';
11475fd0b74Schristos str[5] = (mode & S_IWGRP) != 0 ? 'w' : '-';
11575fd0b74Schristos str[6] = (mode & S_IXGRP) != 0 ? 'x' : '-';
11675fd0b74Schristos str[7] = (mode & S_IROTH) != 0 ? 'r' : '-';
11775fd0b74Schristos str[8] = (mode & S_IWOTH) != 0 ? 'w' : '-';
11875fd0b74Schristos str[9] = (mode & S_IXOTH) != 0 ? 'x' : '-';
11975fd0b74Schristos setst ((unsigned long) mode, str);
12075fd0b74Schristos }
12175fd0b74Schristos
12275fd0b74Schristos /* Return a character indicating the type of file described by
12375fd0b74Schristos file mode BITS:
12475fd0b74Schristos 'd' for directories
12575fd0b74Schristos 'b' for block special files
12675fd0b74Schristos 'c' for character special files
12775fd0b74Schristos 'm' for multiplexer files
12875fd0b74Schristos 'l' for symbolic links
12975fd0b74Schristos 's' for sockets
13075fd0b74Schristos 'p' for fifos
13175fd0b74Schristos '-' for any other file type. */
13275fd0b74Schristos
13375fd0b74Schristos #ifndef S_ISDIR
13475fd0b74Schristos #ifdef S_IFDIR
13575fd0b74Schristos #define S_ISDIR(i) (((i) & S_IFMT) == S_IFDIR)
13675fd0b74Schristos #else /* ! defined (S_IFDIR) */
13775fd0b74Schristos #define S_ISDIR(i) (((i) & 0170000) == 040000)
13875fd0b74Schristos #endif /* ! defined (S_IFDIR) */
13975fd0b74Schristos #endif /* ! defined (S_ISDIR) */
14075fd0b74Schristos
14175fd0b74Schristos #ifndef S_ISBLK
14275fd0b74Schristos #ifdef S_IFBLK
14375fd0b74Schristos #define S_ISBLK(i) (((i) & S_IFMT) == S_IFBLK)
14475fd0b74Schristos #else /* ! defined (S_IFBLK) */
14575fd0b74Schristos #define S_ISBLK(i) 0
14675fd0b74Schristos #endif /* ! defined (S_IFBLK) */
14775fd0b74Schristos #endif /* ! defined (S_ISBLK) */
14875fd0b74Schristos
14975fd0b74Schristos #ifndef S_ISCHR
15075fd0b74Schristos #ifdef S_IFCHR
15175fd0b74Schristos #define S_ISCHR(i) (((i) & S_IFMT) == S_IFCHR)
15275fd0b74Schristos #else /* ! defined (S_IFCHR) */
15375fd0b74Schristos #define S_ISCHR(i) 0
15475fd0b74Schristos #endif /* ! defined (S_IFCHR) */
15575fd0b74Schristos #endif /* ! defined (S_ISCHR) */
15675fd0b74Schristos
15775fd0b74Schristos #ifndef S_ISFIFO
15875fd0b74Schristos #ifdef S_IFIFO
15975fd0b74Schristos #define S_ISFIFO(i) (((i) & S_IFMT) == S_IFIFO)
16075fd0b74Schristos #else /* ! defined (S_IFIFO) */
16175fd0b74Schristos #define S_ISFIFO(i) 0
16275fd0b74Schristos #endif /* ! defined (S_IFIFO) */
16375fd0b74Schristos #endif /* ! defined (S_ISFIFO) */
16475fd0b74Schristos
16575fd0b74Schristos #ifndef S_ISSOCK
16675fd0b74Schristos #ifdef S_IFSOCK
16775fd0b74Schristos #define S_ISSOCK(i) (((i) & S_IFMT) == S_IFSOCK)
16875fd0b74Schristos #else /* ! defined (S_IFSOCK) */
16975fd0b74Schristos #define S_ISSOCK(i) 0
17075fd0b74Schristos #endif /* ! defined (S_IFSOCK) */
17175fd0b74Schristos #endif /* ! defined (S_ISSOCK) */
17275fd0b74Schristos
17375fd0b74Schristos #ifndef S_ISLNK
17475fd0b74Schristos #ifdef S_IFLNK
17575fd0b74Schristos #define S_ISLNK(i) (((i) & S_IFMT) == S_IFLNK)
17675fd0b74Schristos #else /* ! defined (S_IFLNK) */
17775fd0b74Schristos #define S_ISLNK(i) 0
17875fd0b74Schristos #endif /* ! defined (S_IFLNK) */
17975fd0b74Schristos #endif /* ! defined (S_ISLNK) */
18075fd0b74Schristos
18175fd0b74Schristos static char
ftypelet(unsigned long bits)18275fd0b74Schristos ftypelet (unsigned long bits)
18375fd0b74Schristos {
18475fd0b74Schristos if (S_ISDIR (bits))
18575fd0b74Schristos return 'd';
18675fd0b74Schristos if (S_ISLNK (bits))
18775fd0b74Schristos return 'l';
18875fd0b74Schristos if (S_ISBLK (bits))
18975fd0b74Schristos return 'b';
19075fd0b74Schristos if (S_ISCHR (bits))
19175fd0b74Schristos return 'c';
19275fd0b74Schristos if (S_ISSOCK (bits))
19375fd0b74Schristos return 's';
19475fd0b74Schristos if (S_ISFIFO (bits))
19575fd0b74Schristos return 'p';
19675fd0b74Schristos
19775fd0b74Schristos #ifdef S_IFMT
19875fd0b74Schristos #ifdef S_IFMPC
19975fd0b74Schristos if ((bits & S_IFMT) == S_IFMPC
20075fd0b74Schristos || (bits & S_IFMT) == S_IFMPB)
20175fd0b74Schristos return 'm';
20275fd0b74Schristos #endif
20375fd0b74Schristos #ifdef S_IFNWK
20475fd0b74Schristos if ((bits & S_IFMT) == S_IFNWK)
20575fd0b74Schristos return 'n';
20675fd0b74Schristos #endif
20775fd0b74Schristos #endif
20875fd0b74Schristos
20975fd0b74Schristos return '-';
21075fd0b74Schristos }
21175fd0b74Schristos
21275fd0b74Schristos /* Set the 's' and 't' flags in file attributes string CHARS,
21375fd0b74Schristos according to the file mode BITS. */
21475fd0b74Schristos
21575fd0b74Schristos static void
setst(unsigned long bits ATTRIBUTE_UNUSED,char * chars ATTRIBUTE_UNUSED)21675fd0b74Schristos setst (unsigned long bits ATTRIBUTE_UNUSED, char *chars ATTRIBUTE_UNUSED)
21775fd0b74Schristos {
21875fd0b74Schristos #ifdef S_ISUID
21975fd0b74Schristos if (bits & S_ISUID)
22075fd0b74Schristos {
22175fd0b74Schristos if (chars[3] != 'x')
22275fd0b74Schristos /* Set-uid, but not executable by owner. */
22375fd0b74Schristos chars[3] = 'S';
22475fd0b74Schristos else
22575fd0b74Schristos chars[3] = 's';
22675fd0b74Schristos }
22775fd0b74Schristos #endif
22875fd0b74Schristos #ifdef S_ISGID
22975fd0b74Schristos if (bits & S_ISGID)
23075fd0b74Schristos {
23175fd0b74Schristos if (chars[6] != 'x')
23275fd0b74Schristos /* Set-gid, but not executable by group. */
23375fd0b74Schristos chars[6] = 'S';
23475fd0b74Schristos else
23575fd0b74Schristos chars[6] = 's';
23675fd0b74Schristos }
23775fd0b74Schristos #endif
23875fd0b74Schristos #ifdef S_ISVTX
23975fd0b74Schristos if (bits & S_ISVTX)
24075fd0b74Schristos {
24175fd0b74Schristos if (chars[9] != 'x')
24275fd0b74Schristos /* Sticky, but not executable by others. */
24375fd0b74Schristos chars[9] = 'T';
24475fd0b74Schristos else
24575fd0b74Schristos chars[9] = 't';
24675fd0b74Schristos }
24775fd0b74Schristos #endif
24875fd0b74Schristos }
249