/* 29 Sept 2002. Daniel Hellerstein (danielh@econ.ag.gov)
  A browser-callable utility to parse an "x-sre-mixed" file
  and save it's "parts" to seperate files.

** How to use.

You can run this from an OS/2 command prompt, or you can
make it into a helper application.

1) Command prompt

Just run DOMIXED from an OS/2 command prompt, or
 x:>DOMIXED afilename
where afilename is the name of "sre-multipart" response that you
saved to disk.

For each file contained in this "sre-multipart" response file, you
will be asked to provide a name.  Typically, a default name (the name
of the file used by the server) will be available.

2) Netscape helper application

DOMIXED.CMD can be used as a somewhat-clunky, but otherwise reliable,
Netscape helper application.

To do this, the following setup should be done once:

  1) Open NetScape "applications". 
         for NS4.04 -- look in Edit-Preferences-Applications
         for NS2.02 -- look in Options-General_Preferences-Applications

  2) Create a "new type" with:

             Mime Type: application/x-sre-mixed
    Application to Use: cmd.exe /c "x:\dir\DoMixed.cmd"

    where x:\dir\ is the path you copied DoMixed.CMD to.
    Note: the "s MUST be included in this definition!
   
    When you are next sent a "sre-multipart" resource, you may be asked
    to "load" or ("open it") "save" the file -- choose "load" (or "open it")
    DoMixed will then run, and will ask you where each file should be 
    copied to.
            
DoMixed.CMD contains one user-changeable parameter: 
        DEFAULT_OUTDIR : The default directory to write files to.
You can changes this at any time -- be sure to use a fully
qualified directory name!

If you are using a non-OS/2 client, you still might be able
to use DoMixed.CMD -- it's a REXX program, and it should
be possible to instruct your browser to run a REXX emulator.


*/


/* ---------- Begin user changeable parameters --------- */

/* set this to be the  fully qualified default output directory */
default_outdir=''


/* ---------- END of user changeable parameters --------- */

if default_outdir<>'' then
   outdir=strip(default_outdir,'t','\')||'\'
else 
  outdir=directory()

say " <<<<<<< The SREhttp/2 multi-part file utility  >>>>> "
parse arg dafile
if dafile='' then do
   call charout, "Enter name of multi-part file: "
   pull dafile
end 
foo=rxfuncquery('sysloadfuncs')
if foo=1 then do
  call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
  call SysLoadFuncs
end

crlf='0d0a'x

/* 1) read the file */
a=stream(dafile,'c','open read')
if abbrev(translate(a),'READY')<>1 then do
    say "Problem opening: "dafile
    call charout, ' (hit ENTER to continue)' ; pull foo
    exit
end /* do */
ilen=stream(dafile,'c','query size')
if ilen=0 | ilen='' then do
    say "Problem querying: "dafile
    call charout, ' (hit ENTER to continue)' ; pull foo
    exit
end /* do */
stuff=charin(dafile,1,ilen)
foo=stream(dafile,'c','close')

/* parse into head and body */
abound=''
do forever
   if stuff='' then do
        say "Problem: no body for this file: " dafile
        call charout, ' (hit ENTER to continue)';pull foo
        exit
   end /* do */
   parse var stuff aline (crlf) stuff

   taline=strip(translate(aline))
   if taline='' then leave      /* empty line signifies end of head */
   if abbrev(taline,'X-FILECOUNT')=1 then do
        parse var aline . ':' nct
        say ' # of files in this multi-part document: 'nct
   end /* do */

   if abbrev(taline,'CONTENT-TYPE')=0 then iterate
   parse var aline ':' junk
   parse var junk a1 ';' a2
   a1=strip(translate(a1))
   if abbrev(a1,'MULTIPART/')<>1 then iterate /* not a multipart type */
   parse var aline '=' abound
   abound=strip(abound,,'"')
end /* do */
if abound='' then do
   say "Problem: no boundary string defined "
   call charout, ' (hit ENTER to continue)' ; pull foo
   exit
end /* do */

/* find parts */
mimestart='--'||abound
mimestart2=crlf||mimestart

parse var stuff p1 (MIMESTART) AA (CRLF) stuff
if aa='--' then do
   say "Problem: no parts found "
   call charout, ' (hit ENTER to continue)' ; pull foo
   exit
end /* do */
nth=0
ijth=0
do  forever
     parse var stuff thepart (MIMESTART2) AA (CRLF) stuff
     nth=nth+1
     abody=''
     do forever  /* remove local headers */
         if thepart='' then leave    /* no local body */
         parse var thepart aline (crlf) thepart
         if aline='' then leave         /* all done with local head */
         taline=translate(aline)
         if abbrev(taline,'CONTENT-DISPOSITION')=1 then do      /* get "Filename" */
               parse var taline . 'FILENAME' daname ';' .
               daname=space(daname,0)
               daname=strip(daname,,'=')
               daname=strip(daname,,'"')
         end /* do */
         if abbrev(taline,'CONTENT-TYPE')=1 then do      /* get "Filename" */
               parse var aline ':' atype
          end
     end /* do */
     ijth=ijth+1
     say ijth") Length of part= "||length(thepart)". MIME type: "||strip(atype)
     useout=getofile(outdir||daname)
     if useout<>"" then do
           foo=stream(useout,'c','open write')
           foo=charout(useout,thepart,1)
           if foo<>0 then do
                say "Problem writing "useout
           end /* do */
           else
                say "   .... "useout " written successfully "
          foo=stream(useout,'c','close')
           ill=lastpos('\',useout)
           if ill>0 then  outdir=left(useout,ill)
     end /* do */
     IF AA='--' then  LEAVE              /* --   after boundary means "all done */
end /* do */

call charout, 'All done (hit ENTER to exit)' ; pull foo
exit


getofile:procedure
parse arg defout
do forever
  aa="   Output to (.=skip, ENTER="defout"):"
  if length(aa)>40 then do
     say aa
     call charout, "    ? "
  end
  else do
    call charout,aa' ?'
  end

  pull gfile2 ; gfile2=strip(gfile2)
  if right(gfile2,1)='\' & defout<>'' then do
     iu=lastpos('\',defout)
     gfile2=gfile2||substr(defout,iu+1)
  end
  if gfile2='.'  then return ''
  if gfile2="" then gfile2=defout
  if gfile2="" then iterate
  gfile0=stream(gfile2,'c','query exists')
  if gfile0<>"" then do
      call charout,'   'Gfile0 ' exists.  Overwrite (Y/N)'
      pull anans
      if abbrev(strip(anans),'Y')<>1 then iterate
      foo=1
      if rxfuncquery('SYSFILEDELETE')=0 then foo=sysfiledelete(gfile0)
      if foo<>0 then do
          say "    Could not delete. Try a different file name"
          iterate
      end /* do */
  end
  return gfile2
end /* do */

