Skip diskspace checking for symlinks and directories in all cases
We did this in some but not all cases, assuming the 0 value coming out of
libarchive would not be a problem. However, this does not work for "fake"
filesystems such as rpc_pipefs, which reports a free block and total block
count of zero.
Fix this by not ever counting symlinks or directories, and adding a note
explaining that if we someday do count directories, their size needs to be
attributed to the proper place.
- /* skip directories to be consistent with libarchive that reports them
- * to be zero size and to prevent multiple counting across packages */
- if(*(filename + strlen(filename) - 1) == '/') {
+ snprintf(path, PATH_MAX, "%s%s", handle->root, filename);
+ _alpm_lstat(path, &st);
+
+ /* skip directories and symlinks to be consistent with libarchive that
+ * reports them to be zero size */
+ if(S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode)) {
continue;
}
- mp = match_mount_point(mount_points, filename);
+ mp = match_mount_point(mount_points, path);
if(mp == NULL) {
_alpm_log(PM_LOG_WARNING,
_("could not determine mount point for file %s"), filename);
continue;
}
- snprintf(path, PATH_MAX, "%s%s", handle->root, filename);
- _alpm_lstat(path, &st);
-
- /* skip symlinks to be consistent with libarchive that reports them to
- * be zero size */
- if(S_ISLNK(st.st_mode)) {
- continue;
- }
-
- data = mp->data;
/* the addition of (divisor - 1) performs ceil() with integer division */
- data->blocks_needed -=
- (st.st_size + data->fsp.f_bsize - 1l) / data->fsp.f_bsize;
+ mp->blocks_needed -=
+ (st.st_size + mp->fsp.f_bsize - 1l) / mp->fsp.f_bsize;
}
- file = archive_entry_pathname(entry);
+ filename = archive_entry_pathname(entry);
+ mode = archive_entry_mode(entry);
+
+ /* libarchive reports these as zero size anyways */
+ /* NOTE: if we do start accounting for directory size, a dir matching a
+ * mountpoint needs to be attributed to the parent, not the mountpoint. */
+ if(S_ISDIR(mode) || S_ISLNK(mode)) {
+ continue;
+ }
/* approximate space requirements for db entries */
- if(file[0] == '.') {
- file = alpm_option_get_dbpath();
+ if(filename[0] == '.') {
+ filename = alpm_option_get_dbpath();
}
- mp = match_mount_point(mount_points, file);
+ snprintf(path, PATH_MAX, "%s%s", handle->root, filename);
+
+ mp = match_mount_point(mount_points, path);
if(mp == NULL) {
_alpm_log(PM_LOG_WARNING,
- _("could not determine mount point for file %s"), file);
+ _("could not determine mount point for file %s"), filename);
continue;
}