まちゅダイアリー
2005-09-11 (日)
■ Wiki と荒らし (2)
昨日の続き。 PukiWiki にて、大量に書き換えられたページを元に戻す方法を残しておこう。 更新ごとにバックアップを取っていることが前提。 まぁ、更新ごとじゃなくても、最後にバックアップを取った時点までは戻るか。
では、戻し方を。 まずは、書き換えられたページの一覧を作るところから。 仮に、書き換えられたページには、「荒らし」という単語が含まれるとする。
$ cd public_html/pukiwiki/wiki # wiki データのディレクトリへ移動 $ echo * | xargs grep '荒らし' | decode.rb | sort | uniq > ~/list.txt
xargs を使っているのは、ページの数が多すぎるとシェルで展開できなくなるため。 ここで使っている decode.rb の中身はこんな感じ。
ARGF.each do |line|
line =~ /^(.*)\.txt/
page = $1.unpack('H*0').join.upcase
file = "#{$1}.txt"
time = File.ctime(file).strftime('%Y/%m/%d/ %H:%M:%S')
puts "#{page}\t#{file}\t#{time}"
end
これで、書き換えられたページの一覧と、書き換えられた時刻が分かる (サンプル) 。
■ Wiki と荒らし (3)
書き換えられたページを特定したら、次はバックアップからページを元に戻す作業になる。
$ revert.rb ~/list.txt
revert.rb の中身はこの通り。
GZIP = '/usr/bin/gzip -cd'
def restore(filename, gen = 1)
out = []
buf = []
open("|#{GZIP} #{filename}", 'r').each do |line|
if line =~ /^>>>>>>>>>> \d+$/
out.push buf
buf = []
else
buf << line
end
end
out[0 - gen]
end
def revert(filename, buf)
filename =~ %r|([^/]+)\.gz|
file = $1
open("#{file}.txt", 'w') {|out|
out.puts buf
}
end
backup_dir = '~public_html/pukiwiki/backup'
ARGF.each do |line|
line =~ /(\w+).txt/
file = "#{backup_dir}/#{$1}.gz"
revert(file, restore(file, 1))
end
最後に、 diff データを削除しておしまい。
$ cd ../diff $ cut -f2 ~/list.txt | xargs rm -f
…ところが、元に戻した数時間後に、また書き換えられる被害を受けてしまった。 このままじゃ、いたちごっこっぽい。
[ツッコミを入れる]
