@@ -92,6 +92,9 @@ namespace eval macports {
9292 # Options set in the portfile interpreter but only in system_options
9393 variable portinterp_private_options [list clonebin_path macosx_sdk_path]
9494
95+ # Directories in portdbpath that are publicly known
96+ variable wellknown_dirs [dict create build 1 distfiles 1 incoming 1 logs 1 registry 1 software 1 sources 1]
97+
9598 # Only used via override_vars
9699 variable macosx_sdk_path
97100
@@ -3522,6 +3525,16 @@ proc _source_is_obsolete_svn_repo {source_dir} {
35223525 return 0
35233526}
35243527
3528+ # Get path to a well-known directory used by MacPorts
3529+ proc macports::get_dir_path {dir} {
3530+ variable wellknown_dirs
3531+ if {![dict exists $wellknown_dirs $dir ]} {
3532+ error " Unknown directory: $dir "
3533+ }
3534+ variable portdbpath
3535+ return [file join $portdbpath $dir ]
3536+ }
3537+
35253538proc macports::getportbuildpath {id {portname {}}} {
35263539 package require sha1
35273540 variable portdbpath
@@ -3802,6 +3815,49 @@ proc macports::verify_ports_signature {path} {
38023815 error " No known key verified signature for $path "
38033816}
38043817
3818+ # Helper to delete files in the given ports tree dir that are not in
3819+ # the given tarball or are updated in the tarball.
3820+ proc macports::delete_ports_not_in_tarball {extractdir tarball} {
3821+ # First move the PortIndex to avoid deleting it.
3822+ set indexfile ${extractdir} /ports/PortIndex
3823+ if {[file isfile $indexfile ]} {
3824+ file mkdir ${extractdir} /tmp
3825+ file rename -force $indexfile ${extractdir} /tmp/
3826+ if {[file isfile ${indexfile} .quick]} {
3827+ file rename -force ${indexfile} .quick ${extractdir} /tmp/
3828+ }
3829+ }
3830+ package require tar
3831+ set tarfiles [::tar::stat $tarball ]
3832+ set subpath_start [expr {[string length $extractdir ] + 1}]
3833+ fs-traverse -depth f [list ${extractdir} /ports] {
3834+ set subpath [string range $f $subpath_start end]
3835+ file lstat $f statinfo
3836+ if {$statinfo(type) eq " directory" } {
3837+ append subpath /
3838+ }
3839+ if {![dict exists $tarfiles $subpath ]
3840+ || [dict get $tarfiles $subpath type] ne $statinfo(type)
3841+ || ($statinfo(type) ne " directory" && [dict get $tarfiles $subpath mtime] != $statinfo(mtime) )
3842+ || ($statinfo(type) eq " file" && [dict get $tarfiles $subpath size] != $statinfo(size) )
3843+ || ($statinfo(type) eq " link" && [dict get $tarfiles $subpath linkname] ne [file readlink $f ])
3844+ } then {
3845+ file delete -force $f
3846+ }
3847+ }
3848+ # Put PortIndex back
3849+ if {[file isfile ${extractdir} /tmp/PortIndex]} {
3850+ set cur_uid [getuid]
3851+ file rename -force ${extractdir} /tmp/PortIndex $indexfile
3852+ chown $indexfile $cur_uid
3853+ if {[file isfile ${extractdir} /tmp/PortIndex.quick]} {
3854+ file rename -force ${extractdir} /tmp/PortIndex.quick ${indexfile} .quick
3855+ chown ${indexfile} .quick $cur_uid
3856+ }
3857+ }
3858+ file delete -force ${extractdir} /tmp
3859+ }
3860+
38053861proc mportsync {{options {}}} {
38063862 global macports::sources macports::ui_prefix \
38073863 macports::os_platform macports::os_major \
@@ -3969,43 +4025,7 @@ proc mportsync {{options {}}} {
39694025 set kflag {}
39704026 } else {
39714027 # Extract only updated files, and delete ones not in the tarball.
3972- # First move the PortIndex to avoid deleting it.
3973- if {[file isfile $indexfile ]} {
3974- file mkdir ${extractdir} /tmp
3975- file rename -force $indexfile ${extractdir} /tmp/
3976- if {[file isfile ${indexfile} .quick]} {
3977- file rename -force ${indexfile} .quick ${extractdir} /tmp/
3978- }
3979- }
3980- package require tar
3981- set tarfiles [::tar::stat $tarball ]
3982- set subpath_start [expr {[string length $extractdir ] + 1}]
3983- fs-traverse -depth f [list ${extractdir} /ports] {
3984- set subpath [string range $f $subpath_start end]
3985- file lstat $f statinfo
3986- if {$statinfo(type) eq " directory" } {
3987- append subpath /
3988- }
3989- if {![dict exists $tarfiles $subpath ]
3990- || [dict get $tarfiles $subpath type] ne $statinfo(type)
3991- || ($statinfo(type) ne " directory" && [dict get $tarfiles $subpath mtime] != $statinfo(mtime) )
3992- || ($statinfo(type) eq " file" && [dict get $tarfiles $subpath size] != $statinfo(size) )
3993- || ($statinfo(type) eq " link" && [dict get $tarfiles $subpath linkname] ne [file readlink $f ])
3994- } then {
3995- file delete -force $f
3996- }
3997- }
3998- unset tarfiles
3999- # Put PortIndex back
4000- if {[file isfile ${extractdir} /tmp/PortIndex]} {
4001- file rename -force ${extractdir} /tmp/PortIndex $indexfile
4002- macports::chown $indexfile $cur_uid
4003- if {[file isfile ${extractdir} /tmp/PortIndex.quick]} {
4004- file rename -force ${extractdir} /tmp/PortIndex.quick ${indexfile} .quick
4005- macports::chown ${indexfile} .quick $cur_uid
4006- }
4007- }
4008- file delete -force ${extractdir} /tmp
4028+ macports::delete_ports_not_in_tarball $extractdir $tarball
40094029 # use -k if supported to skip extracting files that exist
40104030 global macports::prefix_frozen
40114031 if {[string match ${prefix_frozen} /bin/* $tar ]} {
@@ -4092,7 +4112,8 @@ proc mportsync {{options {}}} {
40924112 # sync a port snapshot tarball
40934113 set indexfile [macports::getindex $source ]
40944114 set destdir [file dirname $indexfile ]
4095- set tarpath [file join [file normalize [file join $destdir ..]] $filename ]
4115+ set tardir [file dirname $destdir ]
4116+ set tarpath [file join $tardir $filename ]
40964117
40974118 set updated 1
40984119 if {[file isdirectory $destdir ]} {
@@ -4116,7 +4137,7 @@ proc mportsync {{options {}}} {
41164137 set progressflag {}
41174138 if {$portverbose } {
41184139 set progressflag [list --progress builtin]
4119- set verboseflag " -v "
4140+ set verboseflag v
41204141 } elseif {[info exists ui_options(progress_download)]} {
41214142 set progressflag [list --progress $ui_options(progress_download) ]
41224143 set verboseflag " "
@@ -4142,13 +4163,39 @@ proc mportsync {{options {}}} {
41424163 continue
41434164 }
41444165
4166+ set tar {}
4167+ global macports::hfscompression
4168+ if {${hfscompression} && [getuid] == 0} {
4169+ ui_debug " Using bsdtar with HFS+ compression (if valid)"
4170+ set tar [macports::find_tar_with_hfscompression]
4171+ }
4172+ if {$tar ne {}} {
4173+ set tar " $tar --hfsCompression"
4174+ } else {
4175+ set tar [macports::findBinary tar $tar_path ]
4176+ }
4177+ # Simply extract if there is no existing ports tree
4178+ if {[llength [glob -nocomplain -directory $destdir *]] == 0} {
4179+ set kflag {}
4180+ } else {
4181+ # Extract only updated files, and delete ones not in the tarball.
4182+ macports::delete_ports_not_in_tarball $tardir $tarpath
4183+ # use -k if supported to skip extracting files that exist
4184+ global macports::prefix_frozen
4185+ if {[string match ${prefix_frozen} /bin/* $tar ]} {
4186+ set kflag k
4187+ } else {
4188+ set kflag $::macports::autoconf::tar_k
4189+ }
4190+ }
4191+
41454192 set extflag {}
41464193 switch -- $extension {
41474194 {tar.gz} {
4148- set extflag - z
4195+ set extflag z
41494196 }
41504197 {tar.bz2} {
4151- set extflag - j
4198+ set extflag j
41524199 }
41534200 }
41544201
@@ -4157,9 +4204,8 @@ proc mportsync {{options {}}} {
41574204 # as top-level directory name.
41584205 set striparg " --strip-components=1"
41594206
4160- set tar [macports::findBinary tar $tar_path ]
41614207 if {[catch {
4162- system -W ${ destdir} " $tar $verboseflag $ striparg $ extflag -xf [ macports::shellescape $tarpath ] "
4208+ system -W $destdir " $tar $striparg -x ${ extflag}${kflag}${verboseflag} f [ macports::shellescape $tarpath ] "
41634209 } error]} {
41644210 ui_error " Extracting $source failed ($error )"
41654211 incr numfailed
@@ -4177,7 +4223,7 @@ proc mportsync {{options {}}} {
41774223 set needs_portindex true
41784224 }
41794225
4180- file delete $tarpath
4226+ file delete $tarpath ${tarpath} .sig
41814227 }
41824228 {^mports$} {
41834229 ui_error " Synchronization using the mports protocol no longer supported."
0 commit comments