From 7d8024041069cbb43930a6666f8854d6d981af12 Mon Sep 17 00:00:00 2001 From: Ward Wouts Date: Fri, 18 Apr 2003 22:53:25 +0000 Subject: [PATCH] prepare foor splitting this off --- trunk/ripnews/encode/uuencode.rb | 187 ++++++++++++++++++ trunk/ripnews/encode/yenc.rb | 321 +++++++++++++++++++++++++++++++ 2 files changed, 508 insertions(+) create mode 100644 trunk/ripnews/encode/uuencode.rb create mode 100644 trunk/ripnews/encode/yenc.rb diff --git a/trunk/ripnews/encode/uuencode.rb b/trunk/ripnews/encode/uuencode.rb new file mode 100644 index 0000000..048bc97 --- /dev/null +++ b/trunk/ripnews/encode/uuencode.rb @@ -0,0 +1,187 @@ +################################# +# +# $Dwarf: article.rb,v 1.59 2002/11/05 10:29:51 ward Exp $ +# $Source$ +# +# article.rb +# +# (C) 2002, Ward Wouts +# +################################# + +require 'tempfile' + +class yEnc + +Debuglevel = 0 + +def uudecode(data, outfile=nil) + case data.type.to_s + when "Array" + print "Calling _uudecode_array\n" if Debuglevel>0 + mode, filename, body = _uudecode_array(data) + when "File", "Tempfile" + unless outfile + print "uudecode: need outfile\n" + exit + end + print "Calling _uudecode_file\n" if Debuglevel>0 + mode, filename, body = _uudecode_file(data, outfile) + else + print "Funny stuff in uudecode. Data of type \"#{data.type.to_s}\"\n" + end + return mode, filename, body +end + +def _uudecode_file(file, outfile) + mode = 0600 + filename = "unknown" + c = 0 + lines = file.pos + percent = 0 + mark = lines/100 + file.pos=0 + + while (! file.eof) + line = file.gets + print "line: #{line}" if Debuglevel > 0 + if line =~ /^begin(.*)/ + m = $1 + print "beginning matched; rest: #{m}\n" if Debuglevel > 0 + if m =~ /^(\s+(\d+))?(\s+(.*?\S))?\s*\Z/ + mode = $2 + filename = $4 + print "found beginning\n" if Debuglevel > 0 + else + print "mode, file set to defaults: #{m}\n" + end + break + end + end + + if file.eof + print "Not UUencoded!\n" + return false + end + print "c: #{c} mark: #{mark} lines: #{lines}\n" if Debuglevel > 1 + + print " UUdecoding...\n" + + while (! file.eof) + if Debuglevel > 1 + c = file.pos + if c > mark + print "#{percent}%\n" + print "c: #{c} mark: #{mark} lines: #{lines}\n" if Debuglevel > 1 + percent += 1 + mark = (lines/100)*(percent+1) + end + end + line = file.gets + print "line: #{line}" if Debuglevel > 1 + return mode, filename if line =~ /^end/ + next if line =~ /[a-z]/ + next if line == nil + next unless ((((line[0] - 32) & 077) + 2) / 3).to_i == + (line.length/4).to_i + outfile.print line.unpack("u") + end + + print "No \"end\" found!!!\n" + #return mode, file, outfile + return false +end + +# gaat volgens mij niet verder als er meerdere uuencoded blocks zijn... +# zal dan meerdere keren aangeroepen moeten worden, grmbl... +# tis getting a mess as we speak... +# toch maar een keer aparte class van maken... +def _uudecode_array(data) + decode = [] + mode = 0600 + filename = "unknown" + c = 0 + lines = data.length + percent = 0 + mark = lines/100 + + i = 0 + while (i < data.length) + if data[i] =~ /^begin(.*)/ + m = $1 + print "beginning matched; rest: #{m}\n" if Debuglevel > 0 + if m =~ /^(\s+(\d+))?(\s+(.*?\S))?\s*\Z/ + mode = $2 + filename = $4 + print "found beginning\n" if Debuglevel > 0 + else + print "mode, filename set to defaults: #{m}\n" + end + break + end + i += 1 + end + + unless (i < data.length) + print "Not UUencoded!\n" + return false + end + + print "UUdecoding...\n" + + while (i < data.length) + if Debuglevel > 1 + if c > mark + print "#{percent}%\n" + print "c: #{c} mark: #{mark} lines: #{lines} i: #{i}\n" if Debuglevel > 1 + percent += 1 + mark = (lines/100)*(percent+1) + end + c += 1 + end + line = data[i] + i += 1 + return mode, filename, decode if line =~ /^end/ + next if line =~ /[a-z]/ + next if line == nil + next unless ((((line[0] - 32) & 077) + 2) / 3).to_i == + (line.length/4).to_i + decode.concat(line.unpack("u")) + end + + print "No \"end\" found!!!\n" + return false +end + +#def uudecode_group(subj, file=nil, outfile=nil) +def uudecode_group(subj, tempdir=nil) + group_subjects unless @grouped + + body = get_group_body_first(subj) + if body.to_s =~ /begin/ + print "uuencoded!\n" if Debuglevel > 0 + if (tempdir != nil) + file = Tempfile.new("#{tempdir}/riptmp") + body.collect{|i| file.print "#{i}\n"} + get_group_body_rest(subj, file) + mode, filename, result = uudecode(file, outfile) + else + body.concat(get_group_body_rest(subj)) + mode, filename, result = uudecode(body) + end + return mode, filename, result + else + print "Not uuencoded!\n" if Debuglevel > 0 + return false + end +end + +def is_uuencoded(data) + if data.to_s =~ /begin\s+\d+?\s+.*?\S?\s*\Z/ + return true + else + return false + end +end + +end # class diff --git a/trunk/ripnews/encode/yenc.rb b/trunk/ripnews/encode/yenc.rb new file mode 100644 index 0000000..d3c5009 --- /dev/null +++ b/trunk/ripnews/encode/yenc.rb @@ -0,0 +1,321 @@ +################################# +# +# $Dwarf: article.rb,v 1.59 2002/11/05 10:29:51 ward Exp $ +# $Source$ +# +# article.rb +# +# (C) 2002, Ward Wouts +# +################################# + +require 'tempfile' + +class Article + +Debuglevel = 0 + +def ydecode(data, outfile=nil) + if @ymap.empty? + (-106..255).each do |b| + @ymap[b]=((b-42)%256) + end + end + + case data.type.to_s + when "Array" + print "Calling _ydecode_array\n" if Debuglevel>0 + mode, filename, body = _ydecode_array(data) + when "File", "Tempfile" + unless outfile + print "ydecode: need outfile\n" + exit + end + print "Calling _ydecode_file\n" if Debuglevel>0 + mode, filename, body = _ydecode_file(data, outfile) + else + print "Funny stuff in ydecode. Data of type \"#{data.type.to_s}\"\n" + end + return mode, filename, body +end + +def _ydecode_line(line) + i = 0 + ll = line.length + ostr = '' + while i < ll + if line[i] == 0x3d + i += 1 + line[i] -= 64 + end + ostr << @ymap[line[i]] + i += 1 + end + return ostr, ostr.length +end + +def _ydecode_file(file, outfile) + mode = 0600 + filename = "unknown" + lines = file.pos + file.pos = 0 + bytes = 0 + total = 0 + oldpartend = 0 + search_begin = false + + while (! file.eof) + line = file.gets + print "line: #{line}" if Debuglevel > 0 + if line =~ /^\=ybegin\s+(.*line\=.*)/ + m = $1 + print "ybegin match; rest: #{m}\n" if Debuglevel > 0 + if m =~ /^\s*(part\=(\d+)\s+)?(total\=(\d+)\s+)?(line\=(\d+))(\s*size\=(\d+))(\s*name=(.*))\Z/ + part = $2.to_i + total = $4.to_i + linesize = $6.to_i + totalsize = $8.to_i + filename = $10 + print "found beginning" + if part != nil + print " of part #{part}" + end + if total != nil + print " of #{total}" + end + print ", linesize = #{linesize}, size = #{totalsize}, filename = #{filename}\n" + break + else + print "not a valid yenc begin line\n" + end + end + end + + if file.eof + print "Not yencoded!\n" + return false + end + + print " ydecoding...\n" + + while (! file.eof) + print "at #{file.pos} need to go to #{lines}\n" if Debuglevel > 1 + line = file.gets + line.chop! + + if line =~ /^=yend\s+(.*)\Z/ + m = $1 + m =~ /(\s*size=(\d+)\s+)(\s*part=(\d+))?(\s+crc32=(\S+))?/ + size = $2.to_i + part = $4.to_i + crc = $6 + if size != bytes + print "part size mismatch, is #{bytes}, should be #{size}\n" + end + if part == nil + return mode, filename + end + total += bytes + if total >= totalsize + if total != totalsize + print "total size mismatch, is #{total}, should be #{totalsize}\n" + end + return mode, filename + end + search_begin = true + bytes = 0 + next + end + if search_begin && line =~ /^\=ybegin\s+(.*)\Z/ + m = $1 + search_begin = false + if m =~ /^\s*(part\=(\d+)\s+)?(total\=(\d+)\s+)?(line\=(\d+))(\s*size\=(\d+))(\s*name=(.*))\Z/ + part = $2.to_i + total = $4.to_i + linesize = $6.to_i + totalsize = $8.to_i + filename = $10 + print "found beginning of part #{part}, linesize = #{linesize}, size = #{totalsize}, filename = #{filename}\n" if Debuglevel > 0 + end + next + end + if search_begin == true + next + end + if line =~ /^=ypart\s+(\s*begin=(\d+))(\s+end=(\d+))/ + b = $2 + e = $4 + print " next part begin #{b}, end #{e}\n" + if b.to_i == oldpartend + 1 + oldpartend = e.to_i + else + raise PermError, "Parts not continuous! last end #{oldpartend}, begin #{b}" + end + next + end + +# This seems to be a common 'error' - maybe I misunderstand the spec or +# something +# if line.length != linesize +# print "linesize mismatch, was #{line.length}, should be #{linesize}...\n" +# end + +# i = 0 +# ll = line.length +# ostr = '' +# while i < ll +# if line[i] == 0x3d +# i += 1 +# line[i] -= 64 +# end +# ostr << ymap[line[i]] +# i += 1 +# end + ostr, ostrl = _ydecode_line(line) + outfile << ostr + bytes += ostrl + end + + print "No \"=yend\" found!!!\n" + return mode, filename, outfile +end + +# toch maar een keer aparte class van maken... geld ook voor dit geneuzel +def _ydecode_array(data) + decode = "" + mode = 0600 + filename = "unknown" + c = 0 + lines = data.length + bytes = 0 + percent = 0 + mark = lines/100 + +# ymap = {} +# (-106..255).each do |b| +# ymap[b]=((b-42)%256) +# end + + i = 0 + while (i < data.length) + if data[i] =~ /^\=ybegin\s+(.*line\=.*)/ + m = $1 + print "ybegin match; rest: #{m}\n" if Debuglevel > 0 + if m =~ /^\s*(part\=(\d+)\s+)?(total\=(\d+)\s+)?(line\=(\d+))(\s*size\=(\d+))(\s*name=(.*))\Z/ + part = $2.to_i + total = $4.to_i + linesize = $6.to_i + size = $8.to_i + filename = $10 + print "found beginning, linesize = #{linesize}, size = #{size}, filename = #{filename}\n" if Debuglevel > 0 + i += 1 + break + else + print "not a valid yenc begin line\n" + end + end + i += 1 + end + + unless (i < data.length) + print "Not yencoded!\n" + return false + end + + print "ydecoding...\n" + + while (i < data.length) + print "at #{i} need to go to #{data.length}\r" if Debuglevel > 1 + line = data[i] + i += 1 + if line =~ /^\=yend(\s+size=(\d+))(\s+crc32=(\S+))?/ + size = $2.to_i + crc = $4 + if size != decode.length + print "size mismatch, was #{decode.length}, should be #{size}\n" + end + dec = [ decode ] + return mode, filename, dec + end + if line =~ /^\=ypart.*\Z/ + # ignore for now + next + end + +# This seems to be a common 'error' - maybe I misunderstand the spec or +# something +# if line.length != linesize +# print "#{i}: linesize mismatch, was #{line.length}, should be #{linesize}...\n" +# end + +# j = 0 +# ll = line.length +# ostr = '' +# while j < ll +# if line[j] == 0x3d +# j += 1 +# line[j] -= 64 +# end +# ostr << ymap[line[j]] +# j += 1 +# end +# decode << ostr +# bytes += ostr.length + ostr, ostrl = _ydecode_line(line) + decode << ostr + bytes += ostrl + +# special = 0 +# str = "" +# line.each_byte { |b| +# if special == 0 +# if b == 0x3d +# special = 1 +# next +# end +# else +# special = 0 +# b = (b - 64) % 256 +# end +# str << ((b - 42) % 256).chr +# } +# decode << str + end + + print "${i}: no \"=yend\" found!!!\n" + dec = [ decode ] + return mode, filename, dec +end + +def ydecode_group(subj, tempdir=nil) + group_subjects unless @grouped + + body = get_group_body_first(subj) + if body.to_s =~ /=ybegin/ + print "yencoded!\n" if Debuglevel > 0 + #if (file and outfile) + if (tempdir != nil) + file = Tempfile.new("#{tempdir}/riptmp") + body.collect{|i| file.print "#{i}\n"} + get_group_body_rest(subj, file) + mode, filename, result = ydecode(file, outfile) + else + body.concat(get_group_body_rest(subj)) + mode, filename, result = ydecode(body) + end + return mode, filename, result + else + print "Not yencoded!\n" if Debuglevel > 0 + return false + end +end + +def is_yencoded(data) + if data.to_s =~ /=ybegin/ + return true + else + return false + end +end + +end # class