129 lines
4.0 KiB
JavaScript
129 lines
4.0 KiB
JavaScript
const fs = require('fs')
|
|
|
|
|
|
let paths = []
|
|
let options = []
|
|
|
|
for(arg of process.argv.slice(3)){
|
|
if(arg.startsWith('--')){
|
|
options.push(arg)
|
|
}
|
|
else if(arg.startsWith('-')){
|
|
for(let option of arg.slice(1)){
|
|
options.push('-' + option);
|
|
}
|
|
}
|
|
else{
|
|
paths.push(arg)
|
|
}
|
|
}
|
|
|
|
if(paths.length == 0){
|
|
paths = ['.'];
|
|
}
|
|
|
|
|
|
try{
|
|
|
|
listFiles(paths[0], options)
|
|
}
|
|
catch(e){
|
|
switch(e.code){
|
|
case "ENOENT":
|
|
console.error(`path "${paths[0]}" does not exist`);
|
|
break;
|
|
default:
|
|
console.error(`ls: ${e.code}`)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
function listFiles(path, options){
|
|
const files = ['.', '..'].concat(fs.readdirSync(paths[0]))
|
|
const nonHiddenFiles = files.filter(file => file[0] != '.')
|
|
colorList = JSON.parse(process.env.ls_color)
|
|
if(options.includes('-l')){
|
|
console.log(`total ${options.includes('-a') ? files.length : nonHiddenFiles.length}`)
|
|
for(let file of options.includes('-a') ? files : nonHiddenFiles){
|
|
|
|
stats = fs.lstatSync(`${path}/${file}`);
|
|
mode = stats.mode
|
|
result = ""
|
|
let color = []
|
|
let defaultColor = "\x1b[0m"
|
|
let fileType = "-"
|
|
if(stats.isFile()){
|
|
fileType = "-";
|
|
if(stats.mode & 00100){ //owner can execute
|
|
color = colorList.ex ? `\x1b[${colorList.ex[0]}m\x1b[${colorList.ex[1]}m` : "\x1b[0m"
|
|
}
|
|
}
|
|
else if (stats.isDirectory()) {
|
|
fileType = "d";
|
|
color = colorList.di ? `\x1b[${colorList.di[0]}m\x1b[${colorList.di[1]}m` : "\x1b[0m"
|
|
}
|
|
else if (stats.isSymbolicLink()){
|
|
fileType = "l"
|
|
color = colorList.ln ? `\x1b[${colorList.ln[0]}m\x1b[${colorList.ln[1]}m` : "\x1b[0m"
|
|
}
|
|
result += fileType;
|
|
permissions = "xwr"
|
|
for(let i=8;i>=0;i--){
|
|
result += parseInt(Math.pow(2,i).toString(2)) & mode ? permissions[i%3] : '-'
|
|
}
|
|
if(01000 & mode){ // check sticky bit
|
|
color = "\x1b[40m\x1b[92m\x1b[7m"
|
|
}
|
|
let date = new Date(stats.mtimeMs*1000).toDateString().split(' ');
|
|
result += ` ${usernameFromUID(stats.uid)}\t${groupnameFromGID(stats.gid)}\t${stats.size}\t${date[2]} ${date[1]}. ${options.includes('--color') ? color : ""}${file}${defaultColor}`
|
|
console.log(result)
|
|
}
|
|
}
|
|
else{
|
|
result = ""
|
|
const defaultColor = "\x1b[0m";
|
|
if(options.includes('--color')){
|
|
for(let file of options.includes('-a') ? files : nonHiddenFiles){
|
|
stats = fs.lstatSync(`${path}/${file}`);
|
|
let color = defaultColor
|
|
if(stats.isDirectory()){
|
|
color = colorList.di ? `\x1b[${colorList.di[1]}m\x1b[${colorList.di[0]}m` : defaultColor
|
|
}
|
|
else if (stats.isSymbolicLink()){
|
|
color = colorList.ln ? `\x1b[${colorList.ln[1]}m\x1b[${colorList.ln[0]}m` : defaultColor
|
|
}
|
|
if(01000 & stats.mode){ // check sticky bit
|
|
color = "\x1b[40m\x1b[92m\x1b[7m"
|
|
}
|
|
result += color + file + defaultColor + " ";
|
|
}
|
|
console.log(result)
|
|
}else{
|
|
console.log(options.includes('-a') ? files.join(' ') : nonHiddenFiles.join(' '))
|
|
}
|
|
}
|
|
}
|
|
|
|
function usernameFromUID(uid){
|
|
const passwd = fs.readFileSync("/etc/passwd", {encoding: 'utf-8'}).split('\n');
|
|
for(let line of passwd){
|
|
let lineSplited = line.split(':')
|
|
if(lineSplited[2] == uid){
|
|
return lineSplited[0];
|
|
}
|
|
}
|
|
return uid
|
|
}
|
|
|
|
function groupnameFromGID(uid){
|
|
const passwd = fs.readFileSync("/etc/passwd", {encoding: 'utf-8'}).split('\n');
|
|
for(let line of passwd){
|
|
let lineSplited = line.split(':')
|
|
if(lineSplited[3] == uid){
|
|
return lineSplited[0];
|
|
}
|
|
}
|
|
return uid
|
|
} |