From: Alastair Hughes <hobbitalastair@yandex.com> Add a pkgsize binary which mimics the behaviour of GNU du --apparent-size -skl. Fixes FS#47943. Signed-off-by: Alastair Hughes <hobbitalastair@gmail.com> --- I haven't done much C programming before - I'd appreciate any feedback you have. At the moment, this patch creates a new pkgsize binary as an extra utility, and installs with the other utilities. I think that it would be better if it installed it to a libexec dir, but I'm not entirely sure how to do that without making a mess. --- configure.ac | 5 --- scripts/Makefile.am | 2 -- scripts/makepkg.sh.in | 2 +- src/util/.gitignore | 2 ++ src/util/Makefile.am | 4 ++- src/util/pkgsize.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 94 insertions(+), 9 deletions(-) create mode 100644 src/util/pkgsize.c diff --git a/configure.ac b/configure.ac index dd4ac04..ee5f7ea 100644 --- a/configure.ac +++ b/configure.ac @@ -332,7 +332,6 @@ OWNERCMD="stat -c '%u:%g'" MODECMD="stat -c '%a'" SIZECMD="stat -c %s" SEDINPLACE="sed --follow-symlinks -i" -DUFLAGS="-sk --apparent-size" STRIP_BINARIES="--strip-all" STRIP_SHARED="--strip-unneeded" STRIP_STATIC="--strip-debug" @@ -343,7 +342,6 @@ case "${host_os}" in MODECMD="stat -f '%Lp'" SIZECMD="stat -f %z" SEDINPLACE="sed -i \"\"" - DUFLAGS="-sk" ;; darwin*) host_os_darwin=yes @@ -352,7 +350,6 @@ case "${host_os}" in MODECMD="/usr/bin/stat -f '%Lp'" SIZECMD="/usr/bin/stat -f %z" SEDINPLACE="/usr/bin/sed -i ''" - DUFLAGS="-sk" STRIP_BINARIES="" STRIP_SHARED="-S" STRIP_STATIC="-S" @@ -360,13 +357,11 @@ case "${host_os}" in esac AM_CONDITIONAL([DARWIN], test "x$host_os_darwin" = "xyes") -AC_PATH_PROGS([DUPATH], [du], [du], [/usr/bin$PATH_SEPARATOR/bin] ) AC_SUBST(INODECMD) AC_SUBST(OWNERCMD) AC_SUBST(MODECMD) AC_SUBST(SIZECMD) AC_SUBST(SEDINPLACE) -AC_SUBST(DUFLAGS) AC_SUBST(STRIP_BINARIES) AC_SUBST(STRIP_SHARED) AC_SUBST(STRIP_STATIC) diff --git a/scripts/Makefile.am b/scripts/Makefile.am index e4f9fb1..ea14e73 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -138,8 +138,6 @@ edit = sed \ -e "s|@MODECMD[@]|$(MODECMD)|g" \ -e 's|@SIZECMD[@]|$(SIZECMD)|g' \ -e 's|@SEDINPLACE[@]|$(SEDINPLACE)|g' \ - -e 's|@DUFLAGS[@]|$(DUFLAGS)|g' \ - -e 's|@DUPATH[@]|$(DUPATH)|g' \ -e 's|@SCRIPTNAME[@]|$@|g' \ -e 's|@configure_input[@]|Generated from $@.sh.in; do not edit by hand.|g' diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index 7b2ce51..249c878 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -605,7 +605,7 @@ write_pkginfo() { local packager="Unknown Packager" fi - local size="$(@DUPATH@ @DUFLAGS@)" + local size="$(pkgsize .)" size="$(( ${size%%[^0-9]*} * 1024 ))" merge_arch_attrs diff --git a/src/util/.gitignore b/src/util/.gitignore index 202fb75..7dbefe8 100644 --- a/src/util/.gitignore +++ b/src/util/.gitignore @@ -6,6 +6,8 @@ pacsort pacsort.exe pactree pactree.exe +pkgsize +pkgsize.exe testpkg testpkg.exe vercmp diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 6a89ea6..84dfce9 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -4,7 +4,7 @@ dbpath = ${localstatedir}/lib/pacman/ gpgdir = ${sysconfdir}/pacman.d/gnupg/ cachedir = ${localstatedir}/cache/pacman/pkg/ -bin_PROGRAMS = vercmp testpkg cleanupdelta pacsort pactree +bin_PROGRAMS = vercmp testpkg cleanupdelta pacsort pactree pkgsize AM_CPPFLAGS = \ -imacros $(top_builddir)/config.h \ @@ -27,6 +27,8 @@ pacsort_LDADD = $(top_builddir)/lib/libalpm/.libs/libalpm.la pactree_SOURCES = pactree.c util-common.c pactree_LDADD = $(top_builddir)/lib/libalpm/.libs/libalpm.la +pkgsize_SOURCES = pkgsize.c + testpkg_SOURCES = testpkg.c testpkg_LDADD = $(top_builddir)/lib/libalpm/.libs/libalpm.la diff --git a/src/util/pkgsize.c b/src/util/pkgsize.c new file mode 100644 index 0000000..5e1b3fc --- /dev/null +++ b/src/util/pkgsize.c @@ -0,0 +1,88 @@ +/* + * pkgsize.c - a du --apparent-size equivalent for systems without GNU du + * + * Copyright (c) 2016 Pacman Development Team <pacman-dev@archlinux.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* This is equivalent to "du -skl --apparent-size". + * Unforunately, there appears to be no easy way of ignoring hard links, hence + * the additional '-l' argument. + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <dirent.h> +#include <unistd.h> + +static long size(char *path) +{ + long total_size, subsize; + DIR *dir; + struct dirent *entry; + struct stat buf; + + if(lstat(path, &buf) != 0) { return -1; } + + if(S_ISLNK(buf.st_mode) || S_ISREG(buf.st_mode)) { + return buf.st_size; + } else if(S_ISDIR(buf.st_mode)) { + total_size = buf.st_size; + dir = opendir(path); + if(dir == NULL || chdir(path) != 0) { return -1; } + while(entry = readdir(dir)) { + if(strcmp(entry->d_name, "..") == 0 || strcmp(entry->d_name, ".") == 0) { + continue; + } + subsize = size(entry->d_name); + if(subsize == -1) { + closedir(dir); + return -1; + } + total_size += subsize; + } + + closedir(dir); + if(chdir("../") != 0) { return -1; } + return total_size; + } + return 0; +} + +int main(int argc, char *argv[]) +{ + long total_size; + + if(argc != 2) { + printf("Invalid argument count %d!\n", argc - 1); + exit(EXIT_FAILURE); + } + + total_size = size(argv[1]); + if(total_size == -1) { + perror(""); + exit(EXIT_FAILURE); + } + + /* Use KB, rounded up - should be equivalent to the du -k flag */ + printf("%ld %s\n", (total_size / 1024) + (total_size % 1024 != 0), argv[1]); + + exit(EXIT_SUCCESS); +} + +/* vim: set noet: */ -- 2.8.3