From: joey Date: Tue, 28 Nov 2006 05:46:13 +0000 (+0000) Subject: * Allow /etc/ikiwiki/wikilist to list just the names of users, if so then X-Git-Tag: 1.34.2~4 X-Git-Url: http://git.tremily.us/?p=ikiwiki.git;a=commitdiff_plain;h=c9983bc7d8855f4d7dfb09c99491576beb8168ae * Allow /etc/ikiwiki/wikilist to list just the names of users, if so then ~user/.ikiwiki/wikilist will be read. --- diff --git a/debian/changelog b/debian/changelog index 68f3ff65e..2e5a6ea15 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +ikiwiki (1.34.2) UNRELEASED; urgency=low + + * Allow /etc/ikiwiki/wikilist to list just the names of users, if so then + ~user/.ikiwiki/wikilist will be read. + + -- Joey Hess Tue, 28 Nov 2006 00:16:40 -0500 + ikiwiki (1.34.1) unstable; urgency=low * Add libtime-duraiton-perl to build deps, as it's used by the svn module diff --git a/doc/ikiwiki-mass-rebuild.mdwn b/doc/ikiwiki-mass-rebuild.mdwn index e5474dd26..5af030eea 100644 --- a/doc/ikiwiki-mass-rebuild.mdwn +++ b/doc/ikiwiki-mass-rebuild.mdwn @@ -10,10 +10,15 @@ ikiwiki-mass-rebuild `ikiwiki-mass-rebuild` can be used to force a rebuild of all the wikis on a system. You will need to list the wikis it shuld build in the file -/etc/ikiwiki/wikilist, which has the format: +`/etc/ikiwiki/wikilist`, which has the format: user /path/to/wiki +It's also possible to let a user list setup files in `~user/.ikiwiki/wikilist` +in their home directory. To do so, list only the user's name, without a +setup file. The format of `~/.ikiwiki/wikilist` is the same as +`/etc/ikiwiki/wikilist`. + # OPTIONS All options are passed on to ikiwiki. diff --git a/doc/todo/user-subdir_mechanism_like_etc_ikiwiki_wikilist.mdwn b/doc/todo/user-subdir_mechanism_like_etc_ikiwiki_wikilist.mdwn index c9f5461d3..826990e9f 100644 --- a/doc/todo/user-subdir_mechanism_like_etc_ikiwiki_wikilist.mdwn +++ b/doc/todo/user-subdir_mechanism_like_etc_ikiwiki_wikilist.mdwn @@ -1 +1,3 @@ Currently, ikiwiki has the configuration file `/etc/ikiwiki/wikilist`, which `ikiwiki-mass-rebuild` can use to rebuild all the ikiwikis on the system, such as when upgrading ikiwiki. This file includes usernames, and `ikiwiki-mass-rebuild` (which must run as root) changes to the specified user to rebuild their wiki. However, this means that adding new ikiwikis to the list must require administrator action, since editing the file would allow you to run ikiwiki as any user. What about a user-subdirectory mechanism for this? If each user could have their own `/etc/ikiwiki/users/$user/wikilist`, which only contained wikis (no users), `ikiwiki-mass-rebuild` could rebuild each wiki in this list as the corresponding user only. This would mean that an administrator need only create the directory and provide user or group write permission, and the user or group can then create wikis as needed. + +[[todo/Done]], though somewhat differently. --[[Joey]] diff --git a/ikiwiki-mass-rebuild b/ikiwiki-mass-rebuild index 7ec41e98f..5b6a90b90 100755 --- a/ikiwiki-mass-rebuild +++ b/ikiwiki-mass-rebuild @@ -1,29 +1,80 @@ -#!/bin/sh -set -e +#!/usr/bin/perl +use warnings; +use strict; -action="$@" +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: $!"; + } + waitpid($pid,0); + if ($?) { + print STDERR "Processing $setup as user $user failed with code $?\n"; + } +} -wikilist=/etc/ikiwiki/wikilist +sub processlist { + my $file=shift; + my $forceuser=shift; -processline () { - user="$1" - setup="$2" - - if [ -z "$user" ] || [ -z "$setup" ]; then - echo "parse failure in /etc/ikiwiki/wikilist, line: '$user $setup'" >&2 - exit 1 - fi - - if [ ! -f "$setup" ]; then - echo "warning: $setup specified in /etc/ikiwiki/wikilist does not exist, skipping" >&2 - else - echo "Processing $setup as user $user ..." - su "$user" -c "ikiwiki -setup $setup $action" - fi + my $list; + open ($list, "<$file") || die "$file: $!"; + while (<$list>) { + chomp; + s/^\s+//; + s/\s+$//; + next if /^#/ || ! length; + + if (/^([^\s]+)\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"; + } + processline($user, $setup); + } + elsif (/^([^\s]+)$/) { + my $user=$1; + my $home=(getpwnam($user))[7]; + if (defined $home && -d $home) { + my $dotfile="$home/.ikiwiki/wikilist"; + if (-e $dotfile) { + processlist($dotfile, $user); + } + } + } + } + close $list; +} + +my $wikilist="/etc/ikiwiki/wikilist"; + +if (-e $wikilist) { + processlist($wikilist); } -if [ -e "$wikilist" ]; then - grep -v '^#' $wikilist | grep -v '^$' | while read line; do - processline $line - done -fi diff --git a/wikilist b/wikilist index f047b6785..b68067a5a 100644 --- a/wikilist +++ b/wikilist @@ -4,5 +4,9 @@ # # ikiwiki-mass-rebuild su's to the listed user and then runs ikiwiki -setup # on the specified ikiwiki setup file. +# +# It's also possible to let a user list setup files in ~user/.ikiwiki/wikilist +# in their home directory. To do so, list only the user's name, without a +# setup file. The format of ~/.ikiwiki/wikilist is the same as this file. #joey /home/joey/.ikiwiki/ikiwiki.setup