#!/usr/bin/ruby # qmailanalog matchup Msg = Struct.new(:m,:bytes,:qp,:uid,:numk,:numd,:numz,:sender,:birth) @msg = {} def msg_find(m) @msg[m] end def msg_add(m) msg = Msg.new msg.m = m @msg[m] = msg msg end def msg_kill(msg) @msg.delete msg.m end Del = Struct.new(:d,:msg,:start,:chan,:recip) @del = {} def del_find(d) @del[d] end def del_add(d) del = Del.new del.d = d @del[d] = del del end def del_kill(del) @del.delete del.d end def clear @del.clear end def starting d = @field[3].to_i m = @field[5].to_i del = del_add(d) del.msg = m del.start = @field[0] del.chan = @field[7] del.recip = @field[8].downcase end def delivery result = '?' reason = '' d = @field[2].to_i del = del_find(d) return unless del m = del.msg msg = msg_find(m) case @field[3] when /^succ/ msg.numk += 1 if msg result = 'd k ' reason = @field[4] || '' when /^fail/ msg.numd += 1 if msg result = 'd d ' reason = @field[4] || '' when /^defer/ msg.numz += 1 if msg result = 'd z ' reason = @field[4] || '' when /^report/ msg.numz += 1 if msg result = 'd z ' reason = 'report_mangled' end print result if msg print msg.birth print ' ', del.start print ' ', @field[0] print ' ', msg.bytes print ' ', msg.sender print ' ', del.chan print '.', del.recip print ' ', msg.qp print ' ', msg.uid print ' ', reason else print del.start print ' ', del.start print ' ', @field[0] print ' 0 ? ', del.chan print '.', del.recip print ' ? ? ', reason end print "\n" del_kill(del) end def newmsg m = @field[3].to_i msg = msg_find(m) return unless msg msg_kill(msg) end def endmsg m = @field[3].to_i msg = msg_find(m) return unless msg print 'm ', msg.birth print ' ', @field[0] print ' ', msg.bytes print ' ', msg.numk print ' ', msg.numd print ' ', msg.numz print ' ', msg.sender print ' ', msg.qp print ' ', msg.uid print "\n" msg_kill(msg) end def info m = @field[3].to_i msg = msg_add(m) msg.bytes = @field[5].to_i msg.qp = @field[9].to_i msg.uid = @field[11].to_i msg.numk = 0 msg.numd = 0 msg.numz = 0 msg.birth = @field[0] msg.sender = @field[7].downcase end def extra m = @field[2].to_i msg = msg_find(m) return unless msg msg.numk = @field[3].to_i msg.numz = @field[4].to_i msg.numd = @field[5].to_i end def pending o = $stderr @msg.each do |m, msg| o.print msg.birth o.print ' info msg ' o.print msg.m o.print ': bytes ' o.print msg.bytes o.print ' from ' o.print msg.sender o.print ' qp ' o.print msg.qp o.print ' uid ' o.print msg.uid o.print "\n" o.print msg.birth o.print ' extra ' o.print msg.m o.print ' ' o.print msg.numk o.print ' ' o.print msg.numz o.print ' ' o.print msg.numd o.print "\n" end @del.each do |d, del| o.print del.start o.print ' starting delivery ' o.print del.d o.print ': msg ' o.print del.msg o.print ' to ' o.print del.chan o.print ' ' o.print del.recip o.print "\n" end end while line = gets @field = line.chomp.split(/ /) case @field[1] when 'status:' when 'starting' starting when 'delivery' delivery when 'new' newmsg when 'end' endmsg when 'info' info when 'extra' extra when 'running' clear when 'exiting' clear when 'number' when 'local' when 'remote' when 'warning:' print line when 'alert:' print line else print '? ' print line end end pending