Index: appfs-cache ================================================================== --- appfs-cache +++ appfs-cache @@ -1,23 +1,36 @@ #! /usr/bin/env bash + +set -x + +appfsd_options=() +if [ "$1" == "--cachedir" ]; then + appfsd_options=("${appfsd_options[@]}" '--cachedir' "$2") + + shift; shift; +fi + +function call_appfsd() { + appfsd "${appfsd_options[@]}" "$@" +} function invalidate() { - appfsd -sqlite3 'UPDATE sites SET ttl = "0";' + call_appfsd --sqlite3 'UPDATE sites SET ttl = "0";' } function remove_site() { local site site="$1" - appfsd -sqlite3 'DELETE FROM sites WHERE hostname = '"'$site'"'; DELETE FROM packages WHERE hostname = '"'$site'"';' || return 1 + call_appfsd --sqlite3 'DELETE FROM sites WHERE hostname = '"'$site'"'; DELETE FROM packages WHERE hostname = '"'$site'"';' || return 1 clean } function clean() { - appfsd -tcl "$(cat <<\_EOF_ + call_appfsd --tcl "$(cat <<\_EOF_ unset -nocomplain row ::appfs::db eval {SELECT sha1, hostname FROM packages;} row { set hostname [::appfs::db onecolumn {SELECT hostname FROM sites WHERE hostname = $row(hostname) LIMIT 1;}] if {$hostname == ""} { continue @@ -53,12 +66,12 @@ echo "not implemented" >&2 return 1 fi - appfsd -tcl 'file delete -force -- {*}[glob -directory $::appfs::cachedir {[0-9a-f][0-9a-f]}]' || return 1 - appfsd -sqlite3 'DELETE FROM sites; DELETE FROM packages; DELETE FROM files; VACUUM;' || return 1 + call_appfsd --tcl 'file delete -force -- {*}[glob -directory $::appfs::cachedir {[0-9a-f][0-9a-f]}]' || return 1 + call_appfsd --sqlite3 'DELETE FROM sites; DELETE FROM packages; DELETE FROM files; VACUUM;' || return 1 } case "$1" in invalidate) invalidate || exit 1 Index: appfsd.c ================================================================== --- appfsd.c +++ appfsd.c @@ -724,23 +724,48 @@ .readlink = appfs_fuse_readlink, .open = appfs_fuse_open, .release = appfs_fuse_close, .read = appfs_fuse_read }; + +/* + * FUSE option parsing callback + */ +static int appfs_fuse_opt_cb(void *data, const char *arg, int key, struct fuse_args *outargs) { + static seen_cachedir = 0; + + if (key == FUSE_OPT_KEY_NONOPT && seen_cachedir == 0) { + seen_cachedir = 1; + + globalThread.cachedir = strdup(arg); + + return(0); + } + + return(1); +} /* * Entry point into this program. */ int main(int argc, char **argv) { struct fuse_args args = FUSE_ARGS_INIT(argc, argv); - const char *cachedir = APPFS_CACHEDIR; int pthread_ret; + /* + * Skip passed program name + */ + if (argc == 0 || argv == NULL) { + return(1); + } + argc--; + argv++; + /* * Set global variables, these should be configuration options. */ - globalThread.cachedir = cachedir; + globalThread.cachedir = APPFS_CACHEDIR; globalThread.options.writable = 1; /* * Set global variable for "boot time" to set a time on directories * that we fake. @@ -764,30 +789,42 @@ if (pthread_ret != 0) { fprintf(stderr, "Unable to create TSD key for Tcl. Aborting.\n"); return(1); } + + /* + * Manually specify cache directory, without FUSE callback + */ + if (argc >= 2) { + if (strcmp(argv[0], "--cachedir") == 0) { + globalThread.cachedir = strdup(argv[1]); + + argc -= 2; + argv += 2; + } + } /* * SQLite3 mode, for running raw SQL against the cache database */ - if (argc == 3 && strcmp(argv[1], "-sqlite3") == 0) { - return(appfs_sqlite3(argv[2])); + if (argc == 2 && strcmp(argv[0], "--sqlite3") == 0) { + return(appfs_sqlite3(argv[1])); } /* * Tcl mode, for running raw Tcl in the same environment AppFSd would * run code. */ - if (argc == 3 && strcmp(argv[1], "-tcl") == 0) { - return(appfs_tcl(argv[2])); + if (argc == 2 && strcmp(argv[0], "--tcl") == 0) { + return(appfs_tcl(argv[1])); } /* * Add FUSE arguments which we always supply */ - fuse_opt_parse(&args, NULL, NULL, NULL); + fuse_opt_parse(&args, NULL, NULL, appfs_fuse_opt_cb); fuse_opt_add_arg(&args, "-odefault_permissions,fsname=appfs,subtype=appfsd,use_ino,kernel_cache,entry_timeout=60,attr_timeout=3600,intr,big_writes"); if (getuid() == 0) { fuse_opt_parse(&args, NULL, NULL, NULL); fuse_opt_add_arg(&args, "-oallow_other");