Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}