#!/bin/sh # # Copyright 2011 iXsystems (Kris Moore) # 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. usage_add_pbi() { cat < -d portdir -- Use different ports dir (Default: /usr/ports) -h script -- Call the following helper script after each build -o outdir -- Where to place the finished PBI file(s) -p -- Number of PBI builds to run concurrently (Defaults to 1) -32 -- Build i386 PBIs on amd64 host --genpatch -- Generate patch files (*.pbp) from archived PBIs to current --keep -- Keep old versions in archive folder for each built PBI --prune -- Remove files from 'outdir' that no longer have a module --pkgcache -- Create and use a .txz pkg cache directory, in the of each PBI --tmpfs -- Use TMPFS for port WRKDIRPREFIX --sign key -- Sign the PBI(s) with specified openssl key EOF exit_trap } usage_create_pbi() { cat < EOF exit_trap } usage_deleterepo_pbi() { cat < EOF exit_trap } usage_mt_add() { cat </dev/null 2>/dev/null if [ -e "${PROGBASE}/etc/rc.d/pbid" ]; then ${PROGBASE}/etc/rc.d/pbid restart >/dev/null 2>/dev/null fi exit 0 ;; esac shift done } # Parse the command line for info parse_info_pbi_cmdline() { while [ $# -gt 0 ]; do case "$1" in -a) PBI_INFONAME="--ALL--" ;; -i) PBI_INFOINDEX="YES" ;; -v) PBI_VERBOSE="YES" ;; *) if [ $# -gt 1 ]; then usage_info_pbi; fi if [ ! -e "${PBI_DBAPPDIR}/${1}" ] ; then exit_err "can't find installed pbi (${1})" fi PBI_INFONAME="$1" ;; esac shift done if [ -z "${PBI_INFONAME}" ] ; then PBI_INFONAME="--ALL--" fi } # Parse the command line for patching parse_makepatch_pbi_cmdline() { while [ $# -gt 0 ]; do case "$1" in -o) if [ $# -eq 1 ]; then usage_makepatch_pbi; fi shift; PBI_PATCHOUTDIR="$1" ;; --sign) if [ $# -eq 1 ]; then usage_makepatch_pbi; fi shift; PBI_SSLPRIVKEY="$1" ;; --tmpfs) PBI_MP_TMPFS="YES" ;; --no-checksig) PBI_SKIPSIGVERIFY="YES" ;; *) if [ $# -gt 2 ]; then usage_makepatch_pbi; fi PBI_OLDFILENAME="$1" shift PBI_FILENAME="$1" ;; esac shift done if [ -z "${PBI_FILENAME}" ]; then usage_makepatch_pbi ; fi if [ -z "${PBI_OLDFILENAME}" ]; then usage_makepatch_pbi ; fi if [ -z "${PBI_PATCHOUTDIR}" ]; then PBI_PATCHOUTDIR=`pwd` ; fi # Load all the information about this PBI / PBP load_info_from_header } # Parse the command line for editing a meta file parse_mt_pbi_cmdline() { case $1 in add) PBI_MT_MODE="ADD" ; shift ; while [ $# -gt 0 ]; do case "$1" in --cat) PBI_MT_TYPE="CAT" ;; --app) PBI_MT_TYPE="APP" ;; -n) if [ $# -eq 1 ]; then usage_mt_add; fi shift; PBI_MT_ADDNAME="$1" ;; -i) if [ $# -eq 1 ]; then usage_mt_add; fi shift; PBI_MT_ADDICON="$1" ;; -d) if [ $# -eq 1 ]; then usage_mt_add; fi shift; PBI_MT_ADDDESC="$1" ;; -c) if [ $# -eq 1 ]; then usage_mt_add; fi shift; PBI_MT_ADDCAT="$1" ;; -a) if [ $# -eq 1 ]; then usage_mt_add; fi shift; PBI_MT_ADDAUTHOR="$1" ;; -u) if [ $# -eq 1 ]; then usage_mt_add; fi shift; PBI_MT_ADDURL="$1" ;; -l) if [ $# -eq 1 ]; then usage_mt_add; fi shift; PBI_MT_ADDLIC="$1" ;; -t) if [ $# -eq 1 ]; then usage_mt_add; fi shift; PBI_MT_ADDTYPE="$1" ;; -k) if [ $# -eq 1 ]; then usage_mt_add; fi shift; PBI_MT_ADDKEYWORDS="$1" ;; -r) PBI_MT_REQUIRESROOT="YES" ;; *) if [ $# -gt 1 ]; then usage_mt_add; fi PBI_MT_METAFILE="$1" ;; esac shift done if [ -z "${PBI_MT_METAFILE}" ] ; then usage_mt_add ; fi ;; rem) PBI_MT_MODE="REM" ; shift ; while [ $# -gt 0 ]; do case "$1" in --cat) PBI_MT_TYPE="CAT" ;; --app) PBI_MT_TYPE="APP" ;; -n) if [ $# -eq 1 ]; then usage_mt_rem; fi shift; PBI_MT_REMNAME="$1" ;; *) if [ $# -gt 1 ]; then usage_mt_rem; fi PBI_MT_METAFILE="$1" ;; esac shift done if [ -z "${PBI_MT_METAFILE}" ] ; then usage_mt_rem ; fi ;; *) usage_mt_unknown ;; esac if [ ! -f "${PBI_MT_METAFILE}" ] ; then exit_err "No such file ${PBI_MT_METAFILE}" fi # Sanity check the values case ${PBI_MT_MODE} in ADD) # Check the common values if [ -z "${PBI_MT_ADDNAME}" ] ; then usage_mt_add ; fi if [ -z "${PBI_MT_ADDICON}" ] ; then usage_mt_add ; fi if [ -z "${PBI_MT_ADDDESC}" ] ; then usage_mt_add ; fi if [ "$PBI_MT_TYPE" = "CAT" ]; then elif [ "$PBI_MT_TYPE" = "APP" ]; then if [ -z "${PBI_MT_ADDCAT}" ]; then usage_mt_add ; fi if [ -z "${PBI_MT_ADDAUTHOR}" ]; then usage_mt_add ; fi if [ -z "${PBI_MT_ADDURL}" ]; then usage_mt_add ; fi if [ -z "${PBI_MT_ADDLIC}" ]; then usage_mt_add ; fi if [ -z "${PBI_MT_ADDTYPE}" ]; then usage_mt_add ; fi if [ -z "${PBI_MT_ADDKEYWORDS}" ]; then usage_mt_add;fi else usage_mt_add fi ;; REM) if [ "$PBI_MT_TYPE" != "CAT" -a "$PBI_MT_TYPE" != "APP" ] then usage_mt_rem fi if [ -z "${PBI_MT_REMNAME}" ] ; then usage_mt_rem ; fi ;; esac } # Parse the command line for editing a index file parse_it_pbi_cmdline() { case $1 in add) PBI_IT_MODE="ADD" ; shift ; while [ $# -gt 0 ]; do case "$1" in -b) if [ $# -eq 1 ]; then usage_it_add; fi shift; PBI_IT_ADDBPVERS="$1" ;; -f) if [ $# -eq 1 ]; then usage_it_add; fi shift; PBI_IT_ADDFILE="$1" ;; -k) if [ $# -eq 1 ]; then usage_it_add; fi shift; PBI_IT_ADDKEEP="$1" ;; -u) if [ $# -eq 1 ]; then usage_it_add; fi shift; PBI_IT_ADDURL="$1" ;; *) if [ $# -gt 1 ]; then usage_it_add; fi PBI_IT_ADDINDEX="$1" ;; esac shift done ;; rem) PBI_IT_MODE="REM" ; shift ; while [ $# -gt 0 ]; do case "$1" in -m) if [ $# -eq 1 ]; then usage_it_rem; fi shift; PBI_IT_REMARCH="$1" ;; -n) if [ $# -eq 1 ]; then usage_it_rem; fi shift; PBI_IT_REMNAME="$1" ;; -v) if [ $# -eq 1 ]; then usage_it_rem; fi shift; PBI_IT_REMVER="$1" ;; *) if [ $# -gt 1 ]; then usage_it_rem; fi PBI_IT_REMINDEX="$1" ;; esac shift done ;; *) usage_it_unknown ;; esac # Sanity check the values case ${PBI_IT_MODE} in ADD) if [ -z "${PBI_IT_ADDFILE}" ] ; then usage_it_add ; fi if [ -z "${PBI_IT_ADDURL}" ] ; then usage_it_add ; fi if [ -z "${PBI_IT_ADDINDEX}" ] ; then usage_it_add ; fi if [ ! -f "${PBI_IT_ADDFILE}" ] ; then exit_err "No such file ${PBI_IT_ADDFILE}" fi if [ ! -f "${PBI_IT_ADDINDEX}" ] ; then exit_err "No such file ${PBI_IT_ADDINDEX}" fi if [ -n "${PBI_IT_ADDKEEP}" ] ; then expr ${PBI_IT_ADDKEEP} + 1 >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then exit_err "-k option must be a integer!" fi fi ;; REM) if [ -z "${PBI_IT_REMNAME}" ] ; then usage_it_rem ; fi if [ -z "${PBI_IT_REMVER}" ] ; then usage_it_rem ; fi if [ -z "${PBI_IT_REMARCH}" ] ; then usage_it_rem ; fi if [ -z "${PBI_IT_REMINDEX}" ] ; then usage_it_rem ; fi ;; esac } # Parse the command line for browsing a repo parse_browse_pbi_cmdline() { while [ $# -gt 0 ]; do case "$1" in --listcats) PBI_BROWSE_LISTCATS="YES" ;; --viewall) PBI_BROWSE_LISTALLPBI="YES" ;; -c) if [ $# -eq 1 ]; then usage_browse_pbi; fi shift; PBI_BROWSE_CAT="$1" ;; -s) if [ $# -eq 1 ]; then usage_browse_pbi; fi shift; PBI_BROWSE_SEARCH="$1" ;; *) if [ $# -gt 1 ]; then usage_browse_pbi; fi PBI_BROWSE_RID="$1" ;; esac shift done # Get / check the repoid if [ -n "${PBI_BROWSE_RID}" ] ; then ls ${PBI_DBREPODIR}/${PBI_BROWSE_RID}.* >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then exit_err "The specified repoid ${PBI_BROWSE_RID} does not exist!" fi else for _repo in `ls ${PBI_DBREPODIR} 2>/dev/null` do PBI_BROWSE_RID=`echo $_repo | cut -d '.' -f 1` break; done if [ -z "$PBI_BROWSE_RID" ] ; then exit_err "No available repos!" ; fi fi PBI_BROWSE_REPOMD5=`ls ${PBI_DBREPODIR}/${PBI_BROWSE_RID}.* 2>/dev/null | cut -d '.' -f 2` PBI_BROWSE_METAFILE=`ls ${PBI_DBINDEXDIR}/${PBI_BROWSE_REPOMD5}*meta 2>/dev/null` if [ -z "${PBI_BROWSE_METAFILE}" ] ; then exit_err "The specified repo has no meta-file." fi } # Parse the command line for listing repos parse_listrepo_pbi_cmdline() { while [ $# -gt 0 ]; do case "$1" in --up) PBI_LISTREPO_UP="YES" ;; --down) PBI_LISTREPO_DOWN="YES" ;; --mirror) if [ $# -eq 1 ]; then usage_listrepo_pbi; fi shift; PBI_LISTREPO_MIRROR="$1" ;; *) if [ $# -gt 1 ]; then usage_listrepo_pbi; fi PBI_LISTREPO_ID="$1" ;; esac shift done if [ "${PBI_LISTREPO_UP}" = "YES" -a "${PBI_LISTREPO_DOWN}" = "YES" ]; then exit_err "Options --up and --down can't both be used at once!" fi if [ "${PBI_LISTREPO_UP}" = "YES" -a -z "${PBI_LISTREPO_ID}" ]; then exit_err "Missing Repo ID to move up in priority." fi if [ "${PBI_LISTREPO_DOWN}" = "YES" -a -z "${PBI_LISTREPO_ID}" ]; then exit_err "Missing Repo ID to move down in priority." fi if [ -n "${PBI_LISTREPO_MIRROR}" -a -z "${PBI_LISTREPO_ID}" ]; then exit_err "Missing Repo ID to change a specific mirror URL." fi if [ -n "${PBI_LISTREPO_ID}" ] ; then ls ${PBI_DBREPODIR}/${PBI_LISTREPO_ID}.* >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then exit_err "The specified repoid ${PBI_LISTREPO_ID} does not exist!" fi fi } # Parse the command line for adding a new repo file parse_addrepo_pbi_cmdline() { while [ $# -gt 0 ]; do case "$1" in *) if [ $# -gt 1 ]; then usage_addrepo_pbi; fi PBI_ADDREPO_FILE="$1" ;; esac shift done if [ -z "$PBI_ADDREPO_FILE" ] ; then usage_addrepo_pbi fi if [ ! -f "$PBI_ADDREPO_FILE" ] ; then exit_err "Repo file ${PBI_ADDREPO_FILE} does not exist!" fi } # Parse the command line for deleting a repo parse_deleterepo_pbi_cmdline() { while [ $# -gt 0 ]; do case "$1" in *) if [ $# -gt 1 ]; then usage_deleterepo_pbi; fi PBI_DELREPO_ID="$1" ;; esac shift done if [ -z "$PBI_DELREPO_ID" ] ; then usage_deleterepo_pbi fi } # Parse the command line for making a new repo file parse_makerepo_pbi_cmdline() { while [ $# -gt 0 ]; do case "$1" in --key) if [ $# -eq 1 ]; then usage_makerepo_pbi; fi shift; PBI_MKREPO_KEY="$1" ;; --url) if [ $# -eq 1 ]; then usage_makerepo_pbi; fi shift; PBI_MKREPO_URL="$1" ;; --desc) if [ $# -eq 1 ]; then usage_makerepo_pbi; fi shift; PBI_MKREPO_DESC="$1" ;; --mirror) if [ $# -eq 1 ]; then usage_makerepo_pbi; fi shift; PBI_MKREPO_MIRROR="$1" ;; *) if [ $# -gt 1 ]; then usage_makerepo_pbi; fi PBI_MKREPO_OUTDIR="$1" ;; esac shift done if [ -z "${PBI_MKREPO_DESC}" ]; then usage_makerepo_pbi ; fi if [ -z "${PBI_MKREPO_KEY}" ]; then usage_makerepo_pbi ; fi if [ -z "${PBI_MKREPO_MIRROR}" ]; then usage_makerepo_pbi ; fi if [ -z "${PBI_MKREPO_URL}" ]; then usage_makerepo_pbi ; fi if [ -z "${PBI_MKREPO_OUTDIR}" ]; then PBI_MKREPO_OUTDIR="${HOME}"; fi if [ ! -f "${PBI_MKREPO_KEY}" ]; then exit_err "The key file ${PBI_MKREPO_KEY} does not exist." ; fi # Make sure we have a valid URL format echo "${PBI_MKREPO_URL}" | grep -q -e "^http://" -e "^https://" -e "^ftp://" if [ $? -ne 0 ] ; then exit_err "Repo URL must begin with http://, https://, or ftp://" fi } # Parse the command line for patching parse_patch_pbi_cmdline() { while [ $# -gt 0 ]; do case "$1" in -e) PBI_EXTRACTONLY="YES" ;; -g) PBI_ADD_GUIDISPLAY="YES" ;; -i) PBI_ADD_INFODISPLAY="YES" ;; -o) if [ $# -eq 1 ]; then usage_patch_pbi; fi shift; PBI_ALTEXTRACT_DIR="$1" ;; --checkscript) PBI_CHECKSCRIPTS="YES" ;; --no-hash) PBI_DISABLEHASHDIR="YES" ;; --no-checksum) PBI_SKIPCHECKSUM="YES" ;; --no-checksig) PBI_SKIPSIGVERIFY="YES" ;; *) if [ $# -gt 1 ]; then usage_patch_pbi; fi PBI_FILENAME="$1" ;; esac shift done if [ -z "${PBI_FILENAME}" ]; then usage_patch_pbi ; fi # Get the absolute patch to the file get_abspath "$PBI_FILENAME" PBI_FILENAME="$_ABSPATH" if [ ! -e "${PBI_FILENAME}" ]; then usage_patch_pbi ; fi # Load all the information about this PBI / PBP load_info_from_header # Make sure this isn't a patch file is_pbi_patch if [ "$?" = "1" ] ; then exit_err "This is not a PBP patch file" fi if [ -z "${PBI_ORIGPROGDIRPATH}" ]; then usage_patch_pbi ; fi # Lastly set PBI_PROGDIRNAME PBI_PROGDIRNAME="`echo ${PBI_ORIGPROGDIRPATH} | rev | cut -d '/' -f 1 | rev`" if [ "${PBI_EXTRACTONLY}" = "YES" ] ; then # If extracting to a alt-outdir, set it now PBI_PROGDIRPATH="`pwd`/${PBI_PROGDIRNAME}" if [ -n "${PBI_ALTEXTRACT_DIR}" ]; then PBI_PROGDIRPATH="${PBI_ALTEXTRACT_DIR}/${PBI_PROGDIRNAME}" fi else # Set the extraction dir PBI_PROGDIRPATH="${PBI_ORIGPROGDIRPATH}-patch" fi } # Parse the command line for adding parse_add_pbi_cmdline() { while [ $# -gt 0 ]; do case "$1" in -e) PBI_EXTRACTONLY="YES" ;; -f) PBI_FORCEADD="YES" ;; -g) PBI_ADD_GUIDISPLAY="YES" ;; -i) PBI_ADD_INFODISPLAY="YES" ;; -l) PBI_ADD_LICDISPLAY="YES" ;; -o) if [ $# -eq 1 ]; then usage_add_pbi; fi shift; PBI_ALTEXTRACT_DIR="$1" ;; -r) PBI_REMOTEFETCH="YES" ;; -R) PBI_REMOTEFETCH="YES" PBI_REMOTEFETCHONLY="YES" ;; -v) PBI_VERBOSE="YES" ;; --rArch) if [ $# -eq 1 ]; then usage_add_pbi; fi shift; PBI_ADD_ALTARCH="$1" ;; --rVer) if [ $# -eq 1 ]; then usage_add_pbi; fi shift; PBI_ADD_ALTVER="$1" ;; --checkscript) PBI_CHECKSCRIPTS="YES" ;; --licagree) PBI_LICAGREE="YES" ;; --no-hash) PBI_DISABLEHASHDIR="YES" ;; --no-checksum) PBI_SKIPCHECKSUM="YES" ;; --no-checksig) PBI_SKIPSIGVERIFY="YES" ;; --repo) if [ $# -eq 1 ]; then usage_add_pbi; fi shift; PBI_ADDREPO_ID="$1" ;; *) if [ $# -gt 1 ]; then usage_add_pbi; fi if [ ! -e "${1}" -a -z "$PBI_REMOTEFETCH" ] ; then exit_err "PBI file not found: (${1})" fi PBI_FILENAME="$1" ;; esac shift done if [ -z "${PBI_FILENAME}" ]; then usage_add_pbi ; fi # If we are doing a remote fetch / install then do it now if [ "$PBI_REMOTEFETCH" = "YES" ] ; then if [ -z "${PBI_ADDREPO_ID}" ] ; then PBI_ADDREPO_ID="AUTO" else ls ${PBI_DBREPODIR}/${PBI_ADDREPO_ID}.* >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then exit_err "No such repo ID: ${PBI_DELREPO_ID}" fi fi # Start fetching file pbi_add_fetch_remote fi # Load all the information about this PBI load_info_from_header if [ -z "${PBI_ORIGPROGDIRPATH}" ]; then usage_add_pbi ; fi # Make sure this isn't a patch file is_pbi_patch if [ "$?" = "0" ] ; then exit_err "This is a PBP patch file, use 'pbi_patch' instead" fi # Lastly set PBI_PROGDIRNAME PBI_PROGDIRNAME="`echo ${PBI_ORIGPROGDIRPATH} | rev | cut -d '/' -f 1 | rev`" if [ "${PBI_EXTRACTONLY}" = "YES" ] ; then # If extracting to a alt-outdir, set it now PBI_PROGDIRPATH="`pwd`/${PBI_PROGDIRNAME}" if [ -n "${PBI_ALTEXTRACT_DIR}" ]; then PBI_PROGDIRPATH="${PBI_ALTEXTRACT_DIR}/${PBI_PROGDIRNAME}" fi else # Set the installation dir PBI_PROGDIRPATH="${PBI_ORIGPROGDIRPATH}" fi } # Parse the command line parse_autob_pbi_cmdline() { while [ $# -gt 0 ]; do case "$1" in -c) if [ $# -eq 1 ]; then usage_autob_pbi; fi if [ -n "${PBI_AB_CONFDIR}" ]; then usage_autob_pbi; fi shift get_abspath "$1" PBI_AB_CONFDIR="$_ABSPATH" if [ ! -d "${PBI_AB_CONFDIR}" ] ; then exit_err "Invalid confdir (${PBI_AB_CONFDIR})" fi ;; -d) if [ $# -eq 1 ]; then usage_autob_pbi; fi shift get_abspath "$1" PORTSDIR="$_ABSPATH" ;; -o) if [ $# -eq 1 ]; then usage_autob_pbi; fi shift get_abspath "$1" PBI_AB_OUTDIR="$_ABSPATH" ;; -p) if [ $# -eq 1 ]; then usage_autob_pbi; fi shift PBI_AB_BUILDERS="$1" if [ ! $(is_num "$PBI_AB_BUILDERS") ] ; then exit_err "Invalid process number specifed!" fi ;; -h) if [ $# -eq 1 ]; then usage_autob_pbi; fi shift get_abspath "$1" PBI_AB_HELPS="$_ABSPATH" ;; -32) if [ "$REALARCH" != "amd64" ] ; then exit_err "-32 can only be used on amd64 host" fi PBI_AB32="YES" ARCH=i386 ;; --genpatch) PBI_AB_GENPATCH="YES" ;; --pkgcache) PBI_AB_PKGCACHE="YES" ;; --keep) if [ $# -eq 1 ]; then usage_autob_pbi; fi shift; PBI_AB_ARCHIVENUM="$1" expr $PBI_AB_ARCHIVENUM + 1 >/dev/null 2>/dev/null if [ $? != 0 ] ; then usage_autob_pbi; fi ;; --prune) PBI_AB_PRUNE="YES" ;; --tmpfs) PBI_AB_TMPFS="YES" ;; --sign) if [ $# -eq 1 ]; then usage_autob_pbi; fi shift; PBI_AB_SSLPRIVKEY="$1" ;; *) usage_autob_pbi ;; esac shift done if [ -z "$PBI_AB_OUTDIR" ] ; then usage_autob_pbi ; fi if [ -z "$PBI_AB_CONFDIR" ] ; then usage_autob_pbi ; fi } # Parse the command line parse_create_pbi_cmdline() { while [ $# -gt 0 ]; do case "$1" in -a) if [ $# -eq 1 ]; then usage_create_pbi; fi shift; PBI_CAUTHOR="$1" ;; -b) PBI_CBACKUP="YES" ;; -c) if [ $# -eq 1 ]; then usage_create_pbi; fi shift; get_abspath "$1" PBI_CONFDIR="$_ABSPATH" if [ ! -d "${PBI_CONFDIR}" ] ; then exit_err "Invalid confdir (${PBI_CONFDIR})" fi load_pbi_conffile ;; -d) if [ $# -eq 1 ]; then usage_create_pbi; fi shift; PORTSDIR="$1" ;; -i) if [ $# -eq 1 ]; then usage_create_pbi; fi shift; PBI_CICON="$1" ;; -n) if [ $# -eq 1 ]; then usage_create_pbi; fi shift; PBI_CNAME="$1" ;; -o) if [ $# -eq 1 ]; then usage_create_pbi; fi shift; PBI_CREATE_OUTDIR="$1" ;; -p) if [ $# -eq 1 ]; then usage_create_pbi; fi shift; PBI_MAKEPORT="$1" ;; -r) if [ $# -eq 1 ]; then usage_create_pbi; fi shift; PBI_CVERSION="$1" ;; -w) if [ $# -eq 1 ]; then usage_create_pbi; fi shift; PBI_CWEB="$1" ;; --no-hash) PBI_DISABLEHASHDIR="YES" ;; --sign) if [ $# -eq 1 ]; then usage_create_pbi; fi shift; PBI_SSLPRIVKEY="$1" ;; *) if [ $# -gt 1 ]; then usage_create_pbi; fi if [ "$PBI_CBACKUP" = "YES" ] ; then if [ ! -e "${PBI_DBAPPDIR}/${1}" ] ; then exit_err "can't find installed pbi (${1})" fi PBI_CBACKUPTARGET="${1}" PBI_PROGDIRPATH="${1}" else get_abspath "$1" PBI_PROGDIRPATH="$_ABSPATH" if [ ! -d "${PBI_PROGDIRPATH}" ] ; then exit_err "Invalid pbidir (${1})" fi fi ;; esac shift done # Make sure this port exists if [ -n "${PBI_MAKEPORT}" -a ! -d "${PORTSDIR}/${PBI_MAKEPORT}" ]; then exit_err "No port (${PORTSDIR}/${PBI_MAKEPORT})" fi # Load the name / version from specified port if [ -n "${PBI_MAKEPORT}" ]; then get_pbi_progversion get_pbi_progname fi if [ -z "${PBI_PROGDIRPATH}" ]; then usage_create_pbi ; fi # Lastly set PBI_PROGDIRNAME PBI_PROGDIRNAME="`echo ${PBI_PROGDIRPATH} | rev | cut -d '/' -f 1 | rev`" } # Override any pbi.conf values with passed command-line values parse_cmdline_overrides() { if [ -n "${PBI_CNAME}" ] ; then PBI_PROGNAME="${PBI_CNAME}" ; fi if [ -n "${PBI_CVERSION}" ] ; then PBI_PROGVERSION="${PBI_CVERSION}" ; fi if [ -n "${PBI_CWEB}" ] ; then PBI_PROGWEB="${PBI_CWEB}" ; fi if [ -n "${PBI_CAUTHOR}" ] ; then PBI_PROGAUTHOR="${PBI_CAUTHOR}" ; fi if [ -n "${PBI_CICON}" ] ; then PBI_PROGICON="${PBI_CICON}" ; fi } # Parse the command line parse_make_pbi_cmdline() { while [ $# -gt 0 ]; do case "$1" in -B) PBI_BUILDONLY="YES" ;; -c) if [ $# -eq 1 ]; then usage_make_pbi; fi if [ -n "${PBI_CONFDIR}" ]; then usage_make_pbi; fi shift get_abspath "$1" PBI_CONFDIR="$_ABSPATH" ;; -d) if [ $# -eq 1 ]; then usage_make_pbi; fi shift; PORTSDIR="$1" ; export PORTSDIR ;; -32) if [ "$REALARCH" != "amd64" -a "`basename $0`" != "pbi_makeport_chroot" ] ; then exit_err "-32 can only be used on amd64 host" fi ARCH=i386 ;; -k) PBI_KEEPBUILDFILES="YES" ;; --delbuild) MKDELBUILD="YES" ;; --no-prune) PBI_PRUNEBUILDPORTS="NO" ;; --mkdebug) MKDEBUG="YES" ;; --tmpfs) MKTMPFS="YES" ;; -o) if [ $# -eq 1 ]; then usage_make_pbi; fi shift get_abspath "$1" PBI_CREATE_OUTDIR="$_ABSPATH" ;; -p) if [ $# -eq 1 ]; then usage_make_pbi; fi if [ -n "${PBI_MAKEPREFIX}" ]; then usage_make_pbi; fi shift; PBI_MAKEPREFIX="$1" ;; --pkgdir) if [ $# -eq 1 ]; then usage_make_pbi; fi shift get_abspath "$1" PBI_PKGCACHEDIR="$_ABSPATH" PBI_PKGCACHE="YES" ;; --sign) if [ $# -eq 1 ]; then usage_make_pbi; fi shift get_abspath "$1" PBI_SSLPRIVKEY="$_ABSPATH" ;; *) if [ $# -gt 1 ]; then usage_make_pbi; fi PBI_MAKEPORT="$1" ;; esac shift done # Override some locations if working in chroot environment if [ "`basename $0`" = "pbi_makeport_chroot" ] ; then if [ -n "${PBI_CONFDIR}" ] ; then PBI_CONFDIR="/pbimodule" ; fi if [ -n "${PBI_SSLPRIVKEY}" ] ; then PBI_SSLPRIVKEY="/privkey.pem" ; fi if [ -n "${PBI_CREATE_OUTDIR}" ] ; then PBI_CREATE_OUTDIR="/pbiout" ; fi if [ -n "${PORTSDIR}" ] ; then PORTSDIR="/usr/ports" ; fi else # If running as pbi_makeport # Make sure the PBI_PKGCACHEDIR exists if [ -n "${PBI_PKGCACHEDIR}" -a ! -d "${PBI_PKGCACHEDIR}" ] ; then exit_err "No such directory: ${PBI_PKGCACHEDIR}" fi fi # Make sure this port exists if [ ! -d "${PORTSDIR}/${PBI_MAKEPORT}" ] ; then exit_err "No port (${PORTSDIR}/${PBI_MAKEPORT})" fi # Make sure we have a valid PBI_CONFDIR if [ -n "${PBI_CONFDIR}" -a ! -d "${PBI_CONFDIR}" ] ; then exit_err "Invalid confdir (${PBI_CONFDIR})" fi # Source the config file if [ -n "${PBI_CONFDIR}" ]; then load_pbi_conffile ; fi if [ -z "${PBI_MAKEPORT}" ]; then usage_make_pbi fi } # Parse the update command line parse_update_pbi_cmdline() { while [ $# -gt 0 ]; do case "$1" in -c) PBI_UPCHECK="YES" ;; --check-all) PBI_UPCHECK="ALL" ;; --disable-auto) PBI_UPENABLEAUTO="NO" ;; --enable-auto) PBI_UPENABLEAUTO="YES" ;; --update-all) PBI_UPDATEAPP="ALL" ;; *) if [ $# -gt 1 ]; then usage_update_pbi; fi if [ -n "$PBI_UPDATEAPP" ] ; then usage_update_pbi ; fi if [ ! -e "${PBI_DBAPPDIR}/${1}" ] ; then exit_err "can't find installed pbi (${1})" fi PBI_UPDATEAPP="$1" ;; esac shift done if [ "${PBI_UPDATEAPP}" = "ALL" -a -n "${PBI_UPCHECK}" ] ; then usage_update_pbi fi # Make sure we aren't trying to enable auto-updating for ALL if [ "${PBI_UPDATEAPP}" = "ALL" -a -n "${PBI_UPENABLEAUTO}" ] ; then usage_update_pbi fi if [ -z "${PBI_UPDATEAPP}" -a -n "${PBI_UPENABLEAUTO}" ] ; then usage_update_pbi fi if [ -z "${PBI_UPDATEAPP}" -a "${PBI_UPCHECK}" != "ALL" ]; then usage_update_pbi fi } # Make some of our required PBI dirs mk_required_dirs() { if [ ! -d "${PBI_APPDIR}" ] ; then mkdir -p ${PBI_APPDIR} >/dev/null 2>/dev/null ; fi if [ ! -d "${PBI_XDGCFGDIR}" ] ; then mkdir -p ${PBI_XDGCFGDIR} >/dev/null 2>/dev/null ; fi if [ ! -d "${PBI_XDGAPPDIR}" ] ; then mkdir -p ${PBI_XDGAPPDIR} >/dev/null 2>/dev/null ; fi if [ ! -d "${PBI_XDGDIRDIR}" ] ; then mkdir -p ${PBI_XDGDIRDIR} >/dev/null 2>/dev/null ; fi if [ ! -d "${PBI_XDGICONDIR}" ] ; then mkdir -p ${PBI_XDGICONDIR} >/dev/null 2>/dev/null ; fi if [ ! -d "${PBI_XDGMIMEDIR}" ] ; then mkdir -p ${PBI_XDGMIMEDIR} >/dev/null 2>/dev/null ; fi if [ ! -d "${PBI_RCDIR}" ] ; then mkdir -p ${PBI_RCDIR} >/dev/null 2>/dev/null ; fi if [ ! -d "${PBI_HASHDIR}" ] ; then mkdir -p ${PBI_HASHDIR} >/dev/null 2>/dev/null ; fi if [ ! -d "${PBI_DBAPPDIR}" ] ; then mkdir -p ${PBI_DBAPPDIR} >/dev/null 2>/dev/null ; fi if [ ! -d "${PBI_DBKEYDIR}" ] ; then mkdir -p ${PBI_DBKEYDIR} >/dev/null 2>/dev/null ; fi if [ ! -d "${PBI_DBMIRRORDIR}" ] ; then mkdir -p ${PBI_DBMIRRORDIR} >/dev/null 2>/dev/null ; fi if [ ! -d "${PBI_DBICONDIR}" ] ; then mkdir -p ${PBI_DBICONDIR} >/dev/null 2>/dev/null ; fi if [ ! -d "${PBI_DBINDEXDIR}" ] ; then mkdir -p ${PBI_DBINDEXDIR} >/dev/null 2>/dev/null ; fi if [ ! -d "${PBI_DBREPODIR}" ] ; then mkdir -p ${PBI_DBREPODIR} >/dev/null 2>/dev/null ; fi if [ ! -d "${PBI_DBHASHQUEUEDIR}" ] ; then mkdir -p ${PBI_DBHASHQUEUEDIR} >/dev/null 2>/dev/null ; fi # Set the permissions for directories if we are running as root if [ `id -u` != "0" ] ; then return ; fi for cDir in $PBI_APPDIR $PBI_DBAPPDIR $PBI_DBHASHQUEUEDIR $PBI_XDGCFGDIR $PBI_XDGAPPDIR $PBI_XDGDIRDIR $PBI_XDGICONDIR $PBI_XDGMIMEDIR do chown root:${PBI_INSTALLGROUP} ${cDir} chmod 775 ${cDir} done # Make sure the hash-dirty file can be written to by all touch ${PBI_DBDIRTYFILE} chown root:${PBI_INSTALLGROUP} ${PBI_DBDIRTYFILE} chmod 664 ${PBI_DBDIRTYFILE} } # Get the absolute path of a dir, even a realative dir. 'realpath' doesn't work here get_abspath() { D=`dirname "$1"` B=`basename "$1"` if [ "$D" = "/" ] ; then _ABSPATH="/$B" else _ABSPATH="`cd \"$D\" 2>/dev/null && pwd || echo \"$D\"`/$B" fi } # Initialize some vars init_vars() { # Set sys vars REALARCH="`uname -m`" ARCH="$REALARCH" # Where is pbi-manager installed? PROGBASE=/usr/local SYS_LOCALBASE=/usr/local if [ -z "${PBI_APPDIR}" -o "`basename $0`" = "pbi_makeport_chroot" ] ; then PBI_APPDIR="/usr/pbi" fi # Set the FreeBSD Major & Release FBSDREL=`uname -r` FBSDMAJOR=${FBSDREL%%.*} PBI_CHROOTFILE="${PBI_APPDIR}/.pbi-world-$ARCH.txz" if [ `id -u` = "0" ] ; then PBI_HASHDIR="${PBI_APPDIR}/.hashdir" else PBI_HASHDIR="${PBI_APPDIR}/.hashdir-`whoami`" fi PBI_AB_BUILDERS=1 PBI_XDGCFGDIR="${PBI_APPDIR}/etc/xdg/menus" PBI_XDGAPPDIR="${PBI_APPDIR}/share/applications" PBI_XDGDIRDIR="${PBI_APPDIR}/share/desktop-directories" PBI_XDGICONDIR="${PBI_APPDIR}/share/icons/hicolor" PBI_XDGMIMEDIR="${PBI_APPDIR}/share/mime/packages" PBI_RCDIR="${SYS_LOCALBASE}/etc/rc.d" PBI_ETCCONF="${SYS_LOCALBASE}/etc/pbi.conf" PCBSD_ETCCONF="${SYS_LOCALBASE}/etc/pcbsd.conf" PBI_DEFAULT_ICON="${PROGBASE}/share/pbi-manager/icons/default.png" PBI_DEFAULT_ICON_CHROOT="/default.png" PBI_PATCH_ICON="${PROGBASE}/share/pbi-manager/icons/patch.png" PBI_LDCONFIGFILE="${PROGBASE}/etc/ldpbiconfig" PBI_LDCONFIGRC="${PROGBASE}/etc/rc.d/ldpbiconfig" PROGVERSION="1.0" PBIDSLEEP="300" # Amount of time to sleep before waking up pbid PBI_LOG_LINES="500" PBI_INSTALLGROUP="operator" # What dirs do we build hash-lists of HASH_SEARCH_DIRS="lib kde4/lib share include info man" # What dbus dirs do we parse for setting up services DBUS_SEARCH_DIRS="share/dbus-1 kde4/share/dbus-1 gnome/share/dbus-1" # Don't modify unless you know what your doing! MOD_PREINS="pre-install.sh" MOD_POSTINS="post-install.sh" MOD_PREREM="pre-remove.sh" MOD_XDGDESK_DIR="xdg-desktop" MOD_XDGMENU_DIR="xdg-menu" MOD_XDGMIME_DIR="xdg-mime" MOD_EXTLINKFILE="external-links" MOD_AUTOEXTLINKFILE=".auto-external-links" PBI_ADD_GUIDISPLAY="NO" PBI_ADD_INFODISPLAY="NO" PBI_ADD_LICDISPLAY="NO" PBI_APPDESK_DIR=".${MOD_XDGDESK_DIR}" PBI_APPMENU_DIR=".${MOD_XDGMENU_DIR}" PBI_APPMIME_DIR=".${MOD_XDGMIME_DIR}" PBI_BUILD_USERS="" PBI_BUILD_GROUPS="" PBI_INS_USERSFILE=".pbi-uids" PBI_INS_GROUPSFILE=".pbi-gids" PBI_DESKADD="NO" PBI_MENUADD="NO" PBI_MIMEADD="NO" PBI_PATHADD="NO" PBI_DESKDEL="NO" PBI_MAKECONF="/etc/pbi-make.conf" PBI_MENUDEL="NO" PBI_MIMEDEL="NO" PBI_PATHDEL="NO" PBI_DELETENAME="" PBI_FAKEBIN_DIR=".sbin" PBI_FILENAME="" PBI_FORCEADD="NO" PBI_HASHLIST=".pbi-hash-list" PBI_INDEXREFRESH="24" # Hours to wait until we re-download PBI indexes PBI_INDEXUPFILE="pbi-index-$FBSDMAJOR" PBI_METAUPFILE="pbi-meta-$FBSDMAJOR" PBI_INFONAME="" PBI_INS_DESKSCRIPT="install-desktop-icons.sh" PBI_INS_MENUSCRIPT="install-menu-icons.sh" PBI_INS_MIMESCRIPT="install-mime.sh" PBI_INS_PATHSCRIPT="install-pathlinks.sh" PBI_ICDIR="pbi-shared-icons" PBI_LISTREPO_UP="" PBI_LISTREPO_DOWN="" PBI_LISTREPO_MIRROR="" PBI_LICAGREE="NO" PBI_LICENSEFILE="LICENSE" PBI_PATCHVERSION="" PBI_PATCHTARGET="" PBI_REMOTEFETCH="" PBI_REMOTEFETCHONLY="" PBI_RESOURCE_DIR="resources" PBI_SS_ICON="__PBI_ICON__" PBI_SS_ARCHIVE="__PBI_ARCHIVE__" PBI_SSLPRIVKEY="" PBI_TMPDIR="/tmp/.PBI.$$" PBI_TMPHASHLIST="" PBI_UPCHECK="" PBI_UPDATEAPP="" PBI_UNINS_DESKSCRIPT="uninstall-desktop-icons.sh" PBI_UNINS_MENUSCRIPT="uninstall-menu-icons.sh" PBI_UNINS_MIMESCRIPT="uninstall-mime.sh" PBI_UNINS_PATHSCRIPT="uninstall-pathlinks.sh" # User overridable variables MKDELBUILD="" MKDEBUG="" MKTMPFS="" PBI_AB_ARCHIVENUM="" PBI_AB_CONFDIR="" PBI_AB_GENPATCH="NO" PBI_AB_HELPS="" PBI_AB_OUTDIR="" PBI_AB_SSLPRIVKEY="" PBI_AB_PRUNE="" PBI_AB_TMPFS="" PBI_BUILDONLY="NO" PBI_CAUTHOR="" PBI_CBACKUP="" PBI_CBACKUPTARGET="" PBI_CHECKSCRIPTS="" PBI_CICON="" PBI_CNAME="" PBI_CONFDIR="" PBI_CONFFILE="pbi.conf" PBI_CONF_SCRIPTSDIR="scripts/" PBI_CREATE_OUTDIR="$HOME" PBI_CREATE_HASHLIST="YES" PBI_CUPDATE="" PBI_CWEB="" if [ -z "${PBI_DBDIR}" ] ; then PBI_DBDIR="/var/db/pbi" fi PBI_DBAPPDIR="${PBI_DBDIR}/installed" PBI_DBDIRTYFILE="${PBI_DBDIR}/.hashdirty" PBI_DBHASHQUEUEDIR="${PBI_DBDIR}/.hashqueue" PBI_DBICONDIR="${PBI_DBDIR}/repo-icons" PBI_DBINDEXDIR="${PBI_DBDIR}/index" PBI_DBKEYDIR="${PBI_DBDIR}/keys" PBI_DBMIRRORDIR="${PBI_DBDIR}/mirrors" PBI_DBREPODIR="${PBI_DBDIR}/repos" PBI_DISABLEHASHDIR="NO" PBI_GUITOPBANNER="gui_banner.png" PBI_GUISIDEBANNER="gui_sidebanner.png" PBI_KEEPBUILDFILES="NO" PBI_MAKEPORT="" PBI_MAKEPREFIX="" PBI_MAKEOPTS="" PBI_MKPORTBEFORE="" PBI_MKPORTAFTER="" PBI_PORTSDIR="" PBI_PROGAUTHOR="" PBI_PROGMDATE="" PBI_PROGEPOCH="" PBI_PROGNAME="" PBI_PROGDIRNAME="" PBI_PROGDIRPATH="" PBI_PROGICON="" PBI_PROGREVISION="" PBI_PROGVERSION="" PBI_PROGWEB="" PBI_PRUNEBUILDPORTS="YES" PBI_SKIPCHECKSUM="" PBI_SKIPSIGVERIFY="" PBI_USESYSGL="YES" PBI_USESYSFONTS="YES" PBI_VERBOSE="NO" PORTSDIR="/usr/ports" } detect_pkgng() { export PORTSDIR # Are we using pkgng? WITH_PKGNG=$(make -f ${PORTSDIR}/Mk/bsd.port.mk -V WITH_PKGNG) if [ -n "${WITH_PKGNG}" ]; then export PKGNG=1 export PKG_ADD="pkg add" export PKG_DELETE="pkg delete -y -f" else export PKGNG=0 export PKG_ADD=pkg_add export PKG_DELETE=pkg_delete fi } # Set and export vars used by module scripts export_script_vars() { # Load some initial values get_pbi_progdir get_pbi_progversion export PBI_PROGNAME PBI_PROGDIRNAME PBI_PROGDIRPATH PBI_PROGVERSION PBI_RCDIR export SYS_LOCALBASE PBI_FAKEBIN_DIR } # init tmpdir init_tmpdir() { if [ -d "${PBI_TMPDIR}" ] ; then return; fi if [ -z "${PBI_TMPDIR}" ] ; then return ; fi if [ "${PBI_TMPDIR}" = "/" ] ; then return ; fi if [ -e "${PBI_TMPDIR}" ] ; then rm -rf "${PBI_TMPDIR}" ; fi mkdir -p "${PBI_TMPDIR}" } # rm tmpdir rm_tmpdir() { if [ -z "${PBI_TMPDIR}" -o "${PBI_TMPDIR}" = "/" ] ; then return 0; fi if [ -e "${PBI_TMPDIR}" ] ; then rm -rf "${PBI_TMPDIR}" ; fi } # rm tmpdir rm_buildfiles() { if [ "${PBI_KEEPBUILDFILES}" = "YES" ] ; then return ; fi if [ -z "$PBI_CHROOTDIR" ] ; then return ; fi chroot_make_cleanup } # Load PBI conf options load_pbi_conffile() { if [ ! -d "${PBI_CONFDIR}" ] ; then return 0 ; fi if [ -e "${PBI_CONFDIR}/${PBI_CONFFILE}" ] ; then unset PBI_MAKEPORT PBI_BUILDKEY PBI_REQUIRESROOT PBI_PROGNAME PBI_PROGWEB PBI_PROGAUTHOR PBI_PROGICON PBI_MKPORTBEFORE PBI_MKPORTAFTER PBI_MAKEOPTS PBI_EXCLUDELIST PBI_AB_PRIORITY PBI_HASH_EXCLUDES PBI_AB_NOTMPFS PBI_PROGREVISION . ${PBI_CONFDIR}/${PBI_CONFFILE} fi } # Get the PBI_PROGVERSION get_pbi_progversion() { if [ -z "${PBI_PROGVERSION}" ] ; then load_pbi_conffile # If we have PBI_PROGVERSION now set if [ -n "${PBI_PROGVERSION}" ] ; then return 0 ; fi else return 0 fi if [ -z "${PBI_PROGVERSION}" -a -n "${PORTSDIR}" -a -n "${PBI_MAKEPORT}" ] ; then PORTVER="`make -C ${PORTSDIR}/${PBI_MAKEPORT} -V DISTVERSION PORTSDIR=${PORTSDIR} 2>/dev/null`" # Check if we have a portrevision to use in version number PORTREV="" PORTREV="`make -C ${PORTSDIR}/${PBI_MAKEPORT} -V PORTREVISION PORTSDIR=${PORTSDIR} 2>/dev/null`" if [ -n "${PORTREV}" -a "${PORTREV}" != "0" ] then PBI_PROGVERSION="${PORTVER}_${PORTREV}" else PBI_PROGVERSION="${PORTVER}" fi if [ -z "${PBI_PROGVERSION}" ] ; then echo "Warning: Unable to set PBI_PROGVERSION with:" echo "make -C ${PORTSDIR}/${PBI_MAKEPORT} -V DISTVERSION PORTSDIR=${PORTSDIR}" fi else echo "PBI_PROGVERSION - $PBI_PROGVERSION - PORTSDIR - ${PORTSDIR} - $PBI_MAKEPORT - $PBI_MAKE_PORT - pbi - $pbi" exit_err "Failed to locate PBI_PROGVERSION" fi # If we have a REVISION, use it as well if [ -n "$PBI_PROGREVISION" ] ; then PBI_PROGVERSION="${PBI_PROGVERSION}_${PBI_PROGREVISION}" fi } # Get the PBI_PROGNAME get_pbi_progname() { if [ -z "${PBI_PROGNAME}" -o "${PBI_PROGNAME}" = " " ] ; then load_pbi_conffile else return 0 fi if [ -z "${PBI_PROGNAME}" -a -n "${PORTSDIR}" -a -n "${PBI_MAKEPORT}" ] ; then # Get the proper package name from the prefix + name + suffix local pkgPrefix="`make -C ${PORTSDIR}/${PBI_MAKEPORT} -V PKGNAMEPREFIX PORTSDIR=${PORTSDIR}`" local pkgName="`make -C ${PORTSDIR}/${PBI_MAKEPORT} -V PORTNAME PORTSDIR=${PORTSDIR}`" local pkgSuffix="`make -C ${PORTSDIR}/${PBI_MAKEPORT} -V PKGNAMESUFFIX PORTSDIR=${PORTSDIR}`" PBI_PROGNAME="${pkgPrefix}${pkgName}${pkgSuffix}" else exit_err "Failed to locate PBI_PROGNAME" fi } # Get the PBI PROGDIR Name get_pbi_progdir() { if [ -z "${PBI_PROGNAME}" ] ; then get_pbi_progname fi tmp="`echo ${PBI_PROGNAME} | tr -d ' ' | tr '[A-Z]' '[a-z]'`" if [ -z "${PBI_PROGDIRNAME}" ] ; then PBI_PROGDIRNAME="${tmp}-${ARCH}" fi if [ -z "${PBI_PROGDIRPATH}" ] ; then PBI_PROGDIRPATH="${PBI_APPDIR}/${PBI_PROGDIRNAME}" fi } # Helper function to exit after a error, and do some cleanup exit_err() { echo -e "`basename ${0}`: ${1}" rm_tmpdir rm_buildfiles rm_pbipatchfiles chroot_make_cleanup clean_remote_dl exit 255 } # Check if we need to cleanup patch files rm_pbipatchfiles() { if [ -z "${_pbiNewDir}${_pbiOldDir}${_pbiPatchDir}" ] ; then return else echo "Cleaning up patch data..." fi # If we used tmpfs, unmount the dirs if [ "$PBI_MP_TMPFS" = "YES" ] ; then umount "${_pbiNewDir}" 2>/dev/null umount "${_pbiOldDir}" 2>/dev/null umount "${_pbiPatchDir}" 2>/dev/null fi if [ -n "${_pbiNewDir}" -a -d "${_pbiNewDir}" -a "${_pbiNewDir}" != "/" ] ; then rm -rf "${_pbiNewDir}" >/dev/null 2>/dev/null chflags -R noschg "${_pbiNewDir}" >/dev/null 2>/dev/null rm -rf "${_pbiNewDir}" >/dev/null 2>/dev/null fi if [ -n "${_pbiOldDir}" -a -d "${_pbiOldDir}" -a "${_pbiOldDir}" != "/" ] ; then rm -rf "${_pbiOldDir}" >/dev/null 2>/dev/null chflags -R noschg "${_pbiOldDir}" >/dev/null 2>/dev/null rm -rf "${_pbiOldDir}" >/dev/null 2>/dev/null fi if [ -n "${_pbiPatchDir}" -a -d "${_pbiPatchDir}" -a "${_pbiPatchDir}" != "/" ] ; then rm -rf "${_pbiPatchDir}" >/dev/null 2>/dev/null chflags -R noschg "${_pbiPatchDir}" >/dev/null 2>/dev/null rm -rf "${_pbiPatchDir}" >/dev/null 2>/dev/null fi } # Check if we need to delete a remotely dl'd file clean_remote_dl() { # If this was a remote fetch, remove dl'd file if [ "$PBI_REMOTEFETCH" = "YES" -a -n "$PBI_FILENAME" ]; then rm "$PBI_FILENAME" >/dev/null 2>/dev/null fi } # Set port make options from config set_make_options() { # Set the LOCALBASE LOCALBASE="${PBI_PROGDIRPATH}" if [ -e "${LOCALBASE}" ] ; then if [ "$MKDELBUILD" != "YES" ] ; then exit_err "${LOCALBASE} already exists! Delete it before doing a rebuild" else if [ -z "${LOCALBASE}" ] ; then exit_err "null LOCALBASE, this shouldn't happen" fi rm -rf "${LOCALBASE}" fi fi local MAKE_CONF="/etc/make.conf" echo "LOCALBASE=${LOCALBASE}" >> ${MAKE_CONF} echo "PACKAGE_BUILDING=yes" >> ${MAKE_CONF} echo "BATCH=yes" >> ${MAKE_CONF} echo "NO_IGNORE=yes" >> ${MAKE_CONF} echo "PACKAGE_BUILDING=yes" >> ${MAKE_CONF} echo "WRKDIRPREFIX=/usr/wrkdirprefix" >> ${MAKE_CONF} echo "DEPENDS_CLEAN=YES" >> ${MAKE_CONF} if [ -n "$PBI_MAKEOPTS" ] ; then # Check if we have custom make opts echo "${PBI_MAKEOPTS}" >> ${MAKE_CONF} fi # Link LOCALBASE -> /usr/local mkdir -p ${LOCALBASE} rm -rf /usr/local ln -s ${LOCALBASE} /usr/local # Make sure ldconfig is primed /etc/rc.d/ldconfig start # Check if using ccache directory if [ -d "/.ccache" ] ; then echo "Enabling ccache..." cd /usr/ports/devel/ccache make install clean if [ $? -eq 0 ] ; then # Setup environment variables CCACHE_PATH="/usr/bin:${LOCALBASE}/bin" export CCACHE_PATH CCACHE_DIR="/.ccache" export CCACHE_DIR PATH="${LOCALBASE}/libexec/ccache:${PATH}" export PATH # Setup make configuration echo ".if !defined(NO_CCACHE)" >> ${MAKE_CONF} echo " CC=${LOCALBASE}/libexec/ccache/world/cc" >> ${MAKE_CONF} echo " CXX=${LOCALBASE}/libexec/ccache/world/c++" >> ${MAKE_CONF} echo ".endif" >> ${MAKE_CONF} else echo "Failed installing ccache! Continuing without it..." fi fi PATH="${PATH}:/usr/local/bin:/usr/local/sbin:${LOCALBASE}/bin:${LOCALBASE}/sbin" export PATH FORCE_PKG_REGISTER="Y" export FORCE_PKG_REGISTER } # Confirm we are running as root require_root() { if [ `id -u` != "0" ] ; then exit_err "Must be run as root!" fi } # Confirm we are running as root or the proper group for installation require_root_or_group() { if [ `id -u` = "0" ] ; then return 0 ; fi touch ${PBI_APPDIR}/.ptest.$$ >/dev/null 2>/dev/null if [ "$?" = "0" ] ; then rm ${PBI_APPDIR}/.ptest.$$ >/dev/null 2>/dev/null return 0 fi exit_err "Must be run as root or a member of the $PBI_INSTALLGROUP group!" } # Function to get the username from a file get_username_from_file() { if [ -f "${1}" ] ; then FILEUSER=`ls -al ${1} | awk '{print $3}'` export FILEUSER return 0 fi if [ -d "${1}" ] ; then FILEUSER=`ls -al ${1} | grep -v "total" | head -n 1 | awk '{print $3}'` export FILEUSER return 0 fi exit_err "Invalid file for usercheck!" } # Start the make patch process pbi_makepatch_init() { require_root init_tmpdir parse_makepatch_pbi_cmdline "$@" # Create a new patch file from the two PBIs specified make_pbi_patchfile "${PBI_FILENAME}" "${PBI_OLDFILENAME}" "${PBI_PATCHOUTDIR}" } # Remove a repo from the DB pbi_deleterepo_init() { require_root parse_deleterepo_pbi_cmdline "$@" delete_pbi_repo } # Do the removal of a PBI repo delete_pbi_repo() { # Make sure this repo exists ls ${PBI_DBREPODIR}/${PBI_DELREPO_ID}.* >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then exit_err "No such repo ID: ${PBI_DELREPO_ID}" fi _md5=`ls ${PBI_DBREPODIR}/${PBI_DELREPO_ID}.* | sed "s|^${PBI_DBREPODIR}/${PBI_DELREPO_ID}.||g"` if [ -e "${PBI_DBREPODIR}/${PBI_DELREPO_ID}.${_md5}" ] ; then rm "${PBI_DBREPODIR}/${PBI_DELREPO_ID}.${_md5}" else echo "Warning: ${PBI_DELREPO_ID}.${_md5} does not exist in the database." fi if [ -e "${PBI_DBKEYDIR}/${_md5}.ssl" ] ; then rm "${PBI_DBKEYDIR}/${_md5}.ssl" else echo "Warning: ${_md5}.ssl does not exist in the keys database." fi if [ -e "${PBI_DBMIRRORDIR}/${_md5}" ] ; then rm "${PBI_DBMIRRORDIR}/${_md5}" else echo "Warning: ${_md5} does not exist in the mirror database." fi # See if we need to remove a downloaded index file if [ -e "${PBI_DBINDEXDIR}/${_md5}-index" ] ; then rm "${PBI_DBINDEXDIR}/${_md5}-index" rm "${PBI_DBINDEXDIR}/${_md5}-index.time" fi # Make sure we renumber the repos renumber_repos echo "Deleted Repository ${PBI_DELREPO_ID}." } # After deleting a repo, this can be run to renumber the IDs renumber_repos() { _rNum="1" for i in `ls ${PBI_DBREPODIR} | sort` do case `echo ${_rNum} | wc -m | tr -d ' '` in 2) _rNum="00${_rNum}" ;; 3) _rNum="0${_rNum}" ;; *) ;; esac _md5=`echo ${i} | cut -d '.' -f 2` mv "${PBI_DBREPODIR}/${i}" "${PBI_DBREPODIR}/${_rNum}.${_md5}" _rNum=`expr ${_rNum} + 1` done } # Add a new repo to the db pbi_addrepo_init() { require_root parse_addrepo_pbi_cmdline "$@" # Create a new repo file add_pbi_repo } # Extract the repo and add it to the DB add_pbi_repo() { init_tmpdir tar xvf "${PBI_ADDREPO_FILE}" -C ${PBI_TMPDIR} >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then exit_err "Failed to read ${PBI_ADDREPO_FILE}" fi if [ ! -f "${PBI_TMPDIR}/repokey.ssl" -o ! -f "${PBI_TMPDIR}/repo-url" -o ! -f "${PBI_TMPDIR}/repo-desc" -o ! -f "${PBI_TMPDIR}/repo-mirror" ] ; then exit_err "Improperly packaged repo file!" fi # Make sure we don't have a duplicate repo key for tr in ${PBI_PUBKEYS} do diff -q ${tr} ${PBI_TMPDIR}/repokey.ssl >/dev/null 2>/dev/null if [ "$?" = "0" ] ; then exit_err "Repo with identical key already registered!" fi done # Figure out the next repo number get_next_repo_num _md5=`md5 -q ${PBI_TMPDIR}/repo-url` _url=`cat ${PBI_TMPDIR}/repo-url` _desc=`cat ${PBI_TMPDIR}/repo-desc` echo "URL: ${_url}" > ${PBI_DBREPODIR}/${_rNum}.${_md5} echo "Desc: ${_desc}" >> ${PBI_DBREPODIR}/${_rNum}.${_md5} cp ${PBI_TMPDIR}/repo-mirror ${PBI_DBMIRRORDIR}/${_md5} cp "${PBI_TMPDIR}/repokey.ssl" "${PBI_DBKEYDIR}/${_md5}.ssl" chmod 755 "${PBI_DBKEYDIR}/${_md5}.ssl" rm_tmpdir echo "Added new repo: \"${_desc}\" to the database." } # Function to do listing of installed repos, and return next available number get_next_repo_num() { _rNum="0" for i in `ls ${PBI_DBREPODIR} | sort` do _rNum=`expr ${_rNum} + 1` done _rNum=`expr ${_rNum} + 1` case `echo ${_rNum} | wc -m | tr -d ' '` in 2) _rNum="00${_rNum}" ;; 3) _rNum="0${_rNum}" ;; *) ;; esac export _rNum } # Start the make patch process pbi_makerepo_init() { require_root parse_makerepo_pbi_cmdline "$@" # Create a new repo file make_pbi_repo } # Create the repo .rpo file make_pbi_repo() { init_tmpdir mkdir ${PBI_TMPDIR}/.mkrepo cp ${PBI_MKREPO_KEY} ${PBI_TMPDIR}/.mkrepo/repokey.ssl echo "${PBI_MKREPO_URL}" > ${PBI_TMPDIR}/.mkrepo/repo-url echo "${PBI_MKREPO_DESC}" > ${PBI_TMPDIR}/.mkrepo/repo-desc echo "${PBI_MKREPO_MIRROR}" | sed 's|,|\ |g' > ${PBI_TMPDIR}/.mkrepo/repo-mirror tar cvzf ${PBI_MKREPO_OUTDIR}/pbi-repo.rpo -C ${PBI_TMPDIR}/.mkrepo . >/dev/null 2>/dev/null echo "New PBI Repo created: ${PBI_MKREPO_OUTDIR}/pbi-repo.rpo" rm_tmpdir } # Init the metatool pbi_mt_init() { parse_mt_pbi_cmdline "$@" case $PBI_MT_MODE in ADD) if [ "$PBI_MT_TYPE" = "CAT" ] ; then do_pbi_mt_add_cat else do_pbi_mt_add_app fi ;; REM) if [ "$PBI_MT_TYPE" = "CAT" ] ; then do_pbi_mt_rem_cat "${PBI_MT_REMNAME}" "${PBI_MT_METAFILE}" else do_pbi_mt_rem_app "${PBI_MT_REMNAME}" "${PBI_MT_METAFILE}" fi ;; *) ;; esac } do_pbi_mt_add_cat() { init_tmpdir # Remove any duplicate name do_pbi_mt_rem_cat "${PBI_MT_ADDNAME}" "${PBI_MT_METAFILE}" cp ${PBI_MT_METAFILE} ${PBI_TMPDIR}/.meta.$$ echo "Cat=${PBI_MT_ADDNAME};${PBI_MT_ADDICON};${PBI_MT_ADDDESC};" \ >> ${PBI_TMPDIR}/.meta.$$ sort ${PBI_TMPDIR}/.meta.$$ > "${PBI_MT_METAFILE}" rm ${PBI_TMPDIR}/.meta.$$ } do_pbi_mt_add_app() { init_tmpdir # Remove any duplicate name do_pbi_mt_rem_app "${PBI_MT_ADDNAME}" "${PBI_MT_METAFILE}" cp ${PBI_MT_METAFILE} ${PBI_TMPDIR}/.meta.$$ echo "App=${PBI_MT_ADDNAME};${PBI_MT_ADDCAT};${PBI_MT_ADDICON};${PBI_MT_ADDAUTHOR};${PBI_MT_ADDURL};${PBI_MT_ADDLIC};${PBI_MT_ADDTYPE};${PBI_MT_ADDKEYWORDS};${PBI_MT_ADDDESC};$PBI_MT_REQUIRESROOT;" \ >> ${PBI_TMPDIR}/.meta.$$ sort ${PBI_TMPDIR}/.meta.$$ > "${PBI_MT_METAFILE}" rm ${PBI_TMPDIR}/.meta.$$ } do_pbi_mt_rem_cat() { sed -i '' "\|^Cat=${1};|d" "${2}" } do_pbi_mt_rem_app() { sed -i '' "\|^App=${1};|d" "${2}" } # Init the indextool pbi_it_init() { parse_it_pbi_cmdline "$@" case $PBI_IT_MODE in ADD) do_pbi_it_add ;; REM) do_pbi_it_rem ;; *) ;; esac } # Remove a target PBI from an index do_pbi_it_rem() { init_tmpdir _pbilow="`echo ${PBI_IT_REMNAME} | tr '[:upper:]' '[:lower:]' | sed 's| ||g'`" cat "${PBI_IT_REMINDEX}" | grep -v "^${_pbilow}:${PBI_IT_REMARCH}:${PBI_IT_REMVER}" \ > "${PBI_TMPDIR}/.indextmp" sort ${PBI_TMPDIR}/.indextmp > "${PBI_IT_REMINDEX}" rm_tmpdir } # Add a new PBI to the specified INDEX file do_pbi_it_add() { init_tmpdir # First load values from the target PBI PBI_FILENAME="$PBI_IT_ADDFILE" load_info_from_header # Get the name in lower-case _pbilow="`echo ${PBI_PROGNAME} | tr '[:upper:]' '[:lower:]' | sed 's| ||g'`" # Prune any old copies of this app from the index prune_from_index "$_pbilow" "$PBI_APPARCH" # Prune any old copies of this app from the index mark_current_active_index "$_pbilow" "$PBI_APPARCH" # Add the new index entry add_to_index rm_tmpdir } # Mark any current versions of this PBI as active in the index mark_current_active_index() { while read iLine do echo "$iLine" | grep "^${1}:${2}:" >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then echo "$iLine" >> ${PBI_TMPDIR}/.indextmp continue fi echo "$iLine" | sed 's|:current|:active|' >> ${PBI_TMPDIR}/.indextmp done < $PBI_IT_ADDINDEX mv "${PBI_TMPDIR}/.indextmp" "${PBI_IT_ADDINDEX}" } # Add the specified PBI to the index add_to_index() { mv "${PBI_IT_ADDINDEX}" "${PBI_TMPDIR}/.indextmp" local _date=`date '+%s'` local _sha256=`sha256 -q ${PBI_FILENAME}` local _psize=`du -k ${PBI_FILENAME} | cut -f 1` echo "${_pbilow}:${PBI_APPARCH}:${PBI_PROGVERSION}:${_sha256}:${PBI_PROGMDATE}:${PBI_IT_ADDURL}:$_date:${PBI_IT_ADDBPVERS}:current:${_psize}:" >>"${PBI_TMPDIR}/.indextmp" sort ${PBI_TMPDIR}/.indextmp > "${PBI_IT_ADDINDEX}" } # Remove a set number of PBIs from the index prune_from_index() { if [ -z "$PBI_IT_ADDKEEP" ]; then return ; fi local found="0" local added="0" while read iLine do echo "$iLine" | grep "^${1}:${2}:" >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then # Ready to add back the saved lines if [ $found -ne 0 ] ; then while read fLine do if [ $found -le $PBI_IT_ADDKEEP ] ; then echo "$fLine" >> ${PBI_TMPDIR}/.indextmp fi found=`expr $found - 1` done < ${PBI_TMPDIR}/.foundtmp fi echo "$iLine" >> ${PBI_TMPDIR}/.indextmp continue fi found=`expr $found + 1` echo "$iLine" >> ${PBI_TMPDIR}/.foundtmp done < $PBI_IT_ADDINDEX mv "${PBI_TMPDIR}/.indextmp" "${PBI_IT_ADDINDEX}" } # Add a new repo to the db pbi_browser_init() { parse_browse_pbi_cmdline "$@" init_tmpdir # Check if we are doing a category listing, the default if no options if [ "$PBI_BROWSE_LISTCATS" = "YES" -o -z "${PBI_BROWSE_LISTALLPBI}${PBI_BROWSE_CAT}${PBI_BROWSE_SEARCH}" ] ; then pbi_browse_listcats else pbi_browse_listpbi fi } # List PBIs from a repo pbi_browse_listpbi() { _rArch=`uname -m` # Figure out which type of display we are doing if [ -n "$PBI_BROWSE_LISTALLPBI" ] ; then echo "Using RepoID: $PBI_BROWSE_RID" echo "Listing all available PBIs" grep -i -e "^App=" $PBI_BROWSE_METAFILE > ${PBI_TMPDIR}/.meta.$$ elif [ -n "$PBI_BROWSE_CAT" ] ; then echo "Using RepoID: $PBI_BROWSE_RID" echo "Available PBIs for Category: $PBI_BROWSE_CAT" grep -i -e "^App=" -i -e ";${PBI_BROWSE_CAT};" $PBI_BROWSE_METAFILE > ${PBI_TMPDIR}/.meta.$$ elif [ -n "$PBI_BROWSE_SEARCH" ] ; then echo "Using RepoID: $PBI_BROWSE_RID" echo "Searching for: $PBI_BROWSE_SEARCH" grep -i -e "^App=" $PBI_BROWSE_METAFILE > ${PBI_TMPDIR}/.meta.$$ else exit_err "No valid search variable set!" fi while read app do line=`echo $app | sed 's|^App=||g'` catCheck=`echo $line | cut -d ';' -f 2 2>/dev/null` aName=`echo $line | cut -d ';' -f 1 2>/dev/null` # Make sure this is from the correct category if [ -n "$PBI_BROWSE_CAT" ] ; then _cCheck=`echo $catCheck | tr '[:lower:]' '[:upper:]'` _cCheck2=`echo $PBI_BROWSE_CAT | tr '[:lower:]' '[:upper:]'` if [ "$_cCheck" != "$_cCheck2" ]; then continue fi fi # Set the displayed arch type aArch="$_rArch" # Make sure this application has an associated PBI available check_pbi_update "$aName" "nodisplay" \ "$aName" "current" \ "$FBSDMAJOR" "$_rArch" "${PBI_BROWSE_RID}" if [ "$?" != "0" ] ; then # On amd64, see if 32bit version exists if [ "$_rArch" = "amd64" ] ; then check_pbi_update "$aName" "nodisplay" \ "$aName" "current" \ "$FBSDMAJOR" "i386" "${PBI_BROWSE_RID}" if [ "$?" != "0" ] ; then continue else # Found a 32bit version of the app aArch="i386" fi else # Not on amd64, continue on continue fi fi aIcon=`echo $line | cut -d ';' -f 3` aAuthor=`echo $line | cut -d ';' -f 4` aUrl=`echo $line | cut -d ';' -f 5` aLic=`echo $line | cut -d ';' -f 6` aType=`echo $line | cut -d ';' -f 7` aKeywords=`echo $line | cut -d ';' -f 8` aDesc=`echo $line | cut -d ';' -f 9` aRoot=`echo $line | cut -d ';' -f 10` # Check for a translation to the description get_meta_trans "App" "$cName" "${PBI_BROWSE_METAFILE}" if [ -n "$MTRANS" ] ; then aDesc="$MTRANS" fi # Search the description / keywords if [ -n "$PBI_BROWSE_SEARCH" ] ; then echo "$aName,$aDesc,$aKeywords,$MTRANS" | grep -i "$PBI_BROWSE_SEARCH" >/dev/null 2>/dev/null if [ "$?" != "0" ]; then continue ; fi fi # Get the local icon file ext=`echo $aIcon | sed 's/.*\.//'` aIcon="${PBI_DBICONDIR}/${PBI_BROWSE_REPOMD5}-${aName}.${ext}" echo "------------------------------------" echo "Application: $aName" echo "Version: $PBI_UPNVER" if [ -n "$PBI_UPSIZE" ] ; then echo "Size: $PBI_UPSIZE" fi if [ -n "$PBI_BROWSE_LISTALLPBI" ] ; then echo "Category: $catCheck" fi echo "Created: `echo $PBI_UPMDATE`" if [ "$aRoot" = "YES" ] ; then echo "RootInstall: YES" else echo "RootInstall: NO" fi echo "Arch: $aArch" echo "Author: $aAuthor" echo "URL: $aUrl" echo "License: $aLic" echo "Type: $aType" echo "Keywords: $aKeywords" echo "Icon: $aIcon" echo "Description: $aDesc" echo "" if [ "$aRoot" = "YES" ] ; then echo "To install this PBI (As Root):" else echo "To install this PBI:" fi echo "# pbi_add --rArch $aArch --repo $PBI_BROWSE_RID -r $aName" echo "" done < ${PBI_TMPDIR}/.meta.$$ } # List available categories for this repository pbi_browse_listcats() { echo "Using RepoID: $PBI_BROWSE_RID" echo "Available Categories:" grep "^Cat=" $PBI_BROWSE_METAFILE > ${PBI_TMPDIR}/.meta.$$ while read cat do line=`echo $cat | sed 's|^Cat=||g'` cName=`echo $line | cut -d ';' -f 1` cIcon=`echo $line | cut -d ';' -f 2` cDesc=`echo $line | cut -d ';' -f 3` # Check for a translation to the description get_meta_trans "Cat" "$cName" "${PBI_BROWSE_METAFILE}" if [ -n "$MTRANS" ] ; then cDesc="$MTRANS" fi # Get the local icon file ext=`echo $cIcon | sed 's/.*\.//'` cIcon="${PBI_DBICONDIR}/${PBI_BROWSE_REPOMD5}-${cName}.${ext}" echo "------------------------------------" echo "Category: $cName" echo "Icon: $cIcon" echo "Description: $cDesc" echo "" done < ${PBI_TMPDIR}/.meta.$$ echo "To view available PBIs for a particular category:" echo " % pbi_browser -c " } # Function to check if we have a translated description get_meta_trans() { local tag="$1" local name="$2" local metaFile="$3" # Check if we have a translation to overwrite with MTRANS="" if [ -z "$LANG" ] ; then return; fi lCheck="`echo $LANG | cut -d '_' -f 1` `echo $LANG | cut -d '.' -f 1`" for l in $lCheck do catTrans=`grep "^${tag}\[$l\]=${name}" ${metaFile}` if [ -n "$catTrans" ] ; then MTRANS=`echo $catTrans | cut -d ";" -f 2` return fi done } # List repos in the db pbi_listrepo_init() { require_root_or_group parse_listrepo_pbi_cmdline "$@" # List the repos if [ -z "$PBI_LISTREPO_ID" ] ; then list_all_pbi_repo else if [ -n "${PBI_LISTREPO_UP}" ]; then require_root move_repo_up "${PBI_LISTREPO_ID}" list_all_pbi_repo elif [ -n "${PBI_LISTREPO_DOWN}" ] ; then require_root move_repo_down "${PBI_LISTREPO_ID}" list_all_pbi_repo elif [ -n "${PBI_LISTREPO_MIRROR}" ] ; then require_root change_repo_mirror "${PBI_LISTREPO_ID}" listrepo_details "${PBI_LISTREPO_ID}" else listrepo_details "${PBI_LISTREPO_ID}" fi fi } # Function to change a specific repos mirror URL change_repo_mirror() { local _rMd5=`ls ${PBI_DBREPODIR}/${1}.* | cut -d '.' -f 2` echo "$PBI_LISTREPO_MIRROR" | sed 's|,|\ |g' > "${PBI_DBMIRRORDIR}/${_rMd5}" } # Move a repo down in priority move_repo_down() { _rFile=`ls ${PBI_DBREPODIR}/${1}.*` _uNum=`expr ${1} + 1` case `echo ${_uNum} | wc -m | tr -d ' '` in 2) _uNum="00${_uNum}" ;; 3) _uNum="0${_uNum}" ;; *) ;; esac _uFile=`ls ${PBI_DBREPODIR}/${_uNum}.* 2>/dev/null` if [ -z "$_uFile" ] ; then exit_err "This repo is already at the lowest priority!" ; fi _umd5=`echo $_uFile | cut -d '.' -f 2` mv "${_uFile}" "${PBI_DBREPODIR}/${1}.${_umd5}" _rmd5=`echo $_rFile | cut -d '.' -f 2` mv "${_rFile}" "${PBI_DBREPODIR}/${_uNum}.${_rmd5}" } # Move a repo up in priority move_repo_up() { _rFile=`ls ${PBI_DBREPODIR}/${1}.*` _uNum=`expr ${1} - 1` case `echo ${_uNum} | wc -m | tr -d ' '` in 2) _uNum="00${_uNum}" ;; 3) _uNum="0${_uNum}" ;; *) ;; esac _uFile=`ls ${PBI_DBREPODIR}/${_uNum}.* 2>/dev/null` if [ -z "$_uFile" ] ; then exit_err "This repo is already at the highest priority!" ; fi _umd5=`echo $_uFile | cut -d '.' -f 2` mv "${_uFile}" "${PBI_DBREPODIR}/${1}.${_umd5}" _rmd5=`echo $_rFile | cut -d '.' -f 2` mv "${_rFile}" "${PBI_DBREPODIR}/${_uNum}.${_rmd5}" } # List all PBI repos listrepo_details() { _rFile=`ls ${PBI_DBREPODIR}/${1}.*` _md5=`ls ${PBI_DBREPODIR}/${1}.* | cut -d '.' -f 2` _desc=`cat ${_rFile} | grep "Desc: " | sed "s|Desc: ||g"` _url=`cat ${_rFile} | grep "URL: " | sed "s|URL: ||g"` _mirror=`cat ${PBI_DBMIRRORDIR}/$_md5` echo "Repo ID: ${1}" echo "Description: ${_desc}" echo "IndexURL: ${_url}" echo "MD5: ${_md5}" echo "LocalMeta: `ls ${PBI_DBINDEXDIR}/${_md5}*meta 2>/dev/null`" echo "LocalIndex: `ls ${PBI_DBINDEXDIR}/${_md5}*index 2>/dev/null`" echo "Mirror(s):" echo "$_mirror" } # List all PBI repos list_all_pbi_repo() { echo "[ID] [Description]" echo "-----------------------------------------------------" for repo in `ls ${PBI_DBREPODIR} | sort ` do _id=`echo $repo | cut -d '.' -f 1` _desc=`cat ${PBI_DBREPODIR}/${repo} | grep "Desc: " | sed "s|Desc: ||g"` echo "${_id} ${_desc}" done } # Start the patch process pbi_patch_init() { require_root_or_group init_tmpdir parse_patch_pbi_cmdline "$@" # Check if we are only displaying information check_pbi_info_display check_pbi_gui_display check_pbi_scripts_display check_pbi_license_display if [ "$PBI_ADD_GUIDISPLAY" = "YES" -o "$PBI_ADD_INFODISPLAY" = "YES" -o "$PBI_CHECKSCRIPTS" = "YES" -o "${PBI_ADD_LICDISPLAY}" = "YES" ] then exit_trap fi # Try to apply this patch file do_pbi_patch } # Start the PBI patch process do_pbi_patch() { # Verify the target PBI is installed verify_pbi_update_target pbi_verify_signatures pbi_verify_archivesum # Extract the archive contents mk_pbi_extract_dir pbi_extract_archive set_patch_wrkdir init_tmpdir # Run the uninstall script if [ -e "${PBI_PATCHWRKDIR}/.sbin/.pbi-uninstall.sh" ] ; then echo "Removing old xdg data..." sh "${PBI_PATCHWRKDIR}/.sbin/.pbi-uninstall.sh" >/dev/null 2>/dev/null fi # Remove old files from the installed PBI patch_rm_old_files # Extract the new files patch_extract_new_files # Merge in the bsdiffs patch_merge_bsdiffs # Make sure we have good permissions on this PBI patch_apply_chmod # Run the install script if [ -e "${PBI_PATCHWRKDIR}/.sbin/.pbi-install.sh" ] ; then echo "Adding new xdg data..." sh "${PBI_PATCHWRKDIR}/.sbin/.pbi-install.sh" >/dev/null 2>/dev/null fi # If running as user, add bin path-links if [ "`id -u`" != "0" ] ; then add_app_path_links "${PBI_PATCHWRKDIR}" ; fi # Update the registered version of the PBI _pbilow="`echo ${PBI_PROGNAME} | tr '[:upper:]' '[:lower:]' | sed 's| ||g'`" oldDir="${PBI_DBAPPDIR}/${_pbilow}-${PBI_PATCHTARGET}-${PBI_APPARCH}" newDir="${PBI_DBAPPDIR}/${_pbilow}-${PBI_PATCHVERSION}-${PBI_APPARCH}" mv "$oldDir" "$newDir" rm ${newDir}/*.sha1 >/dev/null 2>/dev/null # Register the app pbi_add_register_app # Check if we need to run a post-install.sh script again if [ -e "${newDir}/${MOD_POSTINS}" ] ; then export_script_vars sh "${newDir}/${MOD_POSTINS}" fi # Cleanup after our selves if [ -d "$PBI_EXTRACTDIR" ] ; then echo "Cleaning up..." rm -rf "$PBI_EXTRACTDIR" fi # Update the hashdir add_hashdir_trigger # Mark the hash-dir as dirty as well make_hashdir_dirty echo "Finished patching ${_pbilow}: $PBI_PATCHTARGET -> $PBI_PATCHVERSION" } # Mark the hashdir as dirty make_hashdir_dirty() { date "+%s" > "${PBI_DBDIRTYFILE}" } # Do any chmod stuff after patching patch_apply_chmod() { if [ ! -e "${PBI_EXTRACTDIR}/PBI-permList" ] ; then return; fi cuDir=`pwd` cd "${PBI_PATCHWRKDIR}" echo "Applying updated permissions..." while read chLine do $chLine >/dev/null 2>/dev/null done < "${PBI_EXTRACTDIR}/PBI-permList" cd "$cuDir" } # Function which does the merge of bsdiff files patch_merge_bsdiffs() { echo "Applying patch data..." find ${PBI_EXTRACTDIR} | grep '.bsdiff' | sed "s|${PBI_EXTRACTDIR}/||g" > ${PBI_TMPDIR}/.PBI.bspatch.$$ while read pLine do if [ -z "$pLine" ] ; then continue; fi _tFile="`echo $pLine | sed 's|.bsdiff$||g'`" if [ ! -e "${PBI_EXTRACTDIR}/${_tFile}.sha256" ] ; then exit_err "Missing checksums for \"${_tFile}\" this patch is corrupt" fi if [ ! -e "${PBI_PATCHWRKDIR}/${_tFile}" ] ; then echo "Warning: Missing target file for patching: $_tFile" continue fi # Make sure we really are trying to patch the same file sha1="`sha256 -q ${PBI_PATCHWRKDIR}/${_tFile}`" sha2="`cat ${PBI_EXTRACTDIR}/${_tFile}.sha256`" if [ "$sha1" != "$sha2" ] ; then echo "Warning: Checksum failed for ${_tFile}, skipping." continue fi _fPerm=`stat -f %Op "${PBI_PATCHWRKDIR}/${_tFile}" | cut -c 3-6` # See if we have a hard-link to take care of first get_hard_link_count "${PBI_PATCHWRKDIR}/${_tFile}" if [ "$HLINKS" != "1" ] ; then mv "${PBI_PATCHWRKDIR}/${_tFile}" "${PBI_PATCHWRKDIR}/${_tFile}.patch.$$" cp "${PBI_PATCHWRKDIR}/${_tFile}.patch.$$" "${PBI_PATCHWRKDIR}/${_tFile}" rm -f "${PBI_PATCHWRKDIR}/${_tFile}.patch.$$" fi # Now do the patching #echo "Patching $_tFile" mv "${PBI_PATCHWRKDIR}/${_tFile}" "${PBI_PATCHWRKDIR}/${_tFile}.patch.$$" bspatch "${PBI_PATCHWRKDIR}/${_tFile}.patch.$$" \ "${PBI_PATCHWRKDIR}/${_tFile}" \ "${PBI_EXTRACTDIR}/$pLine" >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then echo "Warning: Failed to apply patch to \"$_tFile\"" fi # Re-apply the same permissions to the new file chmod $_fPerm "${PBI_PATCHWRKDIR}/${_tFile}" # Remove the old file rm "${PBI_PATCHWRKDIR}/${_tFile}.patch.$$" done < "${PBI_TMPDIR}/.PBI.bspatch.$$" rm "${PBI_TMPDIR}/.PBI.bspatch.$$" } # Function which does the new file extraction for this PBI patch_extract_new_files() { if [ ! -e "${PBI_EXTRACTDIR}/PBI-newFiles.tar" ] ; then return; fi echo "Installing new files..." tar xvf "${PBI_EXTRACTDIR}/PBI-newFiles.tar" -C "${PBI_PATCHWRKDIR}" >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then echo "Warning: Error during new file extraction, PBI may not function correctly." fi } # Function which removes files that no longer exist in this updated PBI patch_rm_old_files() { if [ ! -e "${PBI_EXTRACTDIR}/PBI-rmList" ] ; then return; fi echo "Removing old files..." while read rmLine do if [ -z "$rmLine" ] ; then continue ; fi if [ ! -e "${PBI_PATCHWRKDIR}/$rmLine" ] ; then continue fi rm -rf "${PBI_PATCHWRKDIR}/${rmLine}" done < "${PBI_EXTRACTDIR}/PBI-rmList" } # Sets the workdir of the target PBI we are patching set_patch_wrkdir() { _pbilow="`echo ${PBI_PROGNAME} | tr '[:upper:]' '[:lower:]' | sed 's| ||g'`" oldDir="${PBI_DBAPPDIR}/${_pbilow}-${PBI_PATCHTARGET}-${PBI_APPARCH}" if [ ! -e "${oldDir}/pbi_defaultpath" ] ; then exit_err "Can not fild default path for \"$PBI_PROGNAME\"!" fi PBI_PATCHWRKDIR="`cat ${oldDir}/pbi_defaultpath`" if [ ! -d "$PBI_PATCHWRKDIR" ] ; then exit_err "Path for \"$PBI_PROGNAME\" does not exist!" fi } # Confirms that the target PBI for this patch is installed # Exits if not and we are not doing a extract only verify_pbi_update_target() { if [ "${PBI_EXTRACTONLY}" = "YES" ] ; then return ; fi # Make sure the target PBI is installed _pbilow="`echo ${PBI_PROGNAME} | tr '[:upper:]' '[:lower:]' | sed 's| ||g'`" oldDir="${PBI_DBAPPDIR}/${_pbilow}-${PBI_PATCHTARGET}-${PBI_APPARCH}" if [ ! -e "${oldDir}" ] ; then exit_err "\"${_pbilow}\" does not appear to be installed!" fi # Check the arch type if [ "`cat ${oldDir}/pbi_arch`" != "$PBI_APPARCH" ] ; then exit_err "Installed \"${PBI_PROGNAME}\" is not compiled for $PBI_APPARCH" fi # Check the taret version if [ "`cat ${oldDir}/pbi_version`" != "$PBI_PATCHTARGET" ] ; then exit_err "\"${_pbilow}\" patch is for \"$PBI_PROGVERSION\" only!" fi # Check the fbsd version _pFbsdVer="`cat ${oldDir}/pbi_fbsdver | cut -c 1`" _sFbsdVer="`echo $PBI_FBSDVER | cut -c 1`" if [ "$_pFbsdVer" != "$_sFbsdVer" ] ; then exit_err "\"${_pbilow}\" patch is for FreeBSD ${_sFbsdVer}.X only!" fi # Check the mdate of the pbi _pMDate="`cat ${oldDir}/pbi_mdate`" _sMDate="$PBI_PATCHMDATE" if [ "$_pMDate" != "$_sMDate" ] ; then exit_err "\"${_pbilow}\" patch is for the $PBI_PATCHMDATE build!" fi } # Start the pbi_add process pbi_add_init() { init_tmpdir parse_add_pbi_cmdline "$@" # Check if we are only displaying information check_pbi_info_display check_pbi_gui_display check_pbi_scripts_display check_pbi_license_display if [ "$PBI_ADD_GUIDISPLAY" = "YES" -o "$PBI_ADD_INFODISPLAY" = "YES" -o "$PBI_CHECKSCRIPTS" = "YES" -o "${PBI_ADD_LICDISPLAY}" = "YES" ] then clean_remote_dl exit_trap fi require_root_or_group # If this app can only be installed as root if [ "$PBI_REQUIRESROOT" = "YES" ] ; then require_root ; fi check_agree_lic check_existing_pbi do_pbi_add } # Check if this PBI exists and exit if so check_existing_pbi() { if [ "${PBI_EXTRACTONLY}" = "YES" ] ; then return 0; fi get_dbdir dir="${APPDBDIR}" # See if this PBI is already installed if [ -d "$dir" ]; then get_username_from_file "${APPDBDIR}/pbi_name" if [ "$FILEUSER" != `whoami` -a `id -u` != "0" ] ; then exit_err "Permission denied to modify PBI installed by: $FILEUSER" fi if [ "${PBI_FORCEADD}" = "YES" ] ; then return 0; fi exit_err "${PBI_PROGNAME} ${PBI_PROGVERSION} is already installed! Use -f to force installation." fi if [ -e "${PBI_PROGDIRPATH}" ]; then get_username_from_file "${PBI_PROGDIRPATH}" if [ "$FILEUSER" != `whoami` -a `id -u` != "0" ] ; then exit_err "Permission denied to modify PBI installed by: $FILEUSER" fi if [ "${PBI_FORCEADD}" = "YES" ] ; then return 0; fi exit_err "${PBI_PROGDIRPATH} already exists! Use -f to force installation." fi } # Check if we have a license to agree to, and if we've provided the flag to do so check_agree_lic() { open_header_tmp if [ -f "${PBI_HEADER_TMPDIR}/${PBI_LICENSEFILE}" -a "${PBI_LICAGREE}" = "NO" ] ; then delete_header_tmp exit_err "LICENSE must be agreed to (--licagree) before this PBI can be installed." fi delete_header_tmp } # See if we need to display pbi license check_pbi_license_display() { if [ "$PBI_ADD_LICDISPLAY" != "YES" ] ; then return 0 ; fi open_header_tmp if [ -f "${PBI_HEADER_TMPDIR}/${PBI_LICENSEFILE}" ] ; then echo "LICENSE:" cat "${PBI_HEADER_TMPDIR}/${PBI_LICENSEFILE}" else echo "`basename $0`: No LICENSE included with this PBI" fi delete_header_tmp } # See if we need to display pbi info check_pbi_info_display() { if [ "$PBI_ADD_INFODISPLAY" != "YES" ] ; then return 0 ; fi pbi_display_info } # Display pbi information to stdout pbi_display_info() { tmp="`echo ${PBI_PROGNAME} | tr -d ' ' | tr '[A-Z]' '[a-z]'`" _appname="${tmp}-${PBI_PROGVERSION}-${PBI_APPARCH}" if [ -z "$PBI_PATCHVERSION" ] ; then echo "PBI Information for: $_appname" else echo "PBP Information for: $_appname" fi echo "-----------------------------------------------------" echo "Name: ${PBI_PROGNAME}" if [ -n "$PBI_PATCHVERSION" ] ; then echo "PatchTarget: $PBI_PATCHTARGET" fi if [ -n "$PBI_INSTALLED_BY" ] ; then echo "InstalledBy: $PBI_INSTALLED_BY" fi # Does this PBI need root to install? if [ "$PBI_REQUIRESROOT" = "YES" ] ; then echo "RootInstall: YES" else echo "RootInstall: NO" fi echo "Version: ${PBI_PROGVERSION}" echo "Built: ${PBI_PROGMDATE}" echo "Prefix: ${PBI_ORIGPROGDIRPATH}" echo "Author: ${PBI_PROGAUTHOR}" echo "Website: ${PBI_PROGWEB}" echo "Arch: ${PBI_APPARCH}" echo "FbsdVer: ${PBI_FBSDVER}" echo "CreatorVer: ${PBI_APPCREATEVER}" echo "ArchiveCount: ${PBI_ARCHIVE_COUNT}" echo "ArchiveSum: ${PBI_ARCHIVE_CHECKSUM}" case ${PBI_SIGVALID} in 0) echo "Signature: Verified" ;; -1) echo "Signature: Not Signed" ;; 1) echo "Signature: Bad" ;; *) echo "Signature: " ;; esac if [ -n "${PBI_REPO}" ] ; then local _rDesc="`cat ${PBI_DBREPODIR}/*.${PBI_REPO} | grep "Desc:" | sed 's|Desc: ||g'`" local _rID="`ls ${PBI_DBREPODIR}/*.${PBI_REPO}`" _rID=`basename $_rID | cut -d '.' -f 1` echo "Associated Repo: ${_rID} (${_rDesc})" fi # Check if autoupdate is enable or not if [ "${PBI_ENABLEAUTOUPDATE}" = "YES" ] ; then echo "AutoUpdate: YES" else echo "AutoUpdate: NO" fi # See if we have any XDG stuff if [ -e "${PBI_ORIGPROGDIRPATH}/.xdg-desktop/install-desktop-icons.sh" ] ; then echo "DesktopIcons: YES" fi if [ -e "${PBI_ORIGPROGDIRPATH}/.xdg-menu/install-menu-icons.sh" ] ; then echo "MenuIcons: YES" fi if [ -e "${PBI_ORIGPROGDIRPATH}/.xdg-mime/install-mime.sh" ] ; then echo "MimeRegistration: YES" fi # If verbose mode, show file contents if [ "$PBI_VERBOSE" = "YES" ] ; then if [ -n "${PBI_FILENAME}" -a -e "${PBI_FILENAME}" ] ; then pbi_find_archive_header echo "TOTALFILES: ${PBI_ARCHIVE_COUNT}" echo "Archive Contents:" echo "--------------------------------------" tail +$PBI_SKIP_ARCHLINES "${PBI_FILENAME}" | tar tvf - fi fi } # See if we need to display gui header info check_pbi_gui_display() { if [ "$PBI_ADD_GUIDISPLAY" != "YES" ] ; then return 0 ; fi open_header_tmp pbi_display_gui "$PBI_HEADER_TMPDIR" "COPY" delete_header_tmp } # Display location of PBI graphics pbi_display_gui() { dir="$1" copy="$2" if [ -e "${dir}/top-banner.png" ] ; then if [ "$copy" = "COPY" ] ; then pbi_guitop="/tmp/.PBI-top.$$.png" cp "${dir}/top-banner.png" "$pbi_guitop" else pbi_guitop="${dir}/top-banner.png" fi echo "TopBanner: ${pbi_guitop}" fi if [ -e "${dir}/side-banner.png" ] ; then if [ "$copy" = "COPY" ] ; then pbi_guiside="/tmp/.PBI-side.$$.png" cp "${dir}/side-banner.png" "$pbi_guiside" else pbi_guiside="${dir}/side-banner.png" fi echo "SideBanner: ${pbi_guiside}" fi # Try to find an icon ls ${dir}/pbi_icon.* >/dev/null 2>/dev/null if [ "$?" = "0" ] ; then _iconExt=`ls ${dir}/pbi_icon.* | head -n 1 | awk -F . '{print $NF}'` if [ "$copy" = "COPY" ] ; then pbi_guiicon="/tmp/.PBI-icon.$$.${_iconExt}" cp "${dir}/pbi_icon.${_iconExt}" "$pbi_guiicon" else pbi_guiicon="${dir}/pbi_icon.${_iconExt}" fi echo "Icon: ${pbi_guiicon}" fi } open_header_tmp() { init_tmpdir # If we have a custom extract dir, use it if [ -z "$1" ] ; then PBI_HEADER_TMPDIR="${PBI_TMPDIR}/.PBI-header.$$" else PBI_HEADER_TMPDIR="${1}/.PBI-header.$$" fi if [ -e "${PBI_HEADER_TMPDIR}" ] ; then rm -rf "${PBI_HEADER_TMPDIR}" ; fi mkdir -p "${PBI_HEADER_TMPDIR}" # Extract the header files tar xvf "${PBI_FILENAME}" -C "${PBI_HEADER_TMPDIR}" >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then exit_err "Failed to read PBI header! Possible corrupt PBI, or wrong PBI version for this OS." ; fi } delete_header_tmp() { if [ -z "${PBI_HEADER_TMPDIR}" ] ; then return 0 ; fi if [ -d "${PBI_HEADER_TMPDIR}" ] ; then rm -rf "${PBI_HEADER_TMPDIR}" ; fi } # Load in all the configuration data from the header load_info_from_header() { open_header_tmp # Start loading our variables load_info_from_dir "${PBI_HEADER_TMPDIR}" delete_header_tmp } # See if we need to display scripts check_pbi_scripts_display() { if [ "$PBI_CHECKSCRIPTS" != "YES" ] ; then return 0 ; fi # Display our scripts open_header_tmp if [ -e "${PBI_HEADER_TMPDIR}/${MOD_PREINS}" ] ; then echo -e "\n${MOD_PREINS}:" echo "--------------------------------" cat "${PBI_HEADER_TMPDIR}/${MOD_PREINS}" fi if [ -e "${PBI_HEADER_TMPDIR}/${MOD_POSTINS}" ] ; then echo -e "\n${MOD_POSTINS}:" echo "--------------------------------" cat "${PBI_HEADER_TMPDIR}/${MOD_POSTINS}" fi if [ -e "${PBI_HEADER_TMPDIR}/${MOD_PREREM}" ] ; then echo -e "\n${MOD_PREREM}:" echo "--------------------------------" cat "${PBI_HEADER_TMPDIR}/${MOD_PREREM}" fi delete_header_tmp } # Load pbi information from the specified directory load_info_from_dir() { REQUIRED_FILES="pbi_defaultpath pbi_name pbi_version pbi_author pbi_web pbi_arch pbi_fbsdver pbi_createver" for f in $REQUIRED_FILES do if [ ! -e "${1}/${f}" ] ; then echo "Warning: Missing file: ${f}" ; fi done PBI_APPARCH="" PBI_APPCREATEVER="" PBI_ARCHIVE_CHECKSUM="" PBI_ARCHIVE_COUNT="" PBI_ENABLEAUTOUPDATE="" PBI_FBSDVER="" PBI_ORIGPROGDIRPATH="" PBI_PATCHMDATE="" PBI_PATCHVERSION="" PBI_PATCHTARGET="" PBI_PROGNAME="" PBI_PROGVERSION="" PBI_PROGAUTHOR="" PBI_PROGMDATE="" PBI_PROGWEB="" PBI_REPO="" PBI_REQUIRESROOT="" PBI_SIGVALID="" PBI_ORIGPROGDIRPATH="`cat ${1}/pbi_defaultpath`" PBI_PROGNAME="`cat ${1}/pbi_name`" PBI_PROGVERSION="`cat ${1}/pbi_version`" PBI_PROGAUTHOR="`cat ${1}/pbi_author`" PBI_PROGWEB="`cat ${1}/pbi_web 2>/dev/null`" PBI_PROGMDATE="`cat ${1}/pbi_mdate 2>/dev/null`" PBI_APPARCH="`cat ${1}/pbi_arch 2>/dev/null`" PBI_FBSDVER="`cat ${1}/pbi_fbsdver 2>/dev/null`" PBI_APPCREATEVER="`cat ${1}/pbi_createver 2>/dev/null`" PBI_ARCHIVE_COUNT="`cat ${1}/pbi_archivecount 2>/dev/null`" PBI_ARCHIVE_CHECKSUM="`cat ${1}/pbi_archivesum 2>/dev/null`" # Check if auto-update is enabled if [ -e "${1}/autoupdate-enable" ] ; then PBI_ENABLEAUTOUPDATE="YES" fi # Does this PBI need to be installed as root if [ -e "${1}/pbi_requiresroot" ] ; then PBI_REQUIRESROOT="YES" fi # Check if this is a patch file if [ -e "${1}/pbi_patchfile" ] ; then PBI_PATCHVERSION=`cat ${1}/pbi_patchfile | cut -d ':' -f 2` PBI_PATCHTARGET=`cat ${1}/pbi_patchfile | cut -d ':' -f 1` fi # Check if this associates with a particular repo if [ -e "${1}/pbi_repo" ] ; then PBI_REPO=`cat ${1}/pbi_repo` fi # See if this patch is for a particular mdate if [ -e "${1}/pbi_patchmdate" ] ; then PBI_PATCHMDATE=`cat ${1}/pbi_patchmdate` fi # See if this PBI was signed if [ -e "${1}/pbi_archivesum.sha1" ] ; then check_valid_sigs "${1}" if [ "$?" = "0" ] ; then PBI_SIGVALID="0" else PBI_SIGVALID="1" fi else PBI_SIGVALID="-1" fi } # Start installing the PBI do_pbi_add() { pbi_verify_signatures pbi_verify_archivesum check_preinstall_script mk_pbi_extract_dir pbi_extract_archive pbi_add_check_gids pbi_add_check_uids pbi_add_run_script check_postinstall_script pbi_add_register_app # Be sure to let the pbid know we have a new hash-dir to register add_hashdir_trigger clean_remote_dl } # Check for any GIDs we need to create pbi_add_check_gids() { if [ ! -e "${PBI_PROGDIRPATH}/${PBI_INS_GROUPSFILE}" ] ; then return ; fi runUID=`id -u` while read gidLine do gName=`echo $gidLine | cut -d ':' -f 1` gID=`echo $gidLine | cut -d ':' -f 3` gUsers=`echo $gidLine | cut -d ':' -f 4` # Is this group already on the system? pw groupshow $gName >/dev/null 2>/dev/null if [ $? -eq 0 ] ; then echo "Using existing group: $gName" else # Are we installing as root? if [ "$runUID" != "0" ] ; then echo "Please create group \"$gName\" manually or re-install PBI as root." else echo "Adding group: $gName" pw groupadd $gName -g $gID; fi fi if [ -n "$gUsers" ] ; then for gUser in `echo $gUsers | sed 's|,| |g'` do pw groupshow ${gName} | grep -qw ${gUser} if [ $? -ne 0 ] ; then # Are we installing as root? if [ "$runUID" != "0" ] ; then echo "Please add user \"$gUser\" to group \"$gName\" manually or re-install PBI as root." continue fi echo "Adding user ${gUser} to group ${gName}" pw groupmod ${gName} -m ${gUser} fi done fi done < ${PBI_PROGDIRPATH}/${PBI_INS_GROUPSFILE} } # Check for any UIDs we need to create pbi_add_check_uids() { if [ ! -e "${PBI_PROGDIRPATH}/${PBI_INS_USERSFILE}" ] ; then return ; fi runUID=`id -u` while read uidLine do uName=`echo $uidLine | cut -d ':' -f 1` # Is this user already on the system? pw usershow $uName >/dev/null 2>/dev/null if [ $? -eq 0 ] ; then echo "Using existing user: $uName"; continue ; fi # Are we installing as root? if [ "$runUID" != "0" ] ; then echo "Please create user \"$uName\" manually or re-install PBI as root." continue fi uID=`echo $uidLine | cut -d ':' -f 3` gID=`echo $uidLine | cut -d ':' -f 4` uClass=`echo $uidLine | cut -d ':' -f 5` uGecos=`echo $uidLine | cut -d ':' -f 8` uHomedir=`echo $uidLine | cut -d ':' -f 9 | sed "s|^/usr/local|${PBI_PROGDIRPATH}|"` uShell=`echo $uidLine | cut -d ':' -f 10` echo "Adding user: $uName" pw useradd $uName -u $uID -g $gID $uClass -c "$uGecos" -d $uHomedir -s $uShell; # Create homedir case $uHomedir in /nonexistent|/var/empty) ;; *) install -d -g $gID -o $uID $uHomedir ;; esac done < ${PBI_PROGDIRPATH}/${PBI_INS_USERSFILE} } add_hashdir_trigger() { get_dbdir _htrig=`echo ${APPDBDIR} | sed "s|${PBI_DBAPPDIR}|${PBI_DBHASHQUEUEDIR}|g"` if [ ! -e "${_htrig}" ] ; then touch "${_htrig}" fi } # Run the install script if exists pbi_add_run_script() { # If running as user, add bin path-links if [ "`id -u`" != "0" ] ; then add_app_path_links "${PBI_PROGDIRPATH}" ; fi insc="${PBI_PROGDIRPATH}/${PBI_FAKEBIN_DIR}/.pbi-install.sh" if [ ! -e "${insc}" ] ; then return 0 ; fi export_script_vars if [ "$PBI_VERBOSE" = "YES" ] ; then ${insc} else ${insc} >/dev/null 2>/dev/null fi } # If we need to, update the hashdir pbi_add_update_hashdir() { if [ "${PBI_NOHASHDIR}" = "YES" ] ; then return 0 ; fi if [ ! -e "${1}/${PBI_HASHLIST}" ] ; then return 0; fi if [ "$PBI_VERBOSE" = "YES" ] ; then echo "HASHCOUNT: `wc -l ${1}/${PBI_HASHLIST} | tr -d ' ' | cut -d '/' -f 1`" else echo -e "Merging with hashdir...\c" fi # Read the hashfile, and start making links to identical files while read hl do file="`echo $hl | sed 's/:::.*$//g'`" # If we are trying to merge a PBI which was deleted, stop if [ -n "${2}" -a -e "${2}" ] ; then echo "HASHDONE - Deleted" return fi # Make sure the target file hasnt been removed if [ ! -e "${1}/${file}" ] ; then continue ; fi # We dont need no stinking sym-links if [ -h "${1}/${file}" ] ; then continue ; fi if [ -f "${PBI_HASHDIR}/${hl}" ] ; then use_hashfile "$hl" "${1}/$file" else mv_ln_hashfile "$hl" "${1}/$file" fi done < "${1}/${PBI_HASHLIST}" if [ "$PBI_VERBOSE" = "YES" ] ; then echo "HASHDONE" else echo -e "Done!" fi } # Use an existing hashfile use_hashfile() { tfile="$1" file="$2" dir="`dirname ${tfile}`" if [ ! -d "${PBI_HASHDIR}/${dir}" ] ; then mkdir -p ${PBI_HASHDIR}/${dir} fi # We have a match! ln -f "${PBI_HASHDIR}/${tfile}" "${file}" if [ $? -ne 0 ] ; then echo "Warning: Unable to make hash-link ${PBI_HASHDIR}/${tfile} -> ${file}" return fi # Make sure the hard-linked file doesn't get changed chmod u-w,g-w,o-w "${file}" if [ $? -ne 0 ] ; then echo "Warning: Unable to chmod ${file}" return fi } # New file we can save to hashdir mv_ln_hashfile() { tfile="$1" file="$2" dir="`dirname ${tfile}`" if [ ! -d "${PBI_HASHDIR}/${dir}" ] ; then mkdir -p ${PBI_HASHDIR}/${dir} fi ln -f "${file}" "${PBI_HASHDIR}/${tfile}" if [ $? -ne 0 ] ; then echo "Warning: Unable to make hash-link ${file} -> ${PBI_HASHDIR}/${tfile}" return fi # Make sure the hard-linked file doesn't get changed chmod u-w,g-w,o-w "${file}" if [ $? -ne 0 ] ; then echo "Warning: Unable to chmod ${file}" return fi # Make sure the hard-linked file doesn't get changed chmod u-w,g-w,o-w "${PBI_HASHDIR}/${tfile}" if [ $? -ne 0 ] ; then echo "Warning: Unable to chmod ${PBI_HASHDIR}/${tfile}" return fi if [ "$PBI_VERBOSE" = "YES" ] ; then echo "L" ; fi } # Return the dbdir for this PBI get_dbdir() { tmp="`echo ${PBI_PROGNAME} | tr -d ' ' | tr '[A-Z]' '[a-z]'`" APPDBDIR="${PBI_DBAPPDIR}/${tmp}-${PBI_PROGVERSION}-${PBI_APPARCH}" } # Register this app as installed pbi_add_register_app() { if [ ! -d "$PBI_DBAPPDIR" ] ; then mkdir -p ${PBI_DBAPPDIR} ; fi open_header_tmp get_dbdir dir="${APPDBDIR}" # Make sure we remove any existing meta-data if forcing an installation if [ "$PBI_FORCEADD" = "YES" ] ; then tmp="`echo ${PBI_PROGNAME} | tr -d ' ' | tr '[A-Z]' '[a-z]'`" rm -rf ${PBI_DBAPPDIR}/${tmp}-*-${PBI_APPARCH} fi mkdir -p "${dir}" tar cvf - -C "${PBI_HEADER_TMPDIR}" . 2>/dev/null | tar xvf - -C "$dir" 2>/dev/null # If this was a patch, use the original path if [ -n "${PBI_ORIGPROGDIRPATH}" ] ; then echo "${PBI_ORIGPROGDIRPATH}" >${dir}/pbi_installedpath else echo "${PBI_PROGDIRPATH}" >${dir}/pbi_installedpath fi # See which repo / key this PBI associates to, if any check_valid_sigs "${dir}" if [ -n "$PBI_VALIDKEYSIG" ] ; then _rMd5="`echo ${PBI_VALIDKEYSIG} | cut -d '.' -f 1`" echo "$_rMd5" | sed "s|${PBI_DBKEYDIR}/||g" > ${dir}/pbi_repo fi # Dont need any patch version info if [ -e "${dir}/pbi_patchfile" ] ; then rm "${dir}/pbi_patchfile" fi delete_header_tmp echo "Installed: ${PBI_PROGNAME}-${PBI_PROGVERSION}" } # Check if we have a postinstall script we need to use check_postinstall_script() { open_header_tmp if [ ! -e "${PBI_HEADER_TMPDIR}/${MOD_POSTINS}" ] ; then delete_header_tmp return 0 fi export_script_vars sh "${PBI_HEADER_TMPDIR}/${MOD_POSTINS}" delete_header_tmp } # Check if we have a preinstall script we need to use check_preinstall_script() { open_header_tmp if [ ! -e "${PBI_HEADER_TMPDIR}/${MOD_PREINS}" ] ; then delete_header_tmp return 0 fi export_script_vars sh "${PBI_HEADER_TMPDIR}/${MOD_PREINS}" if [ "$?" != "0" ] ; then delete_header_tmp exit_err "${MOD_PREINS} returned error status" fi delete_header_tmp } # Verify if we have valid openssl signatures on important parts of PBI pbi_verify_signatures() { if [ "${PBI_SKIPSIGVERIFY}" = "YES" ] ; then return 0 ; fi if [ "$PBI_SIGVALID" = "0" ] ; then return ; fi if [ "$PBI_SIGVALID" = "1" ] ; then kw="Invalid" ; else kw="No" ; fi exit_err "$kw digital signature! If you are *SURE* you trust this PBI, re-install with --no-checksig option. " } # Check if we have valid signatures, and return "0" if success, "1" if failure check_valid_sigs() { PBI_VALIDKEYSIG="" for _pk in ${PBI_PUBKEYS} do good="true" _sf="${1}/pbi_archivesum ${1}/${MOD_PREINS} ${1}/${MOD_POSTINS} ${1}/${MOD_PREREM}" for _ts in $_sf do openssl dgst -sha1 \ -verify ${_pk} \ -signature ${_ts}.sha1 \ ${_ts} >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then good="false" ; break fi PBI_VALIDKEYSIG="$_pk" done if [ "$good" = "true" ] ; then return 0 ; fi done return 1 } # Verify if the archive checksum is good pbi_verify_archivesum() { if [ "${PBI_SKIPCHECKSUM}" = "YES" ] ; then return 0 ; fi echo -e "Verifying Checksum...\c" pbi_find_archive_header sum=`tail +$PBI_SKIP_ARCHLINES "${PBI_FILENAME}" | sha256 -q` if [ "$PBI_VERBOSE" = "YES" ] ; then echo "Archive checksum: ${sum}" echo "Saved checksum: ${PBI_ARCHIVE_CHECKSUM}" fi if [ "$sum" != "$PBI_ARCHIVE_CHECKSUM" ] ; then exit_err "${PBI_FILENAME} failed checksum, the archive may be corrupt." fi echo -e "OK" } # Make our PBI extraction dir mk_pbi_extract_dir() { PBI_EXTRACTDIR="${PBI_PROGDIRPATH}" if [ -e "${PBI_EXTRACTDIR}" ] ; then rm -rf "$PBI_EXTRACTDIR" fi mkdir -p "${PBI_EXTRACTDIR}" >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then exit_err "Failed to create directory: ${PBI_PROGDIRPATH}" fi } pbi_find_archive_header() { # Find the header for the archive # SEARCH FOR: $PBI_SS_ARCHIVE PBI_SKIP_ARCHLINES=`awk "/^${PBI_SS_ARCHIVE}/ { print NR + 1; exit 0; }" "${PBI_FILENAME}"` if [ "$PBI_VERBOSE" = "YES" ] ; then echo "SKIP_ARCHLINES: $PBI_SKIP_ARCHLINES" fi } # Extract the PBI archive file pbi_extract_archive() { pbi_find_archive_header echo "Extracting to: ${PBI_EXTRACTDIR}" tar="xvf -" if [ "$PBI_VERBOSE" = "YES" ] ; then echo "TOTALFILES: ${PBI_ARCHIVE_COUNT}" tail +$PBI_SKIP_ARCHLINES "${PBI_FILENAME}" | tar ${tar} -C "${PBI_EXTRACTDIR}" err="$?" else tail +$PBI_SKIP_ARCHLINES "${PBI_FILENAME}" | tar ${tar} -C "${PBI_EXTRACTDIR}" >/dev/null 2>/dev/null err="$?" fi if [ "$err" != "0" ] ; then exit_err "Failed extracting ${PBI_FILENAME}" ; fi if [ "$PBI_VERBOSE" = "YES" ] ; then echo "Extraction Finished!" ; fi # If this is an extract only, do it and exit if [ "${PBI_EXTRACTONLY}" = "YES" ] ; then exit_trap ; fi } # Starting pbi_create pbi_create_init() { require_root parse_create_pbi_cmdline "$@" # If we are making a backup copy of an installed PBI if [ "$PBI_CBACKUP" = "YES" ] ; then init_tmpdir do_pbi_create_backup exit_trap fi load_pbi_conffile parse_cmdline_overrides # Copy over the application to the correct location echo ${PBI_PROGDIRPATH} | grep -q "^${PBI_APPDIR}/" if [ $? -ne 0 ] ; then _pbilow="`echo ${PBI_PROGNAME} | tr '[:upper:]' '[:lower:]' | sed 's| ||g'`" newPDP="${PBI_APPDIR}/${_pbilow}-${ARCH}" if [ -d "${newPDP}" ] ; then exit_err "Error: ${newPDP} already exists!" ; fi cp -r ${PBI_PROGDIRPATH} ${newPDP} PBI_PROGDIRPATH="${newPDP}" export PBI_PROGDIRPATH fi PBI_CREATEONLY="YES" check_create_required_vars do_pbi_create # Cleanup the copy dir if [ -n "$newPDP" ] ; then if [ "${newPDP}" != "/" -a "${newPDP}" != "${PBI_APPDIR}/-" ] ; then rm -rf "${newPDP}" fi fi } # Start the pbi_create backup process do_pbi_create_backup() { load_info_from_dir "${PBI_DBAPPDIR}/${PBI_CBACKUPTARGET}" echo "Creating backup PBI: ${PBI_PROGNAME}-${PBI_PROGVERSION}" # Start by making a fresh archive of the installed PBI PBI_STAGEDIR="$PBI_ORIGPROGDIRPATH" mk_archive_file # Now make the header dir _hDir="${PBI_TMPDIR}/.header.$$" PBI_HEADERDIR="${_hDir}" mkdir -p "${_hDir}" cp ${PBI_DBAPPDIR}/${PBI_CBACKUPTARGET}/* "${_hDir}" rm ${_hDir}/*.sha1 >/dev/null 2>/dev/null # Get the total number of files in the STAGEDIR get_filetotal_dir "${PBI_STAGEDIR}" echo "${FILETOTAL}" > "${PBI_HEADERDIR}/pbi_archivecount" # Save a checksum of archive file sha256 -q "${PBI_CREATE_ARCHIVE}" > "${PBI_HEADERDIR}/pbi_archivesum" # Sign any header files sign_pbi_files "$PBI_HEADERDIR" # Make the header archive mk_header_file # Remove the new headerdir rm -rf "$PBI_HEADERDIR" # Now finish up and make the resulting PBI file mk_output_pbi } # Vars required for creation check_create_required_vars() { if [ -z "${PBI_PROGNAME}" ] ; then exit_err "Missing PBI_PROGNAME"; fi if [ -z "${PBI_PROGVERSION}" ] ; then exit_err "Missing PBI_PROGVERSION"; fi if [ -z "${PBI_PROGAUTHOR}" ] ; then exit_err "Missing PBI_PROGAUTHOR"; fi if [ -z "${PBI_PROGWEB}" ] ; then exit_err "Missing PBI_PROGWEB"; fi } # Start the pbi_create process do_pbi_create() { get_pbi_progname echo "Creating PBI: ${PBI_PROGNAME}-${PBI_PROGVERSION}" if [ "`basename $0`" = "pbi_makeport" -o "`basename $0`" = "pbi_makeport_chroot" ] ; then PBI_STAGEDIR="${PBI_PROGDIRPATH}" else mk_stage_dir fi copy_resource_dir clean_stage_dir mk_extlink_entries clean_icons_dir mk_xdg_scripts run_pbi_prepkgscript mk_install_script mk_deinstall_script mk_hash_list mk_archive_file mk_header_dir save_pbi_details_to_header mk_header_file rm_header_dir mk_output_pbi rm_stage_dir } # Start looping through and creating a hash-list of files mk_hash_list() { if [ "${PBI_CREATE_HASHLIST}" = "NO" ] ; then return 0 ; fi echo "Creating hash list..." hashfile="${PBI_STAGEDIR}/${PBI_HASHLIST}" if [ -e "${hashfile}" ] ; then rm "${hashfile}" ; fi for hdir in ${HASH_SEARCH_DIRS} do if [ ! -d "${PBI_STAGEDIR}/${hdir}" ] ; then continue ; fi save_dir_hash_list "${hdir}" "${hashfile}" done } # Read the specified directory and save hashsums of each file save_dir_hash_list() { cd ${PBI_STAGEDIR} tmp_hashdir="${PBI_STAGEDIR}/.tmp-hash.$$" find "${1}" -type f > ${tmp_hashdir} while read line do if [ ! -f "$line" -o -h "$line" ] ; then continue ; fi # Make sure this isn't a binary executable file "${line}" | grep "executable," >/dev/null 2>/dev/null if [ "$?" = "0" ] ; then continue ; fi # Ignore files / libs with the full PREFIX hard-coded strings "${line}" | grep "${PBI_PROGDIRPATH}" >/dev/null 2>/dev/null if [ "$?" = "0" ]; then continue ; fi # Check if this hash file is excluded _hfound="0" if [ -n "${PBI_HASH_EXCLUDES}" ] ; then for _hexcl in ${PBI_HASH_EXCLUDES} do if [ "$_hexcl" = "$line" ] ; then _hfound="1" fi done if [ "$_hfound" = "1" ] ; then continue fi fi # Get the file size tSize=`du -k "${line}" | awk '{print $1}'` if [ $(is_num "$tSize") ] ; then # If the file is less than 10Kb, we can skip if [ $tSize -lt 10 ] ; then continue ; fi # Add to the hash-dir sha=`sha256 -q "$line"` echo "${line}:::${sha}" >> ${2} fi done < ${tmp_hashdir} rm ${tmp_hashdir} cd / } # Parse any external link directives mk_extlink_entries() { echo "Creating external link entries..." init_tmpdir _extf="${PBI_CONFDIR}/${MOD_EXTLINKFILE}" _autoextf="${PBI_STAGEDIR}/${MOD_AUTOEXTLINKFILE}" _tmpextf="${PBI_TMPDIR}/${MOD_AUTOEXTLINKFILE}.$$" if [ ! -e "${_extf}" -a ! -e "${_autoextf}" ] ; then return 0 ; fi dir="${PBI_STAGEDIR}/${PBI_FAKEBIN_DIR}" if [ ! -d "${dir}" ] ; then mkdir -p "${dir}" ; fi # Create the headers for the PATH link scripts echo "#!/bin/sh" >"${dir}/${PBI_INS_PATHSCRIPT}" echo "#!/bin/sh" >"${dir}/${PBI_UNINS_PATHSCRIPT}" # Make sure we also set SYS_LOCALBASE in case user runs these stand-alone at some point echo "if [ -z \"\$SYS_LOCALBASE\" ]; then SYS_LOCALBASE=\"${SYS_LOCALBASE}\" ; fi" >"${dir}/${PBI_INS_PATHSCRIPT}" echo "if [ -z \"\$SYS_LOCALBASE\" ]; then SYS_LOCALBASE=\"${SYS_LOCALBASE}\" ; fi" >"${dir}/${PBI_UNINS_PATHSCRIPT}" touch "$_tmpextf" if [ -e "$_autoextf" ]; then cat "${_autoextf}" >> "${_tmpextf}" ; fi if [ -e "$_extf" ]; then cat "${_extf}" >> "${_tmpextf}" ; fi while read line do _bin="NO" _wraponly="NO" _crashhandle="YES" _keep="YES" _linux="NO" echo $line | tr '\t' ' ' | tr -s ' ' | grep "^#" >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then src="`echo $line | tr '\t' ' ' | tr -s ' ' | cut -d ' ' -f 1`" tar="`echo $line | tr '\t' ' ' | tr -s ' ' | cut -d ' ' -f 2`" act="`echo $line | tr '\t' ' ' | tr -s ' ' | cut -d ' ' -f 3`" if [ -z "$src" -o -z "$tar" ] ; then continue ; fi # Check if this is an icon we need to preserve echo $src | grep -q "^share/icons/" if [ $? -eq 0 -a "${PBI_USESYSFONTS}" != "NO" ] ; then iDir=`dirname $src` if [ ! -d "${PBI_STAGEDIR}/${PBI_ICDIR}/${iDir}" ] ; then mkdir -p "${PBI_STAGEDIR}/${PBI_ICDIR}/${iDir}" fi cp "${PBI_STAGEDIR}/${src}" "${PBI_STAGEDIR}/${PBI_ICDIR}/${iDir}" src="${PBI_ICDIR}/${src}" fi if [ ! -e "${PBI_STAGEDIR}/$src" ] ; then echo "WARN: external_link target: \"$src -> $tar $act\" does not exist!" continue fi # Check for act directives for i in `echo ${act} | sed 's|,| |g'` do case ${i} in binary) _bin="YES" ;; binwrapper) _bin="YES" ; _wraponly="YES" ;; nocrash) _crashhandle="NO" ;; keep) _keep="YES" ;; replace) _keep="NO" ;; linux) _bin="YES" ; _linux="YES" ;; *) echo "Warning: Unknown option \"$i\" in ${MOD_EXTLINKFILE}";; esac done # Make sure SYS_LOCALBASE/$tar dir exists echo "_bd=\"\`dirname \$SYS_LOCALBASE/$tar\`\"" >> "${dir}/${PBI_INS_PATHSCRIPT}" echo "if [ ! -d \"\$_bd\" ] ; then" >> "${dir}/${PBI_INS_PATHSCRIPT}" echo " mkdir -p \"\${_bd}\"" >> "${dir}/${PBI_INS_PATHSCRIPT}" echo "fi" >> "${dir}/${PBI_INS_PATHSCRIPT}" # If we are doing a binary, run special function to make wrapper if [ "$_bin" = "YES" ] ; then # Make sure we don't create any duplicates echo "$_donewrap" | grep "#${src}#" >/dev/null 2>/dev/null if [ "$?" = "0" ] ; then continue ; fi # Make the binary wrapper mk_path_wrappers "$src" "$tar" "$_crashhandle" "$_wraponly" "$_linux" # This binary is done, save it now so we don't duplicate later _donewrap="$_donewrap #${src}#" else # Make our link commands if [ "$_keep" = "YES" ] ; then _lop="-fs"; else _lop="-s"; fi echo "ln ${_lop} $PBI_PROGDIRPATH/${src} \$SYS_LOCALBASE/${tar}" \ >> "${dir}/${PBI_INS_PATHSCRIPT}" fi # Make the uninstall command echo "ls -al \"\$SYS_LOCALBASE/$tar\" | grep \"> $PBI_PROGDIRPATH\" >/dev/null 2>/dev/null " \ >> "${dir}/${PBI_UNINS_PATHSCRIPT}" echo "if [ \"\$?\" = \"0\" ] ; then" >> "${dir}/${PBI_UNINS_PATHSCRIPT}" echo " rm \"\$SYS_LOCALBASE/${tar}\"" >> "${dir}/${PBI_UNINS_PATHSCRIPT}" echo "fi" >> "${dir}/${PBI_UNINS_PATHSCRIPT}" echo " " >> "${dir}/${PBI_INS_PATHSCRIPT}" echo " " >> "${dir}/${PBI_UNINS_PATHSCRIPT}" fi done < "${_tmpextf}" rm "${_tmpextf}" chmod 755 "${dir}/${PBI_INS_PATHSCRIPT}" chmod 755 "${dir}/${PBI_UNINS_PATHSCRIPT}" } # Create the wrapper scripts for the specified binaries mk_path_wrappers() { dir="${PBI_STAGEDIR}/${PBI_FAKEBIN_DIR}" if [ ! -d "${dir}" ] ; then mkdir -p "${dir}" ; fi bin="${1}" fbin="`basename ${bin}`" tar="${2}" ch="${3}" onlywrap="${4}" linwrap="${5}" # Check if the fake-bin wrapper already exists, and if so use # a different name if [ -e "${dir}/${fbin}" ] ; then fbin=`echo $bin | sed 's|/|-|g'` fi # Make our link to the system localbase if its not a wrapper only if [ "$onlywrap" != "YES" ] ; then echo "ln -fs $PBI_PROGDIRPATH/${PBI_FAKEBIN_DIR}/${fbin} \$SYS_LOCALBASE/${tar}" \ >> "${dir}/${PBI_INS_PATHSCRIPT}" fi # Copy the wrapper binary PBI_WRAPPERFILE="${PBI_APPDIR}/.pbiwrapper-$ARCH" cp ${PBI_WRAPPERFILE} ${dir}/${fbin} chmod 755 ${dir}/${fbin} # Create the wrapper .pbiopt echo "PROGDIR: ${PBI_PROGDIRPATH}" >${dir}/${fbin}.pbiopt echo "TARGET: ${bin}" >>${dir}/${fbin}.pbiopt # Figure out the extra ldconfig dirs LDCONFIGDIRS="" if [ -d "${PBI_STAGEDIR}/libdata/ldconfig" ] ; then for _ldc in `ls ${PBI_STAGEDIR}/libdata/ldconfig 2>/dev/null` do while read TMP do echo $LDCONFIGDIRS | grep "${TMP}:" >/dev/null 2>/dev/null if [ "$?" != "0" ]; then LDCONFIGDIRS="${TMP}:${LDCONFIGDIRS}" fi done < ${PBI_STAGEDIR}/libdata/ldconfig/${_ldc} done fi # If this is marked as a linux app, make sure we point to the linux libs first if [ "$linwrap" = "YES" ] ; then LDCONFIGDIRS="${PROGDIR}/linuxlib" fi # Create the wrapper .ldhints echo "${LDCONFIGDIRS}" >${dir}/${fbin}.ldhints } # Create any XDG script for install / deinstall mk_xdg_scripts() { echo "Creating xdg scripts..." mk_xdg_desktop_script mk_xdg_menu_script mk_xdg_mime_script } # Create any XDG script for desktop icons mk_xdg_desktop_script() { if [ ! -d "${PBI_CONFDIR}/${MOD_XDGDESK_DIR}" ] ; then return 0 ; fi _dFound=0 dir="${PBI_STAGEDIR}/${PBI_APPDESK_DIR}" if [ ! -d "${dir}" ] ; then mkdir -p "${dir}" ; fi echo "#!/bin/sh" >"${dir}/${PBI_INS_DESKSCRIPT}" echo "#!/bin/sh" >"${dir}/${PBI_UNINS_DESKSCRIPT}" cd "${PBI_CONFDIR}/${MOD_XDGDESK_DIR}" for i in `ls *.desktop 2>/dev/null` do _dFound=1 # Copy over the .desktop file, modifying any variables within cat "${i}" \ | sed "s|%%PBI_EXEDIR%%|$PBI_PROGDIRPATH/$PBI_FAKEBIN_DIR|g" \ | sed "s|%%PBI_APPDIR%%|$PBI_PROGDIRPATH|g" \ > "${dir}/PBI-${i}" # Set the correct permissions on the desktop file chmod 744 "${dir}/PBI-${i}" ifi="$PBI_PROGDIRPATH/${PBI_APPDESK_DIR}/PBI-${i}" echo "xdg-desktop-icon install --novendor ${ifi}" \ >> "${dir}/${PBI_INS_DESKSCRIPT}" echo "xdg-desktop-icon uninstall ${ifi}" \ >> "${dir}/${PBI_UNINS_DESKSCRIPT}" done chmod 755 "${dir}/${PBI_INS_DESKSCRIPT}" chmod 755 "${dir}/${PBI_UNINS_DESKSCRIPT}" # No desktop entries if [ "$_dFound" = "0" ] ; then rm "${dir}/${PBI_INS_DESKSCRIPT}" rm "${dir}/${PBI_UNINS_DESKSCRIPT}" fi } # Create any XDG script for menu icons mk_xdg_menu_script() { if [ ! -d "${PBI_CONFDIR}/${MOD_XDGMENU_DIR}" ] ; then return 0 ; fi _mFound=0 dir="${PBI_STAGEDIR}/${PBI_APPMENU_DIR}" if [ ! -d "${dir}" ] ; then mkdir -p "${dir}" ; fi echo "#!/bin/sh" >"${dir}/${PBI_INS_MENUSCRIPT}" echo "#!/bin/sh" >"${dir}/${PBI_UNINS_MENUSCRIPT}" cd "${PBI_CONFDIR}/${MOD_XDGMENU_DIR}" for i in `ls *.desktop 2>/dev/null` do _mFound=1 # Copy the desktop file, changing any included vars cat "${i}" \ | sed "s|%%PBI_EXEDIR%%|$PBI_PROGDIRPATH/$PBI_FAKEBIN_DIR|g" \ | sed "s|%%PBI_APPDIR%%|$PBI_PROGDIRPATH|g" \ > "${dir}/PBI-${i}" # Set the correct permissions on the menu file chmod 744 "${dir}/PBI-${i}" ifi="$PBI_PROGDIRPATH/${PBI_APPMENU_DIR}/PBI-${i}" # Check for a .directory file associated with this .desktop ifd="" dirfile="`basename -s .desktop ${i}`" if [ -e "${dirfile}.directory" ] ; then cat "${dirfile}.directory" \ | sed "s|%%PBI_EXEDIR%%|$PBI_PROGDIRPATH/$PBI_FAKEBIN_DIR|g" \ | sed "s|%%PBI_APPDIR%%|$PBI_PROGDIRPATH|g" \ > "${dir}/PBI-${dirfile}.directory" #cp "${dirfile}.directory" "${dir}/PBI-${dirfile}.directory" ifd="$PBI_PROGDIRPATH/${PBI_APPMENU_DIR}/PBI-${dirfile}.directory " fi echo "xdg-desktop-menu install --novendor ${ifd}${ifi}" \ >> "${dir}/${PBI_INS_MENUSCRIPT}" echo "xdg-desktop-menu uninstall ${ifd}${ifi}" \ >> "${dir}/${PBI_UNINS_MENUSCRIPT}" done chmod 755 "${dir}/${PBI_INS_MENUSCRIPT}" chmod 755 "${dir}/${PBI_UNINS_MENUSCRIPT}" # No mime entries if [ "$_mFound" = "0" ] ; then rm "${dir}/${PBI_INS_MENUSCRIPT}" rm "${dir}/${PBI_UNINS_MENUSCRIPT}" fi } # Create any XDG script for mime types mk_xdg_mime_script() { if [ ! -d "${PBI_CONFDIR}/${MOD_XDGMIME_DIR}" ] ; then return 0 ; fi _mFound=0 dir="${PBI_STAGEDIR}/${PBI_APPMIME_DIR}" if [ ! -d "${dir}" ] ; then mkdir -p "${dir}" ; fi echo "#!/bin/sh" >"${dir}/${PBI_INS_MIMESCRIPT}" echo "#!/bin/sh" >"${dir}/${PBI_UNINS_MIMESCRIPT}" cd "${PBI_CONFDIR}/${MOD_XDGMIME_DIR}" for i in `ls *.xml 2>/dev/null` do _mFound=1 cp "${i}" "${dir}/PBI-${i}" ifi="$PBI_PROGDIRPATH/${PBI_APPMIME_DIR}/PBI-${i}" # Check for a .directory file associated with this .desktop ifp="" iconfile="`basename -s .xml ${i}`" if [ -e "${iconfile}.png" ] ; then cp "${iconfile}.png" "${dir}/${iconfile}.png" ifp="$PBI_PROGDIRPATH/${PBI_APPMIME_DIR}/${iconfile}.png" mi=`cat "$i" | grep '> "${dir}/${PBI_INS_MIMESCRIPT}" echo "xdg-icon-resource uninstall --context mimetypes ${ifp} --size 64" \ >> "${dir}/${PBI_UNINS_MIMESCRIPT}" fi echo "xdg-mime install --novendor ${ifi}" \ >> "${dir}/${PBI_INS_MIMESCRIPT}" echo "xdg-mime uninstall ${ifi}" \ >> "${dir}/${PBI_UNINS_MIMESCRIPT}" done chmod 755 "${dir}/${PBI_INS_MIMESCRIPT}" chmod 755 "${dir}/${PBI_UNINS_MIMESCRIPT}" # No mime entries if [ "$_mFound" = "0" ] ; then rm "${dir}/${PBI_INS_MIMESCRIPT}" rm "${dir}/${PBI_UNINS_MIMESCRIPT}" fi } # Create the install script for the PBI mk_install_script() { echo "Creating install script..." if [ ! -d "${PBI_STAGEDIR}/${PBI_FAKEBIN_DIR}" ] ; then mkdir -p "${PBI_STAGEDIR}/${PBI_FAKEBIN_DIR}" ; fi insc="${PBI_STAGEDIR}/${PBI_FAKEBIN_DIR}/.pbi-install.sh" echo "#!/bin/sh" > "$insc" echo "PBI_WRAPPERBIN=\"${PBI_FAKEBIN_DIR}\"" >> "$insc" echo "PBI_PROGDIRPATH=\"${PBI_PROGDIRPATH}\"" >> "$insc" echo "SYS_LOCALBASE=\"${SYS_LOCALBASE}\"" >> "$insc" echo "cd \"\$PBI_PROGDIRPATH\"" >> "$insc" # Xorg Font setup if [ "${PBI_USESYSFONTS}" != "NO" ] ; then echo 'if [ -d "${PBI_PROGDIRPATH}/etc" ] ; then' >> "$insc" echo ' rm "${PBI_PROGDIRPATH}/etc/fonts" >/dev/null 2>/dev/null' >> "$insc" echo ' ln -fs "${SYS_LOCALBASE}/etc/fonts" "${PBI_PROGDIRPATH}/etc/fonts"' >> "$insc" echo 'fi' >> "$insc" echo 'if [ -d "${PBI_PROGDIRPATH}/lib/X11" ] ; then' >> "$insc" echo ' rm "${PBI_PROGDIRPATH}/lib/X11/fonts" >/dev/null 2>/dev/null' >> "$insc" echo ' ln -fs "${SYS_LOCALBASE}/lib/X11/fonts" "${PBI_PROGDIRPATH}/lib/X11/fonts"' >> "$insc" echo ' rm "${PBI_PROGDIRPATH}/lib/X11/icons" >/dev/null 2>/dev/null' >> "$insc" echo ' ln -fs "${SYS_LOCALBASE}/lib/X11/icons" "${PBI_PROGDIRPATH}/lib/X11/icons"' >> "$insc" echo ' rm "${PBI_PROGDIRPATH}/share/icons" >/dev/null 2>/dev/null' >> "$insc" echo ' ln -fs "${SYS_LOCALBASE}/share/icons" "${PBI_PROGDIRPATH}/share/icons"' >> "$insc" echo 'fi' >> "$insc" fi # Add the binary wrapper sym-links if [ -e "${PBI_STAGEDIR}/${PBI_FAKEBIN_DIR}/${PBI_INS_PATHSCRIPT}" ] ; then echo 'if [ `id -u` = "0" ] ; then ' >>${insc} echo " $PBI_PROGDIRPATH/${PBI_FAKEBIN_DIR}/${PBI_INS_PATHSCRIPT}" >>${insc} echo "fi" >>${insc} fi # Look for any XDG scripts if [ -e "${PBI_STAGEDIR}/${PBI_APPMIME_DIR}/${PBI_INS_MIMESCRIPT}" ] ; then echo "$PBI_PROGDIRPATH/${PBI_APPMIME_DIR}/${PBI_INS_MIMESCRIPT}" >>${insc} fi if [ -e "${PBI_STAGEDIR}/${PBI_APPMENU_DIR}/${PBI_INS_MENUSCRIPT}" ] ; then echo "$PBI_PROGDIRPATH/${PBI_APPMENU_DIR}/${PBI_INS_MENUSCRIPT}" >>${insc} fi chmod 755 "${insc}" } # Create the deinstall script for the PBI mk_deinstall_script() { echo "Creating deinstall script..." uisc="${PBI_STAGEDIR}/${PBI_FAKEBIN_DIR}/.pbi-uninstall.sh" echo "#!/bin/sh" > "$uisc" echo "PBI_PROGDIRPATH=\"${PBI_PROGDIRPATH}\"" >> "$uisc" echo "SYS_LOCALBASE=\"${SYS_LOCALBASE}\"" >> "$uisc" # Remove the binary wrapper sym-links if [ -e "${PBI_STAGEDIR}/${PBI_FAKEBIN_DIR}/${PBI_UNINS_PATHSCRIPT}" ] ; then echo 'if [ `id -u` = "0" ] ; then ' >>${uisc} echo " $PBI_PROGDIRPATH/${PBI_FAKEBIN_DIR}/${PBI_UNINS_PATHSCRIPT}" >>${uisc} echo "fi" >>${uisc} fi # Look for any XDG scripts if [ -e "${PBI_STAGEDIR}/${PBI_APPMIME_DIR}/${PBI_UNINS_MIMESCRIPT}" ] ; then echo "$PBI_PROGDIRPATH/${PBI_APPMIME_DIR}/${PBI_UNINS_MIMESCRIPT}" >>${uisc} fi if [ -e "${PBI_STAGEDIR}/${PBI_APPMENU_DIR}/${PBI_UNINS_MENUSCRIPT}" ] ; then echo "$PBI_PROGDIRPATH/${PBI_APPMENU_DIR}/${PBI_UNINS_MENUSCRIPT}" >>${uisc} fi chmod 755 "${uisc}" } # Create a dir for manipulating header info mk_header_dir() { PBI_HEADERDIR="${PBI_PROGDIRPATH}/.headerdir" if [ -e "${PBI_HEADERDIR}" ] ; then rm -rf "${PBI_HEADERDIR}" ; fi mkdir -p ${PBI_HEADERDIR} } # Remove the tmp header-dir rm_header_dir() { PBI_HEADERDIR="${PBI_PROGDIRPATH}/.headerdir" if [ -e "${PBI_HEADERDIR}" ] ; then rm -rf "${PBI_HEADERDIR}" ; fi } # Create a dir for staging the final archive mk_stage_dir() { local _excOpts="" PBI_STAGEDIR="${PBI_PROGDIRPATH}/.stagedir" echo "Creating Stage Dir: ${PBI_STAGEDIR}" if [ -e "${PBI_STAGEDIR}" ] ; then rm -rf "${PBI_STAGEDIR}" 2>/dev/null chflags -R noschg ${PBI_STAGEDIR} 2>/dev/null rm -rf "${PBI_STAGEDIR}" 2>/dev/null fi mkdir -p ${PBI_STAGEDIR} # Build module list of excludes if [ -n "$PBI_EXCLUDELIST" ] ; then for excl in $PBI_EXCLUDELIST do if [ -z "$_excOpts" ] ; then _excOpts="--exclude ${excl}" else _excOpts="$_excOpts --exclude ${excl}" fi done fi # Now copy the stagedir tar cvf - ${_excOpts} --exclude .stagedir \ --exclude .pkgdb --exclude .ld-elf.hints --exclude make.conf \ --exclude make.conf.bak --exclude .keepports \ -C "${PBI_PROGDIRPATH}" . 2>/dev/null \ | tar xvpf - -C ${PBI_STAGEDIR} 2>/dev/null } # Remove the stagedir rm_stage_dir() { cd / PBI_STAGEDIR="${PBI_PROGDIRPATH}/.stagedir" if [ -e "${PBI_STAGEDIR}" ] ; then rm -rf "${PBI_STAGEDIR}" 2>/dev/null chflags -R noschg ${PBI_STAGEDIR} 2>/dev/null rm -rf "${PBI_STAGEDIR}" 2>/dev/null fi } # See if we need to clean the icons dir clean_icons_dir() { if [ "${PBI_USESYSFONTS}" != "NO" ] ; then rm -rf ${PBI_STAGEDIR}/share/icons >/dev/null 2>/dev/null fi } # See if we need to clean the stagedir clean_stage_dir() { if [ "${PBI_USESYSGL}" != "NO" ] ; then rm ${PBI_STAGEDIR}/lib/libGl.* >/dev/null 2>/dev/null rm ${PBI_STAGEDIR}/lib/libGL.* >/dev/null 2>/dev/null rm ${PBI_STAGEDIR}/lib/libGLU.* >/dev/null 2>/dev/null fi if [ "${PBI_USESYSFONTS}" != "NO" ] ; then rm -rf ${PBI_STAGEDIR}/etc/fonts >/dev/null 2>/dev/null rm -rf ${PBI_STAGEDIR}/lib/X11/fonts >/dev/null 2>/dev/null rm -rf ${PBI_STAGEDIR}/lib/X11/icons >/dev/null 2>/dev/null fi } # Copy over any resource files into the PBI dir copy_resource_dir() { if [ -d "${PBI_CONFDIR}/${PBI_RESOURCE_DIR}" ] ; then echo "Copying ${PBI_CONFDIR}/${PBI_RESOURCE_DIR} -> ${PBI_STAGEDIR}" tar cvf - -C ${PBI_CONFDIR}/${PBI_RESOURCE_DIR} --exclude .svn . 2>/dev/null \ | tar xvpf - -C ${PBI_STAGEDIR} 2>/dev/null fi } # Check if tar supports lzma compression test_tar_lzma() { touch /tmp/.pbilzma.$$ >/dev/null 2>/dev/null tar cvJf /tmp/.pbilzma.tar.$$ /tmp/.pbilzma.$$ >/dev/null 2>/dev/null _exitcode=$? rm /tmp/.pbilzma.$$ >/dev/null 2>/dev/null rm /tmp/.pbilzma.tar.$$ >/dev/null 2>/dev/null return $_exitcode } # Start creating the application archive mk_archive_file() { # Build module list of excludes if [ -n "$PBI_EXCLUDELIST" ] ; then for excl in $PBI_EXCLUDELIST do if [ -z "$_excOpts" ] ; then _excOpts="--exclude ${excl}" else _excOpts="$_excOpts --exclude ${excl}" fi done fi PBI_CREATE_ARCHIVE="${PBI_CREATE_OUTDIR}/.PBI.$$.tbz" if test_tar_lzma ; then _tcmp="J" ; else _tcmp="j" ; fi echo "Creating compressed archive..." tar cv${_tcmp}f "${PBI_CREATE_ARCHIVE}" ${_excOpts} -C ${PBI_STAGEDIR} . 2>/dev/null } # Start creating the header archive mk_header_file() { PBI_HEADER_ARCHIVE="${PBI_CREATE_OUTDIR}/.PBI-header.$$.tbz" tar cvjf ${PBI_HEADER_ARCHIVE} -C ${PBI_HEADERDIR} . >/dev/null 2>/dev/null } # Start copying pbi details into header file save_pbi_details_to_header() { local _osArch="$ARCH" local _osRel="$FBSDREL" if [ -n "${PBI_OSREL}" ] ; then _osRel="${PBI_OSREL}" fi if [ "${PBI_CREATEONLY}" = "YES" ] ; then _pbilow="`echo ${PBI_PROGNAME} | tr '[:upper:]' '[:lower:]' | sed 's| ||g'`" echo "${PBI_APPDIR}/${_pbilow}-${_osArch}" > "${PBI_HEADERDIR}/pbi_defaultpath" else echo "${PBI_PROGDIRPATH}" > "${PBI_HEADERDIR}/pbi_defaultpath" fi echo "${PBI_PROGNAME}" > "${PBI_HEADERDIR}/pbi_name" echo "${PBI_PROGVERSION}" > "${PBI_HEADERDIR}/pbi_version" echo "${PBI_PROGAUTHOR}" > "${PBI_HEADERDIR}/pbi_author" echo "${PBI_PROGWEB}" > "${PBI_HEADERDIR}/pbi_web" date "+%Y%m%d %H%M%S" > "${PBI_HEADERDIR}/pbi_mdate" if [ "${PBI_REQUIRESROOT}" = "YES" ] ; then touch ${PBI_HEADERDIR}/pbi_requiresroot fi # Do we have a license to accept? if [ -e "${PBI_CONFDIR}/${PBI_LICENSEFILE}" ] ; then cp "${PBI_CONFDIR}/${PBI_LICENSEFILE}" "${PBI_HEADERDIR}/${PBI_LICENSEFILE}" fi # Custom install / remove scripts if [ -e "${PBI_CONFDIR}/${PBI_CONF_SCRIPTSDIR}/${MOD_PREINS}" ] ; then cp "${PBI_CONFDIR}/${PBI_CONF_SCRIPTSDIR}/${MOD_PREINS}" \ "${PBI_HEADERDIR}/${MOD_PREINS}" else echo "#!/bin/sh" > ${PBI_HEADERDIR}/${MOD_PREINS} fi if [ -e "${PBI_CONFDIR}/${PBI_CONF_SCRIPTSDIR}/${MOD_POSTINS}" ] ; then cp "${PBI_CONFDIR}/${PBI_CONF_SCRIPTSDIR}/${MOD_POSTINS}" \ "${PBI_HEADERDIR}/${MOD_POSTINS}" else echo "#!/bin/sh" > ${PBI_HEADERDIR}/${MOD_POSTINS} fi if [ -e "${PBI_CONFDIR}/${PBI_CONF_SCRIPTSDIR}/${MOD_PREREM}" ] ; then cp "${PBI_CONFDIR}/${PBI_CONF_SCRIPTSDIR}/${MOD_PREREM}" \ "${PBI_HEADERDIR}/${MOD_PREREM}" else echo "#!/bin/sh" > ${PBI_HEADERDIR}/${MOD_PREREM} fi # Copy over our icon if [ -n "${PBI_PROGICON}" -a -e "${PBI_STAGEDIR}/${PBI_PROGICON}" ] ; then # Get the file extension _iconExt=`echo "$PBI_PROGICON" | awk -F . '{print $NF}'` cp "${PBI_STAGEDIR}/${PBI_PROGICON}" "${PBI_HEADERDIR}/pbi_icon.${_iconExt}" >/dev/null 2>/dev/null else _iconExt=`echo "$PBI_DEFAULT_ICON_CHROOT" | awk -F . '{print $NF}'` cp "${PBI_DEFAULT_ICON_CHROOT}" "${PBI_HEADERDIR}/pbi_icon.${_iconExt}" >/dev/null 2>/dev/null fi # Check for any gui images if [ -e "${PBI_STAGEDIR}/${PBI_GUITOPBANNER}" ] ; then cp "${PBI_STAGEDIR}/${PBI_GUITOPBANNER}" "${PBI_HEADERDIR}/top-banner.png" fi if [ -e "${PBI_STAGEDIR}/${PBI_GUISIDEBANNER}" ] ; then cp "${PBI_STAGEDIR}/${PBI_GUISIDEBANNER}" "${PBI_HEADERDIR}/side-banner.png" fi # Save the uname details echo "${_osArch}" > "${PBI_HEADERDIR}/pbi_arch" echo "${_osRel}" > "${PBI_HEADERDIR}/pbi_fbsdver" echo "${PROGVERSION}" > "${PBI_HEADERDIR}/pbi_createver" # Get the total number of files in the STAGEDIR get_filetotal_dir "${PBI_STAGEDIR}" echo "${FILETOTAL}" > "${PBI_HEADERDIR}/pbi_archivecount" # Save a checksum of archive file sha256 -q "${PBI_CREATE_ARCHIVE}" > "${PBI_HEADERDIR}/pbi_archivesum" sign_pbi_files "$PBI_HEADERDIR" } # Use openssl to sign parts of the pbi header structure and archive sign_pbi_files() { if [ -z "${PBI_SSLPRIVKEY}" ] ; then return 0 ; fi _sf="${1}/pbi_archivesum ${1}/${MOD_PREINS} ${1}/${MOD_POSTINS} ${1}/${MOD_PREREM}" for i in $_sf do openssl dgst -sha1 \ -sign ${PBI_SSLPRIVKEY} \ -out ${i}.sha1 \ ${i} >/dev/null 2>/dev/null done } # All the pieces are ready, spit out the final PBI file mk_output_pbi() { if [ -n "${PBI_PROGICON}" -a -e "${PBI_STAGEDIR}/${PBI_PROGICON}" ] ; then icon="${PBI_STAGEDIR}/${PBI_PROGICON}" else icon="${PBI_DEFAULT_ICON_CHROOT}" fi _pbilow="`echo ${PBI_PROGNAME} | tr '[:upper:]' '[:lower:]' | sed 's| ||g'`" outfile="${PBI_CREATE_OUTDIR}/${_pbilow}-${PBI_PROGVERSION}-${ARCH}.pbi" mark1="${PBI_CREATE_OUTDIR}/.pbimark1.$$" mark2="${PBI_CREATE_OUTDIR}/.pbimark2.$$" echo " ${PBI_SS_ICON}" >$mark1 echo " ${PBI_SS_ARCHIVE}" >$mark2 # DO IT, DO IT NOW!!! cat ${PBI_HEADER_ARCHIVE} $mark1 ${icon} $mark2 ${PBI_CREATE_ARCHIVE} > ${outfile} sha256 -q ${outfile} > ${outfile}.sha256 echo "Created PBI: ${outfile}" rm $mark1 rm $mark2 rm ${PBI_HEADER_ARCHIVE} rm ${PBI_CREATE_ARCHIVE} } get_filetotal_dir() { FILETOTAL="`find ${1} | wc -l | tr -d ' '`" } pbi_delete_init() { require_root_or_group init_tmpdir parse_delete_pbi_cmdline "$@" do_pbi_delete } # Delete this PBI do_pbi_delete() { load_info_from_dir "${PBI_DBAPPDIR}/${PBI_DELETENAME}" PBI_PROGDIRPATH="${PBI_ORIGPROGDIRPATH}" get_username_from_file "${PBI_DBAPPDIR}/${PBI_DELETENAME}/pbi_name" if [ "$FILEUSER" != `whoami` -a `id -u` != "0" ] ; then exit_err "Permission denied to modify PBI installed by: $FILEUSER" fi # Set the dirty flag that we are removing this PBI touch ${PBI_DBAPPDIR}/${PBI_DELETENAME}/.pbiDeleted check_preremove_script run_remove_script remove_pbidir unregister_pbi # Mark the hashdir as dirty make_hashdir_dirty } # Save the hash-list to run a cleanup afterwards pbirm_save_hashlist() { if [ "${PBI_DISABLEHASHDIR}" = "YES" ] ; then return 0 ; fi if [ -e "${PBI_PROGDIRPATH}/${PBI_HASHLIST}" ] ; then PBI_TMPHASHLIST="${PBI_TMPDIR}/.pbi-hash.$$" cp ${PBI_PROGDIRPATH}/${PBI_HASHLIST} ${PBI_TMPHASHLIST} fi } # Function which removes all empty dirs from the hash-dir pbi_clean_emptyhdirs() { if [ ! -d "${PBI_HASHDIR}" ] ; then return 0 ; fi cd ${PBI_HASHDIR} found="0" for i in `find . -empty -type d 2>/dev/null` do if [ "${i}" = "." ] ; then continue ; fi if [ -d "${PBI_HASHDIR}/${i}" ] ; then rmdir "${PBI_HASHDIR}/${i}" found="1" fi done # Run recursively if [ "$found" = "1" ];then pbi_clean_emptyhdirs ; fi } # Read through and clean the given hash-list pbi_clean_hashlist() { if [ -z "${PBI_TMPHASHLIST}" ] ; then return 0 ; fi while read hl do file="`echo $hl | sed 's/:::.*$//g'`" hash="`echo $hl | sed 's/^.*::://g'`" tfile="${file}:::${hash}" if [ -f "${PBI_HASHDIR}/${tfile}" ] ; then check_remove_hashfile "${tfile}" fi done < ${PBI_TMPHASHLIST} rm ${PBI_TMPHASHLIST} } # Read through and clean the entire hashdir pbi_clean_hashdir() { if [ ! -d "${PBI_HASHDIR}" ] ; then return 0 ; fi echo "Cleaning shared-hash dir..." cd ${PBI_HASHDIR} tmphashlist="${PBI_TMPDIR}/.pbi-hashdir.$$" find * -type f -links 1 > "${tmphashlist}" 2>/dev/null while read hl do if [ ! -f "$hl" -o -h "$hl" ] ; then continue ; fi if [ -f "${PBI_HASHDIR}/${hl}" ] ; then check_remove_hashfile "${hl}" fi done < $tmphashlist rm "$tmphashlist" pbi_clean_emptyhdirs } # Check if this hash-file is ready to be removed from the hash-dir check_remove_hashfile() { tfile="${PBI_HASHDIR}/${1}" get_hard_link_count "${tfile}" if [ "$HLINKS" = "1" ] ; then if [ "${PBI_VERBOSE}" = "YES" ] ; then echo "Removing unused hashfile: $tfile" fi rm -f "${tfile}" fi } # Run the removal script for this PBI run_remove_script() { uisc="${PBI_PROGDIRPATH}/${PBI_FAKEBIN_DIR}/.pbi-uninstall.sh" if [ ! -e "$uisc" ] ; then return 0 ; fi # If not running as root, be sure to cleanup path links if [ "`id -u`" != "0" ]; then cat ${PBI_PROGDIRPATH}/${PBI_FAKEBIN_DIR}/${PBI_UNINS_PATHSCRIPT} | grep 'rm "$SYS_LOCALBASE/bin' | sed 's|$SYS_LOCALBASE|${HOME}|g' >${PBI_TMPDIR}/.binlnks while read lnk do /bin/sh -c "${lnk}" done <${PBI_TMPDIR}/.binlnks rm ${PBI_TMPDIR}/.binlnks fi export_script_vars if [ "$PBI_VERBOSE" = "YES" ] ; then sh "${uisc}" else sh "${uisc}" >/dev/null 2>/dev/null fi } # Function to check the supplied $1 dir for any mounts before we # do a rm -rf umount_before_rm() { if [ -z "${1}" ] ; then return 0 ; fi local _ddir="$1" echo "$_ddir" | rev | grep -q '^/' if [ $? -ne 0 ] ; then _ddir="${_ddir}/" fi mount | grep -q "on ${_ddir}" if [ $? -ne 0 ] ; then return 0; fi for i in `mount | grep "on ${_ddir}" | awk '{print $3}'` do umount -f ${i} >/dev/null 2>/dev/null if [ $? -ne 0 ] ; then exit_err "Could not umount ${i} before rm -rf, bailing!" fi done return 0 } # Remove the pbi directory remove_pbidir() { if [ -z "${PBI_PROGDIRPATH}" ] ; then return 0 ; fi if [ ! -d "${PBI_PROGDIRPATH}" ] ; then return 0 ; fi if [ "${PBI_PROGDIRPATH}" = "/" ] ; then return 0 ; fi if [ "$PBI_VERBOSE" = "YES" ] ; then echo "Removing: ${PBI_PROGDIRPATH}" fi # Make sure we are unmounted umount_before_rm "${PBI_PROGDIRPATH}" rm -rf "${PBI_PROGDIRPATH}" >/dev/null 2>/dev/null # Do we have leftovers? if [ -d "${PBI_PROGDIRPATH}" ] ; then chflags -R noschg "${PBI_PROGDIRPATH}" >/dev/null 2>/dev/null chmod -R 777 "${PBI_PROGDIRPATH}" >/dev/null 2>/dev/null rm -rf "${PBI_PROGDIRPATH}" >/dev/null 2>/dev/null fi } # Remove this PBI registration unregister_pbi() { if [ -z "${PBI_DBAPPDIR}" ] ; then return 0 ; fi if [ -z "${PBI_DELETENAME}" ] ; then return 0 ; fi if [ ! -d "${PBI_DBAPPDIR}/${PBI_DELETENAME}" ] ; then return 0 ; fi if [ "$PBI_VERBOSE" = "YES" ] ; then echo "Removing: ${PBI_DBAPPDIR}/${PBI_DELETENAME}" fi rm -rf "${PBI_DBAPPDIR}/${PBI_DELETENAME}" } # Check if we have a preinstall script we need to use check_preremove_script() { if [ ! -e "${PBI_DBAPPDIR}/${PBI_DELETENAME}/${MOD_PREREM}" ] ; then return 0 ; fi if [ "$PBI_VERBOSE" = "YES" ] ; then echo "Running pre-removal script: ${PBI_DBAPPDIR}/${PBI_DELETENAME}/${MOD_PREREM}" fi export_script_vars sh "${PBI_DBAPPDIR}/${PBI_DELETENAME}/${MOD_PREREM}" } add_app_path_links() { # If root, run the regular path script if [ `id -u` = "0" ] ; then sh "${1}/${PBI_FAKEBIN_DIR}/${PBI_INS_PATHSCRIPT}" >/dev/null 2>/dev/null return fi # Running as user add to ~/bin init_tmpdir if [ ! -d "${HOME}/bin" ] ; then mkdir -p "${HOME}/bin"; fi cat ${1}/${PBI_FAKEBIN_DIR}/${PBI_INS_PATHSCRIPT} | grep "${1}/${PBI_FAKEBIN_DIR}" | grep '$SYS_LOCALBASE/bin' | sed 's|$SYS_LOCALBASE|${HOME}|g' >${PBI_TMPDIR}/.binlnks while read lnk do /bin/sh -c "${lnk}" done <${PBI_TMPDIR}/.binlnks rm ${PBI_TMPDIR}/.binlnks } del_app_path_links() { # If root, run the regular path script if [ `id -u` = "0" ] ; then sh "${1}/${PBI_FAKEBIN_DIR}/${PBI_UNINS_PATHSCRIPT}" >/dev/null 2>/dev/null return fi # Running as user remove from ~/bin if [ ! -d "${HOME}/bin" ] ; then mkdir -p "${HOME}/bin"; fi for lnk in `ls ${1}/${PBI_FAKEBIN_DIR}` do if [ "$lnk" = "$PBI_INS_PATHSCRIPT" -o "$lnk" = "$PBI_UNINS_PATHSCRIPT" ] then continue fi if [ ! -e "${HOME}/bin/$lnk" ] ; then continue ; fi if [ ! -h "${HOME}/bin/$lnk" ] ; then continue ; fi ls -al "${HOME}/bin/$lnk" | awk '{print $11}' | grep $1 >/dev/null 2>/dev/null if [ "$?" = "0" ] ; then rm ${HOME}/bin/$lnk fi done } pbi_icon_init() { parse_icon_pbi_cmdline "$@" do_pbi_icon } # Start the PBI icon process do_pbi_icon() { # Get the dir for this PBI _appDir=`cat ${PBI_DBAPPDIR}/${PBI_ICONTARGETAPP}/pbi_installedpath` if [ "${PBI_PATHADD}" = "YES" ] ; then add_app_path_links "$_appDir" fi if [ "${PBI_PATHDEL}" = "YES" ] ; then del_app_path_links "$_appDir" fi if [ "${PBI_DESKADD}" = "YES" ] ; then if [ ! -e "${_appDir}/.xdg-desktop/${PBI_INS_DESKSCRIPT}" ] ; then exit_err "No desktop icons for this PBI" fi sh "${_appDir}/.xdg-desktop/${PBI_INS_DESKSCRIPT}" fi if [ "${PBI_DESKDEL}" = "YES" ] ; then if [ ! -e "${_appDir}/.xdg-desktop/${PBI_UNINS_DESKSCRIPT}" ] ; then exit_err "No desktop icons for this PBI" fi sh "${_appDir}/.xdg-desktop/${PBI_UNINS_DESKSCRIPT}" fi if [ "${PBI_MENUADD}" = "YES" ] ; then require_root_or_group if [ ! -e "${_appDir}/.xdg-menu/${PBI_INS_MENUSCRIPT}" ] ; then exit_err "No menu icons for this PBI" fi sh "${_appDir}/.xdg-menu/${PBI_INS_MENUSCRIPT}" fi if [ "${PBI_MENUDEL}" = "YES" ] ; then require_root_or_group if [ ! -e "${_appDir}/.xdg-menu/${PBI_UNINS_MENUSCRIPT}" ] ; then exit_err "No menu icons for this PBI" fi sh "${_appDir}/.xdg-menu/${PBI_UNINS_MENUSCRIPT}" fi if [ "${PBI_MIMEADD}" = "YES" ] ; then require_root_or_group if [ ! -e "${_appDir}/.xdg-mime/${PBI_INS_MIMESCRIPT}" ] ; then exit_err "No mime registration for this PBI" fi sh "${_appDir}/.xdg-mime/${PBI_INS_MIMESCRIPT}" fi if [ "${PBI_MIMEDEL}" = "YES" ] ; then require_root_or_group if [ ! -e "${_appDir}/.xdg-mime/${PBI_UNINS_MIMESCRIPT}" ] ; then exit_err "No mime registration for this PBI" fi sh "${_appDir}/.xdg-mime/${PBI_UNINS_MIMESCRIPT}" fi } pbid_init() { require_root parse_pbid_cmdline "$@" do_pbid } # Start the PBID daemon do_pbid() { # Start by sourcing /etc/profile # This grabs any HTTP_ / FTP_ PROXY variables . /etc/profile # Allow user supplied logfile if [ -z "${PBID_LOGFILE}" ] ; then _pbid_log="/var/log/pbid.log" else _pbid_log="${PBID_LOGFILE}" fi # Set verbosity _redir="&1" if [ "${PBI_VERBOSE}" != "YES" ] ; then _redir="/dev/null" ; fi echo "Started pbid: `date`" > ${_pbid_log} while i=1 do # Do regular sleeps qslp=0 # Check if we have any out of date index files to update for _dbIndex in `ls ${PBI_DBREPODIR}` do _iMd5=`echo ${_dbIndex} | cut -d '.' -f 2` check_update_index "${_iMd5}" # If we failed to get an index try again sooner # This is useful if the user has just installed and has not setup # the network yet. We want to fetch indexes quickly after net # comes up so they dont need to wait 15 min or whatever its set to if [ ! -e "${PBI_DBINDEXDIR}/${_iMd5}-index" ] ; then qslp=1; fi done # Check if we have a dirty hash-dir to cleanup check_clean_hashdir "$_pbid_log" "$_redir" # Check if we have any PBIs to auto-update check_autoupdate_pbis "$_pbid_log" "$_redir" # Check if we need to merge files into the hashdir if [ -n "`ls ${PBI_DBHASHQUEUEDIR}`" ] ; then init_tmpdir for _hpbi in `ls ${PBI_DBHASHQUEUEDIR}` do if [ ! -e "${PBI_DBAPPDIR}/${_hpbi}/pbi_installedpath" ] ; then rm ${PBI_DBHASHQUEUEDIR}/${_hpbi} continue fi _hpbipath="" _hpbipath=`cat ${PBI_DBAPPDIR}/${_hpbi}/pbi_installedpath` if [ ! -e "${_hpbipath}/${PBI_HASHLIST}" ] ; then rm ${PBI_DBHASHQUEUEDIR}/${_hpbi} continue fi # Get the username this PBI was installed as get_username_from_file "${_hpbipath}" # Lets start this hash merge echo "Adding ${_hpbipath} to hash-dir ($FILEUSER): `date`" >> ${_pbid_log} if [ "$FILEUSER" = "root" ];then pbi_add_update_hashdir "${_hpbipath}" "${PBI_DBAPPDIR}/${_hpbi}/.pbiDeleted" >${_redir} 2>${_redir} else # Run hashdir command as a user su $FILEUSER -c "pbi_update_hashdir \"${_hpbipath}\" \"${PBI_DBAPPDIR}/${_hpbi}/.pbiDeleted\"" >${_redir} 2>${_redir} fi echo "Finished adding ${_hpbipath} to hash-dir: `date`" >> ${_pbid_log} # Now remove the trigger file rm ${PBI_DBHASHQUEUEDIR}/${_hpbi} done rm_tmpdir fi # Check if we should rotate the logfile _pbidLines=`wc -l ${_pbid_log} | awk '{ print $1 }'` if [ $(is_num "$_pbidLines") ] ; then if [ $_pbidLines -gt $PBI_LOG_LINES ] ; then echo "Logfile turnover: `date`" >${_pbid_log} fi fi # Done with our check, lets go back to sleep now if [ $qslp -eq 1 ] ; then sleep 60 else sleep ${PBIDSLEEP} fi done } # Check if there are any PBIs which are flagged for auto-updates check_autoupdate_pbis() { for i in `ls ${PBI_DBAPPDIR}/ 2>/dev/null` do if [ ! -e "${PBI_DBAPPDIR}/${i}/autoupdate-enable" ] ; then continue fi # Check if this app is already updating if [ -e "${PBI_DBAPPDIR}/${i}/.updating" ] ; then ps -p `cat ${PBI_DBAPPDIR}/${i}/.updating` >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then rm "${PBI_DBAPPDIR}/${PBI_UPDATEAPP}/.updating" else continue fi fi # Found an auto-update enabled APP, see if it needs upping PBI_UPDATEAPP="$i" # Load the details about this app load_info_from_dir "${PBI_DBAPPDIR}/${PBI_UPDATEAPP}" if [ -z "${PBI_REPO}" ]; then pbi_checksig_repomatch "${PBI_DBAPPDIR}/${PBI_UPDATEAPP}" fi if [ -z "${PBI_REPO}" ]; then continue ; fi local _repoID=`ls ${PBI_DBREPODIR}/*.${PBI_REPO} | cut -d '.' -f 1 | sed "s|${PBI_DBREPODIR}/||g"` # Does this need an update? check_pbi_update "$PBI_UPDATEAPP" "nodisplay" \ "$PBI_PROGNAME" "current" \ "$PBI_FBSDVER" "$PBI_APPARCH" "$_repoID" "$PBI_PROGMDATE" if [ "$?" != "0" ] ; then continue fi # Get the username this PBI was installed as get_username_from_file "${PBI_DBAPPDIR}/${PBI_UPDATEAPP}" # Its Update Time! echo "Starting Auto-Update of ${PBI_UPDATEAPP} ($FILEUSER): `date`" >>${_pbid_log} su ${FILEUSER} -c "pbi_update ${PBI_UPDATEAPP}" >>${_pbid_log} 2>>${_pbid_log} if [ "$?" = "0" ] ; then echo "Success! Update of ${PBI_UPDATEAPP}: `date`" >>${_pbid_log} else echo "Failed! Update of ${PBI_UPDATEAPP}: `date`" >>${_pbid_log} fi rm "${PBI_DBAPPDIR}/${i}/.updating" >/dev/null 2>/dev/null done } check_clean_hashdir() { if [ ! -e "${PBI_DBDIRTYFILE}" ] ; then return ; fi # Get the date of the last hash-cleaning done local _curDate="`cat ${PBI_DBDIRTYFILE}`" if [ -e "${PBI_DBDIRTYFILE}.last" ] ; then local _lastDate="`cat ${PBI_DBDIRTYFILE}.last`" else local _lastDate="0" fi # See if we have a new date trigger to do a cleaning if [ "$_curDate" = "${_lastDate}" ]; then return; fi # Loop through and clean any hash-dirs as the appropriate user for cHdir in `ls -d ${PBI_HASHDIR}*` do get_username_from_file "${cHdir}" echo "Cleaning hash-dir ($FILEUSER): `date`" >> ${1} su ${FILEUSER} -c "pbi_delete --clean-hdir" >>${2} 2>>${2} echo "Finished cleaning hash-dir ($FILEUSER): `date`" >> ${1} echo "$_curDate" > ${PBI_DBDIRTYFILE}.last 2>/dev/null done } pbi_info_init() { parse_info_pbi_cmdline "$@" do_pbi_info } # Display information on the PBI / PBIs do_pbi_info() { # If we are listing available PBIs via the index file if [ "$PBI_INFOINDEX" = "YES" ] ; then # List the available PBIs from the index do_index_listing exit_trap fi if [ "$PBI_INFONAME" = "--ALL--" ] ; then for i in `ls ${PBI_DBAPPDIR}/ 2>/dev/null` do if [ -e "${PBI_DBAPPDIR}/${i}/pbi_name" ] ; then if [ "$PBI_VERBOSE" = "YES" ] ; then load_info_from_dir "${PBI_DBAPPDIR}/${i}" get_username_from_file "${PBI_DBAPPDIR}/${i}" PBI_INSTALLED_BY=$FILEUSER pbi_display_info pbi_display_gui "${PBI_DBAPPDIR}/${i}" "" echo " " else echo "${i}" fi fi done else # Start loading our variables load_info_from_dir "${PBI_DBAPPDIR}/${PBI_INFONAME}" get_username_from_file "${PBI_DBAPPDIR}/${PBI_INFONAME}" PBI_INSTALLED_BY=$FILEUSER pbi_display_info fi } # Read through the master index file and provide listing of available PBIs for installation do_index_listing() { # Make sure we have a master index ls ${PBI_DBINDEXDIR}/* >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then return ; fi for _rIndex in `ls ${PBI_DBINDEXDIR}/*index* | grep -v '.time'` do _rMd5=`basename ${_rIndex} | sed 's|-index||g'` _rDesc=`cat ${PBI_DBREPODIR}/*.${_rMd5} | grep 'Desc: ' | sed 's|Desc: ||g'` echo "Current and available PBIs. * = current" echo "Repository: $_rDesc" echo "----------------------------------------------------------------" sort "${_rIndex}" | while read _iLine do PBI_UPNAME="`echo $_iLine | cut -d ':' -f 1`" PBI_UPARCH="`echo $_iLine | cut -d ':' -f 2`" PBI_UPNVER="`echo $_iLine | cut -d ':' -f 3`" PBI_UPSTATUS="`echo $_iLine | cut -d ':' -f 9`" pad_var "${PBI_UPNAME}" "30" PBI_UPNAME="${PAD_VAR}" pad_var "${PBI_UPNVER}" "15" PBI_UPNVER="${PAD_VAR}" pad_var "${PBI_UPARCH}" "6" PBI_UPARCH="${PAD_VAR}" if [ "$PBI_UPSTATUS" = "current" ] ; then echo "$PBI_UPNAME $PBI_UPNVER $PBI_UPARCH *" fi if [ "$PBI_UPSTATUS" = "active" ] ; then echo "$PBI_UPNAME $PBI_UPNVER $PBI_UPARCH" fi done done } # Function to pad a variable to X spaces pad_var() { local _pVar="$1" local _pNum="$2" PAD_VAR="`echo \"$_pVar x\" | cut -c 1-$_pNum`" } # Checks if we have a custom script to run prior to port make run_pbi_preportmake() { if [ ! -d "${PBI_CONFDIR}" ] ; then return 0 ; fi if [ ! -d "${PBI_CONFDIR}/${PBI_CONF_SCRIPTSDIR}" ] ; then return 0 ; fi if [ ! -e "${PBI_CONFDIR}/${PBI_CONF_SCRIPTSDIR}/pre-portmake.sh" ] ; then return 0 ; fi export_script_vars sh "${PBI_CONFDIR}/${PBI_CONF_SCRIPTSDIR}/pre-portmake.sh" if [ "$?" != "0" ] ; then exit_err "pre-portmake.sh failed!" fi } # Checks if we have a custom script to run prior to port make run_pbi_postportmake() { if [ ! -d "${PBI_CONFDIR}" ] ; then return 0 ; fi if [ ! -d "${PBI_CONFDIR}/${PBI_CONF_SCRIPTSDIR}" ] ; then return 0 ; fi if [ ! -e "${PBI_CONFDIR}/${PBI_CONF_SCRIPTSDIR}/post-portmake.sh" ] ; then return 0 ; fi export_script_vars sh "${PBI_CONFDIR}/${PBI_CONF_SCRIPTSDIR}/post-portmake.sh" if [ "$?" != "0" ] ; then echo "Warning: post-portmake.sh returned non-0 status!" fi } # Checks if we have a custom script to run prior to pbi create run_pbi_prepkgscript() { if [ ! -d "${PBI_CONFDIR}" ] ; then return 0 ; fi if [ ! -d "${PBI_CONFDIR}/${PBI_CONF_SCRIPTSDIR}" ] ; then return 0 ; fi if [ ! -e "${PBI_CONFDIR}/${PBI_CONF_SCRIPTSDIR}/pre-pbicreate.sh" ] ; then return 0 ; fi export_script_vars sh "${PBI_CONFDIR}/${PBI_CONF_SCRIPTSDIR}/pre-pbicreate.sh" if [ "$?" != "0" ] ; then echo "Warning: post-portmake.sh returned non-0 status!" fi } # Begins the port make start_pbi_makeport() { do_port_build "/usr/ports/${PBI_MAKEPORT}" } # Prune any ports which aren't required for runtime start_pbi_prune_ports() { if [ "${PBI_PRUNEBUILDPORTS}" = "NO" ] ; then return ; fi local iFile="$PORTSDIR/INDEX-$FBSDMAJOR" get_pkgname "${PORTSDIR}/${PBI_MAKEPORT}" echo "${PKGNAME}" > /.keepports grep "^${PKGNAME}|" $iFile | cut -d '|' -f 9 | tr ' ' '\n' >>/.keepports # Do the same for any OTHERPORTS for port in ${PBI_MKPORTBEFORE} do if [ ! -d "${PORTSDIR}/${port}" ] ; then continue ; fi get_pkgname "${PORTSDIR}/${port}" echo "${PKGNAME}" >> /.keepports grep "^${PKGNAME}|" $iFile | cut -d '|' -f 9 | tr ' ' '\n' >>/.keepports done for port in ${PBI_MKPORTAFTER} do if [ ! -d "${PORTSDIR}/${port}" ] ; then continue ; fi get_pkgname "${PORTSDIR}/${port}" echo "${PKGNAME}" >> /.keepports grep "^${PKGNAME}|" $iFile | cut -d '|' -f 9 | tr ' ' '\n' >>/.keepports done # Sort and clean the ports cat /.keepports | sort | uniq > /.keepports.tmp mv /.keepports.tmp /.keepports # Define some commands if [ $PKGNG -eq 1 ] ; then pkgInf="pkg info -f" else pkgInf="pkg_info -I -a" fi # Now remove any unused ports for j in `$pkgInf | cut -d " " -f 1` do grep -q "^${j}" "/.keepports" if [ $? -ne 0 ] ; then echo "Removing non-required port: ${j}" $PKG_DELETE ${j} fi done } # Get the full package-name for a target port get_pkgname() { name="`make -C ${1} -V PKGNAME PORTSDIR=${PORTSDIR}`" PKGNAME="${name}" } # Make any additional required ports start_pbi_mkportbefore() { if [ -z "${PBI_MKPORTBEFORE}" ] ; then return ; fi for port in ${PBI_MKPORTBEFORE} do if [ ! -d "/usr/ports/${port}" ] ; then exit_err "/usr/ports/${port} does not exist!" fi do_port_build "/usr/ports/${port}" done } # Make any additional required ports start_pbi_mkportafter() { if [ -z "${PBI_MKPORTAFTER}" ] ; then return ; fi for port in ${PBI_MKPORTAFTER} do if [ ! -d "/usr/ports/${port}" ] ; then exit_err "/usr/ports/${port} does not exist!" fi do_port_build "/usr/ports/${port}" done } # Start pbi_update_hashdir pbi_update_hashdir_init() { pbi_add_update_hashdir "$1" "$2" } # Start pbi_update processing pbi_update_init() { parse_update_pbi_cmdline "$@" check_enable_disable_auto # Stop here if we are just enabling / disabling auto-update if [ -n "$PBI_UPENABLEAUTO" ] ; then return 0 ; fi start_update_checks if [ "$?" != "0" ] ; then rm_tmpdir ; exit 1 ; fi # Stop here if only doing update checks if [ -n "${PBI_UPCHECK}" ]; then return 0 ; fi require_root_or_group do_pbi_update } # Check if we are enabling / disabling auto-updating check_enable_disable_auto() { if [ -z "$PBI_UPENABLEAUTO" ] ; then return ; fi if [ ! -d "${PBI_DBAPPDIR}/${PBI_UPDATEAPP}" ] ; then return ; fi # Enable / disable auto-updating now if [ "$PBI_UPENABLEAUTO" = "YES" ]; then touch ${PBI_DBAPPDIR}/${PBI_UPDATEAPP}/autoupdate-enable else rm ${PBI_DBAPPDIR}/${PBI_UPDATEAPP}/autoupdate-enable >/dev/null 2>/dev/null fi } # Function which checks the digital signature of a PBI to match it to a particular repo pbi_checksig_repomatch() { if [ `id -u` != "0" ] ; then return ; fi # See which repo / key this PBI associates to, if any check_valid_sigs "${1}" if [ "$?" = "0" -a -n "$PBI_VALIDKEYSIG" ] ; then _rMd5="`echo ${PBI_VALIDKEYSIG} | cut -d '.' -f 1`" echo "$_rMd5" | sed "s|${PBI_DBKEYDIR}/||g" > ${1}/pbi_repo fi } # See if we are checking for updates and do it start_update_checks() { if [ "${PBI_UPCHECK}" != "YES" -a "${PBI_UPCHECK}" != "ALL" ]; then return 0; fi # Open up the tmpdir init_tmpdir if [ "${PBI_UPCHECK}" = "YES" ] ; then load_info_from_dir "${PBI_DBAPPDIR}/${PBI_UPDATEAPP}" if [ -z "${PBI_REPO}" ]; then pbi_checksig_repomatch "${PBI_DBAPPDIR}/${PBI_UPDATEAPP}" fi if [ -z "${PBI_REPO}" ]; then return 1 else local _repoID=`ls ${PBI_DBREPODIR}/*.${PBI_REPO} | cut -d '.' -f 1 | sed "s|${PBI_DBREPODIR}/||g"` fi check_pbi_update "$PBI_UPDATEAPP" "display" \ "$PBI_PROGNAME" "current" \ "$PBI_FBSDVER" "$PBI_APPARCH" "$_repoID" "$PBI_PROGMDATE" return $? else # Loop and check all PBIs for updates for i in `ls ${PBI_DBAPPDIR}/ 2>/dev/null` do PBI_REPO="" if [ -e "${PBI_DBAPPDIR}/${i}/pbi_name" ] ; then load_info_from_dir "${PBI_DBAPPDIR}/${i}" if [ -z "${PBI_REPO}" ]; then pbi_checksig_repomatch "${PBI_DBAPPDIR}/${i}" fi if [ -z "${PBI_REPO}" ]; then continue else local _repoID=`ls ${PBI_DBREPODIR}/*.${PBI_REPO} | cut -d '.' -f 1 | sed "s|${PBI_DBREPODIR}/||g"` fi check_pbi_update "$i" "display" \ "$PBI_PROGNAME" "current" \ "$PBI_FBSDVER" "$PBI_APPARCH" "$_repoID" "$PBI_PROGMDATE" fi done return 0 fi } # Check if we need to pull down the updated INDEX file check_update_index() { init_tmpdir local _repoMd5="$1" local _rURL=`cat ${PBI_DBREPODIR}/*${_repoMd5} | grep URL: | sed 's|URL: ||g'` _pbiIndex="${PBI_DBINDEXDIR}/${_repoMd5}-index" _pbiMeta="${PBI_DBINDEXDIR}/${_repoMd5}-meta" _pbiIndexTime="${_pbiIndex}.time" _tmpPbiIndex="${PBI_TMPDIR}/.upcheck$$" _tmpPbiMeta="${PBI_TMPDIR}/.upcheck$$" # Check if its been greater than $PBI_INDEXREFRESH hours since the last update if [ -e "${_pbiIndexTime}" ] ; then _curTime=`date +%s` _oTime=`cat ${_pbiIndexTime}` _trigTime=`expr ${PBI_INDEXREFRESH} \* 60 \* 60` expr $_curTime - $_oTime >/dev/null 2>/dev/null if [ "$?" = "0" ] ; then _passed=`expr $_curTime - $_oTime` if [ "$_passed" -lt "$_trigTime" ] ; then return; fi fi fi if [ "${PBI_VERBOSE}" = "YES" ] ; then echo "Updating index ${_pbiIndex}" echo "Updating index ${_pbiIndex}: `date`" >> ${_pbid_log} fi # Check that the last char isn't a '/' _tmp=`echo ${_rURL} | wc -m | tr -s ' ' | tr -d ' '` _tmp2=`expr $_tmp - 1` _lastC=`echo ${_tmp} | cut -c ${_tmp2}-${_tmp}` if [ "${_lastC}" = "/" ] ; then _upURL="`echo ${_rURL} | sed 's|\(.*\).|\1|'`" else _upURL="${_rURL}" fi fetch -o "${_tmpPbiIndex}.bz2" "${_upURL}/${PBI_INDEXUPFILE}.bz2" >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then return fi bzip2 -d "${_tmpPbiIndex}.bz2" >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then return fi # Move the uncompressed file mv "${_tmpPbiIndex}" "${_pbiIndex}" >/dev/null 2>/dev/null # Wait a sec sleep 1 # Now check for an optional meta file update fetch -o "${_tmpPbiMeta}.bz2" "${_upURL}/${PBI_METAUPFILE}.bz2" >/dev/null 2>/dev/null if [ "$?" = "0" ] ; then bzip2 -d "${_tmpPbiMeta}.bz2" >/dev/null 2>/dev/null if [ "$?" = "0" ] ; then mv "${_tmpPbiMeta}" "${_pbiMeta}" >/dev/null 2>/dev/null fi fi # Update the icons for this repos meta file update_repo_icons "${_repoMd5}" "${_pbiMeta}" echo "Finished updating index ${_pbiIndex}: `date`" >> ${_pbid_log} if [ "${PBI_VERBOSE}" = "YES" ] ; then echo "Finished updating index ${_pbiIndex}" fi # Save the time that we are done date +%s > ${_pbiIndexTime} } # Check if we need to update any repository icons update_repo_icons() { _repoMd5="$1" _repoMeta="$2" echo "Updating meta-icons for $_repoMeta: `date`" >> ${_pbid_log} # Loop through, downloading icons we find while read mLine do # Make sure this is an app / cat echo "$mLine" | grep -e "^App=" -e "^Cat=" >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then continue ; fi # Get the icon URL echo "$mLine" | grep "^App=" >/dev/null 2>/dev/null if [ "$?" = "0" ] ; then line=`echo $mLine | sed 's|^App=||g'` aIcon=`echo $line | cut -d ';' -f 3` else line=`echo $mLine | sed 's|^Cat=||g'` aIcon=`echo $line | cut -d ';' -f 2` fi iName=`echo $line | cut -d ';' -f 1` ext=`echo $aIcon | sed 's/.*\.//'` # If we already have this icon, we can skip if [ -e "${PBI_DBICONDIR}/${_repoMd5}-${iName}.${ext}" ] ; then continue fi # Now fetch the file sFile="${PBI_DBICONDIR}/${_repoMd5}-${iName}.${ext}" fetch -o "${sFile}" "${aIcon}" >/dev/null 2>/dev/null if [ $? -ne 0 ]; then # Wait a moment before trying the next sleep 40 fi done < ${_repoMeta} } # Check a specific PBI for updates check_pbi_update() { # Init the tmpdir init_tmpdir # Set the vars _upbi="${1}" _udisp="${2}" _uprog="${3}" _uver="${4}" _ufbsdver="${5}" _uarch="${6}" _urepo="${7}" _omdate="${8}" appname="`echo ${_uprog} | tr '[:lower:]' '[:upper:]'`" PBI_UPNVER="" PBI_UPFILE="" PBI_UPPATCHES="" PBI_UPCSUM="" PBI_UPMDATE="" PBI_UPREPO="" PBI_UPSIZE="" # If we are looking for the current app, set _uver accordingly if [ "$_uver" = "current" ] ; then _uver=":current" else _uver=":${_uver}:" fi for _repo in `ls ${PBI_DBINDEXDIR}` do if [ "$_urepo" = "AUTO" ] ; then _pbiIndex="${PBI_DBINDEXDIR}/${_repo}" _rMd5="`echo ${_repo} | sed 's|-index||g'`" else _rMd5=`ls ${PBI_DBREPODIR}/${_urepo}.* | cut -d '.' -f 2` _pbiIndex="${PBI_DBINDEXDIR}/${_rMd5}-index" fi if [ ! -e "${_pbiIndex}" ] ; then continue ; fi # Search the update index for the specified PBI _upLine=`grep -i -e "^$_uprog:" ${_pbiIndex} | grep ":$_uarch:" | grep "$_uver" | head -n 1` PBI_UPNVER="`echo $_upLine | cut -d ':' -f 3`" PBI_UPFILE="`echo $_upLine | cut -d ':' -f 6`" PBI_UPPATCHES="`echo $_upLine | cut -d ':' -f 8`" PBI_UPCSUM="`echo $_upLine | cut -d ':' -f 4`" PBI_UPMDATE="`echo $_upLine | cut -d ':' -f 5`" PBI_UPSIZE="`echo $_upLine | cut -d ':' -f 8`" PBI_UPMIRROR="`cat ${PBI_DBMIRRORDIR}/${_rMd5} 2>/dev/null`" PBI_UPREPO="${_rMd5}" if [ -n "${PBI_UPNVER}" ] ; then break; fi if [ "${_urepo}" != "AUTO" ] ; then break; fi done # If no new version if [ -z "$PBI_UPNVER" ] ; then return 1 ; fi # See if this update is newer than the installed date if [ -n "$_omdate" ] ; then nDay=`echo $PBI_UPMDATE | cut -d ' ' -f 1` nHour=`echo $PBI_UPMDATE | cut -d ' ' -f 2` oDay=`echo $_omdate | cut -d ' ' -f 1` oHour=`echo $_omdate | cut -d ' ' -f 2` # Make sure we have all legit numbers if [ $(is_num "$nDay") -a $(is_num "$nHour") \ -a $(is_num "$oDay") -a $(is_num "$oHour") ] ; then if [ $oDay -gt $nDay ] ; then return 1 ; fi if [ "$oDay" = "$nDay" -a $oHour -gt $nHour ] ; then return 1 ; fi fi fi if [ "$PBI_UPNVER" != "$PBI_PROGVERSION" ] ; then if [ "$_udisp" = "display" ] ; then echo "${_upbi} - Available: ${PBI_UPNVER}" fi return 0 else return 1 fi } # Start PBI update process do_pbi_update() { if [ -n "${PBI_UPCHECK}" ]; then return 0 ; fi if [ "$PBI_UPDATEAPP" = "ALL" ] ; then # Loop and check all PBIs for updates for i in `ls ${PBI_DBAPPDIR}/ 2>/dev/null` do if [ -e "${PBI_DBAPPDIR}/${i}/.updating" ] ; then ps -p `cat ${PBI_DBAPPDIR}/${PBI_UPDATEAPP}/.updating` >/dev/null 2>/dev/null if [ "$?" = "0" ] ; then continue fi rm "${PBI_DBAPPDIR}/${PBI_UPDATEAPP}/.updating" fi if [ -e "${PBI_DBAPPDIR}/${i}/pbi_name" ] ; then PBI_UPDATEAPP="${i}" start_pbi_updateapp "all" fi done else if [ -e "${PBI_DBAPPDIR}/${PBI_UPDATEAPP}/.updating" ] ; then ps -p `cat ${PBI_DBAPPDIR}/${PBI_UPDATEAPP}/.updating` >/dev/null 2>/dev/null if [ "$?" = "0" ] ; then exit_err "This application is currently updating." fi rm "${PBI_DBAPPDIR}/${PBI_UPDATEAPP}/.updating" fi start_pbi_updateapp "single" fi } # Attempt to download a PBI from the update server for "pbi_add -r" pbi_add_fetch_remote() { # Set the target program we want to download _rtar="$PBI_FILENAME" unset PBI_FILENAME # Check if the user overrode the arch / versions we want to install _rArch=`uname -m` if [ -n "$PBI_ADD_ALTARCH" ] ; then _rArch=$PBI_ADD_ALTARCH ; fi _rVer="current" if [ -n "$PBI_ADD_ALTVER" ] ; then _rVer=$PBI_ADD_ALTVER ; fi check_pbi_update "$_rtar" "nodisplay" \ "$_rtar" "$_rVer" \ "$FBSDMAJOR" "$_rArch" "${PBI_ADDREPO_ID}" if [ "$?" != "0" ] ; then exit_err "Could not find \"$_rtar\" in any indexes" fi # We've gotten this far, now download the updated PBI pbi_update_dl if [ "$?" != "0" ] ; then exit_err "Failed downloading PBI" fi # Now overwrite the PBI_FILENAME and let us proceed to regular install PBI_FILENAME="$PBI_UPDLFILE" # If we are only fetching, finish up now if [ "$PBI_REMOTEFETCHONLY" = "YES" ] ; then mv $PBI_FILENAME ./`basename ${PBI_UPFILE}` echo "PBI saved to ./`basename ${PBI_UPFILE}`" exit_trap fi } # Update the targed PBI start_pbi_updateapp() { _upact="${1}" if [ "$2" = "pbid" ] ; then _pbidlog="$2" else _pbidlog="" fi echo "$$" > "${PBI_DBAPPDIR}/${PBI_UPDATEAPP}/.updating" # Check for update to this app, and exit or return if not available load_info_from_dir "${PBI_DBAPPDIR}/${PBI_UPDATEAPP}" if [ -z "${PBI_REPO}" ]; then pbi_checksig_repomatch "${PBI_DBAPPDIR}/${PBI_UPDATEAPP}" fi if [ -z "${PBI_REPO}" ]; then rm "${PBI_DBAPPDIR}/${PBI_UPDATEAPP}/.updating" return else local _repoID=`ls ${PBI_DBREPODIR}/*.${PBI_REPO} | cut -d '.' -f 1 | sed "s|${PBI_DBREPODIR}/||g"` fi check_pbi_update "$PBI_UPDATEAPP" "nodisplay" \ "$PBI_PROGNAME" "current" \ "$PBI_FBSDVER" "$PBI_APPARCH" "$_repoID" "$PBI_PROGMDATE" if [ "$?" != "0" ] ; then rm "${PBI_DBAPPDIR}/${PBI_UPDATEAPP}/.updating" if [ "$_upact" = "single" ] ; then exit_err "$PBI_UPDATEAPP - no update available!" else return 1 fi fi echo "Starting update of ${PBI_UPDATEAPP} to ${PBI_UPNVER}..." _pbilow="`echo ${PBI_PROGNAME} | tr '[:upper:]' '[:lower:]' | sed 's| ||g'`" # Check if there is a possible patch file for this update # new filename to download _pFile="${_pbilow}-${PBI_PROGVERSION}_to_${PBI_UPNVER}-${PBI_APPARCH}.pbp" # Try downloading the patch file echo "Trying update via patchfile..." pbi_update_dl "$_pFile" "OFF" if [ "$?" = "0" ] ; then # We had a good patch download, try applying it now echo "Updating via patch file..." pbi_patch "$PBI_UPDLFILE" #>/dev/null 2>/dev/null if [ "$?" != "0" ] ; then # Patching failed, we'll grab a fresh copy next echo "Failed to patch with ${PBI_UPDLFILE}" echo "Will try full file update" else echo "Patch successful!" rm "${PBI_DBAPPDIR}/${PBI_UPDATEAPP}/.updating" >/dev/null 2>/dev/null rm "${PBI_UPDLFILE}" >/dev/null 2>/dev/null return 0 fi fi # No patch file, grab the full app echo "Trying update via full-file..." pbi_update_dl if [ "$?" != "0" ] ; then if [ "$_upact" = "single" ] ; then rm "${PBI_DBAPPDIR}/${PBI_UPDATEAPP}/.updating" exit_err "Failed downloading update!" fi fi echo " " # Save the auto-update status if [ -e "${PBI_DBAPPDIR}/${PBI_UPDATEAPP}/autoupdate-enable" ] ; then _autoUpEnable="YES" else _autoUpEnable="NO" fi echo -e "Removing old version...\c" pbi_delete "${PBI_UPDATEAPP}" echo "Done" # Now install new PBI echo -e "Installing new version...\c" pbi_add --licagree -f "$PBI_UPDLFILE" >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then echo "Failed to install PBI: ${PBI_UPDLFILE}" rm "${PBI_UPDLFILE}" rm "${PBI_DBAPPDIR}/${PBI_UPDATEAPP}/.updating" 2>/dev/null return 1 else if [ "$_autoUpEnable" = "YES" ] ; then touch "${PBI_DBAPPDIR}/${_pbilow}-${PBI_UPNVER}-${PBI_APPARCH}/autoupdate-enable" fi echo "Done" rm "${PBI_UPDLFILE}" rm "${PBI_DBAPPDIR}/${PBI_UPDATEAPP}/.updating" 2>/dev/null return 0 fi } # Start downloading the update pbi_update_dl() { _tPatch=$1 local _CKSUM="$2" # Set local download location _dl_loc="${PBI_APPDIR}/.`basename $PBI_UPFILE`" # Have a patch file to download instead, make that the active file to try if [ -n "$_tPatch" ] ; then _bDir=`dirname $PBI_UPFILE` _uFile="${_bDir}/${_tPatch}" else _uFile="${PBI_UPFILE}" fi _mirrorList=`echo $PBI_UPMIRROR | sed 's|\n| |g'` # Start download from repos mirror(s) in order for _cMirror in $_mirrorList do if [ "$_cMirror" = "PCBSDCDN" ] ; then get_pcbsd_mirror _furl="${VAL}${_uFile}" else _furl="`echo $_cMirror | sed 's/\/*$//'`${_uFile}" fi echo "Downloading ${_furl}" pbi_get_file "$_furl" "$_dl_loc" if [ "$?" != "0" ] ; then rm "${_dl_loc}" >/dev/null 2>/dev/null echo "Download Failed: ${_furl}" continue fi _upcsum=`sha256 -q "$_dl_loc"` if [ "$_CKSUM" != "OFF" -a "$_upcsum" != "$PBI_UPCSUM" ] ; then rm "${_dl_loc}" >/dev/null 2>/dev/null echo "Download fails checksum: ${_furl}" continue fi # If we get this far, we have a good file! PBI_UPDLFILE="$_dl_loc" sync return 0 done return 1 } # Function to download a file from remote using fetch pbi_get_file() { _rf="${1}" _lf="${2}" init_tmpdir if [ -e "${_lf}" ] ; then echo "Resuming download of: ${_lf}" fi if [ "$PBI_FETCH_PARSING" != "YES" ] ; then fetch -r -o "${_lf}" "${_rf}" _err=$? else # Doing a front-end download, parse the output of fetch _eFile="${PBI_TMPDIR}/.fetch-exit.$$" fetch -s "${_rf}" > ${PBI_TMPDIR}/.fetch-size.$$ 2>/dev/null _fSize=`cat ${PBI_TMPDIR}/.fetch-size.$$ 2>/dev/null` _fSize="`expr ${_fSize} / 1024 2>/dev/null`" rm "${PBI_TMPDIR}/.fetch-size.$$" 2>/dev/null _time=1 ( fetch -r -o "${_lf}" "${_rf}" >/dev/null 2>/dev/null ; echo "$?" > ${_eFile} ) & FETCH_PID=`ps -auwwwx | grep -v grep | grep "fetch -r -o ${_lf}" | awk '{print $2}'` while : do if [ -e "${_lf}" ] ; then _dSize=`du -k ${_lf} | tr -d '\t' | cut -d '/' -f 1` if [ $(is_num "$_dSize") ] ; then if [ ${_fSize} -lt ${_dSize} ] ; then _dSize="$_fSize" ; fi _kbs=`expr ${_dSize} \/ $_time` echo "SIZE: ${_fSize} DOWNLOADED: ${_dSize} SPEED: ${_kbs} KB/s" fi fi # Make sure download isn't finished ps -p $FETCH_PID >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then break ; fi sleep 2 _time=`expr $_time + 2` done _err="`cat ${_eFile}`" if [ "$_err" = "0" ]; then echo "FETCHDONE" ; fi unset FETCH_PID fi echo "" return $_err } is_num() { expr $1 + 1 2>/dev/null return $? } # Function to check if the port is flagged to only build on specific arch # Returns 0 for OK, 1 for invalid arch check_port_compat_arch() { local sPort=$1 local cValues="`make -C $sPort -V ONLY_FOR_ARCHS PORTSDIR=${PORTSDIR}`" if [ -z "$cValues" ] ; then return 0 ; fi for cArch in $cValues do if [ "$cArch" = "$ARCH" ] ; then return 0; fi done return 1 } # start processing autobuild pbi_autob_init() { require_root parse_autob_pbi_cmdline "$@" do_pbi_autob } check_zfs_ab_destroy() { local bNum=$1 if [ -e "${PBI_TMPDIR}/${bNum}.zmnt" ] ; then zDir=`cat ${PBI_TMPDIR}/${bNum}.zmnt` # Make sure this zfs dataset is in the PBI_APPDIR directory echo $zDir | grep -q "${PBI_APPDIR}/" if [ $? -eq 0 ] ; then # Make sure all is unmounted umount -f ${PBI_CHROOTDIR}/dev >/dev/null 2>/dev/null umount -f ${PBI_CHROOTDIR}/compat/linux/proc >/dev/null 2>/dev/null umount -f ${PBI_CHROOTDIR}/usr/ports >/dev/null 2>/dev/null umount -f ${PBI_CHROOTDIR}/pkgs >/dev/null 2>/dev/null umount -f ${PBI_CHROOTDIR}/.ccache >/dev/null 2>/dev/null umount -f ${PBI_CHROOTDIR}/usr/wrkdirprefix >/dev/null 2>/dev/null sleep 3 umount -f ${PBI_CHROOTDIR}/dev >/dev/null 2>/dev/null sync sleep 3 zfs destroy ${zDir} rmdir ${zDir} >/dev/null 2>/dev/null fi fi } ab_clean_build_tmpfiles() { local build=$1 # Cleanup rm ${PBI_TMPDIR}/${build}.result 2>/dev/null rm ${PBI_TMPDIR}/${build}.pid 2>/dev/null rm ${PBI_TMPDIR}/${build}.bPort 2>/dev/null rm ${PBI_TMPDIR}/${build}.od 2>/dev/null rm ${PBI_TMPDIR}/${build}.mp 2>/dev/null rm ${PBI_TMPDIR}/${build}.cd 2>/dev/null rm ${PBI_TMPDIR}/${build}.pv 2>/dev/null rm ${PBI_TMPDIR}/${build}.zmnt 2>/dev/null } # Start the auto-build traversal process do_pbi_autob() { echo "`basename ${0}` started: `date`" # Prune any outdir files which we don't have modules for do_pbi_autob_prune cd "${PBI_AB_CONFDIR}" init_tmpdir # Get this runs timestamp PBI_AB_TIMESTAMP=`date | md5` # Build our list of targets first echo "=> Creating build queue list..." ab_get_build_list done=0 rebuildlist=0 while :; do activity=0 # Start checking each job for build in ${JOBS-$(jot -w %02d ${PBI_AB_BUILDERS})}; do # Is this builder running? if [ -e "${PBI_TMPDIR}/${build}.pid" ] ; then if pgrep -qF "${PBI_TMPDIR}/${build}.pid" >/dev/null 2>&1; then activity=1 continue; else # Do the ZFS destroy here if necessary check_zfs_ab_destroy "$build" # Run the post-build process ab_post_build ${build} # Cleanup ab_clean_build_tmpfiles ${build} fi fi if [ $done -eq 1 ] ; then continue ; fi # Builder idle, lets figure out the next build echo "==> Finding target for build process [$build]" start_next_ab_target "$build" if [ $? -eq 0 ] ; then # Nothing left to build, lets wait for any existing build to finish before exiting done=1 fi activity=1 done # Every 2 hours, we can re-scan the modules directory, catch any ones which may have been added / changed if [ $rebuildlist -eq 7200 ] ; then rebuildlist=0 ab_get_build_list else rebuildlist=`expr $rebuildlist + 1` fi # Wait before checking again [ $activity -eq 1 ] && sleep 1 # Nothing to do? We can end now [ $activity -eq 0 ] && break done echo "`basename ${0}` Finished: `date`" }; ab_get_build_list() { AB_FOUND="0" unset CUR_PRIORITY_PBI CUR_WORKING_PBI # Clear the tmp build list rm ${PBI_TMPDIR}/.ablist 2>/dev/null cd "${PBI_AB_CONFDIR}" for pbi in `find . -type f -name "${PBI_CONFFILE}" | grep -v '\.svn' | sort` do # Figure out the target port for this build unset PBI_MAKEPORT PBI_BUILDKEY PBI_PROGVERSION PBI_REQUIRESROOT PBI_PROGNAME PBI_PROGWEB PBI_PROGAUTHOR PBI_PROGICON PBI_MKPORTBEFORE PBI_MKPORTAFTER PBI_MAKEOPTS PBI_EXCLUDELIST PBI_AB_PRIORITY PBI_HASH_EXCLUDES PBI_AB_NOTMPFS PBI_PROGREVISION . ${pbi} _cd=$(dirname $pbi | sed 's|./||') PBI_CONFDIR="$_cd" # Make sure PBI_MAKEPORT is set if [ -z "${PBI_MAKEPORT}" ] ; then PBI_MAKEPORT=`echo $pbi | sed 's|./||'` export PBI_MAKEPORT fi if [ ! -d "${PORTSDIR}/${PBI_MAKEPORT}" ] ; then #echo "Skipping invalid port ${PORTSDIR}/${PBI_MAKEPORT}" continue fi # Check if this port can be built on this architecture check_port_compat_arch "${PORTSDIR}/${PBI_MAKEPORT}" if [ "$?" = "1" ] ; then #echo "${PBI_MAKEPORT} - Skipping for invalid system arch" continue fi # Check for missing port target if [ -z "$PBI_MAKEPORT" ] ; then #echo "Warning: Missing PBI_MAKEPORT for ${pbi}" continue fi # Check if another builder is already doing this port pBuilding=0 for p in `ls ${PBI_TMPDIR}/*.bPort 2>/dev/null` do if [ "`cat $p`" = "$PBI_MAKEPORT" ] ; then pBuilding=1 break fi done if [ $pBuilding -eq 1 ] ; then continue fi check_ab_needed "$PBI_MAKEPORT" "${PBI_BUILDKEY}" "$_cd" "$PBI_AB_TIMESTAMP" if [ "$?" = "0" ] ; then AB_FOUND="1" # Unset the priority if set to 00 / 0 if [ "${PBI_AB_PRIORITY}" = "00" -o "${PBI_AB_PRIORITY}" = "0" ] ; then unset PBI_AB_PRIORITY fi # Check the priority of this PBI, see if it rises to the top if [ -z "${CUR_PRIORITY_PBI}" ] ; then CUR_WORKING_PBI="${pbi}" if [ -z "$PBI_AB_PRIORITY" ] ; then CUR_PRIORITY_PBI="$internal_ab_priority" else CUR_PRIORITY_PBI=`expr $PBI_AB_PRIORITY + 10` fi #echo "Setting higher priority target: ${pbi} - Priority: ${CUR_PRIORITY_PBI}" echo "${CUR_PRIORITY_PBI} $pbi" >> ${PBI_TMPDIR}/.abtmp continue fi # Bump up the supplied AB priority if [ -n "${PBI_AB_PRIORITY}" ] ; then internal_ab_priority=`expr $PBI_AB_PRIORITY + 10` fi # Check if this PBI is a higher priority if [ $CUR_PRIORITY_PBI -lt $internal_ab_priority ] ; then #echo "Setting higher priority target: ${pbi} - Priority: ${internal_ab_priority}" CUR_WORKING_PBI="${pbi}" CUR_PRIORITY_PBI="$internal_ab_priority" echo "${internal_ab_priority} $pbi" >> ${PBI_TMPDIR}/.abtmp continue else echo "${internal_ab_priority} $pbi" >> ${PBI_TMPDIR}/.abtmp fi continue fi done # Sort the list sort -n -r ${PBI_TMPDIR}/.abtmp > ${PBI_TMPDIR}/.ablist rm ${PBI_TMPDIR}/.abtmp } start_next_ab_target() { local curBuilder="$1" # No list to parse? if [ ! -e "${PBI_TMPDIR}/.ablist" ] ; then return 0; fi # Get the last on the list CUR_WORKING_PBI=`cat ${PBI_TMPDIR}/.ablist | head -1 | cut -d ' ' -f 2` if [ -z "${CUR_WORKING_PBI}" ] ; then return 0; fi cd "${PBI_AB_CONFDIR}" # We have something to build lets do it! pbi="$CUR_WORKING_PBI" unset PBI_MAKEPORT PBI_BUILDKEY PBI_PROGVERSION PBI_REQUIRESROOT PBI_PROGNAME PBI_PROGWEB PBI_PROGAUTHOR PBI_PROGICON PBI_MKPORTBEFORE PBI_MKPORTAFTER PBI_MAKEOPTS PBI_EXCLUDELIST PBI_AB_PRIORITY PBI_HASH_EXCLUDES PBI_AB_NOTMPFS PBI_PROGREVISION . ${pbi} _cd=$(dirname $pbi | sed 's|./||') PBI_CONFDIR="$_cd" # Get the prog version get_pbi_progversion if [ -z "${PBI_MAKEPORT}" ] ; then PBI_MAKEPORT=$(dirname $pbi | sed 's|./||') fi echo "==> Starting build process [$curBuilder]: $PBI_MAKEPORT" echo "$PBI_MAKEPORT" >${PBI_TMPDIR}/${curBuilder}.bPort # Remove this from the queue cat ${PBI_TMPDIR}/.ablist | tail -n +2 > ${PBI_TMPDIR}/.abtmp mv ${PBI_TMPDIR}/.abtmp ${PBI_TMPDIR}/.ablist # Start the build now start_ext_ab "$PBI_MAKEPORT" \ "${PBI_BUILDKEY}" "${PBI_PROGVERSION}" \ "${_cd}" "${PBI_AB_OUTDIR}" "${PBI_AB_TIMESTAMP}" "${curBuilder}" return 1 }; # Prune any outdir files which don't have matching modules do_pbi_autob_prune() { if [ "${PBI_AB_PRUNE}" != "YES" ] ; then return 0 ; fi echo "=> Cleaning outgoing directory..." # Prune outgoing dirs which don't have matching modules anymore cd "${PBI_AB_OUTDIR}" for i in `find . -type d | grep -v '\.svn'` do if [ "${i}" = "." -o "${i}" = ".." ] ; then continue ; fi _pDir=`dirname ${i}` if [ -d "${i}" -a -n "${i}" ] ; then if [ ! -e "${PBI_AB_CONFDIR}/${_pDir}" ] ; then # Not in our module tree anymore, remove it echo "Auto-Prune: ${PBI_AB_OUTDIR}/${_pDir}" rm -rf "${PBI_AB_OUTDIR}/${_pDir}" fi fi done cd } # Start the pbi_makeport process start_ext_ab() { _mp="${1}" _bk="${2}" _pv="${3}" _cd="${4}" _od="${5}/${_cd}" local _abkey="$6" local eBuilder="$7" _flags="" _flags="-c ${_cd} -d ${PORTSDIR} -o ${_od} --delbuild" if [ -n "${PBI_AB_SSLPRIVKEY}" ] ; then _flags="${_flags} --sign ${PBI_AB_SSLPRIVKEY}" fi # Check if we need to enable tmpfs if [ "$PBI_AB_TMPFS" = "YES" ] ; then if [ -z "${PBI_AB_NOTMPFS}" -o "$PBI_AB_NOTMPFS" != "YES" ] ; then _flags="${_flags} --tmpfs" fi fi # Check if we need to enable pkgcaching if [ "$PBI_AB_PKGCACHE" = "YES" -a -z "$PBI_AB_NOPKGCACHE" ] ; then if [ ! -d "${_od}/pkgcache" ] ; then mkdir -p ${_od}/pkgcache fi _flags="${_flags} --pkgdir ${_od}/pkgcache" fi # Are we doing 32bit builds? if [ "$PBI_AB32" = "YES" ] ; then _flags="${_flags} -32"; fi get_pbi_progversion #echo "Starting build of ${_mp} - ${_pv}" #echo "pbi_makeport ${_flags} ${_mp}" if [ ! -d "${_od}" ] ; then mkdir -p "${_od}" ; fi # Save the autobuild hash key echo "$_abkey" > ${_od}/.abkey # Save the build key for this PBI if [ -n "$_bk" ] ; then echo "$_bk" > "${_od}/pbi-buildkey" else echo "__NONE__" > "${_od}/pbi-buildkey" fi # Clean old log files if [ -e "${_od}/build.log" ] ; then rm "${_od}/build.log" fi if [ -e "${_od}/build.log.bz2" ] ; then rm "${_od}/build.log.bz2" fi if [ -e "${_od}/.failed-csum" ] ; then rm ${_od}/.failed-csum fi # Move old PBIs to archived folder oldVersion=`cat ${_od}/pbi-version 2>/dev/null` if [ "$oldVersion" != "$PBI_PROGVERSION" ]; then #echo "Archiving old PBIs..." archive_old_pbis "${_od}" "$PBI_AB_ARCHIVENUM" fi # Set some variables we can call in pbi_makeport PBI_AB_TMPDIR="${PBI_TMPDIR}" PBI_AB_BUILDER="$eBuilder" export PBI_AB_TMPDIR PBI_AB_BUILDER # Add some header info to log file echo "Starting build: `date`" >${_od}/build.log echo "Build Command:" >>${_od}/build.log echo "pbi_makeport ${_flags} ${_mp}" >>${_od}/build.log echo "------------------------------------------------------" >>${_od}/build.log echo "${_od}" > "${PBI_TMPDIR}/${PBI_AB_BUILDER}.od" echo "${_mp}" > "${PBI_TMPDIR}/${PBI_AB_BUILDER}.mp" echo "${_cd}" > "${PBI_TMPDIR}/${PBI_AB_BUILDER}.cd" echo "${PBI_PROGVERSION}" > "${PBI_TMPDIR}/${PBI_AB_BUILDER}.pv" pbi_makeport ${_flags} ${_mp} >>${_od}/build.log 2>>${_od}/build.log & echo "$!" > ${PBI_TMPDIR}/${eBuilder}.pid } ab_post_build() { local build=$1 _od="`cat ${PBI_TMPDIR}/${build}.od`" _mp="`cat ${PBI_TMPDIR}/${build}.mp`" _cd="`cat ${PBI_TMPDIR}/${build}.cd`" _pv="`cat ${PBI_TMPDIR}/${build}.pv`" sleep 1 if [ -e "${PBI_TMPDIR}/${build}.result" -a "`cat ${PBI_TMPDIR}/${build}.result`" = "0" ] ; then echo "$_pv" > "${_od}/pbi-version" echo "OK" > "${_od}/pbi-result" # Save the mdate file date "+%Y%m%d %H%M%S" >${_od}/pbi-mdate if [ -n "${PBI_AB_HELPS}" ] ; then ${PBI_AB_HELPS} "OK" "${_od}" fi # Copy over a description file if [ -e "${PORTSDIR}/${_mp}/pkg-descr" ] ; then cp "${PORTSDIR}/${_mp}/pkg-descr" "${_od}/pbi-descr" fi if [ -e "${PBI_AB_CONFDIR}/${_cd}/pbi-descr" ] ; then cp "${PBI_AB_CONFDIR}/${_cd}/pbi-descr" "${_od}/pbi-descr" fi # Check if we need to rebuild patches if [ "$PBI_AB_GENPATCH" = "YES" -a -d "${_od}/archived" ] ; then echo "===> Generating patches for [$build]" gen_pbi_patches "${_od}" "${_od}/archived" fi rm "${_od}/build.log.bz2" >/dev/null 2>/dev/null bzip2 "${_od}/build.log" else # Save the md5sum of the ports directory tar cvf - -C "${PORTSDIR}/${_mp}" . 2>/dev/null | md5 -q >${_od}/.failed-csum echo "Failed" > "${_od}/pbi-result" if [ -n "${PBI_AB_HELPS}" ] ; then ${PBI_AB_HELPS} "FAILED" "${_od}" fi fi } # Function which begins to generate patch files from archived PBIs to current gen_pbi_patches() { _curPBIdir="$1" _oldPBIdir="$2" _curPBI=`ls ${_curPBIdir}/*.pbi 2>/dev/null` # First remove any old patches rm ${_curPBIdir}/*.pbp 2>/dev/null rm ${_curPBIdir}/*.pbp.sha256 2>/dev/null # Make sure to enable signing of the patch files if [ -n "${PBI_AB_SSLPRIVKEY}" ] ; then local _mpflags="-o $_curPBIdir --sign ${PBI_AB_SSLPRIVKEY}" else local _mpflags="-o $_curPBIdir" fi # Check if we need to enable tmpfs if [ "$PBI_AB_TMPFS" = "YES" ] ; then _mpflags="${_mpflags} --tmpfs" ; fi # Build a list of old PBIs we need to make patches from for _oPBI in `ls ${_oldPBIdir}/*.pbi 2>/dev/null` do # Make sure we don't try to make a patch of identical files if [ "`basename $_oPBI`" != "`basename $_curPBI`" ] ; then #echo "Building pbp patch of ${_oPBI} -> ${_curPBI}" pbi_makepatch $_mpflags "$_oPBI" "$_curPBI" >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then echo "pbi_makepatch: Failed creating patchfile for $_oPBI -> $_curPBI" fi fi done } # Function which compares two PBIs, and creates a .pbp file from the differences make_pbi_patchfile() { _pbiNew="$1" _pbiOld="$2" _cDir="$3" init_tmpdir # Load all the information about this PBI / PBP PBI_FILENAME="$1" load_info_from_header _pbiNewDir="${PBI_APPDIR}/.newPBI-$$" _pbiOldDir="${PBI_APPDIR}/.oldPBI-$$" _pbiPatchDir="${PBI_APPDIR}/.patchPBI-$$" _pbiPatchHeaderDir="${PBI_APPDIR}/.patchPBIHeaderDir-$$" _pbiPatchArchiveFile="${PBI_APPDIR}/.patchPBIArchive-$$" _pbiPatchHeaderFile="${PBI_APPDIR}/.patchPBIHeaderFile-$$" # Get the PBI Versions get_ver_from_pbi_file "$_pbiNew" _pbiNewVer="$VAL" get_ver_from_pbi_file "$_pbiOld" _pbiOldVer="$VAL" # Get the PBI directory names get_prefix_from_pbi_file "$_pbiNew" _pbiNewPrefix="`basename $VAL`" get_prefix_from_pbi_file "$_pbiOld" _pbiOldPrefix="`basename $VAL`" # Get the mdate of the old PBI get_mdate_from_pbi_file "$_pbiOld" _pbiOldMDate="$VAL" # Sanity check these prefixes if [ "${_pbiNewPrefix}" != "${_pbiOldPrefix}" ] ; then echo "Error: Prefix mismatch between $_pbiNew and $_pbiOld" return fi # Get the arch type get_arch_from_pbi_file "$_pbiNew" _pbiNewArch="$VAL" get_arch_from_pbi_file "$_pbiOld" _pbiOldArch="$VAL" # Sanity check these system types if [ "${_pbiNewArch}" != "${_pbiOldArch}" ] ; then echo "Error: Arch mismatch between $_pbiNew and $_pbiOld" return fi # Make our extraction directories if [ -e "$_pbiNewDir" ] ; then rm -rf "$_pbiNewDir"; fi if [ -e "$_pbiOldDir" ] ; then rm -rf "$_pbiOldDir"; fi if [ -e "$_pbiPatchDir" ] ; then rm -rf "$_pbiPatchDir"; fi mkdir -p "$_pbiNewDir" mkdir -p "$_pbiOldDir" mkdir -p "$_pbiPatchDir" # If using tmpfs to speed up patch process if [ "$PBI_MP_TMPFS" = "YES" ] ; then mount -t tmpfs tmpfs "${_pbiNewDir}" mount -t tmpfs tmpfs "${_pbiOldDir}" mount -t tmpfs tmpfs "${_pbiPatchDir}" fi local _opts="-e --licagree" if [ "${PBI_SKIPSIGVERIFY}" = "YES" ] ; then _opts="${_opts} --no-checksig" fi # Extract the two PBIs echo "Extracting PBI: $_pbiNew" pbi_add ${_opts} -o "${_pbiNewDir}" "${_pbiNew}" >/dev/null 2>/dev/null echo "Extracting PBI: $_pbiOld" pbi_add ${_opts} -o "${_pbiOldDir}" "${_pbiOld}" >/dev/null 2>/dev/null if [ ! -d "${_pbiNewDir}/${_pbiNewPrefix}" -o ! -d "${_pbiOldDir}/${_pbiOldPrefix}" ] ; then exit_err "Failed Extracting PBIs for comparision!" fi # Get a list of files which are removed in the new PBI vs the old gen_rem_list "$_pbiNewDir/$_pbiNewPrefix" "$_pbiOldDir/$_pbiOldPrefix" _rFileList="$VAL" if [ -n "$_rFileList" ] ; then echo "Saving removed file list..." mv "${_rFileList}" ${_pbiPatchDir}/PBI-rmList fi # Get archive of files/dirs which are new to the PBI gen_newfile_list "$_pbiNewDir/$_pbiNewPrefix" "$_pbiOldDir/$_pbiOldPrefix" _nFileList="$VAL" if [ -n "$_nFileList" ] ; then echo "Saving new files archive..." tar cvf "$_pbiPatchDir/PBI-newFiles.tar" \ -C "$_pbiNewDir/$_pbiNewPrefix" -T "$_nFileList" >/dev/null 2>/dev/null rm "$_nFileList" fi # Get a listing of permissions gen_chmod_list "$_pbiNewDir/$_pbiNewPrefix" "$_pbiOldDir/$_pbiOldPrefix" _cFileList="$VAL" if [ -n "$_cFileList" ] ; then echo "Saving permissions list..." mv "${_cFileList}" ${_pbiPatchDir}/PBI-permList fi # Generate diffs of files which have changed between the two gen_bsdiffs_dirs "$_pbiNewDir/$_pbiNewPrefix" "$_pbiOldDir/$_pbiOldPrefix" "$_pbiPatchDir" # Make the file archive if test_tar_lzma ; then _tcmp="J" ; else _tcmp="j" ; fi echo "Creating compressed archive..." tar cv${_tcmp}f "${_pbiPatchArchiveFile}" -C ${_pbiPatchDir} . 2>/dev/null # Make the header file if [ -e "$_pbiPatchHeaderDir" ] ; then rm -rf "$_pbiPatchHeaderDir"; fi mkdir -p "$_pbiPatchHeaderDir" open_header_tmp "${PBI_TMPDIR}" cp ${PBI_HEADER_TMPDIR}/* "$_pbiPatchHeaderDir/" # Save the mdate of the old PBI echo "$_pbiOldMDate" > $_pbiPatchHeaderDir/pbi_patchmdate # Remove any signatures rm $_pbiPatchHeaderDir/*.sha1 >/dev/null 2>/dev/null # Get the archive checksum sha256 -q "${_pbiPatchArchiveFile}" > "${_pbiPatchHeaderDir}/pbi_archivesum" # Set the tag that this is a patch file echo "${_pbiOldVer}:${_pbiNewVer}" > "${_pbiPatchHeaderDir}/pbi_patchfile" # Sign the files if necessary sign_pbi_files "${_pbiPatchHeaderDir}" # Make the header tmpfile tar cvjf "${_pbiPatchHeaderFile}" -C ${_pbiPatchHeaderDir} . 2>/dev/null if [ "$?" != "0" ] ; then echo "Warning: TAR returned error creating header archive!" fi rm -rf ${_pbiPatchHeaderDir} # Make the pbp file get_progname_from_pbi_file "$_pbiNew" _pbilow="`echo ${VAL} | tr '[:upper:]' '[:lower:]' | sed 's| ||g'`" outfile="${_cDir}/${_pbilow}-${_pbiOldVer}_to_${_pbiNewVer}-${_pbiNewArch}.pbp" mark1="${_cDir}/.pbimark1.$$" mark2="${_cDir}/.pbimark2.$$" echo " ${PBI_SS_ICON}" >$mark1 echo " ${PBI_SS_ARCHIVE}" >$mark2 # DO IT, DO IT NOW!!! cat ${_pbiPatchHeaderFile} $mark1 ${PBI_PATCH_ICON} $mark2 ${_pbiPatchArchiveFile} > ${outfile} sha256 -q ${outfile} > ${outfile}.sha256 # Cleanup the archive stuff rm $mark1 rm $mark2 rm ${_pbiPatchHeaderFile} rm ${_pbiPatchArchiveFile} # Cleanup the directories rm_pbipatchfiles # Do some smell testing, make sure the patch file isn't larger than the PBI itself # This happens with some java programs occasionally if [ `du -k ${outfile} | awk '{print $1}'` -gt `du -k ${_pbiNew} | awk '{print $1}'` ]; then rm ${outfile} rm ${outfile}.sha256 exit_err "The patch is larger than the new PBI, aborting!" else # We have a patch! echo "Created PBP: ${outfile}" fi } # Function which compares two directories, and returns a list of chmod commands to get them in line gen_chmod_list() { _chList="${PBI_TMPDIR}/.pbi.chList.$$" if [ -e "$_chList" ] ; then rm "$_chList" ; fi find ${1} | sed "s|^${1}/||g" | sed "s|^${1}||g" >${PBI_TMPDIR}/.pbi.nDir.$$ echo "Getting permissions of changed files..." while read line do # Make sure this file exists in the new / old dirs if [ -z "$line" ] ; then continue ; fi if [ ! -f "${1}/$line" ] ; then continue ; fi if [ ! -e "${2}/$line" ] ; then continue ; fi # Filter out any special files, we don't need diffs of them if [ -L "${1}/$line" ] ; then continue ; fi if [ -p "${1}/$line" ] ; then continue ; fi if [ -S "${1}/$line" ] ; then continue ; fi if [ -d "${1}/$line" ] ; then continue ; fi if [ -b "${1}/$line" ] ; then continue ; fi if [ -c "${1}/$line" ] ; then continue ; fi _newPerm=`stat -f %Op "${1}/$line" | cut -c 3-6` _oldPerm=`stat -f %Op "${1}/$line" | cut -c 3-6` if [ "$_newPerm" != "$_oldPerm" ] ; then # We have new permissions! Lets be sure to save them echo "chmod $_newPerm $line" >> $_chList fi done < ${PBI_TMPDIR}/.pbi.nDir.$$ # Remove the tmp list files rm ${PBI_TMPDIR}/.pbi.nDir.$$ if [ -e "$_chList" ] ; then VAL="$_chList" else VAL="" fi } # Function which compares two directories, and returns a list of files / dirs removed in the new dir gen_bsdiffs_dirs() { find ${1} | sed "s|^${1}/||g" | sed "s|^${1}||g" >${PBI_TMPDIR}/.pbi.nDir.$$ echo "Getting bsdiffs of changed files..." while read line do # Make sure this file exists in the new / old dirs if [ -z "$line" ] ; then continue ; fi if [ ! -f "${1}/$line" ] ; then continue ; fi if [ ! -e "${2}/$line" ] ; then continue ; fi # Filter out any special files, we don't need diffs of them if [ -L "${1}/$line" ] ; then continue ; fi if [ -p "${1}/$line" ] ; then continue ; fi if [ -S "${1}/$line" ] ; then continue ; fi if [ -d "${1}/$line" ] ; then continue ; fi if [ -b "${1}/$line" ] ; then continue ; fi if [ -c "${1}/$line" ] ; then continue ; fi # Check sha256 of each file, see if we have differences sha1=`sha256 -q "${1}/${line}"` sha2=`sha256 -q "${2}/${line}"` if [ "$sha1" != "$sha2" ] ; then # These files differ, get a binary patch made of them _tDir="${3}/`dirname $line`" _bName=`basename $line` if [ ! -d "$_tDir" ] ; then mkdir -p "$_tDir" ; fi bsdiff "${2}/${line}" "${1}/${line}" "${_tDir}/${_bName}.bsdiff" if [ "$?" != "0" ] ; then exit_err "Failed creating bsdiff patch for $line" fi # Save the sha256 of the file to be modified sha256 -q "${2}/${line}" > "${_tDir}/${_bName}.sha256" fi done < ${PBI_TMPDIR}/.pbi.nDir.$$ # Remove the tmp list files rm ${PBI_TMPDIR}/.pbi.nDir.$$ } # Function which compares two directories, and returns a list of files / dirs removed in the new dir gen_rem_list() { find ${1} | sed "s|^${1}/||g" | sed "s|^${1}||g" >${PBI_TMPDIR}/.pbi.nDir.$$ find ${2} | sed "s|^${2}/||g" | sed "s|^${2}||g" >${PBI_TMPDIR}/.pbi.oDir.$$ echo "Finding removed files..." _rmList="${PBI_TMPDIR}/.pbi.rmList.$$" if [ -e "$_rmList" ] ; then rm "$_rmList" ; fi while read line do if [ -z "$line" ] ; then continue ; fi grep "^$line" ${PBI_TMPDIR}/.pbi.nDir.$$ >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then #echo "Removed File: $line" echo "$line" >> ${_rmList} fi done < ${PBI_TMPDIR}/.pbi.oDir.$$ # Remove the tmp list files rm ${PBI_TMPDIR}/.pbi.nDir.$$ rm ${PBI_TMPDIR}/.pbi.oDir.$$ if [ -e "$_rmList" ] ; then VAL="$_rmList" else VAL="" fi } # Function which compares two directories, and returns a list of files / dirs added in the new dir gen_newfile_list() { find ${1} | sed "s|^${1}/||g" | sed "s|^${1}||g" >${PBI_TMPDIR}/.pbi.nDir.$$ echo "Finding new files..." _addList="${PBI_TMPDIR}/.pbi.addList.$$" if [ -e "$_addList" ] ; then rm "$_addList" ; fi while read line do # Search for all new files + symlinks to include in tarball if [ -z "$line" ] ; then continue ; fi if [ ! -e "${2}/$line" -o -L "${1}/$line" ] ; then #echo "New File: $line" echo "./$line" >> ${_addList} fi done < ${PBI_TMPDIR}/.pbi.nDir.$$ # Remove the tmp list files rm ${PBI_TMPDIR}/.pbi.nDir.$$ if [ -e "$_addList" ] ; then VAL="$_addList" else VAL="" fi } # Read the version from a PBI file get_ver_from_pbi_file() { VAL="`pbi_add -i $1 | grep Version: | cut -d ':' -f 2 | tr -d ' '`" export VAL } # Read the version from a PBI file get_progname_from_pbi_file() { VAL="`pbi_add -i $1 | grep Name: | cut -d ':' -f 2 | tr -d ' '`" export VAL } get_prefix_from_pbi_file() { VAL="`pbi_add -i $1 | grep Prefix: | cut -d ':' -f 2 | tr -d ' '`" export VAL } get_mdate_from_pbi_file() { VAL="`pbi_add -i $1 | grep Built: | cut -d ' ' -f 2-5 | tr -s ' '`" export VAL } get_arch_from_pbi_file() { VAL="`pbi_add -i $1 | grep Arch: | cut -d ' ' -f 2-5 | tr -s ' '`" export VAL } # Move old PBIs to the archive archive_old_pbis() { local _od="$1" local _keepnum="$2" # Make sure the archived dir exists if [ ! -d "${_od}/archived" ] ; then mkdir "${_od}/archived"; fi # Make sure we have PBIs to archive ls ${_od}/*.pbi >/dev/null 2>/dev/null if [ "$?" != "0" ] ; then return ; fi #echo "Moving old PBIs from ${_od}/*.pbi -> ${_od}/archived/" mv ${_od}/*.pbi ${_od}/archived/ 2>/dev/null mv ${_od}/*pbi.sha256 ${_od}/archived/ 2>/dev/null # Prune anything beyond the _keepnum #echo "Checking for more than $_keepnum PBIs in archive" oCount="1" for oFile in `ls -t ${_od}/archived/*.pbi 2>/dev/null` do if [ -z "$oFile" ] ; then continue ; fi if [ "$oCount" -gt "$_keepnum" ] ; then #echo "Removing old PBI ${oFile} from archive" rm ${oFile}* fi oCount=`expr $oCount + 1` done } # Check if we need to do an auto-build of the target PBI check_ab_needed() { _port="$1" _bk="$2" _cd="$3" local _abkey="$4" internal_ab_priority="1" export internal_ab_priority unset PBI_PROGVERSION # Check PBI_BUILDKEY, see if we have a manual rebuild triggered if [ -e "${PBI_AB_OUTDIR}/${_cd}/pbi-buildkey" ] ; then if [ "`cat ${PBI_AB_OUTDIR}/${_cd}/pbi-buildkey`" != "$_bk" \ -a -n "${_bk}" ]; then #echo "$_port BUILDKEY bump, rebuild triggered." internal_ab_priority="9" return 0 fi fi # Make sure this PBI hasn't already failed during this run if [ -e "${PBI_AB_OUTDIR}/${_cd}/.abkey" -a -e "${PBI_AB_OUTDIR}/${_cd}/pbi-result" ] ; then if [ "`cat ${PBI_AB_OUTDIR}/${_cd}/.abkey`" = "$_abkey" ] ; then if [ "`cat ${PBI_AB_OUTDIR}/${_cd}/pbi-result`" != "OK" ] ; then #echo "$_port - Skipping failed from this run" return 1 fi fi fi #echo "Checking $_port for rebuild in ${PBI_AB_OUTDIR}/$_cd with key of $_bk" # Check if this is a failed port we should be skipping until its fixed if [ -e "${PBI_AB_OUTDIR}/${_cd}/.failed-csum" ] ; then _fcsum="`cat ${PBI_AB_OUTDIR}/${_cd}/.failed-csum`" _ncsum="`tar cvf - -C "${PORTSDIR}/${_port}" . 2>/dev/null | md5 -q`" if [ "$_fcsum" = "$_ncsum" ] ; then #echo "$_port - Skipping failed" return 1 fi fi # See if we have an existing PBI ls ${PBI_AB_OUTDIR}/${_cd}/*.pbi >/dev/null 2>/dev/null if [ "${?}" != "0" ]; then #echo "$_port - No existing PBI" internal_ab_priority="8" return 0 fi # See if we have a saved version if [ ! -e "${PBI_AB_OUTDIR}/${_cd}/pbi-version" ]; then #echo "No saved pbi-version" #echo "$_port - No existing version" internal_ab_priority="7" return 0 fi # Get the programs port version get_pbi_progversion # See if the version is different now oldVersion=`cat ${PBI_AB_OUTDIR}/${_cd}/pbi-version` if [ "$oldVersion" != "$PBI_PROGVERSION" ]; then oldPortVer="`echo $oldVersion | rev | cut -d '_' -f 2- | rev`" if [ "$PORTVER" = "$oldPortVer" ] ; then # Just a minor portrev bump internal_ab_priority="2" #echo "$_port revision bump: $oldVersion -> $PBI_PROGVERSION" else # Real version change internal_ab_priority="3" #echo "$_port version bump: $oldVersion -> $PBI_PROGVERSION" fi return 0 fi #echo "$_port - is Up2Date!" return 1 } # start processing for make port / pbi compile pbi_make_init() { require_root parse_make_pbi_cmdline "$@" do_pbi_make "$@" } do_pbi_make() { # See if we need to enable pkgng detect_pkgng # Load the PBI settings get_pbi_progversion get_pbi_progname get_pbi_progdir # Check if this is being called from within chroot or outside if [ "`basename $0`" = "pbi_makeport" ] ; then # Extract the chroot chroot_extract # Now re-run pbi_makeport in chroot environment chroot "${PBI_CHROOTDIR}" "/usr/local/sbin/pbi_makeport_chroot" "$@" _err=$? if [ "$_err" = "0" -a "${PBI_BUILDONLY}" != "YES" ] ; then mv ${PBI_CHROOTDIR}/pbiout/*.pbi ${PBI_CREATE_OUTDIR}/ mv ${PBI_CHROOTDIR}/pbiout/*.sha256 ${PBI_CREATE_OUTDIR}/ fi # Break here if we are only doing a build if [ "${PBI_BUILDONLY}" = "YES" ] ; then exit_trap; fi # Lets cleanup the chroot environment chroot_make_cleanup rm_tmpdir # If running as an auto-build, show that we were successful if [ -n "$PBI_AB_TMPDIR" ] ; then echo "$_err" > ${PBI_AB_TMPDIR}/${PBI_AB_BUILDER}.result fi exit $_err fi if [ "`basename $0`" != "pbi_makeport_chroot" ] ; then return ; fi # Check if we have some specific make options to use load_pbi_conffile # init tmpdir init_tmpdir set_make_options # See if we need to run a pre make script run_pbi_preportmake # Start our build start_pbi_mkportbefore start_prebuild_script start_pbi_makeport start_postbuild_script start_pbi_mkportafter # Prune any proto / build specific ports start_pbi_prune_ports # See if we need to run a post make script run_pbi_postportmake # Check for any users / groups we need to save for install time mk_pbi_users_file mk_pbi_groups_file # Auto-generate a external_links directive from plist info mk_auto_ext_linksfile # Check if we created a linux app, and need to copy files for it auto_copy_linuxbase # Break here if we are only doing a build if [ "${PBI_BUILDONLY}" = "YES" ] ; then exit_trap; fi # Start creation of PBI do_pbi_create # Got this far, lets exit with success rm_buildfiles rm_tmpdir exit 0 } # Check if we need to save a list of GROUPS to create at install mk_pbi_groups_file() { if [ -z "$PBI_BUILD_GROUPS" ] ; then return ; fi for group in $PBI_BUILD_GROUPS do # Check /usr/ports/GIDs for group entry gidLine=`cat /usr/ports/GIDs | grep "^$group:"` if [ -z "$gidLine" ] ; then echo "Warning: No entry for \"$group\" in GIDs file..." continue fi grep -q "^$group:" ${PBI_PROGDIRPATH}/${PBI_INS_GROUPSFILE} 2>/dev/null if [ $? -ne 0 ] ; then echo "Saving gid details for group: $group" echo "$gidLine" >> ${PBI_PROGDIRPATH}/${PBI_INS_GROUPSFILE} fi done } # Check if we need to save a list of users to create at install mk_pbi_users_file() { if [ -z "$PBI_BUILD_USERS" ] ; then return ; fi for user in $PBI_BUILD_USERS do # Check /usr/ports/UIDs for user entry uidLine=`cat /usr/ports/UIDs | grep "^$user:"` if [ -z "$uidLine" ] ; then echo "Warning: No entry for \"$user\" in UIDs file..." continue fi grep -q "^$user:" ${PBI_PROGDIRPATH}/${PBI_INS_USERSFILE} 2>/dev/null if [ $? -ne 0 ] ; then echo "Saving uid details for user: $user" echo "$uidLine" >> ${PBI_PROGDIRPATH}/${PBI_INS_USERSFILE} fi done } # Source any pre-build script to allow a custom script to modify the port start_prebuild_script() { if [ -e "/pre-build.sh" ] ; then chmod 755 /pre-build.sh # Source the script . /pre-build.sh fi } # Source any post-build script to allow a custom script to modify the port start_postbuild_script() { if [ -e "/post-build.sh" ] ; then chmod 755 /post-build.sh # Source the script . /post-build.sh fi } # Check if we created any linux stuff, and copy it into the correct PREFIX auto_copy_linuxbase() { echo "Checking for Linux libraries to copy..." if [ -d "/compat/linux/usr/lib" ] ; then mkdir ${PBI_PROGDIRPATH}/linuxlib echo "Copying /compat/linux/lib -> ${PBI_PROGDIRPATH}/linuxlib" tar cvf - -C /compat/linux/lib . 2>/dev/null | \ tar xvf - -C ${PBI_PROGDIRPATH}/linuxlib 2>/dev/null echo "Copying /compat/linux/usr/lib -> ${PBI_PROGDIRPATH}/linuxlib" tar cvf - -C /compat/linux/usr/lib . 2>/dev/null | \ tar xvf - -C ${PBI_PROGDIRPATH}/linuxlib 2>/dev/null fi } # Clean the chroot environment chroot_make_cleanup() { [ -z "${PBI_CHROOTDIR}" ] && return [ -d "${PBI_CHROOTDIR}" ] || return [ "${PBI_CHROOTDIR}" = "/" ] && return # Unmount /dev if mounted echo "Cleaning $PBI_CHROOTDIR" umount -f ${PBI_CHROOTDIR}/dev >/dev/null 2>/dev/null umount -f ${PBI_CHROOTDIR}/compat/linux/proc >/dev/null 2>/dev/null umount -f ${PBI_CHROOTDIR}/usr/ports >/dev/null 2>/dev/null umount -f ${PBI_CHROOTDIR}/pkgs >/dev/null 2>/dev/null umount -f ${PBI_CHROOTDIR}/.ccache >/dev/null 2>/dev/null umount -f ${PBI_CHROOTDIR}/usr/wrkdirprefix >/dev/null 2>/dev/null # Sleep a moment before we try this again, seems it takes a moment to clear up sleep 2 umount -f ${PBI_CHROOTDIR}/dev >/dev/null 2>/dev/null if [ "${PBI_KEEPBUILDFILES}" = "YES" ] ; then return ; fi # Cleanup ZFS dataset isDirZFS "${PBI_CHROOTDIR}" "1" if [ $? -eq 0 ] ; then tank=`getZFSTank "$PBI_CHROOTDIR"` sleep 1 # If we are running as a result of pbi_autobuild, let it do the ZFS cleanup if [ -z "${PBI_AB_TMPDIR}" ] ; then zfs destroy ${tank}${PBI_CHROOTDIR} rmdir ${PBI_CHROOTDIR} >/dev/null 2>/dev/null fi return fi # Cleanup normal directory rm -rf "${PBI_CHROOTDIR}" >/dev/null 2>/dev/null chflags -R noschg ${PBI_CHROOTDIR} >/dev/null 2>/dev/null rm -rf "${PBI_CHROOTDIR}" >/dev/null 2>/dev/null } # Function which extracts the clean chroot environment for the PBI chroot_extract() { # If no freebsd base exists, make it first isDirZFS "${PBI_APPDIR}" if [ $? -eq 0 ] ; then # Use ZFS base for cloning PBI_CHROOTZFS="${PBI_APPDIR}/.pbi-world-$ARCH" [ -e "${PBI_CHROOTZFS}/COPYRIGHT" ] || mk_chroot_file else # Use regular .txz file PBI_CHROOTFILE="${PBI_APPDIR}/.pbi-world-$ARCH.txz" [ -e "${PBI_CHROOTFILE}" ] || mk_chroot_file fi # Set the chroot path PBI_CHROOTDIR="${PBI_PROGDIRPATH}.chroot" export PBI_CHROOTDIR # See if there is old chroot to clean first chroot_make_cleanup # Create the new chroot dir mkdir -p "${PBI_CHROOTDIR}" # If on ZFS, we can just clone our existing base system if [ -n "$PBI_CHROOTZFS" ] ; then tank=`getZFSTank "$PBI_CHROOTZFS"` echo "Cloning ${PBI_CHROOTZFS} -> ${PBI_CHROOTDIR}" if [ -n "${PBI_AB_TMPDIR}" ] ; then echo "${tank}${PBI_CHROOTDIR}" > ${PBI_AB_TMPDIR}/${PBI_AB_BUILDER}.zmnt fi zfs clone ${tank}${PBI_CHROOTZFS}@clean ${tank}${PBI_CHROOTDIR} if [ $? -ne 0 ] ; then exit_err "Failed creating clean ZFS base snapshot"; fi else echo "Extracting chroot environment..." tar xvf ${PBI_CHROOTFILE} -C "${PBI_CHROOTDIR}" >/dev/null 2>/dev/null [ $? -ne 0 ] && exit_err "Failed extracting chroot environment!" fi # If we plan on using TMPFS mount it now mkdir -p ${PBI_CHROOTDIR}/usr/wrkdirprefix if [ "$MKTMPFS" = "YES" ] ; then mount -t tmpfs tmpfs ${PBI_CHROOTDIR}/usr/wrkdirprefix fi # Copy resolv.conf cp /etc/resolv.conf ${PBI_CHROOTDIR}/etc/resolv.conf # Copy our binary wrapper PBI_WRAPPERFILE="${PBI_APPDIR}/.pbiwrapper-$ARCH" mkdir ${PBI_CHROOTDIR}${PBI_APPDIR} 2>/dev/null cp ${PBI_WRAPPERFILE} ${PBI_CHROOTDIR}${PBI_WRAPPERFILE} # If we have a custom PBI_MAKECONF include it [ -e "${PBI_MAKECONF}" ] && cp ${PBI_MAKECONF} ${PBI_CHROOTDIR}/etc/make.conf # Set any target arch vars if [ "${ARCH}" = "i386" -a "${REALARCH}" = "amd64" ];then LOGIN_ENV=",UNAME_p=i386,UNAME_m=i386" cat >> ${PBI_CHROOTDIR}/etc/make.conf << EOF ARCH=i386 MACHINE=i386 MACHINE_ARCH=i386 EOF sed -i .back -e "s/:\(setenv.*\):/:\1${LOGIN_ENV}:/" ${PBI_CHROOTDIR}/etc/login.conf cap_mkdb ${PBI_CHROOTDIR}/etc/login.conf fi #echo "Copying ${PORTSDIR} -> ${PBI_CHROOTDIR}/usr/ports" #tar cvf - -C "${PORTSDIR}" --exclude ./distfiles . 2>/dev/null | tar xvf - -C "${PBI_CHROOTDIR}/usr/ports" 2>/dev/null [ -d "${PORTSDIR}/distfiles" ] || mkdir -p ${PORTSDIR}/distfiles mkdir -p ${PBI_CHROOTDIR}/usr/ports 2>/dev/null mount_nullfs ${PORTSDIR} ${PBI_CHROOTDIR}/usr/ports # Are we doing pkg caching? if [ "$PBI_PKGCACHE" = "YES" ] ; then mkdir ${PBI_CHROOTDIR}/pkgs mount_nullfs ${PBI_PKGCACHEDIR} ${PBI_CHROOTDIR}/pkgs fi # Now copy over the pbi_* scripts mkdir ${PBI_CHROOTDIR}/usr/local/sbin 2>/dev/null cp ${PROGBASE}/sbin/pbi_* ${PBI_CHROOTDIR}/usr/local/sbin cp ${PBI_CHROOTDIR}/usr/local/sbin/pbi_makeport ${PBI_CHROOTDIR}/usr/local/sbin/pbi_makeport_chroot chmod 755 ${PBI_CHROOTDIR}/usr/local/sbin/pbi_* # Copy the default icons cp ${PBI_DEFAULT_ICON} ${PBI_CHROOTDIR}${PBI_DEFAULT_ICON_CHROOT} # Make sure the outgoing dir is created mkdir -p ${PBI_CHROOTDIR}/pbiout 2>/dev/null # Copy over the PBI DB mkdir -p ${PBI_CHROOTDIR}/var/db 2>/dev/null cp -r ${PBI_DBDIR} ${PBI_CHROOTDIR}${PBI_DBDIR} # Copy over the confdir as well if [ -n "${PBI_CONFDIR}" ] ; then mkdir -p "${PBI_CHROOTDIR}/pbimodule" echo "Copying ${PBI_CONFDIR} -> ${PBI_CHROOTDIR}/pbimodule" tar cvf - -C "${PBI_CONFDIR}" . 2>/dev/null | tar xvf - -C "${PBI_CHROOTDIR}/pbimodule" 2>/dev/null fi # Copy over the ssl priv key if used if [ -n "$PBI_SSLPRIVKEY" ] ; then cp "${PBI_SSLPRIVKEY}" "${PBI_CHROOTDIR}/privkey.pem" chmod 600 "${PBI_CHROOTDIR}/privkey.pem" fi # Check if we have a pre-make script to run if [ -n "${PBI_PREMAKE_SCRIPT}" ] ; then if [ -e "${PBI_PREMAKE_SCRIPT}" ] ; then cp ${PBI_PREMAKE_SCRIPT} ${PBI_CHROOTDIR}/pre-build.sh fi fi # Check if we have a post-make script to run if [ -n "${PBI_POSTMAKE_SCRIPT}" ] ; then if [ -e "${PBI_POSTMAKE_SCRIPT}" ] ; then cp ${PBI_POSTMAKE_SCRIPT} ${PBI_CHROOTDIR}/post-build.sh fi fi # Start devfs in the chroot if [ ! -d "${PBI_CHROOTDIR}/dev" ] ; then mkdir ${PBI_CHROOTDIR}/dev fi mount -t devfs devfs ${PBI_CHROOTDIR}/dev # Mount linprocfs mkdir -p ${PBI_CHROOTDIR}/compat/linux/proc >/dev/null 2>/dev/null mount -t linprocfs linprocfs ${PBI_CHROOTDIR}/compat/linux/proc # Make sure the outgoing dir exists mkdir -p ${PBI_CHROOTDIR}${PBI_CREATE_OUTDIR} >/dev/null 2>/dev/null # Check for ccache being enabled on the host and nullfs mount it to the chroot if [ -n "${CCACHE_DIR}" -a -d "${CCACHE_DIR}" ] ; then mkdir ${PBI_CHROOTDIR}/.ccache mount_nullfs ${CCACHE_DIR} ${PBI_CHROOTDIR}/.ccache fi } # Get the default PC-BSD mirror to use get_pcbsd_mirror() { # Check if we already looked up a mirror we can keep using if [ -n "$CACHED_PCBSD_MIRROR" ] ; then VAL="$CACHED_PCBSD_MIRROR" export VAL return fi # Set the mirror URL VAL="`cat ${PCBSD_ETCCONF} 2>/dev/null | grep 'PCBSD_MIRROR: ' | sed 's|PCBSD_MIRROR: ||g'`" if [ -n "$VAL" ] ; then echo "Using mirror: $VAL" CACHED_PCBSD_MIRROR="$VAL" export VAL CACHED_PCBSD_MIRROR return fi echo "Getting regional mirror..." . /etc/profile # No URL? Lets get one from the master server local mFile="${HOME}/.mirrorUrl.$$" touch $mFile fetch -o $mFile http://getmirror.pcbsd.org >/dev/null 2>/dev/null VAL="`cat $mFile | grep 'URL: ' | sed 's|URL: ||g'`" rm $mFile if [ -n "$VAL" ] ; then echo "Using mirror: $VAL" CACHED_PCBSD_MIRROR="$VAL" export VAL CACHED_PCBSD_MIRROR return fi # Still no mirror? Lets try the PC-BSD FTP server... VAL="ftp://ftp.pcbsd.org/pub/mirror" CACHED_PCBSD_MIRROR="$VAL" export VAL CACHED_PCBSD_MIRROR echo "Using mirror: $VAL" return } # No chroot environment tar file exists yet, lets build or extract mk_chroot_file() { # Check if on PC-BSD and we can instead fetch fbsd-release.txz if [ -e "$PCBSD_ETCCONF" -a -z "$FORCE_FBSD_ONLY" ]; then cd "$PBI_APPDIR" # Set the mirror URL get_pcbsd_mirror MIRRORURL="$VAL" # Get the system version we are checking for updates to SYSVER="`pbreg get /PC-BSD/Version`" ; export SYSVER # To fetch the jail environment echo "Fetching FreeBSD chroot environment... This may take a while..." fetch -o rel-$ARCH.txz ${MIRRORURL}/${SYSVER}/${ARCH}/netinstall/fbsd-release.txz fetch -o rel-$ARCH.md5 ${MIRRORURL}/${SYSVER}/${ARCH}/netinstall/fbsd-release.txz.md5 fetch -o src-$ARCH.txz ${MIRRORURL}/${SYSVER}/${ARCH}/netinstall/extras/components/src.txz [ `md5 -q rel-$ARCH.txz` != `cat rel-$ARCH.md5` ] && exit_err "Error in download data, checksum mismatch.. Please try again later." isDirZFS "${PBI_APPDIR}" if [ $? -eq 0 ] ; then # Use ZFS base for cloning echo "Creating ZFS ${PBI_CHROOTZFS} dataset..." tank=`getZFSTank "$PBI_APPDIR"` isDirZFS "${PBI_CHROOTZFS}" "1" if [ $? -ne 0 ] ; then zfs create -o mountpoint=${PBI_CHROOTZFS} -p ${tank}${PBI_CHROOTZFS} if [ $? -ne 0 ] ; then exit_err "Failed creating ZFS base dataset"; fi fi echo "Extracting rel-$ARCH.txz..." tar xvpf rel-$ARCH.txz -C ${PBI_CHROOTZFS} 2>/dev/null if [ $? -ne 0 ] ; then exit_err "Failed extracting ZFS base dataset"; fi mkdir -p ${PBI_CHROOTZFS}/usr/src 2>/dev/null echo "Extracting src-$ARCH.txz..." tar xvpf src-$ARCH.txz -C ${PBI_CHROOTZFS}/usr/src 2>/dev/null if [ $? -ne 0 ] ; then exit_err "Failed extracting ZFS base src dataset"; fi rm rel-$ARCH.txz rm src-$ARCH.txz rm rel-$ARCH.md5 zfs snapshot ${tank}${PBI_CHROOTZFS}@clean if [ $? -ne 0 ] ; then exit_err "Failed creating clean ZFS base snapshot"; fi else mv rel-$ARCH.txz ${PBI_CHROOTFILE} rm rel-$ARCH.md5 fi return fi local _srcdir="/usr/src" if [ -z "${PBI_BUILDSRC}" ] ; then PBI_BUILDSRC="${_srcdir}" fi local _targetDir="${PBI_APPDIR}/.worldTarget.$$" if [ -z "${PBI_BUILDTARGET}" ] ; then PBI_BUILDTARGET="${_targetDir}" fi # Delete source code/build if not /usr/src and PBI_DELETE_BUILD is true if [ -z "${PBI_DELETE_BUILD}" ] ; then PBI_DELETE_BUILD=1 fi # Use existing sources if [ -e "${PBI_BUILDSRC}/COPYRIGHT" -a -z "${PBI_OSREL}" ] ; then PBI_BUILDLOG="${PBI_APPDIR}/.buildWorldLog" : > ${PBI_BUILDLOG} mkdir -p "${PBI_BUILDTARGET}" else # Make sure SVN is installed which svn >/dev/null 2>/dev/null [ "$?" -ne 0 ] && exit_err "Subversion is required to rebuild the chroot environment!" local _osRel=$FBSDREL if [ -n "${PBI_OSREL}" ]; then _osRel="${PBI_OSREL}" fi echo "Building the PBI chroot environment... This may take a while..." PBI_BUILDLOG="${PBI_APPDIR}/.buildWorldLog" echo "" > ${PBI_BUILDLOG} mkdir -p "${PBI_BUILDSRC}" mkdir -p "${PBI_BUILDTARGET}" # Figure out which version of FreeBSD to checkout case $_osRel in *RELEASE) local _osMajor=${_osRel%%.*} local svnUrl="svn://svn.freebsd.org/base/releng/${_osMajor}.0" echo "Using $svnUrl for sources" ;; *CURRENT) local svnUrl="svn://svn.freebsd.org/base/head" echo "Using $svnUrl for sources" ;; *STABLE) local _osMajor=${_osRel%%.*} local svnUrl="svn://svn.freebsd.org/base/stable/${_osMajor}" "Using $svnUrl for sources" ;; *) local svnUrl="svn://svn.freebsd.org/base/head" echo "Using $svnUrl for sources" echo "Assuming a BETA|RC or rarely used FreeBSD version. Using CURRENT!" ;; esac echo "Checking out FreeBSD sources from $svnUrl" if [ -e "${PBI_BUILDSRC}/COPYRIGHT" ] ; then svn update ${PBI_BUILDSRC} >>${PBI_BUILDLOG} 2>>${PBI_BUILDLOG} else svn co ${svnUrl} ${PBI_BUILDSRC} >>${PBI_BUILDLOG} 2>>${PBI_BUILDLOG} fi if [ "$?" != "0" ] ; then if [ "${PBI_DELETE_BUILD}" = "1" ] ; then rm -rf "${PBI_BUILDSRC}" rm -rf "${PBI_BUILDTARGET}" fi exit_err "Subversion checkout failed! Logfile saved: ${PBI_BUILDLOG}" fi fi # End of subversion checkout echo "Running buildworld / installworld (into a chroot)" touch ${PBI_BUILDSRC}/Makefile cd ${PBI_BUILDSRC} make ${PBI_BUILDFLAGS} TARGET=$ARCH buildworld >>${PBI_BUILDLOG} 2>>${PBI_BUILDLOG} if [ "$?" != "0" ] ; then cd if [ "${PBI_BUILDSRC}" != "/usr/src" -a "${PBI_DELETE_BUILD}" != "0" ] ; then rm -rf "${PBI_BUILDSRC}" rm -rf "${PBI_BUILDTARGET}" fi exit_err "Buildworld failed! Logfile saved: ${PBI_BUILDLOG}" fi # See if we need to create a ZFS dataset isDirZFS "${PBI_APPDIR}" if [ $? -eq 0 ] ; then # Use ZFS base for cloning echo "Creating ZFS ${PBI_CHROOTZFS} dataset..." tank=`getZFSTank "$PBI_APPDIR"` isDirZFS "${PBI_CHROOTZFS}" "1" if [ $? -ne 0 ] ; then zfs create -o mountpoint=${PBI_CHROOTZFS} -p ${tank}${PBI_CHROOTZFS} if [ $? -ne 0 ] ; then exit_err "Failed creating ZFS base dataset"; fi fi rmdir "${PBI_BUILDTARGET}" PBI_BUILDTARGET="$PBI_CHROOTZFS" fi make ${PBI_BUILDFLAGS} installworld TARGET=$ARCH DESTDIR=${PBI_BUILDTARGET} >>${PBI_BUILDLOG} 2>>${PBI_BUILDLOG} if [ "$?" != "0" ] ; then cd if [ "${PBI_BUILDSRC}" != "/usr/src" -a "${PBI_DELETE_BUILD}" != "0" ] ; then rm -rf "${PBI_BUILDSRC}" rm -rf "${PBI_BUILDTARGET}" fi exit_err "Buildworld failed! Logfile saved: ${PBI_BUILDLOG}" fi make ${PBI_BUILDFLAGS} distribution TARGET=$ARCH DESTDIR=${PBI_BUILDTARGET} >>${PBI_BUILDLOG} 2>>${PBI_BUILDLOG} if [ "$?" != "0" ] ; then cd if [ "${PBI_BUILDSRC}" != "/usr/src" -a "${PBI_DELETE_BUILD}" != "0" ] ; then rm -rf "${PBI_BUILDSRC}" rm -rf "${PBI_BUILDTARGET}" fi exit_err "Buildworld failed! Logfile saved: ${PBI_BUILDLOG}" fi # Copy the source since some ports need kern sources echo "Copying FreeBSD sources to chroot environment" mkdir -p ${PBI_BUILDTARGET}/usr/src >/dev/null 2>/dev/null tar cvf - -C "${PBI_BUILDSRC}" --exclude "\.svn/" . 2>/dev/null | tar xvf - -C "${PBI_BUILDTARGET}/usr/src" 2>/dev/null # If using ZFS we can stop here if [ -n "$PBI_CHROOTZFS" ] ; then zfs snapshot ${tank}${PBI_CHROOTZFS}@clean if [ $? -ne 0 ] ; then exit_err "Failed creating clean ZFS base snapshot"; fi rm ${PBI_BUILDLOG} return fi echo "Creating chroot environment tarball" tar cvjf ${PBI_CHROOTFILE} -C ${PBI_BUILDTARGET} . >>${PBI_BUILDLOG} 2>>${PBI_BUILDLOG} if [ $? -ne 0 ] ; then cd if [ "${PBI_BUILDSRC}" != "/usr/src" -a "${PBI_DELETE_BUILD}" != "0" ] ; then rm -rf "${PBI_BUILDSRC}" rm -rf "${PBI_BUILDTARGET}" fi rm -rf "${PBI_CHROOTFILE}" exit_err "Making chroot environment tarball failed! Logfile saved: ${PBI_BUILDLOG}" fi # Cleanup after ourselves chflags -R noschg "${PBI_BUILDTARGET}" >/dev/null 2>/dev/null if [ "${PBI_BUILDSRC}" != "/usr/src" -a "${PBI_DELETE_BUILD}" != "0" ] ; then rm -rf "${PBI_BUILDSRC}" fi if [ "${PBI_DELETE_BUILD}" = "1" ] ; then rm -rf "${PBI_BUILDTARGET}" >/dev/null 2>/dev/null fi rm ${PBI_BUILDLOG} } # Read the target ports plist, and generate a external_links config based upon it mk_auto_ext_linksfile() { # Get ports name get_pkgname "${PORTSDIR}/${PBI_MAKEPORT}" _pname="${PKGNAME}" # Define some commands if [ $PKGNG -eq 1 ] ; then pkgInf="pkg info -l" else pkgInf="pkg_info -L" fi ${pkgInf} ${_pname} | sed "s|^${PBI_PROGDIRPATH}/||g" \ | grep -v -e "^Information for" -e "^Files:" -e "owns the following" \ | tr -s '\t' ' ' \ | tr -d ' ' \ > "${PBI_TMPDIR}/.pkg_flist.$$" _ef="${PBI_PROGDIRPATH}/${MOD_AUTOEXTLINKFILE}" [ -e "$_ef" ] && rm "$_ef" while read f do bin="NO" [ -z "${f}" ] && continue [ -e "${PBI_PROGDIRPATH}/${f}" ] || continue # See if this is executable and set it as binary dirname ${f} | grep -e "bin" -e "sbin" >/dev/null 2>/dev/null if [ -x "${PBI_PROGDIRPATH}/${f}" -a $? -eq 0 ] ; then # Check this executable, if Linux binary, flag it file "${PBI_PROGDIRPATH}/${f}" | grep -iq "Linux" if [ $? -ne 0 ] ; then echo "${f} ${f} binary,nocrash" >> "$_ef" else echo "${f} ${f} linux,nocrash" >> "$_ef" fi else echo "${f} ${f} replace" >> "$_ef" fi done < ${PBI_TMPDIR}/.pkg_flist.$$ rm "${PBI_TMPDIR}/.pkg_flist.$$" } # Init the crash handler routine pbi_crash_init() { which "pbi-crashhandler-gui" >/dev/null 2>/dev/null if [ "$?" = "0" -a -n "${DISPLAY}" ] ; then #pbi-crashhandler-gui "$@" fi } # Get the hard-link counter for the specified file get_hard_link_count() { HLINKS=`stat -f %l "${1}"` } # Cleanup after caught exit exit_trap() { # If a download is running, kill it if [ -n "${FETCH_PID}" ] ; then echo "Killing ${FETCH_PID}" kill -s INT ${FETCH_PID} sleep 2 fi # If we are running as an auto-build service we need to cleanup if [ "`basename ${0}`" = "pbi_autobuild" ] ; then for j in `ls ${PBI_TMPDIR}/*.pid 2>/dev/null` do bNum=`basename $j | cut -d '.' -f 1 ` if pgrep -qF "${j}" >/dev/null 2>&1; then echo "===>Cleaning up processes [$bNum]" pkill -9 -P "`cat ${j}`" sleep 10 pkill -9 -F ${j} sleep 10 # Do the ZFS destroy here, since running zfs destroy concurrently as we cleanup can cause a panic check_zfs_ab_destroy "$bNum" fi done fi chroot_make_cleanup rm_pbipatchfiles rm_tmpdir exit 0 } # Read in the global pbi.conf load_pbi_etcconf() { # FTP_PASSIVE_MODE needs to be enabled by default FTP_PASSIVE_MODE=YES export FTP_PASSIVE_MODE PBI_PUBKEYS="`ls ${PBI_DBKEYDIR}/*.ssl 2>/dev/null`" [ -e "${PBI_ETCCONF}" ] || return 0 # See if we have a custom index refresh rate _ckPBIIR="`sed -n 's/^PBI_INDEXREFRESH: //gp' ${PBI_ETCCONF}`" if [ -n "${_ckPBIIR}" -a $(is_num "$_ckPBIIR") ] ; then PBI_INDEXREFRESH="${_ckPBIIR}" fi # See if we have a custom pbid refresh time _ckPBID="`cat ${PBI_ETCCONF} | grep '^PBID_REFRESH: ' | sed 's|PBID_REFRESH: ||g'`" if [ -n "${_ckPBID}" -a $(is_num "$_ckPBID") ] ; then PBIDSLEEP="${_ckPBID}" fi } # If the loaded file is a PBI PatchFile is_pbi_patch() { if [ -z "$PBI_PATCHVERSION" ] ; then return 1 else return 0 fi } # Build the specified port do_port_build() { local _lPort="$1" local iFile="$PORTSDIR/INDEX-$FBSDMAJOR" if [ ! -e "$iFile" ] ; then echo "Creating $iFile " make -C ${PORTSDIR} index fi echo "Checking port: $_lPort" # Make sure this port isn't already loaded local pkgName=`make -V PKGNAME -C $_lPort PORTSDIR=${PORTSDIR}` if [ $PKGNG -eq 1 ] ; then pkg info -e ${pkgName} if [ $? -eq 0 ] ; then return ; fi else if [ -e "/var/db/pkg/${pkgName}" ] ; then return ; fi fi # Save any users / groups we need to create later local pUsers="`make -V USERS -C $_lPort PORTSDIR=${PORTSDIR}`" local pGroups="`make -V GROUPS -C $_lPort PORTSDIR=${PORTSDIR}`" if [ -n "$pUsers" ] ; then PBI_BUILD_USERS="$PBI_BUILD_USERS $pUsers" fi if [ -n "$pGroups" ] ; then PBI_BUILD_GROUPS="$PBI_BUILD_GROUPS $pGroups" fi # Parse the pkg deps for cPkg in `grep "^${pkgName}|" $iFile | cut -d '|' -f 8-9 | sed 's/|/ /g'` do if [ -z "$cPkg" ] ; then continue ; fi # is this installed? if [ $PKGNG -eq 1 ] ; then pkg info -e ${cPkg} if [ $? -eq 0 ] ; then continue ; fi else if [ -e "/var/db/pkg/${cPkg}" ] ; then continue ; fi fi local _port=`grep "^${cPkg}|" $iFile | cut -d '|' -f 2` # Not installed, do this one now until we drill down to the base do_port_build "${_port}" >&1 2>&1 done if [ $PKGNG -eq 1 ] ; then pkgInf="pkg info -e" pkgDep="pkg info -d" pkgCreate="pkg create -f txz" else pkgInf="pkg_info" pkgDep="pkg_info -r" pkgCreate="pkg_create -J -b" fi # Not installed, see if we have a pkg to install instead if [ -e "/pkgs/${pkgName}.txz" ] ; then REBUILDPKG="NO" echo "Checking package: ${pkgName}" $pkgDep /pkgs/${pkgName}.txz | grep -v -e "^Information" -e "depends on:" -e "^Depends" | sed '/^$/d' | sed 's|Dependency: ||g' > /tmp/deps.$$ while read dLine do $pkgInf $dLine >/dev/null 2>/dev/null if [ $? -ne 0 ] ; then echo "Package dependencies updated! Rebuilding port..." REBUILDPKG="YES" break fi done < /tmp/deps.$$ rm /tmp/deps.$$ # Fix some pkgs bugging us with license questions PACKAGE_BUILDING=yes export PACKAGE_BUILDING if [ "$REBUILDPKG" = "NO" ] ; then echo "Adding package: ${pkgName}" $PKG_ADD -f /pkgs/${pkgName}.txz return fi fi # No package, lets do old-fashioned build echo "Compiling port: ${_lPort}" cd ${_lPort} make rmconfig make clean make install if [ "$?" != "0" ] ; then echo "BUILDERROR1!!" sleep 2 make install if [ "$?" != "0" ] ; then if [ "$MKDEBUG" = "YES" ] ; then echo "Failed! Running /bin/sh for debugging, type 'exit' to finish." /bin/sh fi make clean exit_err "make install of ${PBI_MAKEPORT} failed!" fi fi make clean # Are we caching packages? if [ "${PBI_PKGCACHE}" = "YES" ] ; then # Prune outdated versions of cached pkg local basePkgName basePkgName="`echo ${pkgName} | rev | cut -d '-' -f 2- | rev`" for rmPkg in `ls /pkgs/${basePkgName}* 2>/dev/null | sed 's|/pkgs/||g'` do testPkg="`echo ${rmPkg} | rev | cut -d '-' -f 2- | rev`" if [ -n "$testPkg" -a "$testPkg" = "$basePkgName" ] ; then echo "Pruning old cache pkg: ${rmPkg}" rm /pkgs/${rmPkg} fi done # Create new pkg ${pkgCreate} ${pkgName} if [ $? -ne 0 ] ; then exit_err "$pkgCreate ${pkgName} failed!" fi mv ${pkgName}.txz /pkgs/ sha256 -q /pkgs/${pkgName}.txz >/pkgs/${pkgName}.txz.sha256 fi }; # Check if the target directory is on ZFS # Arg1 = The dir to check # Arg2 = If set to 1, don't dig down to lower level directory isDirZFS() { local _chkDir="$1" while : do # Is this dir a ZFS mount mount | grep -w "on $_chkDir " | grep -qw "(zfs," && return 0 # Quit if not walking down if [ "$2" = "1" ] ; then return 1 ; fi if [ "$_chkDir" = "/" ] ; then break ; fi _chkDir=`dirname $_chkDir` done return 1 } # Get the ZFS tank name for a directory # Arg1 = Directory to check getZFSTank() { local _chkDir="$1" while : do line=`mount | grep -w -e $_chkDir -e "(zfs,"` mount | grep -qw -e $_chkDir -e "(zfs," if [ $? -eq 0 ] ; then echo $line | cut -d '/' -f -1 | awk '{print $1}' return 0 fi if [ "$_chkDir" = "/" ] ; then return 1 ; fi _chkDir=`dirname $_chkDir` done return 1 } # Main program operation ############################################################## init_vars mk_required_dirs load_pbi_etcconf trap exit_trap 1 2 3 9 15 # Figure out which mode we are running in case `basename ${0}` in pbi_add) pbi_add_init "$@" ;; pbi_addrepo) pbi_addrepo_init "$@" ;; pbi_autobuild) pbi_autob_init "$@" ;; pbi_browser) pbi_browser_init "$@" ;; pbi_create) pbi_create_init "$@" ;; pbi_deleterepo) pbi_deleterepo_init "$@" ;; pbi_delete) pbi_delete_init "$@" ;; pbi_icon) pbi_icon_init "$@" ;; pbi_indextool) pbi_it_init "$@" ;; pbi_info) pbi_info_init "$@" ;; pbi_listrepo) pbi_listrepo_init "$@" ;; pbi_makeport) pbi_make_init "$@" ;; pbi_makeport_chroot) pbi_make_init "$@" ;; pbi_makepatch) pbi_makepatch_init "$@" ;; pbi_makerepo) pbi_makerepo_init "$@" ;; pbi_metatool) pbi_mt_init "$@" ;; pbi_patch) pbi_patch_init "$@" ;; pbi_update) pbi_update_init "$@" ;; pbi_update_hashdir) pbi_update_hashdir_init "$@" ;; pbi-crashhandler) pbi_crash_init "$@" ;; pbid) pbid_init "$@" ;; *) echo "Error: Called with invalid basename!" ; exit_trap ;; esac rm_tmpdir exit 0