2016/02/03

外部環境からUNIX V6にファイルを持ち込む方法

SIMHのPDP-11上で動作するUNIX V6に外部からファイルを持ち込む方法を考えてみました。まず外部からファイルを持ち込むために仮想テープデバイスが使えることは確認しました。残っている問題は、複数のファイルを如何にして持ち込むかという点です。

tarが使えれば、転送元でファイルをまとめておけるので、それを仮想テープデバイス経由でコピーしてからUNIX V6上で展開すれば終わりなのですが、残念ながらtarはまだ登場していません。最近はあまり見かけませんが、shar形式を使えばよいかとも考えました。しかしsedが無いし、当時のシェルではヒアドキュメントも出来ないようなので、これも駄目です。

shar形式の発想を参考にして、ed(1)を利用してファイルを展開するための手順を考えてみました。以下に示すed(1)コマンドを組み合わせてファイルを作成します。仮にこれをedar形式としておきます。このファイルをUNIX V6に持ち込んで、ed(1)の標準入力に与えると期待した結果が得られそうです。
  1. 「e ファイル名」コマンドで、対象となるファイルを宣言する。
  2. 「a」コマンドでファイルの内容を取り込む。
  3. 「1,$s/^X//」コマンドでshar風にするため付加した文字を取り去る。 
  4. 「w」コマンドでファイルに書き出す。
  5. 「1,$d」コマンドで取り込んだ内容をすべて消去し、次のファイルに備える。

上述したファイルを作成するために「v6edar」というスクリプトを作成しました。
#! /bin/sh
# v6edar -- bind files like using shar

warn () {
    echo "$PROGNAME:$*"
}

oops () {
    warn "$*"
    exit $EXIT_FAILURE
}

usage () {
    cat <<*EOF*
Usage: $PROGNAME [-hvx] files ...
    -h        print this message.
    -v        set shell option verbose.  Useful for debugging.
    -x        set shell option xtrace.  Useful for debugging.
*EOF*
    exit $EXIT_FAILURE
}

EXIT_SUCCESS=0
EXIT_FAILURE=1

PROGNAME=$(basename $0)

while getopts hvx OPT; do
    case $OPT in
        h) usage;;
        v) set -o verbose;;
        x) set -o xtrace;;
        ?) oops "This option isn't accepted.";;
    esac
done
shift $(expr $OPTIND - 1)

for i in $*; do
    [ $i != $(basename $i) ] && warn "$i:Not allowed to use path specification." 1>&2
    echo "e $(basename $i)"
    echo 'a'
    sed -e 's/^.*$/X&/' $i
    echo '.'
    echo '1,$s/^X//'
    echo 'w'
    echo '1,$d'
done
echo 'q'

# That's all
exit $EXIT_SUCCESS
# $Id: v6edar,v 1.2 2016-02-03 05:03:17 furusawa Exp $
またSIMHの仮想テープデバイスで使うための変換をおこなうツールも作成しました。これはBob Supnik, "SIMH Magtape Representation and Handling", Aug. 30, 2006を参考にしました。このツールを「simhtape」とします。
#!/usr/local/bin/python

# simhtape -- convert to the SIMH Magtape Representation format
# Reference: Bob Supnik, "SIMH Magtape Representation and Handling", Aug. 30, 2006

import sys

def main():
    blksiz   = 512
    reclen   = bytearray([0, 2, 0, 0])
    tapemark = bytearray([0, 0, 0, 0])

    while True:
        blk = sys.stdin.read(blksiz)
        if len(blk) == 0: break

        sys.stdout.write(reclen)
        sys.stdout.write(blk)
        if len(blk) != blksiz:
            sys.stdout.write("".join(["\0" for i in xrange(blksiz-len(blk))]))
        sys.stdout.write(reclen)
    sys.stdout.write(tapemark)

if __name__ == "__main__":
    main()
# $Id: simhtape,v 1.3 2016-02-03 05:03:17 furusawa Exp $
これらのツールを使って、以下のようにして転送元でファイルを作成します。
v6edar aaa.c bbb.c | simhtape > working.tap
 作成されたファイルを仮想テープデバイスに割り当てて、UNIX V6側で取り込みます。そしてddでファイルを取り出し、edの標準出力に与えると、ファイルが取り出せるはずです。
# dd if=/dev/mt0 of=a.edar
read: I/O error
4+0 records in
4+0 records out
# cat a.edar | ed -
?
?
# ls -l
total 8
-rw-rw-rw-  1 root     2048 Oct 10 13:12 a.edar
-rw-rw-rw-  1 root      651 Oct 10 13:13 aaa.c
-rw-rw-rw-  1 root      891 Oct 10 13:13 bbb.c
 ddを実行した時に「read: I/O error」というエラーが出ています。何故このようになるのか不明です。edを実行した時には「?」というエラーが出ていますが、これは「e」コマンドを指定した時に与えられているファイル名の実体が無い時に出るようです。これは仕方ないでしょう。

これで複数のファイルを外部から取り込むことが出来るようになったようです。

0 件のコメント:

コメントを投稿