1 6f4d00ee 2013-09-23 0intro #include "stdinc.h"
3 6f4d00ee 2013-09-23 0intro #include "9.h"
5 6f4d00ee 2013-09-23 0intro static struct {
6 4b576658 2013-09-23 0intro QLock lock;
9 6f4d00ee 2013-09-23 0intro int confd[2];
10 6f4d00ee 2013-09-23 0intro ushort tag;
13 6f4d00ee 2013-09-23 0intro static ulong
14 6f4d00ee 2013-09-23 0intro cmd9pStrtoul(char* s)
16 6f4d00ee 2013-09-23 0intro if(strcmp(s, "~0") == 0)
17 6f4d00ee 2013-09-23 0intro return ~0UL;
18 6f4d00ee 2013-09-23 0intro return strtoul(s, 0, 0);
21 6f4d00ee 2013-09-23 0intro static uvlong
22 6f4d00ee 2013-09-23 0intro cmd9pStrtoull(char* s)
24 6f4d00ee 2013-09-23 0intro if(strcmp(s, "~0") == 0)
25 6f4d00ee 2013-09-23 0intro return ~0ULL;
26 6f4d00ee 2013-09-23 0intro return strtoull(s, 0, 0);
29 6f4d00ee 2013-09-23 0intro static int
30 b32de4ae 2013-09-26 0intro cmd9pTag(Fcall* f, int i, char **argv)
34 6f4d00ee 2013-09-23 0intro cbox.tag = strtoul(argv[0], 0, 0)-1;
39 6f4d00ee 2013-09-23 0intro static int
40 b32de4ae 2013-09-26 0intro cmd9pTwstat(Fcall* f, int i, char **argv)
43 6f4d00ee 2013-09-23 0intro static uchar buf[DIRMAX];
46 6f4d00ee 2013-09-23 0intro memset(&d, 0, sizeof d);
47 6f4d00ee 2013-09-23 0intro nulldir(&d);
48 6f4d00ee 2013-09-23 0intro d.name = argv[1];
49 6f4d00ee 2013-09-23 0intro d.uid = argv[2];
50 6f4d00ee 2013-09-23 0intro d.gid = argv[3];
51 6f4d00ee 2013-09-23 0intro d.mode = cmd9pStrtoul(argv[4]);
52 6f4d00ee 2013-09-23 0intro d.mtime = cmd9pStrtoul(argv[5]);
53 6f4d00ee 2013-09-23 0intro d.length = cmd9pStrtoull(argv[6]);
55 6f4d00ee 2013-09-23 0intro f->fid = strtol(argv[0], 0, 0);
56 6f4d00ee 2013-09-23 0intro f->stat = buf;
57 6f4d00ee 2013-09-23 0intro f->nstat = convD2M(&d, buf, sizeof buf);
58 6f4d00ee 2013-09-23 0intro if(f->nstat < BIT16SZ){
59 4b576658 2013-09-23 0intro werrstr("Twstat: convD2M failed (internal error)");
66 6f4d00ee 2013-09-23 0intro static int
67 b32de4ae 2013-09-26 0intro cmd9pTstat(Fcall* f, int i, char** argv)
70 6f4d00ee 2013-09-23 0intro f->fid = strtol(argv[0], 0, 0);
75 6f4d00ee 2013-09-23 0intro static int
76 b32de4ae 2013-09-26 0intro cmd9pTremove(Fcall* f, int i, char** argv)
79 6f4d00ee 2013-09-23 0intro f->fid = strtol(argv[0], 0, 0);
84 6f4d00ee 2013-09-23 0intro static int
85 b32de4ae 2013-09-26 0intro cmd9pTclunk(Fcall* f, int i, char** argv)
88 6f4d00ee 2013-09-23 0intro f->fid = strtol(argv[0], 0, 0);
93 6f4d00ee 2013-09-23 0intro static int
94 b32de4ae 2013-09-26 0intro cmd9pTwrite(Fcall* f, int i, char** argv)
97 6f4d00ee 2013-09-23 0intro f->fid = strtol(argv[0], 0, 0);
98 6f4d00ee 2013-09-23 0intro f->offset = strtoll(argv[1], 0, 0);
99 6f4d00ee 2013-09-23 0intro f->data = argv[2];
100 6f4d00ee 2013-09-23 0intro f->count = strlen(argv[2]);
102 6f4d00ee 2013-09-23 0intro return 1;
105 6f4d00ee 2013-09-23 0intro static int
106 b32de4ae 2013-09-26 0intro cmd9pTread(Fcall* f, int i, char** argv)
109 6f4d00ee 2013-09-23 0intro f->fid = strtol(argv[0], 0, 0);
110 6f4d00ee 2013-09-23 0intro f->offset = strtoll(argv[1], 0, 0);
111 6f4d00ee 2013-09-23 0intro f->count = strtol(argv[2], 0, 0);
113 6f4d00ee 2013-09-23 0intro return 1;
116 6f4d00ee 2013-09-23 0intro static int
117 b32de4ae 2013-09-26 0intro cmd9pTcreate(Fcall* f, int i, char** argv)
120 6f4d00ee 2013-09-23 0intro f->fid = strtol(argv[0], 0, 0);
121 6f4d00ee 2013-09-23 0intro f->name = argv[1];
122 6f4d00ee 2013-09-23 0intro f->perm = strtol(argv[2], 0, 8);
123 6f4d00ee 2013-09-23 0intro f->mode = strtol(argv[3], 0, 0);
125 6f4d00ee 2013-09-23 0intro return 1;
128 6f4d00ee 2013-09-23 0intro static int
129 b32de4ae 2013-09-26 0intro cmd9pTopen(Fcall* f, int i, char** argv)
132 6f4d00ee 2013-09-23 0intro f->fid = strtol(argv[0], 0, 0);
133 6f4d00ee 2013-09-23 0intro f->mode = strtol(argv[1], 0, 0);
135 6f4d00ee 2013-09-23 0intro return 1;
138 6f4d00ee 2013-09-23 0intro static int
139 6f4d00ee 2013-09-23 0intro cmd9pTwalk(Fcall* f, int argc, char** argv)
143 6f4d00ee 2013-09-23 0intro if(argc < 2){
144 4b576658 2013-09-23 0intro werrstr("usage: Twalk tag fid newfid [name...]");
145 6f4d00ee 2013-09-23 0intro return 0;
147 6f4d00ee 2013-09-23 0intro f->fid = strtol(argv[0], 0, 0);
148 6f4d00ee 2013-09-23 0intro f->newfid = strtol(argv[1], 0, 0);
149 6f4d00ee 2013-09-23 0intro f->nwname = argc-2;
150 6f4d00ee 2013-09-23 0intro if(f->nwname > MAXWELEM){
151 4b576658 2013-09-23 0intro werrstr("Twalk: too many names");
152 6f4d00ee 2013-09-23 0intro return 0;
154 6f4d00ee 2013-09-23 0intro for(i = 0; i < argc-2; i++)
155 6f4d00ee 2013-09-23 0intro f->wname[i] = argv[2+i];
157 6f4d00ee 2013-09-23 0intro return 1;
160 6f4d00ee 2013-09-23 0intro static int
161 b32de4ae 2013-09-26 0intro cmd9pTflush(Fcall* f, int i, char** argv)
164 6f4d00ee 2013-09-23 0intro f->oldtag = strtol(argv[0], 0, 0);
166 6f4d00ee 2013-09-23 0intro return 1;
169 6f4d00ee 2013-09-23 0intro static int
170 b32de4ae 2013-09-26 0intro cmd9pTattach(Fcall* f, int i, char** argv)
173 6f4d00ee 2013-09-23 0intro f->fid = strtol(argv[0], 0, 0);
174 6f4d00ee 2013-09-23 0intro f->afid = strtol(argv[1], 0, 0);
175 6f4d00ee 2013-09-23 0intro f->uname = argv[2];
176 6f4d00ee 2013-09-23 0intro f->aname = argv[3];
178 6f4d00ee 2013-09-23 0intro return 1;
181 6f4d00ee 2013-09-23 0intro static int
182 b32de4ae 2013-09-26 0intro cmd9pTauth(Fcall* f, int i, char** argv)
185 6f4d00ee 2013-09-23 0intro f->afid = strtol(argv[0], 0, 0);
186 6f4d00ee 2013-09-23 0intro f->uname = argv[1];
187 6f4d00ee 2013-09-23 0intro f->aname = argv[2];
189 6f4d00ee 2013-09-23 0intro return 1;
192 6f4d00ee 2013-09-23 0intro static int
193 b32de4ae 2013-09-26 0intro cmd9pTversion(Fcall* f, int i, char** argv)
196 6f4d00ee 2013-09-23 0intro f->msize = strtoul(argv[0], 0, 0);
197 6f4d00ee 2013-09-23 0intro if(f->msize > cbox.con->msize){
198 4b576658 2013-09-23 0intro werrstr("msize too big");
199 6f4d00ee 2013-09-23 0intro return 0;
201 6f4d00ee 2013-09-23 0intro f->version = argv[1];
203 6f4d00ee 2013-09-23 0intro return 1;
206 6f4d00ee 2013-09-23 0intro typedef struct Cmd9p Cmd9p;
207 6f4d00ee 2013-09-23 0intro struct Cmd9p {
208 6f4d00ee 2013-09-23 0intro char* name;
209 6f4d00ee 2013-09-23 0intro int type;
210 6f4d00ee 2013-09-23 0intro int argc;
211 6f4d00ee 2013-09-23 0intro char* usage;
212 6f4d00ee 2013-09-23 0intro int (*f)(Fcall*, int, char**);
215 6f4d00ee 2013-09-23 0intro static Cmd9p cmd9pTmsg[] = {
216 6f4d00ee 2013-09-23 0intro "Tversion", Tversion, 2, "msize version", cmd9pTversion,
217 6f4d00ee 2013-09-23 0intro "Tauth", Tauth, 3, "afid uname aname", cmd9pTauth,
218 6f4d00ee 2013-09-23 0intro "Tflush", Tflush, 1, "oldtag", cmd9pTflush,
219 6f4d00ee 2013-09-23 0intro "Tattach", Tattach, 4, "fid afid uname aname", cmd9pTattach,
220 6f4d00ee 2013-09-23 0intro "Twalk", Twalk, 0, "fid newfid [name...]", cmd9pTwalk,
221 6f4d00ee 2013-09-23 0intro "Topen", Topen, 2, "fid mode", cmd9pTopen,
222 6f4d00ee 2013-09-23 0intro "Tcreate", Tcreate, 4, "fid name perm mode", cmd9pTcreate,
223 6f4d00ee 2013-09-23 0intro "Tread", Tread, 3, "fid offset count", cmd9pTread,
224 6f4d00ee 2013-09-23 0intro "Twrite", Twrite, 3, "fid offset data", cmd9pTwrite,
225 6f4d00ee 2013-09-23 0intro "Tclunk", Tclunk, 1, "fid", cmd9pTclunk,
226 6f4d00ee 2013-09-23 0intro "Tremove", Tremove, 1, "fid", cmd9pTremove,
227 6f4d00ee 2013-09-23 0intro "Tstat", Tstat, 1, "fid", cmd9pTstat,
228 6f4d00ee 2013-09-23 0intro "Twstat", Twstat, 7, "fid name uid gid mode mtime length", cmd9pTwstat,
229 6f4d00ee 2013-09-23 0intro "nexttag", 0, 0, "", cmd9pTag,
232 6f4d00ee 2013-09-23 0intro static int
233 6f4d00ee 2013-09-23 0intro cmd9p(int argc, char* argv[])
235 6f4d00ee 2013-09-23 0intro int i, n;
236 6f4d00ee 2013-09-23 0intro Fcall f, t;
237 6f4d00ee 2013-09-23 0intro uchar *buf;
238 6f4d00ee 2013-09-23 0intro char *usage;
239 6f4d00ee 2013-09-23 0intro u32int msize;
241 6f4d00ee 2013-09-23 0intro usage = "usage: 9p T-message ...";
243 6f4d00ee 2013-09-23 0intro ARGBEGIN{
245 6f4d00ee 2013-09-23 0intro return cliError(usage);
247 6f4d00ee 2013-09-23 0intro if(argc < 1)
248 6f4d00ee 2013-09-23 0intro return cliError(usage);
250 6f4d00ee 2013-09-23 0intro for(i = 0; i < nelem(cmd9pTmsg); i++){
251 6f4d00ee 2013-09-23 0intro if(strcmp(cmd9pTmsg[i].name, argv[0]) == 0)
254 6f4d00ee 2013-09-23 0intro if(i == nelem(cmd9pTmsg))
255 6f4d00ee 2013-09-23 0intro return cliError(usage);
258 6f4d00ee 2013-09-23 0intro if(cmd9pTmsg[i].argc && argc != cmd9pTmsg[i].argc){
259 4b576658 2013-09-23 0intro werrstr("usage: %s %s",
260 6f4d00ee 2013-09-23 0intro cmd9pTmsg[i].name, cmd9pTmsg[i].usage);
261 6f4d00ee 2013-09-23 0intro return 0;
264 6f4d00ee 2013-09-23 0intro memset(&t, 0, sizeof(t));
265 6f4d00ee 2013-09-23 0intro t.type = cmd9pTmsg[i].type;
266 6f4d00ee 2013-09-23 0intro if(t.type == Tversion)
267 6f4d00ee 2013-09-23 0intro t.tag = NOTAG;
269 6f4d00ee 2013-09-23 0intro t.tag = ++cbox.tag;
270 6f4d00ee 2013-09-23 0intro msize = cbox.con->msize;
271 6f4d00ee 2013-09-23 0intro if(!cmd9pTmsg[i].f(&t, argc, argv))
272 6f4d00ee 2013-09-23 0intro return 0;
273 4b576658 2013-09-23 0intro buf = vtmalloc(msize);
274 6f4d00ee 2013-09-23 0intro n = convS2M(&t, buf, msize);
275 6f4d00ee 2013-09-23 0intro if(n <= BIT16SZ){
276 4b576658 2013-09-23 0intro werrstr("%s: convS2M error", cmd9pTmsg[i].name);
277 4b576658 2013-09-23 0intro vtfree(buf);
278 6f4d00ee 2013-09-23 0intro return 0;
280 6f4d00ee 2013-09-23 0intro if(write(cbox.confd[0], buf, n) != n){
281 4b576658 2013-09-23 0intro werrstr("%s: write error: %r", cmd9pTmsg[i].name);
282 4b576658 2013-09-23 0intro vtfree(buf);
283 6f4d00ee 2013-09-23 0intro return 0;
285 6f4d00ee 2013-09-23 0intro consPrint("\t-> %F\n", &t);
287 6f4d00ee 2013-09-23 0intro if((n = read9pmsg(cbox.confd[0], buf, msize)) <= 0){
288 4b576658 2013-09-23 0intro werrstr("%s: read error: %r", cmd9pTmsg[i].name);
289 4b576658 2013-09-23 0intro vtfree(buf);
290 6f4d00ee 2013-09-23 0intro return 0;
292 6f4d00ee 2013-09-23 0intro if(convM2S(buf, n, &f) == 0){
293 4b576658 2013-09-23 0intro werrstr("%s: convM2S error", cmd9pTmsg[i].name);
294 4b576658 2013-09-23 0intro vtfree(buf);
295 6f4d00ee 2013-09-23 0intro return 0;
297 6f4d00ee 2013-09-23 0intro consPrint("\t<- %F\n", &f);
299 4b576658 2013-09-23 0intro vtfree(buf);
300 6f4d00ee 2013-09-23 0intro return 1;
303 6f4d00ee 2013-09-23 0intro static int
304 6f4d00ee 2013-09-23 0intro cmdDot(int argc, char* argv[])
307 6f4d00ee 2013-09-23 0intro Dir *dir;
308 6f4d00ee 2013-09-23 0intro int fd, r;
309 6f4d00ee 2013-09-23 0intro vlong length;
310 6f4d00ee 2013-09-23 0intro char *f, *p, *s, *usage;
312 6f4d00ee 2013-09-23 0intro usage = "usage: . file";
314 6f4d00ee 2013-09-23 0intro ARGBEGIN{
316 6f4d00ee 2013-09-23 0intro return cliError(usage);
318 6f4d00ee 2013-09-23 0intro if(argc != 1)
319 6f4d00ee 2013-09-23 0intro return cliError(usage);
321 6f4d00ee 2013-09-23 0intro if((dir = dirstat(argv[0])) == nil)
322 6f4d00ee 2013-09-23 0intro return cliError(". dirstat %s: %r", argv[0]);
323 6f4d00ee 2013-09-23 0intro length = dir->length;
324 6f4d00ee 2013-09-23 0intro free(dir);
327 6f4d00ee 2013-09-23 0intro if(length != 0){
329 6f4d00ee 2013-09-23 0intro * Read the whole file in.
331 6f4d00ee 2013-09-23 0intro if((fd = open(argv[0], OREAD)) < 0)
332 6f4d00ee 2013-09-23 0intro return cliError(". open %s: %r", argv[0]);
333 4b576658 2013-09-23 0intro f = vtmalloc(dir->length+1);
334 6f4d00ee 2013-09-23 0intro if((l = read(fd, f, length)) < 0){
335 4b576658 2013-09-23 0intro vtfree(f);
336 6f4d00ee 2013-09-23 0intro close(fd);
337 6f4d00ee 2013-09-23 0intro return cliError(". read %s: %r", argv[0]);
339 6f4d00ee 2013-09-23 0intro close(fd);
340 6f4d00ee 2013-09-23 0intro f[l] = '\0';
343 6f4d00ee 2013-09-23 0intro * Call cliExec() for each line.
345 6f4d00ee 2013-09-23 0intro for(p = s = f; *p != '\0'; p++){
346 6f4d00ee 2013-09-23 0intro if(*p == '\n'){
347 6f4d00ee 2013-09-23 0intro *p = '\0';
348 6f4d00ee 2013-09-23 0intro if(cliExec(s) == 0){
350 4b576658 2013-09-23 0intro consPrint("%s: %r\n", s);
355 4b576658 2013-09-23 0intro vtfree(f);
358 6f4d00ee 2013-09-23 0intro if(r == 0)
359 4b576658 2013-09-23 0intro werrstr("errors in . %#q", argv[0]);
360 6f4d00ee 2013-09-23 0intro return r;
363 6f4d00ee 2013-09-23 0intro static int
364 6f4d00ee 2013-09-23 0intro cmdDflag(int argc, char* argv[])
366 6f4d00ee 2013-09-23 0intro char *usage;
368 6f4d00ee 2013-09-23 0intro usage = "usage: dflag";
370 6f4d00ee 2013-09-23 0intro ARGBEGIN{
372 6f4d00ee 2013-09-23 0intro return cliError(usage);
375 6f4d00ee 2013-09-23 0intro return cliError(usage);
377 6f4d00ee 2013-09-23 0intro Dflag ^= 1;
378 6f4d00ee 2013-09-23 0intro consPrint("dflag %d\n", Dflag);
380 6f4d00ee 2013-09-23 0intro return 1;
383 6f4d00ee 2013-09-23 0intro static int
384 6f4d00ee 2013-09-23 0intro cmdEcho(int argc, char* argv[])
386 6f4d00ee 2013-09-23 0intro char *usage;
387 6f4d00ee 2013-09-23 0intro int i, nflag;
389 6f4d00ee 2013-09-23 0intro nflag = 0;
390 6f4d00ee 2013-09-23 0intro usage = "usage: echo [-n] ...";
392 6f4d00ee 2013-09-23 0intro ARGBEGIN{
394 6f4d00ee 2013-09-23 0intro return cliError(usage);
395 6f4d00ee 2013-09-23 0intro case 'n':
396 6f4d00ee 2013-09-23 0intro nflag = 1;
400 6f4d00ee 2013-09-23 0intro for(i = 0; i < argc; i++){
401 6f4d00ee 2013-09-23 0intro if(i != 0)
402 6f4d00ee 2013-09-23 0intro consPrint(" %s", argv[i]);
404 6f4d00ee 2013-09-23 0intro consPrint(argv[i]);
406 6f4d00ee 2013-09-23 0intro if(!nflag)
407 6f4d00ee 2013-09-23 0intro consPrint("\n");
409 6f4d00ee 2013-09-23 0intro return 1;
412 6f4d00ee 2013-09-23 0intro static int
413 6f4d00ee 2013-09-23 0intro cmdBind(int argc, char* argv[])
415 6f4d00ee 2013-09-23 0intro ulong flag = 0;
416 6f4d00ee 2013-09-23 0intro char *usage;
418 6f4d00ee 2013-09-23 0intro usage = "usage: bind [-b|-a|-c|-bc|-ac] new old";
420 6f4d00ee 2013-09-23 0intro ARGBEGIN{
421 6f4d00ee 2013-09-23 0intro case 'a':
422 6f4d00ee 2013-09-23 0intro flag |= MAFTER;
424 6f4d00ee 2013-09-23 0intro case 'b':
425 6f4d00ee 2013-09-23 0intro flag |= MBEFORE;
427 6f4d00ee 2013-09-23 0intro case 'c':
428 6f4d00ee 2013-09-23 0intro flag |= MCREATE;
431 6f4d00ee 2013-09-23 0intro return cliError(usage);
434 6f4d00ee 2013-09-23 0intro if(argc != 2 || (flag&MAFTER)&&(flag&MBEFORE))
435 6f4d00ee 2013-09-23 0intro return cliError(usage);
437 b32de4ae 2013-09-26 0intro #ifndef PLAN9PORT
438 6f4d00ee 2013-09-23 0intro if(bind(argv[0], argv[1], flag) < 0){
439 6f4d00ee 2013-09-23 0intro /* try to give a less confusing error than the default */
440 6f4d00ee 2013-09-23 0intro if(access(argv[0], 0) < 0)
441 6f4d00ee 2013-09-23 0intro return cliError("bind: %s: %r", argv[0]);
442 6f4d00ee 2013-09-23 0intro else if(access(argv[1], 0) < 0)
443 6f4d00ee 2013-09-23 0intro return cliError("bind: %s: %r", argv[1]);
445 6f4d00ee 2013-09-23 0intro return cliError("bind %s %s: %r", argv[0], argv[1]);
448 6f4d00ee 2013-09-23 0intro return 1;
452 6f4d00ee 2013-09-23 0intro cmdInit(void)
454 6f4d00ee 2013-09-23 0intro cbox.confd[0] = cbox.confd[1] = -1;
456 6f4d00ee 2013-09-23 0intro cliAddCmd(".", cmdDot);
457 6f4d00ee 2013-09-23 0intro cliAddCmd("9p", cmd9p);
458 6f4d00ee 2013-09-23 0intro cliAddCmd("dflag", cmdDflag);
459 6f4d00ee 2013-09-23 0intro cliAddCmd("echo", cmdEcho);
460 6f4d00ee 2013-09-23 0intro cliAddCmd("bind", cmdBind);
462 6f4d00ee 2013-09-23 0intro if(pipe(cbox.confd) < 0)
463 6f4d00ee 2013-09-23 0intro return 0;
464 6f4d00ee 2013-09-23 0intro if((cbox.con = conAlloc(cbox.confd[1], "console", 0)) == nil){
465 6f4d00ee 2013-09-23 0intro close(cbox.confd[0]);
466 6f4d00ee 2013-09-23 0intro close(cbox.confd[1]);
467 6f4d00ee 2013-09-23 0intro cbox.confd[0] = cbox.confd[1] = -1;
468 6f4d00ee 2013-09-23 0intro return 0;
471 6f4d00ee 2013-09-23 0intro cbox.con->isconsole = 1;
473 6f4d00ee 2013-09-23 0intro return 1;