#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. Load more
#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 int fsstat(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 int fsgetattr(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 int fsrelease(const char *path, struct fuse_file_info *ffi) { return _9pclunk(FFIH(ffi)); } static int fsreleasedir(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 int fstruncate(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 int fsrename(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 int fsopen(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 int fscreate(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 int fsmknod(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 int fsunlink(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 int fsread(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 int fswrite(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 int fsopendir(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 int fsmkdir(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 int fsrmdir(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 int fsreaddir(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 int fschmod(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 void doconnect(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]);