OS.js 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. /**
  2. * Operating system operations.
  3. *
  4. * @author n1474335 [n1474335@gmail.com]
  5. * @copyright Crown Copyright 2016
  6. * @license Apache-2.0
  7. *
  8. * @namespace
  9. */
  10. const OS = {
  11. /**
  12. * Parse UNIX file permissions operation.
  13. *
  14. * @param {string} input
  15. * @param {Object[]} args
  16. * @returns {string}
  17. */
  18. runParseUnixPerms: function(input, args) {
  19. var perms = {
  20. d : false, // directory
  21. sl : false, // symbolic link
  22. np : false, // named pipe
  23. s : false, // socket
  24. cd : false, // character device
  25. bd : false, // block device
  26. dr : false, // door
  27. sb : false, // sticky bit
  28. su : false, // setuid
  29. sg : false, // setgid
  30. ru : false, // read user
  31. wu : false, // write user
  32. eu : false, // execute user
  33. rg : false, // read group
  34. wg : false, // write group
  35. eg : false, // execute group
  36. ro : false, // read other
  37. wo : false, // write other
  38. eo : false // execute other
  39. },
  40. d = 0,
  41. u = 0,
  42. g = 0,
  43. o = 0,
  44. output = "",
  45. octal = null,
  46. textual = null;
  47. if (input.search(/\s*[0-7]{1,4}\s*/i) === 0) {
  48. // Input is octal
  49. octal = input.match(/\s*([0-7]{1,4})\s*/i)[1];
  50. if (octal.length === 4) {
  51. d = parseInt(octal[0], 8);
  52. u = parseInt(octal[1], 8);
  53. g = parseInt(octal[2], 8);
  54. o = parseInt(octal[3], 8);
  55. } else {
  56. if (octal.length > 0) u = parseInt(octal[0], 8);
  57. if (octal.length > 1) g = parseInt(octal[1], 8);
  58. if (octal.length > 2) o = parseInt(octal[2], 8);
  59. }
  60. perms.su = d >> 2 & 0x1;
  61. perms.sg = d >> 1 & 0x1;
  62. perms.sb = d & 0x1;
  63. perms.ru = u >> 2 & 0x1;
  64. perms.wu = u >> 1 & 0x1;
  65. perms.eu = u & 0x1;
  66. perms.rg = g >> 2 & 0x1;
  67. perms.wg = g >> 1 & 0x1;
  68. perms.eg = g & 0x1;
  69. perms.ro = o >> 2 & 0x1;
  70. perms.wo = o >> 1 & 0x1;
  71. perms.eo = o & 0x1;
  72. } else if (input.search(/\s*[dlpcbDrwxsStT-]{1,10}\s*/) === 0) {
  73. // Input is textual
  74. textual = input.match(/\s*([dlpcbDrwxsStT-]{1,10})\s*/)[1];
  75. switch (textual[0]) {
  76. case "d":
  77. perms.d = true;
  78. break;
  79. case "l":
  80. perms.sl = true;
  81. break;
  82. case "p":
  83. perms.np = true;
  84. break;
  85. case "s":
  86. perms.s = true;
  87. break;
  88. case "c":
  89. perms.cd = true;
  90. break;
  91. case "b":
  92. perms.bd = true;
  93. break;
  94. case "D":
  95. perms.dr = true;
  96. break;
  97. }
  98. if (textual.length > 1) perms.ru = textual[1] === "r";
  99. if (textual.length > 2) perms.wu = textual[2] === "w";
  100. if (textual.length > 3) {
  101. switch (textual[3]) {
  102. case "x":
  103. perms.eu = true;
  104. break;
  105. case "s":
  106. perms.eu = true;
  107. perms.su = true;
  108. break;
  109. case "S":
  110. perms.su = true;
  111. break;
  112. }
  113. }
  114. if (textual.length > 4) perms.rg = textual[4] === "r";
  115. if (textual.length > 5) perms.wg = textual[5] === "w";
  116. if (textual.length > 6) {
  117. switch (textual[6]) {
  118. case "x":
  119. perms.eg = true;
  120. break;
  121. case "s":
  122. perms.eg = true;
  123. perms.sg = true;
  124. break;
  125. case "S":
  126. perms.sg = true;
  127. break;
  128. }
  129. }
  130. if (textual.length > 7) perms.ro = textual[7] === "r";
  131. if (textual.length > 8) perms.wo = textual[8] === "w";
  132. if (textual.length > 9) {
  133. switch (textual[9]) {
  134. case "x":
  135. perms.eo = true;
  136. break;
  137. case "t":
  138. perms.eo = true;
  139. perms.sb = true;
  140. break;
  141. case "T":
  142. perms.sb = true;
  143. break;
  144. }
  145. }
  146. } else {
  147. return "Invalid input format.\nPlease enter the permissions in either octal (e.g. 755) or textual (e.g. drwxr-xr-x) format.";
  148. }
  149. output += "Textual representation: " + OS._permsToStr(perms);
  150. output += "\nOctal representation: " + OS._permsToOctal(perms);
  151. // File type
  152. if (textual) {
  153. output += "\nFile type: " + OS._ftFromPerms(perms);
  154. }
  155. // setuid, setgid
  156. if (perms.su) {
  157. output += "\nThe setuid flag is set";
  158. }
  159. if (perms.sg) {
  160. output += "\nThe setgid flag is set";
  161. }
  162. // sticky bit
  163. if (perms.sb) {
  164. output += "\nThe sticky bit is set";
  165. }
  166. // Permission matrix
  167. output += "\n\n +---------+-------+-------+-------+\n" +
  168. " | | User | Group | Other |\n" +
  169. " +---------+-------+-------+-------+\n" +
  170. " | Read | " + (perms.ru ? "X" : " ") + " | " + (perms.rg ? "X" : " ") + " | " + (perms.ro ? "X" : " ") + " |\n" +
  171. " +---------+-------+-------+-------+\n" +
  172. " | Write | " + (perms.wu ? "X" : " ") + " | " + (perms.wg ? "X" : " ") + " | " + (perms.wo ? "X" : " ") + " |\n" +
  173. " +---------+-------+-------+-------+\n" +
  174. " | Execute | " + (perms.eu ? "X" : " ") + " | " + (perms.eg ? "X" : " ") + " | " + (perms.eo ? "X" : " ") + " |\n" +
  175. " +---------+-------+-------+-------+\n";
  176. return output;
  177. },
  178. /**
  179. * Given a permissions object dictionary, generates a textual permissions string.
  180. *
  181. * @private
  182. * @param {Object} perms
  183. * @returns {string}
  184. */
  185. _permsToStr: function(perms) {
  186. var str = "",
  187. type = "-";
  188. if (perms.d) type = "d";
  189. if (perms.sl) type = "l";
  190. if (perms.np) type = "p";
  191. if (perms.s) type = "s";
  192. if (perms.cd) type = "c";
  193. if (perms.bd) type = "b";
  194. if (perms.dr) type = "D";
  195. str = type;
  196. str += perms.ru ? "r" : "-";
  197. str += perms.wu ? "w" : "-";
  198. if (perms.eu && perms.su) {
  199. str += "s";
  200. } else if (perms.su) {
  201. str += "S";
  202. } else if (perms.eu) {
  203. str += "x";
  204. } else {
  205. str += "-";
  206. }
  207. str += perms.rg ? "r" : "-";
  208. str += perms.wg ? "w" : "-";
  209. if (perms.eg && perms.sg) {
  210. str += "s";
  211. } else if (perms.sg) {
  212. str += "S";
  213. } else if (perms.eg) {
  214. str += "x";
  215. } else {
  216. str += "-";
  217. }
  218. str += perms.ro ? "r" : "-";
  219. str += perms.wo ? "w" : "-";
  220. if (perms.eo && perms.sb) {
  221. str += "t";
  222. } else if (perms.sb) {
  223. str += "T";
  224. } else if (perms.eo) {
  225. str += "x";
  226. } else {
  227. str += "-";
  228. }
  229. return str;
  230. },
  231. /**
  232. * Given a permissions object dictionary, generates an octal permissions string.
  233. *
  234. * @private
  235. * @param {Object} perms
  236. * @returns {string}
  237. */
  238. _permsToOctal: function(perms) {
  239. var d = 0,
  240. u = 0,
  241. g = 0,
  242. o = 0;
  243. if (perms.su) d += 4;
  244. if (perms.sg) d += 2;
  245. if (perms.sb) d += 1;
  246. if (perms.ru) u += 4;
  247. if (perms.wu) u += 2;
  248. if (perms.eu) u += 1;
  249. if (perms.rg) g += 4;
  250. if (perms.wg) g += 2;
  251. if (perms.eg) g += 1;
  252. if (perms.ro) o += 4;
  253. if (perms.wo) o += 2;
  254. if (perms.eo) o += 1;
  255. return d.toString() + u.toString() + g.toString() + o.toString();
  256. },
  257. /**
  258. * Given a permissions object dictionary, returns the file type.
  259. *
  260. * @private
  261. * @param {Object} perms
  262. * @returns {string}
  263. */
  264. _ftFromPerms: function(perms) {
  265. if (perms.d) return "Directory";
  266. if (perms.sl) return "Symbolic link";
  267. if (perms.np) return "Named pipe";
  268. if (perms.s) return "Socket";
  269. if (perms.cd) return "Character device";
  270. if (perms.bd) return "Block device";
  271. if (perms.dr) return "Door";
  272. return "Regular file";
  273. },
  274. };
  275. export default OS;