Linux Gazette 2月号増刊
今月のLinux Gazette の内容
nデスクトップのLinux:マルチメディア
nrand()とrandom()を使う
n Merchant Empires:自分のPHP宇宙のコード
nPython (とPerl)を用いる LinuxToday links とLinux Gazette's TOC のダウンロード
nPerlによるハードドライブ緊急消去
nUSB、PCMCLA及びKernel 2,2,18の搭載
nマスターブートレコード(MBR)の消去
n IP スプーフィング
nAOLサーバー内のXML解析

 

デスクトップのLinux:マルチメディア

By Marius Andreiana

 

多くの人が、Linuxはサーバー用だと思っているが、今や、Linuxはデスクトップでもどんどん使われている。

音楽好きの人のため、コンピュータは沢山の曲をハードドライブ又はCD-ROMに収容出来る。それには曲をオーディオCDからコンピュータ・ファイルに変換しなければならない。便利なツールは grip で、 bladeenc (rpm) からダウンロードするとオーディオデータをMP3に変換する。

だがもっと新しい方法がある。 Ogg Vorbis だ。無料だが品質は良い。情報を見るには ここthis article をクリック。

次の RPM : XMMS plugin, encoder and libraries をダウンロードして搭載しoggencをgripのエンコーダとして設定する。手持ちCDをコンピュータ・ファイルにエンコードし、 X Multimedia System で聞く。

X Multimedia System fired up nea

           火に映えるクリスマスツリー

今の曲が終わり近くなったら XMMS plugin for crossfading; を使うと、前の曲が次第に消えて次の曲が現れる。聞きながら絵を描かないか? GNU Image Manipulation Program,がLinux上の最良デジタル技術だ。筆者はデジタルアートはやらないが、Michael Hammelは自分の甥をエイリアンにしてしまった。

at first look, seems a normal hu
but not everything is what it se

 

the Graphics Muse site には沢山のGIMP素材と Linux Artist がある。3Dグラフィックス・プログラムは this articleを参照。歌わせて描かせた次はfestivalで話させる。 無料スピーチシンセサイザだ。いつものように rpmfind がrpmへのリンクを作る。

無料スピーチ認識エンジンはIBM : ViaVoiceから入手出来る。コマンドなどの音声制御は出来るが、文書全部を書き取るのはまだ先の話だ。音楽の他に smpeg で映画もコンピュータで見られる。

'Yes, that is MS Windows', she s

1gb以上を使って320x240解像度では不満足なら、300JMhz以上のプロセッサが要るが、700mb以下で700x400解像度のDivxがある。問題は純正Linuxプレーヤがないことで、avifileはウインドウズDLLを使う。

Project MayoにあるDivxのオープンソースのお陰でLinuxプレーヤも利用出来る。

TVは持っていないが、TVはPCで見ている。遠隔操作もできる。

Tux on TV

TVを予約録画するならMovie Making on your Linux Box.

Linuxデスクトップを楽しむ方法をお教えしよう。ウインドウズとはおさらばだ(On becoming a total Linux userを参照)。英語は不要だ。 GNOME translation project を見れば言葉のサポートが判る。Linuxには新人ならGNOMEの用法を示した筆者の前の文献を見て Linux as a Video Desktopも見られたい。

 

 

rand() と random() を使う

By Ken O. Burtch

 

乱数を使用するプログラムを書くには誤差論、確率論、統計学その他の数学の理解が必要である。乱数はプログラムに予期しない動作をさせる。

本当は無作為でない乱数

コンピュータは「実世界」乱数は使わない。実世界乱数には予期しないバイアスが掛かっていることがあるが、コンピュータはルールと論理的行動に縛られた機械だからだ。

コンピュータは均一分散(つまり無作為だが過剰に無作為でない)の数値を発生する機構に頼る。これは見掛け上繰り返しのない数列を作る数学関数を用いて発生した「準乱数」である。長い間には、全く同じ数列が現れる。

Linux スタンダードC ライブラリ(stdlib.h)は、二つの組み込み乱数機能を持つ。第一は、0と RAND_MAXとの間の無作為integerを返すrand()である。

 printf( " rand() is %d\n", rand() );
 printf( " rand() is %d\n", rand() );
 printf( " rand() is %d\n", rand() );

とタイプすると、rand() は

 rand() is 1750354891
 rand() is 2140807809
 rand() is 1844326400

のように、新規の無作為に抽出された正のintegerを返す。

別の標準ライブラリ関数 random() は正の long integer を返す。Linux では integer と long integer は同じサイズである。random() には後述の別のプロパティがある。

乱数発生には、古い、廃れた方法もある。

 * drand48/erand48 return a random double between 0..1.
 * lrand48/nrand48 return a random long between 0 and 2^31.
 * mrand48/jrand48 return a signed random long.

これは、UNIXの旧式との互換性のため設けられた。

rand()とrandom()は、勿論そのままでは役に立たず、直接呼び出すことは希れである。

0と実際に大きい数との間の数を、実際の問題に適用するため探すことは稀である。rand()を使うには、1と最大値との間のような有用な範囲に尺度を変える必要がある。モジュール(%)演算子がうまく働く。数値を割った時の剰余は、元の数より0と1の間だけ少ない。モジュールに1を加えると探している範囲が示される。

   int rnd( int max ) {

      return (rand() % max) + 1;

   }

この一行関数は、1と定義数との間の数値を返す。rnd(10)は1と10の間、rnd(50)は1と50の間の数を返す。

Linuxマニュアルの rand() は、無作為になり易いので "upper bits"(つまりモジュールでなく除算)を取ることを薦めているが、上記のrnd()の方が殆どの応用に適している。

次のプログラムは1と10の間の数を100回発生し、発生頻度を計数する。完全に均一なら各数値が10回宛現れる筈である。

 int graph[11];
 int i;

 for (i=1; i<=10; i++)
   graph[i] = 0;
 for (i=1; i<=100; i++)
   graph[ rnd(10) ]++;
 printf( "for rnd(), graph[1..10] is " );
 for (i=1; i<=10; i++)
   printf( "%d " , graph[i] );
 printf( "\n" );

このルーチンを走らせて、以下の結果を得た。

 for rnd(), graph[1..10] is 7 12 9 8 14 9 16 5 11 9

Linuxの rand() 関数は高品質乱数の発生に労力を使い過ぎるので費消CPU時間が大きい。中庸品質乱数を多数迅速に発生するには、次のような関数が良い。

unsigned int seed = 0;

int fast_rnd( int max ) {
 unsigned int offset = 12923;
 unsigned int multiplier = 4079;

 seed = seed * multiplier + offset;
 return (int)(seed % max) + 1;
}

この関数の発生する乱数は数学的に一様ではないが迅速に発生する。理想的には、offset とmultiplier を素数にすると、特定の数が他より有利になることがない。

テストファンクションの中のfast_rnd() を持つrndを下記で置き換えてもrand()の良い近似値が得られる

 for fast_rnd(), graph[1..10] is 11 4 4 1 8 8 5 7 6 5

数列の制御

seed は、乱数発生器に与えられて第一乱数を生じる初期値である。初期値を一定にすると同一数値から始まる数列が定まる。例えば、ゲームを書くとき、seedを一定値にして fast_rnd() を用いると、位置情報をセーブしなくても、敵は何時でも同じ位置に現れる。

 seed = room_number;
 num_enemy = fast_rnd( 5 );
 for ( enemy=1; enemy<=num_enemy; enemy++ ) {
   enemy_type[enemy] = fast_rnd( 6 );
   enemy_horizontal[enemy] = fast_rnd( 1024 );
   enemy_vertical[enemy] = fast_rnd( 768 );
 }

Linux rand() 関数用seedは srand()により設定される。例えば、

 srand( 4 );

は rand() seed を4 に設定する。

別のLinux関数random()を用いて数列を制御する方法が二つある。第一は、srandom()で、srand()のようにrandom()のためseedを設定する。

第二は、精度を高くしたいとき、Linuxはrandom()の速度と精度を制御する二つの関数を備えている。initstate()を用いて、random()にseedと関数中間結果保存用バッファを与える事が出来る。バッファの大きさは8, 32, 64, 128 又は 256バイトである。バッファが大きいと精度は上がるが計算時間が長くなる。

 char state[256];         /* 256 byte buffer */
 unsigned int seed = 1;     /* initial seed of 1 */

 initstate( seed, state, 256 );
 printf( "using a 256 byte state, we get %d\n", random() );
 printf( "using a 256 byte state, we get %d\n", random() );
 initstate( seed, state, 256 );
 printf( "resetting the state, we get %d\n", random() );

を実行すると下記が得られる。

 using a 256 byte state, we get 510644794
 using a 256 byte state, we get 625058908
 resetting the state, we get 510644794

seedを特定値に初期化するため、setstate()に続きsrandom() を用いて、random()ステートを切り換えることが出来る。setstate()はポインタを常に以前の状態に戻す。

  oldstate = setstate( newstate );

プログラム開始時にseedを変えない限り、乱数は常に同じになる。乱数列を変えるには、プログラム外から又はユーザー制御でseedを別の値に設定しなければならない。

時刻は常に変わるので、time.hのtime()は良い例である。実行毎に乱数列が変わる。

 srand( time( NULL ) );

リストの無作為化

古典的ゲーム問題の一つは、リストの項目順を無作為に変えることである。例えば0から51の番号のついた52枚のトランプをシャッフルするには、次のようにする。

 int deck[ 52 ];
 int newpos;
 int savecard;
 int i;

 for ( i=0; i<52; i++ )
   deck[i] = i;
 printf( "Deck was " );
 for ( i=0; i<52; i++ )
   printf( "%d ", deck[i] );
 printf( "\n" );
 for ( i=0; i<52; i++ ) {
   newpos = rnd(52)-1;
   savecard = deck[i];
   deck[i] = deck[newpos];
   deck[newpos] = savecard;
 }
 printf( "Deck is " );
 for ( i=0; i<52; i++ )
   printf( "%d ", deck[i] );
 printf( "\n" );

シャッフル前後のトランプ順は

 前は、 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
 後は、35 48 34 13 6 11 49 41 1 32 23 3 16 43 42 18 28 26 25 15 7 27 5 29 44 2 47 38 39 50 31 17 8 14 22 36 12 30 33 10 45 21 46 19 24 9 51 20 4 37 0 40

異なる型の無作為性

統計学に詳しい人は、実生活の出来事が一様なパターンでは起こらない事を知っている。例えば、自動車の最初の大修理は、購入後5年から9年だが、7年が最も多い。

このような出来事は正規分布と言われる頻度で発生する。このように複雑な形状に合致する乱数の発生は難しそうだが、そうでもない。rnd() 関数は均一分布「偶発」事象を発生するので、正規分布乱数の発生に統計学教科書は必要でない。rnd()を数回呼び出して、その平均を取り、正規分布をシミュレートするだけだ。

int normal_rnd( int max ) {
 return (rnd( max ) + rnd( max ) + rnd( max ) + rnd( max ) +
     rnd( max ) + rnd( max ) + rnd( max ) + rnd( max ) ) / 8;

}

このテストファンクションの中の normal_rnd() を用いて、1と最大値との間で分割された数値を得る。

 for normal_rnd(), graph[1..10] is 0 0 4 26 37 23 10 0 0 0

正規乱数は、敵の動きの弾力性を減じてゲームを実際に近くする。

範囲の外側に向かって絞られた数値については、1に近い値を有利にする low_rnd() を作ることが出来る。

 int low_rnd( int max ) {
  int candidate;

  candidate = rnd( max );
  if ( rnd( 2 ) == 1 )
    return candidate;
  else if ( max > 1 )
    return low_rnd( max / 2 );
  else
    return 1;
 }

各回帰において、low_rnd()は範囲を二つに分けて、範囲の下半分を有利にする。

範囲のトップから低い乱数を引いて、最大値に近い値を有利にするhigh_rnd()を作ることが出来る。

 int high_rnd( int max ) {
  return max - low_rnd( max ) + 1;
 }

テストプログラムを用いると絞り込みが容易に見られる。

 low_rnd()について、 graph[1..10] is 36 15 11 8 9 3 4 3 3 8
 high_rnd()について、 graph[1..10] is 4 5 8 5 4 10 6 10 14 34

無作為Ifステートメント

odds()ファンクションを用いて、論理において任意の分岐をおこなうことが出来る。

 int odds( int percent ) {
    if ( percent <= 0 )
     return 0;
    else if ( percent > 100 )
     return 1;
    else if ( rnd( 100 ) <= percent )
     return 1;
    return 0;
 }

この関数は、ifステートメントに組み込まれるのを容易にする規定百分比の時間の間だけtrueである。

if ( odds( 50 ) )
  printf( "The cave did not collapse!\n" )
else
  printf( "Ouch! You are squashed beneath a mountain of boulders.\n" );

スタンダードCライブラリのrand() と random() ファンクションは均一分布乱数を持つプログラムを与える。数列と精度は別のライブラリ関数で制御されるので、数値の分布は簡単な関数で変更することが出来る。乱数は、プログラムに意外性を与え、勿論コンピュータゲームを刺激的にする要素である。

 

 

Merchant Empires: 自分の PHP 宇宙のコード

By Bryan Brunton

 

以下は、Webベースの複数プレーヤ・ロールプレーイング・ゲームMerchant Empiresの創始者であるBryan Bruntonとの対談である。

Q: MEを書いた理由は?

A: 幾つかあります。第一は、宇宙が舞台の戦略ゲームを作りたかったことです。第二は、Space Merchantと言うゲームをプレーして、色々な点で満足出来なかったことです。最も気に入らなかったのは「エラーストームで中断」されることでした。だが同時にSMには啓発されました。

Q: ME 実現に使ったソフトウエアは?

A: ME開発に使った open source ソフトウエアは以下です。

Apache
PHPをサポートするwebserver なら誰でも使えます
PostgreSQL
PHP
PHPLIB
このライプラリはPHPデータベースのアクセスとセッション追跡を簡単にするクラスと提供します
Python
MEの第一バージョンは完全にPythonで書きました。パフォーマンスの点でPHPに乗り換えましたが、MEの一部はPythonのままです
PygreSQL
MEのイベントプロセッサとマップクリエータは、これらのライブラリを使って PostgreSQLサーバー上にあるMEデータを収集し更新します
Medusa Asyncronous Network Libraries
MEのイベントプロセッサにはMedusaを使いました。これらのライブラリはMEに telnetアクセスを提供します
MEのイベントプロセッサとマップクリエータは、これらのライブラリを使って PostgreSQLサーバー上にあるMEデータを収集し更新します
KDevelop
KDevelopは HTML/PHP コード用の偉大なエディタです。Zendから新しいPHP IDEを買うことになるでしょう。
Gimp
殆どすべてのME 画像はこのツールで作成しました

Q: MEプレーヤの多くが、MEサイトは時々安定性が低かった、と言っています。ME開発中に遭遇した問題は?

A: 色々ありました。配布Linux OS自体のスケーラビリティと、Apache やPostgreSQLのようなアプリケーションは脅威的でした。普通の配布CDから平均的PCに搭載された配布(pre-configured)Linuxは中程度の通信量、データベース支援Webサイト (Apache + PHP + PHPLIB + PostgreSQL)、に安定なプラットホームを提供しないと思います。

遭遇した問題は次の通りです(殆どが頭痛の種)

・殆どのLinuxディストロ上の共有メモリ、オープンファイル及びファイルノードの最大量が悲しい程低い
・Apache、PHP 4、PostgreSQLは、pg_pconnect()を使う恒久接続に問題がありました(多分今も)。チャイルドhttp処理が終了したときPHP parser も Apache もデータベース接続を正しくクローズしません
・ReiserFS とPostgreSQL は、-FオプションでPostgreSQLを使うのに、各書込操作に fsyncingがないとの問題がありまた(多分今も)。これはファイルシステムやデータベースを汚染します
・NetGearネットワーク・カードを購入しました。このカードのチューリップ・ドライパは大負荷の下では悲惨な失敗をしす。モノリシック・チューリップ・ドライパは間違いです。再書込すると古いNICが突然止まります。カード全体に一貫して働きません。
・PostgreSQL用のバックグラウンド・マネージャは、検出列を動的に開放しません。これは頻繁に使うテーブルのパフォーマンスに重大な影響を与えます。PostgreSQLの文書には「VACUUMを定期的に動かすとデータベースのユーザー待ち行列処理速度を増す」とありますが、文書は「定期的」の意味を明らかにしていません。高通信量サイトのためデータベースを管理するときPostgreSQLは下り文書を無くするから、Webサーバーの負荷が20なのだと言うことを誰が知っているでしょう。またPostgreSQLはバックエンド処理限度32で出荷されますが、これは中程度通信量のサイトにとっても低過ぎます。
Q: WebブラウザをMEのプレーに開放するため、Quake IIIのような優れたゲームをしまい込むのは一体何故でしょう? 膨大な計算をするためプレーヤのコンピュータ上にCPUが必要としなくなるるとき、ゲームはどのくらい会話的になるでしょう。

A: 敵船が宇宙塵の中にプレーヤを閉じこめたとき、プレーヤがいたい場所は市民権のない無効なHTMLなのは確かです。だがブラウザベースのゲーム環境には、私の認める利点があります。MEを書く前に類似のプロジェクトを沢山調べました。多くは立ち往生しており、デベロッパはプレー出来るゲームを持ないでサーバーとクライアントに手紙を書くのに半年も掛けていました。私は、直ちにゲームコードを書こうと思いました。MEのプレーに共通分母が少ないのが好きです。MEのプレーに必要なのはjavaスクリプトをサポートするWebブラウザだけです。MEは、クライアントに搭載と構成を要求するゲームより遙かに多くの場所からアクセスしてプレーすることが出来ます。良いゲームを作る限り、秒当たりフレームでなく、知的なターンベースのゲームを楽しみます。

Q:MEに関しゲーム産業は沈黙しています。最近、代表的企業にMEについてとMEのようなゲームの市場導入について質問したところ無視されました。MEにどんな商業的関心が示され「死者から復活、BBS2HTML」ゲーム市場の将来を如何お考えですか?

A: 商業的関心はありません。バナー広告は嫌いです。MEを走らせるサイトでは使いません。MEのホスト用に追加帯域幅は買えないと思います(現在友人の768K DSLラインを使用)。MEの帯域幅追加を協賛したい有力組織にはチャンスがあります。DSLは、安い帯域幅を大衆に提供した点では偉いけれども、DSLの信頼性はひどいものです。QWESTのような市場独占会社だけがこんな良い加減なサービスの提供をするのです。

Q: MEはどれ位、普及しましたか?

A: 7,000人以上のユーザーが出来ました。MEには定期的にプレーする百人から二百人位のグループがあります。私の意見では、極端に単純な経済的、政治的モデルのため遊び方が限られています。ここを変えれば伸びるでしょう。海賊行為とプレーヤ殺しを超えたロールプレーイングの可能性は限られています。

MEのホストになることを私は楽しんでいます。何度も使われ沢山のデータを生じるソフトウエアを書くのには、何か爽やかさがあります。データを集めるのも好きです。古いゲームとプレーヤからのデータを削除するときMEデータベースは100メガに達しています。

Q: MEプレーヤが最も楽しんでいるのは何ですか?

A: 殺し合う方法の作戦です。戦闘を含むオンラインゲームでも同じです。MEでは、プレーヤが一方の側に立って銀河征服の目標を目指します。舞台は宇宙です。各種連合軍が作る独裁制から民主制までの組織方法を見るのは楽しいものです。MEプレーヤの多くはプログラマでもあって、開発を助けます。プレーヤはゲームの成長と改良を見るのを楽しみにしています。

Q: MEの改良にどんな計画をお持ちですか?

A: IMO、スケーラブル・ベクトル・グラフィック(SVG)がWebの将来です。SVGは、本質的に Flashをオープンにしたものです。SVGは、XMLやJavaスクリプトのようなオープン標準に基づいているので、もっと強力になる筈です。Linux上のブラウザベースSVGサポートは、 Mozillaで構築したMathML-SVG の中の少ない関数コードに限られているのが不幸です。WindowsとMacの側では、Adoveが良質SVGプラグインを提供しますが、私のデスクトップはLinuxなので、SVGのジレンマに悩んでいます。

MEに入れたいものが少しあります。リアルタイムゲーム情報を提供する java appletを実行したいと思います。コンピュータ制御の宇宙船と惑星も導入したいと思います。最後には、コンピュータ制御Imperium(MEの警察)がゲームと大部分を占めるでしょう。

また、MEのPostgreSQL依存性を消したいと思います。PostgreSQLに反感はありませんが、MEをMySOLで走らせることを求める人がいます。現在、MEのデータベースへはPHPLIBが提供するクラスを通じてアクセスしているので、コードの中の少数のPostgreSQL主義の削除には大して手が掛からないでしょう。

ME2.0では大きい変更を計画しています。多角形ベースマップを作ります(今は正方形)。これにはSVGが必要です。文字通り数百の商品があり契約書ベースの取引が出来る商業モデルにします。別の実体としての港から離れて、港を惑星の特性にします。MEの経験値モデルを技術に基づく進級モデルにします。これらはSourceForgeにあるME Wish Listで論議します。

Q:プレーヤは貴方のコードが吸い込むと言っています。誤解しないで欲しいが賛成です。この対談の前にコードを一覧しましたが、プログラムの情報全部がネットワークループへのコマンドであることに気付きました。

A: MEは私が出来るだけ早く書いたことを考えて下さい。私の方法は簡単です。Space Merchantを見て出来るだけ早くそれを再生します。またMEを書くのは、全く意図的な私自身の学習過程でした。MEの部品はC++、PHP及びPytonを使います。C++の経験はあるが使ったことはなく何も知りません。PHPもPytonもです。これらの言語を習いたいと思いました。CSSの首尾一貫しない用法や戦闘機能性などMEの部品は、未だコンセプト段階のコーディング見地からのものです。イベントプロセッサを書いたとき、私はネットワークループ選択が何かも知りませんでした。今ではそのコンセプトについて学んだことは全部忘れて、コードがまだ働くのを喜んでいるだけです。

Q: つまり貴方のコードは、縁辺で極めて荒っぽいと言うことですね。綺麗にするのに、再帰プログラム技法を使う気はありませんか?

A: 再帰は、正しく使えば、強力なツールですが、使ったことはありません。この記事のため、自分と対談して、再帰の概念を導入すべきだと思ったので、将来考えましょう。

 

 

Python (とPerl)を用いる LinuxToday links と

Linux Gazette's TOC のダウンロード

By Mark Nielsen

内容

1.緒言
2.Pytonスクリプト
3.クロン・ジョブの設定
4.Linux Gazette TOCダウンロードのため書いたPerlスクリプト
5.DebianWeeklyNewsダウンロードのため書いたPerlスクリプト
6.結語
7.参考文献

緒言

私のWebサイトGNUJobs.comにLinux Todayのlinksを別のWebサイトからダウンロードするプログラムをPytonで作った。これにヘッドラインとLG最新版を加える。将来は、同時に沢山のWebサイトからダウンロードする積もり。

プログラム言語でなすべきことは、次のことである。

・Webペイジのダウンロード
・正しく再フォーマットするためデータを分析
・データを再フォーマット
・有効データを含むとき旧ファイルを新ファイルに置換

Python スクリプト

このスクリプトの出力をWebpageにインクルードしたいときは、Apache webserverにあるServer-Side Include (SSI)を使いWebpage内で下記のようなコマンドを用いる。


  <!--#include virtual="/lthead.html" -->


各種プログラミング言語(PHP, Perl ASP, Perl Masonなど)もファイルをインクルード出来る。GNU/Linux OSを使うと仮定する。実行可能にするためにはスクリプト上で


chmod 755 LinuxToday.py


を実行しなければならない。 [Text version of this listing.]


#!/usr/bin/python


# しなければならないのが明白なのはurlダウンロードのためのエラー点検追加である




# ダウンロードには少なくとも一つのエントリが無ければならないが、新ファイルを




# 作ることが出来る。これは後でおこなう


  ### web module, string module, regular expression,  module, os modulを輸入


import urllib, string, re, os


  ### 作成する新webpageと情報入手場所を定義


Download_Location = "/tmp/lthead.html"


Url = "http://linuxtoday.com/backend/lthead.txt"


#-----------------------------------------------------------


  ### Urlのあるwebオブジェクトを作成


LinuxToday = urllib.urlopen( Url )


  ### 全情報補アレーに入れる(大きいときは、一回一行を行うよう変更)


Text_Array =  LinuxToday.readlines()


New_File  = open(Download_Location + "_new", 'w');


New_File.write("<ul>\n") 


  ### デフォルトをInvalidに設定


Valid = 0


  ### 有効エントリ数を記録


Entry_No = 0;


Entry_Valid = 0


  ### デフォルト設定


Date = ""


Link = ""


Header = ""


Count = 0


  ###  mattern matching expressionを作成


Match = re.compile ("^\&\&")


  ### 最終エントリ分析を確認のため && を追加


Text_Array.append('&&')


  ### 行毎に、下記を行う


for Line in Text_Array :


    ### && がある時は、scratchからスタート最終エントリを付加


  if Match.search(Line) :


      ###カレントエントリが有効で第一行を飛ばしているとき


    if (Entry_No > 1) and (Entry_Valid > 0) :


    ### PerlがPythonより良いのはプリントコマンドで、筆者はPython




    ### プリントを好まない(可変内挿がない).


      New_File.write('<li> <a href="' + Link + '">' + Header + '</a>. ' + Date + "</li>\n")


      ## values を nothingにリセット


    Header = ""; Link = ""; Date = ""; Entry_Valid = 0


    Count = 0 


    ### 白紙と行末を削除


  Line = string.rstrip(Line)


    ### カウントが1なら header, 2なら link, 3 ならdate


  if Count == 1:    Header = Line


  elif Count == 2:  Link = Line


  elif Count == 3:  


    Date = Line


      ### 全フィールドを終えたとき、有効エントリを得る  


    if  (Header != "") or (Link != "") or (Date != "") :


      Entry_No = Entry_No + 1


      Entry_Valid = 1  


    ###カウントに1を加える


  Count = Count + 1


New_File.write("</ul>\n")


New_File.close()


  ### 有効エントリがあるときは、新ファイルを実際の場所に移す


if Entry_No > 0 :


  ### os.rename(Download_Location + "_new", Download_Location)
  ### を行えるだけであるが、
  ### 外部コマンドで行う方法を示す
 Command = "mv " + Download_Location + "_new " + Download_Location
 os.system( Command )

夜間走らせるための Cron Script

最良のcrontab ファイルではないが、働く。


#/bin/sh


### Crontab file


### ファイルを "Crontab" と命名して"crontab Crontab"で実行


  ### 二時間毎にダウンロード


*/2 * * * *   /www/Cron/LinuxToday.py >> /www/Cron/out  2>&1  


Linux Gazette TOC ダウンロードのため書いたPerlスクリプト

比較のため、最新版LGの TOCをダウンロードするPerlを書いた [テキスト版.]


#!/usr/bin/perl


# Copyright Mark Nielsen January 20001


# Copyrighted under the GPL license.


system ("lynx --source http://www.linuxgazette.com/ftpfiles.txt > /tmp/List.txt");


  ###ダウンロードしたwebpageを開いてアレーに入れる


open(FILE,'/tmp/List.txt'); my @Lines = <FILE>; close FILE; 


  ### magic 文字を含まない行を篩い分ける


my @Lines = grep(($_ =~ /lg\-issue/) || ($_ =~ /\.tar\.gz/), @Lines );


my @Numbers = ();


foreach my $Line (@Lines)


  {


    ## 左の詰め物を捨てる


  my ($Junk,$Good) = split(/lg\-issue/,$Line,2);


    ## 右の詰め物を捨てる


  ($Good,$Junk) = split(/\.tar\.gz/,$Good,2);


    ## If it is a valid number, it is greater than 1, save it


  if ($Good > 0) {push (@Numbers,$Good);}


  }





   ### 番号をソートして最高に飛ぶ(pop off)


@Numbers = sort {$a<=>$b} @Numbers;


my $Highest = pop @Numbers;


   ## ダウンロードしようとするurlを作る


my $Url = "http://www.linuxgazette.com/issue$Highest/index.html"; 


   ## Download it


system ("lynx --source $Url > /tmp/LG_index.html");


   ### インデクスを開く


open(FILE,"/tmp/LG_index.html"); my @Lines = <FILE>; close FILE;


   ### 始めとTOC終わりとの間にある部分を抽出


my @TOC = ();


my $Count = 0;


my $Start = '<!-- *** BEGIN toc *** -->';


my $End = '<!-- *** END toc *** -->';


foreach my $Line (@Lines) 


  {


  if ($Line =~ /\Q$End\E/) {$Count = 2;}


  if ($Count == 1) {push(@TOC, $Line);}


  if ($Line =~ /\Q$Start\E/) {$Count = 1;}


  }


  ### ポイントへのリンク全部をLinux Gazette magazineに再リンク




my $Relink = "http://www.linuxgazette.com/issue$Highest/";


grep($_ =~ s/HREF\=\"/HREF\=\"$Relink/g, @TOC);


  ###出力をセーブ


open(FILE,">/tmp/TOC.html"); print FILE @TOC; close FILE;


  ### 完了!


Debian Weekly Newsダウンロード用 Perl スクリプト

Debian Weekly Newsを追跡したいので、これも書いた。[テキスト版はここ]


#!/usr/bin/perl


# Copyright Mark Nielsen January 20001


# Copyright under the GPL license.


system ("lynx --source http://www.debian.org/News/weekly/index.html > /tmp/List2.txt");


  ### ダウンロードした webpage を開いてアレーに入れる


open(FILE,'/tmp/List2.txt'); my @Lines = <FILE>; close FILE; 


   ###  始めとTOC終わりとの間にある部分を抽出


my @TOC = ();


my $Count = 0;


my $Start = 'Recent issues of Debian Weekly News';


my $End = '</p>';


foreach my $Line (@Lines) 


  {


  if (($Line =~ /\Q$End\E/i) && ($Count > 0)) {$Count = 2;}


  if ($Count == 1) {push(@TOC, $Line);}


  if ($Line =~ /^\Q$Start\E/i) {$Count = 1;}


  }


  ### ポイントへのリンク全部をDWNに再リンク


my $Relink = "http://www.debian.org/News/weekly/";


grep($_ =~ s/HREF\=\"/HREF\=\"$Relink/ig, @TOC);


grep($_ =~ s/\"\>/\" target=_external\>/ig, @TOC);


  ### 出力をセーブ


open(FILE,">/tmp/D.html"); print FILE @TOC; close FILE;


  ### 完了!


結語

Pythonスクリプトは必要以上に複雑だ。各種モジュールを導入して将来LinuxTodayのフォーマットが変わった時に備えたためだ。このスクリプトで唯一欠けているのはweb pageをダウンロードし新ファイルを書けない時のエラー検出がないことだ。

Pyton を使うのは易しく、Perl の中のLWPよりwebpagesの扱いが容易だ。

参考

1.LinuxToday's links
2.Python's urllib module
1.Original site for this article (更新は全部ここ)
 
 

Perlによるハードドライブ緊急消去

By Mark Nielsen

内容

1.緒言
2.問題の所在
3.Perlスクリプト
4.結語
5.参考

緒言

GNUJobs.comがオハイオ州からカリフォルニア州に移るとき、幾つかのハードドライブをCOLUG (Central Ohio Linux Users Group)に寄付した。寄付前にハードドライブを消去するためこのPerlスクリプトを書いた。

このPerlスクリプトの目的は/dev/hdb (主IDEコントローラ上のスレーブドライブ)にあるハードドライブの消去である。全パーティションを消して全体を一つのパーティションにし、ガベージデータで埋めることであった。

問題点

問題点と解決策を示す。
1.パーティション全部を消去する

選択肢は色々あるが人手が最良だ。昔はPerl Expectスクリプトを用いてfdiskプログラムを自動化したので、これを続けることにした。

ユーザーがfdiskコマンドをタイプするのをシミュレートするExpectコードを用いた。Expectコードが全パーティションを消去し大きいパーティション一つを作った。

2.ハードドライブをガベージデータで満たす

sfdiskで新パーティションの大きさを知り、それが一杯になるまで連続的に、ループでガベージデータを書き込んだ。

3.ハッカーを惑わすためハードドライブにバイナリデータを入れる

Perlの乱数関数と"chr"関数を使って無作為バイナリデータを作り、Perl Blowfishモジュールを使って暗号化した。暗号を解いてもガベージなので惑わされる筈だ。数学的に無作為と見られないように暗号化した。

4.大きいパーティションの再フォーマット

これは簡単。 "mkfs" コマンドを使うだけ。

Perl スクリプト

これに使ったperlは旧版のPerl 5.005_03だが、2001年1月にPerlは5.6の筈。

ユーザーに使い易くするため強調すべき点が多々ある。エラー点検、望み通りになったか聞くためのプロンプトを増やす必要がある。

コードに沢山コメントを付けたので私がしたかったことを、多くのPerlプログラム初心者が理解してくれることを望む。 (このリストのテキスト版はここ)



#!/usr/bin/perl


##### なすべきこと


# 1. 誰かがログインした場合のセキュリティリスクを避けるため




#    一時搭載用の全く新規なディレクトリを作ったことを確認のこと




# 2. 多数のシステムコールを扱うため perl ファンクションを使う


# 3. ハードドライブとフロッピイドライブを自動検出させ、未装着の




#    ハードドライブとフロッピイドライブ上でアクションを実行するだけ




##### 


use strict;


use Expect;


use Crypt::Blowfish;


#-----------------------------------------------


my $Junk;


  ### Primary IDEコントローラ上でドライブをスレーブに設定


my $Drive = "hdb";


  ###  コンピュータに一人加わったと仮定して、




  ###  無作為行動を沢山実行し、それを本当に無作為にするため、




  ### /etc/passwd ファイルから最終行を得る 




my $time = time();


my $Ran = rand($time);


my $Ran = rand(10000000000000);


my $LastLine = `tail -n 1 /etc/passwd`; chomp $LastLine;


$LastLine = substr ($LastLine,0,30);


my $Blowfish_Key = $LastLine . $Ran . $time;


$Blowfish_Key = substr ($Blowfish_Key,0,20);


while (length ($Blowfish_Key) < 56) 


  {


  $Blowfish_Key .= $Ran = rand($time);


  }


$Blowfish_Key = substr ($Blowfish_Key,0,56);


  ### 無作為キイの作成を終わったら、Blowfish Encryption オブジェクトを作る


my $Blowfish_Cipher = new Crypt::Blowfish $Blowfish_Key;


#------------------------------------


system "clear";


print "This will wipe out the hard drive on Drive /dev/$Drive\n";


print "Press enter to continue\n";


my $R = <STDIN>;


  ### 消去するドライブ上に取り付けられたパーティションのリストを入手する




my @Mounted = `df`;


@Mounted = grep($_ =~ /\/dev\/hdb/, @Mounted);


  ### Foreach mounted partition, umount it


foreach my $Mount (@Mounted)


  {


  my ($Partition,$Junk) = split(/\s+/, $Mount,2);


  print "Unmounting $Partition\n";


  my $Result = system ("umount $Partition");


  if ($Result > 0) 


    {


    print "ERROR, unable to umount $Partition, aborting Script, Error = $Result\n";


    exit;


    }


  }


  ### expect scriptを実行、これは人が expect コマンド入力するのをシミュレートする




my $Fdisk = Expect->spawn("/sbin/fdisk /dev/$Drive");


  ### パーティションリストをプリントして取り付けパーティションを入手




print $Fdisk "p\n";


my $match=$Fdisk->expect(30,"Device Boot    Start");


my $Temp = $Fdisk->exp_after();


my @Temp = split(/\n/, $Temp);


  ## パーティションを知らせるラインを入手


my @Partitions = grep($_ =~ /^\/dev\//, @Temp);


  ## 各ラインにつきForeach でパーティションを削除




foreach my $Line (reverse @Partitions)


  {


    ##  /dev/hdbパートと、その番号を入手


  my ($Part,$Junk) = split(/[\t ]/, $Line,2);


  my $No = $Part;


  $No =~ s/^\/dev\/$Drive//;


  print "Deleting no $Drive $No\n";     


    ## コマンドを削除


  print $Fdisk "d\n";    


  $match=$Fdisk->expect(30,"Partition number");


     ## 削除ラインを決定


  print $Fdisk "$No\n";


  $match=$Fdisk->expect(30,"Command (m for help):");


  }


$Fdisk->clear_accum();


  ### パーティションがあれば、変更を書込、無ければ終了




if (@Partitions < 1) {print $Fdisk "q\n"; $Fdisk->expect(2,":");}


else 


  {


  print $Fdisk "w\n";


  $Fdisk->expect(30,"Command (m for help):");


  }


#-------------------------------


  ## ハードドライブのジオメトリを入手


my $Geometry = `/sbin/sfdisk -g /dev/$Drive`;


my ($Junk, $Cyl, $Junk2, $Head, $Junk3, $Sector,@Junk) = split(/\s+/,$Geometry);


if ($Cyl < 1) 


   {print "ERROR: Unable to figure out cylinders for drive. aborting\n"; exit;}


  ### 新xpect スクリプトを作ってfdisk を使う人をシミュレート




my $Fdisk = Expect->spawn("/sbin/fdisk /dev/$Drive");


   #### fdisk に新パーティションを作らせる




print $Fdisk "n\n";


$Fdisk->expect(5,"primary");


  ### 新パーティションは主パーティションであると宣言


print $Fdisk "p\n";


$Fdisk->expect(5,":");


  ### 1番にするパーティション


print $Fdisk "1\n";


$Fdisk->expect(5,":");


  ### シリンダ1からスタート




print $Fdisk "1\n";


$Fdisk->expect(5,":");


  ###  endに行く


print $Fdisk "$Cyl\n";


$Fdisk->expect(5,":");


  ### 書込とセーブ




print $Fdisk "w\n"; 


$Fdisk->expect(30,"Command (m for help):");


#------------------------------------------


### パーティションをフォームして搭載


my $Partition = "/dev/$Drive" . "1";


my $Result = system ("mkfs -t ext2 $Partition");


if ($Result > 0) {print "Error making partition, aborting.\n"; exit;}


   ### ここにエラー点検を入れるのが良い


system "umount /tmp/WIPE_IT";


system "rm -rf /tmp/WIPE_IT";


system "mkdir -p /tmp/WIPE_IT";


system "chmod 700 /tmp/WIPE_IT";


  ## 新パーティションを取付出来るか否かを見る




my $Result = system ("mount $Partition /tmp/WIPE_IT");


if ($Result > 0) {print "Error mounting drive, aborting.\n"; exit;}


system "chmod 700 /tmp/WIPE_IT";


#--------------------------------


### ファイルを作り大きさが一杯になったらstop




my $Count = 0;


my $Written_Size = 0;  


  ### 新ファイルを開く


open(FILE,">>/tmp/WIPE_IT/Message.txt");


   ### 誰かがドライブの周りでうろうろしていたら、




   ### 一緒に遊び、強い相手をあてがって時間を潰させる




my $Ran = rand 259200000;   # between now and ten years ago (approx)


($Ran, $Junk) = split(/\./, $Ran, 2);


   ## 新日付マイナス秒の乱数


my $Date = `date --date '-$Ran seconds'`;


print FILE "DATE CREATED $Date\n";


my $Ran = rand 50;


($Ran, $Junk) = split(/\./, $Ran, 2);


$Ran = $Ran + 10;


print FILE "この文書は極秘です。無資格者は何人も読むことを




    許されません。パスワードを持っている人は




    $Ranメソッドを使ってデータ\nを解読して下さい";




  ### 乱数プラス25000  を作る


my $Ran = rand 25000;


($Ran, $Junk) = split(/\./, $Ran, 2);


$Ran = $Ran + 25000;


  ### 殆どの時間使用する数字のアレーを作る




my @Blank =  (1..$Ran);


  ### アレーを文字列にする


my $Blank = "@Blank";


  ### アレーを空にしてメモリを解放する


@Blank = ();


my $B_Length = length $Blank;


  ### 手持ちパーティションの実際の空き容量を入手




my @Temp = `df`;


@Temp = grep($_ =~ /^$Partition/, @Temp);


my $Line = $Temp[0];


my ($Junk,$Blocks,@Junk) = split(/\s+/, $Line,4);


  ###  1k ブロックを仮定 


my $Size = $Blocks*1000;


  ## 書き込んだ手持ちファイルがパーティションのサイズより




  ## 小さい間、別のデータを書き込む


while ($Written_Size < $Size)


  {


  $Count++;


        ### 10回のうち9回、空白をプリントして時間を節約、




        ### 10回のうち1回だけ、カベージバイナリをプリント




     my $Ran = rand (10);


     if ($Ran > 1) 


       {


       print FILE $Blank; 


       $Written_Size = $Written_Size + $B_Length; 


       }  


     else 


       {


         ## この部分は長い無作為データ文字列(10000バイトまで)を作る




       my $Garbage = "";


       my $Length = rand(10000);


       ($Length, $Junk) = split(/\./, $Length, 2);


       for (my $i = 0; $i < $Length; $i++)


         {


         my $Ran = rand 256;


         ($Ran, $Junk) = split(/\./, $Ran, 2);


         $Garbage .= chr $Ran;


         }


         ## この部分は一度に無作為データ8バイトを暗号化する




       my $Temp = $Garbage;


       my $Encrypted = "";


       while (length $Temp > 0)  


         {


         while (length $Temp < 8) {$Temp .= "\t";}


         my $Temp2 = $Blowfish_Cipher->encrypt(substr($Temp,0,8));


         $Encrypted .= $Temp2; 


         if (length $Temp > 8) {$Temp = substr($Temp,8);} else {$Temp = "";}


         }


         ### 暗号化無作為データをファイルにプリント


       print FILE $Encrypted;


       $Length = length $Encrypted;


       $Written_Size = $Written_Size + $Length;


       my $Rest = $Size - $Written_Size;


       print "$Size - $Written_Size = $Rest to go\n";


       }


   ### 500 プリント毎に新ファイルへの保存をスタート


  if ($Count =~ /500$/) 


    {


    close FILE;


    open(FILE,">>/tmp/WIPE_IT/$Count");


    }


  }


close FILE;


#----------------------------------------------------





my $Result = system ("umount $Partition");


if ($Result > 0) {print "Error unmounting partition $Partition, aborting.\n"; exit; }


  ### パーティションを再フォーマット。データを消去しないで




  ### ディレクトリから移動するだけ




my $Result = system ("mkfs -t ext2 $Partition");


if ($Result > 0) {print "Error making partition, aborting.\n"; exit;}





結語

Expect もBlowfishも使う必要はなかった。実際、ハードドライブを消して空白で埋めるだけなら、このスクリプトは長過ぎる。fdiskは使いたかったから使った。Expectの偉大さを見て貰うためだ。ハッカーを混乱させるための乱数ガベージデータは余分。

ハードドライブが完全に分かっていないので、残留データがあるかも知れない。MILASの開発を進めれば完全になるだろうが、今の目的にはこれで十分。

参考

1.Perl.com ウェブサイト
2.Expect Perl Module
3.Blowfish Perl Module
4.Original site for this article. - http://www.gnujobs.com/Articles/14/Wipe_It.html
(更新があればここに入れる)
[ディスク上書きに /dev/random 又は /dev/urandom が使える。60号の
The Answer Gang: "Classified Disk - Low-level Format" をみよ。
だが、暗号化はしていない -Mike.]
 
 

USB, PCMCIA 及び Kernel 2.2.18 の

ラップトップへの搭載

By Mark Nielsen

[編集者から:Linux ユーザーは2.2 から 2.4に移っています。Linux 2.4 のUSBサポートは大きく変わりました。この記事はkernel 2.2.8についてですが、Linuxで働くusb入手の最新情報は本文末の「参照」を見て下さい。
また2.4 kernelは PCMCIA サポートも含んでいます。これを先ず試して下さい。これらのドライバが働かないときは、 pcmcia-cs パケージを入手して下さい。

緒言

USBポートを用いてラップトップ上でRicochetモデモを使いたかった。
問題は pcmcia デバイスを使っていることだった。後で、 pcmcia-cs をダウンロードして新kernel 2.2.18の後で搭載しなければならないことを知った。

ラップトップでUSBを働かせるのに必要なことは

1.新 kernel 2.2.18の搭載
2. pcmcia driversドライバの搭載
3.新旧Kernelを使用のためLiloをコンフィギュア
4.ブートの際にusbモジュールがロードされることの確認
5.Ricochetモデモのため /dev/usb の下でノードを作る
6. ppp 設定を再構成
7.新 kernel がうまく働いたら、それをコンピュータ・ブーツのデフォルトにする。
8.残念乍ら、pcmciaスロットのどれもを使っていない時しかUSBポートが働かないがこれは筆者のラップトップのBIOSが変なためで、 Linux kernelのためではない。

2.2.18の搭載

kernelとpcmciaドライバの搭載手順は下記である。
1.新kernelをコンソールドライバ、usbサポート、pcmciaと共に構成して搭載。
筆者は、他のオプションも選んだ。
2.pcmcia-csをダウンロードし、新kernelからsrcディレクトリを用いて搭載。
新kernelの搭載に使ったコマンドは


   ## linux kernelのためsrcディレクトリを変更 


   ## xconfigには、オプションとVESA VGA グラフィックコンソールを選んだ


   ## コンソールドライバの下でラップトップのため




make xconfig


make clean


make dep


make bzImage


make install


make modules


make modules_install


pcmcia-cs搭載手順は、


tar -zxvf pcmcia-cs-3.1.23.tar.gz


  ### 新kernel用にルートディレクトリを規定すること




  ### mine は /usr/src/linux-2.2.18/linux


  ### その他のデフォルトオプションは変えなかった


make config


make all


  ### これはモジュールを /lib/modules/2.2.18 の下に置く


make install


新旧 kernel 使用のため lilo をコンフィギュア

筆者の /etc/lilo.confを示したが、自分用に特殊化しているので、使わないことを強く薦める。 /etc/lilo.confを新コンフィギュレーションにエディットした後、コマンドプロンプトから"lilo"とタイプする。コンピュータを再ブートした後、 "linux_new" か "linux"の選択が出来る。新kernelが働くことを確認してから、これをデフォルト変更。

旧コンフィギュレーション



###  GNUJobs.comテストラップトップ用コンフィギュレーション


vga=791 


boot=/dev/hda


map=/boot/map


install=/boot/boot.b


prompt


timeout=50


default=linux


image=/boot/vmlinuz-2.2.12-32


    label=linux


    initrd=/boot/initrd-2.2.12-32.img


    read-only


    append="hdc=ide-scsi"


#        ramdisk_size=40000


    root=/dev/hda5


新 lilo.conf コンフィギュレーション




###   GNUJobs.comテストラップトップ用コンフィギュレーション


### 新 kernel 搭載。コンソールドライバを新kernelに搭載しないと、




###  vga=791 が働かないことに留意.


vga=791 


#vga=ask


boot=/dev/hda


map=/boot/map


install=/boot/boot.b


prompt


timeout=50


default=linux_new


image=/boot/vmlinuz-2.2.18


        label=linux_new


        read-only


        append="hdc=ide-scsi"


              ### /dev/hda5 は GNUJobs.comラップトップ用ルート


        root=/dev/hda5


image=/boot/vmlinuz-2.2.12-32


    label=linux


    initrd=/boot/initrd-2.2.12-32.img


    read-only


    append="hdc=ide-scsi"


              ### /dev/hda5 は GNUJobs.comラップトップ用ルート


    root=/dev/hda5


USB の設定

USBde設定のため、/etc/rc.d/rc.local fileにこれらのコマンドをおかなければならない。


   ### このコマンドはusb用ファイルシステムを /proc/bus/usbに取り付ける




mount -t usbdevfs none /proc/bus/usb


   ### 一般的usbモジュールをロード−、マザーボード又はUSBポートにより




   ###  次に三つのうち一つを選ぶ。筆者はuhci 又は usb-uhcを選んだ




   ### 分からない時はLinux-USB Guideの中の"Basic USB Configuration" を参照




   ###t http://www.linux-usb.org/USB-guide/c122.html#AEN124 にある


insmod /lib/modules/2.2.18/usb/uhci.o


# insmod /lib/modules/2.2.18/usb/usb-uhci.o


# insmod /lib/modules/2.2.18/usb/usb-ohci.o


   ### Ricochetのようなモデモ用モジュールをロード




insmod /lib/modules/2.2.18/usb/acm.o


Ricochet モデモをシリアルから USB に変更

新usb使用のためRicochetモデモを変更するには、前節のモジュールをロードして新ノードを作り、pppコンフィギュレーションに新ノードを使わせなければならなかった。


mkdir /dev/usb


mknod /dev/usb/ttyACM0 c 166 0 


ここでも、モデモを /dev/ttyS0使用から /dev/usb/ttyACM0 に変更した。ここで Ricochetが働いた。これら二つのコマンドは恒久的なので一度入力すれば良いことに注意。またこれは /dev/usbであって、/proc/bus/usb ではない( Linux-USB Guideで説明)。デバイスを差し込み又は引き抜くとkernelファイルが /proc/bus/usb の中に魔術のように出没するが、これはこのファイルあるべき姿ではない。USB Ricochet モデモは /dev エントリを必要とする。usbdevfs は /proc/bus/usb を管理するのであって not /dev/usb ではない。

ラップトップに伴う問題とリソース

新kernelはDELLから搭載した。筆者のラップトップはUSBポートを扱うに十分なirqを備えておらず、問題があった。幾つかのirqを開放するためUSBマウスを買う必要がある。USBポートを使うときpcmciaモデモとpcmciaイーサネットカードを同時に使えな。irq10が使えない、パラレルポート、シリアルポート、内部ps/2マウスがを無効に出来ない。DELLコンピュータはLinux用デスクトップに不適だ。kernel 2.4ではもっと多くのコマーシャルサポートがあると想像する。

GNUJobs.comでEmperor Linuxから別のラップトップを買った。これはうまく働いている。抜かったのはiso960フォーマットをkernelに搭載するのを忘れたことだ。CDROMが読めない。やり直す必要がある。

結語

Linux kernel 2.2.18のUSBサポートには満足したが、Kernel 2.4.1はもっと良いらしい。
新kernelを搭載しても旧kernelは削除されないので、両方使える。元に返りたいとき便利だ。搭載は難しくなかったが、rpmsを使ってLinuxディストリビューション助けを借りるのが良いと思う。

参考

1.ディレクトリは linux/Documentation/usb/usb-help.txt2000-July-12から取った
  linux/Documentation/usb/*にあるreadme ファイル以外の
 USBヘルプは、以下にある
 Linux-USB プロジェクト: http://www.linux-usb.org/
    ミラーは      http://www.suse.cz/development/linux-usb/
      及び      http://usb.in.tum.de/linux-usb/
 Linux USB ガイド:    http://www.linux-usb.org/USB-guide/book1.html
  必ず読むこと!     (又は他の Linux-USB ミラー)
 Linux-USB デバイス概観 (デバイスとドライバ):
          http://www.qbik.ch/usb/devices/
 Linux-USB メールリストは:
  一般的ユーザーヘルプ:linux-usb-users@lists.sourceforge.net
  デベロッパ討論用:  linux-usb-devel@lists.sourceforge.net
2.Linux Kernel 2.2.18
3.PCMCIA-CS source
4.Using the wireless modem Ricochet
5.Original site for this article - http://www.gnujobs.com/Articles/15/USB.html. (更新)
 
 

マスターブートレコード(MBR)の消去

--危険, 孤島に流される!

By Ben Okopnik

 
実験は面白いけれども、困難な問題を起こす危険がある。
次のような質問をよく受ける
「CPUに爆弾仕掛けたのですが、再インストールに問題が起きました・・・」

警察や消防が帰った後、残るのは古典的な「焦げたMBR」だ。Linuxを搭載する。ウインドウズがブートレコードを動かすのに気付く。Linuxパーティションを削除して、ウインドウズを先ず搭載しようとする。ギョッ、ウインドウズが設定出来ない。

原因は、元のMBRを書いたLILOのアンインストールを忘れたからだ。MBRの中のブートレコードがLinuxに制御を渡そうとするが、相手がいない。

救い様がない。白紙のマスターブート・レコードを書く筈の無記録 "fdisk/mbr"オプションは何の効果もない、会話モードの "fdisk" は、爆弾が爆発しなくても、「非DOS」パーティションの削除を拒否する。どうしよう・・・

ともかく、問題の原因はウインドウズの "lock" コマンドだ。規定値で、ディスクへの 'raw writes' を許さない、"lock c:"がドライブの書込許可を「ロック」する。

  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

注記:以下の助言はマスターブート・レコードを完全に消し去る

これにはパーティション情報のすべてが含まれている。本当にそうしたい

との確信が内限り「実行しないこと」ーHDは、「工場出荷状態」即ち、

データが全くなく、パーティションとフォーマットを必要とする状態

になり。ブート出来なくなる。

  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

Linuxベースの対策

少しでも、つまり Tom's Root-Boot フロッピイ経由でLinuxが使えるなら、次のように"dd"を呼び出すだけだ。

dd if=/dev/zero of=/dev/hda bs=512 count=1

これで終わり、MBRは消えた 。これをルートしなければならないのは明らかだ。

DOSベースの対策

"debug" のあるDODフロッピイを使って、 "debug" を走らせる。 '-' プロンプトで、メモリの512バイト分をゼロで"block-fill"する

f 9000:0 200 0

'a' コマンドでアセンプリモードを起動し、次のコードを入力する。

mov dx,9000
mov es,dx
xor bx,bx
mov cx,0001
mov dx,0080
mov ax,0301
int 13
int 20

<Enter> を押してアセンブリモードから出る。 "g" を押して実行。"q" を押して"debug"を出る。HDはバージンになった。

 
 

IP スプーフィング

By Kapil Sharma

スプーフィング・アタックには人のソースアドレスの偽造が含まれる。これは別の人の真似をするためマシンを使うことだ。UNIXの殆どのアプリケーションとツールはIPアドレスに依存する。多くのデベロッパはホストベースのアクセス制御を用いてネットワークを確保している。ソースIPアドレスは独特の識別子だが信頼性は薄く、容易にスプーフされる。スプーフィング手順を説明する前にTCP/IP 認証手続き とアタッカがネットワークをスプーフする方法を説明する。

クライアントシステムはサーバーにSYNTメッセージを送ることから始まる。SYNメッセージを受けたサーバーがSYN-ACKメッセージをクライアントに送ると、クライアントはACKメッセージを送って接続を確立する。互いにサービス固有データの交換が出来るようになる。

TCPは一連番号を使う。二つのホストの間に仮想回路が出来ると、TCPが各パケットに識別票として番号を付ける。両ホストはこの番号をエラー点検と報告に用いる。

Rik Farrowはその著作"Sequence Number Attacks"(一連番号アタック)の中で、一連番号システムを次のように説明している。

「データ受領通知に一連番号が用いられる。TCP接続の始めに、クライアントは初期一連番号を付け、受領通知なしで、TCPパケットを送る。サーバー・アプリケーションが働いていれば、サーバーは自分の初期一連番号と、クライアントの一連番号プラス1の受領通知を付けてTCPパケットを送り返す。クライアント・システムがこのパケットを受け取ると、サーバーの初期連番号プラス1の受領通知を送り返す」

そこでアタッカには二つの課題がある
  1) ソースアドレスの偽造
  2) 攻撃目標に一連番号を維持しなければならない

第二の課題が最も複雑である。攻撃目標が初期一連番号を設定したとき、アタッカは正しい応答をしなければならないからである。一連番号を正しく推定出来れば、攻撃目標に同期して有効なセッションを確立出来る。

IP スプーフィングに弱いサービス:
IPスプーフィングに弱いコンフィギュレーションとサービスは、

・RPC (リモート・プロセジャ呼出サービス)
・IPアドレス認証を用いるサービス全部
・X ウインドウ・システム
・R サービス・スーツ (rlogin, rshなど)

TCP/IP スプーフィング・ツール:
1) Linux用Mendax
Mendax は、TCP一連番号予測とrshdスプーフィングに使いやすいツールである。

2) spoofit.h
spoofit.h は、自分のプログラムにIPスプーフィング機能を含ませるための、巧くコメントされたライブラリである [現 URL は未詳. -Ed.]

3) ipspoof
ipspoof は、TCP / IP スプーフィング・ユティリティである

4) hunt
hunt は、沢山のスプーフィング機能もまた提供するスニッファ(探知器)である。

5) dsniff
dsniff は、関係データ(パスワード、e−メール、ファイルなど)についてネットワークを受動的に監視するdsniff, filesnarf, mailsnarf, msgsnarf, urlsnarf及びwebspy、ネットワーク通信の盗聴を容易にするarpspoof, dnsspoof及びmacof の、ネットワーク監査及び進入試験のためのツールコレクションである。

IPスプーフィング攻撃の防止方法:

・ソースアドレス認証を避け、システム全体で暗号認証を実施する。
・ローカルアドレスからの発信を要求するネットからのパケットを拒絶するようネットワークを構成する。これはルーターが最も普通に取る方法である。
・信頼出来るホストから外部接続を許すときは、ルーターで暗号化出来るようにする。

結語:
スプーフィング攻撃は危険で防御し難い。段々増えている。これら攻撃への防御はネットワーク安全保障のため暗号化認証の様な安全対策を実施しなければならない。

 
 

AOLサーバーの XML 解析

By Irving Washington

AOLサーバー

AOLserver はオープンソース、マルチスレッド、高性能のWebサーバーである。AOLserverは、Apacheほど有名ではないが、優れている。AOLさーばーについては以前のLGの私の記事を参照されたい。 previous LG article

XML

XMLを最も良くあらわす言葉は「XMLは、データをトリーの形でテキスト(ASCII)ファイルとしてあらわす(不完全な)方法」である。

AOLサーバーにおける XML サポート

ArsDigita.が書いた ns_xml モジュールのお陰でAOLでXML処理が出来る。このモジュールは libxml ライブラリのバージョン2.X周りのラッパーであって、埋め込みTclインタプリータに ns_xmlコマンドを加える。


cvs -d:pserver:anonymous@cvs.aolserver.sourceforge.net:/cvsroot/aolserver login


cvs -z3 -d:pserver:anonymous@cvs.aolserver.sourceforge.net:/cvsroot/aolserver co nsxml


を行って、CVSレポジトリからダウンロード出来る。CVSがパスワード(空白)を待っているので1行目の後にエンターを押す。

2.xは自分で搭載する必要がある。 nsxmlモジュールを搭載するには、nsxmlディレクトリに行く。MakefileのパスをAOLサーバーを指すようエディットして、makeを走らせる。nsxml.so入手してAOLサーバーのbinディレクトリに置かなければならない。 nsd.tclコンフィギュファイルに続けて次ぎを加える



ns_section "ns/server/${servername}/modules"


ns_param   nsxml           ${bindir}/ns_xml.so


AOLサーバーを再スタートする。server.logを見てロードを確認する。シェルウインドウ


tail -f $AOLSERVERDIR/log/server.log




をシェルウインドウに使う方法もある。


XML クイックリファレンス

下記は ns_xmlを通じて利用出来るコマンドの早見である。
set doc_id [ns_xml parse ?-persist? $string]
$stringの中のXMLドキュメントを解析してドキュメントIDを返す。?-persist? フラッグを入れないと、文字列があるときメモリは自動的に開放され、入れると、 ns_xml doc freeを呼んでメモリを解放する必要がある。解析したXML文書を文字列間で共有したいときは-persist フラッグを使う必要がある
set doc_stats [ns_xml doc stats $doc_id]
ドキュメントの統計を返す
ns_xml doc free $doc_id
ドキュメントを開放。?-persistent? フラッグがns_xml parse 又は ns_xml doc create のいずれかに渡されているときにのみ呼び出す
set node_id [ns_xml doc root $doc_id]
ドキュメント・ルートのノードIDを返す(ここからドキュメント・ツリー横断を開始)
set children_list [ns_xml node children $node_id]
与えられたノードの子ノードを返す
set node_name [ns_xml node name $node_id]
ノード名を返す
set node_type [ns_xml node type $node_id]
ノード型を返す。可能な型:element, attribute, text, cdata_section, entity_ref, entity, pi, comment, document, document_type, document_frag, notation, html_document
set content [ns_xml node getcontent $node_id]
与えられたノードの内容(テキスト)を得る
set attr [ns_xml node getattr $node_id $attr_name]
与えられたノードのアトリビュート(属性)値を返す.
set doc_id [ns_xml doc create ?-persist? $doc-version]
メモリ内に新ドキュメントを作成。-persist フラッグがあるときは、ns_xml doc freeを用いて、ドキュメントが占めたメモリを明確に開放しなければならない。ないときは、スクリプト実行後自動的に開放される。$doc_versionはXMLのバージョンで指定しないと"1.0"になる
set xml_string [ns_xml doc render $doc_id]
ドキュメントのメモリ内表現からXMLを作成
set node_id [ns_xml doc new_root $doc_id]
ドキュメントのため新ルートを作成
set node_id [ns_xml node new_sibling $node_id $name $content]
与えられたノードのシブリング(同類)を作成
set node_id [ns_xml node new_child $node_id $name $content]
与えられたノードの子ノードを作成
ns_xml node setcontent $node_id $content
与えられたノードのため内容を設定
ns_xml node setattr $node_id $attr_name $value
与えられたノード内の属性値を設定

簡単な例

簡単な学習例はドキュメントを解析してそのツリー構造をプリントすることである。
処理の骨組みは:
ns_xml parse $xml_doc を使って、文字列 $xml_doc の中のXMLドキュメントを解析しそのドキュメントIDを得る
ns_xml doc root $doc_id を使ってルート・ノードのIDを得る。
ns_xml node children $node_id を使ってドキュメントツリーを横断し、ns_xml node ...コマンドを使ってノード内容と属性を得る。
ns_xml parse -persistフラッグを作ったときは、ns_xml doc free $doc_idを呼び出してこのドキュメントに結合するメモリを解放しなければならない。そうでないときはスクリプト実行後自動的に開放される。

コードでは次のようになる。

 



proc dump_node {node_id level} {


    set name [ns_xml node name $node_id]


    set type [ns_xml node type $node_id]


    set content [ns_xml node getcontent $node_id]


    ns_write "<li>"


    ns_write "node id=$node_id name=$name type=$type"


    if { [string compare $type "attribute"] != 0 } {


    ns_write " content=$content\n"


    }


}


proc dump_tree_rec {children} {


    ns_write "<ul>\n"


    foreach child_id $children {


    dump_node $child_id


    set new_children [ns_xml node children $child_id]


    if { [llength $new_children] > 0 } {


        dump_tree_rec $new_children


    }


    }


}


proc dump_tree {node_id} {


    dump_tree_rec [list $node_id] 0


}


proc dump_doc {doc_id} {


    ns_write "doc id=$doc_id<br>\n"


    set root_id [ns_xml doc root $doc_id]


    dump_tree $root_id


}


set xml_doc "<test version="1.0">this is a


<blind>test</blind> of xml</test>"


set doc_id [ns_xml parse $xml_doc]


dump_doc $doc_id 




ns_xml parse コマンドは、XMLドキュメントが無効(例えば、フォームされていない)ときエラーを出すので、コード作成に当たってはこれを捕らえて、例えば次のように意味のあるエラーメッセージを表示しなければならない。  




if { [catch {set doc_id [ns_xml parse $xml_doc]} err] } {


    ns_write "次のXMLドキュメント解析にエラーがありました:"


    ns_write [ns_quotehtml $xml_doc]


    ns_write "エラーは:"


    ns_write [ns_quotehtml $err]


    ns_write "\n"


    return


}


コードをこのように書くのは手間が掛かるが、デバッグの時間が節約出来る筈だ。
コードの働き具合はここSee how the code works これより少し複雑なソース全体はここget the full source

実際の例

XMLはWebサイトで標準として広く使われている。簡単な方法は一つのWebサーバーが別のWebサーバーからXMLフォーマットで情報を取ることである。普通のやり方はヘッドラインの集積である。例えば freshmeat.net に入ると今のヘッドラインを freshmeat.net から作っているのが分かる。同じことを行う。
昔は、HTML全体を読み込むなど、もっと面倒な方法だった。

今日では、人のためにヘッドラインを提供使用とするサイトは、これを一定にURLの下で公表してXMLフォーマット解析を容易にできる。我々の場合データはhttp://www.linuxtoday.com/backend/linuxtoday.xml.で提供される。このファイルのフォーマットは、ここSee the format of this file

お解りの通りLinuxToday サイトでXMLドキュメントはヘッドラインをあらわす。これはストーリイの組で、各ストーリイは、タイトル、URL、著者などを有する。XMLドキュメントを解析した後、容易に情報を取り出すことが出来る。Structure and interpretation of computer programs (偉大な書物だ)で唱道された書込方法を使用する。XML表現をオブジェクトに転換したと仮定する。データを示すHTMLの構築には次の手順が必要である。

・ストーリイの全数を入手: headlines_get_stories_count $headlines
・n番目のストーリイを入手: headlines_get_story $headline $story_no
・入手したストーリイの URL を入手: story_get_url $story
・入手したストーリイのタイトルを入手: story_get_title $story
簡略化のため、URLをタイトルだけを用いるが、他の属性への拡張は簡単だ。これらの手順を用いて、(みっともないが)最も簡単な表を作ることが出来る:


proc story_to_html_table_row { story } {


    set url [story_get_url $story]


    set title [story_get_title $story]


    return "- <a href=\"$url\"><font color=#000000>$title</font></a><br>\n"


}


# 与えられたヘッドラインがこのデータを有する表のHTMLコードを作る




proc headlines_to_html_table { headlines } {


    set to_return "<table border=0 cellspacing=1 cellpadding=3>"


    append to_return "<tr><td><small>"


    set stories_count [headlines_get_stories_count $headlines]


    for {set i 0} {$i < $stories_count} {incr i} {


    set story [headlines_get_story $headlines $i]


    append to_return [story_to_html_table_row $story]


    }


    append to_return "</td></tr></table>\n"


    return $to_return


}


Tcl doesn't give us much choice for representing this object; we'll use lists.


proc headlines_get_stories_count { headlines } {


    return [llength $headlines]


}


proc headlines_get_story { headlines story_no } {


    return [lindex $headlines $story_no]


}


proc story_get_url { story } {


    return [lindex $story 0]


}


proc story_get_title { story } {


    return [lindex $story 1]


}


ピュリティについて忘れたときは、 headlines_to_html_table の次の部分を書き直すことが出来る:


set stories_count [headlines_get_stories_count $headlines]


for {set i 0} {$i < $stories_count} {incr i} {


    set story [headlines_get_story $headlines $i]


    append to_return [story_to_html_table_row $story]


}


in a bit more terse way:


foreach story $headlines {


    append to_return [story_to_html_table_row $story]


}


ここからがXMLドキュメントを選んだ表現に転換する最重要部分である。


# $node_id が識別したノード名は $nameと同じか


proc is_node_name_p { node_id name } {


    set node_name [ns_xml node name $node_id]


    if { [string_equal_p $name $node_name] } {


    return 1


    } else {


    return 0


    }


}


# $node_id が識別したノード型は $typeと同じか


proc is_node_type_p { node_id type } {


    set node_type [ns_xml node type $node_id]


    if { [string_equal_p $type $node_type] } {


    return 1


    } else {


    return 0


    }


}


# これはタイプ「属性」のノードか?




proc is_attribute_node_p { node_id } {


    return [is_node_type_p $node_id "attribute"]


}


# ノード名が $name と異なるときはエラーを起こす




proc error_if_node_name_not {node_id name} {


    if { ![is_node_name_p $node_id $name] } {


    set node_name [ns_xml node name $node_id]


    error "node name should be $name and not $node_name"


    }


}


# ノード型が $type と違う時はエラーを起こす


proc error_if_node_type_not {node_id type} {


    if { ![is_node_type_p $node_id $type] } {


    set node_type [ns_xml node type $node_id]


    error "node type should be $type and not $node_type"


    }


}


# 入手したURLとタイトルがこれら属性を有するストーリイ




# オブジェクトを構成




proc define_story { url title } {


    return [list $url $title]


}


#  "story" 名のノードをストーリイをあらわすオブジェクトに転換




proc story_node_to_story {node_id} {


    set url ""


    set title ""


    # チルドレンを縦覧してurlとタイトルノードを抽出


    set children [ns_xml node children $node_id]


    foreach node_id $children {


    # 名が "url" or "title" のノードにのみ関心がある


    if { [is_attribute_node_p $node_id]} {


        if { [is_node_name_p $node_id "url"] || [is_node_name_p $node_id "title"]} {


        set node_children [ns_xml node children $node_id]


        # those should only have one children node with


        # the name "text" and type "cdata_section"


        if { [llength $node_children] != 1 } {


            set name [ns_xml node name $node_id]


            error "$name node should only have 1 child"


        }


        set one_node_id [lindex $node_children 0]


        error_if_node_type_not $one_node_id "cdata_section"


        error_if_node_name_not $one_node_id "text"


        set txt [ns_xml node getcontent $one_node_id]


        if { [is_node_name_p $node_id "url"] } {


            set url $txt


        }


        if { [is_node_name_p $node_id "title"]} {


            set title $txt


        }


        }


    }


    }


    return [define_story $url $title]


}


# XMLドキュメントをヘッドライン・オブジェクトに転換




proc xml_to_headlines { doc_id } {


    set headlines [list]


    set root_id [ns_xml doc root $doc_id]


    # ルート・ノードの名は "linuxtoday" でタイプは "attribute" でなければならない


    error_if_node_name_not $root_id "linuxtoday"


    error_if_node_type_not $root_id "attribute"


    set children [ns_xml node children $root_id]


    foreach node_id $children {


    # 名が "story" のアトリビュート・タイプ・ノードにのみ関心がある




    if { [is_node_name_p $node_id "story"] && [is_attribute_node_p $node_id]} {


        set story [story_node_to_story $node_id]


        lappend headlines $story


    }


    }


    return $headlines


}


コードは直截的である。XMLファイルに関する知識を用いているが、この場合、ルートノードの名は linuxtoday で、名が story のチャイルドを有する。各 story ノードは名が urltitle などのチャイルドを有する。error コマンドの使用に注意。

データの中間表現は無駄なようだが、理由がある。XMLドキュメントから直接HTMLテーブルを作る proc xml_to_html_tableを書いたがこれは、複雑で大きく修正が困難だ。上のように分割すると、複雑でなくなり、融通性を生じ、別の headlines_to_html_table プロセジュアの書き方が容易に想像できる。

実際の働き方はSee how it works in practice 、ソースを得るにはget the source

linuxtoday
- Kernel Cousin Debian Hurd #73 By Paul Emsley And Zack Brown
- Zope 2.2.5 b1 released
- O#39;Reilly Network: Insecurities in a Nutshell: SAMBA, pine, ircd, and More
- ZDNet: Linux Laptop SuperGuide
- ComputerWorld: Think tank warns that Microsoft hack could pose national security risk

このコードで抜けているのは、取得である。これは、XMLファイルが呼び出される度に他の人のサーバーから取得する。これを新バージョンだけ取得するようなロジックを加えるのは易しい。

データ交換言語としての XML に関するまとめ

Webサーバー間のこのデータ交換は新規なものでなく、別の技術でも行うことが出来るが、一つのWebサーバーがクライアントとなり、別のWebサーバーからHTMLプロトコルを用いてデータを入して何かをするとの、考え方は同じである。クライアント−サーバー型のやりとりで新規性はない。Webプログラムが成熟した証拠である。5年位後に、サーバーが保持するデータから静的htmlを示すか、動的Webペイジを作るかの問題の殆どを解決しているであろう。他のWebサイトのためのサービスを提供する時代に入った。今の技術水準は、ヘッドラインなどの交換には多くの限界があるが、プロトコルに基づく協定に従って、複雑な取引が実行される可能性は高い。

AOLサーバーでの XML 解析についてのまとめ

XMLドキュメントを解析する他に、メモリ内に作って操作しXML ASCII に転換することも出来る。ここでは述べなかったが直截的なのでAPIを見れば出来る筈だ。
ns_xmlモジュールがXML処理の基礎を提供する。多くのことが出来るけれども、もっと多くをさせたい筈だ。明らかに欠けているのは次のことである:
・SAX API (これは既に libxml にあるので、ns_xml の拡張を要するだけである)
・XSLTのサポート (計画はあるが libxmlに未だ存在しない)
ns_xmlモジュールへの代替方法は次ぎであろう:
PyWx、AOLに埋め込まれた Python インタープリータ及び標準 PyXML Python モジュールの利用
・別のXML解析ライブラリを包含する別のモジュールを書くこと
・純粋 Tcl 解析器の利用

リンク

・AOLサーバーについてもっと知りたければ intro in December 2000 issue of LG 又は別のintroの part onepart two を読むこと
AOLserver ホームペイジ
Philip and Alex's Guide to Web Publishing、良いwebプログラマを養成する本
Structure and Interpretation of Computer Programs、良いwebプログラマを養成する本
Tcl for Web Nerds, Tcl についてのハンドブック
・私のwebペイジは ここ this one is mine
コメントや意見があれば, ここへ send them in.