namespace eval sys {
  variable sys_N_errs 0
  variable sys_error 0
  variable sys_result ""
  variable sys_log 0

  #
  # Issue an Operating System command ...
  proc do_SysCmd { cmd } {
    set doit "exec $cmd"
    set sys::sys_error [ catch { eval $doit } sys::sys_result ]
    return $sys::sys_error
  }

  #
  # Process an Operating System command error ...
  proc sys_Error { where } {
   incr sys::sys_N_errs
   out_Log "-- System Command Error:"
   out_Log [format "-- called from: %s" $where ]
   out_Log [format "-- result: '%s'" $sys::sys_result ]
  }

  #
  # System Error Summary ...
  proc sys_Error_Report { what } {
   if { $sys::sys_N_errs == 0 } {
      return
   }
   out_Log "-- Total errors $sys::sys_N_errs while processing $what."
   puts " -- Total errors $sys::sys_N_errs while processing $what."
   set sys::sys_N_errs 0
  }
                                                                                
  #
  # Time an Operating system command ...
  proc do_Timer { cmd } {
    set start [clock seconds]
    if [ do_SysCmd $cmd ] {
  	sys_Error "do_Timer $cmd" 
    }
    set end [clock seconds]
    return [expr $end - $start]
  }

  #
  # Issue a command to a DVD/CD device ...
  proc cd_control { device cnf } {
    set cmd [ format "%s -f %s %s" $::X(cdcontrol) $device $cnf ]
    out_Log $cmd
    if [ do_SysCmd $cmd ] {
  	return [ sys_Error "cd_control: $cmd" ]
    }
    return 0
  }

  #
  # Configure the network interface ...
  proc nw_config { device cnf } {
    set cmd [ format "%s %s %s" $::X(ifconfig) $device $cnf ]
    out_Log $cmd
    if [ do_SysCmd $cmd ] {
  	return [ sys_Error "nw_config: $cmd" ]
    }
    return 0
  }
  proc sys_secret { } {
	return "1853324d60411b1a612b3d646d8d4d6e"
  }

  #
  # An attempt ...
  proc encrypt { text } {
	set cmd [ format "/bin/echo %s | %s enc -e -bf -a -k %s" \
			$text $::X(openssl) [sys::sys_secret] ]
	do_SysCmd $cmd
	return $sys::sys_result
  }

  #
  # An attempt ...
  proc decrypt { text } {
	set cmd [ format "/bin/echo %s | %s enc -d -bf -a -k %s" \
			$text $::X(openssl) [sys::sys_secret] ]
	do_SysCmd $cmd
	return $sys::sys_result
  }

  #
  # Create a Log file for the session ...
  proc new_Log { } {
    set logfile [ file join $::X(archive_path) Bkp_Log]
    catch { file delete $logfile.old } x
    catch { file rename $logfile $logfile.old } x
    set sys::sys_log [ open $logfile w+ ]
  }

  #
  # Log a string to the Log file ...
  proc out_Log { string } {
    set time [ clock format [clock seconds] -format "%Y%m%d.%H%M%S" ]
    set out [ format "%s -- %s" $time $string ]
    puts $sys::sys_log $out
  }

  #
  # Close the Log file ...
  proc close_Log { } {
   return [ close $sys::sys_log ]
  }

  #
  # Reset the dvd player ... (see text)
  proc reset_Drive { } {
      sys::cd_control $::X(dvd_burner) eject
      sys::cd_control $::X(dvd_burner) close
  }

  #
  # Reset the network ... (see text)
  proc reset_Net { } {
    sys::nw_config $::X(network) down
    sys::nw_config $::X(network) up
  }

  #
  # UN-Mount the dvd player ... 
  proc umount_cd9660 { path } {
   set cmd [ format "%s %s" $::X(umount) $path ] 
   out_Log $cmd
   if [ do_SysCmd $cmd ] {
      return [ sys_Error "umount_cd9660: $cmd" ]
   }
   return 0
  }

  #
  # Mount the dvd player ... 
  proc mount_cd9660 { path } {
   set cmd [ format "%s -t cd9660 %s %s" $::X(mount) $::X(dvd_burner) $path ] 
   out_Log $cmd
   if [ do_SysCmd $cmd ] {
      return [ sys_Error "mount_cd9660: $cmd" ]
   }
   return 0
  }

  #
  # Start banner ... 
  proc startup { what } {
    set start [ clock seconds ]
    puts " ======================================================"
    puts " === $what commences at [clock format $start ] "
    puts " ======================================================"
    return $start
  }

  #
  # End banner ... 
  proc finish { what } {
    set end [ clock seconds ]
    puts " "
    puts " ======================================================"
    puts " === $what Finishes at [clock format $end ] "
    puts " ======================================================"
    return $end
  }

  #
  # Elapsed time ...
  proc elapsed { sec } {
   set hrs [ expr int( $sec / 3600 ) ]
   set min [ expr int( $sec / 60 ) % 60 ]
   set sec [ expr int( $sec % 60 ) ]
   return [ format "%2.2d:%2.2d:%2.2d" $hrs $min $sec ]
  }

  #
  # Compress a file ...
  proc file_Compress { from to } {
    set cmd [ format "%s -c %s > %s" $::X(gzip) $from $to ]
    set elapsed [ do_Timer $cmd ] 
    return $elapsed
  }

  #
  # Make an .iso image from a directory ...
  proc mk_ISO { dir target } {
    set cmd [ format "%s -J -R -f -o %s %s" $::X(mkisofs) $target $dir ]
    puts " -- creating iso image $target"
    if [ do_SysCmd $cmd ] {
      return [ sys_Error "mk_ISO: $cmd" ]
    }
   return 0
  }

  #
  # Burn an .iso file onto a dvd ...
  proc burn_ISO { iso } {
    set env(MKISOFS) $::X(mkisofs)
    set cmd [ format "%s -Z %s=%s -overburn -use-the-force-luke=tty" \
	$::X(growisofs) $::X(dvd_burner) $iso ]
    puts " -- burning iso image $iso"
    reset_Drive
    if [ do_SysCmd $cmd ] {
      return [ sys_Error "burn_ISO: $cmd" ]
    }
    return 0
  }

  #
  # Burn a directory right onto a dvd using growisofs ...
  proc burn_Dir { dir } {
    # -J Joliet extensions
    # -R Rockridge extensions
    # -f follow symbolic links 
    # -use-the-force-luke=tty is allow batch burning
    # -overburn allows large iso's to be at least attempted ...
    set env(MKISOFS) $::X(mkisofs)
    puts " -- burning $dir to dvd."
    set cmd [ format "%s -Z %s -overburn -use-the-force-luke=tty -J -R -f %s" \
	$::X(growisofs) $::X(dvd_burner) $dir ]
    reset_Drive
    if [ do_SysCmd $cmd ] {
      return [ sys_Error "burn_DIR: $cmd" ]
    }
    return 0
  }

  #
  # Find an executeable program file ...
  proc find_Prog { program } {
    set ret {}
    set cmd "/usr/bin/whereis $program"
    if [ do_SysCmd $cmd ] {
      sys_Error "find_Prog: $cmd" 
      return $ret
    }
    foreach p $sys::sys_result {
      if [ file executable $p ] {
        lappend ret $p
      }
    }
    return $ret
  }

  #
  # Lookup Windows boxen on network ...
  proc find_Windows { } {
    set cmd [format "%s -T *" $::X(nmblookup) ]
    if [ do_SysCmd $cmd ] {
      return [ sys_Error "find_Windows: $cmd" ]
    }
    puts $sys::sys_result
  }

}
