昔のHDDをマウントしてみたら文字化けしてた

LANDISKが壊れたらしい。
HDDだけ救出してPATA-USBでつないでみた。
マウントは出来たけど、文字化けしてる。
それを救出するエントリ。
キーワード: ReiserFS, Shift_JIS, 文字コード変換

準備

とりあえずフルバックアップ

$ sudo dd if=/dev/sdb1 of=hogehoge/hdd.raw bs=512 conv=noerror,sync

症状

デバイスをマウントしても文字化けをしている。

$ sudo mount -t reiserfs -o loop hogehoge/hdd.raw /media
$ ls /media -F1
(中略)
:90V:82:b5:82:a2:83t:83H:83:8b:83_/

では932でマウントを試みる

$ sudo mount -t reiserfs -o loop,codepage=cp932,iocharset=utf8 hogehoge/hdd.raw /media
mount: wrong fs type, bad option, bad superblock on /dev/loop1,
       missing codepage or helper program, or other error
       In some cases useful info is found in syslog - try
       dmesg | tail  or so

対応

とりあえず変換プログラムを作る。

#include <stdio.h>

int hex2int(char i);

int main(int argc, char** argv){
  char buf[256];

  fgets(buf, 256, stdin);

  int i = 0;
  char out[256];
  int j = 0;

  int low, up;
  while(buf[i] != '\n' && buf[i] != '\0' ){
    if(buf[i]==':'){
      i++;
      out[j++] = hex2int(buf[i])*16 + hex2int(buf[i+1]);
      i+=2;
    }
    else{
      out[j++]=buf[i++];
    }
  }
  out[j]='\0';
  printf("%s", out);
  return 0;
}

int hex2int(char i){
  switch(i){
  case '0':
    return 0;
  case '1':
    return 1;
  case '2':
    return 2;
  case '3':
    return 3;
  case '4':
    return 4;
  case '5':
    return 5;
  case '6':
    return 6;
  case '7':
    return 7;
  case '8':
    return 8;
  case '9':
    return 9;
  case 'a':
    return 10;
  case 'b':
    return 11;
  case 'c':
    return 12;
  case 'd':
    return 13;
  case 'e':
    return 14;
  case 'f':
    return 15;
  }
}

確認

良い感じに。

$ echo ":90V:82:b5:82:a2:83t:83H:83:8b:83_" | ./a.out | nkf -S -w
新しいフォルダ$

実行

スクリプト再帰処理
ローカル変数にする仕方がわからなくてlocalだったり()でくくったりした。
あと、最終的にがcifsな所に移すので"/"(0x2f)は"/"(0x81 0x85)に変換

#!/bin/bash

function rec(){
    local d=
    local i=
    local j=
    (
for d in */
do
    if [ "${d}" != "*/" ] ; then
        # echo pushd "${d}"
        pushd "${d}"

        rec

        # echo popd
        popd
    fi
done

for i in *
do
    t=`echo ${i} | grep ":"`
    if [ "${t}" != "" ] ; then
        j=`echo "${i}" | sed "s/:2f/:81:5e/g" | ~/a.out | nkf -S -w`
        if [ "${i}" != "${j}" ] ; then
            echo mv "${i}" "${j}"
            mv "${i}" "${j}"
        fi
    fi
done
)
}

rec

結果

$ cp -vR /media/ hogehoge/restore

つつがなく終了しました。
おしまい