FreeBSD おまけページ
Last Update (1998/03/25 07:01:21)
waveファイル再生
ものすごーく手抜きなwaveファイル再生プログラム。
/dev/dspWは、16bitのサンプリングデータを扱うデバイスなので、そこにファイルを
catで流し込むだけのプログラム。
サンプリングレートは22.1KHzに固定で、しかもwaveファイルのRIFFヘッダもそのまま再生してしまうという恐怖プログラムある。
詳細はソースを見てね。
/*-----------------------------------------------------------------
* waveplay.c
* original programed by oki(Oki, Masaru)
* little modified by george(Obama, Jun)
*/
#include <sys/ioctl.h>
#include <machine/soundcard.h>
#include <errno.h>
#include <unistd.h>
main(int argc, char *argv[], char *envp[])
{
int f = open("/dev/dspW", 2);
unsigned int i = 22050;
if (ioctl(f, SOUND_PCM_WRITE_RATE, &i))
perror("ioctl 1");
i = 1;
if (ioctl(f, SNDCTL_DSP_STEREO, &i)) {
perror("ioctl 2");
}
close(1);
if (dup(f) != 1)
perror("dup");
execve("/bin/cat", argv, envp);
}
FreeBSDページの目次に戻る
waveファイル録音
究極手抜きサンプリングプログラム。
適当に/dev/dspWを設定した後、いきなりサンプリングを開始して、停止方法はCTRL-Cだけという恐怖プログラム。
詳細はソースを見てね。
/*-----------------------------------------------------------------
* waverec.c
* original programed by oki(Oki, Masaru)
* little modified by george(Obama, Jun)
*/
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/cdio.h>
#include <machine/soundcard.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
main(int argc, char *argv[], char *envp[])
{
unsigned int i = 22050;
char *av[] = { "wavrec (cat)", 0};
int fd;
fd = open("/dev/dspW", 0);
i = 22050;
if (ioctl(fd, SOUND_PCM_WRITE_RATE, &i))
perror("ioctl 1");
i = 1;
if (ioctl(fd, SNDCTL_DSP_STEREO, &i)) {
perror("ioctl 2");
}
close(0);
if (dup(fd) != 0)
perror("dup0");
if ((fd = open(argv[1], O_CREAT | O_TRUNC | O_WRONLY, 0644)) < 0)
perror("open");
close(1);
if (dup(fd) != 1)
perror("dup1");
execve("/bin/cat", av, envp);
}
FreeBSDページの目次に戻る
光磁気ディスクデバイスドライバへの差分(2.1.0R)
かなり手抜きな差分。
FreeBSD 2.1.0Rで光磁気ディスク(MO)を利用する場合、標準ではデバイスドライバが無いため、od-driver-2.1.0R-PL3.tar.gzを利用する。
さて、オリンパス3.5MOドライブの中で、1Mバイトのキャッシュを持つドライブでは、ファームウェアにバグがあり、1Mバイトのキャッシュがあふれた場合、SCSIバスを占有してしまう。
このため、大量に書き込むとSCSIバスを占有してしまい、FreeBSDがカーネルパニックを起こすという問題がある。
この現象を回避するため、以下の差分を作成した。
この差分は、FreeBSD 2.1.0R用のod-driver Patch Level 2/3 をすこし改
造し、オリンパスのドライブでキャッシュを1M持っているドライブで
もカーネルパニックを起こさないようにしている。
変更点は、/usr/src/sys/scsi/od.cのodattach関数の内部でSCSIコマン
ドのMODE SELECTのページコード0x08を使って、MOドライブのREAD/WRITEキャッ
シュをオフにしている。
WRITEキャッシュのオフは、オリンパスのMOドライブに内蔵されている1Mのキャッシュがあふれた際にSCSIバスを占有されるのを防ぐ効果がある。
FreeBSDページの目次に戻る
Netscapeのキャッシュからファイルを取り出すperlスクリプト nesuke.pl
Netscape 4.04 for BSDI 1.1のディスクキャッシュからオリジナルファイルを取り出すスクリプト nesuke.pl を作成してみた。
ファイル名は「ねっとすけーぷ」の略称(?)である「ねすけ」から名前をとった。
(でも、コミュニケーターを略すとコミケになってしまうような気がする...。)
インストール方法は、以下のようになる。
- nesuke.plをどこかにコピー
- chmod +x nesuke.plで実行属性を追加する。
利用方法は、tar like にしてある。
- nesuke.pl --help でヘルプが表示される。
- nesuke.pl t で、キャッシュにあるファイルの一覧が表示される。
- nesuke.pl tv で、ファイルの一覧を詳細に表示する。
- nesuke.pl x で、キャッシュにあるファイルを展開する。
URL中の / は、ディレクトリを作成することに対応する。
- nesuke.pl e で、キャッシュにあるファイルを展開する。
URL中の / は、 _ に変換され、ファイルはカレントディレクトリに展開される。
正式な(?)説明は下記の通り。
- nesuke.pl options [suboptions...] [url regex pattern]
-
- options
-
- t
- キャッシュファイル中のURL一覧を表示する。
- v
- verbose(おしゃべり)モードにする。
- x
- ディスクキャッシュからファイルをディレクトリ付きで展開する。
URL中の / は、ディレクトリを作成することに対応する。
- e
- ディスクキャッシュからファイルをカレントディレクトリに展開する。
URL中の / は、展開ファイル名中の _ に変換される。
- sub options
-
- --help
- ヘルプ表示を行なって終了する。
- --dir [cache dir]
- Netscape Navigatorのキャッシュディレクトリを指定する。
デフォルトでは $HOME/.netscape/cache/ が指定されているものとみなす。
- --debug
- デバッグモードにする。
- --type
- ディスクキャッシュの中で、コンテントタイプがマッチしたファイルのみを展開する。
コンテントタイプは、 text/plain, text/html, image/gif, image/jpg, image/x-bitmap などが多い。
正規表現が利用できる。
- url regex pattern
- ディスクキャッシュの中で、URLが与えられた正規表現とマッチするもののみを展開する。
nesuke.plの技術情報(?)
UNIX版のNetscape Navigatorは、各ユーザーのホームディレクトリに~/.netscape/cacheというディレクトリを作って、その下に一度アクセスしたHTMLファイルやgifファイルを別名で保存している。
~/.netscape/cache/index.dbには、別名ファイルとオリジナルのURLとの対応表があるので、perlのdbmopen関数をつかってデータベースファイルをオープンして、これをもとに一覧の表示やコピーを行っている。
~/.netscape/cache/index.dbがperlのdbmopenで利用できるということを発見したのでnesuke.plを作成したという一発ネタとも言う。(^^;)
FreeBSDページの目次に戻る
iijppp の -background でプロバイダに回線切断させるには(FreeBSD 2.2.2R)
iijpppを使って、特定の時間に自動的にメールなどを取得して回線を切断する方法には、下のものがある。
- ppp -auto で iijppp を起動しておき、ping などでダイヤルアップさせ、 telnet localhost 3000 で close , quit を入力する方法。
ここでは、ppp -background を利用して、特定の時間に自動的にメールなどを取得して回線を切断する方法を検討する。
iijpppを使って、ppp -background dti (dtiはプロバイダDTI用の設定名) などとしてダイアルアップした場合、kill [pppのプロセスID] などとしても電話回線は切断されない。
そこで、電話回線が切断されない理由を探ってみた。
/etc/ppp/ppp.conf で、set debug debug carrier link phase connect lcp として、回線切断部分のデバッグ情報を得る。
インタラクティブモードで接続した場合の回線切断シーケンス(?)部分の /var/log/ppp.log は以下のようになる。
LCP: LayerDown
OsLinkdown: xxx.xxx.xxx.xxx
Phase: Terminate
LCP: SendTerminateReq.
LCP: state change Opend --> Closing
LCP: Received Terminate Ack (2) state = Closing (4)
LCP: state change Closing --> Closed
LCP: LayerFinish
Phase: Dead
PPP Terminated.
ppp -backgournd として、kill で ppp を終了させた場合の/var/log/ppp.log は以下のようになる。
Signal 15, terminate.
LCP: LayerDown
OsLinkdown: xxx.xxx.xxx.xxx
Phase: Terminate
LCP: SendTerminateReq.
LCP: state change Opend --> Closing
PPP Terminated.
インタラクティブモードで close, quit と入力した場合は、ローカルマシンから 「終了要求」を送って、その返事「終了要求承認」を受信してから ppp プロセスが終了している。
一方、kill で終了させた場合は、ローカルマシンから 「終了要求」を送った後に返事を受信せずにpppプロセスが終了している。
-background モードでプロバイダ側から電話回線を切断されないのは、「終了要求承認」を受信していないからではなかろうか。
対策を考えてみる。
- pppプロセスはSIGTERM(signal 15) を受けても終了せずに「終了要求」を送信。「終了要求承認」を受信してから終了する。
SIGTERMを受けても終了しないプロセスというのも不気味だ...。
プロバイダから「終了要求承認」が送られて来なかったら、SIGKILL で殺すしかなくなる。
- pppプロセスはSIGUSR1(signal 30)を受けたら「終了要求」を送信して通常処理を続行。あらためて SIGTERM を受けたら ppp プロセス終了。
安直だが固い線か。
2.の方針で iijppp を改造することにする。
- iijppp-preclose-patch-2.2.1R.diff 1KB
- iijppp-preclose-patch-2.2.2R.diff 1KB
- FreeBSD 2.2.1R/2.2.2R 用の「シグナル SIGUSR1 であらかじめクローズさせる」差分。
インストール方法は、下記のようになる。
- su で root になる。
- cd /usr/src/usr.sbin/ppp として iijppp のディレクトリに移動。
- patch < iijppp-preclose-patch-2.2.1R.diff として差分をあてる。
- make でコンパイル。
- make install でインストールする。
この差分は、コンパイル時オプション HAVE_PRECLOSE_SIGNAL を定義していると動作するようになっている。
利用方法は
- ppp -background dti とかして ppp をバックグラウンド起動。
- メールを取ってくるなどの処理をする。
- kill -SIGUSR1 [pppのプロセス番号] として、あらかじめ close させる。
- プロバイダによって異なるが、5秒くらい待ってからpppに「終了要求承認」を処理させる。
- kill [pppのプロセス番号]として、pppを終了させる。
となるだろう。
自分用の自動メール取得スクリプトはこんなふうにしてみた。
(FreeBSD 2.2.1Rの場合)
#!/bin/sh
ppp -background dti
sleep 5
fetchmail -s &
wait
kill -SIGUSR1 `cat /var/run/ppp.tun0.pid`
sleep 5
kill -SIGTERM `cat /var/run/ppp.tun0.pid`
(FreeBSD 2.2.2Rの場合)
#!/bin/sh
ppp -background dti
sleep 5
fetchmail -s &
wait
kill -SIGUSR1 `cat /var/run/tun0.pid`
sleep 5
kill -SIGTERM `cat /var/run/tun0.pid`
このシェルスクリプトを at 、あるいは crontab などで指定すれば、特定の時間にダイアルアップして自動で処理をさせ、その後に回線切断させることができるだろう。
FreeBSDページの目次に戻る
Copyright(c) 1996,97,98,99,2000,01,02,03,04 George(小濱 純). All rights reserved.
私の作成したページへのリンクはご自由にどうぞ。
このページに間違いや要望などがありましたら
george@yk.rim.or.jp まで御連絡ください。
home:
<george@yk.rim.or.jp>
or
<george@ceres.dti.ne.jp>
(I am using SPAM filter, so please phone me when you wrote mail to me.)