mountpoint.c revision ad3a1b8f8e2a5596afb1b099a69ae6f688887eec
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2006 Timo Sirainen */
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#include "mountpoint.h"
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen#include <sys/stat.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
5666a3d6a7ea89362b8d9e8b39b15424cd9d6388Timo Sirainen#ifdef HAVE_STATFS_MNTFROMNAME
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen# include <sys/param.h> /* BSDs */
146f9076cd456ea1e9b3f8536456d9d3c962fadbStephan Bosch# include <sys/mount.h>
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#elif defined(HAVE_MNTENT_H)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen# include <stdio.h>
8c909e451d14075c05d90382cf8eebc4e354f569Timo Sirainen# include <mntent.h> /* Linux */
8c909e451d14075c05d90382cf8eebc4e354f569Timo Sirainen#elif defined(HAVE_SYS_MNTTAB_H)
8c909e451d14075c05d90382cf8eebc4e354f569Timo Sirainen# include <stdio.h>
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainen# include <sys/mnttab.h> /* Solaris */
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainen#else
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainen# define MOUNTPOINT_UNKNOWN
3ed2d0f6b5e67e2663d44489d9da3176823789a8Timo Sirainen#endif
65f8fb656051f1059f7b5a2da9c5555adcc30439Timo Sirainen
1a5573ebc32fae2fe576ec544e1781323c1db609Timo Sirainen#ifdef HAVE_SYS_MNTTAB_H
1a5573ebc32fae2fe576ec544e1781323c1db609Timo Sirainen# define MTAB_PATH MNTTAB /* Solaris */
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#else
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen# define MTAB_PATH "/etc/mtab" /* Linux */
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#endif
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen/* AIX doesn't have these defined */
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#ifndef MNTTYPE_SWAP
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen# define MNTTYPE_SWAP "swap"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#endif
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen#ifndef MNTTYPE_IGNORE
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen# define MNTTYPE_IGNORE "ignore"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#endif
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenint mountpoint_get(const char *path, pool_t pool, struct mountpoint *point_r)
2dd39e478269d6fb0bb26d12b394aa30ee965e38Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#ifdef MOUNTPOINT_UNKNOWN
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen memset(point_r, 0, sizeof(*point_r));
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen errno = ENOSYS;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen#elif defined (HAVE_STATFS_MNTFROMNAME)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen /* BSDs */
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen struct statfs buf;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen memset(point_r, 0, sizeof(*point_r));
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen if (statfs(path, &buf) < 0) {
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen i_error("statfs(%s) failed: %m", path);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen return -1;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen }
3e564425db51f3921ce4de11859777135fdedd15Timo Sirainen
857c471c13ca215f4be9dd4b336b742b8d434e31Timo Sirainen point_r->device_path = p_strdup(pool, buf.f_mntfromname);
857c471c13ca215f4be9dd4b336b742b8d434e31Timo Sirainen point_r->mount_path = p_strdup(pool, buf.f_mntonname);
857c471c13ca215f4be9dd4b336b742b8d434e31Timo Sirainen point_r->type = p_strdup(pool, buf.f_fstypename);
857c471c13ca215f4be9dd4b336b742b8d434e31Timo Sirainen point_r->block_size = buf.f_bsize;
857c471c13ca215f4be9dd4b336b742b8d434e31Timo Sirainen return 1;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen#else
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen /* Linux, Solaris: /etc/mtab reading */
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#ifdef HAVE_SYS_MNTTAB_H
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct mnttab ent;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#else
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct mntent *ent;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#endif
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen struct stat st, st2;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen const char *device_path = NULL, *mount_path = NULL, *type = NULL;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen unsigned int block_size;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen FILE *f;
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen memset(point_r, 0, sizeof(*point_r));
4ba9a1d3facc515b3feb5238a16bcf91f76fac61Timo Sirainen if (stat(path, &st) < 0) {
4ba9a1d3facc515b3feb5238a16bcf91f76fac61Timo Sirainen i_error("stat(%s) failed: %m", path);
dfaefeabae939803ceb8c503101e86b5496541d1Timo Sirainen return -1;
dfaefeabae939803ceb8c503101e86b5496541d1Timo Sirainen }
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen block_size = st.st_blksize;
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen
8b31f966d9688e07672ef1958dcbdb7686523c04Timo Sirainen#ifdef HAVE_SYS_MNTTAB_H
8b31f966d9688e07672ef1958dcbdb7686523c04Timo Sirainen /* Solaris */
9847ec56efa15fa063eea9988eee2d4ed9ec7d58Timo Sirainen f = fopen(MTAB_PATH, "r");
9847ec56efa15fa063eea9988eee2d4ed9ec7d58Timo Sirainen if (f == NULL) {
9847ec56efa15fa063eea9988eee2d4ed9ec7d58Timo Sirainen i_error("fopen(%s) failed: %m", MTAB_PATH);
d46a1e3f999dda802dc5137e883adcd7a6629cd3Timo Sirainen return -1;
d46a1e3f999dda802dc5137e883adcd7a6629cd3Timo Sirainen }
d46a1e3f999dda802dc5137e883adcd7a6629cd3Timo Sirainen while ((getmntent(f, &ent)) == 0) {
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen if (strcmp(ent.mnt_fstype, MNTTYPE_SWAP) == 0 ||
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen strcmp(ent.mnt_fstype, MNTTYPE_IGNORE) == 0)
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen continue;
291ce16fffca75e8598a8c9dceb08613413dcb07Timo Sirainen
291ce16fffca75e8598a8c9dceb08613413dcb07Timo Sirainen if (stat(ent.mnt_mountp, &st2) == 0 &&
291ce16fffca75e8598a8c9dceb08613413dcb07Timo Sirainen CMP_DEV_T(st.st_dev, st2.st_dev)) {
08e9fd42eb8007e1f9db62c088eef74f906114a5Josef 'Jeff' Sipek device_path = ent.mnt_special;
08e9fd42eb8007e1f9db62c088eef74f906114a5Josef 'Jeff' Sipek mount_path = ent.mnt_mountp;
08e9fd42eb8007e1f9db62c088eef74f906114a5Josef 'Jeff' Sipek type = ent.mnt_fstype;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen break;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen }
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen }
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen fclose(f);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen#else
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen /* Linux */
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen f = setmntent(MTAB_PATH, "r");
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen if (f == NULL) {
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen i_error("setmntent(%s) failed: %m", MTAB_PATH);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen return -1;
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen }
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen while ((ent = getmntent(f)) != NULL) {
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen if (strcmp(ent->mnt_type, MNTTYPE_SWAP) == 0 ||
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen strcmp(ent->mnt_type, MNTTYPE_IGNORE) == 0)
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen continue;
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen
30d50c7e8706f2d750215e009504109ca19cd485Timo Sirainen if (stat(ent->mnt_dir, &st2) == 0 &&
30d50c7e8706f2d750215e009504109ca19cd485Timo Sirainen CMP_DEV_T(st.st_dev, st2.st_dev)) {
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen device_path = ent->mnt_fsname;
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen mount_path = ent->mnt_dir;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen type = ent->mnt_type;
57a8c6a95e4bce3eeaba36985adb81c07dd683ffTimo Sirainen break;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen }
afe1da042382720393eca6497253106e4eec75e0Timo Sirainen }
afe1da042382720393eca6497253106e4eec75e0Timo Sirainen endmntent(f);
afe1da042382720393eca6497253106e4eec75e0Timo Sirainen#endif
afe1da042382720393eca6497253106e4eec75e0Timo Sirainen if (device_path == NULL)
afe1da042382720393eca6497253106e4eec75e0Timo Sirainen return 0;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen point_r->device_path = p_strdup(pool, device_path);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen point_r->mount_path = p_strdup(pool, mount_path);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen point_r->type = p_strdup(pool, type);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen point_r->block_size = block_size;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen return 1;
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen#endif
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen}
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen