はじめまして、漠然とした質問なのですが、 SSLv3のハンドシェイク処理の部分を実際に (Cで)実現する方法を知っている方、もしくは 何か参考になるものがあれば教えてください。 |
環境は、vine linux 、 openssl-0.9.7d-0vl3.2 です。 |
はじめましてe。いつもいろいろと参考にさせてもらってます。 いろいろ試したのですが、わからないので質問させて下さい。 http://tomorrows-wind.at.webry.info/200507/article_21.html ↑ちょうど私の書いたプログラムとほぼ同じだったので ちょっと勝手に拝借したんですが、このソース 私のやってる環境では、エラーがでるんですよね。 エラーが出るのは、最後のRSA_private_decrypt関数です。 これは私だけなんでしょうか?どなたか試していただけませんか? 鍵に関しては、コマンドラインから暗号化,復号化に成功しているので 問題ないと思われます。 お願いします。 実行環境:vine linux OpenSSL 0.9.7d 17 Mar 2004 |
>>4503 esam dectxt = malloc(RSA_size(rsapriv)); を、 dectxt = calloc(1, RSA_size(rsapriv)); と書き換えることでエラーが消えることを確認しました。 (環境: Vine Linux 3.2, OpenSSL 0.9.7d 0vl3.2) |
>>4503 esam >>4504 は無視してください。 > http://tomorrows-wind.at.webry.info/200507/article_21.html の plaintxt = malloc(sizeof(char)*7); strcpy(plaintxt, "abcdefg"); というのがおかしいですね。ここを直せばうまく動いた気がします。 |
>>4503 esam たびたびすみません。 if((enclen = RSA_public_encrypt(strlen(plaintxt), ... を if((enclen = RSA_public_encrypt(strlen(plaintxt) + 1, ... とし、 if((declen = RSA_private_decrypt(strlen(enctxt), ... を if((declen = RSA_private_decrypt(RSA_size(rsapub), ... としなければいけません。 |
>>4503 esam if((declen = RSA_private_decrypt(RSA_size(rsapub), ... は if((declen = RSA_private_decrypt(enclen, ... のほうがスマートな気がしてきました。 |
はじめまして、68userさん おじゃまいたします。 ネットワークプログラミングの基礎知識 大変参考にさせてもらってます! 現在、SSL/TLS でアクセスしてみよう (1) や >>3958 の記事のsslでkeep-aliveを参考にして sslでの接続を勉強させて頂いています。 早速ですが https-client-keep-alive.c や テストで接続と切断を関数化して分けてみて、 リクエストを送らず受信もしないと SSL_shutdown()で0を返します。 (丁度、https-client.c のソースの118行目から146行目までを削った状態です) ためしに接続、受信、切断とすると SSL_shutdown()で1を返すので、 (丁度、https-client.c のソースの118行目から128行目までを削った状態です) 受信が最後まで完了しなければ、 SSL_shutdown()で0を返しERR_print_errors_fp には何も出力しないと推測しているのですが、 間違っていないでしょうか? ご存知の方いらっしゃいましたら ご教授頂けないでしょうか。m(_ _)m (環境: fedora core 4, gcc-4.0.2-8.fc4, openssl-0.9.7f-7.10) |
>>tkobaさん 早急な返信ありがとうございました。 いわれたとおりになおしてみました。 あとは、>>4505の部分ですが。。。 いろいろためしてみましたがやはりエラーがでてしまいます。 |
>>tkobaさん すみませんできていました。 問題は ご指摘のとおりRSA_private_decrypt関数の第一引数でした。 ありがとうございました。 |
はじめまして 先日freebsd 6.0をインストールをしました。昨日までxdm順調に動いていました。 今日、xdmでloginできなくなりました。ユーザー名とパスワードを入力したら、また 登録画面が出てきました。本来welcome to hostname のところは今welcome to 1に なりました。どういう原因でしょうか。よろしくお願いします。 |
>>4500 zsh (NR と FNR では、複数ファイルを入力とした時に値が異なります。) どうなるのでしょうか。 どのように確認できますか。 |
UNIXのシェルで2点教えて頂きたいことがあります。 ●1点目 sedコマンドを使用して置換したいのですが、sed内で変数は 使用可能なのでしょうか。 ----------------- #!/bin/sh DIR="/home/guest/" ls ${DIR}*.CSV | sed 's/$DIR}//g' 置換されずにそのまま出力されます。 シェル内の変数を、sedに渡して置換させることは可能なのでしょうか。 ls ${DIR}*.CSV | sed 's/\/.*\///g' 削除した部分がディレクトリと言う事なので、「's/\/.*\///g'」として みたのですが、正しい使い方なのでしゅか。 ●2点目 変数に格納されているファイル名から番号が一番大きいファイル名 を作りたいのですが、awkを使用して簡単にできますか。 例えば、/tmp配下に、 test0001.CSV test0002.CSV test0004.CSV とファイルがあるとします。 ls、変数に格納し、awk等で、「test0005.CSV」を求めたいのですが。 --------- #!/bin/sh FileLst=`ls /tmp/*.CSV` echo $FileLst | awk ????? |
>>4514 ロー 環境を書き忘れました。 UNIX:Soralis8 シェル:Bシェル |
UNIX の部屋 http://x68000.q-e-d.net/~68user/unix/ を更新しました。 >>4460 mkt > ・fgrep と Gimp の解説文が途中で切れてしまっているように思います。 fgrep については、とりあえず掲示板での発言にリンクを張りました。 http://x68000.q-e-d.net/~68user/unix/pickup?fgrep > ・記号の 2 項目め(「"」の項と思われる部分)の見出し行が抜け落ちてしまってます。 正しく表示されるようにしました。 http://x68000.q-e-d.net/~68user/unix/pickup?%22 " の解決のため、10年近くつぎはぎでやってきた汚い部分を全面的に見直し たため、もしかしたら UNIX の部屋の検索部分にエンバグしている可能性が あります。怪しい挙動を見つけられた方は教えていただけると幸いです。 >>4501 hidemaru > SSLv3のハンドシェイク処理の部分を実際に(Cで)実現する方法 >>4502 hidemaru > 環境は、vine linux 、 openssl-0.9.7d-0vl3.2 です。 OpenSSL を使っていいなら SSL_connect(3) を使えばいいですし、OpenSSL を 使わないなら「環境は OpenSSL」とわざわざ書く理由がわからないです。 >>4508 dynamite > SSL_shutdown()で0を返しERR_print_errors_fp には何も出力しないと > 推測しているのですが わたしもよくわかってませんが調べる時間がないです。すみません。 マニュアルにそう書いてありますか? >>4511 blueeyes > 本来welcome to hostname のところは今welcome to 1になりました。 原因はわかりません。リブートしても同じ挙動かどうか、シングル ユーザモードで起動するとどうなるか、/var/log に何か出ていないかを 確認してください。 >>4514 ロー > ls ${DIR}*.CSV | sed 's/$DIR}//g' '' で囲んだら変数展開されないので、"" で囲みましょう。変数展開できた としても s//home/guest///g は sed 的にエラーですが、これはまた別の話。 > ls、変数に格納し、awk等で、「test0005.CSV」を求めたいのですが。 「ls で表示したときに最後に表示される行」とみなせるのであれば、 echo $FileLst | awk '{print $NF}' など ($NF は gawk では動きましたが、一般的な awk で使用できるかどうかは わかりません)。 まぁ、awk には列で渡すのではなく、行で渡した方が幸せだと思うので、 ls /tmp/*.CSV | awk 'END { print }' の方がいいと思います。とか言い出すと、 ls /tmp/*.CSV | tail -1 でいいじゃん、って話になりますけどね。 |
>>4516 68user ありがとうございます。 >> ls ${DIR}*.CSV | sed 's/$DIR}//g' >'' で囲んだら変数展開されないので、"" で囲みましょう。変数展開できた >としても s//home/guest///g は sed 的にエラーですが、これはまた別の話。 ダブル「""」で囲んだら展開されませんでした。シングル「''」で囲んだら展開 されました。 > echo $FileLst | awk '{print $NF}' >など ($NF は gawk では動きましたが、一般的な awk で使用できるかどうかは >わかりません)。 一般的なawkでも使用できました。 >ls /tmp/*.CSV | awk 'END { print }' は、ダメでした 結果が得られませんでした。 |
>>4512 お FNR に現在処理しているファイルのカレントレコード番号が セットされるのに対して、NR には (n)awk が実行されてから 読み込んだレコード数がセットされています。 $ nawk '{ print "NR:" NR "/FNR:" FNR }' a.txt b.txt 等とすれば違いが確認できると思います。 >>4517 ロー Solarisの(n)awkでは $ /tmp/*.CSV | awk '{ f=$0; } END { print f }' のようにしないといけないようです。 |
>>4518 zsh ありがとうございます。 awkのmatch関数なのですが、awk内で使用するとエラーが ですのですが、どこか使い方がいけないのでしょうか。 抜粋ですが、 awk ' { pos=match($1,/.CSV$/); }' ${TEMPFILE} ファイル名から拡張子以降を取り除くため、拡張子までの 位置を求めようとしています。 awk: syntax error near line 10 awk: illegal statement near line 10 awk: 構文エラー (10 行目の周辺) awk: 不正な文を検出しました。 (10 行目の周辺) が発生します。 |
>>4519 お Solaris 標準の awk (/usr/bin/awk) には、match 関数が存在しません。 対応策としては (1)index 関数を使用する →ただし、index 関数は正規表現を使用できません。 (2)nawk を使用する (3)/usr/xpg4/bin/awk を使用する といった所でしょうか。 |
>>4516 68user 返答ありがとうございます。 マニュアルは下記をざっと目を通してみたのですが、記載が見付けれませんでした。 http://www.infoscience.co.jp/technical/openssl/news/ http://home.att.ne.jp/theta/diatom/ 前回の書き込みで受信関係がおかしいと推測してしまいましたが、 ためしにContent-Lengthの値分だけ受信しても同じ状態なので、 現在、違う部分も検証しています。 また理解が深まりましたら報告させて頂きますm(_ _)m |
はじめまして。素朴な疑問があるので、もし知っておられたらお答えください。 一般論として、ネットワーク上ではTCPとUDPはどっちが優先度が高いのでしょうか? 輻輳した場合に生き残る確率?に違いはありますか? とにかくガンガンパケットを送りつけるプログラムで実験してみたところ、 気持ち程度UDPが優先されている気がしますが、確証が持てません。 LinuxのsocketオプションにSO_PRIORITYというのがあり、デフォルトは TCPもUDPも0でした。 setsockoptで優先度を変えてみても誤差程度の差しか認識できません。 Webで「TCP UDP 優先度」などで探してもいい資料が見つからない状態です。 何かそのあたりの情報を知っていたら教えていただけないでしょうか。 |
>>4522 むう - 一般的に、OS がどちらを優先するということは聞いたことがない。 - ただ、実装によっては得手不得手がある可能性はある。 - しかし一般的に TCP の方が高機能であり行うべき処理も多いため、 スループットという点に関しては UDP の方が有利であろう。 - 当然ながら帯域制御ができるルータ・OS であれば、どちらかを優先する ことは可能であろうが、これは設定の問題。 - SO_PRIORITY は IP の TOS (Type of Service) に設定される。 - TOS の値を改変してしまうルータがあるようで、チェックサム計算からは 除外されたりするかわいそうなフィールド。 - また、TOS は DiffServ など全く別の用途に使われたりもする。 http://x68000.q-e-d.net/~68user/rfc/?key=2474&target=title - OS が TOS を参照するかどうかは怪しいのでは? (ルータならともかく) - TOS で QoS をやりたいならイントラ内で使うこと。ルータは TOS 対応の ものを揃えるべき。 - 少なくともインターネット経由では、ピアまで TOS がそのまま流れる 保障は全くない。 - Arcstar のように、TOS を考慮するとうたっているサービスはある。 http://www.ntt-vpn.com/ip-vpn/faq/faq_02.html というのがわたしの認識です。 |
Wic-PC上で起動した際Teratermウィンドウがタスク上に隠れて しまいタスクトレイ上にある該当画面を選択しなければ画面上 に表示されません。設定で画面がフォアに表示されるように する為の設定方法をご教示下さい。 |
>>4524 かつや http://search.vector.co.jp/search?query=%8D%C5%91O%96%CA などのツールを インストールするのがよいのではないでしょうか。 |
>>4516 68user いろいろありがとうございます。お手数をおかけしました。 > " の解決のため、10年近くつぎはぎでやってきた汚い部分を全面的に見直し > たため、もしかしたら UNIX の部屋の検索部分にエンバグしている可能性が > あります。怪しい挙動を見つけられた方は教えていただけると幸いです。 自分 1 人暴走している感じで恐縮ですが、いろいろ試してしまいました。 全角記号を検索したときの挙動について。 - 半角に変換して検索されている*ものもある*。 (「@」「〜」「:」などは半角に変換されている) - ヒットしなかったときのキーワードの表示が文字化けしている。(*1) (「!」「;」「¥」など多数) - 関係ない結果が表示される。(*2) (「”」「’」「|」など) 半角記号で全文検索したときの挙動について。 - 「ある」はずなのに「ヒットしませんでした。」と言われる。 (「"」→ \"\; がないと言われる、「'」→ \&apos\; がないと言われる、など) - ヒット数表示の次の、リストの先頭に空の項目が入って、 unix-term-dic.html や pregmemo.html などの各検索対象ファイルから 関係ない部分(検索キーワードによって範囲は異なるが google_ad 関連スクリプトの <!-- の後から 先頭項目のあたり?)まで拾ってきてしまっている。 (「!」「=」「:」「@(=@)」「*」など多数) あと、「+」を検索しようとすると「500 Internal Server Error」に なりますね。何も入力しなかった場合とかもですが。 --- (*1)(*2) 記号ばかり試していましたが、普通に言葉を検索しても何か変です。 「あいうえお」→ 1 件ヒットしました。(これは実際存在したので問題ない) 「かきくけこ」→ ヒットしませんでした。(が、キーワード文字化け) 「鶴」→ ヒットしませんでした。(が、キーワード文字化け) 「亀」→ 3 件ヒットしました。(が、どれも関係ないものばかり) という感じで。 …もっとスマートに分類できたらいいんですが、収拾つかなくなってしまいました。 ごちゃごちゃに突っつくだけ突っついて申し訳ありません。 |
>>4526 mkt 言わずもがなですが、 pregmemo.html は prgmemo.html の typo です。失礼しました。 |
>>4526 mkt ずいぶんヌルい修正をしてしまい、お恥ずかしい限りです、 > - ヒットしなかったときのキーワードの表示が文字化けしている。(*1) > (「!」「;」「¥」など多数) 正規表現で検索しているため、入力された文字列は quotemeta している のですが、quotemeta すると EUC-JP の 0x80 以降も quote されてしまい、 その結果化けていました。これまでは quotemeta した後に s/\\([\x80-\xff])/$1/g; で元に戻していたのですが、前回の修正時になぜか戻す必要はないと判断 して、上記の s/// を削除していました。 > - 関係ない結果が表示される。(*2) > (「”」「’」「|」など) 全角->半角変換が甘くて、" ' | などはそもそも半角に置換していません。 調査していないので想像ですが、EUC-JP の 2バイト目 + 後続バイトに マッチしてしまったのではないかと思います。 > <!-- の後から 先頭項目のあたり?)まで拾ってきてしまっている。 > (「!」「=」「:」「@(=@)」「*」など多数) 全文検索のテストが甘かったようです。 > あと、「+」を検索しようとすると「500 Internal Server Error」に > なりますね。何も入力しなかった場合とかもですが。 空の場合は print "検索内容を指定してください。\n"; と表示するようにしていたのですが、前回の修正で Content-type ヘッダの 出力方法を変更したせいで、Content-type より前に 検索内容を指定してください。 が出力され、エラーとなっているようです。 少しずつ直していきます。ご指摘ありがとうございました。 |
>>4524 かつや Tera Term のショートカットのプロパティ中の 『実行時の大きさ』って項目はどうなっていますか? |
Cシェルでシェル変数に代入された数値として 例えば0.12が入っている場合、その変数の数値を$で 参照する時に「0.12」としてではなく、 「.12」と出力させることはできますか? ご教示頂けましたら幸いです。 |
>>4530 でたち printf(1) で何とかならないかと思って試してみましたが、どうやら無理っぽいので echo ${var:s/0././} でどうでしょうか。 |
>>4531 68user echo ${var:s/0././} を行ってみましたが Variable syntax表示で 受け付けて貰えませんでした。 ご返信頂きまして大変ありがとうございます。 |
nawkの使い方について教えて欲しいことがあります。 環境は、Solaris8、shです。 nawk '{ : FNO=sprintf("%d",substr(FNM,19)); : }' ${LIT} 上記のように、ファイル名からファイルの番号を 取得し、格納しています。 "%d"を指定して数値で取得しようとしているのですが 10以上がとれません。 9のまななのですが、どこがいけないのでしょうか。 |
最近掲示板 SPAM がひどいので、特定文字列を含む投稿を禁止するように しました。 >>4540 べた FNM の内容がわからないと何とも言えないです。 |
>>4088 tansy >>4191 無題 >>4225 mmm いまさらですが、当ページのプログラムのライセンスは、特に記述がない限り、 修正 BSD ライセンスっぽいものであることを明記しました。 http://X68000.q-e-d.net/~68user/link.html |
>>4526 mkt 一部のみですが対応しました。 http://x68000.q-e-d.net/~68user/cgi-bin/cvsweb.cgi/public_html/unix/script/pickup#rev1.24 残件は、 - 全文検索がダメダメなのを直す - EUC-JP のバイトの境界を正しく見る (「亀」は「正規表現」の「正」の 2バイト目と「規」の 1バイト目にマッチしている) - 「+」が検索できないのを直す です。忘れないよう http://x68000.q-e-d.net/~68user/bugnote/viewbug.php?projectid=1&bugid=23 に登録済ですが、もしさらなる不具合があれば掲示板にてお教えいただけると幸いです。 |
UNIX の部屋で、各 OS のマニュアルへのリンクを表示するようにしました (先頭部分)。 http://X68000.q-e-d.net/~68user/unix/pickup?find 現時点では、Linux・NetBSD・FreeBSD・HP-UX11i・Solaris10 のセクション 1,1M,8 のみです。 |
ネットワークプログラミングのページはとてもお勉強になります。 非常にありがたく利用させていただきました。感謝です。 ところで素朴な疑問なのですが、TCPでsocket生成→connectの間に bindが不要なのはなぜなのでしょう? |
Solarisで、Perlを組むのですが、参考になる本を 教えてください。 Perlの基本となることが知りたいのです。 変数の設定、判定、ループ、読み書きといったことです。 基本的なことが分かる本を教えてください。 最終的には、Perlでftpやメール送信(smtpでの)を やりたいのです。 この点に関する本も教えて欲しいのですが。 |
>>4550 タバスコ=ダ=ガマ bind(2) することはできますが、普通はしません。connect(2) に 空いているポート番号を選ばせます。 http://www.kt.rim.or.jp/~ksk/sock-faq/unix-socket-faq-ja-3.html#ss3.6 その理由は、ピアのポート番号選択は - 21 なら SMTP - 80 なら HTTP などとサービスの選択も兼ねていますが、ローカルのポート番号は 何番でも構わないからです。 >>4551 だだ > Perlの基本となることが知りたいのです。 > 変数の設定、判定、ループ、読み書きといったことです。 > 基本的なことが分かる本を教えてください。 初心者向けの本は相性が重要ですので、本屋で手にとって立ち読みするのが よいでしょう。本屋に行くことができないなら、わたしは持っていませんが 「初めての Perl」を推薦します。 > 最終的には、Perlでftpやメール送信(smtpでの)をやりたいのです。 「Perl クックブック Volume1・2」で最終的な答えを把握した上で、 「プログラミング Perl」で基礎を固めるのがよいと思います。 |
いつも楽しんでサイトを拝見させていただいております。 今UNIX上でクライアント、サーバのネットワークプログラミングをC言語で 挑戦しているところなんですが、FTPコマンド (QUIT,USER,PASS,PWD,STAT,MKD,RMD,CDW,DEL,LIST,HELPcmd,HELP,PORT,NLST) の組み込み方がイマイチよく分りません。 以下にserverftp.cとclientftp.cのコードを貼り付けておきます。 これらのコードは正常に動いております。 大変お忙しいとは思いますが、 ご教授の程、どうぞよろしくお願い致します。 serverftp.c *********************** #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <netdb.h> #define SERVER_FTP_PORT 9237 // list function prototypes int receiveMsg(int s, char *buf, short bufsize, short *msgsize); int sendMessage(int s, char *buf, short size); main( int argc, char *argv[] ) { int listenSocket; int s; int status; short msgSize; printf("Starting server ftp\n"); status = svcInitServer(&listenSocket); if(status != 0) { printf("Exiting server ftp due to error\n"); exit(-1); } for(;;) { printf("waiting to accept client connection\n"); s = accept(listenSocket, NULL, NULL); if(s < 0) { perror("cannot accept connection: "); exit(-1); } int msg; short size; char recvBuffer[1024]; printf("Server connected to client, issuing recvmsg\n"); status = receiveMsg (s, recvBuffer, 1024, &msgSize); if (status < 0) { close(s); return(status); } char replyMsg[1024]; strcpy(replyMsg, "200 command ok\n"); size = strlen (replyMsg) + 1; status = sendMessage(s, replyMsg, size); if(status < 0) { close(s); return(s); } } close(listenSocket); printf("Exiting from server ftp main\n"); } int svcInitServer( int *s ) { int sock; struct sockaddr_in svcAddr; int qlen; if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("cannot create socket "); return(-1); } memset((char *) &svcAddr, 0, sizeof(svcAddr)); svcAddr.sin_family = AF_INET; svcAddr.sin_addr.s_addr = htonl(INADDR_ANY); svcAddr.sin_port = htons(SERVER_FTP_PORT); if(bind(sock,(struct sockaddr *)&svcAddr, sizeof(svcAddr)) < 0) { perror("cannot bind "); close(sock); return(-1); } qlen = 1; listen(sock, qlen); *s = sock; return(0); } int sendMessage( int s, char *msg, short msgSize ) { int i; for(i = 0; i < msgSize; i++) { printf("%c", msg[i]); } printf(" \n"); if((send(s, msg, msgSize, 0)) < 0) { perror("unable to send "); return(-1); } return(0); } int receiveMsg( int s, char *buffer, short bufferSize, short *msgSize ) { int i; *msgSize = recv(s, buffer, bufferSize, 0); if(*msgSize < 0) { perror("unable to receive"); return(-1); } for(i = 0; i < *msgSize; i++) { printf("%c", buffer[i]); } printf("\n"); return(0); } clientftp.c ********************** #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <netdb.h> #define SERVER_FTP_PORT 9237 int sendMessage(int s, char *msg, short msgSize); int receiveMsg(int s, char *buffer, short bufferSize, short *msgSize); int main( int argc, char *argv[] ) { int status; int s; short msgSize; char FTPcmd[1024]; char replyMsg[1024]; printf("Trying to connect to server FTP\n"); status = clntConnect("//IPアドレス", &s); if(status < 0) { return(status); } printf("Connected to ftp server\n"); strcpy(FTPcmd, "quit"); status = sendMessage(s, FTPcmd, strlen(FTPcmd) + 1); if(status < 0) { close(s); return(s); } printf("Issuing receivemsg to get reply msg from server\n"); status = receiveMsg(s, replyMsg, 1024, &msgSize); if(status < 0) { close(s); return(s); } printf("%c", replyMsg); close(s); return(0); } int sendMessage(int s, char *msg, short msgSize) { int i; for(i = 0; i < msgSize; i++) { printf("%c", msg[i]); } printf(" \n"); if((send(s, msg, msgSize, 0)) < 0) { perror("unable to send "); return(-1); } return(0); } int receiveMsg(int s, char *buffer, short bufferSize, short *msgSize) { int i; *msgSize = recv(s, buffer, bufferSize, 0); if(*msgSize < 0) { perror("unable to receive "); return(-1); } for(i = 0; i < *msgSize; i++) { printf("%c", buffer[i]); } printf("\n"); return(0); } int clntConnect( char *serverName, int *s ) { int sock; struct sockaddr_in us; struct sockaddr_in them; struct hostent *he; if((he = gethostbyname(serverName)) == NULL) { printf("%s is unknown server\n", serverName); return(-1); } if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("cannot create socket "); return(-1); } memset((char *) &us, 0, sizeof(us)); us.sin_family = AF_INET; us.sin_addr.s_addr = htonl(INADDR_ANY); us.sin_port = 0; if(bind(sock,(struct sockaddr *)&us, sizeof(us)) < 0) { perror("cannot bind"); close(sock); return(-1); } memset((char *)&them, 0, sizeof(them)); them.sin_family = AF_INET; memcpy((char *) &them.sin_addr, he->h_addr, he->h_length); them.sin_port = htons(SERVER_FTP_PORT); if(connect(sock,(struct sockaddr *)&them, sizeof(them)) < 0) { perror("cannot connect "); close(sock); return(-1); } printf("Connected to server, socket number: %d\n", sock); *s = sock; return(0); } void clntExtractReplyCode( char *buffer, int *replyCode ) { sscanf(buffer, "%d", replyCode); return; } |
>>4554 かず さんへ > FTPコマンド > (QUIT,USER,PASS,PWD,STAT,MKD,RMD,CDW,DEL,LIST,HELPcmd,HELP,PORT,NLST) > の組み込み方がイマイチよく分りません。 あんまりな方法だと思いますよ。 vsftpd とか proftpd 辺りのソースを拾って読んでみてはどうでしょうか? |
Solarisで、Perlで、smtpで、メール送信をしていいます。 ポート番号25を使って、smtpサーバに接続してメールの 送信をしているのですが、処理は、正常に終わるのですが、 メールが送信されません。届きません。 どこがいけないのでしょうか。 ------------------------------ use Socket; $server = 'SMTPサーバ' ; $from = '送信元アドレス' ; $to = '送信先アドレス' ; $subject = 'テストメール' ; $data = 'メール送信テスト' ; $send_data = 'X-Mailer: SMTP tool' . "\n"; $send_data .= 'MIME-Version: 1.0' . "\n"; $send_data .= 'Content-Type: text/plain; charset=iso-2022-jp' . "\n"; $send_data .= 'From: '. $from . "\n"; $send_data .= 'To: '. $to . "\n"; $send_data .= 'Subject: ' . $subject . "\n"; $send_data .= "\n"; $send_data .= $data; $port = getservbyname('smtp','tcp'); $struct = sockaddr_in($port,inet_aton($server)); socket(SH, PF_INET, SOCK_STREAM, 0) || die("ソケットの生成失敗 $!") ; connect(SH, $struct ) || die("接続失敗 $!") ; select(SH); $| = 1; select(STDOUT); $respons = <SH> ; unless($respons =~ /^220/) { close(SH); die("接続失敗 $!") ; } $command = "HELO $server\n"; print SH $command ; $respons = <SH> ; &decode(\$respons) ; unless($respons =~ /^250/){ close(SH); die("HELOコマンド失敗 $!") ; } $command = "MAIL FROM:$from\n"; print SH $command ; $respons = <SH> ; &decode(\$respons) ; unless($respons =~ /^250/){ print SH "RSET\n"; close(SH); die("MAILコマンド失敗 $!") ; } $command = "RCPT TO:$to\n"; print SH $command ; $respons = <SH> ; &decode(\$respons) ; unless($respons =~ /^25[0|1]/){ print SH "RSET\n"; close(SH); die("RCPTコマンド失敗 $!") ; } $command = "DATA\n"; print SH $command ; $respons = <SH> ; &decode(\$respons) ; unless($respons =~ /^354/){ print SH "RSET\n"; close(SH); die("DATAコマンド失敗 $!") ; } $command = "$send_data\n.\n"; print SH $command ; $respons = <SH> ; &decode(\$respons) ; unless($respons =~ /^250/){ print SH "RSET\n"; close(SH); die("本文、ヘッダ部送信失敗 $!") ; } $command = "QUIT\n"; print SH $command ; close(SH); select(STDOUT); print "MAILは正常に送信されました。\n"; sub decode{ my $inf = $_[0]; $$inf =~ s/\x0D\x0A|\x0D|\x0A/\n/g; } ----------------------------- |
UNIXを良く知らずみようみまねでshellを作成しています。 ある処理のエラーをハンドリングして結果に対してメール を送信する様にしました。 /usr/bin/mail -s "hoge" megu@hoge.com < hoge.txt ここで質問なのですが、該当コマンドをプロンプト上で 実行すると処理が実行されません。 (実行中のまま戻って来ない?) 強制終了すると、dead.letterが更新されます。 該当処理を記載したshellを実行しても、上記コマンド迄 は実行されているのですが、該当mailコマンドの部分で 処理がされない様で、コマンドを実行した様にshell自体も 終了しません。 cronや他ツールで自動実行させる様にすると実行されます。 根本的なOSの知識なのか、環境の問題なのかさえも分かりません。 とても基本的な質問になるかと思うのですが、教えて頂ければと 思います。 |
はじめまして。質問させてください。 sin_port=0で空いているポート番号を自動取得できますが、 ・ここで取得されたくない番号を指定 ・決められた帯域内(5000〜6000など)で限定して取得 ・予め取得される範囲を取得 のいずれかを行いたいのですが、方法はありますでしょうか? |
>>4556 まんたろう > ポート番号25を使って、smtpサーバに接続してメールの > 送信をしているのですが、処理は、正常に終わるのですが、 > メールが送信されません。届きません。 うちの環境では正常に送信されました。telnet での送信や、メーラー 送信のパケット観察などを行って、成功/失敗時の違いを観察してください。 >>4557 megu - 「sh -x スクリプト名」として、実際に実行されているコマンドを確認する。 端末からの入力を待っているなら、リダイレクトまわりが怪しげな気が。 - dead.letter の中を見て、エラーを観察する (dead.letter の中にエラーが 記述されるのかは覚えていませんが) - mail コマンドが吐くエラーを観察する。標準出力・標準エラー出力を捨てて いるなら、捨てないようにする。 >>4558 カルネ Linux なら ip_local_port_range、NetBSD なら net.inet.ip.anonportmax、 FreeBSD なら制限方法がない (たぶん) など、OS によって異なります。 |
シェルで、dateコマンドで取得した時間から5分前の の時間を取得したいのですが、できるでしょうか。 date +%H%M%S と実行します。 結果として、「130530」が取得できます。 そこから、取得した、「1305030」から5分前の「130030」を 求めたいのですが、できるのでしょうか。 環境は、 Solaris、shです。 |
>>4560 べた 上にある方が、現実的な解です。 - perl で localtime(time-5*60) - GNU date をインストールして date --date '5 minutes ago' - http://x68000.q-e-d.net/~68user/cgi-bin/wwwboard.cgi?log=1382 的なやり方 - http://home.catv.ne.jp/pp/ginoue/bn/descend.html の「2002/04/02 ひとこと」 的なやり方 |
プロパーや一次請けが perl を嫌がったり、ましてや非純正な物 (GNU プロダクト)を入れるなんて駄目なんて悲惨な職場を経験したので... Solaris 付属の date コマンドに %T って有りますか? 無かったとしても date +%H:%M:%S って書き方は利用可能ですか? 結果として、13:05:30 が取得できるなら、予め IFS_OLD=$IFS ; IFS=":" して 2 番目のフィールドが 5 未満か? とか 1 番目のフィールドが 0 以下か? って 辺りを条件に繰り下がり処理を手作りするのもありますね。 |
あ... 68user さんが例示してるやん。 リンクは読んでから書かないと駄目ね。 |
>>4561 68user >>4562 hoge ありがとうございます。 日付またがりなどを考えるとPerlでやる方法がいいです。 Perlでやります。 もう1つ質問があります。 シェルを起動し、起動した時間から5分前に出力された時間以降の syslogの内容を別ファイルに出力したいのですが、できるのでしょうか。 例えば、 今が、18:00:00とします。 シェルを起動し、18:00:00を取得します。 18:00:00を基にして、5分前の17:55:00を取得します。 「Apr 6 18:55:00」以降に出力されたsyslogをすべて 別ファイルに出力します。 ということ実現したいのです。 時間は、 $tm = time - 300; my $now = strftime "%b %e %H:%M:%S", localtime($tm); で取得します。 |
あるファイルから指定日時以降に書かれたレコードを 抽出したいのですが、シェルスクリプトでできるので しょうか。 どのしょうにシェルにすればよいか教えてください。 例えば、今が、2006/04/08 12:30:00とします。 ある指定日時というのは、現時点から5分前としますので、 2006/04/08 12:25:00となります。 ファイルでは、「Apr 8 12:30:33 ・・・・・」と出力 されているので、5分まえの時間を、「Apr 8 12:25:00」 で取得し、「Apr 8 12:25:00」以降に書かれたレコードを ファイルに出力したいのです。 環境は、 Solaris8、sh、Perlで実現したいのです。 |
>>4566 べた 無理ではないかと思うのですが。 「Apr 8 12:30:33 ・・・・・」の比較、チェックが簡単 にできないと思います。 こういうのはどうですか。 5分前に動いた時のファイルのレコード数と今回動いた時の ファイルにレコード数の差をtailコマンドでファイルに出力 というのは。? |
>>4567 まんたろう > 「Apr 8 12:30:33 ・・・・・」の比較、チェックが簡単にできないと思います。 echo "Apr 02 12:25:00 ===" | sort -M - logfile | cat -n | grep "===" | awk '{print $1}' として行番号をとって、その行以降を tail で出力とか。 まぁ筋の悪いやり方だとは思いますので、他の方法がよいでしょう。 |
>>4568 68user >echo "Apr 02 12:25:00 ===" | sort -M - logfile | cat -n | grep "===" | awk '{print $1}' >として行番号をとって、その行以降を tail で出力とか。 予めファイルの全体のレコード数も必要ということですか。 マイナスとなった場合、どうなるのですか。? |
>>4578 EBA echo "Apr 10 09:30:00 ===" | sort -M - logfile | cat -n | grep "===" | awk '{print $1}' と実行してみたのですが、行番号が2となります。 # cat logfile <pre> Apr 9 12:23:01 ・・・・・・・ Apr 9 15:17:43 ・・・・・・・ Apr 9 17:48:06 ・・・・・・・ Apr 9 18:05:30 ・・・・・・・ Apr 9 18:06:24 ・・・・・・・ Apr 10 09:23:08 ・・・・・・・ Apr 10 11:47:23 ・・・・・・・ Apr 10 13:35:49 ・・・・・・・ Apr 11 09:54:11 ・・・・・・・ Apr 11 12:17:38 ・・・・・・・ </pre> 行番号ではなく、すべてを表示したのですが、 sortが正しく行われていないみたいなのですが、 どうしてなのでしょうか。 <pre> # echo "Apr 10 09:30:00 ===" | sort -M - logfile | cat -n 1 Apr 9 12:23:01 ・・・・・・・ 2 Apr 10 09:30:00 === 3 Apr 9 15:17:43 ・・・・・・・ 4 Apr 9 17:48:06 ・・・・・・・ 5 Apr 9 18:05:30 ・・・・・・・ 6 Apr 9 18:06:24 ・・・・・・・ 7 Apr 10 09:23:08 ・・・・・・・ 8 Apr 10 11:47:23 ・・・・・・・ 9 Apr 10 13:35:49 ・・・・・・・ 10 Apr 11 09:54:11 ・・・・・・・ 11 Apr 11 12:17:38 ・・・・・・・ </pre> 行番号以降をtailで出力は、 # tail +行番号 logfile でできました。 |
>>4570 べた Linux ではうまくいきましたが、Solaris 環境がないので確認できません。 どなたかご確認いただけませんか? あと、このやり方は新年 00:00:00〜00:05:00 の間はうまく動作しませんので、 おすすめしません。念のため。 |
>>4571 68user ありがとうございます。 >あと、このやり方は新年 00:00:00〜00:05:00 の間はうまく動作しませんので、 >おすすめしません。念のため。 確認して頂いたのですか。 良い方法だと思ってはいたのですが、ダメですか。 他に、良い方法があるのでしたら伺いたいのですが。 |
おひさしぶりです。自分が困ったときだけ出てきてすみません。 Windows のマシンと UNIX のマシンが存在する LAN で、 お互いにメールを送りあうというテストをやっています。 ここでは簡単のため、Windows マシン1台と UNIX マシン1台とします。 W に pmail というフリーウェアの SMTP / POP サーバーを入れた人がいて、 W と U の両方に Mozilla Thunderbird を入れて、 Thunderbird のアカウント設定で、 W の IP アドレスを SMTP / POP アドレス欄に指定することで、 W と U の間でメールのやり取りをすることができました。 しかし、テストの要件のひとつに、 U 側では MUA として /bin/mail も使えるようにする、というものがありました。 sendmail の設定を変えようとしようと思ったのですが、 それは大変だからやめたほうがいいと上司に言われ、 言われるままに U に Postfix を入れました。 ちなみに U の OS は HP-UX 11i ver.2 です。 Postfix のインストールはなんとなく終わりました。 /etc/postfix/main.cf に myhostaname = U.unix.net と変更を加えました。 DNS を立てるのはなかなか面倒だと上司に言われたので、言われるままに U の /etc/hosts および W の C:\Winnt\system32\drivers\etc\hosts に 172.16.10.2 U.unix.net 172.16.10.3 W.windows.net のように書きました。 で、U 側で # mail root nantoka kantoka . のように書くと、 で自分宛に出したメールが確認できましたが、 # mail dareka@W.windows.net nandakakandaka . のようにすると、 Diagnostic-Code: X-Postfix; Host or domain name not found. Name Service error for name=W.windows.net type=A: Host not found のように怒られます。 (ここで、dareka は W の pmail に設定したメールアカウントです。) U から # nslookup > W.windows.net とすると 172.16.10.3 が、 > 172.16.10.3 とすると W.windows.net が正しく帰るのですが、 host W.windows.net とすると not found 3(NXDOMAIN) と言われます。 このへんが原因でしょうか。 この状況で、U から W に /bin/mail でメールを出すことができるでしょうか。 また、W の Thunderbird から出したメールを U の /bin/mail で受けるためには、qpopper のようなプログラムを U に入れないといけないのでしょうか。 他に、いまの私の状況でもっと簡単にテストするアイディアがわかれば ご教示ください。 いろいろ聞いてすみません。よろしくお願いします。 |
>>4572 べた > 他に、良い方法があるのでしたら伺いたいのですが。 まず、syslog の出力には年がないという根本的欠陥があります。なので、 ログファイルを後からチェックするだけでは、完璧な判定はできません。 たとえば Apr 9 12:23:00 ... (2005年出力) Apr 9 12:23:01 ... (2006年出力) とか Apr 9 12:23:01 ... (2005年出力) Apr 9 12:23:00 ... (2006年出力) というケースもありうるわけです。また、現在 1月1日 0時2分だとして、 1分前に出力されたログ Jan 1 00:01:00 ... と、5分前の時刻 Dec 31 12:57:00 ... をソートすると Jan 1 の方が先になり、意図した結果になりません。 それを踏まえた上で、 - 1年前のログが残っていることはないとみなす - 年初 5分は目をつぶる が許容できるかどうかはあなたが判断してください。なお、Jan や Feb の ソートについては、sed で 01 や 02 に置換すれば何とでもできるでしょう。 理想は年が記録されるログに乗り換えることですが (=syslog を捨てる)、 それが許されるシチュエーションはあまりないと思いますので、 >>4567 まんたろう は現実的な落としどころと考えます。 >>4573 ふくし > Diagnostic-Code: X-Postfix; Host or domain name not found. Name Service > error for name=W.windows.net type=A: Host not found Postfix はよく知りませんが、 http://www.kobitosan.net/postfix/ML/arc.4/msg00048.html でしょうか。あと、うまくいくかどうかわかりませんが、 # mail 'dareka@[172.16.10.3]' と IP アドレスを直接指定するとか。@[..] は IP アドレス指定の場合の メールアドレス記述方法だったような気がしますが、使ったことはありません。 # http://x68000.q-e-d.net/~68user/rfc/?key=821&target=title > # nslookup nslookup は、/etc/hosts を参照しません。 と思ったら、HP-UX の nslookup は参照するんですね。へぇ。 http://docs.hp.com/ja/B2355-90851/nslookup.1.html > また、W の Thunderbird から出したメールを > U の /bin/mail で受けるためには、qpopper のようなプログラムを > U に入れないといけないのでしょうか。 mail コマンドには POP クライアントの機能はないと思いますので、 W で POP サーバを動かすという前提であれば、 - W にメールが届くと U に転送し、mail コマンドは /var/spool/mail などを 直接参照する。 - U で fetchmail などの POP クライアントを動かし、/var/spool/mail などに 書き出す。 - W・U 両方で POP サーバを動かし、W 宛のメールは W の POP サーバから 取得し、U 宛のメールは U の POP サーバから取得する。 などの方法があります (他にもあると思いますが)。 言うまでもありませんが、要件自体が不適切である可能性もあります。 |
>>4574 さん、ありがとうございます。 # mail 'dareka@[172.16.10.3]' を指定すると、 Diagnostic-Code; X-Postfix; host 172.16.10.3[172.16.10.3] said: 550 5.1.1 <dareka@[172.16.10.3]>... Not local user, server is not relaid. Recipient error (in reply to RCPT TO command) と言われます。 試みに dareka というコンピューターユーザーを W に作ってみましたが 現象は変わりませんでした ;;; 教えていただいたリンクをたどって http://www.kobitosan.net/postfix/jhtml/faq.html#intranet に到達していくつかのことをやってみました。 ・/etc/postfix/main.cf で disable_dns_lookups = yes と書けば /etc/hosts を見に行って W.windows.net の名前解決をしてくれる? =>ダメでした(dareka@W.windows.net で host not found になる) ・さらに /etc/postfix/main.cf で relayhost = W.windows.net と書く =>同じ状況です。 (# mail dareka@W.windows.net で host not found、 # mail 'dareka[@172.10.16.3]' で not a local user) ・/etc/postfix/main.cf で relayhost = W.windows.net と書く =>同じ状況です。 (# mail dareka@W.windows.net で host not found、 # mail 'dareka[@172.10.16.3]' で not a local user) これ、W.windows.net の smtp サーバーである pmail が POP before SMTP auth をやっているのが原因かも・・・。 (フリー版の制約で切れない) ・relayhost の設定をやめ、 transport_maps = dbm:/etc/postfix/transport と設定する。 /etc/postfix/transport の中身を windows.net :[W.windows.net] .windows.net :[W.windows.net] にし、postmap /etc/postfix/transport をしてから、 postfix reload する。 (/etc/postfix/transport の前に hash、db、dbm などの何をつけるかは postmap が生成するデータベースによる。 間違うと postfix reload で怒られる) =>同じ状況です。 ・/etc/postfix/transport の中身を windows.net :[172.16.10.3] .windows.net :[172.16.10.3] とか windows.net smtp:[W.windows.net] .windows.net smtp:[W.windows.net] とか windows.net smtp:[172.16.10.3] .windows.net smtp:[172.16.10.3] とかにしてみる。 =>同じ状況です。。。 ううーん、困った。 でも人に聞きながらやってると整理がついていいですね (^^) |
>>4547 ありがとうございます。 どうも、無理みたいですね。 1年。つまり、同じ年ということであるのならば、何とかできるの でしょうが、年をまたいでしまうと無理ですね。 >Jan や Feb のソートについては、sed で 01 や 02 に置換すれば >何とでもできるでしょう。 すみません。方法教えてください。 > >>4567 まんたろう > は現実的な落としどころと考えます。 現実な落としどころとは。? |
BCCでwindowsプログラムをコンパイルしようとすると 「外部シンボル '_main' が未解決」というのが出てしまいます。 「-WオプションをつけてコンパイルすればWindowsアプリができます」と本に 書いてあるのですが、どうすればいいのかわかりません |
以下の様なカンマ区切りのファイルがあります。 001,a2,a3,a4,a5,a6,a7,a8,a9,a10,,,,,, 002,a2,a3,a4,a5,a6,a7,a8,a9,a10,111:222,123:456,001:002,100:200,A01:A02,0:1 003,a2,a3,a4,a5,a6,a7,a8,a9,a10,111:222,123:,:,:,A01:A02,: フィールドの11カラム以降からは、コロン区切りで複数設定されている場合がある ので、複数行に分けたいのです。 以下の様に、 001,a2,a3,a4,a5,a6,a7,a8,a9,a10,,,,,, 002,a2,a3,a4,a5,a6,a7,a8,a9,a10,111,123,001,100,A01,0 002,a2,a3,a4,a5,a6,a7,a8,a9,a10,222,456,002,200,A02,1 003,a2,a3,a4,a5,a6,a7,a8,a9,a10,111,123,,,A01, 003,a2,a3,a4,a5,a6,a7,a8,a9,a10,222,,,,A02, に編集し、ファイルに出力したいのですが、11カラム以降の処理が上手く行きません。 3通りほど、試してみたのですが、それぞれ駄目でした。 どこがいけないのかとどうすればよいのかを教えてください。 環境は、 Solaris8、Bシェル です。 No.1 ----------------------------------------------------------------- #!/bin/sh # if [ $# -eq 0 ] ; then echo "$0 FileName" exit 1 fi FILE=$1 OUT_FILE=kekka.log rm ${OUT_FILE} > /dev/null 2>&1 nawk -v OUT=${OUT_FILE} ' function max_desc(lstadr,lst) { m=split(lstadr,lst,":") ; return m ; } { cnt=1 ; n=split($0,arglst,",") ; for(i=11;i<=n;i++) { m=max_desc(arglst[i],lst["${i}"]) ; if (m>cnt) { cnt=m ; } } no=1 ; for(i=1; i<=cnt; i++) { for(j=1; j<=n; j++) { if (j==2) { printf("%d,",no++) >> OUT ; } else if (j==11 || j==12 || j==13 || j==14 || j==15 || j==16) { printf("%s,",lst["${j}"][i]) >> OUT ; } else { printf("%s,",arglst[j]) >> OUT ; } } printf("\n") >> OUT ; } }' ${FILE} exit 0 No.2 ----------------------------------------------------------------- #!/bin/sh # if [ $# -eq 0 ] ; then echo "$0 FileName" exit 1 fi FILE=$1 OUT_FILE=kekka.log rm ${OUT_FILE} > /dev/null 2>&1 nawk -v OUT=${OUT_FILE} ' function max_desc(lstadr,lst) { cnt=split(lstadr,lst,":") ; return cnt ; } { num=1 ; n=split($0,arglst,",") ; for(i=11;i<=n;i++) { ret=max_desc(arglst[i],lst[++x,y]) ; if (ret>num) { num=ret ; } } nf=x ; no=1 ; for(y=1; y<=num; y++) { for(j=1; j<=10; j++) { if (j==2) { printf("%d,",no++) >> OUT ; } else { printf("%s,",arglst[j]) >> OUT ; } } for(x=1; x<=nf; x++) { printf("%s,",lst[x,y]) >> OUT ; } printf("\n") >> OUT ; } }' ${FILE} exit 0 No.3 ----------------------------------------------------------------- #!/bin/sh # if [ $# -eq 0 ] ; then echo "$0 FileName" exit 1 fi FILE=$1 OUT_FILE=kekka.log rm ${OUT_FILE} > /dev/null 2>&1 nawk -v OUT=${OUT_FILE} ' function max_desc(lstadr,lst,x) { cnt=split(lstadr,arrlst,":") ; for(j=1;j<=cnt;j++) { lst[x,j]=arrlst[j] ; } return cnt ; } { num=1 ; n=split($0,arglst,",") ; for(i=11;i<=n;i++) { ret=max_desc(arglst[i],lst[++x,y],x) ; if (ret>num) { num=ret ; } } nf=x ; no=1 ; for(y=1; y<=num; y++) { for(j=1; j<=10; j++) { if (j==2) { printf("%d,",no++) >> OUT ; } else { printf("%s,",arglst[j]) >> OUT ; } } for(x=1; x<=nf; x++) { printf("%s,",lst[x,y]) >> OUT ; } printf("\n") >> OUT ; } }' ${FILE} exit 0 |
>>4579 べた これが賢いやり方とも思えませんが、一応作ってみました。 ------ $ cat a.awk BEGIN { FS=","; chk_col=11; } { if ($chk_col ~ /:/) { str_head=head_string(); split_num=split($chk_col, str_foot, ":"); for (i=1; i<=split_num; i++) { for (j=chk_col+1; j<=NF; j++) { split($j, col_buf, ":"); str_foot[i]=sprintf("%s,%s", str_foot[i], col_buf[i]); } print str_head "," str_foot[i]; } } else { print; } } function head_string() { str_buf=$1; for (k=2; k<chk_col; k++) { str_buf=sprintf("%s,%s", str_buf, $k); } return str_buf; } ------ ------ $ cat a 001,a2,a3,a4,a5,a6,a7,a8,a9,a10,,,,,, 002,a2,a3,a4,a5,a6,a7,a8,a9,a10,111:222,123:456,001:002,100:200,A01:A02,0:1 003,a2,a3,a4,a5,a6,a7,a8,a9,a10,111:222,123:,:,:,A01:A02,: ------ ------ $ awk -f a.awk a 001,a2,a3,a4,a5,a6,a7,a8,a9,a10,,,,,, 002,a2,a3,a4,a5,a6,a7,a8,a9,a10,111,123,001,100,A01,0 002,a2,a3,a4,a5,a6,a7,a8,a9,a10,222,456,002,200,A02,1 003,a2,a3,a4,a5,a6,a7,a8,a9,a10,111,123,,,A01, 003,a2,a3,a4,a5,a6,a7,a8,a9,a10,222,,,,A02, ------ >>4571 68user 今更ですが、Solarisでは $ echo "Apr 02 12:25:00 ===" | sort -M - logfile | \ sort -n -k2,3 | cat -n | grep "===" | awk '{print $1}' 等としないとダメみたいです。 |
>>4580 zsh zshさん、ありがとうございます。 一応、動いたのですが、フィールド2の値を別の 文字置き換えたいのですが、どうすればよいのですか。 ファイル11以降に「:」で区切られたデータが存在した 場合、データの数分順番に番号を振りたいのです。 なければ、デフォルトで”1”としたいのです。 ----- $ cat a 001,a2,a3,a4,a5,a6,a7,a8,a9,a10,,,,,, 002,a2,a3,a4,a5,a6,a7,a8,a9,a10,111:222,123:456,001:002,100:200,A01:A02,0:1 003,a2,a3,a4,a5,a6,a7,a8,a9,a10,111:222,123:,:,:,A01:A02,: ----- 結果 001,1,a3,a4,a5,a6,a7,a8,a9,a10,,,,,, 002,1,a3,a4,a5,a6,a7,a8,a9,a10,111,123,001,100,A01,0 002,2,a3,a4,a5,a6,a7,a8,a9,a10,222,456,002,200,A02,1 003,1,a3,a4,a5,a6,a7,a8,a9,a10,111,123,,,A01, 003,2,a3,a4,a5,a6,a7,a8,a9,a10,222,,,,A02, |
>>4581 べた 適当に直してみました。 ------ BEGIN{ FS=","; chk_col=11; } { str_head_1=$1; if($chk_col ~ /:/) { str_head_2=head_string(chk_col); split_num=split($chk_col, str_foot, ":"); for (i=1; i<=split_num; i++) { for (j=chk_col+1; j<=NF; j++) { split($j, col_buf, ":"); str_foot[i]=sprintf("%s,%s", str_foot[i], col_buf[i]); } print str_head_1 "," i "," str_head_2 "," str_foot[i]; } } else { str_head_2=head_string(NF); print str_head_1 ",1," str_head_2; } } function head_string(chk_point) { str_buf=$3; for (k=3; k<chk_point; k++) { str_buf=sprintf("%s,%s", str_buf, $k); } return str_buf; } ------ |
>>4582 zsh zshさん、ありがとうございます。 >str_head_2=head_string(NF+1); >for (k=4; k<chk_point; k++) { の行を修正したら期待する結果が得られました。 ただ、ファイルのフォーマットに規則性がないことがわかり、 データによっては、正しく出力されないものがでてきました。 フィールド11に、「:」が存在しないデータがあるのです。 a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,111,123,SSS,A01,,: a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,,,,123:456:789:100:100,A01:A02:A03:3A:NTT0001, 「 if($chk_col ~ /:/) {」 の判定を増やし、フィールド番号を取得できればできますか。 |
>>4582 zsh >>4583 べた 一応、動きます。 以下のようになるのでしょうか。 BEGIN{ FS=","; chk_col=11; } { str_head_1=$1; split_num=chk_comma_max(NF); if(split_num!=0) { str_head_2=head_string(chk_col); split($chk_col, str_foot, ":"); for (i=1; i<=split_num; i++) { for (j=chk_col+1; j<=NF; j++) { split($j, col_buf, ":"); str_foot[i]=sprintf("%s,%s", str_foot[i], col_buf[i]); } print str_head_1 "," i "," str_head_2 "," str_foot[i]; } } else { str_head_2=head_string(NF+1); print str_head_1 ",1," str_head_2; } } function chk_comma_max(chk_point) { comma_num=0; for (k=chk_col; k<=chk_point; k++) { if($k ~ /:/) { comma_num=split($k, s, ":"); break; } } return comma_num; } function head_string(chk_point) { str_buf=$3; for (k=4; k<chk_point; k++) { str_buf=sprintf("%s,%s", str_buf, $k); } return str_buf; } |
>>4579 べた No.1 m=max_desc(arglst[i],lst["${i}"]) ; 添え字を利用した配列でいいのかな。 あまり利用したことはないのでなんとも入れないが、こういうところで 使えないのではないでしょうか。 添え字にマッチする文字が出てきたときに、何かするのではなかった かと思います。 No.2、No.3 多次元配列の使い方がおかしいのではないかと思います。 データをセットする側が多次元配列や、アドレス渡しの戻りができて いない。たぶん、縦軸(列)の添え字の値が正しくない。 縦軸(列)の値ってちゃんととれてますか。 |
>>4579 べた 多次元配列の使い方が正しいか問題はありますが、書き込みがあった シェルを使用して、多次元配列で動くのを作ってみました。 一応、動きますが。 ----------------------- #!/bin/sh # if [ $# -eq 0 ]; then echo "$0 FileName" exit 1 fi FILE=$1 OUT_FILE=kekka.log rm ${OUT_FILE} > /dev/null 2>&1 nawk -v OUT=${OUT_FILE} ' function max_desc(lstadr,lst,x,y) { cnt=split(lstadr,arrlst,":"); for(y=1;y<=cnt;y++) { lst[x,y]=arrlst[y]; } return cnt; } { num=1; row=0; col=0; n=split($0,arglst,","); for(i=11;i<=n;i++) { ret=max_desc(arglst[i],lst,++row,col); if (ret>num) { num=ret; } } seqno=1; for(y=1; y<=num; y++) { for(j=1; j<=10; j++) { if (j==2) { printf("%d,",seqno++) >> OUT ; } else { printf("%s,",arglst[j]) >> OUT; } } for(x=1; x<=row; x++) { printf("%s",lst[x,y]) >> OUT; if (x!=row) { printf("%s",",") >> OUT; } } printf("\n") >> OUT; } for(x=1; x<=row; x++) { for(y=1; y<=num; y++) { delete lst[x,y]; } } }' ${FILE} exit 0 ----------------------- |
あるCシェルの本でファイル検査演算子「-f」の意味は 「ファイルは普通のファイル」とあるのですが、 普通の定義が分かりません。 また、逆に普通ではないファイルとはどういったもの になるのでしょうか?? ご回答頂ければ、幸いです。 宜しくお願い致します。 |
>>4575 ふくし もう解決されているとは思いますが一応。 Postfix に hosts を参照させるのが一番の早道かつ王道だと思いますが わたしは Postfix を知らないので、識者のいるメーリングリストなどで 質問するのがよいかと思います。 >>4587 S-MSK☆ > 「ファイルは普通のファイル」とあるのですが、 > 普通の定義が分かりません。 csh 的には、stat(2) した結果の st_mode (構造体 stat のメンバ) に対して、 通常ファイル判定マクロ S_ISREG が真を返したら、「普通」です。 では S_ISREG がどういうケースで真を返すかというと、vfs の vtype の 値が VREG であるときです (vtype はファイル作成時に決定され、ファイル システムに記録される)。 では vfs の vtype の値が VREG であるのはどういうときかというと、 ファイルシステム依存です。ただし一般的な UFS で言うと、vtype は 1. シンボリックリンク 2. ソケット 3. FIFO (名前付きパイプ) 4. デバイスファイル (キャラクタデバイス・ブロックデバイス) と 5. 通常ファイル くらいです。よって、大抵の場合 1〜4 に当てはまらないなら通常ファイル といえます。 実際は、Solaris Door とか、VxFS 圧縮ファイルとか、HP-UX のネットワーク特殊 ファイルなどわけのわからんのがありますので、プログラムとしては 「1〜4 に当てはまらない場合は通常ファイル」 などという仮定はせず、素直に -f を使いましょう。 |
UNIX環境のAとBというプロセス間でsocket通信を行っています。(AF_UNIX指定) 一度、ソケットをcloseして、Bが再接続(connect)するとエラーになる場合があります。 errnoが何で返却されているのかわからないのですが。 たとえばEADDRINUSE の場合の対応策を教えて下さい。 |
番号を昇順に並び替えて、抜けている番号を表示したく、以下の様なシェル でやってみたのですが、上手く行きません。 どうすればいいでしょうか。 Solaris8 Bシェルです。 sort test.txt | nawk -v key="" '{if(FNR!=0 && $1!=key) print $1 ; key=$1}' sort test.txt | nawk -v key="" -F"," '{if(FNR!=0 && $1-1!=key) printf("%0.4d\n",key+1); key=$1}' sort test.txt | nawk -v key="" -F"," '{if(FNR!=0 && $1!=key) printf("%0.4d\n",key+1); key=$1}' # cat test.txt 0006 0009 0004 0010 0003 結果 0001 0002 0005 0007 0008 と表示したい。 |
>>4591 いち nawk -v key=1 '{ for(;;){if($1!=key) {print key; key++;} else{key=$1+1; break;}} }' a.txt でできました。 |
>>No. 4588 68user No.4587のS-MSK☆です。 ご回答有難う御座いました。 |
FTP クライアントを作ってみよう (1) FTP プロトコルの概略 |
>管理人様 FTP クライアントを作ってみよう (1) FTP プロトコルの概略 が大変勉強になりました。ありがとうございました。 |
vmstatをファイルへ出力する時に、1行毎に日時を編集したいのですがうまく出来ません。AIXですと下記のスクリプトでうまくいっているのですがsoralisではどのようにしたらよいでしょうか。 vmstat $1 $2 | awk '!/kthr|---|avm/ {printf("%s | ", $0);system("date")}' >> $LOGDIR$DATE |
>>4596 くるみんパパ system関数が使いたいのであればnawkか/usr/xpg4/bin/awkを使用してください。 |
>>4597zshさん nawkで解決しました。助かりました。ありがとうございました。 |
はじめまして。TCP/IPについて素朴な質問があります。 TCP/IPでは、ACKに対するSYNのタイムアウトがあり、 通常のLINUXであれば180秒ほどだと思います。 一方、telnetで存在しないIPを指定すると上記タイムアウトまでかからず、 以下のメッセージが出て接続できません。 Trying 192.168.60.113... telnet: Unable to connect to remote host: No route to host この場合、なぜ上記タイムアウトまで待たないのでしょうか。 telnetコマンドにて 明示的にTCPリトライ回数を指定していると考えていいのでしょうか。 また、このメッセージの意味するところはどういうところなのでしょう? 誰かご存知の方がいたらご教授願います。 |
>>4599 勉強中 直接的な回答ではありませんが、 http://X68000.q-e-d.net/~68user/net/tcp-connect-1.html をご一読ください。なお、EHOSTUNREACH が No route to host です。 |