return unless defined $plugin;
my ($plugin_read, $plugin_write);
- my $pid = open2($plugin_read, $plugin_write, $plugin);
+ my $pid = open2($plugin_read, $plugin_write,
+ IkiWiki::possibly_foolish_untaint($plugin));
# open2 doesn't respect "use open ':utf8'"
binmode($plugin_read, ':utf8');
$plugins{$plugin}={in => $plugin_read, out => $plugin_write, pid => $pid,
accum => ""};
+ $RPC::XML::ENCODING="utf-8";
rpc_call($plugins{$plugin}, "import");
} #}}}
error("XML RPC parser failure: $r") unless ref $r;
if ($r->isa('RPC::XML::response')) {
my $value=$r->value;
- if ($value->isa('RPC::XML::array')) {
+ if ($r->is_fault($value)) {
+ # throw the error as best we can
+ print STDERR $value->string."\n";
+ return "";
+ }
+ elsif ($value->isa('RPC::XML::array')) {
return @{$value->value};
}
elsif ($value->isa('RPC::XML::struct')) {
return %{$value->value};
}
- elsif ($value->isa('RPC::XML::fault')) {
- die $value->string;
- }
else {
return $value->value;
}
my $plugin=shift;
my $varname="IkiWiki::".shift;
my $key=shift;
+ my $value=shift;
no strict 'refs';
- my $ret=$varname->{$key}=@_;
+ my $ret=$varname->{$key}=$value;
use strict 'refs';
return $ret;
} #}}}
+sub getstate ($$$$) { #{{{
+ my $plugin=shift;
+ my $page=shift;
+ my $id=shift;
+ my $key=shift;
+
+ return $IkiWiki::pagestate{$page}{$id}{$key};
+} #}}}
+
+sub setstate ($$$$;@) { #{{{
+ my $plugin=shift;
+ my $page=shift;
+ my $id=shift;
+ my $key=shift;
+ my $value=shift;
+
+ return $IkiWiki::pagestate{$page}{$id}{$key}=$value;
+} #}}}
+
+sub getargv ($) { #{{{
+ my $plugin=shift;
+
+ return \@ARGV;
+} #}}}
+
+sub setargv ($@) { #{{{
+ my $plugin=shift;
+ my $array=shift;
+
+ @ARGV=@$array;
+} #}}}
+
sub inject ($@) { #{{{
# Bind a given perl function name to a particular RPC request.
my $plugin=shift;
delete $params{call};
IkiWiki::hook(%params, call => sub {
- IkiWiki::Plugin::external::rpc_call($plugin, $callback, @_)
+ my $ret=IkiWiki::Plugin::external::rpc_call($plugin, $callback, @_);
+ return $ret;
});
} #}}}