2 * This file is part of DisOrder.
3 * Copyright (C) 2010 Richard Kettlewell
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 /** @file server/mount.c
19 * @brief Periodically check for devices being mounted and unmounted
21 #include "disorder-server.h"
23 # include <sys/param.h>
24 # include <sys/ucred.h>
25 # include <sys/mount.h>
29 static int compare_fsstat(const void *av, const void *bv) {
30 const struct statfs *a = av, *b = bv;
33 c = memcmp(&a->f_fsid, &b->f_fsid, sizeof a->f_fsid);
36 c = strcmp(a->f_mntonname, b->f_mntonname);
43 void periodic_mount_check(ev_source *ev_) {
45 /* On OS X, we keep track of the hash of the kernel's mounted
48 static unsigned char last[20];
49 unsigned char *current;
50 int nfilesystems, space;
55 space = getfsstat(NULL, 0, MNT_NOWAIT);
56 buf = xcalloc(space, sizeof *buf);
57 nfilesystems = getfsstat(buf, space * sizeof *buf, MNT_NOWAIT);
58 if(nfilesystems > space)
59 // The array grew between check and use! We just give up and try later.
61 // Put into order so we get a bit of consistency
62 qsort(buf, nfilesystems, sizeof *buf, compare_fsstat);
63 if((e = gcry_md_open(&h, GCRY_MD_SHA1, 0))) {
64 disorder_error(0, "gcry_md_open: %s", gcry_strerror(e));
67 for(int n = 0; n < nfilesystems; ++n) {
68 gcry_md_write(h, &buf[n].f_fsid, sizeof buf[n].f_fsid);
69 gcry_md_write(h, buf[n].f_mntonname, 1 + strlen(buf[n].f_mntonname));
71 current = gcry_md_read(h, GCRY_MD_SHA1);
72 if(!first && memcmp(current, last, sizeof last))
73 trackdb_rescan(ev_, 1/*check*/, 0, 0);
74 memcpy(last, current, sizeof last);
76 #elif defined PATH_MTAB
77 /* On Linux we keep track of the modification time of /etc/mtab */
78 static time_t last_mount;
81 if(stat(PATH_MTAB, &sb) >= 0) {
82 if(last_mount != 0 && last_mount != sb.st_mtime)
83 trackdb_rescan(ev_, 1/*check*/, 0, 0);
84 last_mount = sb.st_mtime;