logo

utils-std

Collection of commonly available Unix tools git clone https://anongit.hacktivis.me/git/utils-std.git

mode.c (7129B)


  1. // utils-std: Collection of commonly available Unix tools
  2. // SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
  3. // SPDX-License-Identifier: MPL-2.0
  4. #define _POSIX_C_SOURCE 200809L
  5. #include "../lib/mode.h"
  6. #include <assert.h>
  7. #include <stdio.h> // printf
  8. #include <string.h> // strcmp
  9. #include <sys/stat.h> // umask
  10. int counter = 0;
  11. int t_err = 0;
  12. static void
  13. t_mode(const char *str, mode_t old, mode_t expect)
  14. {
  15. int id = ++counter;
  16. const char *errstr = NULL;
  17. mode_t got = new_mode(str, old, &errstr);
  18. if(got == expect && errstr == NULL)
  19. {
  20. printf("ok %d - new_mode(\"%s\", 0%06o) == 0%06o\n", id, str, old, expect);
  21. return;
  22. }
  23. t_err = 1;
  24. printf("not ok %d - new_mode(\"%s\", 0%06o) == 0%06o\n", id, str, old, expect);
  25. if(got != expect) printf("# Got: 0%06o\n", got);
  26. if(errstr != NULL) printf("# Errstr: \"%s\"\n", errstr);
  27. }
  28. static void
  29. t_mode_errstr(const char *str, mode_t old, const char *expect_errstr)
  30. {
  31. assert(expect_errstr != NULL);
  32. int id = ++counter;
  33. const char *errstr = NULL;
  34. (void)new_mode(str, old, &errstr);
  35. if(errstr != NULL && strcmp(errstr, expect_errstr) == 0)
  36. {
  37. printf("ok %d - new_mode(\"%s\", 0%06o) -> %s\n", id, str, old, expect_errstr);
  38. }
  39. else
  40. {
  41. printf("not ok %d - new_mode(\"%s\", 0%06o) -> %s\n", id, str, old, expect_errstr);
  42. printf("# Got errstr: \"%s\"\n", errstr);
  43. t_err = 1;
  44. }
  45. }
  46. static void
  47. add_read(void)
  48. {
  49. printf("# => add_read\n");
  50. umask(0044);
  51. t_mode("+r", 0, 00400);
  52. t_mode("a+r", 0, 00444);
  53. t_mode("u+r", 0, 00400);
  54. t_mode("g+r", 0, 00040);
  55. t_mode("o+r", 0, 00004);
  56. t_mode("ug+r", 0, 00440);
  57. t_mode("go+r", 0, 00044);
  58. t_mode("uo+r", 0, 00404);
  59. t_mode("u+r,g+r", 0, 00440);
  60. t_mode("g+r,o+r", 0, 00044);
  61. t_mode("u+r,o+r", 0, 00404);
  62. t_mode("+r", 00777, 00777);
  63. t_mode("a+r", 00777, 00777);
  64. t_mode("u+r", 00777, 00777);
  65. t_mode("g+r", 00777, 00777);
  66. t_mode("o+r", 00777, 00777);
  67. t_mode("ug+r", 00777, 00777);
  68. t_mode("go+r", 00777, 00777);
  69. t_mode("uo+r", 00777, 00777);
  70. t_mode("u+r,g+r", 00777, 00777);
  71. t_mode("g+r,o+r", 00777, 00777);
  72. t_mode("u+r,o+r", 00777, 00777);
  73. }
  74. static void
  75. set_read(void)
  76. {
  77. printf("# => set_read\n");
  78. umask(0044);
  79. t_mode("=r", 0, 00400);
  80. t_mode("a=r", 0, 00444);
  81. t_mode("u=r", 0, 00400);
  82. t_mode("g=r", 0, 00040);
  83. t_mode("o=r", 0, 00004);
  84. t_mode("ug=r", 0, 00440);
  85. t_mode("go=r", 0, 00044);
  86. t_mode("uo=r", 0, 00404);
  87. t_mode("u=r,g=r", 0, 00440);
  88. t_mode("g=r,o=r", 0, 00044);
  89. t_mode("u=r,o=r", 0, 00404);
  90. t_mode("go=,u=xr", 0, 00500);
  91. t_mode("go=,u=xr", 00777, 00500);
  92. t_mode("=r", 00777, 00400);
  93. t_mode("a=r", 00777, 00444);
  94. t_mode("u=r", 00777, 00477);
  95. t_mode("g=r", 00777, 00747);
  96. t_mode("o=r", 00777, 00774);
  97. t_mode("ug=r", 00777, 00447);
  98. t_mode("go=r", 00777, 00744);
  99. t_mode("uo=r", 00777, 00474);
  100. t_mode("u=r,g=r", 00777, 00447);
  101. t_mode("g=r,o=r", 00777, 00744);
  102. t_mode("u=r,o=r", 00777, 00474);
  103. }
  104. static void
  105. del_read(void)
  106. {
  107. printf("# => del_read\n");
  108. umask(0044);
  109. t_mode("-r", 0, 0);
  110. t_mode("a-r", 0, 0);
  111. t_mode("u-r", 0, 0);
  112. t_mode("g-r", 0, 0);
  113. t_mode("o-r", 0, 0);
  114. t_mode("ug-r", 0, 0);
  115. t_mode("go-r", 0, 0);
  116. t_mode("uo-r", 0, 0);
  117. t_mode("u-r,g-r", 0, 0);
  118. t_mode("g-r,o-r", 0, 0);
  119. t_mode("u-r,o-r", 0, 0);
  120. t_mode("-r", 00777, 00377);
  121. t_mode("a-r", 00777, 00333);
  122. t_mode("u-r", 00777, 00377);
  123. t_mode("g-r", 00777, 00737);
  124. t_mode("o-r", 00777, 00773);
  125. t_mode("ug-r", 00777, 00337);
  126. t_mode("go-r", 00777, 00733);
  127. t_mode("uo-r", 00777, 00373);
  128. t_mode("u-r,g-r", 00777, 00337);
  129. t_mode("g-r,o-r", 00777, 00733);
  130. t_mode("u-r,o-r", 00777, 00373);
  131. }
  132. static void
  133. search(void)
  134. {
  135. printf("# => search\n");
  136. t_mode("-X", 0, 0);
  137. t_mode("a-X", 0, 0);
  138. t_mode("u-X", 0, 0);
  139. t_mode("g-X", 0, 0);
  140. t_mode("o-X", 0, 0);
  141. t_mode("+X", 0, 0);
  142. t_mode("a+X", 0, 0);
  143. t_mode("u+X", 0, 0);
  144. t_mode("g+X", 0, 0);
  145. t_mode("o+X", 0, 0);
  146. t_mode("=X", 0, 0);
  147. t_mode("a=X", 0, 0);
  148. t_mode("u=X", 0, 0);
  149. t_mode("g=X", 0, 0);
  150. t_mode("o=X", 0, 0);
  151. // S_IFDIR = 0040000
  152. t_mode("-X", 0040777, 0040666);
  153. t_mode("a-X", 0040777, 0040666);
  154. t_mode("u-X", 0040777, 0040677);
  155. t_mode("g-X", 0040777, 0040767);
  156. t_mode("o-X", 0040777, 0040776);
  157. t_mode("+X", 0040777, 0040777);
  158. t_mode("a+X", 0040777, 0040777);
  159. t_mode("u+X", 0040777, 0040777);
  160. t_mode("g+X", 0040777, 0040777);
  161. t_mode("o+X", 0040777, 0040777);
  162. t_mode("=X", 0040777, 0040111);
  163. t_mode("a=X", 0040777, 0040111);
  164. t_mode("u=X", 0040777, 0040177);
  165. t_mode("g=X", 0040777, 0040717);
  166. t_mode("o=X", 0040777, 0040771);
  167. t_mode("-X", 0040000, 0040000);
  168. t_mode("a-X", 0040000, 0040000);
  169. t_mode("u-X", 0040000, 0040000);
  170. t_mode("g-X", 0040000, 0040000);
  171. t_mode("o-X", 0040000, 0040000);
  172. t_mode("+X", 0040000, 0040111);
  173. t_mode("a+X", 0040000, 0040111);
  174. t_mode("u+X", 0040000, 0040100);
  175. t_mode("g+X", 0040000, 0040010);
  176. t_mode("o+X", 0040000, 0040001);
  177. t_mode("=X", 0040000, 0040111);
  178. t_mode("a=X", 0040000, 0040111);
  179. t_mode("u=X", 0040000, 0040100);
  180. t_mode("g=X", 0040000, 0040010);
  181. t_mode("o=X", 0040000, 0040001);
  182. }
  183. static void
  184. syntax(void)
  185. {
  186. printf("# => syntax\n");
  187. t_mode("=", 0, 0);
  188. t_mode("=", 0040777, 0040000);
  189. t_mode("-", 0, 0);
  190. t_mode("-", 0040777, 0040777);
  191. t_mode("+", 0, 0);
  192. t_mode("+", 0040777, 0040777);
  193. t_mode_errstr("/", 0, "syntax error, got invalid character");
  194. t_mode_errstr("foo", 0, "syntax error, got invalid character");
  195. t_mode_errstr("77777", 0, "can't be higher than 0o7777");
  196. t_mode_errstr("-0", 0, "syntax error, got invalid character");
  197. }
  198. static void
  199. posix_examples(void)
  200. {
  201. // Examples as given by POSIX in chmod(1p)
  202. printf("# => posix_examples\n");
  203. // clears all file mode bits.
  204. t_mode("a+=", 0040777, 0040000);
  205. t_mode("a+=", 0040000, 0040000);
  206. // clears group and other write bits
  207. t_mode("go+-w", 0040777, 0040755);
  208. t_mode("go+-w", 0040000, 0040000);
  209. // sets group bit to match other bits and then clears group write bit.
  210. t_mode("g=o-w", 0040777, 0040757);
  211. t_mode("g=o-w", 0040642, 0040602);
  212. t_mode("g=o-w", 0040246, 0040246);
  213. t_mode("g=o-w", 0040000, 0040000);
  214. // clears group read bit and sets group write bit.
  215. t_mode("g-r+w", 0040777, 0040737);
  216. t_mode("g-r+w", 0040000, 0040020);
  217. // Sets owner bits to match group bits and sets other bits to match group bits.
  218. t_mode("uo=g", 0040777, 0040777);
  219. t_mode("uo=g", 0040642, 0040444);
  220. t_mode("uo=g", 0040000, 0040000);
  221. }
  222. static void
  223. non_symbolic(void)
  224. {
  225. printf("# => non_symbolic\n");
  226. t_mode("0", 0, 0);
  227. t_mode("0", 0040777, 0040000);
  228. t_mode("7", 0, 07);
  229. t_mode("7", 0040777, 0040007);
  230. t_mode("77", 0, 077);
  231. t_mode("77", 0040777, 0040077);
  232. t_mode("777", 0, 0777);
  233. t_mode("777", 0040777, 0040777);
  234. t_mode("700", 0, 0700);
  235. t_mode("700", 0040777, 0040700);
  236. t_mode("7777", 0, 07777);
  237. t_mode("7777", 0040777, 0047777);
  238. }
  239. int
  240. main(void)
  241. {
  242. int plan = 155;
  243. printf("1..%d\n", plan);
  244. t_mode(NULL, 0, 0);
  245. t_mode(NULL, 00777, 00777);
  246. t_mode("", 0, 0);
  247. t_mode("", 00777, 00777);
  248. t_mode(",", 0, 0);
  249. t_mode(",", 00777, 00777);
  250. t_mode("-w,+x", 00666, 00577);
  251. add_read();
  252. set_read();
  253. del_read();
  254. search();
  255. posix_examples();
  256. syntax();
  257. non_symbolic();
  258. assert(counter == plan);
  259. return t_err;
  260. }