21 char *cmdhelp(int, char**);
22 char *cmdcd(int, char**);
23 char *cmdpwd(int, char**);
24 char *cmdls(int, char**);
25 char *cmdget(int, char**);
26 char *cmdblock(int, char**);
27 char *cmddisk(int, char**);
29 typedef struct Cmd Cmd;
33 char *(*fn)(int, char**);
39 "cd", cmdcd, "cd dir - change directory",
40 "ls", cmdls, "ls [-d] path... - list file",
41 "get", cmdget, "get path [lpath] - copy file to local directory",
42 "pwd", cmdpwd, "pwd - print working directory",
43 "help", cmdhelp, "help - print usage summaries",
44 "block", cmdblock, "block path offset - print disk offset of path's byte offset",
45 "disk", cmddisk, "disk offset count - dump disk contents"
51 static char buf[ERRMAX];
53 rerrstr(buf, sizeof buf);
58 walk(char *path, Nfs3Handle *ph)
76 if((ok = fsyslookup(fsys, auth, &h, p, &h)) != Nfs3Ok){
86 cmdhelp(int argc, char **argv)
90 for(i=0; i<nelem(cmdtab); i++)
91 print("%s\n", cmdtab[i].help);
96 cmdcd(int argc, char **argv)
104 return "usage: cd dir";
106 if((err = walk(argv[1], &h)) != nil)
108 if((ok = fsysgetattr(fsys, auth, &h, &attr)) != Nfs3Ok){
110 fprint(2, "%s: %r\n");
113 if(attr.type != Nfs3FileDir)
114 return "not a directory";
115 if(argv[1][0] == '/')
118 strcat(pwd, argv[1]);
126 cmdpwd(int argc, char **argv)
136 * XXX maybe make a list of these in memory and then print them nicer
139 ls(char *dir, char *elem, Nfs3Attr *attr)
143 c = ' '; /* use attr->type */
144 Bprint(&bout, "%s%s%s", dir ? dir : "", dir && elem ? "/" : "", elem ? elem : "");
145 Bprint(&bout, " %c%luo %1d %4d %4d", c, attr->mode, attr->nlink, attr->uid, attr->gid);
146 Bprint(&bout, " %11,lld %11,lld %4d.%4d %#11,llux %#11,llux",
147 attr->size, attr->used, attr->major, attr->minor, attr->fsid, attr->fileid);
152 lsdir(char *dir, Nfs3Handle *h)
154 uchar *data, *p, *ep;
165 ok = fsysreaddir(fsys, auth, h, 8192, cookie, &data, &count, &eof);
168 fprint(2, "ls %s: %r\n", dir);
171 fprint(2, "got %d\n", count);
175 if(nfs3entryunpack(p, ep, &p, &e) < 0){
176 fprint(2, "%s: unpacking directory: %r\n", dir);
180 if((ok = fsyslookup(fsys, auth, h, e.name, &eh)) != Nfs3Ok){
182 fprint(2, "%s/%s: %r\n", dir, e.name);
185 if((ok = fsysgetattr(fsys, auth, &eh, &attr)) != Nfs3Ok){
187 fprint(2, "%s/%s: %r\n", dir, e.name);
190 ls(dir, e.name, &attr);
199 cmdls(int argc, char **argv)
214 return "usage: ls [-d] [path...]";
223 for(i=0; i<argc; i++){
224 if((e = walk(argv[i], &h)) != nil){
225 fprint(2, "%s: %s\n", argv[i], e);
228 if((ok = fsysgetattr(fsys, auth, &h, &attr)) != Nfs3Ok){
230 fprint(2, "%s: %r\n", argv[i]);
233 if(attr.type != Nfs3FileDir || dflag)
234 ls(argv[i], nil, &attr);
243 cmdget(int argc, char **argv)
259 return "usage: get path [lpath]]";
262 if(argc != 1 && argc != 2)
265 if((e = walk(argv[0], &h)) != nil){
266 fprint(2, "%s: %s\n", argv[0], e);
269 if((ok = fsysgetattr(fsys, auth, &h, &attr)) != Nfs3Ok){
271 fprint(2, "%s: %r\n", argv[0]);
277 if((fd = create(local, OWRITE, 0666)) < 0){
278 fprint(2, "create %s: %r\n", local);
282 for(o=0; o<attr.size && !eof; o+=n){
283 if((ok = fsysreadfile(fsys, nil, &h, fsys->blocksize, o, &buf, &n, &eof)) != Nfs3Ok){
285 fprint(2, "reading %s: %r\n", argv[0]);
289 if(write(fd, buf, n) != n){
290 fprint(2, "writing %s: %r\n", local);
298 fprint(2, "copied %,lld bytes\n", o);
304 cmdblock(int argc, char **argv)
312 return "usage: block path offset";
316 return "usage: block path offset";
318 if((e = walk(argv[0], &h)) != nil){
319 fprint(2, "%s: %s\n", argv[0], e);
322 if((bno = fsys->fileblock(fsys, &h, strtoll(argv[1], 0, 0))) == 0){
323 fprint(2, "%s: %r\n", argv[0]);
326 print("%#llux\n", bno);
331 cmddisk(int argc, char **argv)
340 return "usage: disk offset count";
344 return "usage: disk offset count";
346 offset = strtoull(argv[0], 0, 0);
347 count = atoi(argv[1]);
348 delta = offset%fsys->blocksize;
350 b = diskread(disk, fsys->blocksize, offset-delta);
352 fprint(2, "diskread: %r\n");
356 for(i=0; i<count; i++){
357 Bprint(&bout, "%2.2ux ", p[i]);
361 Bprint(&bout, " - ");
373 fprint(2, "usage: vftp score\n");
374 threadexitsall("usage");
380 threadmain(int argc, char **argv)
382 char *err, *f[10], *p;
384 uchar score[VtScoreSize];
399 fmtinstall('F', vtfcallfmt);
400 fmtinstall('H', encodefmt);
401 fmtinstall('V', vtscorefmt);
403 if(access(argv[0], AEXIST) >= 0 || strchr(argv[0], '/')){
404 if((disk = diskopenfile(argv[0])) == nil)
405 sysfatal("diskopen: %r");
406 if((disk = diskcache(disk, 32768, 16)) == nil)
407 sysfatal("diskcache: %r");
409 if(vtparsescore(argv[0], nil, score) < 0)
410 sysfatal("bad score '%s'", argv[0]);
411 if((z = vtdial(nil)) == nil)
412 sysfatal("vtdial: %r");
414 sysfatal("vtconnect: %r");
415 if((c = vtcachealloc(z, 32768, 32)) == nil)
416 sysfatal("vtcache: %r");
417 if((disk = diskopenventi(c, score)) == nil)
418 sysfatal("diskopenventi: %r");
420 if((fsys = fsysopen(disk)) == nil)
421 sysfatal("fsysopen: %r");
423 fprint(2, "block size %d\n", fsys->blocksize);
424 buf = emalloc(fsys->blocksize);
425 if((ok = fsysroot(fsys, &root)) != Nfs3Ok){
427 sysfatal("accessing root: %r");
430 Binit(&bin, 0, OREAD);
431 Binit(&bout, 1, OWRITE);
433 while(fprint(2, "vftp> "), (p = Brdstr(&bin, '\n', 1)) != nil){
436 nf = tokenize(p, f, nelem(f));
439 for(i=0; i<nelem(cmdtab); i++){
440 if(strcmp(f[0], cmdtab[i].s) == 0){
441 if((err = cmdtab[i].fn(nf, f)) != nil)
442 fprint(2, "%s\n", err);
446 if(i == nelem(cmdtab))
447 fprint(2, "unknown command '%s'\n", f[0]);