[Limacute-commit] r230 - trunk/tools/cybar
limacute at projects.linpro.no
limacute at projects.linpro.no
Mon Jan 21 23:27:57 CET 2008
Author: limacute
Date: 2008-01-21 23:27:56 +0100 (Mon, 21 Jan 2008)
New Revision: 230
Modified:
trunk/tools/cybar/cybar.ml
Log:
Refactored handling of backed up users that are deleted from mailspool. Corrected handling of ^ and . in name.
Modified: trunk/tools/cybar/cybar.ml
===================================================================
--- trunk/tools/cybar/cybar.ml 2008-01-18 17:40:58 UTC (rev 229)
+++ trunk/tools/cybar/cybar.ml 2008-01-21 22:27:56 UTC (rev 230)
@@ -148,7 +148,11 @@
with
| Unix.Unix_error _ -> {src_stat with Unix.st_mtime = 0.}
in
- if src_stat.Unix.st_mtime > dst_stat.Unix.st_mtime
+ (*
+ * If dst mtime is in the past of src, it is an old backup.
+ * If dst mtime is in the future of src, it is an incomplete transfer
+ *)
+ if src_stat.Unix.st_mtime <> dst_stat.Unix.st_mtime
then
begin
let size = file_copy_via ~via:None ~src ~dst in
@@ -553,17 +557,32 @@
;;
end
-type user = {localpart:string;domain:string option} ;;
+type user = {localpart:string;domain:string option;deleted_age:(float*string) option} ;;
+(* Show user with information about delete time *)
let show_user user =
let post = match user.domain with
| None -> ""
| Some domain -> "@" ^ domain
in
+ let post = match user.deleted_age with
+ | None -> post
+ | Some (age,agestr) -> post ^ " deleted at "^agestr
+ in
user.localpart ^ post
;;
+(* Create the email (uid) of the user, ignoring delete_age *)
+let uid_of_user user =
+ let post = match user.domain with
+ | None -> ""
+ | Some domain -> "@" ^ domain
+ in
+ user.localpart ^ post
+;;
+
let hat_regexp = Str.regexp "\\^";;
+let deleted_user_regexp = Str.regexp "^\\(.+\\)\\.\\([0-9]+\\)$";;
let cyrus_escape s =
Str.global_replace (Str.regexp "\\.") "^" s
@@ -949,7 +968,7 @@
* Show the imap name of the user
*)
let imap_name user =
- "user"^options.hierarchysep^(show_user user)
+ "user"^options.hierarchysep^(uid_of_user user)
;;
(** Wildcard listing for cyrus of user with mailboxes *)
@@ -1062,8 +1081,19 @@
| (localpart::localparts) ->
begin
let dir = Filename.concat base localpart in
+ (* transform localpart.age into different semantic parts *)
+ let (localpart,age) =
+ if Str.string_match deleted_user_regexp localpart 0 then
+ let agestr = Str.matched_group 2 localpart in
+ let age = float_of_string agestr in
+ let localpart = Str.matched_group 1 localpart in
+ (localpart,Some (age,agestr))
+ else
+ (localpart,None)
+ in
+ (* replace ^ with . since cyrus does a ^ to . conversion. *)
let localpart = Str.global_replace hat_regexp "." localpart in
- let user = {localpart=localpart;domain=domain} in
+ let user = {localpart=localpart;domain=domain;deleted_age=age} in
let collected = collector ~collected ~user ~dir in
begin
verbose (lazy("Found user "^(show_user user))) ;
@@ -1149,25 +1179,20 @@
*)
let find_deleted_user_backup_and_sieve_dir deleted_user =
let now = Unix.time () in
- let deleted_user_regexp = Str.regexp "^\\(.+\\)\\.\\([0-9]+\\)$" in
let collector ~collected ~user ~dir =
- if Str.string_match deleted_user_regexp user.localpart 0
- then
+ match user.deleted_age with
+ | Some (age,agestr) ->
begin
- let localpart = Str.matched_group 1 user.localpart in
- let agestr = Str.matched_group 2 user.localpart in
- let age = float_of_string agestr in
let priority = now -. age in (** Most recently deleted user has smallest number, thus highest priority *)
- let user = {user with localpart =localpart} in
- if user = deleted_user then begin
- verbose (lazy("The user "^(show_user user)^" deleted at "^agestr^" is candidate for restore."));
+ if user.localpart = deleted_user.localpart && user.domain = deleted_user.domain then begin
+ verbose (lazy("The user "^(show_user user)^" deleted at "^(agestr)^" is candidate for restore."));
PriorityQueue.insert collected priority (dir,user,agestr)
end else begin
verbose (lazy("The user "^(show_user user)^" is not a restore candidate for "^(show_user deleted_user)^"."));
collected
end
end
- else collected
+ | None -> collected
in
let virtdomains = options.virtdomains in
let hashimapspool = true in
@@ -1191,33 +1216,31 @@
* *)
let find_backup_users () =
let collector ~collected ~user ~dir =
- let priority = (Unix.stat dir).Unix.st_mtime in
- let deleted_user_regexp = Str.regexp "^\\(.+\\)\\.\\([0-9]+\\)$" in
- if Str.string_match deleted_user_regexp user.localpart 0
- then
+ match user.deleted_age with
+ | Some (age,agestr) ->
begin
begin
- let localpart = Str.matched_group 1 user.localpart in
- let age = Str.matched_group 2 user.localpart in
- let age = float_of_string age in
- let user = {user with localpart =localpart} in
if age < options.backup_age
then
begin
if options.dry_run
- then verbose (lazy("Skipping purge of expired user "^(show_user user)))
- else Unixutil.rm ~recursive:true ~force:true dir
+ then verbose (lazy("Skipping purge of expired user "^(show_user user)^" from "^agestr^"."))
+ else begin
+ verbose (lazy("Purge of expired user "^(show_user user))) ;
+ Unixutil.rm ~recursive:true ~force:true dir
+ end
end
else verbose (lazy("User "^(show_user user)^" has not expired from backup yet"))
end ;
collected
end
- else
- begin
- verbose (lazy("The user "^(show_user user)^" was last backed up "^(string_of_float priority))) ;
- Hashtbl.add collected user.localpart (priority,user) ;
- collected
- end
+ | None ->
+ begin
+ let priority = (Unix.stat dir).Unix.st_mtime in
+ verbose (lazy("The user "^(show_user user)^" was last backed up "^(string_of_float priority))) ;
+ Hashtbl.add collected user.localpart (priority,user) ;
+ collected
+ end
in
let virtdomains = options.virtdomains in
let hashimapspool = true in
@@ -1271,7 +1294,7 @@
let rec rename_backup_of_users = function
| [] -> ()
| (deleted_user::deleted_users) ->
- let uid = show_user deleted_user in
+ let uid = uid_of_user deleted_user in
if options.uidfilter uid then
begin
verbose (lazy("User "^uid^" deleted in mailspool, updating backup.")) ;
@@ -1812,7 +1835,7 @@
if options.run
then
let (priority,(user,dir),users_to_backup) = PriorityQueue.extract users_to_backup in
- let uid = (show_user user) in
+ let uid = (uid_of_user user) in
begin
begin
if options.uidfilter uid
@@ -1859,7 +1882,7 @@
let mboxlines_collector ~size ~user =
let mboxlines = Buffer.create size in
let mboxline ~cyrbase =
- let line = ((show_cyrus user)^cyrbase^"\tdefault\t"^(show_user user)^"\tlrswipcda\t\n") in
+ let line = ((show_cyrus user)^cyrbase^"\tdefault\t"^(uid_of_user user)^"\tlrswipcda\t\n") in
verbose (lazy("mboxline:"^line));
Buffer.add_string mboxlines line ;
in
@@ -1869,7 +1892,7 @@
(* Create a regular expression that matches the email address of the given user.
*)
let create_uidfilter_for_user user =
- let uid = show_user user in
+ let uid = uid_of_user user in
(* Replace "." with "\.", modulo string and regexp handling of \ *)
let re_uid = Str.global_replace (Str.regexp "\\.") "\\." uid in
let regexp = Str.regexp ("^"^re_uid^"$") in
@@ -2183,13 +2206,14 @@
* Return list of users in backup that are valid for recovery.
*)
let find_recoverable_users () =
- let deleted_user_regexp = Str.regexp "^\\(.+\\)\\.\\([0-9]+\\)$" in
let collector ~collected ~user ~dir =
verbose (lazy("Checking if recovery is needed for "^(show_user user)));
- if Str.string_match deleted_user_regexp user.localpart 0
- then collected
- else
- begin
+ match user.deleted_age with
+ | Some (age,agestr) -> begin
+ verbose (lazy("Skipping recovery of deleted user "^(show_user user)^"deleted at "^(agestr)^".")) ;
+ collected
+ end
+ | None -> begin
verbose (lazy("Planning to do recovery for user "^(show_user user))) ;
(user,dir)::collected
end
@@ -2248,7 +2272,7 @@
then None
else Some (String.sub domain 1 (length-1)) (* remove the @ *)
in
- cont {localpart=localpart;domain=domain}
+ cont {localpart=localpart;domain=domain;deleted_age=None}
end
else onfail ()
in
More information about the Limacute-commit
mailing list