«前の日記(2005-09-10 (土)) 最新 次の日記(2005-09-12 (月))»  

まちゅダイアリー


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

これで、書き換えられたページの一覧と、書き換えられた時刻が分かる (サンプル) 。

Tags: memo

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

…ところが、元に戻した数時間後に、また書き換えられる被害を受けてしまった。 このままじゃ、いたちごっこっぽい。

Tags: memo