#! /usr/bin/perl # ex:ts=8 sw=4: # $OpenBSD: pkg_subst,v 1.1 2010/08/20 14:38:31 espie Exp $ # # Copyright (c) 2008 Marc Espie # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # rather simple script use strict; use warnings; use OpenBSD::Getopt; use OpenBSD::Subst; use OpenBSD::State; use OpenBSD::IdCache; my $subst = OpenBSD::Subst->new; our $opt_c; my ($fuid, $fgid); my ($uidc, $gidc); my $ui = OpenBSD::State->new('pkg_subst'); $ui->usage_is( '[-c] [-Dvar=value ...] [-g group] [-o owner] [file ...]'); $ui->do_options( sub { getopts('D:g:o:ch', {'D' => sub { $subst->parse_option(shift); }, 'o' => sub { my $owner = shift; $uidc //= OpenBSD::UidCache->new; $fuid = $uidc->lookup($owner, -1); die "$owner is not a valid user" if $fuid == -1; }, 'g' => sub { my $group = shift; $gidc //= OpenBSD::GidCache->new; $fgid = $gidc->lookup($group, -1); die "$group is not a valid group" if $fgid == -1; }, 'h' => sub { $ui->usage; }, }); }); my $bak = $subst->value('BAK'); if (!defined $bak) { $bak = '.beforesubst'; } if (@ARGV == 0) { $subst->copy_fh2(\*STDIN, \*STDOUT); } while (my $src = shift) { my $dest; if ($opt_c) { $dest = shift or die "odd number of files"; } else { $dest = $src; $src .= $bak; rename($dest, $src) or die "Can't rename $dest: $!"; } my $fh = $subst->copy($src, $dest); # copy rights, owner, group as well my ($uid, $gid, $mode) = (stat $src)[4, 5, 2]; my $r1 = chown $fuid // $uid, $fgid // $gid, $fh; my $r2 = chmod $mode & 07777, $fh; if (defined $fuid || defined $fgid || $< == 0) { if ($r1 == 0) { die "chown on $dest failed"; } if ($r2 == 0) { die "chmod on $dest failed"; } } }