Index: appfsd.c ================================================================== --- appfsd.c +++ appfsd.c @@ -501,16 +501,11 @@ interp = appfs_TclInterp(); if (interp == NULL) { return(-EIO); } - appfs_simulate_user_fs_enter(); - tcl_ret = appfs_Tcl_Eval(interp, 2, "::appfs::getattr", path); - - appfs_simulate_user_fs_leave(); - if (tcl_ret != TCL_OK) { APPFS_DEBUG("::appfs::getattr(%s) failed.", path); APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp)); return(-ENOENT); @@ -783,16 +778,11 @@ } filler(buf, ".", NULL, 0); filler(buf, "..", NULL, 0); - appfs_simulate_user_fs_enter(); - tcl_ret = appfs_Tcl_Eval(interp, 2, "::appfs::getchildren", path); - - appfs_simulate_user_fs_leave(); - if (tcl_ret != TCL_OK) { APPFS_DEBUG("::appfs::getchildren(%s) failed.", path); APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp)); return(0); @@ -851,35 +841,27 @@ interp = appfs_TclInterp(); if (interp == NULL) { return(-EIO); } - appfs_simulate_user_fs_enter(); - tcl_ret = appfs_Tcl_Eval(interp, 3, "::appfs::openpath", path, mode); if (tcl_ret != TCL_OK) { - appfs_simulate_user_fs_leave(); - APPFS_DEBUG("::appfs::openpath(%s, %s) failed.", path, mode); APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp)); return(-EIO); } real_path = Tcl_GetStringResult(interp); if (real_path == NULL) { - appfs_simulate_user_fs_leave(); - return(-EIO); } APPFS_DEBUG("Translated request to open %s to opening %s (mode = \"%s\")", path, real_path, mode); fh = open(real_path, fi->flags, 0600); - appfs_simulate_user_fs_leave(); - if (fh < 0) { return(-EIO); } fi->fh = fh; @@ -942,18 +924,16 @@ if ((mode & S_IFBLK) == S_IFBLK) { return(-EPERM); } - appfs_simulate_user_fs_enter(); - real_path = appfs_prepare_to_create(path); if (real_path == NULL) { - appfs_simulate_user_fs_leave(); - return(-EIO); } + + appfs_simulate_user_fs_enter(); mknod_ret = mknod(real_path, mode, device); appfs_simulate_user_fs_leave(); @@ -978,18 +958,16 @@ if ((mode & S_IFBLK) == S_IFBLK) { return(-EPERM); } - appfs_simulate_user_fs_enter(); - real_path = appfs_prepare_to_create(path); if (real_path == NULL) { - appfs_simulate_user_fs_leave(); - return(-EIO); } + + appfs_simulate_user_fs_enter(); fd = creat(real_path, mode); appfs_simulate_user_fs_leave(); @@ -1039,16 +1017,11 @@ interp = appfs_TclInterp(); if (interp == NULL) { return(-EIO); } - appfs_simulate_user_fs_enter(); - tcl_ret = appfs_Tcl_Eval(interp, 2, "::appfs::unlinkpath", path); - - appfs_simulate_user_fs_leave(); - if (tcl_ret != TCL_OK) { APPFS_DEBUG("::appfs::unlinkpath(%s) failed.", path); APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp)); return(-EIO); @@ -1061,18 +1034,17 @@ char *real_path; int mkdir_ret; APPFS_DEBUG("Enter (path = %s, ...)", path); - appfs_simulate_user_fs_enter(); real_path = appfs_prepare_to_create(path); if (real_path == NULL) { - appfs_simulate_user_fs_leave(); - return(-EIO); } + + appfs_simulate_user_fs_enter(); mkdir_ret = mkdir(real_path, mode); appfs_simulate_user_fs_leave(); @@ -1097,28 +1069,24 @@ interp = appfs_TclInterp(); if (interp == NULL) { return(-EIO); } - appfs_simulate_user_fs_enter(); - tcl_ret = appfs_Tcl_Eval(interp, 3, "::appfs::openpath", path, "write"); if (tcl_ret != TCL_OK) { - appfs_simulate_user_fs_leave(); - APPFS_DEBUG("::appfs::openpath(%s, %s) failed.", path, "write"); APPFS_DEBUG("Tcl Error is: %s", Tcl_GetStringResult(interp)); return(-EIO); } real_path = Tcl_GetStringResult(interp); if (real_path == NULL) { - appfs_simulate_user_fs_leave(); - return(-EIO); } + + appfs_simulate_user_fs_enter(); chmod_ret = chmod(real_path, mode); appfs_simulate_user_fs_leave(); Index: appfsd.tcl ================================================================== --- appfsd.tcl +++ appfsd.tcl @@ -121,10 +121,20 @@ } } return -code error "Unable to normalize CPU: $cpu" } + + proc _as_user {code} { + ::appfsd::simulate_user_fs_enter + + set retcode [catch [list uplevel $code] retstr] + + ::appfsd::simulate_user_fs_leave + + return -code $retcode $retstr + } proc init {} { if {[info exists ::appfs::init_called]} { return } @@ -158,17 +168,13 @@ db eval {CREATE INDEX IF NOT EXISTS packages_index ON packages (hostname, package, version, os, cpuArch);} db eval {CREATE INDEX IF NOT EXISTS files_index ON files (package_sha1, file_name, file_directory);} } proc download {hostname hash {method sha1}} { - ::appfsd::simulate_user_fs_leave - set url [_construct_url $hostname $hash $method] set file [_cachefile $url $hash] - ::appfsd::simulate_user_fs_enter - if {![file exists $file]} { return -code error "Unable to fetch (file does not exist: $file)" } return $file @@ -466,35 +472,37 @@ } set retval [::appfs::db eval {SELECT DISTINCT file_name FROM files WHERE package_sha1 = $pathinfo(package_sha1) AND file_directory = $pathinfo(file);}] if {[info exists pathinfo(package)] && [info exists pathinfo(hostname)] && [info exists pathinfo(file)]} { - set dir [_localpath $pathinfo(package) $pathinfo(hostname) $pathinfo(file)] - set whiteoutdir [string range [_whiteoutpath $pathinfo(package) $pathinfo(hostname) $pathinfo(file)] 0 end-15] - - foreach file [glob -nocomplain -tails -directory $whiteoutdir {{.,}*.APPFS.WHITEOUT}] { - set remove [string range $file 0 end-15] - set idx [lsearch -exact $retval $remove] - if {$idx != -1} { - set retval [lreplace $retval $idx $idx] - } - } - - foreach file [glob -nocomplain -tails -directory $dir -types {d f l p s} {{.,}*}] { - if {$file == "." || $file == ".."} { - continue - } - - if {$file == ".APPFS.WHITEOUT"} { - continue - } - - if {[lsearch -exact $retval $file] != -1} { - continue - } - - lappend retval $file + _as_user { + set dir [_localpath $pathinfo(package) $pathinfo(hostname) $pathinfo(file)] + set whiteoutdir [string range [_whiteoutpath $pathinfo(package) $pathinfo(hostname) $pathinfo(file)] 0 end-15] + + foreach file [glob -nocomplain -tails -directory $whiteoutdir {{.,}*.APPFS.WHITEOUT}] { + set remove [string range $file 0 end-15] + set idx [lsearch -exact $retval $remove] + if {$idx != -1} { + set retval [lreplace $retval $idx $idx] + } + } + + foreach file [glob -nocomplain -tails -directory $dir -types {d f l p s} {{.,}*}] { + if {$file == "." || $file == ".."} { + continue + } + + if {$file == ".APPFS.WHITEOUT"} { + continue + } + + if {[lsearch -exact $retval $file] != -1} { + continue + } + + lappend retval $file + } } } return $retval } @@ -513,11 +521,11 @@ } switch -- $pathinfo(_type) { "toplevel" { set retval(type) directory - set retval(childcount) 2; + set retval(childcount) 2 } "sites" { set check [::appfs::db onecolumn {SELECT 1 FROM packages WHERE hostname = $pathinfo(hostname);}] if {$check == "1"} { set retval(type) directory @@ -566,11 +574,13 @@ set retval(whiteoutpath) $whiteoutpath if {[file exists $localpath]} { set retval(is_localfile) 1 catch { - file lstat $localpath localpathinfo + _as_user { + file lstat $localpath localpathinfo + } set retval(time) $localpathinfo(mtime) switch -- $localpathinfo(type) { "directory" { set retval(type) "directory" @@ -577,19 +587,24 @@ set retval(childcount) 2 } "file" { set retval(type) "file" set retval(size) $localpathinfo(size) - if {[file executable $localpath]} { - set retval(perms) "x" - } else { - set retval(perms) "" + _as_user { + if {[file executable $localpath]} { + set retval(perms) "x" + } else { + set retval(perms) "" + } } } "link" { set retval(type) "symlink" - set retval(source) [file readlink $localpath] + + _as_user { + set retval(source) [file readlink $localpath] + } } "fifo" { # Capitalized so that the first char is unique set retval(type) "Fifo" } @@ -653,27 +668,29 @@ } set localcachefile [download $pathinfo(hostname) $pkgpathinfo(file_sha1)] if {$mode == "write"} { - set tmplocalpath "${localpath}.[expr rand()][clock clicks]" - - set failed 0 - if {[catch { - file mkdir [file dirname $localpath] - file copy -force -- $localcachefile $tmplocalpath - - if {$pkgpathinfo(perms) == "x"} { - file attributes $tmplocalpath -permissions +x - } - - file rename -force -- $tmplocalpath $localpath - } err]} { - set failed 1 - } - catch { - file delete -force -- $tmplocalpath + _as_user { + set tmplocalpath "${localpath}.[expr rand()][clock clicks]" + + set failed 0 + if {[catch { + file mkdir [file dirname $localpath] + file copy -force -- $localcachefile $tmplocalpath + + if {$pkgpathinfo(perms) == "x"} { + file attributes $tmplocalpath -permissions +x + } + + file rename -force -- $tmplocalpath $localpath + } err]} { + set failed 1 + } + catch { + file delete -force -- $tmplocalpath + } } if {$failed} { return -code error $err } @@ -721,11 +738,13 @@ set filename [localpath $path] set dirname [file dirname $filename] - file mkdir $dirname + _as_user { + file mkdir $dirname + } return $filename } proc unlinkpath {path} { @@ -744,11 +763,13 @@ if {[llength $children] != 0} { return -code error "Asked to delete non-empty directory" } } - file delete -force -- $localpath + _as_user { + file delete -force -- $localpath + } } elseif {[info exists pathattrs(is_remotefile)]} { if {$pathattrs(type) == "directory"} { set children [getchildren $path] if {[llength $children] != 0} { @@ -759,9 +780,12 @@ return -code error "Unknown if file is remote or local !?" } set whiteoutfile $pathattrs(whiteoutpath) set whiteoutdir [file dirname $whiteoutfile] - file mkdir $whiteoutdir - close [open $whiteoutfile w] + + _as_user { + file mkdir $whiteoutdir + close [open $whiteoutfile w] + } } }