123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- /*
- * Process in-band messages about window title changes.
- * The messages are of the form:
- *
- * \033];xxx\007
- *
- * where xxx is the new directory. This format was chosen
- * because it changes the label on xterm windows.
- */
- #include <u.h>
- #include <libc.h>
- struct {
- char *file;
- char name[512];
- } keep[] = {
- { "/dev/label" },
- { "/dev/wdir" }
- };
- char *prog = "/bin/rwd";
- void
- usage(void)
- {
- fprint(2, "usage: conswdir [/bin/rwd]\n");
- exits("usage");
- }
- void
- save(void)
- {
- int i, fd;
- for(i = 0; i < nelem(keep); i++){
- *keep[i].name = 0;
- if((fd = open(keep[i].file, OREAD)) != -1){
- read(fd, keep[i].name, sizeof(keep[i].name));
- close(fd);
- }
- }
- }
- void
- rest(void)
- {
- int i, fd;
- for(i = 0; i < nelem(keep); i++)
- if((fd = open(keep[i].file, OWRITE)) != -1){
- write(fd, keep[i].name, strlen(keep[i].name));
- close(fd);
- }
- }
- void
- setpath(char *s)
- {
- switch(rfork(RFPROC|RFFDG|RFNOWAIT)){
- case 0:
- execl(prog, prog, s, nil);
- _exits(nil);
- }
- }
- enum
- {
- None,
- Esc,
- Brack,
- Semi,
- Bell,
- };
- int
- process(char *buf, int n, int *pn)
- {
- char *p;
- char path[4096];
- int start, state;
- start = 0;
- state = None;
- for(p=buf; p<buf+n; p++){
- switch(state){
- case None:
- if(*p == '\033'){
- start = p-buf;
- state++;
- }
- break;
- case Esc:
- if(*p == ']')
- state++;
- else
- state = None;
- break;
- case Brack:
- if(*p == ';')
- state++;
- else
- state = None;
- break;
- case Semi:
- if(*p == '\007')
- state++;
- else if((uchar)*p < 040)
- state = None;
- break;
- }
- if(state == Bell){
- memmove(path, buf+start+3, p - (buf+start+3));
- path[p-(buf+start+3)] = 0;
- p++;
- memmove(buf+start, p, n-(p-buf));
- n -= p-(buf+start);
- p = buf+start;
- p--;
- start = 0;
- state = None;
- setpath(path);
- }
- }
- /* give up if we go too long without seeing the close */
- *pn = n;
- if(state == None || p-(buf+start) >= 2048)
- return (p - buf);
- else
- return start;
- }
- static void
- catchint(void*, char *msg)
- {
- if(strstr(msg, "interrupt"))
- noted(NCONT);
- else if(strstr(msg, "kill"))
- noted(NDFLT);
- else
- noted(NCONT);
- }
- void
- main(int argc, char **argv)
- {
- char buf[4096];
- int n, m;
- notify(catchint);
- ARGBEGIN{
- default:
- usage();
- }ARGEND
- if(argc > 1)
- usage();
- if(argc == 1)
- prog = argv[0];
- save();
- n = 0;
- for(;;){
- m = read(0, buf+n, sizeof buf-n);
- if(m < 0){
- rerrstr(buf, sizeof buf);
- if(strstr(buf, "interrupt"))
- continue;
- break;
- }
- n += m;
- m = process(buf, n, &n);
- if(m > 0){
- write(1, buf, m);
- memmove(buf, buf+m, n-m);
- n -= m;
- }
- }
- rest();
- exits(nil);
- }
|