ismounted.c revision 43ec8734f2ecd0a345e831f45fd3dfb077426811
1/*
2 * ismounted.c --- Check to see if the filesystem was mounted
3 *
4 * Copyright (C) 1995 Theodore Ts'o.
5 *
6 * %Begin-Header%
7 * This file may be redistributed under the terms of the GNU Public
8 * License.
9 * %End-Header%
10 */
11
12#include <stdio.h>
13#if HAVE_UNISTD_H
14#include <unistd.h>
15#endif
16#if HAVE_ERRNO_H
17#include <errno.h>
18#endif
19#include <fcntl.h>
20#ifdef HAVE_LINUX_FD_H
21#include <linux/fd.h>
22#endif
23#ifdef HAVE_MNTENT_H
24#include <mntent.h>
25#endif
26#ifdef HAVE_GETMNTINFO
27#include <paths.h>
28#include <sys/param.h>
29#include <sys/mount.h>
30#endif /* HAVE_GETMNTINFO */
31
32#if EXT2_FLAT_INCLUDES
33#include "ext2_fs.h"
34#else
35#include <linux/ext2_fs.h>
36#endif
37
38#include "ext2fs.h"
39
40#ifdef HAVE_MNTENT_H
41/*
42 * XXX we assume that /etc/mtab is located on the root filesystem, and
43 * we only check to see if the mount is readonly for the root
44 * filesystem.
45 */
46static errcode_t check_mntent(const char *file, int *mount_flags,
47			      char *mtpt, int mtlen)
48{
49	FILE * f;
50	struct mntent * mnt;
51	int	fd;
52
53	*mount_flags = 0;
54	if ((f = setmntent (MOUNTED, "r")) == NULL)
55		return errno;
56	while ((mnt = getmntent (f)) != NULL)
57		if (strcmp(file, mnt->mnt_fsname) == 0)
58			break;
59	endmntent (f);
60	if (mnt == 0)
61		return 0;
62	*mount_flags = EXT2_MF_MOUNTED;
63
64	if (!strcmp(mnt->mnt_dir, "/")) {
65		*mount_flags |= EXT2_MF_ISROOT;
66		fd = open(MOUNTED, O_RDWR);
67		if (fd < 0) {
68			if (errno == EROFS)
69				*mount_flags |= EXT2_MF_READONLY;
70		} else
71			close(fd);
72	}
73	if (mtpt)
74		strncpy(mtpt, mnt->mnt_dir, mtlen);
75	return 0;
76}
77#endif
78
79#ifdef HAVE_GETMNTINFO
80static errcode_t check_getmntinfo(const char *file, int *mount_flags,
81				  char *mtpt, int mtlen)
82{
83	struct statfs *mp;
84        int    len, n;
85        const  char   *s1;
86	char	*s2;
87
88        n = getmntinfo(&mp, MNT_NOWAIT);
89        if (n == 0)
90		return errno;
91
92        len = sizeof(_PATH_DEV) - 1;
93        s1 = file;
94        if (strncmp(_PATH_DEV, s1, len) == 0)
95                s1 += len;
96
97	*mount_flags = 0;
98        while (--n >= 0) {
99                s2 = mp->f_mntfromname;
100                if (strncmp(_PATH_DEV, s2, len) == 0) {
101                        s2 += len - 1;
102                        *s2 = 'r';
103                }
104                if (strcmp(s1, s2) == 0 || strcmp(s1, &s2[1]) == 0) {
105			*mount_flags = EXT2_MF_MOUNTED;
106			break;
107		}
108                ++mp;
109	}
110	if (mtpt)
111		strncpy(mtpt, mp->f_mntonname, mtlen);
112	return 0;
113}
114#endif /* HAVE_GETMNTINFO */
115
116/*
117 * ext2fs_check_mount_point() returns 1 if the device is mounted, 0
118 * otherwise.  If mtpt is non-NULL, the directory where the device is
119 * mounted is copied to where mtpt is pointing, up to mtlen
120 * characters.
121 */
122#ifdef __TURBOC__
123#pragma argsused
124#endif
125errcode_t ext2fs_check_mount_point(const char *device, int *mount_flags,
126				  char *mtpt, int mtlen)
127{
128#ifdef HAVE_MNTENT_H
129	return check_mntent(device, mount_flags, mtpt, mtlen);
130#else
131#ifdef HAVE_GETMNTINFO
132	return check_getmntinfo(device, mount_flags, mtpt, mtlen);
133#else
134	*mount_flags = 0;
135	return 0;
136#endif /* HAVE_GETMNTINFO */
137#endif /* HAVE_MNTENT_H */
138}
139
140/*
141 * ext2fs_check_if_mounted() sets the mount_flags EXT2_MF_MOUNTED and
142 * EXT2_MF_READONLY
143 *
144 */
145#ifdef __TURBOC__
146#pragma argsused
147#endif
148errcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags)
149{
150#ifdef HAVE_MNTENT_H
151	return check_mntent(file, mount_flags, NULL, 0);
152#else
153#ifdef HAVE_GETMNTINFO
154	return check_getmntinfo(file, mount_flags, NULL, 0);
155#else
156	*mount_flags = 0;
157	return 0;
158#endif /* HAVE_GETMNTINFO */
159#endif /* HAVE_MNTENT_H */
160}
161