chmod command

This commit is contained in:
Lisa Milne 2023-12-03 18:13:57 +10:00
parent 755c79dd46
commit 5aa0ee97c9

View file

@ -668,6 +668,311 @@ Options:
return 0;
});
clite.commands.load('chmod',function(args,env,io) {
var short = '';
var file = null;
var stdlib = io.include('stdlib');
var stdio = io.include('stdio');
var clite = io.include('clite');
var recurse = false;
var modmask = null;
function help() {
stdio.printf(`
chmod - change file mode bits
Usage: chmod [OPTION] <MODE> <FILE>
Options:
-? Print this help information
`);
}
function getModMask(str) {
var parts = str.split(',');
var modmask = ['???','???','???'];
if (parts.length == 1 && (str.length == 3 || str.length == 4)) {
var iv = parseInt(str,10);
if (iv > 0) {
if (str.length == 4)
str = str.substring(1);
for (var i=0; i<str.length; i++) {
switch(str[i]) {
case '0':
modmask[i] = '---';
break;
case '1':
modmask[i] = '--x';
break;
case '2':
modmask[i] = '-w-';
break;
case '3':
modmask[i] = '-wx';
break;
case '4':
modmask[i] = 'r--';
break;
case '5':
modmask[i] = 'r-x';
break;
case '6':
modmask[i] = 'rw-';
break;
case '7':
modmask[i] = 'rwx';
break;
}
}
return modmask.join('');
}
}
parts.forEach(function(p) { // [who]op[perm]
var u = false;
var g = false;
var o = false;
var op = null;
var s = 0;
for (var i=0; i<p.length; i++) {
if (s == 0) {
switch (p[i]) {
case 'u':
u = true;
break;
case 'g':
g = true;
break;
case 'o':
o = true;
break;
case 'a':
u = true;
g = true;
o = true;
break;
case '=':
case '+':
case '-':
op = p[i];
s = 1;
if (!u && !g && !o) {
u = true;
g = true;
o = true;
}
if (op == '=') {
if (u)
modmask[0] = '---';
if (g)
modmask[1] = '---';
if (o)
modmask[2] = '---';
}
break;
}
}else if (s == 1) {
switch (p[i]) {
case 'r':
if (u) {
if (op == '=' || op == '+') {
modmask[0] = 'r'+modmask[0][1]+modmask[0][2];
}else if (op = '-') {
modmask[0] = '-'+modmask[0][1]+modmask[0][2];
}
}
if (g) {
if (op == '=' || op == '+') {
modmask[1] = 'r'+modmask[1][1]+modmask[1][2];
}else if (op = '-') {
modmask[1] = '-'+modmask[1][1]+modmask[1][2];
}
}
if (o) {
if (op == '=' || op == '+') {
modmask[2] = 'r'+modmask[2][1]+modmask[2][2];
}else if (op = '-') {
modmask[2] = '-'+modmask[2][1]+modmask[2][2];
}
}
break;
case 'w':
if (u) {
if (op == '=' || op == '+') {
modmask[0] = modmask[0][0]+'w'+modmask[0][2];
}else if (op = '-') {
modmask[0] = modmask[0][0]+'-'+modmask[0][2];
}
}
if (g) {
if (op == '=' || op == '+') {
modmask[1] = modmask[1][0]+'w'+modmask[1][2];
}else if (op = '-') {
modmask[1] = modmask[1][0]+'-'+modmask[1][2];
}
}
if (o) {
if (op == '=' || op == '+') {
modmask[2] = modmask[2][0]+'w'+modmask[2][2];
}else if (op = '-') {
modmask[2] = modmask[2][0]+'-'+modmask[2][2];
}
}
break;
case 'x':
if (u) {
if (op == '=' || op == '+') {
modmask[0] = modmask[0][0]+modmask[0][1]+'x';
}else if (op = '-') {
modmask[0] = modmask[0][1]+modmask[0][1]+'-';
}
}
if (g) {
if (op == '=' || op == '+') {
modmask[1] = modmask[1][0]+modmask[1][1]+'x';
}else if (op = '-') {
modmask[1] = modmask[1][0]+modmask[1][1]+'-';
}
}
if (o) {
if (op == '=' || op == '+') {
modmask[2] = modmask[2][0]+modmask[2][1]+'x';
}else if (op = '-') {
modmask[2] = modmask[2][0]+modmask[2][1]+'-';
}
}
break;
case 'X':
if (u) {
if (op == '=' || op == '+') {
modmask[0] = modmask[0][0]+modmask[0][1]+'X';
}else if (op = '-') {
modmask[0] = modmask[0][1]+modmask[0][1]+'Y';
}
}
if (g) {
if (op == '=' || op == '+') {
modmask[1] = modmask[1][0]+modmask[1][1]+'X';
}else if (op = '-') {
modmask[1] = modmask[1][0]+modmask[1][1]+'Y';
}
}
if (o) {
if (op == '=' || op == '+') {
modmask[2] = modmask[2][0]+modmask[2][1]+'X';
}else if (op = '-') {
modmask[2] = modmask[2][0]+modmask[2][1]+'Y';
}
}
break;
case 'u':
if (g)
modmask[1] = modmask[0];
if (o)
modmask[2] = modmask[0];
s = 0;
break;
case 'g':
if (u)
modmask[0] = modmask[1];
if (o)
modmask[2] = modmask[1];
s = 0;
break;
case 'o':
if (u)
modmask[0] = modmask[2];
if (g)
modmask[1] = modmask[2];
s = 0;
break;
}
}else{ // ?
return;
}
}
});
return modmask.join('');
}
function getPerms(str,isdir) {
var n = str.substring(1);
for (var i=0; i<9; i++) {
if (modmask[i] == '?')
continue;
if (modmask[i] == n[i])
continue;
if (modmask[i] == 'X') {
if (isdir)
n = n.substring(0,i)+'x'+n.substring(i+1);
}else if (modmask[i] == 'Y') {
if (isdir)
n = n.substring(0,i)+'-'+n.substring(i+1);
}else{
n = n.substring(0,i)+modmask[i]+n.substring(i+1);
}
}
return n;
}
if (args.length == 3) { // name mode file
modmask = getModMask(args[1]);
short = args[2];
file = clite.resolvePath(short);
}else if (args.length == 4) { // name option mode file
if (args[1][0] != '-') {
stdio.write(io.stderr,'invalid arguments\n');
return 1;
}
for (var j=1; j<args[1].length; j++) {
switch (args[1][j]) {
case 'R':
recurse = true;
break;
case '?':
help();
return 0;
break;
default:
stdio.fprintf(io.stderr,'unknown argument: -%c\n',args[i][j]);
}
}
modmask = getModMask(args[2]);
short = args[3];
file = clite.resolvePath(short);
}else if (args.length == 2 && args[1] == '-?') {
help();
return 0;
}else{
stdio.write(io.stderr,'invalid arguments\n');
return 1;
}
if (modmask == null || modmask == '?????????') {
stdio.write(io.stderr,'invalid mode\n');
return 1;
}
if (file == null) {
stdio.write(io.stderr,'no file specified\n');
return 1;
}
var st = stdio.stat(file);
if (!st) {
stdio.fprintf(io.stderr,'cannot open file: %s\n',short);
return 1;
}
var perms = getPerms(st.perms,(st.type == stdio.types.FT_DIR));
if (!stdio.chmod(file,perms)) {
stdio.fprintf(io.stderr,'cannot write file: %s\n',short);
return 1;
}
return 0;
});
clite.commands.load('file',function(args,env,io) {
var short = '';
var file = null;
@ -693,14 +998,14 @@ Options:
return 0;
break;
default:
stdio.write(io.stderr,'unknown argument: -'+args[i][j]);
stdio.fprintf(io.stderr,'unknown argument: -%c\n',args[i][j]);
}
}
}else if (file == null) {
short = args[i];
file = clite.resolvePath(args[i],false);
}else{
stdio.write(io.stderr,'unknown argument: '+args[i]);
stdio.fprintf(io.stderr,'unknown argument: %s\n',args[i]);
}
}
@ -709,18 +1014,12 @@ Options:
return 1;
}
var fd = stdio.open(file,false);
if (!fd) {
stdio.write(io.stderr,'cannot open file: '+file);
return 1;
}
var st = stdio.fstat(fd);
stdio.close(fd);
var st = stdio.stat(file);
var txt = short+': ';
if (!st) {
txt += 'Unknown';
stdio.fprintf(io.stderr,'cannot open file: %s',file);
return 1;
}else{
switch (st.type) {
case stdio.types.FT_TEXT: