filemode.c 6.0 KB

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