+ eval q{use CGI::FormBuilder};
+ my $form = CGI::FormBuilder->new(
+ fields => [qw(do from page content comments)],
+ header => 1,
+ method => 'POST',
+ validate => {
+ content => '/.+/',
+ },
+ required => [qw{content}],
+ javascript => 0,
+ params => $q,
+ action => $q->request_uri,
+ table => 0,
+ template => "$config{templatedir}/editpage.tmpl"
+ );
+
+ my ($page)=$form->param('page')=~/$config{wiki_file_regexp}/;
+ if (! defined $page || ! length $page || $page ne $q->param('page') ||
+ $page=~/$config{wiki_file_prune_regexp}/ || $page=~/^\//) {
+ error("bad page name");
+ }
+ $page=lc($page);
+
+ $form->field(name => "do", type => 'hidden');
+ $form->field(name => "from", type => 'hidden');
+ $form->field(name => "page", value => "$page", force => 1);
+ $form->field(name => "comments", type => "text", size => 80);
+ $form->field(name => "content", type => "textarea", rows => 20,
+ cols => 80);
+
+ if ($form->submitted eq "Cancel") {
+ print $q->redirect("$config{url}/".htmlpage($page));
+ return;
+ }
+ if (! $form->submitted || ! $form->validate) {
+ if ($form->field("do") eq "create") {
+ if (exists $pagesources{lc($page)}) {
+ # hmm, someone else made the page in the
+ # meantime?
+ print $q->redirect("$config{url}/".htmlpage($page));
+ return;
+ }
+
+ my @page_locs;
+ my ($from)=$form->param('from')=~/$config{wiki_file_regexp}/;
+ if (! defined $from || ! length $from ||
+ $from ne $form->param('from') ||
+ $from=~/$config{wiki_file_prune_regexp}/ || $from=~/^\//) {
+ @page_locs=$page;
+ }
+ else {
+ my $dir=$from."/";
+ $dir=~s![^/]+/$!!;
+ push @page_locs, $dir.$page;
+ push @page_locs, "$from/$page";
+ while (length $dir) {
+ $dir=~s![^/]+/$!!;
+ push @page_locs, $dir.$page;
+ }
+ }
+
+ $form->tmpl_param("page_select", 1);
+ $form->field(name => "page", type => 'select',
+ options => \@page_locs);
+ $form->title("creating $page");
+ }
+ elsif ($form->field("do") eq "edit") {
+ my $content="";
+ if (exists $pagesources{lc($page)}) {
+ $content=readfile("$config{srcdir}/$pagesources{lc($page)}");
+ $content=~s/\n/\r\n/g;
+ }
+ $form->tmpl_param("page_select", 0);
+ $form->field(name => "content", value => $content,
+ force => 1);
+ $form->field(name => "page", type => 'hidden');
+ $form->title("editing $page");
+ }
+
+ $form->tmpl_param("can_commit", $config{svn});
+ $form->tmpl_param("indexlink", indexlink());
+ print $form->render(submit => ["Save Page", "Cancel"]);
+ }
+ else {
+ # save page
+ my $file=$page.$config{default_pageext};
+ my $newfile=1;
+ if (exists $pagesources{lc($page)}) {
+ $file=$pagesources{lc($page)};
+ $newfile=0;
+ }
+
+ my $content=$form->field('content');
+ $content=~s/\r\n/\n/g;
+ $content=~s/\r/\n/g;
+ writefile("$config{srcdir}/$file", $content);
+
+ my $message="web commit ";
+ if ($session->param("name")) {
+ $message.="by ".$session->param("name");
+ }
+ else {
+ $message.="from $ENV{REMOTE_ADDR}";
+ }
+ if (defined $form->field('comments') &&
+ length $form->field('comments')) {
+ $message.=": ".$form->field('comments');
+ }
+
+ if ($config{svn}) {
+ if ($newfile) {
+ rcs_add($file);
+ }
+ # presumably the commit will trigger an update
+ # of the wiki
+ rcs_commit($message);
+ }
+ else {
+ refresh();
+ }
+
+ # The trailing question mark tries to avoid broken
+ # caches and get the most recent version of the page.
+ print $q->redirect("$config{url}/".htmlpage($page)."?updated");
+ }
+} #}}}
+
+sub cgi () { #{{{
+ eval q{use CGI};
+ eval q{use CGI::Session};
+
+ my $q=CGI->new;
+
+ my $do=$q->param('do');
+ if (! defined $do || ! length $do) {
+ error("\"do\" parameter missing");
+ }
+
+ # This does not need a session.
+ if ($do eq 'recentchanges') {
+ cgi_recentchanges($q);
+ return;
+ }
+
+ CGI::Session->name("ikiwiki_session");
+
+ my $oldmask=umask(077);
+ my $session = CGI::Session->new("driver:db_file", $q,
+ { FileName => "$config{srcdir}/.ikiwiki/sessions.db" });
+ umask($oldmask);
+
+ # Everything below this point needs the user to be signed in.
+ if ((! $config{anonok} && ! defined $session->param("name") ||
+ ! userinfo_get($session->param("name"), "regdate")) || $do eq 'signin') {
+ cgi_signin($q, $session);
+
+ # Force session flush with safe umask.
+ my $oldmask=umask(077);
+ $session->flush;
+ umask($oldmask);
+
+ return;
+ }
+
+ if ($do eq 'create' || $do eq 'edit') {
+ cgi_editpage($q, $session);
+ }
+ else {
+ error("unknown do parameter");
+ }
+} #}}}
+
+sub setup () { # {{{
+ my $setup=possibly_foolish_untaint($config{setup});
+ delete $config{setup};
+ open (IN, $setup) || error("read $setup: $!\n");
+ local $/=undef;
+ my $code=<IN>;
+ ($code)=$code=~/(.*)/s;
+ close IN;
+ eval $code;
+ error($@) if $@;
+ print "$config{wikiname} setup complete, now forcing a rebuild.\n";
+ $config{cgi}=0;
+ $config{rebuild}=1;
+ foreach my $c (keys %config) {
+ $config{$c}=possibly_foolish_untaint($config{$c})
+ if defined $config{$c};
+ }
+ refresh();
+ saveindex();
+ exit;
+} #}}}
+
+# main {{{
+setup() if $config{setup};
+if ($config{wrapper}) {
+ gen_wrapper(%config);
+ exit;
+}