* Allow /etc/ikiwiki/wikilist to list just the names of users, if so then
authorjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>
Tue, 28 Nov 2006 05:46:13 +0000 (05:46 +0000)
committerjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>
Tue, 28 Nov 2006 05:46:13 +0000 (05:46 +0000)
  ~user/.ikiwiki/wikilist will be read.

debian/changelog
doc/ikiwiki-mass-rebuild.mdwn
doc/todo/user-subdir_mechanism_like_etc_ikiwiki_wikilist.mdwn
ikiwiki-mass-rebuild
wikilist

index 68f3ff65e900aac70b4acfce6cb1cdebb81df551..2e5a6ea15fb6bb8bb281aa3df96ecd35b006a261 100644 (file)
@@ -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 <joeyh@debian.org>  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
index e5474dd260860532f1d91d95e1e243bf739b9985..5af030eeafe81edf7d7ebdfc426f4170e98e96f5 100644 (file)
@@ -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.
index c9f5461d30c85ae79ef15ed0fb2bf1de08bb99b8..826990e9f50de30cc6d614c988232931ba27d10a 100644 (file)
@@ -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]]
index 7ec41e98f7734db9b132e139c475ac44e869a6f7..5b6a90b9087d4ffdc841c1ed9f10143b1cbddc70 100755 (executable)
@@ -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
index f047b67859ed1a4037354be597bb8435053765ee..b68067a5a0f22487e11cd44e03829a55d6cebed1 100644 (file)
--- 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