Thu, 04 Oct 2012 20:30:05 +0200
Correct out of date build configuration, porting to Solaris 11 network
link infrastructure and new libpcap logic. This additionally allows for
device drivers in subdirectories of /dev. Correct packaged nmap
personalities and signatures to work out of the box. Finally, hack
arpd logic to properly close sockets and quit on TERM by repeating
signaling in the run command script. Sadly, all this fails to correct
the run time behaviour of honeyd which fails to bind to the IP layer.
michael@428 | 1 | ## |
michael@428 | 2 | ## openpkg dev -- OpenPKG Package Development Tool |
michael@428 | 3 | ## Copyright (c) 2008-2012 OpenPKG GmbH <http://openpkg.com/> |
michael@428 | 4 | ## |
michael@428 | 5 | ## This software is property of the OpenPKG GmbH, DE MUC HRB 160208. |
michael@428 | 6 | ## All rights reserved. Licenses which grant limited permission to use, |
michael@428 | 7 | ## copy, modify and distribute this software are available from the |
michael@428 | 8 | ## OpenPKG GmbH. |
michael@428 | 9 | ## |
michael@428 | 10 | ## THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED |
michael@428 | 11 | ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
michael@428 | 12 | ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
michael@428 | 13 | ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR |
michael@428 | 14 | ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
michael@428 | 15 | ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
michael@428 | 16 | ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
michael@428 | 17 | ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
michael@428 | 18 | ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
michael@428 | 19 | ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
michael@428 | 20 | ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
michael@428 | 21 | ## SUCH DAMAGE. |
michael@428 | 22 | ## |
michael@428 | 23 | |
michael@428 | 24 | require 5; |
michael@428 | 25 | |
michael@428 | 26 | # OpenPKG instance prefix and RPM |
michael@428 | 27 | my $openpkg_prefix = $ENV{'OPENPKG_PREFIX'}; |
michael@428 | 28 | delete $ENV{'OPENPKG_PREFIX'}; |
michael@428 | 29 | |
michael@428 | 30 | # program identification |
michael@428 | 31 | my $prog_name = "dev"; |
michael@428 | 32 | my $prog_vers = "20100111"; |
michael@428 | 33 | |
michael@428 | 34 | # home-brewn getopt(3) style option parser |
michael@428 | 35 | sub getopts ($$@) { |
michael@428 | 36 | my ($opt_spec, $opts, @argv_orig) = @_; |
michael@428 | 37 | my (%optf) = map { m/(\w)/; $1 => $_ } $opt_spec =~ m/(\w:|\w)/g; |
michael@428 | 38 | my (@argv, $optarg); |
michael@428 | 39 | |
michael@428 | 40 | foreach (@argv_orig) { |
michael@428 | 41 | if (@argv) { |
michael@428 | 42 | push @argv, $_; |
michael@428 | 43 | } elsif (defined $optarg) { |
michael@428 | 44 | if (exists $opts->{$optarg}) { |
michael@428 | 45 | $opts->{$optarg} .= " $_"; |
michael@428 | 46 | } else { |
michael@428 | 47 | $opts->{$optarg} = $_; |
michael@428 | 48 | } |
michael@428 | 49 | $optarg = undef; |
michael@428 | 50 | } elsif (!/^[-]/) { |
michael@428 | 51 | push @argv, $_; |
michael@428 | 52 | } else { |
michael@428 | 53 | while (/^\-(\w)(.*)/) { |
michael@428 | 54 | if (exists $optf{$1}) { |
michael@428 | 55 | if (length($optf{$1}) > 1) { |
michael@428 | 56 | if ($2 ne '') { |
michael@428 | 57 | if (exists $opts->{$1}) { |
michael@428 | 58 | $opts->{$1} .= " $2"; |
michael@428 | 59 | } else { |
michael@428 | 60 | $opts->{$1} = $2; |
michael@428 | 61 | } |
michael@428 | 62 | } else { |
michael@428 | 63 | $optarg = $1; |
michael@428 | 64 | } |
michael@428 | 65 | last; |
michael@428 | 66 | } else { |
michael@428 | 67 | $opts->{$1} = 1; |
michael@428 | 68 | } |
michael@428 | 69 | } else { |
michael@428 | 70 | warn "openpkg:$prog_name:WARNING: unknown option $_\n"; |
michael@428 | 71 | } |
michael@428 | 72 | $_ = "-$2"; |
michael@428 | 73 | } |
michael@428 | 74 | } |
michael@428 | 75 | } |
michael@428 | 76 | if (defined $optarg) { |
michael@428 | 77 | warn "openpkg:$prog_name:WARNING: option $optarg requires an argument\n"; |
michael@428 | 78 | } |
michael@428 | 79 | foreach my $opt (keys %optf) { |
michael@428 | 80 | if (not exists $opts->{$opt}) { |
michael@428 | 81 | $opts->{$opt} = (length($optf{$opt}) > 1 ? "" : 0); |
michael@428 | 82 | } |
michael@428 | 83 | } |
michael@428 | 84 | return @argv; |
michael@428 | 85 | } |
michael@428 | 86 | |
michael@428 | 87 | # determine reasonable temporary directory |
michael@428 | 88 | my $tmpdir = ($ENV{"TMPDIR"} || "/tmp"); |
michael@428 | 89 | $tmpdir .= "/openpkg-$prog_name-$$"; |
michael@428 | 90 | my $rc = system("umask 022; $openpkg_prefix/lib/openpkg/shtool mkdir -f -p -m 755 $tmpdir || exit $?"); |
michael@428 | 91 | if ($rc != 0) { |
michael@428 | 92 | die "failed to create temporary directory: $tmpdir"; |
michael@428 | 93 | } |
michael@428 | 94 | |
michael@428 | 95 | # parse command line options |
michael@428 | 96 | my $opts = {}; |
michael@428 | 97 | @ARGV = getopts("h", $opts, @ARGV); |
michael@428 | 98 | |
michael@428 | 99 | # usage sanity check and usage help |
michael@428 | 100 | sub usage { |
michael@428 | 101 | my ($rc) = @_; |
michael@428 | 102 | my $usage = |
michael@428 | 103 | "openpkg:$prog_name:USAGE: openpkg dev <command> [<options>]\n"; |
michael@428 | 104 | if ($rc == 0) { |
michael@428 | 105 | print STDOUT $usage; |
michael@428 | 106 | } |
michael@428 | 107 | else { |
michael@428 | 108 | print STDERR $usage; |
michael@428 | 109 | } |
michael@428 | 110 | exit($rc); |
michael@428 | 111 | } |
michael@428 | 112 | if ($opts->{"h"}) { |
michael@428 | 113 | usage(0); |
michael@428 | 114 | } |
michael@428 | 115 | if (@ARGV == 0) { |
michael@428 | 116 | usage(1); |
michael@428 | 117 | } |
michael@428 | 118 | |
michael@428 | 119 | # command map |
michael@428 | 120 | my $map = { |
michael@428 | 121 | "unpack " => { -alias => qr/^(up|ex)$/, -key => "x" }, |
michael@428 | 122 | "edit\n" => { -alias => qr/^(ed|vi)$/, -key => "v" }, |
michael@428 | 123 | "build -s track\n" => { -alias => qr/^(bt|tr)$/, -key => "t" }, |
michael@428 | 124 | "build -s fetch\n" => { -alias => qr/^(bf|fe)$/, -key => "f" }, |
michael@428 | 125 | "build\n" => { -alias => qr/^(ba|bu)$/, -key => "b" }, |
michael@428 | 126 | "build -s prep\n" => { -alias => qr/^bp$/, -key => "1" }, |
michael@428 | 127 | "build -s compile\n" => { -alias => qr/^bc$/, -key => "2" }, |
michael@428 | 128 | "build -s install\n" => { -alias => qr/^bi$/, -key => "3" }, |
michael@428 | 129 | "build -s binary\n" => { -alias => qr/^bb$/, -key => "4" }, |
michael@428 | 130 | "build -s source\n" => { -alias => qr/^bs$/, -key => "s" }, |
michael@428 | 131 | "peek\n" => { -alias => qr/^pe$/, -key => "p" }, |
michael@428 | 132 | "diff\n" => { -alias => qr/^di$/, -key => "d" }, |
michael@428 | 133 | "install\n" => { -alias => qr/^in(?:st)?$/, -key => "i" }, |
michael@428 | 134 | "erase\n" => { -alias => qr/^er$/, -key => "e" }, |
michael@428 | 135 | "lint\n" => { -alias => qr/^li$/, -key => "l" }, |
michael@428 | 136 | "release " => { -alias => qr/^rel?$/, -key => "r" }, |
michael@428 | 137 | }; |
michael@428 | 138 | |
michael@428 | 139 | # dispatch command |
michael@428 | 140 | my $cmd = shift(@ARGV); |
michael@428 | 141 | foreach my $c (keys %{$map}) { |
michael@428 | 142 | my $a = $map->{$c}->{-alias}; |
michael@428 | 143 | if ($cmd =~ $a) { |
michael@428 | 144 | $c =~ s/\n$//; |
michael@428 | 145 | my @args = split(/\s+/, $c); |
michael@428 | 146 | $cmd = shift(@args); |
michael@428 | 147 | unshift(@ARGV, @args); |
michael@428 | 148 | print STDOUT "\033[34m\$ opd $cmd " . join(" ", map { |
michael@428 | 149 | my $x = $_; |
michael@428 | 150 | $x =~ s/"/\\"/g; |
michael@428 | 151 | $x =~ s/^(.*[ \t].*)$/"$1"/; |
michael@428 | 152 | $x |
michael@428 | 153 | } @ARGV) . "\033[0m\n"; |
michael@428 | 154 | } |
michael@428 | 155 | } |
michael@428 | 156 | my $func = "cmd_$cmd"; |
michael@428 | 157 | if (not defined(&$func)) { |
michael@428 | 158 | print STDERR "openpkg:$prog_name:ERROR: invalid command \"$cmd\"\n"; |
michael@428 | 159 | usage(1); |
michael@428 | 160 | } |
michael@428 | 161 | my $rc = &$func($opts, @ARGV); |
michael@428 | 162 | exit($rc); |
michael@428 | 163 | |
michael@428 | 164 | # execute a shell command |
michael@428 | 165 | sub run { |
michael@428 | 166 | my ($cmd) = @_; |
michael@428 | 167 | print STDOUT "\033[34m\$ $cmd\033[0m\n"; |
michael@428 | 168 | my $rc = system($cmd); |
michael@428 | 169 | return $rc; |
michael@428 | 170 | } |
michael@428 | 171 | |
michael@428 | 172 | # determine path to package specification |
michael@428 | 173 | sub specfile { |
michael@428 | 174 | my $specfile = (glob("*.spec"))[0]; |
michael@428 | 175 | if (not defined $specfile) { |
michael@428 | 176 | $specfile = (glob("src/*.spec"))[0]; |
michael@428 | 177 | if (not defined $specfile) { |
michael@428 | 178 | $specfile = (glob("*/*.spec"))[0]; |
michael@428 | 179 | if (not defined $specfile) { |
michael@428 | 180 | print STDERR "openpkg:$prog_name:ERROR: unable to determine package specification file\n"; |
michael@428 | 181 | exit(1); |
michael@428 | 182 | } |
michael@428 | 183 | } |
michael@428 | 184 | } |
michael@428 | 185 | return $specfile; |
michael@428 | 186 | } |
michael@428 | 187 | |
michael@428 | 188 | # command: interactive shell |
michael@428 | 189 | sub cmd_shell ($@) { |
michael@428 | 190 | my ($gopts, @argv) = @_; |
michael@428 | 191 | my $rc = 0; |
michael@428 | 192 | |
michael@428 | 193 | # command line argument processing |
michael@428 | 194 | my $lopts = {}; |
michael@428 | 195 | @argv = getopts("s", $lopts, @argv); |
michael@428 | 196 | |
michael@428 | 197 | # determine release |
michael@428 | 198 | my $release = `$openpkg_prefix/bin/openpkg release -F '%t'`; |
michael@428 | 199 | $release =~ s/\n$//s; |
michael@428 | 200 | |
michael@428 | 201 | # create dot files |
michael@428 | 202 | my $screenrc = "$tmpdir/dot.screenrc"; |
michael@428 | 203 | my $bashsh = "$tmpdir/bash.sh"; |
michael@428 | 204 | my $bashrc = "$tmpdir/dot.bashrc"; |
michael@428 | 205 | my $inputrc = "$tmpdir/dot.inputrc"; |
michael@428 | 206 | unlink("$screenrc"); |
michael@428 | 207 | unlink("$bashsh"); |
michael@428 | 208 | unlink("$bashrc"); |
michael@428 | 209 | unlink("$inputrc"); |
michael@428 | 210 | my $title = "openpkg dev"; |
michael@428 | 211 | $title .= '%? %{= rW} %n %{-}%?'; |
michael@428 | 212 | $title .= ' %=%-w%{= rW}%50>%n %t%{-}%+w'; |
michael@428 | 213 | my $screenrc_data = ""; |
michael@428 | 214 | $screenrc_data .= "source \"$ENV{HOME}/.screenrc\"\n" if (-f "$ENV{HOME}/.screenrc"); |
michael@428 | 215 | $screenrc_data .= |
michael@428 | 216 | "escape ^Aa\n" . |
michael@428 | 217 | "startup_message off\n" . |
michael@428 | 218 | "vbell off\n" . |
michael@428 | 219 | "defscrollback 10000\n" . |
michael@428 | 220 | "defmonitor off\n" . |
michael@428 | 221 | "msgminwait 1\n" . |
michael@428 | 222 | "msgwait 1\n" . |
michael@428 | 223 | "hardstatus alwayslastline \" $title \"\n" . |
michael@428 | 224 | "shell $bashsh\n"; |
michael@428 | 225 | my $bashsh_data = |
michael@428 | 226 | "##\n" . |
michael@428 | 227 | "##\ bash.sh -- \"openpkg dev shell\" GNU bash wrapper script\n" . |
michael@428 | 228 | "##\n" . |
michael@428 | 229 | "\n" . |
michael@428 | 230 | "OPENPKG_PREFIX=\"$openpkg_prefix\"\n" . |
michael@428 | 231 | "export OPENPKG_PREFIX\n" . |
michael@428 | 232 | "INPUTRC=\"$inputrc\"\n" . |
michael@428 | 233 | "export INPUTRC\n" . |
michael@428 | 234 | "SHELL=\"$openpkg_prefix/lib/openpkg/bash\"\n" . |
michael@428 | 235 | "export SHELL\n" . |
michael@428 | 236 | "eval `$openpkg_prefix/bin/openpkg rpm --eval 'T=\"\%{_tmppath}\"; S=\"\%{_specdir}\"; D=\"\%{_sourcedir}\"'`\n" . |
michael@428 | 237 | "export T S D\n" . |
michael@428 | 238 | "\$SHELL --rcfile $bashrc"; |
michael@428 | 239 | my $bashrc_data = |
michael@428 | 240 | "##\n" . |
michael@428 | 241 | "## dot.bashrc -- \"openpkg dev shell\" GNU bash configuration\n" . |
michael@428 | 242 | "##\n" . |
michael@428 | 243 | "\n" . |
michael@428 | 244 | "# load user's standard bash run-command script\n" . |
michael@428 | 245 | "if [ -f ~/.bashrc ]; then\n" . |
michael@428 | 246 | " . ~/.bashrc\n" . |
michael@428 | 247 | "fi\n" . |
michael@428 | 248 | "\n" . |
michael@428 | 249 | "# configure a special command-line prompt\n" . |
michael@428 | 250 | "if [ \".\$TERM\" = .screen ]; then\n" . |
michael@428 | 251 | " PS1=\"\\\\u@\\\\h:\\\\w [P=\\\\e[1m\\\${OPENPKG_PREFIX}\\\\e[0m]\\n\\\\\\\$ \\\\ek\\\\W\\\\e\\\\\\\\\"\n" . |
michael@428 | 252 | "else\n" . |
michael@428 | 253 | " PS1=\"\\\\u@\\\\h:\\\\w [P=\\\\e[1m\\\${OPENPKG_PREFIX}\\\\e[0m]\\n\\\\\\\$ \"\n" . |
michael@428 | 254 | "fi\n" . |
michael@428 | 255 | "alias openpkg=\"\\\${OPENPKG_PREFIX}/bin/openpkg\"\n" . |
michael@428 | 256 | "alias opd=\"\\\${OPENPKG_PREFIX}/bin/openpkg dev\"\n" . |
michael@428 | 257 | "\n"; |
michael@428 | 258 | my $inputrc_data = |
michael@428 | 259 | "##\n" . |
michael@428 | 260 | "## dot.inputrc -- \"openpkg dev shell\" GNU readline configuration\n" . |
michael@428 | 261 | "##\n" . |
michael@428 | 262 | "\n"; |
michael@428 | 263 | foreach my $c (keys %{$map}) { |
michael@428 | 264 | my $k = $map->{$c}->{-key}; |
michael@428 | 265 | $c =~ s/\n/\\n/sg; |
michael@428 | 266 | $inputrc_data .= "\"\\e$k\": \"opd $c\"\n"; |
michael@428 | 267 | } |
michael@428 | 268 | $inputrc_data .= "\n"; |
michael@428 | 269 | open(SCREENRC, ">$screenrc"); |
michael@428 | 270 | print(SCREENRC $screenrc_data); |
michael@428 | 271 | close(SCREENRC); |
michael@428 | 272 | open(BASHSH, ">$bashsh"); |
michael@428 | 273 | print(BASHSH $bashsh_data); |
michael@428 | 274 | close(BASHSH); |
michael@428 | 275 | system("chmod a+x $bashsh"); |
michael@428 | 276 | open(BASHRC, ">$bashrc"); |
michael@428 | 277 | print(BASHRC $bashrc_data); |
michael@428 | 278 | close(BASHRC); |
michael@428 | 279 | open(INPUTRC, ">$inputrc"); |
michael@428 | 280 | print(INPUTRC $inputrc_data); |
michael@428 | 281 | close(INPUTRC); |
michael@428 | 282 | |
michael@428 | 283 | # run interactive shell |
michael@428 | 284 | print STDOUT "\033[34m++ entering OpenPKG $release development shell\033[0m\n"; |
michael@428 | 285 | my $rc; |
michael@428 | 286 | if ($lopts->{"s"}) { |
michael@428 | 287 | $rc = system("screen -c $screenrc -S 'openpkg-dev-shell' -d -R"); |
michael@428 | 288 | } |
michael@428 | 289 | else { |
michael@428 | 290 | $rc = system("$bashsh"); |
michael@428 | 291 | } |
michael@428 | 292 | |
michael@428 | 293 | # cleanup |
michael@428 | 294 | unlink("$tmpdir/dot.screenrc"); |
michael@428 | 295 | unlink("$tmpdir/bash.sh"); |
michael@428 | 296 | unlink("$tmpdir/dot.bashrc"); |
michael@428 | 297 | unlink("$tmpdir/dot.inputrc"); |
michael@428 | 298 | unlink("$tmpdir"); |
michael@428 | 299 | |
michael@428 | 300 | return $rc; |
michael@428 | 301 | } |
michael@428 | 302 | |
michael@428 | 303 | # command: unpack source RPM |
michael@428 | 304 | sub cmd_unpack ($@) { |
michael@428 | 305 | my ($gopts, @argv) = @_; |
michael@428 | 306 | my $rc = 0; |
michael@428 | 307 | |
michael@428 | 308 | # command line argument processing |
michael@428 | 309 | my $lopts = {}; |
michael@428 | 310 | @argv = getopts("l:b:sd", $lopts, @argv); |
michael@428 | 311 | if ($lopts->{"l"} eq "") { |
michael@428 | 312 | $lopts->{"l"} = "structured"; |
michael@428 | 313 | } |
michael@428 | 314 | if ($lopts->{"l"} !~ m/^(global|local|simple|structured|distributed)$/) { |
michael@428 | 315 | die sprintf("invalid layout type \"%s\"", $lopts->{"l"}); |
michael@428 | 316 | } |
michael@428 | 317 | if (@argv != 1) { |
michael@428 | 318 | die sprintf("exactly one SRPM has to be given"); |
michael@428 | 319 | } |
michael@428 | 320 | my $srpm = $argv[0]; |
michael@428 | 321 | if (not -f $srpm) { |
michael@428 | 322 | die sprintf("SRPM \"%s\" has to be a regular file", $srpm); |
michael@428 | 323 | } |
michael@428 | 324 | my $name = `$openpkg_prefix/bin/openpkg rpm -qp --qf '\%{NAME}' $srpm 2>/dev/null || true`; |
michael@428 | 325 | $name =~ s/\r?\n$//s; |
michael@428 | 326 | if ($name eq '') { |
michael@428 | 327 | die sprintf("unable to determine package name from SRPM \"%s\"", $srpm); |
michael@428 | 328 | } |
michael@428 | 329 | if ($lopts->{"b"} eq "") { |
michael@428 | 330 | $lopts->{"b"} = $srpm; |
michael@428 | 331 | if ($lopts->{"b"} =~ m/\.src\.rpm$/) { |
michael@428 | 332 | $lopts->{"b"} =~ s/\.src\.rpm$//; |
michael@428 | 333 | } |
michael@428 | 334 | else { |
michael@428 | 335 | my $subdir = `$openpkg_prefix/bin/openpkg rpm -qp --qf '\%{NAME}-\%{VERSION}-\%{RELEASE}' $srpm 2>/dev/null || true`; |
michael@428 | 336 | $lopts->{"b"} = $subdir; |
michael@428 | 337 | } |
michael@428 | 338 | } |
michael@428 | 339 | |
michael@428 | 340 | # determine result directory |
michael@428 | 341 | my $basedir = $lopts->{"b"}; |
michael@428 | 342 | my ($macrosfile, $specdir, $sourcedir); |
michael@428 | 343 | if ($lopts->{"l"} eq "global") { |
michael@428 | 344 | $macrosdir = "$openpkg_prefix/etc/openpkg"; |
michael@428 | 345 | $macrosfile = "$openpkg_prefix/etc/openpkg/rpmmacros"; |
michael@428 | 346 | $specdir = "$openpkg_prefix/RPM/SRC/$name"; |
michael@428 | 347 | $sourcedir = "$openpkg_prefix/RPM/SRC/$name"; |
michael@428 | 348 | $builddir = "$openpkg_prefix/RPM/TMP"; |
michael@428 | 349 | $tmpdir = "$openpkg_prefix/RPM/TMP"; |
michael@428 | 350 | $binrpmdir = "$openpkg_prefix/RPM/PKG"; |
michael@428 | 351 | $srcrpmdir = "$openpkg_prefix/RPM/PKG"; |
michael@428 | 352 | } |
michael@428 | 353 | elsif ($lopts->{"l"} eq "local") { |
michael@428 | 354 | $macrosdir = "$basedir/.openpkg"; |
michael@428 | 355 | $macrosfile = "$basedir/.openpkg/rpmmacros"; |
michael@428 | 356 | $specdir = "$basedir"; |
michael@428 | 357 | $sourcedir = "$basedir"; |
michael@428 | 358 | $builddir = "$basedir"; |
michael@428 | 359 | $tmpdir = "$basedir"; |
michael@428 | 360 | $binrpmdir = "$basedir"; |
michael@428 | 361 | $srcrpmdir = "$basedir"; |
michael@428 | 362 | } |
michael@428 | 363 | elsif ($lopts->{"l"} eq "simple") { |
michael@428 | 364 | $macrosdir = "$basedir/.openpkg"; |
michael@428 | 365 | $macrosfile = "$basedir/.openpkg/rpmmacros"; |
michael@428 | 366 | $specdir = "$basedir"; |
michael@428 | 367 | $sourcedir = "$basedir"; |
michael@428 | 368 | $builddir = "$tmpdir"; |
michael@428 | 369 | $tmpdir = "$tmpdir"; |
michael@428 | 370 | $binrpmdir = "$basedir/.."; |
michael@428 | 371 | $srcrpmdir = "$basedir/.."; |
michael@428 | 372 | } |
michael@428 | 373 | elsif ($lopts->{"l"} eq "structured") { |
michael@428 | 374 | $macrosdir = "$basedir/.openpkg"; |
michael@428 | 375 | $macrosfile = "$basedir/.openpkg/rpmmacros"; |
michael@428 | 376 | $specdir = "$basedir/src"; |
michael@428 | 377 | $sourcedir = "$basedir/dst"; |
michael@428 | 378 | $builddir = "$basedir/tmp"; |
michael@428 | 379 | $tmpdir = "$basedir/tmp"; |
michael@428 | 380 | $binrpmdir = "$basedir/pkg/bin"; |
michael@428 | 381 | $srcrpmdir = "$basedir/pkg/src"; |
michael@428 | 382 | } |
michael@428 | 383 | elsif ($lopts->{"l"} eq "distributed") { |
michael@428 | 384 | $macrosdir = "$basedir/.openpkg"; |
michael@428 | 385 | $macrosfile = "$basedir/.openpkg/rpmmacros"; |
michael@428 | 386 | $specdir = "$basedir/src/$name"; |
michael@428 | 387 | $sourcedir = "$basedir/dst/$name"; |
michael@428 | 388 | $builddir = "$basedir/tmp"; |
michael@428 | 389 | $tmpdir = "$basedir/tmp"; |
michael@428 | 390 | $binrpmdir = "$basedir/pkg/bin"; |
michael@428 | 391 | $srcrpmdir = "$basedir/pkg/src"; |
michael@428 | 392 | } |
michael@428 | 393 | |
michael@428 | 394 | # create still missing directories |
michael@428 | 395 | foreach my $dir ($macrosdir, $specdir, $sourcedir, $builddir, $tmpdir, $binrpmdir, $srcrpmdir) { |
michael@428 | 396 | if (not -d $dir) { |
michael@428 | 397 | print STDOUT "openpkg:$prog_name: creating directory \"$dir\"\n"; |
michael@428 | 398 | system("$openpkg_prefix/lib/openpkg/shtool mkdir -f -p -m 755 $dir"); |
michael@428 | 399 | } |
michael@428 | 400 | } |
michael@428 | 401 | |
michael@428 | 402 | # unpack SRPM |
michael@428 | 403 | print STDOUT "openpkg:$prog_name: unpacking source: \"$srpm\"\n"; |
michael@428 | 404 | print STDOUT "openpkg:$prog_name: unpacking target: \"$specdir\"\n"; |
michael@428 | 405 | print STDOUT "openpkg:$prog_name: unpacking target: \"$sourcedir\"\n"; |
michael@428 | 406 | my $abs_specdir = $specdir; |
michael@428 | 407 | my $abs_sourcedir = $sourcedir; |
michael@428 | 408 | my $pwd = `pwd`; $pwd =~ s/\r?\n$//s; |
michael@428 | 409 | $abs_specdir = "$pwd/$abs_specdir" if ($abs_specdir !~ m/^\//); |
michael@428 | 410 | $abs_sourcedir = "$pwd/$abs_sourcedir" if ($abs_sourcedir !~ m/^\//); |
michael@428 | 411 | my $rc = system( |
michael@428 | 412 | "$openpkg_prefix/bin/openpkg" . |
michael@428 | 413 | " --keep-privileges" . |
michael@428 | 414 | " rpm" . |
michael@428 | 415 | " -i" . |
michael@428 | 416 | " --define '_specdir $abs_specdir'" . |
michael@428 | 417 | " --define '_sourcedir $abs_sourcedir'" . |
michael@428 | 418 | " $srpm" |
michael@428 | 419 | ); |
michael@428 | 420 | |
michael@428 | 421 | # fix location of files |
michael@428 | 422 | if (not -f "$specdir/$name.spec") { |
michael@428 | 423 | die sprintf("failed to install package \"%s\": file \"%s\" not found\n", $srpm, "$specdir/$name.spec"); |
michael@428 | 424 | } |
michael@428 | 425 | open(SPEC, "<$specdir/$name.spec"); |
michael@428 | 426 | my $spec = ""; { local $/; $spec = <SPEC>; } |
michael@428 | 427 | close(SPEC); |
michael@428 | 428 | my $src = {}; |
michael@428 | 429 | $spec =~ s/^(?:Source|Patch)\d+:\s+(\S+)/$src->{$1} = 1, ''/mgei; |
michael@428 | 430 | foreach my $file (keys %{$src}) { |
michael@428 | 431 | if ($file !~ m/^(https?|ftp):\/\//) { |
michael@428 | 432 | if (not -f "$specdir/$file" and -f "$sourcedir/$file") { |
michael@428 | 433 | system("mv $sourcedir/$file $specdir/$file"); |
michael@428 | 434 | } |
michael@428 | 435 | } |
michael@428 | 436 | } |
michael@428 | 437 | |
michael@428 | 438 | # create .openpkg/rpmmacros file |
michael@428 | 439 | if (not -f $macrosfile) { |
michael@428 | 440 | print STDOUT "openpkg:$prog_name: creating file: \"$macrosfile\"\n"; |
michael@428 | 441 | my $rpmmacros = |
michael@428 | 442 | "##\n" . |
michael@428 | 443 | "## .openpkg/rpmmacros -- local OpenPKG RPM macro definitions\n" . |
michael@428 | 444 | "##\n" . |
michael@428 | 445 | "\n" . |
michael@428 | 446 | "\%openpkg_layout" . |
michael@428 | 447 | " macrosfile=\%{macrosfile}" . |
michael@428 | 448 | " layout=" . $lopts->{"l"} . |
michael@428 | 449 | " shared=" . ($lopts->{"s"} ? "yes" : "no") . |
michael@428 | 450 | " debug=" . ($lopts->{"d"} ? "yes" : "no") . |
michael@428 | 451 | "\n" . |
michael@428 | 452 | "\n"; |
michael@428 | 453 | open(MACROS, ">$macrosfile"); |
michael@428 | 454 | print(MACROS $rpmmacros); |
michael@428 | 455 | close(MACROS); |
michael@428 | 456 | } |
michael@428 | 457 | |
michael@428 | 458 | return $rc; |
michael@428 | 459 | } |
michael@428 | 460 | |
michael@428 | 461 | # command: edit package specification |
michael@428 | 462 | sub cmd_edit ($@) { |
michael@428 | 463 | my ($gopts, @argv) = @_; |
michael@428 | 464 | my $rc = 0; |
michael@428 | 465 | |
michael@428 | 466 | # run editor |
michael@428 | 467 | my $editor = ($ENV{"EDITOR"} || "vi"); |
michael@428 | 468 | my $specfile = ($argv[0] || specfile()); |
michael@428 | 469 | run("$editor $specfile"); |
michael@428 | 470 | |
michael@428 | 471 | return $rc; |
michael@428 | 472 | } |
michael@428 | 473 | |
michael@428 | 474 | # command: build package |
michael@428 | 475 | sub cmd_build ($@) { |
michael@428 | 476 | my ($gopts, @argv) = @_; |
michael@428 | 477 | my $rc = 0; |
michael@428 | 478 | |
michael@428 | 479 | # command line argument processing |
michael@428 | 480 | my $lopts = {}; |
michael@428 | 481 | @argv = getopts("s:D:w:", $lopts, @argv); |
michael@428 | 482 | if ($lopts->{"s"} eq '') { |
michael@428 | 483 | $lopts->{"s"} = "all"; |
michael@428 | 484 | } |
michael@428 | 485 | if ($lopts->{"s"} !~ m/^(track|fetch|prep|compile|install|binary|source|all)$/) { |
michael@428 | 486 | die "invalid step"; |
michael@428 | 487 | } |
michael@428 | 488 | |
michael@428 | 489 | # assembly defines |
michael@428 | 490 | my $defs = ""; |
michael@428 | 491 | if ($lopts->{"D"}) { |
michael@428 | 492 | foreach my $def (split(/\s+/, $lopts->{"D"})) { |
michael@428 | 493 | if ($def =~ m/^([^=]+)=(.+)$/) { |
michael@428 | 494 | $defs .= "--define '$1 $2' "; |
michael@428 | 495 | } |
michael@428 | 496 | else { |
michael@428 | 497 | $defs .= "--define '$def yes' "; |
michael@428 | 498 | } |
michael@428 | 499 | } |
michael@428 | 500 | } |
michael@428 | 501 | if ($lopts->{"w"}) { |
michael@428 | 502 | foreach my $def (split(/\s+/, $lopts->{"w"})) { |
michael@428 | 503 | $defs .= "--with $def "; |
michael@428 | 504 | } |
michael@428 | 505 | } |
michael@428 | 506 | |
michael@428 | 507 | # run build command |
michael@428 | 508 | my $specfile = ($argv[0] || specfile()); |
michael@428 | 509 | if ($lopts->{"s"} eq 'track') { |
michael@428 | 510 | run("$openpkg_prefix/bin/openpkg rpm -bt $defs$specfile"); |
michael@428 | 511 | } |
michael@428 | 512 | elsif ($lopts->{"s"} eq 'fetch') { |
michael@428 | 513 | run("$openpkg_prefix/bin/openpkg rpm -bf $defs$specfile"); |
michael@428 | 514 | } |
michael@428 | 515 | elsif ($lopts->{"s"} eq 'prep') { |
michael@428 | 516 | run("$openpkg_prefix/bin/openpkg rpm -bp $defs$specfile"); |
michael@428 | 517 | } |
michael@428 | 518 | elsif ($lopts->{"s"} eq 'compile') { |
michael@428 | 519 | run("$openpkg_prefix/bin/openpkg rpm -bc --short-circuit $defs$specfile"); |
michael@428 | 520 | } |
michael@428 | 521 | elsif ($lopts->{"s"} eq 'install') { |
michael@428 | 522 | run("$openpkg_prefix/bin/openpkg rpm -bi --short-circuit $defs$specfile"); |
michael@428 | 523 | } |
michael@428 | 524 | elsif ($lopts->{"s"} eq 'binary') { |
michael@428 | 525 | run("$openpkg_prefix/bin/openpkg rpm -bb --short-circuit $defs$specfile"); |
michael@428 | 526 | } |
michael@428 | 527 | elsif ($lopts->{"s"} eq 'source') { |
michael@428 | 528 | run("$openpkg_prefix/bin/openpkg rpm -bs $defs$specfile"); |
michael@428 | 529 | } |
michael@428 | 530 | elsif ($lopts->{"s"} eq 'all') { |
michael@428 | 531 | run("$openpkg_prefix/bin/openpkg rpm -ba $defs$specfile"); |
michael@428 | 532 | } |
michael@428 | 533 | |
michael@428 | 534 | return $rc; |
michael@428 | 535 | } |
michael@428 | 536 | |
michael@428 | 537 | # command: peek into package |
michael@428 | 538 | sub cmd_peek ($@) { |
michael@428 | 539 | my ($gopts, @argv) = @_; |
michael@428 | 540 | my $rc = 0; |
michael@428 | 541 | |
michael@428 | 542 | # run query command |
michael@428 | 543 | my $template = `$openpkg_prefix/bin/openpkg rpm --eval '%{_rpmdir}/%{_rpmfilename}'`; |
michael@428 | 544 | $template =~ s/\n$//s; |
michael@428 | 545 | my $specfile = specfile(); |
michael@428 | 546 | my $rpm = `$openpkg_prefix/bin/openpkg rpm -q --specfile '$specfile' --qf 'XXX$template'`; |
michael@428 | 547 | $rpm =~ s/^XXX//s; |
michael@428 | 548 | $rpm =~ s/\n$//s; |
michael@428 | 549 | |
michael@428 | 550 | # determine files |
michael@428 | 551 | print STDOUT "\033[34m++ determining configuration files\033[0m\n"; |
michael@428 | 552 | my @cfgfiles = split(/\n/, `$openpkg_prefix/bin/openpkg rpm -qplc $rpm`); |
michael@428 | 553 | print STDOUT "\033[34m++ determining documentation files\033[0m\n"; |
michael@428 | 554 | my @docfiles = split(/\n/, `$openpkg_prefix/bin/openpkg rpm -qpld $rpm`); |
michael@428 | 555 | print STDOUT "\033[34m++ determining all file information\033[0m\n"; |
michael@428 | 556 | my @allfiles = split(/\n/, `$openpkg_prefix/bin/openpkg rpm -qplv $rpm`); |
michael@428 | 557 | |
michael@428 | 558 | # create package file listing |
michael@428 | 559 | foreach my $line (@allfiles) { |
michael@428 | 560 | $prefix = ""; |
michael@428 | 561 | foreach my $docfile (@docfiles) { |
michael@428 | 562 | if ($line =~ m/\s+$docfile\b/s) { |
michael@428 | 563 | $prefix .= "D"; |
michael@428 | 564 | last; |
michael@428 | 565 | } |
michael@428 | 566 | } |
michael@428 | 567 | foreach my $cfgfile (@cfgfiles) { |
michael@428 | 568 | if ($line =~ m/\s+$cfgfile\b/s) { |
michael@428 | 569 | $prefix .= "C"; |
michael@428 | 570 | last; |
michael@428 | 571 | } |
michael@428 | 572 | } |
michael@428 | 573 | $prefix .= "--"; |
michael@428 | 574 | $prefix = substr($prefix, 0, 2); |
michael@428 | 575 | if ($line =~ m/^d/) { |
michael@428 | 576 | $line =~ s/(\s+\/\S+)/\033[34m$1\033[0m/s; |
michael@428 | 577 | } |
michael@428 | 578 | print "$prefix $line\n"; |
michael@428 | 579 | } |
michael@428 | 580 | |
michael@428 | 581 | return $rc; |
michael@428 | 582 | } |
michael@428 | 583 | |
michael@428 | 584 | # command: show modifications via VCS |
michael@428 | 585 | sub cmd_diff ($@) { |
michael@428 | 586 | my ($gopts, @argv) = @_; |
michael@428 | 587 | my $rc = 0; |
michael@428 | 588 | |
michael@428 | 589 | my $vcs = ""; |
michael@428 | 590 | my $cmd = ""; |
michael@428 | 591 | if (-d "CVS") { |
michael@428 | 592 | $vcs = "CVS"; |
michael@428 | 593 | $cmd = "cvs diff -u3"; |
michael@428 | 594 | } |
michael@428 | 595 | elsif (-d ".svn") { |
michael@428 | 596 | $vcs = "Subversion"; |
michael@428 | 597 | $cmd = "svn diff"; |
michael@428 | 598 | } |
michael@428 | 599 | elsif (-d "_MTN" or -d ".mtn" or |
michael@428 | 600 | -d "../_MTN" or -d "../.mtn" or |
michael@428 | 601 | -d "../../_MTN" or -d "../../.mtn" or |
michael@428 | 602 | -d "../../../_MTN" or -d "../../../.mtn") { |
michael@428 | 603 | $vcs = "Monotone"; |
michael@428 | 604 | $cmd = "mtn diff ."; |
michael@428 | 605 | } |
michael@428 | 606 | elsif (-d ".git" or |
michael@428 | 607 | -d "../.git" or |
michael@428 | 608 | -d "../../.git" or |
michael@428 | 609 | -d "../../../.git") { |
michael@428 | 610 | $vcs = "Git"; |
michael@428 | 611 | $cmd = "git diff . "; |
michael@428 | 612 | } |
michael@428 | 613 | elsif (-d ".hg" or |
michael@428 | 614 | -d "../.hg" or |
michael@428 | 615 | -d "../../.hg" or |
michael@428 | 616 | -d "../../../.hg") { |
michael@428 | 617 | $vcs = "Mercurial"; |
michael@428 | 618 | $cmd = "hg diff ." |
michael@428 | 619 | } |
michael@428 | 620 | else { |
michael@428 | 621 | $vcs = "OSSP svs"; |
michael@428 | 622 | $cmd = "svs diff"; |
michael@428 | 623 | } |
michael@428 | 624 | print STDOUT "\033[34m++ modifications as known to underlying $vcs VCS\033[0m\n"; |
michael@428 | 625 | run($cmd); |
michael@428 | 626 | } |
michael@428 | 627 | |
michael@428 | 628 | # command: install package |
michael@428 | 629 | sub cmd_install ($@) { |
michael@428 | 630 | my ($gopts, @argv) = @_; |
michael@428 | 631 | my $rc = 0; |
michael@428 | 632 | |
michael@428 | 633 | # command line argument processing |
michael@428 | 634 | my $lopts = {}; |
michael@428 | 635 | @argv = getopts("fnos", $lopts, @argv); |
michael@428 | 636 | |
michael@428 | 637 | # run install command |
michael@428 | 638 | my $template = `$openpkg_prefix/bin/openpkg rpm --eval '%{_rpmdir}/%{_rpmfilename}'`; |
michael@428 | 639 | $template =~ s/\n$//s; |
michael@428 | 640 | my $specfile = specfile(); |
michael@428 | 641 | my $rpm = `$openpkg_prefix/bin/openpkg rpm -q --specfile '$specfile' --qf 'XXX$template'`; |
michael@428 | 642 | $rpm =~ s/^XXX//s; |
michael@428 | 643 | $rpm =~ s/\n$//s; |
michael@428 | 644 | chdir("/"); |
michael@428 | 645 | run(($lopts->{"s"} ? "sudo " : "") . |
michael@428 | 646 | "$openpkg_prefix/bin/openpkg rpm -Uvh" |
michael@428 | 647 | . ($lopts->{"f"} ? " --force" : "") |
michael@428 | 648 | . ($lopts->{"n"} ? " --nodeps" : "") |
michael@428 | 649 | . ($lopts->{"o"} ? " --oldpackage" : "") |
michael@428 | 650 | . " $rpm"); |
michael@428 | 651 | |
michael@428 | 652 | return $rc; |
michael@428 | 653 | } |
michael@428 | 654 | |
michael@428 | 655 | # command: erase package |
michael@428 | 656 | sub cmd_erase ($@) { |
michael@428 | 657 | my ($gopts, @argv) = @_; |
michael@428 | 658 | my $rc = 0; |
michael@428 | 659 | |
michael@428 | 660 | # command line argument processing |
michael@428 | 661 | my $lopts = {}; |
michael@428 | 662 | @argv = getopts("fnas", $lopts, @argv); |
michael@428 | 663 | |
michael@428 | 664 | # run erase command |
michael@428 | 665 | my $specfile = specfile(); |
michael@428 | 666 | my $name = `$openpkg_prefix/bin/openpkg rpm -q --specfile $specfile --qf '%{NAME}'`; |
michael@428 | 667 | $name =~ s/\n$//s; |
michael@428 | 668 | chdir("/"); |
michael@428 | 669 | run(($lopts->{"s"} ? "sudo " : "") . |
michael@428 | 670 | "$openpkg_prefix/bin/openpkg rpm -e" |
michael@428 | 671 | . ($lopts->{"f"} ? " --force" : "") |
michael@428 | 672 | . ($lopts->{"n"} ? " --nodeps" : "") |
michael@428 | 673 | . ($lopts->{"a"} ? " --allmatches" : "") |
michael@428 | 674 | . " $name"); |
michael@428 | 675 | |
michael@428 | 676 | return $rc; |
michael@428 | 677 | } |
michael@428 | 678 | |
michael@428 | 679 | # command: lint package |
michael@428 | 680 | sub cmd_lint ($@) { |
michael@428 | 681 | my ($gopts, @argv) = @_; |
michael@428 | 682 | my $rc = 0; |
michael@428 | 683 | |
michael@428 | 684 | # command line argument processing |
michael@428 | 685 | my $lopts = {}; |
michael@428 | 686 | @argv = getopts("vb", $lopts, @argv); |
michael@428 | 687 | |
michael@428 | 688 | # run source linting commands |
michael@428 | 689 | my $specfile = specfile(); |
michael@428 | 690 | my $fslfile = $specfile; |
michael@428 | 691 | $fslfile =~ s/([^\/]+)\.spec$/fsl.$1/s; |
michael@428 | 692 | my $rcfile = $specfile; |
michael@428 | 693 | $rcfile =~ s/([^\/]+)\.spec$/rc.$1/s; |
michael@428 | 694 | my $name = `$openpkg_prefix/bin/openpkg rpm -q --specfile $specfile --qf '%{NAME}'`; |
michael@428 | 695 | $name =~ s/\n$//s; |
michael@428 | 696 | my $template = `$openpkg_prefix/bin/openpkg rpm --eval '%{_rpmdir}/%{_rpmfilename}'`; |
michael@428 | 697 | $template =~ s/\n$//s; |
michael@428 | 698 | my $rpm = `$openpkg_prefix/bin/openpkg rpm -q --specfile '$specfile' --qf 'XXX$template'`; |
michael@428 | 699 | $rpm =~ s/^XXX//s; |
michael@428 | 700 | $rpm =~ s/\n$//s; |
michael@428 | 701 | my $rc = 0; |
michael@428 | 702 | $rc += run("$openpkg_prefix/bin/openpkg lint-spec" . ($lopts->{"v"} ? " --verbose" : "") . " $specfile"); |
michael@428 | 703 | $rc += run("$openpkg_prefix/bin/openpkg lint-fsl" . ($lopts->{"v"} ? " --verbose" : "") . " $fslfile") if (-f $fslfile); |
michael@428 | 704 | $rc += run("$openpkg_prefix/bin/openpkg lint-rc" . ($lopts->{"v"} ? " --verbose" : "") . " $rcfile") if (-f $rcfile); |
michael@428 | 705 | |
michael@428 | 706 | # optionally run binary linting command |
michael@428 | 707 | run("$openpkg_prefix/bin/openpkg lint-rpm" . ($lopts->{"v"} ? " --verbose" : "") . " $rpm") if (-f $rpm and not $lopts->{"b"}); |
michael@428 | 708 | |
michael@428 | 709 | return $rc; |
michael@428 | 710 | } |
michael@428 | 711 | |
michael@428 | 712 | # command: release package |
michael@428 | 713 | sub cmd_release ($@) { |
michael@428 | 714 | my ($gopts, @argv) = @_; |
michael@428 | 715 | my $rc = 0; |
michael@428 | 716 | |
michael@428 | 717 | # command line argument processing |
michael@428 | 718 | my $lopts = {}; |
michael@428 | 719 | @argv = getopts("nm:f", $lopts, @argv); |
michael@428 | 720 | |
michael@428 | 721 | # implicit linting |
michael@428 | 722 | if (not $lopts->{"f"}) { |
michael@428 | 723 | my $rc = cmd_lint($gopts); |
michael@428 | 724 | if ($rc != 0 and !$lopts->{"f"}) { |
michael@428 | 725 | return $rc; |
michael@428 | 726 | } |
michael@428 | 727 | } |
michael@428 | 728 | |
michael@428 | 729 | # sanity check environment |
michael@428 | 730 | my $cmd = $ENV{"OPENPKG_DEV_RELEASE"} |
michael@428 | 731 | || `$openpkg_prefix/bin/openpkg rpm --eval '%{openpkg_dev_release}' 2>/dev/null || true` || ""; |
michael@428 | 732 | $cmd =~ s/\n$//s; |
michael@428 | 733 | if ($cmd eq "") { |
michael@428 | 734 | print STDERR "openpkg:$prog_name:ERROR: no \$OPENPKG_DEV_RELEASE command defined\n"; |
michael@428 | 735 | exit(1); |
michael@428 | 736 | } |
michael@428 | 737 | |
michael@428 | 738 | # |
michael@428 | 739 | # determine package information |
michael@428 | 740 | # |
michael@428 | 741 | |
michael@428 | 742 | print STDOUT "\033[34m++ determining package information\033[0m\n"; |
michael@428 | 743 | my $info = {}; |
michael@428 | 744 | $info->{"openpkg-prefix"} = $openpkg_prefix; |
michael@428 | 745 | $info->{"option-force"} = $lopts->{"f"} ? "yes" : "no"; |
michael@428 | 746 | |
michael@428 | 747 | print STDOUT "-- determining package name/version/release\n"; |
michael@428 | 748 | my $specfile = specfile(); |
michael@428 | 749 | my $result = `$openpkg_prefix/bin/openpkg rpm -q --specfile $specfile --qf '::%{NAME}::%{VERSION}::%{RELEASE}'`; |
michael@428 | 750 | $result =~ s/\n$//s; |
michael@428 | 751 | $result =~ s/^:://s; |
michael@428 | 752 | my @result = split(/::/, $result); |
michael@428 | 753 | $info->{"package-name"} = $result[0]; |
michael@428 | 754 | $info->{"package-version"} = $result[1]; |
michael@428 | 755 | $info->{"package-release"} = $result[2]; |
michael@428 | 756 | |
michael@428 | 757 | print STDOUT "-- determining package source and distribution location\n"; |
michael@428 | 758 | my $defines = "--define '\%name " . $info->{"package-name"} . "'"; |
michael@428 | 759 | $defines .= " --define '\%version " . $info->{"package-version"} . "'"; |
michael@428 | 760 | $defines .= " --define '\%release " . $info->{"package-release"} . "'"; |
michael@428 | 761 | my $result = `$openpkg_prefix/bin/openpkg rpm $defines --eval '%{_specdir}::%{_sourcedir}'`; |
michael@428 | 762 | $result =~ s/\n$//s; |
michael@428 | 763 | @result = split(/::/, $result); |
michael@428 | 764 | $info->{"spec-dir"} = $result[0]; |
michael@428 | 765 | $info->{"source-dir"} = $result[1]; |
michael@428 | 766 | |
michael@428 | 767 | print STDOUT "-- determining package source and binary RPM files\n"; |
michael@428 | 768 | my $template = `$openpkg_prefix/bin/openpkg rpm --eval '%{_rpmdir}/%{l_binrpmfilename}::%{_srcrpmdir}/%{l_srcrpmfilename}'`; |
michael@428 | 769 | $template =~ s/\n$//s; |
michael@428 | 770 | $result = `$openpkg_prefix/bin/openpkg rpm -q --specfile $specfile --qf '::$template'`; |
michael@428 | 771 | $result =~ s/\n$//s; |
michael@428 | 772 | $result =~ s/^:://s; |
michael@428 | 773 | @result = split(/::/, $result); |
michael@428 | 774 | $info->{"binary-rpm-file"} = $result[0]; |
michael@428 | 775 | $info->{"source-rpm-file"} = $result[1]; |
michael@428 | 776 | $info->{"package-version-old"} = ""; |
michael@428 | 777 | $info->{"package-release-old"} = ""; |
michael@428 | 778 | $info->{"vcs"} = "none"; |
michael@428 | 779 | |
michael@428 | 780 | print STDOUT "-- determining previous package version/release\n"; |
michael@428 | 781 | my $vcs = ""; |
michael@428 | 782 | my $diff = ""; |
michael@428 | 783 | my $content_old = ""; |
michael@428 | 784 | my $specdir = $info->{"spec-dir"}; |
michael@428 | 785 | my $specfile = $info->{"package-name"} . ".spec"; |
michael@428 | 786 | if (-f "$specdir/$specfile") { |
michael@428 | 787 | open(FP, "<$specdir/$specfile"); |
michael@428 | 788 | $content_new .= $_ while (<FP>); |
michael@428 | 789 | close(FP); |
michael@428 | 790 | if ($content_new =~ m/\n\%No(?:Source|Patch)\s+/s) { |
michael@428 | 791 | $info->{"source-rpm-file"} =~ s/\.src\.rpm$/.nosrc.rpm/s; |
michael@428 | 792 | } |
michael@428 | 793 | if (-d "$specdir/CVS") { |
michael@428 | 794 | # package is version controlled via CVS |
michael@428 | 795 | $vcs = "cvs"; |
michael@428 | 796 | $diff = `(cd $specdir && cvs diff -u3 $specfile) 2>/dev/null || true`; |
michael@428 | 797 | } |
michael@428 | 798 | elsif (-d "$specdir/.svn") { |
michael@428 | 799 | # package is version controlled via Subverson (SVN) |
michael@428 | 800 | $vcs = "svn"; |
michael@428 | 801 | $diff = `(cd $specdir && svn diff $specfile) 2>/dev/null || true`; |
michael@428 | 802 | } |
michael@428 | 803 | elsif (-d "$specdir/_MTN" or -d "$specdir/.mtn" or |
michael@428 | 804 | -d "$specdir/../_MTN" or -d "$specdir/../.mtn" or |
michael@428 | 805 | -d "$specdir/../../_MTN" or -d "$specdir/../../.mtn" or |
michael@428 | 806 | -d "$specdir/../../../_MTN" or -d "$specdir/../../../.mtn") { |
michael@428 | 807 | # package is version controlled via Monotone (MTN) |
michael@428 | 808 | $vcs = "mtn"; |
michael@428 | 809 | $diff = `(cd $specdir && mtn diff $specfile) 2>/dev/null || true`; |
michael@428 | 810 | $content_old = `(cd $specdir && mtn automate get_file_of -r h: $specfile) 2>/dev/null || true`; |
michael@428 | 811 | } |
michael@428 | 812 | elsif (-d "$specdir/.git" or |
michael@428 | 813 | -d "$specdir/../.git" or |
michael@428 | 814 | -d "$specdir/../../.git" or |
michael@428 | 815 | -d "$specdir/../../../.git") { |
michael@428 | 816 | # package is version controlled via Git |
michael@428 | 817 | $vcs = "git"; |
michael@428 | 818 | $diff = `(cd $specdir && git diff $specfile) 2>/dev/null || true`; |
michael@428 | 819 | } |
michael@428 | 820 | elsif (-d "$specdir/.hg" or |
michael@428 | 821 | -d "$specdir/../.hg" or |
michael@428 | 822 | -d "$specdir/../../.hg" or |
michael@428 | 823 | -d "$specdir/../../../.hg") { |
michael@428 | 824 | # package is version controlled via Mercurial (Hg) |
michael@428 | 825 | $vcs = "hg"; |
michael@428 | 826 | $diff = `(cd $specdir && hg diff $specfile) 2>/dev/null || true`; |
michael@428 | 827 | } |
michael@428 | 828 | elsif (-f "$specdir/$specfile.orig") { |
michael@428 | 829 | # package is patched via OSSP svs |
michael@428 | 830 | $vcs = "svs"; |
michael@428 | 831 | $diff = `(cd $specdir && svs diff $specfile) 2>/dev/null || true`; |
michael@428 | 832 | } |
michael@428 | 833 | if ($vcs ne '') { |
michael@428 | 834 | $info->{"vcs"} = $vcs; |
michael@428 | 835 | } |
michael@428 | 836 | if ($content_old ne '') { |
michael@428 | 837 | my $define = {}; |
michael@428 | 838 | $content_old =~ s/\n\%define[ \t]+([^ \t\n]+)[ \t]+([^ \t\n]+)/$define->{$1} = $2, ''/sge; |
michael@428 | 839 | $content_old =~ s/\n([^ \t\n]+):[ \t]+([^ \t\n]+)/$define->{lc($1)} = $2, ''/sge; |
michael@428 | 840 | sub resolve { |
michael@428 | 841 | my ($define, $name) = @_; |
michael@428 | 842 | my $value = $define->{$name}; |
michael@428 | 843 | $value = "" if (not defined $value); |
michael@428 | 844 | $value =~ s/\%\{(.+?)\}/resolve($define, $1)/sge; |
michael@428 | 845 | return $value; |
michael@428 | 846 | } |
michael@428 | 847 | $info->{"package-version-old"} = resolve($define, "version"); |
michael@428 | 848 | $info->{"package-release-old"} = resolve($define, "release"); |
michael@428 | 849 | } |
michael@428 | 850 | if (( $info->{"package-version-old"} eq '' |
michael@428 | 851 | or $info->{"package-release-old"} eq '') |
michael@428 | 852 | and $diff ne '' ) { |
michael@428 | 853 | if ($info->{"package-version-old"} eq '' and $diff =~ m/\n-Version:\s+(\S+)/s) { |
michael@428 | 854 | $info->{"package-version-old"} = $1; |
michael@428 | 855 | } |
michael@428 | 856 | if ($info->{"package-release-old"} eq '' and $diff =~ m/\n-Release:\s+(\S+)/s) { |
michael@428 | 857 | $info->{"package-release-old"} = $1; |
michael@428 | 858 | } |
michael@428 | 859 | } |
michael@428 | 860 | } |
michael@428 | 861 | |
michael@428 | 862 | print STDOUT "-- determining commit message\n"; |
michael@428 | 863 | $info->{"commit-message"} = ($lopts->{"m"} || ""); |
michael@428 | 864 | if ($info->{"commit-message"} eq "") { |
michael@428 | 865 | if ($info->{"package-version-old"} ne $info->{"package-version"}) { |
michael@428 | 866 | # new version |
michael@428 | 867 | $info->{"commit-message"} = "upgrading package: " . |
michael@428 | 868 | $info->{"package-name"} . " " . |
michael@428 | 869 | $info->{"package-version-old"} . " -> " . |
michael@428 | 870 | $info->{"package-version"}; |
michael@428 | 871 | } |
michael@428 | 872 | elsif (!$lopts->{"f"}) { |
michael@428 | 873 | print STDERR "openpkg:$prog_name:ERROR: package version not changed -- you have to manually provide a commit message\n"; |
michael@428 | 874 | exit(1); |
michael@428 | 875 | } |
michael@428 | 876 | } |
michael@428 | 877 | |
michael@428 | 878 | # run external command |
michael@428 | 879 | print STDOUT "\033[34m++ executing openpkg development release program\033[0m\n"; |
michael@428 | 880 | $cmd .= " %{openpkg-prefix}"; |
michael@428 | 881 | $cmd .= " %{spec-dir} %{source-dir} %{binary-rpm-file} %{source-rpm-file}"; |
michael@428 | 882 | $cmd .= " %{package-name} %{package-version} %{package-release} %{package-version-old} %{package-release-old}"; |
michael@428 | 883 | $cmd .= " %{commit-message} %{vcs}"; |
michael@428 | 884 | $cmd .= " %{option-force}"; |
michael@428 | 885 | $cmd =~ s/(\%\{([a-z][a-z-]+)\})/&subst($info, $1, $2)/sge; |
michael@428 | 886 | sub subst { |
michael@428 | 887 | my ($info, $text, $name) = @_; |
michael@428 | 888 | if (exists($info->{$name})) { |
michael@428 | 889 | $text = $info->{$name}; |
michael@428 | 890 | $text =~ s/'/\\'/sg; |
michael@428 | 891 | $text = "'$text'"; |
michael@428 | 892 | } |
michael@428 | 893 | } |
michael@428 | 894 | if ($lopts->{"n"}) { |
michael@428 | 895 | print STDOUT "-- DRY RUN:\n"; |
michael@428 | 896 | print STDOUT "-- $cmd\n"; |
michael@428 | 897 | $rc = 0; |
michael@428 | 898 | } |
michael@428 | 899 | else { |
michael@428 | 900 | $rc = system($cmd); |
michael@428 | 901 | } |
michael@428 | 902 | |
michael@428 | 903 | return $rc; |
michael@428 | 904 | } |
michael@428 | 905 |