~daniel-mehrmann/e2fsprogs/master

« back to all changes in this revision

Viewing changes to .pc/git-update-to-3b0018beee/lib/ext2fs/ismounted.c

  • Committer: Package Import Robot
  • Author(s): Dmitrijs Ledkovs
  • Date: 2012-06-14 13:01:21 UTC
  • mfrom: (8.4.18 sid)
  • Revision ID: package-import@ubuntu.com-20120614130121-t2gct0d09jepx0y6
Tags: 1.42.4-3ubuntu1
* Merge from Debian unstable (LP: #978012), remainging changes:
  - debian/control.in: 
      Build-depend on gettext:any instead of on gettext for (cross-building)
      Drop build dependency on dc, which hasn't been needed for some time.
      Update maintainer field.
  - debian/rules:
      Block pkg-create-dbgsym from operating on this package.
      Build without dietlibc-dev, which is in universe 
  - debian/control:
      Regenerate with ./debian/rules debian/control

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 Library
8
 
 * General Public License, version 2.
9
 
 * %End-Header%
10
 
 */
11
 
 
12
 
#include "config.h"
13
 
#include <stdio.h>
14
 
#if HAVE_UNISTD_H
15
 
#include <unistd.h>
16
 
#endif
17
 
#if HAVE_ERRNO_H
18
 
#include <errno.h>
19
 
#endif
20
 
#include <fcntl.h>
21
 
#ifdef HAVE_LINUX_FD_H
22
 
#include <linux/fd.h>
23
 
#endif
24
 
#ifdef HAVE_MNTENT_H
25
 
#include <mntent.h>
26
 
#endif
27
 
#ifdef HAVE_GETMNTINFO
28
 
#include <paths.h>
29
 
#include <sys/param.h>
30
 
#include <sys/mount.h>
31
 
#endif /* HAVE_GETMNTINFO */
32
 
#include <string.h>
33
 
#include <sys/stat.h>
34
 
 
35
 
#include "ext2_fs.h"
36
 
#include "ext2fs.h"
37
 
 
38
 
#ifdef HAVE_MNTENT_H
39
 
/*
40
 
 * Helper function which checks a file in /etc/mtab format to see if a
41
 
 * filesystem is mounted.  Returns an error if the file doesn't exist
42
 
 * or can't be opened.
43
 
 */
44
 
static errcode_t check_mntent_file(const char *mtab_file, const char *file,
45
 
                                   int *mount_flags, char *mtpt, int mtlen)
46
 
{
47
 
        struct mntent   *mnt;
48
 
        struct stat     st_buf;
49
 
        errcode_t       retval = 0;
50
 
        dev_t           file_dev=0, file_rdev=0;
51
 
        ino_t           file_ino=0;
52
 
        FILE            *f;
53
 
        int             fd;
54
 
 
55
 
        *mount_flags = 0;
56
 
        if ((f = setmntent (mtab_file, "r")) == NULL)
57
 
                return (errno == ENOENT ? EXT2_NO_MTAB_FILE : errno);
58
 
        if (stat(file, &st_buf) == 0) {
59
 
                if (S_ISBLK(st_buf.st_mode)) {
60
 
#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
61
 
                        file_rdev = st_buf.st_rdev;
62
 
#endif  /* __GNU__ */
63
 
                } else {
64
 
                        file_dev = st_buf.st_dev;
65
 
                        file_ino = st_buf.st_ino;
66
 
                }
67
 
        }
68
 
        while ((mnt = getmntent (f)) != NULL) {
69
 
                if (mnt->mnt_fsname[0] != '/')
70
 
                        continue;
71
 
                if (strcmp(file, mnt->mnt_fsname) == 0)
72
 
                        break;
73
 
                if (stat(mnt->mnt_fsname, &st_buf) == 0) {
74
 
                        if (S_ISBLK(st_buf.st_mode)) {
75
 
#ifndef __GNU__
76
 
                                if (file_rdev && (file_rdev == st_buf.st_rdev))
77
 
                                        break;
78
 
#endif  /* __GNU__ */
79
 
                        } else {
80
 
                                if (file_dev && ((file_dev == st_buf.st_dev) &&
81
 
                                                 (file_ino == st_buf.st_ino)))
82
 
                                        break;
83
 
                        }
84
 
                }
85
 
        }
86
 
 
87
 
        if (mnt == 0) {
88
 
#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
89
 
                /*
90
 
                 * Do an extra check to see if this is the root device.  We
91
 
                 * can't trust /etc/mtab, and /proc/mounts will only list
92
 
                 * /dev/root for the root filesystem.  Argh.  Instead we
93
 
                 * check if the given device has the same major/minor number
94
 
                 * as the device that the root directory is on.
95
 
                 */
96
 
                if (file_rdev && stat("/", &st_buf) == 0) {
97
 
                        if (st_buf.st_dev == file_rdev) {
98
 
                                *mount_flags = EXT2_MF_MOUNTED;
99
 
                                if (mtpt)
100
 
                                        strncpy(mtpt, "/", mtlen);
101
 
                                goto is_root;
102
 
                        }
103
 
                }
104
 
#endif  /* __GNU__ */
105
 
                goto errout;
106
 
        }
107
 
#ifndef __GNU__ /* The GNU hurd is deficient; what else is new? */
108
 
        /* Validate the entry in case /etc/mtab is out of date */
109
 
        /*
110
 
         * We need to be paranoid, because some broken distributions
111
 
         * (read: Slackware) don't initialize /etc/mtab before checking
112
 
         * all of the non-root filesystems on the disk.
113
 
         */
114
 
        if (stat(mnt->mnt_dir, &st_buf) < 0) {
115
 
                retval = errno;
116
 
                if (retval == ENOENT) {
117
 
#ifdef DEBUG
118
 
                        printf("Bogus entry in %s!  (%s does not exist)\n",
119
 
                               mtab_file, mnt->mnt_dir);
120
 
#endif /* DEBUG */
121
 
                        retval = 0;
122
 
                }
123
 
                goto errout;
124
 
        }
125
 
        if (file_rdev && (st_buf.st_dev != file_rdev)) {
126
 
#ifdef DEBUG
127
 
                printf("Bogus entry in %s!  (%s not mounted on %s)\n",
128
 
                       mtab_file, file, mnt->mnt_dir);
129
 
#endif /* DEBUG */
130
 
                goto errout;
131
 
        }
132
 
#endif /* __GNU__ */
133
 
        *mount_flags = EXT2_MF_MOUNTED;
134
 
 
135
 
#ifdef MNTOPT_RO
136
 
        /* Check to see if the ro option is set */
137
 
        if (hasmntopt(mnt, MNTOPT_RO))
138
 
                *mount_flags |= EXT2_MF_READONLY;
139
 
#endif
140
 
 
141
 
        if (mtpt)
142
 
                strncpy(mtpt, mnt->mnt_dir, mtlen);
143
 
        /*
144
 
         * Check to see if we're referring to the root filesystem.
145
 
         * If so, do a manual check to see if we can open /etc/mtab
146
 
         * read/write, since if the root is mounted read/only, the
147
 
         * contents of /etc/mtab may not be accurate.
148
 
         */
149
 
        if (!strcmp(mnt->mnt_dir, "/")) {
150
 
is_root:
151
 
#define TEST_FILE "/.ismount-test-file"
152
 
                *mount_flags |= EXT2_MF_ISROOT;
153
 
                fd = open(TEST_FILE, O_RDWR|O_CREAT, 0600);
154
 
                if (fd < 0) {
155
 
                        if (errno == EROFS)
156
 
                                *mount_flags |= EXT2_MF_READONLY;
157
 
                } else
158
 
                        close(fd);
159
 
                (void) unlink(TEST_FILE);
160
 
        }
161
 
        retval = 0;
162
 
errout:
163
 
        endmntent (f);
164
 
        return retval;
165
 
}
166
 
 
167
 
static errcode_t check_mntent(const char *file, int *mount_flags,
168
 
                              char *mtpt, int mtlen)
169
 
{
170
 
        errcode_t       retval;
171
 
 
172
 
#ifdef DEBUG
173
 
        retval = check_mntent_file("/tmp/mtab", file, mount_flags,
174
 
                                   mtpt, mtlen);
175
 
        if (retval == 0)
176
 
                return 0;
177
 
#endif /* DEBUG */
178
 
#ifdef __linux__
179
 
        retval = check_mntent_file("/proc/mounts", file, mount_flags,
180
 
                                   mtpt, mtlen);
181
 
        if (retval == 0 && (*mount_flags != 0))
182
 
                return 0;
183
 
#endif /* __linux__ */
184
 
#if defined(MOUNTED) || defined(_PATH_MOUNTED)
185
 
#ifndef MOUNTED
186
 
#define MOUNTED _PATH_MOUNTED
187
 
#endif /* MOUNTED */
188
 
        retval = check_mntent_file(MOUNTED, file, mount_flags, mtpt, mtlen);
189
 
        return retval;
190
 
#else
191
 
        *mount_flags = 0;
192
 
        return 0;
193
 
#endif /* defined(MOUNTED) || defined(_PATH_MOUNTED) */
194
 
}
195
 
 
196
 
#else
197
 
#if defined(HAVE_GETMNTINFO)
198
 
 
199
 
static errcode_t check_getmntinfo(const char *file, int *mount_flags,
200
 
                                  char *mtpt, int mtlen)
201
 
{
202
 
        struct statfs *mp;
203
 
        int    len, n;
204
 
        const  char   *s1;
205
 
        char    *s2;
206
 
 
207
 
        n = getmntinfo(&mp, MNT_NOWAIT);
208
 
        if (n == 0)
209
 
                return errno;
210
 
 
211
 
        len = sizeof(_PATH_DEV) - 1;
212
 
        s1 = file;
213
 
        if (strncmp(_PATH_DEV, s1, len) == 0)
214
 
                s1 += len;
215
 
 
216
 
        *mount_flags = 0;
217
 
        while (--n >= 0) {
218
 
                s2 = mp->f_mntfromname;
219
 
                if (strncmp(_PATH_DEV, s2, len) == 0) {
220
 
                        s2 += len - 1;
221
 
                        *s2 = 'r';
222
 
                }
223
 
                if (strcmp(s1, s2) == 0 || strcmp(s1, &s2[1]) == 0) {
224
 
                        *mount_flags = EXT2_MF_MOUNTED;
225
 
                        break;
226
 
                }
227
 
                ++mp;
228
 
        }
229
 
        if (mtpt)
230
 
                strncpy(mtpt, mp->f_mntonname, mtlen);
231
 
        return 0;
232
 
}
233
 
#endif /* HAVE_GETMNTINFO */
234
 
#endif /* HAVE_MNTENT_H */
235
 
 
236
 
/*
237
 
 * Check to see if we're dealing with the swap device.
238
 
 */
239
 
static int is_swap_device(const char *file)
240
 
{
241
 
        FILE            *f;
242
 
        char            buf[1024], *cp;
243
 
        dev_t           file_dev;
244
 
        struct stat     st_buf;
245
 
        int             ret = 0;
246
 
 
247
 
        file_dev = 0;
248
 
#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
249
 
        if ((stat(file, &st_buf) == 0) &&
250
 
            S_ISBLK(st_buf.st_mode))
251
 
                file_dev = st_buf.st_rdev;
252
 
#endif  /* __GNU__ */
253
 
 
254
 
        if (!(f = fopen("/proc/swaps", "r")))
255
 
                return 0;
256
 
        /* Skip the first line */
257
 
        if (!fgets(buf, sizeof(buf), f))
258
 
                goto leave;
259
 
        if (*buf && strncmp(buf, "Filename\t", 9))
260
 
                /* Linux <=2.6.19 contained a bug in the /proc/swaps
261
 
                 * code where the header would not be displayed
262
 
                 */
263
 
                goto valid_first_line;
264
 
 
265
 
        while (fgets(buf, sizeof(buf), f)) {
266
 
valid_first_line:
267
 
                if ((cp = strchr(buf, ' ')) != NULL)
268
 
                        *cp = 0;
269
 
                if ((cp = strchr(buf, '\t')) != NULL)
270
 
                        *cp = 0;
271
 
                if (strcmp(buf, file) == 0) {
272
 
                        ret++;
273
 
                        break;
274
 
                }
275
 
#ifndef __GNU__
276
 
                if (file_dev && (stat(buf, &st_buf) == 0) &&
277
 
                    S_ISBLK(st_buf.st_mode) &&
278
 
                    file_dev == st_buf.st_rdev) {
279
 
                        ret++;
280
 
                        break;
281
 
                }
282
 
#endif  /* __GNU__ */
283
 
        }
284
 
 
285
 
leave:
286
 
        fclose(f);
287
 
        return ret;
288
 
}
289
 
 
290
 
 
291
 
/*
292
 
 * ext2fs_check_mount_point() fills determines if the device is
293
 
 * mounted or otherwise busy, and fills in mount_flags with one or
294
 
 * more of the following flags: EXT2_MF_MOUNTED, EXT2_MF_ISROOT,
295
 
 * EXT2_MF_READONLY, EXT2_MF_SWAP, and EXT2_MF_BUSY.  If mtpt is
296
 
 * non-NULL, the directory where the device is mounted is copied to
297
 
 * where mtpt is pointing, up to mtlen characters.
298
 
 */
299
 
#ifdef __TURBOC__
300
 
 #pragma argsused
301
 
#endif
302
 
errcode_t ext2fs_check_mount_point(const char *device, int *mount_flags,
303
 
                                  char *mtpt, int mtlen)
304
 
{
305
 
        struct stat     st_buf;
306
 
        errcode_t       retval = 0;
307
 
        int             fd;
308
 
 
309
 
        if (is_swap_device(device)) {
310
 
                *mount_flags = EXT2_MF_MOUNTED | EXT2_MF_SWAP;
311
 
                strncpy(mtpt, "<swap>", mtlen);
312
 
        } else {
313
 
#ifdef HAVE_MNTENT_H
314
 
                retval = check_mntent(device, mount_flags, mtpt, mtlen);
315
 
#else
316
 
#ifdef HAVE_GETMNTINFO
317
 
                retval = check_getmntinfo(device, mount_flags, mtpt, mtlen);
318
 
#else
319
 
#ifdef __GNUC__
320
 
 #warning "Can't use getmntent or getmntinfo to check for mounted filesystems!"
321
 
#endif
322
 
                *mount_flags = 0;
323
 
#endif /* HAVE_GETMNTINFO */
324
 
#endif /* HAVE_MNTENT_H */
325
 
        }
326
 
        if (retval)
327
 
                return retval;
328
 
 
329
 
#ifdef __linux__ /* This only works on Linux 2.6+ systems */
330
 
        if ((stat(device, &st_buf) != 0) ||
331
 
            !S_ISBLK(st_buf.st_mode))
332
 
                return 0;
333
 
        fd = open(device, O_RDONLY | O_EXCL);
334
 
        if (fd < 0) {
335
 
                if (errno == EBUSY)
336
 
                        *mount_flags |= EXT2_MF_BUSY;
337
 
        } else
338
 
                close(fd);
339
 
#endif
340
 
 
341
 
        return 0;
342
 
}
343
 
 
344
 
/*
345
 
 * ext2fs_check_if_mounted() sets the mount_flags EXT2_MF_MOUNTED,
346
 
 * EXT2_MF_READONLY, and EXT2_MF_ROOT
347
 
 *
348
 
 */
349
 
errcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags)
350
 
{
351
 
        return ext2fs_check_mount_point(file, mount_flags, NULL, 0);
352
 
}
353
 
 
354
 
#ifdef DEBUG
355
 
int main(int argc, char **argv)
356
 
{
357
 
        int     retval, mount_flags;
358
 
        char    mntpt[80];
359
 
 
360
 
        if (argc < 2) {
361
 
                fprintf(stderr, "Usage: %s device\n", argv[0]);
362
 
                exit(1);
363
 
        }
364
 
 
365
 
        add_error_table(&et_ext2_error_table);
366
 
        mntpt[0] = 0;
367
 
        retval = ext2fs_check_mount_point(argv[1], &mount_flags,
368
 
                                          mntpt, sizeof(mntpt));
369
 
        if (retval) {
370
 
                com_err(argv[0], retval,
371
 
                        "while calling ext2fs_check_if_mounted");
372
 
                exit(1);
373
 
        }
374
 
        printf("Device %s reports flags %02x\n", argv[1], mount_flags);
375
 
        if (mount_flags & EXT2_MF_BUSY)
376
 
                printf("\t%s is apparently in use.\n", argv[1]);
377
 
        if (mount_flags & EXT2_MF_MOUNTED)
378
 
                printf("\t%s is mounted.\n", argv[1]);
379
 
        if (mount_flags & EXT2_MF_SWAP)
380
 
                printf("\t%s is a swap device.\n", argv[1]);
381
 
        if (mount_flags & EXT2_MF_READONLY)
382
 
                printf("\t%s is read-only.\n", argv[1]);
383
 
        if (mount_flags & EXT2_MF_ISROOT)
384
 
                printf("\t%s is the root filesystem.\n", argv[1]);
385
 
        if (mntpt[0])
386
 
                printf("\t%s is mounted on %s.\n", argv[1], mntpt);
387
 
        exit(0);
388
 
}
389
 
#endif /* DEBUG */