忍者ブログ
PCメモ
PC関係のメモ、気付いたこと。 simhとChromium OSをいじって遊んでいます。 Chromium OSのカスタムビルドを配布しています。(http://chromiumosde.gozaru.jp) twitter: @zui22904336 PGP fingerprint: 45FC 0E47 A68A FA06 02FE 2BEF B72C C6E6 F9FF 1C19
Admin / Write
4/27(木)〜5/7(日)の間はChromium OS カスタムビルドに関する活動をおやすみいたします。期間中にお問い合わせをいただいても対応はできません。
2014/03/11 (Tue) 22:53
以前こちらこちらの記事でsimhで動くUNIX V7とホストOSのLinuxでUUCPで通信できるように設定してみましたが、UUCPの設定をしていれば、メールの送受信もできるはず、ということで試してみました。

Linux側のMTA(postfix)の設定はCentOSインストール時のままで何も変えていません。

手順は簡単で、まずUNIX V7側で以下のコマンドを実行します。
(今回はrootユーザで試してみました)

unixv7# mail centos6!user
uucp mail test
(Ctrl+D)
unixv7#

mailコマンドの引数で、アドレスとしてcentos6のユーザーuserあてにメールを送るように指示しています。
それからLinux側で以下のコマンドを実行します。以前も書きましたがUNIX V7は着信専用なのでLinux側からつなぎに行っています。

linux$ uucico -S unixv7

uulogコマンドでLinux側のUUCPログを見ると以下のように出力されていました。

uucico unixv7 - (2014-03-11 22:10:42.19 7622) Calling system unixv7 (port TCP)
uucico unixv7 - (2014-03-11 22:10:42.73 7622) Login successful
uucico unixv7 - (2014-03-11 22:10:42.91 7622) Handshake successful (protocol 'g' sending packet/window 64/3 receiving 64/7)
uucico unixv7 root (2014-03-11 22:10:43.06 7622) Receiving D.centos6B0008
uucico unixv7 root (2014-03-11 22:10:43.25 7622) Receiving X.mynameX0006
uucico unixv7 - (2014-03-11 22:10:43.34 7622) Protocol 'g' packets: sent 7, resent 0, received 10
uucico unixv7 - (2014-03-11 22:10:43.40 7622) Call complete (1 seconds 139 bytes 139 bps)
uuxqt unixv7 root (2014-03-11 22:10:44.41 7627) Executing X.mynameX0006 (rmail user)

メールは以下のような内容でちゃんと届きました。

Message 56:
From root@where.localdomain  Tue Mar 11 22:10:44 2014
Return-Path: <root@where.localdomain>
X-Original-To: user
Delivered-To: user@centos6.localdomain
Date: Tue, 11 Mar 2014 22:10:44 +0900 (JST)
From: root@where.localdomain (uucp)
To: undisclosed-recipients:;
Status: R

uucp mail test



ちゃんとPostfixの設定をしていないのでいろいろ怪しいですが、一応届きましたね。
ちゃんと設定すればUNIX V7からLinux経由で外の世界にメールを送ることもできるんでしょうね。ちょっとおもしろそうです。気が向いたらやってみるかもしれません。

UNIX V7のmailコマンドのソースを見ると、宛先に"!"が含まれているとuuxコマンドを使ってリモートサイトのrmailコマンドを起動してメールを送信するようになっています。該当箇所のソースを抜粋するとこんな感じです。

sendrmt(n, name)
char *name;
{
(略)
        if (local)
                sprintf(cmd, "mail %s", rsys);
        else {
                if (index(name+1, '!'))
                        sprintf(cmd, "uux - %s!rmail \\(%s\\)", rsys, name+1);
                else
                        sprintf(cmd, "uux - %s!rmail %s", rsys, name+1);
        }


で、よくわからないのが、

  UNIX V7にはmailコマンドはあるがrmailコマンドが存在しない、

ということです。 UNIX V7どうしでメールをやり取りしていた時は一体どうなっていたんでしょうか。

Linuxでman rmailを実行すると、以下の記述があります。

歴史
   rmail プログラムは 4.2BSD から登場しました。 

4.2BSDがリリースされたのはWikiによると1983年だそうです。
一方、UNIX V7のmail.cのファイル日付は1979年になっています。

う~ん、よくわかりませんね。。。


[関連記事]





ランキングに参加してみました。クリックしていただければ嬉しいです。

にほんブログ村 IT技術ブログ IT技術メモへ
にほんブログ村

パソコン ブログランキングへ

拍手[0回]

PR


4/27(木)〜5/7(日)の間はChromium OS カスタムビルドに関する活動をおやすみいたします。期間中にお問い合わせをいただいても対応はできません。
2014/03/09 (Sun) 00:00
前回はUNIX V7側でのUUCPの着信設定を行いましたが、今回はホストOSのLinux CentOS6でUUCPの発信設定を行います。UNIX V7からLinuxへは接続しにいけないので、Linux側は発信設定のみで着信設定はしません。

Linux側の発信設定


Taylor UUCPのダウンロード


EPELなどの外部リポジトリを有効にしていればyumコマンドでUUCPをインストールすることができるようですが、今回は自分でソースからビルドしてみたので、その手順を書きます。

UUCPのソースコードは以下のURLからダウンロードします。

http://airs.com/ian/uucp.html

こちらにアクセスして、download the source codeのリンクからダウンロードします。

ビルド


ダウンロードしたuucp-1.07.tar.gzを展開し、policy.hを編集します。

linux$ tar zxvf uucp-1.07.tar.gz
linux$ cd uucp-1.07
linux$ vi policy.h
/* If you use other programs that also lock devices, such as cu or
   uugetty, the other programs and UUCP must agree on whether a device
   is locked.  This is typically done by creating a lock file in a
   specific directory; the lock files are generally named
   LCK..something or LK.something.  If the LOCKDIR macro is defined,
   these lock files will be placed in the named directory; otherwise
   they will be placed in the default spool directory.  On some HDB
   systems the lock files are placed in /etc/locks.  On some they are
   placed in /usr/spool/locks.  On the NeXT they are placed in
   /usr/spool/uucp/LCK.  */
/* #define LOCKDIR "/usr/spool/uucp" */
#define LOCKDIR "/var/spool/uucp"   ← この行を追加
/* #define LOCKDIR "/etc/locks" */
/* #define LOCKDIR "/usr/spool/locks" */
/* #define LOCKDIR "/usr/spool/uucp/LCK" */
/* #define LOCKDIR "/var/spool/lock" */
/* #define LOCKDIR "/var/lock" */


policy.hを編集したら、以下の手順でビルドします。

linux$ ./configure --prefix=/usr/local
linux$ make
linux$ sudo make install

UUCPの設定


/usr/local/conf/uucpディレクトリを作成して、アーカイブのsamplesにあるファイルをコピーします。以降、この/usr/local/conf/uucpディレクトリで作業を行います。

linux$ sudo mkdir /usr/local/conf/uucp
linux$ sudo cp samples/* /usr/local/conf/uucp/
linux$ cd /usr/local/conf/uucp

続いて、コピーしたファイルのうち、configファイルを編集します。
まず、nodenameという項目を探してサイト名を定義します。今回はcentos6とします。 また、スプールディレクトリのデフォルトが/usr/spoolになっているのですべて/var/spoolに書き換えます。 以下に編集内容のdiffを示します。

linux$ diff -u ./sample/config /usr/local/conf/uucp/config 
--- ./sample/config	2003-05-29 15:08:48.000000000 +0900
+++ /usr/local/conf/uucp/config	2014-03-05 00:04:24.494808788 +0900
@@ -20,12 +20,14 @@
 # you want to use, you do not need to set the name in this file.
 # Otherwise uncomment and edit the following line.
 # nodename uucp				# The UUCP name of this system
+nodename centos6				# The UUCP name of this system
 
 # The default spool directory is set in policy.h (the default is
 # /usr/spool/uucp).  All UUCP jobs and status information are kept in
 # the spool directory.  If you wish to change it, use the spool
 # command.
 # spool /usr/spool/uucp			# The UUCP spool directory
+spool /var/spool/uucp			# The UUCP spool directory
 
 # The default public directory is set in policy.h (the default is
 # /usr/spool/uucppublic).  Remote systems may refer to a file in this
@@ -34,6 +36,7 @@
 # of.  If you wish to change the public directory, use the pubdir
 # command.
 # pubdir /usr/spool/uucppublic		# The UUCP public directory
+pubdir /var/spool/uucppublic		# The UUCP public directory
 
 # The names of the UUCP log files are set in policy.h.  The default
 # names depend on the logging option you have chosen.  If
@@ -43,8 +46,11 @@
 # /usr/spool/uucp/Debug.  These file names may be set by the following
 # commands.
 # logfile /usr/spool/uucp/Log		# The UUCP log file
+logfile /var/spool/uucp/Log		# The UUCP log file
 # statfile /usr/spool/uucp/Stats	# The UUCP statistics file
+statfile /var/spool/uucp/Stats	# The UUCP statistics file
 # debugfile /usr/spool/uucp/Debug	# The UUCP debugging file
+debugfile /var/spool/uucp/Debug	# The UUCP debugging file
 
 # uuxqt is the program which executes UUCP requests from other
 # systems.  Normally one is started after each run of uucico, the
linux$ 


続いて、sysという名前で以下の内容でファイルを作成します。

call-login *
call-password *
local-send /
remote-send /
local-receive /
remote-receive /
time any
system unixv7
port TCP
address 127.0.0.1
protocol g

これもセキュリティについての考慮は全くなしです。
続いて、callファイルにUNIX V7に接続しに行くときの接続先サイト名、ユーザ名、パスワードを定義します。以下の行を追加します。

unixv7 uucp !uucp ← 前回の記事でUNIX V7側のuucpユーザのパスワードとして設定した文字列

続いて、portファイルを開いて、以下の記述を追加します。

port TCP
type tcp
service 4096 ← UNIX V7にtelnet接続する際のポート番号を指定します。

スプールディレクトリの作成


linux側でもuucp用のスプールディレクトリの作成を行います。
linux$ su -
linux# mkdir /var/spool/uucp
linux# mkdir /var/spool/uucppublic
linux# chown uucp:uucp /var/spool/uucp
linux# chown uucp:uucp /var/spool/uucppublic

設定の確認


uuchkコマンドを実行してエラーが出ていないか確認します。 ここまで設定した後のuuchkの出力結果は以下のようになりました。

linux$ uuchk
config file: /usr/local/conf/uucp/config
sys file: /usr/local/conf/uucp/sys
port file: /usr/local/conf/uucp/port
dial file: /usr/local/conf/uucp/dial
dialcode file: /usr/local/conf/uucp/dialcode
passwd file: /usr/local/conf/uucp/passwd
call file: /usr/local/conf/uucp/call
Local node name centos6
Spool directory /var/spool/uucp
Public directory /var/spool/uucppublic
Lock directory /var/spool/uucp
Log file /var/spool/uucp/Log
Statistics file /var/spool/uucp/Stats
Debug file /var/spool/uucp/Debug
Global debugging level 
uucico -l will strip login names and passwords
uucico will strip UUCP protocol commands
Start uuxqt once per uucico invocation

System: unixv7
 When called using any login name
 Call out using port TCP
 The possible ports are:
  Port name TCP
   Port type tcp
   TCP service 4096
   Characteristics: eight-bit-clean reliable end-to-end fullduplex
 Remote address 127.0.0.1
 Chat script "" \r\c ogin:-BREAK-ogin:-BREAK-ogin: \L word: \P
 Chat script timeout 10
 Chat script incoming bytes stripped to seven bits
 Login name uucp
 Password !uucp
 At any time may call if any work
 May retry the call up to 26 times
 May make local requests when calling
 May make local requests when called
 May send by local request: /
 May send by remote request: /
 May accept by local request: /
 May receive by remote request: /
 May execute rnews rmail
 Execution path /bin /usr/bin /usr/local/bin
 Will leave 50000 bytes available
 Public directory is /var/spool/uucppublic
 Will use protocols g


uucpコマンドによるファイルコピー(linux>UNIX V7)


ここまで設定すればuucpコマンドでファイルがコピーできるようになります。
Linuxからファイルをコピーするときは以下のようにします。

linux$ uucp /usr/local/conf/uucp/passwd 'unixv7!/tmp/passwd'

コピー先の指定方法は’相手先サイト名!ファイル名’となります。
ここで、uucpコマンドでファイルをUNIX V7にコピーできるのは、前回の記事に書いた通り、UNIX V7側で/usr/lib/uucp/USERFILEに定義したユーザだけであることに注意が必要です。定義されていないユーザでuucpを実行した場合、コピー指示は無視され、UNIX V7側の/usr/spool/uucp/LOGFILEに以下のような出力が現れます。

uucp centos6 (3/3-7:2) PERMISSION (DENIED)

uucpコマンドは単にファイルをスプールに貯めるだけで、すぐにコピーされるとは限りません。前回の記事でも書いた通り、UUCPはダイヤルアップ接続を前提にしており、デフォルトでは一度接続した後一定時間経過しないと再接続せず、その間の要求はすべてスプールに貯めておくようになっています。
送信要求がキューにたまっているときは、uustatコマンドを実行した時に以下のように出力されます。

linux$ uustat
unixv7.NON1uU6AAFEC unixv7 user 03-09 00:11 Sending /usr/local/conf/uucp/passwd (936 bytes) to /tmp/passwd


送信が終わるとuustatコマンドの出力は空になります。リトライ待ちの時はuulogコマンドでuucpのログを見たときに以下のように出力されます。
linux$ uulog
(略)
uucico unixv7 - (2014-03-09 00:19:14.25 19601) Retry time not reached

この場合は、uucicoコマンドを手動で実行することで即時に接続を実行させることができます。

linux$ uucico -S unixv7

コピーがうまくいくと、uulogコマンドを実行したときに以下のような出力が得られます。
linux$ uulog
(略)
uucico unixv7 - (2014-03-09 00:29:38.08 19677) Calling system unixv7 (port TCP)
uucico unixv7 - (2014-03-09 00:29:39.53 19677) Login successful
uucico unixv7 - (2014-03-09 00:29:39.69 19677) Handshake successful (protocol 'g' sending packet/window 64/3 receiving 64/7)
uucico unixv7 user (2014-03-09 00:29:39.77 19677) Sending /usr/local/conf/uucp/passwd (936 bytes)


UNIX V7側には、/usr/spool/uucp/LOGFILESに以下のような出力が現れます。
uucp centos6 (3/6-23:32) REQUESTED (S /usr/local/conf/uucp/passwd /temp/passwd user)
user centos6 (3/6-23:32) COPY (SUCCEEDED)


uucpコマンドによるファイルコピー(UNIX V7>linux)


UNIX V7からファイルをコピーするときも、同様にuucpコマンドを使います。

unixv7# uucp /usr/src/games/quiz.c 'centos6!/tmp/quiz.c'

ただし、UNIX V7からはLinux側に接続しに行くことができないので、UNIX V7側でuucpコマンドを実行した後に、linux側から上で書いたuucicoコマンドの手動実行により接続を行います。このタイミングでUNIX V7のキューにたまっていたファイルがLinux側に引き取られます。
送信がうまくいくと、UNIX V7の/usr/spool/uucp/LOGFILEに以下のような出力が得られます。
root centos6 (3/6-22:56) REQUEST (S /usr/src/games/quiz.c /tmp/quiz.c root)
root centos6 (3/6-22:56) REQUEST (SUCCEEDED)


一方、Linux側には以下のようなログが得られます。

uucico unixv7 - (2014-03-08 23:52:25.38 19303) Calling system unixv7 (port TCP)
uucico unixv7 - (2014-03-08 23:52:25.59 19303) Login successful
uucico unixv7 - (2014-03-08 23:52:25.72 19303) Handshake successful (protocol 'g' sending packet/window 64/3 receiving 64/7)
uucico unixv7 root (2014-03-08 23:52:25.90 19303) Receiving /tmp/quiz.c
uucico unixv7 - (2014-03-08 23:52:26.75 19303) Protocol 'g' packets: sent 5, resent 0, received 104
uucico unixv7 - (2014-03-08 23:52:26.80 19303) Call complete (1 seconds 6339 bytes 6339 bps)


uucp使用時の注意事項


UUCPで送信できるのはテキストファイルのみです。バイナリファイルはuuencodeでエンコードして送信することになるのですが、UNIX V7にはデフォルトではuuencodeやuudecodeはありません。そのためどこかからソースを持ってきてコンパイルする必要がありますが、まだ試してはいません。

[関連記事]





ランキングに参加してみました。クリックしていただければ嬉しいです。

にほんブログ村 IT技術ブログ IT技術メモへ
にほんブログ村

パソコン ブログランキングへ

拍手[0回]



4/27(木)〜5/7(日)の間はChromium OS カスタムビルドに関する活動をおやすみいたします。期間中にお問い合わせをいただいても対応はできません。
2014/03/08 (Sat) 21:55
simhで動かしているUNIX V7にホストOSのLinuxからファイルを持っていきたいときに、いちいちテープイメージを作るのは面倒くさいので、今回はUUCPでファイルを転送できるようにしてみたいと思います。

UNIX V7の時代はまだTCP/IP自体が存在していなかったそうです。UUCPはTCP/IPによるインターネット接続が一般化する前に使われていた通信方法だそうで、UNIX V7にはデフォルトでUUCPを動かすために必要なプログラムが含まれています。私はUUCPの現役時代は雑誌記事で読んだ程度でほとんど知りません。今回はそれを試してみようと思います。

UUCPの時代は、電話回線経由でダイヤルアップによりコンピュータどうしを接続していたようです。
ただ、simhのPDP-11エミュレータではダイヤラーなどの自分から外部に接続しに行くためのデバイスがサポートされていません。そのため、今回はsimhのUNIX V7は着信専用とし、ホストOSのLinux側からUUCP Over TCP/IPで無理やりUNIX V7につなぎに行くようにしてみます。相手がエミューレーターだからできる技ですね。はっきり言って邪道ですが、まあ良しとします。
残念ながらUNIX V7どうしでのUUCP接続は発信用デバイスがないので断念しました。

着信専用といってもUNIX V7からLinuxにファイルを送ることができないわけではなく、Linuxから接続があった時にキューにたまっているファイルをUNIX V7からLinuxに送信することもできるようになっています。

<UNIX V7側の設定>


まず、前提条件として、こちらの記事で書いた手順で外部からtelnetで接続できるようにしておく必要があります。
(DC11を使った場合はうまく通信できませんでした。DZ11を使う方法でのみ確認しています)
telnet接続できるようになったら以下の手順でUNIX V7側の着信設定を行います。

ユーザuucpの設定


UUCP接続では、Linux側のuucicoというプログラムがUNIX V7に自動でtelnetで接続し、ユーザuucpでログインしてきます。このuucpユーザのシェルをやはりuucicoにすることでuucicoどうしで会話しながらファイルを送受信する、という形態になります。
UNIX V7にはデフォルトでユーザuucpが存在していますが少し手直しします。まず、ユーザuucpのパスワード設定を行います。

# passwd uucp
New password:  ← 今回は!uucpとした
Retype new password:
#

また、/etc/passwdにはデフォルトでシェルのパスとしてuucicoが設定されていますが、パスが実際と食い違っているので直します。

# ed /etc/passwd
154
5
uucp:y/Rxa0fP2UtmA:4:4::/usr/lib/uucp:/usr/lib/uucico ← lib/の後にuucp/が必要
5s/uucico/uucp\/uucico/
5
uucp:y/Rxa0fP2UtmA:4:4::/usr/lib/uucp:/usr/lib/uucp/uucico
w
159
q
# 


スプールディレクトリの作成


UUCPでは、送受信するファイルを一時的にためておくためのスプールディレクトリが必要になります。このスプールディレクトリのパスはハードコーディングされているため、その場所に作ります。アクセスするのはuucpユーザなのでオーナーの変更も行います。

# mkdir /usr/spool/uucp
# chown uucp /usr/spool/uucp

なお、スプールディレクトリのパスを変更するためには/usr/src/cmd/uucp/uucp.hを修正してUUCP関連のプログラムをリビルドする必要があります。今回は面倒なのでやりません。

リモートサイトの定義


uucp関連の設定ファイルは/usr/lib/uucpにあります。ここのL.sysに以下の行を追加して、接続してくるLinuxホストの定義を行います。

centos6 Any tty00 9600 tty00 login uucp assword: uucp

一番左の"centos6"がリモートサイトの名前になります。
次のAnyはいつでも呼び出し可であることをあらわします。当時のUUCPはダイヤルアップ接続がメインであったため、電話代節約の観点で接続時間を限定する、ということがあったようです。今回は関係ないのでAnyにしています。
あとはtty00を使って9600ボーでやり取りする、という意味になるようです。さらに後ろのlogin~は、UNIX V7から別マシンに接続しに行くときに必要になる設定です。具体的には、loginという文字列を受け取ったらuucp送信し、assword:という文字列を受け取ったらuucpを送信する、という意味のようです。要するに相手に接続する際のログインシーケンスです。今回UNIX V7側は着信専用なので、L.sysにもとからある設定をそのままパクっています。

リモートユーザのアクセス権定義


続いて/usr/lib/uucp/USERFILEを編集して、Linux側のユーザのアクセス権を設定します。このファイルに定義されているLinuxユーザだけがUNIX V7にファイルを送信できるようになります。ここにいう「Linuxユーザ」はuucpコマンドでUNIX V7にファイルを送信しようとするユーザを指します。とりあえずは以下の行を追加します。

user,centos6 /

とすると、リモートサイトcentos6のユーザuserが/配下のどこにでもアクセスできるということになります。userは実在のユーザで適宜読み替えてください。実際の運用ではこんな危ない設定はしないと思いますが、まあ、今回は試すだけなので良しとします。
ただし、処理するのはUNIX V7のuucpユーザなので、uucpユーザがアクセスできないところには読み書きできないはずです。

動作確認


ここまで設定したら動作確認します。
UNIX V7にtelnetで接続し、ユーザuucpでログインします。このとき、LinuxのGNOMEやKDEの端末プログラムではなく、WindowsのTeratermなど、外部から接続するようにするのがベストです。(理由は後述します)。

Connected to the PDP-11 simulator DZ device, line 0


login: uucp
Password: ← uucpのパスワード。今回は!uucp
Shere  ←これが表示されるか確認する

この"Shere"が表示されたら、以下のようにタイプします。

(Ctrl+P)Scentos6(Ctrl+Space)

これは接続元のサイト名がcentos6であることを表します。これを入力して

ROKPg

と表示されれば通信ができています。これは接続が許可され、gプロトコルで通信を行います、という意味です。
 
ここで、LinuxのGNOMEやKDEだと、Ctrl+Spaceが日本語入力に割り当てられていることがあり、それだとうまく動作確認ができません。いちいち設定を変えるのも面倒ですので、外部から試すのがお手軽です。

最後に

(Ctrl+P)(Ctrl+H)(Ctrl+Space)

とタイプすると通信が切断されます。

simh起動ファイルの設定

  
いったんUNIX V7を終わらせて、起動ファイルを修正します。

set dz 8b lines=32 ← 7bを8bに変更

7bを8bに変えることで通信中にトップビットがクリアされるのを抑止します。ただし、telnetで外部から接続しようとすると文字化けが起きるようになります。
長くなったのでここでいったん切ります。次はLinux側の設定について書きます。


[関連記事]



ランキングに参加してみました。クリックしていただければ嬉しいです。

にほんブログ村 IT技術ブログ IT技術メモへ
にほんブログ村

パソコン ブログランキングへ

拍手[0回]



4/27(木)〜5/7(日)の間はChromium OS カスタムビルドに関する活動をおやすみいたします。期間中にお問い合わせをいただいても対応はできません。
2014/03/01 (Sat) 22:52
ここまでsimhのPDP-11エミュレータにUNIX V7をインストールしてきましたが、やはり気になるのは日付関連です。

起動直後の状態はこんな感じになっています。

# date
Thu Sep 22 05:47:43 EDT 1988

これを修正しようとするとこうなります。
# date 1403011921
Sun Mar  1 19:21:00 EST 1970
# 

1970年に戻ってしまいました。いわゆる2000年問題というやつですね。 また、タイムゾーンがEST(アメリカの東部標準時)になっているのも気になります。
今回はこの辺を直してみようと思います。

まず、OSのタイムゾーンの変更を行います。UNIX V7でタイムゾーンを変更するためには、ソースを修正したうえでカーネルを再構築する必要があります。修正するソースコードは/usr/sys/h/param.hです。今使っているSoftware Kitの環境では/mnt/usr/sys/h/param.hにあります(こちらの記事参照)。中身はこんな感じです。

# cat param.h
 
/*
 * tunable variables
 */

#define NBUF    29              /* size of buffer cache */
#define NINODE  200             /* number of in core inodes */
#define NFILE   175             /* number of in core file structures */
#define NMOUNT  8               /* number of mountable file systems */
#define MAXMEM  (64*32)         /* max core per process - first # is Kw */
#define MAXUPRC 25              /* max processes per user */
#define SSIZE   20              /* initial stack size (*64 bytes) */
#define SINCR   20              /* increment of stack (*64 bytes) */
#define NOFILE  20              /* max open files per process */
#define CANBSIZ 256             /* max size of typewriter line */
#define CMAPSIZ 50              /* size of core allocation area */
#define SMAPSIZ 50              /* size of swap allocation area */
#define NCALL   20              /* max simultaneous time callouts */
#define NPROC   150             /* max number of processes */
#define NTEXT   40              /* max number of pure texts */
#define NCLIST  100             /* max total clist size */
#define HZ      60              /* Ticks/second of the clock */
#define TIMEZONE (5*60)         /* Minutes westward from Greenwich */
#define DSTFLAG 1               /* Daylight Saving Time applies in this locality */
#define MSGBUFS 128             /* Characters saved from error messages */
#define NCARGS  5120            /* # characters in exec arglist */
(略)

ここの#define TIMEZONEで指定している値を日本時間に直します。
また、DSTFLAGでサマータイムの設定をしています。日本で使う場合は必要ないのでここを0に変えます。修正後は以下のようになります。
#define TIMEZONE (-9*60)                /* Minutes westward from Greenwich */
#define DSTFLAG 0               /* Daylight Saving Time applies in this locality

修正を行ったらカーネルを再構築します。このとき、makeだけではだめで、make allしてからmakeします。
# cd /mnt/usr/sys/conf
# make all
cd ../sys; cc -c -O *.c; mklib; rm *.o
acct.c:
(略)
# make
as -o mch.o mch0.s mch.s
ld -o unix -X -i l.o mch.o c.o ../sys/LIB1 ../dev/LIB2
#

とりあえずこれでOSは日本時間で動くようになりましたが、今のままではタイムゾーン表示ができません。タイムゾーンの表示のための処理は/usr/src/libc/gen/timezone.cにあります。
カーネルソースと違い、ライブラリやコマンドのソースはもとから入っています。 中身をみるとアメリカの各地区とGMTしかタイムゾーンの定義が入っていません。
# cd /usr/src/libc/gen
# cat timezone.c

/*
 * The arguments are the number of minutes of time
 * you are westward from Greenwich and whether DST is in effect.
 * It returns a string
 * giving the name of the local timezone.
 *
 * Sorry, I don't know all the names.
 */

static struct zone {
        int     offset;
        char    *stdzone;
        char    *dlzone;
} zonetab[] = {
        4*60, "AST", "ADT",             /* Atlantic */
        5*60, "EST", "EDT",             /* Eastern */
        6*60, "CST", "CDT",             /* Central */
        7*60, "MST", "MDT",             /* Mountain */
        8*60, "PST", "PDT",             /* Pacific */
        0, "GMT", 0,                    /* Greenwich */
        -1
};
(略)

これではどうしようもないのでタイムゾーンの定義に日本時間を表すJSTを追加します。
(略)
static struct zone {
        int     offset;
        char    *stdzone;
        char    *dlzone;
} zonetab[] = {
        4*60, "AST", "ADT",             /* Atlantic */
        5*60, "EST", "EDT",             /* Eastern */
        6*60, "CST", "CDT",             /* Central */
        7*60, "MST", "MDT",             /* Mountain */
        8*60, "PST", "PDT",             /* Pacific */
        -9*60, "JST", 0,   ← 追加
        0, "GMT", 0,                    /* Greenwich */
        -1
};
(略)

これでソースを再コンパイルします。
# cc -c -O timezone.c

timezoneはlibc.aの一部なので、作成したオブジェクトでlibc.aの中身を置き換えます。
# cd /lib
# cp libc.a libc.a.org
# ar r libc.a /usr/src/libc/gen/timezone.o

最後はdateコマンドの修正です。ソースは/usr/src/cmd/date.cです。問題の処理はgtime()関数にあり、入力された年を無条件で1900年代と扱うようになっています。今回はとりあえず年の値が50以下だったら2000年代と扱うようにします。
(略)
gtime()
{
(略)
        if (hour==24) {
                hour=0; day++;
        }
        if (hour<0 hour="">23)
                return(1);
        timbuf = 0;
        /* fix y2k */
        /*year += 1900;*/  ← ここを修正
        if (year > 50){
                year += 1900;
        }
        else{
                year += 2000;
        }
        /* fix y2k end */
        for(i=1970; i<year; i++)
                timbuf += dysize(i);
        /* Leap year */
        if (dysize(year)==366 && month >= 3)
                timbuf++;
        while(--month)
                timbuf += dmsize[month-1];
        timbuf += day-1;
        timbuf = 24*timbuf + hour;
        timbuf = 60*timbuf + mins;
        timbuf = 60*timbuf + secs;
        return(0);

}


これをコンパイルして/bin/dateを置き換えます。
# cd /usr/src/cmd
# cc -o date date.c
# mv /bin/date /bin/date.org
# cp ./date /bin/

最後にカーネルを置き換えてリブートします。
# cp /mnt/usr/sys/conf/unix /unix
# sync;sync;sync;
# (Ctrl-E)

リブート後のコマンド実行結果はこんな感じです。
# date 1403012025
Sat Mar  1 20:25:00 JST 2014
# date
Sat Mar  1 20:25:02 JST 2014
# date -u
Sat Mar  1 11:25:07 GMT 2014

date -uは日時をGMTで表示します。9時間差なのでうまくいったようです。
ほかにも2000年問題はあると思いますが、気になったら対処するということで今回はここまで。
 
  
[関連記事]



ランキングに参加してみました。クリックしていただければ嬉しいです。

にほんブログ村 IT技術ブログ IT技術メモへ
にほんブログ村

パソコン ブログランキングへ

拍手[0回]



4/27(木)〜5/7(日)の間はChromium OS カスタムビルドに関する活動をおやすみいたします。期間中にお問い合わせをいただいても対応はできません。
2014/02/23 (Sun) 23:08
前回はsimhのサイトで配布されているSoftware kitのUNIX V7を外部からtelnetで接続できるようにしましたが、今回は、こちらの記事でテープイメージからインストールしたUNIX V7を外部からtelnetできるようにしてみます。

前回は通信用デバイスとしてDZ11 Terminal Multiplexerを使いましたが、今回はDC11 Additional Terminal Interfacesを使います。

DZ11は使えるようにするためにmkconfへのパッチが必要でしたが、DC11はパッチの必要がありません。また、テープイメージからインストールしたUNIX V7には最初からカーネルソースが含まれているので、Linux側ではほとんど作業がありません。前回よりも手間がかからずに済みます。

ということで、今回はおもむろにUNIX V7を起動して作業を始めていきます。

linux$ pdp11 UV7.ini 

PDP-11 simulator V3.9-0
Disabling XQ
boot
Boot
: hp(0,0)unix
mem = 177344
# (Ctrl-D)
RESTRICTED RIGHTS: USE, DUPLICATION, OR DISCLOSURE
IS SUBJECT TO RESTRICTIONS STATED IN YOUR CONTRACT WITH
WESTERN ELECTRIC COMPANY, INC.
WED DEC 31 21:55:37 EST 1969

login: root
Password:
You have mail.
#

カーネルソースは/usr/sys配下にあります。設定作業は/usr/sys/confで行います。ここでmkconfに読み込ませる設定ファイルを作ります。
# cd /usr/sys/conf
# cat > unixconf
3dc
(Ctrl-D)
# cat hptmconf >> unixconf
# cat unixconf
3dc
hp
root hp 0
swap hp 1
swplo 0
nswap 8778
tm

前回はdzとという行を追加しましたが、今回つかうdcでは、複数回線使う場合は先頭に回線数を指定する必要があります。今回は3回線分用意するので3dcとします。 また、Software Kitと今回とでは磁気ディスクの種類が違うので、後から追加するファイルも別のものになります。 では、作成した設定ファイルを使ってカーネルを再構築します。
# rm *.o
# mkconf < unixconf
console at 60
clock at 100
clock at 104
parity at 114
tm at 224
hp at 254
dc at 300
dc at 310
dc at 320
# make
as - -o l.o l.s
as -o mch.o mch0.s mch.s
cc  -c c.c
ld -o unix -X -i l.o mch.o c.o ../sys/LIB1 ../dev/LIB2
# 
 

makeconfの出力でdcが3つ作られていることがわかります。 続けて、接続用の/dev/tty??を作っていきます。まず、c.cの内容を確認してdcのメジャー番号を調べます。
# cat c.c
(略)
        dcopen, dcclose, dcread, dcwrite, dcioctl, nulldev, dc11,       /* dc = 3 */


dcのメジャー番号はこの例では3です。ではこれでデバイスファイルを作っていきます。dcを3つ作ったので作るファイルの数も3つにします。
# cd /dev
# /etc/mknod tty00 c 3 0
# /etc/mknod tty01 c 3 1
# /etc/mknod tty02 c 3 2
# 

続けて/etc/ttysを編集してtty00~02を使用可能にします。
# cat /etc/ttys
14console
00tty00   ←
00tty01   ← この3行の先頭を00から13に変える
00tty02   ←
00tty03
00tty04
00tty05
(略)
# ed /etc/ttys
266
2,4s/00/13/  ←2~4行目の先頭を13に書き換え
w      ←編集結果を書き出し
266
q      ←ed終了
# cat /etc/ttys
14console
13tty00
13tty01
13tty02
00tty03
00tty04
00tty05
(略)

前回は12tty??としたのですが、DC11の場合は接続時に"line hangup"というエラーが出て接続できませんでした。13とするのが一番レスポンスが良いようです。

これで準備ができたので、カーネルをルートにコピーしていったん終わらせます。以前のカーネルはコピーして残しておきます。
# cp /unix /unix.old
# cp /usr/sys/conf/unix /
# sync;sync;sync
# (Ctrl-E)
Simulation stopped, PC: 002306 (MOV (SP)+,177776)
sim> q
Goodbye
linux$ 

simhの起動ファイルを書き換えてdcが使えるようにします。dcは入力はdci、出力はdcoと別々のパラメータを使って設定していきます。
linux$ cat UV7.ini
set cpu 11/45
set cpu 256k
set rp0 RP04
att rp0 rp04-0.dsk
set dci en    ← dcを有効にする
set dci lines=3  ← 回線数3
set dco 7b    ← 出力時に先頭ビットをクリア(7bitに)する
att dci 20023  ← 待ち受けポートの指定
boot rp0


dcはデフォルトでは無効になっているため、set dci enとしてデバイスを有効にしないと機能しません。set dco 7bを指定しないと時々文字化けするみたいです。この設定ファイルを使ってUNIX V7を起動します。
linux$ pdp11 UV7.ini 

PDP-11 simulator V3.9-0
Disabling XQ
Listening on port 20023 (socket 5)
boot
Boot
: hp(0,0)unix
mem = 176384
# (Ctrl-D)
RESTRICTED RIGHTS: USE, DUPLICATION, OR DISCLOSURE
IS SUBJECT TO RESTRICTIONS STATED IN YOUR CONTRACT WITH
WESTERN ELECTRIC COMPANY, INC.
WED DEC 31 23:47:25 EST 1969

login: root
Password:
You have mail.
#


無事起動したので外部から接続してみます。

うまく接続できました。

今回はここまで。

[関連記事]



ランキングに参加してみました。クリックしていただければ嬉しいです。

にほんブログ村 IT技術ブログ IT技術メモへ
にほんブログ村

パソコン ブログランキングへ

拍手[0回]



HOME   1  2 
プロフィール
HN:
zui
性別:
非公開
PR
忍者カウンター
忍者ブログ [PR]