135 lines · 2.1 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <thread.h>#include <sunrpc.h>#include <nfs3.h>#include <diskfs.h> int debug; voidusage(void){	fprint(2, "usage: fsview fspartition cmd\n");	fprint(2, "cmd is:\n");	fprint(2, "\tcat file\n");	fprint(2, "\tls dir\n");	fprint(2, "\tstat file\n");	threadexitsall("usage");} voidprintattr(Nfs3Attr *attr){	Fmt fmt;	char buf[256]; 	fmtfdinit(&fmt, 2, buf, sizeof buf);	nfs3attrprint(&fmt, attr);	fmtfdflush(&fmt);	fprint(2, "\n");} char buf[8192]; voidx(int ok){	if(ok != Nfs3Ok){		nfs3errstr(ok);		sysfatal("%r");	}} voidthreadmain(int argc, char **argv){	char *p, *q;	u32int n;	Disk *disk;	Fsys *fsys;	Nfs3Handle h;	SunAuthUnix au;	Nfs3Attr attr;	u64int offset;	u1int eof;	uchar *data;	char *link; 	ARGBEGIN{	case 'd':		debug = 1;		break;	default:		usage();	}ARGEND 	if(argc != 3)		usage(); 	if((disk = diskopenfile(argv[0])) == nil)		sysfatal("diskopen: %r");	if((disk = diskcache(disk, 16384, 16)) == nil)		sysfatal("diskcache: %r");	if((fsys = fsysopen(disk)) == nil)		sysfatal("fsysopen: %r"); 	allowall = 1;	memset(&au, 0, sizeof au); 	/* walk */	if(debug) fprint(2, "get root...");	x(fsysroot(fsys, &h));	p = argv[2];	while(*p){		while(*p == '/')			p++;		if(*p == 0)			break;		q = strchr(p, '/');		if(q){			*q = 0;			q++;		}else			q = "";		if(debug) fprint(2, "walk %s...", p);		x(fsyslookup(fsys, &au, &h, p, &h));		p = q;	} 	if(debug) fprint(2, "getattr...");	x(fsysgetattr(fsys, &au, &h, &attr));	printattr(&attr); 	/* do the op */	if(strcmp(argv[1], "cat") == 0){		switch(attr.type){		case Nfs3FileReg:		case Nfs3FileDir:			offset = 0;			for(;;){				x(fsysreadfile(fsys, &au, &h, sizeof buf, offset, &data, &n, &eof));				if(n){					write(1, data, n);					free(data);					offset += n;				}				if(eof)					break;			}			break;		case Nfs3FileSymlink:			x(fsysreadlink(fsys, &au, &h, &link));			print("%s\n", link);			break;		default:			print("cannot cat: not file, not link\n");			break;		}	}else if(strcmp(argv[1], "ls") == 0){		/* not implemented */	}else if(strcmp(argv[1], "stat") == 0){		/* already done */	}	threadexitsall(nil);}