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