xref: /aosp_15_r20/external/e2fsprogs/misc/ismounted.c (revision 6a54128f25917bfc36a8a6e9d722c04a0b4641b6)
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