X-Git-Url: http://git.tremily.us/?p=ikiwiki.git;a=blobdiff_plain;f=ikiwiki-mass-rebuild;h=9b57532bcce1897454b46a08ef62055c6982525c;hp=5b6a90b9087d4ffdc841c1ed9f10143b1cbddc70;hb=71974c24bbd31e4295b366eeea245131e8a9dc21;hpb=c9983bc7d8855f4d7dfb09c99491576beb8168ae diff --git a/ikiwiki-mass-rebuild b/ikiwiki-mass-rebuild index 5b6a90b90..9b57532bc 100755 --- a/ikiwiki-mass-rebuild +++ b/ikiwiki-mass-rebuild @@ -2,45 +2,45 @@ use warnings; use strict; +my $etcfile="/etc/ikiwiki/wikilist"; + +sub root { + $> == 0; +} + +sub username { + (getpwuid($>))[0]; +} + sub processline { - my $user=shift; my $setup=shift; - if (! getpwnam("$user")) { - print STDERR "warning: user $user does not exist\n"; - return - } if (! -f "$setup") { print STDERR "warning: $setup does not exist, skipping\n"; return; } - print "Processing $setup as user $user ...\n"; - # su is not used because it passes arguments through the shell, - # which is not safe for untrusted setup file names. - defined(my $pid = fork) or die "Can’t fork: $!"; - if (! $pid) { - my ($uuid, $ugid) = (getpwnam($user))[2, 3]; - $)="$ugid $ugid"; - $(=$ugid; - $>=$uuid; - $<=$uuid; - if ($< != $uuid || $> != $uuid || $( != $ugid || $) ne "$ugid $ugid") { - die "failed to drop permissions to $user"; - } - %ENV=(); - $ENV{HOME}=(getpwnam($user))[7]; - exec("ikiwiki", "-setup", $setup, @ARGV); - die "failed to run ikiwiki: $!"; + print "Processing $setup as user ".username()." ...\n"; + my $ret=system("ikiwiki", "-setup", $setup, @ARGV); + if ($ret != 0) { + print STDERR "warning: processing $setup failed with code $ret\n"; } - waitpid($pid,0); - if ($?) { - print STDERR "Processing $setup as user $user failed with code $?\n"; +} + +my %users; +sub processuser { + my $user=shift; + return if $user=~/^-/ || $users{$user}; + $users{$user}=1; + my $ret=system("su", $user, "-s", "/bin/sh", "-c", "--", "$0 --nonglobal @ARGV"); + if ($ret != 0) { + print STDERR "warning: processing for $user failed with code $ret\n"; } } sub processlist { my $file=shift; - my $forceuser=shift; + + return unless -e $file; my $list; open ($list, "<$file") || die "$file: $!"; @@ -49,22 +49,28 @@ sub processlist { s/^\s+//; s/\s+$//; next if /^#/ || ! length; - - if (/^([^\s]+)\s+([^\s]+)$/) { + if (/^([-\w]+)\s+([^\s]+)$/) { my $user=$1; my $setup=$2; - if (defined $forceuser && $forceuser ne $user) { - print STDERR "warning: in $file line $., attempt to set user to $user, but user forced to $forceuser. Skipping\n"; + if (root()) { + processuser($user); + } + else { + if (username() eq $user) { + processline($setup); + } } - processline($user, $setup); } - elsif (/^([^\s]+)$/) { + elsif (/^([-\w]+)$/) { my $user=$1; - my $home=(getpwnam($user))[7]; - if (defined $home && -d $home) { - my $dotfile="$home/.ikiwiki/wikilist"; - if (-e $dotfile) { - processlist($dotfile, $user); + if (root()) { + processuser($user); + } + else { + my $home=(getpwnam($user))[7]; + if (defined $home && -d $home) { + my $dotfile="$home/.ikiwiki/wikilist"; + processlist($dotfile); } } } @@ -72,9 +78,13 @@ sub processlist { close $list; } -my $wikilist="/etc/ikiwiki/wikilist"; - -if (-e $wikilist) { - processlist($wikilist); +if (@ARGV && $ARGV[0] eq "--nonglobal") { + shift; + # avoid recursively processing if the wikilist file has a root + # user in it + if (root()) { + exit 1; + } } +processlist($etcfile);