Patch title: Release 90 bulk changes
Abstract:
File: /linux/storage/cdrom.pli
Key:
    Removed line
    Added line
   
module "/pliant/language/context.pli"
module "/pliant/language/stream.pli"
module "/pliant/language/stream/pipe.pli"
module "/pliant/fullpliant/this_computer.pli"
module "/pliant/linux/kernel/device.pli"
module "/pliant/admin/execute.pli"
module "/pliant/admin/file.pli"
module "/pliant/language/ui/ansi_terminal.pli"


function cdrom_image files options image -> status
  arg List:FileInfo files ; arg Str options ; arg Str image 
  var CBool query_size := options option "query_size"
  var Str path := options option "path" Str
  var Str boot := options option "boot" Str
  if path="" and not (exists  files:first)
    return failure:"Nothing to engrave"
  if path="" and boot<>""
    return failure:"Cannot engrave a bootable CD from a file
  var CBool backup := options option "backup"
  var Str mk:= "mkisofs -quiet -D"
  if (options option "linktransparent")
    mk += " -f"
  if boot<>""
    mk += " -R -b "+boot
  eif backup
    mk += " -R"
  else
    mk += " -r"
  var Str title := options option "title" Str
  if title<>""
    mk += " -V "+title
module "/pliant/language/context.pli"
module "/pliant/language/stream.pli"
module "/pliant/language/stream/pipe.pli"
module "/pliant/fullpliant/this_computer.pli"
module "/pliant/linux/kernel/device.pli"
module "/pliant/admin/execute.pli"
module "/pliant/admin/file.pli"
module "/pliant/language/ui/ansi_terminal.pli"


function cdrom_image files options image -> status
  arg List:FileInfo files ; arg Str options ; arg Str image 
  var CBool query_size := options option "query_size"
  var Str path := options option "path" Str
  var Str boot := options option "boot" Str
  if path="" and not (exists  files:first)
    return failure:"Nothing to engrave"
  if path="" and boot<>""
    return failure:"Cannot engrave a bootable CD from a file
  var CBool backup := options option "backup"
  var Str mk:= "mkisofs -quiet -D"
  if (options option "linktransparent")
    mk += " -f"
  if boot<>""
    mk += " -R -b "+boot
  eif backup
    mk += " -R"
  else
    mk += " -r"
  var Str title := options option "title" Str
  if title<>""
    mk += " -V "+title
  if (options option "macintosh")
  if (options option "macintosh") and (options option "osx")
    mk += " -hfs --netatalk --osx-double"
  eif (options option "macintosh")
    mk += " -hfs --netatalk"
    mk += " -hfs --netatalk"
  eif (options option "osx")
    mk += " -hfs --osx-double"
  if (options option "windows")
    mk += " -J"
   var Str file_in file_out
  if query_size
    mk += " -print-size"
  eif file_os_name:image<>""
    mk += " -o "+file_os_name:image
  if path<>""
    mk += " "+file_os_name:path
  else
    var Str flist := file_temporary
    mk += " -graft-points -path-list "+file_os_name:flist+" 
    (var Stream s) open flist out+safe
    var Pointer:FileInfo file :> files next files:first
    while exists:file
      s writeline mkisofs_name:file
      file :> files next file
    if s:close=failure
      file_delete flist
      return failure:"Failed to generate files list temporar
  if query_size
  if (options option "windows")
    mk += " -J"
   var Str file_in file_out
  if query_size
    mk += " -print-size"
  eif file_os_name:image<>""
    mk += " -o "+file_os_name:image
  if path<>""
    mk += " "+file_os_name:path
  else
    var Str flist := file_temporary
    mk += " -graft-points -path-list "+file_os_name:flist+" 
    (var Stream s) open flist out+safe
    var Pointer:FileInfo file :> files next files:first
    while exists:file
      s writeline mkisofs_name:file
      file :> files next file
    if s:close=failure
      file_delete flist
      return failure:"Failed to generate files list temporar
  if query_size
    var Str sfile := file_temporary
    var Int err := execute mk error sfile
    s open sfile in+safe
    var Str answer := s readline
    var Str ofile := file_temporary
    var Str efile := file_temporary
    var Int err := execute mk output ofile error efile
    s open ofile in+safe
    var Str oanswer := s readline
    s close
    s close
    file_delete sfile
    file_delete ofile
    s open efile in+safe
    var Str eanswer := s readline
    s close
    file_delete efile
    status := shunt err=0 success (failure "mkisofs returned
    status := shunt err=0 success (failure "mkisofs returned
    if (answer parse any "=" (var Intn sectors))
    if (oanswer parse (var Intn sectors)) or (eanswer parse any "=" (var Intn sectors))
      status message := string sectors*2048n
  else
    var Int err
    part mk "Building CD "+title+" ISO9660 image"
      if file_os_name:image<>""
        err := execute mk output "file:/tmp/cdrom.log" mixed
      else
        err := execute mk output image error "file:/tmp/cdro
    status := shunt err=0 success failure:"Failed to build I
    if file_os_name:image<>"" and status=success and (file_q
      status := failure "mkisofs internal bug"
      if debug and path<>""
        file_tree_delete "file:/tmp/bug/"
        var Array:FileInfo pfiles := file_list path standard
        for (var Int i) 0 pfiles:size-1
          if (pfiles:i:name search ".AppleDouble/" -1)<>(-1)
            var Intn remain := pfiles:i:size
            (var Stream src) open path+pfiles:i:name in+safe
            (var Stream dest) open "file:/tmp/bug/"+pfiles:i
            var Address buf := memory_zallocate 4096 null
            while remain>0
              var Int step := shunt remain>4096 4096 (cast r
              src raw_read buf step
              dest raw_write buf step
              remain -= step
            memory_free buf
            src close
            dest close
          else
            var Intn remain := pfiles:i:size
            (var Stream dest) open "file:/tmp/bug/"+pfiles:i
            var Address buf := memory_zallocate 4096 null
            while remain>0
              var Int step := shunt remain>4096 4096 (cast r
              dest raw_write buf step
              remain -= step
            memory_free buf
            dest close
    if status=success
      file_delete "file:/tmp/cdrom.log"
    eif path=""
      file_delete "file:/tmp/cdrom.list"
      file_move flist "file:/tmp/cdrom.list"
  if path=""
    file_delete flist
  if debug
    (var Stream s) open "file:/tmp/mkisofs.log" out+safe
    if path<>""
      s writeline "path is "+string:path
      var Array:FileInfo pfiles := file_list path standard+r
      var Intn total := 0
      for (var Int i) 0 pfiles:size-1
        # s writeline "  "+pfiles:i:name+"  "+(string pfiles
        total += pfiles:i:size
      s writeline (string pfiles:size)+" files "+string:tota
    else
      var Int count := 0 ; var Intn total := 0
      var Pointer:FileInfo file :> files next files:first
      while exists:file
        # s writeline "  "+file:name+"  "+(string file:size)
        count += 1 ; total += file size
        file :> files next file
      s writeline string:count+" files "+string:total+" byte
    if file_os_name:image<>""
      s writeline "ISO9660 file size is "+(string (file_quer
    if status=failure
      s writeline "error message is "+status:message
      status message := string sectors*2048n
  else
    var Int err
    part mk "Building CD "+title+" ISO9660 image"
      if file_os_name:image<>""
        err := execute mk output "file:/tmp/cdrom.log" mixed
      else
        err := execute mk output image error "file:/tmp/cdro
    status := shunt err=0 success failure:"Failed to build I
    if file_os_name:image<>"" and status=success and (file_q
      status := failure "mkisofs internal bug"
      if debug and path<>""
        file_tree_delete "file:/tmp/bug/"
        var Array:FileInfo pfiles := file_list path standard
        for (var Int i) 0 pfiles:size-1
          if (pfiles:i:name search ".AppleDouble/" -1)<>(-1)
            var Intn remain := pfiles:i:size
            (var Stream src) open path+pfiles:i:name in+safe
            (var Stream dest) open "file:/tmp/bug/"+pfiles:i
            var Address buf := memory_zallocate 4096 null
            while remain>0
              var Int step := shunt remain>4096 4096 (cast r
              src raw_read buf step
              dest raw_write buf step
              remain -= step
            memory_free buf
            src close
            dest close
          else
            var Intn remain := pfiles:i:size
            (var Stream dest) open "file:/tmp/bug/"+pfiles:i
            var Address buf := memory_zallocate 4096 null
            while remain>0
              var Int step := shunt remain>4096 4096 (cast r
              dest raw_write buf step
              remain -= step
            memory_free buf
            dest close
    if status=success
      file_delete "file:/tmp/cdrom.log"
    eif path=""
      file_delete "file:/tmp/cdrom.list"
      file_move flist "file:/tmp/cdrom.list"
  if path=""
    file_delete flist
  if debug
    (var Stream s) open "file:/tmp/mkisofs.log" out+safe
    if path<>""
      s writeline "path is "+string:path
      var Array:FileInfo pfiles := file_list path standard+r
      var Intn total := 0
      for (var Int i) 0 pfiles:size-1
        # s writeline "  "+pfiles:i:name+"  "+(string pfiles
        total += pfiles:i:size
      s writeline (string pfiles:size)+" files "+string:tota
    else
      var Int count := 0 ; var Intn total := 0
      var Pointer:FileInfo file :> files next files:first
      while exists:file
        # s writeline "  "+file:name+"  "+(string file:size)
        count += 1 ; total += file size
        file :> files next file
      s writeline string:count+" files "+string:total+" byte
    if file_os_name:image<>""
      s writeline "ISO9660 file size is "+(string (file_quer
    if status=failure
      s writeline "error message is "+status:message
  var Int capacity_mb := options option "capacity_mb" Int
  if capacity_mb=defined and status=success
    var Intn imagesize := (file_query image standard):size
    if imagesize>=capacity_mb*2n^20
      status := failure string:imagesize+" bytes is too much


function cdrom_record image options -> status
  arg Str image options ; arg ExtendedStatus status
  var Str engraver := "engraver"+(options option "engraver" 
  var Str device := this_computer:env:"hardware":engraver:"d
  var Str interface := this_computer:env:"hardware":engraver
  var Str engraver_options := this_computer:env:"hardware":e
  if not (this_computer:env:"hardware":engraver:"speed" pars
    speed := undefined    
  if not (this_computer:env:"hardware":engraver:"cache_mb" p
    cache_mb := memory_assigned\16\2^20
    cache_mb := max (min cache_mb 16) 4
  if interface="ide"
    execute "rmmod ide-cd" quiet
    execute "rmmod cdrom" quiet
    execute "insmod scsi_mod" quiet
    execute "insmod ide-scsi" quiet
    execute "insmod sg" quiet


function cdrom_record image options -> status
  arg Str image options ; arg ExtendedStatus status
  var Str engraver := "engraver"+(options option "engraver" 
  var Str device := this_computer:env:"hardware":engraver:"d
  var Str interface := this_computer:env:"hardware":engraver
  var Str engraver_options := this_computer:env:"hardware":e
  if not (this_computer:env:"hardware":engraver:"speed" pars
    speed := undefined    
  if not (this_computer:env:"hardware":engraver:"cache_mb" p
    cache_mb := memory_assigned\16\2^20
    cache_mb := max (min cache_mb 16) 4
  if interface="ide"
    execute "rmmod ide-cd" quiet
    execute "rmmod cdrom" quiet
    execute "insmod scsi_mod" quiet
    execute "insmod ide-scsi" quiet
    execute "insmod sg" quiet
  eif interface="usb"
    execute "insmod usbcore" quiet
    execute "insmod ehci-hcd" quiet
    execute "insmod usb-storage" quiet
    execute "insmod scsi_mod" quiet
    execute "insmod cdrom" quiet
    execute "insmod sr_mod" quiet
    execute "insmod sg" quiet
    sleep 5
  eif interface="scsi"
    execute "rmmod sr_mod" quiet
    execute "rmmod cdrom" quiet
    execute "insmod sg" quiet
  if (engraver_options option "pio")
    execute "hdparm -d0 "+file_os_name:device quiet
  eif (engraver_options option "dma")
    execute "hdparm -d1 "+file_os_name:device quiet
  if this_computer:env:"pliant":"system":"distribution"="ful
    for (var Int i) 0 15
      kernel_make_device "device:/sg"+string:i
  eif interface="scsi"
    execute "rmmod sr_mod" quiet
    execute "rmmod cdrom" quiet
    execute "insmod sg" quiet
  if (engraver_options option "pio")
    execute "hdparm -d0 "+file_os_name:device quiet
  eif (engraver_options option "dma")
    execute "hdparm -d1 "+file_os_name:device quiet
  if this_computer:env:"pliant":"system":"distribution"="ful
    for (var Int i) 0 15
      kernel_make_device "device:/sg"+string:i
    for (var Int i) 0 3
      kernel_make_device "device:/pg"+string:i
  var Str dev := this_computer:env:"hardware":engraver:"scsi
  if dev=""
    dev := "0,0,0"
  eif (dev parse (var Int scsi_id))
    dev := "0,"+dev+",0"
  eif (dev parse (var Int scsi_channel) "," (var Int scsi_id
    dev := dev+",0"
  var Str dev := this_computer:env:"hardware":engraver:"scsi
  if dev=""
    dev := "0,0,0"
  eif (dev parse (var Int scsi_id))
    dev := "0,"+dev+",0"
  eif (dev parse (var Int scsi_channel) "," (var Int scsi_id
    dev := dev+",0"
  var Str rec := "cdrecord dev="+dev+(shunt speed=defined " 
  var Str rec := "cdrecord"
  rec += shunt (options option "dummy") " -dummy" ""
  rec += shunt (engraver_options option "dao") " -dao" ""
  rec += shunt (engraver_options option "packet") " -packet" ""
  rec += shunt (engraver_options option "eject") " -eject" ""
  rec += " dev="+dev
  rec += shunt speed=defined " speed="+string:speed ""
  rec += shunt cache_mb=defined " fs="+string:cache_mb+"m" ""
  if file_os_name:image="" and (options option "size")
    rec += " tsize="+(string (options option "size" Intn)\2048)
  rec += " "
  var Str stdin := "-"
  if (engraver_options option "growisofs")
    rec := "growisofs -dvd-compat -use-the-force-luke -Z "+file_os_name:device+"="
    stdin := "/proc/self/fd/0"
  var Int err
  part engrave
  var Int err
  part engrave
    if (options option "rw")
      var Str blank := "cdrecord dev="+dev+(shunt speed=defi
    if (options option "rw") and (engraver_options option "blank" Str)<>"no"
      var Str blank := "cdrecord"
      blank += " dev="+dev
      blank += shunt speed=defined " speed="+string:speed ""
      blank += " blank="+(engraver_options option "blank" Str "fast")
      part blank "Blanking read/write CD"
        var Int seconds := engraver_options option "keyboard
        if seconds=defined
          stream_pipe (var Str pipe_in) (var Str pipe_out)
          thread
            (var Stream kbd) open pipe_out out+safe
            sleep seconds
            kbd writeline ""
            kbd flush anytime
          err := execute blank input pipe_in output "file:/t
        else
          err := execute blank output "file:/tmp/cdrom.log" 
      if err=0
        file_delete "file:/tmp/cdrom.log"
      else
        status := failure "Failed to blank RW CD"
        if file_os_name:image=""
          (var Stream pipe) open image in+safe ; pipe close
        leave engrave
    part record "Engraving ISO9660 image on CD "+(options op
      if file_os_name:image<>""
      part blank "Blanking read/write CD"
        var Int seconds := engraver_options option "keyboard
        if seconds=defined
          stream_pipe (var Str pipe_in) (var Str pipe_out)
          thread
            (var Stream kbd) open pipe_out out+safe
            sleep seconds
            kbd writeline ""
            kbd flush anytime
          err := execute blank input pipe_in output "file:/t
        else
          err := execute blank output "file:/tmp/cdrom.log" 
      if err=0
        file_delete "file:/tmp/cdrom.log"
      else
        status := failure "Failed to blank RW CD"
        if file_os_name:image=""
          (var Stream pipe) open image in+safe ; pipe close
        leave engrave
    part record "Engraving ISO9660 image on CD "+(options op
      if file_os_name:image<>""
        err := execute rec+" "+file_os_name:image output "fi
        console rec+file_os_name:image eol
        err := execute rec+file_os_name:image output "file:/tmp/cdrom.log" mixed
      else
      else
        err := execute rec+" -" input image output "file:/tm
        console rec+stdin eol
        err := execute rec+stdin input image output "file:/tmp/cdrom.log" mixed
    if err=0
      file_delete "file:/tmp/cdrom.log"
      status := success
    else
      status := failure "Failed to engrave the CD ISO9660 im
    if err=0
      file_delete "file:/tmp/cdrom.log"
      status := success
    else
      status := failure "Failed to engrave the CD ISO9660 im
      if file_os_name:image<>""
        status message += " ("+(string (file_query image standard):size)+" bytes)"
  if interface="ide"
    execute "rmmod sg" quiet
    execute "rmmod ide-scsi" quiet
    execute "rmmod scsi_mod" quiet
    execute "insmod cdrom" quiet
    execute "insmod ide-cd" quiet
  eif interface="scsi"
    execute "rmmod sg" quiet
    execute "insmod cdrom" quiet
    execute "insmod sr_mod" quiet


function cdrom_engrave files options -> status
  arg List:FileInfo files ; arg Str options ; arg ExtendedSt
  var Str engraver := "engraver"+(options option "engraver" 
  if interface="ide"
    execute "rmmod sg" quiet
    execute "rmmod ide-scsi" quiet
    execute "rmmod scsi_mod" quiet
    execute "insmod cdrom" quiet
    execute "insmod ide-cd" quiet
  eif interface="scsi"
    execute "rmmod sg" quiet
    execute "insmod cdrom" quiet
    execute "insmod sr_mod" quiet


function cdrom_engrave files options -> status
  arg List:FileInfo files ; arg Str options ; arg ExtendedSt
  var Str engraver := "engraver"+(options option "engraver" 
  var CBool indirect := this_computer:env:"hardware":engrave
  var Str engraver_options := this_computer:env:"hardware":engraver:"options"
  var CBool indirect := (engraver_options option "indirect") or (options option "indirect")
  if (options option "macintosh") and (options option "capac
    indirect := true
  var Str path := options option "path" Str
  if (options option "buggy") and path="" # workaround mkiso
    var Str temp := file_temporary+"/"
    cdrom_tree files options temp
    status := cdrom_engrave (var List:FileInfo empty_list) o
    file_tree_delete temp
    return
  if (options option "macintosh") and (options option "capac
    indirect := true
  var Str path := options option "path" Str
  if (options option "buggy") and path="" # workaround mkiso
    var Str temp := file_temporary+"/"
    cdrom_tree files options temp
    status := cdrom_engrave (var List:FileInfo empty_list) o
    file_tree_delete temp
    return
  var Int capacity_mb := options option "capacity_mb" Int
  if capacity_mb=defined
    if ((cdrom_image files options+" query_size" ""):message parse (var Intn size))
      if size>=capacity_mb*2n^20
        status := failure string:size+" bytes is too much for a CD image"
  if indirect
    var Str image := file_temporary
    status := cdrom_image files options image
    if status=success
      status := cdrom_record image options
    if status=success
      var Intn imagesize := (file_query image standard):size
      status message := string:imagesize+" bytes in the CD i
    file_delete image
  else
  if indirect
    var Str image := file_temporary
    status := cdrom_image files options image
    if status=success
      status := cdrom_record image options
    if status=success
      var Intn imagesize := (file_query image standard):size
      status message := string:imagesize+" bytes in the CD i
    file_delete image
  else
    if (options option "capacity_mb")
      status := cdrom_image files options+" query_size" ""
      if status=failure
        return
    var Str extra := ""
    if (engraver_options option "size") and ((cdrom_image files options+" query_size" ""):message parse (var Intn size))
      extra += " size "+string:size
    stream_pipe (var Str pipe_in) (var Str pipe_out)
    var ExtendedStatus status1 status2
    part pipe "CD engraving pipe"
      parallel threads 2
        task
          share status1 := cdrom_image files options pipe_ou
        task
    stream_pipe (var Str pipe_in) (var Str pipe_out)
    var ExtendedStatus status1 status2
    part pipe "CD engraving pipe"
      parallel threads 2
        task
          share status1 := cdrom_image files options pipe_ou
        task
          share status2 := cdrom_record pipe_in options
          share status2 := cdrom_record pipe_in options+extra
    status := shunt status1=failure status1 status2
  if debug and status=success
    file_delete "file:/tmp/mkisofs.log"



export cdrom_engrave
export cdrom_image cdrom_record
export cdrom_file
    status := shunt status1=failure status1 status2
  if debug and status=success
    file_delete "file:/tmp/mkisofs.log"



export cdrom_engrave
export cdrom_image cdrom_record
export cdrom_file