--- rofs-fuse-2006.11.28.orig/Makefile +++ rofs-fuse-2006.11.28/Makefile @@ -0,0 +1,12 @@ +rofs: rofs.c + $(CC) `pkg-config fuse --cflags --libs` $^ -o $@ + +debian/rofs.1: rofs + PATH=.:${PATH} help2man -n"Mounts directories as read-only" -N rofs -o $@ + +clean: + rm -rf rofs debian/rofs.1 + +install: rofs debian/rofs.1 + mkdir -p $(DESTDIR)/usr/bin + cp rofs $(DESTDIR)/usr/bin --- rofs-fuse-2006.11.28.orig/rofs.c +++ rofs-fuse-2006.11.28/rofs.c @@ -2,6 +2,8 @@ * ROFS - The read-only filesystem for FUSE. * Copyright 2006 Matthew Keller. kellermg@potsdam.edu and others. * v2006.11.28 + * + * Some modifications by Chris AtLee * * Mount any filesytem, or folder tree read-only, anywhere else. * No warranties. No guarantees. No lawyers. @@ -12,14 +14,15 @@ * * Consider this code GPLv2. * - * Compile: gcc -o rofs -Wall -ansi -W -std=c99 -g -ggdb -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -lfuse main.c - * Mount: rofsmount readwrite_filesystem mount_point + * Compile: gcc -o rofs -Wall `pkg-config fuse --cflags --libs` rofs.c * */ +#define FUSE_USE_VERSION 26 -#define FUSE_USE_VERSION 25 +static const char* rofsVersion = "2006.11.28"; +#define _GNU_SOURCE #include #include #include @@ -30,21 +33,21 @@ #include #include #include +#ifdef HAVE_SETXATTR #include +#endif #include #include #include - // Global to store our read-write path -char *rw_path; +const char *rw_path; // Translate an rofs path into it's underlying filesystem path static char* translate_path(const char* path) { + char *rPath = malloc(sizeof(char)*(strlen(path)+strlen(rw_path)+1)); - char *rPath= malloc(sizeof(char)*(strlen(path)+strlen(rw_path)+1)); - strcpy(rPath,rw_path); if (rPath[strlen(rPath)-1]=='/') { rPath[strlen(rPath)-1]='\0'; @@ -62,27 +65,29 @@ * * ******************************/ - -static int callback_getattr(const char *path, struct stat *st_data) + +static int rofs_getattr(const char *path, struct stat *st_data) { int res; - path=translate_path(path); - - res = lstat(path, st_data); - free(path); + char *p1 = translate_path(path); + + res = lstat(p1, st_data); + free(p1); + if(res == -1) { return -errno; } return 0; } -static int callback_readlink(const char *path, char *buf, size_t size) +static int rofs_readlink(const char *path, char *buf, size_t size) { - int res; - path=translate_path(path); - - res = readlink(path, buf, size - 1); - free(path); + int res; + char *p1 = translate_path(path); + + res = readlink(p1, buf, size - 1); + free(p1); + if(res == -1) { return -errno; } @@ -90,236 +95,258 @@ return 0; } -static int callback_readdir(const char *path, void *buf, fuse_fill_dir_t filler,off_t offset, struct fuse_file_info *fi) +static int rofs_opendir(const char* path, struct fuse_file_info *fi) +{ + DIR *dp; + char *p1 = translate_path(path); + + dp = opendir(p1); + free(p1); + + if (dp == 0) + { + return -errno; + } + fi->fh = (uint64_t)dp; + return 0; +} + +static int rofs_readdir(const char *path, void *buf, + fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { DIR *dp; struct dirent *de; - int res; (void) offset; - (void) fi; + (void) path; - path=translate_path(path); - - dp = opendir(path); - free(path); - if(dp == NULL) { - res = -errno; - return res; - } + dp = (DIR*)fi->fh; + seekdir(dp, offset); while((de = readdir(dp)) != NULL) { struct stat st; memset(&st, 0, sizeof(st)); st.st_ino = de->d_ino; st.st_mode = de->d_type << 12; - if (filler(buf, de->d_name, &st, 0)) + if (filler(buf, de->d_name, &st, telldir(dp))) break; } - closedir(dp); return 0; } -static int callback_mknod(const char *path, mode_t mode, dev_t rdev) +static int rofs_releasedir(const char* path, struct fuse_file_info *fi) +{ + (void) path; + DIR *dp; + + dp = (DIR*)fi->fh; + return closedir(dp); +} + +static int rofs_mknod(const char *path, mode_t mode, dev_t rdev) { - (void)path; - (void)mode; - (void)rdev; - return -EPERM; + (void)path; + (void)mode; + (void)rdev; + return -EROFS; } -static int callback_mkdir(const char *path, mode_t mode) +static int rofs_mkdir(const char *path, mode_t mode) { - (void)path; - (void)mode; - return -EPERM; + (void)path; + (void)mode; + return -EROFS; } -static int callback_unlink(const char *path) +static int rofs_unlink(const char *path) { - (void)path; - return -EPERM; + (void)path; + return -EROFS; } -static int callback_rmdir(const char *path) +static int rofs_rmdir(const char *path) { - (void)path; - return -EPERM; + (void)path; + return -EROFS; } -static int callback_symlink(const char *from, const char *to) +static int rofs_symlink(const char *from, const char *to) { - (void)from; - (void)to; - return -EPERM; + (void)from; + (void)to; + return -EROFS; } -static int callback_rename(const char *from, const char *to) +static int rofs_rename(const char *from, const char *to) { - (void)from; - (void)to; - return -EPERM; + (void)from; + (void)to; + return -EROFS; } -static int callback_link(const char *from, const char *to) +static int rofs_link(const char *from, const char *to) { - (void)from; - (void)to; - return -EPERM; + (void)from; + (void)to; + return -EROFS; } -static int callback_chmod(const char *path, mode_t mode) +static int rofs_chmod(const char *path, mode_t mode) { - (void)path; - (void)mode; - return -EPERM; - + (void)path; + (void)mode; + return -EROFS; } -static int callback_chown(const char *path, uid_t uid, gid_t gid) +static int rofs_chown(const char *path, uid_t uid, gid_t gid) { - (void)path; - (void)uid; - (void)gid; - return -EPERM; + (void)path; + (void)uid; + (void)gid; + return -EROFS; } -static int callback_truncate(const char *path, off_t size) +static int rofs_truncate(const char *path, off_t size) { - (void)path; - (void)size; - return -EPERM; + (void)path; + (void)size; + return -EROFS; } -static int callback_utime(const char *path, struct utimbuf *buf) +static int rofs_utime(const char *path, struct utimbuf *buf) { - (void)path; - (void)buf; - return -EPERM; + (void)path; + (void)buf; + return -EROFS; } -static int callback_open(const char *path, struct fuse_file_info *finfo) +static int rofs_open(const char *path, struct fuse_file_info *fi) { - int res; - - /* We allow opens, unless they're tring to write, sneaky - * people. - */ - int flags = finfo->flags; - - if ((flags & O_WRONLY) || (flags & O_RDWR) || (flags & O_CREAT) || (flags & O_EXCL) || (flags & O_TRUNC)) { - return -errno; - } - - path=translate_path(path); - - res = open(path, flags); - - free(path); + int res; + + /* We allow opens, unless they're tring to write, sneaky + * people. + */ + int flags = fi->flags; + + if ((flags & O_WRONLY) || (flags & O_RDWR) || (flags & O_CREAT) || \ + (flags & O_EXCL) || (flags & O_TRUNC) || (flags & O_APPEND)) { + return -EROFS; + } + + char *p1 = translate_path(path); + + res = open(p1, flags); + free(p1); + if(res == -1) { return -errno; } - close(res); + fi->fh = res; return 0; } -static int callback_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *finfo) +static int rofs_read(const char *path, char *buf, size_t size, + off_t offset, struct fuse_file_info *fi) { - int fd; + (void) path; int res; - (void)finfo; - path=translate_path(path); - fd = open(path, O_RDONLY); - free(path); - if(fd == -1) { - res = -errno; - return res; - } - res = pread(fd, buf, size, offset); - + res = pread(fi->fh, buf, size, offset); + if(res == -1) { res = -errno; - } - close(fd); + } return res; } -static int callback_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *finfo) +static int rofs_write(const char *path, const char *buf, size_t size, + off_t offset, struct fuse_file_info *fi) { - (void)path; - (void)buf; - (void)size; - (void)offset; - (void)finfo; - return -EPERM; + (void)path; + (void)buf; + (void)size; + (void)offset; + (void)fi; + return -EROFS; } -static int callback_statfs(const char *path, struct statvfs *st_buf) +static int rofs_statfs(const char *path, struct statvfs *st_buf) { - int res; - path=translate_path(path); - - res = statvfs(path, st_buf); - free(path); - if (res == -1) { - return -errno; - } - return 0; + int res; + char *p1 = translate_path(path); + + res = statvfs(p1, st_buf); + free(p1); + + if (res == -1) { + return -errno; + } + return 0; } -static int callback_release(const char *path, struct fuse_file_info *finfo) +static int rofs_release(const char *path, struct fuse_file_info *fi) { - (void) path; - (void) finfo; - return 0; + (void) path; + return close(fi->fh); } -static int callback_fsync(const char *path, int crap, struct fuse_file_info *finfo) +static int rofs_fsync(const char *path, int isdatasync, + struct fuse_file_info *fi) { - (void) path; - (void) crap; - (void) finfo; - return 0; + (void) path; + (void) isdatasync; + (void) fi; + return 0; } -static int callback_access(const char *path, int mode) +static int rofs_access(const char *path, int mode) { - int res; - path=translate_path(path); - - res = access(path, mode); - free(path); - if (res == -1) { - return -errno; - } - return res; + // Don't pretend that we allow writing + if (mode & W_OK) + return -EROFS; + + int res; + char *p1 = translate_path(path); + + res = access(p1, mode); + free(p1); + + if (res == -1) { + return -errno; + } + return 0; } +#ifdef HAVE_SETXATTR /* * Set the value of an extended attribute */ -static int callback_setxattr(const char *path, const char *name, const char *value, size_t size, int flags) +static int rofs_setxattr(const char *path, const char *name, + const char *value, size_t size, int flags) { - (void)path; - (void)name; - (void)value; - (void)size; - (void)flags; - return -EPERM; + (void)path; + (void)name; + (void)value; + (void)size; + (void)flags; + return -EROFS; } /* * Get the value of an extended attribute. */ -static int callback_getxattr(const char *path, const char *name, char *value, size_t size) +static int rofs_getxattr(const char *path, const char *name, + char *value, size_t size) { int res; - - path=translate_path(path); - res = lgetxattr(path, name, value, size); - free(path); + + char *p1 = translate_path(path); + + res = lgetxattr(p1, name, value, size); + free(p1); + if(res == -1) { return -errno; } @@ -329,13 +356,15 @@ /* * List the supported extended attributes. */ -static int callback_listxattr(const char *path, char *list, size_t size) +static int rofs_listxattr(const char *path, char *list, size_t size) { - int res; - - path=translate_path(path); - res = llistxattr(path, list, size); - free(path); + int res; + + char *p1 = translate_path(path); + + res = llistxattr(p1, list, size); + free(p1); + if(res == -1) { return -errno; } @@ -346,55 +375,138 @@ /* * Remove an extended attribute. */ -static int callback_removexattr(const char *path, const char *name) +static int rofs_removexattr(const char *path, const char *name) { - (void)path; - (void)name; - return -EPERM; + (void)path; + (void)name; + return -EROFS; + +} +#endif + +struct fuse_operations rofs_oper = { + .getattr = rofs_getattr, + .readlink = rofs_readlink, + .opendir = rofs_opendir, + .readdir = rofs_readdir, + .releasedir = rofs_releasedir, + .mknod = rofs_mknod, + .mkdir = rofs_mkdir, + .symlink = rofs_symlink, + .unlink = rofs_unlink, + .rmdir = rofs_rmdir, + .rename = rofs_rename, + .link = rofs_link, + .chmod = rofs_chmod, + .chown = rofs_chown, + .truncate = rofs_truncate, + .utime = rofs_utime, + .open = rofs_open, + .read = rofs_read, + .write = rofs_write, + .statfs = rofs_statfs, + .release = rofs_release, + .fsync = rofs_fsync, + .access = rofs_access, + +#ifdef HAVE_SETXATTR + /* Extended attributes support for userland interaction */ + .setxattr = rofs_setxattr, + .getxattr = rofs_getxattr, + .listxattr = rofs_listxattr, + .removexattr = rofs_removexattr +#endif +}; + +enum { + KEY_HELP, + KEY_VERSION, +}; +static void usage(const char* progname) +{ + fprintf(stdout, +"usage: %s readwritepath mountpoint [options]\n" +"\n" +" Mounts readwritepath as a read-only mount at mountpoint\n" +"\n" +"general options:\n" +" -o opt,[opt...] mount options\n" +" -h --help print help\n" +" -V --version print version\n" +"\n", progname); } -struct fuse_operations callback_oper = { - .getattr = callback_getattr, - .readlink = callback_readlink, - .readdir = callback_readdir, - .mknod = callback_mknod, - .mkdir = callback_mkdir, - .symlink = callback_symlink, - .unlink = callback_unlink, - .rmdir = callback_rmdir, - .rename = callback_rename, - .link = callback_link, - .chmod = callback_chmod, - .chown = callback_chown, - .truncate = callback_truncate, - .utime = callback_utime, - .open = callback_open, - .read = callback_read, - .write = callback_write, - .statfs = callback_statfs, - .release = callback_release, - .fsync = callback_fsync, - .access = callback_access, +static int rofs_parse_opt(void *data, const char *arg, int key, + struct fuse_args *outargs) +{ + (void) data; - /* Extended attributes support for userland interaction */ - .setxattr = callback_setxattr, - .getxattr = callback_getxattr, - .listxattr = callback_listxattr, - .removexattr= callback_removexattr + switch (key) + { + case FUSE_OPT_KEY_NONOPT: + if (rw_path == 0) + { + rw_path = canonicalize_file_name(arg); + if (rw_path == 0) + { + fprintf(stderr, "Could not determine absolute path of readwritepath (%s): %s\n", arg, strerror(errno)); + exit(1); + } + return 0; + } + else + { + return 1; + } + case FUSE_OPT_KEY_OPT: + return 1; + case KEY_HELP: + usage(outargs->argv[0]); + fuse_opt_add_arg(outargs, "-h"); + fuse_main(outargs->argc, outargs->argv, &rofs_oper, 0); + exit(0); + case KEY_VERSION: + fprintf(stdout, "ROFS version %s\n", rofsVersion); + exit(0); + default: + fprintf(stderr, "see `%s -h' for usage\n", outargs->argv[0]); + exit(1); + } + return 1; +} + +static struct fuse_opt rofs_opts[] = { + FUSE_OPT_KEY("-h", KEY_HELP), + FUSE_OPT_KEY("--help", KEY_HELP), + FUSE_OPT_KEY("-V", KEY_VERSION), + FUSE_OPT_KEY("--version", KEY_VERSION), + FUSE_OPT_END }; int main(int argc, char *argv[]) { - - rw_path = getenv("ROFS_RW_PATH"); - if (!rw_path) + struct fuse_args args = FUSE_ARGS_INIT(argc, argv); + int res; + + res = fuse_opt_parse(&args, &rw_path, rofs_opts, rofs_parse_opt); + if (res != 0) { - fprintf(stderr, "ROFS_RW_PATH not defined in environment.\n"); - exit(1); + fprintf(stderr, "Invalid arguments\n"); + fprintf(stderr, "see `%s -h' for usage\n", argv[0]); + exit(1); } - - - fuse_main(argc, argv, &callback_oper); + if (rw_path == 0) + { + fprintf(stderr, "Missing readwritepath\n"); + fprintf(stderr, "see `%s -h' for usage\n", argv[0]); + exit(1); + } + + /* Uncomment this to force use_ino to work around "No such file or + * directory" problem (cause unknown) */ + //fuse_opt_add_arg(&args, "-ouse_ino"); + + fuse_main(args.argc, args.argv, &rofs_oper, 0); return 0; } --- rofs-fuse-2006.11.28.orig/debian/copyright +++ rofs-fuse-2006.11.28/debian/copyright @@ -0,0 +1,16 @@ +This package was debianized by Chris AtLee +Mon May 7 14:10:48 EDT 2007 + +It was downloaded from http://mattwork.potsdam.edu/projects/wiki/index.php/Rofs + +Copyright Holder: Matthew Keller + +License: + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +On Debian systems, the complete text of the GNU General Public License +can be found in the file `/usr/share/common-licenses/GPL'. --- rofs-fuse-2006.11.28.orig/debian/control +++ rofs-fuse-2006.11.28/debian/control @@ -0,0 +1,16 @@ +Source: rofs-fuse +Section: utils +Priority: optional +Maintainer: Chris AtLee +Build-Depends: debhelper (>= 4.0.0), libfuse-dev (>= 2.6), help2man, pkg-config +Standards-Version: 3.7.2 + +Package: rofs +Architecture: any +Depends: ${shlibs:Depends}, fuse [linux-any] | fuse4bsd [kfreebsd-any] +Description: Read-Only Filesystem for FUSE + rofs is a read-only filesystem that allows you to create a read-only + mountpoint of a read-write directory on your system. + . + Homepage: http://mattwork.potsdam.edu/projects/wiki/index.php/Rofs + . --- rofs-fuse-2006.11.28.orig/debian/compat +++ rofs-fuse-2006.11.28/debian/compat @@ -0,0 +1 @@ +4 --- rofs-fuse-2006.11.28.orig/debian/rules +++ rofs-fuse-2006.11.28/debian/rules @@ -0,0 +1,59 @@ +#!/usr/bin/make -f + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +# These are used for cross-compiling and for saving the configure script +# from having to guess our platform (since we know it already) +DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) +DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) + +CFLAGS = -Wall -g + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 +else + CFLAGS += -O2 +endif + +build: build-stamp + +build-stamp: + dh_testdir + $(MAKE) + touch build-stamp + +clean: + dh_testdir + dh_testroot + rm -f build-stamp + $(MAKE) clean + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + $(MAKE) install DESTDIR=$(CURDIR)/debian/rofs + +binary-indep: build install + +binary-arch: build install + dh_testdir + dh_testroot + dh_installdocs + dh_installchangelogs + dh_installman debian/rofs.1 + dh_link + dh_strip + dh_compress + dh_fixperms + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install --- rofs-fuse-2006.11.28.orig/debian/changelog +++ rofs-fuse-2006.11.28/debian/changelog @@ -0,0 +1,27 @@ +rofs-fuse (2006.11.28-2.1) unstable; urgency=low + + * Non-maintainer upload. + * Fix installability on kfreebsd-*. (Closes: #634367) + + -- Robert Millan Fri, 02 Dec 2011 19:29:40 +0000 + +rofs-fuse (2006.11.28-2) unstable; urgency=low + + * Handle relative paths as the rw path + * Note additional changes from upstream (also applies to 2006.11.28-1): + - Return EROFS from callbacks instead of EPERM + - Rename callback_* to rofs_* + - Got rid of rofsmount helper script + * Added pkg-config to Build-Depends (Closes: #426816) + + -- Chris AtLee Wed, 30 May 2007 22:10:25 -0700 + +rofs-fuse (2006.11.28-1) unstable; urgency=low + + * Initial Debian release + * Changes from upstream: + - Use 2.6 API + - Save filehandles to make reading more efficient + - Implement access() + + -- Chris AtLee Wed, 23 May 2007 16:19:01 -0400