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);
62 t = emalloc(strlen(s)+1);
68 walk(char *path, Nfs3Handle *ph)
74 path = estrdup(path); /* writable */
87 if((ok = fsyslookup(fsys, auth, &h, p, &h)) != Nfs3Ok){
99 cmdhelp(int argc, char **argv)
103 for(i=0; i<nelem(cmdtab); i++)
104 print("%s\n", cmdtab[i].help);
109 cmdcd(int argc, char **argv)
117 return "usage: cd dir";
119 if((err = walk(argv[1], &h)) != nil)
121 if((ok = fsysgetattr(fsys, auth, &h, &attr)) != Nfs3Ok){
123 fprint(2, "%s: %r\n", argv[1]);
126 if(attr.type != Nfs3FileDir)
127 return "not a directory";
128 if(argv[1][0] == '/')
131 strcat(pwd, argv[1]);
139 cmdpwd(int argc, char **argv)
149 * XXX maybe make a list of these in memory and then print them nicer
152 ls(char *dir, char *elem, Nfs3Attr *attr)
156 c = ' '; /* use attr->type */
157 Bprint(&bout, "%s%s%s", dir ? dir : "", dir && elem ? "/" : "", elem ? elem : "");
158 Bprint(&bout, " %c%luo %1d %4d %4d", c, attr->mode, attr->nlink, attr->uid, attr->gid);
159 Bprint(&bout, " %11,lld %11,lld %4d.%4d %#11,llux %#11,llux",
160 attr->size, attr->used, attr->major, attr->minor, attr->fsid, attr->fileid);
165 lsdir(char *dir, Nfs3Handle *h)
167 uchar *data, *p, *ep;
178 ok = fsysreaddir(fsys, auth, h, 8192, cookie, &data, &count, &eof);
181 fprint(2, "ls %s: %r\n", dir);
184 fprint(2, "got %d\n", count);
188 if(nfs3entryunpack(p, ep, &p, &e) < 0){
189 fprint(2, "%s: unpacking directory: %r\n", dir);
193 if((ok = fsyslookup(fsys, auth, h, e.name, &eh)) != Nfs3Ok){
195 fprint(2, "%s/%s: %r\n", dir, e.name);
198 if((ok = fsysgetattr(fsys, auth, &eh, &attr)) != Nfs3Ok){
200 fprint(2, "%s/%s: %r\n", dir, e.name);
203 ls(dir, e.name, &attr);
212 cmdls(int argc, char **argv)
227 return "usage: ls [-d] [path...]";
236 for(i=0; i<argc; i++){
237 if((e = walk(argv[i], &h)) != nil){
238 fprint(2, "%s: %s\n", argv[i], e);
241 if((ok = fsysgetattr(fsys, auth, &h, &attr)) != Nfs3Ok){
243 fprint(2, "%s: %r\n", argv[i]);
246 if(attr.type != Nfs3FileDir || dflag)
247 ls(argv[i], nil, &attr);
256 cmdget(int argc, char **argv)
272 return "usage: get path [lpath]]";
275 if(argc != 1 && argc != 2)
278 if((e = walk(argv[0], &h)) != nil){
279 fprint(2, "%s: %s\n", argv[0], e);
282 if((ok = fsysgetattr(fsys, auth, &h, &attr)) != Nfs3Ok){
284 fprint(2, "%s: %r\n", argv[0]);
290 if((fd = create(local, OWRITE, 0666)) < 0){
291 fprint(2, "create %s: %r\n", local);
295 for(o=0; o<attr.size && !eof; o+=n){
296 if((ok = fsysreadfile(fsys, nil, &h, fsys->blocksize, o, &buf, &n, &eof)) != Nfs3Ok){
298 fprint(2, "reading %s: %r\n", argv[0]);
302 if(write(fd, buf, n) != n){
303 fprint(2, "writing %s: %r\n", local);
311 fprint(2, "copied %,lld bytes\n", o);
317 cmdblock(int argc, char **argv)
325 return "usage: block path offset";
329 return "usage: block path offset";
331 if((e = walk(argv[0], &h)) != nil){
332 fprint(2, "%s: %s\n", argv[0], e);
335 if((bno = fsys->fileblock(fsys, &h, strtoll(argv[1], 0, 0))) == 0){
336 fprint(2, "%s: %r\n", argv[0]);
339 print("%#llux\n", bno);
344 cmddisk(int argc, char **argv)
353 return "usage: disk offset count";
357 return "usage: disk offset count";
359 offset = strtoull(argv[0], 0, 0);
360 count = atoi(argv[1]);
361 delta = offset%fsys->blocksize;
363 b = diskread(disk, fsys->blocksize, offset-delta);
365 fprint(2, "diskread: %r\n");
369 for(i=0; i<count; i++){
370 Bprint(&bout, "%2.2ux ", p[i]);
374 Bprint(&bout, " - ");
386 fprint(2, "usage: vftp score\n");
387 threadexitsall("usage");
393 threadmain(int argc, char **argv)
395 char *err, *f[10], *p;
397 uchar score[VtScoreSize];
412 fmtinstall('F', vtfcallfmt);
413 fmtinstall('H', encodefmt);
414 fmtinstall('V', vtscorefmt);
416 if(access(argv[0], AEXIST) >= 0 || strchr(argv[0], '/')){
417 if((disk = diskopenfile(argv[0])) == nil)
418 sysfatal("diskopen: %r");
419 if((disk = diskcache(disk, 32768, 16)) == nil)
420 sysfatal("diskcache: %r");
422 if(vtparsescore(argv[0], nil, score) < 0)
423 sysfatal("bad score '%s'", argv[0]);
424 if((z = vtdial(nil)) == nil)
425 sysfatal("vtdial: %r");
427 sysfatal("vtconnect: %r");
428 if((c = vtcachealloc(z, 32768, 32)) == nil)
429 sysfatal("vtcache: %r");
430 if((disk = diskopenventi(c, score)) == nil)
431 sysfatal("diskopenventi: %r");
433 if((fsys = fsysopen(disk)) == nil)
434 sysfatal("fsysopen: %r");
436 fprint(2, "block size %d\n", fsys->blocksize);
437 buf = emalloc(fsys->blocksize);
438 if((ok = fsysroot(fsys, &root)) != Nfs3Ok){
440 sysfatal("accessing root: %r");
443 Binit(&bin, 0, OREAD);
444 Binit(&bout, 1, OWRITE);
446 while(fprint(2, "vftp> "), (p = Brdstr(&bin, '\n', 1)) != nil){
449 nf = tokenize(p, f, nelem(f));
452 for(i=0; i<nelem(cmdtab); i++){
453 if(strcmp(f[0], cmdtab[i].s) == 0){
454 if((err = cmdtab[i].fn(nf, f)) != nil)
455 fprint(2, "%s\n", err);
459 if(i == nelem(cmdtab))
460 fprint(2, "unknown command '%s'\n", f[0]);