#!/bin/bash ############################################################################### # Program: altertrack (alternate slacktrack) # Purpose: Tracking & building packages for Slackware v9.1+ # Inspired by Patrick Volkerding's 'bp' script # # This DOES NOT USE installwatch! # This WILL INSTALL THE PACKAGE ON THE SYSTEM (but it updates the # /var/log/packages database so that you may remove it). # # DO NOT USE THIS ON ANYTHING BUT A PACKAGE BUILDING DEV BOX # # You MUST consult the FAQ before using this script so that you avoid # including unrelated files in your packages. # # Author : Stuart Winter # Date...: 08-May-2005 # Version: 1.18 ############################################################################### # Notes: # [1] Notice how in the slacktrack-examples archive I make extensive use # of ${SLACKTRACKFAKEROOT} in the .build scripts ? # This environment variable is pretty useless for alterslack whilst # doing post install stuff (eg fixing up man pages and hardlinks) # within the main .build script. # However, it *is* useful if you want to use a post installation script # (via -R, --run-after) to tidy up any symlinks or other stuff you # couldn't have easily done whilst still working within the root # file system. # ${SLACKTRACKSCRATCHDIR} will still be useful to you # # [2] You will more than likely have to removepkg first. # This is because unless certain files have changed from last time, # they won't get reinstalled by make install and they will # NOT APPEAR IN THE PACKAGE. # protopkg has this 'feature' also. The only way to avoid this would be # to either use slacktrack or do what 'bp' does and touch all the # files on the file system first. I'd rather use removepkg and # check the output to ensure it has removed everything it should. # * However, using removepkg can be DANGEROUS if you remove a package # that the system relies upon. Please see question 5 of the FAQ * ################################################################################ # Program name PROGNAME="altertrack" # Version SLACKTRACKVERSION="${PROGNAME} v1.18(1.25-slacktrack) by Stuart Winter " # Path to Slackware's makepkg MAKEPKG=/sbin/makepkg # Set defaults. These may be modified via the command line switches unset SLACKWAREPACKAGE PACKAGEDEPEND CREATESYMLINKS=Yes SETROOTOWNER=No CHOWNBINDIRSROOTBIN=No CHOWNBINFILESROOTBIN=No TIDYONFINISH=Yes GZMAN=No GZINFO=No GZMANFIXSYMLINKS=Yes GZINFOFIXSYMLINKS=Yes DELETEUSRINFODIR=No STRIPPROG="$( which strip )" STRIPLIB=No STRIPBIN=No STRIPALLEXEC=No STRIPARCHIVES=No CREATEDESCRIPTION=No CHMODNOGLOBALWRITE=No CHMOD644DOCS=No BUILDSTORE=/tmp/built-slackwarepackages/ # if that dir doesn't exist it'll use /tmp LOGGING=Yes CREATEMD5SUM=No SIGNPACKAGE=No SIGNINGKEY= NOUSRTMP=No LOGHARDLINKS=Yes SLACKTRACKLOGFILE="/var/tmp/$$.$(date +%s).${RANDOM}.slacktrack.log" MANDIR_LIST="/usr/man /usr/local/man /usr/X11R?/man" INFODIR_LIST="/usr/info /usr/local/info" LIBDIR_LIST="/usr/lib /lib /usr/local/lib" BINDIR_LIST="/bin /sbin /usr/sbin /usr/bin /usr/local/bin /usr/local/sbin /usr/X11R?/bin" ROOTDIR=/ USEFAKEROOT=No RUNCMDAFTER= MAKEPKGOPTS= SHOWDEPS=No # Below is the list of files and directories that should be excluded from the list # of files that have changed since before and after the build. # It's in egrep's pattern format. Note that when this string is used in altertrack, # we prefix everything with ^ meaning to only remove the listed value if it is # at the start of a line. Eg, /var/log/monkey.log would be removed from the list # (because /var/log is listed below), but /usr/monkey/var/log/monkey.log would not. EXCLUDE_LIST="/sys$|/sys/|/initrd$|/initrd/|/dev/vc$|/dev/vc/|/dev/console|/dev/pts$|/dev/pts/|/dev/ptmx|/dev/tty|/var/log|/etc/ld.so.cache|/tmp|/root|/proc|/var/tmp|/var/run/utmp" # Basic sanity checks if [ ! -f "${MAKEPKG}" ]; then echo "ERROR: Unable to locate the Slackware 'makepkg' program" echo " Your system is broken. makepkg is part of the pkgtools" echo " package; I suggest you install it" exit 4 fi if [ ! -d /var/log/packages -o ! -d /var/log/scripts ]; then echo "ERROR: Unable to find at least one of the package" echo " information repositories. Your system is broken." exit 4 fi ############################################### Functions################################### function display_usage () { printf "Usage: ${PROGNAME} [options] -p \n" if [ ! -z "$1" ]; then echo "Use $( basename $0 ) --help for a list of options" fi } function display_help () { printf "${SLACKTRACKVERSION}\n\n$(display_usage) Startup: -h, --help Display this help -v, --version Display version information Options to Slackware's 'makepkg': -p, --package Resulting tar file name of the package -s, --nosymlinks Do not create symlinks via install/doinst.sh script -r, --setrootowner Set permissions on directories to 755 and owners to root.root --mpopts \"\" Specify additional options to 'makepkg' Specific altertrack options: -t, --notidy Do not delete temporary package directory -b, --buildstore Location to store built packages [ default: ${BUILDSTORE} ] -l, --logfile Path of altertrack's logfile [ default: (buildstore_path)/.log ] -n, --nologging Delete log file upon altertrack completing successfully -D, --md5sumtgz Create an MD5sum file of the resulting .tgz -G, --gpg-sign [] Sign the resulting .tgz with GnuPG -z, --gzman gzip any man pages found in known locations -I, --gzinfo gzip any info pages found in known locations -Z, --gzman-no-symfix Do not repair broken symlinks caused by the --gzman option [ default is to fix broken symlinks ] -F, --gzinfo-no-symfix Do not repair broken symlinks caused by the --gzinfo option [ default is to fix broken symlinks ] -K, --delete-usrinfodir Delete package's /usr/info/dir file [default is no] -d, --depend \"package1,pack2\" Ensure Slackware packages are installed before continuing -j, --striplib Strip executable ELF .so objects in the library directories -A, --striparchives Strip .a (archive) files found anywhere within the package -k, --stripbin Strip executable ELF files in the binary directories -S, --stripallexec Strip all executable ELF objects found within the package -c, --createdescription Create a slack-desc file named .txt in the build store path -e, --chown-bdirs-root-bin Set ownerships of the standard Slackware binary directories to 'root:bin'. If you use the --setrootowner option then it will reset the directory permissions to root:root -f, --chown-bfiles-root-bin Set ownerships of files contained within the standard Slackware binary directories to 'root:bin' -g, --chmod644docs Run chmod 644 & chown root:root on files in package's /usr/doc/ -U, --nousrtmp If /usr/tmp is a symlink, delete it and its contents -T, --tempdir Specify a temporary path for the package building By default, altertrack will choose one in /var/tmp -L, --nologhardlinks Do not log the existence of hard links -O, --chmod-og-w Run 'chmod -R og-w' over the package directory -x, --exclude '/foo|/bar' Supply replacement egrep pattern for dir/file exclusion -M, --extra-mandir Append path to the man directory list -W, --extra-infodir Append path to the info directory list -E, --extra-libdir Append path to the lib directory list -B, --extra-bindir Append path to the bin directory list -N, --strip-prog Specify the location of the 'strip' binary. -R, --run-after Run command/script after build script finishes -Q, --standard Select options required to build a compliant Slackware package --showdeps List the installed packages on which this new package depend --rootdir Change the directory that altertrack considers to be the root [default: /] --froot Launch fakeroot prior to Slackware-ising the new package --with-scratchbox Delete /dev and /home when working within Scratchbox Suggested usage: ${PROGNAME} -Qp foo-1.0-i486-1.tgz ./foo.build " } # Function to retrieve the package name. # glibc-solibs-2.2-i386-1.tgz = glibc-solibs function package_name () { local PACKAGENAME="$( echo $1 | rev | cut -d- -f4- | rev )" echo ${PACKAGENAME} } # Function to determine whether a supplied package name is already installed # Returns 0 if not installed, 1 if installed. # This function allows us to specify 'autoconf' for example, without having # to worry about the version number installed (unless you specifically want to, # in which case specify the version number as well - e.g. autoconf-2.54) function is_package_installed () { local PACKAGENAME="$1" local installed_package # We have to go through each package like this (rather than just do if -f foobar-* # because otherwise packges such as glibc, glibc-solibs and so on get wildcarded # and things get confused. for installed_package in $( find /var/log/packages/${PACKAGENAME}-* -type f -printf "%f\n" 2>/dev/null ) ; do installed_package="$( package_name ${installed_package} )" if [ "${installed_package}" = "${PACKAGENAME}" ]; then return 1 # the package 'short' name is installed break fi done return 0 } # Check if we have any package dependencies. This is a lame way of doing it and # possibly proves nothing, but it saves me writing it in a few build scripts that # would otherwise fail when they haven't got package X installed. function check_package_dep () { local error pack # Change comma separated input into spaces and consider them one by one for pack in $( echo ${1} | sed s/,/\ /g ); do is_package_installed "${pack}" if [ $? -eq 0 ]; then echo "${PROGNAME}: dependency Slackware package '${pack}' not installed" error=y else echo "${PROGNAME}: dependency Slackware package '${pack}' is installed. OK!" fi done if [ ! -z "${error}" ]; then echo "Error: Package dependencies failed" return 1 fi } # Function to move the temporary log file into the correct place & with the correct name. function move_log () { if [ "${LOGGING}" = "Yes" ]; then if [ -z "${USER_SLACKTRACKLOGFILE}" ]; then # Move /var/tmp/slacklog to /tmp/built-slackwarepackages/packagename.log mv -f ${SLACKTRACKLOGFILE} "${BUILDSTORE}/$( echo $SLACKWAREPACKAGE | rev | cut -d. -f2- | rev ).log" > /dev/null 2>&1 else # The user specified their own log path; rename our /var/tmp/slacklog to their's mv -f ${SLACKTRACKLOGFILE} ${USER_SLACKTRACKLOGFILE} > /dev/null 2>&1 fi else # We don't want a log, so we'll just delete the /var/tmp version rm -f ${SLACKTRACKLOGFILE} fi } # Tidy up the temporary directory (source extraction dir and pseudo root): function tidy_workspace () { ( if [ "${TIDYONFINISH}" = "Yes" ]; then echo -n "${PROGNAME}: Deleting temporary directory" rm -rf /install/* /install > /dev/null 2>&1 # otherwise this may cause trouble for other builds rm -rf "${SLACKTRACKTMPPATH}" if [ $? -gt 0 ]; then echo " ... error removing" else echo " ... done" fi else rm -rf /install/* /install > /dev/null 2>&1 echo "${PROGNAME}: Temporary workspace '${SLACKTRACKTMPPATH}' will remain" fi ) 2>&1 | tee -a ${SLACKTRACKLOGFILE} } ############################################################################################# PARAMS="$( getopt -qn "$( basename $0 )" -o p:b:l:d:M:N:W:E:x:B:R:T:DG::nefgcsrthvzAISjkKULOZQ -l exclude:,mpopts:,tempdir:,package:,buildstore:,logfile:,depend:,extra-mandir:,extra-infodir:,run-after:,extra-libdir:,extra-bindir:,strip-prog:,nologging,createdescription,gzman,gzinfo,gzman-no-symfix,gzinfo-no-symfix,striplib,striparchives,stripbin,stripallexec,nosymlinks,nousrtmp,chmod644docs,setrootowner,chown-bdirs-root-bin,chown-bfiles-root-bin,notidy,help,version,delete-usrinfodir,nologhardlinks,md5sumtgz,gpg-sign::,chmod-og-w,standard,showdeps,rootdir:,froot,with-scratchbox -- "$@" )" # If params are incorrect then if [ $? -gt 0 ]; then display_help >&2 ; exit 2 ; fi eval set -- "${PARAMS}" for param in $* ; do case "$param" in -p|--package) SLACKWAREPACKAGE="$2" shift 2;; -b|--buildstore) BUILDSTORE="$2/" shift 2;; -l|--logfile) USER_SLACKTRACKLOGFILE="$2" shift 2;; -n|--nologging) LOGGING=No shift 1;; -i|--install) INSTALLPACKAGE="Yes" shift 1;; -D|--md5sumtgz) CREATEMD5SUM="Yes" shift 1;; -G|--gpg-sign) SIGNPACKAGE="Yes" SIGNINGKEY="$2" shift 2;; -s|--nosymlinks) CREATESYMLINKS="No" shift 1;; -U|--nousrtmp) NOUSRTMP="Yes" shift 1;; -L|--nologhardlinks) LOGHARDLINKS="No" shift 1;; -O|--chmod-og-w) CHMODNOGLOBALWRITE="Yes" shift 1;; -T|--tempdir) SLACKTRACKTMPPATH="$2" shift 2;; -r|--setrootowner) SETROOTOWNER="Yes" shift 1;; --mpopts) MAKEPKGOPTS="$2" shift 2;; -e|--chown-bdirs-root-bin) CHOWNBINDIRSROOTBIN="Yes" shift 1;; -f|--chown-bfiles-root-bin) CHOWNBINFILESROOTBIN="Yes" shift 1;; -g|--chmod644docs) CHMOD644DOCS="Yes" shift 1;; -t|--notidy) TIDYONFINISH="No" shift 1;; -c|--createdescription) CREATEDESCRIPTION="Yes" shift 1;; -j|--striplib) STRIPLIB="Yes" shift 1;; -k|--stripbin) STRIPBIN="Yes" shift 1;; -S|--stripallexec) STRIPALLEXEC="Yes" shift 1;; -A|--striparchives) STRIPARCHIVES="Yes" shift 1;; -N|--strip-prog) STRIPPROG="$2" shift 2;; -z|--gzman) GZMAN="Yes" shift 1;; -I|--gzinfo) GZINFO="Yes" shift 1;; -Z|--gzman-no-symfix) GZMANFIXSYMLINKS="No" shift 1;; -F|--gzinfo-no-symfix) GZINFOFIXSYMLINKS="No" shift 1;; -K|--delete-usrinfodir) DELETEUSRINFODIR="Yes" shift 1;; -d|--depend) PACKAGEDEPEND="$2" shift 2;; -x|--exclude) EXCLUDE_LIST="$2" shift 2;; -M|--extra-mandir) MANDIR_LIST="${MANDIR_LIST} $( echo ${2} | sed s/,/\ / )" # replace commas with spaces for 'for' loops shift 2;; -W|--extra-infodir) INFODIR_LIST="${INFODIR_LIST} $( echo ${2} | sed s/,/\ / )" shift 2;; -E|--extra-libdir) LIBDIR_LIST="${LIBDIR_LIST} $( echo ${2} | sed s/,/\ / )" shift 2;; -B|--extra-bindir) BINDIR_LIST="${BINDIR_LIST} $( echo ${2} | sed s/,/\ / )" shift 2;; -R|--run-after) RUNCMDAFTER="$2" shift 2;; -v|--version) printf "${SLACKTRACKVERSION}\n" ; exit 0 ;; -h|--help) display_help ; exit 0 ;; -Q|--standard) GZMAN="Yes" GZINFO="Yes" DELETEUSRINFODIR="Yes" STRIPALLEXEC="Yes" CREATEDESCRIPTION="Yes" CHOWNBINDIRSROOTBIN="Yes" CHOWNBINFILESROOTBIN="Yes" CHMOD644DOCS="Yes" NOUSRTMP="Yes" shift ;; --showdeps) SHOWDEPS="Yes" shift ;; --froot) USEFAKEROOT="Yes" shift ;; --rootdir) ROOTDIR="$2" shift 2;; --with-scratchbox) WITHSCRATCHBOX=Yes shift ;; --) shift; break;; esac done # The package name is the final argument in the list COMMANDLINESCRIPT="$@" # Do we have a package name & a build script ? If not, bomb out. if [ -z "${SLACKWAREPACKAGE}" -o -z "${COMMANDLINESCRIPT}" ]; then display_usage help >&2 exit 2 fi # Why don't we check to see if the build script exists? # Well, if I do "/bin/sh foo.build" -- how can I check whether it exists? # Just don't pass altertrack duff stuff ;) # Check package dependencies if [ ! -z "${PACKAGEDEPEND}" ]; then check_package_dep "${PACKAGEDEPEND}" || exit 3 fi # Ensure the package name ends in .tgz (only a sloppy person would mess this up in their script ;) ) if [ "$( echo $SLACKWAREPACKAGE | rev | cut -d. -f1 | rev )" != "tgz" ]; then SLACKWAREPACKAGE="${SLACKWAREPACKAGE}.tgz" fi # If we didn't specify a temporary directory then we need make a random one if [ -z "${SLACKTRACKTMPPATH}" ]; then SLACKTRACKTMPPATH="/var/tmp/$$.$(date +%s).${RANDOM}.slacktrack.FAKEROOT" # Temporary path for file translation fi # If we elected to strip everything in the entire package directory then # set the other two strip options to something sensible to display to the # user/log file. if [ "${STRIPALLEXEC}" = "Yes" ]; then STRIPLIB="--stripallexec used, stripping all" STRIPBIN="${STRIPLIB}" STRIPARCHIVES="${STRIPLIB}" fi # Let's check if user really has gpg. if [ "${SIGNPACKAGE}" = "Yes" ]; then which gpg >/dev/null 2>&1 || { echo "${PROGNAME}: Warning: Cannot find gpg; disabling signature creation"; SIGNPACKAGE="No"; } fi # Display some info about the new package we're going to build ( printf " Package information ------------------- Slackware package name..................: ${SLACKWAREPACKAGE} Build script/command line...............: ${COMMANDLINESCRIPT} Build package store.....................: ${BUILDSTORE} altertrack log file.....................: ${SLACKTRACKLOGFILE} altertrack temporary dir................: ${SLACKTRACKTMPPATH} Logging.................................: ${LOGGING} Create an MD5sum of the resulting .tgz..: ${CREATEMD5SUM} Sign the resulting .tgz with GnuPG......: ${SIGNPACKAGE} Create description file.................: ${CREATEDESCRIPTION} Log hard links..........................: ${LOGHARDLINKS} chmod -R og-w...........................: ${CHMODNOGLOBALWRITE} chown root:bin binary directories.......: ${CHOWNBINDIRSROOTBIN} chown root:bin binaries in bin dirs.....: ${CHOWNBINFILESROOTBIN} chmod 644 & chown root:root /usr/doc/*..: ${CHMOD644DOCS} Additional options to 'makepkg'.........: $( if [ -z "${MAKEPKGOPTS}" ]; then echo "[ None ]" ; else echo "${MAKEPKGOPTS}" ; fi ) Create Symlinks.........................: ${CREATESYMLINKS} Set root owner..........................: ${SETROOTOWNER} Tidy on finish..........................: ${TIDYONFINISH} gzip man pages..........................: ${GZMAN} gzip info pages.........................: ${GZINFO} Fix broken gz man page symlinks.........: ${GZMANFIXSYMLINKS} Fix broken gz info page symlinks........: ${GZINFOFIXSYMLINKS} Delete package's /usr/info/dir page.....: ${DELETEUSRINFODIR} Strip executable ELF binaries...........: ${STRIPBIN} Strip executable ELF shared objects.....: ${STRIPLIB} Strip .a (archive) files................: ${STRIPARCHIVES} Strip all executable ELF files..........: ${STRIPALLEXEC} Path to strip utility...................: ${STRIPPROG} Shared objects (libraries) dirs.........: ${LIBDIR_LIST} Binary objects dirs.....................: ${BINDIR_LIST} Man page dirs...........................: ${MANDIR_LIST} Info page dirs..........................: ${INFODIR_LIST} Delete /usr/tmp symlink.................: ${NOUSRTMP} Show dependencies to other packages.....: ${SHOWDEPS} egrep pattern for dir/file exclusion....: ${EXCLUDE_LIST} Command/script to run after build script: $( if [ -z "${RUNCMDAFTER}" ]; then echo "None" ; else echo ${RUNCMDAFTER} ; fi ) Directory altertrack considers is root..: ${ROOTDIR} Use fakeroot utility whilst packaging...: ${USEFAKEROOT} Working within Scratchbox...............: $( if [ -z "${WITHSCRATCHBOX}" ]; then echo "No" ; else echo "Yes" ; fi ) ....................................................................\n" ) 2>&1 | tee ${SLACKTRACKLOGFILE} # Delete the temporary path. Perhaps this isn't safe, but then again we're running # on a devbox which nobody else has access to, aren't we ;) rm -rf "${SLACKTRACKTMPPATH}" mkdir -pm700 "${SLACKTRACKTMPPATH}" # Create a temporary 'scratch' directory inside the altertrack # temporary dir. This is to save build scripts managing their own # temporary directories should the author be too lazy ;) export SLACKTRACKSCRATCHDIR="${SLACKTRACKTMPPATH}/SCRATCHDIR" mkdir -pm700 "${SLACKTRACKSCRATCHDIR}" export SLACKTRACKFAKEROOT="${SLACKTRACKTMPPATH}/TRANSL" mkdir -pm755 "${SLACKTRACKFAKEROOT}" BEFOREFILESLIST="${SLACKTRACKTMPPATH}/before_files.list" AFTERFILESLIST="${SLACKTRACKTMPPATH}/after_files.list" NEWFILESLIST="${SLACKTRACKTMPPATH}/new_files.list" DIRLIST="${SLACKTRACKTMPPATH}/dir.list" # Generate list of files on the system prior to executing the build script # 'bp' touches all the files on the file system. # The reason you *might* want to touch everything first is so that # if mkdir /etc/package_configdir fails (because it alreasy exists) # then the fact that it's been *tried* will be picked up # when you scan after the build script has finished. # However, altertrack doesn't scan like that so it wouldn't # actually notice a thing ! # This is the exact reason I suggest using removepkg first. # # I remove /mnt, /proc, /tmp and /home here to make the find # execute more quickly. I have a box NFS mounted on /mnt # so it's highly undesirable to scan another OS installation # in addition to our own ;-) echo -n "${PROGNAME}: Finding files on the system, please wait" ( cd ${ROOTDIR} find . \( -regex './\(mnt\|sys\|proc\|tmp\|home\)' -prune \) -o -not -name . -printf "%p %T@ %s\n" | cut -d. -f2- > ${BEFOREFILESLIST} ) >/dev/null 2>&1 echo " ... done" # Launch build script with logging if [ "${LOGGING}" = "Yes" ]; then ( printf "\n\n\n[$( date "+%D %r" )] ${PROGNAME}: Executing command line '${COMMANDLINESCRIPT}'\n\n" ${COMMANDLINESCRIPT} EXIT_CODE=$? if [ ${EXIT_CODE} -gt 0 ]; then printf "\n\n[$( date "+%D %r" )] ${PROGNAME}: * WARNING: ${COMMANDLINESCRIPT} returned exit code ${EXIT_CODE} *\n\n" fi printf "[$( date "+%D %r" )] ${PROGNAME}: command line '${COMMANDLINESCRIPT}' finished\n\n" ) 2>&1 | tee -a ${SLACKTRACKLOGFILE} else # Launch build script without logging (allows perl's CPAN interface to work) ( printf "\n\n\n[$( date "+%D %r" )] ${PROGNAME}: Executing command line '${COMMANDLINESCRIPT}'\n\n" ${COMMANDLINESCRIPT} EXIT_CODE=$? if [ ${EXIT_CODE} -gt 0 ]; then printf "\n\n[$( date "+%D %r" )] ${PROGNAME}: * WARNING: ${COMMANDLINESCRIPT} returned exit code ${EXIT_CODE} *\n\n" fi printf "[$( date "+%D %r" )] ${PROGNAME}: command line '${COMMANDLINESCRIPT}' finished\n\n" ) fi # Generate list of files post installation # Again we miss out /mnt et al to speed up the process. echo -n "${PROGNAME}: Finding files on the system, please wait" ( cd ${ROOTDIR} find . \( -regex './\(mnt\|sys\|proc\|tmp\|home\)' -prune \) -o -not -name . -printf "%p %T@ %s\n" | cut -d. -f2- > ${AFTERFILESLIST} ) >/dev/null 2>&1 echo " ... done" # If we're running within Scratchbox then we delete /dev and /home because # they are empty and are created by scratchbox. if [ "${WITHSCRATCHBOX}" = "Yes" -a -f /scratchbox/scratchbox.config ]; then echo -n "${PROGNAME}: Scratchbox detected; deleting /dev & /home" rmdir ${ROOTDIR}/dev ${ROOTDIR}/home > /dev/null 2>&1 echo " ... done" fi # Generate new list of files on the system (compare before and after file list) # and delete the list of files/dirs that match the egrep pattern exclude list. echo -n "${PROGNAME}: Comparing file lists" diff -Bbu ${BEFOREFILESLIST} ${AFTERFILESLIST} | grep "^+" | awk '{print $1}' | cut -d+ -f2- | \ egrep -v "^(/$|\+\+$|${EXCLUDE_LIST})" > ${NEWFILESLIST} echo " ... done" # Remove all non-empty directories from our package contents list # If we don't and we have any non-empty directories that have # changed (or been accessed) then the tar (below) ends up # including the directory & contents in its entirety into our new package! cd ${SLACKTRACKFAKEROOT} echo -n "${PROGNAME}: Removing non-empty directories from package contents list" ( cd ${ROOTDIR} cat ${NEWFILESLIST} | while read fileline ; do if [ -d "./${fileline}" ]; then # We only retain the *empty* directories otherwise any directories # created by our build scripts (such as place holders) will be # removed. Everything contained within the non-empty directories will # be picked up by tar. if [ "$( find "./${fileline}" | wc -l )" -ne 1 ]; then echo "${fileline}" >> "${DIRLIST}" fi fi done ) > /dev/null 2>&1 ( cat ${NEWFILESLIST} ${DIRLIST} | sort | uniq -u > ${NEWFILESLIST}.new ) > /dev/null 2>&1 mv -f ${NEWFILESLIST}.new ${NEWFILESLIST} echo " ... done" # Copy the changed files into our temporary package directory echo -n "${PROGNAME}: Copying the new/changed files into temporary directory" ( cd ${ROOTDIR} ; cut -d/ -f2- ${NEWFILESLIST} | tar pvvcf - -T- | tar -C${SLACKTRACKFAKEROOT} -pxf - ) >/dev/null 2>&1 echo " ... done" # Do we have any files in the temporary directory ? if [ "$( find ${SLACKTRACKTMPPATH}/TRANSL -print | wc -l )" -le 1 ]; then ( printf "altertrack: failed to track any activity\n" printf " Perhaps the build script doesn't exist or is broken\n\n" printf " ERROR: Cannot build a .tgz package\n\n" ) 2>&1 | tee -a ${SLACKTRACKLOGFILE} move_log # we will want to log this error incase we're using altertrack through an unattended auto builder tidy_workspace # clean up workspace exit 5 fi # Launch the fakeroot utility? if [ "${USEFAKEROOT}" = "Yes" ]; then which faked >/dev/null 2>&1 || NOFAKEFOUND=yes if [ -z "${NOFAKEFOUND}" ]; then export FAKEROOTKEY="$( faked )" export FAKEROOTPID="$( echo ${FAKEROOTKEY} | cut -d: -f2 )" export FAKEROOTKEY="$( echo ${FAKEROOTKEY} | cut -d: -f1 )" FAKEROOT_LIB=${FAKEROOT_LIB:=/lib/libfakeroot.so.0} # you can override this by exporting it from your environment export LD_PRELOAD=${FAKEROOT_LIB} # Otherwise we leave 'faked' sitting around: trap "kill -s TERM ${FAKEROOTPID} >/dev/null 2>&1" EXIT INT else echo "${PROGNAME}: Warning - cannot find faked (fakeroot daemon) in $PATH; not running fakeroot" fi fi # Get back inside the package's root directory # (we shouldn't have left it because all cding is done inside subshells # but it doesn't hurt) cd ${SLACKTRACKFAKEROOT} # Generate a list of the files that have been installed/modified on the # file system which we use to populate the /var/log/packages/$package # entry. The reason we do this here rather than use the contents of the $package.tgz # is because we modify some files (such as gzipping man pages), and as such when # we removepkg $package, it doesn't delete /usr/man/man1/bash.1 because the entry # would contain /usr/man/man1/bash1.gz echo "./$( find . -printf "%P\n" )" > ${SLACKTRACKTMPPATH}/realpackagelist # Restore original directory permissions from root filesytem. # Why? Because we only store (in our file list), EMPTY directories. Example: # I chmod 700 /etc/rc.d (which contains many startup scripts) # My new file rc script is called 'rc.foo' and this is the only thing that's changed # within /etc/rc.d. Therefore altertrack only preserves the file name # '/etc/rc.d/rc.foo', so tar has to create etc/rc.d for itself -- it has no # information about its permissions/ownerships. # Why don't I just tar up the directory? read the comments above the code that does the tar. ( if [ -s ${DIRLIST} ]; then echo -n "${PROGNAME}: Restoring directory permissions & ownerships" cat ${DIRLIST} | while read line ; do find "${ROOTDIR}/${line}" -mindepth 0 -maxdepth 0 -printf "%U:%G" | xargs -0i chown {} "./${line}" find "${ROOTDIR}/${line}" -mindepth 0 -maxdepth 0 -printf "%m" | xargs -0i chmod {} "./${line}" done echo " ... done" fi ) # 2>&1 | tee -a ${SLACKTRACKLOGFILE} # gzip man pages ? # Note that we prefix the dir name with ./ - this is so that if users specify # additional directories with --extra-xxxdir and include / , then it doesn't actually # *look* in the root dir. ( if [ "${GZMAN}" = "Yes" ]; then echo -n "${PROGNAME}: gzipping man pages" for man_dir in ${MANDIR_LIST}; do if [ -d "./${man_dir}" ]; then ( find ./${man_dir} -type f -name '*.bz2' -print0 | xargs -0 bzip2 -df ) >/dev/null 2>&1 ( find ./${man_dir} -type f -print0 | xargs -0 gzip -9 ) >/dev/null 2>&1 ( find ./${man_dir} -type f -print0 | xargs -0 chmod 644 ) >/dev/null 2>&1 fi done echo " ... done" if [ "${GZMANFIXSYMLINKS}" = "Yes" ]; then echo -n "${PROGNAME}: Fixing any broken symlinks in man page directories" # Fix up symlinks unless instructed not to for man_dir in ${MANDIR_LIST}; do if [ -d "./${man_dir}" ]; then ( cd ./${man_dir} # Enter each man page directory (man1,man2..) and whittle them down one by one for i in "$( find . -type d -maxdepth 1 -printf "%P\n" | grep -v "^$" )"; do # We cd into the man dir then use find to construct some shell commands & pipe into # bash for execution. Neat huh? ;) cd ${i} && ( find . -type l -printf "rm -f %P ; ln -s %l.gz %p.gz\n" ) | /bin/bash && cd .. done ) fi done echo " ... done" fi fi ) 2>&1 | tee -a ${SLACKTRACKLOGFILE} # Delete package's /usr/info/dir ? # You're more than likely going to want to do this. ( if [ "${DELETEUSRINFODIR}" = "Yes" -a -f usr/info/dir ]; then echo -n "${PROGNAME}: deleting /usr/info/dir" rm -f usr/info/dir echo " ... done" fi ) 2>&1 | tee -a ${SLACKTRACKLOGFILE} # gzip info pages ? ( if [ "${GZINFO}" = "Yes" ]; then echo -n "${PROGNAME}: gzipping info pages" for info_dir in ${INFODIR_LIST}; do if [ -d "./${info_dir}" ]; then ( find ./${info_dir} -type f -name '*.bz2' -print0 | xargs -0 bzip2 -df ) >/dev/null 2>&1 ( find ./${info_dir} -type f -print0 | xargs -0 gzip -9 ) >/dev/null 2>&1 ( find ./${info_dir} -type f -print0 | xargs -0 chmod 644 ) >/dev/null 2>&1 fi done echo " ... done" if [ "${GZINFOFIXSYMLINKS}" = "Yes" ]; then echo -n "${PROGNAME}: Fixing any broken symlinks in info page directories" # Fix up symlinks unless instructed not to for info_dir in ${INFODIR_LIST}; do if [ -d "./${info_dir}" ]; then ( cd ./${info_dir} && ( find . -type l -printf "rm -f %P ; ln -s %l.gz %p.gz\n" ) | /bin/bash ) fi done echo " ... done" fi fi ) 2>&1 | tee -a ${SLACKTRACKLOGFILE} # Strip shared objects ? ( if [ "${STRIPLIB}" = "Yes" ]; then echo -n "${PROGNAME}: Stripping unstripped ELF shared objects" for i in ${LIBDIR_LIST}; do ( cd ./${i} && find . -name '*.so*' -type f \( -perm -100 -o -perm -010 -o -perm -001 \) -print0 | xargs -0 file | egrep '(ELF.*shared.*not stripped)' | awk -F: '{print $1}' | xargs ${STRIPPROG} -p --strip-unneeded ) > /dev/null 2>&1 done echo " ... done" fi ) 2>&1 | tee -a ${SLACKTRACKLOGFILE} # Strip .a (archive) files ? ( if [ "${STRIPARCHIVES}" = "Yes" ]; then echo -n "${PROGNAME}: Stripping .a (archive) files" ( find . -name '*.a' -type f -print0 | xargs -0 ${STRIPPROG} -p -g ) > /dev/null 2>&1 echo " ... done" fi ) 2>&1 | tee -a ${SLACKTRACKLOGFILE} # Strip binaries? ( if [ "${STRIPBIN}" = "Yes" ]; then echo -n "${PROGNAME}: Stripping unstripped ELF binaries" for i in ${BINDIR_LIST}; do ( cd ./${i} && find . -type f \( -perm -100 -o -perm -010 -o -perm -001 \) -print0 | xargs -0 file | egrep '(ELF.*not stripped)' | awk -F: '{print $1}' | xargs ${STRIPPROG} -p --strip-unneeded ) >/dev/null 2>&1 done echo " ... done" fi ) 2>&1 | tee -a ${SLACKTRACKLOGFILE} # Strip everything? This does the same as the above but instead it does it across # the entire package directory -- therefore it finds stuff in /opt and anywhere else # that files have been created. You may prefer to use this option if you already use -jkA # but it's worth noting that it will take longer (especially on a package with many files # in a deep directory structure) ( if [ "${STRIPALLEXEC}" = "Yes" ]; then echo -n "${PROGNAME}: Stripping all unstripped executable ELF files" ( find . -type f \( -perm -100 -o -perm -010 -o -perm -001 \) -print0 | xargs -0 file | egrep '(ELF.*not stripped)' | awk -F: '{print $1}' | xargs ${STRIPPROG} -p --strip-unneeded ) >/dev/null 2>&1 # Strip the .a archives ( find . -name '*.a' -type f -print0 | xargs -0 ${STRIPPROG} -p -g ) > /dev/null 2>&1 echo " ... done" fi ) 2>&1 | tee -a ${SLACKTRACKLOGFILE} # If we find /usr/tmp is a symlink then delete it. # Some programs such as Apache seem to put stuff in here. /usr/tmp is a symlink and is # created by Slackware's 'aaa_base' package. ( if [ "${NOUSRTMP}" = "Yes" -a -h "usr/tmp" ]; then echo "${PROGNAME}: Deleting /usr/tmp symlink from package build directory" rm -rf "${SLACKTRACKTMPPATH}/TRANSL/usr/tmp" fi ) 2>&1 | tee -a ${SLACKTRACKLOGFILE} # Run chmod -R og-w over the package directory ? # In general you won't want to do this because you should take care of your # own permissions on a per-build-script basis. However, some software such # as PHP leaves files globally writeable (even a recent Slackware PHP package # had files og+w). ( if [ "${CHMODNOGLOBALWRITE}" = "Yes" ]; then echo -n "${PROGNAME}: Running chmod -R og-w on package contents" chmod -R og-w . echo " ... done" fi ) 2>&1 | tee -a ${SLACKTRACKLOGFILE} # Fix up ownerships in the package. According to the 'README' that comes with # Pat's 'slack-tools' scripts say: # "non-setuid binaries in /bin, /sbin, /usr/bin, and /usr/sbin are # all chown root:bin (and the directories are, too)" # However, I spot traceroute as being setuid and owned by root.bin # So we'll just set everything in & including those dirs to be root.bin # You WON'T want to always use this facility -- some build scripts such as # 'floppy' set their own permissions correctly. Again, you need to check over # the .tgz afterwards and make changes to your build script accordingly. ( if [ "${CHOWNBINDIRSROOTBIN}" = "Yes" ]; then echo -n "${PROGNAME}: chowning root:bin the directories ${BINDIR_LIST}" for i in ${BINDIR_LIST}; do # Yes, we're assuming we may have dirs inside our bins. I've yet to see # one but there may be in the future. ( cd ./$i && find . -type d -print0 | xargs -0 chown root:bin ) >/dev/null 2>&1 done echo " ... done" fi ) 2>&1 | tee -a ${SLACKTRACKLOGFILE} # chown root:bin files # Please note that any additional paths specified using --extra-bindir # will NOT be considered here. The Slackware standard is to only chown root:bin on # /usr dirs -- if you look at /opt/kde/bin you'll see the files are owned by root.root ( if [ "${CHOWNBINFILESROOTBIN}" = "Yes" ]; then echo -n "${PROGNAME}: chowning root:bin the files inside ${BINDIR_LIST}" for i in ${BINDIR_LIST}; do ( cd ./$i && find . -type f -printf "chown root:bin '%p' && chmod %m '%p'\n" | /bin/bash ) > /dev/null 2>&1 done echo " ... done" fi ) 2>&1 | tee -a ${SLACKTRACKLOGFILE} # chmod 644 & chown root:root docs in usr/doc ? # This is my own 'thing'. I don't like having any executable files in # my docs directory. ( if [ "${CHMOD644DOCS}" = "Yes" -a -d "usr/doc" ]; then echo -n "${PROGNAME}: Running chmod 644 over documents in usr/doc/" ( find usr/doc/ -type f -print0 | xargs -0 chmod 644 ) >/dev/null 2>&1 ( chown -R root:root usr/doc/ ) >/dev/null 2>&1 echo " ... done" fi ) 2>&1 | tee -a ${SLACKTRACKLOGFILE} # If the user has specified both --setrootowner and --chown-bdirs-root-bin then warn # them that their dirs permissions will be changed # These options aren't mutually exclusive because --chown-bdirs-root-bin # ONLY chowns /bin,/sbin,/usr/bin & /usr/sbin ( if [ "${CHOWNBINDIRSROOTBIN}" = "Yes" -a "${SETROOTOWNER}" = "Yes" ]; then echo "${PROGNAME}: * WARNING *" echo " You have specified both --setrootowner AND --chown-bdirs-root-bin" echo " options, but Slackware's makepkg script will change the" echo " directory permissions to 'root.root'." fi ) 2>&1 | tee -a ${SLACKTRACKLOGFILE} # Ensure the 'root' directory of the tarchive is globally readable # else it breaks your root dir thus your system when you install the package ;) chmod 755 ${SLACKTRACKTMPPATH}/TRANSL chown root:root ${SLACKTRACKTMPPATH}/TRANSL # If the buildstore doesn't exist then we'll use /tmp instead # We don't check this earlier because *my* scripts mkdir /tmp/built-slackwarepackages # and Slackware's SlackBuild scripts leave the .tgz in /tmp -- and /tmp must always exist # We won't try and create the dir because if you made a typo in the dir name, you # make find your .tgz (that may contain sensitive files) ends up in a globally readable # area. if [ ! -d "${BUILDSTORE}" ]; then printf "altertrack: WARNING: The build store directory ${BUILDSTORE}\n" printf " does not exist; using /tmp instead\n\n" BUILDSTORE="/tmp/" fi # Show dependencies to the INSTALLED packages ? ( if [ "${SHOWDEPS}" = "Yes" ]; then LDDEPSFILE="${SLACKTRACKTMPPATH}/ld_list" LDDEPSUNRESOLVED="${SLACKTRACKTMPPATH}/ld_unresolved" LDDEPSFOUNDPACKAGES="${SLACKTRACKTMPPATH}/ld_found_packages" echo -n "${PROGNAME}: Generating list of shared library dependencies" # I grep out 'not found' from the list because if this package CONTAINS the # 'not found' library then we're not going to find it in /var/log/packages # This isn't the same as having what I call an 'orphaned' library. ( find . -type f \( -perm -100 -o -perm -010 -o -perm -001 \) -print0 | xargs -0 file | egrep '(ELF.*shared)' | \ awk -F: '{print $1}' | xargs ldd 2>/dev/null | grep '=>' | grep -vi 'not found' | \ awk '{print $3}' | grep -v "^$" > "${LDDEPSFILE}" ) > /dev/null 2>&1 # If we're running under fakeroot then remove fakeroot from # the dependencies. if [ "$( echo "${LD_LIBRARY_PATH}" | grep libfakeroot )" ]; then mv -f "${LDDEPSFILE}" "${LDDEPSFILE}.temp" grep -v "libfakeroot" "${LDDEPSFILE}.temp" > "${LDDEPSFILE}" fi if [ ! -s "${LDDEPSFILE}" ]; then printf "\n Failed to find any shared object dependencies\n" else # Remove dupes from the list sort "${LDDEPSFILE}" | uniq > "${LDDEPSFILE}.sorted" mv -f "${LDDEPSFILE}.sorted" "${LDDEPSFILE}" # Look in /var/log/packages and /var/log/scripts (because our library # may be linked against a symlink) and find our packages. # Now, a problem that we have is that some of # Slackware's packages have an 'incoming' directory (eg glibc) # to avoid trampling over the running system without doing # some pokery first. # This is why I am *only* keeping the .so name rather than the # full path leading to it. cat "${LDDEPSFILE}" | rev | cut -d/ -f1 | rev | while read library_name ; do ( ( cd /var/log/packages && grep -l ${library_name} * ) || ( cd /var/log/scripts && grep -l ${library_name} * ) ) >> "${LDDEPSFOUNDPACKAGES}" # If we couldn't find it in a package (most likely because # it's linked against something that was compiled 'locally' rather than # being brewed into a package, or because you've broken your packages list) if [ $? -gt 0 ]; then # This way it shows the full path to the library rather than just its file name. egrep "${library_name}$" "${LDDEPSFILE}" >/dev/null 2>&1 && \ echo "$( egrep "${library_name}$" "${LDDEPSFILE}" )" >> "${LDDEPSUNRESOLVED}" fi done # Before you think "Hold on a second old cheese, but some libraries # exist in more than one package (glibc/glibc-solibs is an example) # so what you going to do about that?" # Absolutely nothing! :-) That'd mean having some sort of database # to know that you'd only need one of the packages listed. # *Also*, if you think about it, then who's to tell you whether you # should have glibc OR glibc-solibs? *I* only install 'glibc' because # I compile stuff (you don't need -solibs if you have the # developer/full package) .. then if I compiled this package on a box # that only had 'openssl' (rather than openssl-solibs *AND* openssl) # then... oh it's too complicated. It's like a paradox or something. # Remove any dupes from the package list sort "${LDDEPSFOUNDPACKAGES}" | uniq > "${LDDEPSFOUNDPACKAGES}.sorted" mv -f "${LDDEPSFOUNDPACKAGES}.sorted" "${LDDEPSFOUNDPACKAGES}" # From 'generating list of dependencies' above. echo " ... done" # Dump the list of package dependencies to screen if [ -s "${LDDEPSFOUNDPACKAGES}" ]; then echo "${PROGNAME}: This package depends on libraries within the following installed packages:" cat "${LDDEPSFOUNDPACKAGES}" | while read line ; do printf "\t ${line}\n" done fi # Now dump the list of dependencies into a log file. # We could store it somewhere in the package I suppose, any suggestions? install -m644 "${LDDEPSFOUNDPACKAGES}" "${BUILDSTORE}/$( echo $SLACKWAREPACKAGE | rev | cut -d. -f2- | rev ).ld_deps.log" # And if we found any libraries that aren't part of installed packages, dump # those too. if [ -s "${LDDEPSUNRESOLVED}" ]; then echo "${PROGNAME}: The following libraries were not found in any installed package:" cat "${LDDEPSUNRESOLVED}" | while read line ; do printf "\t ${line}\n" done # Not much point in listing libraries in the package if we can't # tell the user how to get a package containing that library, so # we'll just log it and let the developer fix it afterwards. install -m644 "${LDDEPSUNRESOLVED}" "${BUILDSTORE}/$( echo $SLACKWAREPACKAGE | rev | cut -d. -f2- | rev ).orphaned_ld_deps.log" fi fi fi ) 2>&1 | tee -a ${SLACKTRACKLOGFILE} # Launch an external command/script before running makepkg ? # This may be useful to inspect the package contents with a file manager such as # Midnight Commander or xtc. # This is extremly useful for altertrack as you can fix up symlinks and stuff # that you couldn't do inside the root file system. if [ ! -z "${RUNCMDAFTER}" ]; then echo "${PROGNAME}: Launching external command '${RUNCMDAFTER}'" >> ${SLACKTRACKLOGFILE} # Enter the package's root directory and run the command. We don't log this # because if it's an ncurses type program then who knows what that'd do to # the log file. ( cd ${SLACKTRACKTMPPATH}/TRANSL ; ${RUNCMDAFTER} ) echo "${PROGNAME}: External command finished" >> ${SLACKTRACKLOGFILE} fi # In altertrack you have no choice but to make a .tgz # Execute the Slackware package making utility & append its output to the package logfile ( ${MAKEPKG} ${MAKEPKGOPTS} \ --linkadd $( echo ${CREATESYMLINKS} | cut -b1 | tr A-Z a-z ) \ --chown $( echo ${SETROOTOWNER} | cut -b1 | tr A-Z a-z ) \ ${BUILDSTORE}/${SLACKWAREPACKAGE} # tar up the file without compression so we can see how big it is for # the package description ( tar cf ${SLACKTRACKTMPPATH}/temp.tar . ) > /dev/null 2>&1 # Create a package contents file for /var/log/packages cat << EOF > /var/log/packages/"$( echo $SLACKWAREPACKAGE | rev | cut -d. -f2- | rev )" PACKAGE NAME: $( echo $SLACKWAREPACKAGE | rev | cut -d. -f2- | rev ) COMPRESSED PACKAGE SIZE: $( ls -lah ${BUILDSTORE}/${SLACKWAREPACKAGE} | awk '{print $5}' ) UNCOMPRESSED PACKAGE SIZE: $( ls -lah ${SLACKTRACKTMPPATH}/temp.tar | awk '{print $5}' ) PACKAGE LOCATION: /${SLACKWAREPACKAGE} PACKAGE DESCRIPTION: $( egrep -v '^($|#| *\|)' install/slack-desc 2>/dev/null ) $( cat ${SLACKTRACKTMPPATH}/realpackagelist ) EOF # Add the doinst.sh script into /var/log/scripts/packagename ( tar fOxz ${BUILDSTORE}/${SLACKWAREPACKAGE} install/doinst.sh > /var/log/scripts/$( echo $SLACKWAREPACKAGE | rev | cut -d. -f2- | rev ) chmod 755 /var/log/scripts/$( echo $SLACKWAREPACKAGE | rev | cut -d. -f2- | rev ) ) >/dev/null 2>&1 if [ $? -gt 0 ]; then rm -f /var/log/scripts/$( echo $SLACKWAREPACKAGE | rev | cut -d. -f2- | rev ) fi # Delete useless .tar rm -f ${SLACKTRACKTMPPATH}/temp.tar # Warn if no slack-desc file found. You don't need a doinst.sh script # though, so we won't bother with that one. # Why do this *after* running makepkg? makepkg makes lots of noise # and unless you specifically scroll up or look at logs, you'll miss this warning. if [ ! -s "install/slack-desc" ]; then echo "${PROGNAME}: WARNING - /install/slack-desc not found or is 0 bytes" fi # Display the size of the .tgz. if [ -f "${BUILDSTORE}/${SLACKWAREPACKAGE}" ]; then printf "${PROGNAME}: ${SLACKWAREPACKAGE}'s size is $( ls -lah ${BUILDSTORE}/${SLACKWAREPACKAGE} | awk '{print $5}' )\n" fi # Create an MD5sum of the .tgz if requested if [ "${CREATEMD5SUM}" = "Yes" ]; then echo -n "${PROGNAME}: Creating an MD5 sum of ${SLACKWAREPACKAGE}" ( cd "${BUILDSTORE}" md5sum "${SLACKWAREPACKAGE}" > "${SLACKWAREPACKAGE}.md5" ) echo " ... done" fi # Sign the .tgz if requested to do so. if [ "${SIGNPACKAGE}" = "Yes" ]; then echo "${PROGNAME}: Signing ${SLACKWAREPACKAGE} with ${SIGNINGKEY:-your default} key" ( cd "${BUILDSTORE}" GPG_OPTIONS="--detach-sign --armor" if [ "${SIGNINGKEY}" ]; then GPG_OPTIONS="${GPG_OPTIONS} --local-user $SIGNINGKEY" fi gpg ${GPG_OPTIONS} --output ${SLACKWAREPACKAGE}.asc ${SLACKWAREPACKAGE} if [ $? -ne 0 ]; then echo "${PROGNAME}: ERROR: Signature has not been correctly generated" else echo " ... done" fi ) fi ) 2>&1 | tee -a ${SLACKTRACKLOGFILE} # Copy the slack-desc file into the build store path ? ( if [ "${CREATEDESCRIPTION}" = "Yes" -a -f "${SLACKTRACKTMPPATH}/TRANSL/install/slack-desc" ]; then echo "${PROGNAME}: Installing package description file into build store" # Cut the handy ruler, comments and empty lines out of the file. egrep -v '^($|#| *\|)' ${SLACKTRACKTMPPATH}/TRANSL/install/slack-desc > "${BUILDSTORE}/$( echo $SLACKWAREPACKAGE | rev | cut -d. -f2- | rev ).txt" chmod 644 "${BUILDSTORE}/$( echo $SLACKWAREPACKAGE | rev | cut -d. -f2- | rev ).txt" fi ) 2>&1 | tee -a ${SLACKTRACKLOGFILE} # Log hard links # Some packages (such as Python) use ln to create hard links rather than soft links. # It is impossible to determine the original file name of a hard link, and thus # must be weeded out manually. ( if [ "${LOGHARDLINKS}" = "Yes" ]; then echo -n "${PROGNAME}: Scanning for hard links" printf "$( find ${SLACKTRACKTMPPATH}/TRANSL -type f -links +1 -printf "Hard link: %P\n" )\n" > ${SLACKTRACKLOGFILE}.hardlinks if [ ! -z "$( grep "Hard link:" ${SLACKTRACKLOGFILE}.hardlinks )" ]; then printf "\nWARNING: The following hard links were detected\n" cat ${SLACKTRACKLOGFILE}.hardlinks echo # We will ALWAYS create a log file for hardlinks regardless of whether logging is disabled. # The packager HAS to know about them ! mv ${SLACKTRACKLOGFILE}.hardlinks "${BUILDSTORE}/$( echo $SLACKWAREPACKAGE | rev | cut -d. -f2- | rev ).hardlinks.log" else echo " ... none found" rm -f "${SLACKTRACKLOGFILE}.hardlinks" fi fi ) 2>&1 | tee -a ${SLACKTRACKLOGFILE} # Tidy up workspace: tidy_workspace # Report that altertrack has finished, but to the log only. printf "\n\n[$( date "+%D %r" )] ${PROGNAME} finished.\n" >> ${SLACKTRACKLOGFILE} # Unless the user has specified their own logfile, we'll use packagename-ver-arch-build.log # If they've disabled logging with --nologging then simply delete the log file. # You could say this was sloppy, that we're logging in the first place if we're told not to # but given that most make scripts scroll tens of pages off the screen, I think a log file # is *Always* handy to have, even if you don't retain it. move_log # Report that altertrack has finished (to screen only). printf "\n\n[$( date "+%D %r" )] ${PROGNAME} finished.\n" exit 0 #EOF