119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * ismounted.c --- Check to see if the filesystem was mounted 33984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (C) 1995,1996,1997,1998,1999,2000 Theodore Ts'o. 519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %Begin-Header% 78558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * This file may be redistributed under the terms of the GNU Library 88558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * General Public License, version 2. 919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %End-Header% 1019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 1119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdio.h> 1319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if HAVE_UNISTD_H 1419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <unistd.h> 1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 1619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if HAVE_ERRNO_H 1719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <errno.h> 1819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 1919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <fcntl.h> 2019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_LINUX_FD_H 2119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <linux/fd.h> 2219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 2319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_MNTENT_H 2419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <mntent.h> 2519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 2619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_GETMNTINFO 2719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <paths.h> 2819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/param.h> 2919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/mount.h> 3019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* HAVE_GETMNTINFO */ 3119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <string.h> 3219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/stat.h> 3319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 3419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "ext2_fs.h" 3519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "ext2fs.h" 3619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 3719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_MNTENT_H 3819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 3919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Helper function which checks a file in /etc/mtab format to see if a 4019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * filesystem is mounted. Returns an error if the file doesn't exist 413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * or can't be opened. 4219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic errcode_t check_mntent_file(const char *mtab_file, const char *file, 4419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int *mount_flags, char *mtpt, int mtlen) 4519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 4619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct mntent *mnt; 4719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct stat st_buf; 4819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t retval = 0; 4919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dev_t file_dev=0, file_rdev=0; 5019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ino_t file_ino=0; 5119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project FILE *f; 5219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int fd; 5319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 5419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *mount_flags = 0; 5519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((f = setmntent (mtab_file, "r")) == NULL) 563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return (errno == ENOENT ? EXT2_NO_MTAB_FILE : errno); 5719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (stat(file, &st_buf) == 0) { 5819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (S_ISBLK(st_buf.st_mode)) { 5919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */ 6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project file_rdev = st_buf.st_rdev; 6119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* __GNU__ */ 6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else { 6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project file_dev = st_buf.st_dev; 6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project file_ino = st_buf.st_ino; 6519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 6719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while ((mnt = getmntent (f)) != NULL) { 683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (mnt->mnt_fsname[0] != '/') 693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt continue; 7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (strcmp(file, mnt->mnt_fsname) == 0) 7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 7219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (stat(mnt->mnt_fsname, &st_buf) == 0) { 7319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (S_ISBLK(st_buf.st_mode)) { 7419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifndef __GNU__ 7519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (file_rdev && (file_rdev == st_buf.st_rdev)) 7619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* __GNU__ */ 7819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else { 7919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (file_dev && ((file_dev == st_buf.st_dev) && 8019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (file_ino == st_buf.st_ino))) 8119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 8219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 8319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 8419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 8519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 8619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (mnt == 0) { 8719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */ 8819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 8919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Do an extra check to see if this is the root device. We 9019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * can't trust /etc/mtab, and /proc/mounts will only list 9119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * /dev/root for the root filesystem. Argh. Instead we 9219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * check if the given device has the same major/minor number 9319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * as the device that the root directory is on. 9419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 9519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (file_rdev && stat("/", &st_buf) == 0) { 9619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (st_buf.st_dev == file_rdev) { 9719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *mount_flags = EXT2_MF_MOUNTED; 9819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (mtpt) 9919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project strncpy(mtpt, "/", mtlen); 10019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto is_root; 10119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 10219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 10319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* __GNU__ */ 10419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto errout; 10519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 10619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifndef __GNU__ /* The GNU hurd is deficient; what else is new? */ 10719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* Validate the entry in case /etc/mtab is out of date */ 1083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* 10919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * We need to be paranoid, because some broken distributions 11019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * (read: Slackware) don't initialize /etc/mtab before checking 11119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * all of the non-root filesystems on the disk. 11219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 11319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (stat(mnt->mnt_dir, &st_buf) < 0) { 11419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = errno; 11519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval == ENOENT) { 11619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef DEBUG 11719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("Bogus entry in %s! (%s does not exist)\n", 11819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project mtab_file, mnt->mnt_dir); 11919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* DEBUG */ 12019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = 0; 12119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 12219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto errout; 12319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 12419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (file_rdev && (st_buf.st_dev != file_rdev)) { 12519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef DEBUG 12619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("Bogus entry in %s! (%s not mounted on %s)\n", 12719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project mtab_file, file, mnt->mnt_dir); 12819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* DEBUG */ 12919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto errout; 13019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 13119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* __GNU__ */ 13219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *mount_flags = EXT2_MF_MOUNTED; 1333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 13419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef MNTOPT_RO 13519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* Check to see if the ro option is set */ 13619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (hasmntopt(mnt, MNTOPT_RO)) 13719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *mount_flags |= EXT2_MF_READONLY; 13819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 13919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 14019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (mtpt) 14119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project strncpy(mtpt, mnt->mnt_dir, mtlen); 14219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 14319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Check to see if we're referring to the root filesystem. 14419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If so, do a manual check to see if we can open /etc/mtab 14519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * read/write, since if the root is mounted read/only, the 14619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * contents of /etc/mtab may not be accurate. 14719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 14819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!strcmp(mnt->mnt_dir, "/")) { 14919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectis_root: 1503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#define TEST_FILE "/.ismount-test-file" 15119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *mount_flags |= EXT2_MF_ISROOT; 15219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fd = open(TEST_FILE, O_RDWR|O_CREAT, 0600); 15319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fd < 0) { 15419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (errno == EROFS) 15519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *mount_flags |= EXT2_MF_READONLY; 15619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else 15719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project close(fd); 15819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (void) unlink(TEST_FILE); 15919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 16019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = 0; 16119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projecterrout: 16219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project endmntent (f); 16319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 16419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 16519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 16619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t check_mntent(const char *file, int *mount_flags, 16719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *mtpt, int mtlen) 16819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 16919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t retval; 17019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 17119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef DEBUG 17219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = check_mntent_file("/tmp/mtab", file, mount_flags, 17319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project mtpt, mtlen); 17419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval == 0) 17519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 17619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* DEBUG */ 17719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef __linux__ 17819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = check_mntent_file("/proc/mounts", file, mount_flags, 17919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project mtpt, mtlen); 18019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval == 0 && (*mount_flags != 0)) 18119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 18219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* __linux__ */ 18319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if defined(MOUNTED) || defined(_PATH_MOUNTED) 18419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifndef MOUNTED 18519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define MOUNTED _PATH_MOUNTED 18619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* MOUNTED */ 18719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = check_mntent_file(MOUNTED, file, mount_flags, mtpt, mtlen); 18819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 1893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#else 19019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *mount_flags = 0; 19119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 19219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* defined(MOUNTED) || defined(_PATH_MOUNTED) */ 19319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 19419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 19519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#else 19619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if defined(HAVE_GETMNTINFO) 19719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 19819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t check_getmntinfo(const char *file, int *mount_flags, 19919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *mtpt, int mtlen) 20019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 20119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct statfs *mp; 20219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int len, n; 20319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project const char *s1; 20419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *s2; 20519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 20619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project n = getmntinfo(&mp, MNT_NOWAIT); 20719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (n == 0) 20819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return errno; 20919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 21019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project len = sizeof(_PATH_DEV) - 1; 21119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project s1 = file; 21219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (strncmp(_PATH_DEV, s1, len) == 0) 21319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project s1 += len; 2143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 21519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *mount_flags = 0; 21619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while (--n >= 0) { 21719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project s2 = mp->f_mntfromname; 21819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (strncmp(_PATH_DEV, s2, len) == 0) { 21919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project s2 += len - 1; 22019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *s2 = 'r'; 22119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 22219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (strcmp(s1, s2) == 0 || strcmp(s1, &s2[1]) == 0) { 22319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *mount_flags = EXT2_MF_MOUNTED; 22419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 22519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 22619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ++mp; 22719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 22819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (mtpt) 22919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project strncpy(mtpt, mp->f_mntonname, mtlen); 23019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 23119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 23219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* HAVE_GETMNTINFO */ 23319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* HAVE_MNTENT_H */ 23419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 23519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 23619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Check to see if we're dealing with the swap device. 23719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 23819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int is_swap_device(const char *file) 23919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 24019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project FILE *f; 24119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char buf[1024], *cp; 24219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dev_t file_dev; 24319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct stat st_buf; 24419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int ret = 0; 24519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 24619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project file_dev = 0; 24719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */ 24819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((stat(file, &st_buf) == 0) && 24919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project S_ISBLK(st_buf.st_mode)) 25019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project file_dev = st_buf.st_rdev; 25119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* __GNU__ */ 25219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 25319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!(f = fopen("/proc/swaps", "r"))) 25419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 25519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* Skip the first line */ 2563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!fgets(buf, sizeof(buf), f)) 2573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto leave; 2583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (*buf && strncmp(buf, "Filename\t", 9)) 2593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* Linux <=2.6.19 contained a bug in the /proc/swaps 2603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * code where the header would not be displayed 2613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */ 2623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto valid_first_line; 2633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt while (fgets(buf, sizeof(buf), f)) { 2653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvalid_first_line: 26619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((cp = strchr(buf, ' ')) != NULL) 26719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *cp = 0; 26819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((cp = strchr(buf, '\t')) != NULL) 26919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *cp = 0; 27019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (strcmp(buf, file) == 0) { 27119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ret++; 27219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 27319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 27419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifndef __GNU__ 27519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (file_dev && (stat(buf, &st_buf) == 0) && 27619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project S_ISBLK(st_buf.st_mode) && 27719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project file_dev == st_buf.st_rdev) { 27819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ret++; 27919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 28019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 28119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* __GNU__ */ 28219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 2833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtleave: 28519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fclose(f); 28619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return ret; 28719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 28819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 28919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 29019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 29119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * ext2fs_check_mount_point() fills determines if the device is 29219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * mounted or otherwise busy, and fills in mount_flags with one or 29319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * more of the following flags: EXT2_MF_MOUNTED, EXT2_MF_ISROOT, 29419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * EXT2_MF_READONLY, EXT2_MF_SWAP, and EXT2_MF_BUSY. If mtpt is 29519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * non-NULL, the directory where the device is mounted is copied to 29619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * where mtpt is pointing, up to mtlen characters. 29719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 29819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef __TURBOC__ 29919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project #pragma argsused 30019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 30119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projecterrcode_t ext2fs_check_mount_point(const char *device, int *mount_flags, 30219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *mtpt, int mtlen) 30319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 30419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct stat st_buf; 30519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t retval = 0; 30619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int fd; 30719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 30819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (is_swap_device(device)) { 30919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *mount_flags = EXT2_MF_MOUNTED | EXT2_MF_SWAP; 31019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project strncpy(mtpt, "<swap>", mtlen); 31119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else { 31219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_MNTENT_H 31319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = check_mntent(device, mount_flags, mtpt, mtlen); 3143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#else 31519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_GETMNTINFO 31619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = check_getmntinfo(device, mount_flags, mtpt, mtlen); 31719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#else 31819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef __GNUC__ 31919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project #warning "Can't use getmntent or getmntinfo to check for mounted filesystems!" 32019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 32119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *mount_flags = 0; 32219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* HAVE_GETMNTINFO */ 32319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* HAVE_MNTENT_H */ 32419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 32519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 32619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 32719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 32819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef __linux__ /* This only works on Linux 2.6+ systems */ 32919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((stat(device, &st_buf) != 0) || 33019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project !S_ISBLK(st_buf.st_mode)) 33119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 33219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fd = open(device, O_RDONLY | O_EXCL); 33319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fd < 0) { 33419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (errno == EBUSY) 33519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *mount_flags |= EXT2_MF_BUSY; 33619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else 33719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project close(fd); 33819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 33919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 34019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 34119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 34219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 34319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 34419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * ext2fs_check_if_mounted() sets the mount_flags EXT2_MF_MOUNTED, 34519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * EXT2_MF_READONLY, and EXT2_MF_ROOT 3463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 34719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 34819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projecterrcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags) 34919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 35019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return ext2fs_check_mount_point(file, mount_flags, NULL, 0); 35119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 35219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 35319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef DEBUG 35419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint main(int argc, char **argv) 35519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 35619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int retval, mount_flags; 35719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char mntpt[80]; 3583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 35919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (argc < 2) { 36019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fprintf(stderr, "Usage: %s device\n", argv[0]); 36119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(1); 36219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 36319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 3643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt add_error_table(&et_ext2_error_table); 36519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project mntpt[0] = 0; 36619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_check_mount_point(argv[1], &mount_flags, 36719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project mntpt, sizeof(mntpt)); 36819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) { 36919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err(argv[0], retval, 37019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project "while calling ext2fs_check_if_mounted"); 37119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(1); 37219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 37319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("Device %s reports flags %02x\n", argv[1], mount_flags); 37419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (mount_flags & EXT2_MF_BUSY) 37519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("\t%s is apparently in use.\n", argv[1]); 37619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (mount_flags & EXT2_MF_MOUNTED) 37719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("\t%s is mounted.\n", argv[1]); 37819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (mount_flags & EXT2_MF_SWAP) 37919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("\t%s is a swap device.\n", argv[1]); 38019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (mount_flags & EXT2_MF_READONLY) 38119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("\t%s is read-only.\n", argv[1]); 38219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (mount_flags & EXT2_MF_ISROOT) 38319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("\t%s is the root filesystem.\n", argv[1]); 38419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (mntpt[0]) 38519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("\t%s is mounted on %s.\n", argv[1], mntpt); 38619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(0); 38719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 38819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* DEBUG */ 389