From 3b44d0724366741786a96801d29ddd1c5b949a38 Mon Sep 17 00:00:00 2001 From: Ted Zlatanov Date: Tue, 14 Oct 2014 15:33:22 -0400 Subject: [PATCH] Optionally check the newsrc.eld file's timestamp before saving it. * gnus-start.el (gnus-save-newsrc-file-check-timestamp): New option to check the newsrc.eld file's timestamp before saving it. (gnus-save-newsrc-file): Use it, with a prompt when the newsrc.eld timestamp has changed to be newer. --- lisp/ChangeLog | 7 +++++++ lisp/gnus-start.el | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 7159eb8e7..214a8bf3e 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,10 @@ +2014-10-14 Teodor Zlatanov + + * gnus-start.el (gnus-save-newsrc-file-check-timestamp): New option to + check the newsrc.eld file's timestamp before saving it. + (gnus-save-newsrc-file): Use it, with a prompt when the newsrc.eld + timestamp has changed to be newer. + 2014-10-06 Jan Tatarik * gnus-icalendar.el (gnus-icalendar-identities): diff --git a/lisp/gnus-start.el b/lisp/gnus-start.el index 766e7c26a..5b734d0ae 100644 --- a/lisp/gnus-start.el +++ b/lisp/gnus-start.el @@ -442,6 +442,14 @@ See also `gnus-before-startup-hook'." :group 'gnus-newsrc :type 'hook) +(defcustom gnus-save-newsrc-file-check-timestamp nil + "Check the modification time of the newsrc.eld file before saving it. +When the newsrc.eld file is updated by multiple machines, +checking the file's modification time is a good way to avoid +overwriting updated data." + :group 'gnus-newsrc + :type 'boolean) + (defcustom gnus-save-newsrc-hook nil "A hook called before saving any of the newsrc files." :group 'gnus-newsrc @@ -2783,6 +2791,7 @@ If FORCE is non-nil, the .newsrc file is read." 'msdos-long-file-names (lambda () t)))) +(defvar gnus-save-newsrc-file-last-timestamp nil) (defun gnus-save-newsrc-file (&optional force) "Save .newsrc file." ;; Note: We cannot save .newsrc file if all newsgroups are removed @@ -2821,12 +2830,30 @@ If FORCE is non-nil, the .newsrc file is read." (erase-buffer) (gnus-message 5 "Saving %s.eld..." gnus-current-startup-file) + ;; check timestamp of `gnus-current-startup-file'.eld against + ;; `gnus-save-newsrc-file-last-timestamp' + (when gnus-save-newsrc-file-check-timestamp + (let* ((checkfile (concat gnus-current-startup-file ".eld")) + (mtime (nth 5 (file-attributes checkfile)))) + (when (and gnus-save-newsrc-file-last-timestamp + (time-less-p gnus-save-newsrc-file-last-timestamp + mtime)) + (unless (y-or-n-p + (format "%s was updated externally after %s, save?" + checkfile + (format-time-string + "%c" + gnus-save-newsrc-file-last-timestamp))) + (error "Couldn't save %s: updated externally" checkfile))))) + (if gnus-save-startup-file-via-temp-buffer (let ((coding-system-for-write gnus-ding-file-coding-system) (standard-output (current-buffer))) (gnus-gnus-to-quick-newsrc-format) (gnus-run-hooks 'gnus-save-quick-newsrc-hook) - (save-buffer)) + (save-buffer) + (setq gnus-save-newsrc-file-last-timestamp + (nth 5 (file-attributes buffer-file-name)))) (let ((coding-system-for-write gnus-ding-file-coding-system) (version-control gnus-backup-startup-file) (startup-file (concat gnus-current-startup-file ".eld")) @@ -2861,7 +2888,9 @@ If FORCE is non-nil, the .newsrc file is read." ;; Replace the existing startup file with the temp file. (rename-file working-file startup-file t) - (gnus-set-file-modes startup-file setmodes))) + (gnus-set-file-modes startup-file setmodes) + (setq gnus-save-newsrc-file-last-timestamp + (nth 5 (file-attributes startup-file))))) (condition-case nil (delete-file working-file) (file-error nil))))) -- 2.25.1