#!/bin/sh # makeslapt - make a slapt-get compatible slackware package # by Eko M. Budi # # The original code was included in checkinstall as makepak, # which in turn was from Slakware's makepak # # ---------------------------------------------------------------- # Copyright 1994, 1998 Patrick Volkerding, Moorhead, Minnesota USA # Copyright 2003 Slackware Linux, Inc. Concord, CA USA # All rights reserved. # # Redistribution and use of this script, with or without modification, is # permitted provided that the following conditions are met: # # 1. Redistributions of this script must retain the above copyright # notice, this list of conditions and the following disclaimer. # # 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. # # Wed Mar 18 15:32:33 CST 1998 # Patched to avoid possible symlink attacks in /tmp. # # Sat Dec 09 2000 - Felipe Sanchez # Removed the code for the questions about symlinks and sane permissions # They are useless to CheckInstall # # Fri Jul 20 2001 - Felipe Sanchez # Included the patch made to makepkg in the Slackware 8.0 release. # # Aug, 2004 = Eko M. Budi # patch to simplify symlinks creation using readlink (needs coreutil 5.0 up) # add symlinks to the preexisting doinst.sh (assume it was created by checkinstall) # # Oct, 2004 = Eko M. Budi # Add dependency tracking for slapt-get # # Nov, 2004 = Eko M. Budi, the Dumb Bunny revealed # Fix tar silly ./ problem # # Nov, 2004 = Eko M. Budi & Jason Woodward # Fix package name function # # Nov, 2004 = Eko M. Budi, the Dumber Bunny revealed # Refix tar silly ./ problem. DOH !!! # Her ya her ya ... Use the old tar-1.13 !! # # Dec, 2004 = Eko M. Budi # Checkinstall 1.6.0beta4 out, always want to pass options ... # So combine the original makepkg from Slackware 10 # Renamed to makeslapt, to make it clear # # March, 2006 = Eko M. Budi # - Use 2 digit max dependency rule # (e.g: gtk2+ >= 2.6.8 became gtk2+ >= 2.6) # - Add lib_with_path() patch by YaP # - support tgz, tbz, or tlz format TAR=tar-1.13 umask 022 $TAR --help 1> /dev/null 2> /dev/null if [ ! $? = 0 ]; then TAR=tar fi if [ ! "`LC_MESSAGES=C $TAR --version`" = "tar (GNU tar) 1.13 Copyright (C) 1988, 92,93,94,95,96,97,98, 1999 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Written by John Gilmore and Jay Fenlason." ]; then echo "WARNING: pkgtools are unstable with tar > 1.13." echo " You should provide a \"tar-1.13\" in your \$PATH." sleep 5 fi usage() { cat << EOF Usage: makeslapt [options] package_name.tgz Makes a Slackware compatible package containing the contents of the current and all subdirectories. If symbolic links exist, they will be removed and a doinst.sh script will be made to recreate them later. It also generates dependency rules for slapt-get, named slack-required. The default format is tgz, you may change it to tbz or tlz format by using command line option (-g, -b, -l), or export PKGFORMAT enviromental variable PKGFORMAT, e.g : export PKGFORMAT=tlz options: -s, --slapt y|n add slapt-get dependency info, default Y -f, --full y|n add full dependency info, default Y -l, --linkadd y|n moves symlinks into doinst.sh, default Y. -p, --prepend add symlinks to the front of the existing doinst.sh. -c, --chown y|n resets all permissions to root:root 755, default N -g, --tgz use tgz format (default) -b, --tbz use tbz format -l, --tlz use tlz format EOF } # Return package name, from Jason # This is fast, but DOES NOT WORK if the package does not follow # standard package naming, notably VERSION with -, e.g: # xine-lib-1-rc1-i486-1 --> return xine-lib-1 # In that case, replace '-' with '_'. pkgname() { echo $1 | sed -re "s/(.*{1,})\\-(.*[\\.\\-].*[\\.\\-].*)[ ]{0,}$/\1/" } # return package name, orthodox way # Not used anymore because the reg-exp way is faster # although this Orthodox way can handle nasty name better # put bad guy names here KNOWN_NAMES="cdparanoia slib libjpeg" KNOWN_ARCHS="noarch i386 i486 i586 i686 i786 i886 i986" pkgname1() { name=${1%%-*} ver_rest=${1#$name-} while [ 0 ]; do ## 1st rule, if known name then that's it ! if echo "$KNOWN_NAMES " | grep -q "$name "; then break fi ## 2nd rule, if digits followed by . or - then stop if echo $ver_rest | grep -qe "^[0-9]*[\.\-_]"; then break fi ## 3rd, if the next segment is known architecture, stop extra=${ver_rest%%-*} ver_rest=${ver_rest#$extra-} if echo "$KNOWN_ARCHS " | grep -q `echo $ver_rest | cut -f1 -d-`; then break fi ## 4rd, no more rest, then break if [ "$ver_rest" = "$extra" ]; then break fi ## concat the name then continue name="${name}-${extra}" done echo $name } ## Insert dependency info ala slapt-get ## The autodependency is generated using ldd ala swaret ## Let them fight as they like, we are free to get the best of them :) REQUIRED=install/slack-required DESCRIPTION=install/slack-desc ## Add dependency info if not exist yet add_required() { if ! grep -qw "$1" $REQUIRED 2>/dev/null; then if [ "$SLAPT_FULL" = "y" ] && [ "$3" ]; then # trying to find the lesser version REQ_VERSION=${3%%_*} REQ_VERSION=`echo $REQ_VERSION | cut -f 1-2 -d '.'` echo "$*" >> $REQUIRED echo "$*" else echo "$1" >> $REQUIRED echo "$1" fi fi } ## find dependency find_required() { ## if $2 not null, assume it is a complete requirement if [ "$2" ]; then add_required $* return 0 fi ## try to find version info from the installed packages DDNAME=$1 if ls /var/log/packages/$DDNAME-* &>/dev/null; then for DD in /var/log/packages/$DDNAME-* ; do DDBASE=`basename $DD` if [ "$DDNAME" = "`pkgname $DDBASE`" ]; then DDVERSION=${DDBASE#${DDNAME}-} # Left only version DDVERSION=${DDVERSION%%-*} add_required $DDNAME '>=' $DDVERSION return 0 fi done fi ## Can't find version info, just add it then add_required $DDNAME } # contributed by YaP function lib_with_path() { LIB="$1" if [ "${LIB:0:1}" == "/" ]; then echo "${LIB:1}" return 1 fi if [ -f "/lib/$LIB" ]; then echo "lib/$LIB" return 1; fi if [ -f "/usr/lib/$LIB" ]; then echo "usr/lib/$LIB" return 1; fi cat /etc/ld.so.conf | while read PATH_LINE; do LIBPATH="$PATH_LINE/$LIB" if [ -f "$LIBPATH" ]; then echo "${LIBPATH:1}" return 0 fi done echo "$LIB" return 1 } function add_dependency() { # find the executables and track the required packages find . -perm +1 ! -path './install/*' -print | while read LINE; do [ ! -f "$LINE" ] && continue [ ".${LINE##*.}" = ".la" ] && continue echo "$LINE:" if ! ldd "$LINE" &>/dev/null; then # not a dynamic, possibly script FTYPE=`file "$LINE"` if echo $FTYPE | grep -q "Bourne" ; then find_required bash elif echo $FTYPE | grep -q "C shell" ; then find_required tcsh elif echo $FTYPE | grep -iqw "perl" ; then find_required perl elif echo $FTYPE | grep -iqw "python" ; then find_required python elif echo $FTYPE | grep -iqw "ruby" ; then find_required ruby elif echo $FTYPE | grep -iqw "php" ; then find_required php elif echo $FTYPE | grep -qw "tcl"; then find_required tcl elif echo $FTYPE | grep -qw "expect"; then find_required expect find_required tclx find_required tcl else echo "WARNING: unknown dependency for $LINE" fi else ldd $LINE | while read LINE1; do LIB=`echo $LINE1 | cut -f1 -d ' '` # SELF=$(find -name `basename $LIB`) SELF=$(find -name `basename "$LIB*"`) [ "$SELF" ] && continue LIB="`lib_with_path $LIB`" grep "$LIB" /var/log/packages/* | while read LINE2; do DFULL=`echo $LINE2 | cut -f1 -d:` DBASE=`basename $DFULL` DNAME=`pkgname $DBASE` case "$DNAME" in aaa_elflibs|$PNAME) continue ;; esac DVERSION=${DBASE#${DNAME}-} DVERSION=${DVERSION%%-*} add_required $DNAME '>=' $DVERSION break done if [ $? != 0 ]; then echo "WARNING : Cannot find dependency for $LIB" fi done fi done } function add_doinst() { echo "Moving symbolic links to scripts ..." # Using readlink to read the link, works with coreutils (Slackware 9.1 up). # Old method using ls -l was broken since coreutil 5.0 find . -type l -print | while read LINE; do DIRNAME="`dirname $LINE`" LINKNAME="`basename $LINE`" LINKTO="`readlink $LINE`" echo "( cd $DIRNAME ; rm -rf $LINKNAME )" >> install/doinst.sh echo "( cd $DIRNAME ; ln -sf $LINKTO $LINKNAME )" >> install/doinst.sh rm -fv $LINE done } # Default options LINKADD=y PREPEND=y CHOWN=n SLAPT=y SLAPT_FULL=y PKGFORMAT=${PKGFORMAT:-tgz} # Parse options while [ 0 ]; do if [ "$1" = "--linkadd" -o "$1" = "-l" ]; then if [ "$2" = "y" ]; then LINKADD=y elif [ "$2" = "n" ]; then LINKADD=n else usage exit 2 fi shift 2 elif [ "$1" = "--chown" -o "$1" = "-c" ]; then if [ "$2" = "y" ]; then CHOWN=y elif [ "$2" = "n" ]; then CHOWN=n else usage exit 2 fi shift 2 elif [ "$1" = "--slapt" -o "$1" = "-s" ]; then if [ "$2" = "y" ]; then SLAPT=y elif [ "$2" = "n" ]; then SLAPT=n else usage exit 2 fi shift 2 elif [ "$1" = "--full" -o "$1" = "-f" ]; then if [ "$2" = "y" ]; then SLAPT_FULL=y elif [ "$2" = "n" ]; then SLAPT_FULL=n else usage exit 2 fi shift 2 elif [ "$1" = "-p" -o "$1" = "--prepend" ]; then PREPEND=y shift 1 elif [ "$1" = "-g" -o "$1" = "--tgz" ]; then PKGFORMAT=tgz shift 1 elif [ "$1" = "-b" -o "$1" = "--tbz" ]; then PKGFORMAT=tbz shift 1 elif [ "$1" = "-l" -o "$1" = "--tlz" ]; then PKGFORMAT=tlz shift 1 elif [ "$1" = "-h" -o "$1" = "-H" -o "$1" = "--help" -o $# = 0 ]; then usage exit 0 else break fi done echo echo "Slackware SLAPT-GET package maker, version 2.1." PACKAGE_NAME=$1 PDIR=`dirname $PACKAGE_NAME` PLONG=`basename $PACKAGE_NAME` PSHORT=${PLONG%.*} PEXT=${PLONG##*.} PNAME=`pkgname $PLONG` mkdir -p install if [ "$LINKADD" = "y" ]; then if [ "$PREPEND" = "y" ]; then echo "Prepending doins script ..." touch install/doinst.sh mv install/doinst.sh install/doinst.sh.shipped echo "#!/bin/sh" > install/doinst.sh add_doinst echo "" >> install/doinst.sh cat install/doinst.sh.shipped >> install/doinst.sh rm -f install/doinst.sh.shipped else echo "Concatenating doinst script ..." echo "" >> install/doinst.sh add_doinst fi fi if [ "$CHOWN" = "y" ]; then echo "Fixing permission ..." find . -type d -exec chmod -v 755 {} \; find . -type d -exec chown -v root.root {} \; fi ## Add dependency if [ "$SLAPT" = "y" ]; then echo "Adding slapt-get dependencies ..." add_dependency fi ## Add description, if not yet if [ ! -f install/slack-desc ]; then echo "$PNAME: $PNAME" > install/slack-desc fi echo echo "Creating package $PSHORT.$PKGFORMAT ..." # Don't be a dumb bunny, TAR must be tar-1.13 # With newer tar, these are broken: # tar czvf $PACKAGE_NAME . --> creates leading ./, though fixable by installpkg # tar czvf $PACKAGE_NAME * --> no leading ./, but installpkg will be confused echo echo "Creating tar file $PSHORT.tar..." echo $TAR cvf $PSHORT.tar . # Warn of zero-length files: find . -type f -size 0c | while read file ; do echo "WARNING: zero length file $file" done find . -type f -name '*.gz' -size 20c | while read file ; do echo "WARNING: possible empty gzipped file $file" done # packing the tar file into tgz, tlz, or tbz echo echo "Compressing $PSHORT.$PKGFORMAT ..." case $PKGFORMAT in tgz) gzip -9 $PSHORT.tar mv $PSHORT.tar.gz ${PDIR}/${PSHORT}.${PKGFORMAT} ;; tlz) lzma -7 $PSHORT.tar mv $PSHORT.tar.lzma ${PDIR}/${PSHORT}.${PKGFORMAT} ;; tbz) bzip2 -9 $PSHORT.tar mv $PSHORT.tar.bz2 ${PDIR}/${PSHORT}.${PKGFORMAT} ;; esac echo echo "Package creation $PSHORT.$PEXT complete." echo if [ "$PEXT" != "$PKGFORMAT" ]; then echo "WARNING: The package format is not the same as the given name." echo "Please check the options or PKGFORMAT enviromental variable" fi