]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/aux/conswdir.c
exec(2): fix prototypes
[plan9front.git] / sys / src / cmd / aux / conswdir.c
1 /*
2  * Process in-band messages about window title changes.
3  * The messages are of the form:
4  *
5  *      \033];xxx\007
6  *
7  * where xxx is the new directory.  This format was chosen
8  * because it changes the label on xterm windows.
9  */
10
11 #include <u.h>
12 #include <libc.h>
13
14 struct {
15         char *file;
16         char name[512];
17 } keep[] = {
18         { "/dev/label" },
19         { "/dev/wdir" }
20 };
21
22 char *prog = "/bin/rwd";
23
24 void
25 usage(void)
26 {
27         fprint(2, "usage: conswdir [/bin/rwd]\n");
28         exits("usage");
29 }
30
31 void
32 save(void)
33 {
34         int i, fd;
35         for(i = 0; i < nelem(keep); i++){
36                 *keep[i].name = 0;
37                 if((fd = open(keep[i].file, OREAD)) != -1){
38                         read(fd, keep[i].name, sizeof(keep[i].name));
39                         close(fd);
40                 }
41         }
42 }
43
44 void
45 rest(void)
46 {
47         int i, fd;
48         for(i = 0; i < nelem(keep); i++)
49                 if((fd = open(keep[i].file, OWRITE)) != -1){
50                         write(fd, keep[i].name, strlen(keep[i].name));
51                         close(fd);
52                 }
53
54 }
55
56 void
57 setpath(char *s)
58 {
59         switch(rfork(RFPROC|RFFDG|RFNOWAIT)){
60         case 0:
61                 execl(prog, prog, s, nil);
62                 _exits(nil);
63         }
64 }
65
66 enum
67 {
68         None,
69         Esc,
70         Brack,
71         Semi,
72         Bell,
73 };
74
75 int
76 process(char *buf, int n, int *pn)
77 {
78         char *p;
79         char path[4096];
80         int start, state;
81
82         start = 0;
83         state = None;
84         for(p=buf; p<buf+n; p++){
85                 switch(state){
86                 case None:
87                         if(*p == '\033'){
88                                 start = p-buf;
89                                 state++;
90                         }
91                         break;
92                 case Esc:
93                         if(*p == ']')
94                                 state++;
95                         else
96                                 state = None;
97                         break;
98                 case Brack:
99                         if(*p == ';')
100                                 state++;
101                         else
102                                 state = None;
103                         break;
104                 case Semi:
105                         if(*p == '\007')
106                                 state++;
107                         else if((uchar)*p < 040)
108                                 state = None;
109                         break;
110                 }
111                 if(state == Bell){
112                         memmove(path, buf+start+3, p - (buf+start+3));
113                         path[p-(buf+start+3)] = 0;
114                         p++;
115                         memmove(buf+start, p, n-(p-buf));
116                         n -= p-(buf+start);
117                         p = buf+start;
118                         p--;
119                         start = 0;
120                         state = None;
121                         setpath(path);
122                 }
123         }
124         /* give up if we go too long without seeing the close */
125         *pn = n;
126         if(state == None || p-(buf+start) >= 2048)
127                 return (p - buf);
128         else
129                 return start;
130 }
131
132 static void
133 catchint(void*, char *msg)
134 {
135         if(strstr(msg, "interrupt"))
136                 noted(NCONT);
137         else if(strstr(msg, "kill"))
138                 noted(NDFLT);
139         else
140                 noted(NCONT);
141 }
142
143 void
144 main(int argc, char **argv)
145 {
146         char buf[4096];
147         int n, m;
148
149         notify(catchint);
150
151         ARGBEGIN{
152         default:
153                 usage();
154         }ARGEND
155
156         if(argc > 1)
157                 usage();
158         if(argc == 1)
159                 prog = argv[0];
160
161         save();
162         n = 0;
163         for(;;){
164                 m = read(0, buf+n, sizeof buf-n);
165                 if(m < 0){
166                         rerrstr(buf, sizeof buf);
167                         if(strstr(buf, "interrupt"))
168                                 continue;
169                         break;
170                 }
171                 n += m;
172                 m = process(buf, n, &n);
173                 if(m > 0){
174                         write(1, buf, m);
175                         memmove(buf, buf+m, n-m);
176                         n -= m;
177                 }
178         }
179         rest();
180         exits(nil);
181 }