mountpoint.c revision 2dc6cf8bad599bfe9129bb496539a08ee3631cc0
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2006 Timo Sirainen */
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen#include "lib.h"
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen#include "mountpoint.h"
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen#include <sys/stat.h>
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen#ifdef HAVE_STATVFS_MNTFROMNAME
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen# include <sys/statvfs.h> /* NetBSD 3.0+, FreeBSD 5.0+ */
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen# define STATVFS_STR "statvfs"
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen#elif defined(HAVE_STATFS_MNTFROMNAME)
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen# include <sys/param.h> /* Older BSDs */
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen# include <sys/mount.h>
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen# define statvfs statfs
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen# define STATVFS_STR "statfs"
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen#elif defined(HAVE_MNTENT_H)
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen# include <stdio.h>
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen# include <mntent.h> /* Linux */
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen#elif defined(HAVE_SYS_MNTTAB_H)
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen# include <stdio.h>
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen# include <sys/mnttab.h> /* Solaris */
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen#else
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen# define MOUNTPOINT_UNKNOWN
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen#endif
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen#ifdef HAVE_SYS_MNTTAB_H
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen# define MTAB_PATH MNTTAB /* Solaris */
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen#else
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen# define MTAB_PATH "/etc/mtab" /* Linux */
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen#endif
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen/* AIX doesn't have these defined */
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen#ifndef MNTTYPE_SWAP
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen# define MNTTYPE_SWAP "swap"
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen#endif
79fcd3f95a6266cc62ceaa753e56dd4456ab7c4bTimo Sirainen#ifndef MNTTYPE_IGNORE
3ddbbe03fe74b3ee7b1dff4e08ec706d7880d052Timo Sirainen# define MNTTYPE_IGNORE "ignore"
3ddbbe03fe74b3ee7b1dff4e08ec706d7880d052Timo Sirainen#endif
3ddbbe03fe74b3ee7b1dff4e08ec706d7880d052Timo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen/* autofs mounts will show two entries. First for autofs and second for the
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen actual filesystem type. We want the second one. */
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen#ifndef MNTTYPE_AUTOFS
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen# define MNTTYPE_AUTOFS "autofs"
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen#endif
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainenint mountpoint_get(const char *path, pool_t pool, struct mountpoint *point_r)
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen{
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen#ifdef MOUNTPOINT_UNKNOWN
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen memset(point_r, 0, sizeof(*point_r));
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen errno = ENOSYS;
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen return -1;
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen#elif defined (HAVE_STATFS_MNTFROMNAME) || defined(HAVE_STATVFS_MNTFROMNAME)
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen /* BSDs */
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen struct statvfs buf;
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen
f339a8e73beea7684ea634941ea82593dea522eeTimo Sirainen memset(point_r, 0, sizeof(*point_r));
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen if (statvfs(path, &buf) < 0) {
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen if (errno == ENOENT)
905627a760ce8bf4141b361f72858a99975ded3cTimo Sirainen return 0;
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen i_error(STATVFS_STR"(%s) failed: %m", path);
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen return -1;
defeb23b40f1c1af0535a84529383825e5ef8dfeTimo Sirainen }
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen point_r->device_path = p_strdup(pool, buf.f_mntfromname);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen point_r->mount_path = p_strdup(pool, buf.f_mntonname);
905627a760ce8bf4141b361f72858a99975ded3cTimo Sirainen#ifdef __osf__ /* Tru64 */
905627a760ce8bf4141b361f72858a99975ded3cTimo Sirainen point_r->type = p_strdup(pool, getvfsbynumber(buf.f_type));
905627a760ce8bf4141b361f72858a99975ded3cTimo Sirainen#else
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen point_r->type = p_strdup(pool, buf.f_fstypename);
905627a760ce8bf4141b361f72858a99975ded3cTimo Sirainen#endif
905627a760ce8bf4141b361f72858a99975ded3cTimo Sirainen point_r->block_size = buf.f_bsize;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen return 1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen#else
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen /* Linux, Solaris: /etc/mtab reading */
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen#ifdef HAVE_SYS_MNTTAB_H
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen struct mnttab ent;
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen#else
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen struct mntent *ent;
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen#endif
cddfd1355db6b60c71d7ee3c0b4f23b3efcc9ad1Timo Sirainen struct stat st, st2;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen const char *device_path = NULL, *mount_path = NULL, *type = NULL;
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen unsigned int block_size;
a342a31752dd71ac444259ca57ad33ea6b79a572Timo Sirainen FILE *f;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen memset(point_r, 0, sizeof(*point_r));
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen if (stat(path, &st) < 0) {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (errno == ENOENT)
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainen return 0;
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen i_error("stat(%s) failed: %m", path);
704a96fa677763eef7ae62466e14e83a2f535427Timo Sirainen return -1;
f32c6ed9db6f4c535f97a2020401572efc8abf86Timo Sirainen }
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen block_size = st.st_blksize;
289bd999f282a307b05e6f8beef33155a50fb837Timo Sirainen
289bd999f282a307b05e6f8beef33155a50fb837Timo Sirainen#ifdef HAVE_SYS_MNTTAB_H
289bd999f282a307b05e6f8beef33155a50fb837Timo Sirainen /* Solaris */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen f = fopen(MTAB_PATH, "r");
704a96fa677763eef7ae62466e14e83a2f535427Timo Sirainen if (f == NULL) {
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen i_error("fopen(%s) failed: %m", MTAB_PATH);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen return -1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen }
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen while ((getmntent(f, &ent)) == 0) {
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen if (strcmp(ent.mnt_fstype, MNTTYPE_SWAP) == 0 ||
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen strcmp(ent.mnt_fstype, MNTTYPE_AUTOFS) == 0 ||
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen strcmp(ent.mnt_fstype, MNTTYPE_IGNORE) == 0)
67c25cb4af273aff7384d5028d459cc9afdf8712Timo Sirainen continue;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen if (stat(ent.mnt_mountp, &st2) == 0 &&
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen CMP_DEV_T(st.st_dev, st2.st_dev)) {
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen device_path = ent.mnt_special;
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen mount_path = ent.mnt_mountp;
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen type = ent.mnt_fstype;
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen break;
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen }
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen }
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen fclose(f);
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen#else
2cfe9983ce7a6280636ee12beccc2e865111967bTimo Sirainen /* Linux */
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen f = setmntent(MTAB_PATH, "r");
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen if (f == NULL) {
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen i_error("setmntent(%s) failed: %m", MTAB_PATH);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return -1;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen }
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen while ((ent = getmntent(f)) != NULL) {
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen if (strcmp(ent->mnt_type, MNTTYPE_SWAP) == 0 ||
cddfd1355db6b60c71d7ee3c0b4f23b3efcc9ad1Timo Sirainen strcmp(ent->mnt_type, MNTTYPE_IGNORE) == 0)
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen continue;
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen if (stat(ent->mnt_dir, &st2) == 0 &&
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen CMP_DEV_T(st.st_dev, st2.st_dev)) {
67c25cb4af273aff7384d5028d459cc9afdf8712Timo Sirainen device_path = ent->mnt_fsname;
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen mount_path = ent->mnt_dir;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen type = ent->mnt_type;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen break;
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen }
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen }
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen endmntent(f);
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen#endif
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen if (device_path == NULL)
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen return 0;
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen point_r->device_path = p_strdup(pool, device_path);
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen point_r->mount_path = p_strdup(pool, mount_path);
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen point_r->type = p_strdup(pool, type);
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen point_r->block_size = block_size;
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen return 1;
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen#endif
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen}
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen