#!/bin/sh # # mkpatch 1.1 # # Creates a more-or-less self-contained patch package. # # Copyright (c) Alfredo K. Kojima # # # Syntax: mkpatch old_tree new_tree patch_name # # If a file named mkp.stuff is found in the current directory, it # will be used to extract special handling cases. Each directive must # be placed in a line of the file and the arguments must be separated # by a single space. The currently supported directives are: # # DONTDIFF # Do not use diff in the specified file, replacing the file instead. # The path must exclude the top directory and the path must be # valid from both trees. # It will handle special cases of files that diff thinks are text # files, but actually are not, like XPM files created by stupid, # brain damaged, moron XV. # # Example mkp.stuff file: # DONTDIFF icons/somthing.xpm # DONTDIFF icons/smthingelse.xpm # # # The resulting patch pack will be relatively big (if compared to things # produced by xdelta and others), but it will be self-contained and # hopefully smaller than the whole source tree. # # You MUST run mkpatch from a directory above old_tree and new_tree. # Example: # If newTree and oldTree are located in /tmp # cd /tmp # mkpatch oldTree newTree old_to_new # # File names cannot contain the character # or spaces # if test ! $# = 3 ; then echo "$0:read the script for the syntax." exit 1 fi istext() { a=`file $1|grep text` if test "x$a" = "x"; then return 0 else return 1 fi } put_header() { cat << 'EOF' |sed -e "s#TMP#$TMP#" -e "s#OTREE#$OTREE#"\ -e "s#NTREE#$NTREE#" > $1 #!/bin/sh # # Patch package to upgrade OTREE to NTREE # EOF if [ $# -gt 1 ]; then echo $2 >> $1 fi echo "unalias rm" >> $1 } ########################## check_removed_files() { files=`grep "Only in $OTREE" $TMP/tdiff|sed -e "s#Only in $OTREE##" -e "s#: #/#" -e "s#//#/#"` put_header $TMP/delfiles "# Remove obsolete files" #.................. cat << EOF >> $TMP/delfiles echo "Files that are not needed anymore will be removed now." echo "Do you wish to proceed? [y]" read foo if [ "$foo" = "n" ]; then exit 0 fi EOF #................... echo "Obsoleted Files:" for i in $files; do echo $OTREE/$i echo "echo \"Removing ../$i\"" >> $TMP/delfiles if [ -d $OTREE/$i ]; then echo "rm -rf ../$i" >> $TMP/delfiles else echo "rm ../$i" >> $TMP/delfiles fi done chmod +x $TMP/delfiles } ######################### check_new_files() { files=`grep "Only in $NTREE" $TMP/tdiff|sed -e "s#Only in $NTREE#../#" -e "s#: #/#" -e "s#//#/#"` put_header $TMP/newfiles "# Copy new files" echo "# Table of internal file names to real file names" >> $TMP/newfiles index=0 dindex=0 mkdir $TMP/files echo "New Files:" for i in $files; do name=`basename $i` src=`echo $i|sed -e "s#..#$NTREE#"` file=`echo $i|sed -e "s#../##"` echo $src if [ -d $src ]; then dst="dir$dindex" (dir=`pwd`;cd $NTREE;tar cf $dir/$TMP/files/$dst.tar $file) echo "$dst=\"$file\"" >> $TMP/newfiles dindex=`expr $dindex + 1` else dst="file$index" cp $src $TMP/files/$dst echo "$dst=\"$file\"" >> $TMP/newfiles index=`expr $index + 1` fi done echo "filecount=$index" >> $TMP/newfiles echo "dircount=$dindex" >> $TMP/newfiles #.......... cat << 'EOF' |sed -e "s#TMP#$TMP#" -e "s#OTREE#$OTREE#"\ -e "s#NTREE#$NTREE#" >> $TMP/newfiles #create new directories index=0 mkdir tmpdir while [ $index -lt $dircount ]; do fname="dir$index" eval origname=$"$fname" echo "Recreating directory ../$origname" (cd tmpdir; tar xf ../files/$fname.tar) mv tmpdir/$origname ../$origname index=`expr $index + 1` done rm -fr tmpdir #copy files index=0 while [ $index -lt $filecount ]; do fname="file$index" eval origname=$"$fname" echo "Copying file ../$origname" cp files/$fname ../$origname index=`expr $index + 1` done EOF #.......... chmod +x $TMP/newfiles } ##################### check_binary_changes() { files=`grep "Binary files" $TMP/bindiff|cut -d\ -f5` files=`echo $files` put_header $TMP/updbinfiles "# Replace changed binary files" echo "# Table of internal file names to real file names" >> $TMP/updbinfiles for i in $no_diff; do files="$files $NTREE/$i" done index=0 echo "Binary files changed:" for i in $files; do fname="changed$index" oname=`echo $i|sed -e "s#$NTREE##" -e "s#^/##"` cp $i $TMP/files/$fname echo $i echo "$fname=\"$oname\"" >> $TMP/updbinfiles index=`expr $index + 1` done echo "filecount=$index" >> $TMP/updbinfiles #.......... cat << 'EOF' |sed -e "s#TMP#$TMP#" -e "s#OTREE#$OTREE#"\ -e "s#NTREE#$NTREE#" >> $TMP/updbinfiles index=0 while [ $index -lt $filecount ]; do fname="changed$index" eval origname=$"$fname" echo "Replacing file ../$origname" rm ../$origname cp files/$fname ../$origname index=`expr $index + 1` done EOF #.......... chmod +x $TMP/updbinfiles } ##################### check_text_changes() { echo "diff'ing trees..." diff -rq $OTREE $NTREE > $TMP/tdiff tmp=`egrep "^Files" $TMP/tdiff|cut -d\ -f2|sed -e "s#$OTREE/##"` files="" # remove excluded files for i in $tmp; do ok=1 for j in $no_diff; do if test "$i" = "$j"; then ok=0 break fi done if [ $ok = 1 ]; then files="$files $i" fi done touch $TMP/diff touch $TMP/bindiff # diff remaining files for f in $files; do diff -rc $OTREE/$f $NTREE/$f >> $TMP/tmp foo=`egrep "^Binary" $TMP/tmp` if test "x$foo" = "x"; then cat $TMP/tmp >> $TMP/diff else cat $TMP/tmp >> $TMP/bindiff fi rm -fr $TMP/tmp done } ################# main stripslash() { echo $1|sed -e 's#/$##' } OTREE=`stripslash $1` NTREE=`stripslash $2` OUTPUT=$3 TMP=$OUTPUT.patchd rm -fr $TMP mkdir $TMP if [ -f mkp.stuff ]; then echo "Using mkp.stuff file..." no_diff=`grep DONTDIFF mkp.stuff|cut -d\ -f2` no_diff=`echo $no_diff` fi #.................... cat << 'EOF' |sed -e "s#TMP#$TMP#" -e "s#OTREE#$OTREE#" -e "s#NTREE#$NTREE#" \ > $TMP/runme #!/bin/sh # # Patch package to upgrade OTREE to NTREE # # Automatically generated by mkpatch # # Move the TMP directory to inside NTREE # and run this script. # TARGET_TREE=OTREE savedir=`pwd` cd .. dir=`pwd` dir=`basename $dir` cd $savedir if test "$USER" = root; then echo "Do not run this script as the root user" exit 1 fi if test "$dir" != "$TARGET_TREE"; then echo "You must move the \"TMP\" directory to inside the " echo "\"$TARGET_TREE\" directory before running this script." exit 1 fi echo "################################" echo "Removing Obsolete Files" echo "################################" ./delfiles echo echo "################################" echo "Copying New Files" echo "################################" ./newfiles echo echo "################################" echo "Replacing modified binary files" echo "################################" ./updbinfiles echo echo "################################" echo "Patching modified text files" echo "################################" cd .. patch -p1 -s < $savedir/diff echo "Patching finished." EOF #.................... cat << 'EOF' |sed -e "s#TMP#$TMP#" -e "s#OTREE#$OTREE#" -e "s#NTREE#$NTREE#" \ > $TMP/README This patch package will upgrade OTREE to NTREE. You must unpack it inside the OTREE directory or it will not work. This patch can only be applied over a clean OTREE distribution. To apply, just type (followed by a Return, of course): ./runme EOF #.................... #.................... cat << 'EOF' > $TMP/cleanup #!/bin/sh # # Remove .orig files # find .. -name \*.orig -exec rm {} \; EOF chmod +x $TMP/cleanup #.................... # this must be the first function called check_text_changes check_removed_files check_new_files check_binary_changes rm -f $TMP/tdiff rm -f $TMP/bindiff chmod +x $TMP/runme echo "Do you want to add something to the README file? [n]" read foo if [ "$foo" = "y" ]; then vi $TMP/README fi rm -f $OUTPUT.tar.gz tar czf $OUTPUT.tar.gz $TMP rm -fr $TMP echo "Patch pack $OUTPUT.tar.gz successfully created."