17 |
* Given any other file (or directory), find the mount table entry for its |
* Given any other file (or directory), find the mount table entry for its |
18 |
* filesystem. |
* filesystem. |
19 |
*/ |
*/ |
20 |
struct mntent* FAST_FUNC find_mount_point(const char *name, const char *table) |
struct mntent* FAST_FUNC find_mount_point(const char *name, int subdir_too) |
21 |
{ |
{ |
22 |
struct stat s; |
struct stat s; |
23 |
dev_t mountDevice; |
FILE *mtab_fp; |
|
FILE *mountTable; |
|
24 |
struct mntent *mountEntry; |
struct mntent *mountEntry; |
25 |
|
dev_t devno_of_name; |
26 |
|
bool block_dev; |
27 |
|
|
28 |
if (stat(name, &s) != 0) |
if (stat(name, &s) != 0) |
29 |
return 0; |
return NULL; |
30 |
|
|
31 |
if ((s.st_mode & S_IFMT) == S_IFBLK) |
devno_of_name = s.st_dev; |
32 |
mountDevice = s.st_rdev; |
block_dev = 0; |
33 |
else |
if (S_ISBLK(s.st_mode)) { |
34 |
mountDevice = s.st_dev; |
devno_of_name = s.st_rdev; |
35 |
|
block_dev = 1; |
36 |
|
} |
37 |
|
|
38 |
|
mtab_fp = setmntent(bb_path_mtab_file, "r"); |
39 |
|
if (!mtab_fp) |
40 |
|
return NULL; |
41 |
|
|
42 |
mountTable = setmntent(table ? table : bb_path_mtab_file, "r"); |
while ((mountEntry = getmntent(mtab_fp)) != NULL) { |
43 |
if (!mountTable) |
/* rootfs mount in Linux 2.6 exists always, |
44 |
return 0; |
* and it makes sense to always ignore it. |
45 |
|
* Otherwise people can't reference their "real" root! */ |
46 |
|
if (strcmp(mountEntry->mnt_fsname, "rootfs") == 0) |
47 |
|
continue; |
48 |
|
|
|
while ((mountEntry = getmntent(mountTable)) != 0) { |
|
49 |
if (strcmp(name, mountEntry->mnt_dir) == 0 |
if (strcmp(name, mountEntry->mnt_dir) == 0 |
50 |
|| strcmp(name, mountEntry->mnt_fsname) == 0 |
|| strcmp(name, mountEntry->mnt_fsname) == 0 |
51 |
) { /* String match. */ |
) { /* String match. */ |
52 |
break; |
break; |
53 |
} |
} |
54 |
if (stat(mountEntry->mnt_fsname, &s) == 0 && s.st_rdev == mountDevice) /* Match the device. */ |
|
55 |
|
if (!(subdir_too || block_dev)) |
56 |
|
continue; |
57 |
|
|
58 |
|
/* Is device's dev_t == name's dev_t? */ |
59 |
|
if (stat(mountEntry->mnt_fsname, &s) == 0 && s.st_rdev == devno_of_name) |
60 |
break; |
break; |
61 |
if (stat(mountEntry->mnt_dir, &s) == 0 && s.st_dev == mountDevice) /* Match the directory's mount point. */ |
/* Match the directory's mount point. */ |
62 |
|
if (stat(mountEntry->mnt_dir, &s) == 0 && s.st_dev == devno_of_name) |
63 |
break; |
break; |
64 |
} |
} |
65 |
endmntent(mountTable); |
endmntent(mtab_fp); |
66 |
|
|
67 |
return mountEntry; |
return mountEntry; |
68 |
} |
} |