こんにちは。 apacheのアクセスログのバックアップファイルを 作成したいと思ってます。 cpでファイルを作成しているときに アクセスログに書かれたログは、 反映されるものなのでしょうか? 知っている方がいらしたら教えていただけませんか? よろしくお願いします。 |
1438,1435アドバイスありがとうございます。 結果がこの結果になれば "awk"にはこだわってません (”perlが良いんじゃないか”とか会社の周りの連中は言ってますが..) ●diff を awkで加工... ●comm (Unix歴は長かったつもりですが...こんなコマンドがあったんですね) 来週早々会社のマシンでトライしてみます |
はじめまして。atomと申します。 教えて頂きたい事があります。 unixで特定の文字列を含むファイルを 特定の場所から検索するには どのようにすればよいのでしょうか? "unixの部屋"のgrepの説明で grep −−− dir/* というのがありますが これでよいのでしょうか。 どなたか、教えて下さい。 よろしくお願いします。 |
> sortコマンドではどれくらいの件数をソート出来るか > 知っている方いませんか? 適当なデータを作って、実験してみましょう。sort できる 限界までいったら、swap の状況を見つつ、sort のせいなのか メモリが足りないのか見極めましょう。 > traceroute.cgiを期待をかけてダウンロードさせていただきました。 補足ですが、まずは web サーバのログを見ましょう。 perl -c traceroute.cgi で文法チェックしましょう。 CGI として動かすのはもっと後の話です。 > 正しくは「X68000.startshop.co.jpと指定のホストの間の」では > ないでしょうか。 へい、その通りです。直します。 # が、CGI の小部屋は技術的に未熟だった頃 (今もたいした # ことはないけど) のコンテンツなので、既にメンテナンス # する気力をなくしております。暇を見付けて修正しておきます。 > grep −−− dir/* というのがありますがこれで > よいのでしょうか。 それでよいです。他人に聞く前に自分で試してみましょう。 試してダメだったのなら、何をした結果どうなったか、 というのが第三者にわかるように質問しましょう。 > cpでファイルを作成しているときにアクセスログに > 書かれたログは、反映されるものなのでしょうか? 試してませんが、恐らく反映されません。なので、 log を適当なタイミングで rotate して、古くなった ログファイルをコピーするのがよいでしょう。 apache なら rotatelogs というコマンドが付属しています。 |
>ん、gzip で圧縮して送って、向こうで伸張できたのですか? >なら最大ファイルサイズは関係なかったですね。 ファイルサイズですが、FreeBSD 4.1-RELEASE で 6GB 以上の報告も あるようです。6GB のディスクを dd コマンドでファイル化した なんて話がどこかで書いてありました(URI は失念しました)。 推測の域を出ませんが、2GB で引っかかったというので思い付いたのですが…。 まさかとは思いますが、singed int でファイルサイズを保持しているような 状況だとエラーが出るでしょうね。プログラムのバグかも知れません。 >grep −−− dir/* というのがありますが >これでよいのでしょうか。 この質問は答えにくいですね。dir 以下のディレクトリツリーを トラバースするのなら、これじゃ不足です。 find . -type f -exec grep PATTERN {} \; ですかね。GNU grep 使っているのなら、 grep -r PATTERN * でもすみます。ただし、シンボリックリンクがループしていると死にますね。 質問をみるとファイル名だけが表示されれば良いようにも読めるので、 そういった場合だと、 grep -rl PATTERN * かな? >適当なデータを作って、実験してみましょう。sort できる >限界までいったら、swap の状況を見つつ、sort のせいなのか >メモリが足りないのか見極めましょう。 GNU sort の場合 TMPDIR みていますね。ルートパーティションを 小さめにとっているシステム( 32MB とか 64MB )だと、メモリがあまっているのに ファイルシステムがあふれたりして。256MB メモリのあるマシンで実験したら、 こんな感じです。 % la -alF total 40330 -rw------- 1 root wheel 36666584 Dec 10 05:51 hoge % sort hoge /: write failed, file system is full sort: write error: No space left on device ちなみに、ルートパーティションは 64MB で、のこり 17 MB でした。 >perlが存在するパスは? 蛇足ですが、CGI スクリプトを win から binary mode で転送すると パスが正しくてもアウトですね。一行目が #!/usr/bin/perl^M とかなりますから。^M って CR のことです。つまり ascii の 0x0d |
> GNU grep 使っているのなら、 > grep -r PATTERN * あれ、今の GNU grep って recursive option あるんですか。 と思って ChangeLog 見たら、-r が追加されたのは 1998/08/18 でした。結構前なんですね。 |
nac と申します。ネットワークプログラミング大変参考になりました。 私も、POP3 クライアントを作ってみて疑問がでてきました。 rfc1939 を読んでみると pop3 サーバーの返答は 512文字まで と書いてありました。そこで、一行が512文字以上のメールを pop3 から落してくると、次のように hogehoge...hoge!CRLF hogehoge....hogeCRCF 途中で ! マークが入っておりました。rfc1939 を読む限りこの、! に ついては言及されていないようですが、これはどこで規定されているのでしょうか。 (もし、rfc の中で書いてあるようでしたら、理解不足です、すいません) |
> rfc1939 を読む限りこの、! については言及されて > いないようですが ちらっとしか見てませんが、512 ってレスポンス行 (+OK とか +ERR) の最大長であって、メールの1文の長さとは 無関係じゃないでしょうか? とはいえ、! で fold されていたというのは気になりますね。 現在 IMAP 環境しかないので試せませんが、その POP3 サーバアプリケーションの名前を教えてください。qpopper ですか? |
一応インストールは成功しているみたいです。GNOME+enlightenmentで「サウンドを有効にする」ボタンを押したらでは正常に動いたのですが、その後デスクトップのタスクバーが出なくなり、仕方なく再インストールして一からやり直したんですが、GNOM+Sawmillでは無理なんでしょうか? PCはNECのLAVIE「LV16CWS」(ノート型)です。サウンドカードはESS社 ES1869Sで、動作確認の取れたOSSの最新版ファイルをインストール済みです。ディストリビューションは、Turbo Linux6.0です。 音だけじゃなくて、スクリーンセイバーもKDEだと動くのにGNOMEではプレビューでは見れても、実際には動きません。ウィンドウマネージャーとの愛称って在るんですかね???誰かアドバイスお願いします。 あとメモリーの自動認識ができないのですが、方法ありますか?解れば教えて下さい。96MBなのでデフォルトでは認識しないようです。宜しくお願いします。 |
skel.103Mさん @hayataです。 No.1437でのアドバイスありがとうございます。 出張でこちらの掲示板を見落としてしまいました。これからアドバイスに沿って再挑戦してみます。 成功しましたは報告いたします。 ではでは |
1430の回答、ありがとうございました。 すぐに応答くださったのに、質問を投げた私が、反応が鈍く、 大変失礼いたしました。 「ヘルスチェック」という言い方は、どうやら「職場方言」のようですが、 68userさんの御推測の通りのものです。 回答いただいたうちの、3、及び4を、使用してみようと思っています。 ありがとうございました。 また、なにかの折りには、よろしくお願いいたします。 |
>とはいえ、! で fold されていたというのは気になりますね。 qpopper の場合一行の最大は \0 込みで 1024 bytes です。 ソースを見ると早いでしょう。 /* Send the header of the message followed by a blank line */ while (fgets(buffer, MAXMSGLINELEN, p->drop)) { if (!strncasecmp(buffer, "Content-Length:", 15) || !strncasecmp(buffer, "X-UIDL:", 7)) { /* Skip UIDLs */ continue; /* Content-Length is MTA dependent, don't send to MUA */ } \0 込みと言うのは、fgets 使っているための仕様です。 もしも、512 文字というのが 2 バイト文字の意味で、512 文字なら ちょうどこの制限に引っかかります。\0 込みなので、iso2022-jp なら 途中出来られると ! なんていくらでも出て来ます。iso-2022-jp なら 「。」なんて「!#」とかなりますから。 ただ、普通は困りませんね。rfc で決められている一行の推奨値は 70 bytes + αですから。 問題は本当に POP3 サーバだけの制限なのかということです。 実験の際に使った MUA や MTA の制限も関係あります。 sendmail 8.11.1 のソースを見たら行の長さ関係は 2048 bytes でした。 また POP3 サーバなどをinetd を通している場合 inetd 自体の制限も あります。8192 bytes かな? FreeBSD の inted の場合。ヘッダーしか見て いないので断定できませんけど。 もっとも、自分で /var/mail/ のファイルにメールらしきものを手動で append して実験した場合は話は別ですが。 他にも実験を telnet でやったのなら、telnet などの制限も考えられます。 FreeBSD なら ring buffer 使っているので、 そういう制限はありませんが、OS のベンダによってこの実装は変わるでしょうね。 |
> qpopper の場合一行の最大は \0 込みで 1024 bytes です。 それはヘッダの出力で、本文はその下の /* Send the message body */ while(fgets(buffer, MAXMSGLINELEN, p->drop)) { /* Decrement the lines sent (for a TOP command) */ if (--msg_lines <= 0) break; pop_sendline(p,buffer); if (hangup) return(pop_msg(p, POP_FAILURE, "SIGHUP or SIGPIPE flagged")); } でないでしょうか。で、pop_sendline は pop_sendline(POP *p, char *buffer){ char * bp; /* Look for a <NL> in the buffer */ if (bp = index(buffer,NEWLINE)) *bp = 0; /* Send the line to the client */ (void)fputs(buffer,p->output); /* Put a <CR><NL> if a newline was removed from the buffer */ if (bp) (void)fputs ("\r\n",p->output); } となっているので (一部略)、fgets で得たデータに改行が 含まれない場合も、余計な改行は付加されないように思う のですがどうでしょう # 改行なしだと bp==NULL になって fputs("\r\n") は実行されない。 rosegarden さんは qpopper-2.x 系列を見ておられるよう ですが、僕が見たのは qpopper-2.2 (ってこりゃまた古いな) の pop_send.c です。 |
>rosegarden さんは qpopper-2.x 系列を見ておられるよう >ですが、僕が見たのは qpopper-2.2 (ってこりゃまた古いな) >の pop_send.c です。 私が見たのは、qpopper-2.3 のソースですね。古いことにはかわりないんですが…。 確かに、 >それはヘッダの出力で、本文はその下の > /* Send the message body */ > while(fgets(buffer, MAXMSGLINELEN, p->drop)) { は御指摘の通りです。本質的にソースに差異はありません。でも、 これも結局 #define MAXLINELEN 1024 #define MAXMSGLINELEN MAXLINELEN なんで、結果的には同じですね。ただし、結果的に同じだっただけで、 私の間違いは間違いです。御指摘ありがとうございます。 なお、上のは同じバージョンの popper.h の define です。 >となっているので (一部略)、fgets で得たデータに改行が >含まれない場合も、余計な改行は付加されないように思う >のですがどうでしょう まず、fgets は man 3 fgets すると >The fgets() function reads at most one less than the number of characters >specified by size from the given stream and stores them in the string str. 最大で size で指定された文字から一文字少ない文字をバッファに読み込む とあります。これは \0 をappendしないといけないからです。 サンプルプログラムを次のようにします。 #include <stdio.h> int main( int argc, char **argv ) { FILE *fp; char buff[256]; if( argc != 2 ){ fprintf( stderr, "usage : fgets FILENAME\n" ); exit(1); } if( ( fp = fopen( argv[1], "r" ) ) == NULL ){ fprintf( stderr, "Cannot read %s\n", argv[1] ); exit(1); } while( fgets( buff, 10, fp ) ){ puts(buff); } exit(0); } さらにこれを gcc -g -O -o fgets fgets.c としてコンパイルして gdb で buff の中を見ます。 (gdb) break 18 Breakpoint 1 at 0x8048604: file fgets.c, line 18. (gdb) set arg fgets.c (gdb) run Starting program: /home/user/tmp/fgets fgets.c Breakpoint 1, main (argc=2, argv=0xbfbff740) at fgets.c:18 18 while( fgets( buff, 10, fp ) ){ (gdb) display buff 1: buff = "\201\203 (ゴミのため略) (gdb) n 19 puts(buff); 1: buff = "#include \000\005( 以下ゴミ ) (gdb) q こんな感じですね。 ># 改行なしだと bp==NULL になって fputs("\r\n") は実行されない。 これは違うと思います。bp == NULL なら単に \r\n を append するだけ で bp != NULL なら \n を \0 で潰してから、\r\n を append だと 思います。良く見てください、元のコードを *bp = '\0' となっています。 bp は index が拾って来た \n のあるところのポインタです。 |
ん? 失礼しました。 >># 改行なしだと bp==NULL になって fputs("\r\n") は実行されない。 >これは違うと思います。bp == NULL なら単に \r\n を append するだけ これ間違いですね。 >/* Put a <CR><NL> if a newline was removed from the buffer */ > if (bp) (void)fputs ("\r\n",p->output); bp == NULL だと確かに \r\n は付かないですね。 あと、 >となっているので (一部略)、fgets で得たデータに改行が >含まれない場合も、余計な改行は付加されないように思う 改行がつかないのは確かですね。 すると長い行の場合は次の行と連結するんですかね? 大変失礼しました。 ただ指定のバッファサイズより一文字減るのは確かです。 なんかそれを言おうとして、論点ずれた挙げ句に大量のゴミみたいな メッセージを書き込んでしまい申し訳ありませんでした。 |
2ch 風にリンク張れるようにしてみました。^(>>|@)\d+ は リンクが張られます。ただ、2ch のように数字に identify を 持たせたくないなぁ。 >>1453 さんの言うように…してみたところ、うまく動きました とかはちょっと嫌。 >>1455 rosegarden さん > 論点ずれた挙げ句に大量のゴミみたいな > メッセージを書き込んでしまい申し訳ありませんでした。 いいえ〜。こういう機会でもないとなかなかソース 読まないタチなので、この手の話は歓迎です。 ちなみに僕はデバッガ使えないようなレベルなので (bt しか知らない)、今後ともいろいろと御教示下さい。 >>1449 kiki@TL さん > GNOME+enlightenmentで すいませんが、GNOME も E も KDE もほとんど使ったことが ありませんので、僕はわかりません。 |
こんにちは。 >>1441のmerryです。 68userさん >>1444で質問に答えていただきありがとうございます。 rotateを調べてみたいと思います。 |
こんにちは UNIXでsendmailを使ってメールを送信するスクリプトを Perlで作ろうと思っているのですが、 添付ファイルを付けることは可能なのでしょうか? よろしくお願いします。 |
はじめまして。 crontabで毎日12:00にabcというスクリプトを 起動するといった設定を現在しているんですが、 これを最終金曜日だけ11:00起動でそれ以外は12:00に起動させるっていう 方法はあるんでしょうか? 教えていただきたく。 |
初めまして、辻 です。 HTTPでGETするプログラムを作成しています。HTTP クライアントを作ってみよう(4) を参考にさせていただいて、URLのエンコードしようとしています。 で、 /~user/hoge.cgi?fuga=ABC!"$ DEF+ が /%7euser/hoge.cgi?fuga%3DABC%21%22%5C%24+DEF%20 と書かれています。自分で作ったプログラムで確かめてみると、 /%7euser/hoge.cgi?fuga%3dABC%21%22%24+DEF%2b となりました。 また、URLのエンコードの対象はURL全てですか?それとも、CGIとかで使われる、?の後ろのみなのでしょうか?~が含まれるので、そんなことはないでしょうが。?そのものは、対象にならないようですし、ファイル名に@等がついてたりしたらどうなるのでしょうか? ちなみに、 string yHttpGet::UrlEncode(string url) { char buff[10]; for(int i=0; i<url.length(); i++) { char c = url.at(i); if(((c <'0') || ('9' < c)) && ((c < 'a') || ('z' < c)) && ((c < 'A') || ('Z' < c)) && ('/' != c) && ('?' != c) && (' ' != c) && ('_' != c) && ('-' != c) && ('.' != c) && ('*' != c)) { sprintf(buff, "%%%02x", c); url.replace(i, 1, buff); } else if(c == ' ') { url.replace(i, 1, "+"); } } return url; } 今のところ、このようなコードを書いています。 |
@1458 masa さん > UNIXでsendmailを使ってメールを送信するスクリプトをPerlで作ろうと > 思っているのですが、添付ファイルを付けることは可能なのでしょうか? モジュールが使えるなら http://www.parkcity.ne.jp/~chaichan/qanda/qa425.htm?00-12-13-19-49 で、ふじさんが述べておられる方法がお勧めです。 @1459 M.K さん > これを最終金曜日だけ11:00起動でそれ以外は12:00に起動させる > っていう方法はあるんでしょうか? 少なくとも FreeBSD の crontab では、それを実現する簡単な 方法はありません。 金曜日の 11:00 毎日 12:00 という二つのエントリを作って、スクリプト内で 最終金曜日で12時台なら、処理終了 金曜日 && 最終金曜日でない && 11時台なら、処理終了 とするのがいいでしょう。 試してませんが、*BSD や GNU の date なら、 date +%m … 現在の月を求める date -v+7d +%m … 一週間後の月を求める を利用して 0 11 * * 5 [ `date +%m`!=`date -v+7d +%m` ] && run-script 0 12 * * * [ `date +%w'!='5' -o `date +%m`!=`date -v+7d +%m` ) ] && run-script てなことが可能かもしれません (条件合ってるかな?)。 @1460 辻さん foo.cgi?.... という GET 形式は、? 以降の文字が QUERY_STRING (疑問符文字列) という名前で取り出せることからわかるように、 ? はエンコードする必要はありません。疑問符であることが重要なのです。 > URLのエンコードの対象はURL全てですか? 全て、というかパス (/~user...) も含めてエンコードが必要です。 ただし、引数を渡したい場合は ? はエンコードしません。 でなくて、ファイル名の一部に ? が含まれる場合は エンコードが必要です。 この掲示板の上にある発言フォームから文字を入力すると、 Name … 68user Email … 68user@X68000.startshop.co.jp Message … ほげほげ というような、対応関係が生まれます。このようなフォームで 生成されたデータを POST で送るとき、クライアントは application/x-www-form-urlencoded という mime type で 送信しなければいけません。「HTTP クライアントを作ってみよう」 では手抜きして送ってませんが、本来は送るべきです。 で、GET の場合も同様に x-www-form-urlencoded 形式ならば ?foo=bar は ?foo=bar でよいです。= は URL エンコードしません。 しかし、そうではなく 「foo=bar」という引数を渡したいのなら ?foo%3Dbar となります。 というふうに、本当は /~user/hoge.cgi?fuga=ABC!"$ DEF+ という例だけでは、どこをエンコードすべきかは明確には なりません。なので、あの解説はあまりよろしくないですね。 例えば hoge.cgi?foo=bar&def=ghi は、フォームに foo、 bar という要素があるならこのまま送ればよいですが、 foo=「bar&def=ghi」という意味なら foo=bar%26def%3Dghi」 とすべきです。どちらなのかは hoge.cgi?foo=bar&def=ghi だけでは正確には判断できません。 |
こんばんは、質問をした本人のレスが遅れて申し訳ありません。 (しかも、ソースまで見て頂いて恐縮です。) >サーバアプリケーションの名前を教えてください。qpopper ですか? 一般のプロバイダで実験したので、わかりませんでした。 今度他の qmail, sendmail が動いているサーバーで実験してみます。 さて、私も手元にあった、qpopper3.0.2 のソースを眺めてみました。 (POP_TERMINATE は '.' buffer は buffer[MAXMSGLINELEN] (MAMSGLINELEN=1024) と宣言されています) pop_sendline ( p, buffer ) POP * p; char * buffer; { char * bp; /* * Byte stuff lines that begin with the termination octet */ if ( *buffer == POP_TERMINATE ) (void)fputc ( POP_TERMINATE, p->output ); /* * Terminate the string at a <NL> if one exists in the buffer */ bp = index ( buffer, NEWLINE ); if ( bp != NULL ) *bp = 0; /* * Send the line to the client */ (void) fputs ( buffer, p->output ); /* * Put a <CR><NL> if a newline was removed from the buffer */ if ( bp != NULL ) (void) fputs ( "\r\n", p->output ); } これをみると、やはり、\n がなければそのまま出力されて しまうようですね。なんとなく、最初から、\n があることを 想定しているような感じも受けます。 |
68user さん、何度もありがとうございます。 私は、HTMLにある<A>タグでリンクされているHTMLをGETするプログラムを作っています。フォームに関わるCGIを作ってるわけではないのですが、リンク先が掲示板で?で引数を渡すリンクがある場合は、正しく渡して、取り出したいと考えています。 この場合、GETなのか、POSTなのかはわからないのですが。ブラウザがフォームからの結果以外で単純にリンクから、ページを読み込むときは、GETを使っているのだと思うので、GETでいいのですか? で、よくわかっていないのですが。この場合も、URLを%とかでエンコードすべきかは判断できないのですか?ブラウザはやっているように思えるのですが。。。 |
行頭に「>>1461」または「@1461」と書くと、 >>1461 68user というふうにリンクを張るようにしました。このとき、自動的に リンク先の発言者の名前を補完します。「さん」付けは なしですが、御了承下さい。 また、「>>1461 ほげほげ」と、数字の後に何かを書くと、 >>1461 ほげほげ とリンクだけが張られ、名前の補完はされません。しかしスクリプトが どんどん汚くなってきた…。brush up が必要だなぁ。 >>1463 辻 義一 > GETでいいのですか? foo.cgi?hoge.. という形式なら GET でよいです。 要は、HTML を読んで <A HREF="foo.cgi?hoge=fuga">..</A> という 部分から foo.cgi?hoge=fuga という文字列を切り出した場合、どこを エンコードすべきかということですよね。普通は何もエンコードせず デコードせず、そのまま使えばいいと思います。アンカーに書く URL は既に URL エンコードされているはずだからです。 それを無理にエンコードする必要はないですが、あえて行うならば ?=&%#/.-*_ 以外の記号と 0x80〜0xff はエンコード、でいいのでは ないでしょうか。 >>1462 nac > これをみると、やはり、\n がなければそのまま出力されて > しまうようですね。 そうですね。POP3 サーバとしては、本文の行がどれだけ長くても、 改行は付加しないのが普通ではないかと思います。基本的にクライ アントにデータを流すだけですから。 |
>それを無理にエンコードする必要はないですが、あえて行うならば >?=&%#/.-*_ 以外の記号と 0x80〜0xff はエンコード、でいいのでは >ないでしょうか。 html の文法的には hoge.cgi?foo=1&bar=2 は hoge.cgi?foo=1&bar=2 と書くそうなので、そういった html の文字参照の変換は 必要になるかも知れません。例えば、$ とか…。 |
68user さん。 ありがとうございます、エンコードもデコードもしなくて良いと言うことですか。楽は楽なのですが。~もそのままで良いのかな。。今のプログラムでGETできているので、このままで行こうかと思います。 rosegarden さん。 その変換について走っていますが、、タグ内の文字列(""で囲まれた部分)までは適用しなくても良いと思うのですが。しているのも見たことありませんし。 |
>>1466 辻 義一さん http://www.ne.jp/asahi/minazuki/bakera/html/opinion/ampersand が、良くまとまっています。ご参考まで。 ※ 僕のサイトは、どうしてたかなぁ・・・ |
たまたま、この件で大ハマリしてました (1時間悩んだ)。 http://X68000.startshop.co.jp/~68user/tmp/amp.html FreeBSD jman へのリンクを張ろうとしていたのですが、 上のリンクは mroff.cgi?.....&dir=jpman-4.2.0%2Fman§=8 と書いていますが、うまくいきません。よく知りませんが、&sec か § という実体参照があるのでしょう。で、ブラウザ (FreeBSD+NN4.75) がその文字に置き換えてリクエストを送るので、mroff.cgi 側に こちらの意図したデータを渡せないのでしょう。 下のリンクは mroff.cgi?.....&dir=jpman-4.2.0%2Fman&sect=8 としているので OK です。 うちのページは何も考えず & のままにしていますね。いかんなぁ。 |
>>1467 (自己フォロー) http://www.asahi-net.or.jp/%7Ejy3k-sm/i_net/url.html にも、色々あります。 >>1468 68user 雨が降って、ひまなので、ついでに、調べてみました。 http://www.w3.org/TR/REC-html40/sgml/entities.html によると、sectはsection signだそうです。 因みに、win98/IE4,NN4では§、bidi-mozilla(11-13)では%A1%F8 になりました。 |
どうも、お世話になります。 最近、DNSの勉強していて、試しに立ててみようと 思っています。(Redhat Linux) そこで、質問なんですけど、 ・ダイヤルアップ接続でDNSサーバは動かせますか? #もちろん一時的でいいんで‥ ・DNSサーバで必要なものは何でしょうか? 気をつける点等.. #そういうHPを知っていたら教えて下さい。 よろしくお願いします。 |
>・DNSサーバで必要なものは何でしょうか? 気をつける点等.. >#そういうHPを知っていたら教えて下さい。 Linux-HOWTO で詳しく書いたものがありましたよ。 |
>>1471参照 ついでだったので、調べておきました。 http://www.linux.or.jp/JF/JFdocs/DNS-HOWTO.html JF インストールすれば大抵入っています。 |
rosegardenさん有難う御座います。 教えてくれたページを見て勉強します。 これからもよろしくお願いします。 |
ども。お世話になってます。 管理モードのパスワードとかって、普通crypt()でハッシュしますよね。 でもDESの場合辞書アタックとかで簡単に破られちゃいますよね。 なのでmd5(md5sum)コマンドで「4fcf95ef97e1b7b248698bca83781902」みたいに ハッシュしているのですが、これはcrypt()のDES、MD5($1$...$)と比べてどっちが セキュリティ的によろしいのでしょうか。 |
URLエンコードの件ありがとうございました。 URIですか?に&をそのまま入れているページはたくさんあります。自分のホームページ上のCGIもそうだし、検索エンジンとかもそう。修正しようか迷っています。登録されている実体参照と重なっていないようなので、事実上大丈夫なのでしょうが。勉強になりました。これを、CGIに反映させるかは迷っているのですが。 現在作っているプログラムでは、色々動かして問題がないようですので、このままにしておきます。ブラウザでも正しくエンコードされていない、ページを開くときに支障があるぐらいですから、こちらで変換すれば上手く出来そうですが、ページの責任と言うことで。終わらせます。 ありがとうございました。 今回は、 |
こんちはーっす。 ず、ずいぶんまえに、ここに(そのときとはURL違うような気もするが) 永久保存版の過去ログなかったっすか? 久しぶりに見たくなって検索したのですが・・・・ 最近行ってないけどtestボードまだ、げんきなのかなー・・・・ |
>>1474 ぷに辻 > 管理モードのパスワードとかって、普通crypt()でハッシュしますよね。 DESやmd5を1方向関数として使用している点は了解していると仮定します。 (余談1 ハッシュ関数と1方向関数は同義と言ってもよいですが、一応別物です。 1方向関数は(結果的に)ハッシュ関数ですが、逆は必ずしも真ではありません。 moduloはハッシュ関数ですが、出力から元の値が容易に推測可能なので良い1方向関数ではありません。) > でもDESの場合辞書アタックとかで簡単に破られちゃいますよね。 辞書アタックと言っているのは、1方向関数でエンコードされたパスワードを奪われて、それに対して、しらみつぶしにパスワードを探索していると仮定します。 (余談2 暗号化パスワードと呼ぶ場合もありますが、復号化するわけではないので、誤用に近いと思っています。) 辞書アタックは、ワードを同じ1方向関数でエンコードして、マッチするものを探すことですから、同じ長さのパスワードなら、探索にかかるコストは、DESでもmd5でも大差無いと思います。 ただ、DESの場合、鍵長が56bitで、パスワード自体を鍵に使うことで(本来、暗号化アルゴリズムであるDESを)1方向関数にしているので、パスワードの長さが8文字に制限されます。 md5は(本来から1方向関数で)元データの長さに(現実的な)制限はないので、もっと長いパスワードが選べます。 この差は大きいですが、弱い(or 短い)パスワードを使っている限り、辞書アタックに対する強さは変わらないと思います。 (辞書アタック以外の探索法に対する強さは分かりません。 DESが簡単に破られる、と言っているのは、3年ぐらい前(もっと前?)のRSAコンテストで、約半年かかって破られたことを根拠にしていると思いますが、逆に言えば、未だ辞書アタックしか有効な手が無いという辺り、腐ってもDESと思わせるものもあります。) |
>>1476 SabaCurry > 永久保存版の過去ログなかったっすか? はい、ありました。半永久保存版は1997年9月16日だけですが、 一応 1997/9/29〜1998/09/20 の分は保存してあります。 データはありながらも閲覧用 CGI スクリプトがどっか行っちゃって 見られない状態が続いてましたが、さきほど発掘してきました。 見てたら恥ずかしくなったので (笑)、URL はメールで送ります。 そのうちアナウンスもなくひっそりと公開します。 >>1474 ぷに辻 > crypt()のDES、MD5($1$...$)と比べてどっちがセキュリティ的に > よろしいのでしょうか。 md5 より crypt+md5 の方が、salt という仕組みがある分 強固ではないかと思います。推測にしか過ぎませんが。 >>1477 gixs > RSAコンテストで、約半年かかって破られたこと 専用ハードウェアを使うと、56bit DES 解読に要する時間は 22時間くらいでしたっけ。剣呑剣呑。 |
>>1478 68user > URL はメールで送ります。 From: MAILER-DAEMON@lala.v3.com (Mail Delivery System) <tetuya@i.am>: unknown user: "tetuya" ということで、メールが送れませんでした。 |
>>1478 68user さん >md5 より crypt+md5 の方が、salt という仕組みがある分 >強固ではないかと思います。推測にしか過ぎませんが。 そう言えば、perl スクリプトなどから crypt 使うと FreeBSD の最近の RELEASE では DES で決めうちになっていることが多いようです。 ことに 4.1.1-RELEASE 以降の暗号解禁リリースの話です。 無論 DES 入れなければ、MD5 ですが。 システム全体では、切替え用のライブラリ関数もあって DES と MD5 を切替えて使えるのに perl が FreeBSD の切替えメカニズムに追従できていないようなんです。 それともできるのかな?ご存知の方いたらスクリプトレベルでの 切替え法を教わりたいです。 断定はしませんが、ソースをちょっと見た印象として、 -current は、login.conf で切替えられて、 デフォルトは MD5 です。今の所。4-stable は DES 入れると 有無を言わさず DES みたいですね。 |
>>1480 参照 >ことに 4.1.1-RELEASE 以降の暗号解禁リリースの話です。 正確にはDES が気軽に使えるようになったのは 4.0-RELEASE からですね。 |
>>1480 rosegarden > システム全体では、切替え用のライブラリ関数もあって > DES と MD5 を切替えて使えるのに perl が FreeBSD の > 切替えメカニズムに追従できていないようなんです。 あ、そうなんですか。全然知りませんでした。 /usr/lib/libcrypt* -> libscript* というリンクなら MD5、 /usr/lib/libcrypt* -> libdescript* なら DES、くらいの切り替え方法しかないのかと思ってました。 4.2-BETA (make world しなきゃな〜) のソースを見た限りでは よくわからなかったのですが、切り替え用ライブラリ関数とは どれのことでしょうか? |
>>1480 参照 >今の所。4-stable は DES 入れると有無を言わさず DES みたいですね。 ちょっと調べて見たら、意外に以前のバージョンで変更されていますね。 知らなかった。 green 2000/08/21 19:15:54 PDT Modified files: (略) usr.bin/passwd local_passwd.c usr.sbin/pw Makefile pw_user.c Log: Add working and easy crypt(3)-switching. Yes, we need a whole new API for crypt(3) by now. In any case: Add crypt_set_format(3) + documentation to -lcrypt. Add login_setcryptfmt(3) + documentation to -lutil. Support for switching crypt formats in passwd(8). Support for switching crypt formats in pw(8). The simple synopsis is: edit login.conf; add a passwd_format field set to "des" or "md5"; go nuts :) Reviewed by: peter ちなみに RELENG_4 だと変更のタイムスタンプは 2000/09/20 04:19:56 PDT 見たいですね。ちょうど、4.1.1-RELEASE のでる前後ですね。 >>1482 68user さん >4.2-BETA (make world しなきゃな〜) のソースを見た限りでは >よくわからなかったのですが、切り替え用ライブラリ関数とは >どれのことでしょうか? 答えは上の commitlog を御覧ください。crypt_set_format ですね。 |
失礼しました。転送メールがうまくいってない(?除名された? みたいなので よければ、こちらの方にURLを教えていただけないでしょうか? 久々にセガの過去ログなど見て、懐かしさにひたってしまいました。 |
>>1477 gixs >>1478 68user gixsさん、68userさんありがとうございました。 > md5 より crypt+md5 の方が、salt という仕組みがある分 > 強固ではないかと思います。推測にしか過ぎませんが。 なるほど。では全部のスクリプトcrypt+md5に変えようと思います。 # gixsさんのは難しすぎて僕には分かりませんでした(汗) |
> # gixsさんのは難しすぎて僕には分かりませんでした(汗) 説明する側の落度です。精進します。 >> md5 より crypt+md5 の方が、salt という仕組みがある分 >> 強固ではないかと思います。推測にしか過ぎませんが。 正しいと思います。 下のぼくの(分かりにくい)説明は、crypt+des vs. crypt+md5の話です。 結論は、パスワード長が同じなら辞書アタックに対する強度に差はないだろう、ということです。 saltありなしに関する余談は・・・、また分からないと言われるのが恐いので止めます。 |
>>1483 rosegarden > システム全体では、切替え用のライブラリ関数もあって なるほど。crypt(3) の切り替えではなく、passwd(1)/pw(1) で 使用される crypt ライブラリのフレームワークが追加された ということですね。 > perl が FreeBSD の切替えメカニズムに追従できていないようなんです。 > それともできるのかな? perl も libutil 使えばいいのにってことでしょうか。 でも #ifdef __FreeBSD__ を埋めこむようなものなので (埋めこまないけど、意味としては同じ)、仕組みとしては 美しくないですねぇ。 ここらへんのもどかしさが Yes, we need a whole new API for crypt(3) by now. と言わせるのでしょうか。 > スクリプトレベルでの切替え法を教わりたいです。 安直ですが、MD5 っぽい salt を渡すのはどうでしょう。 % perl -e 'print crypt("secret","salt")."\n"' saHW9GdxihkGQ (DES) % perl -e 'print crypt("secret","\$1\$salt\$")."\n"' $1$salt$ez2vlPGdaLYkJam5pWs/Y1 (MD5) >>1484 SabaCurry > よければ、こちらの方にURLを教えていただけないでしょうか? はい、後ほど送ります。 |
マルチプロセスがよく分かっていませんので お願いします ... 今fork関数を使い,二つのプロセス, 1)表示画面にイヴェントが発生したら処理するプロセスと 2)時間監視を行っているプロセス を作成しました. 2)は,ある時間の条件でXtOpenDisplayでメッセージ画面が表示し,OKボタンが押させるか画面右上のXボタンが押されると,メッセージ画面が消えます.しかし,メッセージ画面が複数個,表示されるのに,一画面を消去するだけで,全てのメーッセージ画面が消去されてしまいます. その為,複数プロセスにしよう ー 3つのメッセージ画面が表示されたら,3つのプロセスが 動いている − フ゜ロク゛ラムを作成中なのですが,3つ出力されればいいのに6つ(3つx2回)出力されたり,.... 何か簡単に作成できる方法はないでしょうか? execl命令などを使わずに簡単にできませんでしょうか. |
>>1487 68user さん >安直ですが、MD5 っぽい salt を渡すのはどうでしょう なるほど、salt をかえればいいんですね。言われて見れば、 確かにそうですね。もっとも、言われるまでは気が付きませんでしたが。 どうもありがとうございました。 |
>>1488 Qさいとう > 今fork関数を使い,二つのプロセス, > 1)表示画面にイヴェントが発生したら処理するプロセスと > 2) 時間監視を行っているプロセス > を作成しました. X サーバとの通信の実態は、ソケット経由でのデータのやりとりです。 大抵は (同一ホスト内なら) /tmp/.X11-unix/X0 経由です。 # つまり UNIX ドメインソケットを使う。 で、ソケットを作成したあと fork して、複数のプロセスが ソケット共有するのは多分うまくいかないでしょう。 # そういう構成であるとは書いてありませんので推測ですが。 クライアント→サーバは OK かもしれませんが、サーバ→ クライアントのデータは親プロセスか子プロセスのどちらに 渡るかが決まっていないからです。 というわけで、そもそも構成がまずいと思います。1プロセスで できませんか? Xt は知らないのですが、何かコールバック関数を 登録できる仕組みがあると思います。 仮に複数プロセスでやるとしても、X サーバと接続する前に fork して、片方は X サーバとの通信、もう片方は監視などと 役割分担し、両プロセスの間はパイプやシグナルやソケット経由で やりとりすべきでしょう。 >>1487 68user >> よければ、こちらの方にURLを教えていただけないでしょうか? > はい、後ほど送ります。 あ、まだ送ってなかったかもしれない。今日明日はちょっと 無理かもしれないので、すいませんが気長にお待ちくださいませ。 |
「UNIXの部屋」で telnet リモートホストにログインする という項目がありました。 ここで 自動的にログインし、自動的にコマンドを実行するには sleep の項のサンプルを参照。 (コマンド sleep *) とありますが、sleepの項では、下記のようになってます。 sleep 指定秒数だけ動作を止める 5分間 (300秒) 動作停止するには % sleep 300 とする。sleep コマンドは、スクリプトの中で使うことが多い。 % ( echo username ; sleep 1 ; echo password ; sleep 1 ; echo ls ; sleep 1 ) | telnet foo.bar.com なんてこともできたりする。 (日本語マニュアル sleep) 実際に自動的にログインし、自動的にコマンドを実行したい場合はどうすれがいいのでしょうか 誠に勝手なお願いですが、ぜひ教えてください。 |
>>1491 酒井 > 実際に自動的にログインし、自動的にコマンドを実行したい場合は > どうすれがいいのでしょうか そこに書いてある % ( echo ... sleep 1 ) | telnet foo.bar.com ではダメだったのでしょうか。 まぁ普通は ssh や rsh を使いますね。 http://X68000.startshop.co.jp/~68user/unix/pickup?keyword=rsh&target=command#rsh http://www.jp.FreeBSD.org/QandA/HTML/1576.html |
古い話ですが >>1380 book > gcc -c share_test.cc > ar cr libtestshare.so share_test.o > ranlib libtestshare.so > CC test_gcc.cc -L. -ltestshare gcc に -g オプションを付ければいける、と fj で読んだような 読んでないような。 >>1484 SabaCurry メールで送りました。 |
BIOSの設定画面で、MPSってありますけど Versionの1.1と1.4の違いってなんでしょうか? |
ある日突然?起動音が出なくなり、サウンドはすべて聞えなくなりました。[リソースの競合に遭遇し、自己流で、[コントロールパネル]-[システム]- デバイスマネージャー]より、「はてなマーク」のものを削除して、 [サウンド関連のデバイス]を手動設定変更し、競合を避けることができ、 デスクトップ右下にスピカーが表示され音が出るようになったのですが、 再起動するたびに、「PCI Universal Sirial Bus」の入手案内が表示され、キャンセルボタンを押してからでないと、正常に作動を開始しません。起動の度に案内画面が出ないようにするにはどうすればよいでしょうか? |
チャトって、どこですか??? |
あけましておめでとうございます。本年もよろしくお願いします。 別のことをやっていて偶然発見したんですが、 ------------------------------ foo #! perl use strict; my $n = 17; # 普通の変数 print "---> $\$n\n"; # リファレンスしていきなりデリファレンス ------------------------------ % perl -w foo Use of uninitialized value in concatenation (.) or string at foo line 5. ---> 17 結果は確かに出てるんだけど、なんかundefの変数を二重引用符に入れたときと同じ 警告メッセージが出ます。これはなぜでしょう? |
>結果は確かに出てるんだけど、 ↓を試してみて下さい。 my $n = 17; # 普通の変数 $\ = '<OUTPUT RECODE SEPARATOR>'; print "---> $\$n\n"; # リファレンスしていきなりデリファレンス ↓こっちも my $n = 17; # 普通の変数 print "---> ${\$n}\n"; # リファレンスしていきなりデリファレンス |
>>1494 CoreFighter > BIOSの設定画面で、MPSってありますけど > Versionの1.1と1.4の違いってなんでしょうか MultiProcessor Specification の略ですが、詳しいことはさっぱりです。 現状では ACPI に取って変わられたんじゃないかな。具体的なことは intel のサイトあたりに仕様書が転がってるかもしれません。 |
>mmさん あー、、、(^^;;;;; すいませんでした。 どうもありがとうございます! |
UNIXで、C言語で、TCP/IPを使って、クライアント/サーバ(マルチクライアントがアクセスする。非ブロッキングという)プログラムをしています。 selectを使用して、特定の、クライアントが接続しているソケットのタイムアウトを知りたいのですが、その方法が、良くわかりません。 こちらの方が詳しいということなので、ぜひ教えてください。 お願いします。本を読んでも、良くわかりませんでした。 |
>>1501 E田 現状はどこまでわかっているんですか? 何もわからないなら、まずは http://X68000.startshop.co.jp/~68user/net/c-echo-1.html を読んでください。で、ソケットを使えるようになると。 で、perl ですが、select の使い方はこんな感じ。イメージをつかんで下さい。 http://X68000.startshop.co.jp/~68user/net/echo-4.html んで、C での select(2) の使い方。 http://home.jp.FreeBSD.ORG/cgi-bin/showmail/FreeBSD-users-jp/54916 http://home.jp.FreeBSD.ORG/cgi-bin/showmail/FreeBSD-users-jp/54917 わからなければ、作ってるソースから余計な部分をそぎ落としたソースを 公開して、再度質問してください。 |
こんにちは。ネットワークプログラミングについて質問があるのですが…。 現在、Debian Linuxをもちいて、簡単なプログラミングから練習している のですが、いき詰まりました。 PF_PACKETをつかってデータリンクに直接データを渡したいのですが、 ethhdrのh_dest や h_sourceにどうやってMACアドレスを入れて良いか 解らなくなりました。IPアドレスでは、inet_ptonとかあったんですが、 MACアドレスの場合もあるのですか?? 宜しくお願いします。 |
>>1503 inpaku > 簡単なプログラミングから練習しているのですが、いき詰まりました。 ははぁ、「簡単なプログラミングから練習」で、いきなりデータリンク層ですか。 僕にはちょっと荷が重いなぁ。 確認ですが、非 TCP/UDP かつ 非 IP のデータを送りたいのですよね? UNIX Magazine 2000年7月号「BSD をハックする - 齊藤明紀」で、 - 非 IP のプロトコルを使うにはどうすればよいか - 送信する Ethernet パケットに含まれる MAC アドレスを自由に 設定することはできるか について、NetBSD での解説が書かれています。 また、「UNIX ネットワークプログラミング第2版 Vol.1」 http://X68000.startshop.co.jp/~68user/net/link-book.html#8 では、データリンクへのアクセス手法として、 - BSD の BPF (BSD Packet Filter) - SVR4 の DLPI (SVR4 Data Link Provider Interface) - Linux の SOCK_PACKET の3つがあげられています。どうやらここらへんは OS により API がまちまちらしいですね。実際、手元の FreeBSD 4.2-BETA では (PF|AF|SOCK)_PACKET という定数は定義されていません。 で、この本によると Linux の SOCK_PACKET を使うなら fd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL)); とすると、データリンクからすべてのフレームを受けとれる らしいです。 あと、tcpdump が使用している libpcap というライブラリが 上記3種の方法に対応しているようなので、参考になるかも しれません。 # libpcap は読み出ししかできませんが、送信に対応させるのは # それほど面倒ではないとか。 > IPアドレスでは、inet_ptonとかあったんですが、 > MACアドレスの場合もあるのですか?? BSD には libc に ether_aton とか ether_hostton てのがあります。 Linux はどうですか? くぅ、面白い話題だけど、調べるのに一杯一杯だ。 |
68userさんへ 親切にお答え下さって、ありがとうございます。 ether_aton とか ether_hostton ですか、探してみます。 実は僕もUNIX ネットワークプログラミング第2版 Vol.1を 持ってますが、はっきりいって、C言語すらおぼつかない僕 には辛いです(笑) たしかにLinuxではSOCK_PACKETを使うと本には書いてあり ましたが、Kernel2.2以降?からはPF_PACKETを使えと、man ページに書いてあったものですから、それを使ってます。 また、libpcapのソースも落としましたが、書き換えるのは 僕には不可能でした(苦笑) ところで、僕は何をしたかったのかというと、自分で任意の プロトコルをつくってそれで通信させてみようということだ ったんです。無謀とお思いでしょうが、やらなきゃならんの です。卒業のために…。とにかくがんばってみます。 ありがとうございました。 |
早速、回答してくださいまして、ありがとうございます。 どこまでわかっているか、ということなので書きますが、 ソケットの生成とかは、できています。 サンプルとかを真似して、クライアント/サーバで動かしてみました。 fork()で、マルチクライアントにもできています。 でも、select()を組み合わせると、よくわかりません。 動作は、教えてもらったページとかで、なんとなくわかるのですが、 それをCでやろうとすると、わからなくなります。 select[1]とかと書いて、タイムアウトの時間を指定してやると、 それをすぎても読み出せない時にはタイムアウトしたっていうことで 検出できるんですか? よろしくお願いします。 |
追伸です。 ソースとかは、まだ、ほとんど、サンプルとかのechoサーバとかなので、 書きませんでした。 |
すみません、もう一つ質問です。 送信するデータで、データの最初に全データの長さが入っていて、 その次に、データのIDが入っていて、その後にデータの本文が 入っているというものを受信する時の方法についてなんですが、 それを読む時、最初のデータの長さとIDを読んで、その後で データの本文を読みたいのですが、構造体みたいなのを用意して、 そこに格納しようと思っています。 データの長さはu_longで4byteで、 IDは、0x00100101(u_longで4byte)とかという番号で、 データの本文は、u_shortで2byte+longで4byte+char[8]です。 socketでの送信用のchar型からキャストしてみようと しているんですが、最初の00がうまく行きません。 (送信する時のキャストはうまく行っています。受信する時は、 ちゃんと全部、もとのままのデータを受け取っています。) これは、socketの扱い方の方のhton()とかでやらないと いけないのですか? それから、もしかすると、Cの方の書き方が下手糞なせいなのかも しれないのですが、構造体に格納するのがうまく行かないので、 たとえばで良いので、もしも良かったら、例を教えてくれませんか? お願いします。 |
> 最初の00がうまく行きません。 うまく行かないプログラムを (余計な部分は削った上で) 公開してください。 はい、C+select の超手抜きサンプル。バグありまくりですが 一応動きます。細部は参考にせず、おおまかな流れを見て下さい。 ------------------ #include <stdio.h> #include <netdb.h> #include <sys/types.h> #include <sys/time.h> #include <sys/socket.h> #include <sys/uio.h> #include <unistd.h> #include <sys/param.h> #include <netinet/in.h> #include <arpa/inet.h> #define BUF_LEN 256 /* バッファのサイズ */ int main( int argc , char *argv[]){ int connected_socket[100]; int listening_socket; struct sockaddr_in sin; int sock_optval = 1; int port = 5000; char buf[BUF_LEN]; struct timeval waitval; fd_set fd; fd_set org_fd; int max_sock = 0; /* リスニングソケットを作成 */ listening_socket = socket(AF_INET,SOCK_STREAM,0); /* ソケットオプション設定 */ if ( setsockopt(listening_socket,SOL_SOCKET,SO_REUSEADDR, &sock_optval,sizeof(sock_optval)) == -1 ){ perror("setsockopt"); exit(1); } /* アドレスファミリ・ポート番号・IPアドレス設定 */ sin.sin_family = AF_INET; sin.sin_port = htons(port); sin.sin_addr.s_addr = htonl(INADDR_ANY); if ( bind(listening_socket,(struct sockaddr *)&sin,sizeof(sin)) < 0 ){ perror("bind"); exit(1); } if ( listen(listening_socket, SOMAXCONN) == -1 ){ perror("listen"); exit(1); } printf("ポート %d を見張ります。\n",port); waitval.tv_sec = 1; waitval.tv_usec = 0; FD_ZERO(&org_fd); FD_SET(listening_socket, &org_fd); max_sock = listening_socket; while (1){ int i; struct hostent *peer_host; struct sockaddr_in peer_sin; memcpy(&fd, &org_fd, sizeof(org_fd)); select(max_sock+1, &fd, NULL, NULL, &waitval); for ( i=0 ; i<=max_sock ; i++ ){ if ( FD_ISSET(i, &fd) ){ if ( i == listening_socket ){ int len; len = sizeof sin; max_sock++; printf("connected_socket[%d]\n",max_sock); connected_socket[max_sock] = accept(listening_socket, (struct sockaddr *)&sin, &len); if ( connected_socket[max_sock] == -1 ){ perror("accept failed.\n"); } len = sizeof(peer_sin); getpeername(connected_socket[max_sock], (struct sockaddr *)&peer_sin,&len); peer_host = gethostbyaddr((char *)&peer_sin.sin_addr.s_addr, sizeof(peer_sin.sin_addr),AF_INET); printf("接続: %s [%s] ポート %d\n", peer_host->h_name, inet_ntoa(peer_sin.sin_addr), ntohs(peer_sin.sin_port) ); FD_SET(max_sock, &org_fd); } else { int read_size; read_size = read(connected_socket[i], buf, sizeof(buf)-1); if ( read_size == 0 ){ printf("接続が切れました。引き続きポート %d を見張ります。\n",port); close(connected_socket[i]); FD_CLR(i, &org_fd); } else { printf("メッセージ: %s",buf); write(connected_socket[i],buf,strlen(buf)); } } } } } close(listening_socket); return 0; } |
もう、お返事を頂けたとは! すごいです。 ありがとうございます。 参考にして、勉強してみます。 それと、構造体に入れるところのプログラムを、そこのところだけ書きます。 テスト用に、こういう構造体を作りました。 struct test_s{ u_long test_1; u_short test_2; u_short test_3; u_short test_4; u_short test_5; }; struct test_s tes; それから、読み込むところのプログラムです。 while(1){ int len; char *ptr; char buf1[256]; len = read( newsockfd, buf1, sizeof( buf1 )); buf1[len] = '\0'; if( len > 0 ){ if( strncmp( buf1, "end", 3 ) == 0 ){ break; } ptr = buf1; tes.test_1 = (int)ptr[0]; tes.test_2 = (atoi)ptr[1]; tes.test_3 = (atol)ptr[2]; tes.test_4 = (int)ptr[3]; tes.test_5 = (int)ptr[4]; } } こんな感じです。 test_2以降に入る予定のデータは、みんな同じのを送っていますけど、 どれも、変な感じになってしまいます。 (ここには書いていないですけど、printf()で表示させています。) 構造体とかポインタとか、意味は勉強したんですが、 書くのは初めてなので、そのせいかなとも思うんですが、 キャストのやり方が違うのかもしれません。 いろいろやっているうちに、自分ではわからなくなってしまいました。 ほんとうにすみませんけれども、教えてください。 お願いします。 |
>>E田 >キャストのやり方が違うのかもしれません。 確かにおかしな部分はあるようです。もっとも、それがどの程度 全体に影響を及ぼしているかは分かりません。参考程度と言うことで。 まず、次のようなサンプルプログラムを用意します。 #include <stdio.h> #include <string.h> struct test_s { unsigned long test1; unsigned short test2; unsigned short test3; unsigned short test4; unsigned short test5; } tes_s; int main(int argc, char *argv[]) { char buff[256]; char *ptr; buff[0] = '\x12'; buff[1] = '\x34'; buff[2] = '\x56'; buff[3] = '\x78'; buff[4] = '\x0'; buff[5] = '\x1'; buff[6] = '\x0'; buff[7] = '\x2'; buff[8] = '\x0'; buff[9] = '\x3'; buff[10] = '\x0'; buff[11] = '\x4'; ptr = buff; tes_s.test1 = ((unsigned long *)ptr)[0]; tes_s.test2 = ((unsigned short *)ptr)[1]; tes_s.test3 = ((unsigned short *)ptr)[2]; tes_s.test4 = ((unsigned short *)ptr)[3]; tes_s.test5 = ((unsigned short *)ptr)[4]; return 0; } なおキャストの仕方がE田さんのとは違いますが、 E田さんの意図を汲むのなら上の方がおそらく良いでしょう。 これをデバッガで検査してみました。最後の手前で break させて 変数を見ます。 (gdb) x/100bx ptr 0xbfbfd6f0: 0x12 0x34 0x56 0x78 0x00 0x01 0x00 0x02 0xbfbfd6f8: 0x00 0x03 0x00 0x04 0x44 0xd7 0xbf 0xbf これを見る限りデータはちゃんとセットされています。 (gdb) p/x tes_s.test1 $1 = 0x78563412 最初の 4 バイトはひっくり返っています。もしも、動作させる予定の 計算機の CPU が little endian なら memcpy などを使って 1byte ずつ コピーした方が無難です。ただし、SPARC とか m68k なら気にしなくて良い 場合もあります。(ただし、完璧に機種依存になるので、その旨コメントで 明記した方が良いでしょう。) (gdb) p/x tes_s.test2 $2 = 0x7856 (gdb) p/x tes_s.test3 $3 = 0x100 (gdb) p/x tes_s.test4 $4 = 0x200 (gdb) p/x tes_s.test5 $5 = 0x0 (gdb) q 次からは、ずれていますね。例えば、tes_s.test2 = ((unsigned short*)ptr)[1] というのは最初から、short が並んでいるとして、最初から 2 番目のものを とりだすことになるので 配列先頭からの 3 バイト目と 4 バイト目をとりだ します。更に、バイトオーダが絡んで来るので、話しは複雑になります。 機種に依存して良いのなら、 union hoge { struct some_struct { .... } hogehoge; char buff[256]; } などとして一気にコピーする手法が典型的ですが、バイトオーダに悩まされま す。これをすると SPARC では動くが intel 系の CPU では動かない、あるい はその逆のプログラムになります。 まるで、馬鹿みたいに思えるかも知れませんが、memcpy で地道に値のコピー を行った方が良いです。 繰り返しますが、これをなおしたとしても、 E田さんの問題の解決になるとは限りませんので、あらかじめおふくみおき下 さい。あくまでも気がついた範囲ではと言う話です。 |
>>1509 68user 68userさんはご存知かもしれませんが、他の人がはまらないように。 Linuxのselect(2)は、戻った時、第5引数の値が残り時間を示して戻ってくる(タイムアウトしたら値はゼロになる)ので、waitvalの値の設定はwhileループ内でやる必要があります(manにも書いてあります)。 > コピーした方が無難です。ただし、SPARC とか m68k なら気にしなくて良い > 場合もあります。(ただし、完璧に機種依存になるので、その旨コメントで > 明記した方が良いでしょう。) 教育的観点から言っても、やはり「常にネットワークバイトオーダに」でしょう。 > まるで、馬鹿みたいに思えるかも知れませんが、memcpy で地道に値のコピー > を行った方が良いです。 バイトオーダと構造体のパディングを考えると、これしかありませんね。 参考 http://www.kt.rim.or.jp/~ksk/sock-faq/unix-socket-faq-ja-2.html#ss2.15 データ型をやりとりしたいなら、構造体ひとつに対し専用の読みだしと書き出しの関数を作るのが常套手段です。 (内部的には、構造体のメンバ変数をチマチマとネットワークバイトオーダにしながら、バッファにバイト列として書き出します。send側)。 もうひとつの手は(書かなかったら、68userさんが指摘するでしょうが)、数値でもなんでも文字列にしてしまう手です。 クライアント側のテストをスクリプト言語やtelnetを使って簡単にできるので、お薦めです(ただし、簡単すぎて卒業研究っぽくならないかもしれませんが)。 |