]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/aux/cdsh.c
audiohda: fix syntax error
[plan9front.git] / sys / src / cmd / aux / cdsh.c
1 /*
2  * The `cd' shell.  
3  * Just has cd and lc.
4  */
5
6 #include <u.h>
7 #include <libc.h>
8 #include <bio.h>
9
10 char *pwd;
11 char *root = "/";
12
13 void
14 usage(void)
15 {
16         fprint(2, "usage: cdsh [-r root]\n");
17         exits("usage");
18 }
19
20 int
21 system(char *cmd)
22 {
23         int pid;
24         if((pid = fork()) < 0)
25                 return -1;
26
27         if(pid == 0) {
28                 dup(2, 1);
29                 execl("/bin/rc", "rc", "-c", cmd, nil);
30                 exits("exec");
31         }
32         waitpid();
33         return 0;
34 }
35
36 int
37 cd(char *s)
38 {
39         char *newpwd;
40         int l;
41
42         if(s[0] == '/') {
43                 cleanname(s);
44                 newpwd = strdup(s);
45         } else {
46                 l = strlen(pwd)+1+strlen(s)+1+50;       /* 50 = crud for unicode mistakes */
47                 newpwd = malloc(l);
48                 snprint(newpwd, l, "%s/%s", pwd, s);
49                 cleanname(newpwd);
50                 assert(newpwd[0] == '/');
51         }
52
53         if(chdir(root) < 0 || (newpwd[1] != '\0' && chdir(newpwd+1) < 0)) {
54                 chdir(root);
55                 chdir(pwd+1);
56                 free(newpwd);
57                 return -1;
58         } else {
59                 free(pwd);
60                 pwd = newpwd;
61                 return 0;
62         }
63 }
64
65 void
66 main(int argc, char **argv)
67 {
68         char *p;
69         Biobuf bin;
70         char *f[2];
71         int nf;
72
73         ARGBEGIN{
74         case 'r':
75                 root = ARGF();
76                 if(root == nil)
77                         usage();
78                 if(root[0] != '/') {
79                         fprint(2, "root must be rooted\n");
80                         exits("root");
81                 }
82                 break;
83         default:
84                 usage();
85         }ARGEND;
86
87         if(argc != 0)
88                 usage();
89
90         cleanname(root);
91         if(cd("/") < 0) {
92                 fprint(2, "cannot cd %s: %r\n", root);
93                 exits("root");
94         }
95
96         Binit(&bin, 0, OREAD);
97         while(fprint(2, "%s%% ", pwd), (p = Brdline(&bin, '\n'))) {
98                 p[Blinelen(&bin)-1] = '\0';
99                 nf = tokenize(p, f, nelem(f));
100                 if(nf < 1)
101                         continue;
102                 if(strcmp(f[0], "exit") == 0)
103                         break;
104                 if(strcmp(f[0], "lc") == 0) {
105                         if(nf == 1) {
106                                 if(system("/bin/lc") < 0)
107                                         fprint(2, "lc: %r\n");
108                         } else if(nf == 2) {
109                                 if(strpbrk(p, "'`{}^@$#&()|\\;><"))
110                                         fprint(2, "no shell characters allowed\n");
111                                 else {
112                                         p = f[1];
113                                         *--p = ' ';
114                                         *--p = 'c';
115                                         *--p = 'l';
116                                         if(system(p) < 0)
117                                                 fprint(2, "lc: %r\n");
118                                 }
119                         }
120                         continue;
121                 }
122                 if(strcmp(f[0], "cd") == 0) {
123                         if(nf < 2)
124                                 fprint(2, "usage: cd dir\n");
125                         else if(cd(f[1]) < 0)
126                                 fprint(2, "cd: %r\n");
127                         continue;
128                 }
129                 fprint(2, "commands are cd, lc, and exit\n");
130         }
131
132         print("%s\n", pwd);
133 }