aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/vbackup
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2005-07-28 12:46:10 +0000
committerrsc <devnull@localhost>2005-07-28 12:46:10 +0000
commitd0cda8c42368dd1208469c7bd81749667df39a03 (patch)
tree861825347da754e11b3e2c701c60eef763903762 /src/cmd/vbackup
parentf19d56825d36b224a376b4012c7656871d9b1535 (diff)
downloadplan9port-d0cda8c42368dd1208469c7bd81749667df39a03.tar.gz
plan9port-d0cda8c42368dd1208469c7bd81749667df39a03.tar.bz2
plan9port-d0cda8c42368dd1208469c7bd81749667df39a03.zip
new
Diffstat (limited to 'src/cmd/vbackup')
-rw-r--r--src/cmd/vbackup/vftp.c379
1 files changed, 379 insertions, 0 deletions
diff --git a/src/cmd/vbackup/vftp.c b/src/cmd/vbackup/vftp.c
new file mode 100644
index 00000000..bae4b901
--- /dev/null
+++ b/src/cmd/vbackup/vftp.c
@@ -0,0 +1,379 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <thread.h>
+#include <venti.h>
+#include <sunrpc.h>
+#include <nfs3.h>
+#include <diskfs.h>
+
+uchar *buf;
+uint bufsize;
+Nfs3Handle cwd, root;
+Biobuf bin, bout;
+char pwd[1000];
+Fsys *fsys;
+SunAuthUnix *auth;
+VtConn *z;
+VtCache *c;
+Disk *disk;
+
+char *cmdhelp(int, char**);
+char *cmdcd(int, char**);
+char *cmdpwd(int, char**);
+char *cmdls(int, char**);
+char *cmdcp(int, char**);
+char *cmdblock(int, char**);
+char *cmddisk(int, char**);
+
+typedef struct Cmd Cmd;
+struct Cmd
+{
+ char *s;
+ char *(*fn)(int, char**);
+ char *help;
+};
+
+Cmd cmdtab[] =
+{
+ "cd", cmdcd, "cd dir - change directory",
+ "ls", cmdls, "ls [-d] path... - list file",
+ "pwd", cmdpwd, "pwd - print working directory",
+ "help", cmdhelp, "help - print usage summaries",
+ "block", cmdblock, "block path offset - print disk offset of path's byte offset",
+ "disk", cmddisk, "disk offset count - dump disk contents",
+};
+
+char*
+ebuf(void)
+{
+ static char buf[ERRMAX];
+
+ rerrstr(buf, sizeof buf);
+ return buf;
+}
+
+char*
+walk(char *path, Nfs3Handle *ph)
+{
+ char *p, *q;
+ Nfs3Handle h;
+ Nfs3Status ok;
+
+ if(path[0] == '/')
+ h = root;
+ else
+ h = cwd;
+ for(p=path; *p; p=q){
+ q = strchr(p, '/');
+ if(q == nil)
+ q = p+strlen(p);
+ else
+ *q++ = 0;
+ if(*p == 0)
+ continue;
+ if((ok = fsyslookup(fsys, auth, &h, p, &h)) != Nfs3Ok){
+ nfs3errstr(ok);
+ return ebuf();
+ }
+ }
+ *ph = h;
+ return nil;
+}
+
+char*
+cmdhelp(int argc, char **argv)
+{
+ int i;
+
+ for(i=0; i<nelem(cmdtab); i++)
+ print("%s\n", cmdtab[i].help);
+ return nil;
+}
+
+char*
+cmdcd(int argc, char **argv)
+{
+ char *err;
+ Nfs3Attr attr;
+ Nfs3Status ok;
+ Nfs3Handle h;
+
+ if(argc != 2)
+ return "usage: cd dir";
+
+ if((err = walk(argv[1], &h)) != nil)
+ return err;
+ if((ok = fsysgetattr(fsys, auth, &h, &attr)) != Nfs3Ok){
+ nfs3errstr(ok);
+ fprint(2, "%s: %r\n");
+ return nil;
+ }
+ if(attr.type != Nfs3FileDir)
+ return "not a directory";
+ if(argv[1][0] == '/')
+ pwd[0] = 0;
+ strcat(pwd, "/");
+ strcat(pwd, argv[1]);
+ cleanname(pwd);
+ cwd = h;
+ print("%s\n", pwd);
+ return nil;
+}
+
+char*
+cmdpwd(int argc, char **argv)
+{
+ if(argc != 1)
+ return "usage: pwd";
+
+ print("%s\n", pwd);
+ return nil;
+}
+
+/*
+ * XXX maybe make a list of these in memory and then print them nicer
+ */
+void
+ls(char *dir, char *elem, Nfs3Attr *attr)
+{
+ char c;
+
+ c = ' '; /* use attr->type */
+ Bprint(&bout, "%s%s%s", dir ? dir : "", dir && elem ? "/" : "", elem ? elem : "");
+ Bprint(&bout, " %c%luo %1d %4d %4d", c, attr->mode, attr->nlink, attr->uid, attr->gid);
+ Bprint(&bout, " %11,lld %11,lld %4d.%4d %#11,llux %#11,llux",
+ attr->size, attr->used, attr->major, attr->minor, attr->fsid, attr->fileid);
+ Bprint(&bout, "\n");
+}
+
+void
+lsdir(char *dir, Nfs3Handle *h)
+{
+ uchar *data, *p, *ep;
+ Nfs3Attr attr;
+ Nfs3Entry e;
+ Nfs3Handle eh;
+ u32int count;
+ u1int eof;
+ Nfs3Status ok;
+ u64int cookie;
+
+ cookie = 0;
+ for(;;){
+ ok = fsysreaddir(fsys, auth, h, 8192, cookie, &data, &count, &eof);
+fprint(2, "got %d\n", count);
+ if(ok != Nfs3Ok){
+ nfs3errstr(ok);
+ fprint(2, "ls %s: %r\n", dir);
+ return;
+ }
+ p = data;
+ ep = data+count;
+ while(p<ep){
+ if(nfs3entryunpack(p, ep, &p, &e) < 0){
+ fprint(2, "%s: unpacking directory: %r\n", dir);
+ break;
+ }
+ cookie = e.cookie;
+ if((ok = fsyslookup(fsys, auth, h, e.name, &eh)) != Nfs3Ok){
+ nfs3errstr(ok);
+ fprint(2, "%s/%s: %r\n", dir, e.name);
+ continue;
+ }
+ if((ok = fsysgetattr(fsys, auth, &eh, &attr)) != Nfs3Ok){
+ nfs3errstr(ok);
+ fprint(2, "%s/%s: %r\n", dir, e.name);
+ continue;
+ }
+ ls(dir, e.name, &attr);
+ }
+ free(data);
+ if(eof)
+ break;
+ }
+}
+
+char*
+cmdls(int argc, char **argv)
+{
+ int i;
+ int dflag;
+ char *e;
+ Nfs3Handle h;
+ Nfs3Attr attr;
+ Nfs3Status ok;
+
+ dflag = 0;
+ ARGBEGIN{
+ case 'd':
+ dflag = 1;
+ break;
+ default:
+ return "usage: ls [-d] [path...]";
+ }ARGEND
+
+ if(argc == 0){
+ lsdir(nil, &cwd);
+ Bflush(&bout);
+ return nil;
+ }
+
+ for(i=0; i<argc; i++){
+ if((e = walk(argv[i], &h)) != nil){
+ fprint(2, "%s: %s\n", argv[i], e);
+ continue;
+ }
+ if((ok = fsysgetattr(fsys, auth, &h, &attr)) != Nfs3Ok){
+ nfs3errstr(ok);
+ fprint(2, "%s: %r\n", argv[i]);
+ continue;
+ }
+ if(attr.type != Nfs3FileDir || dflag)
+ ls(argv[i], nil, &attr);
+ else
+ lsdir(argv[i], &h);
+ Bflush(&bout);
+ }
+ return nil;
+}
+
+char*
+cmdblock(int argc, char **argv)
+{
+ char *e;
+ Nfs3Handle h;
+ u64int bno;
+
+ ARGBEGIN{
+ default:
+ return "usage: block path offset";
+ }ARGEND
+
+ if(argc != 2)
+ return "usage: block path offset";
+
+ if((e = walk(argv[0], &h)) != nil){
+ fprint(2, "%s: %s\n", argv[0], e);
+ return nil;
+ }
+ if((bno = fsys->fileblock(fsys, &h, strtoll(argv[1], 0, 0))) == 0){
+ fprint(2, "%s: %r\n", argv[0]);
+ return nil;
+ }
+ print("%#llux\n", bno);
+ return nil;
+}
+
+char*
+cmddisk(int argc, char **argv)
+{
+ Block *b;
+ int delta, count, i;
+ u64int offset;
+ uchar *p;
+
+ ARGBEGIN{
+ default:
+ return "usage: disk offset count";
+ }ARGEND
+
+ if(argc != 2)
+ return "usage: disk offset count";
+
+ offset = strtoull(argv[0], 0, 0);
+ count = atoi(argv[1]);
+ delta = offset%fsys->blocksize;
+
+ b = diskread(disk, fsys->blocksize, offset-delta);
+ if(b == nil){
+ fprint(2, "diskread: %r\n");
+ return nil;
+ }
+ p = b->data + delta;
+ for(i=0; i<count; i++){
+ Bprint(&bout, "%2.2ux ", p[i]);
+ if(i%16 == 15)
+ Bprint(&bout, "\n");
+ else if(i%8 == 7)
+ Bprint(&bout, " - ");
+ }
+ if(i%16 != 0)
+ Bprint(&bout, "\n");
+ Bflush(&bout);
+ blockput(b);
+ return nil;
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: vftp score\n");
+ threadexitsall("usage");
+}
+
+void
+threadmain(int argc, char **argv)
+{
+ char *err, *f[10], *p;
+ int i, nf;
+ uchar score[VtScoreSize];
+ Nfs3Status ok;
+
+ ARGBEGIN{
+ case 'V':
+ chattyventi++;
+ break;
+ default:
+ usage();
+ }ARGEND
+
+ if(argc != 1)
+ usage();
+
+ fmtinstall('F', vtfcallfmt);
+ fmtinstall('H', encodefmt);
+ fmtinstall('V', vtscorefmt);
+
+ if(vtparsescore(argv[0], nil, score) < 0)
+ sysfatal("bad score '%s'", argv[0]);
+ if((z = vtdial(nil)) == nil)
+ sysfatal("vtdial: %r");
+ if(vtconnect(z) < 0)
+ sysfatal("vtconnect: %r");
+ if((c = vtcachealloc(z, 16384, 32)) == nil)
+ sysfatal("vtcache: %r");
+ if((disk = diskopenventi(c, score)) == nil)
+ sysfatal("diskopenventi: %r");
+ if((fsys = fsysopen(disk)) == nil)
+ sysfatal("ffsopen: %r");
+
+ fprint(2, "block size %d\n", fsys->blocksize);
+ buf = emalloc(fsys->blocksize);
+ if((ok = fsysroot(fsys, &root)) != Nfs3Ok){
+ nfs3errstr(ok);
+ sysfatal("accessing root: %r");
+ }
+ cwd = root;
+ Binit(&bin, 0, OREAD);
+ Binit(&bout, 1, OWRITE);
+
+ while(fprint(2, "vftp> "), (p = Brdstr(&bin, '\n', 1)) != nil){
+ if(p[0] == '#')
+ continue;
+ nf = tokenize(p, f, nelem(f));
+ if(nf == 0)
+ continue;
+ for(i=0; i<nelem(cmdtab); i++){
+ if(strcmp(f[0], cmdtab[i].s) == 0){
+ if((err = cmdtab[i].fn(nf, f)) != nil)
+ fprint(2, "%s\n", err);
+ break;
+ }
+ }
+ if(i == nelem(cmdtab))
+ fprint(2, "unknown command '%s'\n", f[0]);
+ }
+ threadexitsall(nil);
+}
+