#!/bin/sh
: ; exec klone $0 "$@"
; The above line allows not to embed the exact path of the klone executable
;;Skeleton of a typical klone script
;;(kdb t)
;; TODO: verifier thread title ok
;; TODO: simpler display of --verbose, via numids
;; TODO: pouvoir matcher dates day, Month
;; Message separators are recognized by having:
;; Message-Id: <xmh-thread@separator>
(setq args (getopts "USAGE: %0 [options]
Removes the duplicate mails in current dir (mails which have the same body)
The mails with the shortest header is removed"
("-v" () verbose "verbose operation")
))
(setq re-num (regcomp "^[0-9]+$"))
(setq re-dir (regcomp "^(.*)[/]([^/]*)$"))
(setq mails (Hashtable ()))
(setq duplicates (Hashtable ()))
(defstruct Mail
num ;number of the mail (filename in MH)
header
body
)
(defun main (&aux
(n 0)
(start-time (get-internal-run-time))
)
(dolist (file (directory))
(when (regexec re-num file)
(Parse-mail file)
))
(dohash (body ml mails)
(sort ml compare-mails)
(dolist (mail (subseq ml 1))
(verbose? "Removing %0, duplicate of %1"
(Mail-num mail) (Mail-num (0 ml)))
(wait (system (list "rm" "-f" (String (Mail-num mail)))))
)
)
)))
(defun compare-mails (m1 m2)
(compare (length (Mail-header m2)) (length (Mail-header m1)))
)
(defun Parse-mail (filename &aux
(mail (make-Mail :num (Int filename)))
(fd (open filename
:error '(fatal-error 1 "Cannot Open file %0\n" filename)))
curline
(header (copy ""))
(body (copy ""))
m
)
(catch 'EOF
(catch 'HeaderEnd
(doline (line fd)
(if (= "" line) (throw 'HeaderEnd)
(nconc header line "\n")
)))
(with (line
(catch 'SpaceEnd
(doline (line fd)
(if (/= "" line) (throw 'SpaceEnd line))
)))
(nconc body line "\n" (String fd))
)
)
(Mail-body mail body)
(Mail-header mail header)
(if (setq m (getn mails body)) (progn
(lappend m mail)
)
(put mails body (list mail))
)
)
(main)
;;; EMACS MODES
;;; Local Variables: ***
;;; mode:lisp ***
;;; End: ***
syntax highlighted by Code2HTML, v. 0.9.1