home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / b64.zip / b64.cmd next >
OS/2 REXX Batch file  |  1996-06-11  |  6KB  |  173 lines

  1. /*************************************************************************
  2. * PROGRAM: B64.CMD (REXX script)
  3. *
  4. * Intelligent Base64 encoder/decoder. Uses BASE64 API from MD5RX.DLL.
  5. *
  6. * Created by Teet K⌡nnussaar (teet@aetec.estnet.ee)
  7. *
  8. * This program is *freeware*, which means that you don't have to pay
  9. * for it and you may use/modify it whatever way you want.
  10. * But: This program is distributed AS IS, and with NO warranties,
  11. *   neither implied or expressed.
  12. *
  13. * Usage:
  14. *    B64 ( e | d ) [infile [outfile]]
  15. *        e - for encoding (file -> base64)
  16. *        d - for decoding (mail -> file)
  17. *
  18. * Encoding notes:
  19. *     writes 3-line MIME-compliant header
  20. *     if in-file not specified, reads standard input for data to encode
  21. *     if outfile not specified, writes to standard output
  22. *
  23. * Decoding notes:
  24. *     if in-file not specified, reads from standard input
  25. *     auto-detects encoded data postition in file (should have at 
  26. *        least 3 lines of encoded data to detect correctly)
  27. *     if outfile not given, guesses filename to decode or writes to
  28. *        b64out.$$?. Does not overwrite out-files, never.
  29. *
  30. *************************************************************************/
  31.  
  32. /* Note: there might be need for some error handler.
  33.    Do it yourself, if you need it */
  34.  
  35. call rxfuncadd 'B64encode','md5rx','B64encode'
  36. call rxfuncadd 'B64decode','md5rx','B64decode'
  37.  
  38. parse arg mode file ofile
  39. mode=translate(mode)
  40.  
  41. if      mode="D" then call B64Dfile file, ofile
  42. else if mode="E" then call B64Efile file, ofile
  43. else do
  44.   say "Usage: B64 <mode-letter> [infile [<outfile>]]"
  45.   say "    mode-letter is either 'e' or 'd'"
  46. end
  47.  
  48. exit 0
  49.  
  50. B64EFile: procedure; parse arg f, fo
  51.   buf = "";i=0
  52.   call lineout fo, "Content-Transfer-Encoding: base64"
  53.   call lineout fo, "Content-Type: application/octet-stream;"||,
  54.                    " charset=US-ASCII; name="""||f||""""
  55.   call lineout fo, ""
  56.   do while chars(f)>0
  57.     li = chars(f); if li>189 then li=189
  58.     buf = buf || B64Encode(charin(f,,li))
  59.     do while length(buf) >= 76
  60.       call lineout fo, left(buf,76)
  61.       buf = substr(buf,77)
  62.     end
  63.   end
  64.   if length(buf)>0 then call lineout fo, buf
  65.   call stream f ,"c","close"
  66.   if fo<>"" then call stream fo,"c","close"
  67. return
  68.  
  69. B64DFile: procedure; parse arg f, fo0
  70.   if fo0<>"" then if stream(fo0,"c","query exists")<>"" then do
  71.      say "File" fname||fnext "already exists, aborting"
  72.      say "0 files decoded"
  73.      return
  74.   end
  75.   np=0;fname="";fnext=""
  76.   b64sym = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
  77.   fnsym = xrange("A","Z")||xrange("a","z")||xrange("0","9")||,
  78.                           ".~$!-_#@{[()]}"
  79.   filecount = 0; li = 1
  80.   do forever
  81.     hit=0; buf = "";l1 = 0;
  82.     call charout ,"Searching.."
  83.     do li=li while lines(f)>0
  84.       if li//100 = 0 then call charout ,"."
  85.       l = linein(f);ll = length(l)
  86.       if \hit & ll >= 70 & ll <= 80 & verify(l,b64sym)=0 then do
  87.         l1 = ll; buf = l; hit = 1
  88.       end
  89.       else if hit & l1 = ll & verify(l,b64sym)=0 then do
  90.         say;say "Found BASE64 encoded data at line" li-1
  91.         filecount = filecount + 1
  92.         buf = buf || l
  93.         leave
  94.       end
  95.       else if hit then do
  96.         hit=0; buf = ""
  97.       end
  98.       else do
  99.         if fo0=="" then do
  100.           np=pos("name",l)
  101.           if np<>0 &,
  102.               pos(substr(l,np+4,1),fnsym)=0 then do
  103.             fncand=substr(l,np+5)
  104.             np=verify(fncand,fnsym,"M")
  105.             if np<>0 then fncand=substr(fncand,np)
  106.             np=verify(fncand,fnsym,"N")
  107.             if np<>0 then fncand=left(fncand,np-1)
  108.             if length(fncand)>2 then do
  109.               fname=fncand
  110.               fnext=""
  111.               np = lastpos(".",fncand)
  112.               if np<>0 then do
  113.                 fname=left(fncand,np-1)
  114.                 fnext=substr(fncand,np)
  115.               end
  116. /*              say "Found possible file name at" li": '"fname||fnext"'"*/
  117.             end
  118.           end
  119.         end
  120.       end
  121.     end
  122.     if lines(f) = 0 then do
  123.       say;say filecount "file(s) decoded"
  124.       call stream f ,"c","close"
  125.       return
  126.     end
  127.     if fo0=="" then do
  128.       if fname="" & fnext="" then do
  129.         fname="b64out"; fnext=".$$0"
  130.       end
  131.       if stream(fname||fnext,"c","query exists")<>"" then do
  132.         say "File" fname||fnext "already exists"
  133.         do fnn=1 while stream(fname||fnext,"c","query exists")<>""
  134.           fnext = "."||right("$$"||fnn,3)
  135.         end
  136.       end
  137.       fo = fname||fnext
  138.     end
  139.     else do
  140.       fo = fo0
  141.     end
  142.     say "Decoding" fo
  143.     do li=li while lines(f)>0
  144.       if li//25 = 0 then call charout ,"#"
  145.       l = linein(f)
  146.       if l=="" then leave
  147.       if verify(l,b64sym)<>0 then leave
  148.       buf = buf || l
  149.       do while length(buf)>340
  150.         lb = length(buf)%4*4; if lb>340 then lb=340
  151.         call charout fo,B64Decode(left(buf,lb))
  152.         buf = substr(buf,lb+1)
  153.       end
  154.       if pos("=",l)<>0 then leave
  155.     end
  156.     say "- done!"
  157.     do while length(buf)>340
  158.        lb = length(buf)%4*4; if lb>340 then lb=340
  159.        call charout fo,B64Decode(left(buf,lb))
  160.        buf = substr(buf,lb+1)
  161.     end
  162.     if length(buf)>0 then call charout fo, B64Decode(buf)
  163.     call stream fo,"c","close"
  164.     if fo0<>"" then do
  165.       call stream f ,"c","close"
  166.       say "1 file decoded"
  167.       return
  168.     end
  169.   end
  170.   call stream f ,"c","close"
  171. return
  172.  
  173.