@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を使って簡単にできるので、お薦めです(ただし、簡単すぎて卒業研究っぽくならないかもしれませんが)。 |
68userさん MPSの件有難う御座いました。 ところで今疑問に思っている事があるのですが、 NICにはMACアドレスってのがありますよね。 モデムやTAにもMACアドレスってあるのでしょうか? #ものすごい些細な質問で・・すんません。 |
はじめまして すいませんが質問です。 vi でヒアドキメントの使い方がわかりません linuxで試しているのですが ex/vi: Vi's standard input and output must be a terminal とエラーになってしまいます。 できないのでしょうか? |
>>1514 taka > vi でヒアドキメントの使い方がわかりません ex mode なら大丈夫なようです。ただし ex コマンド使わないと いけませんが。そのまま vi mode で使う方法は分かりません。 #!/bin/sh ( vi -e | sed -e 's/^#/foo: /' ) << 'END' a hoge hoge hoge hoge . 1,$s/^/#/ 1,$p q! END あとシングルクォートかエスケープ使った方が良いです。 最後の行の $ とシェル変数がバッティングしますから。 |
有難うございます 以下のシェルで更新できました。 #!/bin/sh vi -e data001 << 'END' i hoge hoge hoge hoge . wq! END ps レスのつけ方がわかりませんでしたすいません |
>>1510 E田 構造体の受け渡しに関しては、僕の出る幕はなさげですが、 一応まとめておきます。まず、E田さんはポインタの使い方を 学んで下さい。rosegarden さんのソースは tes_s.test1 = ((unsigned long *)ptr)[0]; tes_s.test2 = ((unsigned short *)ptr)[1]; となっていますが、rosegarden さん自身が説明されている通り これではまずいので tes_s.test1 = *(unsigned long *)(ptr); tes_s.test2 = *(unsigned short *)(ptr+4); の方がいいでしょう。わからなければ再度質問してください。 で、それを理解してからやっとバイトオーダの話になります。これは 今回の件では関係ないかもしれない (エンディアンによってたまたま 問題が顕在化していないかもしれない) ので、参考程度にどうぞ。 以下のソースでは配列 data から変数 test1/2/3 に値を代入しようと しています。 #include <stdio.h> #include <string.h> void my_memcpy(char *dst, char *src, size_t len){ src += len-1; while (len--) *dst++ = *src--; } main(){ unsigned long test1; unsigned short test2; unsigned short test3; char data[] = {0x12,0x34,0x56,0x78,0x0,0x1,0x0,0x2}; char *ptr = data; test1 = *(unsigned long *)(ptr); test2 = *(unsigned short *)(ptr+4); test3 = *(unsigned short *)(ptr+6); printf("普通に代入 0x%x 0x%x 0x%x\n", test1, test2, test3); memcpy(&test1, ptr+0, sizeof(test1)); memcpy(&test2, ptr+4, sizeof(test2)); memcpy(&test3, ptr+6, sizeof(test3)); printf("memcpy 0x%x 0x%x 0x%x\n", test1, test2, test3); test1 = htonl(*(unsigned long *)(ptr)); test2 = htons(*(unsigned short *)(ptr+4)); test3 = htons(*(unsigned short *)(ptr+6)); printf("hton して代入 0x%x 0x%x 0x%x\n", test1, test2, test3); my_memcpy(&test1, ptr+0, sizeof(test1)); my_memcpy(&test2, ptr+4, sizeof(test2)); my_memcpy(&test3, ptr+6, sizeof(test3)); printf("逆順にmemcpy 0x%x 0x%x 0x%x\n", test1, test2, test3); } このサンプルでは char data[] = {0x12,0x34,0x56,0x78,0x0,0x1,0x0,0x2}; となっていますが、これを適当に切り取って変数に代入すると 順序が狂ってしまいます。実行結果は以下の通り。 普通に代入 0x78563412 0x100 0x200 (間違い) memcpy 0x78563412 0x100 0x200 (間違い) hton して代入 0x12345678 0x1 0x2 (正しい) 逆順にmemcpy 0x12345678 0x1 0x2 (正しい) 前の2つは順序が逆になっています。これはリトルエンディアンマシン (x86 など) で発生します。ビッグエンディアン (68000, Sparc など) では起こりません。 後の2つは htons/htonl や自作の my_memcpy でバイト順を置換して 代入しています (もちろん hton を使う方がよい)。 これはソケット経由でデータを送ると、バイト順が狂うという 意味ではありません。エンディアンが異なるマシン間でも、 データは送った順序で届きます。ですから、同じエンディアン 同士でデータを送りあえば問題は顕在化しません。 ただし、 「異なるエンディアン間で変数の値を直接送信したとき」 は、 「一方の CPU 内部ではバイト順の交換が行われるのに、 他方では行われない」 ので、バイト順が狂ってしまいます。ですから、 「事前にネットワークバイトオーダに変換してから送信」 し、 「受信側はネットワークバイトオーダと認識して変数に代入する」 のが望ましいということです。 実際のソースで書くと、以下のような感じになります。 送受信側でバイトオーダが一致していれば OK。異なるなら NG。 (送信側) long send_num=0x12345678L; write(socket, &send_num, sizeof(send_num)); (受信側) long recv_num; read(socket, &recv_num, sizeof(recv_num)); バイト列をソケット経由で変数に代入する。受け手側が リトルエンディアンなら OK。そうでなければ NG。 (送信側) char buf[]={0x12,0x34,0x56,0x78}; /* 0x12345687 を送りたいとする */ write(socket, buf, sizeof(buf)); (受信側) long recv_num; read(socket, &recv_num, sizeof(recv_num)); ネットワークバイトオーダで送信。ネットワークバイトオーダを ホストバイトオーダにして代入。これが一番よい。 (送信側) long send_num = htonl(0x12345678L); write(socket, &send_num, sizeof(send_num)); (受信側) long recv_num; char buf[256]; read(socket, buf, sizeof(recv_num)); recv_num = ntohl(*(long *)(buf)); なお、ネットワークバイトオーダ=ビッグエンディアンのオーダです。 別に両者で合意が取れていればいいので、リトルエンディアンで 統一したければそれはそれで構いません。 ちなみに X プロトコルでは高速化のため、事前にクライアント・サーバ 間でバイトオーダが異なるかどうかチェックして、 - 同じバイトオーダならそのままデータを送る - 異なるバイトオーダならネットワークバイトオーダに変換してから送る となっているとか。 ところで my_memcpy(void *dst, void *src, size_t len){ とすると gcc に invalid use of void expression と怒られるんですが、 引数を void * で受けるのってできないんでしたっけ? >>1512 gixs > Linuxのselect(2)は、戻った時、第5引数の値が残り時間を示して戻ってくる > (タイムアウトしたら値はゼロになる) ので、waitvalの値の設定はwhile > ループ内でやる必要があります(manにも書いてあります)。 ご指摘どうもです。その通りですね。ちなみに FreeBSD では select(2) の BUGS の項で、本来上記のような動作をするべきだが、 現状ではそうなっていない (waitval の値は書き換えられない) と あります。 >>1513 CoreFighter > NICにはMACアドレスってのがありますよね。 > モデムやTAにもMACアドレスってあるのでしょうか? ないです。なぜかっちゅうと NIC は Ethernet の端点だからです。 # なぜ Ethernet だと MAC アドレスが必要で、モデム/TA に # MAC アドレスが必要ないか…は、うまく説明できないなぁ。 # 誰か教えて下さい。 |
すいませんがまた質問です。 今度はftp でヒアドキメントの使い方がわかりません ftp ftp.xxx.xxx.ne.jp << EOF userid password by EOF これで実行すると Password:Name(ftp.xxx.xxx.ne.jp:root): と聞かれてしまいます。 シェルだけで実行する方法はありませんか? |
>>1518 taka > 今度はftp でヒアドキメントの使い方がわかりません http://X68000.startshop.co.jp/~68user/unix/pickup?ftp の -n オプションの説明を見て下さい (Linux で使えるかどうかは わかりませんが)。 |
>>1487 68user 先日の FreeBSD の crypt(3) のデフォルトについてですが、 暮れから新年にかけてライブラリ関数のレベルで切り替えの メカニズムが commit されたようです。いまとのところ 5-current でしか使えず、管理権限がないと切り替えられないのですが。 /etc/auth.conf に crypt_default=md5 という設定を入れると perl の crypt もデフォルトが md5 になるようです。 # 今日 CVSup でソースとって来た人は 20 時以降のソースとって来た方が # いいです。昼のソースだと pccard 周りのコンパイルが出来ません。 # 今はなおっていますが。 |
せっかくなので、 >>1509 68user のソースを書き直して 「C 言語で echo サーバを作ってみよう (2)」 http://X68000.startshop.co.jp/~68user/net/c-echo-2.html を作ってみました。C言語+select によるタイムアウト機能付き echo サーバです。 # 一応バグは潰したつもり。 あと、これまでご指摘を頂いた >>1389 Yuuki の accept のバグ、 >>1215 UNIX見習い >>1216 68user の LocalAddr のバグを修正しました。お二人に感謝。 |
>>1520 rosegarden おろ、/etc/login.conf には passwd_format=md5 で、/etc/auth.conf には crypt_default = md5 des で、libutil で、libcrypt ですか。全然なにが なんだかわかってませんが、手元にソースがないので調べにくい。MFC を待つか…。 # 軟弱なので、うちは今朝の 4-STABLE です。 |
>>1522 68user 言葉が足りないようですみません。 4-stable では /etc/login.conf に passwd_format=md5 と明示的に 指定することによって passwd コマンドなどで 使用するハッシュ関数は変更できますが、perl などで使用している crypt(3) などのハッシュ関数はそのまま des だったりします。 解禁以降、大抵の人はそのまま des 入れているでしょうから。 一方、5-current だと /etc/login.conf でのハッシュ関数の 指定は passwd コマンドでは有効になりますが、それとは別に crypt(3) のハッシュ関数を /etc/auth.conf で指定できます。 これはさっき CVSup して確かめましたが、4-stable には反映されていません。 http://www.jp.FreeBSD.org/cgi/cvsweb.cgi/src/lib/libcrypt/crypt.c ソースはここで確かめられます。 CGI で差分も見れます。 > # 軟弱なので、うちは今朝の 4-STABLE です。 いや、あまり関係ないかと思います。去年の暮れに 4-stable が page fault 頻発して 放棄せざるを得ない状態まで追い込まれたことあります。結局 kernel panic 起こしながら、数個ずつ kernel のファイルをコンパイルして、 安定した kernel をインストールし、それで回復させましたが。 同じ時期の 5-current はすごく安定していました。 ハード構成いかんではそういうことも起こり得ます。 |
初めまして。 FreeBSD 3.5.1と、それに付属のperlを使っています。 そこでソケットに関するプログラムを組みましたが、ちょっと問題が出てきました。 下記のソースを見てください。 HTTPサーバに接続して、メッセージを受け取り、一定時間何も受信できないと プログラムを終了しようとしています。 (本当は、相手のサーバからコネクションを切られたら終了するようにしたいんです。) サーバと接続されいる状態では、selectは期待した値を戻してくれるのですが、 接続が切断されたあとも、selectの戻り値が 0以外で、いつまでたっても、 ループから抜けられません。 なにか解決方法はないでしょうか? (大抵のサンプルはwhile (<SOCK>) って感じでやってるみたいですが、 バイナリファイルが対象でもうまくいくのでしょうか?) ## ソケットを開いて、ポート80)に繋ぐ。 ## send(SOCK,"GET /index.html HTTP1.0\r\n",0); $rin=''; vec($rin,fileno(SOCK),1)=1; while (1) { $ret = select($rout=$rin,undef,undef,1); if ($ret == 0 ) { last; } #タイムアウト recv(SOCK,$x,1,0); print $x; } |
>>1524 みかん ちろっと見た感じでは 1. \r\n が一個足りません。 2. 相手側がコネクションを切断したときも select は 1 を返します。 その際、recv すると1バイトも読めず、0を返しているはずなのに 無視しているので永遠に終わらないのです。 # http://X68000.startshop.co.jp/~68user/net/echo-4.html |
>>1523 rosegarden > 言葉が足りないようですみません。 いや、解説を催促するつもりはなかったのですが、恐縮です。 login.conf ということはユーザごとに DES か MD5 を定義 できて、しかも各ユーザは ~/.login_conf で上書き自由、 ということだと思うんですが、それが出来て何がうれしい んだろう…ってのが疑問なんです。 # NIS 使用時に幸せ? > 去年の暮れに 4-stable が page fault 頻発して > 放棄せざるを得ない状態まで追い込まれたことあります。 恐いですねぇ。僕は FreeBSD-stable も流し読みだし、make world で こけたとき直すスキルもないので、ビクビクしながらやってます。 4-STABLE じゃなくて 4.2-RELEASE にしとけばよかったな。 >>1524 みかん > 大抵のサンプルはwhile (<SOCK>) って感じでやってるみたいですが、 > バイナリファイルが対象でもうまくいくのでしょうか? <> は C でいうところの fgets 相当 (+バッファサイズが無限長) なので うまくいきます。 うまくいきますが、改行コードが1つもないデータを読もうとすると 一度に多くのバッファ (=メモリ) を消費するので、 sysread(SOCK, $buf, 8192); read(SOCK, $buf, 8192); while ( read(SOCK, $buf, 8192) ){ print $buf } などの方がよいです。 ついでに言っておくと、状況にもよりますが、select に <> や read を使うのは不適切です。select で読み込み 可能だからといって、「改行コードを含むデータ」や 「指定したサイズのデータ」が読み込めるとは限らない ので (データの前半部分だけが先に到着しているかも しれない) からです。せっかく select でブロッキングを 回避しているのに、<> や read の部分でブロッキング してしまうかもしれない。 # ここでいう read は read(2) でなく perl の read (fread(3)) です。 |
>>1517 68user > ところで > my_memcpy(void *dst, void *src, size_t len){ > とすると gcc に invalid use of void expression と怒られるんですが、 > 引数を void * で受けるのってできないんでしたっけ? おや? 68userさんにしては珍しい。 # まあ、プログラミング言語って(自然言語も同じようなものですが)、 # ちょっと離れるだけで勘がにぶって、ポカをやらかしてしまいますが。 そのエラーは、引数で受けた部分ではなく、 dst++などの演算のところのエラーですね。 逆に、char*で受けた場合、gcc -Wallのwarningを黙らすために、 (char*)&test1のようなキャストが必要です。 # gccはいつも-Wall。これでポカミスを結構見付けられます。 |
>>1526 68user > それが出来て何がうれしい うーん、それはそうですね。ただ、人によってこだわりは あるでしょうから。本当の理由は私も良く分かりませんが、 des インストールしても md5 で crypt できるのはやはり 嬉しいです。 |
>>1527 gixs > そのエラーは、引数で受けた部分ではなく、 > dst++などの演算のところのエラーですね なるほどなるほど。 void my_memcpy(void *dst, char *src, size_t len){ (char *)src += len-1; while (len--){ *((char *)dst)++ = *((char *)src)--; } } てな感じでしょうか。 > おや? 68userさんにしては珍しい。 僕は元々ヘボです。-Wall は付けてますが、いつも warning が出る ものの、キャストの仕方がわからず、大抵「まぁ動いているからいいや」で 済ましてしまうレベル (^^; >>1528 rosegarden > des インストールしても md5 で crypt できるのはやはり > 嬉しいです。 ちと考えてみましたが、例えば apache+suExec で CGI を動かす とき、「俺は前の環境で作成したパスワードがあるので DES」 とか「私はセキュリティ重視で MD5」などと、ユーザごとに DES/MD5 を選べたりする、ってな場合があるかもしれませんね。 全然関係ありませんが、掲示板の使い方 http://X68000.startshop.co.jp/~68user/cgi-bin/wwwboard.cgi?howtouse を作りました。上の [使い方] から飛べます。 |
こんにちは、UNIX1年生のみかんと申します。 文字列置換のsedコマンドを使って変数の中の文字列を置換して 別の変数に入れたいと考えております。このようなことは可能でしょうか? sed -e "s/aaa/bbb/g" ${ABC} ここで変数${ABC} の中に入っている値(例えばaaa)を置換して 変数${CBA}に挿入したいと考えております。 大変に恐縮ですが、ご存知の方がいらっしゃいましたらご教授いただけませんでしょうか。よろしくお願いします。 |
>>1505 inpaku あー、もう解決してらっしゃるかもしれませんが、 だいぶ前にこう言うものをつくりました。 http://www.geocities.co.jp/MotorCity/5319/deception_doc.txt http://www.geocities.co.jp/MotorCity/5319/deception.txt 暇つぶしにつくった趣味のソースなんで、ぼく自身が忘れないための やる気のないコメントしか入ってません(苦笑 自ホストのNICからMACアドレスを引っぱってきてるのは、 gethwaddr()関数のあたりです。 あて先ホストのMACはlookup_mac()関数で持ってきてます。 ARPリクエストを流してから、自分のNICにキャッシュされたか 確認することで取得しています。 今見ると、ところどころマヌケできったないソースですが 参考になれば。 |
68userさん、rosegardenさん、gixsさん、 回答、ありがとうございます。 今から、読みながら、また勉強します。 本当に、ありがとうございました。 やってみて、また、わからなかったら質問すると思いますが、 また、よろしくお願いします。 |
はじめまして. IPアドレスとポート番号で,サーバーとそこで動いているサーバープログラムが特定できる所までは理解できました. では,あるマシンで2つWWWブラウザーを立ち上げて,その両方とも同じHTTPサーバーにアクセスした場合,サーバはどちらのブラウザーにHTMLを送り返すか分からないと思うのですが,それはどうやって識別しているのでしょうか. |