/** * Operating system operations. * * @author n1474335 [n1474335@gmail.com] * @copyright Crown Copyright 2016 * @license Apache-2.0 * * @namespace */ var OS = module.exports = { /** * Parse UNIX file permissions operation. * * @param {string} input * @param {Object[]} args * @returns {string} */ runParseUnixPerms: function(input, args) { var perms = { d : false, // directory sl : false, // symbolic link np : false, // named pipe s : false, // socket cd : false, // character device bd : false, // block device dr : false, // door sb : false, // sticky bit su : false, // setuid sg : false, // setgid ru : false, // read user wu : false, // write user eu : false, // execute user rg : false, // read group wg : false, // write group eg : false, // execute group ro : false, // read other wo : false, // write other eo : false // execute other }, d = 0, u = 0, g = 0, o = 0, output = "", octal = null, textual = null; if (input.search(/\s*[0-7]{1,4}\s*/i) === 0) { // Input is octal octal = input.match(/\s*([0-7]{1,4})\s*/i)[1]; if (octal.length === 4) { d = parseInt(octal[0], 8); u = parseInt(octal[1], 8); g = parseInt(octal[2], 8); o = parseInt(octal[3], 8); } else { if (octal.length > 0) u = parseInt(octal[0], 8); if (octal.length > 1) g = parseInt(octal[1], 8); if (octal.length > 2) o = parseInt(octal[2], 8); } perms.su = d >> 2 & 0x1; perms.sg = d >> 1 & 0x1; perms.sb = d & 0x1; perms.ru = u >> 2 & 0x1; perms.wu = u >> 1 & 0x1; perms.eu = u & 0x1; perms.rg = g >> 2 & 0x1; perms.wg = g >> 1 & 0x1; perms.eg = g & 0x1; perms.ro = o >> 2 & 0x1; perms.wo = o >> 1 & 0x1; perms.eo = o & 0x1; } else if (input.search(/\s*[dlpcbDrwxsStT-]{1,10}\s*/) === 0) { // Input is textual textual = input.match(/\s*([dlpcbDrwxsStT-]{1,10})\s*/)[1]; switch (textual[0]) { case "d": perms.d = true; break; case "l": perms.sl = true; break; case "p": perms.np = true; break; case "s": perms.s = true; break; case "c": perms.cd = true; break; case "b": perms.bd = true; break; case "D": perms.dr = true; break; } if (textual.length > 1) perms.ru = textual[1] === "r"; if (textual.length > 2) perms.wu = textual[2] === "w"; if (textual.length > 3) { switch (textual[3]) { case "x": perms.eu = true; break; case "s": perms.eu = true; perms.su = true; break; case "S": perms.su = true; break; } } if (textual.length > 4) perms.rg = textual[4] === "r"; if (textual.length > 5) perms.wg = textual[5] === "w"; if (textual.length > 6) { switch (textual[6]) { case "x": perms.eg = true; break; case "s": perms.eg = true; perms.sg = true; break; case "S": perms.sg = true; break; } } if (textual.length > 7) perms.ro = textual[7] === "r"; if (textual.length > 8) perms.wo = textual[8] === "w"; if (textual.length > 9) { switch (textual[9]) { case "x": perms.eo = true; break; case "t": perms.eo = true; perms.sb = true; break; case "T": perms.sb = true; break; } } } else { return "Invalid input format.\nPlease enter the permissions in either octal (e.g. 755) or textual (e.g. drwxr-xr-x) format."; } output += "Textual representation: " + OS._permsToStr(perms); output += "\nOctal representation: " + OS._permsToOctal(perms); // File type if (textual) { output += "\nFile type: " + OS._ftFromPerms(perms); } // setuid, setgid if (perms.su) { output += "\nThe setuid flag is set"; } if (perms.sg) { output += "\nThe setgid flag is set"; } // sticky bit if (perms.sb) { output += "\nThe sticky bit is set"; } // Permission matrix output += "\n\n +---------+-------+-------+-------+\n" + " | | User | Group | Other |\n" + " +---------+-------+-------+-------+\n" + " | Read | " + (perms.ru ? "X" : " ") + " | " + (perms.rg ? "X" : " ") + " | " + (perms.ro ? "X" : " ") + " |\n" + " +---------+-------+-------+-------+\n" + " | Write | " + (perms.wu ? "X" : " ") + " | " + (perms.wg ? "X" : " ") + " | " + (perms.wo ? "X" : " ") + " |\n" + " +---------+-------+-------+-------+\n" + " | Execute | " + (perms.eu ? "X" : " ") + " | " + (perms.eg ? "X" : " ") + " | " + (perms.eo ? "X" : " ") + " |\n" + " +---------+-------+-------+-------+\n"; return output; }, /** * Given a permissions object dictionary, generates a textual permissions string. * * @private * @param {Object} perms * @returns {string} */ _permsToStr: function(perms) { var str = "", type = "-"; if (perms.d) type = "d"; if (perms.sl) type = "l"; if (perms.np) type = "p"; if (perms.s) type = "s"; if (perms.cd) type = "c"; if (perms.bd) type = "b"; if (perms.dr) type = "D"; str = type; str += perms.ru ? "r" : "-"; str += perms.wu ? "w" : "-"; if (perms.eu && perms.su) { str += "s"; } else if (perms.su) { str += "S"; } else if (perms.eu) { str += "x"; } else { str += "-"; } str += perms.rg ? "r" : "-"; str += perms.wg ? "w" : "-"; if (perms.eg && perms.sg) { str += "s"; } else if (perms.sg) { str += "S"; } else if (perms.eg) { str += "x"; } else { str += "-"; } str += perms.ro ? "r" : "-"; str += perms.wo ? "w" : "-"; if (perms.eo && perms.sb) { str += "t"; } else if (perms.sb) { str += "T"; } else if (perms.eo) { str += "x"; } else { str += "-"; } return str; }, /** * Given a permissions object dictionary, generates an octal permissions string. * * @private * @param {Object} perms * @returns {string} */ _permsToOctal: function(perms) { var d = 0, u = 0, g = 0, o = 0; if (perms.su) d += 4; if (perms.sg) d += 2; if (perms.sb) d += 1; if (perms.ru) u += 4; if (perms.wu) u += 2; if (perms.eu) u += 1; if (perms.rg) g += 4; if (perms.wg) g += 2; if (perms.eg) g += 1; if (perms.ro) o += 4; if (perms.wo) o += 2; if (perms.eo) o += 1; return d.toString() + u.toString() + g.toString() + o.toString(); }, /** * Given a permissions object dictionary, returns the file type. * * @private * @param {Object} perms * @returns {string} */ _ftFromPerms: function(perms) { if (perms.d) return "Directory"; if (perms.sl) return "Symbolic link"; if (perms.np) return "Named pipe"; if (perms.s) return "Socket"; if (perms.cd) return "Character device"; if (perms.bd) return "Block device"; if (perms.dr) return "Door"; return "Regular file"; }, };