Blame


1 7c709434 2005-03-18 devnull /*
2 7c709434 2005-03-18 devnull * Remote file system editing client.
3 7c709434 2005-03-18 devnull * Only talks to acme - external programs do all the hard work.
4 fa325e9b 2020-01-10 cross *
5 7c709434 2005-03-18 devnull * If you add a plumbing rule:
6 7c709434 2005-03-18 devnull
7 7c709434 2005-03-18 devnull # /n/ paths go to simulator in acme
8 7c709434 2005-03-18 devnull kind is text
9 7c709434 2005-03-18 devnull data matches '[a-zA-Z0-9_\-./]+('$addr')?'
10 7c709434 2005-03-18 devnull data matches '(/n/[a-zA-Z0-9_\-./]+)('$addr')?'
11 7c709434 2005-03-18 devnull plumb to netfileedit
12 7c709434 2005-03-18 devnull plumb client Netfiles
13 7c709434 2005-03-18 devnull
14 7c709434 2005-03-18 devnull * then plumbed paths starting with /n/ will find their way here.
15 7c709434 2005-03-18 devnull *
16 7c709434 2005-03-18 devnull * Perhaps on startup should look for windows named /n/ and attach to them?
17 7c709434 2005-03-18 devnull * Or might that be too aggressive?
18 7c709434 2005-03-18 devnull */
19 7c709434 2005-03-18 devnull
20 7c709434 2005-03-18 devnull #include <u.h>
21 7c709434 2005-03-18 devnull #include <libc.h>
22 7c709434 2005-03-18 devnull #include <thread.h>
23 7c709434 2005-03-18 devnull #include <9pclient.h>
24 7c709434 2005-03-18 devnull #include <plumb.h>
25 7c709434 2005-03-18 devnull #include "acme.h"
26 7c709434 2005-03-18 devnull
27 7c709434 2005-03-18 devnull char *root = "/n/";
28 7c709434 2005-03-18 devnull
29 7c709434 2005-03-18 devnull void
30 7c709434 2005-03-18 devnull usage(void)
31 7c709434 2005-03-18 devnull {
32 7c709434 2005-03-18 devnull fprint(2, "usage: Netfiles\n");
33 7c709434 2005-03-18 devnull threadexitsall("usage");
34 7c709434 2005-03-18 devnull }
35 7c709434 2005-03-18 devnull
36 7c709434 2005-03-18 devnull extern int chatty9pclient;
37 7c709434 2005-03-18 devnull int debug;
38 590c5b34 2005-03-21 devnull #define dprint if(debug>1)print
39 590c5b34 2005-03-21 devnull #define cprint if(debug)print
40 7c709434 2005-03-18 devnull Win *mkwin(char*);
41 7c709434 2005-03-18 devnull int do3(Win *w, char *arg);
42 7c709434 2005-03-18 devnull
43 7c709434 2005-03-18 devnull enum {
44 cbeb0b26 2006-04-01 devnull STACK = 128*1024
45 7c709434 2005-03-18 devnull };
46 7c709434 2005-03-18 devnull
47 7c709434 2005-03-18 devnull enum {
48 7c709434 2005-03-18 devnull Put,
49 7c709434 2005-03-18 devnull Get,
50 7c709434 2005-03-18 devnull Del,
51 7c709434 2005-03-18 devnull Delete,
52 7c709434 2005-03-18 devnull Debug,
53 7c709434 2005-03-18 devnull XXX
54 7c709434 2005-03-18 devnull };
55 7c709434 2005-03-18 devnull
56 7c709434 2005-03-18 devnull char *cmds[] = {
57 7c709434 2005-03-18 devnull "Put",
58 7c709434 2005-03-18 devnull "Get",
59 7c709434 2005-03-18 devnull "Del",
60 7c709434 2005-03-18 devnull "Delete",
61 7c709434 2005-03-18 devnull "Debug",
62 7c709434 2005-03-18 devnull nil
63 7c709434 2005-03-18 devnull };
64 7c709434 2005-03-18 devnull
65 590c5b34 2005-03-21 devnull char *debugstr[] = {
66 590c5b34 2005-03-21 devnull "off",
67 590c5b34 2005-03-21 devnull "minimal",
68 cbeb0b26 2006-04-01 devnull "chatty"
69 590c5b34 2005-03-21 devnull };
70 590c5b34 2005-03-21 devnull
71 7c709434 2005-03-18 devnull typedef struct Arg Arg;
72 7c709434 2005-03-18 devnull struct Arg
73 7c709434 2005-03-18 devnull {
74 7c709434 2005-03-18 devnull char *file;
75 7c709434 2005-03-18 devnull char *addr;
76 7c709434 2005-03-18 devnull Channel *c;
77 7c709434 2005-03-18 devnull };
78 7c709434 2005-03-18 devnull
79 7c709434 2005-03-18 devnull Arg*
80 7c709434 2005-03-18 devnull arg(char *file, char *addr, Channel *c)
81 7c709434 2005-03-18 devnull {
82 7c709434 2005-03-18 devnull Arg *a;
83 fa325e9b 2020-01-10 cross
84 7c709434 2005-03-18 devnull a = emalloc(sizeof *a);
85 7c709434 2005-03-18 devnull a->file = estrdup(file);
86 7c709434 2005-03-18 devnull a->addr = estrdup(addr);
87 7c709434 2005-03-18 devnull a->c = c;
88 7c709434 2005-03-18 devnull return a;
89 7c709434 2005-03-18 devnull }
90 7c709434 2005-03-18 devnull
91 5a396071 2005-03-21 devnull Win*
92 5a396071 2005-03-21 devnull winbyid(int id)
93 5a396071 2005-03-21 devnull {
94 5a396071 2005-03-21 devnull Win *w;
95 fa325e9b 2020-01-10 cross
96 5a396071 2005-03-21 devnull for(w=windows; w; w=w->next)
97 5a396071 2005-03-21 devnull if(w->id == id)
98 5a396071 2005-03-21 devnull return w;
99 5a396071 2005-03-21 devnull return nil;
100 5a396071 2005-03-21 devnull }
101 5a396071 2005-03-21 devnull
102 7c709434 2005-03-18 devnull /*
103 5a396071 2005-03-21 devnull * return Win* of a window named name or name/
104 7c709434 2005-03-18 devnull * assumes name is cleaned.
105 7c709434 2005-03-18 devnull */
106 5a396071 2005-03-21 devnull Win*
107 5a396071 2005-03-21 devnull nametowin(char *name)
108 7c709434 2005-03-18 devnull {
109 7c709434 2005-03-18 devnull char *index, *p, *next;
110 7c709434 2005-03-18 devnull int len, n;
111 5a396071 2005-03-21 devnull Win *w;
112 7c709434 2005-03-18 devnull
113 7c709434 2005-03-18 devnull index = winindex();
114 7c709434 2005-03-18 devnull len = strlen(name);
115 7c709434 2005-03-18 devnull for(p=index; p && *p; p=next){
116 7c709434 2005-03-18 devnull if((next = strchr(p, '\n')) != nil)
117 5a396071 2005-03-21 devnull *next++ = 0;
118 7c709434 2005-03-18 devnull if(strlen(p) <= 5*12)
119 7c709434 2005-03-18 devnull continue;
120 7c709434 2005-03-18 devnull if(memcmp(p+5*12, name, len)!=0)
121 7c709434 2005-03-18 devnull continue;
122 7c709434 2005-03-18 devnull if(p[5*12+len]!=' ' && (p[5*12+len]!='/' || p[5*12+len+1]!=' '))
123 7c709434 2005-03-18 devnull continue;
124 7c709434 2005-03-18 devnull n = atoi(p);
125 5a396071 2005-03-21 devnull if((w = winbyid(n)) != nil){
126 5a396071 2005-03-21 devnull free(index);
127 5a396071 2005-03-21 devnull return w;
128 5a396071 2005-03-21 devnull }
129 7c709434 2005-03-18 devnull }
130 7c709434 2005-03-18 devnull free(index);
131 7c709434 2005-03-18 devnull return nil;
132 7c709434 2005-03-18 devnull }
133 5a396071 2005-03-21 devnull
134 7c709434 2005-03-18 devnull
135 7c709434 2005-03-18 devnull /*
136 7c709434 2005-03-18 devnull * look for s in list
137 7c709434 2005-03-18 devnull */
138 7c709434 2005-03-18 devnull int
139 7c709434 2005-03-18 devnull lookup(char *s, char **list)
140 7c709434 2005-03-18 devnull {
141 7c709434 2005-03-18 devnull int i;
142 fa325e9b 2020-01-10 cross
143 7c709434 2005-03-18 devnull for(i=0; list[i]; i++)
144 7c709434 2005-03-18 devnull if(strcmp(list[i], s) == 0)
145 7c709434 2005-03-18 devnull return i;
146 7c709434 2005-03-18 devnull return -1;
147 7c709434 2005-03-18 devnull }
148 7c709434 2005-03-18 devnull
149 7c709434 2005-03-18 devnull /*
150 7c709434 2005-03-18 devnull * move to top of file
151 7c709434 2005-03-18 devnull */
152 7c709434 2005-03-18 devnull void
153 7c709434 2005-03-18 devnull wintop(Win *w)
154 7c709434 2005-03-18 devnull {
155 7c709434 2005-03-18 devnull winaddr(w, "#0");
156 7c709434 2005-03-18 devnull winctl(w, "dot=addr");
157 7c709434 2005-03-18 devnull winctl(w, "show");
158 b1e32ef3 2005-03-21 devnull }
159 b1e32ef3 2005-03-21 devnull
160 b1e32ef3 2005-03-21 devnull int
161 b1e32ef3 2005-03-21 devnull isdot(Win *w, uint xq0, uint xq1)
162 b1e32ef3 2005-03-21 devnull {
163 b1e32ef3 2005-03-21 devnull uint q0, q1;
164 b1e32ef3 2005-03-21 devnull
165 b1e32ef3 2005-03-21 devnull winctl(w, "addr=dot");
166 b1e32ef3 2005-03-21 devnull q0 = winreadaddr(w, &q1);
167 b1e32ef3 2005-03-21 devnull return xq0==q0 && xq1==q1;
168 7c709434 2005-03-18 devnull }
169 7c709434 2005-03-18 devnull
170 7c709434 2005-03-18 devnull /*
171 7c709434 2005-03-18 devnull * Expand the click further than acme usually does -- all non-white space is okay.
172 7c709434 2005-03-18 devnull */
173 7c709434 2005-03-18 devnull char*
174 7c709434 2005-03-18 devnull expandarg(Win *w, Event *e)
175 7c709434 2005-03-18 devnull {
176 b8c9f317 2005-03-21 devnull uint q0, q1;
177 fa325e9b 2020-01-10 cross
178 b1e32ef3 2005-03-21 devnull if(e->c2 == 'l') /* in tag - no choice but to accept acme's expansion */
179 7c709434 2005-03-18 devnull return estrdup(e->text);
180 b8c9f317 2005-03-21 devnull winaddr(w, ",");
181 b8c9f317 2005-03-21 devnull winctl(w, "addr=dot");
182 b8c9f317 2005-03-21 devnull
183 b8c9f317 2005-03-21 devnull q0 = winreadaddr(w, &q1);
184 b8c9f317 2005-03-21 devnull cprint("acme expanded %d-%d into %d-%d (dot %d-%d)\n",
185 b8c9f317 2005-03-21 devnull e->oq0, e->oq1, e->q0, e->q1, q0, q1);
186 b8c9f317 2005-03-21 devnull
187 b8c9f317 2005-03-21 devnull if(e->oq0 == e->oq1 && e->q0 != e->q1 && !isdot(w, e->q0, e->q1)){
188 7c709434 2005-03-18 devnull winaddr(w, "#%ud+#1-/[^ \t\\n]*/,#%ud-#1+/[^ \t\\n]*/", e->q0, e->q1);
189 b8c9f317 2005-03-21 devnull q0 = winreadaddr(w, &q1);
190 fa325e9b 2020-01-10 cross cprint("\tre-expand to %d-%d\n", q0, q1);
191 b8c9f317 2005-03-21 devnull }else
192 7c709434 2005-03-18 devnull winaddr(w, "#%ud,#%ud", e->q0, e->q1);
193 7c709434 2005-03-18 devnull return winmread(w, "xdata");
194 7c709434 2005-03-18 devnull }
195 7c709434 2005-03-18 devnull
196 7c709434 2005-03-18 devnull /*
197 7c709434 2005-03-18 devnull * handle a plumbing message
198 7c709434 2005-03-18 devnull */
199 7c709434 2005-03-18 devnull void
200 7c709434 2005-03-18 devnull doplumb(void *vm)
201 7c709434 2005-03-18 devnull {
202 7c709434 2005-03-18 devnull char *addr;
203 7c709434 2005-03-18 devnull Plumbmsg *m;
204 7c709434 2005-03-18 devnull Win *w;
205 fa325e9b 2020-01-10 cross
206 7c709434 2005-03-18 devnull m = vm;
207 7c709434 2005-03-18 devnull if(m->ndata >= 1024){
208 7c709434 2005-03-18 devnull fprint(2, "insanely long file name (%d bytes) in plumb message (%.32s...)\n",
209 7c709434 2005-03-18 devnull m->ndata, m->data);
210 7c709434 2005-03-18 devnull plumbfree(m);
211 7c709434 2005-03-18 devnull return;
212 7c709434 2005-03-18 devnull }
213 fa325e9b 2020-01-10 cross
214 7c709434 2005-03-18 devnull addr = plumblookup(m->attr, "addr");
215 7c709434 2005-03-18 devnull w = nametowin(m->data);
216 7c709434 2005-03-18 devnull if(w == nil)
217 7c709434 2005-03-18 devnull w = mkwin(m->data);
218 7c709434 2005-03-18 devnull winaddr(w, "%s", addr);
219 7c709434 2005-03-18 devnull winctl(w, "dot=addr");
220 7c709434 2005-03-18 devnull winctl(w, "show");
221 cbeb0b26 2006-04-01 devnull /* windecref(w); */
222 7c709434 2005-03-18 devnull plumbfree(m);
223 7c709434 2005-03-18 devnull }
224 7c709434 2005-03-18 devnull
225 7c709434 2005-03-18 devnull /*
226 7c709434 2005-03-18 devnull * dispatch messages from the plumber
227 7c709434 2005-03-18 devnull */
228 7c709434 2005-03-18 devnull void
229 7c709434 2005-03-18 devnull plumbthread(void *v)
230 7c709434 2005-03-18 devnull {
231 7c709434 2005-03-18 devnull CFid *fid;
232 7c709434 2005-03-18 devnull Plumbmsg *m;
233 fa325e9b 2020-01-10 cross
234 78b5635d 2005-03-24 devnull threadsetname("plumbthread");
235 7c709434 2005-03-18 devnull fid = plumbopenfid("netfileedit", OREAD);
236 7c709434 2005-03-18 devnull if(fid == nil){
237 7c709434 2005-03-18 devnull fprint(2, "cannot open plumb/netfileedit: %r\n");
238 7c709434 2005-03-18 devnull return;
239 7c709434 2005-03-18 devnull }
240 7c709434 2005-03-18 devnull while((m = plumbrecvfid(fid)) != nil)
241 7c709434 2005-03-18 devnull threadcreate(doplumb, m, STACK);
242 7c709434 2005-03-18 devnull fsclose(fid);
243 7c709434 2005-03-18 devnull }
244 7c709434 2005-03-18 devnull
245 7c709434 2005-03-18 devnull /*
246 7c709434 2005-03-18 devnull * parse /n/system/path
247 7c709434 2005-03-18 devnull */
248 7c709434 2005-03-18 devnull int
249 7c709434 2005-03-18 devnull parsename(char *name, char **server, char **path)
250 7c709434 2005-03-18 devnull {
251 7c709434 2005-03-18 devnull char *p, *nul;
252 fa325e9b 2020-01-10 cross
253 7c709434 2005-03-18 devnull cleanname(name);
254 7c709434 2005-03-18 devnull if(strncmp(name, "/n/", 3) != 0 && name[3] == 0)
255 7c709434 2005-03-18 devnull return -1;
256 7c709434 2005-03-18 devnull nul = nil;
257 7c709434 2005-03-18 devnull if((p = strchr(name+3, '/')) == nil)
258 7c709434 2005-03-18 devnull *path = estrdup("/");
259 7c709434 2005-03-18 devnull else{
260 7c709434 2005-03-18 devnull *path = estrdup(p);
261 7c709434 2005-03-18 devnull *p = 0;
262 7c709434 2005-03-18 devnull nul = p;
263 7c709434 2005-03-18 devnull }
264 7c709434 2005-03-18 devnull p = name+3;
265 7c709434 2005-03-18 devnull if(p[0] == 0){
266 7c709434 2005-03-18 devnull free(*path);
267 7c709434 2005-03-18 devnull *server = *path = nil;
268 7c709434 2005-03-18 devnull if(nul)
269 7c709434 2005-03-18 devnull *nul = '/';
270 7c709434 2005-03-18 devnull return -1;
271 7c709434 2005-03-18 devnull }
272 7c709434 2005-03-18 devnull *server = estrdup(p);
273 7c709434 2005-03-18 devnull if(nul)
274 7c709434 2005-03-18 devnull *nul = '/';
275 7c709434 2005-03-18 devnull return 0;
276 7c709434 2005-03-18 devnull }
277 7c709434 2005-03-18 devnull
278 7c709434 2005-03-18 devnull /*
279 7c709434 2005-03-18 devnull * shell out to find the type of a given file
280 7c709434 2005-03-18 devnull */
281 7c709434 2005-03-18 devnull char*
282 7c709434 2005-03-18 devnull filestat(char *server, char *path)
283 7c709434 2005-03-18 devnull {
284 590c5b34 2005-03-21 devnull char *type;
285 590c5b34 2005-03-21 devnull static struct {
286 590c5b34 2005-03-21 devnull char *server;
287 590c5b34 2005-03-21 devnull char *path;
288 590c5b34 2005-03-21 devnull char *type;
289 590c5b34 2005-03-21 devnull } cache;
290 590c5b34 2005-03-21 devnull
291 590c5b34 2005-03-21 devnull if(cache.server && strcmp(server, cache.server) == 0)
292 590c5b34 2005-03-21 devnull if(cache.path && strcmp(path, cache.path) == 0){
293 590c5b34 2005-03-21 devnull type = estrdup(cache.type);
294 590c5b34 2005-03-21 devnull cprint("9 netfilestat %q %q => %s (cached)\n", server, path, type);
295 590c5b34 2005-03-21 devnull return type;
296 590c5b34 2005-03-21 devnull }
297 590c5b34 2005-03-21 devnull
298 590c5b34 2005-03-21 devnull type = sysrun(2, "9 netfilestat %q %q", server, path);
299 590c5b34 2005-03-21 devnull
300 590c5b34 2005-03-21 devnull free(cache.server);
301 590c5b34 2005-03-21 devnull free(cache.path);
302 590c5b34 2005-03-21 devnull free(cache.type);
303 590c5b34 2005-03-21 devnull cache.server = estrdup(server);
304 590c5b34 2005-03-21 devnull cache.path = estrdup(path);
305 590c5b34 2005-03-21 devnull cache.type = estrdup(type);
306 590c5b34 2005-03-21 devnull
307 590c5b34 2005-03-21 devnull cprint("9 netfilestat %q %q => %s\n", server, path, type);
308 590c5b34 2005-03-21 devnull return type;
309 7c709434 2005-03-18 devnull }
310 7c709434 2005-03-18 devnull
311 7c709434 2005-03-18 devnull /*
312 7c709434 2005-03-18 devnull * manage a single window
313 7c709434 2005-03-18 devnull */
314 7c709434 2005-03-18 devnull void
315 7c709434 2005-03-18 devnull filethread(void *v)
316 7c709434 2005-03-18 devnull {
317 7c709434 2005-03-18 devnull char *arg, *name, *p, *server, *path, *type;
318 7c709434 2005-03-18 devnull Arg *a;
319 7c709434 2005-03-18 devnull Channel *c;
320 7c709434 2005-03-18 devnull Event *e;
321 7c709434 2005-03-18 devnull Win *w;
322 7c709434 2005-03-18 devnull
323 7c709434 2005-03-18 devnull a = v;
324 7c709434 2005-03-18 devnull threadsetname("file %s", a->file);
325 7c709434 2005-03-18 devnull w = newwin();
326 7c709434 2005-03-18 devnull winname(w, a->file);
327 7c709434 2005-03-18 devnull winprint(w, "tag", "Get Put Look ");
328 7c709434 2005-03-18 devnull c = wineventchan(w);
329 fa325e9b 2020-01-10 cross
330 7c709434 2005-03-18 devnull goto caseGet;
331 fa325e9b 2020-01-10 cross
332 7c709434 2005-03-18 devnull while((e=recvp(c)) != nil){
333 7c709434 2005-03-18 devnull if(e->c1!='K')
334 7c709434 2005-03-18 devnull dprint("acme %E\n", e);
335 7c709434 2005-03-18 devnull if(e->c1=='M')
336 7c709434 2005-03-18 devnull switch(e->c2){
337 7c709434 2005-03-18 devnull case 'x':
338 7c709434 2005-03-18 devnull case 'X':
339 7c709434 2005-03-18 devnull switch(lookup(e->text, cmds)){
340 7c709434 2005-03-18 devnull caseGet:
341 7c709434 2005-03-18 devnull case Get:
342 7c709434 2005-03-18 devnull server = nil;
343 7c709434 2005-03-18 devnull path = nil;
344 7c709434 2005-03-18 devnull if(parsename(name=wingetname(w), &server, &path) < 0){
345 7c709434 2005-03-18 devnull fprint(2, "Netfiles: bad name %s\n", name);
346 7c709434 2005-03-18 devnull goto out;
347 7c709434 2005-03-18 devnull }
348 7c709434 2005-03-18 devnull type = filestat(server, path);
349 7c709434 2005-03-18 devnull if(type == nil)
350 7c709434 2005-03-18 devnull type = estrdup("");
351 7c709434 2005-03-18 devnull if(strcmp(type, "file")==0 || strcmp(type, "directory")==0){
352 7c709434 2005-03-18 devnull winaddr(w, ",");
353 7c709434 2005-03-18 devnull winprint(w, "data", "[reading...]");
354 7c709434 2005-03-18 devnull winaddr(w, ",");
355 fa325e9b 2020-01-10 cross cprint("9 netfileget %s%q %q\n",
356 590c5b34 2005-03-21 devnull strcmp(type, "file") == 0 ? "" : "-d", server, path);
357 7c709434 2005-03-18 devnull if(strcmp(type, "file")==0)
358 b6364661 2005-03-18 devnull twait(pipetowin(w, "data", 2, "9 netfileget %q %q", server, path));
359 7c709434 2005-03-18 devnull else
360 b6364661 2005-03-18 devnull twait(pipetowin(w, "data", 2, "9 netfileget -d %q %q | winid=%d mc", server, path, w->id));
361 7c709434 2005-03-18 devnull cleanname(name);
362 7c709434 2005-03-18 devnull if(strcmp(type, "directory")==0){
363 7c709434 2005-03-18 devnull p = name+strlen(name);
364 7c709434 2005-03-18 devnull if(p[-1] != '/'){
365 7c709434 2005-03-18 devnull p[0] = '/';
366 7c709434 2005-03-18 devnull p[1] = 0;
367 7c709434 2005-03-18 devnull }
368 7c709434 2005-03-18 devnull }
369 7c709434 2005-03-18 devnull winname(w, name);
370 7c709434 2005-03-18 devnull wintop(w);
371 7c709434 2005-03-18 devnull winctl(w, "clean");
372 7c709434 2005-03-18 devnull if(a && a->addr){
373 7c709434 2005-03-18 devnull winaddr(w, "%s", a->addr);
374 7c709434 2005-03-18 devnull winctl(w, "dot=addr");
375 7c709434 2005-03-18 devnull winctl(w, "show");
376 7c709434 2005-03-18 devnull }
377 7c709434 2005-03-18 devnull }
378 7c709434 2005-03-18 devnull free(type);
379 7c709434 2005-03-18 devnull out:
380 7c709434 2005-03-18 devnull free(server);
381 7c709434 2005-03-18 devnull free(path);
382 7c709434 2005-03-18 devnull if(a){
383 7c709434 2005-03-18 devnull if(a->c){
384 7c709434 2005-03-18 devnull sendp(a->c, w);
385 7c709434 2005-03-18 devnull a->c = nil;
386 7c709434 2005-03-18 devnull }
387 7c709434 2005-03-18 devnull free(a->file);
388 7c709434 2005-03-18 devnull free(a->addr);
389 7c709434 2005-03-18 devnull free(a);
390 7c709434 2005-03-18 devnull a = nil;
391 7c709434 2005-03-18 devnull }
392 7c709434 2005-03-18 devnull break;
393 7c709434 2005-03-18 devnull case Put:
394 7c709434 2005-03-18 devnull server = nil;
395 7c709434 2005-03-18 devnull path = nil;
396 7c709434 2005-03-18 devnull if(parsename(name=wingetname(w), &server, &path) < 0){
397 7c709434 2005-03-18 devnull fprint(2, "Netfiles: bad name %s\n", name);
398 7c709434 2005-03-18 devnull goto out;
399 7c709434 2005-03-18 devnull }
400 590c5b34 2005-03-21 devnull cprint("9 netfileput %q %q\n", server, path);
401 b6364661 2005-03-18 devnull if(twait(pipewinto(w, "body", 2, "9 netfileput %q %q", server, path)) >= 0){
402 7c709434 2005-03-18 devnull cleanname(name);
403 7c709434 2005-03-18 devnull winname(w, name);
404 7c709434 2005-03-18 devnull winctl(w, "clean");
405 7c709434 2005-03-18 devnull }
406 7c709434 2005-03-18 devnull free(server);
407 7c709434 2005-03-18 devnull free(path);
408 7c709434 2005-03-18 devnull break;
409 7c709434 2005-03-18 devnull case Del:
410 7c709434 2005-03-18 devnull winctl(w, "del");
411 7c709434 2005-03-18 devnull break;
412 7c709434 2005-03-18 devnull case Delete:
413 7c709434 2005-03-18 devnull winctl(w, "delete");
414 7c709434 2005-03-18 devnull break;
415 7c709434 2005-03-18 devnull case Debug:
416 590c5b34 2005-03-21 devnull debug = (debug+1)%3;
417 590c5b34 2005-03-21 devnull print("Netfiles debug %s\n", debugstr[debug]);
418 7c709434 2005-03-18 devnull break;
419 7c709434 2005-03-18 devnull default:
420 7c709434 2005-03-18 devnull winwriteevent(w, e);
421 7c709434 2005-03-18 devnull break;
422 7c709434 2005-03-18 devnull }
423 7c709434 2005-03-18 devnull break;
424 7c709434 2005-03-18 devnull case 'l':
425 7c709434 2005-03-18 devnull case 'L':
426 7c709434 2005-03-18 devnull arg = expandarg(w, e);
427 7c709434 2005-03-18 devnull if(arg!=nil && do3(w, arg) < 0)
428 7c709434 2005-03-18 devnull winwriteevent(w, e);
429 7c709434 2005-03-18 devnull free(arg);
430 7c709434 2005-03-18 devnull break;
431 7c709434 2005-03-18 devnull }
432 7c709434 2005-03-18 devnull }
433 7c709434 2005-03-18 devnull winfree(w);
434 7c709434 2005-03-18 devnull }
435 7c709434 2005-03-18 devnull
436 7c709434 2005-03-18 devnull /*
437 7c709434 2005-03-18 devnull * handle a button 3 click
438 7c709434 2005-03-18 devnull */
439 7c709434 2005-03-18 devnull int
440 7c709434 2005-03-18 devnull do3(Win *w, char *text)
441 7c709434 2005-03-18 devnull {
442 7c709434 2005-03-18 devnull char *addr, *name, *type, *server, *path, *p, *q;
443 7c709434 2005-03-18 devnull static char lastfail[1000];
444 7c709434 2005-03-18 devnull
445 590c5b34 2005-03-21 devnull if(text[0] == '/'){
446 590c5b34 2005-03-21 devnull p = nil;
447 7c709434 2005-03-18 devnull name = estrdup(text);
448 590c5b34 2005-03-21 devnull }else{
449 7c709434 2005-03-18 devnull p = wingetname(w);
450 5a396071 2005-03-21 devnull if(text[0] != ':'){
451 5a396071 2005-03-21 devnull q = strrchr(p, '/');
452 5a396071 2005-03-21 devnull *(q+1) = 0;
453 5a396071 2005-03-21 devnull }
454 7c709434 2005-03-18 devnull name = emalloc(strlen(p)+1+strlen(text)+1);
455 7c709434 2005-03-18 devnull strcpy(name, p);
456 5a396071 2005-03-21 devnull if(text[0] != ':')
457 5a396071 2005-03-21 devnull strcat(name, "/");
458 7c709434 2005-03-18 devnull strcat(name, text);
459 7c709434 2005-03-18 devnull }
460 590c5b34 2005-03-21 devnull cprint("button3 %s %s => %s\n", p, text, name);
461 7c709434 2005-03-18 devnull if((addr = strchr(name, ':')) != nil)
462 7c709434 2005-03-18 devnull *addr++ = 0;
463 7c709434 2005-03-18 devnull cleanname(name);
464 590c5b34 2005-03-21 devnull cprint("b3 \t=> name=%s addr=%s\n", name, addr);
465 7c709434 2005-03-18 devnull if(strcmp(name, lastfail) == 0){
466 65fb6fb7 2005-03-24 devnull cprint("b3 \t=> nonexistent (cached)\n");
467 7c709434 2005-03-18 devnull free(name);
468 7c709434 2005-03-18 devnull return -1;
469 7c709434 2005-03-18 devnull }
470 7c709434 2005-03-18 devnull if(parsename(name, &server, &path) < 0){
471 590c5b34 2005-03-21 devnull cprint("b3 \t=> parsename failed\n");
472 7c709434 2005-03-18 devnull free(name);
473 7c709434 2005-03-18 devnull return -1;
474 7c709434 2005-03-18 devnull }
475 7c709434 2005-03-18 devnull type = filestat(server, path);
476 7c709434 2005-03-18 devnull free(server);
477 7c709434 2005-03-18 devnull free(path);
478 7c709434 2005-03-18 devnull if(strcmp(type, "file")==0 || strcmp(type, "directory")==0){
479 7c709434 2005-03-18 devnull w = nametowin(name);
480 590c5b34 2005-03-21 devnull if(w == nil){
481 7c709434 2005-03-18 devnull w = mkwin(name);
482 590c5b34 2005-03-21 devnull cprint("b3 \t=> creating new window %d\n", w->id);
483 590c5b34 2005-03-21 devnull }else
484 590c5b34 2005-03-21 devnull cprint("b3 \t=> reusing window %d\n", w->id);
485 590c5b34 2005-03-21 devnull if(addr){
486 590c5b34 2005-03-21 devnull winaddr(w, "%s", addr);
487 590c5b34 2005-03-21 devnull winctl(w, "dot=addr");
488 590c5b34 2005-03-21 devnull }
489 7c709434 2005-03-18 devnull winctl(w, "show");
490 7c709434 2005-03-18 devnull free(name);
491 7c709434 2005-03-18 devnull free(type);
492 7c709434 2005-03-18 devnull return 0;
493 7c709434 2005-03-18 devnull }
494 7c709434 2005-03-18 devnull /*
495 7c709434 2005-03-18 devnull * remember last name that didn't exist so that
496 7c709434 2005-03-18 devnull * only the first right-click is slow when searching for text.
497 7c709434 2005-03-18 devnull */
498 590c5b34 2005-03-21 devnull cprint("b3 caching %s => type %s\n", name, type);
499 7c709434 2005-03-18 devnull strecpy(lastfail, lastfail+sizeof lastfail, name);
500 7c709434 2005-03-18 devnull free(name);
501 590c5b34 2005-03-21 devnull free(type);
502 7c709434 2005-03-18 devnull return -1;
503 7c709434 2005-03-18 devnull }
504 7c709434 2005-03-18 devnull
505 7c709434 2005-03-18 devnull Win*
506 7c709434 2005-03-18 devnull mkwin(char *name)
507 7c709434 2005-03-18 devnull {
508 7c709434 2005-03-18 devnull Arg *a;
509 7c709434 2005-03-18 devnull Channel *c;
510 7c709434 2005-03-18 devnull Win *w;
511 fa325e9b 2020-01-10 cross
512 7c709434 2005-03-18 devnull c = chancreate(sizeof(void*), 0);
513 7c709434 2005-03-18 devnull a = arg(name, nil, c);
514 7c709434 2005-03-18 devnull threadcreate(filethread, a, STACK);
515 7c709434 2005-03-18 devnull w = recvp(c);
516 7c709434 2005-03-18 devnull chanfree(c);
517 7c709434 2005-03-18 devnull return w;
518 7c709434 2005-03-18 devnull }
519 7c709434 2005-03-18 devnull
520 7c709434 2005-03-18 devnull void
521 7c709434 2005-03-18 devnull loopthread(void *v)
522 7c709434 2005-03-18 devnull {
523 7c709434 2005-03-18 devnull QLock lk;
524 fa325e9b 2020-01-10 cross
525 78b5635d 2005-03-24 devnull threadsetname("loopthread");
526 7c709434 2005-03-18 devnull qlock(&lk);
527 7c709434 2005-03-18 devnull qlock(&lk);
528 7c709434 2005-03-18 devnull }
529 fa325e9b 2020-01-10 cross
530 7c709434 2005-03-18 devnull void
531 7c709434 2005-03-18 devnull threadmain(int argc, char **argv)
532 7c709434 2005-03-18 devnull {
533 7c709434 2005-03-18 devnull ARGBEGIN{
534 7c709434 2005-03-18 devnull case '9':
535 7c709434 2005-03-18 devnull chatty9pclient = 1;
536 7c709434 2005-03-18 devnull break;
537 7c709434 2005-03-18 devnull case 'D':
538 7c709434 2005-03-18 devnull debug = 1;
539 7c709434 2005-03-18 devnull break;
540 7c709434 2005-03-18 devnull default:
541 7c709434 2005-03-18 devnull usage();
542 7c709434 2005-03-18 devnull }ARGEND
543 fa325e9b 2020-01-10 cross
544 7c709434 2005-03-18 devnull if(argc)
545 7c709434 2005-03-18 devnull usage();
546 7c709434 2005-03-18 devnull
547 78b5635d 2005-03-24 devnull cprint("netfiles starting\n");
548 78b5635d 2005-03-24 devnull
549 7c709434 2005-03-18 devnull threadnotify(nil, 0); /* set up correct default handlers */
550 7c709434 2005-03-18 devnull
551 7c709434 2005-03-18 devnull fmtinstall('E', eventfmt);
552 7c709434 2005-03-18 devnull doquote = needsrcquote;
553 7c709434 2005-03-18 devnull quotefmtinstall();
554 fa325e9b 2020-01-10 cross
555 7c709434 2005-03-18 devnull twaitinit();
556 7c709434 2005-03-18 devnull threadcreate(plumbthread, nil, STACK);
557 7c709434 2005-03-18 devnull threadcreate(loopthread, nil, STACK);
558 7c709434 2005-03-18 devnull threadexits(nil);
559 7c709434 2005-03-18 devnull }