aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Percival <cperciva@FreeBSD.org>2023-04-23 01:07:14 +0000
committerColin Percival <cperciva@FreeBSD.org>2023-04-23 01:12:37 +0000
commitdf53ae0fdd98e9452095ac2fdaf95fcfac8c9c7f (patch)
tree61471b72c3aec1d08944cafac4605a0df000442e
parentfb30bb0d4d0ed3beb27116761ac0c941607e3906 (diff)
downloadsrc-df53ae0fdd98.tar.gz
src-df53ae0fdd98.zip
Remove portsnap(8)
Rather than having a tool in the FreeBSD base system for obtaining the FreeBSD ports tree, users are encouraged to `pkg install git` and then `git clone https://git.FreeBSD.org/ports.git /usr/ports`. The portsnap servers will continue operating until FreeBSD 13 reaches its End-of-Life, and portsnap is available from the ports tree as ports-mgmt/portsnap. Requested by: portmgr Relnotes: yes Differential Revision: https://reviews.freebsd.org/D39563 X-MFC: no
-rw-r--r--ObsoleteFiles.inc7
-rw-r--r--UPDATING4
-rw-r--r--libexec/Makefile2
-rw-r--r--share/examples/etc/README.examples5
-rw-r--r--share/man/man5/Makefile3
-rw-r--r--share/man/man5/portsnap.conf.5147
-rw-r--r--share/man/man5/src.conf.54
-rw-r--r--share/mk/src.opts.mk1
-rw-r--r--targets/pseudo/userland/Makefile.depend3
-rw-r--r--tools/build/mk/OptionalObsoleteFiles.inc10
-rw-r--r--tools/build/options/WITHOUT_PORTSNAP4
-rw-r--r--usr.sbin/Makefile1
-rw-r--r--usr.sbin/portsnap/Makefile5
-rw-r--r--usr.sbin/portsnap/Makefile.inc5
-rw-r--r--usr.sbin/portsnap/make_index/Makefile8
-rw-r--r--usr.sbin/portsnap/make_index/Makefile.depend16
-rw-r--r--usr.sbin/portsnap/make_index/make_index.c515
-rw-r--r--usr.sbin/portsnap/portsnap/Makefile7
-rw-r--r--usr.sbin/portsnap/portsnap/Makefile.depend11
-rw-r--r--usr.sbin/portsnap/portsnap/portsnap.8288
-rw-r--r--usr.sbin/portsnap/portsnap/portsnap.conf36
-rw-r--r--usr.sbin/portsnap/portsnap/portsnap.sh1156
22 files changed, 16 insertions, 2222 deletions
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index 3b3141d15629..6e7c5205a2bf 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -52,6 +52,13 @@
# xargs -n1 | sort | uniq -d;
# done
+# 20230420: portsnap.8 removed
+OLD_FILES+=etc/portsnap.conf
+OLD_FILES+=usr/libexec/make_index
+OLD_FILES+=usr/sbin/portsnap
+OLD_FILES+=usr/share/examples/etc/portsnap.conf
+OLD_FILES+=usr/share/man/man8/portsnap.8.gz
+
# 20230331: libpcap updated to 1.10.3
OLD_FILES+=usr/include/fmtutils.h
diff --git a/UPDATING b/UPDATING
index 70e5a58352af..17d80334c794 100644
--- a/UPDATING
+++ b/UPDATING
@@ -27,6 +27,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 14.x IS SLOW:
world, or to merely disable the most expensive debugging functionality
at runtime, run "ln -s 'abort:false,junk:false' /etc/malloc.conf".)
+20230422:
+ Remove portsnap(8). Users are encouraged to obtain the ports tree
+ using git instead.
+
20230420:
Add jobs.mk to save typing. Enables -j${JOB_MAX} and logging
eg.
diff --git a/libexec/Makefile b/libexec/Makefile
index 057bad07de5b..a890115fd15a 100644
--- a/libexec/Makefile
+++ b/libexec/Makefile
@@ -49,7 +49,7 @@ SUBDIR+= bootpd
SUBDIR+= fingerd
.endif
-.if ${MK_FREEBSD_UPDATE} != "no" || ${MK_PORTSNAP} != "no"
+.if ${MK_FREEBSD_UPDATE} != "no"
_phttpget= phttpget
.endif
diff --git a/share/examples/etc/README.examples b/share/examples/etc/README.examples
index 3d284f31fdea..606b2b40d60c 100644
--- a/share/examples/etc/README.examples
+++ b/share/examples/etc/README.examples
@@ -44,12 +44,11 @@ nsmb.conf - smbfs lookups configuration file
pf.conf - pf(4) example configuration file
pf.os - SYN fingerprint database
phones - phone number database for tip(1)
-portsnap.conf - portsnap(8) configuration file
printcap - configuration file for lpr(1)
profile - system-wide .profile for sh(1)
protocols - see protocols(5)
rc - system startup script (see init(8))
-rc.bsdextended - startup policy for the mac_bsdextended(4) security module.
+rc.bsdextended - startup policy for the mac_bsdextended(4) security module.
rc.firewall - ipfw(8) setup script with basic rulesets
rc.initdiskless - configuration file to boot a diskless machine
rc.resume - sample run command file for APM Resume Event
@@ -65,7 +64,7 @@ snmpd.config - example configuration file for bsnmpd(1)
sysctl.conf - configuration file for sysctl(8)
syslog.conf - configuration file for syslogd(8)
ttys - defines port configuration for init(8)
-defaults/bluetooth.device.conf -
+defaults/bluetooth.device.conf -
defaults/devfs.rules - default configuration rules for devfs(8)
defaults/periodic.conf - default configuration file for periodic(8)
defaults/rc.conf - default system configuration info (see rc.conf(5))
diff --git a/share/man/man5/Makefile b/share/man/man5/Makefile
index f6e91e4ed00b..731c79fe0f97 100644
--- a/share/man/man5/Makefile
+++ b/share/man/man5/Makefile
@@ -53,7 +53,6 @@ MAN= acct.5 \
periodic.conf.5 \
phones.5 \
portindex.5 \
- portsnap.conf.5 \
procfs.5 \
protocols.5 \
quota.user.5 \
@@ -103,7 +102,7 @@ MAN+= freebsd-update.conf.5
.endif
.if ${MK_HESIOD} != "no"
-MAN+= hesiod.conf.5
+MAN+= hesiod.conf.5
.endif
.if ${MK_PF} != "no"
diff --git a/share/man/man5/portsnap.conf.5 b/share/man/man5/portsnap.conf.5
deleted file mode 100644
index cef4c24815bf..000000000000
--- a/share/man/man5/portsnap.conf.5
+++ /dev/null
@@ -1,147 +0,0 @@
-.\"-
-.\" Copyright 2004-2005 Colin Percival
-.\" All rights reserved
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted providing that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-.\" POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd January 30, 2005
-.Dt PORTSNAP.CONF 5
-.Os FreeBSD
-.Sh NAME
-.Nm portsnap.conf
-.Nd configuration file for
-.Xr portsnap 8
-.Sh DESCRIPTION
-The
-.Nm
-file controls where
-.Xr portsnap 8
-fetches ports tree snapshots from,
-which RSA key should be trusted to sign the updates, and what
-directories should hold the compressed and live ports trees.
-.Pp
-A line of the form
-.Dl SERVERNAME=portsnap.example.com
-specifies the source from which snapshots should be fetched.
-This is equivalent to the
-.Fl s Ar server
-option to
-.Xr portsnap 8 ,
-and will be ignored if the command-line
-option is used.
-.Pp
-A line of the form
-.Dl KEYPRINT=0123456789abc ... 456789abcdef
-(64 characters in total)
-specifies the SHA-256 hash of the OpenSSL public key file
-belonging to an RSA keypair which is trusted to sign updates.
-This is equivalent to the
-.Fl k Ar KEY
-option to
-.Xr portsnap 8 ,
-and will be ignored if the command-line
-option is used.
-.Pp
-A line of the form
-.Dl WORKDIR=/path/to/workdir
-specifies the directory in which portsnap should maintain its compressed
-snapshot of the ports tree.
-This is equivalent to the
-.Fl d Ar workdir
-option to
-.Xr portsnap 8 ,
-and will be ignored if the command-line option
-is used.
-.Pp
-A line of the form
-.Dl PORTSDIR=/path/to/portstree
-specifies the directory in which portsnap will create the live ports
-tree from its compressed snapshot via the
-.Cm extract
-and
-.Cm update
-commands.
-This is equivalent to the
-.Fl p Ar portsdir
-option to
-.Xr portsnap 8 ,
-and will be ignored if the command-line option
-is used.
-.Pp
-If more than one line of any of the above forms is included in
-.Nm
-then only the last one will take effect.
-.Pp
-A line of the form
-.Dl INDEX INDEXFILE DESCRIBEFILE
-will instruct
-.Xr portsnap 8
-that the specified INDEX file is generated from the specified
-describe file distributed by the portsnap server.
-.Pp
-Finally, a line of the form
-.Dl REFUSE foo bar
-will instruct
-.Xr portsnap 8
-to ignore parts of the ports tree with paths starting with
-.Ar foo
-or
-.Ar bar ,
-which are interpreted as extended regular expressions by
-.Xr egrep 1 .
-This will result in those parts of the tree not being updated
-in the compressed snapshot when the
-.Cm fetch
-and
-.Cm cron
-commands are used and not being extracted when the
-.Cm extract
-command is used (unless a specific
-.Ar path
-is passed to
-.Xr portsnap 8 ) ,
-and if those parts of the ports tree are present they
-will not be updated when the
-.Cm update
-command is used.
-Unlike the other options, the parameters in REFUSE lines
-accumulate and all such lines are considered.
-.Bf Em
-Note that operating with an incomplete ports tree is not
-supported and may cause unexpected results.
-.Ef
-.Pp
-Any lines not of the above forms will be ignored.
-.Sh FILES
-.Bl -tag -width "/etc/portsnap.conf"
-.It Pa /etc/portsnap.conf
-Default location of the portsnap configuration file.
-.El
-.Sh SEE ALSO
-.Xr egrep 1 ,
-.Xr fetch 1 ,
-.Xr sha256 1 ,
-.Xr portsnap 8
-.Sh AUTHORS
-.An Colin Percival Aq Mt cperciva@FreeBSD.org
diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5
index 9029732f0fe8..8cabfb16462b 100644
--- a/share/man/man5/src.conf.5
+++ b/share/man/man5/src.conf.5
@@ -1437,10 +1437,6 @@ bootstrap tool.
Do not build
.Xr pmccontrol 8
and related programs.
-.It Va WITHOUT_PORTSNAP
-Do not build or install
-.Xr portsnap 8
-and related files.
.It Va WITHOUT_PPP
Do not build
.Xr ppp 8
diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk
index d6f6650effd5..8f56f757b60b 100644
--- a/share/mk/src.opts.mk
+++ b/share/mk/src.opts.mk
@@ -155,7 +155,6 @@ __DEFAULT_YES_OPTIONS = \
PF \
PKGBOOTSTRAP \
PMC \
- PORTSNAP \
PPP \
QUOTAS \
RADIUS_SUPPORT \
diff --git a/targets/pseudo/userland/Makefile.depend b/targets/pseudo/userland/Makefile.depend
index 19e3d754cffa..b933b54dd26c 100644
--- a/targets/pseudo/userland/Makefile.depend
+++ b/targets/pseudo/userland/Makefile.depend
@@ -645,9 +645,6 @@ DIRDEPS+= \
usr.sbin/pmccontrol \
usr.sbin/pmcstat \
usr.sbin/pmcstudy \
- usr.sbin/portsnap/make_index \
- usr.sbin/portsnap/phttpget \
- usr.sbin/portsnap/portsnap \
usr.sbin/powerd \
usr.sbin/ppp \
usr.sbin/pppctl \
diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc
index 0d19eab23c8e..9c7e40ee563a 100644
--- a/tools/build/mk/OptionalObsoleteFiles.inc
+++ b/tools/build/mk/OptionalObsoleteFiles.inc
@@ -2025,7 +2025,7 @@ OLD_FILES+=usr/share/man/man5/freebsd-update.conf.5.gz
OLD_FILES+=usr/share/man/man8/freebsd-update.8.gz
.endif
-.if ${MK_FREEBSD_UPDATE} == no && ${MK_PORTSNAP} == no
+.if ${MK_FREEBSD_UPDATE} == no
OLD_FILES+=usr/libexec/phttpget
OLD_FILES+=usr/share/man/man8/phttpget.8.gz
.endif
@@ -6843,14 +6843,6 @@ OLD_FILES+=usr/share/man/man8/pmcstat.8.gz
OLD_FILES+=usr/share/man/man8/pmcstudy.8.gz
.endif
-.if ${MK_PORTSNAP} == no
-OLD_FILES+=etc/portsnap.conf
-OLD_FILES+=usr/libexec/make_index
-OLD_FILES+=usr/sbin/portsnap
-OLD_FILES+=usr/share/examples/etc/portsnap.conf
-OLD_FILES+=usr/share/man/man8/portsnap.8.gz
-.endif
-
.if ${MK_PPP} == no
OLD_FILES+=etc/newsyslog.conf.d/ppp.conf
OLD_FILES+=etc/ppp/ppp.conf
diff --git a/tools/build/options/WITHOUT_PORTSNAP b/tools/build/options/WITHOUT_PORTSNAP
deleted file mode 100644
index 8b023fd65251..000000000000
--- a/tools/build/options/WITHOUT_PORTSNAP
+++ /dev/null
@@ -1,4 +0,0 @@
-.\" $FreeBSD$
-Do not build or install
-.Xr portsnap 8
-and related files.
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile
index e2f382303d6e..9fa1dc05a1cc 100644
--- a/usr.sbin/Makefile
+++ b/usr.sbin/Makefile
@@ -187,7 +187,6 @@ SUBDIR.${MK_OPENSSL_KTLS}+= rpc.tlsservd
SUBDIR.${MK_PF}+= ftp-proxy
SUBDIR.${MK_PKGBOOTSTRAP}+= pkg
SUBDIR.${MK_PMC}+= pmc pmcannotate pmccontrol pmcstat pmcstudy
-SUBDIR.${MK_PORTSNAP}+= portsnap
SUBDIR.${MK_PPP}+= ppp
SUBDIR.${MK_QUOTAS}+= edquota
SUBDIR.${MK_QUOTAS}+= quotaon
diff --git a/usr.sbin/portsnap/Makefile b/usr.sbin/portsnap/Makefile
deleted file mode 100644
index 169befd6e726..000000000000
--- a/usr.sbin/portsnap/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-# $FreeBSD$
-
-SUBDIR= portsnap make_index
-
-.include <bsd.subdir.mk>
diff --git a/usr.sbin/portsnap/Makefile.inc b/usr.sbin/portsnap/Makefile.inc
deleted file mode 100644
index 5f6527edb373..000000000000
--- a/usr.sbin/portsnap/Makefile.inc
+++ /dev/null
@@ -1,5 +0,0 @@
-# $FreeBSD$
-
-LIBEXECDIR?= /usr/libexec
-
-.include "../Makefile.inc"
diff --git a/usr.sbin/portsnap/make_index/Makefile b/usr.sbin/portsnap/make_index/Makefile
deleted file mode 100644
index 92e91450e4fd..000000000000
--- a/usr.sbin/portsnap/make_index/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# $FreeBSD$
-
-PROG= make_index
-MAN=
-
-BINDIR= ${LIBEXECDIR}
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/portsnap/make_index/Makefile.depend b/usr.sbin/portsnap/make_index/Makefile.depend
deleted file mode 100644
index 8d409f5263ac..000000000000
--- a/usr.sbin/portsnap/make_index/Makefile.depend
+++ /dev/null
@@ -1,16 +0,0 @@
-# $FreeBSD$
-# Autogenerated - do NOT edit!
-
-DIRDEPS = \
- include \
- include/xlocale \
- lib/${CSU_DIR} \
- lib/libc \
- lib/libcompiler_rt \
-
-
-.include <dirdeps.mk>
-
-.if ${DEP_RELDIR} == ${_DEP_RELDIR}
-# local dependencies - needed for -jN in clean tree
-.endif
diff --git a/usr.sbin/portsnap/make_index/make_index.c b/usr.sbin/portsnap/make_index/make_index.c
deleted file mode 100644
index 642404b63605..000000000000
--- a/usr.sbin/portsnap/make_index/make_index.c
+++ /dev/null
@@ -1,515 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright 2005 Colin Percival
- * All rights reserved
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted providing that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <err.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-struct port;
-
-typedef union {
- char * name;
- struct port * p;
-} DEP;
-
-typedef struct port {
- char * pkgname;
- char * portdir;
- char * prefix;
- char * comment;
- char * pkgdescr;
- char * maintainer;
- char * categories;
- size_t n_edep;
- DEP * edep;
- size_t n_pdep;
- DEP * pdep;
- size_t n_fdep;
- DEP * fdep;
- size_t n_bdep;
- DEP * bdep;
- size_t n_rdep;
- DEP * rdep;
- char * www;
- int recursed;
-} PORT;
-
-static void usage(void);
-static char * strdup2(const char *str);
-static DEP * makelist(char * str, size_t * n);
-static PORT * portify(char * line);
-static int portcompare(char * a, char * b);
-static void heapifyports(PORT **pp, size_t size, size_t pos);
-static PORT * findport(PORT ** pp, size_t st, size_t en, char * name, char * from);
-static void translateport(PORT ** pp, size_t pplen, PORT * p);
-static DEP * recurse_one(DEP * d, size_t * nd);
-static void recurse(PORT * p);
-static void heapifypkgs(DEP * d, size_t size, size_t pos);
-static void sortpkgs(DEP * d, size_t nd);
-static void printport(PORT * p);
-
-static void
-usage(void)
-{
-
- fprintf(stderr, "usage: make_index file\n");
- exit(1);
- /* NOTREACHED */
-}
-
-static char *
-strdup2(const char *str)
-{
- char * r;
-
- r = strdup(str);
- if (r == NULL)
- err(1, "strdup");
- return r;
-}
-
-/* Take a space-separated list and return an array of (char *) */
-static DEP *
-makelist(char * str, size_t * n)
-{
- DEP * d;
- size_t i;
-
- /* No depends at all? */
- if (str[0] == 0) {
- *n = 0;
- return NULL;
- }
-
- /* Count the number of fields */
- *n = 1;
- for (i = 0; str[i] != 0; i++)
- if (str[i] == ' ')
- (*n)++;
-
- /* Allocate and fill an array */
- d = malloc(*n * sizeof(DEP));
- if (d == NULL)
- err(1, "malloc(DEP)");
- for (i = 0; i < *n; i++) {
- d[i].name = strdup2(strsep(&str, " "));
-
- /* Strip trailing slashes */
- if (d[i].name[strlen(d[i].name) - 1] == '/')
- d[i].name[strlen(d[i].name) - 1] = 0;
- }
-
- return d;
-}
-
-/* Take a port's describe line and split it into fields */
-static PORT *
-portify(char * line)
-{
- PORT * p;
- size_t i, n;
-
- /* Verify that line has the right number of fields */
- for (n = i = 0; line[i] != 0; i++)
- if (line[i] == '|')
- n++;
- if (n != 12)
- errx(1, "Port describe line is corrupt:\n%s\n", line);
-
- p = malloc(sizeof(PORT));
- if (p == NULL)
- err(1, "malloc(PORT)");
-
- p->pkgname = strdup2(strsep(&line, "|"));
- p->portdir = strdup2(strsep(&line, "|"));
- p->prefix = strdup2(strsep(&line, "|"));
- p->comment = strdup2(strsep(&line, "|"));
- p->pkgdescr = strdup2(strsep(&line, "|"));
- p->maintainer = strdup2(strsep(&line, "|"));
- p->categories = strdup2(strsep(&line, "|"));
- p->edep = makelist(strsep(&line, "|"), &p->n_edep);
- p->pdep = makelist(strsep(&line, "|"), &p->n_pdep);
- p->fdep = makelist(strsep(&line, "|"), &p->n_fdep);
- p->bdep = makelist(strsep(&line, "|"), &p->n_bdep);
- p->rdep = makelist(strsep(&line, "|"), &p->n_rdep);
- p->www = strdup2(strsep(&line, "|"));
-
- p->recursed = 0;
-
- /*
- * line will now be equal to NULL -- we counted the field
- * separators at the top of the function.
- */
-
- return p;
-}
-
-/* Returns -1, 0, or 1 based on a comparison of the portdir strings */
-static int
-portcompare(char * a, char * b)
-{
- size_t i;
-
- /* Find first non-matching position */
- for (i = 0; ; i++) {
- if (a[i] != b[i])
- break;
- if (a[i] == 0) /* End of strings */
- return 0;
- }
-
- /* One string is a prefix of the other */
- if (a[i] == 0)
- return -1;
- if (b[i] == 0)
- return 1;
-
- /* One string has a category which is a prefix of the other */
- if (a[i] == '/')
- return -1;
- if (b[i] == '/')
- return 1;
-
- /* The two strings are simply different */
- if (a[i] < b[i])
- return -1;
- else
- return 1;
-}
-
-/* Heapify (PORT *) number pos in a pseudo-heap pp[0]..pp[size - 1] */
-static void
-heapifyports(PORT **pp, size_t size, size_t pos)
-{
- size_t i = pos;
- PORT * tmp;
-
-top:
- /* Find the largest value out of {pos, 2*pos+1, 2*pos+2} */
- if ((2 * pos + 1 < size) &&
- (portcompare(pp[i]->portdir, pp[2 * pos + 1]->portdir) < 0))
- i = 2 * pos + 1;
- if ((2 * pos + 2 < size) &&
- (portcompare(pp[i]->portdir, pp[2 * pos + 2]->portdir) < 0))
- i = 2 * pos + 2;
-
- /* If necessary, swap elements and iterate down the tree. */
- if (i != pos) {
- tmp = pp[pos];
- pp[pos] = pp[i];
- pp[i] = tmp;
- pos = i;
- goto top;
- }
-}
-
-/* Translate a port directory name into a (PORT *), and free the name */
-static PORT *
-findport(PORT ** pp, size_t st, size_t en, char * name, char * from)
-{
- size_t mid;
- int r;
-
- if (st == en)
- errx(1, "%s: no entry for %s", from, name);
-
- mid = (st + en) / 2;
- r = portcompare(pp[mid]->portdir, name);
-
- if (r == 0) {
- free(name);
- return pp[mid];
- } else if (r < 0)
- return findport(pp, mid + 1, en, name, from);
- else
- return findport(pp, st, mid, name, from);
-}
-
-/* Translate all depends from names into PORT *s */
-static void
-translateport(PORT ** pp, size_t pplen, PORT * p)
-{
- size_t i;
-
- for (i = 0; i < p->n_edep; i++)
- p->edep[i].p = findport(pp, 0, pplen, p->edep[i].name, p->portdir);
- for (i = 0; i < p->n_pdep; i++)
- p->pdep[i].p = findport(pp, 0, pplen, p->pdep[i].name, p->portdir);
- for (i = 0; i < p->n_fdep; i++)
- p->fdep[i].p = findport(pp, 0, pplen, p->fdep[i].name, p->portdir);
- for (i = 0; i < p->n_bdep; i++)
- p->bdep[i].p = findport(pp, 0, pplen, p->bdep[i].name, p->portdir);
- for (i = 0; i < p->n_rdep; i++)
- p->rdep[i].p = findport(pp, 0, pplen, p->rdep[i].name, p->portdir);
-}
-
-/* Recurse on one specific depends list */
-static DEP *
-recurse_one(DEP * d, size_t * nd)
-{
- size_t i, j, k, n, N;
-
- N = n = *nd;
- for (i = 0; i < n; i++) {
- recurse(d[i].p);
- for (j = 0; j < d[i].p->n_rdep; j++) {
- for (k = 0; k < N; k++) {
- if (d[i].p->rdep[j].p == d[k].p)
- break;
- }
- if (k == N) {
- N++;
- if (N >= *nd) {
- *nd += *nd;
- d = realloc(d, *nd * sizeof(DEP));
- if (d == NULL)
- err(1, "realloc(d)");
- }
- d[k].p = d[i].p->rdep[j].p;
- }
- }
- }
- *nd = N;
-
- return d;
-}
-
-/* Recurse on the depends lists */
-static void
-recurse(PORT * p)
-{
- switch (p->recursed) {
- case 0:
- /* First time we've seen this port */
- p->recursed = 1;
- break;
- case 1:
- /* We're in the middle of recursing this port */
- errx(1, "Circular dependency loop found: %s"
- " depends upon itself.\n", p->pkgname);
- case 2:
- /* This port has already been recursed */
- return;
- }
-
- p->edep = recurse_one(p->edep, &p->n_edep);
- p->pdep = recurse_one(p->pdep, &p->n_pdep);
- p->fdep = recurse_one(p->fdep, &p->n_fdep);
- p->bdep = recurse_one(p->bdep, &p->n_bdep);
- p->rdep = recurse_one(p->rdep, &p->n_rdep);
-
- /* Finished recursing on this port */
- p->recursed = 2;
-}
-
-/* Heapify an element in a package list */
-static void
-heapifypkgs(DEP * d, size_t size, size_t pos)
-{
- size_t i = pos;
- PORT * tmp;
-
-top:
- /* Find the largest value out of {pos, 2*pos+1, 2*pos+2} */
- if ((2 * pos + 1 < size) &&
- (strcmp(d[i].p->pkgname, d[2 * pos + 1].p->pkgname) < 0))
- i = 2 * pos + 1;
- if ((2 * pos + 2 < size) &&
- (strcmp(d[i].p->pkgname, d[2 * pos + 2].p->pkgname) < 0))
- i = 2 * pos + 2;
-
- /* If necessary, swap elements and iterate down the tree. */
- if (i != pos) {
- tmp = d[pos].p;
- d[pos].p = d[i].p;
- d[i].p = tmp;
- pos = i;
- goto top;
- }
-}
-
-/* Sort a list of dependent packages in alphabetical order */
-static void
-sortpkgs(DEP * d, size_t nd)
-{
- size_t i;
- PORT * tmp;
-
- if (nd == 0)
- return;
-
- for (i = nd; i > 0; i--)
- heapifypkgs(d, nd, i - 1); /* Build a heap */
- for (i = nd - 1; i > 0; i--) {
- tmp = d[0].p; /* Extract elements */
- d[0].p = d[i].p;
- d[i].p = tmp;
- heapifypkgs(d, i, 0); /* And re-heapify */
- }
-}
-
-/* Output an index line for the given port. */
-static void
-printport(PORT * p)
-{
- size_t i;
-
- sortpkgs(p->edep, p->n_edep);
- sortpkgs(p->pdep, p->n_pdep);
- sortpkgs(p->fdep, p->n_fdep);
- sortpkgs(p->bdep, p->n_bdep);
- sortpkgs(p->rdep, p->n_rdep);
-
- printf("%s|%s|%s|%s|%s|%s|%s|",
- p->pkgname, p->portdir, p->prefix, p->comment, p->pkgdescr,
- p->maintainer, p->categories);
- for (i = 0; i < p->n_bdep; i++)
- printf("%s%s", i ? " " : "", p->bdep[i].p->pkgname);
- printf("|");
- for (i = 0; i < p->n_rdep; i++)
- printf("%s%s", i ? " " : "", p->rdep[i].p->pkgname);
- printf("|");
- printf("%s|", p->www);
- for (i = 0; i < p->n_edep; i++)
- printf("%s%s", i ? " " : "", p->edep[i].p->pkgname);
- printf("|");
- for (i = 0; i < p->n_pdep; i++)
- printf("%s%s", i ? " " : "", p->pdep[i].p->pkgname);
- printf("|");
- for (i = 0; i < p->n_fdep; i++)
- printf("%s%s", i ? " " : "", p->fdep[i].p->pkgname);
- printf("\n");
-}
-
-/*
- * Algorithm:
- * 1. Suck in all the data, splitting into fields.
- * 1a. If there are no ports, there is no INDEX.
- * 2. Sort the ports according to port directory.
- * 3. Using a binary search, translate each dependency from a
- * port directory name into a pointer to a port.
- * 4. Recursively follow dependencies, expanding the lists of
- * pointers as needed (using realloc).
- * 5. Iterate through the ports, printing them out (remembering
- * to list the dependent ports in alphabetical order).
- */
-
-int
-main(int argc, char *argv[])
-{
- FILE * f;
- char * line;
- size_t linelen;
- PORT ** pp; /* Array of pointers to PORTs */
- PORT * tmp;
- size_t pplen; /* Allocated size of array */
- size_t i;
-
- if (argc != 2)
- usage();
- if ((f = fopen(argv[1], "r")) == NULL)
- err(1, "fopen(%s)", argv[1]);
-
- pplen = 1024;
- if ((pp = malloc(pplen * sizeof(PORT *))) == NULL)
- err(1, "malloc(pp)");
-
- /*
- * 1. Suck in all the data, splitting into fields.
- */
- for(i = 0; (line = fgetln(f, &linelen)) != NULL; i++) {
- if (line[linelen - 1] != '\n')
- errx(1, "Unterminated line encountered");
- line[linelen - 1] = 0;
-
- /* Enlarge array if needed */
- if (i >= pplen) {
- pplen *= 2;
- if ((pp = realloc(pp, pplen * sizeof(PORT *))) == NULL)
- err(1, "realloc(pp)");
- }
-
- pp[i] = portify(line);
- }
- /* Reallocate to the correct size */
- pplen = i;
- if ((pp = realloc(pp, pplen * sizeof(PORT *))) == NULL)
- err(1, "realloc(pp)");
-
- /* Make sure we actually reached the EOF */
- if (!feof(f))
- err(1, "fgetln(%s)", argv[1]);
- /* Close the describes file */
- if (fclose(f) != 0)
- err(1, "fclose(%s)", argv[1]);
-
- /*
- * 1a. If there are no ports, there is no INDEX.
- */
- if (pplen == 0)
- return 0;
-
- /*
- * 2. Sort the ports according to port directory.
- */
- for (i = pplen; i > 0; i--)
- heapifyports(pp, pplen, i - 1); /* Build a heap */
- for (i = pplen - 1; i > 0; i--) {
- tmp = pp[0]; /* Extract elements */
- pp[0] = pp[i];
- pp[i] = tmp;
- heapifyports(pp, i, 0); /* And re-heapify */
- }
-
- /*
- * 3. Using a binary search, translate each dependency from a
- * port directory name into a pointer to a port.
- */
- for (i = 0; i < pplen; i++)
- translateport(pp, pplen, pp[i]);
-
- /*
- * 4. Recursively follow dependencies, expanding the lists of
- * pointers as needed (using realloc).
- */
- for (i = 0; i < pplen; i++)
- recurse(pp[i]);
-
- /*
- * 5. Iterate through the ports, printing them out (remembering
- * to list the dependent ports in alphabetical order).
- */
- for (i = 0; i < pplen; i++)
- printport(pp[i]);
-
- return 0;
-}
diff --git a/usr.sbin/portsnap/portsnap/Makefile b/usr.sbin/portsnap/portsnap/Makefile
deleted file mode 100644
index 6acd3f523751..000000000000
--- a/usr.sbin/portsnap/portsnap/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-# $FreeBSD$
-
-CONFS= portsnap.conf
-SCRIPTS=portsnap.sh
-MAN= portsnap.8
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/portsnap/portsnap/Makefile.depend b/usr.sbin/portsnap/portsnap/Makefile.depend
deleted file mode 100644
index f80275d86ab1..000000000000
--- a/usr.sbin/portsnap/portsnap/Makefile.depend
+++ /dev/null
@@ -1,11 +0,0 @@
-# $FreeBSD$
-# Autogenerated - do NOT edit!
-
-DIRDEPS = \
-
-
-.include <dirdeps.mk>
-
-.if ${DEP_RELDIR} == ${_DEP_RELDIR}
-# local dependencies - needed for -jN in clean tree
-.endif
diff --git a/usr.sbin/portsnap/portsnap/portsnap.8 b/usr.sbin/portsnap/portsnap/portsnap.8
deleted file mode 100644
index 6357fe0f9e8b..000000000000
--- a/usr.sbin/portsnap/portsnap/portsnap.8
+++ /dev/null
@@ -1,288 +0,0 @@
-.\"-
-.\" Copyright 2004-2005 Colin Percival
-.\" All rights reserved
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted providing that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-.\" POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd July 1, 2018
-.Dt PORTSNAP 8
-.Os FreeBSD
-.Sh NAME
-.Nm portsnap
-.Nd fetch and extract compressed snapshots of the ports tree
-.Sh SYNOPSIS
-.Nm
-.Op Fl I
-.Op Fl d Ar workdir
-.Op Fl f Ar conffile
-.Op Fl k Ar KEY
-.Op Fl l Ar descfile
-.Op Fl p Ar portsdir
-.Op Fl s Ar server
-.Cm command ...
-.Op Ar path
-.Sh DESCRIPTION
-The
-.Nm
-tool is used to fetch and update compressed snapshots
-of the
-.Fx
-ports tree, and extract and update an
-uncompressed ports tree.
-.Pp
-In a normal update operation,
-.Nm
-will routinely restore modified files to their unmodified state and
-delete unrecognized local files.
-.Sh OPTIONS
-The following options are supported:
-.Bl -tag -width "-f conffile"
-.It Fl d Ar workdir
-Store working files (e.g.\& downloaded updates) in
-.Ar workdir .
-(default:
-.Pa /var/db/portsnap ,
-or as given in the configuration file.)
-.It Fl f Ar conffile
-Read the configuration from
-.Ar conffile .
-(default:
-.Pa /etc/portsnap.conf )
-.It Fl I
-For the
-.Cm update
-command, update INDEX files, but not the rest of the ports tree.
-.It Fl k Ar KEY
-Expect a public key with given SHA256 hash.
-(default: read value from configuration file.)
-.It Fl l Ar descfile
-Merge the specified local describes file into the INDEX files being
-built.
-The
-.Ar descfile
-should be generated by running
-.Cm make describe
-in each of the local port directories.
-.It Fl p Ar portsdir
-When extracting or updating an uncompressed snapshot,
-operate on the directory
-.Ar portsdir .
-(default:
-.Pa /usr/ports/ ,
-or as given in the configuration file.)
-.It Fl s Ar server
-Fetch files from the specified server or server pool.
-(default: portsnap.FreeBSD.org, or as given in the
-configuration file.)
-.It path
-For
-.Cm extract
-command only, operate only on parts of the ports tree starting with
-.Ar path .
-(e.g.\&
-.Nm
-.Cm extract
-.Ar sysutils/port
-would extract sysutils/portsman, sysutils/portsnap,
-sysutils/portupgrade, etc.)
-.It Fl Fl interactive
-override auto-detection of calling process.
-Only use this when calling portsnap from an
-.Sy interactive, non-terminal application.
-(Cron jobs are particularly bad since they cause
-load spikes on the Portsnap mirrors.)
-.El
-.Sh COMMANDS
-The
-.Cm command
-can be any one of the following:
-.Bl -tag -width "-f conffile"
-.It fetch
-Fetch a compressed snapshot of the ports tree, or update
-the existing snapshot.
-This command should only be used interactively; for
-non-interactive use, you should use the
-.Cm cron
-command.
-.It cron
-Sleep a random amount of time between 1 and 3600 seconds,
-then operate as if the
-.Cm fetch
-command was specified.
-As the name suggests, this command is designed for running
-from
-.Xr cron 8 ;
-the random delay serves to minimize the probability that
-a large number of machines will simultaneously attempt to
-fetch updates.
-.It extract
-Extract a ports tree, replacing existing files and directories.
-NOTE: This will remove anything occupying the location where
-files or directories are being extracted; in particular, any
-changes made locally to the ports tree (for example, adding new
-patches) will be silently obliterated.
-.Pp
-Only run this command to initialize your portsnap-maintained
-ports tree for the first time, if you wish to start over with
-a clean, completely unmodified tree, or if you wish to extract
-a specific part of the tree (using the
-.Ar path
-option).
-.It update
-Update a ports tree extracted using the
-.Cm extract
-command.
-You must run this command to apply changes to your ports tree
-after downloading updates via the
-.Cm fetch
-or
-.Cm cron
-commands.
-Again, note that in the parts of the ports tree which are being
-updated, any local changes or additions will be removed.
-.It auto
-Run
-.Cm fetch
-or
-.Cm cron
-depending on whether stdin is a terminal; then run
-.Cm update
-or
-.Cm extract
-depending on whether
-.Ar portsdir
-exists.
-.El
-.Sh TIPS
-.Bl -bullet
-.It
-If your clock is set to local time, adding the line
-.Pp
-.Dl 0 3 * * * root /usr/sbin/portsnap cron
-.Pp
-to
-.Pa /etc/crontab
-is a good way to make sure you always have
-an up-to-date snapshot of the ports tree available which
-can quickly be extracted into
-.Pa /usr/ports .
-If your clock is set to UTC, please pick a random time other
-than 3AM, to avoid overly imposing an uneven load on the
-server(s) hosting the snapshots.
-.Pp
-Note that running
-.Nm
-.Cm cron
-or
-.Nm
-.Cm fetch
-does not apply the changes that were received: they only download
-them.
-To apply the changes, you must follow these commands with
-.Nm
-.Cm update .
-The
-.Nm
-.Cm update
-command is normally run by hand at a time when you are sure that
-no one is manually working in the ports tree.
-.It
-Running
-.Nm
-.Cm update
-from
-.Xr cron 8
-is a bad idea -- if you are ever installing or updating a
-port at the time the cron job runs, you will probably end up
-in a mess when
-.Nm
-updates or removes files which are being used by the port
-build.
-However, running
-.Nm
-.Fl I
-.Cm update
-is probably safe, and can be used together with
-.Xr pkg-version 8
-to identify installed software which is out of date.
-.It
-If you wish to use
-.Nm
-to keep a large number of machines up to date, you may wish
-to set up a caching HTTP proxy.
-Since
-.Nm
-uses
-.Xr fetch 1
-to download updates, setting the
-.Ev HTTP_PROXY
-environment variable will direct it to fetch updates from
-the given proxy.
-This is much more efficient than
-.Em mirroring
-the files on the portsnap server, since the vast majority
-of files are not needed by any particular client.
-.El
-.Sh PRIVACY NOTICE
-As an unavoidable part of its operation, a machine running
-.Nm
-will make its public IP address and the list of files it fetches
-available to the server from which it fetches updates.
-Using these it may be possible to recognize a machine over an extended
-period of time, determine when it is updated, and identify which
-portions of the FreeBSD ports tree, if any, are being ignored using
-"REFUSE" directives in
-.Pa portsnap.conf .
-In addition, the FreeBSD release level is transmitted to the server.
-.Pp
-Statistical data generated from information collected in this manner
-may be published, but only in aggregate and after anonymizing the
-individual systems.
-.Sh FILES
-.Bl -tag -width "/etc/portsnap.conf"
-.It Pa /etc/portsnap.conf
-Default location of the portsnap configuration file.
-.It Pa /var/db/portsnap
-Default location where compressed snapshots are stored.
-.It Pa /usr/ports
-Default location where the ports tree is extracted.
-.El
-.Sh EXAMPLES
-Fetch the snapshots and create the
-.Xr ports 7
-tree under
-.Pa /usr/ports :
-.Dl Nm Ar fetch Ar extract
-.Pp
-Update the ports tree:
-.Dl Nm Ar fetch Ar update
-.Sh SEE ALSO
-.Xr fetch 1 ,
-.Xr sha256 1 ,
-.Xr fetch 3 ,
-.Xr portsnap.conf 5 ,
-.Xr pkg 7 ,
-.Xr pkg-version 8
-.Sh AUTHORS
-.An Colin Percival Aq Mt cperciva@FreeBSD.org
diff --git a/usr.sbin/portsnap/portsnap/portsnap.conf b/usr.sbin/portsnap/portsnap/portsnap.conf
deleted file mode 100644
index ab1d93c9b653..000000000000
--- a/usr.sbin/portsnap/portsnap/portsnap.conf
+++ /dev/null
@@ -1,36 +0,0 @@
-# $FreeBSD$
-
-# Default directory where compressed snapshots are stored.
-# WORKDIR=/var/db/portsnap
-
-# Default location of the ports tree (target for "update" and "extract").
-# PORTSDIR=/usr/ports
-
-# Server or server pool from which to fetch updates. You can change
-# this to point at a specific server if you want, but in most cases
-# using a "nearby" server won't provide a measurable improvement in
-# performance.
-SERVERNAME=portsnap.FreeBSD.org
-
-# Trusted keyprint. Changing this is a Bad Idea unless you've received
-# a PGP-signed email from <security-officer@FreeBSD.org> telling you to
-# change it and explaining why.
-KEYPRINT=9b5feee6d69f170e3dd0a2c8e469ddbd64f13f978f2f3aede40c98633216c330
-
-# Example of ignoring parts of the ports tree. If you know that you
-# absolutely will not need certain parts of the tree, this will save
-# some bandwidth and disk space. See the manual page for more details.
-#
-# WARNING: Working with an incomplete ports tree is not supported and
-# can cause problems due to missing dependencies. If you have REFUSE
-# directives and experience problems, remove them and update your tree
-# before asking for help on the mailing lists.
-#
-# REFUSE arabic chinese french german hebrew hungarian japanese
-# REFUSE korean polish portuguese russian ukrainian vietnamese
-
-# List of INDEX files to build and the DESCRIBE file to use for each
-#INDEX INDEX-11 DESCRIBE.11
-#INDEX INDEX-12 DESCRIBE.12
-#INDEX INDEX-13 DESCRIBE.13
-INDEX INDEX-14 DESCRIBE.14
diff --git a/usr.sbin/portsnap/portsnap/portsnap.sh b/usr.sbin/portsnap/portsnap/portsnap.sh
deleted file mode 100644
index ad40e3c9c95c..000000000000
--- a/usr.sbin/portsnap/portsnap/portsnap.sh
+++ /dev/null
@@ -1,1156 +0,0 @@
-#!/bin/sh
-
-#-
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
-#
-# Copyright 2004-2005 Colin Percival
-# All rights reserved
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted providing that the following conditions
-# are met:
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-
-# $FreeBSD$
-
-#### Usage function -- called from command-line handling code.
-
-# Usage instructions. Options not listed:
-# --debug -- don't filter output from utilities
-# --no-stats -- don't show progress statistics while fetching files
-usage() {
- cat <<EOF
-usage: `basename $0` [options] command ... [path]
-
-Options:
- -d workdir -- Store working files in workdir
- (default: /var/db/portsnap/)
- -f conffile -- Read configuration options from conffile
- (default: /etc/portsnap.conf)
- -I -- Update INDEX only. (update command only)
- -k KEY -- Trust an RSA key with SHA256 hash of KEY
- -l descfile -- Merge the specified local describes file into the INDEX.
- -p portsdir -- Location of uncompressed ports tree
- (default: /usr/ports/)
- -s server -- Server from which to fetch updates.
- (default: portsnap.FreeBSD.org)
- --interactive -- interactive: override auto-detection of calling process
- (use this when calling portsnap from an interactive, non-
- terminal application AND NEVER ELSE).
- path -- Extract only parts of the tree starting with the given
- string. (extract command only)
-Commands:
- fetch -- Fetch a compressed snapshot of the ports tree,
- or update an existing snapshot.
- cron -- Sleep rand(3600) seconds, and then fetch updates.
- extract -- Extract snapshot of ports tree, replacing existing
- files and directories.
- update -- Update ports tree to match current snapshot, replacing
- files and directories which have changed.
- auto -- Fetch updates, and either extract a new ports tree or
- update an existing tree.
-EOF
- exit 0
-}
-
-#### Parameter handling functions.
-
-# Initialize parameters to null, just in case they're
-# set in the environment.
-init_params() {
- KEYPRINT=""
- EXTRACTPATH=""
- WORKDIR=""
- PORTSDIR=""
- CONFFILE=""
- COMMAND=""
- COMMANDS=""
- QUIETREDIR=""
- QUIETFLAG=""
- STATSREDIR=""
- XARGST=""
- NDEBUG=""
- DDSTATS=""
- INDEXONLY=""
- SERVERNAME=""
- REFUSE=""
- LOCALDESC=""
- INTERACTIVE=""
-}
-
-# Parse the command line
-parse_cmdline() {
- while [ $# -gt 0 ]; do
- case "$1" in
- -d)
- if [ $# -eq 1 ]; then usage; fi
- if [ ! -z "${WORKDIR}" ]; then usage; fi
- shift; WORKDIR="$1"
- ;;
- --debug)
- QUIETREDIR="/dev/stderr"
- STATSREDIR="/dev/stderr"
- QUIETFLAG=" "
- NDEBUG=" "
- XARGST="-t"
- DDSTATS=".."
- ;;
- --interactive)
- INTERACTIVE="YES"
- ;;
- -f)
- if [ $# -eq 1 ]; then usage; fi
- if [ ! -z "${CONFFILE}" ]; then usage; fi
- shift; CONFFILE="$1"
- ;;
- -h | --help | help)
- usage
- ;;
- -I)
- INDEXONLY="YES"
- ;;
- -k)
- if [ $# -eq 1 ]; then usage; fi
- if [ ! -z "${KEYPRINT}" ]; then usage; fi
- shift; KEYPRINT="$1"
- ;;
- -l)
- if [ $# -eq 1 ]; then usage; fi
- if [ ! -z "${LOCALDESC}" ]; then usage; fi
- shift; LOCALDESC="$1"
- ;;
- --no-stats)
- if [ -z "${STATSREDIR}" ]; then
- STATSREDIR="/dev/null"
- DDSTATS=".. "
- fi
- ;;
- -p)
- if [ $# -eq 1 ]; then usage; fi
- if [ ! -z "${PORTSDIR}" ]; then usage; fi
- shift; PORTSDIR="$1"
- ;;
- -s)
- if [ $# -eq 1 ]; then usage; fi
- if [ ! -z "${SERVERNAME}" ]; then usage; fi
- shift; SERVERNAME="$1"
- ;;
- cron | extract | fetch | update | auto)
- COMMANDS="${COMMANDS} $1"
- ;;
- up)
- COMMANDS="${COMMANDS} update"
- ;;
- alfred)
- COMMANDS="${COMMANDS} auto"
- ;;
- *)
- if [ $# -gt 1 ]; then usage; fi
- if echo ${COMMANDS} | grep -vq extract; then
- usage
- fi
- EXTRACTPATH="$1"
- ;;
- esac
- shift
- done
-
- if [ -z "${COMMANDS}" ]; then
- usage
- fi
-}
-
-# If CONFFILE was specified at the command-line, make
-# sure that it exists and is readable.
-sanity_conffile() {
- if [ ! -z "${CONFFILE}" ] && [ ! -r "${CONFFILE}" ]; then
- echo -n "File does not exist "
- echo -n "or is not readable: "
- echo ${CONFFILE}
- exit 1
- fi
-}
-
-# If a configuration file hasn't been specified, use
-# the default value (/etc/portsnap.conf)
-default_conffile() {
- if [ -z "${CONFFILE}" ]; then
- CONFFILE="/etc/portsnap.conf"
- fi
-}
-
-# Read {KEYPRINT, SERVERNAME, WORKDIR, PORTSDIR} from the configuration
-# file if they haven't already been set. If the configuration
-# file doesn't exist, do nothing.
-# Also read REFUSE (which cannot be set via the command line) if it is
-# present in the configuration file.
-parse_conffile() {
- if [ -r "${CONFFILE}" ]; then
- for X in KEYPRINT WORKDIR PORTSDIR SERVERNAME; do
- eval _=\$${X}
- if [ -z "${_}" ]; then
- eval ${X}=`grep "^${X}=" "${CONFFILE}" |
- cut -f 2- -d '=' | tail -1`
- fi
- done
-
- if grep -qE "^REFUSE[[:space:]]" ${CONFFILE}; then
- REFUSE="^(`
- grep -E "^REFUSE[[:space:]]" "${CONFFILE}" |
- cut -c 7- | xargs echo | tr ' ' '|'
- `)"
- fi
-
- if grep -qE "^INDEX[[:space:]]" ${CONFFILE}; then
- INDEXPAIRS="`
- grep -E "^INDEX[[:space:]]" "${CONFFILE}" |
- cut -c 7- | tr ' ' '|' | xargs echo`"
- fi
- fi
-}
-
-# If parameters have not been set, use default values
-default_params() {
- _QUIETREDIR="/dev/null"
- _QUIETFLAG="-q"
- _STATSREDIR="/dev/stdout"
- _WORKDIR="/var/db/portsnap"
- _PORTSDIR="/usr/ports"
- _NDEBUG="-n"
- _LOCALDESC="/dev/null"
- for X in QUIETREDIR QUIETFLAG STATSREDIR WORKDIR PORTSDIR \
- NDEBUG LOCALDESC; do
- eval _=\$${X}
- eval __=\$_${X}
- if [ -z "${_}" ]; then
- eval ${X}=${__}
- fi
- done
- if [ -z "${INTERACTIVE}" ]; then
- if [ -t 0 ]; then
- INTERACTIVE="YES"
- else
- INTERACTIVE="NO"
- fi
- fi
-}
-
-# Perform sanity checks and set some final parameters
-# in preparation for fetching files. Also chdir into
-# the working directory.
-fetch_check_params() {
- export HTTP_USER_AGENT="portsnap (${COMMAND}, `uname -r`)"
-
- _SERVERNAME_z=\
-"SERVERNAME must be given via command line or configuration file."
- _KEYPRINT_z="Key must be given via -k option or configuration file."
- _KEYPRINT_bad="Invalid key fingerprint: "
- _WORKDIR_bad="Directory does not exist or is not writable: "
-
- if [ -z "${SERVERNAME}" ]; then
- echo -n "`basename $0`: "
- echo "${_SERVERNAME_z}"
- exit 1
- fi
- if [ -z "${KEYPRINT}" ]; then
- echo -n "`basename $0`: "
- echo "${_KEYPRINT_z}"
- exit 1
- fi
- if ! echo "${KEYPRINT}" | grep -qE "^[0-9a-f]{64}$"; then
- echo -n "`basename $0`: "
- echo -n "${_KEYPRINT_bad}"
- echo ${KEYPRINT}
- exit 1
- fi
- if ! [ -d "${WORKDIR}" -a -w "${WORKDIR}" ]; then
- echo -n "`basename $0`: "
- echo -n "${_WORKDIR_bad}"
- echo ${WORKDIR}
- exit 1
- fi
- cd ${WORKDIR} || exit 1
-
- BSPATCH=/usr/bin/bspatch
- SHA256=/sbin/sha256
- PHTTPGET=/usr/libexec/phttpget
-}
-
-# Perform sanity checks and set some final parameters
-# in preparation for extracting or updating ${PORTSDIR}
-# Complain if ${PORTSDIR} exists but is not writable,
-# but don't complain if ${PORTSDIR} doesn't exist.
-extract_check_params() {
- _WORKDIR_bad="Directory does not exist: "
- _PORTSDIR_bad="Directory is not writable: "
-
- if ! [ -d "${WORKDIR}" ]; then
- echo -n "`basename $0`: "
- echo -n "${_WORKDIR_bad}"
- echo ${WORKDIR}
- exit 1
- fi
- if [ -d "${PORTSDIR}" ] && ! [ -w "${PORTSDIR}" ]; then
- echo -n "`basename $0`: "
- echo -n "${_PORTSDIR_bad}"
- echo ${PORTSDIR}
- exit 1
- fi
-
- if ! [ -d "${WORKDIR}/files" -a -r "${WORKDIR}/tag" \
- -a -r "${WORKDIR}/INDEX" -a -r "${WORKDIR}/tINDEX" ]; then
- echo "No snapshot available. Try running"
- echo "# `basename $0` fetch"
- exit 1
- fi
-
- MKINDEX=/usr/libexec/make_index
-}
-
-# Perform sanity checks and set some final parameters
-# in preparation for updating ${PORTSDIR}
-update_check_params() {
- extract_check_params
-
- if ! [ -r ${PORTSDIR}/.portsnap.INDEX ]; then
- echo "${PORTSDIR} was not created by portsnap."
- echo -n "You must run '`basename $0` extract' before "
- echo "running '`basename $0` update'."
- exit 1
- fi
-
-}
-
-#### Core functionality -- the actual work gets done here
-
-# Use an SRV query to pick a server. If the SRV query doesn't provide
-# a useful answer, use the server name specified by the user.
-# Put another way... look up _http._tcp.${SERVERNAME} and pick a server
-# from that; or if no servers are returned, use ${SERVERNAME}.
-# This allows a user to specify "portsnap.freebsd.org" (in which case
-# portsnap will select one of the mirrors) or "portsnap5.tld.freebsd.org"
-# (in which case portsnap will use that particular server, since there
-# won't be an SRV entry for that name).
-#
-# We ignore the Port field, since we are always going to use port 80.
-
-# Fetch the mirror list, but do not pick a mirror yet. Returns 1 if
-# no mirrors are available for any reason.
-fetch_pick_server_init() {
- : > serverlist_tried
-
-# Check that host(1) exists (i.e., that the system wasn't built with the
-# WITHOUT_BIND set) and don't try to find a mirror if it doesn't exist.
- if ! which -s host; then
- : > serverlist_full
- return 1
- fi
-
- echo -n "Looking up ${SERVERNAME} mirrors... "
-
-# Issue the SRV query and pull out the Priority, Weight, and Target fields.
-# BIND 9 prints "$name has SRV record ..." while BIND 8 prints
-# "$name server selection ..."; we allow either format.
- MLIST="_http._tcp.${SERVERNAME}"
- host -t srv "${MLIST}" |
- sed -nE "s/${MLIST} (has SRV record|server selection) //Ip" |
- cut -f 1,2,4 -d ' ' |
- sed -e 's/\.$//' |
- sort > serverlist_full
-
-# If no records, give up -- we'll just use the server name we were given.
- if [ `wc -l < serverlist_full` -eq 0 ]; then
- echo "none found."
- return 1
- fi
-
-# Report how many mirrors we found.
- echo `wc -l < serverlist_full` "mirrors found."
-
-# Generate a random seed for use in picking mirrors. If HTTP_PROXY
-# is set, this will be used to generate the seed; otherwise, the seed
-# will be random.
- if [ -n "${HTTP_PROXY}${http_proxy}" ]; then
- RANDVALUE=`sha256 -qs "${HTTP_PROXY}${http_proxy}" |
- tr -d 'a-f' |
- cut -c 1-9`
- else
- RANDVALUE=`jot -r 1 0 999999999`
- fi
-}
-
-# Pick a mirror. Returns 1 if we have run out of mirrors to try.
-fetch_pick_server() {
-# Generate a list of not-yet-tried mirrors
- sort serverlist_tried |
- comm -23 serverlist_full - > serverlist
-
-# Have we run out of mirrors?
- if [ `wc -l < serverlist` -eq 0 ]; then
- echo "No mirrors remaining, giving up."
- return 1
- fi
-
-# Find the highest priority level (lowest numeric value).
- SRV_PRIORITY=`cut -f 1 -d ' ' serverlist | sort -n | head -1`
-
-# Add up the weights of the response lines at that priority level.
- SRV_WSUM=0
- while read X; do
- case "$X" in
- ${SRV_PRIORITY}\ *)
- SRV_W=`echo $X | cut -f 2 -d ' '`
- SRV_WSUM=$(($SRV_WSUM + $SRV_W))
- ;;
- esac
- done < serverlist
-
-# If all the weights are 0, pretend that they are all 1 instead.
- if [ ${SRV_WSUM} -eq 0 ]; then
- SRV_WSUM=`grep -E "^${SRV_PRIORITY} " serverlist | wc -l`
- SRV_W_ADD=1
- else
- SRV_W_ADD=0
- fi
-
-# Pick a value between 0 and the sum of the weights - 1
- SRV_RND=`expr ${RANDVALUE} % ${SRV_WSUM}`
-
-# Read through the list of mirrors and set SERVERNAME. Write the line
-# corresponding to the mirror we selected into serverlist_tried so that
-# we won't try it again.
- while read X; do
- case "$X" in
- ${SRV_PRIORITY}\ *)
- SRV_W=`echo $X | cut -f 2 -d ' '`
- SRV_W=$(($SRV_W + $SRV_W_ADD))
- if [ $SRV_RND -lt $SRV_W ]; then
- SERVERNAME=`echo $X | cut -f 3 -d ' '`
- echo "$X" >> serverlist_tried
- break
- else
- SRV_RND=$(($SRV_RND - $SRV_W))
- fi
- ;;
- esac
- done < serverlist
-}
-
-# Check that we have a public key with an appropriate hash, or
-# fetch the key if it doesn't exist. Returns 1 if the key has
-# not yet been fetched.
-fetch_key() {
- if [ -r pub.ssl ] && [ `${SHA256} -q pub.ssl` = ${KEYPRINT} ]; then
- return 0
- fi
-
- echo -n "Fetching public key from ${SERVERNAME}... "
- rm -f pub.ssl
- fetch ${QUIETFLAG} http://${SERVERNAME}/pub.ssl \
- 2>${QUIETREDIR} || true
- if ! [ -r pub.ssl ]; then
- echo "failed."
- return 1
- fi
- if ! [ `${SHA256} -q pub.ssl` = ${KEYPRINT} ]; then
- echo "key has incorrect hash."
- rm -f pub.ssl
- return 1
- fi
- echo "done."
-}
-
-# Fetch a snapshot tag
-fetch_tag() {
- rm -f snapshot.ssl tag.new
-
- echo ${NDEBUG} "Fetching snapshot tag from ${SERVERNAME}... "
- fetch ${QUIETFLAG} http://${SERVERNAME}/$1.ssl \
- 2>${QUIETREDIR} || true
- if ! [ -r $1.ssl ]; then
- echo "failed."
- return 1
- fi
-
- openssl rsautl -pubin -inkey pub.ssl -verify \
- < $1.ssl > tag.new 2>${QUIETREDIR} || true
- rm $1.ssl
-
- if ! [ `wc -l < tag.new` = 1 ] ||
- ! grep -qE "^portsnap\|[0-9]{10}\|[0-9a-f]{64}" tag.new; then
- echo "invalid snapshot tag."
- return 1
- fi
-
- echo "done."
-
- SNAPSHOTDATE=`cut -f 2 -d '|' < tag.new`
- SNAPSHOTHASH=`cut -f 3 -d '|' < tag.new`
-}
-
-# Sanity-check the date on a snapshot tag
-fetch_snapshot_tagsanity() {
- if [ `date "+%s"` -gt `expr ${SNAPSHOTDATE} + 31536000` ]; then
- echo "Snapshot appears to be more than a year old!"
- echo "(Is the system clock correct?)"
- echo "Cowardly refusing to proceed any further."
- return 1
- fi
- if [ `date "+%s"` -lt `expr ${SNAPSHOTDATE} - 86400` ]; then
- echo -n "Snapshot appears to have been created more than "
- echo "one day into the future!"
- echo "(Is the system clock correct?)"
- echo "Cowardly refusing to proceed any further."
- return 1
- fi
-}
-
-# Sanity-check the date on a snapshot update tag
-fetch_update_tagsanity() {
- fetch_snapshot_tagsanity || return 1
-
- if [ ${OLDSNAPSHOTDATE} -gt ${SNAPSHOTDATE} ]; then
- echo -n "Latest snapshot on server is "
- echo "older than what we already have!"
- echo -n "Cowardly refusing to downgrade from "
- date -r ${OLDSNAPSHOTDATE}
- echo "to `date -r ${SNAPSHOTDATE}`."
- return 1
- fi
-}
-
-# Compare old and new tags; return 1 if update is unnecessary
-fetch_update_neededp() {
- if [ ${OLDSNAPSHOTDATE} -eq ${SNAPSHOTDATE} ]; then
- echo -n "Latest snapshot on server matches "
- echo "what we already have."
- echo "No updates needed."
- rm tag.new
- return 1
- fi
- if [ ${OLDSNAPSHOTHASH} = ${SNAPSHOTHASH} ]; then
- echo -n "Ports tree hasn't changed since "
- echo "last snapshot."
- echo "No updates needed."
- rm tag.new
- return 1
- fi
-
- return 0
-}
-
-# Fetch snapshot metadata file
-fetch_metadata() {
- rm -f ${SNAPSHOTHASH} tINDEX.new
-
- echo ${NDEBUG} "Fetching snapshot metadata... "
- fetch ${QUIETFLAG} http://${SERVERNAME}/t/${SNAPSHOTHASH} \
- 2>${QUIETREDIR} || return
- if [ "`${SHA256} -q ${SNAPSHOTHASH}`" != ${SNAPSHOTHASH} ]; then
- echo "snapshot metadata corrupt."
- return 1
- fi
- mv ${SNAPSHOTHASH} tINDEX.new
- echo "done."
-}
-
-# Warn user about bogus metadata
-fetch_metadata_freakout() {
- echo
- echo "Portsnap metadata is correctly signed, but contains"
- echo "at least one line which appears bogus."
- echo "Cowardly refusing to proceed any further."
-}
-
-# Sanity-check a snapshot metadata file
-fetch_metadata_sanity() {
- if grep -qvE "^[0-9A-Z.]+\|[0-9a-f]{64}$" tINDEX.new; then
- fetch_metadata_freakout
- return 1
- fi
- if [ `look INDEX tINDEX.new | wc -l` != 1 ]; then
- echo
- echo "Portsnap metadata appears bogus."
- echo "Cowardly refusing to proceed any further."
- return 1
- fi
-}
-
-# Take a list of ${oldhash}|${newhash} and output a list of needed patches
-fetch_make_patchlist() {
- local IFS='|'
- echo "" 1>${QUIETREDIR}
- grep -vE "^([0-9a-f]{64})\|\1$" |
- while read X Y; do
- printf "Processing: $X $Y ...\r" 1>${QUIETREDIR}
- if [ -f "files/${Y}.gz" -o ! -f "files/${X}.gz" ]; then continue; fi
- echo "${X}|${Y}"
- done
- echo "" 1>${QUIETREDIR}
-}
-
-# Print user-friendly progress statistics
-fetch_progress() {
- LNC=0
- while read x; do
- LNC=$(($LNC + 1))
- if [ $(($LNC % 10)) = 0 ]; then
- echo -n $LNC
- elif [ $(($LNC % 2)) = 0 ]; then
- echo -n .
- fi
- done
- echo -n " "
-}
-
-pct_fmt()
-{
- if [ $TOTAL -gt 0 ]; then
- printf " \r"
- printf "($1/$2) %02.2f%% " `echo "scale=4;$LNC / $TOTAL * 100"|bc`
- fi
-}
-
-fetch_progress_percent() {
- TOTAL=$1
- LNC=0
- pct_fmt $LNC $TOTAL
- while read x; do
- LNC=$(($LNC + 1))
- if [ $(($LNC % 100)) = 0 ]; then
- pct_fmt $LNC $TOTAL
- elif [ $(($LNC % 10)) = 0 ]; then
- echo -n .
- fi
- done
- pct_fmt $LNC $TOTAL
- echo " done. "
-}
-
-# Sanity-check an index file
-fetch_index_sanity() {
- if grep -qvE "^[-_+./@0-9A-Za-z]+\|[0-9a-f]{64}$" INDEX.new ||
- fgrep -q "./" INDEX.new; then
- fetch_metadata_freakout
- return 1
- fi
-}
-
-# Verify a list of files
-fetch_snapshot_verify() {
- while read F; do
- if [ "`gunzip -c < snap/${F}.gz | ${SHA256} -q`" != ${F} ]; then
- echo "snapshot corrupt."
- return 1
- fi
- done
- return 0
-}
-
-# Fetch a snapshot tarball, extract, and verify.
-fetch_snapshot() {
- while ! fetch_tag snapshot; do
- fetch_pick_server || return 1
- done
- fetch_snapshot_tagsanity || return 1
- fetch_metadata || return 1
- fetch_metadata_sanity || return 1
-
- rm -rf snap/
-
-# Don't ask fetch(1) to be quiet -- downloading a snapshot of ~ 35MB will
-# probably take a while, so the progrees reports that fetch(1) generates
-# will be useful for keeping the users' attention from drifting.
- echo "Fetching snapshot generated at `date -r ${SNAPSHOTDATE}`:"
- fetch -r http://${SERVERNAME}/s/${SNAPSHOTHASH}.tgz || return 1
-
- echo -n "Extracting snapshot... "
- tar -xz --numeric-owner -f ${SNAPSHOTHASH}.tgz snap/ || return 1
- rm ${SNAPSHOTHASH}.tgz
- echo "done."
-
- echo -n "Verifying snapshot integrity... "
-# Verify the metadata files
- cut -f 2 -d '|' tINDEX.new | fetch_snapshot_verify || return 1
-# Extract the index
- rm -f INDEX.new
- gunzip -c < snap/`look INDEX tINDEX.new |
- cut -f 2 -d '|'`.gz > INDEX.new
- fetch_index_sanity || return 1
-# Verify the snapshot contents
- cut -f 2 -d '|' INDEX.new | fetch_snapshot_verify || return 1
- cut -f 2 -d '|' tINDEX.new INDEX.new | sort -u |
- lam -s 'snap/' - -s '.gz' > files.expected
- find snap -mindepth 1 | sort > files.snap
- if ! cmp -s files.expected files.snap; then
- echo "unexpected files in snapshot."
- return 1
- fi
- rm files.expected files.snap
- echo "done."
-
-# Move files into their proper locations
- rm -f tag INDEX tINDEX
- rm -rf files
- mv tag.new tag
- mv tINDEX.new tINDEX
- mv INDEX.new INDEX
- mv snap/ files/
-
- return 0
-}
-
-# Update a compressed snapshot
-fetch_update() {
- rm -f patchlist diff OLD NEW filelist INDEX.new
-
- OLDSNAPSHOTDATE=`cut -f 2 -d '|' < tag`
- OLDSNAPSHOTHASH=`cut -f 3 -d '|' < tag`
-
- while ! fetch_tag latest; do
- fetch_pick_server || return 1
- done
- fetch_update_tagsanity || return 1
- fetch_update_neededp || return 0
- fetch_metadata || return 1
- fetch_metadata_sanity || return 1
-
- echo -n "Updating from `date -r ${OLDSNAPSHOTDATE}` "
- echo "to `date -r ${SNAPSHOTDATE}`."
-
-# Generate a list of wanted metadata patches
- join -t '|' -o 1.2,2.2 tINDEX tINDEX.new |
- fetch_make_patchlist > patchlist
-
-# Attempt to fetch metadata patches
- echo -n "Fetching `wc -l < patchlist | tr -d ' '` "
- echo ${NDEBUG} "metadata patches.${DDSTATS}"
- tr '|' '-' < patchlist |
- lam -s "tp/" - -s ".gz" |
- xargs ${XARGST} ${PHTTPGET} ${SERVERNAME} \
- 2>${STATSREDIR} | fetch_progress
- echo "done."
-
-# Attempt to apply metadata patches
- echo -n "Applying metadata patches... "
- local oldifs="$IFS" IFS='|'
- while read X Y; do
- if [ ! -f "${X}-${Y}.gz" ]; then continue; fi
- gunzip -c < ${X}-${Y}.gz > diff
- gunzip -c < files/${X}.gz > OLD
- cut -c 2- diff | join -t '|' -v 2 - OLD > ptmp
- grep '^\+' diff | cut -c 2- |
- sort -k 1,1 -t '|' -m - ptmp > NEW
- if [ `${SHA256} -q NEW` = ${Y} ]; then
- mv NEW files/${Y}
- gzip -n files/${Y}
- fi
- rm -f diff OLD NEW ${X}-${Y}.gz ptmp
- done < patchlist 2>${QUIETREDIR}
- IFS="$oldifs"
- echo "done."
-
-# Update metadata without patches
- join -t '|' -v 2 tINDEX tINDEX.new |
- cut -f 2 -d '|' /dev/stdin patchlist |
- while read Y; do
- if [ ! -f "files/${Y}.gz" ]; then
- echo ${Y}
- fi
- done > filelist
- echo -n "Fetching `wc -l < filelist | tr -d ' '` "
- echo ${NDEBUG} "metadata files... "
- lam -s "f/" - -s ".gz" < filelist |
- xargs ${XARGST} ${PHTTPGET} ${SERVERNAME} \
- 2>${QUIETREDIR}
-
- while read Y; do
- echo -n "Verifying ${Y}... " 1>${QUIETREDIR}
- if [ `gunzip -c < ${Y}.gz | ${SHA256} -q` = ${Y} ]; then
- mv ${Y}.gz files/${Y}.gz
- else
- echo "metadata is corrupt."
- return 1
- fi
- echo "ok." 1>${QUIETREDIR}
- done < filelist
- echo "done."
-
-# Extract the index
- echo -n "Extracting index... " 1>${QUIETREDIR}
- gunzip -c < files/`look INDEX tINDEX.new |
- cut -f 2 -d '|'`.gz > INDEX.new
- fetch_index_sanity || return 1
-
-# If we have decided to refuse certain updates, construct a hybrid index which
-# is equal to the old index for parts of the tree which we don't want to
-# update, and equal to the new index for parts of the tree which gets updates.
-# This means that we should always have a "complete snapshot" of the ports
-# tree -- with the caveat that it isn't actually a snapshot.
- if [ ! -z "${REFUSE}" ]; then
- echo "Refusing to download updates for ${REFUSE}" \
- >${QUIETREDIR}
-
- grep -Ev "${REFUSE}" INDEX.new > INDEX.tmp
- grep -E "${REFUSE}" INDEX |
- sort -m -k 1,1 -t '|' - INDEX.tmp > INDEX.new
- rm -f INDEX.tmp
- fi
-
-# Generate a list of wanted ports patches
- echo -n "Generating list of wanted patches..." 1>${QUIETREDIR}
- join -t '|' -o 1.2,2.2 INDEX INDEX.new |
- fetch_make_patchlist > patchlist
- echo " done." 1>${QUIETREDIR}
-
-# Attempt to fetch ports patches
- patchcnt=`wc -l < patchlist | tr -d ' '`
- echo -n "Fetching $patchcnt "
- echo ${NDEBUG} "patches.${DDSTATS}"
- echo " "
- tr '|' '-' < patchlist | lam -s "bp/" - |
- xargs ${XARGST} ${PHTTPGET} ${SERVERNAME} \
- 2>${STATSREDIR} | fetch_progress_percent $patchcnt
- echo "done."
-
-# Attempt to apply ports patches
- PATCHCNT=`wc -l patchlist`
- echo "Applying patches... "
- local oldifs="$IFS" IFS='|'
- I=0
- while read X Y; do
- I=$(($I + 1))
- F="${X}-${Y}"
- if [ ! -f "${F}" ]; then
- XS=${X%[0-9a-f][0-9a-f][0-9a-f][0-9a-f]}
- XE=${X#[0-9a-f][0-9a-f][0-9a-f][0-9a-f]}
- YS=${Y%[0-9a-f][0-9a-f][0-9a-f][0-9a-f]}
- YE=${Y#[0-9a-f][0-9a-f][0-9a-f][0-9a-f]}
- F="${X%${XE}}...${X#${XS}}-${Y%${YE}}...${Y#${YS}}"
- printf " Skipping ${F} (${I} of ${PATCHCNT}).\r"
- continue
- fi
- echo " Processing ${F}..." 1>${QUIETREDIR}
- gunzip -c < files/${X}.gz > OLD
- ${BSPATCH} OLD NEW ${X}-${Y}
- if [ `${SHA256} -q NEW` = ${Y} ]; then
- mv NEW files/${Y}
- gzip -n files/${Y}
- fi
- rm -f diff OLD NEW ${X}-${Y}
- done < patchlist 2>${QUIETREDIR}
- IFS="$oldifs"
- echo "done."
-
-# Update ports without patches
- join -t '|' -v 2 INDEX INDEX.new |
- cut -f 2 -d '|' /dev/stdin patchlist |
- while read Y; do
- if [ ! -f "files/${Y}.gz" ]; then
- echo ${Y}
- fi
- done > filelist
- echo -n "Fetching `wc -l < filelist | tr -d ' '` "
- echo ${NDEBUG} "new ports or files... "
- lam -s "f/" - -s ".gz" < filelist |
- xargs ${XARGST} ${PHTTPGET} ${SERVERNAME} \
- 2>${QUIETREDIR}
-
- I=0
- while read Y; do
- I=$(($I + 1))
- printf " Processing ${Y} (${I} of ${PATCHCNT}).\r" 1>${QUIETREDIR}
- if [ `gunzip -c < ${Y}.gz | ${SHA256} -q` = ${Y} ]; then
- mv ${Y}.gz files/${Y}.gz
- else
- echo "snapshot is corrupt."
- return 1
- fi
- done < filelist
- echo "done."
-
-# Remove files which are no longer needed
- cut -f 2 -d '|' tINDEX INDEX | sort -u > oldfiles
- cut -f 2 -d '|' tINDEX.new INDEX.new | sort -u | comm -13 - oldfiles |
- lam -s "files/" - -s ".gz" | xargs rm -f
- rm patchlist filelist oldfiles
-
-# We're done!
- mv INDEX.new INDEX
- mv tINDEX.new tINDEX
- mv tag.new tag
-
- return 0
-}
-
-# Do the actual work involved in "fetch" / "cron".
-fetch_run() {
- fetch_pick_server_init && fetch_pick_server
-
- while ! fetch_key; do
- fetch_pick_server || return 1
- done
-
- if ! [ -d files -a -r tag -a -r INDEX -a -r tINDEX ]; then
- fetch_snapshot || return 1
- fi
- fetch_update || return 1
-}
-
-# Build a ports INDEX file
-extract_make_index() {
- if ! look $1 ${WORKDIR}/tINDEX > /dev/null; then
- echo -n "$1 not provided by portsnap server; "
- echo "$2 not being generated."
- else
- gunzip -c < "${WORKDIR}/files/`look $1 ${WORKDIR}/tINDEX |
- cut -f 2 -d '|'`.gz" |
- cat - ${LOCALDESC} |
- ${MKINDEX} /dev/stdin > ${PORTSDIR}/$2
- fi
-}
-
-# Create INDEX, INDEX-5, INDEX-6
-extract_indices() {
- echo -n "Building new INDEX files... "
- for PAIR in ${INDEXPAIRS}; do
- INDEXFILE=`echo ${PAIR} | cut -f 1 -d '|'`
- DESCRIBEFILE=`echo ${PAIR} | cut -f 2 -d '|'`
- extract_make_index ${DESCRIBEFILE} ${INDEXFILE} || return 1
- done
- echo "done."
-}
-
-# Create .portsnap.INDEX; if we are REFUSEing to touch certain directories,
-# merge the values from any exiting .portsnap.INDEX file.
-extract_metadata() {
- if [ -z "${REFUSE}" ]; then
- sort ${WORKDIR}/INDEX > ${PORTSDIR}/.portsnap.INDEX
- elif [ -f ${PORTSDIR}/.portsnap.INDEX ]; then
- grep -E "${REFUSE}" ${PORTSDIR}/.portsnap.INDEX \
- > ${PORTSDIR}/.portsnap.INDEX.tmp
- grep -vE "${REFUSE}" ${WORKDIR}/INDEX | sort |
- sort -m - ${PORTSDIR}/.portsnap.INDEX.tmp \
- > ${PORTSDIR}/.portsnap.INDEX
- rm -f ${PORTSDIR}/.portsnap.INDEX.tmp
- else
- grep -vE "${REFUSE}" ${WORKDIR}/INDEX | sort \
- > ${PORTSDIR}/.portsnap.INDEX
- fi
-}
-
-# Do the actual work involved in "extract"
-extract_run() {
- local oldifs="$IFS" IFS='|'
- mkdir -p ${PORTSDIR} || return 1
-
- if !
- if ! [ -z "${EXTRACTPATH}" ]; then
- grep "^${EXTRACTPATH}" ${WORKDIR}/INDEX
- elif ! [ -z "${REFUSE}" ]; then
- grep -vE "${REFUSE}" ${WORKDIR}/INDEX
- else
- cat ${WORKDIR}/INDEX
- fi | while read FILE HASH; do
- echo ${PORTSDIR}/${FILE}
- if ! [ -s "${WORKDIR}/files/${HASH}.gz" ]; then
- echo "files/${HASH}.gz not found -- snapshot corrupt."
- return 1
- fi
- case ${FILE} in
- */)
- rm -rf ${PORTSDIR}/${FILE%/}
- mkdir -p ${PORTSDIR}/${FILE}
- tar -xz --numeric-owner -f ${WORKDIR}/files/${HASH}.gz \
- -C ${PORTSDIR}/${FILE}
- ;;
- *)
- rm -f ${PORTSDIR}/${FILE}
- tar -xz --numeric-owner -f ${WORKDIR}/files/${HASH}.gz \
- -C ${PORTSDIR} ${FILE}
- ;;
- esac
- done; then
- return 1
- fi
- if [ ! -z "${EXTRACTPATH}" ]; then
- return 0
- fi
-
- IFS="$oldifs"
-
- extract_metadata
- extract_indices
-}
-
-update_run_extract() {
- local IFS='|'
-
-# Install new files
- echo "Extracting new files:"
- if !
- if ! [ -z "${REFUSE}" ]; then
- grep -vE "${REFUSE}" ${WORKDIR}/INDEX | sort
- else
- sort ${WORKDIR}/INDEX
- fi |
- comm -13 ${PORTSDIR}/.portsnap.INDEX - |
- while read FILE HASH; do
- echo ${PORTSDIR}/${FILE}
- if ! [ -s "${WORKDIR}/files/${HASH}.gz" ]; then
- echo "files/${HASH}.gz not found -- snapshot corrupt."
- return 1
- fi
- case ${FILE} in
- */)
- mkdir -p ${PORTSDIR}/${FILE}
- tar -xz --numeric-owner -f ${WORKDIR}/files/${HASH}.gz \
- -C ${PORTSDIR}/${FILE}
- ;;
- *)
- tar -xz --numeric-owner -f ${WORKDIR}/files/${HASH}.gz \
- -C ${PORTSDIR} ${FILE}
- ;;
- esac
- done; then
- return 1
- fi
-}
-
-# Do the actual work involved in "update"
-update_run() {
- if ! [ -z "${INDEXONLY}" ]; then
- extract_indices >/dev/null || return 1
- return 0
- fi
-
- if sort ${WORKDIR}/INDEX |
- cmp -s ${PORTSDIR}/.portsnap.INDEX -; then
- echo "Ports tree is already up to date."
- return 0
- fi
-
-# If we are REFUSEing to touch certain directories, don't remove files
-# from those directories (even if they are out of date)
- echo -n "Removing old files and directories... "
- if ! [ -z "${REFUSE}" ]; then
- sort ${WORKDIR}/INDEX |
- comm -23 ${PORTSDIR}/.portsnap.INDEX - | cut -f 1 -d '|' |
- grep -vE "${REFUSE}" |
- lam -s "${PORTSDIR}/" - |
- sed -e 's|/$||' | xargs rm -rf
- else
- sort ${WORKDIR}/INDEX |
- comm -23 ${PORTSDIR}/.portsnap.INDEX - | cut -f 1 -d '|' |
- lam -s "${PORTSDIR}/" - |
- sed -e 's|/$||' | xargs rm -rf
- fi
- echo "done."
-
- update_run_extract || return 1
- extract_metadata
- extract_indices
-}
-
-#### Main functions -- call parameter-handling and core functions
-
-# Using the command line, configuration file, and defaults,
-# set all the parameters which are needed later.
-get_params() {
- init_params
- parse_cmdline $@
- sanity_conffile
- default_conffile
- parse_conffile
- default_params
-}
-
-# Fetch command. Make sure that we're being called
-# interactively, then run fetch_check_params and fetch_run
-cmd_fetch() {
- if [ "${INTERACTIVE}" != "YES" ]; then
- echo -n "`basename $0` fetch should not "
- echo "be run non-interactively."
- echo "Run `basename $0` cron instead"
- exit 1
- fi
- fetch_check_params
- fetch_run || exit 1
-}
-
-# Cron command. Make sure the parameters are sensible; wait
-# rand(3600) seconds; then fetch updates. While fetching updates,
-# send output to a temporary file; only print that file if the
-# fetching failed.
-cmd_cron() {
- fetch_check_params
- sleep `jot -r 1 0 3600`
-
- TMPFILE=`mktemp /tmp/portsnap.XXXXXX` || exit 1
- if ! fetch_run >> ${TMPFILE}; then
- cat ${TMPFILE}
- rm ${TMPFILE}
- exit 1
- fi
-
- rm ${TMPFILE}
-}
-
-# Extract command. Make sure the parameters are sensible,
-# then extract the ports tree (or part thereof).
-cmd_extract() {
- extract_check_params
- extract_run || exit 1
-}
-
-# Update command. Make sure the parameters are sensible,
-# then update the ports tree.
-cmd_update() {
- update_check_params
- update_run || exit 1
-}
-
-# Auto command. Run 'fetch' or 'cron' depending on
-# whether stdin is a terminal; then run 'update' or
-# 'extract' depending on whether ${PORTSDIR} exists.
-cmd_auto() {
- if [ "${INTERACTIVE}" = "YES" ]; then
- cmd_fetch
- else
- cmd_cron
- fi
- if [ -r ${PORTSDIR}/.portsnap.INDEX ]; then
- cmd_update
- else
- cmd_extract
- fi
-}
-
-#### Entry point
-
-# Make sure we find utilities from the base system
-export PATH=/sbin:/bin:/usr/sbin:/usr/bin:${PATH}
-
-# Set LC_ALL in order to avoid problems with character ranges like [A-Z].
-export LC_ALL=C
-
-get_params $@
-for COMMAND in ${COMMANDS}; do
- cmd_${COMMAND}
-done