Whamcloud - gitweb
Comment out ext2_find_first_bit_set and ext2fs_find_next_bit_set
[tools/e2fsprogs.git] / lib / ext2fs / ismounted.c
1 /*
2  * ismounted.c --- Check to see if the filesystem was mounted
3  * 
4  * Copyright (C) 1995,1996,1997,1998,1999,2000 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 #include <sys/stat.h>
33
34 #include "ext2_fs.h"
35 #include "ext2fs.h"
36
37 #ifdef HAVE_MNTENT_H
38 /*
39  * Helper function which checks a file in /etc/mtab format to see if a
40  * filesystem is mounted.  Returns an error if the file doesn't exist
41  * or can't be opened.  
42  */
43 static errcode_t check_mntent_file(const char *mtab_file, const char *file, 
44                                    int *mount_flags, char *mtpt, int mtlen)
45 {
46         FILE * f;
47         struct mntent * mnt;
48         int     fd;
49
50         *mount_flags = 0;
51         if ((f = setmntent (mtab_file, "r")) == NULL)
52                 return errno;
53         while ((mnt = getmntent (f)) != NULL)
54                 if (strcmp(file, mnt->mnt_fsname) == 0)
55                         break;
56
57         if (mnt == 0) {
58 #ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
59                 struct stat st_root, st_file;
60                 /*
61                  * Do an extra check to see if this is the root device.  We
62                  * can't trust /etc/fstab, and /proc/mounts will only list
63                  * /dev/root for the root filesystem.  Argh.  Instead we
64                  * check if the given device has the same major/minor number
65                  * as the device that the root directory is on.
66                  */
67                 if (stat("/", &st_root) == 0 && stat(file, &st_file) == 0) {
68                         if (st_root.st_dev == st_file.st_rdev) {
69                                 *mount_flags = EXT2_MF_MOUNTED;
70                                 if (mtpt)
71                                         strncpy(mtpt, "/", mtlen);
72                                 goto is_root;
73                         }
74                 }
75 #endif
76                 endmntent (f);
77                 return 0;
78         }
79         *mount_flags = EXT2_MF_MOUNTED;
80         
81         /* Check to see if the ro option is set */
82         if (hasmntopt(mnt, MNTOPT_RO))
83                 *mount_flags |= EXT2_MF_READONLY;
84
85         if (mtpt)
86                 strncpy(mtpt, mnt->mnt_dir, mtlen);
87         /*
88          * Check to see if we're referring to the root filesystem.
89          * If so, do a manual check to see if we can open /etc/mtab
90          * read/write, since if the root is mounted read/only, the
91          * contents of /etc/mtab may not be accurate.
92          */
93         if (!strcmp(mnt->mnt_dir, "/")) {
94 is_root:
95 #define TEST_FILE "/.ismount-test-file"         
96                 *mount_flags |= EXT2_MF_ISROOT;
97                 fd = open(TEST_FILE, O_RDWR|O_CREAT);
98                 if (fd < 0) {
99                         if (errno == EROFS)
100                                 *mount_flags |= EXT2_MF_READONLY;
101                 } else
102                         close(fd);
103                 (void) unlink(TEST_FILE);
104         }
105         endmntent (f);
106         return 0;
107 }
108
109 static errcode_t check_mntent(const char *file, int *mount_flags,
110                               char *mtpt, int mtlen)
111 {
112         errcode_t       retval;
113
114 #ifdef __linux__
115         retval = check_mntent_file("/proc/mounts", file, mount_flags,
116                                    mtpt, mtlen);
117         if (retval == 0)
118                 return 0;
119 #endif
120         retval = check_mntent_file(MOUNTED, file, mount_flags, mtpt, mtlen);
121         return retval;
122 }
123
124 #elif defined(HAVE_GETMNTINFO)
125
126 static errcode_t check_getmntinfo(const char *file, int *mount_flags,
127                                   char *mtpt, int mtlen)
128 {
129         struct statfs *mp;
130         int    len, n;
131         const  char   *s1;
132         char    *s2;
133
134         n = getmntinfo(&mp, MNT_NOWAIT);
135         if (n == 0)
136                 return errno;
137
138         len = sizeof(_PATH_DEV) - 1;
139         s1 = file;
140         if (strncmp(_PATH_DEV, s1, len) == 0)
141                 s1 += len;
142  
143         *mount_flags = 0;
144         while (--n >= 0) {
145                 s2 = mp->f_mntfromname;
146                 if (strncmp(_PATH_DEV, s2, len) == 0) {
147                         s2 += len - 1;
148                         *s2 = 'r';
149                 }
150                 if (strcmp(s1, s2) == 0 || strcmp(s1, &s2[1]) == 0) {
151                         *mount_flags = EXT2_MF_MOUNTED;
152                         break;
153                 }
154                 ++mp;
155         }
156         if (mtpt)
157                 strncpy(mtpt, mp->f_mntonname, mtlen);
158         return 0;
159 }
160 #endif /* HAVE_GETMNTINFO */
161
162 /*
163  * ext2fs_check_mount_point() returns 1 if the device is mounted, 0
164  * otherwise.  If mtpt is non-NULL, the directory where the device is
165  * mounted is copied to where mtpt is pointing, up to mtlen
166  * characters.
167  */
168 #ifdef __TURBOC__
169  #pragma argsused
170 #endif
171 errcode_t ext2fs_check_mount_point(const char *device, int *mount_flags,
172                                   char *mtpt, int mtlen)
173 {
174 #ifdef HAVE_MNTENT_H
175         return check_mntent(device, mount_flags, mtpt, mtlen);
176 #else 
177 #ifdef HAVE_GETMNTINFO
178         return check_getmntinfo(device, mount_flags, mtpt, mtlen);
179 #else
180 #warning "Can't use getmntent or getmntinfo to check for mounted filesystems!"
181         *mount_flags = 0;
182         return 0;
183 #endif /* HAVE_GETMNTINFO */
184 #endif /* HAVE_MNTENT_H */
185 }
186
187 /*
188  * ext2fs_check_if_mounted() sets the mount_flags EXT2_MF_MOUNTED,
189  * EXT2_MF_READONLY, and EXT2_MF_ROOT
190  * 
191  */
192 errcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags)
193 {
194         return ext2fs_check_mount_point(file, mount_flags, NULL, 0);
195 }
196
197 #ifdef DEBUG
198 int main(int argc, char **argv)
199 {
200         int     retval, mount_flags;
201         
202         if (argc < 2) {
203                 fprintf(stderr, "Usage: %s device\n", argv[0]);
204                 exit(1);
205         }
206
207         retval = ext2fs_check_if_mounted(argv[1], &mount_flags);
208         if (retval) {
209                 com_err(argv[0], retval,
210                         "while calling ext2fs_check_if_mounted");
211                 exit(1);
212         }
213         printf("Device %s reports flags %02x\n", argv[1], mount_flags);
214         if (mount_flags & EXT2_MF_MOUNTED)
215                 printf("\t%s is mounted.\n", argv[1]);
216         
217         if (mount_flags & EXT2_MF_READONLY)
218                 printf("\t%s is read-only.\n", argv[1]);
219         
220         if (mount_flags & EXT2_MF_ISROOT)
221                 printf("\t%s is the root filesystem.\n", argv[1]);
222         
223         exit(0);
224 }
225 #endif