黒田%しまったです。

mailmsg ができた時点で満足してしまって未完成なのですが…

 >長い計算ジョブの終わりを知るために、IPMessenger というアプリケーションに
 >メッセージを送るスクリプトを書いてみました。
 >これを拡張して ruby/tk と組み合わせれば使えるアプリケーションになるかな?

以下のを使って、ruby のクライアント同士がしゃべれるのは確認したのです
が、xipmsg 等を相手にするとうまくいかなかったです。多分、僕の実装ミス
だと思うんですが。

- ipmsg.rb -- 
# IPmesssenger Class for Ruby

require "socket"

class IPMSG

  VERSION = 0x0001
  DEFAULT_PORT = 0x0979
  NOOPERATION = 0x00000000
  BR_ENTRY = 0x00000001
  BR_EXIT = 0x00000002
  ANSENTRY = 0x00000003
  BR_ABSENCE = 0x00000004
  BR_ISGETLIST = 0x00000010
  OKGETLIST = 0x00000011
  GETLIST = 0x00000012
  ANSLIST = 0x00000013
  SENDMSG = 0x00000020
  RECVMSG = 0x00000021
  READMSG = 0x00000030
  DELMSG = 0x00000031
  GETINFO = 0x00000040
  SENDINFO = 0x00000041
  GETABSENCEINFO = 0x00000050
  SENDABSENCEINFO = 0x00000051
  ABSENCEOPT = 0x00000100
  SERVEROPT = 0x00000200
  DIALUPOPT = 0x00010000
  SENDCHECKOPT = 0x00000100
  SECRETOPT = 0x00000200
  BROADCASTOPT = 0x00000400
  MULTICASTOPT = 0x00000800
  NOPOPUPOPT = 0x00001000
  AUTORETOPT = 0x00002000
  RETRYOPT = 0x00004000
  PASSWORDOPT = 0x00008000
  NOLOGOPT = 0x00020000
  NEWMUTIOPT = 0x00040000
  NOADDLISTOPT = 0x00080000

  attr :user_name, TRUE

  def initialize(host = nil, port = DEFAULT_PORT)
    @msg_no = 0
    @sock = UDPsocket.new
    if ENV.has_key?("LOGNAME")
      @user_name = ENV["LOGNAME"]
    elsif ENV.has_key?("USER")
      @user_name = ENV["USER"]
    else
      @user_name = "nobody"
    end
    connect(host, port) if (host != nil)
  end

  def connect(host, port = DEFAULT_PORT)
    @sock.connect(host, port)
  end

  ####

  def ipmsg_send(cmd = NOOPERATION, msg = "")
    p_no = Process.pid + @msg_no
    rmsg = format("%d:%d:%s:%s:%d:%s",
		  VERSION, p_no, @user_name.gsub(/:/, ';'),
		  Socket.gethostname.gsub(/:/, ';'),
		  cmd, msg
		  )
    @sock.send(rmsg, 0)
    print rmsg, "\n"
    @msg_no += 1
  end
  private :ipmsg_send

  def bro_ipmsg_send(cmd = NOOPERATION, msg = "")
    p_no = Process.pid + @msg_no
    rmsg = format("%d:%d:%s:%s:%d:%s",
		  VERSION, p_no, @user_name.gsub(/:/, ';'),
		  Socket.gethostname.gsub(/:/, ';'),
		  cmd, msg
		  )
    @bro_sock.send(rmsg, 0)
    print rmsg, "\n"
    @msg_no += 1
  end
  private :bro_ipmsg_send

  ####

  def sendmsg(msg, flags = 0)
    cmd = SENDMSG | flags
    ipmsg_send(cmd, msg)
  end

  def answer(host = nil)
    @sock.connect(host, DEFAULT_PORT) if (host != nil)
    cmd = ANSENTRY
    ipmsg_send(cmd)
  end

  def recvmsg(host = nil)
#, p_no = 0)
    @sock.connect(host, DEFAULT_PORT) if (host != nil)
    cmd = RECVMSG
    ipmsg_send(cmd) #, p_no)
  end
  
  def br_sendmsg(msg, flags = 0)
    cmd = SENDMSG | BROADCASTOPT | flags
    bro_ipmsg_send(cmd, msg)
  end

  def entry(port = DEFAULT_PORT)
    @status = BR_ENTRY

    @bro_sock = UDPsocket.new
    @bro_sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, 1)
    @bro_sock.connect("<broadcast>", port)

    bro_ipmsg_send(BR_ENTRY)
  end

  def exit
    return if @status != BR_ENTRY
    @status = BR_EXIT

    bro_ipmsg_send(BR_EXIT)
    @bro_sock.close
  end

  def close
    self.exit if @status == BR_ENTRY
    @sock.close
  end
end
- --

- mailmsg みたいなもの --
#!/usr/local/bin/ruby

require "ipmsg.rb"

#ヘッダを読んで
#from と subj に値をセットする

msg = Kconv::tosjis("メイルが届きました。\n#{from}\n#{subj}\n")
im = IPMSG.new(HOST)
im.user_name = "MailMsg"
im.sendmsg(msg, (IPMSG::NOLOGOPT|IPMSG::NOADDLISTOPT))
im.close
- --