Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <thread.h>
5 #include <venti.h>
6 #include <sunrpc.h>
7 #include <nfs3.h>
8 #include <diskfs.h>
10 uchar *buf;
11 uint bufsize;
12 Nfs3Handle cwd, root;
13 Biobuf bin, bout;
14 char pwd[1000];
15 Fsys *fsys;
16 SunAuthUnix *auth;
17 VtConn *z;
18 VtCache *c;
19 Disk *disk;
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;
30 struct Cmd
31 {
32 char *s;
33 char *(*fn)(int, char**);
34 char *help;
35 };
37 Cmd cmdtab[] =
38 {
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",
46 };
48 char*
49 ebuf(void)
50 {
51 static char buf[ERRMAX];
53 rerrstr(buf, sizeof buf);
54 return buf;
55 }
57 char*
58 walk(char *path, Nfs3Handle *ph)
59 {
60 char *p, *q;
61 Nfs3Handle h;
62 Nfs3Status ok;
64 if(path[0] == '/')
65 h = root;
66 else
67 h = cwd;
68 for(p=path; *p; p=q){
69 q = strchr(p, '/');
70 if(q == nil)
71 q = p+strlen(p);
72 else
73 *q++ = 0;
74 if(*p == 0)
75 continue;
76 if((ok = fsyslookup(fsys, auth, &h, p, &h)) != Nfs3Ok){
77 nfs3errstr(ok);
78 return ebuf();
79 }
80 }
81 *ph = h;
82 return nil;
83 }
85 char*
86 cmdhelp(int argc, char **argv)
87 {
88 int i;
90 for(i=0; i<nelem(cmdtab); i++)
91 print("%s\n", cmdtab[i].help);
92 return nil;
93 }
95 char*
96 cmdcd(int argc, char **argv)
97 {
98 char *err;
99 Nfs3Attr attr;
100 Nfs3Status ok;
101 Nfs3Handle h;
103 if(argc != 2)
104 return "usage: cd dir";
106 if((err = walk(argv[1], &h)) != nil)
107 return err;
108 if((ok = fsysgetattr(fsys, auth, &h, &attr)) != Nfs3Ok){
109 nfs3errstr(ok);
110 fprint(2, "%s: %r\n");
111 return nil;
113 if(attr.type != Nfs3FileDir)
114 return "not a directory";
115 if(argv[1][0] == '/')
116 pwd[0] = 0;
117 strcat(pwd, "/");
118 strcat(pwd, argv[1]);
119 cleanname(pwd);
120 cwd = h;
121 print("%s\n", pwd);
122 return nil;
125 char*
126 cmdpwd(int argc, char **argv)
128 if(argc != 1)
129 return "usage: pwd";
131 print("%s\n", pwd);
132 return nil;
135 /*
136 * XXX maybe make a list of these in memory and then print them nicer
137 */
138 void
139 ls(char *dir, char *elem, Nfs3Attr *attr)
141 char c;
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);
148 Bprint(&bout, "\n");
151 void
152 lsdir(char *dir, Nfs3Handle *h)
154 uchar *data, *p, *ep;
155 Nfs3Attr attr;
156 Nfs3Entry e;
157 Nfs3Handle eh;
158 u32int count;
159 u1int eof;
160 Nfs3Status ok;
161 u64int cookie;
163 cookie = 0;
164 for(;;){
165 ok = fsysreaddir(fsys, auth, h, 8192, cookie, &data, &count, &eof);
166 if(ok != Nfs3Ok){
167 nfs3errstr(ok);
168 fprint(2, "ls %s: %r\n", dir);
169 return;
171 fprint(2, "got %d\n", count);
172 p = data;
173 ep = data+count;
174 while(p<ep){
175 if(nfs3entryunpack(p, ep, &p, &e) < 0){
176 fprint(2, "%s: unpacking directory: %r\n", dir);
177 break;
179 cookie = e.cookie;
180 if((ok = fsyslookup(fsys, auth, h, e.name, &eh)) != Nfs3Ok){
181 nfs3errstr(ok);
182 fprint(2, "%s/%s: %r\n", dir, e.name);
183 continue;
185 if((ok = fsysgetattr(fsys, auth, &eh, &attr)) != Nfs3Ok){
186 nfs3errstr(ok);
187 fprint(2, "%s/%s: %r\n", dir, e.name);
188 continue;
190 ls(dir, e.name, &attr);
192 free(data);
193 if(eof)
194 break;
198 char*
199 cmdls(int argc, char **argv)
201 int i;
202 int dflag;
203 char *e;
204 Nfs3Handle h;
205 Nfs3Attr attr;
206 Nfs3Status ok;
208 dflag = 0;
209 ARGBEGIN{
210 case 'd':
211 dflag = 1;
212 break;
213 default:
214 return "usage: ls [-d] [path...]";
215 }ARGEND
217 if(argc == 0){
218 lsdir(nil, &cwd);
219 Bflush(&bout);
220 return nil;
223 for(i=0; i<argc; i++){
224 if((e = walk(argv[i], &h)) != nil){
225 fprint(2, "%s: %s\n", argv[i], e);
226 continue;
228 if((ok = fsysgetattr(fsys, auth, &h, &attr)) != Nfs3Ok){
229 nfs3errstr(ok);
230 fprint(2, "%s: %r\n", argv[i]);
231 continue;
233 if(attr.type != Nfs3FileDir || dflag)
234 ls(argv[i], nil, &attr);
235 else
236 lsdir(argv[i], &h);
237 Bflush(&bout);
239 return nil;
242 char*
243 cmdget(int argc, char **argv)
245 uchar eof;
246 u32int n;
247 int dflag, fd;
248 char *e, *local;
249 uchar *buf;
250 Nfs3Handle h;
251 Nfs3Attr attr;
252 Nfs3Status ok;
253 vlong o;
255 dflag = 0;
256 ARGBEGIN{
257 default:
258 usage:
259 return "usage: get path [lpath]]";
260 }ARGEND
262 if(argc != 1 && argc != 2)
263 goto usage;
265 if((e = walk(argv[0], &h)) != nil){
266 fprint(2, "%s: %s\n", argv[0], e);
267 return nil;
269 if((ok = fsysgetattr(fsys, auth, &h, &attr)) != Nfs3Ok){
270 nfs3errstr(ok);
271 fprint(2, "%s: %r\n", argv[0]);
272 return nil;
274 local = argv[0];
275 if(argc == 2)
276 local = argv[1];
277 if((fd = create(local, OWRITE, 0666)) < 0){
278 fprint(2, "create %s: %r\n", local);
279 return nil;
281 eof = 0;
282 for(o=0; o<attr.size && !eof; o+=n){
283 if((ok = fsysreadfile(fsys, nil, &h, fsys->blocksize, o, &buf, &n, &eof)) != Nfs3Ok){
284 nfs3errstr(ok);
285 fprint(2, "reading %s: %r\n", argv[0]);
286 close(fd);
287 return nil;
289 if(write(fd, buf, n) != n){
290 fprint(2, "writing %s: %r\n", local);
291 close(fd);
292 free(buf);
293 return nil;
295 free(buf);
297 close(fd);
298 fprint(2, "copied %,lld bytes\n", o);
299 return nil;
303 char*
304 cmdblock(int argc, char **argv)
306 char *e;
307 Nfs3Handle h;
308 u64int bno;
310 ARGBEGIN{
311 default:
312 return "usage: block path offset";
313 }ARGEND
315 if(argc != 2)
316 return "usage: block path offset";
318 if((e = walk(argv[0], &h)) != nil){
319 fprint(2, "%s: %s\n", argv[0], e);
320 return nil;
322 if((bno = fsys->fileblock(fsys, &h, strtoll(argv[1], 0, 0))) == 0){
323 fprint(2, "%s: %r\n", argv[0]);
324 return nil;
326 print("%#llux\n", bno);
327 return nil;
330 char*
331 cmddisk(int argc, char **argv)
333 Block *b;
334 int delta, count, i;
335 u64int offset;
336 uchar *p;
338 ARGBEGIN{
339 default:
340 return "usage: disk offset count";
341 }ARGEND
343 if(argc != 2)
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);
351 if(b == nil){
352 fprint(2, "diskread: %r\n");
353 return nil;
355 p = b->data + delta;
356 for(i=0; i<count; i++){
357 Bprint(&bout, "%2.2ux ", p[i]);
358 if(i%16 == 15)
359 Bprint(&bout, "\n");
360 else if(i%8 == 7)
361 Bprint(&bout, " - ");
363 if(i%16 != 0)
364 Bprint(&bout, "\n");
365 Bflush(&bout);
366 blockput(b);
367 return nil;
370 void
371 usage(void)
373 fprint(2, "usage: vftp score\n");
374 threadexitsall("usage");
377 void
378 threadmain(int argc, char **argv)
380 char *err, *f[10], *p;
381 int i, nf;
382 uchar score[VtScoreSize];
383 Nfs3Status ok;
385 ARGBEGIN{
386 case 'V':
387 chattyventi++;
388 break;
389 default:
390 usage();
391 }ARGEND
393 if(argc != 1)
394 usage();
396 fmtinstall('F', vtfcallfmt);
397 fmtinstall('H', encodefmt);
398 fmtinstall('V', vtscorefmt);
400 if(access(argv[0], AEXIST) >= 0 || strchr(argv[0], '/')){
401 if((disk = diskopenfile(argv[0])) == nil)
402 sysfatal("diskopen: %r");
403 if((disk = diskcache(disk, 16384, 16)) == nil)
404 sysfatal("diskcache: %r");
405 }else{
406 if(vtparsescore(argv[0], nil, score) < 0)
407 sysfatal("bad score '%s'", argv[0]);
408 if((z = vtdial(nil)) == nil)
409 sysfatal("vtdial: %r");
410 if(vtconnect(z) < 0)
411 sysfatal("vtconnect: %r");
412 if((c = vtcachealloc(z, 16384, 32)) == nil)
413 sysfatal("vtcache: %r");
414 if((disk = diskopenventi(c, score)) == nil)
415 sysfatal("diskopenventi: %r");
417 if((fsys = fsysopen(disk)) == nil)
418 sysfatal("ffsopen: %r");
420 fprint(2, "block size %d\n", fsys->blocksize);
421 buf = emalloc(fsys->blocksize);
422 if((ok = fsysroot(fsys, &root)) != Nfs3Ok){
423 nfs3errstr(ok);
424 sysfatal("accessing root: %r");
426 cwd = root;
427 Binit(&bin, 0, OREAD);
428 Binit(&bout, 1, OWRITE);
430 while(fprint(2, "vftp> "), (p = Brdstr(&bin, '\n', 1)) != nil){
431 if(p[0] == '#')
432 continue;
433 nf = tokenize(p, f, nelem(f));
434 if(nf == 0)
435 continue;
436 for(i=0; i<nelem(cmdtab); i++){
437 if(strcmp(f[0], cmdtab[i].s) == 0){
438 if((err = cmdtab[i].fn(nf, f)) != nil)
439 fprint(2, "%s\n", err);
440 break;
443 if(i == nelem(cmdtab))
444 fprint(2, "unknown command '%s'\n", f[0]);
446 threadexitsall(nil);