#!/bin/sh # # $Revision: 1.2 $ # # rpmpatch # Perform a patch on an src rpm file rebuilding the new patched src rpm. # - this script is only intended to work on src rpms. # # Copyright (C) 2005 Simon J. Mudd (sjmudd@pobox.com) # # Newer versions of this script may be made available at: # http://ftp.wl0.org/rpmdiff # # Usage: rpmpatch [] [] # # patchfile is the file containing the patches (from rpmdiff). # originalrpm is the unpatched src rpm # newrpm is the newly created src rpm (built to $pwd) # # Exit Status # As patch 0 = ok, otherwise trouble. # # License: # 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 may have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, # USA. # # An on-line copy of the GNU General Public License can be found # http://www.fsf.org/copyleft/gpl.html. [ -n "$DEBUG" ] && set -x myname=$(basename $0) myversion=$(echo '$Id: rpmpatch,v 1.2 2005/01/08 20:10:32 sjmudd Exp $' | awk '{ print $3 }') # fatal error and stop msg_fatal () { echo "FATAL: $*" >&2 exit 1 } # standard message msg_info () { echo "$*" } # extract rpm to path, ensure destination directory does not exist. extract_rpm () { local local_rpm="$1" local local_dir="$2" [ "${local_rpm}" = "${local_dir}" ] || { [ -d "${local_dir}" ] && msg_fatal "directory ${local_dir} already exists" msg_info "Extracting files from $(basename ${local_dir})" ( mkdir ${local_dir} && cd ${local_dir} && rpm2cpio ${local_rpm} | cpio -im --quiet) ||\ msg_fatal "problem extracting ${local_rpm}" } } # remove temporary directory remove_rpmdir () { local local_dir="$1" msg_info "Removing ${local_dir}" [ -d ${local_dir} ] || msg_fatal "${local_dir} is not a directory" rm -rf ${local_dir} || msg_fatal "problems removing ${local_dir}" } # generate macro contents based on repo name # - this is only from src rpms so don't worry too much about it's contents # - provide the old file if any so we can restore it later generate_rpmmacros_file () { local srpmdir="$1" local rpmmacros=$HOME/.rpmmacros local tmpdir=${TMPDIR:-/tmp} local backup # backup file if needed [ -f ${rpmmacros} ] && \ backup=$HOME/.rpmmacros.backup.$(date +%y%m%d.%H%M%S) && \ mv ${rpmmacros} ${backup} cat <<-EOF > ${rpmmacros} # Temporary RPM macros configuration file used by $myname. %_sourcedir ${srpmdir} %_specdir ${srpmdir} %_tmppath ${tmpdir} # build the rpm into this directory %_srcrpmdir ${PWD} EOF echo ${backup} } build_srpm () { local sdir="$1" local srpm="$2" msg_info "generating ${srpm}" local backup=$(generate_rpmmacros_file ${sdir}) # assume only one spec file! rpmbuild --nodeps -bs $sdir/*.spec # return the rpmmacros file back to it's location [ -f "${backup}" ] && mv ${backup} $HOME/.rpmmacros } [ $# = 1 -o $# = 2 -o $# = 3 ] || msg_fatal "usage: rpmpatch [] []" patch_file="$1" from_rpm="$2" to_rpm="$3" patchoptions= tmpdir=${TMPDIR:-/tmp} # check the patchfile [ -n "${patch_file}" ] || msg_fatal "empty given" [ -f "${patch_file}" ] || msg_fatal "${patch_file} not found" # determine the from_rpm if [ -z ${from_rpm} ]; then # try and determine the from_rpm from the patch file # - look for #diff -uNr /tmp/postfix-2.0.16-13.RHEL3.src.rpm/postfix.spec /tmp/postfix-2.0.16-14.RHEL3.src.rpm/postfix.spec # and return postfix-2.0.16-13.RHEL3.src.rpm # this won't work if we have subdirectories in the system! from_rpm=$(awk '$1 == "diff" { print $3 }' ${patch_file} | head -1) from_rpm=$(dirname $from_rpm) from_rpm=$(basename $from_rpm) msg_info "Assuming is $from_rpm" fi # determine the to_rpm if [ -z ${to_rpm} ]; then # try and determine the to_rpm from the patch file # - look for #diff -uNr /tmp/postfix-2.0.16-13.RHEL3.src.rpm/postfix.spec /tmp/postfix-2.0.16-14.RHEL3.src.rpm/postfix.spec # and return postfix-2.0.16-14.RHEL3.src.rpm # this won't work if we have subdirectories in the system! to_rpm=$(awk '$1 == "diff" { print $4 }' ${patch_file} | head -1) to_rpm=$(dirname $to_rpm) to_rpm=$(basename $to_rpm) msg_info "Assuming is $to_rpm" fi # now check the results [ -n "${from_rpm}" ] || msg_fatal "empty " [ -f "${from_rpm}" ] || msg_fatal "${from_rpm} not found or is not a file" [ -n "${to_rpm}" ] || msg_fatal "empty rpm " [ -e ${to_rpm} ] && msg_fatal " already exists" # ready to extract from_rpm #exit # #&& to_dir=${tmpdir}/$(basename ${to_rpm}) #[ -f ${to_rpm} ] && to_dir=${tmpdir}/$(basename ${to_rpm}) #[ -d ${to_rpm} ] && to_dir=${to_rpm} #[ -n ${to_dir} ] || msg_fatal "can not find rpm ${to_rpm} (and not a directory)" # generate location of the extracted rpm [ -f ${from_rpm} ] && from_dir=${tmpdir}/$(basename ${from_rpm}) [ -d ${from_rpm} ] && from_dir=${from_rpm} [ -n ${from_dir} ] || msg_fatal "can not find rpm ${from_rpm} (and not a directory)" # extract the rpm extract_rpm ${from_rpm} ${from_dir} # patch the rpm directory cat ${patch_file} | { cd ${from_dir} patch -i- } rc=$? if [ $rc = 0 ]; then # patch went ok so attempt to rebuild src.rpm # the ${to_rpm} may not actually be created as it depends on rpmbuild build_srpm ${from_dir} ${to_rpm} rc=$? [ -f "${to_rpm}" ] || msg_fatal "${to_rpm} not found! PLEASE INVESTIGATE" fi # remove the temporary directory remove_rpmdir ${from_dir} # provide the exit result exit $rc .