ismounted.c revision 31dbecd482405e0d3a67eb58e1a1c8cb9f2ad83e
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#include <string.h>
32
33#if EXT2_FLAT_INCLUDES
34#include "ext2_fs.h"
35#else
36#include <linux/ext2_fs.h>
37#endif
38
39#include "ext2fs.h"
40
41#ifdef HAVE_MNTENT_H
42/*
43 * XXX we assume that /etc/mtab is located on the root filesystem, and
44 * we only check to see if the mount is readonly for the root
45 * filesystem.
46 */
47static errcode_t check_mntent(const char *file, int *mount_flags,
48			      char *mtpt, int mtlen)
49{
50	FILE * f;
51	struct mntent * mnt;
52	int	fd;
53
54	*mount_flags = 0;
55	if ((f = setmntent (MOUNTED, "r")) == NULL)
56		return errno;
57	while ((mnt = getmntent (f)) != NULL)
58		if (strcmp(file, mnt->mnt_fsname) == 0)
59			break;
60	endmntent (f);
61	if (mnt == 0)
62		return 0;
63	*mount_flags = EXT2_MF_MOUNTED;
64
65	if (!strcmp(mnt->mnt_dir, "/")) {
66		*mount_flags |= EXT2_MF_ISROOT;
67		fd = open(MOUNTED, O_RDWR);
68		if (fd < 0) {
69			if (errno == EROFS)
70				*mount_flags |= EXT2_MF_READONLY;
71		} else
72			close(fd);
73	}
74	if (mtpt)
75		strncpy(mtpt, mnt->mnt_dir, mtlen);
76	return 0;
77}
78#endif
79
80#ifdef HAVE_GETMNTINFO
81static errcode_t check_getmntinfo(const char *file, int *mount_flags,
82				  char *mtpt, int mtlen)
83{
84	struct statfs *mp;
85        int    len, n;
86        const  char   *s1;
87	char	*s2;
88
89        n = getmntinfo(&mp, MNT_NOWAIT);
90        if (n == 0)
91		return errno;
92
93        len = sizeof(_PATH_DEV) - 1;
94        s1 = file;
95        if (strncmp(_PATH_DEV, s1, len) == 0)
96                s1 += len;
97
98	*mount_flags = 0;
99        while (--n >= 0) {
100                s2 = mp->f_mntfromname;
101                if (strncmp(_PATH_DEV, s2, len) == 0) {
102                        s2 += len - 1;
103                        *s2 = 'r';
104                }
105                if (strcmp(s1, s2) == 0 || strcmp(s1, &s2[1]) == 0) {
106			*mount_flags = EXT2_MF_MOUNTED;
107			break;
108		}
109                ++mp;
110	}
111	if (mtpt)
112		strncpy(mtpt, mp->f_mntonname, mtlen);
113	return 0;
114}
115#endif /* HAVE_GETMNTINFO */
116
117/*
118 * ext2fs_check_mount_point() returns 1 if the device is mounted, 0
119 * otherwise.  If mtpt is non-NULL, the directory where the device is
120 * mounted is copied to where mtpt is pointing, up to mtlen
121 * characters.
122 */
123#ifdef __TURBOC__
124 #pragma argsused
125#endif
126errcode_t ext2fs_check_mount_point(const char *device, int *mount_flags,
127				  char *mtpt, int mtlen)
128{
129#ifdef HAVE_MNTENT_H
130	return check_mntent(device, mount_flags, mtpt, mtlen);
131#else
132#ifdef HAVE_GETMNTINFO
133	return check_getmntinfo(device, mount_flags, mtpt, mtlen);
134#else
135	*mount_flags = 0;
136	return 0;
137#endif /* HAVE_GETMNTINFO */
138#endif /* HAVE_MNTENT_H */
139}
140
141/*
142 * ext2fs_check_if_mounted() sets the mount_flags EXT2_MF_MOUNTED and
143 * EXT2_MF_READONLY
144 *
145 */
146#ifdef __TURBOC__
147 #pragma argsused
148#endif
149errcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags)
150{
151#ifdef HAVE_MNTENT_H
152	return check_mntent(file, mount_flags, NULL, 0);
153#else
154#ifdef HAVE_GETMNTINFO
155	return check_getmntinfo(file, mount_flags, NULL, 0);
156#else
157	*mount_flags = 0;
158	return 0;
159#endif /* HAVE_GETMNTINFO */
160#endif /* HAVE_MNTENT_H */
161}
162