1*6a54128fSAndroid Build Coastguard Worker /*
2*6a54128fSAndroid Build Coastguard Worker * ismounted.c --- Check to see if the filesystem was mounted
3*6a54128fSAndroid Build Coastguard Worker *
4*6a54128fSAndroid Build Coastguard Worker * Copyright (C) 1995,1996,1997,1998,1999,2000,2008 Theodore Ts'o.
5*6a54128fSAndroid Build Coastguard Worker *
6*6a54128fSAndroid Build Coastguard Worker * %Begin-Header%
7*6a54128fSAndroid Build Coastguard Worker * This file may be redistributed under the terms of the GNU Public
8*6a54128fSAndroid Build Coastguard Worker * License.
9*6a54128fSAndroid Build Coastguard Worker * %End-Header%
10*6a54128fSAndroid Build Coastguard Worker */
11*6a54128fSAndroid Build Coastguard Worker
12*6a54128fSAndroid Build Coastguard Worker #include "config.h"
13*6a54128fSAndroid Build Coastguard Worker #include <stdio.h>
14*6a54128fSAndroid Build Coastguard Worker #if HAVE_UNISTD_H
15*6a54128fSAndroid Build Coastguard Worker #include <unistd.h>
16*6a54128fSAndroid Build Coastguard Worker #endif
17*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_STDLIB_H
18*6a54128fSAndroid Build Coastguard Worker #include <stdlib.h>
19*6a54128fSAndroid Build Coastguard Worker #endif
20*6a54128fSAndroid Build Coastguard Worker #if HAVE_ERRNO_H
21*6a54128fSAndroid Build Coastguard Worker #include <errno.h>
22*6a54128fSAndroid Build Coastguard Worker #endif
23*6a54128fSAndroid Build Coastguard Worker #include <fcntl.h>
24*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_LINUX_FD_H
25*6a54128fSAndroid Build Coastguard Worker #include <linux/fd.h>
26*6a54128fSAndroid Build Coastguard Worker #endif
27*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_MNTENT_H
28*6a54128fSAndroid Build Coastguard Worker #include <mntent.h>
29*6a54128fSAndroid Build Coastguard Worker #endif
30*6a54128fSAndroid Build Coastguard Worker #include <string.h>
31*6a54128fSAndroid Build Coastguard Worker #include <sys/stat.h>
32*6a54128fSAndroid Build Coastguard Worker #include <ctype.h>
33*6a54128fSAndroid Build Coastguard Worker
34*6a54128fSAndroid Build Coastguard Worker #include "fsck.h"
35*6a54128fSAndroid Build Coastguard Worker
36*6a54128fSAndroid Build Coastguard Worker /*
37*6a54128fSAndroid Build Coastguard Worker * ext2fs_check_if_mounted flags
38*6a54128fSAndroid Build Coastguard Worker */
39*6a54128fSAndroid Build Coastguard Worker #define MF_MOUNTED 1
40*6a54128fSAndroid Build Coastguard Worker
41*6a54128fSAndroid Build Coastguard Worker #include "et/com_err.h"
42*6a54128fSAndroid Build Coastguard Worker
43*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_SETMNTENT
skip_over_blank(char * cp)44*6a54128fSAndroid Build Coastguard Worker static char *skip_over_blank(char *cp)
45*6a54128fSAndroid Build Coastguard Worker {
46*6a54128fSAndroid Build Coastguard Worker while (*cp && isspace(*cp))
47*6a54128fSAndroid Build Coastguard Worker cp++;
48*6a54128fSAndroid Build Coastguard Worker return cp;
49*6a54128fSAndroid Build Coastguard Worker }
50*6a54128fSAndroid Build Coastguard Worker
skip_over_word(char * cp)51*6a54128fSAndroid Build Coastguard Worker static char *skip_over_word(char *cp)
52*6a54128fSAndroid Build Coastguard Worker {
53*6a54128fSAndroid Build Coastguard Worker while (*cp && !isspace(*cp))
54*6a54128fSAndroid Build Coastguard Worker cp++;
55*6a54128fSAndroid Build Coastguard Worker return cp;
56*6a54128fSAndroid Build Coastguard Worker }
57*6a54128fSAndroid Build Coastguard Worker
parse_word(char ** buf)58*6a54128fSAndroid Build Coastguard Worker static char *parse_word(char **buf)
59*6a54128fSAndroid Build Coastguard Worker {
60*6a54128fSAndroid Build Coastguard Worker char *word, *next;
61*6a54128fSAndroid Build Coastguard Worker
62*6a54128fSAndroid Build Coastguard Worker word = *buf;
63*6a54128fSAndroid Build Coastguard Worker if (*word == 0)
64*6a54128fSAndroid Build Coastguard Worker return 0;
65*6a54128fSAndroid Build Coastguard Worker
66*6a54128fSAndroid Build Coastguard Worker word = skip_over_blank(word);
67*6a54128fSAndroid Build Coastguard Worker next = skip_over_word(word);
68*6a54128fSAndroid Build Coastguard Worker if (*next)
69*6a54128fSAndroid Build Coastguard Worker *next++ = 0;
70*6a54128fSAndroid Build Coastguard Worker *buf = next;
71*6a54128fSAndroid Build Coastguard Worker return word;
72*6a54128fSAndroid Build Coastguard Worker }
73*6a54128fSAndroid Build Coastguard Worker #endif
74*6a54128fSAndroid Build Coastguard Worker
75*6a54128fSAndroid Build Coastguard Worker /*
76*6a54128fSAndroid Build Coastguard Worker * Helper function which checks a file in /etc/mtab format to see if a
77*6a54128fSAndroid Build Coastguard Worker * filesystem is mounted. Returns an error if the file doesn't exist
78*6a54128fSAndroid Build Coastguard Worker * or can't be opened.
79*6a54128fSAndroid Build Coastguard Worker */
check_mntent_file(const char * mtab_file,const char * file,int * mount_flags)80*6a54128fSAndroid Build Coastguard Worker static errcode_t check_mntent_file(const char *mtab_file, const char *file,
81*6a54128fSAndroid Build Coastguard Worker int *mount_flags)
82*6a54128fSAndroid Build Coastguard Worker {
83*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_SETMNTENT
84*6a54128fSAndroid Build Coastguard Worker struct stat st_buf;
85*6a54128fSAndroid Build Coastguard Worker errcode_t retval = 0;
86*6a54128fSAndroid Build Coastguard Worker dev_t file_dev=0, file_rdev=0;
87*6a54128fSAndroid Build Coastguard Worker ino_t file_ino=0;
88*6a54128fSAndroid Build Coastguard Worker FILE *f;
89*6a54128fSAndroid Build Coastguard Worker char buf[1024], *device = 0, *mnt_dir = 0, *cp;
90*6a54128fSAndroid Build Coastguard Worker
91*6a54128fSAndroid Build Coastguard Worker *mount_flags = 0;
92*6a54128fSAndroid Build Coastguard Worker if ((f = setmntent (mtab_file, "r")) == NULL)
93*6a54128fSAndroid Build Coastguard Worker return errno;
94*6a54128fSAndroid Build Coastguard Worker if (stat(file, &st_buf) == 0) {
95*6a54128fSAndroid Build Coastguard Worker if (S_ISBLK(st_buf.st_mode)) {
96*6a54128fSAndroid Build Coastguard Worker #ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
97*6a54128fSAndroid Build Coastguard Worker file_rdev = st_buf.st_rdev;
98*6a54128fSAndroid Build Coastguard Worker #endif /* __GNU__ */
99*6a54128fSAndroid Build Coastguard Worker } else {
100*6a54128fSAndroid Build Coastguard Worker file_dev = st_buf.st_dev;
101*6a54128fSAndroid Build Coastguard Worker file_ino = st_buf.st_ino;
102*6a54128fSAndroid Build Coastguard Worker }
103*6a54128fSAndroid Build Coastguard Worker }
104*6a54128fSAndroid Build Coastguard Worker while (1) {
105*6a54128fSAndroid Build Coastguard Worker if (!fgets(buf, sizeof(buf), f)) {
106*6a54128fSAndroid Build Coastguard Worker device = mnt_dir = 0;
107*6a54128fSAndroid Build Coastguard Worker break;
108*6a54128fSAndroid Build Coastguard Worker }
109*6a54128fSAndroid Build Coastguard Worker buf[sizeof(buf)-1] = 0;
110*6a54128fSAndroid Build Coastguard Worker
111*6a54128fSAndroid Build Coastguard Worker cp = buf;
112*6a54128fSAndroid Build Coastguard Worker device = parse_word(&cp);
113*6a54128fSAndroid Build Coastguard Worker if (!device || *device == '#')
114*6a54128fSAndroid Build Coastguard Worker return 0; /* Ignore blank lines and comments */
115*6a54128fSAndroid Build Coastguard Worker mnt_dir = parse_word(&cp);
116*6a54128fSAndroid Build Coastguard Worker
117*6a54128fSAndroid Build Coastguard Worker if (device[0] != '/')
118*6a54128fSAndroid Build Coastguard Worker continue;
119*6a54128fSAndroid Build Coastguard Worker
120*6a54128fSAndroid Build Coastguard Worker if (strcmp(file, device) == 0)
121*6a54128fSAndroid Build Coastguard Worker break;
122*6a54128fSAndroid Build Coastguard Worker if (stat(device, &st_buf) == 0) {
123*6a54128fSAndroid Build Coastguard Worker if (S_ISBLK(st_buf.st_mode)) {
124*6a54128fSAndroid Build Coastguard Worker #ifndef __GNU__
125*6a54128fSAndroid Build Coastguard Worker if (file_rdev && (file_rdev == st_buf.st_rdev))
126*6a54128fSAndroid Build Coastguard Worker break;
127*6a54128fSAndroid Build Coastguard Worker #endif /* __GNU__ */
128*6a54128fSAndroid Build Coastguard Worker } else {
129*6a54128fSAndroid Build Coastguard Worker if (file_dev && ((file_dev == st_buf.st_dev) &&
130*6a54128fSAndroid Build Coastguard Worker (file_ino == st_buf.st_ino)))
131*6a54128fSAndroid Build Coastguard Worker break;
132*6a54128fSAndroid Build Coastguard Worker }
133*6a54128fSAndroid Build Coastguard Worker }
134*6a54128fSAndroid Build Coastguard Worker }
135*6a54128fSAndroid Build Coastguard Worker
136*6a54128fSAndroid Build Coastguard Worker if (mnt_dir == 0) {
137*6a54128fSAndroid Build Coastguard Worker #ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
138*6a54128fSAndroid Build Coastguard Worker /*
139*6a54128fSAndroid Build Coastguard Worker * Do an extra check to see if this is the root device. We
140*6a54128fSAndroid Build Coastguard Worker * can't trust /etc/mtab, and /proc/mounts will only list
141*6a54128fSAndroid Build Coastguard Worker * /dev/root for the root filesystem. Argh. Instead we
142*6a54128fSAndroid Build Coastguard Worker * check if the given device has the same major/minor number
143*6a54128fSAndroid Build Coastguard Worker * as the device that the root directory is on.
144*6a54128fSAndroid Build Coastguard Worker */
145*6a54128fSAndroid Build Coastguard Worker if (file_rdev && (stat("/", &st_buf) == 0) &&
146*6a54128fSAndroid Build Coastguard Worker (st_buf.st_dev == file_rdev))
147*6a54128fSAndroid Build Coastguard Worker *mount_flags = MF_MOUNTED;
148*6a54128fSAndroid Build Coastguard Worker #endif /* __GNU__ */
149*6a54128fSAndroid Build Coastguard Worker goto errout;
150*6a54128fSAndroid Build Coastguard Worker }
151*6a54128fSAndroid Build Coastguard Worker #ifndef __GNU__ /* The GNU hurd is deficient; what else is new? */
152*6a54128fSAndroid Build Coastguard Worker /* Validate the entry in case /etc/mtab is out of date */
153*6a54128fSAndroid Build Coastguard Worker /*
154*6a54128fSAndroid Build Coastguard Worker * We need to be paranoid, because some broken distributions
155*6a54128fSAndroid Build Coastguard Worker * (read: Slackware) don't initialize /etc/mtab before checking
156*6a54128fSAndroid Build Coastguard Worker * all of the non-root filesystems on the disk.
157*6a54128fSAndroid Build Coastguard Worker */
158*6a54128fSAndroid Build Coastguard Worker if (stat(mnt_dir, &st_buf) < 0) {
159*6a54128fSAndroid Build Coastguard Worker retval = errno;
160*6a54128fSAndroid Build Coastguard Worker if (retval == ENOENT) {
161*6a54128fSAndroid Build Coastguard Worker #ifdef DEBUG
162*6a54128fSAndroid Build Coastguard Worker printf("Bogus entry in %s! (%s does not exist)\n",
163*6a54128fSAndroid Build Coastguard Worker mtab_file, mnt_dir);
164*6a54128fSAndroid Build Coastguard Worker #endif /* DEBUG */
165*6a54128fSAndroid Build Coastguard Worker retval = 0;
166*6a54128fSAndroid Build Coastguard Worker }
167*6a54128fSAndroid Build Coastguard Worker goto errout;
168*6a54128fSAndroid Build Coastguard Worker }
169*6a54128fSAndroid Build Coastguard Worker if (file_rdev && (st_buf.st_dev != file_rdev)) {
170*6a54128fSAndroid Build Coastguard Worker #ifdef DEBUG
171*6a54128fSAndroid Build Coastguard Worker printf("Bogus entry in %s! (%s not mounted on %s)\n",
172*6a54128fSAndroid Build Coastguard Worker mtab_file, file, mnt_dir);
173*6a54128fSAndroid Build Coastguard Worker #endif /* DEBUG */
174*6a54128fSAndroid Build Coastguard Worker goto errout;
175*6a54128fSAndroid Build Coastguard Worker }
176*6a54128fSAndroid Build Coastguard Worker #endif /* __GNU__ */
177*6a54128fSAndroid Build Coastguard Worker *mount_flags = MF_MOUNTED;
178*6a54128fSAndroid Build Coastguard Worker
179*6a54128fSAndroid Build Coastguard Worker retval = 0;
180*6a54128fSAndroid Build Coastguard Worker errout:
181*6a54128fSAndroid Build Coastguard Worker endmntent (f);
182*6a54128fSAndroid Build Coastguard Worker return retval;
183*6a54128fSAndroid Build Coastguard Worker #else /* !HAVE_SETMNTENT */
184*6a54128fSAndroid Build Coastguard Worker return 0;
185*6a54128fSAndroid Build Coastguard Worker #endif /* HAVE_MNTENT_H */
186*6a54128fSAndroid Build Coastguard Worker }
187*6a54128fSAndroid Build Coastguard Worker
is_mounted(const char * file)188*6a54128fSAndroid Build Coastguard Worker int is_mounted(const char *file)
189*6a54128fSAndroid Build Coastguard Worker {
190*6a54128fSAndroid Build Coastguard Worker errcode_t retval;
191*6a54128fSAndroid Build Coastguard Worker int mount_flags = 0;
192*6a54128fSAndroid Build Coastguard Worker
193*6a54128fSAndroid Build Coastguard Worker #ifdef __linux__
194*6a54128fSAndroid Build Coastguard Worker retval = check_mntent_file("/proc/mounts", file, &mount_flags);
195*6a54128fSAndroid Build Coastguard Worker if (retval)
196*6a54128fSAndroid Build Coastguard Worker return 0;
197*6a54128fSAndroid Build Coastguard Worker if (mount_flags)
198*6a54128fSAndroid Build Coastguard Worker return 1;
199*6a54128fSAndroid Build Coastguard Worker #endif /* __linux__ */
200*6a54128fSAndroid Build Coastguard Worker retval = check_mntent_file("/etc/mtab", file, &mount_flags);
201*6a54128fSAndroid Build Coastguard Worker if (retval)
202*6a54128fSAndroid Build Coastguard Worker return 0;
203*6a54128fSAndroid Build Coastguard Worker return (mount_flags);
204*6a54128fSAndroid Build Coastguard Worker }
205*6a54128fSAndroid Build Coastguard Worker
206*6a54128fSAndroid Build Coastguard Worker #ifdef DEBUG
main(int argc,char ** argv)207*6a54128fSAndroid Build Coastguard Worker int main(int argc, char **argv)
208*6a54128fSAndroid Build Coastguard Worker {
209*6a54128fSAndroid Build Coastguard Worker if (argc < 2) {
210*6a54128fSAndroid Build Coastguard Worker fprintf(stderr, "Usage: %s device\n", argv[0]);
211*6a54128fSAndroid Build Coastguard Worker exit(1);
212*6a54128fSAndroid Build Coastguard Worker }
213*6a54128fSAndroid Build Coastguard Worker
214*6a54128fSAndroid Build Coastguard Worker if (is_mounted(argv[1]))
215*6a54128fSAndroid Build Coastguard Worker printf("\t%s is mounted.\n", argv[1]);
216*6a54128fSAndroid Build Coastguard Worker exit(0);
217*6a54128fSAndroid Build Coastguard Worker }
218*6a54128fSAndroid Build Coastguard Worker #endif /* DEBUG */
219