#!/usr/bin/perl # # Copyright (C) 2007-2008 Canonical, Ltd., # 2011, Stefano Rivera # Author: Kees Cook # # ################################################################## # # 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 3 # 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. # # See file /usr/share/common-licenses/GPL for more details. # # ################################################################## # # This script is used to repeat a change log into an older release. It # expects that --build-tree is laid out with each Ubuntu release as a # separate directory ("feisty", "edgy", etc). # # For example, if gimp had a security update prepared for Feisty in # $TREE/feisty/gimp-2.2.13, running "dch-repeat" in # $TREE/edgy/gimp-2.2.13 would pull in the latest changelog from the Feisty # build. use strict; use warnings; use Getopt::Long; use Cwd; use File::Glob ':glob'; sub Usage { print <; # Collect changelog while ($line=) { last if ($line=~/^\S/); # Stop on next changelog entry $log.=$line; } close(LOG); return $log; } sub replace_changelog($) { my ($log) = @_; open(LOG,"debian/changelog.new") || die "Cannot write changelog\n"; my $line; while ($line=) { last if ($line =~ /^\s*$/); print NEWLOG $line || die "Changelog write failed: $!\n"; } print NEWLOG $log || die "Changelog write failed: $!\n"; # Skip log items while ($line=) { last if ($line =~ /^\S/); } print NEWLOG $line || die "Changelog write failed: $!\n"; while ($line=) { print NEWLOG $line || die "Changelog write failed: $!\n"; } close(LOG); close(NEWLOG) || die "Changelog close failed: $!\n"; rename("debian/changelog.new","debian/changelog") || die "Changelog rename failed: $!\n"; } # By default examine Cwd for target release if (!defined($opt_target_release)) { my $dir = getcwd; if ($dir =~ m#^$opt_build_tree/([^/]+)/[^/]+$#) { $opt_target_release = $1; } else { die "No --target-release used, or current directory '$dir' outside of --build-tree of '$opt_build_tree'\n"; } } warn "target-release: '$opt_target_release'\n" if ($opt_verbose); # By default, examine changelog for package if (!defined($opt_package)) { chomp($opt_package=`dpkg-parsechangelog | grep ^"Source: " | cut -d" " -f2`); if ($opt_package eq "") { die "Cannot figure out package name from changelog\n"; } } warn "package: '$opt_package\n" if ($opt_verbose); # By default, take changelog from newer release if (!defined($opt_source_release)) { if ($opt_target_release eq $devel_release) { die "No more recent release than '$devel_release' to take changelog from\n"; } foreach my $i (0 .. $#releases) { if ($releases[$i] eq $opt_target_release) { $opt_source_release = $releases[$i+1]; } } if (!defined($opt_source_release)) { die "Could not locate a newer release than '$releases[$#releases]'"; } } warn "source-release: '$opt_source_release\n" if ($opt_verbose); warn "devel-release: '$devel_release\n" if ($opt_verbose); # By default, use "security" pocket for non-devel releases if (!defined($opt_pocket)) { if ($opt_target_release eq $devel_release) { $opt_pocket = ""; } else { $opt_pocket = "security"; } } warn "pocket: '$opt_pocket'\n" if ($opt_verbose); # Source location my @dirs = grep((-d $_),bsd_glob("$opt_build_tree/$opt_source_release/$opt_package-*")); if (scalar(@dirs)==0) { die "Cannot find '$opt_build_tree/$opt_source_release/$opt_package-*'\n"; } elsif (scalar(@dirs)>1) { warn "Multiple possible source dirs, using '$dirs[0]'\n"; } warn "source dir: '$dirs[0]'\n" if ($opt_verbose); my $log = get_changelog($dirs[0]); my $args = ""; if ($opt_pocket ne "") { $args = "-s -D $opt_target_release-$opt_pocket"; } else { $args = "-i"; } system("dch $args auto-changelog")==0 || die "dch failed: $!\n"; replace_changelog($log); # Report! system("dpkg-parsechangelog"); exit(0);