diff options
author | Ludovic Courtès <ludo@gnu.org> | 2023-10-18 18:17:36 +0200 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2023-10-18 18:21:04 +0200 |
commit | d0fed2f4df06446eafcc992f0bc7ea154124fdf4 (patch) | |
tree | be6cf68a3bd47c4cf4e42026757b4714c738cfe2 /guix | |
parent | 1076f32111e512ed437f135c9eb6ce2daaafd623 (diff) | |
download | guix-patches-d0fed2f4df06446eafcc992f0bc7ea154124fdf4.tar guix-patches-d0fed2f4df06446eafcc992f0bc7ea154124fdf4.tar.gz |
locate: Do not return the system database when it is too old.
Fixes a bug whereby ‘guix locate’ would pick the system database, then
decide it’s too old, try to update it, and fail because it’s not
writable by unprivileged users.
Fixes <https://issues.guix.gnu.org/66612>.
* guix/scripts/locate.scm (file-age): New procedure.
(suitable-database): Add ‘age-update-threshold’ parameter and honor it.
(guix-locate): Remove ‘file-age’. Pass ‘age-update-threshold’ to the
‘database’ option.
Reported-by: Matt Wette <matt.wette@gmail.com>
Diffstat (limited to 'guix')
-rw-r--r-- | guix/scripts/locate.scm | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/guix/scripts/locate.scm b/guix/scripts/locate.scm index 5f3e28797f..ae64f46896 100644 --- a/guix/scripts/locate.scm +++ b/guix/scripts/locate.scm @@ -196,10 +196,15 @@ SELECT version FROM SchemaVersion ORDER BY version DESC LIMIT 1;" ;; System-wide database file name. (string-append %localstatedir "/cache/guix/locate/db.sqlite")) -(define (suitable-database create?) +(define (file-age stat) + "Return the age of the file denoted by STAT in seconds." + (- (current-time) (stat:mtime stat))) + +(define (suitable-database create? age-update-threshold) "Return a suitable database file. When CREATE? is true, the returned database will be opened for writing; otherwise, return the most recent one, -user or system." +user or system. Do not return the system database if it is older than +AGE-UPDATE-THRESHOLD seconds." (if (zero? (getuid)) system-database-file (if create? @@ -207,10 +212,13 @@ user or system." (let ((system (stat system-database-file #f)) (user (stat user-database-file #f))) (if user - (if (and system (> (stat:mtime system) (stat:mtime user))) + (if (and system + (> (stat:mtime system) (stat:mtime user)) + (< (file-age system) age-update-threshold)) system-database-file user-database-file) - (if system + (if (and system + (< (file-age system) age-update-threshold)) system-database-file user-database-file)))))) @@ -595,10 +603,6 @@ Locate FILE and return the list of packages that contain it.\n")) ;; database. (* 9 30 (* 24 60 60))) - (define (file-age stat) - ;; Return true if TIME denotes an "old" time. - (- (current-time) (stat:mtime stat))) - (with-error-handling (let* ((opts (parse-command-line args %options (list %default-options) @@ -610,7 +614,7 @@ Locate FILE and return the list of packages that contain it.\n")) (clear? (assoc-ref opts 'clear?)) (update? (assoc-ref opts 'update?)) (glob? (assoc-ref opts 'glob?)) - (database ((assoc-ref opts 'database) update?)) + (database ((assoc-ref opts 'database) update? age-update-threshold)) (method (assoc-ref opts 'method)) (files (reverse (filter-map (match-lambda (('argument . arg) arg) |