Sigrid Solveig Haflínudóttirstricter about ptototypesfdc289411 months agoHistory
780 lines · 13.6 KB · C
RawDownload
#include <sys/types.h>#include <sys/socket.h>#include <sys/un.h> #ifdef __linux__#include <linux/vm_sockets.h>#endif #include <netinet/in.h>#include <netinet/tcp.h>#include <netdb.h> #include <unistd.h>#include <fcntl.h>#include <fuse.h>#include <pwd.h>#include <grp.h>#include <err.h>#include <errno.h> #include <stdlib.h>#include <stdint.h>#include <string.h>#include <stdio.h>#include <stdarg.h> #include "libc.h"#include "fcall.h"#include "9pfs.h"#include "auth.h"#include "util.h" #define CACHECTL ".fscache"#define FFIH(ffi) ((FFid*)(uintptr_t)(ffi)->fh) enum{	CACHECTLSIZE = 8, /* sizeof("cleared\n") - 1 */	Msize = 32768,}; void dir2stat(struct stat*, Dir*);Dir *iscached(const char*);Dir *addtocache(const char*);void clearcache(const char*);int iscachectl(const char*);char *breakpath(char*);void usage(void); Dir *rootdir;FILE *logfile;FFid *rootfid;FFid *authfid;int msize;int infd, outfd;int debug; static intfsstat(const char *path, struct stat *st){	FFid *f;	Dir *d; 	if((f = _9pwalk(path)) == NULL)		return -EIO;	if((d = _9pstat(f)) == NULL){		_9pclunk(f);		return -EACCES;	}	dir2stat(st, d);	_9pclunk(f);	free(d);	return 0;} static intfsgetattr(const char *path, struct stat *st){	Dir *d; 	if(iscachectl(path)){		st->st_mode = 0666 | S_IFREG;		st->st_uid = getuid();		st->st_gid = getgid();		st->st_size = CACHECTLSIZE;		return 0;	}	if((d = iscached(path)) == NULL)		d = addtocache(path);	if(d == NULL)		return -ENOENT;	if(strcmp(d->uid, "stub") == 0) /* hack for aux/stub */		return fsstat(path, st);	dir2stat(st, d);	return 0;} static intfsrelease(const char *path, struct fuse_file_info *ffi){	return _9pclunk(FFIH(ffi));} static intfsreleasedir(const char *path, struct fuse_file_info *ffi){	FFid *f; 	f = FFIH(ffi);	if(f == NULL)		return 0;	if((f->qid.type & QTDIR) == 0)		return -ENOTDIR;	return _9pclunk(f);} static intfstruncate(const char *path, off_t off){	FFid *f;	Dir *d; 	if(iscachectl(path))		return 0;	if((f = _9pwalk(path)) == NULL)		return -ENOENT;	if(off == 0){		f->mode = OWRITE | OTRUNC;		if(_9popen(f) == -1){			_9pclunk(f);			return -EIO;		}	}else{		if((d = _9pstat(f)) == NULL){			_9pclunk(f);			return -EIO;		}		d->length = off;		if(_9pwstat(f, d) == -1){			_9pclunk(f);			free(d);			return -EACCES;		}		free(d);	}	_9pclunk(f);	clearcache(path);	return 0;} static intfsrename(const char *opath, const char *npath){	Dir *d;	FFid *f;	char *dname, *bname; 	if(iscachectl(opath))		return -EACCES;	if((f = _9pwalk(opath)) == NULL)		return -ENOENT;	dname = estrdup(npath);	bname = strrchr(dname, '/');	if(strncmp(opath, npath, bname-dname) != 0){		_9pclunk(f);		free(dname);		return -EACCES;	}	*bname++ = '\0';	if((d = _9pstat(f)) == NULL){		_9pclunk(f);		free(dname);		return -EIO;	}	d->name = bname;	if(_9pwstat(f, d) == -1){		_9pclunk(f);		free(dname);		free(d);		return -EACCES;	}	_9pclunk(f);	free(dname);	free(d);	clearcache(opath);	return 0;} static intfsopen(const char *path, struct fuse_file_info *ffi){	FFid *f; 	if(iscachectl(path))		return 0;	if((f = _9pwalk(path)) == NULL)		return -ENOENT;	f->mode = ffi->flags & O_ACCMODE;	if(ffi->flags & O_TRUNC)		f->mode |= OTRUNC;	if(_9popen(f) == -1){		_9pclunk(f);		return -EACCES;	}	ffi->fh = (uintptr_t)f;	ffi->direct_io = 1;	return 0;} static intfscreate(const char *path, mode_t perm, struct fuse_file_info *ffi){	FFid *f;	char *dname, *bname; 	if(iscachectl(path))		return -EACCES;	if((f = _9pwalk(path)) == NULL){		dname = estrdup(path);		bname = breakpath(dname);		if((f = _9pwalk(dname)) == NULL){			free(dname);			return -ENOENT;		}		f->mode = ffi->flags & O_ACCMODE;		f = _9pcreate(f, bname, perm, 0);		free(dname);		if(f == NULL)			return -EACCES;	}else{		if(ffi->flags | O_EXCL){			_9pclunk(f);			return -EEXIST;		}		f->mode = ffi->flags & O_ACCMODE;		if(_9popen(f) == -1){			_9pclunk(f);			return -EIO;		}	}	ffi->fh = (uintptr_t)f;	clearcache(path);	return 0;} static intfsmknod(const char *path, mode_t perm, dev_t dev){	FFid *f;	char *dname, *bname; 	if(iscachectl(path))		return -EACCES;	if((f = _9pwalk(path)) == NULL){		dname = estrdup(path);		bname = breakpath(dname);		if((f = _9pwalk(dname)) == NULL){			free(dname);			return -ENOENT;		}		f = _9pcreate(f, bname, perm, 0);		free(dname);		if(f == NULL)			return -EACCES;	}	_9pclunk(f);	clearcache(path);	return 0;} static intfsunlink(const char *path){	FFid *f; 	if(iscachectl(path))		return 0;	if((f = _9pwalk(path)) == NULL)		return -ENOENT;	if(_9premove(f) == -1)		return -EACCES;	clearcache(path);	return 0;} static intfsread(const char *path, char *buf, size_t size, off_t off,	struct fuse_file_info *ffi){	FFid *f;	int r; 	if(iscachectl(path)){		if(off >= CACHECTLSIZE)			return 0;		if(size > CACHECTLSIZE - off)			size = CACHECTLSIZE - off;		memcpy(buf, &"cleared\n"[off], size);		clearcache(path);		return size;	}	f = FFIH(ffi);	if(f->mode & O_WRONLY)		return -EACCES;	f->offset = off;	if((r = _9pread(f, buf, size)) < 0)		return -EIO;	return r;} static intfswrite(const char *path, const char *buf, size_t size, off_t off,	struct fuse_file_info *ffi){	FFid *f;	int r; 	if(iscachectl(path)){		clearcache(path);		return size;	}	f = FFIH(ffi);	if(f->mode & O_RDONLY)		return -EACCES;	f->offset = off;	if((r = _9pwrite(f, (char*)buf, size)) < 0)		return -EIO;	clearcache(path);	return r;} static intfsopendir(const char *path, struct fuse_file_info *ffi){	FFid *f; 	if(lookupdir(path, GET) != NULL){		ffi->fh = (uintptr_t)0;		return 0;	}	if((f = _9pwalk(path)) == NULL)		return -ENOENT;	f->mode = ffi->flags & O_ACCMODE;	if(_9popen(f) == -1){		_9pclunk(f);		return -EACCES;	}	if(!(f->qid.type & QTDIR)){		_9pclunk(f);		return -ENOTDIR;	}	ffi->fh = (uintptr_t)f;	return 0;} static intfsmkdir(const char *path, mode_t perm){	FFid *f;	char *dname, *bname; 	if((f = _9pwalk(path)) != NULL){		_9pclunk(f);		return -EEXIST;	}	dname = estrdup(path);	bname = breakpath(dname);	if((f = _9pwalk(dname)) == NULL){		free(dname);		return -ENOENT;	}	if((f = _9pcreate(f, bname, perm, 1)) == NULL){		free(dname);		return -EACCES;	}	_9pclunk(f);	free(dname);	clearcache(path);	return 0;} static intfsrmdir(const char *path){	FFid *f; 	if((f = _9pwalk(path)) == NULL)		return -ENOENT;	if((f->qid.type & QTDIR) == 0){		_9pclunk(f);		return -ENOTDIR;	}	if(_9premove(f) == -1)		return -EIO;	clearcache(path);	return 0;} static intfsreaddir(const char *path, void *data, fuse_fill_dir_t ffd,	off_t off, struct fuse_file_info *ffi){	FDir *f;	Dir *d, *e;	long n;	struct stat s; 	ffd(data, ".", NULL, 0);	ffd(data, "..", NULL, 0);	ffd(data, CACHECTL, NULL, 0);	if((f = lookupdir(path, GET)) != NULL){		d = f->dirs;		n = f->ndirs;	}else{		if((n = _9pdirread(FFIH(ffi), &d)) < 0)			return -EIO;	}	for(e = d; e < d+n; e++){		s.st_ino = e->qid.path;		s.st_mode = e->mode & 0777;		ffd(data, e->name, &s, 0);	}	return 0;} static intfschmod(const char *path, mode_t perm){	FFid *f;	Dir *d; 	if((f = _9pwalk(path)) == NULL)		return -ENOENT;	if((d = _9pstat(f)) == NULL){		_9pclunk(f);		return -EIO;	}	d->mode = perm & 0777;	if(_9pwstat(f, d) == -1){		_9pclunk(f);		free(d);		return -EACCES;	}	_9pclunk(f);	free(d);	clearcache(path);	return 0;} static struct fuse_operations fsops = {	.getattr =		fsgetattr,	.truncate =		fstruncate,	.rename =		fsrename,	.open =			fsopen,	.create =		fscreate,	.mknod =		fsmknod,	.unlink =		fsunlink,	.read =			fsread,	.write =		fswrite,	.opendir =		fsopendir,	.mkdir =		fsmkdir,	.rmdir =		fsrmdir,	.readdir =		fsreaddir,	.release =		fsrelease,	.releasedir =	fsreleasedir,	.chmod =		fschmod}; static int uflag, tflag, vflag; static voiddoconnect(char *name, char *port){	struct sockaddr_un uaddr;#ifdef __linux__	struct sockaddr_vm vaddr;#endif	struct addrinfo *a, *ainfo, hint;	int e, n, yes;	int p1[2], p2[2]; 	if(tflag){		if(pipe(p1) < 0 || pipe(p2) < 0)			err(1, "Could not create pipe");		switch(fork()){		case -1:			err(1, "fork");		case 0:			close(p1[0]);			dup2(p1[1], 1); 			dup2(p2[0], 0);			close(p2[1]); 			execlp("tlsclient", "tlsclient", "-h", name, "-p", port, NULL);			err(1, "Could not exec tlsclient");		default:			infd = p1[0];			close(p1[1]); 

Lines 1–500 of 780.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t