diff options
author | iru <devnull@localhost> | 2011-04-14 00:35:48 -0300 |
---|---|---|
committer | iru <devnull@localhost> | 2011-04-14 00:35:48 -0300 |
commit | fd8d404d520a3f10c143f5cbe7c170606fffc75c (patch) | |
tree | fbc8bf7218eca7d6290ffb1109fcc73b5b5cda33 /sys/src/cmd/aux/cdsh.c | |
parent | dd468419f2fbaa2c3fec570a88d13e8eae8f3faf (diff) |
Promote the old installer/livecd specific tools to normal tools under /sys/src/cmd. Where similar common tools already existed, I kept them.
Diffstat (limited to 'sys/src/cmd/aux/cdsh.c')
-rw-r--r-- | sys/src/cmd/aux/cdsh.c | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/sys/src/cmd/aux/cdsh.c b/sys/src/cmd/aux/cdsh.c new file mode 100644 index 000000000..2162350bf --- /dev/null +++ b/sys/src/cmd/aux/cdsh.c @@ -0,0 +1,133 @@ +/* + * The `cd' shell. + * Just has cd and lc. + */ + +#include <u.h> +#include <libc.h> +#include <bio.h> + +char *pwd; +char *root = "/"; + +void +usage(void) +{ + fprint(2, "usage: cdsh [-r root]\n"); + exits("usage"); +} + +int +system(char *cmd) +{ + int pid; + if((pid = fork()) < 0) + return -1; + + if(pid == 0) { + dup(2, 1); + execl("/bin/rc", "rc", "-c", cmd, nil); + exits("exec"); + } + waitpid(); + return 0; +} + +int +cd(char *s) +{ + char *newpwd; + int l; + + if(s[0] == '/') { + cleanname(s); + newpwd = strdup(s); + } else { + l = strlen(pwd)+1+strlen(s)+1+50; /* 50 = crud for unicode mistakes */ + newpwd = malloc(l); + snprint(newpwd, l, "%s/%s", pwd, s); + cleanname(newpwd); + assert(newpwd[0] == '/'); + } + + if(chdir(root) < 0 || (newpwd[1] != '\0' && chdir(newpwd+1) < 0)) { + chdir(root); + chdir(pwd+1); + free(newpwd); + return -1; + } else { + free(pwd); + pwd = newpwd; + return 0; + } +} + +void +main(int argc, char **argv) +{ + char *p; + Biobuf bin; + char *f[2]; + int nf; + + ARGBEGIN{ + case 'r': + root = ARGF(); + if(root == nil) + usage(); + if(root[0] != '/') { + fprint(2, "root must be rooted\n"); + exits("root"); + } + break; + default: + usage(); + }ARGEND; + + if(argc != 0) + usage(); + + cleanname(root); + if(cd("/") < 0) { + fprint(2, "cannot cd %s: %r\n", root); + exits("root"); + } + + Binit(&bin, 0, OREAD); + while(fprint(2, "%s%% ", pwd), (p = Brdline(&bin, '\n'))) { + p[Blinelen(&bin)-1] = '\0'; + nf = tokenize(p, f, nelem(f)); + if(nf < 1) + continue; + if(strcmp(f[0], "exit") == 0) + break; + if(strcmp(f[0], "lc") == 0) { + if(nf == 1) { + if(system("/bin/lc") < 0) + fprint(2, "lc: %r\n"); + } else if(nf == 2) { + if(strpbrk(p, "'`{}^@$#&()|\\;><")) + fprint(2, "no shell characters allowed\n"); + else { + p = f[1]; + *--p = ' '; + *--p = 'c'; + *--p = 'l'; + if(system(p) < 0) + fprint(2, "lc: %r\n"); + } + } + continue; + } + if(strcmp(f[0], "cd") == 0) { + if(nf < 2) + fprint(2, "usage: cd dir\n"); + else if(cd(f[1]) < 0) + fprint(2, "cd: %r\n"); + continue; + } + fprint(2, "commands are cd, lc, and exit\n"); + } + + print("%s\n", pwd); +} |