Beispiel #1
0
static int
fsdirstat(char *path, int dev, Dir *d)
{
	int fd;
	struct stat st;
	
	if(stat(path, &st) < 0 && lstat(path, &st) < 0)
		return -1;

	d->name = lastelem(path);
	d->uid = uidtoname(st.st_uid);
	d->gid = gidtoname(st.st_gid);
	d->muid = "";
	d->qid = fsqid(&st);
	d->mode = (d->qid.type<<24) | (st.st_mode&0777);
	d->atime = st.st_atime;
	d->mtime = st.st_mtime;
	d->length = st.st_size;
	if(S_ISBLK(st.st_mode) && (fd = open(path, O_RDONLY)) >= 0){
		d->length = disksize(fd, &st);
		close(fd);
	}
	
	// devmnt leaves 1-9 unused so that we can steal them.
	// it is easier for all involved if #Z shows M as the file type instead of Z.
	// dev is c->dev, either 1 (#Z) or 2 (#Zplan9).
	d->type = 'M';
	d->dev = dev;
	return 0;
}
Beispiel #2
0
static Chan*
fsattach(char *spec)
{
	struct stat st;
	Chan *c;
	UnixFd *ufd;
	int dev;
	
	dev = 1;
	if(spec && spec[0]){
		snprint(up->genbuf, sizeof up->genbuf, "no file system #%C%s", FsChar, spec);
		error(up->genbuf);
	}

	if(stat("/", &st) < 0)
		oserror();

	c = devattach(FsChar, 0);
	ufd = mallocz(sizeof(UnixFd), 1);
	ufd->path = newpath("/");
	ufd->fd = -1;

	c->aux = ufd;
	c->dev = dev;
	c->qid = fsqid(&st);
	
	if(Trace)
		print("fsattach /\n");

	return c;
}
Beispiel #3
0
static int
fswalk1(Chan *c, char *name)
{
	struct stat st;
	char *path;
	UnixFd *ufd;
	
	ufd = c->aux;
	if(strcmp(name, "..") == 0 && strcmp(ufd->path->s, "/") == 0)
		return 0;
	
	path = fspath(c, name);
	if(stat(path, &st) < 0){
		if(Trace)
			print("fswalk1 %s (%s)\n", path, strerror(errno));	
		free(path);
		return -1;
	}
	if(Trace)
		print("fswalk1 %s\n", path);	
	free(path);
	
	c->qid = fsqid(&st);
	return 0;
}
Beispiel #4
0
static Chan*
fsattach(char *spec)
{
	struct stat st;
	Chan *c;
	UnixFd *ufd;
	int plan9, dev;
	
	dev = 1;
	plan9 = 0;
	if(spec && spec[0]){
		if(strcmp(spec, "plan9") == 0) {
			plan9 = 1;
			dev = 2;
		} else{
			snprint(up->genbuf, sizeof up->genbuf, "no file system #%C%s", FsChar, spec);
			error(up->genbuf);
		}
	}

	if(plan9){
		if(localroot == nil)
			error("no #Zplan9 root without -r");
		if(stat(localroot, &st) < 0)
			oserror();
	}else{
		if(stat("/", &st) < 0)
			oserror();
	}

	c = devattach(FsChar, spec);
	ufd = mallocz(sizeof(UnixFd), 1);
	ufd->path = newpath("/");
	ufd->plan9 = plan9;
	ufd->fd = -1;

	c->aux = ufd;
	c->dev = dev;
	c->qid = fsqid(&st);
	
	if(Trace)
		print("fsattach /\n");

	return c;
}
Beispiel #5
0
static void
fscreate(Chan *c, char *name, int mode, ulong perm)
{
	char *path, *path0;
	int fd, mm;
	UnixFd *ufd;
	struct stat st;

	ufd = c->aux;
	if(Trace)
		print("fscreate %s %#x %#o\n", ufd->path->s, mode, perm);

	if(!(c->qid.type & QTDIR))
		error(Enotdir);

	if(mode & ~(OTRUNC|ORCLOSE|3))
		error(Ebadarg);

	if(perm & ~(DMDIR|0777))
		error(Ebadarg);

	path0 = fspath(c, nil);
	path = fspath(c, name);
	if(waserror()){
		free(path);
		free(path0);
		nexterror();
	}
	
	if(stat(path0, &st) < 0)
		oserror();

	if(perm & DMDIR){
		if(mode != OREAD)
			error(Eperm);
		/* have to do the minimum 0400 so we can open it */
		if(mkdir(path, (0400 | perm) & 0777) < 0)
			oserror();
		if((fd = open(path, 0)) < 0)
			oserror();
		fchown(fd, -1, st.st_gid);
		if(fstat(fd, &st) < 0){
			close(fd);
			oserror();
		}
		if((ufd->dir = opendir(path)) == nil) {
			/* arguably we should set the mode here too 
 			 * but it's hard to see that this case 
 			 * will ever happen 
 			 */
			close(fd);
			oserror();
		}
		// Be like Plan 9 file servers: inherit mode bits 
		// and group from parent.
		fchmod(fd, perm & st.st_mode & 0777);
		close(fd);
		ufd->diroffset = 0;
		ufd->nextde = nil;
	}else{
		mm = mode & 3;
		if(mode & OTRUNC)
			mm |= O_TRUNC;
		if((fd = open(path, mm|O_CREAT|O_EXCL, 0666)) < 0)
			oserror();
		// Be like Plan 9 file servers: inherit mode bits 
		// and group from parent.
		fchmod(fd, perm & st.st_mode & 0777);
		fchown(fd, -1, st.st_gid);
		if(fstat(fd, &st) < 0){
			close(fd);
			oserror();
		}
		ufd->fd = fd;
	}
	free(path);
	free(path0);
	poperror();
	
	ufd->path = addelem(ufd->path, name, nil);
	c->qid = fsqid(&st);
	c->offset = 0;
	c->flag |= COPEN;
	c->mode = openmode(mode);
}