aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--IkiWiki/Rcs/SVN.pm34
-rw-r--r--IkiWiki/Rcs/Stub.pm6
-rw-r--r--IkiWiki/Wrapper.pm8
-rw-r--r--doc/security.mdwn4
-rw-r--r--doc/todo/blogging.mdwn8
-rw-r--r--doc/usage.mdwn7
-rwxr-xr-xikiwiki3
7 files changed, 54 insertions, 16 deletions
diff --git a/IkiWiki/Rcs/SVN.pm b/IkiWiki/Rcs/SVN.pm
index 946412320..083b869df 100644
--- a/IkiWiki/Rcs/SVN.pm
+++ b/IkiWiki/Rcs/SVN.pm
@@ -1,10 +1,12 @@
-#!/usr/bin/perl -T
+#!/usr/bin/perl
# For subversion support.
use warnings;
use strict;
package IkiWiki;
+
+my $svn_log_infoline=qr/^r(\d+)\s+\|\s+([^\s]+)\s+\|\s+(\d+-\d+-\d+\s+\d+:\d+:\d+\s+[-+]?\d+).*/;
sub svn_info ($$) { #{{{
my $field=shift;
@@ -107,7 +109,6 @@ sub rcs_recentchanges ($) { #{{{
my ($svn_base)=$svn_url=~m!(/trunk(?:/.*)?)$!;
my $div=qr/^--------------------+$/;
- my $infoline=qr/^r(\d+)\s+\|\s+([^\s]+)\s+\|\s+(\d+-\d+-\d+\s+\d+:\d+:\d+\s+[-+]?\d+).*/;
my $state='start';
my ($rev, $user, $when, @pages, @message);
foreach (`LANG=C svn log --limit $num -v '$svn_url'`) {
@@ -115,7 +116,7 @@ sub rcs_recentchanges ($) { #{{{
if ($state eq 'start' && /$div/) {
$state='header';
}
- elsif ($state eq 'header' && /$infoline/) {
+ elsif ($state eq 'header' && /$svn_log_infoline/) {
$rev=$1;
$user=$2;
$when=concise(ago(time - str2time($3)));
@@ -166,4 +167,31 @@ sub rcs_recentchanges ($) { #{{{
return @ret;
} #}}}
+sub rcs_getctime () { #{{{
+ eval q{use Date::Parse};
+ foreach my $page (keys %pagectime) {
+ my $file="$config{srcdir}/$pagesources{$page}";
+ my $child = open(SVNLOG, "-|");
+ if (! $child) {
+ exec("svn", "log", $file) || error("svn log $file failed to run");
+ }
+
+ my $date;
+ while (<SVNLOG>) {
+ if (/$svn_log_infoline/) {
+ $date=$3;
+ }
+ }
+ close SVNLOG || warn "svn log $file exited $?";
+
+ if (! defined $date) {
+ warn "failed to parse svn log for $file\n";
+ next;
+ }
+
+ $pagectime{$page}=$date=str2time($date);
+ debug("found ctime ".localtime($date)." for $page");
+ }
+} #}}}
+
1
diff --git a/IkiWiki/Rcs/Stub.pm b/IkiWiki/Rcs/Stub.pm
index d3b72b5ea..d2a6ad003 100644
--- a/IkiWiki/Rcs/Stub.pm
+++ b/IkiWiki/Rcs/Stub.pm
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -T
+#!/usr/bin/perl
# Stubs for no revision control.
use warnings;
@@ -23,4 +23,8 @@ sub rcs_add ($) {
sub rcs_recentchanges ($) {
}
+sub rcs_getctime () {
+ error "getctime not implemented";
+}
+
1
diff --git a/IkiWiki/Wrapper.pm b/IkiWiki/Wrapper.pm
index 4966c453a..85d259117 100644
--- a/IkiWiki/Wrapper.pm
+++ b/IkiWiki/Wrapper.pm
@@ -38,7 +38,7 @@ EOF
$configstring=~s/\\/\\\\/g;
$configstring=~s/"/\\"/g;
- open(OUT, ">ikiwiki-wrap.c") || error("failed to write ikiwiki-wrap.c: $!");;
+ open(OUT, ">$wrapper.c") || error("failed to write $wrapper.c: $!");;
print OUT <<"EOF";
/* A wrapper for ikiwiki, can be safely made suid. */
#define _GNU_SOURCE
@@ -66,10 +66,10 @@ $envsave
}
EOF
close OUT;
- if (system("gcc", "ikiwiki-wrap.c", "-o", $wrapper) != 0) {
- error("failed to compile ikiwiki-wrap.c");
+ if (system("gcc", "$wrapper.c", "-o", $wrapper) != 0) {
+ error("failed to compile $wrapper.c");
}
- unlink("ikiwiki-wrap.c");
+ unlink("$wrapper.c");
if (defined $config{wrappermode} &&
! chmod(oct($config{wrappermode}), $wrapper)) {
error("chmod $wrapper: $!");
diff --git a/doc/security.mdwn b/doc/security.mdwn
index c7a6fcd69..48d82db89 100644
--- a/doc/security.mdwn
+++ b/doc/security.mdwn
@@ -46,7 +46,9 @@ this wiki, BTW.
Anyone with svn commit access can forge "web commit from foo" and make it appear on [[RecentChanges]] like foo committed. One way to avoid this would be to limit web commits to those done by a certian user.
-It's actually possible to force a whole series of svn commits to appear to have come just before yours, by forging svn log output. This could be guarded against somewhat by revision number scanning, since the forged revisions would duplicate the numbers of unforged ones. Or subversion could fix svn log to indent commit messages, which would make such forgery impossible..
+It's actually possible to force a whole series of svn commits to appear to
+have come just before yours, by forging svn log output. This could be
+guarded against by using svn log --xml.
ikiwiki escapes any html in svn commit logs to prevent other mischief.
diff --git a/doc/todo/blogging.mdwn b/doc/todo/blogging.mdwn
index 7d89a9904..680570d84 100644
--- a/doc/todo/blogging.mdwn
+++ b/doc/todo/blogging.mdwn
@@ -3,10 +3,4 @@
- The [[TODO]] page would work better if the first N were shown in full,
and then all open items were shown in summary. Maybe add this mode.
- Add Discussion and Edit links at the bottom of each inlined post.
-- Still not completly comfortable with ikiwiki only knowing when a page was
- posted based on the on-disk mtime the first time it sees the page. svn doesn't
- preserve mtimes and also if the index gets broken it will see new mtimes for any
- pages that were actually modified in the interim. I suppose that info could
- be pulled out of svn log by a utility that was run if the index or mtimes
- got screwed up.
-- It would be possible to support rss enclosures for eg, podcasts, pretty easily. \ No newline at end of file
+- It would be possible to support rss enclosures for eg, podcasts, pretty easily.
diff --git a/doc/usage.mdwn b/doc/usage.mdwn
index f36886d75..aa4978773 100644
--- a/doc/usage.mdwn
+++ b/doc/usage.mdwn
@@ -30,6 +30,13 @@ flags such as --verbose can be negated with --no-verbose.
Force a rebuild of all pages.
+* --fixctime
+
+ Pull last changed time for all pages out of the revision control system.
+ This rarely used option provides a way to get the real creation times of
+ items in weblogs, for example when building a wiki from a new subversion
+ checkout. It is unoptimised and quite slow.
+
* --templatedir
Specify the directory that the page [[templates]] are stored in.
diff --git a/ikiwiki b/ikiwiki
index 235a72102..ab9f3fc2f 100755
--- a/ikiwiki
+++ b/ikiwiki
@@ -34,6 +34,7 @@ sub getconfig () { #{{{
anonok => 0,
rss => 0,
rebuild => 0,
+ getctime => 0,
wrapper => undef,
wrappermode => undef,
srcdir => undef,
@@ -49,6 +50,7 @@ sub getconfig () { #{{{
"wikiname=s" => \$config{wikiname},
"verbose|v!" => \$config{verbose},
"rebuild!" => \$config{rebuild},
+ "getctime" => \$config{getctime},
"wrappermode=i" => \$config{wrappermode},
"svn!" => \$config{svn},
"anonok!" => \$config{anonok},
@@ -486,6 +488,7 @@ sub main () { #{{{
loadindex();
require IkiWiki::Render;
rcs_update();
+ rcs_getctime() if $config{getctime};
refresh();
saveindex();
}