#!/bin/sh
: ; exec klone $0 "$@"
; The above line finds the klone executable in the $PATH
;; gets in cur dir the files up to N megs (default 125)

(setq args (getopts
"tar-chunk [options] [N]
lists the oldest files in current dir upto a total of N megabytes
(default 125)"
("-r" () reverse "lists in reverse time order, most recent first")
("-v" () verbose "verbose (debug)")
("-l" () line-list 
  "lists files on a line, blank-separated, instead of one per line")
("-u" upto-file upto "lists up to file")
))

;; ALL SIZES ARE IN BLOCKS (512), not in K

(if args (progn
    (setq total (Number (get args 0 120)))
    (setq total (Int (- (* 2048 total) 2))) ; 2 b are added by tar at the end
  )
  (setq total 245760)			;120M + 2 bytes
)

; round down total to a multiple of 8192

(setq total (* 16 (/ total 16)))

(system '("ls" "-1tr") :output 'ls)

(setq files (list))
(setq K 0)
(setq upto-k 0)
(setq upto-n 0)
(setq separator (if line-list " " "\n"))

(defun size-to-k (s)			; 1 block added for header + roundup
  (+ (/ (+ s 511) 512) 1)
)

(catch 'EOF
  (while (setq file (read-line ls))
    
    (setq size (get (file-stats file) 'size))
    (setq k (size-to-k size))
    (if verbose (print-format *standard-error* "%0[%1] " file (/ k 2)))
    (if (> (+ k K) total)
      (throw 'EOF)
    )
    (incf K k)
    (put files -1 file)
))

(print-format *standard-error*
  "Total: %0 K (%1 M, %3 bytes) in %2 files\n"
  (/ K 2) (/ (/ (+ K 1023) 1024) 2)
  (length files)
  (* (/ (+ (* K 512) 8191) 8192) 8192)
)

(defun exit-upto ()
  (print-format *standard-error*
  "Total up to %3: %0 K (%1 M) in %2 files\n"
    (/ upto-k 2) (/ (/ (+ upto-k 1023) 1024) 2)
  upto-n
  upto)
  (exit 0)
)

(setq i (- (length files) 1))
(if reverse
  (while (>= i 0)
    (setq file (get files i))
    (? file separator)
    (if upto (progn
	(incf upto-k (size-to-k (get (file-stats file) 'size)))
	(incf upto-n)
	(if (= upto file) (exit-upto))
    ))
    (incf i -1)
  )
  (dolist (file files)
    (? file separator)
    (if upto (progn
	(incf upto-k (size-to-k (get (file-stats file) 'size)))
	(incf upto-n)
	(if (= upto file) (exit-upto))
    ))
  )
)

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

