summaryrefslogtreecommitdiff
path: root/sys/src/cmd/aux/cdsh.c
diff options
context:
space:
mode:
authoriru <devnull@localhost>2011-04-14 00:35:48 -0300
committeriru <devnull@localhost>2011-04-14 00:35:48 -0300
commitfd8d404d520a3f10c143f5cbe7c170606fffc75c (patch)
treefbc8bf7218eca7d6290ffb1109fcc73b5b5cda33 /sys/src/cmd/aux/cdsh.c
parentdd468419f2fbaa2c3fec570a88d13e8eae8f3faf (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.c133
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);
+}