2 # Ikiwiki setup files can be perl files that 'use IkiWiki::Setup::foo',
3 # passing it some sort of configuration data. Or, they can contain
4 # the module name at the top, without the 'use', and the whole file is
5 # then fed into that module.
7 package IkiWiki::Setup;
12 use open qw{:utf8 :std};
16 my $setup=IkiWiki::possibly_foolish_untaint(shift);
19 $config{setupfile}=File::Spec->rel2abs($setup);
21 #translators: The first parameter is a filename, and the second
22 #translators: is a (probably not translated) error message.
23 open (IN, $setup) || error(sprintf(gettext("cannot read %s: %s"), $setup, $!));
27 $content=<IN> || error("$setup: $!");
31 if ($content=~/(use\s+)?(IkiWiki::Setup::\w+)/) {
32 $config{setuptype}=$2;
34 error sprintf(gettext("cannot load %s in safe mode"), $setup)
36 eval IkiWiki::possibly_foolish_untaint($content);
37 error("$setup: ".$@) if $@;
40 eval qq{require $config{setuptype}};
42 $config{setuptype}->loaddump(IkiWiki::possibly_foolish_untaint($content));
46 error sprintf(gettext("failed to parse %s"), $setup);
51 # Merge setup into existing config and untaint.
54 if (exists $setup{add_plugins} && exists $config{add_plugins}) {
55 push @{$setup{add_plugins}}, @{$config{add_plugins}};
57 if (exists $setup{exclude}) {
58 push @{$config{wiki_file_prune_regexps}}, $setup{exclude};
60 foreach my $c (keys %setup) {
61 if (defined $setup{$c}) {
62 if (! ref $setup{$c} || ref $setup{$c} eq 'Regexp') {
63 $config{$c}=IkiWiki::possibly_foolish_untaint($setup{$c});
65 elsif (ref $setup{$c} eq 'ARRAY') {
66 if ($c eq 'wrappers') {
67 # backwards compatability code
68 $config{$c}=$setup{$c};
71 $config{$c}=[map { IkiWiki::possibly_foolish_untaint($_) } @{$setup{$c}}]
74 elsif (ref $setup{$c} eq 'HASH') {
75 foreach my $key (keys %{$setup{$c}}) {
76 $config{$c}{$key}=IkiWiki::possibly_foolish_untaint($setup{$c}{$key});
85 if (length $config{cgi_wrapper}) {
86 push @{$config{wrappers}}, {
88 wrapper => $config{cgi_wrapper},
89 wrappermode => (defined $config{cgi_wrappermode} ? $config{cgi_wrappermode} : "06755"),
95 # Gets all available setup data from all plugins. Returns an
96 # ordered list of [plugin, setup] pairs.
98 # disable logging to syslog while dumping, broken plugins may
100 my $syslog=$config{syslog};
101 $config{syslog}=undef;
103 # Load all plugins, so that all setup options are available.
104 my @plugins=IkiWiki::listplugins();
105 foreach my $plugin (@plugins) {
106 eval { IkiWiki::loadplugin($plugin) };
107 if (exists $IkiWiki::hooks{checkconfig}{$plugin}{call}) {
108 my @s=eval { $IkiWiki::hooks{checkconfig}{$plugin}{call}->() };
113 foreach my $plugin (@plugins) {
114 if (exists $IkiWiki::hooks{getsetup}{$plugin}{call}) {
115 # use an array rather than a hash, to preserve order
116 my @s=eval { $IkiWiki::hooks{getsetup}{$plugin}{call}->() };
119 # set default section value (note use of shared
120 # hashref between array and hash)
122 if (! exists $s{plugin} || ! $s{plugin}->{section}) {
123 $s{plugin}->{section}="other";
126 # only the selected rcs plugin is included
127 if ($config{rcs} && $plugin eq $config{rcs}) {
128 $s{plugin}->{section}="core";
130 elsif ($s{plugin}->{section} eq "rcs") {
134 push @{$sections{$s{plugin}->{section}}}, [ $plugin, \@s ];
138 $config{syslog}=$syslog;
140 return map { sort { $a->[0] cmp $b->[0] } @{$sections{$_}} }
141 sort { # core first, other last, otherwise alphabetical
142 ($b eq "core") <=> ($a eq "core")
144 ($a eq "other") <=> ($b eq "other")
151 my $file=IkiWiki::possibly_foolish_untaint(shift);
153 eval qq{require $config{setuptype}};
155 my @dump=$config{setuptype}->gendump("Setup file for ikiwiki.");
157 open (OUT, ">", $file) || die "$file: $!";
158 print OUT "$_\n" foreach @dump;