summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMartin Quinson <mquinson@debian.org>2003-01-29 09:19:25 +0000
committerMartin Quinson <mquinson@debian.org>2003-01-29 09:19:25 +0000
commit9df01863feac767ebe01e99cfc597632416ca27a (patch)
tree27b023026b54e2db2a784ce86b7b075868eaf960 /lib
parent55181ac1bcf951cc22cba26dfbca813fba2b0167 (diff)
downloadquilt-9df01863feac767ebe01e99cfc597632416ca27a.tar.gz
Version 0.21 from Andreas Gruenbacher
Diffstat (limited to 'lib')
-rwxr-xr-xlib/apatch.in114
-rw-r--r--lib/backup-files.c228
-rwxr-xr-xlib/parse-patch46
-rw-r--r--lib/patchfns.in434
-rwxr-xr-xlib/rpatch.in148
-rwxr-xr-xlib/spec2series223
-rwxr-xr-xlib/touched-by-patch69
7 files changed, 883 insertions, 379 deletions
diff --git a/lib/apatch.in b/lib/apatch.in
index 0e0c366..76d9dc7 100755
--- a/lib/apatch.in
+++ b/lib/apatch.in
@@ -1,4 +1,4 @@
-#! /bin/bash
+#!/bin/bash
# This script is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
@@ -6,48 +6,85 @@
#
# See the COPYING and AUTHORS files for more details.
-if ! [ -r @LIB@/patchfns ]
+# Read in library functions
+if [ "$(type -t patch_file_name)" != function ]
then
- echo "Cannot read library @LIB@/patchfns" >&2
- exit 1
+ if ! [ -r @LIB@/patchfns ]
+ then
+ echo "Cannot read library @LIB@/patchfns" >&2
+ exit 1
+ fi
+ . @LIB@/patchfns
fi
-. @LIB@/patchfns
usage()
{
- echo "Usage: apatch [-fq] patchname"
+ echo "Usage: $0 [-fqv] patchname"
exit 1
}
+rollback_patch()
+{
+ local patch=$1 pc_file=$(pc_file_name $patch)
+ @LIB@/backup-files $silent_unless_verbose \
+ -f $pc_file -B .pc/$patch/ -r
+ rm -f $(files_in_patch $patch | sed -e 's/$/\.rej/')
+}
+
interrupt()
{
- local pc_file=$(pc_file_name $1)
- @LIB@/backup-files -s -f $pc_file -B .pc/$patch/ -r
- echo "apatch interrupted by user"
+ rollback_patch $1
+ echo "Interrupted by user; patch $patch was not applied."
exit 1
}
apply_patch()
{
+ local patch=$1
+ local patch_file=$(patch_file_name $patch)
+
+ if ! [ -s $patch_file ]
+ then
+ echo "Patch file $patch_file appears to be empty"
+ return 0
+ fi
+
+ if [ "x${patch_file:(-3)}" = "x.gz" ]
+ then
+ gzip -cd $patch_file \
+ | patch $(patch_args $patch) --no-backup-if-mismatch \
+ -E $silent
+ elif [ "x${patch_file:(-4)}" = "x.bz2" ]
+ then
+ bzip2 -cd $patch_file \
+ | patch $(patch_args $patch) --no-backup-if-mismatch \
+ -E $silent
+ else
+ patch $(patch_args $patch) --no-backup-if-mismatch \
+ -E $silent -i $patch_file
+ fi
+}
+
+apatch()
+{
local patch=$(stripit $1)
local pc_file=$(pc_file_name $patch)
- local patch_file=$(patch_file_name $patch)
local file status
- if ! [ -e "$patch_file" ]
+ trap "" SIGINT
+ if ! refresh_file_list $patch
then
- echo "No patch named $patch found."
+ echo "refresh_file_list failed"
return 1
fi
- #if is_applied "$patch"
- #then
- # echo "$patch" is already applied
- # return 1
- #fi
-
- trap "" SIGINT
- refresh_file_list $patch
+ if ! [ -e $pc_file ]
+ then
+ echo "Patch $patch appears to be empty, applied"
+ add_to_db $patch
+ return 0
+ fi
+
status=$?
if [ $status -eq 2 ]
then
@@ -57,21 +94,20 @@ apply_patch()
return 1
fi
- if ! @LIB@/backup-files -s -f $pc_file -B .pc/$patch/
+ if ! @LIB@/backup-files $silent_unless_verbose \
+ -f $pc_file -B .pc/$patch/
then
exit 1
fi
trap "interrupt $patch" SIGINT
- # (patch -b fails if a file appears more than once in a patch!)
- #patch $(patch_args $patch) --no-backup-if-mismatch \
- # -E $silent -i $patch_file
- patch $(patch_args $patch) --no-backup-if-mismatch \
- -E $silent -i $patch_file
+
+ apply_patch $patch
status=$?
+
trap "" SIGINT
- # Remember date/time of applying so that poppatch can
+ # Remember date/time of applying so that pop can
# avoid reverse applying the patch in the usual cases.
touch $pc_file
@@ -81,20 +117,20 @@ apply_patch()
if [ $status -eq 0 ]
then
echo "Applied $patch"
- rm -f $(pc_file_name $patch)~forced
+ rm -f $pc_file~refresh
else
- touch $(pc_file_name $patch)~forced
- echo "Applied $patch (forced; needs refpatch)"
+ touch $pc_file~refresh
+ echo "Applied $patch (forced; needs refresh)"
fi
else
- @LIB@/backup-files -s -f $pc_file -B .pc/$patch/ -r
- echo "Patch $patch does not apply"
+ rollback_patch $patch
+ echo "Patch $patch does not apply (enforce with -f)"
fi
trap - SIGINT
return $status
}
-options=`getopt -o fqh -- "$@"`
+options=`getopt -o fqvh -- "$@"`
if [ $? -ne 0 ]
then
@@ -112,6 +148,9 @@ do
-q)
opt_quiet=1
shift ;;
+ -v)
+ opt_verbose=1
+ shift ;;
-h)
usage -h ;;
--)
@@ -126,16 +165,15 @@ then
fi
[ -n "$opt_quiet" ] && silent=-s
+[ -z "$opt_verbose" ] && silent_unless_verbose=-s
patch=$(stripit $1)
top=$(top_patch)
-if [ -n "$top" -a -e $(pc_file_name $top)~forced ]
+if [ -n "$top" -a -e $(pc_file_name $top)~refresh ]
then
- echo "The topmost patch $top was force applied. Please run" \
- "refpatch before applying other patches."
+ echo "The topmost patch $top needs to be refreshed first."
exit 1
fi
-apply_patch $patch
-
+apatch $patch
diff --git a/lib/backup-files.c b/lib/backup-files.c
index b9f1b21..c6e0c6d 100644
--- a/lib/backup-files.c
+++ b/lib/backup-files.c
@@ -1,14 +1,29 @@
-/* backup-files.c
- Andreas Gruenbacher, 18 January 2003
+/*
+ File: backup-files.c
+
+ Copyright (C) 2003 Andreas Gruenbacher <agruen@suse.de>
+ SuSE Labs, SuSE Linux AG
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library 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
+ Library General Public License for more details.
- `patch -b' fails to back up files correctly if a file occurs
- more than once in a patch, so we use this utility instead.
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
- - catch SIGINT
- - remove backup files and directories
-*/
+ * Create backup files of a list of files similar to GNU patch. A path
+ * name prefix and suffix for the backup file can be specified with the
+ * -B and -Z options.
+ */
#include <sys/types.h>
#include <sys/stat.h>
@@ -20,10 +35,18 @@
const char *progname;
+enum { what_backup, what_restore, what_remove };
+
+const char *opt_prefix="", *opt_suffix="", *opt_file=NULL;
+int opt_silent=0, opt_what=what_backup;
+
+#define LINE_LENGTH 1024
+
+
void
usage(void)
{
- printf("Usage: %s [-B prefix] [-z suffix] [-f filelist] [-s] [-r|-x]\n"
+ printf("Usage: %s [-B prefix] [-z suffix] [-f {filelist|-}] [-s] [-r|-x] filename ...\n"
"\n"
"\tCreate hard linked backup copies of a list of files\n"
"\tread from standard input.\n"
@@ -60,26 +83,96 @@ create_parents(char *filename)
void
remove_parents(char *filename)
{
- char *f;
+ char *f, *g = NULL;
+ f = strrchr(filename, '/');
while ((f = strrchr(filename, '/')) != NULL) {
- *f = '\0';
+ if (g != NULL)
+ *g = '/';
+ g = f;
+ *f= '\0';
+
rmdir(filename);
}
+ if (g != NULL)
+ *g = '/';
}
-enum { what_backup, what_restore, what_remove };
+int
+process_file(char *file)
+{
+ char backup[LINE_LENGTH];
-#define LINE_LENGTH 1024
+ if (strlen(opt_prefix) + strlen(file) +
+ strlen(opt_suffix) >= sizeof(backup)) {
+ perror("Line buffer too small\n");
+ return 1;
+ }
+
+ snprintf(backup, sizeof(backup), "%s%s%s",
+ opt_prefix, file, opt_suffix);
+
+ if (opt_what == what_backup) {
+ int fd;
+ create_parents(backup);
+
+ unlink(backup);
+ if (link(file, backup) == 0) {
+ if (!opt_silent)
+ printf("Copying %s\n", file);
+ } else if ((fd = creat(backup, 0666)) != -1) {
+ close(fd);
+ if (!opt_silent)
+ printf("New file %s\n", file);
+ } else {
+ perror(backup);
+ return 1;
+ }
+ return 0;
+ } else if (opt_what == what_restore) {
+ struct stat st;
+ create_parents(file);
+
+ if (stat(backup, &st) != 0) {
+ perror(backup);
+ return 1;
+ }
+ if (st.st_size == 0) {
+ if (unlink(file) == 0 || errno == ENOENT) {
+ if (!opt_silent)
+ printf("Removing %s\n", file);
+ unlink(backup);
+ remove_parents(backup);
+ } else {
+ perror(file);
+ return 1;
+ }
+ } else {
+ unlink(file);
+ if (link(backup, file) == 0) {
+ if (!opt_silent)
+ printf("Restoring %s\n", file);
+ unlink(backup);
+ remove_parents(backup);
+ } else {
+ fprintf(stderr, "Could not restore "
+ "file `%s' to `%s': %s\n",
+ backup, file, strerror(errno));
+ return 1;
+ }
+ }
+ return 0;
+ } else if (opt_what == what_remove) {
+ unlink(backup);
+ remove_parents(backup);
+ return 0;
+ } else
+ return 1;
+}
int
main(int argc, char *argv[])
{
- char orig[LINE_LENGTH], *o, backup[LINE_LENGTH];
- FILE *file;
-
- const char *opt_prefix="", *opt_suffix="", *opt_file=NULL;
- int opt_silent=0, opt_what=what_backup;
int opt, status=0;
progname = argv[0];
@@ -117,95 +210,44 @@ main(int argc, char *argv[])
}
}
- if ((*opt_prefix == '\0' && *opt_suffix == '\0') || optind != argc) {
+ if ((*opt_prefix == '\0' && *opt_suffix == '\0') ||
+ (opt_file == NULL && optind == argc)) {
usage();
return 1;
}
if (opt_file != NULL) {
- if ((file = fopen(opt_file, "r")) == NULL) {
- perror(opt_file);
- return 1;
- }
- } else {
- file = stdin;
- }
-
- while (fgets(orig, sizeof(orig), file)) {
- if (strlen(opt_prefix) + strlen(orig) + strlen(opt_suffix) >=
- sizeof(backup)) {
- perror("Line buffer too small\n");
- return 1;
- }
-
- o = strchr(orig, '\0');
- if (o > orig && *(o-1) == '\n')
- *(o-1) = '\0';
- if (*orig == '\0')
- continue;
-
- snprintf(backup, sizeof(backup), "%s%s%s",
- opt_prefix, orig, opt_suffix);
+ FILE *file;
+ char line[LINE_LENGTH];
- if (opt_what == what_backup) {
- int fd;
- create_parents(backup);
-
- if (link(orig, backup) == 0) {
- if (!opt_silent)
- printf("Copying %s\n", orig);
- } else if ((fd = creat(backup, 0666)) != -1) {
- close(fd);
- if (!opt_silent)
- printf("New file %s\n", orig);
- } else {
- perror(backup);
+ if (!strcmp(opt_file, "-")) {
+ file = stdin;
+ } else {
+ if ((file = fopen(opt_file, "r")) == NULL) {
+ perror(opt_file);
return 1;
}
- } else if (opt_what == what_restore) {
- struct stat st;
+ }
- create_parents(orig);
+ while (fgets(line, sizeof(line), file)) {
+ char *l = strchr(line, '\0');
- if (stat(backup, &st) != 0) {
- perror(backup);
- status=1;
+ if (l > line && *(l-1) == '\n')
+ *(l-1) = '\0';
+ if (*line == '\0')
continue;
- }
- if (st.st_size == 0) {
- if (unlink(orig) == 0 || errno == ENOENT) {
- if (!opt_silent)
- printf("Removing %s\n", orig);
- unlink(backup);
- remove_parents(backup);
- } else {
- if (errno != ENOENT) {
- perror(orig);
- status=1;
- }
- }
- } else {
- unlink(orig);
- if (link(backup, orig) == 0) {
- if (!opt_silent)
- printf("Restoring %s\n", orig);
- unlink(backup);
- remove_parents(backup);
- } else {
- fprintf(stderr, "Could not restore "
- "file `%s' to `%s': %s\n",
- backup, orig, strerror(errno));
- status=1;
- }
- }
- } else {
- unlink(backup);
- remove_parents(backup);
+
+ if ((status = process_file(line)) != 0)
+ return status;
}
- }
- if (file != stdin) {
- fclose(file);
+ if (file != stdin) {
+ fclose(file);
+ }
+ }
+ for (; optind < argc; optind++) {
+ if ((status = process_file(argv[optind])) != 0)
+ return status;
}
return status;
diff --git a/lib/parse-patch b/lib/parse-patch
index b4dded2..9d38e36 100755
--- a/lib/parse-patch
+++ b/lib/parse-patch
@@ -1,10 +1,17 @@
#!/usr/bin/perl -w
+# This script is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# See the COPYING and AUTHORS files for more details.
+
# Extract or update a section from a combined patch + documentation +
# meta information file.
use FileHandle;
use Getopt::Long;
+use File::Temp qw(tempfile);
use strict;
my $select;
@@ -20,7 +27,9 @@ if (!GetOptions("s|select=s" => \$select,
foreach my $arg (@ARGV) {
my $fh;
- if ($arg =~ /\.gz$/) {
+ if (! -e $arg) {
+ $fh = new FileHandle("/dev/null");
+ } elsif ($arg =~ /\.gz$/) {
$fh = new FileHandle("gzip -cd $arg |");
} elsif ($arg =~ /\.bz2$/) {
$fh = new FileHandle("bzip2 -cd $arg |");
@@ -53,31 +62,43 @@ foreach my $arg (@ARGV) {
}
}
} elsif (defined $update) {
- my $fh2;
+ my ($fh2, $tempname) = tempfile("$arg.XXXXXX");
if ($arg =~ /\.gz$/) {
- $fh2 = new FileHandle("| gzip -c > $arg.parse");
+ $fh2->close();
+ if (! -e $tempname) {
+ die "File $tempname disappeared!\n";
+ }
+ $fh2 = new FileHandle("| gzip -c > $tempname");
} elsif ($arg =~ /\.bz2$/) {
- $fh2 = new FileHandle("| bzip2 -c > $arg.parse");
- } else {
- $fh2 = new FileHandle("$arg.parse", O_CREAT|O_WRONLY);
+ $fh2->close();
+ if (! -e $tempname) {
+ die "File $tempname disappeared!\n";
+ }
+ $fh2 = new FileHandle("| bzip2 -c > $tempname");
}
unless ($fh2) {
- die "$arg.parse: $!\n";
+ die "$tempname: $!\n";
}
# Copy things before updated section
+ my $last_was_newline=1; # start first section in first line
while (<$fh>) {
if (/^%(.*)/ && $1 eq $update) {
last;
}
+ $last_was_newline = ($_ eq "\n");
print $fh2 $_;
}
+ print $fh2 "\n"
+ unless ($last_was_newline);
+
# Create/replace updated section
print $fh2 "%$update\n";
while (<STDIN>) {
print $fh2 $_;
}
print $fh2 "\n";
+
# Skip obsolete section
while (<$fh>) {
if (/^%(.*)/) {
@@ -93,11 +114,14 @@ foreach my $arg (@ARGV) {
die "$arg.patch: $!\n";
}
- unlink "$arg~";
- unless (rename $arg, "$arg~") {
- die "Failed to rename $arg to $arg~: $!\n";
+ if (-e $arg) {
+ unlink "$arg~";
+ unless (rename $arg, "$arg~") {
+ die "Failed to rename $arg to $arg~: $!\n";
+ }
}
- unless (rename "$arg.parse", $arg) {
+ unless (rename $tempname, $arg) {
+ rename("$arg~", $arg);
die "Failed to rename $arg.parse to $arg: $!\n";
}
}
diff --git a/lib/patchfns.in b/lib/patchfns.in
index 63fae45..17c5b56 100644
--- a/lib/patchfns.in
+++ b/lib/patchfns.in
@@ -1,8 +1,10 @@
-debug()
-{
- #echo "$@" >&2
- true
-}
+#!/bin/bash
+
+# This script is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# See the COPYING and AUTHORS files for more details.
if [ -n "$PATCHSCRIPTS" ]
then
@@ -23,20 +25,36 @@ fi
DB=".pc/applied-patches"
+# Define where diffstat lives (may be missing)
+DIFFSTAT=/usr/bin/diffstat
+
quote_re()
{
echo "$1" | sed -e 's:\([/.+*\[\\]\):\\\1:g'
}
+#basename()
+#{
+# local path=${1%/}
+# echo "${path/*\/}"
+#}
+
+#dirname()
+#{
+# local path=${1%/}
+#}
+
patch_file_name()
{
local patch=$1
if [ -e $SERIES ]
then
- awk '/^'"$(quote_re $patch)"'(|\.patch|\.diff?)([ \t]|$)/ \
- { printf "'"$P"'patches/%s\n", $1; exit }' \
- $SERIES
+ awk '/^'"$(quote_re $patch)"'(|\.patch|\.diff?)(|\.gz|\.bz2)([ \t]|$)/ \
+ { printf "'"$P"'patches/%s\n", $1
+ exit
+ }
+ ' $SERIES
fi
}
@@ -47,13 +65,16 @@ patch_args()
if [ -e $SERIES ]
then
- awk '/^'"$(quote_re $patch)"'(|\.patch|\.diff?)([ \t]|$)/ \
+ awk '
+ /^'"$(quote_re $patch)"'(|\.patch|\.diff?)(|\.gz|\.bz2)([ \t]|$)/ \
{ if (NF >= 2)
for (i=2; i <= NF; i++)
- print $i ;
- else print "-p1" ;
- exit }' \
- $SERIES
+ print $i
+ else
+ print "-p1" ;
+ exit
+ }
+ ' $SERIES
fi
}
@@ -87,20 +108,24 @@ change_db_strip_level()
if [ -e $SERIES ]
then
- local tmp=$(mktemp /tmp/patch-scripts.XXXXXX)
- awk '/^'"$(quote_re $patch)"'(\.patch|\.diff?)([ \t]|$)/ \
- {for(i=2; i<=NF; i++)
- if ($i ~ /^-p/)
- {$i="'"$level"'" ; break}
- if (i > NF)
- $i="'"$level"'"}
- {print}' \
- $SERIES > $tmp
- if cmp $SERIES $tmp >/dev/null 2>/dev/null
+ local tmpfile=$(mktemp /tmp/patch-scripts.XXXXXX)
+ awk '
+ /^'"$(quote_re $patch)"'(\.patch|\.diff?)(|\.gz|\.bz2)([ \t]|$)/ \
+ { for(i=2; i<=NF; i++)
+ if ($i ~ /^-p/) {
+ $i="'"$level"'"
+ break
+ }
+ if (i > NF)
+ $i="'"$level"'"
+ }
+ { print }
+ ' $SERIES > $tmpfile
+ if cmp $SERIES $tmpfile >/dev/null 2>/dev/null
then
- rm -f $tmp
+ rm -f $tmpfile
else
- mv -f $tmp $SERIES
+ mv -f $tmpfile $SERIES
fi
else
return 1
@@ -115,7 +140,7 @@ patch_in_series()
then
return 1
else
- grep -q '^'"$(quote_re $patch)"'\(\|\.patch\|.diff\?\)\([ \t]\|$\)' $SERIES
+ grep -q '^'"$(quote_re $patch)"'\(\|\.patch\|.diff\?\)\(\|\.gz\|\.bz2\)\([ \t]\|$\)' $SERIES
fi
}
@@ -123,31 +148,54 @@ patch_in_series()
insert_in_series()
{
local patch=$1 patch_args=$2
- local top=$(top_patch) tmp
+ local top=$(top_patch) tmpfile
if [ -n "$patch_args" ]
then
patch_args=" $patch_args"
fi
- tmp=$(mktemp /tmp/patch-scripts.XXXXXX) || return 1
+ tmpfile=$(mktemp /tmp/patch-scripts.XXXXXX) || return 1
+ mkdir -p $(dirname $SERIES)
if [ -n "$top" ]
then
- awk ' { print }
- /^'"$(quote_re $top)"'(|\.patch|\.diff?)([ \t]|$)/ \
- { print "'"$patch$patch_args"'" }' \
- < $SERIES \
- > $tmp \
- || return 1
+ awk '
+ { print }
+ /^'"$(quote_re $top)"'(|\.patch|\.diff?)(|\.gz|\.bz2)([ \t]|$)/ \
+ { print "'"$patch$patch_args"'" }
+ ' $SERIES > $tmpfile
+ status=$?
+ if [ $status -ne 0 ]
+ then
+ rm -f $tmpfile
+ return 1
+ fi
else
- echo $patch$patch_args > $tmp
+ echo $patch$patch_args > $tmpfile
if [ -e $SERIES ]
then
- cat $SERIES >> $tmp
+ cat $SERIES >> $tmpfile
fi
fi
- mkdir -p $(dirname $SERIES)
- mv -f $tmp $SERIES
+ mv -f $tmpfile $SERIES
+}
+
+remove_from_series()
+{
+ local patch=$1
+
+ tmpfile=$(mktemp /tmp/patch-scripts.XXXXXX) || return 1
+ awk '
+ ! /^'"$(quote_re $patch)"'(|\.patch|\.diff?)(|\.gz|\.bz2)([ \t]|$)/ \
+ { print }
+ ' $SERIES > $tmpfile
+ if [ $? -eq 0 ]
+ then
+ mv -f $tmpfile $SERIES
+ else
+ rm -f $tmpfile
+ return 1
+ fi
}
pc_file_name()
@@ -170,34 +218,23 @@ backup_file_name()
done
}
-__cat_series()
+cat_series()
{
- local series=$1
- if [ -e $series ]
+ if [ -e $SERIES ]
then
sed -e '/^#/d' -e 's/^[ \t]*//' -e 's/[ \t].*//' \
- -e 's/\.patch$//' -e 's/\.diff\?//' $series
+ -e 's/\.gz$//' -e 's/\.bz2$//' \
+ -e 's/\.patch$//' -e 's/\.diff\?$//' $SERIES
else
return 1
fi
}
-cat_series()
-{
- __cat_series $SERIES
-}
-
top_patch()
{
[ -e $DB ] && tail -1 $DB
}
-die()
-{
- echo "error: $*"
- exit 1
-}
-
is_numeric()
{
echo $1 | grep -q -e '^[0-9]*$'
@@ -219,17 +256,30 @@ is_applied()
patches_before()
{
local patch=$1
- cat_series \
- | awk '$0 == "'"$patch"'" { exit }
- { print }'
+
+ if [ -n "$patch" ]
+ then
+ cat_series \
+ | awk '
+ $0 == "'"$patch"'" { exit }
+ { print }
+ '
+ fi
}
patches_after()
{
local patch=$1
- cat_series \
- | awk 'seen { print }
- $0 == "'"$patch"'" { seen=1 }'
+ if [ -n "$patch" ]
+ then
+ cat_series \
+ | awk '
+ seen { print }
+ $0 == "'"$patch"'" { seen=1 }
+ '
+ else
+ cat_series
+ fi
}
# List all patches that have been applied on top of patch $1
@@ -237,8 +287,10 @@ patches_on_top_of()
{
local patch=$1
[ -e $DB ] || return
- awk '$0 == "'"$patch"'" { seen=1 ; next }
- seen { print }' $DB
+ awk '
+ $0 == "'"$patch"'" { seen=1 ; next }
+ seen { print }
+ ' $DB
}
# Print the name of the patch that modified the file $2 next after
@@ -255,30 +307,106 @@ next_patch_for_file()
| head -1 \
| sed -e 's:^\.pc/::' -e 's:/\.pc$::'
fi
+
+ #modified_files $file -- $patches_on_top \
+ #| cut -d $'\t' -f2 \
+ #| cut -d ' ' -f1
}
-can_apply()
+# Create a list of files and the patches that modify them.
+refresh_patches_per_file()
{
- local silent
- if [ "x$1" == "x-s" ]
+ local pc_files=$(pc_file_name $(cat_series))
+ local ex_pc_files pc_file
+
+ if [ -e .pc/patches-per-file ]
then
- silent=-s
- shift
+ local needs_refresh
+ for pc_file in pc_files
+ do
+ if [ .pc/patches-per-file -ot $pc_file ]
+ then
+ needs_refresh=1
+ break
+ fi
+ done
+ if [ -z "$needs_refresh" ]
+ then
+ return 0
+ fi
fi
- local patch=$1
- patch -p1 --dry-run -f $silent -i $(patch_file_name $patch) < /dev/null
-}
-can_remove()
-{
- local silent
- if [ "x$1" == "x-s" ]
+ for pc_file in $pc_files
+ do
+ if [ -e $pc_file ]
+ then
+ ex_pc_files[${#ex_pc_files[@]}]=$pc_file
+ fi
+ done
+
+ if [ ${#ex_pc_files[@]} -eq 0 ]
then
- silent=-s
- shift
+ rm -f .pc/patches-per-file
+ return 0
fi
- local patch=$1
- patch -R -p1 --dry-run -f $silent -i $(patch_file_name $patch) < /dev/null
+
+ awk '
+ ARGIND!=saved { sub(/^.pc\//, "", FILENAME)
+ sub(/\/\.pc/, "", FILENAME)
+ saved=ARGIND
+ }
+ { if (files[$0])
+ files[$0]=files[$0] " " FILENAME
+ else
+ files[$0]=FILENAME
+ }
+ END { for (file in files)
+ printf "%s\t%s\n", file, files[file]
+ }
+ ' "${ex_pc_files[@]}" > .pc/patches-per-file
+}
+
+# For a lists of patches and a list of files, compute which patches
+# modify which files. Invoked as
+# modified_files file ... [-- patch ...]
+#
+modified_files()
+{
+ if ! refresh_patches_per_file
+ then
+ return 1
+ fi
+
+ awk '
+ BEGIN { no_files=1
+ no_patches=1
+ for (i=1; i<ARGC; i++) {
+ if (ARGV[i]=="--")
+ break
+ files[ARGV[i]]=1
+ no_files=0
+ }
+ for (i++; i<ARGC; i++) {
+ patches[ARGV[i]]=1
+ no_patches=0
+ }
+ split("", ARGV) # read from standard input
+ }
+ no_files || files[$1] {
+ if (no_patches) {
+ print
+ next
+ }
+ for (i=2; i<=NF; i++)
+ if ($i in patches) {
+ printf "%s\t%s", $1, $i
+ for (i++; i<=NF; i++)
+ if ($i in patches)
+ printf " %s", $i
+ printf "\n"
+ }
+ }
+ ' "$@" < .pc/patches-per-file
}
add_to_db()
@@ -290,10 +418,13 @@ remove_from_db()
{
local patch=$1
local tmpfile
- tmpfile=$(mktemp /tmp/patch-scripts.XXXXXX)
- grep -v "^$patch\$" $DB > $tmpfile
- mv -f $tmpfile $DB
- [ -s $DB ] || rm -f $DB
+ if tmpfile=$(mktemp /tmp/patch-scripts.XXXXXX)
+ then
+ grep -v "^$(quote_re $patch)\$" $DB > $tmpfile
+ mv -f $tmpfile $DB
+ rm -f $tmpfile
+ [ -s $DB ] || rm -f $DB
+ fi
}
stripit()
@@ -303,6 +434,7 @@ stripit()
echo $1 |
sed -e 's/^\(\.\/\)*//' \
-e 's/^'"$P"'patches\///' -e 's/^\.pc\///' \
+ -e 's/\.gz$//' -e 's/\.bz2$//' \
-e 's/\.patch$//' -e 's/\.diff\?$//'
fi
}
@@ -322,15 +454,19 @@ files_in_patch()
fi
}
-install_file_in_patch()
+touched_by_patch()
{
- local file=$1 patch=$2 bup_file=$(backup_file_name $patch $file)
-
- if ! echo $file  @LIB@/backup-file -s -B .pc/$patch/ || \
- ! echo $file >> $(pc_file_name $patch)
- then
- return 1
- fi
+ local strip=$1 patch=$2
+ cat_file $(patch_file_name $patch) \
+ | awk '
+ /^\+\+\+[ \t]/ {
+ sub(/^\+\+\+[ \t]/, "")
+ sub(/[ \t].*/, "")
+ sub(/^\/dev\/null/, "")
+ for (i=0; i<'$strip'; i++)
+ sub(/^[^\/]*\//, "")
+ print
+ }'
}
refresh_file_list()
@@ -341,40 +477,103 @@ refresh_file_list()
if ! [ -e "$patch_file" ]
then
- echo "Patch file $patch_file does not exist"
- return 1
+ return 0
fi
- if [ ! -e $pc_file -o $pc_file -ot $patch_file ]
+ if [ ! -e $pc_file -o \
+ $pc_file -ot $patch_file -o \
+ $pc_file -ot $SERIES ]
then
- mkdir -p $(dirname $pc_file)
- echo "touched-by-patch $(patch_strip_level $patch) $patch_file > $pc_file" >&2
- @LIB@/touched-by-patch -p$(patch_strip_level $patch) \
- $patch_file > $pc_file
- if [ $? -ne 0 ]
+ local tmpfile status
+ if ! mkdir -p $(dirname $pc_file) || \
+ ! tmpfile=$(mktemp /tmp/patch-scripts.XXXXXX)
+ then
+ return 1
+ fi
+
+ if [ -e $pc_file ]
+ then
+ cat $pc_file >> $tmpfile
+ fi
+ if ! touched_by_patch $(patch_strip_level $patch) \
+ $patch >> $tmpfile
then
return 1
fi
- return 2
+ sort $tmpfile | uniq > $pc_file
+ rm $tmpfile
+ return 0
fi
}
-directory_names()
+diff_file()
+{
+ local file=$1 suffix=$2 old_file=$3 new_file=$4
+ local old_file new_file
+
+ if [ ! -e "$old_file" -a ! -e "$new_file" ]
+ then
+ echo "File $file does not exist" >&2
+ return 0
+ fi
+ local old_hdr new_hdr
+ if [ $opt_strip_level -eq 0 ]
+ then
+ old_hdr=$file$suffix
+ new_hdr=$file
+ else
+ local dir=$(basename $PWD)
+ old_hdr=$dir$suffix/$file
+ new_hdr=$dir/$file
+ fi
+
+ echo Index: $new_hdr
+ diff -Nu $DIFF_OPTS $old_file $new_file |
+ fix_diff_header $old_hdr $new_hdr
+}
+
+fix_diff_header()
{
- echo "$@" \
- | awk 'BEGIN {RS=" "}
- {sub(/\/?[^\/]*$/, "") ; printf "[%s]\n", $0}
- {if (last != $0)
- print last
- last = $0}
- END {print last}'
+ local from=$1 to=$2
+ sed -e 's:^--- [^ \t]*:--- '"$from"':' \
+ -e 's:^+++ [^ \t]*:+++ '"$to"':'
}
-need_file_there()
+cat_file()
{
- if [ ! -e $1 ]
+ local filename
+
+ for filename in "$@"
+ do
+ if [ -e "$filename" ]
+ then
+ case "$filename" in
+ *.gz|*.tgz)
+ gzip -cd "$filename" ;;
+ *.bz2)
+ bzip2 -cd "$filename" ;;
+ *)
+ cat "$filename" ;;
+ esac
+ fi
+ done
+}
+
+cat_to_file()
+{
+ local filename="$1"
+
+ if [ -z "$filename" ]
then
- echo "File $1 does not exist"
- exit 1
+ cat
+ else
+ case "$filename" in
+ *.gz|*.tgz)
+ gzip -c > "$filename" ;;
+ *.bz2)
+ bzip2 -c > "$filename" ;;
+ *)
+ cat > "$filename" ;;
+ esac
fi
}
@@ -384,10 +583,15 @@ patch_description()
if [ -e "$patch_file" ]
then
- awk '/^--- / {exit}
- diff {print diff ; diff=""}
- /^diff / {diff=$0 ; next}
- {print}' \
- $patch_file
+ awk '
+ /^--- / { exit }
+ diff_line { print diff_line
+ diff_line=""
+ }
+ /^diff / { diff_line=$0
+ next
+ }
+ { print }
+ ' $patch_file
fi
}
diff --git a/lib/rpatch.in b/lib/rpatch.in
index 3c05c0a..85e8408 100755
--- a/lib/rpatch.in
+++ b/lib/rpatch.in
@@ -1,4 +1,4 @@
-#! /bin/bash
+#!/bin/bash
# This script is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
@@ -6,16 +6,20 @@
#
# See the COPYING and AUTHORS files for more details.
-if ! [ -r @LIB@/patchfns ]
+# Read in library functions
+if [ "$(type -t patch_file_name)" != function ]
then
- echo "Cannot read library @LIB@/patchfns" >&2
- exit 1
+ if ! [ -r @LIB@/patchfns ]
+ then
+ echo "Cannot read library @LIB@/patchfns" >&2
+ exit 1
+ fi
+ . @LIB@/patchfns
fi
-. @LIB@/patchfns
usage()
{
- echo "Usage: rpatch [-fRq] patchname"
+ echo "Usage: $0 [-fRq] patchname"
exit 1
}
@@ -52,10 +56,17 @@ verify_removal()
files_may_have_changed()
{
local patch=$1 file
+ local patch_file=$(patch_file_name $patch)
local pc_file=$(pc_file_name $patch)
+
+ if ! [ -e $pc_file ]
+ then
+ return 1
+ fi
+
local apply_ts=$(date -r $pc_file '+%s') ts
- if [ $pc_file -ot $(patch_file_name $patch) ]
+ if [ -e "$patch_file" -a $pc_file -ot "$patch_file" ]
then
return 0
fi
@@ -76,25 +87,60 @@ files_may_have_changed()
return 1
}
-abort_patch()
+rollback_patch()
{
- local pc_file=$(pc_file_name $1)
- @LIB@/backup-files -s -f $pc_file -z ~rpatch -r
- exit 1
+ local patch=$1 pc_file=$(pc_file_name $patch)
+ @LIB@/backup-files $silent_unless_verbose \
+ -f $pc_file -z ~rpatch -r
+ rm -f $(files_in_patch $patch | sed -e 's/$/\.rej/')
}
interrupt()
{
local patch=$1
- abort_patch $patch
- echo "rpatch interrupted by user"
+ rollback_patch $patch
+ echo "Interrupted by user; patch $patch was not removed."
exit 1
}
-do_remove()
+reverse_patch()
+{
+ local patch=$1
+ local patch_file=$(patch_file_name $patch)
+
+ if ! [ -s $patch_file ]
+ then
+ echo "Patch file $patch_file appears to be empty"
+ return 0
+ fi
+
+ if [ "x${patch_file:(-3)}" = "x.gz" ]
+ then
+ gzip -cd $patch_file \
+ | patch $(patch_args $patch) --no-backup-if-mismatch \
+ -R -E $silent
+ elif [ "x${patch_file:(-4)}" = "x.bz2" ]
+ then
+ bzip2 -cd $patch_file \
+ | patch $(patch_args $patch) --no-backup-if-mismatch \
+ -R -E $silent
+ else
+ patch $(patch_args $patch) --no-backup-if-mismatch \
+ -R -E $silent -i $patch_file
+ fi
+}
+
+rpatch()
{
local patch=$1 pc_file=$(pc_file_name $patch)
+ if ! [ -e $pc_file ]
+ then
+ echo "Patch $patch appears to be empty, removed"
+ remove_from_db $patch
+ return 0
+ fi
+
trap "" SIGINT
if [ -n "$opt_force" ] || \
( [ -z "$opt_remove" ] && ! files_may_have_changed $patch )
@@ -106,44 +152,53 @@ do_remove()
@LIB@/backup-files $silent -f $pc_file -B .pc/$patch/ -r
status=$?
remove_from_db $patch
- rm -f $(pc_file_name $patch)~forced
- return $status
+ rm -f $pc_file~refresh
+ if [ $status != 0 ]
+ then
+ exit $status
+ fi
else
- local patch_file=$(patch_file_name $patch)
- if ! [ -e "$patch_file" ]
+ if ! @LIB@/backup-files $silent_unless_verbose \
+ -f $pc_file -z ~rpatch
then
- echo "No patch named $patch found."
+ echo "Failed to create temporary files" >&2
return 1
fi
trap "interrupt $patch" SIGINT
- #if [ ! -e $patch_file ] || grep -q '^%patch$' $patch_file
- #then
- # @LIB@/parse-patch -s patch $patch_file \
- # | patch $(patch_args $patch) --no-backup-if-mismatch \
- # -R -E $silent
- #else
- patch $(patch_args $patch) --no-backup-if-mismatch \
- -R -E $silent -i $patch_file
- #fi
+
+ reverse_patch $patch
status=$?
+
trap "" SIGINT
+
if [ $status -eq 0 ] && verify_removal $patch
then
- @LIB@/backup-files -s -f $pc_file -z ~rpatch -x
- @LIB@/backup-files -s -f $pc_file -B .pc/$patch/ -x
+ @LIB@/backup-files $silent_unless_verbose \
+ -f $pc_file -z ~rpatch -x
+ @LIB@/backup-files $silent_unless_verbose \
+ -f $pc_file -B .pc/$patch/ -x
remove_from_db $patch
else
- @LIB@/backup-files -s -f $pc_file -z ~rpatch -r
- echo "Patch $patch does not remove cleanly"
+ rollback_patch $patch
+ echo "Patch $patch does not remove (enforce with -f)"
return 1
fi
fi
trap - SIGINT
+
+ local top=$(top_patch) where
+ if [ -z "$top" ]
+ then
+ where="no patches applied"
+ else
+ where="now at $top"
+ fi
+ echo "Removed $patch, $where"
}
-options=`getopt -o fRqh -- "$@"`
+options=`getopt -o fRqvh -- "$@"`
if [ $? -ne 0 ]
then
@@ -165,6 +220,9 @@ do
-q)
opt_quiet=1
shift ;;
+ -v)
+ opt_verbose=1
+ shift ;;
-h)
usage -h ;;
--)
@@ -180,29 +238,13 @@ fi
patch=$(stripit $1)
[ -n "$opt_quiet" ] && silent=-s
+[ -z "$opt_verbose" ] && silent_unless_verbose=-s
top=$(top_patch)
-if [ -n "$top" -a -e $(pc_file_name $top)~forced -a -z "$opt_force" ]
+if [ -n "$top" -a -e $(pc_file_name $top)~refresh -a -z "$opt_force" ]
then
- echo "The topmost patch $top was force applied. Please run" \
- "refpatch before removing it."
+ echo "The topmost patch $top needs to be refreshed first."
exit 1
fi
-#if is_applied "$patch"
-#then
- do_remove "$patch" || exit 1
-#else
-# echo "Patch $patch is not applied"
-# exit 1
-#fi
-
-top=$(top_patch)
-if [ -z "$top" ]
-then
- where="no patches applied"
-else
- where="now at $top"
-fi
-echo "Removed $patch, $where"
-
+rpatch "$patch" || exit 1
diff --git a/lib/spec2series b/lib/spec2series
new file mode 100755
index 0000000..685f8e0
--- /dev/null
+++ b/lib/spec2series
@@ -0,0 +1,223 @@
+#!/bin/bash
+
+# This script is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# See the COPYING and AUTHORS files for more details.
+
+# defaults
+debug=0
+specfile=""
+outfile=""
+
+function usage() {
+cat <<EOF
+Usage: quilt spec2series [ options ] specfile
+
+-h print this text
+-d debug mode (prints lots additional info
+ as comments into the output file)
+-o <file>
+ specify output file, stdout if unspecified
+
+EOF
+}
+
+# parse args
+while test "$1" != ""; do
+ case "$1" in
+ -h | --help)
+ usage; exit 0
+ ;;
+ -d | --debug)
+ debug=1; shift
+ ;;
+ -o | --outfile)
+ outfile="$2"; shift; shift
+ ;;
+ *)
+ specfile="$1"
+ break;
+ ;;
+ esac
+done
+
+if test ! -f "$specfile"; then
+ usage
+ exit 1
+fi
+
+# get absolute patch for specfile location
+specdir=`dirname $specfile`
+specfile=`basename $specfile`
+case "$specdir" in
+ .) specdir="`pwd`"
+ ;;
+ /*) # nothing
+ ;;
+ *) specdir="`pwd`/$specdir"
+ ;;
+esac
+
+# create tmp work dir
+WORK="${TMPDIR-/tmp}/rpmlog-$$"
+mkdir -p "$WORK" || exit 1
+trap 'rm -rf "$WORK"' EXIT
+mkdir -p "$WORK/build"
+mkdir -p "$WORK/bin"
+
+# create md5 sums, also for uncompressed files
+echo -n "### md5: " >&2
+(cd $specdir; for file in /dev/null *; do
+ case "$file" in
+ ready | bigpack | MD5SUMS | MD5SUMS.meta | *.spec | *.changes)
+ continue
+ ;;
+ esac
+ type="`file -b $file | cut -d" " -f1`"
+ case "$type" in
+ compress*)
+ echo -n "z" >&2
+ set -- `zcat $file | md5sum`
+ echo "$1 zcat ${file}"
+ ;;
+ gzip)
+ echo -n "g" >&2
+ set -- `zcat $file | md5sum`
+ echo "$1 zcat ${file}"
+ ;;
+ bzip2)
+ echo -n "b" >&2
+ set -- `bzcat $file | md5sum`
+ echo "$1 bzcat ${file}"
+ ;;
+ esac
+ echo -n "." >&2
+ set -- `md5sum < $file`
+ echo "$1 cat ${file}"
+done) > $WORK/md5sum
+echo " done" >&2
+
+# prepare rpm dir fixups and hooks
+RPM="rpm --rcfile=/usr/lib/rpm/rpmrc:$WORK/rpmrc"
+PATH="$WORK/bin:$PATH"
+grep ^macrofiles /usr/lib/rpm/rpmrc \
+ | sed -e "/macrofiles/s|$|:$WORK/rpmmacros|" \
+ > $WORK/rpmrc
+cat <<-EOF > "$WORK/rpmmacros"
+ %_sourcedir $specdir
+ %_specdir $specdir
+ %_builddir $WORK/build
+EOF
+
+# wrapper script for patch and tar
+cat <<-'EOF' > "$WORK/bin/patch"
+ #!/bin/sh
+
+ # save stuff for log
+ unpackcmd=`basename $0`
+ unpackdir=`pwd`
+ unpackargs="$*"
+ uncompress="false"
+ unpackfile="[oops]"
+
+ # sort of progress bar
+ case $unpackcmd in
+ tar) echo -n "t" >&2;;
+ patch) echo -n "p" >&2;;
+ *) echo -n "?" >&2;;
+ esac
+
+ # find real binary
+ realcmd=""
+ test -x "/bin/$unpackcmd" && realcmd="/bin/$unpackcmd"
+ test -x "/usr/bin/$unpackcmd" && realcmd="/usr/bin/$unpackcmd"
+ test "$realcmd" = "" && exit 1
+
+ # put data into tmpfile, exec real cmd, return on failure
+ WORK=`dirname $RPM_BUILD_DIR`
+ cat > "$WORK/data"
+ if test -x /bin/$unpackcmd; then
+ cmddir="/bin"
+ fi
+ $realcmd $* < "$WORK/data"
+ retval="$?"
+ test "$retval" != "0" && exit $retval
+
+ # find original data file by md5sum
+ set -- `md5sum < "$WORK/data"`
+ unpackfile="[$1]"
+ set -- `cat "$WORK/md5sum"`
+ while test "$1" != ""; do
+ if test "[$1]" = "$unpackfile"; then
+ uncompress="$2"
+ unpackfile="$3"
+ break
+ fi
+ shift
+ done
+
+ # print results
+ unpackdir=`echo $unpackdir | sed -e "s|$RPM_BUILD_DIR|BUILD|"`
+ echo -n "# log: [$unpackdir] $uncompress $unpackfile" >>$WORK/cmdlog
+ echo " | $unpackcmd $unpackargs" >>$WORK/cmdlog
+ if test "$unpackcmd" = "patch" -a \
+ -f "$RPM_SOURCE_DIR/$unpackfile"; then
+ patchdir="${unpackdir#BUILD/}"
+ if test ! -f "$WORK/patchdir"; then
+ echo -n $patchdir > $WORK/patchdir
+ fi
+ if test "`cat $WORK/patchdir`" = "$patchdir"; then
+ level=`echo $unpackargs | tr " " "\n" | grep ^-p`
+ echo "$unpackfile $level" >> $WORK/patchlog
+ fi
+ fi
+ if test "$unpackcmd" = "tar" -a \
+ -f "$RPM_SOURCE_DIR/$unpackfile"; then
+ echo -n "# Source: $unpackfile" >>$WORK/tarlog
+ if test "$unpackdir" != "BUILD"; then
+ echo -n " -C ${unpackdir#BUILD/}" >>$WORK/tarlog
+ fi
+ echo "" >>$WORK/tarlog
+ fi
+EOF
+chmod 755 "$WORK/bin/patch"
+ln -s patch "$WORK/bin/tar"
+
+# let rpm do all the dirty specfile stuff ...
+echo -n "### rpm: " >&2
+touch $WORK/patchlog
+$RPM --nodeps --quiet -bp "$specdir/$specfile" </dev/null
+echo " done" >&2
+
+# print results saved by the wrapper script
+(
+ # header
+ echo "# Patch series file for quilt, created by $0"
+ echo "#"
+ echo "# Sourcedir: $specdir"
+ echo "# Specfile: $specfile"
+ if test -f $WORK/patchdir; then
+ echo "# Patchdir: `cat $WORK/patchdir`"
+ fi
+ echo "#"
+
+ # additional info for trouble shooting
+ if test "$debug" = "1"; then
+ cat $WORK/md5sum | sed -e 's/^/# md5: /'
+ echo "#"
+
+ test -f $WORK/cmdlog && cat $WORK/cmdlog && echo "#"
+ fi
+
+ # list tarballs + patches
+ test -f $WORK/tarlog && cat $WORK/tarlog && echo "#"
+ test -f $WORK/patchlog && cat $WORK/patchlog
+)|(
+ if test "$outfile" != ""; then
+ cat > "$outfile"
+ else
+ cat
+ fi
+)
diff --git a/lib/touched-by-patch b/lib/touched-by-patch
deleted file mode 100755
index bdfc296..0000000
--- a/lib/touched-by-patch
+++ /dev/null
@@ -1,69 +0,0 @@
-#! /bin/bash
-# Extract names of new files from a patch, print them out
-
-# This script is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# See the COPYING and AUTHORS files for more details.
-
-usage()
-{
- echo "Usage: touched-by-patch [-p num] patchname"
- exit 1
-}
-
-options=`getopt -o p:h -- "$@"`
-
-if [ $? -ne 0 ]
-then
- usage
-fi
-
-eval set -- "$options"
-
-while true
-do
- case "$1" in
- -p)
- opt_p=$2
- shift 2 ;;
- -h)
- usage ;;
- --)
- shift
- break ;;
- esac
-done
-
-if [ $# -ne 1 ]
-then
- usage
-fi
-
-patch_file=$1
-[ -z "$opt_p" ] && opt_p=1
-
-case "$patch_file" in
-*.bz2)
- command="bzip2 -cd $patch_file";;
-*.gz)
- command="gzip -cd $patch_file";;
-*)
- command="cat $patch_file";;
-esac
-
-# Neither `+++' nor `---' works for all patches; patch looks at the
-# file system to determine which file name to use.
-
-eval $command \
-| awk '/^\+\+\+[ \t]/ {
- sub(/^\+\+\+[ \t]/, "")
- sub(/[ \t].*/, "")
- sub(/^\/dev\/null/, "")
- for (i=0; i<'$opt_p'; i++)
- sub(/^[^\/]*\//, "")
- print
- }' \
-| sort \
-| uniq