aboutsummaryrefslogtreecommitdiff
path: root/IkiWiki
diff options
context:
space:
mode:
Diffstat (limited to 'IkiWiki')
-rw-r--r--IkiWiki/CGI.pm29
-rw-r--r--IkiWiki/Plugin/404.pm77
-rw-r--r--IkiWiki/Plugin/aggregate.pm5
-rw-r--r--IkiWiki/Plugin/bzr.pm20
-rw-r--r--IkiWiki/Plugin/comments.pm39
-rw-r--r--IkiWiki/Plugin/editpage.pm66
-rw-r--r--IkiWiki/Plugin/goto.pm75
-rw-r--r--IkiWiki/Plugin/graphviz.pm2
-rw-r--r--IkiWiki/Plugin/inline.pm12
-rw-r--r--IkiWiki/Plugin/meta.pm7
-rw-r--r--IkiWiki/Plugin/recentchanges.pm47
-rw-r--r--IkiWiki/Plugin/shortcut.pm14
-rw-r--r--IkiWiki/Plugin/sparkline.pm2
-rw-r--r--IkiWiki/Plugin/tag.pm8
-rw-r--r--IkiWiki/Plugin/template.pm3
-rw-r--r--IkiWiki/Plugin/underlay.pm40
-rw-r--r--IkiWiki/Plugin/wmd.pm44
-rw-r--r--IkiWiki/Setup/Automator.pm13
-rw-r--r--IkiWiki/Wrapper.pm8
19 files changed, 347 insertions, 164 deletions
diff --git a/IkiWiki/CGI.pm b/IkiWiki/CGI.pm
index 3fadc462e..04f24b04f 100644
--- a/IkiWiki/CGI.pm
+++ b/IkiWiki/CGI.pm
@@ -142,7 +142,12 @@ sub cgi_postsignin ($$) {
exit;
}
else {
- error(gettext("login failed, perhaps you need to turn on cookies?"));
+ if ($config{sslcookie} && ! $q->https()) {
+ error(gettext("probable misconfiguration: sslcookie is set, but you are attepting to login via http, not https"));
+ }
+ else {
+ error(gettext("login failed, perhaps you need to turn on cookies?"));
+ }
}
}
@@ -229,6 +234,20 @@ sub cgi_prefs ($$) {
showform($form, $buttons, $session, $q);
}
+sub cgi_custom_failure ($$) {
+ my $header=shift;
+ my $message=shift;
+
+ print $header;
+ print $message;
+
+ # Internet Explod^Hrer won't show custom 404 responses
+ # unless they're >= 512 bytes
+ print ' ' x 512;
+
+ exit;
+}
+
sub check_banned ($$) {
my $q=shift;
my $session=shift;
@@ -236,11 +255,11 @@ sub check_banned ($$) {
my $name=$session->param("name");
if (defined $name) {
if (grep { $name eq $_ } @{$config{banned_users}}) {
- print $q->header(-status => "403 Forbidden");
$session->delete();
- print gettext("You are banned.");
cgi_savesession($session);
- exit;
+ cgi_custom_failure(
+ $q->header(-status => "403 Forbidden"),
+ gettext("You are banned."));
}
}
}
@@ -317,7 +336,7 @@ sub cgi (;$$) {
error("\"do\" parameter missing");
}
}
-
+
# Need to lock the wiki before getting a session.
lockwiki();
loadindex();
diff --git a/IkiWiki/Plugin/404.pm b/IkiWiki/Plugin/404.pm
new file mode 100644
index 000000000..5550ea7d1
--- /dev/null
+++ b/IkiWiki/Plugin/404.pm
@@ -0,0 +1,77 @@
+#!/usr/bin/perl
+# Copyright © 2009 Simon McVittie <http://smcv.pseudorandom.co.uk/>
+# Licensed under the GNU GPL, version 2, or any later version published by the
+# Free Software Foundation
+package IkiWiki::Plugin::404;
+
+use warnings;
+use strict;
+use IkiWiki 3.00;
+
+sub import {
+ hook(type => "cgi", id => '404', call => \&cgi);
+ IkiWiki::loadplugin("goto");
+}
+
+sub getsetup () {
+ return
+ plugin => {
+ # not really a matter of safety, but enabling/disabling
+ # through a web interface is useless - it needs web
+ # server admin action too
+ safe => 0,
+ rebuild => 0,
+ }
+}
+
+sub cgi_page_from_404 ($$$) {
+ my $path = shift;
+ my $baseurl = shift;
+ my $usedirs = shift;
+
+ # fail if missing from environment or whatever
+ return undef unless defined $path;
+ return undef unless defined $baseurl;
+
+ # with usedirs on, path is like /~fred/foo/bar/ or /~fred/foo/bar or
+ # /~fred/foo/bar/index.html
+ # with usedirs off, path is like /~fred/foo/bar.html
+ # baseurl is like 'http://people.example.com/~fred'
+
+ # convert baseurl to ~fred
+ unless ($baseurl =~ s{^https?://[^/]+/?}{}) {
+ return undef;
+ }
+
+ # convert path to /~fred/foo/bar
+ if ($usedirs) {
+ $path =~ s/\/*(?:index\.$config{htmlext})?$//;
+ }
+ else {
+ $path =~ s/\.$config{htmlext}$//;
+ }
+
+ # remove /~fred/
+ unless ($path =~ s{^/*\Q$baseurl\E/*}{}) {
+ return undef;
+ }
+
+ # special case for the index
+ unless ($path) {
+ return 'index';
+ }
+
+ return $path;
+}
+
+sub cgi ($) {
+ my $cgi=shift;
+
+ if ($ENV{REDIRECT_STATUS} eq '404') {
+ my $page = cgi_page_from_404($ENV{REDIRECT_URL},
+ $config{url}, $config{usedirs});
+ IkiWiki::Plugin::goto::cgi_goto($cgi, $page);
+ }
+}
+
+1;
diff --git a/IkiWiki/Plugin/aggregate.pm b/IkiWiki/Plugin/aggregate.pm
index c667ee2a9..e1baae666 100644
--- a/IkiWiki/Plugin/aggregate.pm
+++ b/IkiWiki/Plugin/aggregate.pm
@@ -534,6 +534,11 @@ sub aggregate (@) {
}
foreach my $entry ($f->entries) {
+ # XML::Feed doesn't work around XML::Atom's bizarre
+ # API, so we will. Real unicode strings? Yes please.
+ # See [[bugs/Aggregated_Atom_feeds_are_double-encoded]]
+ local $XML::Atom::ForceUnicode = 1;
+
my $c=$entry->content;
# atom feeds may have no content, only a summary
if (! defined $c && ref $entry->summary) {
diff --git a/IkiWiki/Plugin/bzr.pm b/IkiWiki/Plugin/bzr.pm
index 16c959069..883007367 100644
--- a/IkiWiki/Plugin/bzr.pm
+++ b/IkiWiki/Plugin/bzr.pm
@@ -255,6 +255,26 @@ sub rcs_recentchanges ($) {
return @ret;
}
+sub rcs_diff ($) {
+ my $taintedrev=shift;
+ my ($rev) = $taintedrev =~ /^(\d+(\.\d+)*)$/; # untaint
+
+ my $prevspec = "before:" . $rev;
+ my $revspec = "revno:" . $rev;
+ my @cmdline = ("bzr", "diff", "--old", $config{srcdir},
+ "--new", $config{srcdir},
+ "-r", $prevspec . ".." . $revspec);
+ open (my $out, "@cmdline |");
+
+ my @lines = <$out>;
+ if (wantarray) {
+ return @lines;
+ }
+ else {
+ return join("", @lines);
+ }
+}
+
sub rcs_getctime ($) {
my ($file) = @_;
diff --git a/IkiWiki/Plugin/comments.pm b/IkiWiki/Plugin/comments.pm
index b2243ce4c..ee53dbc91 100644
--- a/IkiWiki/Plugin/comments.pm
+++ b/IkiWiki/Plugin/comments.pm
@@ -25,8 +25,9 @@ sub import {
hook(type => "sessioncgi", id => 'comment', call => \&sessioncgi);
hook(type => "htmlize", id => "_comment", call => \&htmlize);
hook(type => "pagetemplate", id => "comments", call => \&pagetemplate);
- hook(type => "cgi", id => "comments", call => \&linkcgi);
hook(type => "formbuilder_setup", id => "comments", call => \&formbuilder_setup);
+ # Load goto to fix up user page links for logged-in commenters
+ IkiWiki::loadplugin("goto");
IkiWiki::loadplugin("inline");
}
@@ -167,7 +168,7 @@ sub preprocess {
}
else {
$commentauthorurl = IkiWiki::cgiurl(
- do => 'commenter',
+ do => 'goto',
page => (length $config{userdir}
? "$config{userdir}/$commentuser"
: "$commentuser"));
@@ -235,35 +236,6 @@ sub preprocess {
return $content;
}
-# This is exactly the same as recentchanges_link :-(
-sub linkcgi ($) {
- my $cgi=shift;
- if (defined $cgi->param('do') && $cgi->param('do') eq "commenter") {
-
- my $page=decode_utf8($cgi->param("page"));
- if (! defined $page) {
- error("missing page parameter");
- }
-
- IkiWiki::loadindex();
-
- my $link=bestlink("", $page);
- if (! length $link) {
- print "Content-type: text/html\n\n";
- print IkiWiki::misctemplate(gettext(gettext("missing page")),
- "<p>".
- sprintf(gettext("The page %s does not exist."),
- htmllink("", "", $page)).
- "</p>");
- }
- else {
- IkiWiki::redirect($cgi, urlto($link, undef, 1));
- }
-
- exit;
- }
-}
-
sub sessioncgi ($$) {
my $cgi=shift;
my $session=shift;
@@ -477,7 +449,7 @@ sub editcomment ($$) {
IkiWiki::printheader($session);
print IkiWiki::misctemplate(gettext(gettext("comment stored for moderation")),
"<p>".
- gettext("Your comment will be posted after moderator review"),
+ gettext("Your comment will be posted after moderator review").
"</p>");
exit;
}
@@ -633,7 +605,8 @@ sub formbuilder_setup (@) {
my %params=@_;
my $form=$params{form};
- if ($form->title eq "preferences") {
+ if ($form->title eq "preferences" &&
+ IkiWiki::is_admin($params{session}->param("name"))) {
push @{$params{buttons}}, "Comment Moderation";
if ($form->submitted && $form->submitted eq "Comment Moderation") {
commentmoderation($params{cgi}, $params{session});
diff --git a/IkiWiki/Plugin/editpage.pm b/IkiWiki/Plugin/editpage.pm
index 480e82804..0068a6b11 100644
--- a/IkiWiki/Plugin/editpage.pm
+++ b/IkiWiki/Plugin/editpage.pm
@@ -51,73 +51,9 @@ sub refresh () {
# Back to ikiwiki namespace for the rest, this code is very much
# internal to ikiwiki even though it's separated into a plugin,
-# and other plugins use the functions below.
+# and other plugins use the function below.
package IkiWiki;
-sub check_canedit ($$$;$) {
- my $page=shift;
- my $q=shift;
- my $session=shift;
- my $nonfatal=shift;
-
- my $canedit;
- run_hooks(canedit => sub {
- return if defined $canedit;
- my $ret=shift->($page, $q, $session);
- if (defined $ret) {
- if ($ret eq "") {
- $canedit=1;
- }
- elsif (ref $ret eq 'CODE') {
- $ret->() unless $nonfatal;
- $canedit=0;
- }
- elsif (defined $ret) {
- error($ret) unless $nonfatal;
- $canedit=0;
- }
- }
- });
- return defined $canedit ? $canedit : 1;
-}
-
-sub check_content (@) {
- my %params=@_;
-
- return 1 if ! exists $hooks{checkcontent}; # optimisation
-
- if (exists $pagesources{$params{page}}) {
- my @diff;
- my %old=map { $_ => 1 }
- split("\n", readfile(srcfile($pagesources{$params{page}})));
- foreach my $line (split("\n", $params{content})) {
- push @diff, $line if ! exists $old{$_};
- }
- $params{diff}=join("\n", @diff);
- }
-
- my $ok;
- run_hooks(checkcontent => sub {
- return if defined $ok;
- my $ret=shift->(%params);
- if (defined $ret) {
- if ($ret eq "") {
- $ok=1;
- }
- elsif (ref $ret eq 'CODE') {
- $ret->() unless $params{nonfatal};
- $ok=0;
- }
- elsif (defined $ret) {
- error($ret) unless $params{nonfatal};
- $ok=0;
- }
- }
-
- });
- return defined $ok ? $ok : 1;
-}
-
sub cgi_editpage ($$) {
my $q=shift;
my $session=shift;
diff --git a/IkiWiki/Plugin/goto.pm b/IkiWiki/Plugin/goto.pm
new file mode 100644
index 000000000..3f40c5859
--- /dev/null
+++ b/IkiWiki/Plugin/goto.pm
@@ -0,0 +1,75 @@
+#!/usr/bin/perl
+package IkiWiki::Plugin::goto;
+
+use warnings;
+use strict;
+use IkiWiki 3.00;
+
+sub import {
+ hook(type => "cgi", id => 'goto', call => \&cgi);
+}
+
+sub getsetup () {
+ return
+ plugin => {
+ safe => 1,
+ rebuild => 0,
+ }
+}
+
+# cgi_goto(CGI, [page])
+# Redirect to a specified page, or display "not found". If not specified,
+# the page param from the CGI object is used.
+sub cgi_goto ($;$) {
+ my $q = shift;
+ my $page = shift;
+
+ if (!defined $page) {
+ $page = IkiWiki::decode_utf8($q->param("page"));
+
+ if (!defined $page) {
+ error("missing page parameter");
+ }
+ }
+
+ IkiWiki::loadindex();
+
+ # If the page is internal (like a comment), see if it has a
+ # permalink. Comments do.
+ if (IkiWiki::isinternal($page) &&
+ defined $pagestate{$page}{meta}{permalink}) {
+ IkiWiki::redirect($q, $pagestate{$page}{meta}{permalink});
+ }
+
+ my $link = bestlink("", $page);
+
+ if (! length $link) {
+ IkiWiki::cgi_custom_failure(
+ $q->header(-status => "404 Not Found"),
+ IkiWiki::misctemplate(gettext("missing page"),
+ "<p>".
+ sprintf(gettext("The page %s does not exist."),
+ htmllink("", "", $page)).
+ "</p>")
+ )
+ }
+ else {
+ IkiWiki::redirect($q, urlto($link, undef, 1));
+ }
+
+ exit;
+}
+
+sub cgi ($) {
+ my $cgi=shift;
+ my $do = $cgi->param('do');
+
+ if (defined $do && ($do eq 'goto' || $do eq 'commenter' ||
+ $do eq 'recentchanges_link')) {
+ # goto is the preferred name for this; recentchanges_link and
+ # commenter are for compatibility with any saved URLs
+ cgi_goto($cgi);
+ }
+}
+
+1;
diff --git a/IkiWiki/Plugin/graphviz.pm b/IkiWiki/Plugin/graphviz.pm
index b43e96a73..32e994d6b 100644
--- a/IkiWiki/Plugin/graphviz.pm
+++ b/IkiWiki/Plugin/graphviz.pm
@@ -45,7 +45,7 @@ sub render_graph (\%) {
if (! -e "$config{destdir}/$dest") {
my $pid;
- my $sigpipe=0;;
+ my $sigpipe=0;
$SIG{PIPE}=sub { $sigpipe=1 };
$pid=open2(*IN, *OUT, "$params{prog} -Tpng");
diff --git a/IkiWiki/Plugin/inline.pm b/IkiWiki/Plugin/inline.pm
index d8b5f8548..2205ebffc 100644
--- a/IkiWiki/Plugin/inline.pm
+++ b/IkiWiki/Plugin/inline.pm
@@ -519,9 +519,15 @@ sub genfeed ($$$$$@) {
mdate_3339 => date_3339($pagemtime{$p}),
);
- if (exists $pagestate{$p} &&
- exists $pagestate{$p}{meta}{guid}) {
- $itemtemplate->param(guid => $pagestate{$p}{meta}{guid});
+ if (exists $pagestate{$p}) {
+ if (exists $pagestate{$p}{meta}{guid}) {
+ $itemtemplate->param(guid => $pagestate{$p}{meta}{guid});
+ }
+
+ if (exists $pagestate{$p}{meta}{updated}) {
+ $itemtemplate->param(mdate_822 => date_822($pagestate{$p}{meta}{updated}));
+ $itemtemplate->param(mdate_3339 => date_3339($pagestate{$p}{meta}{updated}));
+ }
}
if ($itemtemplate->query(name => "enclosure")) {
diff --git a/IkiWiki/Plugin/meta.pm b/IkiWiki/Plugin/meta.pm
index 15bb29b3f..4a22fed30 100644
--- a/IkiWiki/Plugin/meta.pm
+++ b/IkiWiki/Plugin/meta.pm
@@ -128,6 +128,13 @@ sub preprocess (@) {
$IkiWiki::pagectime{$page}=$time if defined $time;
}
}
+ elsif ($key eq 'updated') {
+ eval q{use Date::Parse};
+ if (! $@) {
+ my $time = str2time($value);
+ $pagestate{$page}{meta}{updated}=$time if defined $time;
+ }
+ }
if (! defined wantarray) {
# avoid collecting duplicate data during scan pass
diff --git a/IkiWiki/Plugin/recentchanges.pm b/IkiWiki/Plugin/recentchanges.pm
index ef108b3f0..329dd6f32 100644
--- a/IkiWiki/Plugin/recentchanges.pm
+++ b/IkiWiki/Plugin/recentchanges.pm
@@ -13,7 +13,8 @@ sub import {
hook(type => "refresh", id => "recentchanges", call => \&refresh);
hook(type => "pagetemplate", id => "recentchanges", call => \&pagetemplate);
hook(type => "htmlize", id => "_change", call => \&htmlize);
- hook(type => "cgi", id => "recentchanges", call => \&cgi);
+ # Load goto to fix up links from recentchanges
+ IkiWiki::loadplugin("goto");
}
sub getsetup () {
@@ -79,48 +80,6 @@ sub htmlize (@) {
return $params{content};
}
-sub cgi ($) {
- my $cgi=shift;
- if (defined $cgi->param('do') && $cgi->param('do') eq "recentchanges_link") {
- # This is a link from a change page to some
- # other page. Since the change pages are only generated
- # once, statically, links on them won't be updated if the
- # page they link to is deleted, or newly created, or
- # changes for whatever reason. So this CGI handles that
- # dynamic linking stuff.
- my $page=decode_utf8($cgi->param("page"));
- if (!defined $page) {
- error("missing page parameter");
- }
-
- IkiWiki::loadindex();
-
- # If the page is internal (like a comment), see if it has a
- # permalink. Comments do.
- if (IkiWiki::isinternal($page) &&
- defined $pagestate{$page}{meta}{permalink}) {
- IkiWiki::redirect($cgi,
- $pagestate{$page}{meta}{permalink});
- exit;
- }
-
- my $link=bestlink("", $page);
- if (! length $link) {
- print "Content-type: text/html\n\n";
- print IkiWiki::misctemplate(gettext(gettext("missing page")),
- "<p>".
- sprintf(gettext("The page %s does not exist."),
- htmllink("", "", $page)).
- "</p>");
- }
- else {
- IkiWiki::redirect($cgi, urlto($link, undef, 1));
- }
-
- exit;
- }
-}
-
sub store ($$$) {
my $change=shift;
@@ -138,7 +97,7 @@ sub store ($$$) {
if (length $config{cgiurl}) {
$_->{link} = "<a href=\"".
IkiWiki::cgiurl(
- do => "recentchanges_link",
+ do => "goto",
page => $_->{page}
).
"\" rel=\"nofollow\">".
diff --git a/IkiWiki/Plugin/shortcut.pm b/IkiWiki/Plugin/shortcut.pm
index 0e7cbd4d1..1840a5722 100644
--- a/IkiWiki/Plugin/shortcut.pm
+++ b/IkiWiki/Plugin/shortcut.pm
@@ -20,14 +20,20 @@ sub getsetup () {
}
sub checkconfig () {
- if (defined $config{srcdir}) {
+ if (defined $config{srcdir} && length $config{srcdir}) {
# Preprocess the shortcuts page to get all the available shortcuts
# defined before other pages are rendered.
- my $srcfile=srcfile("shortcuts.mdwn", 1);
+ my $srcfile=srcfile("shortcuts.".$config{default_pageext}, 1);
if (! defined $srcfile) {
- error(gettext("shortcut plugin will not work without a shortcuts.mdwn"));
+ $srcfile=srcfile("shortcuts.mdwn", 1);
+ }
+ if (! defined $srcfile) {
+ print STDERR sprintf(gettext("shortcut plugin will not work without %s"),
+ "shortcuts.".$config{default_pageext})."\n";
+ }
+ else {
+ IkiWiki::preprocess("shortcuts", "shortcuts", readfile($srcfile));
}
- IkiWiki::preprocess("shortcuts", "shortcuts", readfile($srcfile));
}
}
diff --git a/IkiWiki/Plugin/sparkline.pm b/IkiWiki/Plugin/sparkline.pm
index 1ed65e5b7..458192695 100644
--- a/IkiWiki/Plugin/sparkline.pm
+++ b/IkiWiki/Plugin/sparkline.pm
@@ -130,7 +130,7 @@ sub preprocess (@) {
if (! -e "$config{destdir}/$fn") {
my $pid;
- my $sigpipe=0;;
+ my $sigpipe=0;
$SIG{PIPE}=sub { $sigpipe=1 };
$pid=open2(*IN, *OUT, "php");
diff --git a/IkiWiki/Plugin/tag.pm b/IkiWiki/Plugin/tag.pm
index d43910910..8fe9c6828 100644
--- a/IkiWiki/Plugin/tag.pm
+++ b/IkiWiki/Plugin/tag.pm
@@ -125,4 +125,12 @@ sub pagetemplate (@) {
}
}
+package IkiWiki::PageSpec;
+
+sub match_tagged ($$;@) {
+ my $page = shift;
+ my $glob = shift;
+ return match_link($page, IkiWiki::Plugin::tag::tagpage($glob));
+}
+
1
diff --git a/IkiWiki/Plugin/template.pm b/IkiWiki/Plugin/template.pm
index 57bff20ff..b872f0962 100644
--- a/IkiWiki/Plugin/template.pm
+++ b/IkiWiki/Plugin/template.pm
@@ -10,7 +10,8 @@ use Encode;
sub import {
hook(type => "getsetup", id => "template", call => \&getsetup);
- hook(type => "preprocess", id => "template", call => \&preprocess);
+ hook(type => "preprocess", id => "template", call => \&preprocess,
+ scan => 1);
}
sub getsetup () {
diff --git a/IkiWiki/Plugin/underlay.pm b/IkiWiki/Plugin/underlay.pm
new file mode 100644
index 000000000..380d418fb
--- /dev/null
+++ b/IkiWiki/Plugin/underlay.pm
@@ -0,0 +1,40 @@
+#!/usr/bin/perl
+package IkiWiki::Plugin::underlay;
+# Copyright © 2008 Simon McVittie <http://smcv.pseudorandom.co.uk/>
+# Licensed under the GNU GPL, version 2, or any later version published by the
+# Free Software Foundation
+
+use warnings;
+use strict;
+use IkiWiki 3.00;
+
+sub import {
+ hook(type => "getsetup", id => "underlay", call => \&getsetup);
+ hook(type => "checkconfig", id => "underlay", call => \&checkconfig);
+}
+
+sub getsetup () {
+ return
+ plugin => {
+ safe => 0,
+ rebuild => undef,
+ },
+ add_underlays => {
+ type => "string",
+ default => [],
+ description => "extra underlay directories to add",
+ advanced => 1,
+ safe => 0,
+ rebuild => 1,
+ },
+}
+
+sub checkconfig () {
+ return unless exists $config{add_underlays};
+
+ foreach my $dir (@{$config{add_underlays}}) {
+ add_underlay($dir);
+ }
+}
+
+1;
diff --git a/IkiWiki/Plugin/wmd.pm b/IkiWiki/Plugin/wmd.pm
new file mode 100644
index 000000000..3372ffe38
--- /dev/null
+++ b/IkiWiki/Plugin/wmd.pm
@@ -0,0 +1,44 @@
+#!/usr/bin/perl
+package IkiWiki::Plugin::wmd;
+
+use warnings;
+use strict;
+use IkiWiki 3.00;
+use POSIX;
+use Encode;
+
+sub import {
+ add_underlay("wmd");
+ hook(type => "getsetup", id => "wmd", call => \&getsetup);
+ hook(type => "formbuilder_setup", id => "wmd", call => \&formbuilder_setup);
+}
+
+sub getsetup () {
+ return
+ plugin => {
+ safe => 1,
+ },
+}
+
+sub formbuilder_setup (@) {
+ my %params=@_;
+ my $form=$params{form};
+
+ return if ! defined $form->field("do");
+
+ return unless (($form->field("do") eq "edit") ||
+ ($form->field("do") eq "create"));
+
+ $form->tmpl_param("wmd_preview", "<div class=\"wmd-preview\"></div>\n".
+ include_javascript(undef, 1));
+}
+
+sub include_javascript ($;$) {
+ my $page=shift;
+ my $absolute=shift;
+
+ return '<script src="'.urlto("wmd.js", $page, $absolute).
+ '" type="text/javascript"></script>'."\n";
+}
+
+1
diff --git a/IkiWiki/Setup/Automator.pm b/IkiWiki/Setup/Automator.pm
index 42caf3039..7d9eca3af 100644
--- a/IkiWiki/Setup/Automator.pm
+++ b/IkiWiki/Setup/Automator.pm
@@ -110,11 +110,20 @@ sub import (@) {
next if $admin=~/^http\?:\/\//; # openid
# Prompt for password w/o echo.
+ my ($password, $password2);
system('stty -echo 2>/dev/null');
local $|=1;
print "\n\nCreating wiki admin $admin ...\n";
- print "Choose a password: ";
- chomp(my $password=<STDIN>);
+ for (;;) {
+ print "Choose a password: ";
+ chomp($password=<STDIN>);
+ print "Confirm password: ";
+ chomp($password2=<STDIN>);
+
+ last if $password2 eq $password;
+
+ print "Password mismatch.\n\n";
+ }
print "\n\n\n";
system('stty sane 2>/dev/null');
diff --git a/IkiWiki/Wrapper.pm b/IkiWiki/Wrapper.pm
index dd9971a34..6555fe625 100644
--- a/IkiWiki/Wrapper.pm
+++ b/IkiWiki/Wrapper.pm
@@ -28,7 +28,8 @@ sub gen_wrapper () {
my @envsave;
push @envsave, qw{REMOTE_ADDR QUERY_STRING REQUEST_METHOD REQUEST_URI
CONTENT_TYPE CONTENT_LENGTH GATEWAY_INTERFACE
- HTTP_COOKIE REMOTE_USER HTTPS} if $config{cgi};
+ HTTP_COOKIE REMOTE_USER HTTPS REDIRECT_STATUS
+ REDIRECT_URL} if $config{cgi};
my $envsave="";
foreach my $var (@envsave) {
$envsave.=<<"EOF";
@@ -92,10 +93,7 @@ EOF
$configstring=~s/"/\\"/g;
$configstring=~s/\n/\\n/g;
- #translators: The first parameter is a filename, and the second is
- #translators: a (probably not translated) error message.
- open(OUT, ">$wrapper.c") || error(sprintf(gettext("failed to write %s: %s"), "$wrapper.c", $!));;
- print OUT <<"EOF";
+ writefile(basename("$wrapper.c"), dirname($wrapper), <<"EOF");
/* A wrapper for ikiwiki, can be safely made suid. */
#include <stdio.h>
#include <sys/types.h>