xref: /netbsd-src/external/gpl3/binutils.old/dist/binutils/filemode.c (revision e992f068c547fd6e84b3f104dc2340adcc955732)
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