#!/bin/sh
: ; exec klone $0 "$@"
; The above line finds the klone executable in the $PATH
;;Skeleton of a typical klone script

(setq args (getopts "USAGE: %0 files...
fixes netscape binaries (bug when forking external commands with some shells)
replaces the string \"((^@cat %s | ^@); rm \" 
by:                 \"( ^@cat %s | ^@ ; rm \""
))

(defun fix-netscape-executable (file &aux
    (buffer (String (open file)))
    pos pos1 pos2
    fd
  )
  (if (setq pos (seek buffer "\x00cat %s | \x00"))
    (if (and
	(setq pos1 (revseek buffer "\x00((\x00" pos (- pos 1000)))
	(setq pos2 (seek buffer "); rm " pos))
      )
      (progn
	(put buffer (+ pos1 2) #\ )
	(put buffer pos2 #\ )
	(PF "patching file %0\n" file)
	(sh chmod "u+w" ,file)
	(setq fd (open file :if-exists :overwrite :direction :output))
	(write-string buffer fd)
      )
      (and (setq pos1 (revseek buffer "\x00( \x00" pos (- pos 1000)))
	(setq pos2 (seek buffer " ; rm " pos))
      )
      (PF "file %0 already patched\n" file)
      t
      (PF "strange netscape file %0!\n" file) ;; cat %s found but not others
    )
    (PF "Cannot recognize file %0\n" file) ;; not cat %s found
  )
)

;; naive, slow implementation
(defun revseek (buffer s &optional (offset (length s)) (max 0) &aux
    (l (length s))
  )
  (if (< max 0) (setq max 0))
  (if (< offset 0) (setq offset 0))
  (catch 'Found
    (while (>= offset max)
      (if (= s (substring-ptr buffer offset (+ offset l)))
	(throw 'Found offset)
      )
      (incf offset -1)
    )
    ()
  )
)

(defun main (&aux
  )
  (dolist (file args)
    (fix-netscape-executable file)
  )
)

(main)

;;; EMACS MODES
;;; Local Variables: ***
;;; mode:lisp ***
;;; End: ***

