Index: appfsd.c ================================================================== --- appfsd.c +++ appfsd.c @@ -554,10 +554,36 @@ return(NULL); } return(strdup(real_path)); } + +static char *appfs_localpath(const char *path) { + Tcl_Interp *interp; + const char *real_path; + int tcl_ret; + + interp = appfs_TclInterp(); + if (interp == NULL) { + return(NULL); + } + + tcl_ret = appfs_Tcl_Eval(interp, 2, "::appfs::localpath", path); + if (tcl_ret != TCL_OK) { + APPFS_DEBUG("::appfs::localpath(%s) failed.", path); + APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp)); + + return(NULL); + } + + real_path = Tcl_GetStringResult(interp); + if (real_path == NULL) { + return(NULL); + } + + return(strdup(real_path)); +} static int appfs_fuse_readlink(const char *path, char *buf, size_t size) { struct appfs_pathinfo pathinfo; int retval = 0; @@ -832,10 +858,30 @@ return(-EIO); } return(fd); } + +static int appfs_fuse_truncate(const char *path, off_t size) { + char *real_path; + int truncate_ret; + + real_path = appfs_localpath(path); + if (real_path == NULL) { + return(-EIO); + } + + truncate_ret = truncate(real_path, size); + + free(real_path); + + if (truncate_ret != 0) { + return(errno * -1); + } + + return(truncate_ret); +} /* * SQLite3 mode: Execute raw SQL and return success or failure */ static int appfs_sqlite3(const char *sql) { @@ -927,10 +973,11 @@ .release = appfs_fuse_close, .read = appfs_fuse_read, .write = appfs_fuse_write, .mknod = appfs_fuse_mknod, .create = appfs_fuse_create, + .truncate = appfs_fuse_truncate, }; /* * FUSE option parsing callback */ Index: appfsd.tcl ================================================================== --- appfsd.tcl +++ appfsd.tcl @@ -666,6 +666,32 @@ file mkdir $dirname return $filename } + + proc prepare_to_create {path} { + if {[exists $path] != ""} { + return -code error "File already exists" + } + + set filename [openpath $path "create"] + + set dirname [file dirname $filename] + + file mkdir $dirname + + return $filename + } + + proc localpath {path} { + array set pathinfo [_parsepath $path] + + if {$pathinfo(_type) != "files"} { + return -code error "invalid type" + } + + set localpath [_localpath $pathinfo(package) $pathinfo(hostname) $pathinfo(file)] + + return $localpath + } }