mountpoint.c revision d8eedfaad386a8776e4931086b039b72e1ad38c4
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen/* Copyright (c) 2006 Timo Sirainen */
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#include "lib.h"
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#include "mountpoint.h"
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#include <sys/stat.h>
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#ifdef HAVE_STATFS_MNTFROMNAME
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen# include <sys/param.h> /* BSDs */
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen# include <sys/mount.h>
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#elif defined(HAVE_MNTENT_H)
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen# include <stdio.h>
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen# include <mntent.h> /* Linux */
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#elif defined(HAVE_SYS_MNTTAB_H)
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen# include <stdio.h>
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen# include <sys/mnttab.h> /* Solaris */
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#else
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen# define MOUNTPOINT_UNKNOWN
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#endif
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#ifdef HAVE_SYS_MNTTAB_H
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen# define MTAB_PATH MNTTAB /* Solaris */
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#else
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen# define MTAB_PATH "/etc/mtab" /* Linux */
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#endif
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen/* AIX doesn't have these defined */
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#ifndef MNTTYPE_SWAP
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen# define MNTTYPE_SWAP "swap"
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#endif
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#ifndef MNTTYPE_IGNORE
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen# define MNTTYPE_IGNORE "ignore"
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#endif
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainenint mountpoint_get(const char *path, pool_t pool, struct mountpoint *point_r)
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen{
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#ifdef MOUNTPOINT_UNKNOWN
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen memset(point_r, 0, sizeof(*point_r));
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen errno = ENOSYS;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen return -1;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#elif defined (HAVE_STATFS_MNTFROMNAME)
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen /* BSDs */
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen struct statfs buf;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen memset(point_r, 0, sizeof(*point_r));
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen if (statfs(path, &buf) < 0) {
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen i_error("statfs(%s) failed: %m", path);
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen return -1;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen }
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen point_r->device_path = p_strdup(pool, buf.f_mntfromname);
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen point_r->mount_path = p_strdup(pool, buf.f_mntonname);
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen point_r->mount_path = p_strdup(pool, buf.f_fstypename);
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen point_r->block_size = buf.f_bsize;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen return 1;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#else
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen /* Linux, Solaris: /etc/mtab reading */
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#ifdef HAVE_SYS_MNTTAB_H
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen struct mnttab ent;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#else
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen struct mntent *ent;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#endif
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen struct stat st, st2;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen const char *device_path = NULL, *mount_path = NULL, *type = NULL;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen unsigned int block_size;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen FILE *f;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen memset(point_r, 0, sizeof(*point_r));
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen if (stat(path, &st) < 0) {
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen i_error("stat(%s) failed: %m", path);
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen return -1;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen }
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen block_size = st.st_blksize;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#ifdef HAVE_SYS_MNTTAB_H
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen /* Solaris */
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen f = fopen(MTAB_PATH, "r");
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen if (f == NULL) {
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen i_error("fopen(%s) failed: %m", MTAB_PATH);
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen return -1;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen }
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen while ((getmntent(f, &ent)) == 0) {
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen if (strcmp(ent.mnt_fstype, MNTTYPE_SWAP) == 0 ||
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen strcmp(ent.mnt_fstype, MNTTYPE_IGNORE) == 0)
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen continue;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen if (stat(ent.mnt_mountp, &st2) == 0 &&
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen CMP_DEV_T(st.st_dev, st2.st_dev)) {
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen device_path = ent.mnt_special;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen mount_path = ent.mnt_mountp;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen type = ent.mnt_fstype;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen break;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen }
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen }
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen fclose(f);
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#else
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen /* Linux */
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen f = setmntent(MTAB_PATH, "r");
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen if (f == NULL) {
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen i_error("setmntent(%s) failed: %m", MTAB_PATH);
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen return -1;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen }
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen while ((ent = getmntent(f)) != NULL) {
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen if (strcmp(ent->mnt_type, MNTTYPE_SWAP) == 0 ||
strcmp(ent->mnt_type, MNTTYPE_IGNORE) == 0)
continue;
if (stat(ent->mnt_dir, &st2) == 0 &&
CMP_DEV_T(st.st_dev, st2.st_dev)) {
device_path = ent->mnt_fsname;
mount_path = ent->mnt_dir;
type = ent->mnt_type;
break;
}
}
endmntent(f);
#endif
if (device_path == NULL)
return 0;
point_r->device_path = p_strdup(pool, device_path);
point_r->mount_path = p_strdup(pool, mount_path);
point_r->type = p_strdup(pool, type);
point_r->block_size = block_size;
return 1;
#endif
}