X-Git-Url: https://sipb.mit.edu/gitweb.cgi/ikiwiki.git/blobdiff_plain/ddef0d3170b1543e6ed580c7ce00849e3ed1550f..b203b58f48e6f7109c621172d0a479de0a885ed7:/IkiWiki.pm diff --git a/IkiWiki.pm b/IkiWiki.pm index 0746ef24b..4e4da11c5 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -13,7 +13,8 @@ use open qw{:utf8 :std}; use vars qw{%config %links %oldlinks %pagemtime %pagectime %pagecase %pagestate %renderedfiles %oldrenderedfiles %pagesources - %destsources %depends %hooks %forcerebuild $gettext_obj}; + %destsources %depends %hooks %forcerebuild $gettext_obj + %loaded_plugins}; use Exporter q{import}; our @EXPORT = qw(hook debug error template htmlpage add_depends pagespec_match @@ -40,6 +41,28 @@ sub getsetup () { #{{{ safe => 1, rebuild => 1, }, + adminemail => { + type => "string", + default => undef, + example => 'me@example.com', + description => "contact email for wiki", + safe => 1, + rebuild => 0, + }, + adminuser => { + type => "string", + default => [], + description => "users who are wiki admins", + safe => 1, + rebuild => 0, + }, + banned_users => { + type => "string", + default => [], + description => "users who are banned from the wiki", + safe => 1, + rebuild => 0, + }, srcdir => { type => "string", default => undef, @@ -56,21 +79,6 @@ sub getsetup () { #{{{ safe => 0, # path rebuild => 1, }, - adminuser => { - type => "string", - default => [], - description => "user names of wiki admins", - safe => 1, - rebuild => 0, - }, - adminemail => { - type => "string", - default => undef, - example => 'me@example.com', - description => "contact email for wiki", - safe => 1, - rebuild => 0, - }, url => { type => "string", default => '', @@ -91,7 +99,7 @@ sub getsetup () { #{{{ type => "string", default => '', example => "/var/www/wiki/ikiwiki.cgi", - description => "cgi executable to generate", + description => "cgi wrapper to generate", safe => 0, # file rebuild => 0, }, @@ -113,9 +121,9 @@ sub getsetup () { #{{{ type => "internal", default => [qw{mdwn link inline htmlscrubber passwordauth openid signinedit lockedit conditional - recentchanges parentlinks}], + recentchanges parentlinks editpage}], description => "plugins to enable by default", - safe => 1, + safe => 0, rebuild => 1, }, add_plugins => { @@ -136,6 +144,7 @@ sub getsetup () { #{{{ type => "string", default => "$installdir/share/ikiwiki/templates", description => "location of template files", + advanced => 1, safe => 0, # path rebuild => 1, }, @@ -143,6 +152,7 @@ sub getsetup () { #{{{ type => "string", default => "$installdir/share/ikiwiki/basewiki", description => "base wiki source location", + advanced => 1, safe => 0, # path rebuild => 0, }, @@ -162,14 +172,14 @@ sub getsetup () { #{{{ }, verbose => { type => "boolean", - default => 0, + example => 1, description => "display verbose messages when building?", safe => 1, rebuild => 0, }, syslog => { type => "boolean", - default => 0, + example => 1, description => "log to syslog?", safe => 1, rebuild => 0, @@ -195,6 +205,14 @@ sub getsetup () { #{{{ safe => 1, rebuild => 1, }, + sslcookie => { + type => "boolean", + default => 0, + description => "only send cookies over SSL connections?", + advanced => 1, + safe => 1, + rebuild => 0, + }, default_pageext => { type => "string", default => "mdwn", @@ -213,6 +231,7 @@ sub getsetup () { #{{{ type => "string", default => '%c', description => "strftime format string to display date", + advanced => 1, safe => 1, rebuild => 1, }, @@ -221,16 +240,10 @@ sub getsetup () { #{{{ default => undef, example => "en_US.UTF-8", description => "UTF-8 locale to use", + advanced => 1, safe => 0, rebuild => 1, }, - sslcookie => { - type => "boolean", - default => 0, - description => "only send cookies over SSL connections?", - safe => 1, - rebuild => 0, - }, userdir => { type => "string", default => "", @@ -250,6 +263,7 @@ sub getsetup () { #{{{ type => "boolean", default => 0, description => "attempt to hardlink source files? (optimisation for large files)", + advanced => 1, safe => 0, # paranoia rebuild => 0, }, @@ -258,6 +272,7 @@ sub getsetup () { #{{{ description => "", example => "022", description => "force ikiwiki to use a particular umask", + advanced => 1, safe => 0, # paranoia rebuild => 0, }, @@ -266,6 +281,7 @@ sub getsetup () { #{{{ default => "", example => "$ENV{HOME}/.ikiwiki/", description => "extra library and plugin directory", + advanced => 1, safe => 0, # directory rebuild => 0, }, @@ -281,6 +297,7 @@ sub getsetup () { #{{{ default => undef, example => '\.wav$', description => "regexp of source files to ignore", + advanced => 1, safe => 0, # regexp rebuild => 1, }, @@ -295,9 +312,15 @@ sub getsetup () { #{{{ safe => 0, rebuild => 1, }, + wiki_file_chars => { + type => "string", + description => "specifies the characters that are allowed in source filenames", + default => "-[:alnum:]+/.:_", + safe => 0, + rebuild => 1, + }, wiki_file_regexp => { type => "internal", - default => qr/(^[-[:alnum:]_.:\/+]+$)/, description => "regexp of legal source files", safe => 0, rebuild => 1, @@ -337,6 +360,13 @@ sub getsetup () { #{{{ safe => 0, rebuild => 0, }, + setup => { + type => "internal", + default => undef, + description => "running in setup mode", + safe => 0, + rebuild => 0, + }, refresh => { type => "internal", default => 0, @@ -358,10 +388,17 @@ sub getsetup () { #{{{ safe => 0, rebuild => 0, }, - setup => { + setupfile => { type => "internal", default => undef, - description => "setup file to read", + description => "path to setup file", + safe => 0, + rebuild => 0, + }, + allow_symlinks_before_srcdir => { + type => "string", + default => 0, + description => "allow symlinks in the path leading to the srcdir (potentially insecure)", safe => 0, rebuild => 0, }, @@ -389,6 +426,10 @@ sub checkconfig () { #{{{ $gettext_obj=undef; } } + + if (! defined $config{wiki_file_regexp}) { + $config{wiki_file_regexp}=qr/(^[$config{wiki_file_chars}]+$)/; + } if (ref $config{ENV} eq 'HASH') { foreach my $val (keys %{$config{ENV}}) { @@ -412,13 +453,6 @@ sub checkconfig () { #{{{ $config{wikistatedir}="$config{srcdir}/.ikiwiki" unless exists $config{wikistatedir}; - - if ($config{rcs}) { - loadplugin($config{rcs}); - } - else { - loadplugin("norcs"); - } if (defined $config{umask}) { umask(possibly_foolish_untaint($config{umask})); @@ -433,14 +467,14 @@ sub listplugins () { #{{{ my %ret; foreach my $dir (@INC, $config{libdir}) { - next unless defined $dir; + next unless defined $dir && length $dir; foreach my $file (glob("$dir/IkiWiki/Plugin/*.pm")) { my ($plugin)=$file=~/.*\/(.*)\.pm$/; $ret{$plugin}=1; } } foreach my $dir ($config{libdir}, "$installdir/lib/ikiwiki") { - next unless defined $dir; + next unless defined $dir && length $dir; foreach my $file (glob("$dir/plugins/*")) { $ret{basename($file)}=1 if -x $file; } @@ -450,11 +484,23 @@ sub listplugins () { #{{{ } #}}} sub loadplugins () { #{{{ - if (defined $config{libdir}) { + if (defined $config{libdir} && length $config{libdir}) { unshift @INC, possibly_foolish_untaint($config{libdir}); } - loadplugin($_) foreach @{$config{default_plugins}}, @{$config{add_plugins}}; + foreach my $plugin (@{$config{default_plugins}}, @{$config{add_plugins}}) { + loadplugin($plugin); + } + + if ($config{rcs}) { + if (exists $IkiWiki::hooks{rcs}) { + error(gettext("cannot use multiple rcs plugins")); + } + loadplugin($config{rcs}); + } + if (! exists $IkiWiki::hooks{rcs}) { + loadplugin("norcs"); + } run_hooks(getopt => sub { shift->() }); if (grep /^-/, @ARGV) { @@ -474,8 +520,13 @@ sub loadplugin ($) { #{{{ foreach my $dir (defined $config{libdir} ? possibly_foolish_untaint($config{libdir}) : undef, "$installdir/lib/ikiwiki") { if (defined $dir && -x "$dir/plugins/$plugin") { - require IkiWiki::Plugin::external; + eval { require IkiWiki::Plugin::external }; + if ($@) { + my $reason=$@; + error(sprintf(gettext("failed to load external plugin needed for %s plugin: %s"), $plugin, $reason)); + } import IkiWiki::Plugin::external "$dir/plugins/$plugin"; + $loaded_plugins{$plugin}=1; return 1; } } @@ -485,6 +536,7 @@ sub loadplugin ($) { #{{{ if ($@) { error("Failed to load plugin $mod: $@"); } + $loaded_plugins{$plugin}=1; return 1; } #}}} @@ -739,7 +791,7 @@ sub bestlink ($$) { #{{{ elsif (exists $pagecase{lc $l}) { return $pagecase{lc $l}; } - } while $cwd=~s!/?[^/]+$!!; + } while $cwd=~s{/?[^/]+$}{}; if (length $config{userdir}) { my $l = "$config{userdir}/".lc($link); @@ -777,13 +829,16 @@ sub pagetitle ($;$) { #{{{ sub titlepage ($) { #{{{ my $title=shift; - $title=~s/([^-[:alnum:]:+\/.])/$1 eq ' ' ? '_' : "__".ord($1)."__"/eg; + # support use w/o %config set + my $chars = defined $config{wiki_file_chars} ? $config{wiki_file_chars} : "-[:alnum:]+/.:_"; + $title=~s/([^$chars]|_)/$1 eq ' ' ? '_' : "__".ord($1)."__"/eg; return $title; } #}}} sub linkpage ($) { #{{{ my $link=shift; - $link=~s/([^-[:alnum:]:+\/._])/$1 eq ' ' ? '_' : "__".ord($1)."__"/eg; + my $chars = defined $config{wiki_file_chars} ? $config{wiki_file_chars} : "-[:alnum:]+/.:_"; + $link=~s/([^$chars])/$1 eq ' ' ? '_' : "__".ord($1)."__"/eg; return $link; } #}}} @@ -1021,6 +1076,8 @@ sub preprocess ($$$;$$) { #{{{ my $prefix=shift; my $command=shift; my $params=shift; + $params="" if ! defined $params; + if (length $escape) { return "[[$prefix$command $params]]"; }