mirror of
https://github.com/moparisthebest/pacman
synced 2024-12-23 08:18:51 -05:00
fd38319106
Currently bacman always compresses with gzip now matter what PKGEXT is set to. Rework the entire package creation process to be similar to that in makepkg. This also make the explicit assumption that PKGEXT is defined in makepkg.conf. Thanks to Nelson Chan <khcha.n.el@gmail.com> for the original patch to fix the incorrect package compression. Signed-off-by: Allan McRae <allan@archlinux.org> Signed-off-by: Dan McGee <dan@archlinux.org>
311 lines
7.2 KiB
Bash
Executable File
311 lines
7.2 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# bacman: recreate a package from a running system
|
|
# This script rebuilds an already installed package using metadata
|
|
# stored into the pacman database and system files
|
|
#
|
|
# (c) 2008 - locci <carlocci_at_gmail_dot_com>
|
|
#
|
|
# 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
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
readonly progname="bacman"
|
|
readonly progver="0.2.1"
|
|
|
|
#
|
|
# User Friendliness
|
|
#
|
|
function usage(){
|
|
echo "This program recreates a package using pacman's db and system files"
|
|
echo "Usage: $progname <installed package name>"
|
|
echo "Example: $progname kernel26"
|
|
}
|
|
|
|
if [ $# -ne 1 ] ; then
|
|
usage
|
|
exit 1
|
|
fi
|
|
|
|
if [ "$1" = "--help" -o "$1" = "-h" ] ; then
|
|
usage
|
|
exit 0
|
|
fi
|
|
|
|
if [ "$1" = "--version" -o "$1" = "-v" ]; then
|
|
echo "$progname version $progver"
|
|
echo "Copyright (C) 2008 locci"
|
|
exit 0
|
|
fi
|
|
|
|
#
|
|
# Fakeroot support
|
|
#
|
|
if [ $EUID -gt 0 ]; then
|
|
if [ -f /usr/bin/fakeroot ]; then
|
|
echo "Entering fakeroot environment"
|
|
export INFAKEROOT="1"
|
|
/usr/bin/fakeroot -u -- $0 $1
|
|
exit $?
|
|
else
|
|
echo "WARNING: installing fakeroot or running ${progname} as root is required to"
|
|
echo " preserve the ownership permissions of files in some packages"
|
|
echo ""
|
|
fi
|
|
fi
|
|
|
|
#
|
|
# Setting environmental variables
|
|
#
|
|
if [ ! -r /etc/pacman.conf ]; then
|
|
echo "ERROR: unable to read /etc/pacman.conf"
|
|
exit 1
|
|
fi
|
|
|
|
eval $(awk '/DBPath/ {print $1$2$3}' /etc/pacman.conf)
|
|
pac_db="${DBPath:-/var/lib/pacman/}/local"
|
|
|
|
if [ ! -r /etc/makepkg.conf ]; then
|
|
echo "ERROR: unable to read /etc/makepkg.conf"
|
|
exit 1
|
|
fi
|
|
|
|
source "/etc/makepkg.conf"
|
|
if [ -r ~/.makepkg.conf ]; then
|
|
source ~/.makepkg.conf
|
|
fi
|
|
|
|
pkg_arch=${CARCH:-'unknown'}
|
|
pkg_dest="${PKGDEST:-$PWD}"
|
|
pkg_pkger=${PACKAGER:-'Unknown Packager'}
|
|
|
|
pkg_name="$1"
|
|
pkg_dir="$(echo $pac_db/$pkg_name-[0-9]*)"
|
|
pkg_namver="${pkg_dir##*/}"
|
|
|
|
#
|
|
# Checks everything is in place
|
|
#
|
|
if [ ! -d "$pac_db" ] ; then
|
|
echo "ERROR: pacman database directory ${pac_db} not found"
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -d "$pkg_dir" ] ; then
|
|
echo "ERROR: package ${pkg_name} not found in pacman database"
|
|
exit 1
|
|
fi
|
|
|
|
#
|
|
# Begin
|
|
#
|
|
echo Package: ${pkg_namver}
|
|
work_dir=$(mktemp -d -p /tmp)
|
|
cd "$work_dir" || exit 1
|
|
|
|
#
|
|
# File copying
|
|
#
|
|
echo "Copying package files..."
|
|
|
|
cat "$pkg_dir"/files |
|
|
while read i; do
|
|
if [ -z "$i" ] ; then
|
|
continue
|
|
fi
|
|
|
|
if [[ "$i" =~ %[A-Z]*% ]] ; then
|
|
current=$i
|
|
continue
|
|
fi
|
|
|
|
case $current in
|
|
%FILES%)
|
|
ret=0
|
|
if [ -e "/$i" ]; then
|
|
bsdtar -cnf - "/$i" 2> /dev/null | bsdtar -xpf -
|
|
|
|
# Workaround to bsdtar not reporting a missing file as an error
|
|
if [ ! -e "$work_dir/$i" -a ! -L "$work_dir/$i" ]; then
|
|
echo ""
|
|
echo "ERROR: unable to add /$i to the package"
|
|
echo " If your user does not have permssion to read this file then"
|
|
echo " you will need to run $progname as root"
|
|
rm -rf "$work_dir"
|
|
exit 1
|
|
fi
|
|
else
|
|
echo ""
|
|
echo "WARNING: package file /$i is missing"
|
|
echo ""
|
|
fi
|
|
|
|
|
|
;;
|
|
esac
|
|
done
|
|
|
|
ret=$?
|
|
if [ $ret -ne 0 ]; then
|
|
rm -rf "$work_dir"
|
|
exit 1
|
|
fi
|
|
|
|
pkg_size=$(du -sk | awk '{print $1 * 1024}')
|
|
|
|
#
|
|
# .PKGINFO stuff
|
|
#
|
|
echo Generating .PKGINFO metadata...
|
|
echo "# Generated by $progname $progver" > .PKGINFO
|
|
if [ "$INFAKEROOT" = "1" ]; then
|
|
echo "# Using $(fakeroot -v)" >> .PKGINFO
|
|
fi
|
|
echo "# $(LC_ALL=C date)" >> .PKGINFO
|
|
echo "#" >> .PKGINFO
|
|
|
|
cat "$pkg_dir"/{desc,files,depends} |
|
|
while read i; do
|
|
if [[ -z "$i" ]]; then
|
|
continue;
|
|
fi
|
|
|
|
if [[ "$i" =~ %[A-Z]*% ]] ; then
|
|
current=$i
|
|
continue
|
|
fi
|
|
|
|
case "$current" in
|
|
# desc
|
|
%NAME%)
|
|
echo "pkgname = $i" >> .PKGINFO
|
|
;;
|
|
%VERSION%)
|
|
echo "pkgver = $i" >> .PKGINFO
|
|
;;
|
|
%DESC%)
|
|
echo "pkgdesc = $i" >> .PKGINFO
|
|
;;
|
|
%URL%)
|
|
echo "url = $i" >> .PKGINFO
|
|
;;
|
|
%LICENSE%)
|
|
echo "license = $i" >> .PKGINFO
|
|
;;
|
|
%ARCH%)
|
|
echo "arch = $i" >> .PKGINFO
|
|
;;
|
|
%BUILDDATE%)
|
|
echo "builddate = $(date -u "+%s")" >> .PKGINFO
|
|
;;
|
|
%PACKAGER%)
|
|
echo "packager = $pkg_pkger" >> .PKGINFO
|
|
;;
|
|
%SIZE%)
|
|
echo "size = $pkg_size" >> .PKGINFO
|
|
;;
|
|
%GROUPS%)
|
|
echo "group = $i" >> .PKGINFO
|
|
;;
|
|
%REPLACES%)
|
|
echo "replaces = $i" >> .PKGINFO
|
|
;;
|
|
%FORCE%)
|
|
echo "force = true" >> .PKGINFO
|
|
;;
|
|
|
|
# files
|
|
%BACKUP%)
|
|
# strip the md5sum after the tab
|
|
echo "backup = ${i%%$'\t'*}" >> .PKGINFO
|
|
;;
|
|
|
|
# depends
|
|
%DEPENDS%)
|
|
echo "depend = $i" >> .PKGINFO
|
|
;;
|
|
%OPTDEPENDS%)
|
|
echo "optdepend = $i" >> .PKGINFO
|
|
;;
|
|
%CONFLICTS%)
|
|
echo "conflict = $i" >> .PKGINFO
|
|
;;
|
|
%PROVIDES%)
|
|
echo "provides = $i" >> .PKGINFO
|
|
;;
|
|
esac
|
|
done
|
|
|
|
comp_files=".PKGINFO"
|
|
|
|
if [ -f "$pkg_dir/install" ] ; then
|
|
cp "$pkg_dir/install" "$work_dir/.INSTALL"
|
|
comp_files+=" .INSTALL"
|
|
fi
|
|
if [ -f $pkg_dir/changelog ] ; then
|
|
cp "$pkg_dir/changelog" "$work_dir/.CHANGELOG"
|
|
comp_files+=" .CHANGELOG"
|
|
fi
|
|
|
|
#
|
|
# Fixes owner:group and permissions for .PKGINFO, .CHANGELOG, .INSTALL
|
|
#
|
|
chown root:root "$work_dir"/{.PKGINFO,.CHANGELOG,.INSTALL} 2> /dev/null
|
|
chmod 644 "$work_dir"/{.PKGINFO,.CHANGELOG,.INSTALL} 2> /dev/null
|
|
|
|
#
|
|
# Generate the package
|
|
#
|
|
echo "Generating the package..."
|
|
|
|
case "$PKGEXT" in
|
|
*tar.gz) EXT=${PKGEXT%.gz} ;;
|
|
*tar.bz2) EXT=${PKGEXT%.bz2} ;;
|
|
*tar.xz) EXT=${PKGEXT%.xz} ;;
|
|
*tar) EXT=${PKGEXT} ;;
|
|
*) echo "WARNING: '%s' is not a valid archive extension." \
|
|
"$PKGEXT" ; EXT=$PKGEXT ;;
|
|
esac
|
|
|
|
pkg_file="$pkg_dest/$pkg_namver-$pkg_arch${PKGEXT}"
|
|
ret=0
|
|
|
|
# when fileglobbing, we want * in an empty directory to expand to
|
|
# the null string rather than itself
|
|
shopt -s nullglob
|
|
# TODO: Maybe this can be set globally for robustness
|
|
shopt -s -o pipefail
|
|
bsdtar -cf - $comp_files * |
|
|
case "$PKGEXT" in
|
|
*tar.gz) gzip -c -f -n ;;
|
|
*tar.bz2) bzip2 -c -f ;;
|
|
*tar.xz) xz -c -z - ;;
|
|
*tar) cat ;;
|
|
esac > ${pkg_file} || ret=$?
|
|
|
|
if [ $ret -ne 0 ]; then
|
|
echo "ERROR: unable to write package to $pkg_dest"
|
|
echo " Maybe the disk is full or you do not have write access"
|
|
rm -rf "$work_dir"
|
|
exit 1
|
|
fi
|
|
|
|
rm -rf "$work_dir"
|
|
|
|
echo Done
|
|
|
|
exit 0
|
|
|
|
# vim: set ts=2 sw=2 noet:
|
|
|