1 /* filemode.c -- make a string describing file modes 2 Copyright 1985, 1990, 1991, 1994, 1995, 1997, 1999, 2002, 2003, 2005 3 Free Software Foundation, Inc. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2, or (at your option) 8 any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 18 02110-1301, USA. */ 19 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 } 249