]> sipb.mit.edu Git - ikiwiki.git/blobdiff - ikiwiki
web commit by joey
[ikiwiki.git] / ikiwiki
diff --git a/ikiwiki b/ikiwiki
index 1c16b67258d1cc9fb776df620d12b6cd53095695..cb90ef04f10b7cee9a81d2223df028feb98e8438 100755 (executable)
--- a/ikiwiki
+++ b/ikiwiki
@@ -10,7 +10,8 @@ use Getopt::Long;
 
 my (%links, %oldlinks, %oldpagemtime, %renderedfiles, %pagesources);
 
-my %config=( #{{{
+# Holds global config settings, also used by some modules.
+our %config=( #{{{
        wiki_file_prune_regexp => qr{((^|/).svn/|\.\.|^\.|\/\.|\.html?$)},
        wiki_link_regexp => qr/\[\[([^\s]+)\]\]/,
        wiki_file_regexp => qr/(^[-A-Za-z0-9_.:\/+]+$)/,
@@ -165,14 +166,17 @@ sub writefile ($$) { #{{{
        close OUT;
 } #}}}
 
-sub findlinks ($) { #{{{
+sub findlinks ($$) { #{{{
        my $content=shift;
+       my $page=shift;
 
        my @links;
        while ($content =~ /(?<!\\)$config{wiki_link_regexp}/g) {
                push @links, lc($1);
        }
-       return @links;
+       # Discussion links are a special case since they're not in the text
+       # of the page, but on its template.
+       return @links, "$page/discussion";
 } #}}}
 
 sub bestlink ($$) { #{{{
@@ -377,7 +381,7 @@ sub render ($) { #{{{
        if ($type ne 'unknown') {
                my $page=pagename($file);
                
-               $links{$page}=[findlinks($content)];
+               $links{$page}=[findlinks($content, $page)];
                
                $content=linkify($content, $file);
                $content=htmlize($type, $content);
@@ -397,6 +401,25 @@ sub render ($) { #{{{
        }
 } #}}}
 
+sub lockwiki () { #{{{
+       # Take an exclusive lock on the wiki to prevent multiple concurrent
+       # run issues. The lock will be dropped on program exit.
+       if (! -d "$config{srcdir}/.ikiwiki") {
+               mkdir("$config{srcdir}/.ikiwiki");
+       }
+       open(WIKILOCK, ">$config{srcdir}/.ikiwiki/lockfile") || error ("cannot write to lockfile: $!");
+       if (! flock(WIKILOCK, 2 | 4)) {
+               debug("wiki seems to be locked, waiting for lock");
+               my $wait=600; # arbitrary, but don't hang forever to 
+                             # prevent process pileup
+               for (1..600) {
+                       return if flock(WIKILOCK, 2 | 4);
+                       sleep 1;
+               }
+               error("wiki is locked; waited $wait seconds without lock being freed (possible stuck process or stale lock?)");
+       }
+} #}}}
+
 sub loadindex () { #{{{
        open (IN, "$config{srcdir}/.ikiwiki/index") || return;
        while (<IN>) {
@@ -521,7 +544,7 @@ sub rcs_recentchanges ($) { #{{{
                                @pages=@message=();
                        }
                        elsif ($state eq 'body') {
-                               push @message, {line => $_},
+                               push @message, {line => escapeHTML($_)},
                        }
                }
        }
@@ -553,7 +576,7 @@ sub refresh () { #{{{
                                $File::Find::prune=1;
                                use warnings "all";
                        }
-                       elsif (! -d $_) {
+                       elsif (! -d $_ && ! -l $_) {
                                my ($f)=/$config{wiki_file_regexp}/; # untaint
                                if (! defined $f) {
                                        warn("skipping bad filename $_\n");
@@ -636,8 +659,7 @@ FILE:               foreach my $file (@files) {
                foreach my $file (keys %rendered, @del) {
                        my $page=pagename($file);
                        if (exists $links{$page}) {
-                               foreach my $link (@{$links{$page}}) {
-                                       $link=bestlink($page, $link);
+                               foreach my $link (map { bestlink($page, $_) } @{$links{$page}}) {
                                        if (length $link &&
                                            ! exists $oldlinks{$page} ||
                                            ! grep { $_ eq $link } @{$oldlinks{$page}}) {
@@ -646,8 +668,7 @@ FILE:               foreach my $file (@files) {
                                }
                        }
                        if (exists $oldlinks{$page}) {
-                               foreach my $link (@{$oldlinks{$page}}) {
-                                       $link=bestlink($page, $link);
+                               foreach my $link (map { bestlink($page, $_) } @{$oldlinks{$page}}) {
                                        if (length $link &&
                                            ! exists $links{$page} ||
                                            ! grep { $_ eq $link } @{$links{$page}}) {
@@ -1164,25 +1185,13 @@ sub setup () { # {{{
        ($code)=$code=~/(.*)/s;
        close IN;
 
-       my (%setup);
        eval $code;
        error($@) if $@;
-       
-       gen_wrapper(%config, %setup, %{$setup{cgiwrapper}}) if $setup{cgiwrapper};
-       gen_wrapper(%config, %setup, %{$setup{svnwrapper}}) if $setup{svnwrapper};
-       
-       print "$setup{wikiname} setup complete, now forcing a rebuild\n";
-       foreach my $c (keys %setup) {
-               $config{$c}=possibly_foolish_untaint($setup{$c})
-                       if defined $setup{$c} && ! ref $setup{$c};
-       }
-       $config{rebuild}=1;
-       refresh();
-       saveindex();
        exit;
 } #}}}
 
 # main {{{
+lockwiki();
 setup() if $config{setup};
 if ($config{wrapper}) {
        gen_wrapper(%config);