Add function for listing system mount points

Add a mount_point_list() function that attempts to portably obtain
a list of system mount points and a struct to hold needed mount point
information.

Abort the transaction if we are unable to determine the mount points.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
Allan McRae 2010-11-16 16:15:21 +10:00 committed by Dan McGee
parent adb10c3ab2
commit f4e9deb6d7
3 changed files with 160 additions and 1 deletions

View File

@ -169,7 +169,9 @@ AS_IF([test "x$with_fetch" != "xno"],
AM_CONDITIONAL([HAVE_LIBFETCH], [test "x$ac_cv_lib_fetch_fetchParseURL" = "xyes"])
# Checks for header files.
AC_CHECK_HEADERS([fcntl.h glob.h libintl.h limits.h locale.h string.h strings.h sys/ioctl.h sys/param.h sys/statvfs.h sys/syslimits.h sys/time.h syslog.h wchar.h])
AC_CHECK_HEADERS([fcntl.h glob.h libintl.h limits.h locale.h mntent.h string.h strings.h \
sys/ioctl.h sys/mount.h sys/param.h sys/statvfs.h sys/syslimits.h \
sys/time.h sys/types.h sys/ucred.h syslog.h wchar.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_INLINE
@ -183,12 +185,30 @@ AC_STRUCT_DIRENT_D_TYPE
# Checks for library functions.
AC_FUNC_FORK
AC_FUNC_GETMNTENT
AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK
AC_FUNC_MKTIME
AC_CHECK_FUNCS([geteuid realpath regcomp strcasecmp \
strndup strrchr strsep swprintf \
wcwidth uname])
# Checks for getmntinfo and determines whether it uses statfs or statvfs
AC_CHECK_FUNC(getmntinfo,
[AC_MSG_CHECKING(parameter style for getmntinfo)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
# include <sys/param.h>
# include <sys/mount.h>
#if HAVE_SYS_UCRED_H
#include <sys/ucred.h>
#endif
extern int getmntinfo (struct statfs **, int);
]], [])],
[AC_DEFINE(HAVE_GETMNTINFO_STATFS, [], [getmntinfo uses statfs])
AC_MSG_RESULT(statfs)],
[AC_DEFINE(HAVE_GETMNTINFO_STATVFS, [], [getmntinfo uses statvfs])
AC_MSG_RESULT(statvfs)])
])
# Enable large file support if available
AC_SYS_LARGEFILE

View File

@ -17,11 +17,130 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#if defined HAVE_GETMNTENT
#include <mntent.h>
#include <sys/statvfs.h>
#elif defined HAVE_GETMNTINFO_STATFS
#include <sys/param.h>
#include <sys/mount.h>
#if HAVE_SYS_UCRED_H
#include <sys/ucred.h>
#endif
#elif defined HAVE_GETMNTINFO_STATVFS
#include <sys/types.h>
#include <sys/statvfs.h>
#endif
/* libalpm */
#include "diskspace.h"
#include "alpm_list.h"
#include "util.h"
#include "log.h"
static alpm_list_t *mount_point_list()
{
alpm_list_t *mount_points = NULL;
alpm_mountpoint_t *mp;
#if defined HAVE_GETMNTENT
struct mntent *mnt;
FILE *fp;
struct statvfs fsp;
fp = setmntent(MOUNTED, "r");
if (fp == NULL) {
return NULL;
}
while((mnt = getmntent (fp))) {
if(statvfs(mnt->mnt_dir, &fsp) != 0) {
_alpm_log(PM_LOG_WARNING, "could not get filesystem information for %s\n", mnt->mnt_dir);
continue;
}
MALLOC(mp, sizeof(alpm_mountpoint_t), RET_ERR(PM_ERR_MEMORY, NULL));
mp->mount_dir = strdup(mnt->mnt_dir);
MALLOC(mp->fsp, sizeof(struct statvfs), RET_ERR(PM_ERR_MEMORY, NULL));
memcpy((void *)(mp->fsp), (void *)(&fsp), sizeof(struct statvfs));
mp->blocks_needed = 0;
mp->max_blocks_needed = 0;
mp->used = 0;
mount_points = alpm_list_add(mount_points, mp);
}
endmntent(fp);
#elif defined HAVE_GETMNTINFO_STATFS
int entries;
struct statfs *fsp;
entries = getmntinfo(&fsp, MNT_NOWAIT);
if (entries < 0) {
return NULL;
}
for(; entries-- > 0; fsp++) {
MALLOC(mp, sizeof(alpm_mountpoint_t), RET_ERR(PM_ERR_MEMORY, NULL));
mp->mount_dir = strdup(fsp->f_mntonname);
MALLOC(mp->fsp, sizeof(struct statfs), RET_ERR(PM_ERR_MEMORY, NULL));
memcpy((void *)(mp->fsp), (void *)fsp, sizeof(struct statfs));
mp->blocks_needed = 0;
mp->max_blocks_needed = 0;
mount_points = alpm_list_add(mount_points, mp);
}
#elif defined HAVE_GETMNTINFO_STATVFS
int entries;
struct statvfs *fsp;
entries = getmntinfo(&fsp, MNT_NOWAIT);
if (entries < 0) {
return NULL;
}
for (; entries-- > 0; fsp++) {
MALLOC(mp, sizeof(alpm_mountpoint_t), RET_ERR(PM_ERR_MEMORY, NULL));
mp->mount_dir = strdup(fsp->f_mntonname);
MALLOC(mp->fsp, sizeof(struct statvfs), RET_ERR(PM_ERR_MEMORY, NULL));
memcpy((void *)(mp->fsp), (void *)fsp, sizeof(struct statvfs));
mp->blocks_needed = 0;
mp->max_blocks_needed = 0;
mount_points = alpm_list_add(mount_points, mp);
}
#endif
return(mount_points);
}
int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db)
{
alpm_list_t *mount_points;
mount_points = mount_point_list();
if(mount_points == NULL) {
_alpm_log(PM_LOG_ERROR, _("count not determine filesystem mount points"));
return -1;
}
for(i = mount_points; i; i = alpm_list_next(i)) {
alpm_mountpoint_t *data = i->data;
FREE(data->mount_dir);
FREE(data->fsp);
}
FREELIST(mount_points);
return 0;
}

View File

@ -20,8 +20,28 @@
#ifndef _ALPM_DISKSPACE_H
#define _ALPM_DISKSPACE_H
#if defined HAVE_GETMNTINFO_STATFS
#include <sys/mount.h>
#else
#include <sys/statvfs.h>
#endif
#include "alpm.h"
typedef struct __alpm_mountpoint_t {
/* mount point information */
char *mount_dir;
#if defined HAVE_GETMNTINFO_STATFS
struct statfs *fsp;
#else
struct statvfs *fsp;
#endif
/* storage for additional disk usage calculations */
long blocks_needed;
long max_blocks_needed;
int used;
} alpm_mountpoint_t;
int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db);
#endif /* _ALPM_DISKSPACE_H */