summaryrefslogtreecommitdiffstats
path: root/lib/libalpm/diskspace.c
diff options
context:
space:
mode:
authorAllan McRae <allan@archlinux.org>2010-11-16 07:15:21 +0100
committerDan McGee <dan@archlinux.org>2010-12-13 03:29:43 +0100
commitf4e9deb6d74614ac427b37513359d91588dd1542 (patch)
tree3f707d2046a12ee0808a3e0cbd3eed8a1d036767 /lib/libalpm/diskspace.c
parentadb10c3ab244cc00eb863d5b036fa7bdd76f8152 (diff)
downloadpacman-f4e9deb6d74614ac427b37513359d91588dd1542.tar.gz
pacman-f4e9deb6d74614ac427b37513359d91588dd1542.tar.xz
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>
Diffstat (limited to 'lib/libalpm/diskspace.c')
-rw-r--r--lib/libalpm/diskspace.c119
1 files changed, 119 insertions, 0 deletions
diff --git a/lib/libalpm/diskspace.c b/lib/libalpm/diskspace.c
index 31a2760d..a5beb84f 100644
--- a/lib/libalpm/diskspace.c
+++ b/lib/libalpm/diskspace.c
@@ -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;
}