雑な k|m の生態について

その 41 - 下り坂って楽ちんですね

2003-09-06

なぜか元気な Microsoft さん

このショートカットは InfoViewer トピック ウィンドウでも使えます!

そうですか 元気ですね

私は最近,常に疲れている状態です (:´Д`) どっか体でも壊したかなあ。

2003-09-05

[C/C++] 勘違いしやすい EOF [私だけ?]

未だにこんな勘違いをするのは私だけかなあ?

#include <stdio.h>
#include <assert.h>

int main( int ac, char *av[] ) {

  // 5bytes.dat は 5 バイトのファイル
  FILE *fp = fopen("5bytes.dat", "rb");
  char buf[5];

  // 5 バイト読む
  fread( buf, 1, 5, fp );

  // 上で 5 バイト読んだ。もう EOF だろう?
  assert( feof(fp) );


  // えっ,違うの!?


  fclose( fp );
  return 0;
}

これは C スタイルのファイル記述子だけでなく,std::fstream クラスでも同様。ファイルの中身全てを読んだからと言って,EOF になるとは限らないんですよね。fread() が 1 バイトでも読み込みに失敗した時に,はじめて EOF が検出されるのです。

分かってはいるんですマジで。でも,今でもたまーに間違えています。。。

[ 今でもたまーに ]
てか,EOF の検出自体,あまり気にしない事の方が多いです。てか「読めるまで読む! 読めなくなったら終了!」という戦略をとる方が多いです。

2003-09-04

Postfix をいじってたんですよ

昨日のネタの続きっぽいんですが,お客様はどうやらネットワークの外部から私が設定した Postfix を使ってメールを送信したいらしくて。で,何度も試してみたけど,送信できないとのこと。

これは当然の事で,/etc/postfix/main.cf の mynetworks には 192.168.... のようなアドレスと 127.0.0.1 のようなアドレスしか記述していない = 許可していないからですね。外からの送信を許可すると,ウザい SPAM 業者が無断で使う事になります。

本来ならば "POP before SMTP",可能ならば "ssh port forward" で対処するらしいですが,いかんせん私もかなりの素人である事と,もう実務で稼動していなければならないはずなので,追加的にソフトをインストールするのはかなりの危険を伴います。仕方がないので mynetworks に客の使っている IP ── グローバル IP とネットマスウの組み合わせ ── を記述する事にしました。

お客様曰く:グローバル IP 分かりません。

あれだ,この事態を解説できるほどの知識は持っていませんが,よくある事ですよね。客の利用しているプロバイダはさらに別の接続業者に繋がっている関係で,外部向けの IP を調べ難いのです。仕方が無いので /var/log/maillog から客が使ったらしい IP を抜き出し,whois コマンドで接続業者を調べます。whois の応答は '***.0.0.0 - ***.31.0.0' と範囲があるので,ネットマスクもここから計算するのでしょう。そうやって,なんとかその接続業者が利用しているらしいグローバル IP を得る事ができました。

# ここまでの手順で間違いがあったら恥ずかしいんだけど,これで問題なさげだもん

ログに書き込まれなくなった!?

mynetworks の使い方が間違っていないかどうかをチェックするために,私の方でもいろいろテストしてみました・・・ん,問題なくメールを送信する事ができます。ログにもちゃんと・・?

ログ,更新されていません

私は客の IP を調べた時,less や tail コマンドではどうにも我慢が出来なかったので,Windows のエディタでログを読もうと思ったのです。FTP でファイルを受け取るために一般ユーザのディレクトリに maillog を移したのですが,その時,

cp /var/log/maillog ~tkuri/mlog

と入力しようとして何を思ったか

mv /var/log/maillog ~tkuri/mlog

と入力してしまいました。急いで cp ~tkuri/mlog /var/log/maillog として復帰を試みましたが,おそらくそれが問題だったのでしょう。超高速で Google 検索。キーワードにちょっと苦労しましたが,無事に同様の問題と解決法を発見。

[linux-users:87888] Re: maillog

全く同じ事例ではありませんが,rm も mv も似たようなもんです。早速

/etc/rc.d/init.d/syslog stop
touch /var/log/maillog
chmod 600 /var/log/maillog
/etc/rc.d/init.d/syslog start

( 引用元の入力に対して,スラッシュを補完してあります )

と入力して,事なきを得ましたとさ。。。

2003-09-03

[日記?] 行き渡らないドメイン・・・

さる事情により,DNS とメールサーバの設定をしていました。・・正確には,私が某会社に在籍していた時に隣に座っていた人がいつか管理を任されるらしいサーバの設定のお手伝いですが・・。アタシこんなの初めてなのでドキドキです。SPAM メール中継されたらごめんなさいです>皆様

話によると,彼が担当する予定のサーバ `123.45.67.89' および `123.45.67.90' の DNS の設定は終了しており,上位 DNS を担当してくれている (という表現は正確?) クララオンラインさんも準備は整っているとの事。

例えば気性の荒いチンパンジーこと某国大統領が,今回私たちが設定した (はずの) ドメイン `newserver.ne.jp' にアクセスしようとした場合,ちょっとした紆余曲折を経て,クララオンラインさんの DNS に "キミ,`newserver.ne.jp' はどこかね?" と尋ねる事になります。そこでクララオンラインさんの DNS が "それならば `123.45.67.89' か `123.45.67.90' に聞けば分かるよ" と案内してくれます。最後に `123.45.67.89' もしくは `123.45.67.90' が "`newserver.ne.jp' とはうちのサーバの事だよ" と答えるのです。

でも・・・なかなか `newserver.ne.jp' でアクセス出来るようになりません。nslookup でもだめ。dig でどこの DNS に尋ねても応答はありません:"`newserver.ne.jp' なんて知らないよ" って事ですね。・・・って,`123.45.67.89' 自身に尋ねてもかよ! んーなはずねぇだろ。ギャグにしては面白くありません・・・。

まあ落ちとしては `123.45.67.89' には一切の設定がされてなかったってわけで,急いで named.conf やらを設定してあげて事なきを得ましたが・・・。今回の騒動の原因は

こんなもんですか。先行き不安です。私にはあまり関係ないけど。

[ 123.45.67.89 ]
もちろん,こんなのテキトーな値に決まってるじゃないスか
[ ズブの素人 ]
とは言うものの,私も素人です。笑い

2003-09-02

複雑系はじめました 2

私はこんなパズルを用意しました:2 ビット〜 11 ビットそれぞれ一つずつ,10 個のビット列があります。この 10 個のビット列が全て登場するような n ビットのビット列を作って下さい。

このパズルの性質をもう少し分かりやすく説明するために,バリエーションを考えます。2 ビット '01','10' 両方とも登場するような 3 ビットのビット列を作る事は可能でしょうか? 正解は '010' もしくは '101'。答えが複数存在する場合があるんですね。

<<問題>> '01' '10' が登場する 3 ビットのビット列とは?

<<答え 1>>
    '010'
     01   <- ここに '01' が
      10  <- ここに '10' が登場する

<<答え 2>>
    '101'
      01  <- ここに '01' が
     10   <- ここに '10' が登場する

では '00','11' 両方とも登場する 3 ビットのビット列を作る事は・・・これは無理です。つまりこのパズルはもしかしたら解けないかもしれないという性質もあるのです。

さて,2 〜 11 ビットが 1 つずつという事は,全て一直線に並べれば 65 ビット。「65 ビットのビット列を作れ」なんてパズルならば何も考えずに解く事が出来るわけです。じゃあ例えば,40 ビットのビット列を作る事は可能?

->本日のコード (lzh 圧縮)

とソースコードをアプしてはみたものの,大した技術を使っているわけでもないのであまり楽しくはありません。出力結果を以下に載せてみます。

E:\>puzzle
disease patterns :
 00
 110
 1000
 11101
 100110
 0001101
 00111100
 000110111
 1001100011
 11010010000
perfect: 1001111000001110100100001001100011011100
perfect: 0010011000110111010010000000000011110011
--- all dead.

`--- all dead.' は,試行錯誤している全てのビット列の寿命が尽きてプログラムが終了した事を意味しています。`disease patterns' で出題された '00'〜'11010010000' 10 個のビット列が,`perfect:' で示されたようなビット列内にちゃんと収まっています。決して私はこのパズルを解くような,明示的なコードは書いていません。40 ビットのビット列を改造していきながら,あまりにも改造箇所が多いビット列は破棄して,そうでないビット列を増やしてみただけなのです。

しかし実はコレ,10 回プログラムを実行してやっと perfect なビット列が現れるという効率。もっとパラメータを調整してやらなければならないようです。

2003-09-01

複雑系はじめました

「ブラクラチェッカー」の改良は少しずつ進んではいますが,そればっかりでは雑記のネタが出てきません。ネタの確保のために,何か別のプロジェクトも同時進行させなければ。

私の愛読書「人工社会 複雑系とマルチエージェント・シミュレーション」の中で,免疫機構を題材にした面白い実験が行われています。

50 ビット程度のビット列を免疫機構に見立て,5〜6 ビットほどのビット列をウィルスに見立てます。エージェントはウィルスに感染した時,自分の 50 ビットの免疫機構のうち,もっともウィルスのビット列に似ている部分を探します。完全に一致している部分があれば,エージェントはウィルスに対して完全な免疫を持っているため,発病しません。そうでなければエージェントは自分の免疫機構にウィルスのパターンを覚えこませるため,少しばかりの時間と体力を消耗します。つまりゲホゲホと苦しんでいる状態。

<< 免疫とウィルスはこんなビット列 >>
  免疫  .....001001110000110..... ( 50 ビットくらい )
 ウィルス 111111 ( 5〜6 ビットくらい )

<< なるべく似ている部分を探す >>
  免疫  .....001001110000110.....
 ウィルス      111111    ( 4 ビット違い )
            111111   ( 3 ビット違い )
             111111  ( 2 ビット違い )
              111111 ( 3 ビット違い )
                .....

<< 免疫に覚えさせる >>
              v-- まずこのビットをフリップ
  免疫  .....001101110000110.....
 ウィルス        111111

               v-- 次にこのビットをフリップ
  免疫  .....001111110000110.....
 ウィルス        111111

 .. 2 回のフリップで免疫に新たなウィルスを
    覚えこませる事が出来た

本当に単純に考えると,50 ビットの免疫機構に覚えさせられる 6 ビットのウィルスのパターンは 8 種類。でも,免疫機構のパターンを・・こう・・うまくオーバーラップさせて再利用させてなんとかやりくりすれば,9 つより多くのウィルスのパターンに完全に対応できるはずだと思えませんか? まるでパズルの問題のようです。

ここで重要な事:私は一切,このパズルを解く努力をしません。全てエージェントたちにやってもらうのです。あまりにもウィルスに弱いエージェントは速やかに退場して頂き,多くのウィルスに対応できているエージェントはどんどん増殖していってもらいます。

そして,進化していきます。

「人工社会 複雑系とマルチエージェント・シミュレーション」の実験によれば ── エージェントたちの生老病死のダイナミクスの挟間で ── 平均 5.5 ビット ( 1〜10 ビットの一様分布 ) のウィルス 10 種類すべてのパターンを 50 ビットに収める事に成功したエージェントが現れたとの事。

うし,なんとかやる気が出てきました。続きます。。。

[ 雑記のネタ ]
・・というのは建前で,実はチェッカーの改良に飽きていたりします。とほほ。

2003-08-31

夏が終わったー

今日で 1 年の 2/3 が終わるわけなんだけど,まあいつもの事ながら,私何もやり遂げていません。下り坂って楽でいいわ。

口を開けば鬱な事だらけ。。。リソース汚し,すいません。

[メモ] IEEE 浮動小数点表現と MS Binary っていうのがあるらしい

float 型の表現にもイロイロとあるらしいんですが,まだ私あんましよく分かっていません。MS Binary ってのは Mirosoft のサイトの中でよく使われる "MBF" と同じもの?

とりあえず,脳内の勉強予定キューに突っ込んでおくのです。

ところで今気づいたんですが,最近の Google さんは「ウェブ全体から検索」してもトップには母国語を一つ挙げてくれるので萌え。

[ IEEE ]
あいとりぷるいー。別名「いええええええれぇええええあr@mlぎぃう$・ェ」
[ キュー ]
先入先出。ただし私の脳内キューや脳内スタックは,必ずしも先入先出/先入後出が守られる保障はありません。ひでぇ。

2003-08-30

最小の od コマンド

od というのはバイナリビューアの事で,UNIX には搭載されています。もちろん Linux,cygwin にもね。でも Windows には標準では搭載されていないので,自分で作ってみました。

#include <stdio.h>
#include <fcntl.h>
#include <io.h>

int main( int ac, char *av[] ) {
  int c, bytes = 0;

  _setmode( _fileno(stdin), _O_BINARY );

  while ((c = getchar()) != EOF) {
    if ( (bytes & 0xf) == 0 ) printf("%07x ", bytes );
    printf("%02x ", c );
    if ( (bytes & 0xf) == 0xf ) putchar( '\n' );
    ++bytes;
  }

  return 0;
}

たったこれだけで最小の od は完成。コマンドプロンプトでこう使います:

E:\>od < something.dat
0000000 4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00
0000010 b8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00
0000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0000030 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00
0000040 0e 1f ba 0e 00 b4 09 cd 21 b8 01 4c cd 21 54 68
0000050 69 73 20 70 72 6f 67 72 61 6d 20 63 61 6e 6e 6f
0000060 74 20 62 65 20 72 75 6e 20 69 6e 20 44 4f 53 20
0000070 6d 6f 64 65 2e 0d 0d 0a 24 00 00 00 00 00 00 00
0000080 50 45 00 00 4c 01 05 00 91 a4 51 3f 00 00 00 00
以下略 ...

大きなファイルを表示させるならパイプで more と繋げてもいいし:

E:\>od < big.dat | more

さらにパイプを繋げて:

E:\>some_app | od | more

Windows でもこんな事が出来るのは初めて知りました。。。

2003-08-29

[C++] C++ 風 Singleton パターンは本当に大丈夫?

C++ 版の Singleton パターンは基本的に次のようなコードで表現されます。しかしこれ,本当にプロセスが終わるまでに Singleton なクラスのデストラクタが呼ばれるのかなあ? 「main() の外で生成されたオブジェクトは,もしかしたらデストラクタがきちんと呼ばれない可能性がある」なんて事をどこかで聞いた気がするのです。常識的な OS ならば大抵のリソースは面倒を見てくらるらしいですが,私が扱っているのはそこらへんが非常識で有名な OS なので大変

#include <stdio.h>

class AObj {

private:
  AObj()
    { puts("AObj ctor"); }

public:

  static AObj& getInstance() {
    static AObj instance;
    return instance;
  }

  ~AObj()
    { puts("AObj dtor"); }
};


int main() {

  puts("beginning main()");

  {
    AObj& a = AObj::getInstance();
  }

  puts("returning main()");

  return 0;
}
出力結果
beginning main()
AObj ctor
returning main()
AObj dtor

詳しく解説するのは骨の折れる仕事ですが,VC++5.0 のデバッガで追っていくと面白い事が分かりました。

main() を抜けた後に一旦 mainCRTStartup() に制御が戻り,直後に exit() が呼ばれます。その中でさらに doexit() が呼ばれ,中でなにやら・・どうやらテーブルを参照しているつもりらしいですが・・コード自体は簡単なんだけど,わけの分からない事を少し行います。その最中に AObj のデストラクタが呼ばれました。その後,また少しばかりの終了処理の後に ExitProcess() でプロセスが終了します。

要するに,大丈夫って事でした。hehehe...

2003-08-28

template は友達さ・・・

C++ は仕様の複雑さのお陰で,デザインパターンを応用すると本当に奇妙でスマートなトリックが出来上がります。その分,知らなかった罠にも出会うわけで。。。

// このコードはコンパイルできません ...

// それぞれのコントロール /////////////////
class Button {
  private:  Button() { }
  public:   ~Button() { }
};

class EditBox {
  private: EditBox() { }
  public:  ~EditBox() { }
};

class Frame {
  private: Frame() { }
  public:  ~Frame() { }
};

// ファクトリクラス ///////////////////////
template<typename _Control_t>
class VariatedFactory {
public:
  _Control_t *createControl() {
    _Control_t *ctrl = new _Control_t();

    setupControl( ctrl );
      // なんだかわからない複雑な工程

    return ctrl;
  }
};

typedef VariatedFactory<Button> ButtonFactory;
typedef VariatedFactory<EditBox> EditBoxFactory;
typedef VariatedFactory<Frame> FrameFactory;

別に奇妙なトリックというわけでもないけど。。。Button,EditBox,Frame コントロールクラスはそのクラス自身のコンストラクタが作るよりも,ファクトリクラスを用意した方が良いと判断しました。だとすれば各コントロールクラスのコンストラクタは private もしくは protected にしたくなります。それが上のコード。

このままではファクトリクラスからコントロールのコンストラクタが見えないので,いよいよ friend キーワードのお出ましなのです。

class Button {
  friend class VariatedFactory;
  private: Button() { }
  public:  ~Button() { }
};

おっと,これではコンパイルできませんでした。VC++ によれば `error C2989',VariatedFactory クラスはテンプレートなのかテンプレートなのかハッキリしろ,との事。

Google で検索した結果,テンプレートクラスを friend とするには,次のような文にしなければならないそうです。

class Button {
  template<typename _Control_t> friend class VariatedFactory;
  private: Button() { }
  public:  ~Button() { }
};

で,VC++5.0 と 6.0 はこれに対応していませんでした

('A`;)ノ < 今日の落ちはまた一段と酷いな

Written by kuri|minima(tkuri {at} fat.coara.or.jp) - all rights reserved.(warai
このリソースの位置情報は http://www.coara.or.jp/%7etkuri/D/041.htm で安定しています。