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
);
77 #elif defined PATH_MTAB
78 /* On Linux we keep track of the modification time of /etc/mtab */
79 static time_t last_mount
;
82 if(stat(PATH_MTAB
, &sb
) >= 0) {
83 if(last_mount
!= 0 && last_mount
!= sb
.st_mtime
)
84 trackdb_rescan(ev_
, 1/*check*/, 0, 0);
85 last_mount
= sb
.st_mtime
;