diff options
Diffstat (limited to 'mk/fetch/fetch.mk')
-rw-r--r-- | mk/fetch/fetch.mk | 453 |
1 files changed, 453 insertions, 0 deletions
diff --git a/mk/fetch/fetch.mk b/mk/fetch/fetch.mk new file mode 100644 index 00000000000..7f9a0176844 --- /dev/null +++ b/mk/fetch/fetch.mk @@ -0,0 +1,453 @@ +# $NetBSD: fetch.mk,v 1.1 2006/06/06 03:05:48 jlam Exp $ + +###################################################################### +### fetch (PUBLIC) +###################################################################### +### fetch is a public target to fetch all of the package distribution +### files. +### +.PHONY: fetch +.if !target(fetch) +fetch: pre-fetch do-fetch post-fetch +.endif + +# If this host is behind a filtering firewall, use passive ftp(1) +FETCH_BEFORE_ARGS+= ${PASSIVE_FETCH:D-p} + +_MASTER_SITE_BACKUP= ${MASTER_SITE_BACKUP:=${DIST_SUBDIR}${DIST_SUBDIR:D/}} +_MASTER_SITE_OVERRIDE= ${MASTER_SITE_OVERRIDE:=${DIST_SUBDIR}${DIST_SUBDIR:D/}} + +# Where to put distfiles that don't have any other master site +MASTER_SITE_LOCAL?= ${MASTER_SITE_BACKUP:=LOCAL_PORTS/} + +ALLFILES?= ${DISTFILES} ${PATCHFILES} +CKSUMFILES?= ${ALLFILES} +.for __tmp__ in ${IGNOREFILES} +CKSUMFILES:= ${CKSUMFILES:N${__tmp__}} +.endfor + +# List of all files, with ${DIST_SUBDIR} in front. Used for fetch and checksum. +.if defined(DIST_SUBDIR) +_CKSUMFILES?= ${CKSUMFILES:S/^/${DIST_SUBDIR}\//} +_DISTFILES?= ${DISTFILES:S/^/${DIST_SUBDIR}\//} +_IGNOREFILES?= ${IGNOREFILES:S/^/${DIST_SUBDIR}\//} +_PATCHFILES?= ${PATCHFILES:S/^/${DIST_SUBDIR}\//} +.else +_CKSUMFILES?= ${CKSUMFILES} +_DISTFILES?= ${DISTFILES} +_IGNOREFILES?= ${IGNOREFILES} +_PATCHFILES?= ${PATCHFILES} +.endif +_ALLFILES?= ${_DISTFILES} ${_PATCHFILES} + +BUILD_DEFS+= _DISTFILES _PATCHFILES + +### +### _RESUME_TRANSFER: +### +### Macro to resume a previous transfer, needs to have defined +### the following options in mk.conf: +### +### PKG_RESUME_TRANSFERS +### FETCH_RESUME_ARGS (if FETCH_CMD != default) +### FETCH_OUTPUT_ARGS (if FETCH_CMD != default) +### +### For example if you want to use wget (pkgsrc/net/wget): +### +### FETCH_CMD=wget +### FETCH_RESUME_ARGS=-c +### FETCH_OUTPUT_ARGS=-O +### +### How does it work? +### +### FETCH_CMD downloads the file and saves it temporally into $$bfile.temp +### if the checksum match the correct one, $$bfile.temp is renamed to +### the original name. +### + +_RESUME_TRANSFER= \ + ofile="${DISTDIR}/${DIST_SUBDIR}/$$bfile"; \ + tfile="${DISTDIR}/${DIST_SUBDIR}/$$bfile.temp"; \ + tsize=`${AWK} '/^Size/ && $$2 == '"\"($$file)\""' { print $$4 }' ${DISTINFO_FILE}` || ${TRUE}; \ + osize=`${WC} -c < $$ofile`; \ + \ + case "$$tsize" in \ + "") ${ECHO_MSG} "No size in distinfo file (${DISTINFO_FILE})"; \ + break;; \ + esac; \ + \ + if [ "$$osize" -eq "$$tsize" ]; then \ + if [ -f "$$tfile" ]; then \ + ${RM} $$tfile; \ + fi; \ + need_fetch=no; \ + elif [ "$$osize" -lt "$$tsize" -a ! -f "$$tfile" ]; then \ + ${CP} $$ofile $$tfile; \ + dsize=`${WC} -c < $$tfile`; \ + need_fetch=yes; \ + elif [ -f "$$tfile" -a "$$dsize" -gt "$$ossize" ]; then \ + dsize=`${WC} -c < $$tfile`; \ + need_fetch=yes; \ + else \ + if [ -f "$$tfile" ]; then \ + dsize=`${WC} -c < $$tfile`; \ + fi; \ + need_fetch=yes; \ + fi; \ + if [ "$$need_fetch" = "no" ]; then \ + break; \ + elif [ -f "$$tfile" -a "$$dsize" -eq "$$tsize" ]; then \ + ${MV} $$tfile $$ofile; \ + break; \ + elif [ -n "$$ftp_proxy" -o -n "$$http_proxy" ]; then \ + ${ECHO_MSG} "===> Resume is not supported by ftp(1) using http/ftp proxies."; \ + break; \ + elif [ "$$need_fetch" = "yes" -a "$$dsize" -lt "$$tsize" ]; then \ + if [ "${FETCH_CMD:T}" != "ftp" -a -z "${FETCH_RESUME_ARGS}" ]; then \ + ${ECHO_MSG} "=> Resume transfers are not supported, FETCH_RESUME_ARGS is empty."; \ + break; \ + else \ + for res_site in $$sites; do \ + if [ -z "${FETCH_OUTPUT_ARGS}" ]; then \ + ${ECHO_MSG} "=> FETCH_OUTPUT_ARGS has to be defined."; \ + break; \ + fi; \ + ${ECHO_MSG} "=> $$bfile not completed, resuming:"; \ + ${ECHO_MSG} "=> Downloaded: $$dsize Total: $$tsize."; \ + ${ECHO_MSG}; \ + cd ${DISTDIR}; \ + ${FETCH_CMD} ${FETCH_BEFORE_ARGS} ${FETCH_RESUME_ARGS} \ + ${FETCH_OUTPUT_ARGS} $${bfile}.temp $${res_site}$${bfile}; \ + if [ $$? -eq 0 ]; then \ + ndsize=`${WC} -c < $$tfile`; \ + if [ "$$tsize" -eq "$$ndsize" ]; then \ + ${MV} $$tfile $$ofile; \ + fi; \ + break; \ + fi; \ + done; \ + fi; \ + elif [ "$$dsize" -gt "$$tsize" ]; then \ + ${ECHO_MSG} "==> Downloaded file larger than the recorded size."; \ + break; \ + fi + +# +# Define the elementary fetch macros. +# +_FETCH_FILE= \ + if [ ! -f $$file -a ! -f $$bfile -a ! -h $$bfile ]; then \ + ${ECHO_MSG} "=> $$bfile doesn't seem to exist on this system."; \ + if [ ! -w ${_DISTDIR}/. ]; then \ + ${ECHO_MSG} "=> Can't download to ${_DISTDIR} (permission denied?)."; \ + exit 1; \ + fi; \ + for site in $$sites; do \ + ${ECHO_MSG} "=> Attempting to fetch $$bfile from $${site}."; \ + if [ -f ${DISTINFO_FILE} ]; then \ + ${AWK} 'NF == 5 && $$1 == "Size" && $$2 == "('$$bfile')" { printf("=> [%s %s]\n", $$4, $$5) }' ${DISTINFO_FILE}; \ + fi; \ + if ${FETCH_CMD} ${FETCH_BEFORE_ARGS} $${site}$${bfile} ${FETCH_AFTER_ARGS}; then \ + if [ -n "${FAILOVER_FETCH}" -a -f ${DISTINFO_FILE} -a -f ${_DISTDIR}/$$bfile ]; then \ + alg=`${AWK} 'NF == 4 && $$2 == "('$$file')" && $$3 == "=" {print $$1; exit}' ${DISTINFO_FILE}`; \ + if [ -z "$$alg" ]; then \ + alg=${PATCH_DIGEST_ALGORITHM};\ + fi; \ + CKSUM=`${DIGEST} $$alg < ${_DISTDIR}/$$bfile`; \ + CKSUM2=`${AWK} '$$1 == "'$$alg'" && $$2 == "('$$file')" {print $$4; exit}' <${DISTINFO_FILE}`; \ + if [ "$$CKSUM" = "$$CKSUM2" -o "$$CKSUM2" = "IGNORE" ]; then \ + break; \ + else \ + ${ECHO_MSG} "=> Checksum failure - trying next site."; \ + fi; \ + elif [ ! -f ${_DISTDIR}/$$bfile ]; then \ + ${ECHO_MSG} "=> FTP didn't fetch expected file, trying next site." ; \ + else \ + break; \ + fi; \ + fi \ + done; \ + if [ ! -f ${_DISTDIR}/$$bfile ]; then \ + ${ECHO_MSG} "=> Couldn't fetch $$bfile - please try to retrieve this";\ + ${ECHO_MSG} "=> file manually into ${_DISTDIR} and try again."; \ + exit 1; \ + fi; \ + fi + +_CHECK_DIST_PATH= \ + if [ "X${DIST_PATH}" != "X" ]; then \ + for d in "" ${DIST_PATH:S/:/ /g}; do \ + case $$d in "" | ${DISTDIR}) continue;; esac; \ + if [ -f $$d/${DIST_SUBDIR}/$$bfile ]; then \ + ${ECHO} "Using $$d/${DIST_SUBDIR}/$$bfile"; \ + ${RM} -f $$bfile; \ + ${LN} -s $$d/${DIST_SUBDIR}/$$bfile $$bfile; \ + break; \ + fi; \ + done; \ + fi + +# +# Set up ORDERED_SITES to work out the exact list of sites for every file, +# using the dynamic sites script, or sorting according to the master site +# list or the patterns in MASTER_SORT or MASTER_SORT_REGEX as appropriate. +# No actual sorting is done until ORDERED_SITES is expanded. +# +.if defined(MASTER_SORT) || defined(MASTER_SORT_REGEX) +MASTER_SORT?= +MASTER_SORT_REGEX?= +MASTER_SORT_REGEX+= ${MASTER_SORT:S/./\\./g:C/.*/:\/\/[^\/]*&\//} + +MASTER_SORT_AWK= BEGIN { RS = " "; ORS = " "; IGNORECASE = 1 ; gl = "${MASTER_SORT_REGEX:S/\\/\\\\/g}"; } +. for srt in ${MASTER_SORT_REGEX} +MASTER_SORT_AWK+= /${srt:C/\//\\\//g}/ { good["${srt:S/\\/\\\\/g}"] = good["${srt:S/\\/\\\\/g}"] " " $$0 ; next; } +. endfor +MASTER_SORT_AWK+= { rest = rest " " $$0; } END { n=split(gl, gla); for(i=1;i<=n;i++) { print good[gla[i]]; } print rest; } + +SORT_SITES_CMD= ${ECHO} $$unsorted_sites | ${AWK} '${MASTER_SORT_AWK}' +ORDERED_SITES= ${_MASTER_SITE_OVERRIDE} `${SORT_SITES_CMD:S/\\/\\\\/g:C/"/\"/g}` +.else +ORDERED_SITES= ${_MASTER_SITE_OVERRIDE} $$unsorted_sites +.endif + +# +# Associate each file to fetch with the correct site(s). +# +.if defined(DYNAMIC_MASTER_SITES) +. for fetchfile in ${_ALLFILES} +SITES_${fetchfile:T:S/=/--/}?= `${SH} ${FILESDIR}/getsite.sh ${fetchfile:T}` +SITES.${fetchfile:T:S/=/--/}?= ${SITES_${fetchfile:T:S/=/--/}} +. endfor +.endif +.if !empty(_DISTFILES) +. for fetchfile in ${_DISTFILES} +SITES_${fetchfile:T:S/=/--/}?= ${MASTER_SITES} +SITES.${fetchfile:T:S/=/--/}?= ${SITES_${fetchfile:T:S/=/--/}} +. endfor +.endif +.if !empty(_PATCHFILES) +. for fetchfile in ${_PATCHFILES} +SITES_${fetchfile:T:S/=/--/}?= ${PATCH_SITES} +SITES.${fetchfile:T:S/=/--/}?= ${SITES_${fetchfile:T:S/=/--/}} +. endfor +.endif + +# This code is only called in a batch case, to check for the presence of +# the distfiles +.PHONY: batch-check-distfiles +batch-check-distfiles: + ${_PKG_SILENT}${_PKG_DEBUG} \ + gotfiles=yes; \ + for file in "" ${_ALLFILES}; do \ + case "$$file" in \ + "") continue ;; \ + *) if [ ! -f ${DISTDIR}/$$file ]; then \ + gotfiles=no; \ + fi ;; \ + esac; \ + done; \ + case "$$gotfiles" in \ + no) ${ECHO} "*** This package requires user intervention to download the distfiles"; \ + ${ECHO} "*** Please fetch the distfiles manually and place them in"; \ + ${ECHO} "*** ${DISTDIR}"; \ + [ ! -z "${MASTER_SITES}" ] && \ + ${ECHO} "*** The distfiles are available from ${MASTER_SITES}"; \ + [ ! -z "${HOMEPAGE}" ] && \ + ${ECHO} "*** See ${HOMEPAGE} for more details"; \ + ${ECHO}; \ + ${TOUCH} ${_INTERACTIVE_COOKIE}; \ + ${FALSE} ;; \ + esac + +.PHONY: do-fetch +.if !target(do-fetch) +do-fetch: +. if !defined(ALLOW_VULNERABLE_PACKAGES) + ${_PKG_SILENT}${_PKG_DEBUG} \ + if [ -f ${PKGVULNDIR}/pkg-vulnerabilities ]; then \ + ${PHASE_MSG} "Checking for vulnerabilities in ${PKGNAME}"; \ + vul=`${MAKE} ${MAKEFLAGS} check-vulnerable`; \ + case "$$vul" in \ + "") ;; \ + *) ${ECHO} "$$vul"; \ + ${ECHO} "or define ALLOW_VULNERABLE_PACKAGES if this package is absolutely essential"; \ + ${FALSE} ;; \ + esac; \ + else \ + ${WARNING_MSG} "No ${PKGVULNDIR}/pkg-vulnerabilities file found,"; \ + ${WARNING_MSG} "skipping vulnerability checks. To fix, install"; \ + ${WARNING_MSG} "the pkgsrc/security/audit-packages package and run"; \ + ${WARNING_MSG} "\`\`${LOCALBASE}/sbin/download-vulnerability-list''."; \ + fi +. endif +. if !empty(_ALLFILES) + ${_PKG_SILENT}${_PKG_DEBUG} \ + ${TEST} -d ${_DISTDIR} || ${MKDIR} ${_DISTDIR} +. if !empty(INTERACTIVE_STAGE:Mfetch) && defined(BATCH) + ${_PKG_SILENT}${_PKG_DEBUG} \ + ${MAKE} ${MAKEFLAGS} batch-check-distfiles +. else +. for fetchfile in ${_ALLFILES} +. if defined(FETCH_MESSAGE) && !empty(FETCH_MESSAGE) + ${_PKG_SILENT}${_PKG_DEBUG} set -e; \ + ${TEST} -f ${DISTDIR:Q}/${fetchfile:Q} || { \ + h="==============="; h="$$h$$h$$h$$h$$h"; \ + ${ECHO} "$$h"; ${ECHO} ""; \ + for l in ${FETCH_MESSAGE}; do ${ECHO} "$$l"; done; \ + ${ECHO} ""; ${ECHO} "$$h"; \ + exit 1; \ + } +. elif defined(_FETCH_MESSAGE) + ${_PKG_SILENT}${_PKG_DEBUG} \ + file="${fetchfile}"; \ + if [ ! -f ${DISTDIR}/$$file ]; then \ + ${_FETCH_MESSAGE}; \ + fi +. else + ${_PKG_SILENT}${_PKG_DEBUG} \ + cd ${_DISTDIR}; \ + file="${fetchfile}"; \ + bfile="${fetchfile:T}"; \ + unsorted_sites="${SITES.${fetchfile:T:S/=/--/}} ${_MASTER_SITE_BACKUP}"; \ + sites="${ORDERED_SITES}"; \ + ${_CHECK_DIST_PATH}; \ + if ${TEST} "${PKG_RESUME_TRANSFERS:M[Yy][Ee][Ss]}" ; then \ + ${_FETCH_FILE}; ${_RESUME_TRANSFER}; \ + else \ + ${_FETCH_FILE}; \ + fi +. endif # defined(_FETCH_MESSAGE) +. endfor +. endif # INTERACTIVE_STAGE == fetch +. endif # !empty(_ALLFILES) +.endif + +.PHONY: show-distfiles +.if !target(show-distfiles) +show-distfiles: +. if defined(PKG_FAIL_REASON) + ${_PKG_SILENT}${_PKG_DEBUG}${DO_NADA} +. else + ${_PKG_SILENT}${_PKG_DEBUG} \ + for file in "" ${_CKSUMFILES}; do \ + if [ "X$$file" = "X" ]; then continue; fi; \ + ${ECHO} $$file; \ + done +. endif +.endif + +.if !target(pre-fetch) +pre-fetch: + @${DO_NADA} +.endif +.if !target(post-fetch) +post-fetch: + @${DO_NADA} +.endif + +# This is for the use of sites which store distfiles which others may +# fetch - only fetch the distfile if it is allowed to be +# re-distributed freely +.PHONY: mirror-distfiles +mirror-distfiles: +.if !defined(NO_SRC_ON_FTP) + @${_PKG_SILENT}${_PKG_DEBUG}${MAKE} ${MAKEFLAGS} fetch NO_SKIP=yes +.endif + +# Prints out a script to fetch all needed files (no checksumming). +.PHONY: fetch-list +.if !target(fetch-list) + +fetch-list: + @${ECHO} '#!/bin/sh' + @${ECHO} '#' + @${ECHO} '# This is an auto-generated script, the result of running' + @${ECHO} '# `${MAKE} fetch-list'"'"' in directory "'"`${PWD_CMD}`"'"' + @${ECHO} '# on host "'"`${UNAME} -n`"'" on "'"`date`"'".' + @${ECHO} '#' + @${MAKE} ${MAKEFLAGS} fetch-list-recursive +.endif # !target(fetch-list) + +.PHONY: fetch-list-recursive +.if !target(fetch-list-recursive) + +fetch-list-recursive: + ${_PKG_SILENT}${_PKG_DEBUG} \ + for dir in `${MAKE} ${MAKEFLAGS} show-all-depends-dirs`; do \ + (cd ../../$$dir && \ + ${MAKE} ${MAKEFLAGS} fetch-list-one-pkg \ + | ${AWK} ' \ + /^[^#]/ { FoundSomething = 1 } \ + /^unsorted/ { gsub(/[[:space:]]+/, " \\\n\t") } \ + /^echo/ { gsub(/;[[:space:]]+/, "\n") } \ + { block[line_c++] = $$0 } \ + END { if (FoundSomething) \ + for (line = 0; line < line_c; line++) \ + print block[line] } \ + ') \ + done +.endif # !target(fetch-list-recursive) + +.PHONY: fetch-list-one-pkg +.if !target(fetch-list-one-pkg) + +fetch-list-one-pkg: +. if !empty(_ALLFILES) + @${ECHO} + @${ECHO} '#' + @location=`${PWD_CMD} | ${AWK} -F / '{ print $$(NF-1) "/" $$NF }'`; \ + ${ECHO} '# Need additional files for ${PKGNAME} ('$$location')...' +. for fetchfile in ${_ALLFILES} +. if defined(_FETCH_MESSAGE) + @(if [ ! -f ${_DISTDIR}/${fetchfile:T} ]; then \ + ${ECHO}; \ + filesize=`${AWK} ' \ + /^Size/ && $$2 == "(${fetchfile})" { print $$4 } \ + ' ${DISTINFO_FILE}` || true; \ + ${ECHO} '# Prompt user to get ${fetchfile} ('$${filesize-???}' bytes) manually:'; \ + ${ECHO} '#'; \ + ${ECHO} ${_FETCH_MESSAGE:Q}; \ + fi) +. elif defined(DYNAMIC_MASTER_SITES) + @(if [ ! -f ${_DISTDIR}/${fetchfile:T} ]; then \ + ${ECHO}; \ + filesize=`${AWK} ' \ + /^Size/ && $$2 == "(${fetchfile})" { print $$4 } \ + ' ${DISTINFO_FILE}` || true; \ + ${ECHO} '# Fetch ${fetchfile} ('$${filesize-???}' bytes):'; \ + ${ECHO} '#'; \ + ${ECHO} '${SH} -s ${fetchfile:T} <<"EOF" |('; \ + ${CAT} ${FILESDIR}/getsite.sh; \ + ${ECHO} EOF; \ + ${ECHO} read unsorted_sites; \ + ${ECHO} 'unsorted_sites="$${unsorted_sites} ${_MASTER_SITE_BACKUP}"'; \ + ${ECHO} sites='"'${ORDERED_SITES:Q}'"'; \ + ${ECHO} "${MKDIR} ${_DISTDIR}"; \ + ${ECHO} 'cd ${_DISTDIR} && [ -f ${fetchfile} -o -f ${fetchfile:T} ] ||'; \ + ${ECHO} 'for site in $$sites; do'; \ + ${ECHO} ' ${FETCH_CMD} ${FETCH_BEFORE_ARGS} "$${site}${fetchfile:T}" ${FETCH_AFTER_ARGS} && break ||'; \ + ${ECHO} ' ${ECHO} ${fetchfile:T} not fetched'; \ + ${ECHO} done; \ + ${ECHO} ')'; \ + fi) +. else + @(if [ ! -f ${_DISTDIR}/${fetchfile:T} ]; then \ + ${ECHO}; \ + filesize=`${AWK} ' \ + /^Size/ && $$2 == "(${fetchfile})" { print $$4 } \ + ' ${DISTINFO_FILE}` || true; \ + ${ECHO} '# Fetch ${fetchfile} ('$${filesize-???}' bytes):'; \ + ${ECHO} '#'; \ + ${ECHO} 'unsorted_sites="${SITES.${fetchfile:T:S/=/--/}} ${_MASTER_SITE_BACKUP}"'; \ + ${ECHO} sites='"'${ORDERED_SITES:Q}'"'; \ + ${ECHO} "${MKDIR} ${_DISTDIR}"; \ + ${ECHO} 'cd ${_DISTDIR} && [ -f ${fetchfile} -o -f ${fetchfile:T} ] ||'; \ + ${ECHO} 'for site in $$sites; do'; \ + ${ECHO} ' ${FETCH_CMD} ${FETCH_BEFORE_ARGS} "$${site}${fetchfile:T}" ${FETCH_AFTER_ARGS} && break ||'; \ + ${ECHO} ' ${ECHO} ${fetchfile:T} not fetched'; \ + ${ECHO} done; \ + fi) +. endif # defined(_FETCH_MESSAGE) || defined(DYNAMIC_MASTER_SITES) +. endfor +. endif # !empty(_ALLFILES) +.endif # !target(fetch-list-one-pkg) |