123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- /*
- * 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);
- }
|