Diff

Differences From Artifact [649eb3a6a1]:

To Artifact [969f157ddb]:


   119    119   			"noarch" - "none" - "any" - "all" {
   120    120   				return "noarch"
   121    121   			}
   122    122   		}
   123    123   
   124    124   		return -code error "Unable to normalize CPU: $cpu"
   125    125   	}
          126  +
          127  +	proc _as_user {code} {
          128  +		::appfsd::simulate_user_fs_enter
          129  +
          130  +		set retcode [catch [list uplevel $code] retstr]
          131  +
          132  +		::appfsd::simulate_user_fs_leave
          133  +
          134  +		return -code $retcode $retstr
          135  +	}
   126    136   
   127    137   	proc init {} {
   128    138   		if {[info exists ::appfs::init_called]} {
   129    139   			return
   130    140   		}
   131    141   
   132    142   		# Force [parray] to be loaded
................................................................................
   156    166   		# Create indexes
   157    167   		db eval {CREATE INDEX IF NOT EXISTS sites_index ON sites (hostname);}
   158    168   		db eval {CREATE INDEX IF NOT EXISTS packages_index ON packages (hostname, package, version, os, cpuArch);}
   159    169   		db eval {CREATE INDEX IF NOT EXISTS files_index ON files (package_sha1, file_name, file_directory);}
   160    170   	}
   161    171   
   162    172   	proc download {hostname hash {method sha1}} {
   163         -		::appfsd::simulate_user_fs_leave
   164         -
   165    173   		set url [_construct_url $hostname $hash $method]
   166    174   		set file [_cachefile $url $hash]
   167    175   
   168         -		::appfsd::simulate_user_fs_enter
   169         -
   170    176   		if {![file exists $file]} {
   171    177   			return -code error "Unable to fetch (file does not exist: $file)"
   172    178   		}
   173    179   
   174    180   		return $file
   175    181   	}
   176    182   
................................................................................
   464    470   				catch {
   465    471   					::appfs::getpkgmanifest $pathinfo(hostname) $pathinfo(package_sha1)
   466    472   				}
   467    473   
   468    474   				set retval [::appfs::db eval {SELECT DISTINCT file_name FROM files WHERE package_sha1 = $pathinfo(package_sha1) AND file_directory = $pathinfo(file);}]
   469    475   
   470    476   				if {[info exists pathinfo(package)] && [info exists pathinfo(hostname)] && [info exists pathinfo(file)]} {
   471         -					set dir [_localpath $pathinfo(package) $pathinfo(hostname) $pathinfo(file)]
   472         -					set whiteoutdir [string range [_whiteoutpath $pathinfo(package) $pathinfo(hostname) $pathinfo(file)] 0 end-15]
          477  +					_as_user {
          478  +						set dir [_localpath $pathinfo(package) $pathinfo(hostname) $pathinfo(file)]
          479  +						set whiteoutdir [string range [_whiteoutpath $pathinfo(package) $pathinfo(hostname) $pathinfo(file)] 0 end-15]
   473    480   
   474         -					foreach file [glob -nocomplain -tails -directory $whiteoutdir {{.,}*.APPFS.WHITEOUT}] {
   475         -						set remove [string range $file 0 end-15]
   476         -						set idx [lsearch -exact $retval $remove]
   477         -						if {$idx != -1} {
   478         -							set retval [lreplace $retval $idx $idx]
   479         -						}
   480         -					}
   481         -
   482         -					foreach file [glob -nocomplain -tails -directory $dir -types {d f l p s} {{.,}*}] {
   483         -						if {$file == "." || $file == ".."} {
   484         -							continue
          481  +						foreach file [glob -nocomplain -tails -directory $whiteoutdir {{.,}*.APPFS.WHITEOUT}] {
          482  +							set remove [string range $file 0 end-15]
          483  +							set idx [lsearch -exact $retval $remove]
          484  +							if {$idx != -1} {
          485  +								set retval [lreplace $retval $idx $idx]
          486  +							}
   485    487   						}
   486    488   
   487         -						if {$file == ".APPFS.WHITEOUT"} {
   488         -							continue
          489  +						foreach file [glob -nocomplain -tails -directory $dir -types {d f l p s} {{.,}*}] {
          490  +							if {$file == "." || $file == ".."} {
          491  +								continue
          492  +							}
          493  +
          494  +							if {$file == ".APPFS.WHITEOUT"} {
          495  +								continue
          496  +							}
          497  +
          498  +							if {[lsearch -exact $retval $file] != -1} {
          499  +								continue
          500  +							}
          501  +
          502  +							lappend retval $file
   489    503   						}
   490         -
   491         -						if {[lsearch -exact $retval $file] != -1} {
   492         -							continue
   493         -						}
   494         -
   495         -						lappend retval $file
   496    504   					}
   497    505   				}
   498    506   
   499    507   				return $retval
   500    508   			}
   501    509   		}
   502    510   
................................................................................
   511    519   			::appfs::getindex $pathinfo(hostname)
   512    520   			::appfs::getpkgmanifest $pathinfo(hostname) $pathinfo(package_sha1)
   513    521   		}
   514    522   
   515    523   		switch -- $pathinfo(_type) {
   516    524   			"toplevel" {
   517    525   				set retval(type) directory
   518         -				set retval(childcount) 2;
          526  +				set retval(childcount) 2
   519    527   			}
   520    528   			"sites" {
   521    529   				set check [::appfs::db onecolumn {SELECT 1 FROM packages WHERE hostname = $pathinfo(hostname);}]
   522    530   				if {$check == "1"} {
   523    531   					set retval(type) directory
   524    532   					set retval(childcount) 2;
   525    533   				}
................................................................................
   564    572   
   565    573   				set retval(localpath) $localpath
   566    574   				set retval(whiteoutpath) $whiteoutpath
   567    575   
   568    576   				if {[file exists $localpath]} {
   569    577   					set retval(is_localfile) 1
   570    578   					catch {
   571         -						file lstat $localpath localpathinfo
          579  +						_as_user {
          580  +							file lstat $localpath localpathinfo
          581  +						}
   572    582   						set retval(time) $localpathinfo(mtime)
   573    583   
   574    584   						switch -- $localpathinfo(type) {
   575    585   							"directory" {
   576    586   								set retval(type) "directory"
   577    587   								set retval(childcount) 2
   578    588   							}
   579    589   							"file" {
   580    590   								set retval(type) "file"
   581    591   								set retval(size) $localpathinfo(size)
   582         -								if {[file executable $localpath]} {
   583         -									set retval(perms) "x"
   584         -								} else {
   585         -									set retval(perms) ""
          592  +								_as_user {
          593  +									if {[file executable $localpath]} {
          594  +										set retval(perms) "x"
          595  +									} else {
          596  +										set retval(perms) ""
          597  +									}
   586    598   								}
   587    599   							}
   588    600   							"link" {
   589    601   								set retval(type) "symlink"
   590         -								set retval(source) [file readlink $localpath]
          602  +
          603  +								_as_user {
          604  +									set retval(source) [file readlink $localpath]
          605  +								}
   591    606   							}
   592    607   							"fifo" {
   593    608   								# Capitalized so that the first char is unique
   594    609   								set retval(type) "Fifo"
   595    610   							}
   596    611   							"socket" {
   597    612   								# Capitalized so that the first char is unique
................................................................................
   651    666   		if {$pkgpathinfo(file_sha1) == ""} {
   652    667   			return -code error "No such file or directory"
   653    668   		}
   654    669   
   655    670   		set localcachefile [download $pathinfo(hostname) $pkgpathinfo(file_sha1)]
   656    671   
   657    672   		if {$mode == "write"} {
   658         -			set tmplocalpath "${localpath}.[expr rand()][clock clicks]"
          673  +			_as_user {
          674  +				set tmplocalpath "${localpath}.[expr rand()][clock clicks]"
   659    675   
   660         -			set failed 0
   661         -			if {[catch {
   662         -				file mkdir [file dirname $localpath]
   663         -				file copy -force -- $localcachefile $tmplocalpath
          676  +				set failed 0
          677  +				if {[catch {
          678  +					file mkdir [file dirname $localpath]
          679  +					file copy -force -- $localcachefile $tmplocalpath
   664    680   
   665         -				if {$pkgpathinfo(perms) == "x"} {
   666         -					file attributes $tmplocalpath -permissions +x
          681  +					if {$pkgpathinfo(perms) == "x"} {
          682  +						file attributes $tmplocalpath -permissions +x
          683  +					}
          684  +
          685  +					file rename -force -- $tmplocalpath $localpath
          686  +				} err]} {
          687  +					set failed 1
   667    688   				}
   668         -
   669         -				file rename -force -- $tmplocalpath $localpath
   670         -			} err]} {
   671         -				set failed 1
   672         -			}
   673         -			catch {
   674         -				file delete -force -- $tmplocalpath
          689  +				catch {
          690  +					file delete -force -- $tmplocalpath
          691  +				}
   675    692   			}
   676    693   
   677    694   			if {$failed} {
   678    695   				return -code error $err
   679    696   			}
   680    697   
   681    698   			return $localpath
................................................................................
   719    736   			}
   720    737   		}
   721    738   
   722    739   		set filename [localpath $path]
   723    740   
   724    741   		set dirname [file dirname $filename]
   725    742   
   726         -		file mkdir $dirname
          743  +		_as_user {
          744  +			file mkdir $dirname
          745  +		}
   727    746   
   728    747   		return $filename
   729    748   	}
   730    749   
   731    750   	proc unlinkpath {path} {
   732    751   		array set pathattrs [exists $path]
   733    752   
................................................................................
   742    761   				set children [getchildren $path]
   743    762   
   744    763   				if {[llength $children] != 0} {
   745    764   					return -code error "Asked to delete non-empty directory"
   746    765   				}
   747    766   			}
   748    767   
   749         -			file delete -force -- $localpath
          768  +			_as_user {
          769  +				file delete -force -- $localpath
          770  +			}
   750    771   		} elseif {[info exists pathattrs(is_remotefile)]} {
   751    772   			if {$pathattrs(type) == "directory"} {
   752    773   				set children [getchildren $path]
   753    774   
   754    775   				if {[llength $children] != 0} {
   755    776   					return -code error "Asked to delete non-empty directory"
   756    777   				}
................................................................................
   757    778   			}
   758    779   		} else {
   759    780   			return -code error "Unknown if file is remote or local !?"
   760    781   		}
   761    782   
   762    783   		set whiteoutfile $pathattrs(whiteoutpath)
   763    784   		set whiteoutdir [file dirname $whiteoutfile]
   764         -		file mkdir $whiteoutdir
   765         -		close [open $whiteoutfile w]
          785  +
          786  +		_as_user {
          787  +			file mkdir $whiteoutdir
          788  +			close [open $whiteoutfile w]
          789  +		}
   766    790   	}
   767    791   }