diff --git a/clite/commands.js b/clite/commands.js index 194ed29..56f2408 100644 --- a/clite/commands.js +++ b/clite/commands.js @@ -54,7 +54,7 @@ Options: `); } - function writeNodeData(st,fd) { + function writeNodeData(st,fn) { if (long) { var pw = stdlib.getpwuid(st.st_uid); var gr = stdlib.getgrgid(st.st_gid); @@ -80,9 +80,14 @@ Options: } var ms = clite.strmode(st.st_mode); if (st.type == stdio.types.FT_LINK) { - var lp = stdio.readAll(fd); - if (!lp) - lp = '?'; + var lp = '?'; + var fd = stdio.open(fn,stdio.flags.O_RDONLY|stdio.flags.O_NOFOLLOW|stdio.flags.O_SYNC); + if (fd) { + lp = stdio.readAll(fd); + stdio.close(fd); + if (!lp) + lp = '?'; + } stdio.printf('%s%12s%12s%14s%12s -> %s\n',ms,uname,gname,d,st.name,lp); }else{ stdio.printf('%s%12s%12s%14s%12s\n',ms,uname,gname,d,st.name); @@ -149,19 +154,12 @@ Options: while ((e = stdio.read(fd)) != null) { if (e[0] == '.' && !all) continue; - var efd = stdio.open(dir+'/'+e,stdio.flags.O_RDONLY|stdio.flags.O_NOFOLLOW|stdio.flags.O_SYNC); - if (!efd) { - stdio.fprintf(io.stderr,'cannot read contents: %s\n',dir); - break; - } - var est = stdio.fstatat(efd,stdio.flags.AT_SYMLINK_NOFOLLOW); + var est = stdio.lstat(dir+'/'+e,stdio.flags.AT_SYMLINK_NOFOLLOW); if (!est) { - stdio.close(efd); stdio.fprintf(io.stderr,'cannot read content: %s\n',dir); break; } - writeNodeData(est,efd); - stdio.close(efd); + writeNodeData(est,dir+'/'+e); } stdio.close(fd); if (!one && !long) @@ -2172,6 +2170,149 @@ Options: return main(args); }); +clite.commands.load('su',function(args,env,io) { + var stdio = io.include('stdio'); + var stdlib = io.include('stdlib'); + var auth = io.include('auth'); + + var pw = null; + var preserve = true; + var shell = null; + + function help() { + stdio.printf(` +su - switch users +Usage: su [OPTION] + +Options: +-? Print this help information +-l Simulate a full login +-m Preserve the environment +-s Use the shell at +`); + } + + function changeUser() { + if (!stdlib.setgid(pw.pw_gid)) { + stdio.write(io.stderr,'internal error\n'); + io.exit(1); + return; + } + + if (!stdlib.setuid(pw.pw_uid)) { + stdio.write(io.stderr,'internal error\n'); + io.exit(1); + return; + } + + var e = null; + + if (preserve) { + e = structuredClone(env); + }else{ + e = {}; + e.USER = pw.pw_name; + e.PWD = pw.pw_dir; + e.HOME = pw.pw_dir; + e.SHELL = pw.pw_shell; + } + + if (shell == null) + shell = e.SHELL; + + var args = [shell]; + + var r = stdlib.exec(shell,args,e,io); + if (r == 0) + return; + + stdio.write(io.stderr,'internal error\n'); + + io.exit(1); + } + + function doLogin(str) { + if (!auth.checkpassuid(pw.pw_uid,str)) { + stdio.printf('authentication error\n'); + io.exit(1); + return; + } + + changeUser(); + } + + function main(args) { + var user = 'root'; + var shellnext = false; + for (var i=1; i