diff options
author | Colin Percival <cperciva@FreeBSD.org> | 2023-04-23 01:07:14 +0000 |
---|---|---|
committer | Colin Percival <cperciva@FreeBSD.org> | 2023-04-23 01:12:37 +0000 |
commit | df53ae0fdd98e9452095ac2fdaf95fcfac8c9c7f (patch) | |
tree | 61471b72c3aec1d08944cafac4605a0df000442e | |
parent | fb30bb0d4d0ed3beb27116761ac0c941607e3906 (diff) | |
download | src-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.inc | 7 | ||||
-rw-r--r-- | UPDATING | 4 | ||||
-rw-r--r-- | libexec/Makefile | 2 | ||||
-rw-r--r-- | share/examples/etc/README.examples | 5 | ||||
-rw-r--r-- | share/man/man5/Makefile | 3 | ||||
-rw-r--r-- | share/man/man5/portsnap.conf.5 | 147 | ||||
-rw-r--r-- | share/man/man5/src.conf.5 | 4 | ||||
-rw-r--r-- | share/mk/src.opts.mk | 1 | ||||
-rw-r--r-- | targets/pseudo/userland/Makefile.depend | 3 | ||||
-rw-r--r-- | tools/build/mk/OptionalObsoleteFiles.inc | 10 | ||||
-rw-r--r-- | tools/build/options/WITHOUT_PORTSNAP | 4 | ||||
-rw-r--r-- | usr.sbin/Makefile | 1 | ||||
-rw-r--r-- | usr.sbin/portsnap/Makefile | 5 | ||||
-rw-r--r-- | usr.sbin/portsnap/Makefile.inc | 5 | ||||
-rw-r--r-- | usr.sbin/portsnap/make_index/Makefile | 8 | ||||
-rw-r--r-- | usr.sbin/portsnap/make_index/Makefile.depend | 16 | ||||
-rw-r--r-- | usr.sbin/portsnap/make_index/make_index.c | 515 | ||||
-rw-r--r-- | usr.sbin/portsnap/portsnap/Makefile | 7 | ||||
-rw-r--r-- | usr.sbin/portsnap/portsnap/Makefile.depend | 11 | ||||
-rw-r--r-- | usr.sbin/portsnap/portsnap/portsnap.8 | 288 | ||||
-rw-r--r-- | usr.sbin/portsnap/portsnap/portsnap.conf | 36 | ||||
-rw-r--r-- | usr.sbin/portsnap/portsnap/portsnap.sh | 1156 |
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 @@ -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 |