# pkgutils
#
# Copyright (c) 2000-2005 Per Liden
-# Copyright (c) 2006-2007 by CRUX team (http://crux.nu)
+# Copyright (c) 2006-2013 by CRUX team (http://crux.nu)
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# USA.
#
+##
+# error codes
+E_GENERAL=1
+E_PKGFILE=2 # invalid Pkgfile
+E_DIR_PERM=3 # (source/build) directory missing or missing read/write permission
+E_DOWNLOAD=4 # error during download
+E_UNPACK=5 # error during unpacking of source file(s)
+E_MD5=6 # md5sum verification failed
+E_FOOTPRINT=7 # footprint check failure
+E_BUILD=8 # error while running 'build()'
+E_INSTALL=9 # error while installing the package via 'pkgadd'
+
info() {
echo "=======> $1"
}
}
get_filename() {
- local FILE="`echo $1 | sed 's|^.*://.*/||g'`"
-
- if [ "$FILE" != "$1" ]; then
- FILE="$PKGMK_SOURCE_DIR/$FILE"
+ if [[ $1 =~ ^(http|https|ftp|file)://.*/(.+) ]]; then
+ echo "$PKGMK_SOURCE_DIR/${BASH_REMATCH[2]}"
+ else
+ echo $1
fi
+}
+get_basename() {
+ local FILE="`echo $1 | sed 's|^.*://.*/||g'`"
echo $FILE
}
check_pkgfile() {
if [ ! "$name" ]; then
error "Variable 'name' not specified in $PKGMK_PKGFILE."
- exit 1
+ exit $E_PKGFILE
elif [ ! "$version" ]; then
error "Variable 'version' not specified in $PKGMK_PKGFILE."
- exit 1
+ exit $E_PKGFILE
elif [ ! "$release" ]; then
error "Variable 'release' not specified in $PKGMK_PKGFILE."
- exit 1
+ exit $E_PKGFILE
elif [ "`type -t build`" != "function" ]; then
error "Function 'build' not specified in $PKGMK_PKGFILE."
- exit 1
+ exit $E_PKGFILE
fi
}
check_directory() {
if [ ! -d $1 ]; then
error "Directory '$1' does not exist."
- exit 1
+ exit $E_DIR_PERM
elif [ ! -w $1 ]; then
error "Directory '$1' not writable."
- exit 1
+ exit $E_DIR_PERM
elif [ ! -x $1 ] || [ ! -r $1 ]; then
error "Directory '$1' not readable."
+ exit $E_DIR_PERM
+ fi
+}
+
+check_file() {
+ if [ -e $1 ] && [ ! -w $1 ]; then
+ error "File '$1' is not writable."
exit 1
fi
}
if [ ! "`type -p wget`" ]; then
error "Command 'wget' not found."
- exit 1
+ exit $E_GENERAL
fi
LOCAL_FILENAME=`get_filename $1`
LOCAL_FILENAME_PARTIAL="$LOCAL_FILENAME.partial"
- DOWNLOAD_CMD="--passive-ftp --no-directories --tries=3 --waitretry=3 \
- --directory-prefix=$PKGMK_SOURCE_DIR --output-document=$LOCAL_FILENAME_PARTIAL $1"
+ DOWNLOAD_OPTS="--passive-ftp --no-directories --tries=3 --waitretry=3 \
+ --directory-prefix=$PKGMK_SOURCE_DIR \
+ --output-document=$LOCAL_FILENAME_PARTIAL --no-check-certificate"
if [ -f "$LOCAL_FILENAME_PARTIAL" ]; then
info "Partial download found, trying to resume"
RESUME_CMD="-c"
fi
- while true; do
- wget $RESUME_CMD $DOWNLOAD_CMD
+ error=1
+
+ BASENAME=`get_basename $1`
+ for REPO in ${PKGMK_SOURCE_MIRRORS[@]}; do
+ REPO="`echo $REPO | sed 's|/$||'`"
+ wget $RESUME_CMD $DOWNLOAD_OPTS $PKGMK_WGET_OPTS $REPO/$BASENAME
error=$?
- if [ $error != 0 ] && [ "$RESUME_CMD" ]; then
- info "Partial download failed, restarting"
- rm -f "$LOCAL_FILENAME_PARTIAL"
- RESUME_CMD=""
- else
+ if [ $error == 0 ]; then
break
fi
done
+
+ if [ $error != 0 ]; then
+ while true; do
+ wget $RESUME_CMD $DOWNLOAD_OPTS $PKGMK_WGET_OPTS $1
+ error=$?
+ if [ $error != 0 ] && [ "$RESUME_CMD" ]; then
+ info "Partial download failed, restarting"
+ rm -f "$LOCAL_FILENAME_PARTIAL"
+ RESUME_CMD=""
+ else
+ break
+ fi
+ done
+ fi
if [ $error != 0 ]; then
error "Downloading '$1' failed."
- exit 1
+ exit $E_DOWNLOAD
fi
mv -f "$LOCAL_FILENAME_PARTIAL" "$LOCAL_FILENAME"
if [ ! -e $LOCAL_FILENAME ]; then
if [ "$LOCAL_FILENAME" = "$FILE" ]; then
error "Source file '$LOCAL_FILENAME' not found (can not be downloaded, URL not specified)."
- exit 1
+ exit $E_DOWNLOAD
else
if [ "$PKGMK_DOWNLOAD" = "yes" ]; then
download_file $FILE
else
error "Source file '$LOCAL_FILENAME' not found (use option -d to download)."
- exit 1
+ exit $E_DOWNLOAD
fi
fi
fi
for FILE in ${source[@]}; do
LOCAL_FILENAME=`get_filename $FILE`
case $LOCAL_FILENAME in
- *.tar.gz|*.tar.Z|*.tgz)
- COMMAND="tar -C $SRC --use-compress-program=gzip -xf $LOCAL_FILENAME" ;;
- *.tar.bz2)
- COMMAND="tar -C $SRC --use-compress-program=bzip2 -xf $LOCAL_FILENAME" ;;
- *.zip)
- COMMAND="unzip -qq -o -d $SRC $LOCAL_FILENAME" ;;
+ *.tar|*.tar.gz|*.tar.Z|*.tgz|*.tar.bz2|*.tbz2|*.tar.xz|*.txz|*.tar.lzma|*.zip|*.rpm)
+ COMMAND="bsdtar -p -o -C $SRC -xf $LOCAL_FILENAME" ;;
*)
COMMAND="cp $LOCAL_FILENAME $SRC" ;;
esac
rm -rf $PKGMK_WORK_DIR
fi
error "Building '$TARGET' failed."
- exit 1
+ exit $E_UNPACK
fi
done
}
if [ "$PKGMK_CHECK_MD5SUM" = "yes" ]; then
error "Md5sum not ok."
- exit 1
+ exit $E_MD5
fi
error "Building '$TARGET' failed."
- exit 1
+ exit $E_MD5
fi
else
if [ "$PKGMK_CHECK_MD5SUM" = "yes" ]; then
rm -rf $PKGMK_WORK_DIR
fi
info "Md5sum not found."
- exit 1
+ exit $E_MD5
fi
warning "Md5sum not found, creating new."
sed 's/^+/NEW /g' | \
sed 's/^-/MISSING /g' > $FILE.footprint.diff
if [ -s $FILE.footprint.diff ]; then
- error "Footprint mismatch found:"
+ if [ "$PKGMK_IGNORE_NEW" = "yes" ] && \
+ [ -z "$(egrep -l ^MISSING $FILE.footprint.diff)" ] ; then
+ info "New files found:"
+ else
+ error "Footprint mismatch found:"
+ BUILD_SUCCESSFUL="no"
+ fi
cat $FILE.footprint.diff >&2
- BUILD_SUCCESSFUL="no"
fi
else
warning "Footprint not found, creating new."
fi
}
-build_package() {
- local BUILD_SUCCESSFUL="no"
-
+make_work_dir() {
export PKG="$PKGMK_WORK_DIR/pkg"
export SRC="$PKGMK_WORK_DIR/src"
umask 022
cd $PKGMK_ROOT
- rm -rf $PKGMK_WORK_DIR
+ remove_work_dir
mkdir -p $SRC $PKG
-
+
if [ "$PKGMK_IGNORE_MD5SUM" = "no" ]; then
check_md5sum
fi
+}
+
+remove_work_dir() {
+ rm -rf $PKGMK_WORK_DIR
+}
+
+
+build_package() {
+ local BUILD_SUCCESSFUL="no"
+ local COMPRESSION
+
+ check_file "$TARGET"
+ make_work_dir
if [ "$UID" != "0" ]; then
warning "Packages should be built as root."
cd $PKG
info "Build result:"
- tar czvvf $TARGET *
-
+
+ case $PKGMK_COMPRESSION_MODE in
+ gz) COMPRESSION="-z" ;;
+ bz2) COMPRESSION="-j" ;;
+ xz) COMPRESSION="-J" ;;
+ esac
+ bsdtar -c $COMPRESSION -f $TARGET * && bsdtar -t -v -f $TARGET
+
if [ $? = 0 ]; then
BUILD_SUCCESSFUL="yes"
fi
if [ "$PKGMK_KEEP_WORK" = "no" ]; then
- rm -rf $PKGMK_WORK_DIR
+ remove_work_dir
fi
if [ "$BUILD_SUCCESSFUL" = "yes" ]; then
exit 1
fi
+ check_file "$PKGMK_FOOTPRINT"
make_footprint > $PKGMK_FOOTPRINT
touch $TARGET
echo " -r, --recursive search for and build packages recursively"
echo " -d, --download download missing source file(s)"
echo " -do, --download-only do not build, only download missing source file(s)"
+ echo " -eo, --extract-only do not build, only extract source file(s)"
echo " -utd, --up-to-date do not build, only check if package is up to date"
echo " -uf, --update-footprint update footprint using result from last build"
echo " -if, --ignore-footprint build package without checking footprint"
+ echo " -in, --ignore-new build package, ignore new files in a footprint missmatch"
echo " -um, --update-md5sum update md5sum"
echo " -im, --ignore-md5sum build package without checking md5sum"
echo " -cm, --check-md5sum do not build, only check md5sum"
-do|--download-only)
PKGMK_DOWNLOAD="yes"
PKGMK_DOWNLOAD_ONLY="yes" ;;
+ -eo|--extract-only)
+ PKGMK_EXTRACT_ONLY="yes" ;;
-utd|--up-to-date)
PKGMK_UP_TO_DATE="yes" ;;
-uf|--update-footprint)
PKGMK_UPDATE_FOOTPRINT="yes" ;;
-if|--ignore-footprint)
PKGMK_IGNORE_FOOTPRINT="yes" ;;
+ -in|--ignore-new)
+ PKGMK_IGNORE_NEW="yes" ;;
-um|--update-md5sum)
PKGMK_UPDATE_MD5SUM="yes" ;;
-im|--ignore-md5sum)
}
main() {
+ # multilib
+ PKGMK_ARCH=64
+ if [ -f ".32bit" ]; then
+ PKGMK_ARCH=32
+ fi
+
local FILE TARGET
parse_options "$@"
check_directory "`dirname $PKGMK_WORK_DIR`"
check_pkgfile
-
- TARGET="$PKGMK_PACKAGE_DIR/$name#$version-$release.pkg.tar.gz"
-
+
+ case $PKGMK_COMPRESSION_MODE in
+ gz|bz2|xz)
+ TARGET="$PKGMK_PACKAGE_DIR/$name#$version-$release.pkg.tar.$PKGMK_COMPRESSION_MODE"
+ ;;
+ *)
+ error "Compression mode '$PKGMK_COMPRESSION_MODE' not supported"
+ exit 1
+ ;;
+ esac
+
if [ "$PKGMK_CLEAN" = "yes" ]; then
clean
exit 0
if [ "$PKGMK_UPDATE_MD5SUM" = "yes" ]; then
download_source
+ check_file "$PKGMK_MD5SUM"
make_md5sum > $PKGMK_MD5SUM
info "Md5sum updated."
exit 0
exit 0
fi
+ if [ "$PKGMK_EXTRACT_ONLY" = "yes" ]; then
+ download_source
+ make_work_dir
+ info "Extracting sources of package '$name-$version'."
+ unpack_source
+ exit 0
+ fi
+
if [ "$PKGMK_UP_TO_DATE" = "yes" ]; then
if [ "`build_needed`" = "yes" ]; then
info "Package '$TARGET' is not up to date."
PKGMK_MD5SUM=".md5sum"
PKGMK_NOSTRIP=".nostrip"
+PKGMK_SOURCE_MIRRORS=()
PKGMK_SOURCE_DIR="$PWD"
PKGMK_PACKAGE_DIR="$PWD"
PKGMK_WORK_DIR="$PWD/work"
+PKGMK_COMPRESSION_MODE="gz"
+
PKGMK_INSTALL="no"
PKGMK_RECURSIVE="no"
PKGMK_DOWNLOAD="no"
PKGMK_DOWNLOAD_ONLY="no"
+PKGMK_EXTRACT_ONLY="no"
PKGMK_UP_TO_DATE="no"
PKGMK_UPDATE_FOOTPRINT="no"
PKGMK_IGNORE_FOOTPRINT="no"
+PKGMK_IGNORE_NEW="no"
PKGMK_FORCE="no"
PKGMK_KEEP_WORK="no"
PKGMK_UPDATE_MD5SUM="no"