<pre style='margin:0'>
Joshua Root (jmroot) pushed a commit to branch master
in repository macports-base.

</pre>
<p><a href="https://github.com/macports/macports-base/commit/dd3acc4b974d274d922b705a9115ba1dc786104f">https://github.com/macports/macports-base/commit/dd3acc4b974d274d922b705a9115ba1dc786104f</a></p>
<pre style="white-space: pre; background: #F8F8F8">The following commit(s) were added to refs/heads/master by this push:
<span style='display:block; white-space:pre;color:#404040;'>     new dd3acc4b9 macports1.0: Selfupdate using HTTP(S)
</span>dd3acc4b9 is described below

<span style='display:block; white-space:pre;color:#808000;'>commit dd3acc4b974d274d922b705a9115ba1dc786104f
</span>Author: Clemens Lang <cal@macports.org>
AuthorDate: Sat Jul 6 23:00:41 2024 +1000

<span style='display:block; white-space:pre;color:#404040;'>    macports1.0: Selfupdate using HTTP(S)
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Refactor the selfupdate package into smaller functions and switch to
</span><span style='display:block; white-space:pre;color:#404040;'>    a control flow of:
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>     1. checking for newer versions by downloading a single URL
</span><span style='display:block; white-space:pre;color:#404040;'>     2. downloading the new version using HTTP when available
</span><span style='display:block; white-space:pre;color:#404040;'>     3. verifying the signature using EdDSA with ed25519 elliptic curve
</span><span style='display:block; white-space:pre;color:#404040;'>        crypto with the help of OpenBSD's signify(1)
</span><span style='display:block; white-space:pre;color:#404040;'>     4. Fall back to the old rsync method if the above fails.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    This allows us to automatically fall back to other mirrors should our
</span><span style='display:block; white-space:pre;color:#404040;'>    main mirror not be available. We did not have this functionality
</span><span style='display:block; white-space:pre;color:#404040;'>    available for our previous rsync-based mechanism.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Additionally, the use of our standard curl wrapper enables displaying
</span><span style='display:block; white-space:pre;color:#404040;'>    a progress bar for the download and automatically uses any proxies that
</span><span style='display:block; white-space:pre;color:#404040;'>    might already be configured for HTTP.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Since we currently do not have a standard mechanism to sign the source
</span><span style='display:block; white-space:pre;color:#404040;'>    code tarballs uploaded to our distfiles server and github releases page
</span><span style='display:block; white-space:pre;color:#404040;'>    (we only sign the tarball pushed to rsync), I've taken the liberty to
</span><span style='display:block; white-space:pre;color:#404040;'>    introduce a new modern signature scheme for this channel – if we have to
</span><span style='display:block; white-space:pre;color:#404040;'>    touch this anyway, we might as well use modern tools and algorithms.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Co-authored-by: Joshua Root <jmr@macports.org>
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Closes: https://trac.macports.org/ticket/38265
</span><span style='display:block; white-space:pre;color:#404040;'>    Closes: https://github.com/macports/macports-base/pull/184
</span>---
 doc/port-selfupdate.1.txt      |  22 +-
 src/macports1.0/selfupdate.tcl | 675 ++++++++++++++++++++++++++++++-----------
 2 files changed, 516 insertions(+), 181 deletions(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/doc/port-selfupdate.1.txt b/doc/port-selfupdate.1.txt
</span><span style='display:block; white-space:pre;color:#808080;'>index 1a8de6fd3..d7a6bb0c5 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/doc/port-selfupdate.1.txt
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/doc/port-selfupdate.1.txt
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -55,11 +55,11 @@ When no new versions are available, *selfupdate* looks like this:
</span> [subs="verbatim,attributes"]
 ----
 $ sudo port selfupdate
<span style='display:block; white-space:pre;background:#ffe0e0;'>----> Updating MacPorts base sources using rsync
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--->  Checking for newer releases of MacPorts
</span> MacPorts base version {manversion} installed,
<span style='display:block; white-space:pre;background:#ffe0e0;'>-MacPorts base version {manversion} downloaded.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>----> Updating the ports tree
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+MacPorts base version {manversion} available.
</span> ---> MacPorts base is already the latest version
<span style='display:block; white-space:pre;background:#e0ffe0;'>+---> Updating the ports tree
</span> ----
 
 If *selfupdate* detects that a newer version of MacPorts is available, it
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -69,12 +69,14 @@ different:
</span> [subs="verbatim,attributes"]
 ----
 $ sudo port selfupdate
<span style='display:block; white-space:pre;background:#ffe0e0;'>----> Updating MacPorts base sources using rsync
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-MacPorts base version 2.3.0 installed,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-MacPorts base version {manversion} downloaded.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>----> Updating the ports tree
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--->  Checking for newer releases of MacPorts
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+MacPorts base version 2.6.0 installed,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+MacPorts base version {manversion} available.
</span> ---> MacPorts base is outdated, installing new version {manversion}
<span style='display:block; white-space:pre;background:#ffe0e0;'>-Installing new MacPorts release in /opt/local as root:admin; permissions 755
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+---> Updating the ports tree
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--->  Attempting to fetch MacPorts {manversion} source code from https://github.com/macports/macports-base/releases/download/v{manversion}/MacPorts-{manversion}.tar.bz2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--->  Extracting MacPorts {manversion}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--->  Installing new MacPorts release in /opt/local as root:admin; permissions 0755
</span> ----
 
 TROUBLESHOOTING
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -83,7 +85,7 @@ If *selfupdate* fails, it usually does so in one of two places: The network
</span> connection, or the installation of the update.
 
 Network Problems::
<span style='display:block; white-space:pre;background:#ffe0e0;'>-MacPorts uses the 'rsync' protocol to update its sources to the latest version.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+MacPorts uses the 'rsync' protocol to update its port tree to the latest version.
</span> This will fail if you are on a network that blocks TCP connections to the rsync
 port 873. Talk to your network administrators and ask them to allow connections
 to port 873 if this happens to you. Alternatively, you can just download a new
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -118,5 +120,5 @@ man:port[1], man:port-sync[1]
</span> 
 AUTHORS
 -------
<span style='display:block; white-space:pre;background:#ffe0e0;'>- (C) 2014 The MacPorts Project
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ (C) 2014-2020 The MacPorts Project
</span>  Clemens Lang <cal@macports.org>
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/macports1.0/selfupdate.tcl b/src/macports1.0/selfupdate.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index e148e0dcb..9f8a20297 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/macports1.0/selfupdate.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/macports1.0/selfupdate.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -31,40 +31,282 @@
</span> package provide selfupdate 1.0
 
 package require macports
<span style='display:block; white-space:pre;background:#e0ffe0;'>+package require Pextlib 1.0
</span> 
 namespace eval selfupdate {
     namespace export main
 }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-proc selfupdate::main {{options {}} {updatestatusvar {}}} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    global macports::portdbpath macports::rsync_server macports::rsync_dir \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           macports::rsync_options macports::autoconf::macports_version \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-           macports::autoconf::rsync_path macports::ui_prefix
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc selfupdate::can_use_https {provider} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global macports::os_platform macports::os_major
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    switch -- $provider {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        letsencrypt {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            return [expr {${os_platform} ne "darwin" || ${os_major} == 16 || ${os_major} > 18}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        github {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            return [expr {${os_platform} ne "darwin" || ${os_major} >= 13}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    # variable that indicates whether we actually updated base
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    if {$updatestatusvar ne ""} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        upvar $updatestatusvar updatestatus
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set updatestatus no
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Determine the current MacPorts version from one of the configured \c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# macports::release_version_url.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# On success, return the current version number. On error, prints error
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# messages and raises an error.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# @param mp_source_path Directory to use for the download
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# @return current macports version on success, an error if the current version
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#         could not be determined
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc selfupdate::get_current_version {mp_source_path} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports::release_version_urls \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports::ui_prefix
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # Check for newer MacPorts versions
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    ui_msg "$ui_prefix Checking for newer releases of MacPorts"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {![info exists release_version_urls]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set release_version_urls [list]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {[can_use_https github]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            lappend release_version_urls \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                "https://raw.githubusercontent.com/macports/macports-base/master/config/RELEASE_URL"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {[can_use_https letsencrypt]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            lappend release_version_urls \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                "https://distfiles.macports.org/MacPorts/RELEASE_URL"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                "https://trac.macports.org/export/HEAD/macports-base/config/RELEASE_URL" \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            lappend release_version_urls \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                "http://distfiles.macports.org/MacPorts/RELEASE_URL"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span>     }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    set rsync_url rsync://${rsync_server}/
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    # are we syncing a tarball? (implies detached signature)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    set is_tarball 0
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    if {[string range $rsync_dir end-3 end] eq ".tar"} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set is_tarball 1
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set tarballs_dir [file dirname $rsync_dir]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        append rsync_url ${tarballs_dir}/
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set mp_source_path [file join $portdbpath sources $rsync_server $tarballs_dir]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set tarfile [file tail $rsync_dir]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set include_options " --include=[macports::shellescape /${tarfile}] --include=[macports::shellescape /${tarfile}.rmd160] --exclude=*"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set progressflag {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {$macports::portverbose} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set progressflag "--progress builtin"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    array set selfupdate_errors {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    foreach release_version_url $release_version_urls {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Try every URL until one of them succeeds or all failed
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set filename [file tail $release_version_url]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set filepath [file join $mp_source_path $filename]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_debug "Attempting to fetch version file $release_version_url"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports_try -pass_signal {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            curl fetch {*}$progressflag $release_version_url $filepath
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        } on error {eMessage} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set selfupdate_errors($release_version_url) "Error downloading $release_version_url: $eMessage"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_debug [set selfupdate_errors($release_version_url)]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            continue
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Read the downloaded file and attempt to extract the version
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports_try -pass_signal {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set fd [open $filepath r]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[gets $fd line] < 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                error "Could not read $filepath (or file is empty)"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # Expected format is https://github.com/macports/macports-base/releases/tag/v2.6.2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # We extract 2.6.2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set tag [file tail [string trim $line]]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[string index $tag 0] ne "v" || [string length $tag] <= 1} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                error "Version in $tag extracted from $line does not match expected format ^v(.+)\$"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set macports_version_new [string range $tag 1 end]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # Successfully determined current version, break out of the loop
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            break
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        } on error {eMessage} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set selfupdate_errors($release_version_url) "Error extracting release version from $release_version_url: $eMessage"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_debug [set selfupdate_errors($release_version_url)]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            continue
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # If macports_version_new isn't set, all available download URLs must have failed
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {![info exists macports_version_new]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_error "Failed to determine the current MacPorts release from any of the configured URLs:"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        foreach release_version_url [array names selfupdate_errors] {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_error "  [set selfupdate_errors($release_version_url)]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_error "Please check your internet connection and proxy configuration."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        error "Error determining current MacPorts release version"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return $macports_version_new
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Get version from extracted MacPorts source directory
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc selfupdate::get_current_version_from_sources {mp_source_path} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set version_file [file join $mp_source_path config macports_version]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {[file exists $version_file]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set fd [open $version_file r]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        gets $fd macports_version_new
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        close $fd
</span>     } else {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        if {[string index $rsync_dir end] ne "/"} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            append rsync_dir /
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_warn "No version file found in downloaded MacPorts source code!"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set macports_version_new 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return $macports_version_new
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Download the MacPorts version \a macports_version_new from one of the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# mirrors, verify a detached signature against one of the public keys in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# $prefix/share/macports/keys/base and extract it into \a mp_source_path.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# On success, return the path to the extracted source code. On error, throws
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# after printing an error message.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# @param mp_source_path Temporary path to use for downloading and extracting
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# @param macports_version_new MacPorts version to download and extract
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc selfupdate::download_source {mp_source_path macports_version_new} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports::release_urls \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports::ui_options \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports::ui_prefix
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # create the path to the to be downloaded sources if it doesn't exist
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {![file exists $mp_source_path]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        file mkdir $mp_source_path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    ui_debug "MacPorts sources location: $mp_source_path"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {![info exists release_urls]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set release_urls [list]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {[can_use_https github]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            lappend release_urls \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                "https://github.com/macports/macports-base/releases/download/v{version}/MacPorts-{version}.tar.bz2"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {[can_use_https letsencrypt]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            lappend release_urls \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                "https://distfiles.macports.org/MacPorts/MacPorts-{version}.tar.bz2"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            lappend release_urls \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                "http://distfiles.macports.org/MacPorts/MacPorts-{version}.tar.bz2"
</span>         }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        append rsync_url $rsync_dir
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set mp_source_path [file join $portdbpath sources $rsync_server $rsync_dir]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set include_options ""
</span>     }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #global macports::os_major macports::os_platform
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #set base_mirror_site_list [macports::getdefaultportresourcepath "port1.0/fetch/base_mirror_sites.list"]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #set maybe_https [expr {${os_platform} eq "darwin" && ${os_major} < 10 ? "http" : "https"}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #macports_try -pass_signal {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #    set fd [open $base_mirror_site_list r]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #    while {[gets $fd base_mirror_site] >= 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #        set base_mirror_site [string trimright [string trim $base_mirror_site] /]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #        set base_mirror_site [string map "{{maybe_https}} $maybe_https" $base_mirror_site]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #        lappend release_urls "${base_mirror_site}/MacPorts/MacPorts-{version}.tar.bz2"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #    close $fd
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #} on error {eMessage} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #    ui_warn "Error reading mirror list: $eMessage"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #    ui_warn "Continuing with reduced list of mirrors"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set full_release_urls [list]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    foreach release_url $release_urls {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        lappend full_release_urls [string map [list {{version}} $macports_version_new] $release_url]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set progressflag {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set quietprogressflag {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {$macports::portverbose} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set progressflag "--progress builtin"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set quietprogressflag $progressflag
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } elseif {[info exists macports::ui_options(progress_download)]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set progressflag "--progress ${macports::ui_options(progress_download)}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    array set selfupdate_errors {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    foreach release_url $full_release_urls {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Try every URL until one of them succeeds or all failed
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set filename [file tail $release_url]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set filepath [file join $mp_source_path $filename]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set signature_url "${release_url}.sig"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set signature_filename [file tail $signature_url]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set signature_filepath [file join $mp_source_path $signature_filename]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Download source code tarball
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_msg "$ui_prefix Attempting to fetch MacPorts $macports_version_new source code from $release_url"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports_try -pass_signal {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            curl fetch {*}$progressflag $release_url $filepath
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        } on error {eMessage} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set selfupdate_errors($release_url) "Error downloading $release_url: $eMessage"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_info [set selfupdate_errors($release_url)]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            continue
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Download signature file
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports_try -pass_signal {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_info "Attempting to fetch signature from $signature_url"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            curl fetch {*}$progressflag $signature_url $signature_filepath
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        } on error {eMessage} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set selfupdate_errors($release_url) "Error downloading signature from $signature_url: $eMessage"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_info [set selfupdate_errors($release_url)]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            continue
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports_try -pass_signal {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            selfupdate::verify_signature $filepath $signature_filepath
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        } on error {eMessage} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set selfupdate_errors($release_url) "Error verifying signature for $release_url: $eMessage"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_info [set selfupdate_errors($release_url)]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            continue
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set tarball $filepath
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        break
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {![info exists tarball]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_error "Failed to download MacPorts $macports_version_new from any of the configured mirrors:"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        foreach release_url [array names selfupdate_errors] {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_error "  [set selfupdate_errors($release_url)]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_error "Please check your internet connection and proxy configuration."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        error "Error downloading MacPorts $macports_version_new"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # extract tarball and move into place
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    ui_msg "$ui_prefix Extracting MacPorts $macports_version_new"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set tar [macports::findBinary tar $macports::autoconf::tar_path]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    file mkdir ${mp_source_path}/tmp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set tarflags [macports::get_tar_flags [file extension $tarball]]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set tar_cmd "$tar -C [macports::shellescape ${mp_source_path}/tmp] ${tarflags}xf [macports::shellescape $tarball]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    macports_try -pass_signal {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        system $tar_cmd
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } on error {eMessage} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        error "Failed to extract MacPorts sources from tarball: $eMessage"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    file delete -force ${mp_source_path}/base
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    foreach path [glob -nocomplain -tails -directory ${mp_source_path}/tmp *] {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        file rename ${mp_source_path}/tmp/${path} ${mp_source_path}/base/
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    file delete -force ${mp_source_path}/tmp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # set the final extracted source path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return ${mp_source_path}/base
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Download source using legacy rsync method
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc selfupdate::download_source_rsync {} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global macports::portdbpath \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports::hfscompression \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports::rsync_server \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports::rsync_dir \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports::rsync_options \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports::ui_prefix \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports::autoconf::rsync_path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set rsync_url rsync://${rsync_server}/
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # are we syncing a tarball? (implies detached signature)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {[string range $rsync_dir end-3 end] ne ".tar"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        error "Selfupdate from unsigned rsync sources is no longer supported. Please update rsync_dir."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set tarballs_dir [file dirname $rsync_dir]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    append rsync_url ${tarballs_dir}/
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set mp_source_path [file join $portdbpath sources $rsync_server $tarballs_dir]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set tarfile [file tail $rsync_dir]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set include_options " --include=[macports::shellescape /${tarfile}] --include=[macports::shellescape /${tarfile}.rmd160] --exclude=*"
</span>     # create the path to the to be downloaded sources if it doesn't exist
     if {![file exists $mp_source_path]} {
         file mkdir $mp_source_path
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -79,84 +321,194 @@ proc selfupdate::main {{options {}} {updatestatusvar {}}} {
</span>         error "Error synchronizing MacPorts sources: $eMessage"
     }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    if {$is_tarball} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        # verify signature for tarball
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        global macports::archivefetch_pubkeys macports::hfscompression \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-               macports::autoconf::openssl_path
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set openssl [macports::findBinary openssl $openssl_path]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set tarball ${mp_source_path}/${tarfile}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set signature ${tarball}.rmd160
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set verified 0
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        foreach pubkey $archivefetch_pubkeys {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            macports_try -pass_signal {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                exec $openssl dgst -ripemd160 -verify $pubkey -signature $signature $tarball
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                set verified 1
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                ui_debug "successful verification with key $pubkey"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                break
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            } on error {eMessage} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                ui_debug "failed verification with key $pubkey"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                ui_debug "openssl output: $eMessage"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        if {!$verified} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            return -code error "Failed to verify signature for MacPorts source!"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # verify signature for tarball
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set tarball ${mp_source_path}/${tarfile}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set signature ${tarball}.rmd160
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    selfupdate::verify_signature_legacy $tarball $signature
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        if {${hfscompression} && [getuid] == 0 &&
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                ![catch {macports::binaryInPath bsdtar}] &&
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                ![catch {exec bsdtar -x --hfsCompression < /dev/null >& /dev/null}]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            ui_debug "Using bsdtar with HFS+ compression (if valid)"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set tar "bsdtar --hfsCompression"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            global macports::autoconf::tar_path
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set tar [macports::findBinary tar $tar_path]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {${hfscompression} && [getuid] == 0 &&
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ![catch {macports::binaryInPath bsdtar}] &&
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ![catch {exec bsdtar -x --hfsCompression < /dev/null >& /dev/null}]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_debug "Using bsdtar with HFS+ compression (if valid)"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set tar "bsdtar --hfsCompression"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        global macports::autoconf::tar_path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set tar [macports::findBinary tar $tar_path]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # extract tarball and move into place
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    file mkdir ${mp_source_path}/tmp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set tar_cmd "$tar -C [macports::shellescape ${mp_source_path}/tmp] -xf [macports::shellescape $tarball]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    macports_try -pass_signal {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        system $tar_cmd
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } on error {} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        error "Failed to extract MacPorts sources from tarball!"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    file delete -force ${mp_source_path}/base
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    file rename ${mp_source_path}/tmp/base ${mp_source_path}/base
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    file delete -force ${mp_source_path}/tmp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # set the final extracted source path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return ${mp_source_path}/base
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Verify the given file \a path against the signify(1) signature in \a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# signature_path.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# If the signature is valid and matches one of the macports public keys, return
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# success. Otherwise, raise an error.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# @param path The path of the file to verify
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# @param signature_path The path of the detached signature file
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# @return nothing on success, an error if the signature could not be verified
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc selfupdate::verify_signature {path signature_path} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set verified 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    foreach pubkey [glob -nocomplain -tails -directory $macports::autoconf::macports_keys_base *.pub] {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports_try -pass_signal {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set command [list \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                $macports::autoconf::signify_path -V \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                -p [file join $macports::autoconf::macports_keys_base $pubkey] \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                -x $signature_path \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                -m $path]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_debug "Invoking ${command} to verify signature"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            exec {*}$command
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set verified 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_debug "$path successfully verified with public key $pubkey"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            break
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        } on error {eMessage} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_debug "$path failed to verify with public key $pubkey"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_debug "signify output: $eMessage"
</span>         }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        # extract tarball and move into place
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        file mkdir ${mp_source_path}/tmp
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set tar_cmd "$tar -C [macports::shellescape ${mp_source_path}/tmp] -xf [macports::shellescape $tarball]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {!$verified} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        error "Failed to verify signature"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# verify legacy .rmd160 signature
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc selfupdate::verify_signature_legacy {path signature_path} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global macports::archivefetch_pubkeys \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports::autoconf::openssl_path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set openssl [macports::findBinary openssl $openssl_path]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set verified 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    foreach pubkey $archivefetch_pubkeys {
</span>         macports_try -pass_signal {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            system $tar_cmd
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        } on error {} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            error "Failed to extract MacPorts sources from tarball!"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            exec $openssl dgst -ripemd160 -verify $pubkey -signature $signature_path $path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set verified 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_debug "successful verification with key $pubkey"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            break
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        } on error {eMessage} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_debug "failed verification with key $pubkey"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_debug "openssl output: $eMessage"
</span>         }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        file delete -force ${mp_source_path}/base
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        file rename ${mp_source_path}/tmp/base ${mp_source_path}/base
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        file delete -force ${mp_source_path}/tmp
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        # set the final extracted source path
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set mp_source_path ${mp_source_path}/base
</span>     }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {!$verified} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        error "Failed to verify signature for MacPorts source!"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    # echo current MacPorts version
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    ui_msg "MacPorts base version $macports_version installed,"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Install a new MacPorts version from the given \a source code path.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# @param source Path to the source code to be installed.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc selfupdate::install {source} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports::developer_dir \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports::macos_version_major \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports::os_major \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports::prefix \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports::ui_prefix \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        macports::os_platform \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        tcl_platform
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    if {[dict exists $options ports_force] && [dict get $options ports_force]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set use_the_force_luke yes
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        ui_debug "Forcing a rebuild and reinstallation of MacPorts"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set use_the_force_luke no
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        ui_debug "Rebuilding and reinstalling MacPorts if needed"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # get installation user/group and permissions
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set owner [file attributes $prefix -owner]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set group [file attributes $prefix -group]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set perms [string range [file attributes $prefix -permissions] end-3 end]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {$tcl_platform(user) ne "root" && $tcl_platform(user) ne $owner} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        error "User $tcl_platform(user) does not own $prefix - try using sudo"
</span>     }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    ui_debug "Permissions OK"
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    # Choose what version file to use: old, floating point format or new, real version number format
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    set version_file [file join $mp_source_path config macports_version]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    if {[file exists $version_file]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set fd [open $version_file r]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        gets $fd macports_version_new
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        close $fd
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        # echo downloaded MacPorts version
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        ui_msg "MacPorts base version $macports_version_new downloaded."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set configure_args [list \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        --prefix=$prefix \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        --with-install-user=$owner \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        --with-install-group=$group \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        --with-directory-mode=$perms]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # too many users have an incompatible readline in /usr/local, see ticket #10651
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {$os_platform ne "darwin" || $prefix eq "/usr/local"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        || ([glob -nocomplain /usr/local/lib/lib{readline,history}*] eq "" && [glob -nocomplain /usr/local/include/readline/*.h] eq "")} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        lappend configure_args --enable-readline
</span>     } else {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        ui_warn "No version file found, please rerun selfupdate."
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set macports_version_new 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_warn "Disabling readline support due to readline in /usr/local"
</span>     }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    # check if we we need to rebuild base
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    set comp [vercmp $macports_version_new $macports_version]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {$prefix eq "/usr/local" || $prefix eq "/usr"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        lappend configure_args --with-unsupported-prefix
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set configure_args_string [join [lmap arg $configure_args {macports::shellescape $arg}]]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # Choose a sane compiler and SDK
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set cc_arg {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set sdk_arg {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set jobs [macports::get_parallel_jobs yes]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {$os_platform eq "darwin"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        catch {exec /usr/bin/cc 2>@1} output
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set output [join [lrange [split $output "\n"] 0 end-1] "\n"]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {[string match -nocase *license* $output]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_error "It seems you have not accepted the Xcode license; unable to build."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_error "Agree to the license by opening Xcode or running `sudo xcodebuild -license'."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            return -code error "Xcode license acceptance required"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set cc_arg "CC=/usr/bin/cc "
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {$os_major >= 18 || ![file exists /usr/include/sys/cdefs.h]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set cltpath /Library/Developer/CommandLineTools
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set sdk_version $macos_version_major
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set check_dirs [list ${cltpath}/SDKs \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                ${developer_dir}/Platforms/MacOSX.platform/Developer/SDKs \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                ${developer_dir}/SDKs]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            foreach check_dir $check_dirs {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set sdk ${check_dir}/MacOSX${sdk_version}.sdk
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                if {[file exists $sdk]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    set sdk_arg "SDKROOT=[macports::shellescape ${sdk}] "
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    break
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                } elseif {$os_major >= 20} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    set matches [glob -nocomplain -directory ${check_dir} MacOSX${sdk_version}*.sdk]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    if {[llength $matches] > 1} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        set matches [lsort -decreasing -command vercmp $matches]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    if {[llength $matches] > 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        set sdk_arg "SDKROOT=[macports::shellescape [lindex $matches 0]] "
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        break
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # do the actual configure, build and installation of new base
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    ui_msg "$ui_prefix Installing new MacPorts release in $prefix as ${owner}:${group}; permissions ${perms}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    macports_try -pass_signal {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        system -W $source "${cc_arg}${sdk_arg}./configure $configure_args_string && ${sdk_arg}make -j${jobs} SELFUPDATING=1 && make install SELFUPDATING=1"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } on error {eMessage} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        error "Error installing new MacPorts base: $eMessage"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    # syncing ports tree.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc selfupdate::cleanup_sources {mp_source_path} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global macports::portdbpath macports::rsync_server
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    file delete -force $mp_source_path [file join $portdbpath sources $rsync_server]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc selfupdate::do_sync {options presync} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set needed_portindex 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set synced 0
</span>     if {![dict exists $options ports_selfupdate_no-sync] || ![dict get $options ports_selfupdate_no-sync]} {
         set syncoptions $options
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        if {$comp > 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {$presync} {
</span>             # updated portfiles potentially need new base to parse - tell sync to try to
             # use prefabricated PortIndex files and signal if it couldn't
             dict set syncoptions no_reindex 1
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -167,6 +519,52 @@ proc selfupdate::main {{options {}} {updatestatusvar {}}} {
</span>         } on error {eMessage} {
             error "Couldn't sync the ports tree: $eMessage"
         }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+        set synced 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return [list $synced $needed_portindex]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc selfupdate::main {{options {}} {updatestatusvar {}}} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global   \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            macports::autoconf::macports_version \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            macports::portdbpath \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            macports::ui_prefix
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # variable that indicates whether we actually updated base
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {$updatestatusvar ne ""} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        upvar $updatestatusvar updatestatus
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set updatestatus no
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set mp_source_path [file join $portdbpath sources selfupdate]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set rsync_fetched 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    macports_try -pass_signal {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set macports_version_new [get_current_version $mp_source_path]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } on error {eMessage} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_debug "get_current_version failed: $eMessage"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set source_code [download_source_rsync]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set macports_version_new [get_current_version_from_sources $source_code]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set rsync_fetched 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # Print current MacPorts version
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    ui_msg "MacPorts base version $macports_version installed,"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    ui_msg "MacPorts base version $macports_version_new available."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # check if we we need to rebuild base
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set comp [vercmp $macports_version_new $macports_version]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {[dict exists $options ports_force] && [dict get $options ports_force]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set use_the_force_luke yes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_debug "Forcing a rebuild and reinstallation of MacPorts"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set use_the_force_luke no
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_debug "Rebuilding and reinstalling MacPorts if needed"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # pre-syncing ports tree if needed (batch, shell modes)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {$comp > 0 && [dict exists $options ports_selfupdate_presync] && [dict get $options ports_selfupdate_presync]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        lassign [do_sync $options 1] synced need_reindex
</span>     }
 
     # Check whether we need to re-install base because of a migration
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -178,80 +576,28 @@ proc selfupdate::main {{options {}} {updatestatusvar {}}} {
</span>         } else {
             ui_msg "$ui_prefix MacPorts base is outdated, installing new version $macports_version_new"
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            global macports::developer_dir macports::macos_version_major \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   macports::os_major macports::os_platform macports::prefix \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                   tcl_platform
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            # get installation user/group and permissions
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set owner [file attributes $prefix -owner]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set group [file attributes $prefix -group]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set perms [string range [file attributes $prefix -permissions] end-3 end]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {$tcl_platform(user) ne "root" && $tcl_platform(user) ne $owner} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                return -code error "User $tcl_platform(user) does not own $prefix - try using sudo"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            ui_debug "Permissions OK"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set configure_args "--prefix=[macports::shellescape $prefix] --with-install-user=[macports::shellescape $owner] --with-install-group=[macports::shellescape $group] --with-directory-mode=[macports::shellescape $perms]"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            # too many users have an incompatible readline in /usr/local, see ticket #10651
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {$os_platform ne "darwin" || $prefix eq "/usr/local"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                || ([glob -nocomplain /usr/local/lib/lib{readline,history}*] eq "" && [glob -nocomplain /usr/local/include/readline/*.h] eq "")} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                append configure_args " --enable-readline"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                ui_warn "Disabling readline support due to readline in /usr/local"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {$prefix eq "/usr/local" || $prefix eq "/usr"} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                append configure_args " --with-unsupported-prefix"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            # Choose a sane compiler and SDK
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set cc_arg {}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set sdk_arg {}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set jobs [macports::get_parallel_jobs yes]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {$os_platform eq "darwin"} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                catch {exec /usr/bin/cc 2>@1} output
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                set output [join [lrange [split $output "\n"] 0 end-1] "\n"]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                if {[string match -nocase *license* $output]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    ui_error "It seems you have not accepted the Xcode license; unable to build."
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    ui_error "Agree to the license by opening Xcode or running `sudo xcodebuild -license'."
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    return -code error "Xcode license acceptance required"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                set cc_arg "CC=/usr/bin/cc "
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                if {$os_major >= 18 || ![file exists /usr/include/sys/cdefs.h]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    set cltpath /Library/Developer/CommandLineTools
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    set sdk_version $macos_version_major
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    set check_dirs [list ${cltpath}/SDKs \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        ${developer_dir}/Platforms/MacOSX.platform/Developer/SDKs \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        ${developer_dir}/SDKs]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    foreach check_dir $check_dirs {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        set sdk ${check_dir}/MacOSX${sdk_version}.sdk
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        if {[file exists $sdk]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                            set sdk_arg "SDKROOT=[macports::shellescape ${sdk}] "
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                            break
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        } elseif {$os_major >= 20} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                            set matches [glob -nocomplain -directory ${check_dir} MacOSX${sdk_version}*.sdk]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                            if {[llength $matches] > 1} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                                set matches [lsort -decreasing -command vercmp $matches]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                            }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                            if {[llength $matches] > 0} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                                set sdk_arg "SDKROOT=[macports::shellescape [lindex $matches 0]] "
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                                break
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                            }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {!$rsync_fetched} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                macports_try -pass_signal {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    set source_code [download_source $mp_source_path $macports_version_new]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                } on error {} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    ui_debug "download_source failed: $eMessage"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    set source_code [download_source_rsync]
</span>                 }
             }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+            install $source_code
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            # do the actual configure, build and installation of new base
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            ui_msg "Installing new MacPorts release in $prefix as ${owner}:${group}; permissions ${perms}\n"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            try {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                system -W $mp_source_path "${cc_arg}${sdk_arg}./configure $configure_args && ${sdk_arg}make -j${jobs} SELFUPDATING=1 && make install SELFUPDATING=1"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            } on error {eMessage} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                error "Error installing new MacPorts base: $eMessage"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            }
</span>             if {[info exists updatestatus]} {
                 set updatestatus yes
             }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[info exists need_reindex] && $need_reindex} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                ui_msg "Not all sources could be fully synced using the old version of MacPorts."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                ui_msg "Please run selfupdate again now that MacPorts base has been updated."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            cleanup_sources $mp_source_path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # Return here, port.tcl will re-execute selfupdate with the updated
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # base to trigger sync and portindex with the new version
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            return 0
</span>         }
     } elseif {$comp < 0} {
         ui_msg "$ui_prefix MacPorts base is probably master or a release candidate"
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -259,23 +605,10 @@ proc selfupdate::main {{options {}} {updatestatusvar {}}} {
</span>         ui_msg "$ui_prefix MacPorts base is already the latest version"
     }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    # set the MacPorts sources to the right owner
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    set sources_owner [file attributes [file join $portdbpath sources/] -owner]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    ui_debug "Setting MacPorts sources ownership to $sources_owner"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    try {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        exec [macports::findBinary chown $macports::autoconf::chown_path] -R $sources_owner [file join $portdbpath sources/]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    } on error {eMessage} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        error "Couldn't change permissions of the MacPorts sources at $mp_source_path to ${sources_owner}: $eMessage"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    if {![dict exists $options ports_selfupdate_no-sync] || ![dict get $options ports_selfupdate_no-sync]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        if {[info exists needed_portindex]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            ui_msg "Not all sources could be fully synced using the old version of MacPorts."
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            ui_msg "Please run selfupdate again now that MacPorts base has been updated."
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            ui_msg "\nThe ports tree has been updated. To upgrade your installed ports, you should run"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            ui_msg "  port upgrade outdated"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    lassign [do_sync $options 0] synced
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {$synced} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_msg "\nThe ports tree has been updated. To upgrade your installed ports, you should run"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_msg "  port upgrade outdated"
</span>     }
 
     return 0
</pre><pre style='margin:0'>

</pre>