#!/usr/local/bin/ruby -w # $Id: view-state.rb,v 1.8 2008/03/03 15:53:35 dm Exp $ # (c) 2005, Dirk Meyer, Im Grund 4, 34317 Habichtswald # # Updates on: # http://anime.dinoex.net/xdcc/tools/ # $chroot = "" def usage(msg) print msg, "\nUsage: #{File.basename($0)} statefile [statefile ...]\n\n" print "export iroffer statefile to text.\n" exit 64 end def filesize_cache(key) if ( $size_cache.has_key?( key ) ) return $size_cache[ key ] end bytes = File.size( "#{$chroot}#{key}") $size_cache[ key ] = bytes $size_cache_dirty += 1 return bytes end def makesize(bytes) nbytes = bytes if ( nbytes < 1000 ) return sprintf( "%3db", nbytes ) end nbytes = ( nbytes + 512 ) / 1024 if ( nbytes < 1000 ) return sprintf( "%3dk", nbytes ) end nbytes = ( nbytes + 512 ) / 1024 if ( nbytes < 1000 ) return sprintf( "%3dM", nbytes ) end if ( nbytes < 10000 ) return sprintf( "%3.1fG", ( nbytes.to_f / 1024) ) end nbytes = ( nbytes + 512 ) / 1024 if ( nbytes < 1000 ) return sprintf( "%3dG", nbytes ) end if ( nbytes < 10000 ) return sprintf( "%3.1fT", ( nbytes.to_f / 1024 ) ) end nbytes = ( nbytes + 512 ) / 1024 if ( nbytes < 1000 ) return sprintf( "%3dT", nbytes ) end return sprintf( "%3dE", nbytes ) end def ausgabe() if $xf.nil? return end $pack += 1 $all_pack += 1 printf( "%3s %3dx [%4s] %s\n", "##{$pack}", $xg, $size, $xd ) $xf = nil end def ausgabetotal() $sum_size = makesize( $sum_bytes ) $transfer_size = makesize( $transfer_bytes ) $partial_bytes = $transfer_bytes - $sum_xg_bytes if ( $partial_bytes >= 0 ) $partial_size = makesize( $partial_bytes ) else $partial_size = '-' << makesize( $partial_bytes ) end $total = sprintf( "total in files, [%4s] total downloaded, [%4s] partial", $transfer_size, $partial_size ) printf( "%3s %3dx [%4s] %s\n", "##{$pack}", $sum_xg, $sum_size, $total ) end def get_long(string) return string.unpack('N')[ 0 ] end def get_xlong(string) ll = string.unpack('NN') l = ll[ 0 ] * ( 2 ** 32 ) l += ll[ 1 ] return l end def get_text(string) l = string.unpack('C')[ 0 ] l -= 1 return string[1, l] end def parse_buffer(buffer, bsize) $xf = nil fsize = bsize - 16; ipos = 8 while ipos < fsize tag = get_long( buffer[ipos, 4] ) len = get_long( buffer[ipos + 4, 4] ) if ( len <= 8 ) printf( ":tag=%d
\n", tag ) printf( ":len=%d
\n", len ) printf( "Warning: parsing statfile aborted\n" ) ipos = fsize break end case tag when 514 # TOTAL_SENT text = buffer[ipos + 8, len - 8] $total = get_xlong( text ) if ( $all_transfer_bytes > 0 ) print "\n" end $transfer_bytes += $total $all_transfer_bytes += $total $pack = 0 when 3072 # XDCCS chunkdata = buffer[ipos, len] jpos = 8 while jpos < len jtag = get_long( chunkdata[jpos, 4] ) jlen = get_long( chunkdata[jpos + 4, 4] ) if ( len <= 8 ) printf( ":xtag=%d
\n", jtag ) printf( ":xlen=%d
\n", jlen ) printf( "Warning: parsing statfile aborted\n" ) jpos = len break end case jtag when 0 jpos = len when 3073 # FILE ausgabe() text = chunkdata[jpos + 7, jlen - 8] $xf = get_text( text ) $bytes = filesize_cache( $xf ) $sum_bytes += $bytes $all_bytes += $bytes $size = makesize( $bytes ) $xd = text.gsub( /^.*\//, '' ) when 3074 # DESC text = chunkdata[jpos + 7, jlen - 8] $xd = get_text( text ) when 3076 # GETS text = chunkdata[jpos + 8, jlen - 8] $xg = get_long( text ) $sum_xg += $xg $all_xg += $xg $xg_bytes = $xg * $bytes $sum_xg_bytes += $xg_bytes $all_xg_bytes += $xg_bytes # when 3080 # GROUP NAME # text = chunkdata[jpos + 7, jlen - 8] # group = get_text( text ) # when 3081 # GROUP DESC # text = chunkdata[jpos + 7, jlen - 8] # groupdesc = get_text( text ) # printf( "groupdesc %s %s\n", group, groupdesc ) when 3082 # LOCK text = chunkdata[jpos + 7, jlen - 8] $lock = get_text( text ) case $lock when 'badcrc', 'old' $xd << " (#{$lock})" else $xd << ' (gesperrt)' end end jpos += jlen r = jlen % 4 if ( r > 0 ) jpos += 4 - r end end end ipos += len; r = len % 4; if ( r > 0 ) ipos += 4 - r; end end ausgabe() ausgabetotal() $pack = 0 $sum_bytes = 0 $sum_xg = 0 $sum_xg_bytes = 0 $transfer_bytes = 0 end $size_filename = "size.data" $size_cache_dirty = 0 $size_cache = Hash.new(0) if ( FileTest.exist?($size_filename) ) begin File.open($size_filename, 'r').each_line { |line| line.delete!( "\n" ) line.delete!( "\r" ) words = line.split( ':' ) i = words[ 1 ].to_i if ( i > 0 ) $size_cache[ words[ 0 ] ] = i end } rescue $stderr.print "Failure at #{$size_filename}: #{$!} => Skipping!\n" end end $all_pack = 0 $all_bytes = 0 $all_xg = 0 $all_xg_bytes = 0 $all_transfer_bytes = 0 $pack = 0 $sum_bytes = 0 $sum_xg = 0 $sum_xg_bytes = 0 $transfer_bytes = 0 if ARGV.size > 0 then ARGV.each { |filename| File.stat(filename).file? or next if ( /removed/.match( filename ) ) File.open(filename, 'r').each_line { |line| line.delete!( "\n" ) line.delete!( "\r" ) if ( /^Do Not Edit This File[:] /.match( line ) ) parts = line.split( ': ', 2 ) words = parts[ 1 ].split( ' ', 4 ) $total = words[ 2 ].to_i if ( $all_transfer_bytes > 0 ) print "\n" end $transfer_bytes += $total $all_transfer_bytes += $total next end words = line.split( ' ', 2 ) case words[ 0 ] when 'xx_file' $xf = words[ 1 ] $bytes = 0 when 'xx_desc' $xd = words[ 1 ] when 'xx_size' $bytes = words[ 1 ].to_i when 'xx_gets' if $bytes == 0 $bytes = filesize_cache( $xf ) end $sum_bytes += $bytes $all_bytes += $bytes $size = makesize( $bytes ) $xg = words[ 1 ].to_i $sum_xg += $xg $all_xg += $xg $xg_bytes = $xg * $bytes $sum_xg_bytes += $xg_bytes $all_xg_bytes += $xg_bytes ausgabe() end } else bsize = File.size(filename) begin buffer = File.open(filename, 'r').read parse_buffer( buffer, bsize ) rescue $stderr.print "Failure at #{filename}: #{$!} => Skipping!\n" end end } else usage('State-file not given!') end if ( $sum_bytes != $all_bytes ) print "\n" $pack = $all_pack $sum_bytes = $all_bytes $sum_xg = $all_xg $sum_xg_bytes = $all_xg_bytes $transfer_bytes = $all_transfer_bytes ausgabetotal() end if ( $size_cache_dirty > 0 ) f = File.new($size_filename, 'w') if ( f.nil? ) $stderr.print "Failure to save cache #{$size_filename}\n" exit 1 end $size_cache.each {|key, value| f.write( "#{key}:#{value}\n" ) } f.close end exit 0 #