di-6.0.0/0000755000175000017500000000000014763624477010241 5ustar bllblldi-6.0.0/dimath.h0000644000175000017500000002252314756614105011651 0ustar bllbll/* Copyright 2025 Brad Lanam Pleasant Hill CA */ #ifndef INC_DIMATH_H #define INC_DIMATH_H #include "config.h" #if _hdr_stdio # include #endif #if _hdr_stddef # include #endif #if _hdr_stdint # include #endif #if _hdr_inttypes # include #endif # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wbad-function-cast" /* a double has a longer mantissa than an unsigned int, */ /* but the accuracy may be less. */ #if _siz_long_double > 8 typedef long double di_unum_t; typedef long double di_snum_t; # define DI_INTERNAL_DOUBLE #elif _siz_double == 8 typedef double di_unum_t; typedef double di_snum_t; # define DI_INTERNAL_DOUBLE #elif _siz_uint64_t == 8 typedef uint64_t di_unum_t; typedef int64_t di_snum_t; # define DI_INTERNAL_INT #elif _siz_long == 8 typedef unsigned long di_unum_t; typedef long di_snum_t; # define DI_INTERNAL_INT #elif _siz_long_long == 8 typedef unsigned long long di_unum_t; typedef long long di_snum_t; # define DI_INTERNAL_INT #elif _siz_long == 4 typedef unsigned long di_unum_t; typedef long di_snum_t; # define DI_INTERNAL_INT #else # error "unable to locate a valid type" #endif #if _siz_uint64_t == 8 typedef uint64_t di_ui_t; typedef int64_t di_si_t; #elif _siz_long == 8 typedef unsigned long di_ui_t; typedef long di_si_t; #elif _siz_long_long == 8 typedef unsigned long long di_ui_t; typedef long long di_si_t; #elif _siz_long == 4 typedef unsigned long di_ui_t; typedef long di_si_t; #else # error "unable to locate a valid type" #endif #if _use_math == DI_GMP # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wunknown-warning-option" # pragma clang diagnostic ignored "-Wsign-conversion" # pragma clang diagnostic ignored "-Wreserved-identifier" # pragma gcc diagnostic push # pragma gcc diagnostic ignored "-Wsign-conversion" # include # pragma clang diagnostic pop # pragma gcc diagnostic pop typedef mpz_t dinum_t; #elif _use_math == DI_TOMMATH # define MP_WUR # if _hdr_tommath # include # endif # if _hdr_libtommath_tommath # include # endif typedef mp_int dinum_t; # else /* DI_INTERNAL */ typedef di_unum_t dinum_t; #endif # if defined (__cplusplus) || defined (c_plusplus) extern "C" { # endif #define DI_PERC_PRECISION 1000000 #define DI_PERC_DIV ( (double) (DI_PERC_PRECISION / 100)); #define DI_SCALE_PREC 1000 static inline void dinum_init (dinum_t *r) { #if _use_math == DI_GMP mpz_init_set_ui (*r, (unsigned long) 0); #elif _use_math == DI_TOMMATH mp_init_u64 (r, 0); #else *r = 0; #endif } static inline void dinum_clear (dinum_t *r) { #if _use_math == DI_GMP mpz_clear (*r); #elif _use_math == DI_TOMMATH mp_clear (r); #endif } static inline void dinum_str (const dinum_t *r, char *str, Size_t sz) { #if _use_math == DI_GMP gmp_snprintf (str, sz, "%Zd", *r); #elif _use_math == DI_TOMMATH mp_to_decimal (r, str, sz); #else # if defined (DI_INTERNAL_DOUBLE) # if _siz_long_double > 8 Snprintf1 (str, sz, "%.0Lf", *r); # else Snprintf1 (str, sz, "%.0f", *r); # endif # else # if _hdr_inttypes && _siz_uint64_t == 8 Snprintf1 (str, sz, "%" PRIu64, *r); # elif _siz_long == 8 Snprintf1 (str, sz, "%ld", *r); # elif _siz_long_long == 8 Snprintf1 (str, sz, "%lld", *r); # else Snprintf1 (str, sz, "%d", *r); # endif # endif #endif } static inline void dinum_set (dinum_t *r, const dinum_t *val) { #if _use_math == DI_GMP mpz_set (*r, *val); #elif _use_math == DI_TOMMATH mp_copy (val, r); #else *r = *val; #endif } static inline void dinum_set_u (dinum_t *r, di_ui_t val) { #if _use_math == DI_GMP mpz_set_ui (*r, (unsigned long) val); #elif _use_math == DI_TOMMATH mp_set_u64 (r, val); #else *r = (dinum_t) val; #endif } static inline void dinum_set_s (dinum_t *r, di_si_t val) { #if _use_math == DI_GMP mpz_set_si (*r, (long) val); #elif _use_math == DI_TOMMATH mp_set_i64 (r, val); #else *r = (dinum_t) val; #endif } static inline void dinum_add_u (dinum_t *r, di_ui_t val) { #if _use_math == DI_GMP mpz_t v; mpz_t t; mpz_init_set_ui (v, (unsigned long) val); mpz_init (t); mpz_set (t, *r); mpz_add (*r, t, v); mpz_clear (t); mpz_clear (v); #elif _use_math == DI_TOMMATH mp_int v; mp_init_u64 (&v, val); mp_add (r, &v, r); mp_clear (&v); #else *r += (dinum_t) val; #endif } static inline void dinum_sub_u (dinum_t *r, di_ui_t val) { #if _use_math == DI_GMP mpz_t v; mpz_t t; mpz_init_set_ui (v, (unsigned long) val); mpz_init (t); mpz_set (t, *r); mpz_sub (*r, t, v); mpz_clear (t); mpz_clear (v); #elif _use_math == DI_TOMMATH mp_int v; mp_init_u64 (&v, val); mp_sub (r, &v, r); mp_clear (&v); #else *r -= (dinum_t) val; #endif } static inline void dinum_add (dinum_t *r, const dinum_t *val) { #if _use_math == DI_GMP mpz_t t; mpz_init (t); mpz_set (t, *r); mpz_add (*r, t, *val); mpz_clear (t); #elif _use_math == DI_TOMMATH mp_add (r, val, r); #else *r += *val; #endif } static inline void dinum_sub (dinum_t *r, const dinum_t *val) { #if _use_math == DI_GMP mpz_t t; mpz_init (t); mpz_set (t, *r); mpz_sub (*r, t, *val); mpz_clear (t); #elif _use_math == DI_TOMMATH mp_sub (r, val, r); #else *r -= *val; #endif } static inline int dinum_cmp (const dinum_t *r, const dinum_t *val) { #if _use_math == DI_GMP return mpz_cmp (*r, *val); #elif _use_math == DI_TOMMATH return mp_cmp (r, val); #else int rc = 0; if (*r < *val) { rc = -1; } else if (*r > *val) { rc = 1; } return rc; #endif } static inline int dinum_cmp_s (const dinum_t *r, di_si_t val) { #if _use_math == DI_GMP return mpz_cmp_si (*r, (long) val); #elif _use_math == DI_TOMMATH mp_int t; int rv; mp_init (&t); mp_set_i64 (&t, val); rv = mp_cmp (r, &t); mp_clear (&t); return rv; #else di_snum_t t; int rc = 0; t = (di_snum_t) *r; if (t < val) { rc = -1; } else if (t > val) { rc = 1; } return rc; #endif } static inline void dinum_mul (dinum_t *r, const dinum_t *val) { #if _use_math == DI_GMP mpz_mul (*r, *r, *val); #elif _use_math == DI_TOMMATH mp_mul (r, (mp_int *) val, r); #else *r *= *val; #endif } static inline void dinum_mul_u (dinum_t *r, di_ui_t val) { #if _use_math == DI_GMP mpz_mul_ui (*r, *r, (unsigned long) val); #elif _use_math == DI_TOMMATH mp_int v; mp_init (&v); mp_set_u64 (&v, val); mp_mul (r, &v, r); mp_clear (&v); #else *r *= (dinum_t) val; #endif } static inline void dinum_mul_uu (dinum_t *r, di_ui_t vala, di_ui_t valb) { #if _use_math == DI_GMP mpz_set_ui (*r, (unsigned long) 1); mpz_mul_ui (*r, *r, (unsigned long) vala); mpz_mul_ui (*r, *r, (unsigned long) valb); #elif _use_math == DI_TOMMATH mp_int t; mp_int v; mp_set_u64 (r, 1); mp_init (&t); mp_init (&v); mp_set_u64 (&t, vala); mp_set_u64 (&v, valb); mp_mul (&t, &v, r); mp_clear (&t); mp_clear (&v); #else *r = (dinum_t) vala; *r *= (dinum_t) valb; #endif } static inline double dinum_scale (dinum_t *r, dinum_t *val) { double dval; #if _use_math == DI_GMP mpz_t t; mpz_t result; if (mpz_cmp_si (*val, (long) 0) == 0) { return 0.0; } mpz_init_set_ui (t, (unsigned long) DI_SCALE_PREC); mpz_init (result); mpz_mul (t, t, *r); mpz_cdiv_q (result, t, *val); dval = mpz_get_d (result); dval /= (double) DI_SCALE_PREC; mpz_clear (result); mpz_clear (t); #elif _use_math == DI_TOMMATH mp_int rem; mp_int t; mp_int result; mp_init_u64 (&t, 0); if (mp_cmp (val, &t) == 0) { mp_clear (&t); return 0.0; } mp_init (&rem); mp_init (&result); mp_set_u64 (&t, DI_SCALE_PREC); mp_mul (&t, r, &t); mp_div (&t, val, &result, &rem); dval = mp_get_double (&result); dval /= (double) DI_SCALE_PREC; mp_clear (&t); mp_clear (&rem); mp_clear (&result); #else # if defined (DI_INTERNAL_INT) dinum_t t; if (*val == 0) { return 0.0; } t = (*r * DI_SCALE_PREC) / *val; dval = (double) t; dval /= (double) DI_SCALE_PREC; # endif # if defined (DI_INTERNAL_DOUBLE) if (*val == (dinum_t) 0.0) { return (dinum_t) 0.0; } dval = (double) (*r / *val); # endif #endif return dval; } static inline double dinum_perc (dinum_t *r, dinum_t *val) { double dval = 0.0; #if _use_math == DI_GMP mpz_t quot; mpz_t t; mpz_init (quot); mpz_init (t); /* multiply by a larger value */ /* so that the double can get rounded appropriately */ mpz_mul_ui (t, *r, (unsigned long) DI_PERC_PRECISION); mpz_tdiv_q (quot, t, *val); dval = mpz_get_d (quot); dval /= DI_PERC_DIV; mpz_clear (quot); mpz_clear (t); #elif _use_math == DI_TOMMATH mp_int quot; mp_int rem; mp_int t; mp_init ("); mp_init (&rem); mp_init (&t); /* multiply by a larger value */ /* so that the double can get rounded appropriately */ mp_set_u64 (&t, DI_PERC_PRECISION); mp_mul (r, &t, &t); mp_div (&t, val, ", &rem); dval = mp_get_double ("); dval /= DI_PERC_DIV; mp_clear (&t); mp_clear ("); mp_clear (&rem); #else # if defined (DI_INTERNAL_DOUBLE) dval = (double) (*r / *val); # endif # if defined (DI_INTERNAL_INT) /* in the case of a uint, simply convert and divide */ dval = (double) *r / (double) *val; # endif dval *= 100.0; #endif return dval; } # pragma clang diagnostic pop # if defined (__cplusplus) || defined (c_plusplus) } # endif #endif /* INC_DIMATH_H */ di-6.0.0/mkc_config/0000755000175000017500000000000014761606465012333 5ustar bllblldi-6.0.0/mkc_config/di.mkc0000644000175000017500000001752414761605247013431 0ustar bllbll# # Copyright 2006-2018 Brad Lanam, Walnut Creek, California USA # Copyright 2025 Brad Lanam, Pleasnt Hill, California USA # loadunit c-main loadunit c-include-conflict output config.h standard hdr ctype.h hdr dirent.h hdr errno.h hdr fcntl.h hdr fshelp.h hdr inttypes.h hdr jfs/quota.h hdr kernel/fs_info.h hdr limits.h hdr linux/dqblk_xfs.h # aix 5 doesn't declare their own, use the compatibility version hdr linux/quota.h hdr libintl.h hdr libprop/proplib.h hdr locale.h hdr malloc.h hdr math.h hdr memory.h hdr mntent.h hdr mnttab.h # NetBSD hdr quota.h hdr rpc/rpc.h # SCO OpenServer and OpenBSD requires rpc.h first hdr rpc/auth.h rpc/rpc.h # Linux rquota.h includes rpc/rpc.h which is in the tirpc dir hdr rpcsvc/rquota.h rpc/rpc.h hdr stdbool.h hdr stddef.h hdr stdint.h hdr storage/Directory.h hdr storage/Entry.h hdr storage/Path.h hdr string.h hdr strings.h hdr time.h hdr tommath.h hdr libtommath/tommath.h hdr ufs/quota.h hdr ufs/ufs/quota.h sys/types.h hdr unistd.h hdr wchar.h hdr windows.h hdr winioctl.h windows.h hdr zone.h sys dcmd_blk.h sys file.h sys fs_types.h sys fs/ufs_quota.h sys/types.h sys fstyp.h sys fstypes.h sys ftype.h sys io.h sys mntctl.h # SCO OpenServer/UnixWare require sys/mnttab.h for struct mnttab declaration. sys mntent.h sys/mnttab.h sys mnttab.h sys mount.h sys quota.h sys stat.h sys statfs.h sys statvfs.h sys time.h sys vfs.h sys vfs_quota.h sys vfstab.h sys vmount.h include_conflict time.h sys/time.h include_conflict sys/quota.h linux/quota.h const O_NOCTTY define IOCTL_STORAGE_CHECK_VERIFY2 define MCTL_QUERY define QCMD define S_ISLNK typ struct dqblk typ struct quotaval typ struct ufs_dqblk typ fs_disk_quota_t typ gid_t typ statvfs_t typ size_t typ uid_t size long double size double size uint64_t size long long size long lib bcopy lib bindtextdomain -lintl, -lintl -liconv lib bzero lib CreateFile lib DeviceIoControl # unknown if -lsun, -lseq are needed (old irix, sequent) lib endmntent -lsun, -lseq lib fs_stat_dev lib fshelp lib GetDiskFreeSpace lib GetDiskFreeSpaceEx lib GetDriveType lib getfsstat lib GetLogicalDriveStrings lib GetVolumeInformation lib getmnt # unixware put getmntent into libgen for some reason # -lsun, -lseq are untested (old irix, sequent) lib getmntent -lgen, -lsun, -lseq lib getmntinfo lib gettext -lintl, -lintl -liconv lib getvfsstat lib getzoneid lib hasmntopt lib lstat lib mbrlen lib memcpy lib memset # AIX doesn't declare this :( # Look for MCTL_QUERY (see below) lib mntctl lib next_dev # dragonflybsd; need this to get the library lib prop_dictionary_create -lprop # quota_open is a new interface from NetBSD lib quota_open -lquota lib quotactl lib realpath lib setlocale -lintl, -lintl -liconv # unknown if -lsun, -lseq are needed (old irix, sequent) lib setmntent -lsun, -lseq lib snprintf -lsnprintf lib statfs lib statvfs lib stpecpy lib strcoll lib strdup lib strstr lib strtok_r lib sysfs lib textdomain -lintl, -lintl -liconv # dragonflybsd lib vquotactl # need this to get the optional library lib xdr_int -ltirpc, -lnsl lib zone_getattr lib zone_list # check for basic existence... member struct rquota rq_bhardlimit member struct getquota_args gqa_uid # check for the correct xdr types... memberxdr rquota rq_bhardlimit memberxdr rquota rq_bsoftlimit memberxdr rquota rq_curblocks memberxdr rquota rq_fhardlimit memberxdr rquota rq_fsoftlimit memberxdr rquota rq_curfiles memberxdr getquota_args gqa_uid # to prevent warnings # some systems are u_int, size_t, u_long args getfsstat args getvfsstat args quotactl setint _quotactl_pos_1 0 setint _quotactl_pos_2 0 if quotactl_pos_1 == _c_arg_1_quotactl 'char *' setint _quotactl_pos_1 1 endif if quotactl_pos_1 == _c_arg_1_quotactl 'const char *' setint _quotactl_pos_1 1 endif if quotactl_pos_2 == _c_arg_2_quotactl 'char *' setint _quotactl_pos_2 1 endif if quotactl_pos_2 == _c_arg_2_quotactl 'const char *' setint _quotactl_pos_2 1 endif if quotactl_pos_2 == _c_arg_2_quotactl 'caddr_t' setint _quotactl_pos_2 1 endif args setmntent args statfs npt getenv npt mntctl npt quotactl npt statfs _lib_statfs dcl int errno dcl ptr mnt_names member struct dqblk dqb_curspace member struct dqblk dqb_curblocks member struct dqblk dqb_fhardlimit member struct dqblk dqb_fsoftlimit member struct dqblk dqb_curfiles member struct getquota_rslt gqr_status member struct getquota_rslt gqr_rquota member struct mnttab mt_mntopts member struct statfs f_bsize member struct statfs f_fsize member struct statfs f_fstyp member struct statfs f_iosize member struct statfs f_frsize member struct statfs f_fstypename member struct statfs mount_info member struct statfs f_type member struct statvfs f_basetype # workaround for AIX # mntctl() is not declared if AIX_mntctl _sys_vmount && _define_MCTL_QUERY set _lib_mntctl 1 endif # dragonflybsd may have vquotactl, but it may not be turned on. if DFLYBSD_vquotactl _lib_vquotactl grep DFLYBSD_vquota vfs.quota_enabled=.*1 /boot/loader.conf if DFLYBSD_vquota_chk ! _grep_DFLYBSD_vquota set _lib_vquotactl 0 set _lib_prop_dictionary_create 0 endif endif if stdquotas ( _lib_quotactl || _lib_quota_open || _lib_vquotactl || \ _typ_struct_dqblk || _typ_struct_ufs_dqblk ) setint _has_std_quotas 1 else setint _has_std_quotas 0 endif if stdnfsquotas _hdr_rpc_rpc && \ _hdr_rpcsvc_rquota && \ _lib_xdr_int && \ _mem_struct_rquota_rq_bhardlimit && \ _mem_struct_getquota_args_gqa_uid setint _has_std_nfs_quotas 1 else setint _has_std_nfs_quotas 0 endif if hasnls _lib_bindtextdomain && _lib_gettext && _lib_setlocale && \ _lib_textdomain && _hdr_libintl && _hdr_locale setint _enable_nls 1 else setint _enable_nls 0 endif env DI_PREFIX quote env DI_VERSION quote env DI_RELEASE_STATUS quote env DI_USE_MATH if nousemath ! _env_DI_USE_MATH if havegmp _pkg_libs_gmp env DI_USE_MATH DI_GMP endif # at the moment, libtommath in macports has a broken pkg-config if havetommath _pkg_libs_libtommath && ! _pkg_libs_gmp && ! == _MKCONFIG_SYSTYPE Darwin env DI_USE_MATH DI_TOMMATH endif if nousemath ! _env_DI_USE_MATH env DI_USE_MATH DI_INTERNAL endif endif include #if ! defined (DI_PREFIX) # error "DI_PREFIX is not set" #endif #define DI_BUILD_SYS "mkconfig" #define DI_LOCALE_DIR DI_PREFIX "/share/locale" #define DI_INTERNAL 0 #define DI_GMP 1 #define DI_TOMMATH 2 #define _use_math DI_USE_MATH #if _typ_statvfs_t # define Statvfs_t statvfs_t #else # define Statvfs_t struct statvfs #endif #if _typ_size_t # define Size_t size_t #else # define Size_t unsigned long #endif #if _typ_uid_t # define Uid_t uid_t #else # define Uid_t int #endif #if _typ_gid_t # define Gid_t gid_t #else # define Gid_t int #endif /* Do this the old-fashioned way for old compilers */ /* Have to work around MacOSX's snprintf macro. */ #if _lib_snprintf # define Snprintf1 snprintf # define Snprintf2 snprintf # define Snprintf3 snprintf # define Snprintf4 snprintf #else # define Snprintf1(a1,a2,a3,a4) sprintf(a1,a3,a4) # define Snprintf2(a1,a2,a3,a4,a5) sprintf(a1,a3,a4,a5) # define Snprintf3(a1,a2,a3,a4,a5,a6) sprintf(a1,a3,a4,a5,a6) # define Snprintf4(a1,a2,a3,a4,a5,a6,a7) sprintf(a1,a3,a4,a5,a6,a7) #endif #if ! _lib_strcoll # define strcoll strcmp #endif #if ! _dcl_errno extern int errno; #endif #if ! _const_O_NOCTTY # define O_NOCTTY 0 #endif /* macro for gettext() */ #ifndef DI_GT # if _enable_nls # define DI_GT(args) gettext(args) # else # define DI_GT(args) (args) # endif #endif endinclude di-6.0.0/mkc_config/di-env.mkc0000644000175000017500000000473014756442012014203 0ustar bllbllloadunit env-main loadunit env-systype loadunit env-cc loadunit env-msgfmt loadunit env-extension output di.env standard_system standard_cc addcflag -fno-common addcflag -Wall addcflag -Wextra addcflag -Wconversion addcflag -Wno-unused-but-set-variable addcflag -Wno-unused-parameter addcflag -Wno-unknown-pragmas addcflag -Wno-float-equal addcflag -Wno-stringop-overflow addcflag -Wformat addcflag -Wformat-security addcflag -Werror=format-security addcflag -Werror=return-type addcflag -Wunreachable-code addcflag -Wdeclaration-after-statement addcflag -Wmissing-prototypes addcflag -Wmaybe-uninitialized addcflag -Wno-unused-but-set-variable addcflag -Wno-stringop-overflow addcflag -Wno-stringop-truncation addcflag -Wno-format-truncation addcflag -Wno-extra-semi-stmt addcflag -Wno-unsafe-buffer-usage addcflag -Wno-poison-system-directories addcflag -Wno-shift-sign-overflow addcflag -Wno-pragma-pack addcflag -Wno-ignored-attributes addcflag -Wno-reserved-id-macro addcflag -Wno-implicit-int-conversion addcflag -Wno-switch-enum addcflag -Wno-gnu-zero-variadic-macro-arguments addcflag -Wno-documentation-deprecated-sync addcflag -Wno-documentation-unknown-command addcflag -Wno-documentation addcflag -Wno-used-but-marked-unused env DI_FORTIFY # these confuse other compilers...make them GCC only # solaris will not link w/-fstack-protector, so it # can only be set when the gnu linker is in use. if UsingGNU_LD == _env_DI_FORTIFY Y && == _MKCONFIG_USING_GNU_LD Y && == _MKCONFIG_USING_GCC Y # gcc hardening # reference: wiki.debian.org/Hardening addcflag -D_FORTIFY_SOURCE=2 addcflag -fstack-protector-strong addcflag -fstack-protector-all addldflag -fstack-protector-strong addldflag -fstack-protector-all addldflag -Wl,-z,relro addldflag -Wl,-z,now endif # these confuse other compilers...make them CLANG only if UsingCLANG == DI_FORTIFY Y && == _MKCONFIG_USING_CLANG Y addcflag -Werror,-Wunused-command-line-argument # gcc hardening # reference: wiki.debian.org/Hardening addcflag -D_FORTIFY_SOURCE=2 addcflag -fstack-protector-strong addcflag -fstack-protector-all addldflag -fstack-protector-strong addldflag -fstack-protector-all endif pkg cflags libtirpc pkg libs libtirpc env DI_USE_MATH if nousemath ! _env_DI_USE_MATH || == _env_DI_USE_MATH DI_GMP pkg cflags gmp pkg libs gmp endif if nomath_g ! _pkg_libs_gmp || == _env_DI_USE_MATH DI_TOMMATH pkg cflags libtommath pkg libs libtommath endif libs shared_flags extension obj extension exe extension shlib cmd_msgfmt di-6.0.0/LICENSE.txt0000644000175000017500000000166114737467301012060 0ustar bllbll Copyright 1994-2021 Brad Lanam, Walnut Creek, CA, USA Copyright 2023-2025 Brad Lanam Pleasant Hill CA, USA This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. di-6.0.0/config.h.in0000644000175000017500000001712414761605226012256 0ustar bllbll/* Copyright 2025 Brad Lanam Pleasant Hill CA */ #ifndef INC_CONFIG_H #define INC_CONFIG_H 1 #cmakedefine01 _hdr_stdio #cmakedefine01 _hdr_stdlib #cmakedefine01 _sys_types #cmakedefine01 _sys_param #define _key_void 1 #define _key_const 1 #define _param_void_star 1 #cmakedefine01 _hdr_ctype #cmakedefine01 _hdr_dirent #cmakedefine01 _hdr_errno #cmakedefine01 _hdr_fcntl #cmakedefine01 _hdr_fshelp #cmakedefine01 _hdr_inttypes #cmakedefine01 _hdr_jfs_quota #cmakedefine01 _hdr_kernel_fs_info #cmakedefine01 _hdr_limits #cmakedefine01 _hdr_linux_dqblk_xfs #cmakedefine01 _hdr_linux_quota #cmakedefine01 _hdr_libintl #cmakedefine01 _hdr_libprop_proplib #cmakedefine01 _hdr_locale #cmakedefine01 _hdr_malloc #cmakedefine01 _hdr_math #cmakedefine01 _hdr_memory #cmakedefine01 _hdr_mntent #cmakedefine01 _hdr_mnttab #cmakedefine01 _hdr_quota #cmakedefine01 _hdr_rpc_rpc #cmakedefine01 _hdr_rpc_auth #cmakedefine01 _hdr_rpcsvc_rquota #cmakedefine01 _hdr_stdbool #cmakedefine01 _hdr_stddef #cmakedefine01 _hdr_stdint #cmakedefine01 _hdr_storage_Directory #cmakedefine01 _hdr_storage_Entry #cmakedefine01 _hdr_storage_Path #cmakedefine01 _hdr_string #cmakedefine01 _hdr_strings #cmakedefine01 _hdr_time #cmakedefine01 _hdr_tommath #cmakedefine01 _hdr_libtommath_tommath #cmakedefine01 _hdr_ufs_quota #cmakedefine01 _hdr_ufs_ufs_quota #cmakedefine01 _hdr_unistd #cmakedefine01 _hdr_wchar #cmakedefine01 _hdr_windows #cmakedefine01 _hdr_winioctl #cmakedefine01 _hdr_zone #cmakedefine01 _sys_dcmd_blk #cmakedefine01 _sys_file #cmakedefine01 _sys_fs_types #cmakedefine01 _sys_fs_ufs_quota #cmakedefine01 _sys_fstyp #cmakedefine01 _sys_fstypes #cmakedefine01 _sys_ftype #cmakedefine01 _sys_io #cmakedefine01 _sys_mntctl #cmakedefine01 _sys_mntent #cmakedefine01 _sys_mnttab #cmakedefine01 _sys_mount #cmakedefine01 _sys_quota #cmakedefine01 _sys_stat #cmakedefine01 _sys_statfs #cmakedefine01 _sys_statvfs #cmakedefine01 _sys_time #cmakedefine01 _sys_vfs #cmakedefine01 _sys_vfs_quota #cmakedefine01 _sys_vfstab #cmakedefine01 _sys_vmount #cmakedefine01 _inc_conflict__hdr_time__sys_time #cmakedefine01 _inc_conflict__sys_quota__hdr_linux_quota #cmakedefine01 _const_O_NOCTTY #cmakedefine01 _define_IOCTL_STORAGE_CHECK_VERIFY2 #cmakedefine01 _define_MCTL_QUERY #cmakedefine01 _define_QCMD #cmakedefine01 _define_S_ISLNK #cmakedefine01 _typ_struct_dqblk #cmakedefine01 _typ_struct_quotaval #cmakedefine01 _typ_struct_ufs_dqblk #cmakedefine01 _typ_fs_disk_quota_t #cmakedefine01 _typ_gid_t #cmakedefine01 _typ_statvfs_t #cmakedefine01 _typ_size_t #cmakedefine01 _typ_uid_t #define _siz_long_double ${_siz_long_double} #define _siz_double ${_siz_double} #define _siz_uint64_t ${_siz_uint64_t} #define _siz_long_long ${_siz_long_long} #define _siz_long ${_siz_long} #cmakedefine01 _lib_bcopy #cmakedefine01 _lib_bindtextdomain #cmakedefine01 _lib_bzero #cmakedefine01 _lib_CreateFile #cmakedefine01 _lib_DeviceIoControl #cmakedefine01 _lib_endmntent #cmakedefine01 _lib_fs_stat_dev #cmakedefine01 _lib_fshelp #cmakedefine01 _lib_GetDiskFreeSpace #cmakedefine01 _lib_GetDiskFreeSpaceEx #cmakedefine01 _lib_GetDriveType #cmakedefine01 _lib_getfsstat #cmakedefine01 _lib_GetLogicalDriveStrings #cmakedefine01 _lib_GetVolumeInformation #cmakedefine01 _lib_getmnt #cmakedefine01 _lib_getmntent #cmakedefine01 _lib_getmntinfo #cmakedefine01 _lib_gettext #cmakedefine01 _lib_getvfsstat #cmakedefine01 _lib_getzoneid #cmakedefine01 _lib_hasmntopt #cmakedefine01 _lib_lstat #cmakedefine01 _lib_mbrlen #cmakedefine01 _lib_memcpy #cmakedefine01 _lib_memset #cmakedefine01 _lib_mntctl #cmakedefine01 _lib_next_dev #cmakedefine01 _lib_prop_dictionary_create #cmakedefine01 _lib_quota_open #cmakedefine01 _lib_quotactl #cmakedefine01 _lib_realpath #cmakedefine01 _lib_setlocale #cmakedefine01 _lib_setmntent #cmakedefine01 _lib_snprintf #cmakedefine01 _lib_statfs #cmakedefine01 _lib_statvfs #cmakedefine01 _lib_stpecpy #cmakedefine01 _lib_strcoll #cmakedefine01 _lib_strdup #cmakedefine01 _lib_strstr #cmakedefine01 _lib_strtok_r #cmakedefine01 _lib_sysfs #cmakedefine01 _lib_textdomain #cmakedefine01 _lib_vquotactl #cmakedefine01 _lib_xdr_int #cmakedefine01 _lib_zone_getattr #cmakedefine01 _lib_zone_list #cmakedefine01 _mem_struct_rquota_rq_bhardlimit #cmakedefine01 _mem_struct_getquota_args_gqa_uid #define xdr_rq_bhardlimit ${xdr_rq_bhardlimit} #define xdr_rq_bsoftlimit ${xdr_rq_bsoftlimit} #define xdr_rq_curblocks ${xdr_rq_curblocks} #define xdr_rq_fhardlimit ${xdr_rq_fhardlimit} #define xdr_rq_fsoftlimit ${xdr_rq_fsoftlimit} #define xdr_rq_curfiles ${xdr_rq_curfiles} #define xdr_gqa_uid ${xdr_gqa_uid} #define _c_arg_2_getfsstat ${_c_arg_2_getfsstat} #define _args_getvfsstat ${_args_getvfsstat} #define _c_arg_2_quotactl ${_c_arg_2_quotactl} #define _args_quotactl ${_args_quotactl} #cmakedefine01 _quotactl_pos_1 #cmakedefine01 _quotactl_pos_2 #define _args_setmntent ${_args_setmntent} #define _args_statfs ${_args_statfs} #cmakedefine01 _npt_getenv #cmakedefine01 _npt_mntctl #cmakedefine01 _npt_quotactl #cmakedefine01 _npt_statfs #cmakedefine01 _dcl_errno #cmakedefine01 _dcl_mnt_names #cmakedefine01 _mem_struct_dqblk_dqb_curspace #cmakedefine01 _mem_struct_dqblk_dqb_curblocks #cmakedefine01 _mem_struct_dqblk_dqb_fhardlimit #cmakedefine01 _mem_struct_dqblk_dqb_fsoftlimit #cmakedefine01 _mem_struct_dqblk_dqb_curfiles #cmakedefine01 _mem_struct_getquota_rslt_gqr_status #cmakedefine01 _mem_struct_getquota_rslt_gqr_rquota #cmakedefine01 _mem_struct_mnttab_mt_mntopts #cmakedefine01 _mem_struct_statfs_f_bsize #cmakedefine01 _mem_struct_statfs_f_fsize #cmakedefine01 _mem_struct_statfs_f_fstyp #cmakedefine01 _mem_struct_statfs_f_iosize #cmakedefine01 _mem_struct_statfs_f_frsize #cmakedefine01 _mem_struct_statfs_f_fstypename #cmakedefine01 _mem_struct_statfs_mount_info #cmakedefine01 _mem_struct_statfs_f_type #cmakedefine01 _mem_struct_statvfs_f_basetype #cmakedefine01 _has_std_quotas #cmakedefine01 _has_std_nfs_quotas #cmakedefine01 _enable_nls #define DI_PREFIX "${CMAKE_INSTALL_PREFIX}" #define DI_VERSION "${DI_VERSION}" #define DI_RELEASE_STATUS "${DI_RELEASE_STATUS}" #ifndef MKC_STANDARD_DEFS # define MKC_STANDARD_DEFS 1 # if ! _key_void # define void int # endif # if ! _key_void || ! _param_void_star typedef char *pvoid; # else typedef void *pvoid; # endif # if ! _key_const # define const # endif #endif /* MKC_STANDARD_DEFS */ #if ! defined (DI_PREFIX) # error "DI_PREFIX is not set" #endif #define DI_BUILD_SYS "${DI_BUILD_SYS}" #define DI_LOCALE_DIR DI_PREFIX "/share/locale" #define DI_INTERNAL 0 #define DI_GMP 1 #define DI_TOMMATH 2 #define DI_USE_MATH ${DI_USE_MATH} #define _use_math DI_USE_MATH #if _typ_statvfs_t # define Statvfs_t statvfs_t #else # define Statvfs_t struct statvfs #endif #if _typ_size_t # define Size_t size_t #else # define Size_t unsigned long #endif #if _typ_uid_t # define Uid_t uid_t #else # define Uid_t int #endif #if _typ_gid_t # define Gid_t gid_t #else # define Gid_t int #endif /* Do this the old-fashioned way for old compilers */ /* Have to work around MacOSX's snprintf macro. */ #if _lib_snprintf # define Snprintf1 snprintf # define Snprintf2 snprintf # define Snprintf3 snprintf # define Snprintf4 snprintf #else # define Snprintf1(a1,a2,a3,a4) sprintf(a1,a3,a4) # define Snprintf2(a1,a2,a3,a4,a5) sprintf(a1,a3,a4,a5) # define Snprintf3(a1,a2,a3,a4,a5,a6) sprintf(a1,a3,a4,a5,a6) # define Snprintf4(a1,a2,a3,a4,a5,a6,a7) sprintf(a1,a3,a4,a5,a6,a7) #endif #if ! _lib_strcoll # define strcoll strcmp #endif #if ! _dcl_errno extern int errno; #endif #if ! _const_O_NOCTTY # define O_NOCTTY 0 #endif /* macro for gettext() */ #ifndef DI_GT # if _enable_nls # define DI_GT(args) gettext(args) # else # define DI_GT(args) (args) # endif #endif #endif /* INC_CONFIG_H */ di-6.0.0/dilib.c0000644000175000017500000014674214763621703011473 0ustar bllbll/* * Copyright 1994-2018 Brad Lanam, Walnut Creek, CA * Copyright 2023-2025 Brad Lanam, Pleasant Hill, CA */ #include "config.h" #if _hdr_stdio # include #endif #if _hdr_stddef # include #endif #if _hdr_stdbool # include #endif #if _hdr_stdlib # include #endif #if _hdr_stdbool # include #endif #if _sys_types \ && ! defined (DI_INC_SYS_TYPES_H) /* xenix */ # define DI_INC_SYS_TYPES_H # include #endif #if _hdr_ctype # include #endif #if _hdr_errno # include #endif #if _hdr_string # include #endif #if _hdr_strings # include #endif #if _sys_stat # include #endif #if _hdr_unistd # include #endif #if _hdr_memory # include #endif #if _hdr_malloc # include #endif #if _hdr_zone # include #endif #if _sys_file # include #endif #if _hdr_fcntl && ! defined (DI_INC_FCNTL_H) /* xenix */ // # define DI_INC_FCNTL_H # include /* O_RDONLY, O_NOCTTY */ #endif #include "di.h" #include "disystem.h" #include "dimath.h" #include "diinternal.h" #include "dizone.h" #include "diquota.h" #include "dioptions.h" #include "distrutils.h" #if defined (__cplusplus) || defined (c_plusplus) extern "C" { #endif #if _npt_getenv extern char *getenv (const char *); #endif #if defined (__cplusplus) || defined (c_plusplus) } #endif /* end of system specific includes/configurations */ #define DI_UNKNOWN_DEV -1L #define DI_SORT_OPT_NONE 'n' #define DI_SORT_OPT_MOUNT 'm' #define DI_SORT_OPT_FILESYSTEM 's' #define DI_SORT_OPT_TOTAL 'T' #define DI_SORT_OPT_FREE 'f' #define DI_SORT_OPT_AVAIL 'a' #define DI_SORT_OPT_REVERSE 'r' #define DI_SORT_OPT_TYPE 't' #define DI_SORT_OPT_ASCENDING 1 static void checkDiskInfo (di_data_t *, int); static void checkDiskQuotas (di_data_t *); static int checkFileInfo (di_data_t *); static int getDiskSpecialInfo (di_data_t *, int); static void getDiskStatInfo (di_data_t *); static void preCheckDiskInfo (di_data_t *); static void checkExcludeList (di_data_t *di_data, di_disk_info_t *, di_strarr_t *); static void checkIncludeList (di_data_t *, di_disk_info_t *, di_strarr_t *); static int isIgnoreFSType (const char *); static int isIgnoreFilesystem (const char *); static int isIgnoreFS (const char *, const char *); static int checkForUUID (const char *); static int di_sort_compare (const di_opt_t *, const char *sortType, const di_disk_info_t *, int, int); static void checkZone (di_disk_info_t *, di_zone_info_t *, di_opt_t *); static void di_sort_disk_info (di_opt_t *, di_disk_info_t *, int, const char *, int); static void init_scale_values (di_data_t *, di_opt_t *); static void di_calc_space (di_data_t *di_data, int infoidx, int validxA, int validxB, int validxC, dinum_t *val); static double di_calc_perc (di_data_t *di_data, int infoidx, int validxA, int validxB, int validxC, int validxD, int validxE); static void processTotals (di_data_t *di_data); static void addTotals (di_data_t *di_data, const di_disk_info_t *dinfo, di_disk_info_t *totals, int inpool); static const char *getPrintFlagText (int); void * di_initialize (void) { di_data_t *di_data; di_data = (di_data_t *) malloc (sizeof (di_data_t)); di_data->scale_values_init = false; di_data->fscount = 0; di_data->dispcount = 0; di_data->haspooledfs = false; di_data->disppooledfs = false; di_data->totsorted = false; di_data->diskInfo = (di_disk_info_t *) NULL; /* options defaults */ di_data->options = di_init_options (); di_data->pub = NULL; di_data->iteridx = 0; di_data->iteropt = 0; return di_data; } void di_cleanup (void *tdi_data) { di_data_t *di_data = (di_data_t *) tdi_data; int i; di_opt_t *diopts; di_zone_info_t *zinfo; if (di_data == NULL) { return; } if (di_data->diskInfo != (di_disk_info_t *) NULL) { di_disk_info_t *dinfo; /* the totals bucket is at di_data->fscount */ for (i = 0; i <= di_data->fscount; ++i) { dinfo = &di_data->diskInfo [i]; di_free_disk_info (dinfo); } free (di_data->diskInfo); } if (di_data->pub != NULL) { free (di_data->pub); } diopts = (di_opt_t *) di_data->options; di_opt_cleanup (diopts); zinfo = (di_zone_info_t *) di_data->zoneInfo; di_free_zones (zinfo); if (di_data->scale_values_init) { for (i = 0; i < DI_SCALE_MAX; ++i) { dinum_clear (&di_data->scale_values [i]); } } free (di_data); } const char * di_version (void) { return DI_VERSION; } int di_process_options (void *tdi_data, int argc, const char * argv [], int offset) { di_data_t *di_data = (di_data_t *) tdi_data; di_opt_t *diopts; int exitflag; if (di_data == NULL) { return DI_EXIT_FAIL; } diopts = (di_opt_t *) di_data->options; exitflag = di_get_options (argc, argv, diopts, offset); if (diopts->optval [DI_OPT_DEBUG] > 0) { fprintf (stdout, "# BUILD: %s\n", DI_BUILD_SYS); #if _use_math == DI_GMP fprintf (stdout, "# MATH: GMP\n"); #elif _use_math == DI_TOMMATH fprintf (stdout, "# MATH: TOMMATH\n"); #else fprintf (stdout, "# MATH: INTERNAL: ld:%d d:%d u64:%d ll:%d l:%d\n", _siz_long_double, _siz_double, _siz_uint64_t, _siz_long, _siz_long_long); #endif } init_scale_values (di_data, diopts); return exitflag; } /* option processing */ int di_check_option (void *tdi_data, int optidx) { di_data_t *di_data = (di_data_t *) tdi_data; di_opt_t *diopts; if (di_data == NULL) { return 0; } diopts = (di_opt_t *) di_data->options; return di_opt_check_option (diopts, optidx); } extern void di_format_iter_init (void *tdi_data) { di_data_t *di_data = (di_data_t *) tdi_data; di_opt_t *diopts; if (di_data == NULL) { return; } diopts = (di_opt_t *) di_data->options; di_opt_format_iter_init (diopts); } extern int di_format_iterate (void *tdi_data) { di_data_t *di_data = (di_data_t *) tdi_data; di_opt_t *diopts; if (di_data == NULL) { return -1; } diopts = (di_opt_t *) di_data->options; return di_opt_format_iterate (diopts); } /* data processing */ int di_get_all_disk_info (void *tdi_data) { di_data_t *di_data = (di_data_t *) tdi_data; di_opt_t *diopts; int hasLoop; if (di_data == NULL) { return DI_EXIT_FAIL; } /* initialization */ diopts = (di_opt_t *) di_data->options; di_data->zoneInfo = di_initialize_zones (diopts); if (diopts->optval [DI_OPT_DEBUG] > 0) { printf ("di version %s %s\n", DI_VERSION, DI_RELEASE_STATUS); } /* main processing */ if (di_get_disk_entries (di_data, &di_data->fscount) < 0) { return DI_EXIT_FAIL; } di_data->dispcount = di_data->fscount; if (diopts->optval [DI_OPT_DISP_TOTALS]) { di_data->dispcount += 1; } hasLoop = false; preCheckDiskInfo (di_data); if (diopts->optidx < diopts->argc || diopts->optval [DI_OPT_EXCL_LOOPBACK]) { getDiskStatInfo (di_data); hasLoop = getDiskSpecialInfo (di_data, diopts->optval [DI_OPT_NO_SYMLINK]); } if (diopts->optidx < diopts->argc) { int rc; rc = checkFileInfo (di_data); if (rc < 0) { return DI_EXIT_WARN; } } di_get_disk_info (di_data, &di_data->fscount); /* need the sort-by-filesystem before checkDiskInfo() is called */ if ((di_data->haspooledfs || diopts->optval [DI_OPT_DISP_TOTALS]) && ! di_data->totsorted) { di_sort_disk_info (diopts, di_data->diskInfo, di_data->fscount, "s", DI_SORT_TOTAL); di_data->totsorted = true; } if (strcmp (diopts->sortType, "n") != 0) { /* user's specified sort */ di_sort_disk_info (diopts, di_data->diskInfo, di_data->fscount, diopts->sortType, DI_SORT_MAIN); } checkDiskInfo (di_data, hasLoop); if (diopts->optval [DI_OPT_QUOTA_CHECK] == true) { checkDiskQuotas (di_data); } di_initialize_disk_info (&di_data->diskInfo [di_data->fscount], di_data->fscount); di_data->diskInfo [di_data->fscount].doPrint = 0; di_data->diskInfo [di_data->fscount].printFlag = DI_PRNT_SKIP; if (diopts->optval [DI_OPT_DISP_TOTALS]) { processTotals (di_data); } return DI_EXIT_NORM; } int di_iterate_init (void *tdi_data, int iteropt) { di_data_t *di_data = (di_data_t *) tdi_data; di_disk_info_t *dinfo; int i; int count; if (di_data->pub == NULL) { di_data->pub = (di_pub_disk_info_t *) malloc (sizeof (di_pub_disk_info_t)); } di_data->iteridx = 0; di_data->iteropt = iteropt; count = di_data->dispcount; if (iteropt == DI_ITER_PRINTABLE) { count = 0; for (i = 0; i < di_data->dispcount; ++i) { dinfo = &di_data->diskInfo [i]; if (dinfo->doPrint) { ++count; } } } return count; } const di_pub_disk_info_t * di_iterate (void *tdi_data) { di_data_t *di_data = (di_data_t *) tdi_data; di_pub_disk_info_t *pub; di_disk_info_t *dinfo; int i; int sortidx; if (di_data == NULL) { return NULL; } if (di_data->iteridx >= di_data->dispcount) { return NULL; } pub = (di_pub_disk_info_t *) di_data->pub; if (pub == NULL) { return NULL; } sortidx = di_data->diskInfo [di_data->iteridx].sortIndex [DI_SORT_MAIN]; dinfo = & (di_data->diskInfo [sortidx]); if (di_data->iteropt == DI_ITER_PRINTABLE) { while (! dinfo->doPrint) { ++di_data->iteridx; if (di_data->iteridx >= di_data->dispcount) { break; } sortidx = di_data->diskInfo [di_data->iteridx].sortIndex [DI_SORT_MAIN]; dinfo = & (di_data->diskInfo [sortidx]); } } if (di_data->iteridx >= di_data->dispcount) { return NULL; } /* populate pub structure */ pub->index = sortidx; for (i = 0; i < DI_DISP_MAX; ++i) { pub->strdata [i] = dinfo->strdata [i]; } pub->doPrint = dinfo->doPrint; pub->printFlag = dinfo->printFlag; pub->isLocal = dinfo->isLocal; pub->isReadOnly = dinfo->isReadOnly; pub->isLoopback = dinfo->isLoopback; ++di_data->iteridx; return pub; } int di_get_scale_max (void *tdi_data, int infoidx, int validxA, int validxB, int validxC) { di_data_t *di_data = (di_data_t *) tdi_data; di_opt_t *diopts; int scaleidx; dinum_t val; int i; if (di_data == NULL) { return DI_SCALE_GIGA; } if (infoidx < 0 || infoidx > di_data->dispcount) { return DI_SCALE_GIGA; } diopts = (di_opt_t *) di_data->options; init_scale_values (di_data, diopts); dinum_init (&val); di_calc_space (di_data, infoidx, validxA, validxB, validxC, &val); /* if the comparison loop doesn't find it, it's a large number */ scaleidx = DI_SCALE_MAX - 1; for (i = DI_SCALE_KILO; i < DI_SCALE_MAX; ++i) { if (dinum_cmp (&val, &di_data->scale_values [i]) < 0) { scaleidx = i - 1; break; } } dinum_clear (&val); return scaleidx; } double di_get_scaled (void *tdi_data, int infoidx, int scaleidx, int validxA, int validxB, int validxC) { di_data_t *di_data = (di_data_t *) tdi_data; di_opt_t *diopts; dinum_t val; double dval; if (di_data == NULL) { return 0.0; } if (infoidx < 0 || infoidx > di_data->dispcount) { return 0.0; } diopts = (di_opt_t *) di_data->options; init_scale_values (di_data, diopts); dinum_init (&val); di_calc_space (di_data, infoidx, validxA, validxB, validxC, &val); dval = dinum_scale (&val, &di_data->scale_values [scaleidx]); return dval; } void di_disp_scaled (void *tdi_data, char *buff, long sz, int infoidx, int scaleidx, int validxA, int validxB, int validxC) { di_data_t *di_data = (di_data_t *) tdi_data; double dval; *buff = '\0'; if (di_data == NULL) { return; } if (infoidx < 0 || infoidx > di_data->dispcount) { return; } dval = di_get_scaled (di_data, infoidx, scaleidx, validxA, validxB, validxC); if (scaleidx == DI_SCALE_BYTE) { Snprintf1 (buff, (Size_t) sz, "%.0f", dval); } else { Snprintf1 (buff, (Size_t) sz, "%.1f", dval); } } double di_get_perc (void *tdi_data, int infoidx, int validxA, int validxB, int validxC, int validxD, int validxE) { di_data_t *di_data = (di_data_t *) tdi_data; di_opt_t *diopts; double dval; if (di_data == NULL) { return 0.0; } if (infoidx < 0 || infoidx > di_data->dispcount) { return 0.0; } diopts = (di_opt_t *) di_data->options; init_scale_values (di_data, diopts); dval = di_calc_perc (di_data, infoidx, validxA, validxB, validxC, validxD, validxE); return dval; } void di_disp_perc (void *tdi_data, char *buff, long sz, int infoidx, int validxA, int validxB, int validxC, int validxD, int validxE) { di_data_t *di_data = (di_data_t *) tdi_data; double dval; *buff = '\0'; if (di_data == NULL) { return; } if (infoidx < 0 || infoidx >= di_data->dispcount) { return; } dval = di_get_perc (di_data, infoidx, validxA, validxB, validxC, validxD, validxE); Snprintf1 (buff, (Size_t) sz, "%.0f", dval); } /* internal routines */ static int checkFileInfo (di_data_t *di_data) { int rc; int i; int j; struct stat statBuf; di_opt_t *diopts; di_disk_info_t *diskInfo; rc = 0; diopts = (di_opt_t *) di_data->options; diskInfo = di_data->diskInfo; for (i = diopts->optidx; i < diopts->argc; ++i) { int fd; int src = -1; int saveIdx; int found = false; int inpool = false; Size_t lastpoollen = 0; char lastpool [DI_FILESYSTEM_LEN]; /* do this to automount devices. */ /* stat () will not necessarily cause an automount. */ fd = open (diopts->argv [i], O_RDONLY | O_NOCTTY); if (fd < 0) { src = stat (diopts->argv [i], &statBuf); } else { src = fstat (fd, &statBuf); } if (fd >= 0) { close (fd); } if (src != 0) { if (errno != EACCES && errno != EPERM) { fprintf (stderr, "stat: %s ", diopts->argv [i]); perror (""); } rc = -1; continue; } saveIdx = 0; /* should get overridden below */ for (j = 0; j < di_data->fscount; ++j) { di_disk_info_t *dinfo; int startpool; int poolmain; startpool = false; poolmain = false; dinfo = & (diskInfo [diskInfo [j].sortIndex [DI_SORT_TOTAL]]); /* is it a pooled filesystem type? */ if (di_data->haspooledfs && di_isPooledFs (dinfo)) { if (lastpoollen == 0 || strncmp (lastpool, dinfo->strdata [DI_DISP_FILESYSTEM], lastpoollen) != 0) { stpecpy (lastpool, lastpool + DI_FILESYSTEM_LEN, dinfo->strdata [DI_DISP_FILESYSTEM]); lastpoollen = di_mungePoolName (lastpool); inpool = false; } if (strncmp (lastpool, dinfo->strdata [DI_DISP_FILESYSTEM], lastpoollen) == 0) { startpool = true; if (inpool == false) { poolmain = true; } } } else { inpool = false; } if (poolmain) { saveIdx = j; } if (found && inpool) { dinfo = & (diskInfo [diskInfo [j].sortIndex [DI_SORT_TOTAL]]); dinfo->printFlag = DI_PRNT_SKIP; if (diopts->optval [DI_OPT_DEBUG] > 2) { printf (" inpool B: also process %s %s\n", dinfo->strdata [DI_DISP_FILESYSTEM], dinfo->strdata [DI_DISP_MOUNTPT]); } } /* when the filesystem name is specified on the command line */ /* report for that filesystem, not devfs or / */ if (strcmp (dinfo->strdata [DI_DISP_FILESYSTEM], diopts->argv [i]) == 0 || (dinfo->st_dev != (unsigned long) DI_UNKNOWN_DEV && (unsigned long) statBuf.st_dev == dinfo->st_dev && ! dinfo->isLoopback)) { int foundnew = 0; ++foundnew; if (dinfo->printFlag == DI_PRNT_OK) { ++foundnew; } if (! isIgnoreFSType (dinfo->strdata [DI_DISP_FSTYPE])) { ++foundnew; } if (foundnew == 3) { dinfo->printFlag = DI_PRNT_FORCE; found = true; } if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("file %s: found device or fs-match %ld : %d (%s %s)\n", diopts->argv [i], (long) dinfo->st_dev, foundnew, dinfo->strdata [DI_DISP_FILESYSTEM], dinfo->strdata [DI_DISP_MOUNTPT]); } if (inpool) { int k; for (k = saveIdx; k < j; ++k) { dinfo = & (diskInfo [diskInfo [k].sortIndex [DI_SORT_TOTAL]]); if (dinfo->printFlag != DI_PRNT_FORCE) { dinfo->printFlag = DI_PRNT_SKIP; } if (diopts->optval [DI_OPT_DEBUG] > 2) { printf (" inpool A: also process %s %s\n", dinfo->strdata [DI_DISP_FILESYSTEM], dinfo->strdata [DI_DISP_MOUNTPT]); } } } } if (startpool) { inpool = true; } } } /* for each file specified on command line */ /* turn everything off */ for (j = 0; j < di_data->fscount; ++j) { di_disk_info_t *dinfo; dinfo = &di_data->diskInfo [j]; if (dinfo->printFlag == DI_PRNT_OK) { dinfo->printFlag = DI_PRNT_IGNORE; } } /* also turn off the -I and -x lists */ diopts->include_list.count = 0; diopts->exclude_list.count = 0; return rc; } /* * getDiskStatInfo * * gets the disk device number for each entry. * */ static void getDiskStatInfo (di_data_t *di_data) { int i; struct stat statBuf; di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; for (i = 0; i < di_data->fscount; ++i) { di_disk_info_t *dinfo; dinfo = &di_data->diskInfo [i]; /* don't try to stat devices that are not accessible */ if (dinfo->printFlag == DI_PRNT_EXCLUDE || dinfo->printFlag == DI_PRNT_BAD || dinfo->printFlag == DI_PRNT_OUTOFZONE) { continue; } dinfo->st_dev = (unsigned long) DI_UNKNOWN_DEV; if (stat (dinfo->strdata [DI_DISP_MOUNTPT], &statBuf) == 0) { dinfo->st_dev = (unsigned long) statBuf.st_dev; if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("dev: %s: %ld\n", dinfo->strdata [DI_DISP_MOUNTPT], (long) dinfo->st_dev); } } else { if (errno != EACCES && errno != EPERM) { fprintf (stderr, "stat: %s ", dinfo->strdata [DI_DISP_MOUNTPT]); perror (""); } } } } /* * getDiskSpecialInfo * * gets the disk device number for each entry. * */ static int getDiskSpecialInfo (di_data_t *di_data, int dontResolveSymlink) { int i; struct stat statBuf; int hasLoop; di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; hasLoop = false; for (i = 0; i < di_data->fscount; ++i) { di_disk_info_t *dinfo; dinfo = &di_data->diskInfo [i]; /* check for initial slash; otherwise we can pick up normal files */ if (* (dinfo->strdata [DI_DISP_FILESYSTEM]) == '/' && stat (dinfo->strdata [DI_DISP_FILESYSTEM], &statBuf) == 0) { if (! dontResolveSymlink && checkForUUID (dinfo->strdata [DI_DISP_FILESYSTEM])) { #if _lib_realpath && _define_S_ISLNK && _lib_lstat int rc; struct stat tstatBuf; rc = lstat (dinfo->strdata [DI_DISP_FILESYSTEM], &tstatBuf); if (rc == 0 && S_ISLNK (tstatBuf.st_mode)) { char tspecial [DI_FILESYSTEM_LEN]; if (realpath (dinfo->strdata [DI_DISP_FILESYSTEM], tspecial) != (char *) NULL) { stpecpy (dinfo->strdata [DI_DISP_FILESYSTEM], dinfo->strdata [DI_DISP_FILESYSTEM] + DI_FILESYSTEM_LEN, tspecial); } } #endif } dinfo->sp_dev = (unsigned long) statBuf.st_dev; dinfo->sp_rdev = (unsigned long) statBuf.st_rdev; /* Solaris's loopback device is "lofs" */ /* linux loopback device is "none" */ /* linux has rdev = 0 */ /* DragonFlyBSD's loopback device is "null" */ /* but not with special = /.../@@- */ /* DragonFlyBSD has rdev = -1 */ /* solaris is more consistent; rdev != 0 for lofs */ /* solaris makes sense. */ if (di_isLoopbackFs (dinfo)) { dinfo->isLoopback = true; hasLoop = true; } if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("special dev: %s %s: %ld rdev: %ld loopback: %d\n", dinfo->strdata [DI_DISP_FILESYSTEM], dinfo->strdata [DI_DISP_MOUNTPT], (long) dinfo->sp_dev, (long) dinfo->sp_rdev, dinfo->isLoopback); } } else { dinfo->sp_dev = 0; dinfo->sp_rdev = 0; } } return hasLoop; } /* * checkDiskInfo * * checks the disk information returned for various return values. * */ static void checkDiskInfo (di_data_t *di_data, int hasLoop) { int i; int j; di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; for (i = 0; i < di_data->fscount; ++i) { di_disk_info_t *dinfo; dinfo = &di_data->diskInfo [i]; dinfo->doPrint = 1; /* these are never printed... */ if (dinfo->printFlag == DI_PRNT_EXCLUDE || dinfo->printFlag == DI_PRNT_BAD || dinfo->printFlag == DI_PRNT_OUTOFZONE) { if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("chk: skipping (%s):%s\n", getPrintFlagText ( (int) dinfo->printFlag), dinfo->strdata [DI_DISP_MOUNTPT]); } dinfo->doPrint = 0; continue; } /* need to check against include list */ if (dinfo->printFlag == DI_PRNT_IGNORE || dinfo->printFlag == DI_PRNT_SKIP) { if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("chk: skipping (%s):%s\n", getPrintFlagText ( (int) dinfo->printFlag), dinfo->strdata [DI_DISP_MOUNTPT]); } dinfo->doPrint = diopts->optval [DI_OPT_DISP_ALL]; } /* Solaris reports a cdrom as having no free blocks, */ /* no available. Their df doesn't always work right! */ /* -1 is returned. */ if (diopts->optval [DI_OPT_DEBUG] > 5) { char tbuff [100]; dinum_str (&dinfo->values [DI_SPACE_FREE], tbuff, sizeof (tbuff)); printf ("chk: %s free: %s\n", dinfo->strdata [DI_DISP_MOUNTPT], tbuff); } if (dinum_cmp_s (&dinfo->values [DI_SPACE_FREE], (di_si_t) -1) == 0 || dinum_cmp_s (&dinfo->values [DI_SPACE_FREE], (di_si_t) -2) == 0) { dinum_set_u (&dinfo->values [DI_SPACE_FREE], (di_ui_t) 0); } if (dinum_cmp_s (&dinfo->values [DI_SPACE_AVAIL], (di_si_t) -1) == 0 || dinum_cmp_s (&dinfo->values [DI_SPACE_AVAIL], (di_si_t) -2) == 0) { dinum_set_u (&dinfo->values [DI_SPACE_AVAIL], (di_ui_t) 0); } { dinum_t temp; dinum_init (&temp); dinum_set_u (&temp, (di_ui_t) ~0); if (dinum_cmp (&dinfo->values [DI_INODE_TOTAL], &temp) == 0) { dinum_set_u (&dinfo->values [DI_INODE_TOTAL], (di_ui_t) 0); dinum_set_u (&dinfo->values [DI_INODE_FREE], (di_ui_t) 0); dinum_set_u (&dinfo->values [DI_INODE_AVAIL], (di_ui_t) 0); } dinum_clear (&temp); } if (dinfo->printFlag == DI_PRNT_OK) { if (diopts->optval [DI_OPT_DEBUG] > 5) { char tbuff [100]; dinum_str (&dinfo->values [DI_SPACE_TOTAL], tbuff, sizeof (tbuff)); printf ("chk: %s total: %s\n", dinfo->strdata [DI_DISP_MOUNTPT], tbuff); } if (isIgnoreFSType (dinfo->strdata [DI_DISP_FSTYPE])) { dinfo->printFlag = DI_PRNT_IGNORE; dinfo->doPrint = diopts->optval [DI_OPT_DISP_ALL]; if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("chk: ignore-fstype: %s\n", dinfo->strdata [DI_DISP_FSTYPE]); } } if (isIgnoreFilesystem (dinfo->strdata [DI_DISP_FILESYSTEM])) { dinfo->printFlag = DI_PRNT_IGNORE; dinfo->doPrint = diopts->optval [DI_OPT_DISP_ALL]; if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("chk: ignore-filesystem: %s\n", dinfo->strdata [DI_DISP_FILESYSTEM]); } } if (isIgnoreFS (dinfo->strdata [DI_DISP_FSTYPE], dinfo->strdata [DI_DISP_MOUNTPT])) { dinfo->printFlag = DI_PRNT_IGNORE; dinfo->doPrint = diopts->optval [DI_OPT_DISP_ALL]; if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("chk: ignore-fs: %s\n", dinfo->strdata [DI_DISP_MOUNTPT]); } } /* Some systems return a -1 or -2 as an indicator. */ if (dinum_cmp_s (&dinfo->values [DI_SPACE_TOTAL], (di_si_t) 0) == 0 || dinum_cmp_s (&dinfo->values [DI_SPACE_TOTAL], (di_si_t) -1) == 0 || dinum_cmp_s (&dinfo->values [DI_SPACE_TOTAL], (di_si_t) -2L) == 0) { dinfo->printFlag = DI_PRNT_IGNORE; dinfo->doPrint = diopts->optval [DI_OPT_DISP_ALL]; if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("chk: ignore: values [DI_SPACE_TOTAL] <= 0: %s\n", dinfo->strdata [DI_DISP_MOUNTPT]); } } } /* make sure anything in the include list didn't get turned off */ checkIncludeList (di_data, dinfo, &diopts->include_list); } /* for all disks */ if (hasLoop && diopts->optval [DI_OPT_EXCL_LOOPBACK]) { /* this loop sets duplicate entries to be ignored. */ for (i = 0; i < di_data->fscount; ++i) { di_disk_info_t *dinfo; dinfo = &di_data->diskInfo [i]; if (dinfo->printFlag != DI_PRNT_OK) { if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("dup: chk: skipping (%s):%s\n", getPrintFlagText ( (int) dinfo->printFlag), dinfo->strdata [DI_DISP_MOUNTPT]); } continue; } /* don't need to bother checking real partitions */ if (dinfo->sp_dev != 0 && dinfo->isLoopback) { unsigned long sp_dev; unsigned long sp_rdev; sp_dev = dinfo->sp_dev; sp_rdev = dinfo->sp_rdev; if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("dup: chk: i: %s dev: %ld rdev: %ld\n", dinfo->strdata [DI_DISP_MOUNTPT], (long) sp_dev, (long) sp_rdev); } for (j = 0; j < di_data->fscount; ++j) { di_disk_info_t *dinfob; if (i == j) { continue; } dinfob = &di_data->diskInfo [j]; if (dinfob->sp_dev != 0 && dinfob->st_dev == sp_dev) { if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("dup: for %s %ld: found: %s %ld\n", dinfo->strdata [DI_DISP_MOUNTPT], (long) sp_dev, dinfob->strdata [DI_DISP_MOUNTPT], (long) dinfob->st_dev); } dinfo->printFlag = DI_PRNT_IGNORE; dinfo->doPrint = diopts->optval [DI_OPT_DISP_ALL]; if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("dup: chk: ignore: %s duplicate of %s\n", dinfo->strdata [DI_DISP_MOUNTPT], dinfob->strdata [DI_DISP_MOUNTPT]); printf ("dup: j: dev: %ld rdev: %ld \n", (long) dinfob->sp_dev, (long) dinfob->sp_rdev); } } /* if dup */ } } /* if this is a loopback, non-real */ else { if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("chk: dup: not checked: %s prnt: %d dev: %ld rdev: %ld %s\n", dinfo->strdata [DI_DISP_MOUNTPT], dinfo->printFlag, (long) dinfo->sp_dev, (long) dinfo->sp_rdev, dinfo->strdata [DI_DISP_FSTYPE]); } } } /* for each disk */ } /* if the duplicate loopback mounts are to be excluded */ } static void checkDiskQuotas (di_data_t *di_data) { int i; int j; Uid_t uid; Gid_t gid; di_quota_t diqinfo; di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; uid = 0; gid = 0; #if _has_std_quotas uid = geteuid (); gid = getegid (); #endif for (j = 0; j < DI_QVAL_MAX; ++j) { dinum_init (&diqinfo.values [j]); } if (diopts->optval [DI_OPT_DEBUG] > 0) { const char *str; int pos; /* freebsd 10.3 */ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunreachable-code" str = _lib_quotactl ? "quotactl" : ""; str = _lib_vquotactl ? "vquotactl" : str; str = _lib_quota_open ? "quota_open" : str; pos = _quotactl_pos_1 ? 1 : _quotactl_pos_2 ? 2 : 0; #pragma clang diagnostic pop printf ("# QUOTA: %d:%s(%d) nfs:%d\n", _has_std_quotas, str, pos, _has_std_nfs_quotas); } for (i = 0; i < di_data->fscount; ++i) { di_disk_info_t *dinfo; dinfo = &di_data->diskInfo [i]; if (! dinfo->doPrint) { continue; } diqinfo.filesystem = dinfo->strdata [DI_DISP_FILESYSTEM]; diqinfo.mountpt = dinfo->strdata [DI_DISP_MOUNTPT]; diqinfo.fstype = dinfo->strdata [DI_DISP_FSTYPE]; diqinfo.uid = uid; diqinfo.gid = gid; for (j = 0; j < DI_QVAL_MAX; ++j) { dinum_set_u (&diqinfo.values [j], (di_ui_t) 0); } diquota (di_data, &diqinfo); if (diopts->optval [DI_OPT_DEBUG] > 2) { char tbuff [100]; dinum_str (&diqinfo.values [DI_QUOTA_LIMIT], tbuff, sizeof (tbuff)); printf ("quota: %s limit: %s\n", dinfo->strdata [DI_DISP_MOUNTPT], tbuff); dinum_str (&dinfo->values [DI_SPACE_TOTAL], tbuff, sizeof (tbuff)); printf ("quota: tot: %s\n", tbuff); dinum_str (&diqinfo.values [DI_QUOTA_USED], tbuff, sizeof (tbuff)); printf ("quota: %s used: %s\n", dinfo->strdata [DI_DISP_MOUNTPT], tbuff); dinum_str (&dinfo->values [DI_SPACE_AVAIL], tbuff, sizeof (tbuff)); printf ("quota: avail: %s\n", tbuff); } if (dinum_cmp_s (&diqinfo.values [DI_QUOTA_LIMIT], (di_si_t) 0) != 0 && dinum_cmp (&diqinfo.values [DI_QUOTA_LIMIT], &dinfo->values [DI_SPACE_TOTAL]) < 0) { dinum_t tsize; dinum_init (&tsize); dinum_set (&dinfo->values [DI_SPACE_TOTAL], &diqinfo.values [DI_QUOTA_LIMIT]); dinum_set (&tsize, &diqinfo.values [DI_QUOTA_LIMIT]); dinum_sub (&tsize, &diqinfo.values [DI_QUOTA_USED]); if (dinum_cmp_s (&tsize, (di_si_t) 0) < 0) { dinum_set_s (&tsize, (di_si_t) 0); } if (dinum_cmp (&tsize, &dinfo->values [DI_SPACE_AVAIL]) < 0) { dinum_set (&dinfo->values [DI_SPACE_AVAIL], &tsize); dinum_set (&dinfo->values [DI_SPACE_FREE], &tsize); if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("quota: using quota for: total free avail\n"); } } else if (dinum_cmp (&tsize, &dinfo->values [DI_SPACE_AVAIL]) > 0 && dinum_cmp (&tsize, &dinfo->values [DI_SPACE_FREE]) < 0) { dinum_set (&dinfo->values [DI_SPACE_FREE], &tsize); if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("quota: using quota for: total free\n"); } } else { if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("quota: using quota for: total\n"); } } dinum_clear (&tsize); } if (dinum_cmp_s (&diqinfo.values [DI_QUOTA_ILIMIT], (di_si_t) 0) != 0 && dinum_cmp (&diqinfo.values [DI_QUOTA_ILIMIT], &dinfo->values [DI_INODE_TOTAL]) < 0) { dinum_t tsize; dinum_init (&tsize); dinum_set (&dinfo->values [DI_INODE_TOTAL], &diqinfo.values [DI_QUOTA_ILIMIT]); dinum_set (&tsize, &diqinfo.values [DI_QUOTA_ILIMIT]); dinum_sub (&tsize, &diqinfo.values [DI_QUOTA_IUSED]); if (dinum_cmp_s (&tsize, (di_si_t) 0) < 0) { dinum_set_u (&tsize, (di_ui_t) 0); } if (dinum_cmp (&tsize, &dinfo->values [DI_INODE_AVAIL]) < 0) { dinum_set (&dinfo->values [DI_INODE_AVAIL], &tsize); dinum_set (&dinfo->values [DI_INODE_FREE], &tsize); if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("quota: using quota for inodes: total free avail\n"); } } else if (dinum_cmp (&tsize, &dinfo->values [DI_INODE_AVAIL]) > 0 && dinum_cmp (&tsize, &dinfo->values [DI_INODE_FREE]) < 0) { dinum_set (&dinfo->values [DI_INODE_FREE], &tsize); if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("quota: using quota for inodes: total free\n"); } } else { if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("quota: using quota for inodes: total\n"); } } } } for (j = 0; j < DI_QVAL_MAX; ++j) { dinum_clear (&diqinfo.values [j]); } return; } /* * preCheckDiskInfo * * checks for ignore/include list; check for remote filesystems * and local only flag set. * checks for zones (Solaris) * */ static void preCheckDiskInfo (di_data_t *di_data) { int i; di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; for (i = 0; i < di_data->fscount; ++i) { di_disk_info_t *dinfo; dinfo = &di_data->diskInfo [i]; if (diopts->optval [DI_OPT_DEBUG] > 4) { printf ("## prechk:%s:\n", dinfo->strdata [DI_DISP_MOUNTPT]); } checkZone (dinfo, (di_zone_info_t *) di_data->zoneInfo, diopts); if (di_isPooledFs (dinfo)) { di_data->haspooledfs = true; } if (dinfo->printFlag == DI_PRNT_OK) { /* don't bother w/this check is all flag is set. */ if (! diopts->optval [DI_OPT_DISP_ALL]) { di_is_remote_disk (dinfo); if (dinfo->isLocal == false && diopts->optval [DI_OPT_LOCAL_ONLY]) { dinfo->printFlag = DI_PRNT_IGNORE; if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("prechk: ignore: remote disk; local flag set: %s\n", dinfo->strdata [DI_DISP_MOUNTPT]); } } } } if (dinfo->printFlag == DI_PRNT_OK || dinfo->printFlag == DI_PRNT_IGNORE) { /* do these checks to override the all flag */ checkExcludeList (di_data, dinfo, &diopts->exclude_list); checkIncludeList (di_data, dinfo, &diopts->include_list); } } /* for all disks */ } static void checkExcludeList (di_data_t *di_data, di_disk_info_t *dinfo, di_strarr_t *exclude_list) { char *ptr; Size_t i; di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; /* if the file system type is in the ignore list, skip it */ if (exclude_list->count > 0) { for (i = 0; i < exclude_list->count; ++i) { ptr = exclude_list->list [i]; if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("chkign: test: fstype %s/%s : %s\n", ptr, dinfo->strdata [DI_DISP_FSTYPE], dinfo->strdata [DI_DISP_MOUNTPT]); } if (strcmp (ptr, dinfo->strdata [DI_DISP_FSTYPE]) == 0 || (strcmp (ptr, "fuse") == 0 && strncmp ("fuse", dinfo->strdata [DI_DISP_FSTYPE], (Size_t) 4) == 0)) { dinfo->printFlag = DI_PRNT_EXCLUDE; dinfo->doPrint = false; if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("chkign: ignore: fstype %s match: %s\n", ptr, dinfo->strdata [DI_DISP_MOUNTPT]); } break; } } } /* if an ignore list was specified */ } static void checkIncludeList (di_data_t *di_data, di_disk_info_t *dinfo, di_strarr_t *include_list) { char *ptr; Size_t i; di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; /* if the file system type is not in the include list, skip it */ if (include_list->count > 0) { for (i = 0; i < include_list->count; ++i) { ptr = include_list->list [i]; if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("chkinc: test: fstype %s/%s : %s\n", ptr, dinfo->strdata [DI_DISP_FSTYPE], dinfo->strdata [DI_DISP_MOUNTPT]); } if (strcmp (ptr, dinfo->strdata [DI_DISP_FSTYPE]) == 0 || (strcmp (ptr, "fuse") == 0 && strncmp ("fuse", dinfo->strdata [DI_DISP_FSTYPE], (Size_t) 4) == 0)) { dinfo->printFlag = DI_PRNT_OK; dinfo->doPrint = true; if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("chkinc:include:fstype %s match: %s\n", ptr, dinfo->strdata [DI_DISP_MOUNTPT]); } break; } else { dinfo->printFlag = DI_PRNT_EXCLUDE; dinfo->doPrint = false; if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("chkinc:!include:fstype %s no match: %s\n", ptr, dinfo->strdata [DI_DISP_MOUNTPT]); } } } } /* if an include list was specified */ } static void checkZone (di_disk_info_t *dinfo, di_zone_info_t *zoneInfo, di_opt_t *diopts) { #if _lib_zone_list && _lib_getzoneid && _lib_zone_getattr int i; int idx = -1; if (zoneInfo == NULL) { return; } if (strcmp (diopts->zoneDisplay, "all") == 0 && zoneInfo->uid == 0) { return; } for (i = 0; i < (int) zoneInfo->zoneCount; ++i) { /* find the zone the filesystem is in, if non-global */ if (diopts->optval [DI_OPT_DEBUG] > 5) { printf (" checkZone:%s:compare:%d:%s:\n", dinfo->strdata [DI_DISP_MOUNTPT], (int) zoneInfo->zones [i].rootpathlen, zoneInfo->zones [i].rootpath); } if (strncmp (zoneInfo->zones [i].rootpath, dinfo->strdata [DI_DISP_MOUNTPT], zoneInfo->zones [i].rootpathlen) == 0) { if (diopts->optval [DI_OPT_DEBUG] > 4) { printf (" checkZone:%s:found zone:%s:\n", dinfo->strdata [DI_DISP_MOUNTPT], zoneInfo->zones [i].name); } idx = i; break; } if (idx == -1) { idx = zoneInfo->globalIdx; } } /* no root access, ignore any zones */ /* that don't match our zone id */ /* this will override any ignore flags */ /* already set */ if (zoneInfo->uid != 0) { if (diopts->optval [DI_OPT_DEBUG] > 5) { printf (" checkZone:uid non-zero:chk zone:%d:%d:\n", (int) zoneInfo->myzoneid, (int) zoneInfo->zones [idx].zoneid); } if (zoneInfo->myzoneid != zoneInfo->zones [idx].zoneid) { if (diopts->optval [DI_OPT_DEBUG] > 4) { printf (" checkZone:not root, not zone:%d:%d:outofzone:\n", (int) zoneInfo->myzoneid, (int) zoneInfo->zones [idx].zoneid); } dinfo->printFlag = DI_PRNT_OUTOFZONE; } } if (diopts->optval [DI_OPT_DEBUG] > 5) { printf (" checkZone:chk name:%s:%s:\n", diopts->zoneDisplay, zoneInfo->zones [idx].name); } /* not the zone we want. ignore */ if (! diopts->optval [DI_OPT_DISP_ALL] && dinfo->printFlag == DI_PRNT_OK && strcmp (diopts->zoneDisplay, "all") != 0 && strcmp (diopts->zoneDisplay, zoneInfo->zones [idx].name) != 0) { if (diopts->optval [DI_OPT_DEBUG] > 4) { printf (" checkZone:wrong zone:ignore:\n"); } dinfo->printFlag = DI_PRNT_IGNORE; } /* if displaying a non-global zone, */ /* don't display loopback filesystems */ if (! diopts->optval [DI_OPT_DISP_ALL] && dinfo->printFlag == DI_PRNT_OK && strcmp (diopts->zoneDisplay, "global") != 0 && dinfo->isLoopback) { if (diopts->optval [DI_OPT_DEBUG] > 4) { printf (" checkZone:non-global/lofs:ignore:\n"); } dinfo->printFlag = DI_PRNT_IGNORE; } #endif return; } static int isIgnoreFilesystem (const char *filesystem) { static const char *appletimemachine = "com.apple.TimeMachine."; if (strncmp (filesystem, appletimemachine, strlen (appletimemachine)) == 0) { return true; } return false; } static int isIgnoreFS (const char *fstype, const char *name) { static const char *applesystem = "/System/"; if (strcmp (fstype, "apfs") == 0 && strncmp (name, applesystem, strlen (applesystem)) == 0) { return true; } return false; } static int isIgnoreFSType (const char *fstype) { /* solaris: swap */ /* linux: cgroup, tmpfs, squashfs, overlay */ if (strcmp (fstype, "rootfs") == 0 || strcmp (fstype, "procfs") == 0 || strcmp (fstype, "ptyfs") == 0 || strcmp (fstype, "kernfs") == 0 || strcmp (fstype, "devfs") == 0 || strcmp (fstype, "tmpfs") == 0 || strcmp (fstype, "cgroup") == 0 || strcmp (fstype, "swap") == 0 || strcmp (fstype, "squashfs") == 0 || strcmp (fstype, "overlay") == 0 || strcmp (fstype, "devtmpfs") == 0) { return true; } return false; } static int checkForUUID (const char *spec) { #if _lib_realpath && _define_S_ISLNK && _lib_lstat /* * /dev/mapper/luks-828fc648-9f30-43d8-a0b1-f7196a2edb66 * /dev/disk/by-uuid/cfbbd7b3-b37a-4587-a711-58fd36b2cac6 * 1 2 3 4 * 01234567890123456789012345678901234567890 * cfbbd7b3-b37a-4587-a711-58fd36b2cac6 */ Size_t len; len = strlen (spec); if (len > 36) { Size_t offset; offset = len - 36; if (* (spec + offset + 8) == '-' && * (spec + offset + 13) == '-' && * (spec + offset + 18) == '-' && * (spec + offset + 23) == '-' && strspn (spec + offset, "-1234567890abcdef") == 36) { return true; } } #endif /* have _lib_realpath, etc. */ return false; } /* for diopts->optval [DI_OPT_DEBUG]ging */ static const char * getPrintFlagText (int pf) { return pf == DI_PRNT_OK ? "ok" : pf == DI_PRNT_BAD ? "bad" : pf == DI_PRNT_IGNORE ? "ignore" : pf == DI_PRNT_EXCLUDE ? "exclude" : pf == DI_PRNT_OUTOFZONE ? "outofzone" : pf == DI_PRNT_FORCE ? "force" : pf == DI_PRNT_SKIP ? "skip" : "unknown"; } static void di_sort_disk_info (di_opt_t *diopts, di_disk_info_t *data, int count, const char *sortType, int sidx) { int tempIndex; int gap; int j; int i; if (count <= 1) { return; } gap = 1; while (gap < count) { gap = 3 * gap + 1; } for (gap /= 3; gap > 0; gap /= 3) { for (i = gap; i < count; ++i) { tempIndex = data [i].sortIndex [sidx]; j = i - gap; while (j >= 0 && di_sort_compare (diopts, sortType, data, data [j].sortIndex [sidx], tempIndex) > 0) { data [j + gap].sortIndex [sidx] = data [j].sortIndex [sidx]; j -= gap; } j += gap; if (j != i) { data [j].sortIndex [sidx] = tempIndex; } } } } static int di_sort_compare (const di_opt_t *diopts, const char *sortType, const di_disk_info_t *data, int idx1, int idx2) { int rc; int sortOrder; const char *ptr; const di_disk_info_t *d1; const di_disk_info_t *d2; /* reset sort order to the default start value */ sortOrder = DI_SORT_OPT_ASCENDING; rc = 0; d1 = & (data [idx1]); d2 = & (data [idx2]); ptr = sortType; while (*ptr) { switch (*ptr) { case DI_SORT_OPT_NONE: { break; } case DI_SORT_OPT_MOUNT: { rc = strcoll (d1->strdata [DI_DISP_MOUNTPT], d2->strdata [DI_DISP_MOUNTPT]); rc *= sortOrder; break; } case DI_SORT_OPT_REVERSE: { sortOrder *= -1; break; } case DI_SORT_OPT_FILESYSTEM: { rc = strcoll (d1->strdata [DI_DISP_FILESYSTEM], d2->strdata [DI_DISP_FILESYSTEM]); rc *= sortOrder; break; } case DI_SORT_OPT_TYPE: { rc = strcoll (d1->strdata [DI_DISP_FSTYPE], d2->strdata [DI_DISP_FSTYPE]); rc *= sortOrder; break; } case DI_SORT_OPT_AVAIL: case DI_SORT_OPT_FREE: case DI_SORT_OPT_TOTAL: { switch (*ptr) { case DI_SORT_OPT_AVAIL: { rc = dinum_cmp (&d1->values [DI_SPACE_AVAIL], &d2->values [DI_SPACE_AVAIL]); break; } case DI_SORT_OPT_FREE: { rc = dinum_cmp (&d1->values [DI_SPACE_FREE], &d2->values [DI_SPACE_FREE]); break; } case DI_SORT_OPT_TOTAL: { rc = dinum_cmp (&d1->values [DI_SPACE_TOTAL], &d2->values [DI_SPACE_TOTAL]); break; } default: { break; } } rc *= sortOrder; break; } default: { break; } } /* switch on sort type */ if (rc != 0) { return rc; } ++ptr; } return rc; } static void init_scale_values (di_data_t *di_data, di_opt_t *diopts) { int i; dinum_t base; if (di_data->scale_values_init) { return; } for (i = 0; i < DI_SCALE_MAX; ++i) { dinum_init (&di_data->scale_values [i]); } dinum_init (&base); dinum_set_u (&base, (di_ui_t) diopts->blockSize); dinum_set_u (&di_data->scale_values [DI_SCALE_BYTE], (di_ui_t) 1); for (i = DI_SCALE_KILO; i < DI_SCALE_MAX; ++i) { dinum_set (&di_data->scale_values [i], &base); dinum_mul (&di_data->scale_values [i], &di_data->scale_values [i - 1]); } di_data->scale_values_init = 1; dinum_clear (&base); } static void di_calc_space (di_data_t *di_data, int infoidx, int validxA, int validxB, int validxC, dinum_t *val) { dinum_t sub; di_disk_info_t *dinfo; dinfo = &di_data->diskInfo [infoidx]; dinum_init (&sub); dinum_set_u (&sub, (di_ui_t) 0); if (validxB != DI_VALUE_NONE) { dinum_set (&sub, &dinfo->values [validxB]); } if (validxB != DI_VALUE_NONE && validxC != DI_VALUE_NONE) { dinum_sub (&sub, &dinfo->values [validxC]); } dinum_set (val, &dinfo->values [validxA]); if (dinum_cmp_s (val, (di_si_t) 0) == 0) { dinum_set_u (val, (di_ui_t) 0); } else { dinum_sub (val, &sub); } dinum_clear (&sub); } static double di_calc_perc (di_data_t *di_data, int infoidx, int validxA, int validxB, int validxC, int validxD, int validxE) { dinum_t subd; dinum_t subr; dinum_t dividend; dinum_t divisor; di_disk_info_t *dinfo; double dval; dinfo = &di_data->diskInfo [infoidx]; dinum_init (&subd); dinum_init (&subr); dinum_init (÷nd); dinum_init (&divisor); dinum_set_u (&subd, (di_ui_t) 0); dinum_set_u (&subr, (di_ui_t) 0); if (validxB != DI_VALUE_NONE) { dinum_set (&subd, &dinfo->values [validxB]); } dinum_set (÷nd, &dinfo->values [validxA]); dinum_sub (÷nd, &subd); if (validxD != DI_VALUE_NONE) { dinum_set (&subr, &dinfo->values [validxD]); } if (validxD != DI_VALUE_NONE && validxE != DI_VALUE_NONE) { dinum_sub (&subr, &dinfo->values [validxE]); } dinum_set (&divisor, &dinfo->values [validxC]); dinum_sub (&divisor, &subr); if (dinum_cmp_s (&divisor, (di_si_t) 0) == 0) { dval = 0.0; } else { dval = dinum_perc (÷nd, &divisor); } dinum_clear (&subd); dinum_clear (&subr); dinum_clear (÷nd); dinum_clear (&divisor); return dval; } static void processTotals (di_data_t *di_data) { int i; Size_t lastpoollen = 0; char lastpool [DI_FILESYSTEM_LEN]; int inpool = 0; di_disk_info_t *totals; di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; /* all of the space allocations for diskinfo have + 1 */ /* count is the number of filesystems */ totals = &di_data->diskInfo [di_data->fscount]; totals->doPrint = 1; totals->printFlag = DI_PRNT_OK; for (i = 0; i < di_data->fscount; ++i) { di_disk_info_t *dinfo; int sortidx; int startpool; startpool = false; sortidx = di_data->diskInfo [i].sortIndex [DI_SORT_TOTAL]; dinfo = & (di_data->diskInfo [sortidx]); /* is it a pooled filesystem type? */ if (di_data->haspooledfs && di_isPooledFs (dinfo)) { if (lastpoollen == 0 || strncmp (lastpool, dinfo->strdata [DI_DISP_FILESYSTEM], lastpoollen) != 0) { stpecpy (lastpool, lastpool + DI_FILESYSTEM_LEN, dinfo->strdata [DI_DISP_FILESYSTEM]); lastpoollen = di_mungePoolName (lastpool); inpool = false; startpool = true; if (strcmp (dinfo->strdata [DI_DISP_FSTYPE], "null") == 0 && strcmp (dinfo->strdata [DI_DISP_FILESYSTEM] + strlen (dinfo->strdata [DI_DISP_FILESYSTEM]) - 5, "00000") != 0) { /* dragonflybsd doesn't have the main pool mounted */ inpool = true; } } } else { inpool = false; } if (dinfo->doPrint) { addTotals (di_data, dinfo, totals, inpool); } else { if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("tot:%s:%s:skip\n", dinfo->strdata [DI_DISP_FILESYSTEM], dinfo->strdata [DI_DISP_MOUNTPT]); } } if (startpool) { inpool = true; } } /* for each entry */ } static void addTotals (di_data_t *di_data, const di_disk_info_t *dinfo, di_disk_info_t *totals, int inpool) { di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("tot:%s:%s:inp:%d\n", dinfo->strdata [DI_DISP_FILESYSTEM], dinfo->strdata [DI_DISP_MOUNTPT], inpool); } /* * zfs: * The total is the space used + the space free. * Free space is the space available in the pool. * Available space is the space available in the pool. * Thus: total - free = used. * -- To get the real total, add the total for the pool * and all used space for all inpool filesystems. * * apfs: * An easy hierarchy: * /dev/disk1 the container, is not mounted. * /dev/disk1s1 partition 1 * /dev/disk1s2 partition 2 * /dev/disk1s3 partition 3 * The first disk is used as the root of the pool, even though it * is not the container. * The total is the total space. * Free space is the space available + space used. * (or total space - space used). * Available space is the space available in the pool. * Thus: total - free = used. * -- To get (totals - free) to work for the totals, subtract * all free space returned by in-pool filesystems. * * hammer, hammer2: * Typically, a null mount is used such as: * /dev/serno/SERIAL.s1a /build hammer * /build/usr /usr null * /build/usr.local /usr/local null * There are also pfs mounts: * /dev/ad1s1a@LOCAL /d1 hammer2 * /dev/ad1s1a@d1.a /d1/a hammer2 * Or * /dev/serno/SERIAL.s1a /mnt hammer2 * /dev/serno/SERIAL.s1a@mnt.usr /mnt/usr hammer2 * Or * @build /build hammer2 * @build.var /build/var null * Difficult to process, as the naming is not consistent. * Not implemented. * * advfs: * Unknown. Assume the same as zfs. */ if (inpool) { if (diopts->optval [DI_OPT_DEBUG] > 2) { printf (" tot:inpool:\n"); } if (strcmp (dinfo->strdata [DI_DISP_FSTYPE], "apfs") == 0) { dinum_t tval; dinum_init (&tval); dinum_set (&tval, &dinfo->values [DI_SPACE_TOTAL]); dinum_sub (&tval, &dinfo->values [DI_SPACE_FREE]); dinum_sub (&totals->values [DI_SPACE_FREE], &tval); dinum_clear (&tval); } else { /* zfs, old hammer, advfs */ dinum_t tval; dinum_init (&tval); dinum_set (&tval, &dinfo->values [DI_SPACE_TOTAL]); dinum_sub (&tval, &dinfo->values [DI_SPACE_FREE]); dinum_add (&totals->values [DI_SPACE_TOTAL], &tval); dinum_set (&tval, &dinfo->values [DI_INODE_TOTAL]); dinum_sub (&tval, &dinfo->values [DI_INODE_FREE]); dinum_add (&totals->values [DI_INODE_TOTAL], &tval); dinum_clear (&tval); } } else { if (diopts->optval [DI_OPT_DEBUG] > 2) {printf (" tot:not inpool:add all totals\n"); } dinum_add (&totals->values [DI_SPACE_TOTAL], &dinfo->values [DI_SPACE_TOTAL]); dinum_add (&totals->values [DI_SPACE_FREE], &dinfo->values [DI_SPACE_FREE]); dinum_add (&totals->values [DI_SPACE_AVAIL], &dinfo->values [DI_SPACE_AVAIL]); dinum_add (&totals->values [DI_INODE_TOTAL], &dinfo->values [DI_INODE_TOTAL]); dinum_add (&totals->values [DI_INODE_FREE], &dinfo->values [DI_INODE_FREE]); dinum_add (&totals->values [DI_INODE_AVAIL], &dinfo->values [DI_INODE_AVAIL]); } } di-6.0.0/dizone.h0000644000175000017500000000162114746003705011664 0ustar bllbll/* Copyright 2025 Brad Lanam Pleasant Hill CA */ #ifndef INC_DIZONE_H #define INC_DIZONE_H #include "config.h" #include "disystem.h" #include "dioptions.h" #if _hdr_unistd # include #endif #if _hdr_zone # include #endif # if defined (__cplusplus) || defined (c_plusplus) extern "C" { # endif #if ! _lib_zone_list # define zoneid_t int # define ZONENAME_MAX 65 #endif typedef struct { zoneid_t zoneid; char name [ZONENAME_MAX]; char rootpath [MAXPATHLEN]; Size_t rootpathlen; } di_zone_summ_t; typedef struct { Uid_t uid; zoneid_t myzoneid; di_zone_summ_t *zones; unsigned int zoneCount; int globalIdx; } di_zone_info_t; di_zone_info_t *di_initialize_zones (di_opt_t *diopts); void di_free_zones (di_zone_info_t *); # if defined (__cplusplus) || defined (c_plusplus) } # endif #endif /* INC_DIZONE_H */ di-6.0.0/dioptions.h0000644000175000017500000000272614761606413012415 0ustar bllbll/* Copyright 2023-2025 Brad Lanam, Pleasant Hill, CA */ #ifndef INC_DIOPTIONS_H #define INC_DIOPTIONS_H #include "disystem.h" #include "di.h" #include "getoptn.h" # if defined (__cplusplus) || defined (c_plusplus) extern "C" { # endif #define DI_BLKSZ_1 1 #define DI_BLKSZ_1000 1000 #define DI_BLKSZ_1024 1024 #define DI_SORT_TYPE_MAX 10 typedef struct { Size_t count; char **list; } di_strarr_t; typedef struct di_opt { getoptn_opt_t *opts; const char ** argv; const char *formatString; di_strarr_t exclude_list; di_strarr_t include_list; char zoneDisplay [MAXPATHLEN]; int optinit; /* will be either 1000 or 1024 */ int blockSize; int scale; char sortType [DI_SORT_TYPE_MAX]; int optval [DI_OPT_MAX]; int exitFlag; int formatLen; int errorCount; int optidx; int argc; int optiteridx; } di_opt_t; extern di_opt_t * di_init_options (void); extern void di_opt_cleanup (di_opt_t *diopts); extern int di_get_options (int argc, const char * argv [], di_opt_t *diopts, int offset); extern void di_opt_format_iter_init (di_opt_t *diopts); extern int di_opt_format_iterate (di_opt_t *diopts); int di_opt_check_option (di_opt_t *diopts, int optidx); # if defined (__cplusplus) || defined (c_plusplus) } # endif #endif /* INC_DIOPTIONS_H */ di-6.0.0/CMakeLists.txt0000644000175000017500000011141714762361126012772 0ustar bllbll# # Copyright 2025 Brad Lanam Pleasant Hill CA # cmake_minimum_required (VERSION 3.13) # avoid msys2/windows issue set (CMAKE_C_COMPILER_WORKS 1) ### # load the DI_* variables from VERSION.txt file (STRINGS VERSION.txt tdivars) foreach (tvar IN LISTS tdivars) # the export lines are not needed if (tvar MATCHES "=") string (REGEX MATCH "^[^=]*" tnm ${tvar}) string (REGEX MATCH "=.*" tvala ${tvar}) string (REPLACE "=" "" tval ${tvala}) set (${tnm} ${tval}) endif() endforeach() ### # also set DI_USE_MATH from the environment if there if (DEFINED ENV{DI_USE_MATH}) set (DI_USE_MATH $ENV{DI_USE_MATH}) # these are the only supported values as of 2025-2-6 if (NOT DI_USE_MATH STREQUAL "DI_INTERNAL" AND NOT DI_USE_MATH STREQUAL "DI_GMP" AND NOT DI_USE_MATH STREQUAL "DI_TOMMATH") unset (DI_USE_MATH) endif() endif() if (NOT DEFINED DI_BUILD_SYS OR DI_BUILD_SYS STREQUAL "") set (DI_BUILD_SYS cmake) endif() ### # check to make sure cmake-install-prefix is set if (NOT DEFINED CMAKE_INSTALL_PREFIX OR CMAKE_INSTALL_PREFIX STREQUAL "") message (FATAL_ERROR "CMAKE_INSTALL_PREFIX is not set") endif() project (DI VERSION ${DI_VERSION} DESCRIPTION "di - disk information utility" HOMEPAGE_URL "https://diskinfo-di.sourceforge.io" LANGUAGES C ) option (BUILD_SHARED_LIBS "Build dynamic library" ON) set (default_build_type "Release") include (GNUInstallDirs) set (DI_LIBNAME libdi) SET (CMAKE_SKIP_BUILD_RPATH FALSE) SET (CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) if (DEFINED ENV{CMAKE_SKIP_RPATH} AND NOT ENV{CMAKE_SKIP_RPATH} STREQUAL "") set (CMAKE_SKIP_RPATH "$ENV{CMAKE_SKIP_RPATH}") endif() include (CheckCCompilerFlag) include (CheckLinkerFlag) include (CheckIncludeFile) include (CheckIncludeFiles) include (CheckLibraryExists) include (CheckLinkerFlag) include (CheckStructHasMember) include (CheckSymbolExists) include (CheckTypeSize) include (CheckVariableExists) include (CheckPrototypeDefinition) if (APPLE) # MacOS cmake uses a path for the compiler that doesn't # have the proper include paths built in. /usr/bin/clang # works with command line tools, but apparently not for xcode. # if the SDKROOT environment variable is not set, set it. if (NOT DEFINED ENV{SDKROOT}) execute_process ( OUTPUT_VARIABLE sdktemp ERROR_QUIET COMMAND xcrun --sdk macosx --show-sdk-path COMMAND tr -d "\n" ) if (DEFINED sdktemp AND NOT sdktemp STREQUAL "") set (ENV{SDKROOT} ${sdktemp}) endif() endif() endif() #### compile options macro (checkAddCompileFlag flag) string (REPLACE "-" "_" tflag ${flag}) string (REPLACE "=" "_" tflag ${tflag}) check_c_compiler_flag (${flag} cfchk${tflag}) if (cfchk${tflag}) add_compile_options (${flag}) endif() endmacro() macro (checkAddLinkFlag flag) string (REPLACE "-" "_" tflag ${flag}) string (REPLACE "=" "_" tflag ${tflag}) check_linker_flag ("C" ${flag} lfchk${tflag}) if (lfchk${tflag}) add_link_options (${flag}) endif() endmacro() checkAddCompileFlag ("-fPIC") checkAddLinkFlag ("-fPIC") checkAddCompileFlag ("-Wall") checkAddCompileFlag ("-Wextra") checkAddCompileFlag ("-Wconversion") checkAddCompileFlag ("-Wno-unused-but-set-variable") checkAddCompileFlag ("-Wno-unused-parameter") checkAddCompileFlag ("-Wno-unknown-pragmas") checkAddCompileFlag ("-Wno-float-equal") checkAddCompileFlag ("-Wformat") checkAddCompileFlag ("-Wformat-security") checkAddCompileFlag ("-Werror=format-security") checkAddCompileFlag ("-Werror=return-type") checkAddCompileFlag ("-Wdeprecated-declarations") checkAddCompileFlag ("-Wunreachable-code") # these don't work w/c++ checkAddCompileFlag ("-Wdeclaration-after-statement") checkAddCompileFlag ("-Wmissing-prototypes") #### compiler-specific compile options checkAddCompileFlag ("-Wmaybe-uninitialized") checkAddCompileFlag ("-Wno-unused-but-set-variable") checkAddCompileFlag ("-Wno-stringop-overflow") checkAddCompileFlag ("-Wno-stringop-truncation") checkAddCompileFlag ("-Wno-format-truncation") checkAddCompileFlag ("-Wno-extra-semi-stmt") checkAddCompileFlag ("-Wno-poison-system-directories") checkAddCompileFlag ("-Wno-shift-sign-overflow") checkAddCompileFlag ("-Wno-pragma-pack") checkAddCompileFlag ("-Wno-ignored-attributes") checkAddCompileFlag ("-Wno-reserved-macro-identifier") checkAddCompileFlag ("-Wno-reserved-id-macro") checkAddCompileFlag ("-Wno-implicit-int-conversion") checkAddCompileFlag ("-Wno-switch-enum") checkAddCompileFlag ("-Wno-gnu-zero-variadic-macro-arguments") checkAddCompileFlag ("-Wno-documentation-deprecated-sync") checkAddCompileFlag ("-Wno-documentation-unknown-command") checkAddCompileFlag ("-Wno-documentation") checkAddCompileFlag ("-Wno-unsafe-buffer-usage") # llvm-19 creating errors about *printf checkAddCompileFlag ("-Wno-used-but-marked-unused") ### # LFS_CFLAGS, LFS_LDFLAGS, LFS_LIBS macro (applygetconfflags which) execute_process ( OUTPUT_VARIABLE lfs${which} ERROR_QUIET COMMAND getconf LFS_${which} COMMAND tr -d "\n" ) separate_arguments (lfsl${which} UNIX_COMMAND ${lfs${which}}) if (DEFINED lfs${which} AND NOT lfs${which} STREQUAL "") message ("-- getconf: ${which}: ${lfs${which}}") foreach (tvar IN LISTS lfsl${which}) if (${which} STREQUAL "CFLAGS") add_compile_options (${tvar}) endif() if (${which} STREQUAL "LDFLAGS") add_link_options (${tvar}) endif() if (${which} STREQUAL "LIBS") # extremely rare, if ever link_libraries (${tvar}) endif() endforeach() endif() endmacro() message ("-- Getting LFS flags via getconf") applygetconfflags ("CFLAGS") applygetconfflags ("LDFLAGS") applygetconfflags ("LIBS") #### build compile options if (NOT DEFINED DI_BUILD OR DI_BUILD STREQUAL "") set (DI_BUILD "Release") endif() if (DI_BUILD STREQUAL "Release") add_compile_options (-O2) endif() if (DI_BUILD STREQUAL "Debug") add_compile_options (-O0) endif() add_compile_options (-g) add_link_options (-g) #### more compile options: fortification/address sanitizer set (DI_FORTIFY Y) if (DEFINED ENV{DI_FORTIFY} AND NOT ENV{DI_FORTIFY} STREQUAL "") set (DI_FORTIFY $ENV{DI_FORTIFY}) endif() # address sanitizer if (DI_BUILD STREQUAL "SanitizeAddress") set (DI_FORTIFY N) add_compile_options (-O0) checkAddCompileFlag ("-ggdb") add_link_options (-g) checkAddCompileFlag ("-fsanitize=address") checkAddLinkFlag ("-fsanitize=address") checkAddCompileFlag ("-fsanitize-address-use-after-scope") checkAddLinkFlag ("-fsanitize-address-use-after-scope") checkAddCompileFlag ("-fsanitize-recover=address") checkAddLinkFlag ("-fsanitize-recover=address") checkAddCompileFlag ("-fno-omit-frame-pointer") checkAddCompileFlag ("-fno-common") checkAddCompileFlag ("-fno-inline") if (CMAKE_C_COMPILER_ID STREQUAL "GNU") # the gnu C compiler needs this library for the sanitizer # other compilers should not link it in. checkAddLinkFlag ("-lrt") endif() endif() # on solaris, the flags are accepted, but the link fails. if (DI_FORTIFY STREQUAL Y AND NOT CMAKE_HOST_SOLARIS) # hardening checkAddCompileFlag ("-fstack-protector-strong") checkAddCompileFlag ("-fstack-protector-all") add_compile_options ("-D_FORTIFY_SOURCE=2") else() checkAddCompileFlag ("-Wno-macro-redefined") add_compile_options ("-U_FORTIFY_SOURCE") add_compile_options ("-D_FORTIFY_SOURCE=0") endif() #### system specific compile options if (NOT WIN32) SET (CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR}) if (NOT APPLE) # SET (CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR} "\${ORIGIN}") endif() if (APPLE) # SET (CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR} "@loader_path") # 10.6 = Snow Leopard, 10.7 = Lion # 10.8 = Mountain Lion, 10.9 = Mavericks # 10.10 = Yosemite, 10.11 = El Capitan # 10.12 = Sierra, 10.13 = High Sierra # 10.14 = Mojave, 10.15 = Catalina # 11 = Big Sur, 12 = Monterey, # 13 = Ventura, 14 = Sonoma # 15 = Sequoia # set (CMAKE_OSX_ARCHITECTURES "arm64;x86_64") endif() else() add_link_options (-static-libgcc) add_link_options (-static-libstdc++) endif() #### include paths include_directories ( SYSTEM # for macos /opt/local/include /opt/homebrew/include # for freebsd /usr/local/include "${CMAKE_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/include" ) set (required_includes # for macos /opt/local/include /opt/homebrew/include # for freebsd /usr/local/include ) set (CMAKE_REQUIRED_INCLUDES ${required_includes}) if (WIN32) add_compile_options (-DWIN32_LEAN_AND_MEAN=1) endif() #### configuration find_package (PkgConfig) find_package (Intl) find_package (Iconv) pkg_check_modules (GMP gmp) pkg_check_modules (TOMMATH libtommath) pkg_check_modules (TIRPC libtirpc) ### # macros for capability testing macro (checkPrototype_quotactl hdr) # this fails when using the c++ compiler. # the c++ compiler is only needed on Haiku, # but it would be nice to be able to test it elsewhere # the mkconfig suite can be used to test c++. check_prototype_definition (quotactl "int quotactl (const char * a, int b, int c, void * d)" 0 "${hdr}" _quotactl_pos_1a ) # OpenBSD has char *, but caddr_t works... # "int quotactl (const char *path, int cmd, int id, char *addr)" check_prototype_definition (quotactl "int quotactl (const char * a, int b, int c, caddr_t d)" 0 "${hdr}" _quotactl_pos_1b ) check_prototype_definition (quotactl "int quotactl (int a, const char * b, int c, caddr_t d)" 0 "${hdr}" _quotactl_pos_2a ) # alpine linux check_prototype_definition (quotactl "int quotactl (int a, const char * b, int c, char *d)" 0 "${hdr}" _quotactl_pos_2b ) if (_quotactl_pos_1a OR _quotactl_pos_1b) set (_quotactl_pos_1 1) endif() if (_quotactl_pos_2a OR _quotactl_pos_2b) set (_quotactl_pos_2 1) endif() if (_quotactl_pos_1) set (_c_arg_2_quotactl "int") set (_args_quotactl 4) endif() if (_quotactl_pos_2) set (_c_arg_2_quotactl "const char *") set (_args_quotactl 4) endif() endmacro() macro (checkPrototype_statfs hdr) check_prototype_definition (statfs "int statfs (const char * a, struct statfs * b)" 0 "${hdr}" _args_statfs_2 ) check_prototype_definition (statfs "int statfs (const char * a, struct statfs * b, int c)" 0 "${hdr}" _args_statfs_3 ) check_prototype_definition (statfs "int statfs (const char * a, struct statfs * b, int c, int d)" 0 "${hdr}" _args_statfs_4 ) if (_args_statfs_2) set (_args_statfs 2) endif() if (_args_statfs_3) set (_args_statfs 3) endif() if (_args_statfs_4) set (_args_statfs 4) endif() endmacro() macro (checkMember_statfs hdr) check_struct_has_member ("struct statfs" f_bsize "${hdr}" _mem_struct_statfs_f_bsize) check_struct_has_member ("struct statfs" f_fsize "${hdr}" _mem_struct_statfs_f_fsize) check_struct_has_member ("struct statfs" f_fstyp "${hdr}" _mem_struct_statfs_f_fstyp) check_struct_has_member ("struct statfs" f_iosize "${hdr}" _mem_struct_statfs_f_iosize) check_struct_has_member ("struct statfs" f_frsize "${hdr}" _mem_struct_statfs_f_frsize) check_struct_has_member ("struct statfs" f_fstypename "${hdr}" _mem_struct_statfs_f_fstypename) check_struct_has_member ("struct statfs" mount_info "${hdr}" _mem_struct_statfs_mount_info) check_struct_has_member ("struct statfs" f_type "${hdr}" _mem_struct_statfs_f_type) endmacro() macro (checkPrototype_setmntent hdr) check_prototype_definition (setmntent "FILE * setmntent (const char * a)" "NULL" "stdio.h;stddef.h;${hdr}" _args_setmntent_1 ) check_prototype_definition (setmntent "FILE * setmntent (const char * a, const char * b)" "NULL" "stdio.h;stddef.h;${hdr}" _args_setmntent_2 ) if (_args_setmntent_1) set (_args_setmntent 1) endif() if (_args_setmntent_2) set (_args_setmntent 2) endif() endmacro() macro (checkPrototype_getfsstat hdr) check_prototype_definition (getfsstat "int getfsstat (struct statfs * a, int b, int c)" 0 "stdio.h;stddef.h;${hdr}" _getfsstat_type_int ) check_prototype_definition (getfsstat "int getfsstat (struct statfs * a, long b, int c)" 0 "stdio.h;stddef.h;${hdr}" _getfsstat_type_long ) check_prototype_definition (getfsstat "int getfsstat(struct statfs *buf, size_t bufsize, int flags)" 0 "stdio.h;stddef.h;${hdr}" _getfsstat_type_size_t ) if (_getfsstat_type_int) set (_c_arg_2_getfsstat int) endif() if (_getfsstat_type_long) set (_c_arg_2_getfsstat long) endif() if (_getfsstat_type_size_t) set (_c_arg_2_getfsstat size_t) endif() endmacro() macro (checkPrototype_getvfsstat hdr) check_prototype_definition (getvfsstat "int getvfsstat (struct statvfs *buf, size_t bufsize, int flags)" 0 "stdio.h;stddef.h;${hdr}" _args_getvfsstat_3a ) check_prototype_definition (getvfsstat "int getvfsstat (struct statvfs *buf, int bufsize, int flags)" 0 "stdio.h;stddef.h;${hdr}" _args_getvfsstat_3b ) if (_args_getvfsstat_3a OR _args_getvfsstat_3b) set (_args_getvfsstat 3) endif() endmacro() macro (checkdqblk hdr) # the calls to checkdqblk do not include the angle brackets set (CMAKE_EXTRA_INCLUDE_FILES "${hdr}") check_type_size ("struct dqblk" _typ_struct_dqblk) check_type_size ("struct quotaval" _typ_struct_quotaval) check_type_size ("struct ufs_dqblk" _typ_struct_ufs_dqblk) check_struct_has_member ("struct dqblk" dqb_curspace "${hdr}" _mem_struct_dqblk_dqb_curspace) check_struct_has_member ("struct dqblk" dqb_curblocks "${hdr}" _mem_struct_dqblk_dqb_curblocks) check_struct_has_member ("struct dqblk" dqb_fhardlimit "${hdr}" _mem_struct_dqblk_dqb_fhardlimit) check_struct_has_member ("struct dqblk" dqb_fsoftlimit "${hdr}" _mem_struct_dqblk_dqb_fsoftlimit) check_struct_has_member ("struct dqblk" dqb_curfiles "${hdr}" _mem_struct_dqblk_dqb_curfiles) unset (CMAKE_EXTRA_INCLUDE_FILES) endmacro () macro (memberxdr structnm membernm) message ("-- Determining ${structnm} ${membernm} xdr type") set (txdrdir "${CMAKE_BINARY_DIR}/tmpxdr") file (MAKE_DIRECTORY "${txdrdir}") file (WRITE "${txdrdir}/${membernm}.c" " #include int main (int argc, char *argv []) { return 0; } ") set (tinc ".") if (NOT ${TIRPC_INCLUDE_DIRS} STREQUAL "") set (tinc ${TIRPC_INCLUDE_DIRS}) endif() execute_process ( OUTPUT_FILE "${txdrdir}/${membernm}.out" ERROR_QUIET COMMAND ${CMAKE_C_COMPILER} -I ${tinc} -E "${txdrdir}/${membernm}.c" ) unset (tinc) if (EXISTS "${txdrdir}/${membernm}.out") execute_process ( OUTPUT_VARIABLE xdr_out # unfortunately, the sed command will find other matches # try this and see how it works out. # possibly will switch to awk in the future. # Some headers have tabs, use the [^a-z0-9_] to avoid putting # them in here. COMMAND sed -n -e "/struct *${structnm}/,/^ *};/ p" "${txdrdir}/${membernm}.out" COMMAND grep "^[^a-z0-9_]*[a-z0-9_][a-z0-9_]*[^a-z0-9_]*${membernm};" COMMAND sed -e "s,^[^a-z0-9_]*,," -e "s,[^a-z0-9_].*,," COMMAND tr -d "\n" ) set (xdr_${membernm} xdr_${xdr_out}) endif() file (REMOVE "${txdrdir}/${membernm}.c") if (EXISTS "${txdrdir}/${membernm}.out") file (REMOVE "${txdrdir}/${membernm}.out") endif() endmacro() macro (checkIncludeConflict hdrvara hdra hdrvarb hdrb varnm) message ("-- Check for include conflict ${hdra} ${hdrb}") if (NOT ${hdrvara} OR NOT ${hdrvarb}) set (${varnm} 1) else() check_include_files ("${hdra};${hdrb}" ${varnm}) endif() endmacro() macro (checkvquotactlenabled) message ("-- Check if vquotactl is enabled") set (tvquotactl 0) if (_lib_vquotactl) execute_process ( OUTPUT_QUIET ERROR_QUIET RESULT_VARIABLE tvquotactl COMMAND grep vfs.quota_enabled=.*1 /boot/loader.conf ) endif() if (NOT tvquotactl) set (_lib_vquotactl 0) set (_lib_prop_dictionary_create 0) endif() endmacro() check_include_file (ctype.h _hdr_ctype) check_include_file (dirent.h _hdr_dirent) check_include_file (errno.h _hdr_errno) check_include_file (fcntl.h _hdr_fcntl) set (CMAKE_REQUIRED_INCLUDES ${required_includes} ${GMP_INCLUDE_DIRS}) check_include_file (gmp.h _hdr_gmp) set (CMAKE_REQUIRED_INCLUDES ${required_includes}) check_include_file (fshelp.h _hdr_fshelp) check_include_file (inttypes.h _hdr_inttypes) check_include_file (jfs/quota.h _hdr_jfs_quota) check_include_file (kernel/fs_info.h _hdr_kernel_fs_info) check_include_file (limits.h _hdr_limits) check_include_file (linux/dqblk_xfs.h _hdr_linux_dqblk_xfs) check_include_file (linux/quota.h _hdr_linux_quota) check_include_file (libintl.h _hdr_libintl) check_include_file (libprop/proplib.h _hdr_libprop_proplib) check_include_file (locale.h _hdr_locale) check_include_file (malloc.h _hdr_malloc) check_include_file (math.h _hdr_math) check_include_file (memory.h _hdr_memory) check_include_file (mntent.h _hdr_mntent) check_include_file (mnttab.h _hdr_mnttab) # NetBSD check_include_file (quota.h _hdr_quota) set (CMAKE_REQUIRED_INCLUDES ${required_includes} ${TIRPC_INCLUDE_DIRS}) # OpenBSD rpc/auth requires rpc/rpc check_include_files ("rpc/rpc.h;rpc/auth.h" _hdr_rpc_auth) check_include_file (rpc/rpc.h _hdr_rpc_rpc) # Linux: rquota.h includes rpc/rpc.h check_include_file (rpcsvc/rquota.h _hdr_rpcsvc_rquota) set (CMAKE_REQUIRED_INCLUDES ${required_includes}) check_include_file (storage/Directory.h _hdr_storage_Directory) check_include_file (storage/Entry.h _hdr_storage_Entry) check_include_file (storage/Path.h _hdr_storage_Path) check_include_file (stdbool.h _hdr_stdbool) check_include_file (stddef.h _hdr_stddef) check_include_file (stdio.h _hdr_stdio) check_include_file (stdint.h _hdr_stdint) check_include_file (stdlib.h _hdr_stdlib) check_include_file (string.h _hdr_string) check_include_file (strings.h _hdr_strings) check_include_file (time.h _hdr_time) set (CMAKE_REQUIRED_INCLUDES ${required_includes} ${TOMMATH_INCLUDE_DIRS}) check_include_file (tommath.h _hdr_tommath) check_include_file (libtommath/tommath.h _hdr_libtommath_tommath) set (CMAKE_REQUIRED_INCLUDES ${required_includes}) check_include_file (ufs/quota.h _hdr_ufs_quota) # FreeBSD/OpenBSD ufs/ufs/quota.h does not include its dependencies check_include_files ("sys/types.h;ufs/ufs/quota.h" _hdr_ufs_ufs_quota) check_include_file (unistd.h _hdr_unistd) check_include_file (wchar.h _hdr_wchar) check_include_file (windows.h _hdr_windows) check_include_file (winioctl.h _hdr_winioctl) check_include_file (zone.h _hdr_zone) check_include_file (sys/dcmd_blk.h _sys_dcmd_blk) check_include_file (sys/file.h _sys_file) check_include_file (sys/fs_types.h _sys_fs_types) check_include_files ("sys/types.h;sys/fs/ufs_quota.h" _sys_fs_ufs_quota) check_include_file (sys/fstyp.h _sys_fstyp) # solaris # NetBSD requires sys/types.h check_include_files ("sys/types.h;sys/fstypes.h" _sys_fstypes) check_include_file (sys/ftype.h _sys_ftype) check_include_file (sys/io.h _sys_io) check_include_file (sys/mntctl.h _sys_mntctl) check_include_file (sys/param.h _sys_param) check_include_file (sys/types.h _sys_types) # SCO OpenServer/UnixWare require sys/mnttab.h for struct mnttab declaration. # solaris check_include_file (sys/mnttab.h _sys_mnttab) if (_sys_mnttab) check_include_files ("sys/mnttab.h;sys/mntent.h" _sys_mntent) else() check_include_file ("sys/mntent.h" _sys_mntent) endif() # openbsd, dragonflybsd, freebsd check_include_files ("sys/types.h;sys/mount.h" _sys_mount) check_include_files ("sys/types.h;sys/quota.h" _sys_quota) check_include_file (sys/stat.h _sys_stat) check_include_file (sys/statfs.h _sys_statfs) check_include_file (sys/statvfs.h _sys_statvfs) check_include_file (sys/time.h _sys_time) check_include_file (sys/vfs.h _sys_vfs) check_include_file (sys/vfs_quota.h _sys_vfs_quota) # dfly-bsd # SCO OpenServer/UnixWare require stdio.h for sys/vfstab.h check_include_files ("stdio.h;sys/vfstab.h" _sys_vfstab) check_include_file (sys/vmount.h _sys_vmount) # AIX check_symbol_exists (bcopy strings.h _lib_bcopy) check_symbol_exists (bzero strings.h _lib_bzero) # -lsun, -lseq check_symbol_exists (endmntent mntent.h _lib_endmntent) check_symbol_exists (fs_stat_dev kernel/fs_info.h _lib_fs_stat_dev) # haiku check_symbol_exists (fshelp fshelp.h _lib_fshelp) # AIX # macos, freebsd, openbsd check_symbol_exists (getfsstat "sys/stat.h;sys/mount.h" _lib_getfsstat) # ultrix, .h file may be wrong check_symbol_exists (getmnt mntent.h _lib_getmnt) set (_lib_getmntent 0) check_symbol_exists (getmntent mntent.h _lib_getmntent_a) check_symbol_exists (getmntent sys/mnttab.h _lib_getmntent_b) set (LIBGEN_REQUIRED 0) if (NOT _lib_getmntent_a) # unixware put getmntent into libgen for some reason set (CMAKE_REQUIRED_LIBRARIES -lgen) check_symbol_exists (getmntent mntent.h _lib_getmntent_c) if (_lib_getmntent) set (LIBGEN_REQUIRED 1) endif() unset (CMAKE_REQUIRED_LIBRARIES) endif() if (_lib_getmntent_a OR _lib_getmntent_b OR _lib_getmntent_c) set (_lib_getmntent 1) endif() set (_lib_getmntinfo 0) check_symbol_exists (getmntinfo sys/statvfs.h _lib_getmntinfo_a) # netbsd # macos, openbsd (req sys/types.h) check_symbol_exists (getmntinfo "sys/types.h;sys/mount.h" _lib_getmntinfo_b) if (_lib_getmntinfo_a OR _lib_getmntinfo_b) set (_lib_getmntinfo 1) endif() check_symbol_exists (getvfsstat sys/statvfs.h _lib_getvfsstat) check_symbol_exists (getzoneid zone.h _lib_getzoneid) set (_lib_hasmntopt 0) check_symbol_exists (hasmntopt mntent.h _lib_hasmntopt_a) check_symbol_exists (hasmntopt sys/mnttab.h _lib_hasmntopt_b) # solaris if (_lib_hasmntopt_a OR _lib_hasmntopt_b) set (_lib_hasmntopt 1) endif() check_symbol_exists (lstat sys/stat.h _lib_lstat) check_symbol_exists (mbrlen wchar.h _lib_mbrlen) check_symbol_exists (memcpy string.h _lib_memcpy) check_symbol_exists (memset string.h _lib_memset) # AIX doesn't declare this :( # Look for MCTL_QUERY (see below) check_symbol_exists (mntctl sys/mntctl.h _lib_mntctl) check_symbol_exists (next_dev kernel/fs_info.h _lib_next_dev) # haiku # dragonflybsd; need this to get the library set (CMAKE_REQUIRED_LIBRARIES -lprop) check_symbol_exists (prop_dictionary_create libprop/proplib.h _lib_prop_dictionary_create) unset (CMAKE_REQUIRED_LIBRARIES) # quota_open is a new interface from NetBSD set (LIBQUOTACTL_REQUIRED 0) set (CMAKE_REQUIRED_LIBRARIES -lquota) check_symbol_exists (quota_open quota.h _lib_quota_open) unset (CMAKE_REQUIRED_LIBRARIES) if (_lib_quota_open) set (LIBQUOTACTL_REQUIRED 1) endif() set (_lib_quotactl 0) check_symbol_exists (quotactl "unistd.h" _lib_quotactl_a) check_symbol_exists (quotactl "sys/types.h;sys/quota.h" _lib_quotactl_b) check_symbol_exists (quotactl "sys/types.h;ufs/ufs/quota.h" _lib_quotactl_c) if (_lib_quotactl_a OR _lib_quotactl_b OR _lib_quotactl_c) set (_lib_quotactl 1) endif() check_symbol_exists (realpath stdlib.h _lib_realpath) # unknown if -lsun, -lseq are needed (old irix, sequent) check_symbol_exists (setmntent mntent.h _lib_setmntent) check_symbol_exists (snprintf stdio.h _lib_snprintf_a) set (LIBSNPRINTF_REQUIRED 0) if (NOT _lib_snprintf_a) set (CMAKE_REQUIRED_LIBRARIES -lsnprintf) check_symbol_exists (snprintf stdio.h _lib_snprintf_b) if (_lib_snprintf_b) set (LIBSNPRINTF_REQUIRED 1) endif() unset (CMAKE_REQUIRED_LIBRARIES) endif() if (_lib_snprintf_a OR _lib_snprintf_b) set (_lib_snprintf 1) endif() check_symbol_exists (setlocale locale.h _lib_setlocale) set (_lib_statfs 0) check_symbol_exists (statfs "sys/statfs.h;sys/vfs.h" _lib_statfs_a) # openbsd (requires sys/types) check_symbol_exists (statfs "sys/types.h;sys/mount.h" _lib_statfs_b) if (_lib_statfs_a OR _lib_statfs_b) set (_lib_statfs 1) endif() check_symbol_exists (statvfs sys/statvfs.h _lib_statvfs) check_symbol_exists (stpecpy string.h _lib_stpecpy) check_symbol_exists (strcoll string.h _lib_strcoll) check_symbol_exists (strdup string.h _lib_strdup) check_symbol_exists (strstr string.h _lib_strstr) check_symbol_exists (strtok_r string.h _lib_strtok_r) check_symbol_exists (sysfs sys/fstyp.h _lib_sysfs) # solaris # dragonflybsd check_symbol_exists (vquotactl sys/vfs_quota.h _lib_vquotactl) set (CMAKE_REQUIRED_INCLUDES ${required_includes} ${TIRPC_INCLUDE_DIRS}) check_symbol_exists (xdr_int rpc/rpc.h _lib_xdr_int) set (LIBNSL_REQUIRED 0) set (LIBTIRPC_REQUIRED 0) if (NOT _lib_xdr_int) # check with nsl library (solaris 10) set (CMAKE_REQUIRED_LIBRARIES nsl) check_symbol_exists (xdr_int rpc/rpc.h _lib_xdr_int_nsl) if (_lib_xdr_int_nsl) set (_lib_xdr_int 1) set (LIBNSL_REQUIRED 1) endif() unset (CMAKE_REQUIRED_LIBRARIES) endif() if (NOT _lib_xdr_int) # check with tirpc library set (CMAKE_REQUIRED_LIBRARIES tirpc) check_symbol_exists (xdr_int rpc/rpc.h _lib_xdr_int_tirpc) if (_lib_xdr_int_tirpc) set (_lib_xdr_int 1) set (LIBTIRPC_REQUIRED 1) endif() unset (CMAKE_REQUIRED_LIBRARIES) endif() set (CMAKE_REQUIRED_INCLUDES ${required_includes}) # solaris check_symbol_exists (zone_getattr zone.h _lib_zone_getattr) check_symbol_exists (zone_list zone.h _lib_zone_list) # windows routines check_symbol_exists (GetDiskFreeSpace windows.h _lib_GetDiskFreeSpace) check_symbol_exists (GetDiskFreeSpaceEx windows.h _lib_GetDiskFreeSpaceEx) check_symbol_exists (GetDriveType windows.h _lib_GetDriveType) check_symbol_exists (GetLogicalDriveStrings windows.h _lib_GetLogicalDriveStrings) check_symbol_exists (GetVolumeInformation windows.h _lib_GetVolumeInformation) if (Intl_LIBRARY AND NOT Intl_LIBRARY STREQUAL "NOTFOUND") set (CMAKE_REQUIRED_LIBRARIES ${Intl_LIBRARY}) endif() if (Iconv_LIBRARY AND NOT Iconv_LIBRARY STREQUAL "NOTFOUND") set (CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};${Iconv_LIBRARY}") endif() check_symbol_exists (bindtextdomain libintl.h _lib_bindtextdomain) check_symbol_exists (gettext libintl.h _lib_gettext) check_symbol_exists (textdomain libintl.h _lib_textdomain) unset (CMAKE_REQUIRED_LIBRARIES) if (_sys_mnttab) set (MNTTAB_HDR sys/mnttab.h) endif() if (_hdr_mnttab) set (MNTTAB_HDR mnttab.h) endif() if (DEFINED MNTTAB_HDR) message ("mnttab header: ${MNTTAB_HDR}") check_struct_has_member ("struct mnttab" mt_mntopts ${MNTTAB_HDR} _mem_struct_mnttab_mt_mntopts) endif() if (_sys_statvfs) # cmake: check_type_size and extra-include files issue set (CMAKE_EXTRA_INCLUDE_FILES sys/statvfs.h) check_type_size ("statvfs_t" _typ_statvfs_t) set (CMAKE_EXTRA_INCLUDE_FILES ) check_struct_has_member ("struct statvfs" f_basetype sys/statvfs.h _mem_struct_statvfs_f_basetype) unset (CMAKE_EXTRA_INCLUDE_FILES) endif() check_type_size ("gid_t" _typ_gid_t) check_type_size ("size_t" _typ_size_t) check_type_size ("uid_t" _typ_uid_t) check_type_size ("double" _siz_double) check_type_size ("long double" _siz_long_double) check_type_size ("uint64_t" _siz_uint64_t) check_type_size ("long" _siz_long) check_type_size ("long long" _siz_long_long) if (_hdr_ufs_ufs_quota) # FreeBSD ufs/ufs/quota.h does not include its dependencies # OpenBSD declares quotactl in unistd.h set (QUOTA_HDR "sys/types.h;unistd.h;ufs/ufs/quota.h") endif() if (_sys_quota) set (QUOTA_HDR "sys/types.h;sys/quota.h") endif() if (_hdr_ufs_quota) set (QUOTA_HDR "ufs/quota.h") endif() if (_sys_fs_ufs_quota) # solaris set (QUOTA_HDR "sys/types.h;sys/fs/ufs_quota.h") endif() if (_hdr_quota) # NetBSD : put this after ufs/ufs/quota.h and sys/quota.h set (QUOTA_HDR "quota.h") endif() set (_args_quotactl 0) if (DEFINED QUOTA_HDR) message ("quota header: ${QUOTA_HDR}") checkdqblk ("${QUOTA_HDR}") checkPrototype_quotactl ("${QUOTA_HDR}") check_symbol_exists (QCMD "${QUOTA_HDR}" _define_QCMD) if (_hdr_linux_dqblk_xfs) # cmake doesn't properly handle the angle brackets when # using check_type_size set (CMAKE_EXTRA_INCLUDE_FILES linux/dqblk_xfs.h) endif() check_type_size ("fs_disk_quota_t" _typ_fs_disk_quota_t) unset (CMAKE_EXTRA_INCLUDE_FILES) endif() if (_sys_mnttab) set (SETMNTENT_HDR sys/mnttab.h) endif() if (_hdr_mntent) set (SETMNTENT_HDR mntent.h) endif() set (_args_setmntent 0) if (DEFINED SETMNTENT_HDR) message ("setmntent header: ${SETMNTENT_HDR}") checkPrototype_setmntent ("${SETMNTENT_HDR}") endif() if (_hdr_rpcsvc_rquota) # linux rpcsvc/rquota.h includes rpc/rpc.h set (CMAKE_REQUIRED_INCLUDES ${required_includes} ${TIRPC_INCLUDE_DIRS}) check_struct_has_member ("struct getquota_rslt" gqr_status rpcsvc/rquota.h _mem_struct_getquota_rslt_gqr_status) check_struct_has_member ("struct getquota_rslt" gqr_rquota rpcsvc/rquota.h _mem_struct_getquota_rslt_gqr_rquota) check_struct_has_member ("struct rquota" rq_bhardlimit rpcsvc/rquota.h _mem_struct_rquota_rq_bhardlimit) check_struct_has_member ("struct getquota_args" gqa_uid rpcsvc/rquota.h _mem_struct_getquota_args_gqa_uid) set (CMAKE_REQUIRED_INCLUDES ${required_includes}) memberxdr (rquota rq_bhardlimit) memberxdr (rquota rq_bsoftlimit) memberxdr (rquota rq_curblocks) memberxdr (rquota rq_fhardlimit) memberxdr (rquota rq_fsoftlimit) memberxdr (rquota rq_curfiles) memberxdr (getquota_args gqa_uid) endif() if ((_lib_statfs OR _lib_getfsstat) AND _sys_mount) # OpenBSD has broken headers set (STATFS_HDR "sys/types.h;sys/mount.h") endif() if ((_lib_statfs OR _lib_getfsstat) AND _sys_vfs) set (STATFS_HDR "sys/vfs.h") endif() if ((_lib_statfs OR _lib_getfsstat) AND _sys_statfs) set (STATFS_HDR "sys/statfs.h") endif() set (_args_statfs 0) if (DEFINED STATFS_HDR) message ("statfs header: ${STATFS_HDR}") checkPrototype_statfs ("${STATFS_HDR}") checkMember_statfs ("${STATFS_HDR}") endif() if (DEFINED STATFS_HDR AND _lib_getfsstat) message ("getfsstat header: ${STATFS_HDR}") checkPrototype_getfsstat ("${STATFS_HDR}") endif() set (_args_getvfsstat 0) set (GETVFSSTAT_HDR "sys/mount.h") if (DEFINED GETVFSSTAT_HDR AND _lib_getvfsstat) message ("getvfsstat header: ${GETVFSSTAT_HDR}") checkPrototype_getvfsstat ("${GETVFSSTAT_HDR}") endif() if (_lib_getenv) check_prototype_definition (getenv "char * getenv (const char * a)" "NULL" stdlib.h _npt_getenv ) if (_npt_getenv) set (_npt_getenv 0) else() set (_npt_getenv 1) endif() else() set (_npt_getenv 0) endif() if (_lib_mntctl) # AIX check_prototype_definition (mntctl "int mntctl (int a, size_t b, char * c)" 0 sys/mntctl.h _npt_mntctl ) if (_npt_mntctl) set (_npt_mntctl 0) else() set (_npt_mntctl 1) endif() else() set (_npt_mntctl 0) endif() # HP-UX if (_lib_quotactl AND NOT _lib_vquotactl AND NOT _quotactl_pos_1 AND NOT _quotactl_pos_2) check_prototype_definition (quotactl "int quotactl (int a, const char * b, uid_t c, void * d)" 0 "${QUOTA_HDR}" _npt_quotactl ) if (_npt_quotactl) set (_npt_quotactl 0) else() set (_npt_quotactl 1) endif() else() set (_npt_quotactl 0) endif() if (_lib_statfs AND _args_statfs STREQUAL "0") set (_npt_statfs 1) set (_args_statfs 2) # no idea which one... else() set (_npt_statfs 0) endif() check_symbol_exists (errno errno.h _dcl_errno) # *BSD # which include files? # check_symbol_exists (mnt_names ${STATFS_HDR} _dcl_mnt_names) checkvquotactlenabled () set (_has_std_quotas 0) if (_lib_quotactl OR _lib_quota_open OR _lib_vquotactl OR _typ_struct_dqblk OR _typ_struct_ufs_dqblk) set (_has_std_quotas 1) endif() set (_has_std_nfs_quotas 0) if (_hdr_rpc_rpc AND _hdr_rpcsvc_rquota AND _lib_xdr_int AND _mem_struct_rquota_rq_bhardlimit AND _mem_struct_getquota_args_gqa_uid) set (_has_std_nfs_quotas 1) endif() set (_enable_nls 0) if (_lib_bindtextdomain AND _lib_gettext AND _lib_setlocale AND _lib_textdomain AND _hdr_libintl AND _hdr_locale) set (_enable_nls 1) endif() checkIncludeConflict (_hdr_time time.h _sys_time sys/time.h _inc_conflict__hdr_time__sys_time) checkIncludeConflict (_sys_quota sys/quota.h _linux_quota linux/quota.h _inc_conflict__sys_quota__hdr_linux_quota) check_symbol_exists (O_NOCTTY fcntl.h _const_O_NOCTTY) check_symbol_exists (IOCTL_STORAGE_CHECK_VERIFY2 winioctl.h _define_IOCTL_STORAGE_CHECK_VERIFY2) check_symbol_exists (MCTL_QUERY sys/mntctl.h _define_MCTL_QUERY) check_symbol_exists (S_ISLNK sys/stat.h _define_S_ISLNK) if (NOT DEFINED DI_USE_MATH OR DI_USE_MATH STREQUAL "") # GMP is the default, as it is more common if (_hdr_gmp AND GMP_LDFLAGS) set (DI_USE_MATH DI_GMP) endif() # at the moment, libtommath in macports has a broken pkg-config # hence the not-apple if ((_hdr_tommath OR _hdr_libtommath_tommath) AND TOMMATH_LDFLAGS AND NOT _hdr_gmp AND NOT APPLE) set (DI_USE_MATH DI_TOMMATH) endif() endif() if (NOT DEFINED DI_USE_MATH OR DI_USE_MATH STREQUAL "") set (DI_USE_MATH DI_INTERNAL) endif() set (_use_math ${DI_USE_MATH}) message ("math-library: ${_use_math}") configure_file (config.h.in config.h) ### # macros for building macro (addIntlLibrary name) if (_enable_nls AND Intl_LIBRARY AND NOT Intl_LIBRARY STREQUAL "NOTFOUND") target_include_directories (${name} PRIVATE ${Intl_INCLUDE_DIRS} ) target_link_libraries (${name} PRIVATE ${Intl_LIBRARY} ) endif() if (_enable_nls AND Iconv_LIBRARY AND NOT Iconv_LIBRARY STREQUAL "NOTFOUND") target_include_directories (${name} PRIVATE ${Iconv_INCLUDE_DIRS} ) target_link_libraries (${name} PRIVATE ${Iconv_LIBRARY} ) endif() endmacro() ### # libraries add_library (objdistrutils OBJECT distrutils.c ) add_library (${DI_LIBNAME} didiskutil.c digetentries.c digetinfo.c dilib.c diquota.c dizone.c getoptn.c dioptions.c ) target_include_directories (${DI_LIBNAME} PRIVATE ${TIRPC_INCLUDE_DIRS} ${GMP_INCLUDE_DIRS} ${TOMMATH_INCLUDE_DIRS} ) target_link_libraries (${DI_LIBNAME} PRIVATE objdistrutils ) # cmake's auto prefixing is annoying set_target_properties (${DI_LIBNAME} PROPERTIES PREFIX "") if (WIN32) set (CMAKE_SHARED_LIBRARY_PREFIX "lib") set (CMAKE_STATIC_LIBRARY_PREFIX "lib") endif() if (LIBQUOTACTL_REQUIRED) # NetBSD target_link_libraries (${DI_LIBNAME} PRIVATE -lquota ) endif() if (LIBGEN_REQUIRED) # Unixware target_link_libraries (${DI_LIBNAME} PRIVATE -lgen ) endif() if (LIBNSL_REQUIRED) target_link_libraries (${DI_LIBNAME} PRIVATE -lnsl ) endif() if (LIBTIRPC_REQUIRED) target_link_libraries (${DI_LIBNAME} PRIVATE ${TIRPC_LDFLAGS} ) endif() if (LIBSNPRINTF_REQUIRED) target_link_libraries (${DI_LIBNAME} PRIVATE -lsnprintf ) endif() if (_use_math STREQUAL "DI_GMP") target_link_libraries (${DI_LIBNAME} PRIVATE ${GMP_LDFLAGS} ) endif() if (_use_math STREQUAL "DI_TOMMATH") target_link_libraries (${DI_LIBNAME} PRIVATE ${TOMMATH_LDFLAGS} ) endif() set_target_properties (${DI_LIBNAME} PROPERTIES VERSION ${DI_LIBVERSION} SOVERSION ${DI_SOVERSION} ) # I don't know if this is needed. windows works fine for me. if (WIN32) set_target_properties (${DI_LIBNAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) endif() #### executables add_executable (di di.c ) addIntlLibrary (di) target_include_directories (di PRIVATE ${TIRPC_INCLUDE_DIRS} ) if (CMAKE_HOST_SOLARIS) target_link_options (di PRIVATE "-Wl,-R${CMAKE_INSTALL_FULL_LIBDIR}" ) endif() target_link_libraries (di PRIVATE ${TIRPC_LDFLAGS} ) target_link_libraries (di PRIVATE ${DI_LIBNAME} ) if (_use_math STREQUAL "DI_GMP") target_link_libraries (di PRIVATE ${GMP_LDFLAGS} ) endif() if (_use_math STREQUAL "DI_TOMMATH") target_link_libraries (di PRIVATE ${TOMMATH_LDFLAGS} ) endif() set (DI_LINK_EXTRA "") if (${CMAKE_SYSTEM_NAME} STREQUAL "NetBSD") target_link_options (di PRIVATE -Wl,-R/usr/pkg/lib ) endif() add_executable (dimathtest dimathtest.c ) target_include_directories (dimathtest PRIVATE ${GMP_INCLUDE_DIRS} ${TOMMATH_INCLUDE_DIRS} ) if (_use_math STREQUAL "DI_GMP") target_link_libraries (dimathtest PRIVATE ${GMP_LDFLAGS} ) endif() if (_use_math STREQUAL "DI_TOMMATH") target_link_libraries (dimathtest PRIVATE ${TOMMATH_LDFLAGS} ) endif() add_executable (getoptn_test getoptn.c ) target_compile_options (getoptn_test PRIVATE -DTEST_GETOPTN ) target_link_libraries (getoptn_test PRIVATE objdistrutils ) # di.pc configure_file (${CMAKE_SOURCE_DIR}/di.pc.in di.pc @ONLY) #### install install (TARGETS ${DI_LIBNAME} ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" # windows seems to need this RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" ) install (TARGETS di RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" ) install (FILES di.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" ) install (FILES man/di.1 DESTINATION "${CMAKE_INSTALL_MANDIR}/man1" ) install (FILES man/libdi.3 DESTINATION "${CMAKE_INSTALL_MANDIR}/man3" ) install (FILES ${CMAKE_BINARY_DIR}/di.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig" ) if (_enable_nls) install (CODE "execute_process ( COMMAND \"${PROJECT_SOURCE_DIR}/utils/instpo.sh\" \"${PROJECT_SOURCE_DIR}/po\" \"${CMAKE_INSTALL_FULL_LOCALEDIR}\" \"${CMAKE_BINARY_DIR}/tmppo\" )" ) endif() di-6.0.0/distrutils.h0000644000175000017500000000130214761606005012575 0ustar bllbll/* Copyright 2025 Brad Lanam Pleasant Hill CA */ #ifndef INC_DISTRUTILS_H #define INC_DISTRUTILS_H #include "config.h" #if _hdr_stddef # include #endif # if defined (__cplusplus) || defined (c_plusplus) extern "C" { # endif extern void * di_realloc (void *, Size_t); extern void di_trimchar (char *, int); char * di_strtok (char *str, const char *delim, char **tokstr); # if ! _lib_stpecpy char * stpecpy (char *dst, char *end, const char *src); # endif # if ! _lib_strdup extern char * strdup (const char *); # endif # if ! _lib_strstr extern char * strstr (const char *, const char *); # endif # if defined (__cplusplus) || defined (c_plusplus) } # endif #endif /* INC_DISTRUTILS_H */ di-6.0.0/dimathtest.c0000644000175000017500000002005714756647471012560 0ustar bllbll/* Copyright 2025 Brad Lanam Pleasant Hill CA */ #include "config.h" #include #include #include #include #include #include #include #include "dimath.h" int main (int argc, char *argv []) { dinum_t a; dinum_t b; dinum_t r; double dval; di_ui_t ival; char buff [200]; int tcount = 0; int ecount = 0; #if _use_math == DI_GMP fprintf (stdout, "GMP:\n"); #elif _use_math == DI_TOMMATH fprintf (stdout, "TOMMATH:\n"); #else fprintf (stdout, "INTERNAL: ld:%d d:%d u64:%d ll:%d l:%d\n", _siz_long_double, _siz_double, _siz_uint64_t, _siz_long, _siz_long_long); #endif dinum_init (&a); dinum_init (&b); dinum_init (&r); /* set */ dinum_set_u (&a, (di_ui_t) 1); ++tcount; if (dinum_cmp_s (&a, (di_si_t) 1) != 0) { fprintf (stderr, "%d: cmp-s 1 != 0 fail %d\n", tcount, dinum_cmp_s (&a, (di_si_t) 1)); ++ecount; } ++tcount; if (dinum_cmp_s (&a, (di_si_t) 0) <= 0) { fprintf (stderr, "%d: cmp-s 1 > 0 fail %d\n", tcount, dinum_cmp_s (&a, (di_si_t) 0)); ++ecount; } ++tcount; if (dinum_cmp_s (&a, (di_si_t) 2) >= 0) { fprintf (stderr, "%d: cmp-s 1 < 2 fail %d\n", tcount, dinum_cmp_s (&a, (di_si_t) 2)); ++ecount; } dinum_str (&a, buff, sizeof (buff)); ++tcount; if (strcmp (buff, "1") != 0) { fprintf (stderr, "%d: str 1 fail %s\n", tcount, buff); ++ecount; } /* set negative, must use _s suffix */ dinum_set_s (&a, (di_si_t) -1); ++tcount; if (dinum_cmp_s (&a, (di_si_t) -1) != 0) { fprintf (stderr, "%d: set-s -1 != 0 fail %d\n", tcount, dinum_cmp_s (&a, (di_si_t) -1)); ++ecount; } ++tcount; if (dinum_cmp_s (&a, (di_si_t) 0) >= 0) { fprintf (stderr, "%d: set-s -1 >= 0 fail %d\n", tcount, dinum_cmp_s (&a, (di_si_t) 0)); ++ecount; } /* add */ dinum_set_u (&a, (di_ui_t) 0); dinum_add_u (&a, (di_ui_t) 1); ++tcount; if (dinum_cmp_s (&a, (di_si_t) 1) != 0) { fprintf (stderr, "%d: add-u 1 != 0 fail %d\n", tcount, dinum_cmp_s (&a, (di_si_t) 1)); ++ecount; } ++tcount; if (dinum_cmp_s (&a, (di_si_t) 0) <= 0) { fprintf (stderr, "%d: add-u 1 <= 0 fail %d\n", tcount, dinum_cmp_s (&a, (di_si_t) 1)); ++ecount; } dinum_str (&a, buff, sizeof (buff)); ++tcount; if (strcmp (buff, "1") != 0) { fprintf (stderr, "%d: str 1 fail %s\n", tcount, buff); ++ecount; } dinum_add_u (&a, (di_ui_t) 1); ++tcount; if (dinum_cmp_s (&a, (di_si_t) 2) != 0) { fprintf (stderr, "%d: add-u 0 fail %d\n", tcount, dinum_cmp_s (&a, (di_si_t) 0)); ++ecount; } dinum_str (&a, buff, sizeof (buff)); ++tcount; if (strcmp (buff, "2") != 0) { fprintf (stderr, "%d: str 2 fail %s\n", tcount, buff); ++ecount; } dinum_add_u (&a, (di_ui_t) 1); ++tcount; if (dinum_cmp_s (&a, (di_si_t) 3) != 0) { fprintf (stderr, "%d: add-u 1 fail %d\n", tcount, dinum_cmp_s (&a, (di_si_t) 1)); ++ecount; } dinum_str (&a, buff, sizeof (buff)); ++tcount; if (strcmp (buff, "3") != 0) { fprintf (stderr, "%d: str 3 fail %s\n", tcount, buff); ++ecount; } dinum_set_u (&b, (di_ui_t) 1); dinum_add (&a, &b); ++tcount; if (dinum_cmp_s (&a, (di_si_t) 4) != 0) { fprintf (stderr, "%d: add 1 fail %d\n", tcount, dinum_cmp_s (&a, (di_si_t) 1)); ++ecount; } dinum_str (&a, buff, sizeof (buff)); ++tcount; if (strcmp (buff, "4") != 0) { fprintf (stderr, "%d: str 4 fail %s\n", tcount, buff); ++ecount; } /* subtract */ dinum_sub_u (&a, (di_ui_t) 1); ++tcount; if (dinum_cmp_s (&a, (di_si_t) 3) != 0) { fprintf (stderr, "%d: sub-u 1 fail %d\n", tcount, dinum_cmp_s (&a, (di_si_t) 1)); ++ecount; } dinum_str (&a, buff, sizeof (buff)); ++tcount; if (strcmp (buff, "3") != 0) { fprintf (stderr, "%d: str 3 fail %s\n", tcount, buff); ++ecount; } dinum_sub (&a, &b); ++tcount; if (dinum_cmp_s (&a, (di_si_t) 2) != 0) { fprintf (stderr, "%d: sub 1 fail %d\n", tcount, dinum_cmp_s (&a, (di_si_t) 1)); ++ecount; } dinum_str (&a, buff, sizeof (buff)); ++tcount; if (strcmp (buff, "2") != 0) { fprintf (stderr, "%d: str 2 fail %s\n", tcount, buff); ++ecount; } dinum_sub_u (&a, (di_ui_t) 1); ++tcount; if (dinum_cmp_s (&a, (di_si_t) 1) != 0) { fprintf (stderr, "%d: sub-u 1 fail %d\n", tcount, dinum_cmp_s (&a, (di_si_t) 1)); ++ecount; } dinum_str (&a, buff, sizeof (buff)); ++tcount; if (strcmp (buff, "1") != 0) { fprintf (stderr, "%d: str 1 fail %s\n", tcount, buff); ++ecount; } dinum_sub_u (&a, (di_ui_t) 1); ++tcount; if (dinum_cmp_s (&a, (di_si_t) 0) != 0) { fprintf (stderr, "%d: sub-u 1 fail %d\n", tcount, dinum_cmp_s (&a, (di_si_t) 1)); ++ecount; } dinum_str (&a, buff, sizeof (buff)); ++tcount; if (strcmp (buff, "0") != 0) { fprintf (stderr, "%d: str 0 fail %s\n", tcount, buff); ++ecount; } dinum_sub_u (&a, (di_ui_t) 1); ++tcount; if (dinum_cmp_s (&a, (di_si_t) -1) != 0) { fprintf (stderr, "%d: sub-u 1 fail %d\n", tcount, dinum_cmp_s (&a, (di_si_t) 1)); ++ecount; } /* multiply */ dinum_mul_uu (&a, (di_ui_t) 1, (di_ui_t) 1024); ++tcount; if (dinum_cmp_s (&a, (di_si_t) 1024) != 0) { fprintf (stderr, "%d: mul-uu 1024 fail %d\n", tcount, dinum_cmp_s (&a, (di_si_t) 1024)); ++ecount; } dinum_str (&a, buff, sizeof (buff)); ++tcount; if (strcmp (buff, "1024") != 0) { fprintf (stderr, "%d: str 1024 fail %s\n", tcount, buff); ++ecount; } dinum_set_u (&b, (di_ui_t) 1024); dinum_mul (&a, &b); ++tcount; if (dinum_cmp_s (&a, (di_si_t) (1024 * 1024)) != 0) { fprintf (stderr, "%d: mul 1024*1024 fail %d\n", tcount, dinum_cmp_s (&a, (di_si_t) (1024 * 1024)) ); ++ecount; } dinum_str (&a, buff, sizeof (buff)); ++tcount; if (strcmp (buff, "1048576") != 0) { fprintf (stderr, "%d: str 1048576 fail %s\n", tcount, buff); ++ecount; } dinum_mul_u (&a, (di_ui_t) 1024); ++tcount; if (dinum_cmp_s (&a, (di_si_t) (1024 * 1024 * 1024)) != 0) { fprintf (stderr, "%d: mul-u 1024*1024*1024 fail %d\n", tcount, dinum_cmp_s (&a, (di_si_t) (1024*1024*1024)) ); ++ecount; } dinum_str (&a, buff, sizeof (buff)); ++tcount; if (strcmp (buff, "1073741824") != 0) { fprintf (stderr, "%d: str 1073741824 fail %s\n", tcount, buff); ++ecount; } /* scaled value tests */ dinum_set_u (&a, (di_ui_t) (1024 * 1024)); dinum_set_u (&b, (di_ui_t) 1024); dval = dinum_scale (&a, &b); ++tcount; if (dval != 1024.0) { Snprintf1 (buff, sizeof (buff), "%.3f", dval); fprintf (stderr, "%d: scale 1024 a fail %s\n", tcount, buff); ++ecount; } dinum_set_u (&a, (di_ui_t) (1024 * 1024 + 2)); dinum_set_u (&b, (di_ui_t) 1024); dval = dinum_scale (&a, &b); ++tcount; if (dval > 1025.0) { Snprintf1 (buff, sizeof (buff), "%.3f", dval); fprintf (stderr, "%d: scale 1025 b fail %s\n", tcount, buff); ++ecount; } dinum_set_u (&a, (di_ui_t) (1024 * 1024 + 512)); dinum_set_u (&b, (di_ui_t) 1024); dval = dinum_scale (&a, &b); ++tcount; if (dval > 1025.0) { Snprintf1 (buff, sizeof (buff), "%.3f", dval); fprintf (stderr, "%d: scale 1025 c fail %s\n", tcount, buff); ++ecount; } /* percentage tests */ ival = 1024 * 1024 / 100; dinum_set_u (&a, (di_ui_t) ival); dinum_set_u (&b, (di_ui_t) (1024 * 1024)); dval = dinum_perc (&a, &b); ++tcount; if (fabs (dval - 1.0) > 0.0001) { fprintf (stderr, "%d: perc 1024 a fail %.4f\n", tcount, dval); ++ecount; } ival = 1024 * 1024 / 2; dinum_set_u (&a, (di_ui_t) ival); dinum_set_u (&b, (di_ui_t) (1024 * 1024)); dval = dinum_perc (&a, &b); ++tcount; if (fabs (dval - 50.0) > 0.0001) { fprintf (stderr, "%d: perc 1024 b fail %.4f\n", tcount, dval); ++ecount; } dinum_set_u (&a, (di_ui_t) (1024 * 1024)); dinum_set_u (&b, (di_ui_t) (1024 * 1024)); dval = dinum_perc (&a, &b); ++tcount; if (fabs (dval - 100.0) > 0.0001) { fprintf (stderr, "%d: perc 1024 c fail %.4f\n", tcount, dval); ++ecount; } dinum_clear (&a); dinum_clear (&b); dinum_clear (&r); fprintf (stdout, "tests: %d errors: %d\n", tcount, ecount); return ecount; } di-6.0.0/man/0000755000175000017500000000000014751206310010767 5ustar bllblldi-6.0.0/man/di.10000644000175000017500000003065614750755333011474 0ustar bllbll.\" .\" di.1 .\" .\" Copyright 1994-2018 Brad Lanam Walnut Creek CA USA .\" Copyright 2025 Brad Lanam Pleasant Hill CA USA .\" .\" brad.lanam.di_at_gmail.com .\" .TH di 1 "17 Jan 2013" .SH Name di \- disk information .SH Synopsis .\" di [-AacghHjklLmnPqRtZ] [-B block-size] [-d display-size] [-f format] .\" [-I include-fstyp-list] [-s sort-type] .\" [-x exclude-fstyp-list] [-X debug-level] .\" [-z zone-name] [file [...]] .B di [\fB\-AacghHjklLmnPqRtZ\fP] [\fB\-B\fP \fIblock\-size\fP] [\fB\-d\fP \fIdisplay\-size\fP] [\fB\-f\fP \fIformat\fP] [\fB\-I\fP \fIinclude\-fstyp\-list\fP] [\fB\-s\fP \fIsort\-type\fP] [\fB\-x\fP \fIexclude\-fstyp\-list\fP] [\fB\-X\fP \fIdebug-level\fP] [\fB\-z\fP \fIzone\-name\fP] [\fIfile\fP [...]] .PP If \fIfile\fP is specified, the usage information for the partition on which \fIfile\fP is located is printed. .PP Unless the \-a flag is specified, the following mounted filesystems will not normally be displayed: filesystems with total space <= 0; loopback filesystems that are duplicates of other normally mounted filesystems (filesystem type of \[aq]lofs\[aq], \[aq]none\[aq], or \[aq]nullfs\[aq]); loopback filesystems that are part of a zone (Solaris); filesystems for which the system's ignore flag is set; filesystems that have a device name of \[aq]tmpfs\[aq], \[aq]cgroup\[aq] or \[aq]swap\[aq]; filesystems that have a device name starting with \[aq]/System/\[aq] or \[aq]com.apple.TimeMachine.\[aq] (both MacOS). .PP Filesystems that the user does not have permissions to access will not be displayed at all. .PP Several options may be specified to control the output of \fIdi\fP: .TP .B \-A Print all fields (used for debugging). .TP .B \-a (compatibility: \fB\-\-all\fP) .br Prints all mounted devices (normally, those with a total space of zero are not printed e.g. \fB/dev/proc\fP, \fB/dev/fd\fP). .TP .B \-B .I block\-size (compatibility: \fB\-\-block\-size\fP, \fB\-b\fP) .br Change the base block size from 1024 (default) to the size specified. \fIblock\-size\fP may be either: k\ \-\ 1024 bytes or si\ \-\ 1000 bytes. .PP Use the \fI\-d\fP option to change the scaling display. .TP .B \-c (alias: \fB\-\-csv\-output\fP) .br Comma separated values are output. The titles are output as the format string specifiers. Totals are turned off. See also the \-n flag. .TP .B \-C (alias: \fB\-\-csv\-tabs\fP) .br Values are output with tab separators. See also the \-c option. .TP .B \-d .I display\-size (alias: \fB\-\-display\-size\fP) .br Display the usage in units specified by \fIdisplay\-size\fP. The display size is calculated based on the block size (\-B). \fIdisplay\-size\fP may be one of: k\ \-\ kilobytes (POSIX), m\ \-\ megabytes, g\ \-\ gigabytes, t\ \-\ terabytes, p\ \-\ petabytes, e\ \-\ exabytes, z\ \-\ zettabytes, y\ \-\ yottabytes, r\ \-\ ronnabytes, q\ \-\ quetta, h\ \-\ human readable, H\ \-\ human readable alternative. .IP The human readable format scales the sizes displayed and appends a suffix (e.g. 48.0k, 3.4M). Sizes within a line may scale to different units. .IP The human readable alternative scales all the sizes in each individual line to the same unit size (the largest needed). .IP If \fIdi\fP is compiled without large number support, the larger units may not work correctly or may be inaccurate. .TP .B \-f .I format Use the specified format string \fIformat\fP. See the \fBFormat Strings\fP section. .TP .B \-g (alias for: \fB\-dg\fP) .br Display sizes in gigabytes. .TP .B \-h (alias for: \fB\-dh\fP) .br Display partition sizes in human readable format. Sizes within a line may scale to different unit sizes. .TP .B \-\-help .br Display some basic usage information. .TP .B \-H (alias for: \fB\-dH\fP; compatibility: \fB\-\-human\-readable\fP) .br Display partition sizes in human readable alternative format. All sizes in each individual line are scaled to the same unit size. .TP .B \-I .I include\-fstype\-list (compatibility: \fB\-F\fP, \fB\-\-type\fP) .br Include \fIonly\fP the filesystem types listed in \fIinclude\-fstyp\-list\fP. The list is a comma separated list of filesystem types. Multiple \-I options may be specified. If the \[aq]fuse\[aq] filesystem type is specified, all fuse* filesystems will be included. .br e.g. \-I nfs,tmpfs or \-I nfs \-I tmpfs. .TP .B \-\-inodes Ignored. Use the \-f option. .TP .B \-j (alias: \fB\-\-json\-output\fP) .br The data is output as an array of JSON objects. Totals are turned off. Use of format specifiers that specify the same field will result in duplicated field names. (e.g. \fBp\fP, \fB1\fP, \fB2\fP) .IP Possible JSON identifiers are: scaling, blocksize, partitions, filesystem, mount, fstype, options, size, used, free, available, percused, percfree, inodes, inodesused, inodesfree, percinodesused. .IP .B Example Output: .EX { "scaling" : "human", "blocksize" : "1024", "partitions" : [ { "filesystem" : "/dev/nvme0n1p7", "mount" : "/", "size" : "19.1G", "used" : "11.0G", "available" : "7.0G", "percused" : "63%", "fstype" : "ext4" } ] } .EE .TP .B \-k (alias for: \fB\-dk\fP) .br Display sizes in Kbytes. .TP .B \-l (compatibility: \fB\-\-local\fP) .br Display only local filesystems. .TP .B \-L Turn off check for duplicate filesystems (loopback (lofs/none) mounts). .TP .B \-m (alias for: \fB\-dm\fP) .br Display sizes in megabytes. .TP .B \-n Do not print a header line above the list of filesystems. Useful when parsing the output of \fIdi\fP. .TP .B \-\-no\-sync Ignored. .TP .B \-P (compatibility: \fB\-\-portability\fP) .br Output format is POSIX standard. A 1024 byte block size and a display size of kilobytes (\-d\ k) is the default. .TP .B \-\-print\-type Ignored. Use the \-f option. .TP .B \-q Disable quota checks. .TP .B \-R (alias: \-\-dont\-resolve\-symlinks) .br Do not resolve symlinks (for mount points that have a trailing UUID). .TP .B \-s .I sort\-type .br Use \fIsort\-type\fP to sort the output. The output of \fIdi\fP is normally sorted by mount point. The following sort flags may be used to change the sort order: .IP .RS \fBm\fP \- by mount point (default) .br \fBn\fP \- leave unsorted (as it appears in the mount table) .br \fBs\fP \- by filesystem .br \fBT\fP \- by total space .br \fBf\fP \- by free space .br \fBa\fP \- by available space .br \fBt\fP \- by filesystem type .br \fBr\fP \- reverse the sort order; This will apply to all sort flags following this sort flag. .RE .IP These sort options may be combined in any order. e.g.: .RS di \-stsrm # by type, device name, reversed mount; .br di \-strsrm # by type, reversed device-name, mount. .RE .TP .B \-\-si An alias for \fB-dh -Bsi\fP. .TP .B \-\-sync Ignored. .TP .B \-t (compatibility: \fB\-\-total\fP) .br Print a totals line below the list of filesystems. Only the main pool of pooled filesystems (zfs, advfs, apfs) are added to the total. Pooled filesystems that do not have pool information available (btrfs) will not total up correctly. .PP It is up to the user to exclude (using the \-x option) read\-only filesystems (cdfs, iso9660), swap-based (memfs, mfs, tmpfs) filesystems and user (fuse*) filesystems. Excluding the \[aq]fuse\[aq] filesystem will exclude all fuse* filesystems. .TP .B \-v Ignored. .TP .B \-\-version .br Display the di version. .TP .B \-w (backwards compatibility) .br Ignored. The following argument is ignored. .TP .B \-W (backwards compatibility) .br Ignored. The following argument is ignored. .TP .B \-x .I exclude\-fstype\-list (compatibility: \fB\-\-exclude\-type\fP) .br Exclude the filesystem types listed in \fIexclude\-fstyp\-list\fP. The list is a comma separated list of filesystem types. Multiple \-x options may be specified. If the \[aq]fuse\[aq] filesystem type is excluded, all fuse* filesystems will be excluded. e.g. \-x nfs,tmpfs or \-x nfs \-x tmpfs. .TP .B \-X .I level .br Set the program's debugging level to \fIdebug-level\fP. .TP .B \-z .I zone-name .br Display the filesystems for the specified zone. The zone must be visible to the user. .TP .B \-Z (alias for: \fB\-z all\fP) .br Display the filesystems for all visible zones. .SH Format Strings The output of \fIdi\fP may be specified via a format string. This string may be given either via the \fB-f\fP command line option or as part of the \fBDI_ARGS\fP environment variable. The format string may specify the following columns: .RS .5 .TP .B m Print the name of the mount point. .TP .B M (backwards compatibility) Print the name of the mount point. .TP .B s Print the filesystem name (device name). .TP .B S (backwards compatibility) Print the filesystem name. .TP .B t Print the filesystem type. .TP .B T (backwards compatibility) Print the filesystem type. .TP .B O Print the filesystem mount options. .TP .B Total Available .TP .B b Print the total space on the filesystem. .TP .B B Print the total space on the filesystem available for use by normal users. .TP .B In Use .TP .B u Print the space in use on the filesystem (actual space used = total \- free). .TP .B c Print the space not available for use by normal users (total \- available). Note that this calculation does not work correctly on the \[aq]apfs\[aq] filesystem. .TP .B Free .TP .B f Print the amount of free (unused) space on the filesystem. .TP .B v Print the space available for use by normal users. .TP .B Percentage Used .TP .B p Print the percentage of space not available for use by normal users (space not available for use / total disk space). .TP .B 1 Print the percentage of space in use (actual space used / total disk space). .TP .B 2 Print the percentage of space in use, BSD-style. Represents the percentage of user-available space in use. Note that values over 100% are possible (actual space used / disk space available to normal users). .TP .B Percentage Free .TP .B a Print the percentage of space available for use by normal users (space available for use / total disk space). .TP .B 3 Print the percentage of space free (actual space free / total disk space). .TP .B Inodes .TP .B i Print the total number of file slots (inodes) that can be created on the filesystem. .TP .B U Print the number of file slots in use. .TP .B F Print the number of file slots available. .TP .B P Print the percentage of file slots in use. .RE .PP The default format string for \fIdi\fP is \fBsmbuvpT\fP. .PP The format string may also contain any other character not listed above. The character will be printed as is. e.g. di \-f \[aq]mbuvp|iUFP\[aq] will print the character \[aq]|\[aq] between the disk usage and the file slot usage. The command sequence: .RS .br di \-f \[aq]mbuvp .br miUFP\[aq] .br .RE will print two lines of data for each filesystem. .SH Examples As of version 5.0.0, \fIdi\fP no longer supports 512-byte blocks. There may not be an exact match to 512-byte block output. .PP Various \fIdf\fP equivalent format strings for System V release 4 are: .RS \fI/usr/bin/df \-v\fP di \-P \-f msbuf1 .br \fI/usr/bin/df \-k\fP di \-d k \-f sbcvpm .br \fI/usr/ucb/df\fP di \-d k \-f sbuv2m .RE GNU df: .RS \fIdf\fP di \-dk \-f SbuvpM .br \fIdf \-T\fP di \-dk \-f STbuvpM .br \fIdf \-h \-T\fP di \-dh \-f STbuvpM .RE AIX df: .RS \fIdf\fP di \-d k \-f Sbf1UPM .br \fIdf \-I\fP di -d k \-f Sbuf1M .br \fIdf \-I \-M\fP di \-d k \-f SMbuf1 .RE HP-UX bdf: .RS \fIbdf\fP di \-d k \-f Sbuv2M .br \fIbdf \-i\fP di \-d k \-f Sbuv2UFPM .RE .RE MacOS df: .RS \fIbdf \-k\fP di \-d k \-f Sbuv2UFPM .br \fIbdf \-I \-h\fP di \-d h \-B si \-f Sbuv2M .br \fIbdf \-Y \-I \-h\fP di \-d h \-B si \-f STbuv2M .RE .PP If you like your numbers to add up/calculate the percentage correctly, try one of the following format strings: .PP .RS di \-f SMbuf1T .br di \-f SMbcvpT .br di \-f SMBuv2T .RE .SH Environment Variables The DI_ARGS environment variable may be used to specify command line arguments. e.g. If you always want gigabytes displayed, set DI_ARGS equal to "\-dg". Any command line arguments specified will override the DI_ARGS environment variable. .PP The GNU df POSIXLY_CORRECT, and DF_BLOCK_SIZE and the BSD BLOCKSIZE environment variables are honored when possible. .SH See Also df(1), libdi(3) .SH Bugs Open a ticket at https://sourceforge.net/p/diskinfo-di/tickets/ .br Send bug reports to: brad.lanam.di @ gmail.com .PP .SH Links Home Page: https://diskinfo-di.sourceforge.io/ .br Wiki: https://sourceforge.net/p/diskinfo-di/wiki/Home/ .br Change Log: https://sourceforge.net/p/diskinfo-di/wiki/ChangeLog/ .SH Author Copyright 1994-2025 by Brad Lanam Pleasant Hill, CA di-6.0.0/man/libdi.30000644000175000017500000002474214751205635012160 0ustar bllbll'\" .\" .\" libdi.3 .\" .\" Copyright 2025 Brad Lanam Pleasant Hill CA USA .\" .\" brad.lanam.di_at_gmail.com .\" .TH libdi 3 "28 Jan 2025" .SH Name \fBlibdi\fP - disk information library .SH Synopsis .SS Initialization #include .PP void * \fBdi_initialize\fP (void); .br int \fBdi_process_options\fP (void *\fIdi_data\fP, int \fItargc\fP, const char *\fItargv\fP [], int \fIoffset\fP); .br void \fBdi_cleanup\fP (void *\fIdi_data\fP); .br const char *\fBdi_version\fP (void); .SS Options .PP int \fBdi_check_option\fP (void *\fIdi_data\fP, int \fIoption\fP); .br void \fBdi_format_iter_init\fP (void *\fIdi_data\fP); .br int \fBdi_format_iterate\fP (void *\fIdi_data\fP); .br .SS Getting data .PP void \fBdi_get_all_disk_info\fP (void *\fIdi_data\fP); .br int \fBdi_iterate_init\fP (void *\fIdi_data\fP, int \fIiteroption\fP); .br .EX typedef struct { const char *strdata [DI_DISP_MAX]; /* string data */ int index; /* internal index value */ int doPrint; /* printable flag based on options */ int printFlag; /* print result flag */ int isLocal; /* filesystem is local */ int isReadOnly; /* filesystem is read-only */ int isLoopback; /* filesystme is a loopback filesystem */ } di_pub_disk_info_t; .EE .PP const di_pub_disk_info_t * \fBdi_iterate\fP (void *\fIdi_data\fP); .br int \fBdi_get_scale_max\fP (void *\fIdi_data\fP, int \fIindex\fP, .br int \fIvalueidxA\fP, int \fIvalueidxB\fP, int \fIvalueidxC\fP); .br double \fBdi_get_scaled\fP (void *\fIdi_data\fP, int \fIindex\fP, .br int \fIscaleidx\fP, int \fIvalueidxA\fP, int \fIvalueidxB\fP, int \fIvalueidxC\fP); .br void \fBdi_disp_scaled\fP (void *\fIdi_data\fP, char *\fIbuff\fP, long \fIbuffsz\fP, .br int \fIindex\fP, int \fIscaleidx\fP, .br int \fIvalueidxA\fP, int \fIvalueidxB\fP, int \fIvalueidxC\fP); .br double \fBdi_get_perc\fP (void *\fIdi_data\fP, int \fIindex\fP, .br int \fIvalueidxA\fP, int \fIvalueidxB\fP, .br int \fIvalueidxC\fP, int \fIvalueidxB\fP, int \fIvalueidxE\fP); .br void \fBdi_disp_perc\fP (void *\fIdi_data\fP, char *\fIbuff\fP, long \fIbuffsz\fP, .br int \fIindex\fP, .br int \fIvalueidxA\fP, int \fIvalueidxB\fP, .br int \fIvalueidxC\fP, int \fIvalueidxB\fP, int \fIvalueidxE\fP); .SH Overview .SS Initialization \fBdi_initialize\fP returns a pointer to a \fIdi_data\fP structure, used in all of the other library calls. The returned pointer must be freed with \fBdi_cleanup\fP. .PP \fBdi_process_options\fP processes the arguments to \fIdi\fP. These are passed as strings via an \fIargv\fP structure as if on the command line. If no call to \fBdi_process_options\fP is made, \fIdi\fP will use the defaults and the \fIDI_ARGS\fP environment variable will not be processed. .PP \fBdi_cleanup\fP frees all allocated data. .SS Options \fBdi_check_option\fP returns the value of the specified option. All options will return a boolean value, excepting: DI_OPT_DEBUG, DI_OPT_FMT_STR_LEN, DI_OPT_SCALE and DI_OPT_BLOCK_SZ. .PP \fIoption\fP may be one of: .IP DI_OPT_POSIX_COMPAT .br DI_OPT_QUOTA_CHECK .br DI_OPT_DISP_CSV .br DI_OPT_DISP_CSV_TAB .br DI_OPT_EXCL_LOOPBACK .br DI_OPT_DISP_JSON .br DI_OPT_DISP_TOTALS .br DI_OPT_DISP_HEADER .br DI_OPT_DISP_ALL .br DI_OPT_LOCAL_ONLY .br DI_OPT_NO_SYMLINK .br DI_OPT_DEBUG .br DI_OPT_FMT_STR_LEN .br DI_OPT_SCALE .br DI_OPT_BLOCK_SZ .PP \fBdi_format_iter_init\fP initializes the format string iterator. .PP \fBdi_format_iterate\fP iterates through each format character in the format string. Note that \fIdi\fP allows unrecognized format characters. In the main \fIdi\fP program, these are printed as-is. .SS Getting Data \fBdi_get_all_disk_info\fP retrieves and processes all of the disk information from the operating system. .PP \fBdi_iterate_init\fP initializes the disk information iterator. \fIiteroption\fP is one of DI_ITER_PRINTABLE or DI_ITER_ALL. If DI_ITER_PRINTABLE is specified, only the partitions with the \fIdoPrint\fP flag set will be returned by the iterator. .PP \fBdi_iterate\fP iterates through the filesystems, returning a \fIdi_pub_disk_info_t\fP structure for each filesystem. If the \fI\-\-totals\fP flag was specified as an option, the totals will be the last item returned by the iterator. .PP \fBdi_get_scale_max\fP gets the maximum scaling unit for the space value. .PP \fIindex\fP is the index from the \fIdi_pub_disk_info_t\fP structure. .PP The \fIvalueidx\fP arguments indicate which disk space values to use to calculate the the space value. The formula is: \fBA\~-\~(B\~-\~C)\fP. Valid combinations are: .IP DI_SPACE_TOTAL, DI_VALUE_NONE, DI_VALUE_NONE // total .br DI_SPACE_TOTAL, DI_SPACE_FREE, DI_SPACE_AVAIL // used .br DI_SPACE_TOTAL, DI_SPACE_FREE, DI_VALUE_NONE // used .br DI_SPACE_TOTAL, DI_SPACE_AVAIL, DI_VALUE_NONE // used .br DI_SPACE_FREE, DI_VALUE_NONE, DI_VALUE_NONE // free .br DI_SPACE_AVAIL, DI_VALUE_NONE, DI_VALUE_NONE // free .br DI_INODE_TOTAL, DI_VALUE_NONE, DI_VALUE_NONE // inode total .br DI_INODE_TOTAL, DI_INODE_FREE, DI_VALUE_NONE // inodes used .br DI_INODE_FREE, DI_VALUE_NONE, DI_VALUE_NONE // inodes free .PP \fBdi_get_scaled\fP gets a space value scaled according to the scaling unit. .PP \fIindex\fP is the index from the \fIdi_pub_disk_info_t\fP structure. .PP \fIscaleidx\fP is the scaling index to use. Use a scaling index returned from \fBdi_get_scale_max\fP or use one of the following values: .IP DI_SCALE_BYTE .br DI_SCALE_KILO .br DI_SCALE_MEGA .br DI_SCALE_GIGA .br DI_SCALE_TERA .br DI_SCALE_PETA .br DI_SCALE_EXA .br DI_SCALE_ZETTA .br DI_SCALE_YOTTA .br DI_SCALE_RONNA .br DI_SCALE_QUETTA .PP The \fIvalueidx\fP arguments indicate which disk space values to use to calculate the the space value. The formula is: \fBA\~-\~(B\~-\~C)\fP. See \fBdi_get_scale_max\fP for a list of valid combinations. .PP \fBdi_disp_scaled\fP gets a space value scaled according to the scaling unit, and creates a string that can be printed. .PP \fBbuff\fP is the character string where the string will be stored. .PP \fBbuffsz\fP is the size of the character string. .PP \fIindex\fP is the index from the \fIdi_pub_disk_info_t\fP structure. .PP \fIscaleidx\fP is the scaling index to use. Use a scaling index returned from \fBdi_get_scale_max\fP or one of the values as listed in \fBdi_get_scaled\fP. .PP The \fIvalueidx\fP arguments indicate which disk space values to use to calculate the the space value. The formula is: \fBA\~\-\~(B\~\-\~C)\fP. See \fBdi_get_scale_max\fP for a list of valid combinations. .PP \fBdi_get_perc\fP retrieves the disk space value as a percentage. .PP \fIindex\fP is the index from the \fIdi_pub_disk_info_t\fP structure. .PP The \fIvalueidx\fP arguments indicate which disk space values to use to calculate the percentage. The formula is: \fB(A\~\-\~B)\~/\~(C\~\-\~(D\~\-\~E))\fP. .PP Valid combinations are: .IP /* percent used */ .br DI_SPACE_TOTAL, DI_SPACE_AVAIL, .br DI_SPACE_TOTAL, DI_VALUE_NONE, DI_VALUE_NONE .br /* percent used */ .br DI_SPACE_TOTAL, DI_SPACE_FREE, .br DI_SPACE_TOTAL, DI_VALUE_NONE, DI_VALUE_NONE .br /* percent used, BSD style */ .br DI_SPACE_TOTAL, DI_SPACE_FREE, .br DI_SPACE_TOTAL, DI_VALUE_FREE, DI_VALUE_AVAIL .br /* percent free */ .br DI_SPACE_AVAIL, DI_VALUE_NONE, .br DI_SPACE_TOTAL, DI_VALUE_NONE, DI_VALUE_NONE, .br /* percent free */ .br DI_SPACE_FREE, DI_VALUE_NONE, .br DI_SPACE_TOTAL, DI_VALUE_NONE, DI_VALUE_NONE, .br /* inodes used */ .br DI_INODE_TOTAL, DI_INODE_AVAIL, .br DI_INODE_TOTAL, DI_VALUE_NONE, DI_VALUE_NONE .br .PP \fBdi_disp_perc\fP retrieves the disk space value as a percentage and creates a string that can be printed. .PP \fBbuff\fP is the character string where the string will be stored. .PP \fBbuffsz\fP is the size of the character string. .PP \fIindex\fP is the index from the \fIdi_pub_disk_info_t\fP structure. .PP The \fIvalueidx\fP arguments indicate which disk space values to use to calculate the percentage. The formula is: \fB(A\~\-\~B)\~/\~(C\~\-\~(D\~\-\~E))\fP. See \fBdi_get_perc\fP for valid combinations. .SH Example .EX /* this code is in the public domain */ #include #include #include #include #include enum { HAVE_SPACE = 0, NO_SPACE = 1, }; int check_space (const char *fn, double space_wanted) { void *di_data; int targc; const char *targv [10]; int exitflag; const di_pub_disk_info_t *pub; int rval = NO_SPACE; int count; targc = 1; targv [0] = fn; targv [1] = NULL; di_data = di_initialize (); exitflag = di_process_options (di_data, targc, targv, 0); if (exitflag != DI_EXIT_NORM) { di_cleanup (di_data); exit (exitflag); } di_get_all_disk_info (di_data); count = di_iterate_init (di_data, DI_ITER_PRINTABLE); while ((pub = di_iterate (di_data)) != NULL) { double dval; /* compare terabytes available */ dval = di_get_scaled (di_data, pub->index, DI_SCALE_TERA, DI_SPACE_AVAIL, DI_VALUE_NONE, DI_VALUE_NONE); if (dval >= space_wanted) { rval = HAVE_SPACE; } } di_cleanup (di_data); return rval; } int main (int argc, char *argv []) { const char *fn = "/home/bll/s/di"; double spwant = 0.2; /* terabytes */ bool rval; if (argc > 1) { fn = argv [1]; } if (argc > 2) { spwant = atof (argv [2]); } rval = check_space (fn, spwant); if (rval == NO_SPACE) { fprintf (stdout, "Not enough disk space\n"); } if (rval == HAVE_SPACE) { fprintf (stdout, "Enough disk space\n"); } return rval; } .EE .SS Compile and Link .EX dilibd=$HOME/local/lib diinc=$(pkg-config --with-path ${dilibd}/pkgconfig --cflags di) dilibs=$(pkg-config --with-path ${dilibd}/pkgconfig --libs di) cc -o tt ${diinc} tt.c -Wl,-R${dilibd} ${dilibs}) .EE .SS Example Run .PP .EX bll-g7:bll$ ./tt /home/bll 0.5 Not enough disk space bll-g7:bll$ ./tt /home/bll 0.1 Enough disk space .EE .SH See Also df(1), di(1) .SH Bugs Open a ticket at https://sourceforge.net/p/diskinfo-di/tickets/ .br Send bug reports to: brad.lanam.di @ gmail.com .PP .SH Links Home Page: https://diskinfo-di.sourceforge.io/ .br Wiki: https://sourceforge.net/p/diskinfo-di/wiki/Home/ .br Change Log: https://sourceforge.net/p/diskinfo-di/wiki/ChangeLog/ .SH Author Copyright 1994-2025 by Brad Lanam Pleasant Hill, CA di-6.0.0/diinternal.h0000644000175000017500000000704614746051702012534 0ustar bllbll/* Copyright 2025 Brad Lanam Pleasant Hill CA */ #ifndef INC_DIINTERNAL_H #define INC_DIINTERNAL_H #include "config.h" #include "disystem.h" #include "di.h" #include "dimath.h" #include "dioptions.h" // ### temporary # if defined (__cplusplus) || defined (c_plusplus) extern "C" { # endif /* di defines */ #define DI_MOUNTPT_LEN MAXPATHLEN #define DI_FILESYSTEM_LEN MAXPATHLEN #define DI_MOUNTOPT_LEN MAXPATHLEN #define DI_MNT_TIME_LEN 24 #ifndef DI_DEFAULT_DISP_SIZE # define DI_DEFAULT_DISP_SIZE "h" #endif #ifndef DI_DEFAULT_FORMAT # define DI_DEFAULT_FORMAT "smbuvpT" #endif #define DI_SORT_MAIN 0 #define DI_SORT_TOTAL 1 #define DI_SORT_MAX 2 /* structures */ typedef struct { int sortIndex [DI_SORT_MAX]; dinum_t values [DI_VALUE_MAX]; unsigned long st_dev; /* disk device number */ unsigned long sp_dev; /* special device number */ unsigned long sp_rdev; /* special rdev # */ char *strdata [DI_DISP_MAX]; /* mount point */ /* special device name */ /* type of file system */ /* mount options */ int doPrint; /* should this entry */ /* be printed? */ int printFlag; /* print flags */ int isLocal; /* is this mount point */ /* local? */ int isReadOnly; /* is this mount point */ /* read-only? */ int isLoopback; /* lofs or none fs type? */ } di_disk_info_t; typedef struct { dinum_t scale_values [DI_SCALE_MAX]; void *options; di_disk_info_t *diskInfo; di_disk_info_t totals; void *zoneInfo; void *pub; int scale_values_init; /* fscount is the number of partitions */ /* the allocation count is one greater to hold the totals bucket */ int fscount; int dispcount; int iteridx; int iteropt; int haspooledfs; int disppooledfs; int totsorted; } di_data_t; /* digetentries.c */ extern int di_get_disk_entries (di_data_t *di_data, int *); /* digetinfo.c */ extern void di_get_disk_info (di_data_t *di_data, int *); /* didiskutil.c */ extern void di_initialize_disk_info (di_disk_info_t *, int); extern void di_free_disk_info (di_disk_info_t *); extern void di_save_block_sizes (di_disk_info_t *, di_ui_t, di_ui_t, di_ui_t, di_ui_t); extern void di_save_inode_sizes (di_disk_info_t *, di_ui_t, di_ui_t, di_ui_t); #if _lib_getmntent \ && ! _lib_getmntinfo \ && ! _lib_getfsstat \ && ! _lib_getvfsstat \ && ! _lib_mntctl extern char *chkMountOptions (const char *, const char *); #endif extern void convertMountOptions (unsigned long, di_disk_info_t *); extern void convertNFSMountOptions (long, long, long, di_disk_info_t *); extern void di_is_remote_disk (di_disk_info_t *); extern int di_isPooledFs (di_disk_info_t *); extern int di_isLoopbackFs (di_disk_info_t *); extern Size_t di_mungePoolName (char *); # if defined (__cplusplus) || defined (c_plusplus) } # endif #endif /* INC_DIINTERNAL_H */ di-6.0.0/README.txt0000644000175000017500000001146514763624257011742 0ustar bllblldi - disk information utility Website: https://diskinfo-di.sourceforge.io/ SourceForge: https://sourceforge.net/projects/diskinfo-di/ CONTENTS Important Notes: Version 5/6 Description Documentation Installation Requirements Porting Help Acknowledgements Copyright IMPORTANT NOTES: VERSION 5/6 (2025-3-10) Version 5's code base has changed. The build process has changed and optionally uses cmake (3.13+). The display processing is entirely new code. Version 6 had an ABI change to fix a crash. Version 5/6 installs a shared library that can be used to get the disk space or percentages. Version 5/6 is very new, and there could still be errors. DESCRIPTION 'di' is a disk information utility, displaying everything (and more) that your 'df' command does. It features the ability to display your disk usage in whatever format you prefer. It is designed to be highly portable. Great for heterogenous networks. DOCUMENTATION wiki: https://sourceforge.net/p/diskinfo-di/wiki/Home/ Change Log: https://sourceforge.net/p/diskinfo-di/wiki/ChangeLog Test Results: https://sourceforge.net/p/diskinfo-di/wiki/Testing INSTALLATION To build: make -e PREFIX=$HOME/local make -e PREFIX=$HOME/local install The build will use cmake if it is available and recent enough (3.13), otherwise the mkconfig configuration tool will be used. To use cmake in a stand-alone fashion (version 5.0.4): cmake -DCMAKE_INSTALL_PREFIX=$HOME/local -S . -B build cmake --build build cmake --install build If the GMP or libtommath library is found, it will be used, otherwise the numerics will be handled using standard C data types (long double, double, etc.). To turn off the use of the multi-precision libraries; make -e PREFIX=$HOME/local DI_USE_MATH=DI_INTERNAL Long doubles are quite capable, there's nothing wrong with building it this way (as of 2025). To force GMP: make -e PREFIX=$HOME/local DI_USE_MATH=DI_GMP To force libtommath: make -e PREFIX=$HOME/local DI_USE_MATH=DI_TOMMATH For OpenSUSE and others that use .../lib64, with mkconfig (cmake will generate the proper path): make -e PREFIX=$HOME/local LIBNM=lib64 make -e PREFIX=$HOME/local LIBNM=lib64 install REQUIREMENTS cmake build make cmake (3.13+) pkg-config msgfmt C compiler sed grep tr test /bin/sh awk (gawk/nawk/awk) mkconfig build make pkg-config msgfmt C compiler bourne/ksh/bash shell awk (gawk/nawk/awk) cat chmod ln mkdir mv rm sed test expr grep sort libraries: Linux: tirpc (nfs quotas) MP Math: gmp or libtommath (optional) BUG REPORTS I need to know what operating system and what version of operating system you are on. Also which compiler, and the version of the compiler. For build issues, capture the output from `make`, and the files listed below. For runtime issues, I want to see the output from 'di -A -a -X 5' and the output from your standard df command (as verbose as possible), Files to include in your report: cmake: build/config.h build/CMakeOutput.log build/CMakeError.log build/CMakeFiles/CMakeConfigureLog.yaml mkconfig: config.h di.env di.reqlibs mkc_files/mkconfig.log mkc_files/mkconfig_env.log mkc_files/mkc_compile.log Open a ticket at : https://sourceforge.net/p/diskinfo-di/tickets/ Or e-mail : brad.lanam.di_at_gmail.com PORTING HELP I use my own set of virtual machines, the gcc compile farm, and polarhome (which is now limited, and will probably die at some point). If you have a computer on the internet with a less common or older operating system, I could use access for portability testing. I need access to HP-UX. ACKNOWLEDGEMENTS And for their comments/source/manual pages and/or bug fixes, thanks! J.J.Bailey Karl Vogel [pyramid] Bryan Costales Mark Neale Pat Myrto [sunOS filesystem type stuff] Henri Karrenbeld [sgi] Peter Bray George M. Sipe [manual page] Jeffrey Mogul [ultrix, osf/1, manual page, new format options] Th. Bullinger [help usage] Seth Theriault [next, tru64] Stephen J. Walick [SCO] Gerald Rinske [sgi] Mike Grupenhoff [linux] R.K.Lloyd [hpux] William Gibbs [xenix] Randy Thompson [sequent] Erik O'Shaughnessy [aix] Bill Davidsen [linux, SCO, etc., new format options] Fred Smith [coherent 4.2.05] Andrey Blochintsev [bsdi] Brian Ginsbach [netbsd, irix, unicos] et. al. COPYRIGHT Copyright 1994-2025 Brad Lanam, Pleasant Hill, CA, USA brad.lanam.di_at_gmail.com https://diskinfo-di.sourceforge.io di-6.0.0/Makefile0000644000175000017500000002631614760377646011711 0ustar bllbll# # di makefile - C # # Copyright 2001-2018 Brad Lanam Walnut Creek CA, USA # Copyright 2023-2025 Brad Lanam, Pleasant Hill, CA # # for checking cmake CMAKE_REQ_MAJ_VERSION = 3 CMAKE_REQ_MIN_VERSION = 13 BUILDDIR = build DI_BUILD = Release # DI_USE_MATH = DI_GMP # DI_USE_MATH = DI_TOMMATH # DI_USE_MATH = DI_INTERNAL # for mkconfig MKC_CONFDIR = mkc_config MKC_FILES = mkc_files MKC_ENV = di.env MKC_CONF = $(MKC_CONFDIR)/di.mkc MKC_ENV_CONF = $(MKC_CONFDIR)/di-env.mkc # # To turn off stack fortification: # # make -e DI_FORTIFY=N PREFIX=$HOME/local # make -e DI_FORTIFY=N PREFIX=$HOME/local install # DI_FORTIFY = Y OBJ_EXT = .o EXE_EXT = ### # installation locations # the cmake install only uses PREFIX # PREFIX = BINDIR = $(PREFIX)/bin LIBNM = lib LIBDIR = $(PREFIX)/$(LIBNM) INCDIR = $(PREFIX)/include PKGCDIR = $(LIBDIR)/pkgconfig SHAREDIR = $(PREFIX)/share MANDIR = $(SHAREDIR)/man LOCALEDIR = $(SHAREDIR)/locale INST_DIR = $(DESTDIR)$(PREFIX) INST_INCDIR = $(DESTDIR)$(INCDIR) INST_BINDIR = $(DESTDIR)$(BINDIR) INST_LIBDIR = $(DESTDIR)$(LIBDIR) INST_SHAREDIR = $(DESTDIR)$(SHAREDIR) INST_PKGCDIR = $(DESTDIR)$(PKGCDIR) INST_MANDIR = $(DESTDIR)$(MANDIR) INST_LOCALEDIR = $(DESTDIR)$(LOCALEDIR) ### # mkconfig variables MKC_DIR = mkconfig MKCONFIG_TYPE = sh MKC_REQLIB = di.reqlibs MKC_ECHO = #MKC_ECHO = -e ### # generic targets .PHONY: all all: @$(MAKE) -e TARGET=$@ switcher .PHONY: install install: @$(MAKE) -e TARGET=$@ switcher .PHONY: test test: @$(MAKE) -e TARGET=$@ switcher .PHONY: chkswitcher chkswitcher: @$(MAKE) -e TARGET=$@ switcher # checks the cmake version, and builds using either cmake or mkconfig .PHONY: switcher switcher: @if [ "$(PREFIX)" = "" ]; then echo "No prefix set"; exit 1; fi @bldval=`./utils/chkcmake.sh \ $(CMAKE_REQ_MAJ_VERSION) $(CMAKE_REQ_MIN_VERSION)` ; \ if [ $$bldval = cmake ]; then \ $(MAKE) -e cmake-$(TARGET) ; \ else \ $(MAKE) -e mkc-$(TARGET) ; \ fi ### # cleaning # clean temporary files .PHONY: tclean tclean: @-rm -f w ww asan.* *.orig \ dep-*.txt >/dev/null 2>&1; exit 0 @-find . -name '*~' -print0 | xargs -0 rm > /dev/null 2>&1; exit 0 @-find . -name '*.orig' -print0 | xargs -0 rm > /dev/null 2>&1; exit 0 # leaves config.h .PHONY: clean clean: @$(MAKE) tclean @-rm -f \ di libdi.* dimathtest getoptn_test \ di.exe libdi.dll dimathtest.exe getoptn_test.exe \ *.o *.obj \ $(MKC_FILES)/mkc_compile.log \ tests.d/chksh* \ >/dev/null 2>&1; exit 0 @-test -d $(BUILDDIR) && cmake --build $(BUILDDIR) --target clean .PHONY: realclean realclean: @$(MAKE) clean >/dev/null 2>&1 @-rm -rf config.h \ $(MKC_ENV) $(MKC_REQLIB) \ _mkconfig_runtests \ >/dev/null 2>&1; exit 0 .PHONY: distclean distclean: @$(MAKE) realclean >/dev/null 2>&1 @-rm -rf test_di _mkconfig_runtests \ test_results x \ $(MKC_FILES) \ $(BUILDDIR) \ >/dev/null 2>&1; exit 0 ### # utility .PHONY: tar tar: ./utils/mktar.sh .PHONY: betatar betatar: ./utils/mktar.sh beta ### # cmake .PHONY: cmake-debug cmake-debug: $(MAKE) -e DI_BUILD=Debug cmake-all .PHONY: cmake-sanitize cmake-sanitize: $(MAKE) -e DI_BUILD=SanitizeAddress cmake-all # parallel doesn't seem to work under msys2 # cmake doesn't seem to support parallel under *BSD # (passing -j w/o arguments, and *BSD complains) .PHONY: cmake-all cmake-all: @case `uname -s` in \ CYGWIN*) \ COMP=$(CC) \ $(MAKE) -e cmake-unix; \ $(MAKE) -e cmake-build; \ ;; \ MSYS*|MINGW*) \ COMP=$(CC) \ $(MAKE) -e cmake-windows; \ $(MAKE) -e cmake-build; \ ;; \ *BSD*) \ COMP=$(CC) \ $(MAKE) -e cmake-unix; \ $(MAKE) -e cmake-build; \ ;; \ *) \ COMP=$(CC) \ $(MAKE) -e cmake-unix; \ pmode=--parallel $(MAKE) -e cmake-build; \ ;; \ esac .PHONY: cmakeclang cmakeclang: case `uname -s` in \ *BSD*) \ COMP=$(CC) \ $(MAKE) -e cmake-unix; \ $(MAKE) -e cmake-build; \ ;; \ MSYS*|MINGW*) \ COMP=/ucrt64/bin/clang.exe \ $(MAKE) -e cmake-windows; \ $(MAKE) -e cmake-build; \ ;; \ *) \ $(MAKE) -e cmake-unix; \ pmode=--parallel $(MAKE) -e cmake-build; \ ;; \ esac # --debug-trycompile # internal use .PHONY: cmake-unix cmake-unix: @if [ "$(PREFIX)" = "" ]; then echo "No prefix set"; exit 1; fi @test -d $(BUILDDIR) || mkdir $(BUILDDIR) cmake \ -DCMAKE_C_COMPILER=$(COMP) \ -DCMAKE_INSTALL_PREFIX="$(PREFIX)" \ -DDI_BUILD:STATIC=$(DI_BUILD) \ -DDI_BUILD_SYS:STATIC=make-cmake \ -S . -B $(BUILDDIR) -Werror=deprecated # internal use .PHONY: cmake-windows cmake-windows: @if [ "$(PREFIX)" = "" ]; then echo "No prefix set"; exit 1; fi @test -d $(BUILDDIR) || mkdir $(BUILDDIR) cmake \ -DCMAKE_C_COMPILER=$(COMP) \ -DCMAKE_INSTALL_PREFIX="$(PREFIX)" \ -DDI_BUILD:STATIC=$(DI_BUILD) \ -DDI_BUILD_SYS:STATIC=make-cmake \ -G "MSYS Makefiles" \ -S . -B $(BUILDDIR) -Werror=deprecated # cmake on windows installs extra unneeded crap # --parallel does not work correctly on msys2 # --parallel also seems to not work on *BSD .PHONY: cmake-build cmake-build: cmake --build $(BUILDDIR) $(pmode) .PHONY: cmake-install cmake-install: cmake --install $(BUILDDIR) .PHONY: cmake-test cmake-test: ./build/dimathtest ./build/getoptn_test .PHONY: cmake-chkswitcher cmake-chkswitcher: @echo "cmake" ### # main # have to get various environment variables set up. # don't know any good way to determine if lib64 is preferred .PHONY: mkc-all mkc-all: @. ./VERSION.txt ; \ libnm=`./utils/chklibnm.sh` ; \ $(MAKE) -e LIBNM=$$libnm mkc-sh .PHONY: mkc-sh mkc-sh: $(MKC_ENV) . ./$(MKC_ENV);$(MAKE) -e MKCONFIG_TYPE=sh \ DI_PREFIX=$(PREFIX) \ mkc-di-programs .PHONY: mkc-perl mkc-perl: $(MKC_ENV) . ./$(MKC_ENV) ; \ DI_PREFIX=$(PREFIX) \ DI_VERSION=$(DI_VERSION) \ DI_LIBVERSION=$(DI_LIBVERSION) \ DI_SOVERSION=$(DI_SOVERSION) \ DI_RELEASE_STATUS=$(DI_RELEASE_STATUS) \ $(MAKE) -e MKCONFIG_TYPE=perl \ mkc-di-programs .PHONY: mkc-test mkc-test: . ./$(MKC_ENV); \ ./dimathtest$(EXE_EXT); \ ./getoptn_test$(EXE_EXT) .PHONY: mkc-chkswitcher mkc-chkswitcher: @echo "mkc" .PHONY: mkc-install mkc-install: $(MKC_ENV) mkc-all @. ./VERSION.txt ; \ libnm=`./utils/chklibnm.sh` ; \ . ./$(MKC_ENV);$(MAKE) -e \ PREFIX=$(PREFIX) LIBNM=$$libnm mkc-install-all ### # installation .PHONY: mkc-install-all mkc-install-all: $(MAKE) -e mkc-install-di $(MAKE) -e mkc-install-include $(MAKE) -e mkc-install-libdi -$(MAKE) -e mkc-install-po $(MAKE) -e mkc-install-man $(MAKE) -e mkc-install-pc .PHONY: mkc-install-po mkc-install-po: -./utils/instpo.sh "`pwd`/po" $(INST_LOCALEDIR) "`pwd`/tmp" # -lintl and -liconv are removed, as those libraries are only needed # for the main di program, not to link with the library. .PHONY: mkc-install-pc mkc-install-pc: $(MKC_REQLIB) test -d $(INST_PKGCDIR) || mkdir -p $(INST_PKGCDIR) cat di.pc.in | \ sed -e 's,@CMAKE_INSTALL_PREFIX@,$(PREFIX),g' \ -e 's,@CMAKE_INSTALL_FULL_INCLUDEDIR@,$(INCDIR),g' \ -e 's,@CMAKE_INSTALL_FULL_LIBDIR@,$(LIBDIR),g' \ -e 's,@DI_VERSION@,$(DI_VERSION),g' \ > $(INST_PKGCDIR)/di.pc .PHONY: mkc-install-di mkc-install-di: test -d $(INST_BINDIR) || mkdir -p $(INST_BINDIR) cp -f di$(EXE_EXT) $(INST_BINDIR) .PHONY: mkc-install-include mkc-install-include: test -d $(INST_INCDIR) || mkdir -p $(INST_INCDIR) cp -f di.h $(INST_INCDIR) # not sure about how the naming works on aix # OpenBSD only has the main version, no plain .so .PHONY: mkc-install-libdi mkc-install-libdi: test -d $(INST_LIBDIR) || mkdir -p $(INST_LIBDIR) ./utils/instlibdi.sh "$(INST_LIBDIR)" "$(INST_BINDIR)" $(DI_LIBVERSION) $(DI_SOVERSION) # incorrect for netbsd .PHONY: mkc-install-man mkc-install-man: ./utils/instman.sh "$(PREFIX)" "$(MANDIR)" ### # mkc environment $(MKC_ENV): $(MKC_ENV_CONF) @-rm -f $(MKC_ENV) CC=$(CC) DI_FORTIFY=$(DI_FORTIFY) \ $(_MKCONFIG_SHELL) $(MKC_DIR)/mkconfig.sh $(MKC_ENV_CONF) ### # programs .PHONY: mkc-di-programs mkc-di-programs: di$(EXE_EXT) dimathtest$(EXE_EXT) getoptn_test$(EXE_EXT) ### # configuration file config.h: $(MKC_ENV) $(MKC_CONF) @-rm -f config.h @if [ "$(MKCONFIG_TYPE)" = "sh" -o "$(MKCONFIG_TYPE)" = "" ]; then \ . ./$(MKC_ENV);$(_MKCONFIG_SHELL) \ $(MKC_DIR)/mkconfig.sh \ $(MKC_CONF); fi @if [ "$(MKCONFIG_TYPE)" = "perl" ]; then \ . ./$(MKC_ENV);perl \ $(MKC_DIR)/mkconfig.pl \ $(MKC_CONF); fi $(MKC_REQLIB): config.h @$(_MKCONFIG_SHELL) $(MKC_DIR)/mkc.sh -reqlib \ -o $(MKC_REQLIB) config.h ### # executables LIBOBJECTS = dilib$(OBJ_EXT) didiskutil$(OBJ_EXT) \ digetentries$(OBJ_EXT) digetinfo$(OBJ_EXT) \ diquota$(OBJ_EXT) dizone$(OBJ_EXT) getoptn$(OBJ_EXT) \ dioptions$(OBJ_EXT) distrutils$(OBJ_EXT) MAINOBJECTS = di$(OBJ_EXT) libdi$(SHLIB_EXT): $(MKC_REQLIB) $(LIBOBJECTS) @$(_MKCONFIG_SHELL) $(MKC_DIR)/mkc.sh \ -link -shared $(MKC_ECHO) \ -r $(MKC_REQLIB) \ -o libdi$(SHLIB_EXT) \ $(LIBOBJECTS) di$(EXE_EXT): $(MKC_REQLIB) $(MAINOBJECTS) libdi$(SHLIB_EXT) @$(_MKCONFIG_SHELL) $(MKC_DIR)/mkc.sh \ -link -exec $(MKC_ECHO) \ -r $(MKC_REQLIB) \ -o di$(EXE_EXT) \ $(MAINOBJECTS) \ -L . -ldi \ -R $(LIBDIR) dimathtest$(EXE_EXT): dimathtest$(OBJ_EXT) @$(_MKCONFIG_SHELL) $(MKC_DIR)/mkc.sh \ -link -exec $(MKC_ECHO) \ -o dimathtest$(EXE_EXT) \ dimathtest$(OBJ_EXT) \ -l m getoptn_test$(EXE_EXT): getoptn_test$(OBJ_EXT) distrutils$(OBJ_EXT) @$(_MKCONFIG_SHELL) $(MKC_DIR)/mkc.sh \ -link -exec $(MKC_ECHO) \ -o getoptn_test$(EXE_EXT) \ getoptn_test$(OBJ_EXT) \ distrutils$(OBJ_EXT) \ -l m ### # objects .c$(OBJ_EXT): @$(_MKCONFIG_SHELL) $(MKC_DIR)/mkc.sh -compile -shared $(MKC_ECHO) $< di$(OBJ_EXT): di.c didiskutil$(OBJ_EXT): didiskutil.c digetentries$(OBJ_EXT): digetentries.c digetinfo$(OBJ_EXT): digetinfo.c dilib$(OBJ_EXT): dilib.c dimathtest$(OBJ_EXT): dimathtest.c dioptions$(OBJ_EXT): dioptions.c diquota$(OBJ_EXT): diquota.c distrutils$(OBJ_EXT): distrutils.c dizone$(OBJ_EXT): dizone.c getoptn$(OBJ_EXT): getoptn.c getoptn_test$(OBJ_EXT): getoptn.c @$(_MKCONFIG_SHELL) $(MKC_DIR)/mkc.sh \ -compile $(MKC_ECHO) \ -DTEST_GETOPTN=1 \ -o getoptn_test$(OBJ_EXT) getoptn.c # DO NOT DELETE di.o: config.h di.o: di.h di.o: disystem.h distrutils.h didiskutil.o: config.h didiskutil.o: di.h disystem.h didiskutil.o: diinternal.h didiskutil.o: dimath.h dioptions.h getoptn.h didiskutil.o: distrutils.h dimntopt.h digetentries.o: config.h digetentries.o: di.h disystem.h digetentries.o: diinternal.h dimath.h digetentries.o: dioptions.h getoptn.h distrutils.h digetentries.o: dimntopt.h digetinfo.o: config.h digetinfo.o: di.h disystem.h digetinfo.o: diinternal.h digetinfo.o: dimath.h dioptions.h getoptn.h digetinfo.o: dimntopt.h digetinfo.o: distrutils.h dilib.o: config.h dilib.o: di.h disystem.h dilib.o: dimath.h diinternal.h dilib.o: dioptions.h getoptn.h dizone.h diquota.h distrutils.h dimathtest.o: config.h dimathtest.o: dimath.h dioptions.o: config.h dioptions.o: di.h disystem.h dioptions.o: diinternal.h dioptions.o: dimath.h dioptions.h getoptn.h dioptions.o: distrutils.h diquota.o: config.h diquota.o: di.h diquota.o: disystem.h dimath.h diquota.o: diquota.h diinternal.h dioptions.h diquota.o: getoptn.h distrutils.h distrutils.o: config.h distrutils.o: distrutils.h dizone.o: config.h dizone.o: di.h dizone.h disystem.h dizone.o: dioptions.h getoptn.h distrutils.h getoptn.o: config.h getoptn.o: disystem.h getoptn.o: distrutils.h getoptn.h di-6.0.0/mkconfig/0000755000175000017500000000000014756672321012027 5ustar bllblldi-6.0.0/mkconfig/mkconfig.sh0000755000175000017500000004644414746511107014170 0ustar bllbll#!/bin/sh # # Copyright 2009-2018 Brad Lanam Walnut Creek, CA USA # Copyright 2020 Brad Lanam Pleasant Hill CA # # # speed at the cost of maintainability... # File Descriptors: # 9 - >>$LOG (mkconfig.sh) # 8 - >>$VARSFILE, >>$CONFH (mkconfig.sh) # 7 - saved stdin (mkconfig.sh) # 6 - temporary (c-main.sh, mkconfig.sh) # 4 - temporary (c-main.sh) # # disable path name expansion set -f # set this globally. origcwd=`pwd` unset CDPATH # this is a workaround for ksh93 on solaris if [ "$1" = -d ]; then cd $2 shift shift fi mypath=`echo $0 | sed -e 's,/[^/]*$,,' -e 's,^\.,./.,'` _MKCONFIG_DIR=`(cd $mypath;pwd)` export _MKCONFIG_DIR . ${_MKCONFIG_DIR}/bin/shellfuncs.sh . ${_MKCONFIG_DIR}/bin/envfuncs.sh doshelltest $0 $@ MKC_FILES=${MKC_FILES:-mkc_files} LOG="${MKC_FILES}/mkconfig.log" _MKCONFIG_TMP="${MKC_FILES}/_tmp_mkconfig" CACHEFILE="${MKC_FILES}/mkconfig.cache" allchglist="" INC="mkcinclude.txt" # temporary _chkconfigfname () { if [ "$CONFH" = "" ]; then puts "Config file name not set. Exiting." _exitmkconfig 1 fi } _exitmkconfig () { rc=$1 exit $rc } _savecache () { # And save the data for re-use. # Some shells don't quote the values in the set # command like bash does. So we do it. # Then we have to undo it for bash. # # The $'' syntax interpolates backslashes and nothing else. # For these, remove the $. # # And then there's: x='', which gets munged. # Any value that actually ends with an '=' is going to get mangled. # #savecachedebug=F #if [ $savecachedebug = T ]; then # puts "## savecache original" # set | grep "^mkc_" # puts "## savecache A" # set | grep "^mkc_" | \ # sed -e "s/=/='/" # puts "## savecache B" # set | grep "^mkc_" | \ # sed -e "s/=/='/" -e "s/$/'/" # puts "## savecache C" # set | grep "^mkc_" | \ # sed -e "s/=/='/" -e "s/$/'/" -e "s/''/'/g" # puts "## savecache D" # set | grep "^mkc_" | \ # sed -e "s/=/='/" -e "s/$/'/" -e "s/''/'/g" \ # -e "s/^\([^=]*\)='$/\1=''/" # puts "## savecache E" # set | grep "^mkc_" | \ # sed -e "s/=/='/" -e "s/$/'/" -e "s/''/'/g" \ # -e "s/^\([^=]*\)='$/\1=''/" -e "s/='\$'/='/" #fi #unset savecachedebug set | grep "^mkc_" | \ sed -e "s/=/='/" -e "s/$/'/" -e "s/''/'/g" \ -e "s/^\([^=]*\)='$/\1=''/" -e "s/='\$'/='/" \ > ${CACHEFILE} } setvariable () { svname=$1 if [ $varsfileopen = F ]; then for v in `set | grep "^mkv_" | sed -e 's/=.*$//'`; do unset $v done varsfileopen=T >$VARSFILE exec 8>>$VARSFILE fi cmd="test \"X\$mkv_${svname}\" != X > /dev/null 2>&1" eval $cmd rc=$? # if already in the list of vars, don't add it to the file again. if [ $rc -ne 0 ]; then puts ${svname} >&8 fi cmd="mkv_${svname}=T" eval $cmd puts " setvariable: $cmd" >&9 } setdata () { sdname=$1 sdval=$2 if [ "$_MKCONFIG_EXPORT" = T ]; then _doexport $sdname "$sdval" fi cmd="mkc_${sdname}=\"${sdval}\"" eval $cmd puts " setdata: $cmd" >&9 setvariable $sdname } getdata () { var=$1 gdname=$2 cmd="${var}=\${mkc_${gdname}}" eval $cmd } _setifleveldisp () { ifleveldisp="" for il in $iflevels; do ifleveldisp="${il}${ifleveldisp}" done if [ "$ifleveldisp" != "" ]; then doappend ifleveldisp " " fi } printlabel () { tname=$1 tlabel=$2 puts " $ifleveldisp[${tname}] ${tlabel} ... " >&9 putsnonl "${ifleveldisp}${tlabel} ..." >&1 } _doexport () { var=$1 val=$2 cmd="${var}=\"${val}\"" eval $cmd cmd="export ${var}" eval $cmd } printyesno_actual () { ynname=$1 ynval=$2 yntag=${3:-} puts " [${ynname}] $ynval ${yntag}" >&9 puts " $ynval ${yntag}" >&1 } printyesno_val () { ynname=$1 ynval=$2 yntag=${3:-} if [ "$ynval" != 0 ]; then printyesno_actual "$ynname" "$ynval" "${yntag}" else printyesno_actual "$ynname" no "${yntag}" fi } printyesno () { ynname=$1 ynval=$2 yntag=${3:-} if [ "$ynval" != 0 ]; then ynval=yes fi printyesno_val "$ynname" $ynval "$yntag" } checkcache_val () { tname=$1 getdata tval ${tname} rc=1 if [ "$tval" != "" ]; then setvariable $tname printyesno_actual $tname "$tval" " (cached)" rc=0 fi return $rc } checkcache () { tname=$1 getdata tval ${tname} rc=1 if [ "$tval" != "" ]; then setvariable $tname printyesno $tname $tval " (cached)" rc=0 fi return $rc } check_command () { name=$1 shift ccmd=$1 locnm=_cmd_loc_${ccmd} printlabel $name "command: ${ccmd}" checkcache $name if [ $rc -eq 0 ]; then return; fi trc=0 val="" while test $# -gt 0; do ccmd=$1 shift locatecmd tval $ccmd if [ "$tval" != "" ]; then val=$tval trc=1 fi done printyesno_val $name $val setdata ${name} ${trc} if [ $trc -eq 1 ]; then setdata ${locnm} ${val} fi } check_grep () { name=$1; shift tag=$1; shift pat=$1; shift fn=$1; shift locnm=_grep_${name} printlabel $name "grep: ${tag}" checkcache $name if [ $rc -eq 0 ]; then return; fi ${grepcmd} -l ${pat} ${fn} > /dev/null 2>&1 rc=$? if [ $rc -eq 0 ]; then trc=1; else trc=0; fi printyesno $name $trc setdata ${name} ${trc} } check_if () { iflabel=$1 ifdispcount=$2 ifline=$3 name=$iflabel printlabel $name, "if ($ifdispcount): $iflabel"; boolclean ifline puts "## ifline: $ifline" >&9 trc=0 # if option is not set, it's false nline="test " ineq=0 qtoken="" quoted=0 for token in $ifline; do puts "## token: $token" >&9 case $token in \'*\') token=`puts $token | sed -e s,\',,g` puts "## begin/end quoted token" >&9 ;; \'*) qtoken=$token puts "## begin qtoken: $qtoken" >&9 quoted=1 continue ;; esac if [ $quoted -eq 1 ]; then case $token in *\') token="${qtoken} $token" token=`puts $token | sed -e s,\',,g` puts "## end qtoken: $token" >&9 quoted=0 ;; *) qtoken="$qtoken $token" puts "## in qtoken: $qtoken" >&9 continue ;; esac fi if [ $ineq -eq 1 ]; then ineq=2 getdata tvar $token elif [ $ineq -eq 2 ]; then doappend nline " ( '$tvar' = '$token' )" ineq=0 else case $token in ==) ineq=1 ;; \(|\)|-a|-o|!) doappend nline " $token" ;; *) getdata tvar $token if [ "$tvar" != 0 -a "$tvar" != "" ]; then tvar=1; else tvar=0; fi tvar="( $tvar = 1 )" doappend nline " $tvar" ;; esac fi done if [ "$ifline" != "" ]; then dosubst nline '(' '\\\\\\(' ')' '\\\\\\)' puts "## nline: $nline" >&9 eval $nline trc=$? puts "## eval nline: $trc" >&9 # replace w/ shell return if [ $trc -eq 0 ]; then trc=1; else trc=0; fi puts "## eval nline final: $trc" >&9 fi texp=$_MKCONFIG_EXPORT _MKCONFIG_EXPORT=F printyesno "$name" $trc _MKCONFIG_EXPORT=$texp return $trc } check_set () { nm=$1 type=$2 sval=$3 name=$type tnm=$1 dosubst tnm '_setint_' '' '_setstr' '' printlabel $name "${type}: ${tnm}" if [ "$type" = set ]; then getdata tval ${prefix} ${nm} if [ "$tval" != "" ]; then printyesno $nm "${sval}" setdata ${nm} "${sval}" else printyesno_actual $nm "no such variable" fi elif [ "$type" = setint ]; then printyesno_actual $nm "${sval}" setdata ${nm} "${sval}" else printyesno_actual $nm "${sval}" setdata ${nm} "${sval}" fi } check_env () { type=$1 envvar=$2 dflt=$3 quoted=0 if [ "x$dflt" = xquote ]; then quoted=1 dflt=$4 fi name="_${type}_${envvar}" qname="_${type}quote_${envvar}" printlabel $name "env: ${envvar}" # do not check the cache eval "${envvar}=\${${envvar}:-${dflt}}" eval val="\$${envvar}" trc=0 if [ "x$val" != x ]; then trc=1 fi printyesno_val $name "$val" setdata ${name} "${val}" setdata ${qname} $quoted } check_echo () { val=$1 puts "## echo: $val" >&9 puts "$val" >&1 } check_exit () { puts "## exit" >&9 _exitmkconfig 5 } check_substitute () { nm=$1 sub1=$2 sub2=$3 printlabel $nm "substitute: ${sub1} ${sub2}" doappend allchglist " -e 's~${sub1}~${sub2}~g'" printyesno $nm 1 } _doloadunit () { lu=$1 dep=$2 if [ "$dep" = Y ]; then slu=${lu} tag=" (dependency)" fi if [ -f ${_MKCONFIG_DIR}/units/${lu}.sh ]; then puts "load-unit: ${lu} ${tag}" >&1 puts " found ${lu} ${tag}" >&9 . ${_MKCONFIG_DIR}/units/${lu}.sh tlu=$lu dosubst tlu '-' '_' eval "_MKCONFIG_UNIT_${tlu}=Y" fi if [ "$dep" = Y ]; then lu=$slu tag="" fi } require_unit () { units=$@ for rqu in $units; do trqu=$rqu dosubst trqu '-' '_' cmd="val=\$_MKCONFIG_UNIT_${trqu}" eval $cmd if [ "$val" = Y ]; then puts " required unit ${rqu} already loaded" >&9 continue fi puts " required unit ${rqu} needed" >&9 _doloadunit $rqu Y done } _create_output () { if [ ${CONFH} != none ]; then confdir=`puts ${CONFH} | sed -e 's,/[^/]*$,,'` test -d $confdir || mkdir -p $confdir > ${CONFH} exec 8>>${CONFH} preconfigfile ${CONFH} ${configfile} >&8 if [ -f $VARSFILE ]; then exec 6<&0 < $VARSFILE while read cfgvar; do getdata val $cfgvar output_item ${CONFH} ${cfgvar} "${val}" >&8 done exec <&6 6<&- fi stdconfigfile ${CONFH} >&8 cat $INC >&8 postconfigfile ${CONFH} >&8 exec 8>&- if [ "$allchglist" != "" ]; then cmd="sed ${allchglist} ${CONFH} > ${CONFH}.tmp;mv ${CONFH}.tmp ${CONFH}" eval $cmd fi fi } main_process () { configfile=$1 reqlibs="" if [ -f "$CACHEFILE" ]; then . $CACHEFILE fi reqhdr="" inproc=0 ininclude=0 doproclist="" doproc=1 linenumber=0 ifstmtcount=0 ifleveldisp="" iflevels="" ifcurrlvl=0 doif=$ifcurrlvl initifs > $INC case ${configfile} in /*) ;; *) configfile="../../${configfile}" ;; esac # save stdin in fd 7. # and reset stdin to get from the configfile. # this allows us to run the while loop in the # current shell rather than a subshell. # default varsfile. # a main loadunit will override this. # but don't open it unless it is needed. varsfileopen=F if [ "$VARSFILE" = "" ]; then VARSFILE="../mkc_none.vars" fi # ksh93 93u 'read' changed. Need the raw read for 'include'. # Unfortunately, this affects other shells. # shellfuncs tests for the necessity. rawarg= # save stdin in fd 7; open stdin exec 7<&0 < ${configfile} while read ${rawarg} tdatline; do resetifs domath linenumber "$linenumber + 1" puts "#### ${linenumber}: ${tdatline}" >&9 if [ $ininclude -eq 1 ]; then if [ "${tdatline}" = endinclude ]; then ininclude=0 rawarg= resetifs else if [ $shreqreadraw -eq 1 ]; then # have to do our own backslash processing. # backquotes suck. tdatline=`puts "${tdatline}" | sed -e 's/\\\\\\([^\\\\]\\)/\\1/g' -e 's/\\\\\\\\/\\\\/g'` fi puts "${tdatline}" >> $INC fi else case ${tdatline} in "") continue ;; \#*) continue ;; *) puts "#### ${linenumber}: ${tdatline}" >&9 ;; esac fi if [ $ininclude -eq 0 ]; then case ${tdatline} in "else") if [ $ifcurrlvl -eq $doif ]; then if [ $doproc -eq 0 ]; then doproc=1; else doproc=0; fi set -- $iflevels shift iflevels=$@ iflevels="-$ifstmtcount $iflevels" _setifleveldisp puts "## else: ifcurrlvl: $ifcurrlvl doif: $doif doproc:$doproc" >&9 puts "## else: iflevels: $iflevels" >&9 else puts "## else: ifcurrlvl: $ifcurrlvl doif: $doif doproc:$doproc" >&9 fi ;; "if "*) if [ $doproc -eq 0 ]; then domath ifcurrlvl "$ifcurrlvl + 1" puts "## if: ifcurrlvl: $ifcurrlvl doif: $doif" >&9 fi ;; "endif") puts "## endifA: ifcurrlvl: $ifcurrlvl doif: $doif" >&9 if [ $ifcurrlvl -eq $doif ]; then set $doproclist c=$# if [ $c -gt 0 ]; then puts "## doproclist: $doproclist" >&9 doproc=$1 shift doproclist=$@ puts "## doproc: $doproc doproclist: $doproclist" >&9 set -- $iflevels shift iflevels=$@ _setifleveldisp puts "## endif iflevels: $iflevels" >&9 else doproc=1 ifleveldisp="" iflevels="" fi domath doif "$doif - 1" fi domath ifcurrlvl "$ifcurrlvl - 1" puts "## endifB: ifcurrlvl: $ifcurrlvl doif: $doif" >&9 ;; esac if [ $doproc -eq 1 ]; then case ${tdatline} in \#*) ;; "") ;; command*) _chkconfigfname set $tdatline cmd=$2 shift nm="_command_${cmd}" check_command ${nm} $@ ;; grep*) _chkconfigfname set $tdatline tag=$2 shift nm="_grep_${tag}" check_grep ${nm} $@ ;; "echo"*) _chkconfigfname set $tdatline shift val=$@ check_echo "${val}" ;; "exit") check_exit ;; substitute) check_substitute $@ ;; endinclude) ;; "if "*) _chkconfigfname set $tdatline shift label=$1 shift ifline=$@ domath ifcurrlvl "$ifcurrlvl + 1" puts "## if: ifcurrlvl: $ifcurrlvl" >&9 domath ifstmtcount "$ifstmtcount + 1" check_if $label $ifstmtcount "$ifline" rc=$? iflevels="+$ifstmtcount $iflevels" _setifleveldisp puts "## if iflevels: $iflevels" >&9 doproclist="$doproc $doproclist" doproc=$rc doif=$ifcurrlvl puts "## doproc: $doproc doproclist: $doproclist" >&9 ;; "else") ;; "endif") ;; include) _chkconfigfname ininclude=1 if [ $shreqreadraw -eq 1 ]; then rawarg=-r fi ;; loadunit*) set $tdatline type=$1 file=$2 _doloadunit ${file} N if [ $varsfileopen = T ]; then exec 8>&- varsfileopen=F fi VARSFILE="../mkc_${CONFHTAG}.vars" ;; output*) newout=F if [ $varsfileopen = T ]; then exec 8>&- varsfileopen=F newout=T fi if [ $inproc -eq 1 ]; then _create_output CONFH=none CONFHTAG=none CONFHTAGUC=NONE fi if [ $newout = T ]; then new_output_file > $INC # restart include fi set $tdatline type=$1 file=$2 case ${file} in none) CONFH=${file} ;; /*) CONFH=${file} ;; *) CONFH="../../${file}" ;; esac puts "output-file: ${file}" >&1 puts " config file name: ${CONFH}" >&9 file=`puts $file | sed -e 's,.*/,,'` file=`puts $file | sed -e 's/\..*//'` CONFHTAG=$file CONFHTAGUC=$file toupper CONFHTAGUC VARSFILE="../mkc_${CONFHTAG}.vars" inproc=1 ;; standard) _chkconfigfname standard_checks ;; "set "*|setint*|setstr*) _chkconfigfname set $tdatline type=$1 nm=$2 if [ "$type" = setint -o "$type" = setstr ]; then nm="_${type}_$2" fi shift; shift tval=$@ check_set ${nm} $type "${tval}" ;; *) _chkconfigfname set $tdatline type=$1 chk="check_${type}" cmd="$chk $@" eval $cmd ;; esac fi # doproc fi # ininclude if [ $ininclude -eq 1 ]; then setifs fi done # reset the file descriptors back to the norm. # set stdin to saved fd 7; close fd 7 exec <&7 7<&- if [ $varsfileopen = T ]; then exec 8>&- varsfileopen=F fi _savecache # save the cache file. _create_output } usage () { puts "Usage: $0 [-C] [-c ] [-L ] -C : clear cache-file defaults: : mkconfig.cache : mkconfig.log" } # main mkconfigversion unset GREP_OPTIONS unset ENV unalias sed > /dev/null 2>&1 unalias grep > /dev/null 2>&1 unalias ls > /dev/null 2>&1 unalias rm > /dev/null 2>&1 LC_ALL=C export LC_ALL clearcache=0 while test $# -gt 1; do case $1 in -C) shift clearcache=1 ;; -c) shift CACHEFILE=$1 shift ;; -L) shift LOG=$1 shift ;; esac done configfile=$1 if [ $# -ne 1 ] || [ ! -f $configfile ]; then puts "No configuration file specified or not found." usage exit 1 fi if [ -d $_MKCONFIG_TMP -a $_MKCONFIG_TMP != ${MKC_FILES}/_tmp_mkconfig ]; then puts "$_MKCONFIG_TMP must not exist." usage exit 1 fi test -d $_MKCONFIG_TMP && rm -rf $_MKCONFIG_TMP > /dev/null 2>&1 mkdir -p $_MKCONFIG_TMP cd $_MKCONFIG_TMP LOG="../../$LOG" REQLIB="../../$REQLIB" CACHEFILE="../../$CACHEFILE" VARSFILE="../../$VARSFILE" CONFH=none CONFHTAG=none CONFHTAGUC=NONE if [ $clearcache -eq 1 ]; then rm -f $CACHEFILE > /dev/null 2>&1 rm -f ../mkconfig_*.vars > /dev/null 2>&1 fi dt=`date` exec 9>>$LOG puts "#### " >&9 puts "# Start: $dt " >&9 puts "# $0 ($shell) using $configfile " >&9 puts "#### " >&9 puts "shell: $shell" >&9 puts "has printf: ${shhasprintf}" >&9 puts "has append: ${shhasappend}" >&9 puts "has math: ${shhasmath}" >&9 puts "has upper: ${shhasupper}" >&9 puts "has lower: ${shhaslower}" >&9 puts "read raw req: ${shreqreadraw}" >&9 locateawkcmd puts "awk: $awkcmd" >&9 locatepkgconfigcmd echo "pkg-config: $pkgconfigcmd" >&9 puts "$0 ($shell) using $configfile" main_process $configfile dt=`date` puts "#### " >&9 puts "# End: $dt " >&9 puts "#### " >&9 exec 9>&- cd .. if [ "$MKC_KEEP_TMP" = "" ]; then test -d $_MKCONFIG_TMP && rm -rf $_MKCONFIG_TMP > /dev/null 2>&1 fi exit 0 di-6.0.0/mkconfig/mkc.sh0000755000175000017500000000303114746517071013134 0ustar bllbll#!/bin/sh # # Copyright 2009-2018 Brad Lanam Walnut Creek, CA USA # Copyright 2020 Brad Lanam Pleasant Hill CA # # this is a workaround for ksh93 on solaris unset CDPATH if [ "$1" = "-d" ]; then cd $2 shift shift fi mypath=`echo $0 | sed -e 's,/[^/]*$,,' -e 's,^\.,./.,'` _MKCONFIG_DIR=`(cd $mypath;pwd)` export _MKCONFIG_DIR . ${_MKCONFIG_DIR}/bin/shellfuncs.sh . ${_MKCONFIG_DIR}/bin/envfuncs.sh doshelltest $0 $@ if [ "$MKC_PREFIX" != "" ]; then if [ "$MKC_CONFDIR" = "" ]; then MKC_CONFDIR=. export MKC_CONFDIR else test -d "${MKC_CONFDIR}" || mkdir -p "${MKC_CONFDIR}" fi if [ "$MKC_OUTPUT" = "" ]; then MKC_OUTPUT=config.h export MKC_OUTPUT fi if [ ! -f ${MKC_CONFDIR}/${MKC_PREFIX}.env ]; then ${_MKCONFIG_SHELL} ${MKC_DIR}/mkconfig.sh ${MKC_CONFDIR}/${MKC_PREFIX}-env.mkc fi if [ -f ${MKC_PREFIX}.env ]; then . ./${MKC_PREFIX}.env if [ ! -f ${MKC_OUTPUT} ]; then ${_MKCONFIG_SHELL} ${MKC_DIR}/mkconfig.sh ${MKC_CONFDIR}/${MKC_PREFIX}.mkc fi fi fi rc=0 args=$@ found=T case $1 in -compile|-comp|-link) ${_MKCONFIG_SHELL} ${_MKCONFIG_DIR}/bin/mkcl.sh -d `pwd` "$@" rc=$? shift ;; -staticlib) shift ${_MKCONFIG_SHELL} ${_MKCONFIG_DIR}/bin/mkstaticlib.sh -d `pwd` "$@" rc=$? ;; -reqlib) shift ${_MKCONFIG_SHELL} ${_MKCONFIG_DIR}/bin/mkreqlib.sh -d `pwd` "$@" rc=$? ;; -makeconfig) rc=0 ;; *) found=F ;; esac if [ $found = F ]; then echo "Usage: $0 {-compile|-link|-reqlib|-shared} " exit 1 fi exit $rc di-6.0.0/mkconfig/units/0000755000175000017500000000000014756672233013173 5ustar bllblldi-6.0.0/mkconfig/units/env-systype.sh0000755000175000017500000000670214746502571016041 0ustar bllbll#!/bin/sh # # Copyright 2010-2018 Brad Lanam Walnut Creek, CA USA # Copyright 2020 Brad Lanam Pleasant Hill CA # # # speed at the cost of maintainability... # File Descriptors: # 9 - >>$LOG (mkconfig.sh) # 8 - >>$VARSFILE, >>$CONFH (mkconfig.sh) # 7 - temporary for mkconfig.sh (mkconfig.sh) # 6 - temporary for c-main.sh (c-main.sh) # 5 - temporary for c-main.sh (c-main.sh) # require_unit env-main env_dolocuname=F _dolocuname () { if [ $env_dolocuname = "T" ]; then return fi locatecmd xuname uname puts "uname located: ${xuname}" >&9 env_dolocuname=T } check_system () { name="_MKCONFIG_SYS" arg=$2 uarg=$arg toupper uarg name="${name}${uarg}" _dolocuname if [ "$arg" = "type" ]; then printlabel $name "system: type" if [ "${xuname}" != "" ] then _MKCONFIG_SYSTYPE=`${xuname} -s` else puts "no uname, try some guessing" >&9 # no uname...we'll have to do some guessing. _MKCONFIG_SYSTYPE="unknown" if [ -f /vmunix ]; then # some sort of BSD variant _MKCONFIG_SYSTYPE="BSD" else _MKCONFIG_SYSTYPE="SYSV" # some SysV variant, probably. fi fi puts "type: ${_MKCONFIG_SYSTYPE}" >&9 printyesno_val _MKCONFIG_SYSTYPE "${_MKCONFIG_SYSTYPE}" setdata _MKCONFIG_SYSTYPE "${_MKCONFIG_SYSTYPE}" fi if [ "$arg" = "rev" ]; then printlabel $name "system: rev" if [ "${xuname}" != "" ] then case ${_MKCONFIG_SYSTYPE} in AIX) tmp=`( (oslevel) 2>/dev/null || puts "not found") 2>&1` case "$tmp" in 'not found') _MKCONFIG_SYSREV="$4"."$3" ;; '<3240'|'<>3240') _MKCONFIG_SYSREV=3.2.0 ;; '=3240'|'>3240'|'<3250'|'<>3250') _MKCONFIG_SYSREV=3.2.4 ;; '=3250'|'>3250') _MKCONFIG_SYSREV=3.2.5 ;; *) _MKCONFIG_SYSREV=$tmp ;; esac ;; *) _MKCONFIG_SYSREV=`${xuname} -r` ;; esac else puts "no uname, try some guessing" >&9 # no uname...we'll have to do some guessing. _MKCONFIG_SYSREV="unknown" if [ -f /vmunix ]; then # sys/param.h might have: # #define BSD 43 # #define BSD4_3 1 rev=`grep '^#define.*BSD[^0-9]' /usr/include/sys/param.h | sed 's,/.*,,'` if [ "rev" != "" ]; then rev=`puts $rev | sed 's/^[^0-9]*\([0-9]\)\([0-9]\).*/\1.\2/'` _MKCONFIG_SYSREV="$rev" fi fi fi puts "rev: ${_MKCONFIG_SYSREV}" >&9 printyesno_val _MKCONFIG_SYSREV "${_MKCONFIG_SYSREV}" setdata _MKCONFIG_SYSREV "${_MKCONFIG_SYSREV}" fi if [ "$arg" = "arch" ]; then printlabel $name "system: arch" if [ "${xuname}" != "" ] then _MKCONFIG_SYSARCH=`${xuname} -m` else puts "no uname, try some guessing" >&9 # no uname...we'll have to do some guessing. _MKCONFIG_SYSARCH="unknown" locatecmd xarch arch puts "arch located: ${xarch}" >&9 if [ "${xarch}" != "" ]; then _MKCONFIG_SYSARCH=`arch` fi fi puts "arch: ${_MKCONFIG_SYSARCH}" >&9 printyesno_val _MKCONFIG_SYSARCH "${_MKCONFIG_SYSARCH}" setdata _MKCONFIG_SYSARCH "${_MKCONFIG_SYSARCH}" fi } check_standard_system () { check_system system type check_system system rev check_system system arch } di-6.0.0/mkconfig/units/env-main.sh0000755000175000017500000001110114750245307015226 0ustar bllbll#!/bin/sh # # Copyright 2010-2018 Brad Lanam Walnut Creek CA USA # Copyright 2020 Brad Lanam Pleasant Hill CA # # # # speed at the cost of maintainability... # File Descriptors: # 9 - >>$LOG (mkconfig.sh) # 8 - >>$VARSFILE, >>$CONFH (mkconfig.sh) # 7 - temporary for mkconfig.sh (mkconfig.sh) # 6 - temporary for c-main.sh (c-main.sh) # 5 - temporary for c-main.sh (c-main.sh) # _MKCONFIG_HASEMPTY=T _MKCONFIG_EXPORT=T preconfigfile () { pc_configfile=$1 configfile=$2 puts "#!/bin/sh" puts "# Created on: `date`" puts "# From: ${configfile}" puts "# Using: mkconfig-${_MKCONFIG_VERSION}" return } stdconfigfile () { pc_configfile=$1 return } postconfigfile () { pc_configfile=$1 return } standard_checks () { return } check_source () { nm=$1 fn=$2 tfn=$fn dosubst tfn '.*/' '' '\.' '' '-' '' name=_${nm}_${tfn} printlabel $nm "source: $fn" trc=0 val=0 if [ -f $fn ]; then trc=1 val=$fn fi printyesno $name $trc setdata ${name} $val } output_item () { out=$1 name=$2 val=$3 case $name in _source_*) if [ $val != "0" ]; then puts ". ${val}" fi ;; _setint*|_setstr*|_opt_*) tname=$name dosubst tname '_setint_' '' '_setstr_' '' '_opt_' '' puts "${tname}=\"${val}\"" puts "export ${tname}" ;; *) puts "${name}=\"${val}\"" puts "export ${name}" ;; esac } check_test_multword () { name=$1 printlabel $name "test: multiword" val="word1 word2" printyesno_val $name "$val" setdata $name "$val" } new_output_file () { return 0 } check_pkg () { type=$2 pkgname=$3 pkgpath=$4 name=_pkg_${type}_${pkgname} dosubst name '\.' '' '-' '' puts "pkg $type: $pkgname $pkgpath" >&9 printlabel $name "pkg ${type}: ${pkgname}" check_pkg_exists $name $pkgname $pkgpath trc=$? if [ $trc -eq 0 ]; then return $trc fi check_pkg_$type $name $pkgname $pkgpath trc=$? return $trc } check_pkg_exists () { name=$1 pkgname=$2 pkgpath=$3 trc=0 if [ "${pkgconfigcmd}" = "" ]; then printyesno $name $trc "(no pkg-config)" return $trc fi OPKG_CONFIG_PATH=$PKG_CONFIG_PATH if [ "$pkgpath" != "" ]; then if [ "$PKG_CONFIG_PATH" != "" ]; then doappend PKG_CONFIG_PATH : fi doappend PKG_CONFIG_PATH $pkgpath fi export PKG_CONFIG_PATH ${pkgconfigcmd} --exists $pkgname rc=$? if [ $rc -ne 0 ]; then printyesno $name $trc "(no such package)" else trc=1 fi unset PKG_CONFIG_PATH if [ "$OPKG_CONFIG_PATH" != "" ]; then PKG_CONFIG_PATH=$OPKG_CONFIG_PATH fi return $trc } test_cflag () { flag=$1 quoted=$2 puts "#include int main (int argc, char *argv []) { return 0; }" > t.c puts "# test ${flag}" >&9 # need to set w/all cflags; gcc doesn't always error out otherwise TMPF=t$$.txt setcflags if [ "$quoted" != "" ]; then ${CC} ${CFLAGS} "${flag}" t.c > $TMPF 2>&1 rc=$? else ${CC} ${CFLAGS} ${flag} t.c > $TMPF 2>&1 rc=$? fi if [ $rc -ne 0 ]; then flag=0 fi grep -i "warning.*${flag}" $TMPF > /dev/null 2>&1 rc=$? if [ $rc -eq 0 ]; then flag=0 fi grep -i "error.*${flag}" $TMPF > /dev/null 2>&1 rc=$? if [ $rc -eq 0 ]; then flag=0 fi # AIX grep -i "Option.*incorrectly specified" $TMPF > /dev/null 2>&1 rc=$? if [ $rc -eq 0 ]; then flag=0 fi cat $TMPF >&9 rm -f $TMPF > /dev/null 2>&1 } test_ldflags () { flag=$1 quoted=$2 setcflags setldflags setlibs puts "#include int main (int argc, char *argv []) { return 0; }" > t.c puts "# test ${flag}" >&9 # need to set w/all cflags/ldflags; gcc doesn't always error out otherwise TMPF=t$$.txt if [ "$quoted" != "" ]; then ${CC} ${CFLAGS} ${LDFLAGS} "${flag}" -o t t.c > $TMPF 2>&1 rc=$? else ${CC} ${CFLAGS} ${LDFLAGS} ${flag} -o t t.c > $TMPF 2>&1 rc=$? fi if [ $rc -ne 0 ]; then flag=0 fi grep -i "warning.*${flag}" $TMPF > /dev/null 2>&1 rc=$? if [ $rc -eq 0 ]; then flag=0 fi grep -i "error.*${flag}" $TMPF > /dev/null 2>&1 rc=$? if [ $rc -eq 0 ]; then flag=0 fi cat $TMPF >&9 rm -f $TMPF > /dev/null 2>&1 } test_incpath () { flag=$1 if [ -d "$flag" ]; then test_cflag "-I$flag" quoted else if [ -d "$origcwd/$flag" ]; then test_cflag "-I$origcwd/$flag" quoted else flag=0 fi fi } test_ldsrchpath () { flag=$1 if [ -d "$flag" ]; then test_ldflags "-L$flag" quoted else if [ -d "$origcwd/$flag" ]; then test_cflag "-L$origcwd/$flag" quoted else flag=0 fi fi } di-6.0.0/mkconfig/units/c-support.sh0000755000175000017500000001357614746502651015475 0ustar bllbll#!/bin/sh # # Copyright 2010-2018 Brad Lanam Walnut Creek CA USA # Copyright 2020 Brad Lanam Pleasant Hill CA # CPPCOUNTER=1 postcc=" /* some gcc's (cygwin) redefine __restrict again */ #if defined (__restrict) # undef __restrict #endif #define __restrict " _c_print_headers () { incheaders=$1 cppchk=$2 if [ "$incheaders" = "none" ]; then return fi out="${PH_PREFIX}${incheaders}" if [ -f $out ]; then cat $out return fi if [ "$PH_STD" = "T" -a "$incheaders" = "std" ]; then _c_print_hdrs std $cppchk > $out cat $out return fi if [ "$PH_ALL" = "T" -a "$incheaders" = "all" ]; then _c_print_hdrs all $cppchk > $out cat $out return fi # until PH_STD/PH_ALL becomes true, just do normal processing. _c_print_hdrs $incheaders $cppchk } _c_print_hdrs () { incheaders=$1 cppchk=$2 if [ "${incheaders}" = "all" -o "${incheaders}" = "std" ]; then for tnm in '_hdr_stdio' '_hdr_stdlib' '_sys_types' '_sys_param'; do getdata tval ${tnm} if [ "${tval}" != "0" -a "${tval}" != "" ]; then puts "#include <${tval}>" # for cygwin/gcc if [ "$cppchk" = T -a $tnm = _hdr_stdio ]; then puts "${postcc}" fi fi done fi if [ "${incheaders}" = "all" -a -f "$VARSFILE" ]; then # save stdin in fd 6; open stdin exec 6<&0 < ${VARSFILE} while read cfgvar; do getdata hdval ${cfgvar} case ${cfgvar} in _hdr_stdio|_hdr_stdlib|_sys_types|_sys_param) ;; _hdr_linux_quota) if [ "${hdval}" != "0" ]; then getdata iqval '_inc_conflict__sys_quota__hdr_linux_quota' if [ "${iqval}" = "1" ]; then puts "#include <${hdval}>" fi fi ;; _sys_time) if [ "${hdval}" != "0" ]; then getdata itval '_inc_conflict__hdr_time__sys_time' if [ "${itval}" = "1" ]; then puts "#include <${hdval}>" fi fi ;; _hdr_*|_sys_*) if [ "${hdval}" != "0" -a "${hdval}" != "" ]; then puts "#include <${hdval}>" fi ;; esac done # set std to saved fd 6; close 6 exec <&6 6<&- fi } _c_chk_run () { crname=$1 code=$2 inc=$3 _c_chk_link_libs ${crname} "${code}" $inc rc=$? puts "## run test: link: $rc" >&9 rval=0 if [ $rc -eq 0 ]; then rval=`./${crname}.exe` rc=$? puts "## run test: run: $rc retval:$rval" >&9 if [ $rc -lt 0 ]; then _exitmkconfig $rc fi fi _retval=$rval return $rc } _c_chk_link_libs () { cllname=$1 code=$2 inc=$3 shift;shift;shift ocounter=0 clotherlibs="'$otherlibs'" dosubst clotherlibs ',' "' '" if [ "${clotherlibs}" != "" ]; then eval "set -- $clotherlibs" ocount=$# else ocount=0 fi tcfile=${cllname}.c >${tcfile} # $cllname should be unique exec 4>>${tcfile} puts "${precc}" >&4 _c_print_headers $inc >&4 puts "${code}" | sed 's/_dollar_/$/g' >&4 exec 4>&- dlibs="" otherlibs="" _c_chk_link $cllname rc=$? puts "## link test (none): $rc" >&9 if [ $rc -ne 0 ]; then while test $ocounter -lt $ocount; do domath ocounter "$ocounter + 1" eval "set -- $clotherlibs" cmd="olibs=\$${ocounter}" eval $cmd dlibs=${olibs} otherlibs=${olibs} _c_chk_link $cllname rc=$? puts "## link test (${olibs}): $rc" >&9 if [ $rc -eq 0 ]; then break fi done fi _retdlibs=$dlibs return $rc } _c_chk_cpp () { cppname=$1 code="$2" inc=$3 tcppfile=${cppname}.c tcppout=${cppname}.out tcppreuse=F if [ "$code" = "" -a $inc = all ]; then tcppreuse=T tcppfile=chkcpp_${CPPCOUNTER}.c tcppout=chkcpp_${CPPCOUNTER}.out if [ -f $tcppfile -a -f $tcppout ]; then test -f ${cppname}.out && rm -f ${cppname}.out ln -s ${tcppout} ${cppname}.out puts "## _cpp test: reusing $tcppout" >&9 rc=0 return $rc fi fi # $cppname should be unique exec 4>>${tcppfile} puts "${precc}" >&4 _c_print_headers $inc T >&4 puts "${code}" | sed 's/_dollar_/$/g' >&4 exec 4>&- setcflags cmd="${CC} ${CFLAGS} -E ${tcppfile} > ${tcppout} " puts "## _cpp test: $cmd" >&9 cat ${tcppfile} >&9 eval $cmd >&9 2>&9 rc=$? if [ $rc -lt 0 ]; then _exitmkconfig $rc fi if [ $tcppreuse = T ]; then test -f ${cppname}.out && rm -f ${cppname}.out ln -s ${tcppout} ${cppname}.out fi puts "## _cpp test: $rc" >&9 return $rc } _c_chk_link () { clname=$1 setcflags setldflags setlibs cmd="${CC} ${CFLAGS} -o ${clname}.exe ${clname}.c " cmd="${cmd} ${LDFLAGS} ${LIBS} " _clotherlibs=$otherlibs if [ "$staticlib" = "T" ]; then _tolibs=${_clotherlibs} _clotherlibs="$LDFLAGS_STATIC_LIB_LINK ${_tolibs} $LDFLAGS_SHARED_LIB_LINK " unset _tolibs fi if [ "${_clotherlibs}" != "" ]; then cmd="${cmd} ${_clotherlibs} " fi puts "## _link test: $cmd" >&9 cat ${clname}.c >&9 eval $cmd >&9 2>&9 rc=$? if [ $rc -lt 0 ]; then _exitmkconfig $rc fi puts "## _link test: $rc" >&9 if [ $rc -eq 0 ]; then if [ ! -x "${clname}.exe" ]; then # not executable rc=1 puts "## _link test: not executable $rc" >&9 fi fi return $rc } _c_chk_compile () { ccname=$1 code=$2 inc=$3 tcfile=${ccname}.c >${tcfile} # $ccname should be unique exec 4>>${tcfile} puts "${precc}" >&4 _c_print_headers $inc >&4 puts "${code}" | sed 's/_dollar_/$/g' >&4 exec 4>&- setcflags cmd="${CC} ${CFLAGS} -c ${tcfile}" puts "## compile test: $cmd" >&9 cat ${ccname}.c >&9 eval ${cmd} >&9 2>&9 rc=$? puts "## compile test: $rc" >&9 return $rc } do_c_check_compile () { dccname=$1 code=$2 inc=$3 _c_chk_compile ${dccname} "${code}" $inc rc=$? try=0 if [ $rc -eq 0 ]; then try=1 fi printyesno $dccname $try setdata ${dccname} ${try} } di-6.0.0/mkconfig/units/env-cc.sh0000755000175000017500000005614414756670532014717 0ustar bllbll#!/bin/sh # # Copyright 2001-2018 Brad Lanam, Walnut Creek, California USA # Copyright 2020 Brad Lanam Pleasant Hill CA # # # speed at the cost of maintainability... # File Descriptors: # 9 - >>$LOG (mkconfig.sh) # 8 - >>$VARSFILE, >>$CONFH (mkconfig.sh) # 7 - temporary for mkconfig.sh (mkconfig.sh) # 6 - temporary for c-main.sh (c-main.sh) # 5 - temporary for c-main.sh (c-main.sh) # require_unit env-main require_unit env-systype env_dogetconf=F _MKCONFIG_32BIT_FLAGS=F # helper routine _setflags () { while test $# -gt 0; do _tvar=$1 _tenm=$2 shift;shift eval _tval=\$$_tvar dosubst _tval '^ *' '' setdata ${_tenm} "$_tval" done } _dogetconf () { if [ "$env_dogetconf" = T ]; then return fi if [ ${_MKCONFIG_32BIT_FLAGS} = T ]; then lfccflags= lfldflags= lflibs= env_dogetconf=T return fi locatecmd xgetconf getconf if [ z${xgetconf} != z ] then puts "using flags from getconf" >&9 lfccflags=`${xgetconf} LFS_CFLAGS 2>/dev/null` if [ "$lfccflags" = undefined ]; then lfccflags= fi lfldflags=`${xgetconf} LFS_LDFLAGS 2>/dev/null` if [ "$lfldflags" = undefined ]; then lfldflags= fi lflibs=`${xgetconf} LFS_LIBS 2>/dev/null` if [ "$lflibs" = undefined ]; then lflibs= fi fi env_dogetconf=T } check_32bitflags () { _MKCONFIG_32BIT_FLAGS=T printlabel _MKCONFIG_32BIT_FLAGS "32 bit flags" printyesno_val _MKCONFIG_32BIT_FLAGS "${_MKCONFIG_32BIT_FLAGS}" setdata _MKCONFIG_32BIT_FLAGS "${_MKCONFIG_32BIT_FLAGS}" } check_cc () { CC=${CC:-${oval}} printlabel CC "C compiler" case ${_MKCONFIG_SYSTYPE} in BeOS|Haiku) case ${CC} in cc|gcc) CC=g++ ;; esac ;; syllable) case ${CC} in cc|gcc) CC=g++ ;; esac ;; esac puts "cc:${CC}" >&9 printyesno_val CC "${CC}" setdata CC "${CC}" if [ ${_MKCONFIG_32BIT_FLAGS} = F ]; then setdata _MKCONFIG_32BIT_FLAGS "${_MKCONFIG_32BIT_FLAGS}" fi } check_using_cplusplus () { usingcplusplus="N" printlabel _MKCONFIG_USING_CPLUSPLUS "Using c++" case ${CC} in *g++*|*clang++*|*c++*) usingcplusplus="Y" ;; esac printyesno_val _MKCONFIG_USING_CPLUSPLUS "${usingcplusplus}" setdata _MKCONFIG_USING_CPLUSPLUS "${usingcplusplus}" } check_using_gcc () { usinggcc="N" printlabel _MKCONFIG_USING_GCC "Using gcc/g++" # check for gcc... ${CC} -v 2>&1 | grep 'gcc version' >/dev/null 2>&1 rc=$? if [ $rc -eq 0 ]; then puts "found gcc" >&9 usinggcc="Y" fi case ${CC} in *gcc*|*g++*) usinggcc="Y" ;; esac printyesno_val _MKCONFIG_USING_GCC "${usinggcc}" setdata _MKCONFIG_USING_GCC "${usinggcc}" } check_using_clang () { usingclang="N" printlabel _MKCONFIG_USING_CLANG "Using clang" # check for clang... ${CC} -v 2>&1 | grep 'clang version' > /dev/null 2>&1 rc=$? if [ $rc -eq 0 ]; then puts "found clang" >&9 usingclang="Y" fi case ${CC} in *clang*) usingclang="Y" ;; esac printyesno_val _MKCONFIG_USING_CLANG "${usingclang}" setdata _MKCONFIG_USING_CLANG "${usingclang}" } check_using_gnu_ld () { usinggnuld="N" printlabel _MKCONFIG_USING_GNU_LD "Using gnu ld" # check for gnu ld... # dragonfly bsd 5.8.1 gcc8 reports 'GNU gold' rather than 'GNU ld'. ld -v 2>&1 | grep 'GNU' > /dev/null 2>&1 rc=$? if [ $rc -eq 0 ]; then puts "found gnu ld" >&9 usinggnuld="Y" fi printyesno_val _MKCONFIG_USING_GNU_LD "${usinggnuld}" setdata _MKCONFIG_USING_GNU_LD "${usinggnuld}" } check_cflags () { cflags_debug=${CFLAGS_DEBUG:-} cflags_optimize=${CFLAGS_OPTIMIZE:--O2} cflags_include=${CFLAGS_INCLUDE} cflags_user=${CFLAGS_USER} cflags_compiler=${CFLAGS_COMPILER} cflags_system=${CFLAGS_SYSTEM} cflags_application=${CFLAGS_APPLICATION} if [ "${_MKCONFIG_USING_GCC}" = Y ]; then puts "set gcc flags" >&9 gccflags="-Wall -Waggregate-return -Wconversion -Wformat -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Wpointer-arith -Wshadow -Wstrict-prototypes -Wunused -Wno-unknown-pragmas" # -Wextra -Wno-unused-but-set-variable -Wno-unused-parameter case ${CC} in g++|c++) if [ "${_MKCONFIG_USING_GCC}" = Y ]; then puts "set g++ flags" >&9 gccflags="-Wall -Waggregate-return -Wconversion -Wformat -Wpointer-arith -Wshadow -Wunused" fi ;; esac doappend cflags_compiler " $gccflags" fi if [ "${_MKCONFIG_USING_CLANG}" = Y ]; then puts "set clang flags" >&9 doappend cflags_compiler " -Wno-unknown-warning-option -Weverything -Wno-padded -Wno-format-nonliteral -Wno-cast-align -Wno-system-headers -Wno-disabled-macro-expansion" fi TCC=${CC} if [ "${_MKCONFIG_USING_GCC}" = Y ]; then TCC=gcc fi case ${_MKCONFIG_SYSTYPE} in AIX) if [ "${_MKCONFIG_USING_GCC}" = N ]; then doappend cflags_system " -qhalt=e -qmaxmem=-1" case ${_MKCONFIG_SYSREV} in 4.*) doappend cflags_system " -DUSE_ETC_FILESYSTEMS=1" ;; esac fi ;; Darwin) if [ -d /opt/local/include ]; then doappend cflags_include " -I/opt/local/include" fi if [ -d /opt/homebrew/include ]; then doappend cflags_include " -I/opt/homebrew/include" fi ;; DragonFly|FreeBSD|OpenBSD) # *BSD has many packages that get installed in /usr/local doappend cflags_include " -I/usr/local/include" ;; NetBSD) doappend cflags_include " -I/usr/pkg/include" ;; HP-UX) if [ "z${lfccflags}" = z -a "${_MKCONFIG_32BIT_FLAGS}" = F ]; then doappend cflags_system " -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64" fi case ${TCC} in cc) case ${_MKCONFIG_SYSREV} in *.10.*) doappend cflags_system " +DAportable" ;; esac case ${_MKCONFIG_SYSARCH} in ia64) doappend cflags_system " +DD64" ;; esac cc -v 2>&1 | grep -l Bundled > /dev/null 2>&1 rc=$? if [ $rc -ne 0 ]; then doappend cflags_system " -Ae" fi _MKCONFIG_USING_GCC=N ;; esac if [ -d /usr/local/include -a \ -d /usr/local/lib ]; then doappend cflags_include " -I/usr/local/include" fi ;; SunOS) case ${_MKCONFIG_SYSREV} in 5.*) case ${TCC} in cc) # If solaris is compile w/strict ansi, we get # a work-around for the long long type with # large files. So we compile w/extensions. doappend cflags_system " -Xa -v" # optimization; -xO3 is good. -xO4 must be set by user. cflags_optimize="-xO3" ;; esac ;; esac ;; esac _dogetconf # largefile flags doappend cflags_system " $lfccflags" # plain CFLAGS will be interpreted as the user's cflags cflags_user=$CFLAGS if [ "z$CFLAGS_DEBUG" != z ]; then cflags_debug="$CFLAGS_DEBUG" fi if [ "z$CFLAGS_OPTIMIZE" != z ]; then cflags_optimize="$CFLAGS_OPTIMIZE" fi doappend cflags_include " $CFLAGS_INCLUDE" doappend cflags_include " $CPPFLAGS" puts "cflags_debug:${cflags_debug}" >&9 puts "cflags_optimize:${cflags_optimize}" >&9 puts "cflags_include:${cflags_include}" >&9 puts "cflags_user:${cflags_user}" >&9 puts "cflags_compiler:${cflags_compiler}" >&9 puts "cflags_system:${cflags_system}" >&9 puts "cflags_application:${cflags_application}" >&9 _setflags \ cflags_debug CFLAGS_DEBUG \ cflags_optimize CFLAGS_OPTIMIZE \ cflags_user CFLAGS_USER \ cflags_include CFLAGS_INCLUDE \ cflags_compiler CFLAGS_COMPILER \ cflags_system CFLAGS_SYSTEM \ cflags_application CFLAGS_APPLICATION } check_addcflag () { name=$1 shift flag=$* printlabel CFLAGS_APPLICATION "Add C flag: ${flag}" test_cflag "$flag" printyesno $name "${flag}" if [ "$flag" != 0 ]; then doappend CFLAGS_APPLICATION " $flag" setdata CFLAGS_APPLICATION "$CFLAGS_APPLICATION" fi } check_addincpath () { name=$1 flag=$2 printlabel CFLAGS_APPLICATION "Add Include Path: ${flag}" test_incpath "$flag" printyesno $name "${flag}" if [ "$flag" != 0 ]; then dosubst flag ' ' '\\\\\\\\\ ' doappend CFLAGS_APPLICATION " " initifs setifs doappend CFLAGS_APPLICATION $flag resetifs setdata CFLAGS_APPLICATION "$CFLAGS_APPLICATION" fi } helper_pkg_path () { for p in $HOME/local/lib /usr/local/lib \ /opt/local/lib /opt/homebrew/lib /usr/pkg/lib /usr/local/lib/hpux64; do if [ -d $td ]; then doappend PKG_CONFIG_PATH $p fi done } check_pkg_cflags () { name=$1 pkgname=$2 pkgpath=$3 OPKG_CONFIG_PATH=$PKG_CONFIG_PATH helper_pkg_path if [ "$pkgpath" != "" ]; then if [ "$PKG_CONFIG_PATH" != "" ]; then doappend PKG_CONFIG_PATH : fi doappend PKG_CONFIG_PATH $pkgpath fi export PKG_CONFIG_PATH tcflags=`${pkgconfigcmd} --cflags $pkgname` unset PKG_CONFIG_PATH if [ "$OPKG_CONFIG_PATH" != "" ]; then PKG_CONFIG_PATH=$OPKG_CONFIG_PATH fi test_cflag "$tcflags" printyesno_val $name "${flag}" if [ "$flag" != 0 ]; then doappend CFLAGS_APPLICATION " $flag" setdata CFLAGS_APPLICATION "$CFLAGS_APPLICATION" setdata ${name} "$flag" fi } check_pkg_include () { name=$1 pkgname=$2 pkgpath=$3 OPKG_CONFIG_PATH=$PKG_CONFIG_PATH helper_pkg_path if [ "$pkgpath" != "" ]; then if [ "$PKG_CONFIG_PATH" != "" ]; then doappend PKG_CONFIG_PATH : fi doappend PKG_CONFIG_PATH $pkgpath fi export PKG_CONFIG_PATH tcflags=`${pkgconfigcmd} --cflags-only-I $pkgname` unset PKG_CONFIG_PATH if [ "$OPKG_CONFIG_PATH" != "" ]; then PKG_CONFIG_PATH=$OPKG_CONFIG_PATH fi test_cflag "$tcflags" printyesno_val $name "${flag}" if [ "$flag" != 0 ]; then doappend CFLAGS_APPLICATION " $flag" setdata CFLAGS_APPLICATION "$CFLAGS_APPLICATION" setdata ${name} "$flag" fi } check_pkg_libs () { name=$1 pkgname=$2 pkgpath=$3 OPKG_CONFIG_PATH=$PKG_CONFIG_PATH helper_pkg_path if [ "$pkgpath" != "" ]; then if [ "$PKG_CONFIG_PATH" != "" ]; then doappend PKG_CONFIG_PATH : fi doappend PKG_CONFIG_PATH $pkgpath export PKG_CONFIG_PATH fi export PKG_CONFIG_PATH tldflags=`${pkgconfigcmd} --libs $pkgname` unset PKG_CONFIG_PATH if [ "$OPKG_CONFIG_PATH" != "" ]; then PKG_CONFIG_PATH=$OPKG_CONFIG_PATH fi test_ldflags "$tldflags" printyesno_val $name "$flag" if [ "$flag" != 0 ]; then doappend LDFLAGS_LIBS_APPLICATION " $flag" setdata LDFLAGS_LIBS_APPLICATION "$LDFLAGS_LIBS_APPLICATION" setdata ${name} "$flag" fi } check_addldflag () { name=$1 shift flag=$* printlabel LDFLAGS_APPLICATION "Add LD flag: ${flag}" test_ldflags "$flag" printyesno $name "$flag" if [ "$flag" != 0 ]; then doappend ldflags_application " " doappend ldflags_application "\"$flag\"" _setflags ldflags_application LDFLAGS_APPLICATION fi } check_addlibs () { name=$1 shift flag=$* printlabel LDFLAGS_LIBS_APPLICATION "Add Library: ${flag}" test_ldflags "$flag" printyesno $name "$flag" if [ "$flag" != 0 ]; then doappend ldflags_libs_application " " doappend ldflags_libs_application "\"$flag\"" _setflags ldflags_libs_application LDFLAGS_LIBS_APPLICATION fi } check_addldsrchpath () { name=$1 flag=$2 printlabel LDFLAGS_APPLICATION "Add LD Search Path: ${flag}" test_ldsrchpath "$flag" printyesno $name "$flag" if [ "$flag" != 0 ]; then doappend ldflags_application " " initifs setifs doappend ldflags_application "\"$flagi\"" resetifs _setflags ldflags_application LDFLAGS_APPLICATION fi } check_ldflags () { TCC=${CC} if [ "${_MKCONFIG_USING_GCC}" = Y ]; then TCC=gcc fi ldflags_debug=${LDFLAGS_DEBUG:-} ldflags_optimize=${LDFLAGS_OPTIMIZE:-} ldflags_user=${LDFLAGS_USER:-} ldflags_compiler=${LDFLAGS_COMPILER:-} ldflags_system=${LDFLAGS_SYSTEM:-} ldflags_application=${LDFLAGS_APPLICATION:-} doappend ldflags_system " " doappend ldflags_system " $lfldflags" case ${_MKCONFIG_SYSTYPE} in Darwin) if [ -d /opt/local/include ]; then doappend ldflags_system " -L/opt/local/lib" fi if [ -d /opt/homebrew/include ]; then doappend ldflags_system " -L/opt/homebrew/lib" fi doappend ldflags_system " -L/usr/local/lib" ;; DragonFly|FreeBSD|OpenBSD) # *BSD has many packages that get installed in /usr/local doappend ldflags_system " -L/usr/local/lib" ;; NetBSD) doappend ldflags_system " -Wl,-R/usr/pkg/lib -L/usr/pkg/lib" ;; HP-UX) # check for libintl in other places... if [ -d /usr/local/include -a \ -d /usr/local/lib ]; then doappend ldflags_system " -L/usr/local/lib" if [ -d /usr/local/lib/hpux64 ]; then doappend ldflags_system " -L/usr/local/lib/hpux64" elif [ -d /usr/local/lib/hpux32 ]; then doappend ldflags_system " -L/usr/local/lib/hpux32" fi fi case ${TCC} in cc) doappend ldflags_system " -Wl,+s" ;; esac ;; OS/2) doappend ldflags_system " -Zexe" ;; SunOS) case ${_MKCONFIG_SYSREV} in 5.*) case ${TCC} in cc) case $CFLAGS_OPTIMIZE in -xO[3456]) ldflags_optimize="-fast" ;; esac ;; esac ;; esac ;; esac _dogetconf # plain LDFLAGS will be interpreted as the user's ldflags ldflags_user=$LDFLAGS if [ "z$LDFLAGS_DEBUG" != z ]; then ldflags_debug="$LDFLAGS_DEBUG" else if [ "z$CFLAGS_DEBUG" != z ]; then ldflags_debug="$CFLAGS_DEBUG" fi fi if [ "z$LDFLAGS_OPTIMIZE" != z ]; then ldflags_optimize="$LDFLAGS_OPTIMIZE" else if [ "z$CFLAGS_OPTIMIZE" != z ]; then ldflags_optimize="$CFLAGS_OPTIMIZE" fi fi puts "ldflags_debug:${ldflags_debug}" >&9 puts "ldflags_optimize:${ldflags_optimize}" >&9 puts "ldflags_user:${ldflags_user}" >&9 puts "ldflags_compiler:${ldflags_compiler}" >&9 puts "ldflags_system:${ldflags_system}" >&9 puts "ldflags_application:${ldflags_application}" >&9 _setflags \ ldflags_debug LDFLAGS_DEBUG \ ldflags_optimize LDFLAGS_OPTIMIZE \ ldflags_user LDFLAGS_USER \ ldflags_compiler LDFLAGS_COMPILER \ ldflags_system LDFLAGS_SYSTEM \ ldflags_application LDFLAGS_APPLICATION } check_libs () { _dogetconf ldflags_libs_user=${LDFLAGS_LIBS_USER:-} ldflags_libs_application=${LDFLAGS_LIBS_APPLICATION:-} ldflags_libs_system=${LDFLAGS_LIBS_SYSTEM:-} TCC=${CC} if [ "${_MKCONFIG_USING_GCC}" = Y ]; then TCC=gcc fi case ${_MKCONFIG_SYSTYPE} in BeOS|Haiku) # uname -m does not reflect actual architecture doappend ldflags_libs_system " -lroot -lbe" ;; esac # largefile flags doappend ldflags_libs_system " $lflibs" doappend ldflags_libs_user " $LIBS" puts "ldflags_libs_user:${ldflags_libs_user}" >&9 puts "ldflags_libs_application:${ldflags_libs_application}" >&9 puts "ldflags_libs_system:${ldflags_libs_system}" >&9 _setflags \ ldflags_libs_user LDFLAGS_LIBS_USER \ ldflags_libs_application LDFLAGS_LIBS_APPLICATION \ ldflags_libs_system LDFLAGS_LIBS_SYSTEM } # for backwards compatibility check_shcflags () { check_cflags_shared } check_cflags_shared () { printlabel CFLAGS_SHARED "shared library cflags" cflags_shared="" if [ "$_MKCONFIG_USING_GCC" != Y -a "$_MKCONFIG_USING_CLANG" != Y ]; then case ${_MKCONFIG_SYSTYPE} in CYGWIN*|MSYS*|MINGW*) # apparently, clang does not need this any more. doappend cflags_shared "" ;; Darwin) doappend cflags_shared " -fno-common" ;; HP-UX) doappend cflags_shared " +Z" ;; IRIX*) doappend cflags_shared " -KPIC" ;; OSF1) # none doappend cflags_shared " -fPIC" ;; SCO_SV) doappend cflags_shared " -KPIC" ;; SunOS) doappend cflags_shared " -KPIC" ;; UnixWare) doappend cflags_shared " -KPIC" ;; *) doappend cflags_shared " -fPIC" ;; esac else doappend cflags_shared " -fPIC" fi if [ "z$CFLAGS_SHARED" != z ]; then cflags_shared_user="${CFLAGS_SHARED}" fi printyesno_val CFLAGS_SHARED "$cflags_shared $cflags_shared_user" _setflags \ cflags_shared CFLAGS_SHARED \ cflags_shared_user CFLAGS_SHARED_USER } # for backwards compatibility check_shldflags () { check_ldflags_shared } check_ldflags_shared () { printlabel LDFLAGS_SHARED_LIBLINK "shared library ldflags" if [ "$_MKCONFIG_USING_GCC" != Y -a "$_MKCONFIG_USING_CLANG" != Y ]; then case ${_MKCONFIG_SYSTYPE} in AIX) doappend ldflags_shared_liblink " -G" ;; Darwin) doappend ldflags_shared_liblink " -dynamiclib" ;; HP-UX) doappend ldflags_shared_liblink " -b" ;; IRIX*) # "-shared" doappend ldflags_shared_liblink " -shared" ;; OSF1) doappend ldflags_shared_liblink " -msym -no_archive -shared" ;; SCO_SV) doappend ldflags_shared_liblink " -G" ;; SunOS) doappend ldflags_shared_liblink " -G" ;; UnixWare) doappend ldflags_shared_liblink " -G" ;; *) doappend ldflags_shared_liblink " -shared" ;; esac else doappend ldflags_shared_liblink " -shared" fi if [ "z$LDFLAGS_SHARED" != z ]; then ldflags_shared_user="${LDFLAGS_SHARED}" fi printyesno_val LDFLAGS_SHARED "$ldflags_shared_liblink $ldflags_shared_user" _setflags \ ldflags_shared_liblink LDFLAGS_SHARED_LIBLINK ldflags_shared_user LDFLAGS_SHARED_USER } check_sharednameflag () { printlabel SHLDNAMEFLAG "shared lib name flag" SHLDNAMEFLAG="-Wl,-soname=" if [ "$_MKCONFIG_USING_GNU_LD" != Y ]; then case ${_MKCONFIG_SYSTYPE} in Darwin) # -compatibility_version -current_version ;; HP-UX) SHLDNAMEFLAG="-Wl,+h " ;; IRIX*) # -soname ;; OSF1) # -soname ;; SunOS) SHLDNAMEFLAG="-Wl,-h " ;; *) SHLDNAMEFLAG="" ;; esac fi printyesno_val SHLDNAMEFLAG "$SHLDNAMEFLAG" setdata SHLDNAMEFLAG "$SHLDNAMEFLAG" } check_sharedliblinkflag () { printlabel LDFLAGS_SHARED_LIB_LINK "link flag for shared libraries " LDFLAGS_SHARED_LIB_LINK="-Wl,-Bdynamic" if [ "$_MKCONFIG_USING_GNU_LD" != Y ]; then case ${_MKCONFIG_SYSTYPE} in AIX) LDFLAGS_SHARED_LIB_LINK="" ;; HP-UX) LDFLAGS_SHARED_LIB_LINK="" ;; OSF1) LDFLAGS_SHARED_LIB_LINK="" ;; SunOS) # -Bdynamic ;; *) LDFLAGS_SHARED_LIB_LINK="" ;; esac if [ "$_MKCONFIG_USING_GCC" = Y -o "$_MKCONFIG_USING_CLANG" = Y ]; then LDFLAGS_SHARED_LIB_LINK=`echo "$LDFLAGS_SHARED_LIB_LINK" | sed -e 's/^-/-Wl,-/' -e 's/^\+/-Wl,+/' -e 's/ */ -Wl,/g'` fi fi printyesno_val LDFLAGS_SHARED_LIB_LINK "$LDFLAGS_SHARED_LIB_LINK" setdata LDFLAGS_SHARED_LIB_LINK "$LDFLAGS_SHARED_LIB_LINK" } check_staticliblinkflag () { printlabel LDFLAGS_STATIC_LIB_LINK "link flag for static libraries " LDFLAGS_STATIC_LIB_LINK="-Wl,-Bstatic" if [ "$_MKCONFIG_USING_GNU_LD" != Y ]; then case ${_MKCONFIG_SYSTYPE} in AIX) LDFLAGS_STATIC_LIB_LINK="" ;; HP-UX) LDFLAGS_STATIC_LIB_LINK="" ;; OSF1) LDFLAGS_STATIC_LIB_LINK="" ;; SunOS) # -Bdynamic ;; *) LDFLAGS_STATIC_LIB_LINK="" ;; esac if [ "$_MKCONFIG_USING_GCC" = Y -o "$_MKCONFIG_USING_CLANG" = Y ]; then LDFLAGS_STATIC_LIB_LINK=`echo "$LDFLAGS_STATIC_LIB_LINK" | sed -e 's/^-/-Wl,-/' -e 's/^\+/-Wl,+/' -e 's/ */ -Wl,/g'` fi fi printyesno_val LDFLAGS_STATIC_LIB_LINK "$LDFLAGS_STATIC_LIB_LINK" setdata LDFLAGS_STATIC_LIB_LINK "$LDFLAGS_STATIC_LIB_LINK" } check_shareexeclinkflag () { printlabel LDFLAGS_EXEC_LINK "shared executable link flag " LDFLAGS_EXEC_LINK="-Bdynamic" if [ "$_MKCONFIG_USING_GNU_LD" != Y ]; then case ${_MKCONFIG_SYSTYPE} in AIX) LDFLAGS_EXEC_LINK="-brtl -bdynamic" ;; HP-UX) LDFLAGS_EXEC_LINK="" ;; OSF1) LDFLAGS_EXEC_LINK="" ;; SunOS) # -Bdynamic ;; *) LDFLAGS_EXEC_LINK="" ;; esac if [ "$_MKCONFIG_USING_GCC" = Y -o "$_MKCONFIG_USING_CLANG" = Y ]; then LDFLAGS_EXEC_LINK=`echo "$LDFLAGS_EXEC_LINK" | sed -e 's/^-/-Wl,-/' -e 's/^\+/-Wl,+/' -e 's/ */ -Wl,/g'` fi fi printyesno_val LDFLAGS_EXEC_LINK "$LDFLAGS_EXEC_LINK" setdata LDFLAGS_EXEC_LINK "$LDFLAGS_EXEC_LINK" } check_sharerunpathflag () { printlabel LDFLAGS_RUNPATH "shared run path flag " LDFLAGS_RUNPATH="-Wl,-rpath=" if [ "$_MKCONFIG_USING_GNU_LD" != Y ]; then case ${_MKCONFIG_SYSTYPE} in HP-UX) LDFLAGS_RUNPATH="+b " ;; IRIX*) LDFLAGS_RUNPATH="-rpath " ;; OSF1) LDFLAGS_RUNPATH="-rpath " ;; SCO_SV) LDFLAGS_RUNPATH="-Wl,-R" ;; SunOS) LDFLAGS_RUNPATH="-R" ;; UnixWare) LDFLAGS_RUNPATH="-R " ;; *) LDFLAGS_RUNPATH="" ;; esac if [ "$_MKCONFIG_USING_GNU_LD" != Y -a "$_MKCONFIG_USING_CLANG" = Y ]; then LDFLAGS_RUNPATH="-rpath " fi # if [ "$_MKCONFIG_USING_GCC" = Y -o "$_MKCONFIG_USING_CLANG" = Y ]; then # # the trailing space will be converted to ' -Wl,' and # # the library runpath will be appended by mkcl.sh # LDFLAGS_RUNPATH=`echo "$LDFLAGS_RUNPATH" | # sed -e 's/^-/-Wl,-/' -e 's/^\+/-Wl,+/' -e 's/ */ -Wl,/g'` # fi fi set +x printyesno_val LDFLAGS_RUNPATH "$LDFLAGS_RUNPATH" setdata LDFLAGS_RUNPATH "$LDFLAGS_RUNPATH" } check_addconfig () { name=$1 evar=$2 addto=$3 printlabel ADDCONFIG "Add Config: ${evar} ${addto}" eval _tvar="\$$evar" if [ "z$_tvar" != z ]; then printyesno_val $name yes doappend $addto " $_tvar" puts "got: ${evar} ${_tvar}" >&9 eval puts "\"$addto: \$$addto\"" >&9 ucaddto=$addto toupper ucaddto _setflags $addto $ucaddto else printyesno_val $name no fi } check_standard_cc () { check_cc check_using_gcc check_using_gnu_ld check_using_clang check_using_cplusplus check_cflags check_ldflags } check_shared_flags () { check_cflags_shared check_ldflags_shared check_sharednameflag check_shareexeclinkflag check_sharerunpathflag check_sharedliblinkflag check_staticliblinkflag } di-6.0.0/mkconfig/units/env-extension.sh0000755000175000017500000000375114755476624016347 0ustar bllbll#!/bin/sh # # Copyright 2001-2018 Brad Lanam, Walnut Creek, California, USA # Copyright 2020 Brad Lanam Pleasant Hill CA # # # speed at the cost of maintainability... # File Descriptors: # 9 - >>$LOG (mkconfig.sh) # 8 - >>$VARSFILE, >>$CONFH (mkconfig.sh) # 7 - temporary for mkconfig.sh (mkconfig.sh) # 6 - temporary for c-main.sh (c-main.sh) # 5 - temporary for c-main.sh (c-main.sh) # require_unit env-main check_extension () { type=$2 name="${type}ext" eval check_${name} } check_objext () { name=OBJ_EXT printlabel $name "extension: object" TMPF=objext CC=${CC:-cc} > $TMPF.c puts ' #include int main () { printf ("hello\n"); return 0; } ' ${CC} -c $TMPF.c > /dev/null 2>&1 # don't care about warnings... OBJ_EXT=".o" if [ -f "$TMPF.obj" ]; then puts "object extension is .obj" >&9 OBJ_EXT=".obj" else puts "object extension is .o" >&9 fi printyesno_val $name "${OBJ_EXT}" setdata $name "${OBJ_EXT}" } check_exeext () { name=EXE_EXT printlabel $name "extension: executable" TMPF=exeext CC=${CC:-cc} > $TMPF.c puts ' #include int main () { printf ("hello\n"); return 0; } ' ${CC} -o $TMPF $TMPF.c > /dev/null 2>&1 # don't care about warnings EXE_EXT="" if [ -f "$TMPF.exe" ] then puts "executable extension is .exe" >&9 EXE_EXT=".exe" else puts "executable extension is none" >&9 fi printyesno_val $name "${EXE_EXT}" setdata $name "${EXE_EXT}" } check_shlibext () { name=SHLIB_EXT printlabel $name "extension: shared library" SHLIB_EXT=".so" case ${_MKCONFIG_SYSTYPE} in HP-UX) case ${_MKCONFIG_SYSARCH} in ia64) ;; *) SHLIB_EXT=".sl" ;; esac ;; AIX) SHLIB_EXT=".a" ;; Darwin) SHLIB_EXT=".dylib" ;; CYGWIN*|MSYS*|MINGW*) SHLIB_EXT=".dll" ;; esac printyesno_val $name "$SHLIB_EXT" setdata $name "$SHLIB_EXT" } di-6.0.0/mkconfig/units/c-include-conflict.sh0000755000175000017500000000306714746503011017164 0ustar bllbll#!/bin/sh # # Copyright 2010-2018 Brad Lanam Walnut Creek CA USA # Copyright 2020 Brad Lanam Pleasant Hill CA # # # check and see if there is a conflict between include files. # # # speed at the cost of maintainability... # File Descriptors: # 9 - >>$LOG (mkconfig.sh) # 8 - >>$VARSFILE, >>$CONFH (mkconfig.sh) # 7 - temporary for mkconfig.sh (mkconfig.sh) # 6 - temporary for c-main.sh (c-main.sh) # 5 - temporary for c-main.sh (c-main.sh) # require_unit c-main _prefix_header () { nm=$1 val=$2 case $val in sys*) eval "$nm=_${val}" ;; *) eval "$nm=_hdr_${val}" ;; esac } check_include_conflict () { i1=$2 i2=$3 if [ "${CC}" = "" ]; then puts "No compiler specified" >&2 return fi oi1=$i1 dosubst i1 '/' '_' ':' '_' '\.h' '' _prefix_header i1 $i1 oi2=$i2 dosubst i2 '/' '_' ':' '_' '\.h' '' _prefix_header i2 $i2 name="_inc_conflict_${i1}_${i2}" # by default, ok to include both # if one or the other does not exist, the flag will be true. # if it compiles ok with both, the flag will be true. trc=1 printlabel $name "header: include both ${oi1} & ${oi2}" getdata h1 $i1 getdata h2 $i2 if [ "${h1}" != "0" -a "${h2}" != "0" ]; then checkcache $name if [ $rc -eq 0 ]; then return; fi code="#include <${h1}> #include <${h2}> int main () { return 0; } " do_c_check_compile "${name}" "${code}" std else setdata "${name}" "${trc}" printyesno "${name}" $trc "" fi } di-6.0.0/mkconfig/units/c-main.sh0000755000175000017500000004403114750152767014677 0ustar bllbll#!/bin/sh # # Copyright 2010-2018 Brad Lanam Walnut Creek CA USA # Copyright 2020 Brad Lanam Pleasant Hill CA # # # The four headers: stdio.h, stdlib.h, sys/types.h, and sys/param.h # are always checked. FreeBSD has header inclusion bugs and requires # sys/param.h. # # The keywords 'void' and 'const' are always tested. # # Prototype support is always tested. # # The following code is present in the final config.h file: # # #ifndef MKC_STANDARD_DEFS # # define MKC_STANDARD_DEFS 1 # # if ! _key_void # # define void int # # endif # # if ! _key_const # # define const # # endif # # if ! _key_void || ! _param_void_star # # define void char # # endif # #endif /* MKC_STANDARD_DEFS */ # # # speed at the cost of maintainability... # File Descriptors: # 9 - >>$LOG (mkconfig.sh) # 8 - >>$VARSFILE, >>$CONFH (mkconfig.sh) # 7 - temporary for mkconfig.sh (mkconfig.sh) # 6 - temporary for c-main.sh (c-main.sh) # 4 - temporary for c-main.sh (c-main.sh) # require_unit c-support _MKCONFIG_HASEMPTY=F _MKCONFIG_EXPORT=F PH_PREFIX="mkc_ph." PH_STD=F PH_ALL=F precc=' #if defined(__cplusplus) || defined (c_plusplus) # define CPP_EXTERNS_BEG extern "C" { # define CPP_EXTERNS_END } CPP_EXTERNS_BEG extern int printf (const char *, ...); CPP_EXTERNS_END #else # define CPP_EXTERNS_BEG # define CPP_EXTERNS_END #endif ' preconfigfile () { pc_configfile=$1 configfile=$2 # log all of the compiler and linker options for nm in CC CFLAGS_OPTIMIZE CFLAGS_DEBUG CFLAGS_INCLUDE CFLAGS_USER \ CFLAGS_APPLICATION CFLAGS_COMPILER \ CFLAGS_SYSTEM CFLAGS_SHARED \ CFLAGS_SHARED_USER LDFLAGS_OPTIMIZE LDFLAGS_DEBUG LDFLAGS_USER \ LDFLAGS_APPLICATION LDFLAGS_COMPILER LDFLAGS_SYSTEM \ LDFLAGS_SHARED LDFLAGS_SHARED_LIBLINK LDFLAGS_SHARED_USER \ LDFLAGS_LIBS_USER LDFLAGS_LIBS_APPLICATION LDFLAGS_LIBS_SYSTEM; do cmd="puts \"$nm: \${$nm}\"" eval $cmd >&9 done if [ "${CC}" = "" ]; then puts "No compiler specified" >&2 return fi puts "/* Created on: `date`" puts " From: ${configfile}" puts " Using: mkconfig-${_MKCONFIG_VERSION} */" puts '' puts "#ifndef INC_${CONFHTAGUC}_H #define INC_${CONFHTAGUC}_H 1 " } stdconfigfile () { pc_configfile=$1 puts ' #ifndef MKC_STANDARD_DEFS # define MKC_STANDARD_DEFS 1 # if ! _key_void # define void int # endif # if ! _key_void || ! _param_void_star typedef char *pvoid; # else typedef void *pvoid; # endif # if ! _key_const # define const # endif #endif /* MKC_STANDARD_DEFS */ ' } postconfigfile () { pc_configfile=$1 puts " #endif /* INC_${CONFHTAGUC}_H */" } standard_checks () { if [ "${CC}" = "" ]; then puts "No compiler specified" >&2 return fi check_hdr hdr "stdio.h" check_hdr hdr "stdlib.h" check_hdr sys "types.h" check_hdr sys "param.h" PH_STD=T check_key key "void" check_key key "const" check_param_void_star check_proto "_proto_stdc" PH_ALL=T } check_header_reset () { printlabel "" "reset headers" out="${PH_PREFIX}all" rm -f $out } check_hdr () { type=$1 hdr=$2 shift;shift reqhdr=$* # input may be: ctype.h kernel/fs_info.h # storage/Directory.h nm1=`puts ${hdr} | sed -e 's,/.*,,'` nm2="_`puts $hdr | sed -e s,\^${nm1},, -e 's,^/*,,'`" nm="_${type}_${nm1}" if [ "$nm2" != "_" ]; then doappend nm $nm2 fi dosubst nm '/' '_' ':' '_' '\.h' '' case ${type} in sys) hdr="sys/${hdr}" ;; esac name=$nm file=$hdr printlabel $name "header: ${file}" checkcache $name if [ $rc -eq 0 ]; then return; fi code="" if [ "${reqhdr}" != "" ]; then set ${reqhdr} while test $# -gt 0; do doappend code " #include <$1> " shift done fi doappend code " #include <$file> int main (int argc, char *argv []) { return 0; } " rc=1 _c_chk_compile ${name} "${code}" std rc=$? val=0 if [ $rc -eq 0 ]; then val=${file} fi if [ "$CPPCOUNTER" != "" ]; then domath CPPCOUNTER "$CPPCOUNTER + 1" fi printyesno $name $val setdata ${name} ${val} } check_sys () { check_hdr $@ } check_const () { constant=$2 shift;shift reqhdr=$* nm="_const_${constant}" name=$nm printlabel $name "constant: ${constant}" checkcache $name if [ $rc -eq 0 ]; then return; fi code="" if [ "${reqhdr}" != "" ]; then set ${reqhdr} while test $# -gt 0; do doappend code " #include <$1> " shift done fi doappend code " int main (int argc, char *argv []) { if (${constant} == 0) { 1; } return 0; } " do_c_check_compile ${name} "${code}" all } check_key () { keyword=$2 name="_key_${keyword}" printlabel $name "keyword: ${keyword}" checkcache $name if [ $rc -eq 0 ]; then return; fi code="int main (int argc, char *argv []) { int ${keyword}; ${keyword} = 1; return 0; }" _c_chk_compile ${name} "${code}" std rc=$? trc=0 if [ $rc -ne 0 ]; then # failure means it is reserved... trc=1 fi printyesno $name $trc setdata ${name} ${trc} } check_proto () { name=$1 printlabel $name "supported: prototypes" checkcache $name if [ $rc -eq 0 ]; then return; fi code=' CPP_EXTERNS_BEG extern int foo (int, int); CPP_EXTERNS_END int bar () { int rc; rc = foo (1,1); return 0; } ' do_c_check_compile ${name} "${code}" std } check_typ () { shift type=$@ nm="_typ_${type}" dosubst nm ' ' '_' name=$nm dosubst type 'star' '*' printlabel $name "type: ${type}" checkcache $name if [ $rc -eq 0 ]; then return; fi code=" struct xxx { ${type} mem; }; static struct xxx v; struct xxx* f() { return &v; } int main (int argc, char *argv []) { struct xxx *tmp; tmp = f(); return 0; } " do_c_check_compile ${name} "${code}" all } check_define () { shift def=$1 nm="_define_${def}" name=$nm printlabel $name "defined: ${def}" checkcache $name if [ $rc -eq 0 ]; then return; fi code="int main (int argc, char *argv []) { #if defined(${def}) # define MKC_DEFINED 1 #endif #ifdef MKC_DEFINED printf (\"mkc_defined ${def}\"); #endif return 0; }" trc=0 _c_chk_cpp "$name" "$code" all rc=$? if [ $rc -eq 0 ]; then ${grepcmd} -l mkc_defined $name.out >/dev/null 2>&1 rc=$? if [ $rc -eq 0 ]; then trc=1 fi fi setdata ${name} ${trc} printyesno $name $trc } check_param_void_star () { name="_param_void_star" printlabel $name "parameter: void *" checkcache $name if [ $rc -eq 0 ]; then return; fi code=" char * tparamvs (ptr) void *ptr; { ptr = (void *) NULL; return (char *) ptr; } " do_c_check_compile ${name} "${code}" all } check_member () { shift struct=$1 if [ "$struct" = "struct" ]; then shift struct="struct $1" fi if [ "$struct" = "union" ]; then shift struct="union $1" fi shift member=$1 nm="_mem_${struct}_${member}" dosubst nm ' ' '_' name=$nm printlabel $name "exists: ${struct}.${member}" checkcache $name if [ $rc -eq 0 ]; then return; fi code="int main (int argc, char *argv []) { ${struct} s; int i; i = sizeof (s.${member}); return 0; }" do_c_check_compile ${name} "${code}" all } check_memberxdr () { shift struct=$1 shift member=$1 nm="_memberxdr_${struct}_${member}" dosubst nm ' ' '_' name=$nm printlabel $name "member:XDR: ${struct} ${member}" # no cache _c_chk_cpp $name "" all rc=$? trc=0 if [ $rc -eq 0 ]; then st=`${awkcmd} -f ${_MKCONFIG_DIR}/util/mkcextstruct.awk ${name}.out ${struct}` if [ "$st" != "" ]; then puts " ${struct}: ${st}" >&9 tmem=`puts "$st" | grep "${member} *;\$"` rc=$? puts " found: ${tmem}" >&9 if [ $rc -eq 0 ]; then mtype=`puts $tmem | sed -e "s/ *${member} *;$//" -e 's/^ *//'` puts " type: ${mtype}" >&9 trc=1 setdata xdr_${member} xdr_${mtype} fi fi # found the structure fi # cpp worked printyesno $name $trc "" setdata ${name} ${trc} } check_size () { shift type=$* otherlibs="-lintl" nm="_siz_${type}" dosubst nm ' ' '_' name=$nm printlabel $name "sizeof: ${type}" if [ "$MKC_CROSS" = Y ]; then puts "## size: cross compiling is active" >&9 code="int main (int argc, char *argv []) { printf(\"%u\", sizeof(${type})); return 0; }" _c_chk_compile ${name} "${code}" all rc=$? if [ $rc -eq 0 ]; then sz=1 # this could be sped up by moving the common sizes to the beginning # of the list of sizes to test. while test $sz -lt 129; do code=" #include #include int main () { size_t a = sizeof(int); switch (a) { case ${sz}: case sizeof(${type}): { break; } } } " _c_chk_compile ${name} "${code}" all trc=$? if [ $trc -ne 0 ]; then _retval=$sz rc=0 break fi if [ $sz -eq 1 ]; then sz=2 else domath sz "$sz + 2" fi done else _retval=0 rc=1 fi else puts "## size: cross compiling is NOT active" >&9 code="int main (int argc, char *argv []) { printf(\"%u\", sizeof(${type})); return 0; }" _c_chk_run ${name} "${code}" all rc=$? fi dlibs=$_retdlibs val=$_retval if [ $rc -ne 0 ]; then val=0 fi if [ $rc -eq 0 -a "$dlibs" != "" ]; then cmd="mkc_lnk_${name}=\"${dlibs}\"" eval $cmd fi otherlibs="" printyesno_val $name $val setdata ${name} ${val} } check_dcl () { type=$2 var=$3 nm="_dcl_${var}" if [ "$type" = "int" ]; then check_int_declare $nm $var elif [ "$type" = "ptr" ]; then check_ptr_declare $nm $var fi } check_args () { type=$1 noconst=F if [ "$2" = "noconst" ]; then noconst=T shift fi funcnm=$2 nm="_args_${funcnm}" name=$nm printlabel $name "args: ${funcnm}" # no cache trc=0 ccount=0 oldprecc="${precc}" if [ "$_have_variadic" = "" ]; then precc="" code="#define testvariadic(...)" _c_chk_cpp _args_testvariadic "$code" all rc=$? _have_variadic=F if [ $rc -eq 0 ]; then _have_variadic=T fi fi asmdef="#define __asm__(a)" if [ $_have_variadic = T ]; then asmdef="#define __asm__(...)" fi precc="$oldprecc" doappend precc "/* get rid of most gcc-isms */ #define __asm(a) $asmdef #define __attribute__(a) #define __nonnull__(a,b) #define __restrict #define __restrict__ #if defined(__THROW) # undef __THROW #endif #define __THROW #define __const const " code="" _c_chk_cpp ${name} "/**/" all # force no-reuse due to precc. rc=$? precc="${oldprecc}" if [ $rc -eq 0 ]; then ${grepcmd} -l "[ *]${funcnm}[ ]*\(" $name.out >/dev/null 2>&1 rc=$? if [ $rc -eq 0 ]; then trc=1 fi # have a declaration if [ $trc -eq 1 ]; then dcl=`${awkcmd} -f ${_MKCONFIG_DIR}/util/mkcextdcl.awk ${name}.out ${funcnm}` # make single line, use no quotes # remove carriage returns...msys2 sometimes has them embedded. # \r is not recognized by older shells, use tr. dcl=`puts $dcl | tr '\r' ' '` # extern will be replaced # ; may or may not be present, so remove it. cmd="dcl=\`puts \"\$dcl\" | sed -e 's/extern *//' -e 's/;//' \`" eval $cmd puts "## dcl(A): ${dcl}" >&9 cmd="dcl=\`puts \"\$dcl\" | sed -e 's/( *void *)/()/' \`" eval $cmd puts "## dcl(C): ${dcl}" >&9 c=`puts "${dcl}" | sed 's/[^,]*//g'` ccount=`putsnonl "$c" | wc -c` domath ccount "$ccount + 1" # 0==1 also, unfortunately c=`puts "${dcl}" | sed 's/^[^(]*(//'` c=`puts "${c}" | sed 's/)[^)]*$//'` puts "## c(E): ${c}" >&9 val=1 while test "${c}" != ""; do tmp=$c tmp=`puts "${c}" | sed -e 's/ *,.*$//' -e 's/[ ]/ /g'` dosubst tmp 'struct ' 'struct#' 'union ' 'union#' 'enum ' 'enum#' # only do the following if the names of the variables are declared puts "${tmp}" | grep ' ' > /dev/null 2>&1 rc=$? if [ $rc -eq 0 ]; then tmp=`puts "${tmp}" | sed -e 's/ *[A-Za-z0-9_]*$//'` fi dosubst tmp 'struct#' 'struct ' 'union#' 'union ' 'enum#' 'enum ' if [ $noconst = T ]; then tmp=`puts "${tmp}" | sed -e 's/const *//'` fi puts "## tmp(F): ${tmp}" >&9 nm="_c_arg_${val}_${funcnm}" setdata ${nm} "${tmp}" domath val "$val + 1" c=`puts "${c}" | sed -e 's/^[^,]*//' -e 's/^[ ,]*//'` puts "## c(G): ${c}" >&9 done c=`puts "${dcl}" | sed -e 's/[ ]/ /g' \ -e "s/\([ \*]\)${funcnm}[ (].*/\1/" \ -e 's/^ *//' \ -e 's/ *$//'` puts "## c(T0): ${c}" >&9 if [ $noconst = T ]; then c=`puts "${c}" | sed -e 's/const *//'` fi puts "## c(T1): ${c}" >&9 nm="_c_type_${funcnm}" setdata ${nm} "${c}" fi fi printyesno_val $name $ccount "" nm="_args_${funcnm}" setdata ${nm} ${ccount} } check_int_declare () { name=$1 function=$2 printlabel $name "declared: ${function}" checkcache $name if [ $rc -eq 0 ]; then return; fi code="int main (int argc, char *argv []) { int x; x = ${function}; return 0; }" do_c_check_compile ${name} "${code}" all } check_ptr_declare () { name=$1 function=$2 printlabel $name "declared: ${function}" checkcache $name if [ $rc -eq 0 ]; then return; fi code=" int main (int argc, char *argv []) { void *x; x = ${function}; return 0; }" do_c_check_compile ${name} "${code}" all } check_npt () { func=$2 req=$3 has=1 if [ "${req}" != "" ]; then getdata has "${req}" fi nm="_npt_${func}" name=$nm proto=$func printlabel $name "need prototype: ${proto}" checkcache $name if [ $rc -eq 0 ]; then return; fi if [ ${has} -eq 0 ]; then setdata ${name} 0 printyesno $name 0 return fi code=" CPP_EXTERNS_BEG struct _TEST_struct { int _TEST_member; }; extern struct _TEST_struct* ${proto} _((struct _TEST_struct*)); CPP_EXTERNS_END " do_c_check_compile ${name} "${code}" all } check_staticlib () { staticlib=T check_lib "$@" unset staticlib } check_lib () { func=$2 shift;shift otherlibs=$* nm="_lib_${func}" name=$nm rfunc=$func dosubst rfunc '_dollar_' '$' if [ "${otherlibs}" != "" ]; then printlabel $name "function: ${rfunc} [${otherlibs}]" # code to check the cache for which libraries are specified is not written else printlabel $name "function: ${rfunc}" checkcache $name if [ $rc -eq 0 ]; then return; fi fi trc=0 # unfortunately, this does not work if the function # is not declared. if [ "$_MKCONFIG_USING_CPLUSPLUS" = Y ]; then hinc=none code=" CPP_EXTERNS_BEG #undef $rfunc typedef char (*test_func)(); char $rfunc(); test_func f = (test_func) $rfunc; CPP_EXTERNS_END int main (int argc, char *argv []) { if (f == (test_func) $rfunc) { return 0; } return 1; } " else hinc=all code=" CPP_EXTERNS_BEG typedef char (*test_func)(); test_func f = (test_func) $rfunc; CPP_EXTERNS_END int main (int argc, char *argv []) { f(); if (f == (test_func) $rfunc) { return 0; } return 1; } " fi _c_chk_link_libs ${name} "${code}" $hinc rc=$? dlibs=$_retdlibs if [ $rc -eq 0 ]; then trc=1 fi tag="" if [ $rc -eq 0 -a "$dlibs" != "" ]; then if [ "$staticlib" = "T" ]; then dlibs="$LDFLAGS_STATIC_LIB_LINK $dlibs $LDFLAGS_SHARED_LIB_LINK" fi tag=" with ${dlibs}" cmd="mkc_lnk_${name}=\"${dlibs}\"" eval $cmd fi if [ ${trc} -eq 0 -a "$_MKCONFIG_TEST_EXTERN" != "" ]; then if [ $_MKCONFIG_USING_CPLUSPLUS = Y ]; then hinc=none code=" CPP_EXTERNS_BEG #undef $rfunc typedef char (*test_func)(); char $rfunc(); test_func f = (test_func) $rfunc; CPP_EXTERNS_END int main (int argc, char *argv []) { if (f == (test_func) $rfunc) { return 0; } return 1; } " else hinc=all code=" CPP_EXTERNS_BEG /* Normally, we don't want to do this, as on some systems we can get spurious errors where the lib does not exist and the link works! On modern systems, this simply isn't necessary. */ extern int ${func}(); typedef char (*test_func)(); test_func f = (test_func) $rfunc; CPP_EXTERNS_END int main (int argc, char *argv []) { f(); if (f == (test_func) $rfunc) { return 0; } return 1; } " fi _c_chk_link_libs ${name} "${code}" $hinc rc=$? dlibs=$_retdlibs if [ $rc -eq 0 ]; then trc=1 fi tag="" if [ $rc -eq 0 -a "$dlibs" != "" ]; then tag=" with ${dlibs}" cmd="mkc_lnk_${name}=\"${dlibs}\"" eval $cmd fi fi otherlibs="" printyesno $name $trc "$tag" setdata ${name} ${trc} return $trc } check_class () { class=$2 shift;shift otherlibs=$* nm="_class_${class}" dosubst nm '/' '_' ':' '_' name=$nm trc=0 code=" int main (int argc, char *argv []) { ${class} testclass; return 0; } " if [ "$otherlibs" != "" ]; then printlabel $name "class: ${class} [${otherlibs}]" else printlabel $name "class: ${class}" checkcache $name if [ $rc -eq 0 ]; then return; fi fi _c_chk_link_libs ${name} "${code}" all rc=$? if [ $rc -eq 0 ]; then trc=1 fi tag="" if [ $rc -eq 0 -a "${dlibs}" != "" ]; then tag=" with ${dlibs}" cmd="mkc_lnk_${name}=\"${dlibs}\"" eval $cmd fi otherlibs="" printyesno $name $trc "$tag" setdata ${name} ${trc} } output_item () { out=$1 name=$2 val=$3 tval=0 if [ "$val" != "0" ]; then tval=1 fi case ${name} in _setint_*) tname=$name dosubst tname '_setint_' '' puts "#define ${tname} ${val}" ;; _envquote_*) ;; _env_*) if [ "x${val}" != x ]; then tname=$name dosubst tname '_env_' '' eval q=\${mkc__envquote_${tname}} if [ $q -eq 1 ]; then puts "#define ${tname} \"${val}\"" else puts "#define ${tname} ${val}" fi fi ;; _setstr_*|_cmd_loc_*) tname=$name dosubst tname '_setstr_' '' puts "#define ${tname} \"${val}\"" ;; _hdr_*|_sys_*|_command_*) puts "#define ${name} ${tval}" ;; *) # _c_arg, _c_type go here also puts "#define ${name} ${val}" ;; esac } new_output_file () { return 0 } di-6.0.0/mkconfig/units/env-msgfmt.sh0000755000175000017500000000174514746502574015623 0ustar bllbll#!/bin/sh # # Copyright 2010-2018 Brad Lanam, Walnut Creek, California USA # Copyright 2020 Brad Lanam Pleasant Hill CA # # # speed at the cost of maintainability... # File Descriptors: # 9 - >>$LOG (mkconfig.sh) # 8 - >>$VARSFILE, >>$CONFH (mkconfig.sh) # 7 - temporary for mkconfig.sh (mkconfig.sh) # 6 - temporary for c-main.sh (c-main.sh) # 5 - temporary for c-main.sh (c-main.sh) # require_unit env-main # optional unit: cflags check_cmd_msgfmt () { name="$1" name=XMSGFMT printlabel $name "command: locate msgfmt" locatecmd xmsgfmt msgfmt locatecmd xgmsgfmt gmsgfmt mfmt="${xmsgfmt}" if [ "$_MKCONFIG_USING_GCC" = "Y" ] then mfmt="${xgmsgfmt:-${xmsgfmt}}" if [ -x "${xccpath}/msgfmt" ] then mfmt="${xccpath}/msgfmt" fi if [ -x "${xccpath}/gmsgfmt" ] then mfmt="${xccpath}/gmsgfmt" fi fi printyesno_val XMSGFMT $xmsgfmt setdata "XMSGFMT" "${xmsgfmt}" } di-6.0.0/mkconfig/README.txt0000644000175000017500000000516214750757361013533 0ustar bllbllmkconfig - configuration tool Website: https://mkconfig.sourceforge.io/ SourceForge: https://sourceforge.net/projects/mkconfig/ mkconfig is a build configuration utility. It creates an output file intended to be included as a header file, run as a shell script, used as a configuration file, or any other use. mkconfig is written in portable shell script and designed to be extensible for any configuration use. It also includes tools that can be used to compile, link and build libraries and executables using the shell configuration previously built. See: examples/helloworld for a simple example. Another example of mkconfig in use can be seen in the 'di' program at https://sourceforge.net/projects/diskinfo-di/ mkconfig works with most any bourne shell compatible shell. Modern shells that are not bourne shell compatible are: posh, bosh, zsh (compatibility mode). Very old shells do not have the memory capabilities needed in order to save the large number of variables that mkconfig needs. TESTING Version 2.4 has been tested on: Linux Debian 9 (gcc6) (bash4, dash) Fedora 7 (gcc) (bash3, sh/bash3) Fedora 27 (gcc7) (bash4, sh/bash4) MX Linux 19.2 (gcc8, clang) (ksh93 osh bash5 dash mksh yash) BSD DragonflyBSD 5.8.1 (gcc) (bash5, dash, pdksh, ksh93, mksh) FreeBSD 7.0 (gcc4) (sh) FreeBSD 11.0 (clang6) (sh, bash4, dash, pdksh, ksh93, mksh) FreeBSD 12.0 (clang6) (sh, bash4) NetBSD 9.0 (gcc) (pdksh, sh) OpenBSD 6.3 (clang5) (pdksh, sh) Windows Msys2 (gcc9, clang) (ash, bash4, dash, sh/bash4) Cygwin (gcc8, clang8) (ash, bash4, dash, mksh, sh/bash4) Other AIX 7.1 (xlc, gcc4) (bash4, ksh, ksh93, sh) AIX 7.2 (xlc, gcc7) (bash4, ksh, ksh93, sh) HP-UX 11.11 (gcc4) (sh, ksh, bash4) Mac OS X 10.15.5 (clang) (bash3, dash, ksh93, sh/bash3) QNX 6.5 (cc) (pdksh, bash4, sh/pdksh) SCO SV 6.0.0 (cc, gcc2) (sh, ksh, ksh93, bash3, bash2) Solaris 11/x86 (cc 12.3, gcc5) (bash4, ksh93, sh/ksh93) Solaris 10/sparc (cc 12.3, gcc5) (bash4, sh(1), sh, bash3, ksh) Solaris 9/x86 (cc 12, gcc4) (bash4, ksh93, sh(1), bash2, sh) Tru64 5.1b (cc, gcc) (sh, ksh, bash2) UnixWare 7.1.4 (cc, gcc2) (sh, ksh93, ksh88, bash2) (1) not a standard solaris shell ISSUES - D Compiler bugs: ldc2 has structure size problems on 64bit (issue #28). gdc 4.6.3 (LinuxMint) has structure size problems on 64bit. - The D language portions have not been tested or used in a very long time. di-6.0.0/mkconfig/LICENSE0000644000175000017500000000166114005317662013027 0ustar bllbll Copyright 2010-2018 Brad Lanam, Walnut Creek, CA, USA Copyright 2020-2021 Brad Lanam Pleasant Hill CA, USA This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. di-6.0.0/mkconfig/mkconfig.pl0000755000175000017500000013620214746515027014166 0ustar bllbll#!/usr/bin/perl # # Copyright 2006-2018 Brad Lanam Walnut Creek, CA USA # Copyright 2020 Brad Lanam Pleasant Hill CA # # HP-UX doesn't have these installed. # use strict; # use Config; require 5.005; my $CONFH; my $MKC_FILES = 'mkc_files'; if ( $ENV{'MKC_FILES'} ne "" ) { $MKC_FILES = $ENV{'MKC_FILES'}; } mkdir $MKC_FILES, 0777; my $LOG = "../../${MKC_FILES}/mkconfig.log"; my $_MKCONFIG_TMP = "${MKC_FILES}/_tmp_mkconfig"; my $VARSFILE = "../../${MKC_FILES}/mkc_none.vars"; my $CACHEFILE = "../../${MKC_FILES}/mkconfig.cache"; my $REQLIB = "../../${MKC_FILES}/mkconfig.reqlibs"; my $_MKCONFIG_DIR = "invalid"; my $precc = <<'_HERE_'; #if defined(__cplusplus) || defined (c_plusplus) # define CPP_EXTERNS_BEG extern "C" { # define CPP_EXTERNS_END } CPP_EXTERNS_BEG extern int printf (const char *, ...); CPP_EXTERNS_END #else # define CPP_EXTERNS_BEG # define CPP_EXTERNS_END #endif _HERE_ my $postcc = <<'_HERE_'; /* some gcc's (cygwin) redefine __restrict again */ #if defined (__restrict) # undef __restrict #endif #define __restrict _HERE_ my $iflevels = ''; my $awkcmd = 'awk'; foreach my $p (split /[;:]/o, $ENV{'PATH'}) { if (-x "$p/awk" && $awkcmd eq "") { $awkcmd = "$p/awk"; } if (-x "$p/nawk" && $awkcmd !~ /mawk$/o && $awkcmd !~ /gawk$/o) { $awkcmd = "$p/nawk"; } if (-x "$p/mawk" && $awkcmd !~ /gawk$/o) { $awkcmd = "$p/mawk"; } if (-x "$p/gawk") { $awkcmd = "$p/gawk"; } } sub exitmkconfig { my $rc = shift; exit 1; } sub printlabel { my ($name, $label) = @_; print LOGFH "## ${iflevels}[$name] $label ... \n"; print STDOUT "${iflevels}$label ... "; } sub printyesno_actual { my ($name, $val, $tag) = @_; print LOGFH "## [$name] $val $tag\n"; print STDOUT "$val $tag\n"; } sub printyesno_val { my ($name, $val, $tag) = @_; if ($val ne '0') { printyesno_actual ($name, $val, $tag); } else { printyesno_actual ($name, 'no', $tag); } } sub printyesno { my ($name, $val, $tag) = @_; if ($val ne "0") { $val = "yes"; } printyesno_val $name, $val, $tag; } sub savevars { my ($r_clist) = @_; open (MKCV, ">$VARSFILE"); foreach my $val (@{$r_clist->{'vars'}}) { print MKCV $val, "\n"; } close (MKCV); } sub savecache { my ($r_clist, $r_config) = @_; open (MKCC, ">$CACHEFILE"); foreach my $val (@{$r_clist->{'clist'}}) { if ($val =~ /^lnk__lib_/o) { $tval = $val; $tval =~ s/^lnk_//o; print MKCC "mkc_lnk__lib_${tval}='" . $r_config->{$val} . "'\n"; } else { print MKCC "mkc_${val}='" . $r_config->{$val} . "'\n"; } } close (MKCC); } sub checkcache_val { my ($name, $r_clist, $r_config) = @_; my $rc = 1; if (defined ($r_config->{$name}) && $r_config->{$name} ne "" ) { push @{$r_clist->{'vars'}}, $name; my $r_hash = $r_clist->{'vhash'}; $r_hash->{$name} = 1; printyesno_val $name, $r_config->{$name}, " (cached)"; $rc = 0; } return $rc; } sub checkcache { my ($name, $r_clist, $r_config) = @_; my $rc = 1; if (defined ($r_config->{$name}) && $r_config->{$name} ne "" ) { push @{$r_clist->{'vars'}}, $name; my $r_hash = $r_clist->{'vhash'}; $r_hash->{$name} = 1; printyesno $name, $r_config->{$name}, " (cached)"; $rc = 0; } return $rc; } sub setclist { my ($r_clist, $name) = @_; $r_hash = $r_clist->{'chash'}; if (! defined ($r_hash->{$name})) { push @{$r_clist->{'clist'}}, $name; $r_hash->{$name} = 1; } } sub setlist { my ($r_clist, $name) = @_; my $r_hash = $r_clist->{'vhash'}; if (! defined ($r_hash->{$name})) { push @{$r_clist->{'vars'}}, $name; $r_hash->{$name} = 1; } setclist ($r_clist, $name); } sub setcflags { my $CFLAGS = ''; if ( $ENV{'CFLAGS_ALL'} ne "" ) { $CFLAGS= $ENV{'CFLAGS_ALL'}; } else { $CFLAGS .= ' ' . $ENV{'CFLAGS_OPTIMIZE'}; $CFLAGS .= ' ' . $ENV{'CFLAGS_DEBUG'}; $CFLAGS .= ' ' . $ENV{'CFLAGS_INCLUDE'}; $CFLAGS .= ' ' . $ENV{'CFLAGS_USER'}; $CFLAGS .= ' ' . $ENV{'CFLAGS_APPLICATION'}; $CFLAGS .= ' ' . $ENV{'CFLAGS_COMPILER'}; $CFLAGS .= ' ' . $ENV{'CFLAGS_SYSTEM'}; } $ENV{'CFLAGS'} = $CFLAGS; } sub setldflags { my $LDFLAGS = ''; if ( $ENV{'LDFLAGS_ALL'} ne "" ) { $LDFLAGS = $ENV{'LDFLAGS_ALL'} } else { $LDFLAGS .= ' ' . $ENV{'LDFLAGS_OPTIMIZE'}; $LDFLAGS .= ' ' . $ENV{'LDFLAGS_DEBUG'}; $LDFLAGS .= ' ' . $ENV{'LDFLAGS_USER'}; $LDFLAGS .= ' ' . $ENV{'LDFLAGS_APPLICATION'}; $LDFLAGS .= ' ' . $ENV{'LDFLAGS_COMPILER'}; $LDFLAGS .= ' ' . $ENV{'LDFLAGS_SYSTEM'}; } $ENV{'LDFLAGS'} = $LDFLAGS; } sub setlibs { my $LIBS = ''; if ( $ENV{'LDFLAGS_LIBS_ALL'} ne "" ) { $LIBS = $ENV{'LDFLAGS_LIBS_ALL'} } else { $LIBS .= ' ' . $ENV{'LDFLAGS_LIBS_USER'}; $LIBS .= ' ' . $ENV{'LDFLAGS_LIBS_APPLICATION'}; $LIBS .= ' ' . $ENV{'LDFLAGS_LIBS_SYSTEM'}; } $ENV{'LIBS'} = $LIBS; } sub print_headers { my ($r_a, $r_clist, $r_config, $cppchk) = @_; my $txt; $txt = ''; if ($r_a->{'incheaders'} eq 'none') { return $txt; } if ($r_a->{'incheaders'} eq 'all' || $r_a->{'incheaders'} eq 'std') { # always include these four if present ... foreach my $val ('_hdr_stdio', '_hdr_stdlib', '_sys_types', '_sys_param') { if (defined ($r_config->{$val}) && $r_config->{$val} ne '0') { $txt .= "#include <" . $r_config->{$val} . ">\n"; # for cygwin/gcc if ($cppchk && $val eq '_hdr_stdio') { $txt .= $postcc; } } } } if ($r_a->{'incheaders'} eq 'all') { foreach my $val (@{$r_clist->{'vars'}}) { if ($val !~ m#^(_hdr_|_sys_)#o) { next; } if ($val eq '_hdr_stdio' || $val eq '_hdr_stdlib' || $val eq '_sys_types' || $val eq '_sys_param') { next; } if ($val eq '_sys_time' && $r_config->{'_sys_time'} ne '0' && $r_config->{'_inc_conflict__hdr_time__sys_time'} eq '0') { next; } if ($val eq '_hdr_linux_quota' && $r_config->{'_hdr_linux_quota'} ne '0' && $r_config->{'_inc_conflict__sys_quota__hdr_linux_quota'} eq '0') { next; } if ($r_config->{$val} ne '0') { $txt .= "#include <" . $r_config->{$val} . ">\n"; } } $txt .= "\n"; } return $txt; } sub _chk_run { my ($name, $code, $r_val, $r_clist, $r_config, $r_a) = @_; my $rc = _chk_link ($name, $code, $r_clist, $r_config, { 'incheaders' => 'all', %$r_a, }); print LOGFH "## run test: link: $rc\n"; $$r_val = 0; if ($rc == 0) { $rc = system ("./$name.exe > $name.out"); if ($rc & 127) { exitmkconfig ($rc); } $rc >>= 8; print LOGFH "## run test: run: $rc\n"; if ($rc == 0) { open (CRFH, "<$name.out"); $$r_val = ; chomp $$r_val; close CRFH; } } return $rc; } sub _chk_link { my ($name, $code, $r_clist, $r_config, $r_a) = @_; my $otherlibs = ''; if (defined ($r_a->{'otherlibs'})) { $otherlibs = $r_a->{'otherlibs'}; } open (CLFH, ">$name.c"); print CLFH $precc; my $hdrs = print_headers ($r_a, $r_clist, $r_config, 0); print CLFH $hdrs; print CLFH $code; close CLFH; my $rc = system ("cat $name.c >> $LOG"); if ($rc & 127) { exitmkconfig ($rc); } my $dlibs = ''; $rc = _chk_link_libs ($name, {} ); if ($rc != 0) { if ($otherlibs ne '') { my @olibs = split (/,/, $otherlibs); my $oliblist = ''; foreach my $olib (@olibs) { $oliblist = $oliblist . ' ' . $olib; $rc = _chk_link_libs ($name, { 'otherlibs' => $oliblist, } ); if ($rc == 0) { my $r_hash = $r_config->{'reqlibs'}; my @vals = split (/\s+/, $oliblist); $dlibs = ''; foreach my $val (@vals) { if ($val eq '') { next; } if (! defined ($r_hash->{$val})) { print LOGFH " reqlib: $val: new\n"; push @{$r_config->{'reqlibs_list'}}, $val; } else { print LOGFH " reqlib: $val: already\n"; } $r_hash->{$val} = 1; $dlibs .= $val . ' '; } last; } } } } $dlibs =~ s/ *$//o; $r_a->{'dlibs'} = $dlibs; return $rc; } sub _chk_link_libs { my ($name, $r_a) = @_; setcflags setldflags setlibs my $cmd = "$ENV{'CC'} $ENV{'CFLAGS'} "; if (defined ($r_a->{'cflags'})) { $cmd .= ' ' . $r_a->{'cflags'} . ' '; } $cmd .= "-o $name.exe $name.c"; $cmd .= " $ENV{'LDFLAGS'} $ENV{'LIBS'}"; if (defined ($r_a->{'otherlibs'}) && $r_a->{'otherlibs'} ne undef) { $cmd .= ' ' . $r_a->{'otherlibs'} . ' '; } print LOGFH "## link test: $cmd\n"; my $rc = system ("$cmd >> $LOG 2>&1"); if ($rc & 127) { exitmkconfig ($rc); } print LOGFH "## link test: $rc\n"; if ($rc == 0) { if (! -x "$name.exe") # not executable. { $rc = 1; } } return $rc; } sub _chk_cpp { my ($name, $code, $r_clist, $r_config, $r_a) = @_; open (CCFH, ">$name.c"); print CCFH $precc; my $hdrs = print_headers ($r_a, $r_clist, $r_config, 1); print CCFH $hdrs; print CCFH $code; close CCFH; setcflags my $cmd = "$ENV{'CC'} $ENV{'CFLAGS'} "; if (defined ($r_a->{'cflags'})) { $cmd .= ' ' . $r_a->{'cflags'} . ' '; } $cmd .= "-E $name.c > $name.out "; my $rc = system ("cat $name.c >> $LOG"); if ($rc & 127) { exitmkconfig ($rc); } $rc = system ("$cmd 2>>$LOG"); print LOGFH "## cpp test: $cmd\n"; if ($rc & 127) { exitmkconfig ($rc); } print LOGFH "## cpp test: $rc\n"; if ($rc == 0 && ! -f "$name.out") { print LOGFH "## can't locate $name.out\n"; $rc = -2; } return $rc; } sub _chk_compile { my ($name, $code, $r_clist, $r_config, $r_a) = @_; open (CCFH, ">$name.c"); print CCFH $precc; my $hdrs = print_headers ($r_a, $r_clist, $r_config, 0); print CCFH $hdrs; print CCFH $code; close CCFH; setcflags my $cmd = "$ENV{'CC'} $ENV{'CFLAGS'} -c $name.c"; print LOGFH "## compile test: $cmd\n"; my $rc = system ("cat $name.c >> $LOG"); if ($rc & 127) { exitmkconfig ($rc); } $rc = system ("$cmd >> $LOG 2>&1"); if ($rc & 127) { exitmkconfig ($rc); } print LOGFH "## compile test: $rc\n"; return $rc; } sub do_chk_compile { my ($name, $code, $inc, $r_clist, $r_config) = @_; my $rc = _chk_compile ($name, $code, $r_clist, $r_config, { 'incheaders' => $inc, }); my $trc = 0; if ($rc == 0) { $trc = 1; } printyesno $name, $trc; setlist $r_clist, $name; $r_config->{$name} = $trc; } sub check_header { my ($name, $file, $r_clist, $r_config, $r_a) = @_; printlabel $name, "header: $file"; if (checkcache ($name, $r_clist, $r_config) == 0) { return; } my $r_rh = $r_a->{'reqhdr'} || []; my $code = ''; foreach my $reqhdr (@$r_rh) { $code .= <<"_HERE_"; #include <$reqhdr> _HERE_ } $code .= <<"_HERE_"; #include <${file}> int main () { return (0); } _HERE_ my $rc = 1; $rc = _chk_compile ($name, $code, $r_clist, $r_config, { 'incheaders' => 'std', }); my $val = 0; if ($rc == 0) { $val = $file; } printyesno $name, $val; setlist $r_clist, $name; $r_config->{$name} = $val; } sub check_constant { my ($name, $constant, $r_clist, $r_config, $r_a) = @_; printlabel $name, "constant: $constant"; if (checkcache ($name, $r_clist, $r_config) == 0) { return; } my $r_rh = $r_a->{'reqhdr'} || []; my $code = ''; foreach my $reqhdr (@$r_rh) { $code .= <<"_HERE_"; #include <$reqhdr> _HERE_ } $code .= <<"_HERE_"; int main () { if (${constant} == 0) { 1; } return (0); } _HERE_ do_chk_compile ($name, $code, 'all', $r_clist, $r_config); } # if the keyword is reserved, the compile will fail. sub check_keyword { my ($name, $keyword, $r_clist, $r_config) = @_; printlabel $name, "keyword: $keyword"; if (checkcache ($name, $r_clist, $r_config) == 0) { return; } $r_config->{$name} = 0; my $code = <<"_HERE_"; int main () { int ${keyword}; ${keyword} = 1; return (0); } _HERE_ my $rc = _chk_compile ($name, $code, $r_clist, $r_config, { 'incheaders' => 'std', }); setlist $r_clist, $name; if ($rc != 0) # failure means it is reserved... { $r_config->{$name} = 1; } printyesno $name, $r_config->{$name}; } sub check_proto { my ($name, $r_clist, $r_config) = @_; printlabel $name, "supported: prototypes"; if (checkcache ($name, $r_clist, $r_config) == 0) { return; } my $code = <<"_HERE_"; CPP_EXTERNS_BEG extern int foo (int, int); CPP_EXTERNS_END int bar () { int rc; rc = foo (1,1); return 0; } _HERE_ my $rc = _chk_compile ($name, $code, $r_clist, $r_config, { 'incheaders' => 'all', }); setlist $r_clist, $name; $r_config->{$name} = 0; if ($rc == 0) { $r_config->{$name} = 1; } printyesno $name, $r_config->{$name}; } sub check_command { my ($name, $cmds, $r_clist, $r_config) = @_; my @cmdlist = split (/ +/o, $cmds); my $cmd = $cmdlist[0]; $name = "_command_${cmd}"; my $locnm = "_cmd_loc_${cmd}"; printlabel $name, "command: $cmd"; if (checkcache ($name, $r_clist, $r_config) == 0) { return; } setlist $r_clist, $name; $r_config->{$name} = 0; foreach my $cmd (@cmdlist) { foreach my $p (split /[;:]/o, $ENV{'PATH'}) { if (-x "$p/$cmd") { setlist $r_clist, $locnm; $r_config->{$locnm} = "$p/$cmd"; $r_config->{$name} = 1; last; } } } printyesno_val $name, $r_config->{$name}; } sub check_env { my ($name, $envvar, $val, $r_clist, $r_config) = @_; $name = "_env_${envvar}"; printlabel $name, "env: $envvar"; # do not check cache if ($ENV{$envvar} ne '') { $val = $ENV{$envvar}; } $val =~ s/^"//; $val =~ s/"$//; if ($val ne "") { setlist $r_clist, $name; $r_config->{$name} = $val; } printyesno_val $name, $r_config->{$name}; } sub check_grep { my ($name, $args, $r_clist, $r_config) = @_; my @arglist = split (/ +/o, $args); my $tag = $arglist[0]; my $pat= $arglist[1]; my $fn = $arglist[2]; $name = "_grep_${tag}"; my $locnm = "_grep_${tag}"; printlabel $name, "grep: $tag"; if (checkcache ($name, $r_clist, $r_config) == 0) { return; } setlist $r_clist, $name; $r_config->{$name} = 0; my $rc = system ("grep '${pat}' $fn > /dev/null 2>&1"); if ($rc == 0) { $r_config->{$name} = 1; } printyesno_val $name, $r_config->{$name}; } sub check_if { my ($iflabel, $ifcount, $ifline, $r_clist, $r_config) = @_; my $name = "_if_$iflabel"; my $trc = 0; # make parseable $ifline =~ s/!/ ! /og; $ifline =~ s/\(/ ( /og; $ifline =~ s/\)/ ) /og; $ifline =~ s/&&/ \&\& /og; $ifline =~ s/ and / && /og; $ifline =~ s/ -a / && /og; $ifline =~ s/\|\|/ || /og; $ifline =~ s/ or / || /og; $ifline =~ s/ -o / || /og; $ifline =~ s/ not / ! /og; $ifline =~ s/ +/ /og; $ifline =~ s/^ *//og; $ifline =~ s/ *$//og; printlabel $name, "if ($ifcount): $iflabel"; my $nline = ''; print LOGFH "## ifline: $ifline\n"; my $ineq = 0; my $val; my $quoted = 0; my $qtoken; foreach my $token (split (/\s/, $ifline)) { if ($token =~ /^'.*'$/o) { print LOGFH "## start/end qtoken\n"; $token =~ s/'//go; } elsif ($token =~ /^'/o) { $qtoken = $token; $quoted = 1; print LOGFH "## start qtoken\n"; next; } if ($quoted) { if ($token =~ /'$/o) { $token = $qtoken . ' ' . $token; $token =~ s/'//go; print LOGFH "## end qtoken\n"; $quoted = 0; } else { $qtoken = $qtoken . ' ' . $token; print LOGFH "## in qtoken\n"; next; } } if ($ineq == 1) { $ineq = 2; print LOGFH "## value of $token(B): " . $r_config->{$token} . "\n"; $val = $r_config->{$token}; } elsif ($ineq == 2) { print LOGFH "## end ==\n"; $ineq = 0; $nline .= "('$val' eq '$token') ? 1 : 0"; $nline .= ' '; } elsif ($token eq '==') { print LOGFH "## begin ==\n"; $ineq = 1; } elsif ($token eq '(' || $token eq ')' || $token eq '&&' || $token eq '||' || $token eq '!') { $nline .= $token . ' '; } else { print LOGFH "## value of $token: " . $r_config->{$token} . "\n"; $nline .= $r_config->{$token} ne '0' && $r_config->{$token} ne '' ? 1 : 0; $nline .= ' '; } } print LOGFH "## nline: $nline\n"; $trc = eval $nline; printyesno $name, $trc; return $trc; } sub check_set { my ($name, $type, $val, $r_clist, $r_config) = @_; my $tnm = $name; $tnm =~ s/^_setint_//; $tnm =~ s/^_setstr_//; printlabel $name, "${type}: $tnm"; if ($type eq 'set') { if (defined ($r_config->{$name})) { setlist $r_clist, $name; $r_config->{$name} = $val; printyesno $name, $r_config->{$name}; } else { printyesno_actual $name, 'no such variable'; } } elsif ($type eq 'setint') { setlist $r_clist, $name; $r_config->{$name} = $val; printyesno_actual $name, $r_config->{$name}; } else { setlist $r_clist, $name; $r_config->{$name} = $val; printyesno_actual $name, $r_config->{$name}; } } sub check_include_conflict { my ($name, $h1, $h2, $r_clist, $r_config) = @_; my $i1 = $h1; $i1 =~ s,/,_,go; $i1 =~ s,\.h$,,o; $i1 =~ s,:,,go; if ($i1 =~ m#^sys#o) { $i1 = "_${i1}"; } else { $i1 = "_hdr_${i1}"; } my $i2 = $h2; $i2 =~ s,/,_,go; $i2 =~ s,\.h$,,o; $i2 =~ s,:,,go; if ($i2 =~ m#^sys#o) { $i2 = "_${i2}"; } else { $i2 = "_hdr_${i2}"; } $name = "${name}_${i1}_${i2}"; printlabel $name, "header: include both $h1 & $h2"; if (defined ($r_config->{${i1}}) && $r_config->{${i1}} ne '0' && defined ($r_config->{${i2}}) && $r_config->{${i2}} ne '0') { if (checkcache ($name, $r_clist, $r_config) == 0) { return; } my $code = <<"_HERE_"; #include <$h1> #include <$h2> int main () { return 0; } _HERE_ do_chk_compile ($name, $code, 'std', $r_clist, $r_config); } else { setlist $r_clist, $name; $r_config->{$name} = 1; printyesno $name, $r_config->{$name}; } } sub check_npt { my ($name, $proto, $req, $r_clist, $r_config) = @_; printlabel $name, "need prototype: $proto"; if (checkcache ($name, $r_clist, $r_config) == 0) { return; } if (defined ($r_config->{$req}) && $r_config->{$req} eq '0') { $r_config->{$name} = 0; setlist $r_clist, $name; printyesno $name, $r_config->{$name}; return; } my $code = <<"_HERE_"; CPP_EXTERNS_BEG struct _TEST_struct { int _TEST_member; }; extern struct _TEST_struct* $proto _((struct _TEST_struct*)); CPP_EXTERNS_END _HERE_ do_chk_compile ($name, $code, 'all', $r_clist, $r_config); } sub check_type { my ($name, $type, $r_clist, $r_config) = @_; $type =~ s/star/*/og; printlabel $name, "type: $type"; if (checkcache ($name, $r_clist, $r_config) == 0) { return; } my $code = <<"_HERE_"; struct xxx { $type mem; }; static struct xxx v; struct xxx* f() { return &v; } int main () { struct xxx *tmp; tmp = f(); return (0); } _HERE_ do_chk_compile ($name, $code, 'all', $r_clist, $r_config); } sub check_defined { my ($name, $def, $r_clist, $r_config) = @_; printlabel $name, "defined: $def"; if (checkcache ($name, $r_clist, $r_config) == 0) { return; } setlist $r_clist, $name; my $code = <<"_HERE_"; int main () { #ifdef ${def} return (0); #else return (1); #endif } _HERE_ my $val = 0; my $rc = _chk_run ($name, $code, \$val, $r_clist, $r_config, {}); $r_config->{$name} = $rc == 0 ? 1 : 0; printyesno $name, $r_config->{$name}; } sub check_param_void_star { my ($name, $r_clist, $r_config) = @_; printlabel $name, "parameter: void *"; if (checkcache ($name, $r_clist, $r_config) == 0) { return; } my $code = <<"_HERE_"; char * tparamvs (ptr) void *ptr; { ptr = (void *) NULL; return (char *) ptr; } _HERE_ do_chk_compile ($name, $code, 'all', $r_clist, $r_config); } sub check_printf_long_double { my ($name, $r_clist, $r_config) = @_; printlabel $name, "printf: long double printable"; if (checkcache ($name, $r_clist, $r_config) == 0) { return; } setlist $r_clist, $name; my $code = << "_HERE_"; int main (int argc, char *argv[]) { long double a; long double b; char t[40]; a = 1.0; b = 2.0; a = a / b; sprintf (t, \"%.1Lf\", a); if (strcmp(t,\"0.5\") == 0) { return (0); } return (1); } _HERE_ my $val = 0; my %a = ( 'incheaders' => 'all', ); my $rc = _chk_run ($name, $code, \$val, $r_clist, $r_config, \%a); $r_config->{$name} = $rc == 0 ? 1 : 0; printyesno $name, $r_config->{$name}; } sub check_lib { my ($name, $func, $r_clist, $r_config, $r_a) = @_; setlist $r_clist, $name; my $val = $r_a->{'otherlibs'} || ''; $rfunc = $func; $rfunc =~ s/_dollar_/\$/g; if ($val ne '') { printlabel $name, "function: $rfunc [$val]"; } else { printlabel $name, "function: $rfunc"; if (checkcache ($name, $r_clist, $r_config) == 0) { return; } } $r_config->{$name} = 0; # unfortunately, this does not work if the function # is not declared. my $hinc = 'all'; my $code = ''; if ($ENV{'_MKCONFIG_USING_CPLUSPLUS'} eq 'Y') { $hinc = 'none'; $code = <<"_HERE_"; CPP_EXTERNS_BEG #undef $rfunc typedef char (*_TEST_fun_)(); char $rfunc(); _TEST_fun_ f = $rfunc; CPP_EXTERNS_END int main () { if (f == $rfunc) { return 0; } return 1; } _HERE_ } else { $hinc = 'all'; $code = <<"_HERE_"; CPP_EXTERNS_BEG typedef char (*_TEST_fun_)(); _TEST_fun_ f = $rfunc; CPP_EXTERNS_END int main () { f(); if (f == $rfunc) { return 0; } return 1; } _HERE_ } my %a = ( 'incheaders' => $hinc, 'otherlibs' => $val, ); my $rc = _chk_link ($name, $code, $r_clist, $r_config, \%a); my $tag = ''; if ($rc == 0) { $r_config->{$name} = 1; if ($a{'dlibs'} ne '') { $tag = " with $a{'dlibs'}"; $r_config->{"lib_$name"} = $a{'dlibs'}; setclist $r_clist, "lib_$name"; } } printyesno $name, $r_config->{$name}, $tag; } sub check_class { my ($name, $class, $r_clist, $r_config, $r_a) = @_; setlist $r_clist, $name; my $val = $r_a->{'otherlibs'} || ''; if ($val ne '') { printlabel $name, "class: $class [$val]"; } else { printlabel $name, "class: $class"; if (checkcache ($name, $r_clist, $r_config) == 0) { return; } } $r_config->{$name} = 0; my $code = <<"_HERE_"; int main () { $class testclass; } _HERE_ my %a = ( 'incheaders' => 'all', 'otherlibs' => $val, ); my $rc = _chk_link ($name, $code, $r_clist, $r_config, \%a); my $tag = ''; if ($rc == 0) { $r_config->{$name} = 1; if ($a{'dlibs'} ne '') { $tag = " with $a{'dlibs'}"; $r_config->{"lib_$name"} = $a{'dlibs'}; setlist $r_clist, "lib_$name"; } } printyesno $name, $r_config->{$name}, $tag; } sub check_args { my ($name, $funcnm, $r_a, $r_clist, $r_config) = @_; printlabel $name, "args: $funcnm"; # no cache if ($ENV{'_MKCONFIG_USING_GCC'} eq 'N' && $ENV{'_MKCONFIG_SYSTYPE'} eq 'HP-UX' ) { my $tcc = `$ENV{'CC'} -v 2>&1`; if ($tcc =~ /Bundled/o) { print " bundled cc; skipped"; return; } } my $oldprecc = $precc; $precc .= "/* get rid of most gcc-isms */ #define __asm(a) #define __asm__(a) #define __attribute__(a) #define __nonnull__(a,b) #define __restrict #define __restrict__ #if defined(__THROW) # undef __THROW #endif #define __THROW #define __const const "; my $rc = _chk_cpp ($name, "", $r_clist, $r_config, { 'incheaders' => 'all', }); $precc = $oldprecc; my $ccount = 0; if ($rc == 0) { my $cmd = "egrep \"[ *]" . ${funcnm} . "[ ]*\\(\" $name.out >/dev/null 2>&1"; $rc = system ($cmd); print LOGFH "## args: $cmd $rc\n"; if ($rc == 0) { my $dcl = `${awkcmd} -f ${_MKCONFIG_DIR}/util/mkcextdcl.awk ${name}.out ${funcnm}`; # $dcl may be multi-line...fix this now. $dcl =~ s/[ \n\r]/ /gos; $dcl =~ s/extern *//o; $dcl =~ s/;//o; print LOGFH "## dcl(A): $dcl\n"; $dcl =~ s/\( *void *\)/()/o; print LOGFH "## dcl(C): $dcl\n"; my $c = $dcl; $c =~ s/[^,]*//go; $ccount = length ($c); $ccount += 1; $c = $dcl; $c =~ s/^[^\(]*\(//o; $c =~ s/\)[^\)]*$//o; print LOGFH "## c(E): ${c}\n"; my $val = 1; while (${c} ne "") { my $tc = $c; $tc =~ s/ *,.*$//o; $tc =~ s/[ ]+/ /go; if ($r_a->{'noconst'} eq 'T') { $tc =~ s/const *//o; } $tc =~ s/^ *//; $tc =~ s/ *$//; # only do the following if the names of the variables are declared $tc =~ s/(struct|union|enum) /$1#/; if ($tc =~ / /o) { $tc =~ s/ *[A-Za-z0-9_]*$//o; } $tc =~ s/(struct|union|enum)#/$1 /; print LOGFH "## tc(F): ${tc}\n"; my $nm = "_c_arg_${val}_${funcnm}"; setlist $r_clist, $nm; $r_config->{$nm} = $tc; $val += 1; $c =~ s/^[^,]*//o; $c =~ s/^[ ,]*//o; print LOGFH "## c(G): ${c}\n"; } $c = $dcl; $c =~ s/[ ]+/ /go; $c =~ s/([ \*])${funcnm}[ \(].*/$1/; $c =~ s/^ *//o; $c =~ s/ *$//o; if ($r_a->{'noconst'}) { $c =~ s/const *//; } $nm = "_c_type_${funcnm}"; setlist $r_clist, $nm; $r_config->{$nm} = $c; } } setlist $r_clist, $name; $r_config->{$name} = $ccount; printyesno_val $name, $r_config->{$name}; } sub check_size { my ($name, $type, $r_clist, $r_config) = @_; printlabel $name, "sizeof: $type"; if (checkcache ($name, $r_clist, $r_config) == 0) { return; } setlist $r_clist, $name; $r_config->{$name} = 0; my $code = <<"_HERE_"; int main () { printf("%u\\n", sizeof($type)); return (0); } _HERE_ my $val = 0; my $rc = _chk_run ($name, $code, \$val, $r_clist, $r_config, {}); if ($rc == 0) { $val =~ s/\r//gos; $r_config->{$name} = $val; } printyesno_val $name, $r_config->{$name}; } sub check_member { my ($name, $struct, $member, $r_clist, $r_config) = @_; printlabel $name, "exists: $struct.$member"; if (checkcache ($name, $r_clist, $r_config) == 0) { return; } setlist $r_clist, $name; $r_config->{$name} = 0; my $code = <<"_HERE_"; int main () { $struct s; int i; i = sizeof (s.$member); } _HERE_ my $rc = _chk_compile ($name, $code, $r_clist, $r_config, { 'incheaders' => 'all', }); if ($rc == 0) { $r_config->{$name} = 1; } printyesno $name, $r_config->{$name}; } sub check_memberxdr { my ($name, $struct, $member, $r_clist, $r_config) = @_; printlabel $name, "member:xdr: $struct.$member"; # no cache $r_config->{$name} = 0; my $rc = _chk_cpp ($name, "", $r_clist, $r_config, { 'incheaders' => 'all', }); if ($rc == 0) { print LOGFH `pwd` . "\n"; print LOGFH "## ${awkcmd} -f ${_MKCONFIG_DIR}/util/mkcextstruct.awk ${name}.out ${struct}\n"; my $st = `${awkcmd} -f ${_MKCONFIG_DIR}/util/mkcextstruct.awk ${name}.out ${struct}`; print LOGFH "## xdr(A): $st\n"; if ($st =~ m/${member}\s*;/s) { my $mtype = $st; $mtype =~ s/\s*${member}\s*;.*//s; $mtype =~ s/.*\s//os; print LOGFH "## xdr(B): $mtype\n"; setlist $r_clist, "xdr_${member}"; $r_config->{"xdr_${member}"} = "xdr_${mtype}"; $r_config->{$name} = 1; } } setlist $r_clist, $name; printyesno $name, $r_config->{$name}; } sub check_int_declare { my ($name, $function, $r_clist, $r_config) = @_; printlabel $name, "declared: $function"; if (checkcache ($name, $r_clist, $r_config) == 0) { return; } setlist $r_clist, $name; $r_config->{$name} = 0; my $code = <<"_HERE_"; int main () { int x; x = $function; } _HERE_ my $rc = _chk_compile ($name, $code, $r_clist, $r_config, { 'incheaders' => 'all', }); if ($rc == 0) { $r_config->{$name} = 1; } printyesno $name, $r_config->{$name}; } sub check_ptr_declare { my ($name, $function, $r_clist, $r_config) = @_; printlabel $name, "declared: $function"; if (checkcache ($name, $r_clist, $r_config) == 0) { return; } setlist $r_clist, $name; $r_config->{$name} = 0; my $code = <<"_HERE_"; int main () { void *x; x = $function; } _HERE_ my $rc = _chk_compile ($name, $code, $r_clist, $r_config, { 'incheaders' => 'all', }); if ($rc == 0) { $r_config->{$name} = 1; } printyesno $name, $r_config->{$name}; } sub check_standard { my ($r_clist, $r_config) = @_; # FreeBSD has buggy headers, requires sys/param.h as a required include. # always check for these headers. my @headlist1 = ( [ "_hdr_stdio", "stdio.h", ], [ "_hdr_stdlib", "stdlib.h", ], [ "_sys_types", "sys/types.h", ], [ "_sys_param", "sys/param.h", ], ); foreach my $r_arr (@headlist1) { check_header ($$r_arr[0], $$r_arr[1], $r_clist, $r_config, { 'reqhdr' => [], }); } check_keyword ('_key_void', 'void', $r_clist, $r_config); check_keyword ('_key_const', 'const', $r_clist, $r_config); check_param_void_star ('_param_void_star', $r_clist, $r_config); check_proto ('_proto_stdc', $r_clist, $r_config); } sub create_output { my ($r_clist, $r_config, $include, $configfile) = @_; if ($CONFH eq 'none') { return; } my $dt=`date`; chomp $dt; open (CCOFH, ">$CONFH"); print CCOFH <<"_HERE_"; /* Created on: ${dt} From: ${configfile} Using: mkconfig-${_MKCONFIG_VERSION} (perl) */ #ifndef INC_${CONFHTAGUC}_H #define INC_${CONFHTAGUC}_H 1 _HERE_ foreach my $val (@{$r_clist->{'vars'}}) { if ($val =~ m#^lib__lib_#o) { next; } my $tval = 0; if ($r_config->{$val} ne "0") { $tval = 1; } if ($val =~ m#^_envquote_#o) { ; } elsif ($val =~ m#^_setint_#o) { $tnm = $val; $tnm =~ s/^_setint_//; print CCOFH "#define $tnm " . $r_config->{$val} . "\n"; } elsif ($val =~ m#^(_setstr_|_opt_|_cmd_loc_)#o) { my $isopt = 0; if ($val =~ m#^_opt_#o) { $isopt = 1; } $tnm = $val; $tnm =~ s/^_setstr_//; $tnm =~ s/^_opt_//; if (! $isopt || ($isopt && $r_config->{$val} != "")) { print CCOFH "#define $tnm \"" . $r_config->{$val} . "\"\n"; } } elsif ($val =~ m#^(_hdr|_sys|_command)#o) { print CCOFH "#define $val $tval\n"; } elsif ($val =~ m#^(_env_)#o) { my $envvar = $val; $envvar =~ s/^_env_//; my $qnm = "_envquote_${envvar}"; my $data = $r_config->{$val}; if (defined ($r_config->{$qnm}) && $r_config->{$qnm} eq '1') { print CCOFH "#define $envvar \"$data\"\n"; } else { print CCOFH "#define $envvar $data\n"; } } else { print CCOFH "#define $val " . $r_config->{$val} . "\n"; } } # standard tail -- always needed; non specific print CCOFH <<'_HERE_'; #ifndef MKC_STANDARD_DEFS # define MKC_STANDARD_DEFS 1 # if ! _key_void # define void int # endif # if ! _key_void || ! _param_void_star typedef char *pvoid; # else typedef void *pvoid; # endif # if ! _key_const # define const # endif #endif /* MKC_STANDARD_DEFS */ _HERE_ print CCOFH $include; print CCOFH <<"_HERE_"; #endif /* INC_${CONFHTAGUC}_H */ _HERE_ close CCOFH; } sub main_process { my ($configfile) = @_; my (%clist, %config); $clist{'clist'} = (); $clist{'chash'} = {}; $clist{'vars'} = (); $clist{'vhash'} = {}; $config{'reqlibs'} = {}; $config{'reqlibs_list'} = (); if (-f $CACHEFILE) { open (MKCC, "<$CACHEFILE"); while (my $line = ) { chomp $line; if ($line =~ m/^mkc(.*)=\$?'?(.*)'?/o) { my $name = $1; my $val = $2; $config{$name} = $val; push @{$clist{'clist'}}, $name; $clist{'chash'}->{$name} = 1; } } close (MKCC); } my $tconfigfile = $configfile; if ($configfile !~ m#^/#) { $tconfigfile = "../../$configfile"; } if (! open (DATAIN, "<$tconfigfile")) { print STDOUT "$configfile: $!\n"; exit 1; } my $linenumber = 0; my $inheaders = 1; my $ininclude = 0; my @doproclist; my $inproc = 0; my $doproc = 1; my $include = ''; my $tline = ''; my $ifstmtcount = 0; my $ifcurrlvl = 0; my $doif = $ifcurrlvl; while (my $line = ) { chomp $line; ++$linenumber; if ($ininclude == 0 && ($line =~ /^#/o || $line eq '')) { next; } if ($tline ne '') { $line = $tline . ' ' . $line; $tline = ''; } if ($line =~ /[^\\]\\$/o) { $tline = $line; $tline =~ s/\\$//o; next; } if ($ininclude == 1 && $line =~ m#^\s*endinclude$#o) { print LOGFH "end include\n"; $ininclude = 0; next; } elsif ($ininclude == 1) { $line =~ s,\\(.),$1,g; $include .= $line . "\n"; next; } if ($inheaders && $line !~ m#^\s*(hdr|sys)#o) { $inheaders = 0; } print LOGFH "#### ${linenumber}: ${line}\n"; if ($line =~ m#^\s*else#o) { if ($ifcurrlvl == $doif) { $doproc = $doproc == 0 ? 1 : 0; $iflevels =~ s/.\d+\s$//; $iflevels .= "-$ifstmtcount "; } } elsif ($line =~ m#^\s*if\s#o) { if ($doproc == 0) { $ifcurrlvl += 1; } } elsif ($line =~ m#^\s*endif#o) { if ($ifcurrlvl == $doif) { if ($#doproclist >= 0) { print LOGFH "## endif: doproclist: " . join (' ', @doproclist) . "\n"; $doproc = shift @doproclist; print LOGFH "## endif: doproclist now : " . join (' ', @doproclist) . "\n"; print LOGFH "## endif: doproc: $doproc\n"; $iflevels =~ s/.\d+\s$//; } else { $doproc = 1; $iflevels = ''; } $doif -= 1; } $ifcurrlvl -= 1; } if ($doproc == 1) { if ($line =~ m#^\s*output\s+([^\s]+)#o) { if ($inproc == 1) { savevars (\%clist); create_output (\%clist, \%config, $include, $configfile); $CONFH = 'none'; $CONFHTAG = 'none'; $CONFHTAGUC = 'NONE'; $include = ''; } print "output-file: $1\n"; my $tconfh = $1; if ($tconfh =~ m#^/#o) { $CONFH = $tconfh; } else { $CONFH = "../../$tconfh"; } $CONFHTAG = $tconfh; $CONFHTAG =~ s,.*/,,; $CONFHTAG =~ s,\..*$,,; $CONFHTAGUC = uc $CONFHTAG; print LOGFH "config file: $CONFH\n"; $inproc = 1; $VARSFILE = "../../${MKC_FILES}/mkc_${CONFHTAG}.vars"; $clist{'vars'} = (); $clist{'vhash'} = {}; } elsif ($line =~ m#^\s*standard#o) { check_standard (\%clist, \%config); } elsif ($line =~ m#^\s*loadunit#o) { ; } elsif ($line =~ m#^\s*args\s+(.*)$#o) { my $funcnm = $1; %args = ( 'noconst' => 'F' ); if ($funcnm =~ /^noconst */o) { $funcnm =~ s/^noconst *//o; $args{'noconst'} = 'T'; } my $nm = "_args_${funcnm}"; $nm =~ s,/,_,go; $nm =~ s,:,_,go; check_args ($nm, $funcnm, \%args, \%clist, \%config); } elsif ($line =~ m#^\s*include_conflict\s+([^\s]+)\s+([^\s]+)#o) { my $i1 = $1; my $i2 = $2; check_include_conflict ('_inc_conflict', $i1, $i2, \%clist, \%config); } elsif ($line =~ m#^\s*rquota_xdr$#o) { check_rquota_xdr ('_rquota_xdr', \%clist, \%config); } elsif ($line =~ m#^\s*gqa_uid_xdr$#o) { check_gqa_uid_xdr ('_gqa_uid_xdr', \%clist, \%config); } elsif ($line =~ m#^\s*include$#o) { print LOGFH "start include\n"; $ininclude = 1; } elsif ($line =~ m#^\s*(hdr|sys)\s+([^\s]+)\s*(.*)#o) { my $typ = $1; my $hdr = $2; my $reqhdr = $3; my $nm = "_${typ}_"; # create the standard header name for config.h $nm .= $hdr; $nm =~ s,/,_,go; $nm =~ s,\.h$,,o; $nm =~ s,:,_,go; if ($typ eq 'sys') { $hdr = 'sys/' . $hdr; } $reqhdr =~ s/^\s*//o; $reqhdr =~ s/\s*$//o; my @oh = split (/\s+/, $reqhdr); check_header ($nm, $hdr, \%clist, \%config, { 'reqhdr' => \@oh, }); } elsif ($line =~ m#^\s*const\s+([^\s]+)\s*(.*)#o) { my $tnm = $1; my $reqhdr = $2; my $nm = "_const_" . $tnm; $reqhdr =~ s/^\s*//o; $reqhdr =~ s/\s*$//o; my @oh = split (/\s+/, $reqhdr); check_constant ($nm, $tnm, \%clist, \%config, { 'reqhdr' => \@oh, }); } elsif ($line =~ m#^\s*command\s+(.*)#o) { my $cmds = $1; check_command ('', $cmds, \%clist, \%config); } elsif ($line =~ m#^\s*grep\s+(.*)#o) { check_grep ('', $1, \%clist, \%config); } elsif ($line =~ m#^\s*if\s+([^\s]+)\s+(.*)#o) { my $iflabel = $1; my $ifline = $2; ++$ifcurrlvl; ++$ifstmtcount; print LOGFH "## if: label: $iflabel count $ifstmtcount line: $ifline\n"; my $rc = check_if ($iflabel, $ifstmtcount, $ifline, \%clist, \%config); $iflevels .= "+$ifstmtcount "; unshift @doproclist, $doproc; $doproc = $rc; $doif = $ifcurrlvl; print LOGFH "## if: doproclist: " . join (' ', @doproclist) . "\n"; print LOGFH "## if: doproc: $doproc\n"; } elsif ($line =~ m#^\s*(endif|else)#o) { ; } elsif ($line =~ m#^\s*echo\s+(.*)$#o) { print $1; } elsif ($line =~ m#^\s*exit$#o) { print $1; } elsif ($line =~ m#^\s*(set(int|str)?)\s+([^\s]+)\s*(.*)#o) { my $type = $1; my $nm = $3; if ($type eq 'setint' || $type eq 'setstr') { $nm = "_${type}_$3"; } my $val = $4; check_set ($nm, $type, $val, \%clist, \%config); } elsif ($line =~ m#^\s*npt\s+([^\s]*)\s*(.*)#o) { my $func = $1; my $req = $2; my $nm = "_npt_" . $func; check_npt ($nm, $func, $req, \%clist, \%config); } elsif ($line =~ m#^\s*key\s+(.*)#o) { my $tnm = $1; my $nm = "_key_" . $tnm; if (! defined ($config{$nm}) || $config{$nm} eq '0') { check_keyword ($nm, $tnm, \%clist, \%config); } } elsif ($line =~ m#^\s*class\s+([^\s]+)\s*(.*)?#o) { my $class = $1; my $libs = $2 || ''; my $nm = "_class_" . $class; $nm =~ s,:,_,go; if (! defined ($config{$nm}) || $config{$nm} eq '0') { check_class ($nm, $class, \%clist, \%config, { 'otherlibs' => $libs, }); } } elsif ($line =~ m#^\s*typ\s+(.*)#o) { my $tnm = $1; my $nm = "_typ_" . $tnm; $nm =~ s, ,_,go; if (! defined ($config{$nm}) || $config{$nm} eq '0') { check_type ($nm, $tnm, \%clist, \%config); } } elsif ($line =~ m#^\s*define\s+(.*)#o) { my $tnm = $1; my $nm = "_define_" . $tnm; if (! defined ($config{$nm}) || $config{$nm} eq '0') { check_defined ($nm, $tnm, \%clist, \%config); } } elsif ($line =~ m#^\s*lib\s+([^\s]+)\s*(.*)?#o) { my $func = $1; my $libs = $2 || ''; my $nm = "_lib_" . $func; if (! defined ($config{$nm}) || $config{$nm} eq '0') { check_lib ($nm, $func, \%clist, \%config, { 'otherlibs' => $libs, }); } } elsif ($line =~ m#^\s*dcl\s+([^\s]*)\s+(.*)#o) { my $type = $1; my $var = $2; my $nm = "_dcl_" . $var; if (! defined ($config{$nm}) || $config{$nm} eq '0') { if ($type eq 'int') { check_int_declare ($nm, $var, \%clist, \%config); } elsif ($type eq 'ptr') { check_ptr_declare ($nm, $var, \%clist, \%config); } } } elsif ($line =~ m#^\s*printf_long_double#o) { check_printf_long_double ('_printf_long_double', \%clist, \%config); } elsif ($line =~ m#^\s*member\s+(.*)\s+([^\s]+)#o) { my $struct = $1; my $member = $2; my $nm = "_mem_" . $struct . '_' . $member; $nm =~ s/ /_/go; if (! defined ($config{$nm}) || $config{$nm} eq '0') { check_member ($nm, $struct, $member, \%clist, \%config); } } elsif ($line =~ m#^\s*memberxdr\s+(.*)\s+([^\s]+)#o) { my $struct = $1; my $member = $2; my $nm = "_memberxdr_" . $struct . '_' . $member; $nm =~ s/ /_/go; if (! defined ($config{$nm}) || $config{$nm} eq '0') { check_memberxdr ($nm, $struct, $member, \%clist, \%config); } } elsif ($line =~ m#^\s*size\s+(.*)#o) { my $typ = $1; $typ =~ s/\s*$//o; my $nm = "_siz_" . $typ; $nm =~ s, ,_,go; if (! defined ($config{$nm}) || $config{$nm} eq '0') { check_size ($nm, $typ, \%clist, \%config); } } elsif ($line =~ m#^\s*env\s+(\w+)(\s+(quote))?(\s+(.*))?#o) { my $envvar = $1; my $qnm = "_envquote_" . $envvar; my $nm = "_env_" . $envvar; my $val = ''; setclist \%clist, $qnm; $config{$qnm} = '0'; if ($3 eq "quote") { $config{$qnm} = '1'; } $val = $5; check_env ($nm, $envvar, $val, \%clist, \%config); } else { print LOGFH "unknown command: $line\n"; print STDOUT "unknown command: $line\n"; } } } savevars (\%clist); savecache (\%clist, \%config); create_output (\%clist, \%config, $include, $configfile); # This is here for os/2 and other systems w/no usable bourne shell. # it is not up to date, as it will output libraries that are not # needed by the final configuration. open (RLIBFH, ">$REQLIB"); my $r_list = $config{'reqlibs_list'}; print RLIBFH join (' ', @{$r_list}) . "\n"; close RLIBFH; } sub usage { print STDOUT "Usage: $0 [-c ] [-L ]\n"; print STDOUT " [-C] \n"; print STDOUT " -C : clear cache-file\n"; print STDOUT "defaults:\n"; print STDOUT " : mkconfig.cache\n"; print STDOUT " : mkconfig.log\n"; } # main my $clearcache = 0; while ($#ARGV > 0) { if ($ARGV[0] eq "-C") { shift @ARGV; $clearcache = 1; } if ($ARGV[0] eq "-c") { shift @ARGV; $CACHEFILE = $ARGV[0]; shift @ARGV; } if ($ARGV[0] eq "-L") { shift @ARGV; $LOG = $ARGV[0]; shift @ARGV; } } my $configfile = $ARGV[0]; if (! defined ($configfile) || ! -f $configfile) { usage; exit 1; } if (-d $_MKCONFIG_TMP && $_MKCONFIG_TMP ne "mkc_files/_tmp_mkconfig") { usage; exit 1; } delete $ENV{'CDPATH'}; delete $ENV{'GREP_OPTIONS'}; delete $ENV{'ENV'}; $ENV{'LC_ALL'} = "C"; my $tpath = $0; $tpath =~ s,/[^/]*$,,; my $currdir =`pwd`; chomp $currdir; if (! chdir $tpath) { die ("Unable to cd to $tpath. $!\n"); } $_MKCONFIG_VERSION=`cat $tpath/VERSION`; chomp $_MKCONFIG_VERSION; $_MKCONFIG_DIR = `pwd`; chomp $_MKCONFIG_DIR; if (! chdir $currdir) { die ("Unable to cd to $currdir. $!\n"); } if (-d $_MKCONFIG_TMP) { system ("rm -rf $_MKCONFIG_TMP"); } mkdir $_MKCONFIG_TMP, 0777; if (! chdir $_MKCONFIG_TMP) { die ("Unable to cd to $_MKCONFIG_TMP. $!\n"); } if ($clearcache) { unlink $CACHEFILE; unlink $VARSFILE; } print STDOUT "$0 using $configfile\n"; unlink $LOG; open (LOGFH, ">>$LOG"); $ENV{'CFLAGS'} = $ENV{'CFLAGS'}; foreach my $nm ('CC', 'CFLAGS_OPTIMIZE', 'CFLAGS_DEBUG', 'CFLAGS_INCLUDE', 'CFLAGS_USER', 'CFLAGS_APPLICATION', 'CFLAGS_COMPILER', 'CFLAGS_SYSTEM', 'CFLAGS_SHARED', 'CFLAGS_SHARED_USER', 'LDFLAGS_OPTIMIZE', 'LDFLAGS_DEBUG', 'LDFLAGS_USER', 'LDFLAGS_APPLICATION', 'LDFLAGS_COMPILER', 'LDFLAGS_SYSTEM', 'LDFLAGS_SHARED', 'LDFLAGS_SHARED_LIBLINK', 'LDFLAGS_LIBS_USER', 'LDFLAGS_LIBS_APPLICATION', 'LDFLAGS_LIBS_SYSTEM') { print LOGFH "$nm: $ENV{$nm}\n"; } print LOGFH "awk: $awkcmd\n"; main_process $configfile; close LOGFH; if ($ENV{'MKC_KEEP_TMP'} eq "") { if (-d $_MKCONFIG_TMP) { system ("rm -rf $_MKCONFIG_TMP"); } } exit 0; di-6.0.0/mkconfig/VERSION0000644000175000017500000000000614756672132013073 0ustar bllbll2.6.8 di-6.0.0/mkconfig/util/0000755000175000017500000000000014756672233013006 5ustar bllblldi-6.0.0/mkconfig/util/mkcextmacro.awk0000755000175000017500000000710013671051627016021 0ustar bllbll#!/usr/bin/awk # # Copyright 2010-2018 Brad Lanam Walnut Creek CA # Copyright 2020 Brad Lanam Pleasant Hill CA BEGIN { macrostart = "^#[ ]*define[ ]*" ARGV[2] "[ (]" delete ARGV[2]; ins = 0; doend = 0; #print "macrostart:" macrostart; cf = ENVIRON["CFLAGS"]; #print "cf:" cf ":"; split (cf,cfa); for (cfi in cfa) { #print "cfi:" cfi ":cfa[cfi]:" cfa[cfi]; if (cfa[cfi] ~ /^-D/) { gsub (/-D/,"",cfa[cfi]); if (match (cfa[cfi], "=")) { split (cfa[cfi], cfaa, /=/); tcfv = cfaa[1]; if (cfaa[2] > 0) { #print "cflags:" tcfv ":"; cflags[tcfv] = 1; } } else { #print "cflags:" cfa[cfi] ":"; cflags[cfa[cfi]] = 1; } } } exclude = 0; } { #print NR ": " $0; # remove comments gsub (/\/\/.*$/, ""); gsub (/\/\*.*\*\//, ""); gsub (/[ ]*$/, ""); if ($0 ~ /^# *ifndef/) { gsub (/^# *ifndef/, "#if !"); } if ($0 ~ /^# *ifdef/) { gsub (/^# *ifdef/, "#if "); } # this is very simplistic. # there is no precedence and no handling of parentheses if ($0 ~ /^# *if/) { #print "if:"; l = $0; gsub (/^# *if[a-z]*/, "", l); gsub (/defined *\(/, "", l); gsub (/\)/, "", l); gsub (/!/, " NOT ", l); gsub (/\&\&/, " AND ", l); gsub (/\|\|/, " OR ", l); gsub (/^ */, "", l); #print "if:l:" l; l = l " END"; split (l, la); ecount = 0; for (val in ea) { delete ea[val]; } rval = 0; dopop = 0; for (li = 1; la[li] != "END"; ++li) { #print "if:token:" li ":" la[li]; if (la[li] == "END") { continue; } else if (la[li] == "AND" || la[li] == "OR") { ea[ecount++] = rval; ea[ecount++] = la[li]; continue; } else if (la[li] == "NOT") { ea[ecount++] = la[li]; continue; } else { val = 0; if (la[li] ~ /^[0-9]+$/) { val = la[li]; } else if (la[li] in cflags) { #print "ifB':la[li]:" la[li] ":cflags[la[li]]:" cflags[la[li]] ":"; val = 1; } #print "ifB:val:" val; if (ecount > 0) { --ecount; if (ea[ecount] == "AND") { rval = ea[ecount - 1] && val; --ecount; } if (ea[ecount] == "OR") { rval = ea[ecount - 1] || val; --ecount; } if (ea[ecount] == "NOT") { rval = 1 - val; } } else { rval = val; } #print "ifA:rval:" rval; } dopop = 0; } #print "ifEND:rval:" rval; if (rval == 0) { exclude = 1; } } if ($0 ~ /^# *else/) { #print "else:"; exclude = 1 - exclude; } if ($0 ~ /^# *endif/) { #print "endif:"; exclude = 0; } if (exclude == 1) { #print "excluding"; next; } if ($0 ~ /^# *define/ && (NF == 3 || NF == 4)) { l = $0; gsub (/^# *define */, "", l); #print "check define:" l ":"; split (l, la); if (la[2] ~ /^[0-9]+$/) { #print "define:" la[1] ":" la[2]; if (la[2] > 0) { cflags[la[1]] = 1; } if (la[1] in cflags) { cflags[la[1]] = 1; } } } #print "main:" $0; if (ins == 0 && $0 ~ macrostart) { #print "start: " $0; ins = 1; macro = $0; #print "macroA:" macro; doend = 1; if ($0 ~ /\\$/) { doend = 0; gsub (/[ ]*\\$/, " ", macro); #print "macroB:" macro; #print "not end: "; } } else if (ins == 1) { #print "cont: " $0; macro = macro $0; #print "macroC:" macro; doend = 1; if ($0 ~ /\\$/) { doend = 0; gsub (/[ ]*\\$/, " ", macro); #print "macroD:" macro; #print "not end: "; } } else if (ins == 1) { #print "ins = 1; end "; doend = 1; } if (doend == 1) { print macro; exit; } } di-6.0.0/mkconfig/util/mkcextdcl.awk0000755000175000017500000000333014746500757015472 0ustar bllbll#!/usr/bin/awk # # Copyright 2010-2018 Brad Lanam Walnut Creek CA # Copyright 2020 Brad Lanam Pleasant Hill CA BEGIN { dclstart = "[ *]" ARGV[2] "[ ]*\\("; delete ARGV[2]; bcount = 0; acount = 0; ins = 0; havestart = 0; doend = 0; sarr[0] = ""; #print "dclstart:" dclstart; } { #print "havestart:" havestart " ins:" ins " bcount:" bcount " acount:" acount; if ($0 ~ /^#/) { next; } else if (ins == 0 && $0 ~ dclstart) { #print "start: " $0; ins = 1; acount = 0; sarr[acount] = $0; acount = acount + 1; havestart = 1; tstr = $0; gsub (/[^\(]/, "", tstr); bcount = bcount + length (tstr); #print "start: " length(tstr) " ("; tstr = $0; gsub (/[^\)]/, "", tstr); bcount = bcount - length (tstr); #print "start: " length(tstr) " )"; if (bcount <= 0 && length (tstr) > 0) { doend = 1; } } else if (ins == 1 && $0 ~ /\(/) { #print "(: " $0; sarr[acount] = $0; acount = acount + 1; tstr = $0; gsub (/[^\(]/, "", tstr); bcount = bcount + length (tstr); #print "(: " length(tstr) " ("; tstr = $0; gsub (/[^\(]/, "", tstr); bcount = bcount - length (tstr); #print "(: " length(tstr) " )"; if (bcount <= 0) { ins = 0; } } else if (ins == 1 && $0 ~ /\)/) { #print "): " $0; sarr[acount] = $0; acount = acount + 1; tstr = $0; gsub (/[^\)]/, "", tstr); bcount = bcount - length (tstr); #print "): " length(tstr) " )"; if (bcount <= 0) { if (havestart == 1) { doend = 1; } ins = 0; } } else if (ins == 1) { #print "1: " $0; sarr[acount] = $0; acount = acount + 1; } if (doend == 1) { for (i = 0; i < acount; ++i) { print sarr[i]; } exit; } } di-6.0.0/mkconfig/util/mkcextstruct.awk0000755000175000017500000001740113671051626016250 0ustar bllbll#!/usr/bin/awk # # Copyright 2010-2018 Brad Lanam Walnut Creek CA # Copyright 2020 Brad Lanam Pleasant Hill CA BEGIN { if (dcode != "T") { dcode = "F"; } ststructA = "(struct|class|union|enum)[ ]*"; ststruct1 = "(struct|class|union|enum)[ ]*\\{"; ststruct2 = "typedef[ ][ ]*(struct|class|union|enum)[ ]*[a-zA-Z0-9_]*[ ]*{?[ ]*$"; ststart1 = "(struct|class|union|enum)[ ]*" ARGV[2] "$"; ststart2 = "(struct|class|union|enum)[ ]*" ARGV[2] "[^a-zA-Z0-9_]"; stforward = "(struct|class|union|enum)[ ]*" ARGV[2] "[ ]*;"; stother = "(struct|class|union|enum)[ ]*" ARGV[2] "[ ][ ]*[*a-zA-Z0-9_]"; stend = "[ *]" ARGV[2] "_t[ ]*;"; stendb = "[ *]" ARGV[2] "[ ]*;"; delete ARGV[2]; bcount = 0; acount = 0; ins = 0; inend = 0; havestart = 0; doend = 0; hadend = 0; sarr[0] = ""; nsarr[0] = ""; savens = ""; lineno = 0; #print "dcode:" dcode; #print "ststruct1:" ststruct1; #print "ststruct2:" ststruct2; #print "ststart1:" ststart1; #print "ststart2:" ststart2; #print "stforward:" stforward; #print "stother:" stother; #print "stend:" stend; #print "stendb:" stendb; } { lineno = lineno + 1; #print lineno ": " $0; #if ($0 ~ ststruct1) { print " " lineno ": matches ststruct1"; } #if ($0 ~ ststruct2) { print " " lineno ": matches ststruct2"; } #if ($0 ~ ststart1) { print " " lineno ": matches ststart"; } #if ($0 ~ ststart2) { print " " lineno ": matches ststart"; } #if ($0 ~ stforward) { print " " lineno ": matches stforward"; } #if ($0 ~ stother) { print " " lineno ": matches stother: " $0; } #if ($0 ~ stend) { print " " lineno ": matches stend: " $0; } #if ($0 ~ stendb) { print " " lineno ": matches stendb: " $0; } #print "havestart:" havestart ":ins:" ins ":bcount:" bcount ":hadend:" hadend ":"; if ($0 ~ /^#/) { next; } else if (ins == 0 && ($0 ~ ststart1 || $0 ~ ststart2) && $0 !~ stforward && $0 !~ stother) { #print lineno ": start: "; hadend = 0; savens = ""; for (val in nsarr) { delete nsarr[val]; } nsarr[0] = ""; acount = 0; ins = 1; gsub (/[ ]*$/, "", $0); sarr[acount] = $0; acount = acount + 1; havestart = 1; tstr = $0; gsub (/[^\{]/, "", tstr); bcount = bcount + length (tstr); tstr = $0; gsub (/[^}]/, "", tstr); bcount = bcount - length (tstr); if (bcount <= 0 && length (tstr) > 0) { doend = 1; } } else if (havestart == 0 && bcount == 0 && ($0 ~ ststruct1 || $0 ~ ststruct2) && $0 !~ stforward && $0 !~ stother) { #print lineno ": struct: "; hadend = 0; savens = ""; for (val in nsarr) { delete nsarr[val]; } nsarr[0] = ""; acount = 0; ins = 1; tstr = $0; gsub (/[^\{]/, "", tstr); bcount = bcount + length (tstr); tstr = $0; gsub (/[^}]/, "", tstr); bcount = bcount - length (tstr); if (bcount <= 0 && length(tstr) > 0) { ins = 0; bcount = 0; savens = ""; for (val in nsarr) { delete nsarr[val]; } nsarr[0] = ""; } if ($0 ~ stend || $0 ~ stendb) { #print lineno ": matches endA: doend"; doend = 1; } acount = 0; gsub (/[ ]*$/, "", $0); sarr[acount] = $0; acount = acount + 1; } else if (hadend == 1 && acount > 0 && bcount == 0 && havestart == 0 && ($0 ~ stend || $0 ~ stendb)) { #print lineno ": endB: "; hadend = 0; gsub (/[ ]*$/, "", $0); sarr[acount] = $0; acount = acount + 1; doend = 1; } else if (ins == 1 && $0 !~ /(struct|class|union|enum)[ ]*\{/ && $0 ~ /(const *)?(struct|class|union|enum)[ ]*[a-zA-Z_][a-zA-Z0-9_]*[ \{]*$/ && $0 !~ /(const *)?(struct|class|union|enum)[ ].*;/) { # nested structure, not an unnamed structure # is named, but not followed by anything else #print lineno ": nested struct: "; hadend = 0; savens = ""; gsub (/[ ]*$/, "", $0); tstr = $0; if (dcode) { if ($0 ~ /struct/) { ttype = "struct"; tlab = "C_ST_"; #print lineno ": found struct" } if ($0 ~ /class/) { ttype = "class"; tlab = "C_CLASS_"; #print lineno ": found class" } if ($0 ~ /union/) { ttype = "union"; tlab = "C_UN_"; #print lineno ": found union" } if ($0 ~ /enum/) { ttype = "enum"; tlab = "C_ENUM_"; #print lineno ": found enum" } sub (/(struct|class|union|enum)[ ]*/, "&" tlab, tstr); #print lineno ": nested(A): " tstr } sarr [acount] = tstr; acount = acount + 1; tstr = $0; gsub (/[^\{]/, "", tstr); bcount = bcount + length (tstr); tstr = $0; gsub (/[^}]/, "", tstr); bcount = bcount - length (tstr); if (bcount <= 0 && length(tstr) > 0) { ins = 0; } if (ins == 1) { tstr = $0; #print lineno ": nested(B): ", $0 if (dcode) { sub (/[ const]*(struct|class|union|enum)[ ]*/, "", tstr); sub (/[ ].*/, "", tstr); } #print lineno ": nested(C): ", tstr; savens = tstr; if (bcount > 1) { nsarr[bcount] = tstr; savens = ""; #print lineno ": nested save: " tstr; } } } else if (ins == 1 && $0 ~ /\{/) { #print lineno ": {: "; hadend = 0; sarr[acount] = $0; acount = acount + 1; tstr = $0; gsub (/[^\{]/, "", tstr); bcount = bcount + length (tstr); tstr = $0; gsub (/[^}]/, "", tstr); bcount = bcount - length (tstr); if (bcount <= 0 && length(tstr) > 0) { ins = 0; } if (ins == 1 && bcount > 1 && savens != "") { #print lineno ": nested last: ", savens; if (bcount > 1) { nsarr[bcount] = savens; #print lineno ": nested save: " savens; } savens = ""; } } else if (ins == 1 && $0 ~ /}/) { #print lineno ": }: "; gsub (/[ ]*$/, "", $0); sarr[acount] = $0; acount = acount + 1; tstr = $0; gsub (/[^}]/, "", tstr); l = length(tstr); bcount = bcount - l; stendtestb = "}[ *][a-zA-Z0-9_]*[ ]*;"; if (l > 0 && $0 !~ stendtestb) { #print lineno ": }: hadend: =1: "; hadend = 1; } else { #print lineno ": }: hadend: =0: "; hadend = 0; } if (bcount <= 0) { #print lineno ": }: bcount: 0"; bcount = 0; if (havestart == 1) { #print lineno ": }: havestart: doend"; doend = 1; } if ($0 ~ stend || $0 ~ stendb) { #print lineno ": matches endC: doend"; doend = 1; } ins = 0; } else if (l > 0 && $0 !~ /}[ ;]*$/) { #print lineno ": end struct dcl: " $0; if (dcode) { tstr = $0; # if there's a declaration of a pointer to the nested structure # we'll be adding the declaration. # if so, remove the name now. # otherwise, keep the name for processing by d-main.sh if (nsarr[bcount + 1] != "") { sub (/}.*/, "};", tstr); sarr [acount - 1] = tstr; } #print lineno ": nsarr1: " nsarr[bcount + 1]; if (nsarr[bcount + 1] != "") { tstr = $0; sub (/}[ ]*/, tlab nsarr[bcount + 1] " ", tstr); sarr [acount] = tstr; acount = acount + 1; } } hadend = 0; } } else if (ins == 1) { #print lineno ": 1: " $0; #print lineno ": 1: hadend:" hadend; if (hadend == 1 && nsarr[bcount + 1] != "") { if ($0 ~ /[ *]*[_A-Za-z]/) { #print lineno ": 1: hadend: match" tstr = $0; if (dcode) { tstr = " " tlab nsarr[bcount + 1] " " $0; } sarr[acount] = tstr; acount = acount + 1; } else { gsub (/[ ]*$/, "", $0); sarr[acount] = $0; acount = acount + 1; } } else { gsub (/[ ]*$/, "", $0); sarr[acount] = $0; acount = acount + 1; } hadend = 0; } else if (ins == 0) { if ($0 ~ ststructA) { hadend = 0; } } if (doend == 1) { for (i = 0; i < acount; ++i) { print sarr[i]; } exit; } } di-6.0.0/mkconfig/util/mkcexttypedef.awk0000755000175000017500000000240013671051623016352 0ustar bllbll#!/usr/bin/awk # # Copyright 2010-2018 Brad Lanam Walnut Creek CA # Copyright 2020 Brad Lanam Pleasant Hill CA BEGIN { tdstart = "[ ]*typedef"; funcpat = "[ (*]" ARGV[2] "[ )]"; semipat = "[ *]" ARGV[2] "[ ]*;$"; delete ARGV[2]; intypedef = 0; acount = 0; docheck = 0; tarr = ""; lineno = 0; #print "tdstart:" tdstart ":"; #print "funcpat:" funcpat ":"; #print "semipat:" semipat ":"; } { lineno = lineno + 1; #print lineno ": " $0; if ($0 ~ /^#/) { next; } else if (intypedef == 0 && $0 ~ tdstart) { #print "start:"; intypedef = 1; acount = 0; sarr[acount] = $0; acount = acount + 1; tarr = tarr $0; if ($0 ~ /;$/) { #print "have semi"; docheck = 1; } } else if (intypedef == 1) { #print "in:"; sarr[acount] = $0; acount = acount + 1; tarr = tarr $0; if ($0 ~ /;$/) { #print "have semi"; docheck = 1; } } if (docheck == 1) { #print "docheck: tarr:" tarr ":"; if (tarr ~ funcpat || tarr ~ semipat) { #print "docheck: match"; doend = 1; } } if (doend == 1) { for (i = 0; i < acount; ++i) { print sarr[i]; } exit; } if (docheck == 1) { #print "docheck: no match"; acount = 0; tarr = ""; docheck = 0; intypedef = 0; } } di-6.0.0/mkconfig/bin/0000755000175000017500000000000014756672233012601 5ustar bllblldi-6.0.0/mkconfig/bin/mkcl.sh0000755000175000017500000001775314745750745014106 0ustar bllbll#!/bin/sh # # Copyright 2010-2018 Brad Lanam Walnut Creek, CA USA # Copyright 2020 Brad Lanam Pleasant Hill CA # unset CDPATH # this is a workaround for ksh93 on solaris if [ "$1" = "-d" ]; then cd $2 shift shift fi . ${_MKCONFIG_DIR}/bin/shellfuncs.sh doshelltest $0 $@ addlib () { lfn=$1 found=F nlibnames= for tf in $libnames; do if [ $lfn = $tf ]; then found=T # a match will be moved to the end of the list else doappend nlibnames " $tf" fi done doappend nlibnames " ${lfn}" libnames=${nlibnames} } addlibpath () { lp=$1 found=F for tp in $libpathnames; do if [ $lp = $tp ]; then found=T # a match will be kept. break fi done if [ $found = F ]; then doappend libpathnames " ${lp}" fi } addrunpath () { lp=$1 found=F for tp in $runpathnames; do if [ $lp = $tp ]; then found=T # a match will be kept. break fi done if [ $found = F ]; then doappend runpathnames " ${lp}" fi } compile=F link=F shared=F mkexec=F mklib=F doecho=F comp=${CC} reqlibfiles= MKC_FILES=${MKC_FILES:-mkc_files} logfile=${MKC_FILES}/mkc_compile.log c=T d=F while test $# -gt 0; do case $1 in -compile|-comp) shift compile=T shared=F ;; -link) shift link=T ;; -log) shift logfile=$1 shift ;; -shared) shift shared=T ;; -exec) shift mkexec=T ;; -lib) shift mkexec=F mklib=T ;; -c) shift comp=$1 shift ;; -d) shift ndir=$1 cd $ndir rc=$? if [ $rc -ne 0 ]; then puts "## Unable to cd to $ndir" grc=$rc exit $grc fi shift ;; -e) doecho=T shift ;; -o) shift outfile=$1 shift ;; -r) shift doappend reqlibfiles " $1" shift ;; [A-Za-z0-9_][A-Za-z0-9_]*=[\'\"]*[\'\"]) eval $1 shift ;; -D*|-U*) doappend CFLAGS_USER " $1" shift ;; -Wc*) doappend CFLAGS_APPLICATION " $1" ;; --) shift break ;; *) break ;; esac done if [ "$logfile" != "" ]; then exec 9>>$logfile puts "# `date`" >&9 fi OUTFLAG="-o " flags= files= objects= libnames= libpathnames= runpathnames= islib=0 ispath=0 isrpath=0 olibs= havesource=F if [ "$reqlibfiles" != "" ]; then for rf in $reqlibfiles; do doappend olibs "`cat $rf` " done fi grc=0 for f in $@ $olibs; do case $f in -D*) doappend CFLAGS_USER $1 shift ;; -L) ispath=1 ;; -L*) tf=$f dosubst tf '-L' '' if [ ! -d "$tf" ]; then # puts "## unable to locate dir $tf (-L)" : else addlibpath $tf fi ;; -R|-rpath) isrpath=1 ;; -R*|-rpath*) tf=$f dosubst tf '-R' '' dosubst tf '-rpath' '' addrunpath $tf ;; -l) islib=1 ;; -l*) addlib $f ;; -Wl*) addlib $f ;; lib*) addlib $f ;; *${OBJ_EXT}) if [ ! -f "$f" ]; then puts "## unable to locate $f" grc=1 else doappend objects " $f" fi ;; *.c|*.d|*.m|*.cpp|*.res) if [ ! -f "$f" ]; then puts "## unable to locate $f" grc=1 else doappend files " $f" havesource=T fi ;; "-"*) doappend flags " $f" if [ $f = "-c" ]; then compile=T fi ;; *) if [ $islib -eq 1 ]; then addlib "-l$f" elif [ $isrpath -eq 1 ]; then addrunpath $f elif [ $ispath -eq 1 ]; then if [ ! -d "$f" ]; then puts "## unable to locate dir $f (ispath)" grc=1 else addlibpath $f fi fi islib=0 ispath=0 isrpath=0 ;; esac done libs= for lfn in $libnames; do doappend libs " ${lfn}" done LDFLAGS_LIBPATH=-L libpath= for lp in $libpathnames; do doappend libpath " ${LDFLAGS_LIBPATH}${lp}" done runpath= for lp in $runpathnames; do doappend runpath " ${LDFLAGS_RUNPATH}${lp}" done outflags="" if [ "$outfile" = "" ]; then flags="${flags} -c" else outflags="${OUTFLAG}$outfile" case ${outfile} in *.o|*.obj) flags="${flags} -c" ;; esac fi allcflags= if [ $havesource = T ]; then if [ $c = T ];then if [ "$CFLAGS_ALL" != "" ]; then doappend allcflags " ${CFLAGS_ALL}" else doappend allcflags " ${CFLAGS_OPTIMIZE}" # optimization flags doappend allcflags " ${CFLAGS_DEBUG}" # debug flags doappend allcflags " ${CFLAGS_INCLUDE}" # any include files doappend allcflags " ${CFLAGS_USER}" # specified by the user if [ $shared = T ];then doappend allcflags " ${CFLAGS_SHARED}" doappend allcflags " ${CFLAGS_SHARED_USER}" fi doappend allcflags " ${CFLAGS_APPLICATION}" # added by the config process doappend allcflags " ${CFLAGS_COMPILER}" # compiler flags doappend allcflags " ${CFLAGS_SYSTEM}" # needed for this system fi fi fi allldflags= ldflags_libpath= ldflags_runpath= ldflags_shared_libs= ldflags_exec_link= if [ $link = T ]; then if [ "$LDFLAGS_ALL" != "" ]; then doappend allldflags " ${LDFLAGS_ALL}" else doappend allldflags " ${LDFLAGS_OPTIMIZE}" # optimization flags doappend allldflags " ${LDFLAGS_DEBUG}" # debug flags doappend allldflags " ${LDFLAGS_USER}" # specified by the user doappend allldflags " ${LDFLAGS_APPLICATION}" # added by the config process doappend allldflags " ${LDFLAGS_COMPILER}" # link flags doappend allldflags " ${LDFLAGS_SYSTEM}" # needed for this system fi fi if [ $link = T -a $shared = T ]; then doappend allldflags " ${LDFLAGS_SHARED_LIBLINK}" doappend allldflags " ${LDFLAGS_SHARED_USER}" fi if [ \( $shared = T \) -o \( $mkexec = T \) ]; then ldflags_libpath="" if [ "${libpath}" != "" -a "${LDFLAGS_LIBPATH}" != "" ]; then ldflags_libpath="${libpath}" fi ldflags_runpath="" if [ "${runpath}" != "" -a "${LDFLAGS_RUNPATH}" != "" ]; then ldflags_runpath="${runpath}" fi ldflags_shared_libs="" if [ "${libs}" != "" -a "${libpath}" != "" ]; then ldflags_shared_libs="${libpath}" fi ldflags_exec_link="" if [ $mklib = F -a $mkexec = T ]; then if [ "${LDFLAGS_EXEC_LINK}" != "" ]; then ldflags_exec_link="${LDFLAGS_EXEC_LINK}" fi fi fi if [ $link = T ]; then if [ "$LDFLAGS_LIBS_ALL" != "" ]; then doappend alllibs " ${LDFLAGS_LIBS_ALL}" else doappend alllibs " ${LDFLAGS_LIBS_USER}" doappend alllibs " ${LDFLAGS_LIBS_APPLICATION}" doappend alllibs " ${LDFLAGS_LIBS_SYSTEM}" fi fi # clear the standard env vars so they don't get picked up. CFLAGS= CPPFLAGS= LDFLAGS= LIBS= cmd="${comp} ${allcflags} ${flags} ${allldflags} ${ldflags_exec_link} \ $outflags $objects \ ${files} ${ldflags_libpath} ${ldflags_runpath} \ ${ldflags_shared_libs} ${alllibs} ${libs}" disp="" if [ $compile = T ]; then disp="${disp}COMPILE ${files} ... " if [ "$logfile" != "" ]; then puts "COMPILE ${files}" >&9 fi fi if [ $link = T ]; then disp="${disp}LINK ${outfile} ... " if [ "$logfile" != "" ]; then puts "LINK ${outfile}" >&9 fi fi if [ $doecho = T ]; then puts "" puts " $cmd" fi if [ "$logfile" != "" ]; then puts " $cmd" >&9 fi out="" if [ "$logfile" != "" ]; then out=`eval $cmd 2>&1` rc=$? puts "$out" >&9 if [ $doecho = F -a $rc -ne 0 ]; then puts "" puts " $cmd" puts "$out" fi if [ $doecho = T ]; then puts "$out" fi else eval $cmd rc=$? fi if [ $rc -eq 0 ]; then puts "$out" | grep -i warning: >/dev/null 2>&1 rc=$? if [ $rc -eq 0 ]; then if [ $doecho = F ]; then puts "" puts " $cmd" puts "$out" fi disp="${disp} warnings" else disp="${disp} ok" fi else disp="${disp} fail" grc=$rc fi puts $disp if [ "$logfile" != "" ]; then exec 9>&- fi exit $grc di-6.0.0/mkconfig/bin/capabilities.sh0000755000175000017500000000125114745757132015570 0ustar bllbll#!/bin/sh # # Copyright 2020 Brad Lanam Pleasant Hill CA USA # Copyright 2020 Brad Lanam Pleasant Hill CA # if [ "${_MKCONFIG_DIR}" = "" ]; then echo "Usage: _MKCONFIG_DIR= bin/capabilities.sh" exit 1 fi unset CDPATH # this is a workaround for ksh93 on solaris if [ "$1" = "-d" ]; then cd $2 shift shift fi . ${_MKCONFIG_DIR}/bin/shellfuncs.sh doshelltest $0 $@ puts "$shell $shvers" puts "printf: $shhasprintf ($shhasprintferr)" puts "append: $shhasappend" puts "math: $shhasmath ($shhasmatherr)" puts "typeset -u: $shhasupper" puts "typeset -l: $shhaslower" puts "readraw required: $shreqreadraw" puts "hasgrepe: $hasgrepe" puts "hasegrep: $hasegrep" di-6.0.0/mkconfig/bin/envfuncs.sh0000755000175000017500000000220714745750001014754 0ustar bllbll#!/bin/sh # # Copyright 2010-2018 Brad Lanam Walnut Creek, CA, USA # Copyright 2020 Brad Lanam Pleasant Hill CA # setcflags () { CFLAGS="" if [ "$CFLAGS_ALL" != "" ]; then CFLAGS="$CFLAGS_ALL" else doappend CFLAGS " ${CFLAGS_OPTIMIZE}" doappend CFLAGS " ${CFLAGS_DEBUG}" doappend CFLAGS " ${CFLAGS_INCLUDE}" doappend CFLAGS " ${CFLAGS_USER}" doappend CFLAGS " ${CFLAGS_APPLICATION}" doappend CFLAGS " ${CFLAGS_COMPILER}" doappend CFLAGS " ${CFLAGS_SYSTEM}" fi export CFLAGS } setldflags () { LDFLAGS="" if [ "$LDFLAGS_ALL" != "" ]; then LDFLAGS="$LDFLAGS_ALL" else doappend LDFLAGS " ${LDFLAGS_OPTIMIZE}" doappend LDFLAGS " ${LDFLAGS_DEBUG}" doappend LDFLAGS " ${LDFLAGS_USER}" doappend LDFLAGS " ${LDFLAGS_APPLICATION}" doappend LDFLAGS " ${LDFLAGS_COMPILER}" doappend LDFLAGS " ${LDFLAGS_SYSTEM}" fi export LDFLAGS } setlibs () { LIBS="" if [ "$LDFLAGS_LIBS_ALL" != "" ]; then LIBS="$LDFLAGS_LIBS_ALL" else doappend LIBS " ${LDFLAGS_LIBS_USER}" doappend LIBS " ${LDFLAGS_LIBS_APPLICATION}" doappend LIBS " ${LDFLAGS_LIBS_SYSTEM}" fi export LIBS } di-6.0.0/mkconfig/bin/shellfuncs.sh0000755000175000017500000003061514745757161015315 0ustar bllbll#!/bin/sh # # Copyright 2010-2018 Brad Lanam Walnut Creek, CA, USA # Copyright 2020 Brad Lanam Pleasant Hill CA # if [ ! -f "${_MKCONFIG_DIR}/VERSION" ]; then echo "Unable to locate ${_MKCONFIG_DIR}/VERSION." echo "Not a valid mkconfig installation." exit 1 fi # dash on Mandriva 2011 segfaults intermittently when: # read _MKCONFIG_VERSION < ${_MKCONFIG_DIR}/VERSION # export _MKCONFIG_VERSION # was used. _MKCONFIG_VERSION=`cat ${_MKCONFIG_DIR}/VERSION` export _MKCONFIG_VERSION # posh set command doesn't output correct data; don't bother with it. # older yash has quoting/backquote issues (what version did this get fixed?) # bosh is a disaster. # zsh is not bourne shell compatible # set | grep can be fixed (nulls are output) with: set | strings | grep # and 'emulate ksh' can be set in mkconfig.sh, but there # are more issues, and I'm not interested in tracking them down. tryshell="bash bash5 bash4 bash3 ksh ksh88 ksh93 mksh pdksh yash ash dash bash2 sh sh5 osh" mkconfigversion () { echo "mkconfig version ${_MKCONFIG_VERSION}" } dosubst () { subvar=$1 shift sa="" while test $# -gt 0; do pattern=$1 sub=$2 shift shift sa="${sa} -e \"s~${pattern}~${sub}~g\"" done cmd="${subvar}=\`echo \${${subvar}} | sed ${sa}\`" eval $cmd; } test_echo () { shhasprintf=0 shhasprintferr="" (eval 'printf %s hello >/dev/null') 2>/dev/null rc=$? # Virtually all shells have printf. # I had not known it was supported so far back -- most # everything used echo, and printf was not mentioned much. # 'printf' is POSIX compliant. if [ $rc -eq 0 ]; then shhasprintf=1 eval 'putsnonl () { printf '%s' "$*"; }' eval 'puts () { printf "%s\n" "$*"; }' else shhasprintferr=none fi # # Backslash interpolation with echo and single quotes has issues. # Apparently I didn't code anything that ran into that problem. # # echo with single quotes should be avoided as too many shells # interpolate backslashes when they should not. # # The read/printf combo fails due to differences from read/echo. # # 2019-6-26: Apparently some older ksh93 also have this issue. # 2020-6-10: Apparently there are differences in quite a few shells here. # I am surprised I did not run into portability issues with this. # # $ echo "a \\ b" # a \ b # $ printf "%s\n" "a \\ b" # a \ b # $ cat tt # a \\ b # $ read tdat < tt # $ echo "$tdat" # a \ b # should be: a \ b # $ printf "%s\n" "$tdat" # a \\ b # should be: a \ b # $ echo 'a \\ b' # a \ b # should be: a \\ b # $ printf "%s\n" 'a \\ b' # a \\ b # should be: a \\ b # $ # # Test for interpolation bugs. # If bugs are present, use 'echo'. tz="a \\\\ b" # should always interpolate as: a \\ b t1=`echo "$tz"` # and both of these should return: a \\ b t2=`printf '%s\n' "$tz"` # have to test against the original in order to catch the change # if echo and printf do not match each other, it is very likely # that the read/echo/printf mismatches also occur. # osh does some odd stuff internally according to the output here, # but echo and printf still seem to work. if [ \( "$tz" != "$t1" \) -o \( "$tz" != "$t2" \) ]; then shhasprintf=0 shhasprintferr=mismatch fi # 'echo' works everywhere, but is not a POSIX compliant command. # Have not found any bourne compatible shell that does not support # either -n or \c. if [ $shhasprintf -eq 0 ]; then _tEN='-n' _tEC='' if [ "`echo -n test`" = "-n test" ]; then _tEN='' _tEC='\c' fi eval 'putsnonl () { echo ${_tEN} "$*${_tEC}"; }' eval 'puts () { echo "$*"; }' fi } # The += form is much, much faster and less prone to errors. test_append () { shhasappend=0 (eval 'x=a;x+=b; test z$x = zab') 2>/dev/null if [ $? -eq 0 ]; then shhasappend=1 eval 'doappend () { eval $1+=\$2; }' else eval 'doappend () { eval $1=\$${1}\$2; }' fi } test_readraw () { # $ cat tt # a \\ b # $ read tdat < tt # $ echo "$tdat" # a \ b # should be: a \ b # $ printf "%s\n" "$tdat" # a \\ b # should be: a \ b shreqreadraw=0 # unixware 7.14 compiles and runs this code ok, but it's shell gets # completely wacked out later. So run it in a subshell. # (similar to mandriva 2011 problem with read < file) ( rrv='aa\\\\bb' read rrx << _HERE_ $rrv _HERE_ ( eval "read -r rry <<_HERE_ $rrv _HERE_" ) 2>/dev/null yrc=$? if [ $yrc -eq 0 ]; then read -r rry << _HERE_ $rrv _HERE_ if [ "${rrx}" != 'aa\\bb' -a "${rry}" = 'aa\\\\bb' ]; then shreqreadraw=1 fi fi exit $shreqreadraw ) shreqreadraw=$? } # use the faster method $((expr)) if possible. test_math () { shhasmath=0 shhasmatherr=none (eval 'x=1;y=$(($x+1)); test z$y = z2') 2>/dev/null rc=$? if [ $rc -eq 0 ]; then shhasmath=1 shhasmatherr="" eval 'domath () { mthvar=$1; mthval=\$\(\($2\)\); eval $mthvar=$mthval; }' fi if [ $shhasmath -eq 0 ]; then eval 'domath () { mthvar=$1; mthval=`expr $2`; eval $mthvar=$mthval; }' fi } # use the faster shell built-in if possible. test_upper () { shhasupper=0 (eval 'typeset -u xuvar;xuvar=x;test z$xuvar = zX') 2>/dev/null if [ $? -eq 0 ]; then shhasupper=1 eval 'toupper () { ucvar=$1; typeset -u ucval; eval "ucval=\${$ucvar};$ucvar=\$ucval"; }' else eval 'toupper () { ucvar=$1; cmd="$ucvar=\`echo \${$ucvar} | tr \"[a-z]\" \"[A-Z]\"\`"; eval "$cmd"; }' fi } # use the faster shell built-in if possible. test_lower () { shhaslower=0 (eval 'typeset -l xuvar;xuvar=X;test z$xuvar = zx') 2>/dev/null if [ $? -eq 0 ]; then shhaslower=1 eval 'tolower () { lcvar=$1; typeset -l lcval; eval "lcval=\${$lcvar};$lcvar=\$lcval"; }' else eval 'tolower () { lcvar=$1; cmd="$lcvar=\`echo \${$lcvar} | tr \"[A-Z]\" \"[a-z]\"\`"; eval "$cmd"; }' fi } test_egrep () { hasgrepe=0 hasegrep=0 tfn=egreptest echo "a b c" > ${tfn} # use grep -E by preference (eval 'grep -E "a|b" ${tfn}') >/dev/null 2>&1 if [ $? -eq 0 ]; then hasgrepe=1 grepcmd="grep -E" else (eval 'egrep "a|b" ${tfn}') >/dev/null 2>&1 if [ $? -eq 0 ]; then hasegrep=1 grepcmd="egrep" fi fi rm -f ${tfn} } testshcapability () { test_echo test_append test_readraw test_math test_upper test_lower test_egrep } getshelltype () { if [ "$1" != "" ]; then trs=$1 shift fi gstecho=F if [ "$1" = echo ]; then gstecho=T fi baseshell=${_shell:-sh} # unknown or old shell=${_shell:-sh} # unknown or old if [ "$trs" != "" ]; then dispshell=`echo $trs | sed -e 's,.*/,,'` else dispshell=$shell fi ( eval 'echo ${.sh.version}' ) >/dev/null 2>&1 if [ $? -eq 0 ]; then eval 'KSH_VERSION=${.sh.version}' fi if [ "$KSH_VERSION" != "" ]; then shell=ksh baseshell=ksh shvers=$KSH_VERSION case $KSH_VERSION in *PD*) shell=pdksh ;; *93*) shell=ksh93 ;; *88*) shell=ksh88 ;; *MIRBSD*) shell=mksh ;; esac elif [ "$BASH_VERSION" != "" ]; then shvers=$BASH_VERSION ver=`echo $BASH_VERSION | sed 's/\..*//'` shell=bash${ver} baseshell=bash elif [ "$ZSH_VERSION" != "" ]; then shvers=$ZSH_VERSION shell=zsh baseshell=zsh elif [ "$POSH_VERSION" != "" ]; then shvers=$POSH_VERSION shell=posh baseshell=posh elif [ "$YASH_VERSION" != "" ]; then shvers=$YASH_VERSION shell=yash baseshell=yash elif [ "$OIL_VERSION" != "" ]; then shvers=$OIL_VERSION shell=osh baseshell=osh fi if [ $dispshell = sh -a $dispshell != $shell ]; then dispshell="$dispshell-$shell" elif [ $dispshell = $baseshell ]; then dispshell=$shell fi # can try --version, but don't really know the path # of the shell running us; can't depend on $SHELL. # and it only works for bash and some versions of ksh. if [ $gstecho = T ]; then echo $dispshell $shvers fi } doshelltest () { # force shell type. if [ "$_MKCONFIG_SHELL" != "" ]; then if [ "$SHELL" != "$_MKCONFIG_SHELL" ]; then SHELL="$_MKCONFIG_SHELL" export SHELL loc=`pwd` s=$1 shift exec $SHELL $dstscript $s -d $loc $@ fi fi getshelltype # for display of error below chkshell "" $shell if [ $? -ne 0 ]; then echo "The shell in use ($dispshell) does not have the correct functionality:" >&2 echo $chkmsg >&2 echo "Please try another shell. _MKCONFIG_SHELL can be set to the path of another shell to override /bin/sh." >&2 exit 1 fi testshcapability } locatecmd () { lvar=$1 ltcmd=$2 getpaths lcmd="" for p in $_pthlist; do if [ -x "$p/$ltcmd" ]; then lcmd="$p/$ltcmd" break fi done eval $lvar=$lcmd } mkverscomp () { v=$1 # put a 1 in front to avoid any octal constant issue. echo $v | $awkcmd -F. '{ printf("1%03d%03d%03d\n", $1,$2,$3); }' } # rc = 0 : same version # rc = 1 : smaller version # rc = 2 : greater version versioncompare () { v1=`mkverscomp $1` v2=`mkverscomp $2` rc=0 if [ $v1 -lt $v2 ]; then rc=1 fi if [ $v1 -gt $v2 ]; then rc=2 fi return $rc } # function to make sure the shell has # some basic capabilities w/o weirdness. chkshell () { doecho=F if [ "$1" = "echo" ]; then doecho=T fi shellpath=$2 grc=0 case $shellpath in *yash) # reject older versions of yash # I do not know in what version the quoting/backquoting issues # got fixed. locateawkcmd versioncompare $YASH_VERSION 2.48 rc=$? if [ $rc -eq 1 ]; then chkmsg="${chkmsg} older versions of yash are not supported" grc=1 fi ;; esac chkmsg="" # test to make sure the set command works properly # some shells output xyzzy=abc def # some shells output xyzzy='abc def' # some shells output xyzzy=$'abc def' (ok; handled in mkconfig.sh) # yash does this correctly, but had quoting/backquote issues in older versions. ( cmd='xyzzy="abc def"; val=`set | grep "^xyzzy"`; test "$val" = "xyzzy=abc def"' eval $cmd 2>/dev/null if [ $? -eq 0 ]; then exit 0 fi cmd="xyzzy=\"abc def\"; val=\`set | grep \"^xyzzy\"\`; test \"\$val\" = \"xyzzy='abc def'\" -o \"\$val\" = \"xyzzy=\\$'abc def'\"" eval $cmd 2>/dev/null rc=$? exit $rc ) rc=$? if [ $rc -ne 0 ]; then grc=$rc chkmsg="${chkmsg} 'set' output not x=a b or x='a b' or x=\$'a b'." fi # test to make sure the 'set -f' command is supported. ( cmd='set -f' eval $cmd 2>/dev/null rc=$? if [ $rc -eq 0 ]; then exit 0 fi exit $rc ) rc=$? if [ $rc -ne 0 ]; then grc=$rc chkmsg="${chkmsg} 'set -f' not supported" fi if [ $doecho = "T" ]; then echo $chkmsg fi return $grc } getpaths () { if [ "$_pthlist" != "" ]; then return fi systype=`uname -s` tpthlist=`echo $PATH | sed 's/:/ /g'` # cygwin's /bin and /usr/bin are both mounted on same spot case ${systype} in CYGWIN*) d=/bin tpthlist=`echo $tpthlist | sed -e "s,^$d ,," -e "s, $d,,"` ;; esac # remove symlinks for d in $tpthlist; do if [ ! -d $d ]; then tpthlist=`echo $tpthlist | sed -e "s,^$d ,," -e "s, $d,,"` else if [ -h $d ]; then tpthlist=`echo $tpthlist | sed -e "s,^$d ,," -e "s, $d,,"` # make sure path symlink is pointing to is in the list npath=`ls -ld $d | sed 's/.*-> //'` tpthlist="$tpthlist $npath" fi fi done # remove dups _pthlist="" for d in $tpthlist; do _pthlist="$_pthlist $d" done _pthlist=`echo $_pthlist | sort -u` } initifs () { hasifs=0 if [ "$IFS" != "" ]; then OIFS="$IFS" hasifs=1 fi } setifs () { # just newline for parsing include section IFS=" " } resetifs () { if [ $hasifs -eq 1 ]; then IFS="$OIFS" else unset IFS fi } boolclean () { nm=$1 dosubst $nm '(' ' ( ' ')' ' ) ' dosubst $nm ' not ' ' ! ' ' and ' ' -a ' ' or ' ' -o ' dosubst $nm '!' ' ! ' '&&' ' -a ' '||' ' -o ' dosubst $nm ' \+' ' ' '^ *' '' ' *$' '' } locateawkcmd () { locatecmd awkcmd awk locatecmd nawkcmd nawk locatecmd gawkcmd gawk locatecmd mawkcmd mawk if [ "$nawkcmd" != "" ]; then awkcmd=$nawkcmd fi if [ "$mawkcmd" != "" ]; then awkcmd=$mawkcmd fi if [ "$gawkcmd" != "" ]; then awkcmd=$gawkcmd fi } locatepkgconfigcmd () { locatecmd pkgconfigcmd pkg-config } di-6.0.0/mkconfig/bin/mkstaticlib.sh0000755000175000017500000000441513671051706015441 0ustar bllbll#!/bin/sh # # Copyright 2010-2018 Brad Lanam Walnut Creek, CA USA # Copyright 2020 Brad Lanam Pleasant Hill CA # unset CDPATH # this is a workaround for ksh93 on solaris if [ "$1" = "-d" ]; then cd $2 shift shift fi . ${_MKCONFIG_DIR}/bin/shellfuncs.sh doshelltest $0 $@ libnm="" objects="" grc=0 doecho=F MKC_FILES=${MKC_FILES:-mkc_files} logfile=${MKC_FILES}/mkc_compile.log while test $# -gt 0; do case $1 in -e) shift doecho=T ;; --) shift ;; -log) shift logfile=$1 shift ;; -o) shift tf=$1 shift if [ "$libnm" = "" ]; then libnm=$tf continue fi ;; *${OBJ_EXT}) tf=$1 shift if [ ! -f "$tf" ]; then puts "## unable to locate $tf" grc=1 else doappend objects " $tf" fi ;; *) tf=$1 shift if [ "$libnm" = "" ]; then libnm=$tf continue fi ;; esac done if [ "$logfile" != "" ]; then exec 9>>$logfile puts "# `date`" >&9 fi locatecmd ranlibcmd ranlib locatecmd arcmd ar locatecmd lordercmd lorder locatecmd tsortcmd tsort if [ "$arcmd" = "" ]; then puts "## Unable to locate 'ar' command" grc=1 fi if [ $grc -eq 0 ]; then dosubst libnm '${SHLIB_EXT}$' '' libfnm=${libnm} # for really old systems... if [ "$ranlibcmd" = "" -a "$lordercmd" != "" -a "$tsortcmd" != "" ]; then objects=`$lordercmd ${objects} | $tsortcmd` fi test -f $libfnm && rm -f $libfnm cmd="$arcmd cq $libfnm ${objects}" putsnonl "CREATE ${libfnm} ..." if [ "$logfile" != "" ]; then puts "CREATE ${libfnm}" >&9 fi if [ $doecho = "T" ]; then puts "" puts $cmd fi if [ "$logfile" != "" ]; then out=`eval $cmd 2>&1` rc=$? puts "$out" >&9 if [ $doecho = T ]; then puts "$out" fi else eval $cmd rc=$? fi if [ $rc -ne 0 ]; then grc=$rc fi if [ "$ranlibcmd" != "" ]; then cmd="$ranlibcmd $libfnm" if [ $doecho = "T" ]; then puts $cmd fi if [ "$logfile" != "" ]; then eval $cmd >&9 rc=$? else eval $cmd rc=$? fi fi if [ $rc -ne 0 ]; then puts " fail" grc=$rc else puts " ok" fi fi if [ "$logfile" != "" ]; then exec 9>&- fi exit $grc di-6.0.0/mkconfig/bin/testfuncs.sh0000755000175000017500000000533114746510767015162 0ustar bllbll#!/bin/sh # # Copyright 2011-2018 Brad Lanam Walnut Creek, CA, USA # Copyright 2020 Brad Lanam Pleasant Hill CA # maindodisplay () { snm=$2 if [ "$1" = "-d" ]; then echo $snm exit 0 fi } maindoquery () { if [ "$1" = "-q" ]; then exit $2 fi } chkccompiler () { if [ "${CC}" = "" ]; then echo " no C compiler; skipped" >&5 exit 0 fi } getsname () { tsnm=$1 tsnm=`echo $tsnm | sed -e 's,.*/,,' -e 's,\.sh$,,'` scriptnm=${tsnm} } dosetup () { grc=0 stag="" if [ $# -eq 2 ];then stag=$1 shift fi script=$@ set -f } dorunmkc () { drmclear="-C" if [ "$1" = "-nc" ];then drmclear="" shift fi case ${script} in *mkconfig.sh) ${_MKCONFIG_SHELL} ${script} -d `pwd` \ ${drmclear} ${_MKCONFIG_RUNTESTDIR}/${scriptnm}.dat ;; *) perl ${script} ${drmclear} ${_MKCONFIG_RUNTESTDIR}/${scriptnm}.dat ;; esac if [ "$1" = "reqlibs" ]; then case $script in *mkconfig.sh) ${_MKCONFIG_SHELL} ${_MKCONFIG_RUNTOPDIR}/mkc.sh -d `pwd` -reqlib $2 ;; esac fi } chkccompile () { fn=$1 ${CC} -c ${CFLAGS} ${fn} if [ $? -ne 0 ]; then echo "## compile of ${fn} failed" grc=1 fi } chkouthcompile () { if [ $grc -eq 0 ]; then > testouth.c echo ' #include #include int main () { return 0; } ' chkccompile testouth.c fi } chkdiff () { f1=$1 f2=$2 echo "## diff of $f1 $f2" diff -b $f1 $f2 rc=$? if [ $rc -ne 0 ]; then echo "## diff of $f1 $f2 failed" grc=$rc; fi } chkgrep () { pat=$1 fn=$2 arg=$3 arg2=$4 if [ "$arg" = "wc" ]; then tl=`${grepcmd} -l "$pat" ${fn} 2>/dev/null | wc -l` rc=$? if [ ${tl} -ne ${arg2} ]; then echo "chkgrep: fail wc" grc=1 fi else ${grepcmd} -l "$pat" ${fn} >/dev/null 2>&1 rc=$? fi if [ "$arg" = "" -a $rc -ne 0 ]; then echo "chkgrep: pattern match fail" grc=$rc echo "## ${fn}: grep for '$pat' failed" fi if [ "$arg" = "neg" -a $rc -eq 0 ]; then echo "chkgrep: neg test fail" grc=$rc echo "## ${fn}: grep for '$pat' succeeded when it should not" fi } chkouth () { xp=$1 shift chkgrep "$xp" out.h $@ } chkoutd () { xp=$1 shift chkgrep "$xp" out.d $@ } chkcache () { xp=$1 shift chkgrep "$xp" ${MKC_FILES}/mkconfig.cache $@ } chkenv () { xp=$1 shift chkgrep "$xp" test.env $@ } testcleanup () { if [ "$stag" != "none" ]; then for x in out.h out.d testouth.c opts test.env c.env \ mkc_files \ $@; do # test -e is not supported by older shells. test -f ${x} && mv ${x} ${x}${stag} test -d ${x} && mv ${x} ${x}${stag} done fi } if [ x${grepcmd} = x ]; then . $_MKCONFIG_DIR/bin/shellfuncs.sh test_egrep fi di-6.0.0/mkconfig/bin/mkreqlib.sh0000755000175000017500000000326414746517062014750 0ustar bllbll#!/bin/sh # # Copyright 2009-2018 Brad Lanam Walnut Creek, CA USA # Copyright 2020 Brad Lanam Pleasant Hill CA # set -f unset CDPATH # this is a workaround for ksh93 on solaris if [ "$1" = "-d" ]; then cd $2 shift shift fi . ${_MKCONFIG_DIR}/bin/shellfuncs.sh doshelltest $0 $@ RUNTOPDIR=`pwd` MKC_FILES=${MKC_FILES:-mkc_files} CACHEFILE="${MKC_FILES}/mkconfig.cache" unset GREP_OPTIONS unset ENV getlibdata () { var=$1 gdname=$2 lang=$3 cmd="${var}=\${mkc_lnk_${gdname}}" eval $cmd } mkconfigversion debug=F OUTLIBFILE="${MKC_FILES}/mkconfig.reqlibs" while test $# -gt 1; do case $1 in -X) shift debug=T ;; -c) shift CACHEFILE=$1 shift ;; -o|-l) # -l backwards compatibility shift OUTLIBFILE=$1 shift ;; esac done CONFH=$1 ok=1 if [ ! -f "${CONFH}" ]; then echo "Unable to locate ${CONFH}" ok=0 fi if [ ! -f "$RUNTOPDIR/$CACHEFILE" ]; then echo "Unable to locate $RUNTOPDIR/$CACHEFILE" ok=0 fi if [ $ok -eq 0 ]; then exit 1 fi reqlibs="" . $RUNTOPDIR/$CACHEFILE exec 7<&0 < ${CONFH} dver=0 while read cline; do if [ $debug = T ]; then echo "cline:$cline:" fi case $cline in "#define _lib_"*1) lang=c ;; *) continue ;; esac dosubst cline '#define ' '' ' 1' '' getlibdata var $cline $lang if [ $debug = T ]; then echo "cline:$cline:lang:$lang:var:$var:" fi if [ "$var" != "" ]; then echo $reqlibs | grep -- $var > /dev/null 2>&1 rc=$? if [ $rc -ne 0 ]; then doappend reqlibs " $var" if [ $debug = T ]; then echo "append:$var" fi fi fi done exec <&7 7<&- echo $reqlibs > $OUTLIBFILE di-6.0.0/mkconfig/Makefile.inc0000644000175000017500000000340013670254714014230 0ustar bllbll# included by MKC_FILES = mkc_files MKC_FILET = $(MKC_FILES)/$(MKC_PREFIX).t MKC_REQLIB = $(MKC_FILES)/$(MKC_PREFIX).reqlibs MKC_DEPFILE = $(MKC_FILES)/$(MKC_PREFIX).depends MKC_ENVFILE = $(MKC_PREFIX).env MKC_CONFDIR = . MKC_CONF = $(MKC_CONFDIR)/$(MKC_PREFIX).mkc MKC_ENV_CONF = $(MKC_CONFDIR)/$(MKC_PREFIX)-env.mkc # executable $(MKC_PREFIX)$(EXE_EXT): $(MKC_DEPFILE) $(MKC_REQLIB) $(objects) @CC=$(CC) $(_MKCONFIG_SHELL) $(MKC_DIR)/mkc.sh \ -link -exec -r $(MKC_REQLIB) \ -o $(MKC_PREFIX)$(EXE_EXT) $(objects) # required libraries $(MKC_REQLIB): $(MKC_FILET) $(MKC_OUTPUT) @CC=$(CC) $(_MKCONFIG_SHELL) $(MKC_DIR)/mkc.sh \ -reqlib -o $(MKC_REQLIB) $(MKC_OUTPUT) # dependencies $(MKC_DEPFILE): $(MKC_FILET) $(MKC_OUTPUT) $(sources) $(CC) -E -MM $(sources) > $(MKC_DEPFILE) sed -e '/# DO NOT DELETE/,$$ d' Makefile > Makefile.bak (cat Makefile.bak;echo "# DO NOT DELETE";cat $(MKC_DEPFILE)) > Makefile @rm -f Makefile.bak # output configuration file $(MKC_OUTPUT): $(MKC_FILET) $(MKC_ENVFILE) $(MKC_CONF) @CC=$(CC) $(_MKCONFIG_SHELL) $(MKC_DIR)/mkconfig.sh $(MKC_CONF) # object files .c$(OBJ_EXT): @CC=$(CC) $(_MKCONFIG_SHELL) $(MKC_DIR)/mkc.sh -compile $< # environment variables $(MKC_ENVFILE): $(MKC_FILET) $(MKC_ENV_CONF) @CC=$(CC) $(_MKCONFIG_SHELL) $(MKC_DIR)/mkconfig.sh $(MKC_ENV_CONF) $(MKC_FILET): @test -d $(MKC_FILES) || mkdir $(MKC_FILES) @touch $(MKC_FILET) .PHONY: mkc-clean mkc-clean: -rm -f $(objects) \ $(MKC_PREFIX)$(EXE_EXT) \ > /dev/null 2>&1; exit 0 .PHONY: mkc-distclean mkc-distclean: $(MKC_FILET) -$(MAKE) mkc-clean > /dev/null 2>&1 -rm -rf mkc_* mkconfig.cache mkconfig.log \ $(MKC_FILES) $(MKC_OUTPUT) $(MKC_ENVFILE) \ _tmp_mkconfig _mkconfig_runtests \ > /dev/null 2>&1; exit 0 di-6.0.0/mkconfig/runtests.sh0000755000175000017500000002743614746507606014273 0ustar bllbll#!/bin/sh # # Copyright 1994-2018 Brad Lanam, Walnut Creek, CA # Copyright 2020 Brad Lanam Pleasant Hill CA # # # speed at the cost of maintainability... # File Descriptors: # 9 - $TSTRUNLOG # 8 - $MAINLOG # 7 - $TMPORDER # 5 - stdout (as 1 is directed to the log) # set -f # global DOPERL=T TESTORDER=test_order SUBDIR=F # this is a workaround for ksh93 on solaris if [ "$1" = -d ]; then cd $2 shift shift fi unset CDPATH if [ "$1" = -s ]; then SUBDIR=T shift CC="$1" shelllist="$2" _pthlist="$3" TMPOUT="$4" shift; shift; shift; shift fi if [ $# -lt 1 ]; then echo "Usage: $0 [ ...]" exit 1 fi unset GREP_OPTIONS unset ENV unalias sed > /dev/null 2>&1 unalias grep > /dev/null 2>&1 unalias ls > /dev/null 2>&1 unalias rm > /dev/null 2>&1 LC_ALL=C export LC_ALL # this is used for regression testing. getlistofshells () { getpaths echo "## PATH: $PATH" >&8 echo "## paths: $_pthlist" >&8 tshelllist="" inodelist="" for d in $_pthlist; do for s in $tryshell ; do rs=$d/$s if [ -x $rs ]; then while [ -h $rs -a $s != osh ]; do ors=$rs rs="`ls -l $rs | sed 's/.* //'`" case $rs in /*) ;; *) rs="$d/$rs" ;; esac # /etc/alternatives/xxx has some weird names w/dots. # all ksh* are ksh # anything not ksh/bash/zsh/osh is sh # if the name is sh->bash or sh->ksh; don't follow symlink. ts=`echo $rs | sed -e 's,.*[/\.],,' \ -e 's/ksh88/ksh/' -e 's/ksh93/ksh/' ` tts=`echo $s | sed -e 's/ksh88/ksh/' -e 's/ksh93/ksh/' ` if [ $ts != ksh -a $ts != bash -a $ts != zsh ]; then ts=sh fi if [ $ts != ksh -a $tts != bash -a $tts != zsh ]; then tts=sh fi if [ $ts != $tts ]; then rs=$ors break fi rs=`echo $rs | sed 's,/[^/]*/\.\./,/,'` rs=`echo $rs | sed 's,/[^/]*/\.\./,/,'` rs=`echo $rs | sed 's,/[^/]*/\.\./,/,'` rs=`echo $rs | sed 's,/[^/]*/\.\./,/,'` done inode=`ls -i ${rs} | sed -e 's/^ *//' -e 's/ .*//'` inode=${inode}${s} # append shell type also found=F for i in $inodelist; do if [ "$inode" = "${i}" ]; then found=T break fi done if [ $found = T ]; then continue fi if [ -x $rs ]; then cmd="$rs -c \". $_MKCONFIG_DIR/bin/shellfuncs.sh;getshelltype $rs echo\"" set `eval $cmd` dispshell=$1 echo " found: $rs ($dispshell)" >&8 case $dispshell in *) tshelllist="${tshelllist} $rs" if [ "${inode}" != ${s} ]; then inodelist="${inodelist} ${inode}" fi ;; esac fi # if executable fi # if there is a file done done tshelllist=`echo "$tshelllist" | sort -u` systype=`uname -s` shelllist="" for s in $tshelllist; do putsnonl " check $s" >&8 putsnonl " $s" cmd="$s -c \". $_MKCONFIG_DIR/bin/shellfuncs.sh;chkshell echo $s\"" eval $cmd >&8 2>&1 rc=$? cmd="$s -c \". $_MKCONFIG_DIR/bin/shellfuncs.sh;getshelltype $s echo\"" set `eval $cmd` dispshell=$1 shift shvers=$@ if [ $rc -eq 0 ]; then echo " ok" >&8 shelllist="${shelllist} $s" echo " [$dispshell $shvers] (ok)" else echo " ng" >&8 echo " : $chkmsg" >&8 echo " [$dispshell $shvers] (ng)" fi done } runshelltest () { stag="" if [ "$_MKCONFIG_SHELL" != "" ]; then stag=".${scount}_${dispshell}" fi TSTRUNLOG=${_MKCONFIG_TSTRUNTMPDIR}/${tbase}.log${stag} > $TSTRUNLOG exec 9>>$TSTRUNLOG echo "####" >&9 echo "# Test: $tbase $arg" >&9 if [ "$_MKCONFIG_SHELL" != "" ]; then echo "## testing with ${_MKCONFIG_SHELL} " >&9 fi echo "# $dt" >&9 echo "####" >&9 cd $_MKCONFIG_TSTRUNTMPDIR if [ "$_MKCONFIG_SHELL" != "" ]; then putsnonl " ${dispshell}" fi targ=$arg if [ "$arg" != "" ]; then targ="$_MKCONFIG_DIR/$arg" fi # dup stdout to 5; redirect stdout to 9; redirect stderr to new 1. ${_MKCONFIG_SHELL} $_MKCONFIG_RUNTESTDIR/$tf "$stag" $targ 5>&1 >&9 2>&1 rc=$? cd $_MKCONFIG_RUNTESTDIR dt=`date` echo "####" >&9 echo "# $dt" >&9 echo "# exit $rc" >&9 echo "####" >&9 exec 9>&- if [ $rc -ne 0 -a "$_MKCONFIG_SHELL" != "" ]; then putsnonl "*" fi return $rc } # # main # _MKCONFIG_RUNTOPDIR=`pwd` export _MKCONFIG_RUNTOPDIR mypath=`echo $0 | sed -e 's,/[^/]*$,,' -e 's,^\.,./.,'` if [ "$mypath" = runtests.sh ]; then mypath=. fi _MKCONFIG_DIR=`(cd $mypath;pwd)` export _MKCONFIG_DIR . ${_MKCONFIG_DIR}/bin/shellfuncs.sh _MKC_ONCE=0 export _MKC_ONCE _MKC_SH=1 export _MKC_SH _MKC_PL=2 export _MKC_PL _MKC_SH_PL=3 export _MKC_SH_PL doshelltest $0 $@ if [ $SUBDIR = F ]; then mkconfigversion fi testdir=$1 if [ ! -d $testdir ]; then echo "## Unable to locate $testdir" exit 1 fi shift teststorun=$* cd $testdir if [ $? != 0 ]; then echo "## Unable to cd to $testdir" exit 1 fi _MKCONFIG_RUNTESTDIR=`pwd` export _MKCONFIG_RUNTESTDIR MKC_FILES=${MKC_FILES:-mkc_files} export MKC_FILES if [ $SUBDIR = F ]; then _MKCONFIG_RUNTMPDIR=$_MKCONFIG_RUNTOPDIR/${MKC_FILES}/_mkconfig_runtests export _MKCONFIG_RUNTMPDIR CC=${CC:-cc} export CC else btestdir=`echo $testdir | sed 's,.*/,,'` _MKCONFIG_RUNTMPDIR=$_MKCONFIG_RUNTOPDIR/${MKC_FILES}/_mkconfig_runtests/$btestdir export _MKCONFIG_RUNTMPDIR fi d=`dirname $_MKCONFIG_RUNTMPDIR` test -d $d || mkdir -p $d TMPORDER=test_order.tmp > $TMPORDER if [ "$teststorun" = "" ]; then if [ ! -f "$TESTORDER" ]; then ls -1d *.d *.sh 2>/dev/null | sed -e 's/\.sh$//' -e 's/^/1/' >> $TMPORDER else sort -n $TESTORDER >> $TMPORDER fi else for t in $teststorun; do echo "1 $t" done >> $TMPORDER fi if [ $SUBDIR = F ]; then test -d $_MKCONFIG_RUNTMPDIR && rm -rf "$_MKCONFIG_RUNTMPDIR" fi test -d $_MKCONFIG_RUNTMPDIR || mkdir $_MKCONFIG_RUNTMPDIR MAINLOG=${_MKCONFIG_RUNTMPDIR}/main.log if [ $SUBDIR = F ]; then > $MAINLOG fi exec 8>>$MAINLOG if [ $SUBDIR = F ]; then echo "## locating valid shells" getlistofshells fi locateawkcmd echo "awk: $awkcmd" >&8 locatepkgconfigcmd echo "pkg-config: $pkgconfigcmd" >&8 export shelllist grc=0 count=0 fcount=0 fpass=0 lastpass="" # save stdin in fd 7 exec 7<&0 < ${TMPORDER} while read tline; do set $tline pass=$1 tbase=$2 if [ "$lastpass" = "" ]; then lastpass=$pass fi if [ $grc -ne 0 -a "$lastpass" != "$pass" ]; then if [ $SUBDIR = F ]; then echo "## stopping tests due to failures in $testdir/ pass $lastpass" else fpass=$lastpass fi echo "## stopping tests due to failures in $testdir/ pass $lastpass" >&8 break fi if [ -d "$tbase" ]; then ocwd=`pwd` cd $_MKCONFIG_DIR TMPOUT=${_MKCONFIG_RUNTMPDIR}/${tbase}.out ${_MKCONFIG_SHELL} ./runtests.sh -s "$CC" "$shelllist" "$_pthlist" $TMPOUT $testdir/$tbase retvals=`tail -1 $TMPOUT` rm -f $TMPOUT > /dev/null 2>&1 set $retvals retcount=$1 retfcount=$2 retfpass=$3 domath count "$count + $retcount" domath fcount "$fcount + $retfcount" rc=$retfcount if [ $rc -ne 0 ]; then grc=$rc echo "## stopping tests due to failures in $testdir/$tbase/ pass $retfpass (pass $lastpass) " echo "## stopping tests due to failures in $testdir/$tbase/ pass $retfpass (pass $lastpass)" >&8 break fi cd $ocwd continue fi tprefix=`echo $tbase | sed 's/-.*//'` if [ "${CC}" = "" -a "$tprefix" = c ]; then continue fi tf="${tbase}.sh" tconfig="${tbase}.config" tconfh="${tbase}.ctmp" ok=T if [ ! -f ./$tf ]; then echo "$tbase ... missing ... failed" echo "$tbase ... missing ... failed" >&8 ok=F elif [ ! -x ./$tf ]; then echo "$tbase ... permission denied ... failed" echo "$tbase ... permission denied ... failed" >&8 ok=F fi if [ $ok = F ]; then domath fcount "$fcount + 1" domath count "$count + 1" continue fi dt=`date` arg="mkconfig.sh" scount="" putsnonl "$tbase ..." putsnonl "$tbase ..." >&8 _MKCONFIG_TSTRUNTMPDIR=$_MKCONFIG_RUNTMPDIR/${tbase} export _MKCONFIG_TSTRUNTMPDIR mkdir ${_MKCONFIG_TSTRUNTMPDIR} if [ -f $tconfig ]; then cp $tconfig $_MKCONFIG_TSTRUNTMPDIR/$tconfh fi tfdisp=`$_MKCONFIG_RUNTESTDIR/$tf -d` putsnonl " ${tfdisp}" putsnonl " ${tfdisp}" >&8 $_MKCONFIG_RUNTESTDIR/$tf -q runshpl=$? if [ $runshpl -eq $_MKC_SH -o $runshpl -eq $_MKC_SH_PL ]; then putsnonl " ..." putsnonl " ..." >&8 src=0 scount=1 for s in $shelllist; do unset _shell unset dispshell cmd="$s -c \". $_MKCONFIG_DIR/bin/shellfuncs.sh;getshelltype $s echo\"" set `eval $cmd` dispshell=$1 _MKCONFIG_SHELL=$s export _MKCONFIG_SHELL test_egrep runshelltest rc=$? if [ $rc -ne 0 ]; then src=$rc; fi domath scount "$scount + 1" unset _shell unset dispshell unset _MKCONFIG_SHELL done else runshelltest src=$? fi if [ $src -eq 166 ]; then echo " ... skipped" echo " skipped" >&8 elif [ $src -ne 0 ]; then src=1 grc=1 if [ $tbase = c-compiler -a $grc -ne 0 ]; then CC="" grc=0 fi if [ $grc -eq 0 ]; then echo " ... skipping $tprefix compiler tests" echo " skipping $tprefix compiler tests" >&8 else echo " ... failed" echo " failed" >&8 domath fcount "$fcount + 1" fi else echo " ... success" echo " success" >&8 fi domath count "$count + 1" if [ $src -eq 0 -a "$MKC_CLEAN_RUN_TMP" = Y ]; then test -d "$_MKCONFIG_TSTRUNTMPDIR" && rm -rf "$_MKCONFIG_TSTRUNTMPDIR" fi # for some reason, unixware can't handle this if it is split into # multiple lines. if [ "$DOPERL" = T -a \( $runshpl -eq $_MKC_PL -o $runshpl -eq $_MKC_SH_PL \) ]; then _MKCONFIG_TSTRUNTMPDIR=$_MKCONFIG_RUNTMPDIR/${tbase}_pl export _MKCONFIG_TSTRUNTMPDIR mkdir ${_MKCONFIG_TSTRUNTMPDIR} TSTRUNLOG=$_MKCONFIG_TSTRUNTMPDIR/${tbase}.log > $TSTRUNLOG exec 9>>$TSTRUNLOG dt=`date` echo "####" >&9 echo "# Test: $tf mkconfig.pl" >&9 echo "# $dt" >&9 echo "####" >&9 putsnonl "$tbase ..." putsnonl "$tbase ..." >&8 putsnonl " ${tfdisp}" putsnonl " ${tfdisp}" >&8 putsnonl " ... perl" putsnonl " ... perl" >&8 echo "## Using mkconfig.pl " >&9 if [ -f $tconfig ]; then cp $tconfig $_MKCONFIG_TSTRUNTMPDIR/$tconfh fi cd $_MKCONFIG_TSTRUNTMPDIR # dup stdout to 5; redirect stdout to 9; redirect stderr to new 1. $_MKCONFIG_RUNTESTDIR/$tf none $_MKCONFIG_DIR/mkconfig.pl 5>&1 >&9 2>&1 rc=$? cd $_MKCONFIG_RUNTESTDIR dt=`date` echo "####" >&9 echo "# $dt" >&9 echo "# exit $rc" >&9 echo "####" >&9 exec 9>&- if [ $rc -ne 0 ]; then echo " ... failed" echo " failed" >&8 domath fcount "$fcount + 1" grc=1 else echo " ... success" echo " success" >&8 fi domath count "$count + 1" if [ $rc -eq 0 -a "$MKC_CLEAN_RUN_TMP" = Y ]; then test -d "$_MKCONFIG_TSTRUNTMPDIR" && rm -rf "$_MKCONFIG_TSTRUNTMPDIR" fi fi lastpass=$pass done # set std to saved fd 7; close 7 exec <&7 7<&- test -f $TMPORDER && rm -f $TMPORDER if [ $count -eq 0 ]; then # this can't be right... $fcount = -1 fi exec 8>&- if [ $SUBDIR = F ]; then echo "$count tests $fcount failures" if [ $fcount -eq 0 ]; then if [ "$MKC_KEEP_RUN_TMP" = "" ]; then ( cd $_MKCONFIG_RUNTMPDIR/../.. test -d "$_MKCONFIG_RUNTMPDIR" && rm -rf "$_MKCONFIG_RUNTMPDIR" test -d "${MKC_FILES}" && rmdir "${MKC_FILES}" > /dev/null 2>&1 ) fi fi else echo "$count $fcount $fpass" > $TMPOUT fi exit $fcount di-6.0.0/mkconfig/ChangeLog0000644000175000017500000003741414756672123013612 0ustar bllbllCHANGES 2.6.8 2025-2-23 Env: NetBSD Fix. Env: pkg-config cleanup. 2.6.7 2025-2-21 Env: Add flags and paths for HP-UX ia64. 2.6.6 2025-2-18 Env: Add some additional paths to check for pkg-config files. Env: Update paths for MacOS, NetBSD. 2.6.5 2025-2-8 Env: Fixed cflags processing. 2.6.4 2025-2-5 CC: Added 'staticlib' directive. CC: Added 'header_reset' directive. Env: Added 'addincpath' and 'addldsrchpath' directives. Env: Fixed addldpath/addcflags to handle multiple arguments. Env: Added 'sharedliblinkflag' and 'staticliblinkflag'. Env: Added 'shared_flags' directive that runs all shared options. Env: Remove non-working cache checks. New directive: 'env' : environment variable check. Options: Removed. mkcl.sh: Handle runpath. mkcl.sh: Fix ldpaths/runpath generation. units/c-main.sh: Remove define of _ for ancient C compilers. units/env-cc: AIX: Correctly check cflags. units/env-cc: Fixed clang issue for shared linking. units/env-cc: Fixed test for C flags. capabilities: test for grep -E / egrep. Remove D language. Merge env/c namespaces. 2.6.3 2021-1-30 Fix 'pkg libs' directive. 2.6.2 2021-1-30 Add 'pkg include' directive. Update documentation. 2.6.1 2020-9-25 Fix PKG_CONFIG_PATH handling. 2.6 2020-9-25 Add support for pkg-config --cflags and pkg-config --libs 2.5 2020-7 Rework domath function so that it can be used with osh. 2.4 2020-6-13 Added 'standard_cc' (env-cc), 'standard_system' (env-system) commands. Fixed 'defined', 'size' directives so that they will work with a cross-compile (MKC_CROSS=Y must be defined). Added examples/helloworld. Added Makefile.inc for simple builds. Made easier to use. Move most work files to a sub-directory. Fixed AIX shared library linking (xlc and gcc). Fixed HP-UX shared library linking. Fixed OSF1 (Tru64) shared library linking (cc and gcc). Fixed Msys2 and Cygwin shared library linking (clang). Tested on 23 platforms. 2.3 [2020-6-3] Fixed an issue propogating LDFLAGS_SHARED. Fix library check when using g++. Propogate CFLAGS_OPTIMIZE and CFLAGS_DEBUG properly to linker. Added bin/capabilities.sh script. Added yash to the supported scripts list (version 2.48 or later; I don't know when its issues were fixed). 2.2 [2020-5-22] Added support for oilshell (osh; oilshell.org). mkcl.sh will display its messages as a single printf so that make -j does not look really weird. 2.1.1 [2019-6-25] env-cc: Fix getconf/cflags_system. Fix putsnonl function when 'echo' is in use. 2.1.0 [2018-12-27] Add test for shell interpolation bug. Use printf if possible for POSIX compliance. env-cc: Fix cflags_shared. env-cc: Pick up all cflags* and ldflags* defaults from the environment. mkcl.sh: Fix processing of LDFLAGS. mkcl.sh: Support .m extension. mkcl.sh: Support command line set of env vars (must be quoted). env-cc: Add support for DragonFlyBSD. env-cc: Add support for pkgconfig files (findpc). 2.0.0 [2018-8-12] C: split CFLAGS, LDFLAGS, LIBS into multiple environment variables for easier processing. D language is probably broken. C: fix shared flags C: Various bug fixes for msys2, tru64, etc. Clean up interfaces to mkcl.sh, mkstaticlib.sh Clean output style for mkc.sh. Added compilation log file. Added 'findconfig' and 'addconfig' commands for *Config.sh files. Removed 'findincludefile' command. Remove mksharedlib.sh (now part of mkcl.sh). 1.31 [2018-4-11] env-cc: update findincludepath to search more common paths. Remove Makefile and MANIFEST from standard distribution. 1.30 [2018-4-10] Repo got completely mucked up. Restore lost code. C: size: -lintl option for modern libintl.h C: printf_long_double : -lintl option for modern libintl.h Minor code cleanup. Update copyrights. 1.29 [2018-4-6] Changed .tar.gz creation to not include tests. 1.28 [2016-8-9] Cleaned up some compiler warnings. More fixes for msys/mingw. 1.27 [2016-2-22] Protected standard definitions from multiple inclusion. Fixed ifoption/ifnotoption. Removed 'lib' prefix when creating libraries. Removed LDFLAGS when creating shared libraries. Fixes to run under msys. Added printf_long_double test (for mingw). Fix cache bug with values ending in '='. Fixed args test on mac os x. Fixed args test for cygwin. 1.26 [2016-1-6] Added yes/no as possible option values. Options can be overridden by environment variables. 1.25 [2015-10-18] Fix 'using_gnu_ld' environment test. Add 'addldflag' to env-cc. 1.24 [2014-2-15] Updates for MirOS and Irix. Added -Wno-disabled-macro-expansion for clang. 1.23 [19 Jan 2013] Added the 'using_clang' environment directive. Added default flags for the clang compiler. 1.22 [15 Nov 2012] Fixed the display of the define directive. Fixed issues where the cache should not be used for XDR types and library function arguments. Fixed processing of nested if statements. 1.21 [18 Oct 2012] Added examples directory. clang: add -Wno-unknown-warning-option addcflag directive updated to not add the flag if the compiler has a warning. Fixed read problems with ksh93 93u+. Added a work-around for cd problem w/debian ksh93 93u+ (bug #679966). Handle __restrict__ on NetBSD 6. Remove improper link flags for AIX. Not tested. 1.20 [25 Jan 2012] D: rewrite c-typedef extraction. D: handle situations where structure is typedef'd and a ctypedef directive is issued. D: several fixes for C structure extraction. D: improved nested structure handling. D: basic handling for bitfields in structures. D: changed prefix from C_TYP_ to C_NATIVE_ for native c types. D: Added the noprefix directive to not add C_ST_, C_TYP_, etc. prefixes to the original C language types (but not C_NATIVE_). D: Casts are converted. May still be some issues. env: Added the source directive. D: fixed macro extraction with partial name. D: convert the version keyword to version_ D: handle multi-line statements better. D: added the module directive. D: added the substitute directive. Minor speed improvements for header extraction. D: fixed multiple output files. mkc.sh: -comp: fixed to add -c flag when compiling to object w/-o flag. mkc.sh: merge -link and -comp. D: fixed some D1 conversion issues. Fixed if statements with unknown variables. D: wrap ctypes in extern D: fixed type conversions (followed by asterisk, lone unsigned) 1.19 [20 Nov 2011] Created mkc.sh as a single entry point for compiling, linking, creating libraries, setting options and finding required libraries. Solaris 2.6 /bin/sh is no longer excluded. Fixed problem with .vars file not being cleaned on remake. D: Rework c-structure extraction. D: Better handling of nested structures and typedef'd structures. D: Add aliases for c argument types. D: revert cache check where it shouldn't be cached. D: Add aliases for c basic types (csizes directive). Fixed mkreqlib.sh to handle clibs for D. Fixed c-declaration test for freebsd. Change support for tango library and Dv1. Changed env-dc to compile to get D version. Changed env-cc and env-dc to pick up standard env variables from the options file. This allows the options file to keep all configuration data. Rearranged directory structure. 1.18 [8 Oct 2011] D: C structures are wrapped in extern (C) {} (to properly declare functions). Fixed multiple output files in the same directory. Fixed multiple inclusion tag for C output file. Fixed and updated shell locater for runtests.sh. Removed -std1 for OSF1 (Tru64). Added 'ksh88', 'ksh93' as valid shell names. 1.17 [30 Sep 2011] Fixed cmacro directive for D. Added cmembertype, cmemberxdr for D. Added memberxdr for C. Removed rquota_xdr, gqa_uid_xdr. Improved documentation. Rewrote test suite. Fixed 'lib' for D. Updated env-cc.sh for SCO OpenServer and UnixWare. Fixed structure extraction for HP-UX. Various fixes for HP-UX, SCO OpenServer, UnixWare. * Shared lib tests fail for HP-UX ansi cc. 1.16 [16 Sep 2011] Removed 'di' leftovers. Changed internal prefix to 'mkc'. Added 'echo' and 'exit' directives. Fixed d language tests to be 32/64 bit safe. Fixed d language tests for d version 1. Fixed d language tests for tango library. Added initial support for ldc and tango libraries. * On 64-bit, ldc's unions don't match C language sizes. * ldc1 doesn't have alias for 'string'. * ldc2 tested w/-d flag. Tested with dmd1, dmd2, ldc1, ldc2 on 64-bit. Tested with dmd1, dmd2, ldc1, ldc2, gdc1, gdc2 on 32-bit. 1.15 [11 Sep 2011] Added pdksh in as a valid shell Added 'args' directive (C) Removed statfs, setmntent, quotactl, getfsstat_type (breaks backwards compatibility) Added 'addcflags' directive (env) Fixed args directive to return valid types (C) Fixed cdcl directive to return valid types (D) Updated args directive to save return type (C) Updated cdcl directive to save return type (D) Fixed shell validity tests. 1.14 [22 May 2011] Renamed ctypeconv to ctype (breaks backwards compatibility). Rewrite ctype check command to use the C typedef name, and add an alias. Fixed ctype to handle unsigned typedefs correctly. Fixed nested structure handling. ctypedef will now find function pointer typedefs. Made D-C prefixes more consistent (breaks backwards compatibility). Added cmacro to convert C macros to functions. Merged cdefint and cdefstr to cdefine; made more generic (breaks backwards compatibility). Added breakdown of arg types for "cdcl args ...". 1.13 [27 Feb 2011] Handle gcc __asm__ function renames. Update doc for cdcl. 1.12 [16 Feb 2011] Added d-ctypeconv check command. Renamed d-ctype to d-ctypedef. Updated to work with D1. More fixes for D, D-C checks. 1.11 [29 Dec 2010] Fixed output of "yes with" libraries. Rearranged tests and test directories. Fixed test subdirectory handling. Added c-rquota, c-getfsstat. Added unset CDPATH. The output from the cd command broke the scripts. Added D language (not yet complete). Backwards compatibility broken for mklink.sh. 1.10 [22 Jul 2010] Renamed reqlibs.txt to mkconfig.reqlibs. Breaks backwards compatibility. Added support for multiple output files. Fixed naming of runtest log files. Added mkstaticlib.sh. Added mksharedlib.sh: preliminary support for shared libs. Added mklink.sh: preliminary Added new env-cc vars to support shared libs. Added new env-extension vars to support shared libs. Bug fix: workaround for ksh93 unable to getcwd() on Solaris. Fixed env-extension to match manual page. 1.9 [12 Jul 2010] Fixed regression tests to work w/c++. Code cleanup. 1.8 [10 Jul 2010] Internal code cleanup. Modify tests to take -d parameter for description output. Stop tests on change of pass number on failure. Add check_option. Fixed member test so either structs or typedefs can be used. Changed member test names to be _mem_struct_s_member or _mem_sometype_member. Breaks backwards compatibility. 1.7 [5 Jul 2010] Add labels to if statement. if statement counter and display. 1.6 [4 Jul 2010] Fix getlistofshells() when absolute path. Added c-quotactl unit. Renamed c-include-time to c-include-conflict, and changed how c-include-conflict works. Added define, set, setint, setstr, ifoption, ifnotoption, if. Added option-file. Added mkcsetopt.sh 1.5 [13 May 2010 - separate release] Change tmp directory structure and where logs go. Fixes for mkconfig.pl to handle absolute paths. Remove /bin from path for cygwin (duplicate of /usr/bin). Code cleanup. 1.4 (di ver 4.23) [10 May 2010] Move -lsun, -lseq out of env-cc.sh Update env-cc.sh to handle QNX getconf 'undefined' output. Fix cache test (tests.d/cache.sh). Fix edit when /bin is symlink (shellfuncs.sh). Added test for -n support for shells. Added support to mkconfig.sh to munge set output that has $s in it. Export shelllist in runtests.sh; more efficient. Redo paths in shellfuncs; make sure symlinked paths are present. Needed for Tru64, do: export BIN_SH=svr4 beforehand. 1.3 (di ver 4.22) [1 may 2010] Use the configuration file and cache to determine the necessary libraries to link in rather than linking in all found. Change library format to allow better control of link tests. Change dosubst() to always use sed. It's more reliable. 1.2 (di ver 4.20, 4.21) [12 mar 2010] Rewrite mkconfig.sh to use unit scripts and increase performance. Add environment units. Allow _MKCONFIG_SHELL to override shell. 1.1 (di ver 4.19) [1 Feb 2010] Changed format of config.h file. Fixed a quoting bug in mkconfig.sh. mkconfig enhancements and cleanup. 1.0 (di ver 4.18) [29 Nov 2009] Initial coding di-6.0.0/digetentries.c0000644000175000017500000013726214747231124013067 0ustar bllbll/* * Copyright 1994-2018 Brad Lanam, Walnut Creek, CA * Copyright 2023-2025 Brad Lanam, Pleasant Hill, CA */ /* * * di_get_disk_entries () * Get a list of mounted filesystems. * In many cases, this also does the work of di_get_disk_info (). */ #include "config.h" #if _hdr_stdio # include #endif #if _hdr_stdlib # include #endif #if _hdr_stdbool # include #endif #if _hdr_dirent # include #endif #if _sys_types && ! defined (DI_INC_SYS_TYPES_H) /* xenix */ # define DI_INC_SYS_TYPES_H # include #endif #if _sys_param # include #endif #if _sys_ftype /* QNX */ # include #endif #if _sys_dcmd_blk /* QNX */ # include #endif #if _sys_io /* QNX */ # include #endif #if _hdr_errno # include #endif #if _hdr_string # include #endif #if _hdr_strings # include #endif #if _hdr_memory # include #endif #if _hdr_malloc # include #endif #if _hdr_mntent \ && ! defined (DI_INC_MNTENT) /* Linux, kFreeBSD, HP-UX */ # define DI_INC_MNTENT 1 # include /* hasmntopt (); _PATH_MNTTAB */ #endif /* HP-UX: set/get/endmntent (); hasmntopt () */ /* FreeBSD, OpenBSD, old NetBSD, HP-UX, MacOS */ #if _sys_mount && ! defined (DI_INC_SYS_MOUNT) # define DI_INC_SYS_MOUNT 1 # include /* getmntinfo (); struct statfs */ #endif #if _sys_fstypes /* NetBSD */ # include #endif #if _sys_fs_types /* OSF/1, AROS */ # include #endif #if _sys_mnttab /* Solaris, SCO_SV, UnixWare */ # include /* getmntent (); MNTTAB */ #endif #if _sys_statfs && ! _sys_statvfs /* Linux, FreeBSD, SysV.3 */ # include /* struct statfs; statfs () */ #endif #if _sys_statvfs /* NetBSD, Solaris */ # include /* struct statvfs; statvfs () */ #endif #if _sys_vfs /* BSD 4.3 */ # include /* struct statfs */ #endif #if _sys_mntctl /* AIX */ # include #endif #if _sys_vmount /* AIX */ # include #endif #if _hdr_fshelp /* AIX */ # include #endif #if _hdr_windows /* windows */ # include #endif #if _hdr_winioctl /* windows */ # include #endif #if _hdr_kernel_fs_info /* haiku */ # include #endif #if _hdr_storage_Directory /* haiku */ # include #endif #if _hdr_storage_Entry /* haiku */ # include #endif #if _hdr_storage_Path /* haiku */ # include #endif #include "di.h" #include "disystem.h" #include "diinternal.h" #include "distrutils.h" #include "dimntopt.h" #if defined (__cplusplus) || defined (c_plusplus) extern "C" { #endif /* workaround for AIX - mntctl not declared */ # if _lib_mntctl && _npt_mntctl extern int mntctl (int, Size_t, char *); # endif #if defined (__cplusplus) || defined (c_plusplus) } #endif #if (_lib_getmntent || _args_statfs > 0) && \ ! _lib_getmntinfo && \ ! _lib_getfsstat && \ ! _lib_getvfsstat && \ ! _lib_mntctl && \ ! _lib_getmnt # if defined (_PATH_MOUNTED) # define DI_MOUNT_FILE _PATH_MOUNTED # else # if defined (_PATH_MNTTAB) # define DI_MOUNT_FILE _PATH_MNTTAB # else # if defined (MOUNTED) # define DI_MOUNT_FILE MOUNTED # else # if defined (MNTTAB) # define DI_MOUNT_FILE MNTTAB # else # if (USE_ETC_FILESYSTEMS) # define DI_MOUNT_FILE "/etc/filesystems" /* AIX 4.x or /etc/mntent? */ # else # define DI_MOUNT_FILE "/etc/mnttab" /* SysV.3 default */ # endif # endif # endif # endif # endif #endif #if defined (__QNX__) static int di_getQNXDiskEntries (di_data_t *di_data, char *ipath, int *diCount); #endif #if _lib_getmntent \ && ! _lib_setmntent \ && ! _lib_mntctl static char *checkMountOptions (struct mnttab *, char *); /* * di_get_disk_entries * * For SysV.4, we open the file and call getmntent () repeatedly. * */ int di_get_disk_entries (di_data_t *di_data, int *diCount) { di_disk_info_t *diptr; FILE *f; int idx; struct mnttab mntEntry; char *devp; /* local ptr to dev entry */ di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; if (diopts->optval [DI_OPT_DEBUG] > 0) { printf ("# di_get_disk_entries: getmntent\n"); } if ( (f = fopen (DI_MOUNT_FILE, "r")) == (FILE *) NULL) { fprintf (stderr, "Unable to open: %s errno %d\n", DI_MOUNT_FILE, errno); return -1; } while (getmntent (f, &mntEntry) == 0) { idx = *diCount; ++*diCount; di_data->diskInfo = (di_disk_info_t *) di_realloc ( (char *) di_data->diskInfo, sizeof (di_disk_info_t) * (Size_t) (*diCount + 1)); if (di_data->diskInfo == (di_disk_info_t *) NULL) { fprintf (stderr, "malloc failed for diskInfo. errno %d\n", errno); return -1; } diptr = di_data->diskInfo + idx; di_initialize_disk_info (diptr, idx); stpecpy (diptr->strdata [DI_DISP_FILESYSTEM], diptr->strdata [DI_DISP_FILESYSTEM] + DI_FILESYSTEM_LEN, mntEntry.mnt_special); stpecpy (diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_MOUNTPT] + DI_MOUNTPT_LEN, mntEntry.mnt_mountp); if (checkMountOptions (&mntEntry, DI_MNTOPT_IGNORE) != (char *) NULL) { diptr->printFlag = DI_PRNT_IGNORE; if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("mnt: ignore: mntopt 'ignore': %s\n", diptr->strdata [DI_DISP_MOUNTPT]); } } if ( (devp = checkMountOptions (&mntEntry, DI_MNTOPT_DEV)) != (char *) NULL) { if (devp != mntEntry.mnt_mntopts) { --devp; } *devp = 0; /* point to preceeding comma and cut off */ } if (checkMountOptions (&mntEntry, DI_MNTOPT_RO) != (char *) NULL) { diptr->isReadOnly = true; } stpecpy (diptr->strdata [DI_DISP_MOUNTOPT], diptr->strdata [DI_DISP_MOUNTOPT] + DI_MOUNTOPT_LEN, mntEntry.mnt_mntopts); /* get the file system type now... */ stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, mntEntry.mnt_fstype); if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("mnt:%s - %s\n", diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_FSTYPE]); } if (diopts->optval [DI_OPT_DEBUG] > 1) { printf ("mnt:%s - %s\n", diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_FILESYSTEM]); } } fclose (f); return 0; } static char * checkMountOptions (struct mnttab *mntEntry, char *str) { # if _lib_hasmntopt return hasmntopt (mntEntry, str); # else return chkMountOptions (mntEntry->mnt_mntopts, str); # endif } #endif #if _lib_getmntent && \ _lib_setmntent && \ _lib_endmntent && \ ! _lib_getmntinfo && \ ! _lib_getfsstat && \ ! _lib_getvfsstat && \ ! _lib_mntctl #if ! defined (MNTTYPE_IGNORE) # define MNTTYPE_IGNORE "ignore" #endif int di_get_disk_entries (di_data_t *di_data, int *diCount) { di_disk_info_t *diptr; FILE *f; int idx; struct mntent *mntEntry; char *devp; /* local ptr to dev entry */ di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; if (diopts->optval [DI_OPT_DEBUG] > 0) { printf ("# di_get_disk_entries: set/get/endmntent\n"); } /* if both are set not an ansi compiler... */ #if _args_setmntent == 1 if ( (f = setmntent (DI_MOUNT_FILE)) == (FILE *) NULL) { #else if ( (f = setmntent (DI_MOUNT_FILE, "r")) == (FILE *) NULL) { #endif fprintf (stderr, "Unable to open: %s errno %d\n", DI_MOUNT_FILE, errno); return -1; } while ( (mntEntry = getmntent (f)) != (struct mntent *) NULL) { idx = *diCount; ++*diCount; di_data->diskInfo = (di_disk_info_t *) di_realloc ( (char *) di_data->diskInfo, sizeof (di_disk_info_t) * (Size_t) (*diCount + 1)); if (di_data->diskInfo == (di_disk_info_t *) NULL) { fprintf (stderr, "malloc failed for diskInfo. errno %d\n", errno); return -1; } diptr = di_data->diskInfo + idx; di_initialize_disk_info (diptr, idx); stpecpy (diptr->strdata [DI_DISP_FILESYSTEM], diptr->strdata [DI_DISP_FILESYSTEM] + DI_FILESYSTEM_LEN, mntEntry->mnt_fsname); stpecpy (diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_MOUNTPT] + DI_MOUNTPT_LEN, mntEntry->mnt_dir); stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, mntEntry->mnt_type); if (strcmp (mntEntry->mnt_fsname, "none") == 0) { diptr->printFlag = DI_PRNT_IGNORE; if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("mnt: ignore: special 'none': %s\n", diptr->strdata [DI_DISP_MOUNTPT]); } } if (strcmp (mntEntry->mnt_type, MNTTYPE_IGNORE) == 0) { diptr->printFlag = DI_PRNT_IGNORE; if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("mnt: ignore: mntopt 'ignore': %s\n", diptr->strdata [DI_DISP_MOUNTPT]); } } if ( (devp = strstr (mntEntry->mnt_opts, "dev=")) != (char *) NULL) { if (devp != mntEntry->mnt_opts) { --devp; } *devp = 0; /* point to preceeding comma and cut off */ } if (chkMountOptions (mntEntry->mnt_opts, DI_MNTOPT_RO) != (char *) NULL) { diptr->isReadOnly = true; } stpecpy (diptr->strdata [DI_DISP_MOUNTOPT], diptr->strdata [DI_DISP_MOUNTOPT] + DI_MOUNTOPT_LEN, mntEntry->mnt_opts); if (diopts->optval [DI_OPT_DEBUG] > 1) { printf ("mnt:%s - %s : %s\n", diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_FILESYSTEM], diptr->strdata [DI_DISP_FSTYPE]); } } endmntent (f); return 0; } #endif /* _lib_getmntent && _lib_setmntent && _lib_endmntent */ /* QNX */ #if defined (__QNX__) /* * di_get_disk_entries * * QNX * * This is bloody slow. * It would be nice to have a way to short-circuit some of * the directory subtrees. * /proc/mount/dev is not processed...hopefully that won't affect much. * */ int di_get_disk_entries (di_data_t *di_data, int *diCount) { di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; if (diopts->optval [DI_OPT_DEBUG] > 0) { printf ("# di_get_disk_entries: QNX\n"); } return di_getQNXDiskEntries (di_data, "/proc/mount", diCount); } static int di_getQNXDiskEntries (di_data_t *di_data, char *ipath, int *diCount) { di_disk_info_t *diptr; int idx; char path [MAXPATHLEN]; char *p; char *pathend; int len; /* current length of path */ DIR *dirp; struct dirent *dent; int ret; int nodeid; int pid; int chid; int handle; int ftype; struct stat statinfo; int fd; char tfilesystem [DI_FILESYSTEM_LEN]; di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; if (strcmp (ipath, "/proc/mount/dev") == 0) { return 0; } p = path; pathend = path + MAXPATHLEN; p = stpecpy (p, pathend, ipath); len = (int) strlen (path); if (! (dirp = opendir (path))) { return 0; } while ( (dent = readdir (dirp))) { if (strcmp (dent->d_name, ".") == 0 || strcmp (dent->d_name, "..") == 0) { continue; } ret = sscanf (dent->d_name, "%d,%d,%d,%d,%d", &nodeid, &pid, &chid, &handle, &ftype); if (len + (int) strlen (dent->d_name) + 1 > MAXPATHLEN) { continue; } p = stpecpy (p, pathend, "/"); p = stpecpy (p, pathend, dent->d_name); if (diopts->optval [DI_OPT_DEBUG] > 4) { printf ("check: %s\n", path); } memset (&statinfo, 0, sizeof (statinfo)); if (stat (path, &statinfo) == -1) { continue; } if (ret != 5) { if (S_ISDIR (statinfo.st_mode)) { if (diopts->optval [DI_OPT_DEBUG] > 4) { printf ("into: %s\n", path); } di_getQNXDiskEntries (di_data, path, diCount); } continue; } if (ftype != _FTYPE_ANY) { continue; } *tfilesystem = '\0'; if (S_ISDIR (statinfo.st_mode) && ftype == _FTYPE_ANY) { if ( (fd = open (path, /* O_ACCMODE */ O_RDONLY | O_NOCTTY)) != -1) { devctl (fd, DCMD_FSYS_MOUNTED_ON, tfilesystem, DI_FILESYSTEM_LEN, 0); close (fd); if (*tfilesystem == '\0') { /* unfortunately, this cuts out /proc, /dev/sem, etc. */ /* but it also removes strange duplicate stuff */ continue; } } else { continue; } } else { continue; } idx = *diCount; ++*diCount; di_data->diskInfo = (di_disk_info_t *) di_realloc ( (char *) di_data->diskInfo, sizeof (di_disk_info_t) * (Size_t) (*diCount + 1)); if (di_data->diskInfo == (di_disk_info_t *) NULL) { fprintf (stderr, "malloc failed for diskInfo. errno %d\n", errno); return -1; } diptr = di_data->diskInfo + idx; di_initialize_disk_info (diptr, idx); path [len] = '\0'; stpecpy (diptr->strdata [DI_DISP_FILESYSTEM], diptr->strdata [DI_DISP_FILESYSTEM] + DI_FILESYSTEM_LEN, tfilesystem); stpecpy (diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_MOUNTPT] + DI_MOUNTPT_LEN, path + 11); if (*diptr->strdata [DI_DISP_MOUNTPT] == '\0') { stpecpy (diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_MOUNTPT] + DI_MOUNTPT_LEN, "/"); } if (diopts->optval [DI_OPT_DEBUG] > 4) { printf ("found: %s %s\n", diptr->strdata [DI_DISP_FILESYSTEM], diptr->strdata [DI_DISP_MOUNTPT]); } } closedir (dirp); return 0; } #endif /* QNX */ /* if nothing matches, assume a SysV.3 /etc/mnttab or similar */ #if ! _lib_getmntent && \ ! _lib_mntctl && \ ! _lib_getmntinfo && \ ! _lib_getfsstat && \ ! _lib_getvfsstat && \ ! _lib_getmnt && \ ! _lib_GetDriveType && \ ! _lib_GetLogicalDriveStrings && \ ! _lib_fs_stat_dev && \ ! defined (__QNX__) /* * di_get_disk_entries * * For SysV.3 we open the file and read it ourselves. * */ int di_get_disk_entries (di_data_t *di_data, int *diCount) { di_disk_info_t *diptr; FILE *f; int idx; struct mnttab mntEntry; di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; if (diopts->optval [DI_OPT_DEBUG] > 0) { printf ("# di_get_disk_entries: not anything; sys v.3\n"); } if ( (f = fopen (DI_MOUNT_FILE, "r")) == (FILE *) NULL) { fprintf (stderr, "Unable to open: %s errno %d\n", DI_MOUNT_FILE, errno); return -1; } while (fread ( (char *) &mntEntry, sizeof (struct mnttab), 1, f) == 1) { /* xenix allows null mount table entries */ /* sco nfs background mounts are marked as "nothing" */ if (mntEntry.mt_filsys [0] && strcmp (mntEntry.mt_filsys, "nothing") != 0) { idx = *diCount; ++*diCount; di_data->diskInfo = (di_disk_info_t *) di_realloc ( (char *) di_data->diskInfo, sizeof (di_disk_info_t) * (Size_t) (*diCount + 1)); if (di_data->diskInfo == (di_disk_info_t *) NULL) { fprintf (stderr, "malloc failed for diskInfo. errno %d\n", errno); return -1; } diptr = di_data->diskInfo + idx; di_initialize_disk_info (diptr, idx); # if defined (COHERENT) /* Coherent seems to have these fields reversed. oh well. */ stpecpy (diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_MOUNTPT] + DI_MOUNTPT_LEN, mntEntry.mt_dev); stpecpy (diptr->strdata [DI_DISP_FILESYSTEM], diptr->strdata [DI_DISP_FILESYSTEM] + DI_FILESYSTEM_LEN, mntEntry.mt_filsys); # else stpecpy (diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_MOUNTPT] + DI_MOUNTPT_LEN, mntEntry.mt_filsys); stpecpy (diptr->strdata [DI_DISP_FILESYSTEM], diptr->strdata [DI_DISP_FILESYSTEM] + DI_FILESYSTEM_LEN, mntEntry.mt_dev); # endif # if _mem_struct_mnttab_mntopts stpecpy (diptr->strdata [DI_DISP_MOUNTOPT], diptr->strdata [DI_DISP_MOUNTOPT] + DI_MOUNTOPT_LEN, mntEntry.mt_mntopts); # endif } if (diopts->optval [DI_OPT_DEBUG] > 1) { printf ("mnt:%s - %s\n", diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_FILESYSTEM]); } } fclose (f); return 0; } #endif /* Sys V.3 */ /* * All of the following routines also replace di_get_disk_info () */ #if _lib_getfsstat \ && ! (_lib_getvfsstat && _args_getvfsstat == 3) /* * di_get_disk_entries * * OSF/1 / Digital Unix / Compaq Tru64 / FreeBSD / NetBSD 2.x / OpenBSD * MacOS * */ # if _dcl_mnt_names # if ! defined (MNT_NUMTYPES) # define MNT_NUMTYPES (sizeof (mnt_names)/sizeof (char *)) # endif # endif int di_get_disk_entries (di_data_t *di_data, int *diCount) { di_disk_info_t *diptr; int count; int idx; # if _dcl_mnt_names && _mem_struct_statfs_f_type short fstype; # endif _c_arg_2_getfsstat bufsize; struct statfs *mntbufp; struct statfs *sp; di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; if (diopts->optval [DI_OPT_DEBUG] > 0) { printf ("# di_get_disk_entries: getfsstat\n"); } count = getfsstat ( (struct statfs *) NULL, (_c_arg_2_getfsstat) 0, MNT_NOWAIT); if (count < 1) { fprintf (stderr, "Unable to do getfsstat () errno %d\n", errno); return -1; } bufsize = (_c_arg_2_getfsstat) (sizeof (struct statfs) * (Size_t) count); mntbufp = (struct statfs *) malloc ( (Size_t) bufsize); if (mntbufp == (struct statfs *) NULL) { fprintf (stderr, "malloc failed for mntbufp. errno %d\n", errno); return -1; } memset ( (char *) mntbufp, '\0', sizeof (struct statfs) * (Size_t) count); count = getfsstat (mntbufp, bufsize, MNT_NOWAIT); *diCount = count; di_data->diskInfo = (di_disk_info_t *) malloc (sizeof (di_disk_info_t) * (Size_t) (count + 1)); if (di_data->diskInfo == (di_disk_info_t *) NULL) { fprintf (stderr, "malloc failed for diskInfo. errno %d\n", errno); return -1; } memset ((char *) di_data->diskInfo, '\0', sizeof (di_disk_info_t) * (Size_t) count); for (idx = 0; idx < count; idx++) { di_ui_t tblocksz = 0; diptr = di_data->diskInfo + idx; di_initialize_disk_info (diptr, idx); sp = mntbufp + idx; # if defined (MNT_RDONLY) if ( (sp->f_flags & MNT_RDONLY) == MNT_RDONLY) { diptr->isReadOnly = true; } # endif # if defined (MNT_LOCAL) if ( (sp->f_flags & MNT_LOCAL) != MNT_LOCAL) { diptr->isLocal = false; } # endif convertMountOptions ( (unsigned long) sp->f_flags, diptr); # if _mem_struct_statfs_f_type # if defined (MOUNT_NFS3) if (sp->f_type == MOUNT_NFS3) { strncat (diptr->strdata [DI_DISP_MOUNTOPT], "v3,", DI_MOUNTOPT_LEN - strlen (diptr->strdata [DI_DISP_MOUNTOPT]) - 1); } # endif # endif # if _mem_struct_statfs_mount_info \ && defined (MOUNT_NFS) \ && (_mem_struct_statfs_f_type || _mem_struct_statfs_f_fstypename) # if _mem_struct_statfs_f_type if (sp->f_type == MOUNT_NFS # endif # if _mem_struct_statfs_f_fstypename if (strcmp (sp->f_fstypename, MOUNT_NFS) == 0 # endif # if _mem_struct_statfs_f_fstypename && defined (MOUNT_NFS3) || strcmp (sp->f_fstypename, MOUNT_NFS3) == 0 # endif # if _mem_struct_statfs_f_type && defined (MOUNT_NFS3) || sp->f_type == MOUNT_NFS3 # endif ) { struct nfs_args *na; na = &sp->mount_info.nfs_args; convertNFSMountOptions (na->flags, na->wsize, na->rsize, diptr); } # endif di_trimchar (diptr->strdata [DI_DISP_MOUNTOPT], ','); stpecpy (diptr->strdata [DI_DISP_FILESYSTEM], diptr->strdata [DI_DISP_FILESYSTEM] + DI_FILESYSTEM_LEN, sp->f_mntfromname); stpecpy (diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_MOUNTPT] + DI_MOUNTPT_LEN, sp->f_mntonname); # if _mem_struct_statfs_f_fsize tblocksz = (di_ui_t) sp->f_fsize; # endif # if _mem_struct_statfs_f_bsize && ! _mem_struct_statfs_f_fsize tblocksz = (di_ui_t) sp->f_bsize; # endif # if ! _mem_struct_statfs_f_bsize && ! _mem_struct_statfs_f_fsize # error "struct statfs location failure" # endif di_save_block_sizes (diptr, tblocksz, (di_ui_t) sp->f_blocks, (di_ui_t) sp->f_bfree, (di_ui_t) sp->f_bavail); di_save_inode_sizes (diptr, (di_ui_t) sp->f_files, (di_ui_t) sp->f_ffree, (di_ui_t) sp->f_ffree); # if _mem_struct_statfs_f_fstypename stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, sp->f_fstypename); # else # if _lib_sysfs && _mem_struct_statfs_f_type sysfs (GETFSTYP, sp->f_type, diptr->strdata [DI_DISP_FSTYPE]); # else # if _dcl_mnt_names && _mem_struct_statfs_f_type # define DI_UNKNOWN_FSTYPE " (%.2d)?" fstype = sp->f_type; if ( (fstype >= 0) && (fstype < MNT_NUMTYPES)) { stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, mnt_names [fstype]); } else { Snprintf1 (diptr->strdata [DI_DISP_FSTYPE], DI_FSTYPE_LEN, DI_UNKNOWN_FSTYPE, fstype); } # endif # endif # endif } free ( (char *) mntbufp); return 0; } #endif /* _lib_getfsstat */ #if _lib_getmntinfo \ && ! _lib_getfsstat \ && ! _lib_getvfsstat /* * di_get_disk_entries * * Old OSF/1 system call. * OSF/1 does this with a system call and library routine. * [Jeffrey Mogul] * */ # if defined (INITMOUNTNAMES) && ! _dcl_mnt_names static char *mnt_names [] = INITMOUNTNAMES; # if ! defined (MNT_NUMTYPES) # define MNT_NUMTYPES (MOUNT_MAXTYPE + 1) # endif # endif int di_get_disk_entries (di_data_t *di_data, int *diCount) { di_disk_info_t *diptr; int count; int idx; short fstype; struct statfs *mntbufp; di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; if (diopts->optval [DI_OPT_DEBUG] > 0) { printf ("# di_get_disk_entries: getmntinfo\n"); } count = getmntinfo (&mntbufp, MNT_WAIT); if (count < 1) { fprintf (stderr, "Unable to do getmntinfo () errno %d\n", errno); return -1; } *diCount = count; di_data->diskInfo = (di_disk_info_t *) malloc (sizeof (di_disk_info_t) * (Size_t) (count + 1)); if (di_data->diskInfo == (di_disk_info_t *) NULL) { fprintf (stderr, "malloc failed for diskInfo. errno %d\n", errno); return -1; } memset ((char *) di_data->diskInfo, '\0', sizeof (di_disk_info_t) * (Size_t) count); if (diopts->optval [DI_OPT_DEBUG] > 1) { printf ("type_len %d name_len %d spec_name_len %d\n", DI_FSTYPE_LEN, DI_MOUNTPT_LEN, DI_FILESYSTEM_LEN); } for (idx = 0; idx < count; idx++) { di_ui_t tblocksz; diptr = di_data->diskInfo + idx; di_initialize_disk_info (diptr, idx); # if defined (MNT_LOCAL) if ( (mntbufp [idx].f_flags & MNT_LOCAL) != MNT_LOCAL) { diptr->isLocal = false; } # endif stpecpy (diptr->strdata [DI_DISP_FILESYSTEM], diptr->strdata [DI_DISP_FILESYSTEM] + DI_FILESYSTEM_LEN, mntbufp [idx].f_mntfromname); stpecpy (diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_MOUNTPT] + DI_MOUNTPT_LEN, mntbufp [idx].f_mntonname); tblocksz = 1024; # if _mem_struct_statfs_f_fsize /* OSF 1.x */ tblocksz = mntbufp [idx].f_fsize; # endif # if _mem_struct_statfs_f_bsize /* OSF 2.x */ tblocksz = mntbufp [idx].f_bsize; # endif di_save_block_sizes (diptr, tblocksz, (di_ui_t) mntbufp [idx].f_blocks, (di_ui_t) mntbufp [idx].f_bfree, (di_ui_t) mntbufp [idx].f_bavail); di_save_inode_sizes (diptr, (di_ui_t) mntbufp [idx].f_files, (di_ui_t) mntbufp [idx].f_ffree, (di_ui_t) mntbufp [idx].f_ffree); fstype = mntbufp [idx].f_type; # if ! _sys_fs_types && ! defined (INITMOUNTNAMES) \ && ! _mem_struct_statfs_f_fstypename if ( (fstype >= 0) && (fstype <= MOUNT_MAXTYPE)) { switch (fstype) { # if defined (MOUNT_NONE) case MOUNT_NONE: { /* No Filesystem */ stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, "none"); break; } # endif # if defined (MOUNT_UFS) case MOUNT_UFS: { /* UNIX "Fast" Filesystem */ stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, "ufs"); break; } # endif # if defined (MOUNT_NFS) case MOUNT_NFS: { /* Network Filesystem */ stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, "nfs"); break; } # endif # if defined (MOUNT_MFS) case MOUNT_MFS: { /* Memory Filesystem */ stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, "mfs"); break; } # endif # if defined (MOUNT_MSDOS) case MOUNT_MSDOS: { /* MSDOS Filesystem */ stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, "msdos"); break; } # endif # if defined (MOUNT_LFS) case MOUNT_LFS: { stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, "lfs"); break; } # endif # if defined (MOUNT_LOFS) case MOUNT_LOFS: { stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, "lofs"); break; } # endif # if defined (MOUNT_FDESC) case MOUNT_FDESC: { stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, "fdesc"); break; } # endif # if defined (MOUNT_PORTAL) case MOUNT_PORTAL: { stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, "portal"); break; } # endif # if defined (MOUNT_NULL) case MOUNT_NULL: { stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, "null"); break; } # endif # if defined (MOUNT_UMAP) case MOUNT_UMAP: { stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, "umap"); break; } # endif # if defined (MOUNT_KERNFS) case MOUNT_KERNFS: { stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, "kernfs"); break; } # endif # if defined (MOUNT_PROCFS) case MOUNT_PROCFS: { /* proc filesystem */ stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, "pfs"); break; } # endif # if defined (MOUNT_AFS) case MOUNT_AFS: { stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, "afs"); break; } # endif # if defined (MOUNT_ISOFS) case MOUNT_ISOFS: { /* iso9660 cdrom */ stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, "iso9660fs"); break; } # endif # if defined (MOUNT_ISO9660) && ! defined (MOUNT_CD9660) case MOUNT_ISO9660: { /* iso9660 cdrom */ stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, "iso9660"); break; } # endif # if defined (MOUNT_CD9660) case MOUNT_CD9660: { /* iso9660 cdrom */ stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, "cd9660"); break; } # endif # if defined (MOUNT_UNION) case MOUNT_UNION: { stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, "union"); break; } # endif } /* switch on mount type */ } # else # if _mem_struct_statfs_f_fstypename stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, mntbufp [idx].f_fstypename); # else # define DI_UNKNOWN_FSTYPE " (%.2d)?" /* could use getvfsbytype here... */ if ( (fstype >= 0) && (fstype < MNT_NUMTYPES)) { stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, mnt_names [fstype]); } else { Snprintf1 (diptr->strdata [DI_DISP_FSTYPE], DI_FSTYPE_LEN, DI_UNKNOWN_FSTYPE, fstype); } # endif # endif /* else has sys/fs_types.h */ diptr->isReadOnly = false; # if defined (MNT_RDONLY) if ( (mntbufp [idx].f_flags & MNT_RDONLY) == MNT_RDONLY) { diptr->isReadOnly = true; } # endif convertMountOptions ( (unsigned long) mntbufp [idx].f_flags, diptr); di_trimchar (diptr->strdata [DI_DISP_MOUNTOPT], ','); if (diopts->optval [DI_OPT_DEBUG] > 1) { printf ("%s: %s\n", diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_FSTYPE]); printf ("\tblocks: tot:%ld free:%ld avail:%ld\n", (long) mntbufp [idx].f_blocks, (long) mntbufp [idx].f_bfree, (long) mntbufp [idx].f_bavail); # if _mem_struct_statfs_f_fsize printf ("\tfsize:%ld \n", (long) mntbufp [idx].f_fsize); # endif # if _mem_struct_statfs_f_bsize printf ("\tbsize:%ld \n", (long) mntbufp [idx].f_bsize); # endif # if _mem_struct_statfs_f_iosize printf ("\tiosize:%ld \n", (long) mntbufp [idx].f_iosize); # endif printf ("\tinodes: tot:%ld free:%ld\n", (long) mntbufp [idx].f_files, (long) mntbufp [idx].f_ffree); } } free ( (char *) mntbufp); /* man page says this can't be freed. */ /* is it ok to try? */ return 0; } #endif /* _lib_getmntinfo */ #if _lib_getvfsstat && _args_getvfsstat == 3 /* * di_get_disk_entries * * NetBSD * */ int di_get_disk_entries (di_data_t *di_data, int *diCount) { di_disk_info_t *diptr; int count; int idx; Size_t bufsize; struct statvfs *mntbufp; struct statvfs *sp; di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; if (diopts->optval [DI_OPT_DEBUG] > 0) { printf ("# di_get_disk_entries: getvfsstat\n"); } count = getvfsstat ( (struct statvfs *) NULL, 0, ST_NOWAIT); if (count < 1) { fprintf (stderr, "Unable to do getvfsstat () errno %d\n", errno); return -1; } bufsize = sizeof (struct statvfs) * (Size_t) count; mntbufp = (struct statvfs *) malloc ( (Size_t) bufsize); if (mntbufp == (struct statvfs *) NULL) { fprintf (stderr, "malloc failed for mntbufp. errno %d\n", errno); return -1; } memset ( (char *) mntbufp, '\0', sizeof (struct statvfs) * (Size_t) count); count = getvfsstat (mntbufp, (Size_t) bufsize, ST_NOWAIT); *diCount = count; di_data->diskInfo = (di_disk_info_t *) malloc (sizeof (di_disk_info_t) * (Size_t) (count + 1)); if (di_data->diskInfo == (di_disk_info_t *) NULL) { fprintf (stderr, "malloc failed for diskInfo. errno %d\n", errno); return -1; } memset ((char *) di_data->diskInfo, '\0', sizeof (di_disk_info_t) * (Size_t) count); for (idx = 0; idx < count; idx++) { di_ui_t tblocksz; diptr = di_data->diskInfo + idx; di_initialize_disk_info (diptr, idx); sp = mntbufp + idx; # if defined (MNT_RDONLY) if ( (sp->f_flag & MNT_RDONLY) == MNT_RDONLY) { diptr->isReadOnly = true; } # endif # if defined (MNT_LOCAL) if ( (sp->f_flag & MNT_LOCAL) != MNT_LOCAL) { diptr->isLocal = false; } # endif convertMountOptions ( (unsigned long) sp->f_flag, diptr); di_trimchar (diptr->strdata [DI_DISP_MOUNTOPT], ','); if (sp->f_frsize == 0 && sp->f_bsize != 0) { tblocksz = sp->f_bsize; } else { tblocksz = sp->f_frsize; } di_save_block_sizes (diptr, tblocksz, (di_ui_t) sp->f_blocks, (di_ui_t) sp->f_bfree, (di_ui_t) sp->f_bavail); di_save_inode_sizes (diptr, (di_ui_t) sp->f_files, (di_ui_t) sp->f_ffree, (di_ui_t) sp->f_ffree); stpecpy (diptr->strdata [DI_DISP_FILESYSTEM], diptr->strdata [DI_DISP_FILESYSTEM] + DI_FILESYSTEM_LEN, sp->f_mntfromname); stpecpy (diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_MOUNTPT] + DI_MOUNTPT_LEN, sp->f_mntonname); stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, sp->f_fstypename); if (diopts->optval [DI_OPT_DEBUG] > 1) { printf ("%s: %s\n", diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_FSTYPE]); printf ("\tbsize:%ld frsize:%ld\n", (long) sp->f_bsize, (long) sp->f_frsize); printf ("\tblocks: tot:%lu free:%ld avail:%ld\n", (unsigned long) sp->f_blocks, (unsigned long) sp->f_bfree, (unsigned long) sp->f_bavail); printf ("\tinodes: tot:%lu free:%lu avail:%lu\n", (unsigned long) sp->f_files, (unsigned long) sp->f_ffree, (unsigned long) sp->f_favail); } } free ( (char *) mntbufp); return 0; } #endif /* _lib_getvfsstat */ #if _lib_getmnt # if _npt_getmnt int getmnt (int *, struct fs_data *, int, int, char *); # endif /* * di_get_disk_entries * * ULTRIX does this with a system call. The system call allows one * to retrieve the information in a series of calls, but coding that * looks a little tricky; I just allocate a huge buffer and do it in * one shot. * * [Jeffrey Mogul] */ int di_get_disk_entries (di_data_t *di_data, int *diCount) { di_disk_info_t *diptr; int count; int bufsize; int idx; short fstype; struct fs_data *fsdbuf; int start; int len; di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; if (diopts->optval [DI_OPT_DEBUG] > 0) { printf ("# di_get_disk_entries: getmnt\n"); } bufsize = NMOUNT * sizeof (struct fs_data); /* enough for max # mounts */ fsdbuf = (struct fs_data *) malloc ( (Size_t) bufsize); if (fsdbuf == (struct fs_data *) NULL) { fprintf (stderr, "malloc (%d) for getmnt () failed errno %d\n", bufsize, errno); return -1; } start = 0; count = getmnt (&start, fsdbuf, bufsize, STAT_MANY, 0); if (count < 1) { fprintf (stderr, "Unable to do getmnt () [= %d] errno %d\n", count, errno); free ( (char *) fsdbuf); return -1; } *diCount = count; di_data->diskInfo = (di_disk_info_t *) malloc (sizeof (di_disk_info_t) * (Size_t) (count + 1)); if (di_data->diskInfo == (di_disk_info_t *) NULL) { fprintf (stderr, "malloc failed for diskInfo. errno %d\n", errno); free ( (char *) fsdbuf); return -1; } memset ((char *) di_data->diskInfo, '\0', sizeof (di_disk_info_t) * count); for (idx = 0; idx < count; idx++) { diptr = di_data->diskInfo + idx; di_initialize_disk_info (diptr, idx); if ( (fsdbuf [idx].fd_req.flags & MNT_LOCAL) != MNT_LOCAL) { diptr->isLocal = false; } stpecpy (diptr->strdata [DI_DISP_FILESYSTEM], diptr->strdata [DI_DISP_FILESYSTEM] + DI_FILESYSTEM_LEN, fsdbuf [idx].fd_filesystem); stpecpy (diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_MOUNTPT] + DI_MOUNTPT_LEN, fsdbuf [idx].fd_path); /* ULTRIX keeps these fields in units of 1K byte */ di_save_block_sizes (diptr, 1024, (di_ui_t) fsdbuf [idx].fd_btot, (di_ui_t) fsdbuf [idx].fd_bfree, (di_ui_t) fsdbuf [idx].fd_bfreen); di_save_inode_sizes (diptr, (di_ui_t) fsdbuf [idx].fd_gtot, (di_ui_t) fsdbuf [idx].fd_gfree, (di_ui_t) fsdbuf [idx].fd_gfree); fstype = fsdbuf [idx].fd_fstype; if (fstype == GT_UNKWN) { diptr->printFlag = DI_PRNT_IGNORE; if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("mnt: ignore: disk type unknown: %s\n", diptr->strdata [DI_DISP_MOUNTPT]); } } else if ( (fstype > 0) && (fstype < GT_NUMTYPES)) { stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, gt_names [fstype]); } else { Snprintf1 (diptr->strdata [DI_DISP_FSTYPE], DI_FSTYPE_LEN, "Unknown fstyp %.2d", fstype); } if ( (fsdbuf [idx].fd_req.flags & MNT_RDONLY) == MNT_RDONLY) { diptr->isReadOnly = true; } else { diptr->isReadOnly = false; } convertMountOptions ( (unsigned long) fsdbuf [idx].fd_req.flags, diptr); di_trimchar (diptr->strdata [DI_DISP_MOUNTOPT], ','); if (diopts->optval [DI_OPT_DEBUG] > 1) { printf ("%s: %s\n", diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_FSTYPE]); printf ("\tblocks: tot:%ld free:%ld avail:%ld\n", fsdbuf [idx].fd_btot, fsdbuf [idx].fd_bfree, (int) fsdbuf [idx].fd_bfreen); printf ("\tinodes: tot:%ld free:%ld\n", fsdbuf [idx].fd_gtot, fsdbuf [idx].fd_gfree); } } free ( (char *) fsdbuf); return 0; } #endif /* _lib_getmnt */ #if _lib_mntctl /* * di_get_disk_entries * * AIX uses mntctl to find out about mounted file systems * This seems to be better than set/get/end, as we get the * remote filesystem flag. * */ # define DI_FSMAGIC 10 /* base AIX configuration has 5 file systems */ # define NUM_AIX_FSTYPES 6 static char *AIX_fstype [NUM_AIX_FSTYPES] = { "oaix", "", "nfs", "jfs", "", "cdrom" }; /* * from xfsm-1.80: * * MNT_AIX - "aix" * MNT_NFS - "nfs" * MNT_JFS - "jfs" * MNT_CDROM - "cdrom" * other - "user defined" * */ #define DI_RETRY_COUNT 5 int di_get_disk_entries (di_data_t *di_data, int *diCount) { di_disk_info_t *diptr = NULL; int num; /* number of vmount structs returned */ char *vmbuf; /* buffer for vmount structs returned */ Size_t vmbufsz; /* size in bytes of vmbuf */ int i; /* index for looping and stuff */ char *bufp; /* pointer into vmbuf */ struct vmount *vmtp; /* pointer into vmbuf */ struct vfs_ent *ve; /* pointer for file system type entry */ di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; if (diopts->optval [DI_OPT_DEBUG] > 0) { printf ("# di_get_disk_entries: mntctl\n"); } i = 0; vmbufsz = sizeof (struct vmount) * DI_FSMAGIC; /* initial vmount buffer */ do { if ( (vmbuf = (char *) malloc (vmbufsz)) == (char *) NULL) { fprintf (stderr, "malloc (%d) for mntctl () failed errno %d\n", (int) vmbufsz, errno); return -1; } num = mntctl (MCTL_QUERY, vmbufsz, vmbuf); /* * vmbuf is too small, could happen for * following reasons: * - inital buffer is too small * - newly mounted file system */ if (num == 0) { memcpy (&vmbufsz, vmbuf, sizeof (vmbufsz)); /* see mntctl (2) */ if (diopts->optval [DI_OPT_DEBUG] > 0) { printf ("vmbufsz too small, new size: %d\n", (int) vmbufsz); } free ( (char *) vmbuf); /* free this last, it's still being used! */ ++i; } } while (num == 0 && i < DI_RETRY_COUNT); if (i >= DI_RETRY_COUNT) { free ( (char *) vmbuf); fprintf (stderr, "unable to allocate adequate buffer for mntctl\n"); return -1; } if (num == -1) { free ( (char *) vmbuf); fprintf (stderr, "%s errno %d\n", strerror (errno), errno); return -1; } /* vmount structs returned in vmbuf */ *diCount = num; di_data->diskInfo = (di_disk_info_t *) malloc (sizeof (di_disk_info_t) * (Size_t) (*diCount + 1)); if (di_data->diskInfo == (di_disk_info_t *) NULL) { fprintf (stderr, "malloc failed for diskInfo. %s errno %d\n", strerror (errno), errno); return -1; } bufp = vmbuf; for (i = 0; i < num; i++) { char *p; char *end; diptr = di_data->diskInfo + i; di_initialize_disk_info (diptr, i); p = diptr->strdata [DI_DISP_FILESYSTEM]; end = diptr->strdata [DI_DISP_FILESYSTEM] + DI_FILESYSTEM_LEN; vmtp = (struct vmount *) bufp; if ( (vmtp->vmt_flags & MNT_REMOTE) == MNT_REMOTE) { diptr->isLocal = false; } if ( (vmtp->vmt_flags & MNT_RDONLY) == MNT_RDONLY) { diptr->isReadOnly = true; } *diptr->strdata [DI_DISP_FILESYSTEM] = '\0'; if (diptr->isLocal == false) { p = stpecpy (p, end, (char *) vmt2dataptr (vmtp, VMT_HOSTNAME)); p = stpecpy (p, end, ":"); } p = stpecpy (p, end, (char *) vmt2dataptr (vmtp, VMT_OBJECT)); stpecpy (diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_MOUNTPT] + DI_MOUNTPT_LEN, (char *) vmt2dataptr (vmtp, VMT_STUB)); ve = getvfsbytype (vmtp->vmt_gfstype); if (ve == (struct vfs_ent *) NULL || *ve->vfsent_name == '\0') { if (vmtp->vmt_gfstype >= 0 && (vmtp->vmt_gfstype < NUM_AIX_FSTYPES)) { stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, AIX_fstype [vmtp->vmt_gfstype]); } } else { stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, ve->vfsent_name); } stpecpy (diptr->strdata [DI_DISP_MOUNTOPT], diptr->strdata [DI_DISP_MOUNTOPT] + DI_MOUNTOPT_LEN, vmt2dataptr (vmtp, VMT_ARGS)); di_trimchar (diptr->strdata [DI_DISP_MOUNTOPT], ','); bufp += vmtp->vmt_length; if (diopts->optval [DI_OPT_DEBUG] > 1) { printf ("mnt:%s - %s : %s\n", diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_FILESYSTEM], diptr->strdata [DI_DISP_FSTYPE]); printf ("\t%s\n", (char *) vmt2dataptr (vmtp, VMT_ARGS)); } } return 0; } #endif /* _lib_mntctl */ #if ! _lib_getmntent && \ _lib_GetDriveType && \ _lib_GetLogicalDriveStrings /* windows */ # define MSDOS_BUFFER_SIZE 256 # define BYTES_PER_LOGICAL_DRIVE 4 int di_get_disk_entries (di_data_t *di_data, int *diCount) { di_disk_info_t *diptr; int i; char diskflag; int rc; char *p; char buff [MSDOS_BUFFER_SIZE]; di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; if (diopts->optval [DI_OPT_DEBUG] > 0) { printf ("# di_get_disk_info: GetLogicalDriveStrings GetDriveType\n"); } diskflag = DI_PRNT_SKIP; rc = (int) GetLogicalDriveStrings (MSDOS_BUFFER_SIZE, buff); *diCount = rc / BYTES_PER_LOGICAL_DRIVE; di_data->diskInfo = (di_disk_info_t *) malloc (sizeof (di_disk_info_t) * (Size_t) (*diCount + 1)); if (di_data->diskInfo == (di_disk_info_t *) NULL) { fprintf (stderr, "malloc failed for diskInfo. errno %d\n", errno); return -1; } for (i = 0; i < *diCount; ++i) { diptr = di_data->diskInfo + i; di_initialize_disk_info (diptr, i); p = buff + (BYTES_PER_LOGICAL_DRIVE * i); stpecpy (diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_MOUNTPT] + DI_MOUNTPT_LEN, p); rc = (int) GetDriveType (p); diptr->printFlag = DI_PRNT_OK; if (rc == DRIVE_NO_ROOT_DIR) { diptr->printFlag = DI_PRNT_BAD; } else if (rc == DRIVE_REMOVABLE) { char *hnp; char *hnend; /* assume that any removable drives before the */ /* first non-removable disk are floppies... */ DWORD br; BOOL bSuccess; char handleName [MSDOS_BUFFER_SIZE]; diptr->printFlag = diskflag; bSuccess = 1; hnp = handleName; hnend = handleName + MSDOS_BUFFER_SIZE; hnp = stpecpy (hnp, hnend, "\\\\.\\"); hnp = stpecpy (hnp, hnend, p); { # if _define_IOCTL_STORAGE_CHECK_VERIFY2 HANDLE hDevice = CreateFile (handleName, FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); bSuccess = DeviceIoControl (hDevice, IOCTL_STORAGE_CHECK_VERIFY2, NULL, 0, NULL, 0, &br, (LPOVERLAPPED) NULL); # else HANDLE hDevice = CreateFile (handleName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); bSuccess = DeviceIoControl (hDevice, IOCTL_STORAGE_CHECK_VERIFY, NULL, 0, NULL, 0, &br, (LPOVERLAPPED) NULL); # endif CloseHandle (hDevice); } if (! bSuccess) { diptr->printFlag = DI_PRNT_BAD; } } else { diskflag = DI_PRNT_OK; } if (rc != DRIVE_REMOTE) { diptr->isLocal = true; } } /* for each mounted drive */ return *diCount; } #endif /* _lib_GetDiskFreeSpace || _lib_GetDiskFreeSpaceEx */ #if _lib_fs_stat_dev && _lib_next_dev /* beos, haiku */ int di_get_disk_entries (di_data_t *di_data, int *diCount) { di_disk_info_t *diptr; status_t stat; int idx; int32 count; dev_t dev; char buff [B_FILE_NAME_LENGTH]; fs_info fsinfo; node_ref nref; BDirectory *dir; BEntry entry; BPath path; di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; if (diopts->optval [DI_OPT_DEBUG] > 0) { printf ("# di_get_disk_entries: fs_stat_dev\n"); } count = 0; while ( (dev = next_dev (&count)) != B_BAD_VALUE) { if ( (stat = fs_stat_dev (dev, &fsinfo)) == B_BAD_VALUE) { break; } idx = *diCount; ++*diCount; di_data->diskInfo = (di_disk_info_t *) di_realloc ( (char *) di_data->diskInfo, sizeof (di_disk_info_t) * (*diCount + 1)); if (di_data->diskInfo == (di_disk_info_t *) NULL) { fprintf (stderr, "malloc failed for diskInfo. errno %d\n", errno); return -1; } diptr = di_data->diskInfo + idx; di_initialize_disk_info (diptr, idx); *buff = '\0'; nref.device = dev; nref.node = fsinfo.root; dir = new BDirectory (&nref); stat = dir->GetEntry (&entry); stat = entry.GetPath (&path); stpecpy (diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_MOUNTPT] + DI_MOUNTPT_LEN, path.Path ()); stpecpy (diptr->strdata [DI_DISP_FILESYSTEM], diptr->strdata [DI_DISP_FILESYSTEM] + DI_FILESYSTEM_LEN, fsinfo.device_name); stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, fsinfo.fsh_name); di_save_block_sizes (diptr, (di_ui_t) fsinfo.block_size, (di_ui_t) fsinfo.total_blocks, (di_ui_t) fsinfo.free_blocks, (di_ui_t) fsinfo.free_blocks); di_save_inode_sizes (diptr, (di_ui_t) fsinfo.total_nodes, (di_ui_t) fsinfo.free_nodes, (di_ui_t) fsinfo.free_nodes); # if defined (MNT_RDONLY) if ( (fsinfo.flags & MNT_RDONLY) == MNT_RDONLY) { diptr->isReadOnly = true; } # endif # if defined (MNT_PERSISTENT) if ( (fsinfo.flags & MNT_PERSISTENT) != MNT_PERSISTENT) { diptr->printFlag = DI_PRNT_IGNORE; } # endif convertMountOptions ( (unsigned long) fsinfo.flags, diptr); di_trimchar (diptr->strdata [DI_DISP_MOUNTOPT], ','); if (diopts->optval [DI_OPT_DEBUG] > 1) { printf ("mnt:%s - %s\n", diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_FILESYSTEM]); printf ("dev:%d fs:%s\n", dev, diptr->strdata [DI_DISP_FSTYPE]); printf ("%s: %s\n", diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_FSTYPE]); printf ("\tblocks: tot:%ld free:%ld\n", fsinfo.total_blocks, fsinfo.free_blocks); printf ("\tinodes: tot:%ld free:%ld\n", fsinfo.total_nodes, fsinfo.free_nodes); } } return 0; } #endif di-6.0.0/di.h0000644000175000017500000001210714763621244010774 0ustar bllbll/* * Copyright 2016-2018 Brad Lanam Walnut Creek CA USA * Copyright 2023-2025 Brad Lanam, Pleasant Hill, CA */ #ifndef INC_DI_H #define INC_DI_H # if defined (__cplusplus) || defined (c_plusplus) extern "C" { # endif /* scaled values */ #define DI_SCALE_BYTE 0 #define DI_SCALE_KILO 1 #define DI_SCALE_MEGA 2 #define DI_SCALE_GIGA 3 #define DI_SCALE_TERA 4 #define DI_SCALE_PETA 5 #define DI_SCALE_EXA 6 #define DI_SCALE_ZETTA 7 #define DI_SCALE_YOTTA 8 #define DI_SCALE_RONNA 9 #define DI_SCALE_QUETTA 10 #define DI_SCALE_MAX 11 /* human readable */ #define DI_SCALE_HR -20 #define DI_SCALE_HR_ALT -21 /* print flags */ #define DI_PRNT_IGNORE 0 #define DI_PRNT_OK 1 #define DI_PRNT_BAD 2 #define DI_PRNT_OUTOFZONE 3 #define DI_PRNT_EXCLUDE 4 #define DI_PRNT_FORCE 5 #define DI_PRNT_SKIP 6 /* string identifiers */ #define DI_DISP_MOUNTPT 0 #define DI_DISP_FILESYSTEM 1 #define DI_DISP_FSTYPE 2 #define DI_DISP_MOUNTOPT 3 #define DI_DISP_MAX 4 /* value identifiers */ #define DI_SPACE_TOTAL 0 #define DI_SPACE_FREE 1 #define DI_SPACE_AVAIL 2 #define DI_INODE_TOTAL 3 #define DI_INODE_FREE 4 #define DI_INODE_AVAIL 5 #define DI_VALUE_MAX 6 #define DI_VALUE_NONE -1 /* options return values */ #define DI_EXIT_NORM 0 #define DI_EXIT_HELP 1 #define DI_EXIT_VERS 2 #define DI_EXIT_WARN 3 #define DI_EXIT_FAIL 4 /* iterator options */ /* these match the true/false value of the DI_OPT_DISP_ALL value */ #define DI_ITER_PRINTABLE 0 #define DI_ITER_ALL 1 /* di options */ #define DI_OPT_POSIX_COMPAT 0 #define DI_OPT_QUOTA_CHECK 1 #define DI_OPT_DISP_CSV 2 #define DI_OPT_DISP_CSV_TAB 3 #define DI_OPT_EXCL_LOOPBACK 4 #define DI_OPT_DISP_JSON 5 #define DI_OPT_DISP_TOTALS 6 #define DI_OPT_DISP_HEADER 7 #define DI_OPT_DISP_ALL 8 #define DI_OPT_LOCAL_ONLY 9 #define DI_OPT_NO_SYMLINK 10 #define DI_OPT_DEBUG 11 #define DI_OPT_MAX 12 #define DI_OPT_FMT_STR_LEN 13 #define DI_OPT_SCALE 14 #define DI_OPT_BLOCK_SZ 15 #define DI_FMT_ITER_STOP -1 /* format string characters */ /* strings */ #define DI_FMT_MOUNT 'm' #define DI_FMT_FILESYSTEM 's' #define DI_FMT_FSTYPE 't' #define DI_FMT_MOUNT_OPTIONS 'O' /* these will be processed (forever probably), but are no longer used */ #define DI_FMT_MOUNT_FULL 'M' #define DI_FMT_FILESYSTEM_FULL 'S' #define DI_FMT_FSTYPE_FULL 'T' /* space */ #define DI_FMT_BTOT 'b' #define DI_FMT_BTOT_AVAIL 'B' #define DI_FMT_BUSED 'u' #define DI_FMT_BCUSED 'c' #define DI_FMT_BFREE 'f' #define DI_FMT_BAVAIL 'v' /* percentages */ #define DI_FMT_BPERC_NAVAIL 'p' #define DI_FMT_BPERC_USED '1' #define DI_FMT_BPERC_BSD '2' #define DI_FMT_BPERC_AVAIL 'a' #define DI_FMT_BPERC_FREE '3' /* inodes */ #define DI_FMT_ITOT 'i' #define DI_FMT_IUSED 'U' #define DI_FMT_IFREE 'F' #define DI_FMT_IPERC 'P' #define DI_FMT_MAX 19 typedef struct { const char *strdata [DI_DISP_MAX]; /* mount point */ /* special device name */ /* type of file system */ /* mount options */ int index; /* the index for this entry */ int doPrint; /* should this entry */ /* be printed? */ int printFlag; /* print flags */ int isLocal; /* is this mount point */ /* local? */ int isReadOnly; /* is this mount point */ /* read-only? */ int isLoopback; /* lofs or none fs type? */ } di_pub_disk_info_t; /* dilib.c */ extern void * di_initialize (void); extern void di_cleanup (void *di_data); extern int di_process_options (void *di_data, int argc, const char * argv[], int offset); extern const char * di_version (void); extern int di_check_option (void *di_data, int optidx); extern void di_format_iter_init (void *di_data); extern int di_format_iterate (void *di_data); extern int di_get_all_disk_info (void *di_data); extern int di_iterate_init (void *di_data, int itertype); extern const di_pub_disk_info_t *di_iterate (void *di_data); extern int di_get_scale_max (void *, int, int, int, int); extern double di_get_scaled (void *, int, int, int, int, int); extern void di_disp_scaled (void *, char *, long, int, int, int, int, int); extern double di_get_perc (void *, int, int, int, int, int, int); extern void di_disp_perc (void *, char *, long, int, int, int, int, int, int); # if defined (__cplusplus) || defined (c_plusplus) } # endif #endif /* INC_DI_H */ di-6.0.0/distrutils.c0000644000175000017500000000423514761605634012607 0ustar bllbll/* * Copyright 1994-2018 Brad Lanam, Walnut Creek, CA * Copyright 2023-2025 Brad Lanam, Pleasant Hill, CA */ #include "config.h" #if _hdr_stdio # include #endif # if _hdr_stdlib # include # endif # if _hdr_memory # include # endif # if _hdr_malloc # include # endif # if _hdr_string # include # endif # if _hdr_strings # include # endif #include "distrutils.h" /* * * portable realloc * some very old variants don't accept a null pointer for initial allocation. * */ void * di_realloc (void * ptr, Size_t size) { if (ptr == (void *) NULL) { ptr = (void *) malloc (size); } else { ptr = (void *) realloc (ptr, size); } return ptr; } void di_trimchar (char *str, int ch) { int len; len = (int) strlen (str); if (len > 0) { --len; } if (len >= 0) { if (str [len] == ch) { str [len] = '\0'; } } } char * di_strtok (char *str, const char *delim, char **tokstr) { char *ptr = NULL; #if _lib_strtok_r ptr = strtok_r (str, delim, tokstr); #else ptr = strtok_r (str, delim); #endif return ptr; } #if ! _lib_stpecpy /* the following code is in the public domain */ /* modified from the linux stpecpy manual page */ char * stpecpy (char *dst, char *end, const char *src) { char *p; if (dst == end) { return end; } p = (char *) memccpy (dst, src, '\0', (Size_t) (end - dst)); if (p != NULL) { return p - 1; } /* truncation detected */ end [-1] = '\0'; return end; } #endif /* ! _lib_stpecpy */ #if ! _lib_strdup char * strdup (const char *ptr) { Size_t len; char *nptr; if (ptr == NULL) { return NULL; } len = strlen (ptr); nptr = (char *) malloc (len + 1); stpecpy (nptr, nptr + len + 1, ptr); return nptr; } #endif /* ! _lib_strdup */ #if ! _lib_strstr char * strstr (const char *buff, const char *srch) { Size_t len; char * p; p = buff; if (srch == NULL) { return p; } len = strlen (srch); for (; (p = strchr (p, *srch)) != NULL; p++) { if (strncmp (p, srch, len) == 0) { return (p); } } return (char *) NULL; } #endif /* ! _lib_strstr */ di-6.0.0/diquota.c0000644000175000017500000007162014752156025012044 0ustar bllbll/* * Copyright 2011-2018 Brad Lanam, Walnut Creek, CA * Copyright 2023-2025 Brad Lanam, Pleasant Hill, CA */ #include "config.h" #if _hdr_stdio # include #endif #if _hdr_stddef # include #endif #if _hdr_stdlib # include #endif #if _hdr_stdbool # include #endif #if _hdr_unistd # include #endif #if _sys_param # include #endif #if _hdr_string # include #endif #if _hdr_strings # include #endif #if _sys_types \ && ! defined (DI_INC_SYS_TYPES_H) /* xenix */ # define DI_INC_SYS_TYPES_H # include #endif #if _hdr_errno # include #endif #if _hdr_time # include #endif #if _sys_time && _inc_conflict__hdr_time__sys_time # include #endif #if _hdr_libprop_proplib /* dragonflybsd */ # include #endif #if _hdr_quota # include #endif #if _sys_quota /* netbsd */ # include #endif #if _sys_fs_ufs_quota # include #endif #if _sys_vfs_quota /* dragonflybsd */ # include #endif #if _hdr_ufs_quota # include #endif #if _hdr_ufs_ufs_quota # include #endif #if _hdr_linux_dqblk_xfs # include #endif #if _hdr_jfs_quota # include #endif // ### FIX /* AIX 5.1 doesn't seem to have quotactl declared.... */ /* use their compatibility routine. */ #if ! _args_quotactl && _hdr_linux_quota \ && _inc_conflict__sys_quota__hdr_linux_quota # include #endif #if _hdr_rpc_rpc /* tirpc is a separate library, but defines reserved symbols */ # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wunknown-warning-option" # pragma clang diagnostic ignored "-Wreserved-identifier" # include # pragma clang diagnostic pop #endif #if _hdr_rpc_auth # include #endif #if _hdr_rpcsvc_rquota # include #endif #include "di.h" #include "disystem.h" #include "dimath.h" #include "diquota.h" #include "diinternal.h" #include "distrutils.h" #include "dioptions.h" #if _has_std_quotas /* workaround for HPUX - quotactl not declared */ # if _lib_quotactl && _npt_quotactl # if defined (__cplusplus) || defined (c_plusplus) extern "C" { # endif extern int quotactl (int, const char *, uid_t, void *); # if defined (__cplusplus) || defined (c_plusplus) } # endif # endif typedef union { int val; # if _typ_struct_dqblk struct dqblk qinfo; # endif # if _typ_struct_ufs_dqblk struct ufs_dqblk qinfo; # endif # if _typ_fs_disk_quota_t fs_disk_quota_t xfsqinfo; # endif # if _typ_struct_quotaval struct qval { struct quotaval qbval; struct quotaval qival; } qval; # endif # if _lib_vquotactl struct vqval { struct vqvalentry { dinum_t usage; dinum_t limit; } uvqval; struct vqvalentry gvqval; struct vqvalentry *vqvalptr; } vqval; # endif } qdata_t; static void di_process_quotas (di_data_t *di_data, const char *, di_quota_t *, int, int, qdata_t *); #endif #if _has_std_quotas && _lib_vquotactl static void vq_updUsage (struct vqvalentry *, dinum_t); static void vq_updLimit (struct vqvalentry *, dinum_t); static int vquotactl_send (char *, char *, prop_dictionary_t, prop_dictionary_t *); static int vquotactl_get (di_quota_t *, struct vqval *); #endif #if _has_std_quotas && _lib_quota_open static int quota_open_get (struct quotahandle *, int, Uid_t, struct qval *); #endif #if _has_std_quotas && ! _lib_quota_open && ! _lib_vquotactl static int quotactl_get (di_data_t *di_data, di_quota_t *, int, Uid_t, qdata_t *); #endif #if _has_std_nfs_quotas && ! _lib_quota_open static bool_t xdr_quota_get (XDR *, struct getquota_args *); static bool_t xdr_quota_rslt (XDR *, struct getquota_rslt *); static void diquota_nfs (di_data_t *, di_quota_t *); #endif #ifdef BLOCK_SIZE /* linux */ # define DI_QUOT_BLOCK_SIZE BLOCK_SIZE #else # ifdef DQBSIZE /* AIX */ # define DI_QUOT_BLOCK_SIZE DQBSIZE # else # ifdef DEV_BSIZE /* tru64, et. al. */ # define DI_QUOT_BLOCK_SIZE DEV_BSIZE # else # define DI_QUOT_BLOCK_SIZE 512 # endif # endif #endif /* rename certain structure members for portability */ /* it make the code below cleaner, but it's a bit more */ /* difficult to read it */ #if _mem_struct_dqblk_dqb_fsoftlimit # define dqb_isoftlimit dqb_fsoftlimit #endif #if _mem_struct_dqblk_dqb_fhardlimit # define dqb_ihardlimit dqb_fhardlimit #endif #if _mem_struct_dqblk_dqb_curfiles # define dqb_curinodes dqb_curfiles #endif /* dragonflybsd has a rather complicated method of getting */ /* the quota data. */ /* Since all results are returned, make sure to only iterate */ /* once. Much of this code is straight from vquota.c. */ #if _lib_vquotactl static void vq_updUsage (struct vqvalentry *entry, dinum_t usage) { if (usage > entry->usage) { entry->usage = usage; } } static void vq_updLimit (struct vqvalentry *entry, dinum_t limit) { if (entry->values [DI_QUOTA_LIMIT] == 0 || limit < entry->values [DI_QUOTA_LIMIT]) { entry->values [DI_QUOTA_LIMIT] = limit; } } static int vquotactl_send (char *spec, char *cmd, prop_dictionary_t args, prop_dictionary_t *res) { prop_dictionary_t dict; struct plistref pref; int rv; int error; dict = prop_dictionary_create (); if (dict == NULL) { return false; } rv = prop_dictionary_set_cstring (dict, "command", cmd); if (! rv) { prop_object_release (dict); return false; } rv = prop_dictionary_set (dict, "arguments", args); if (! rv) { prop_object_release (dict); return false; } error = prop_dictionary_send_syscall (dict, &pref); if (error != 0) { prop_object_release (dict); return false; } error = vquotactl (spec, &pref); if (error != 0) { prop_object_release (dict); return false; } error = prop_dictionary_recv_syscall (&pref, res); if (error != 0) { prop_object_release (dict); return false; } prop_object_release (dict); return true; } static int vquotactl_get (di_quota_t *diqinfo, struct vqval *vqval) { prop_dictionary_t args; prop_dictionary_t res; prop_array_t reslist; prop_object_iterator_t iter; prop_dictionary_t item; int rv; int urv; int grv; Uid_t tuid; Uid_t tgid; dinum_t space; dinum_t limit; args = prop_dictionary_create (); if (args == NULL) { return errno; } res = prop_dictionary_create (); if (res == NULL) { return errno; } rv = vquotactl_send (diqinfo->mountpt, "get usage all", args, &res); if (! rv) { prop_object_release (args); prop_object_release (res); return -4; } reslist = prop_dictionary_get (res, "returned data"); if (reslist == NULL) { prop_object_release (args); prop_object_release (res); return errno; } iter = prop_array_iterator (reslist); if (iter == NULL) { prop_object_release (args); prop_object_release (res); return errno; } vqval->uvqval.usage = 0; vqval->uvqval.values [DI_QUOTA_LIMIT] = 0; vqval->gvqval.usage = 0; vqval->gvqval.values [DI_QUOTA_LIMIT] = 0; while ( (item = prop_object_iterator_next (iter)) != NULL) { rv = prop_dictionary_get_uint64 (item, "limit", &limit); if (rv && limit != 0) { rv = prop_dictionary_get_uint64 (item, "space used", &space); urv = prop_dictionary_get_uint32 (item, "uid", &tuid); grv = prop_dictionary_get_uint32 (item, "gid", &tgid); if (urv && tuid == diqinfo->uid) { vq_updUsage (& (vqval->uvqval), space); vq_updLimit (& (vqval->uvqval), limit); } else if (grv && tgid == diqinfo->gid) { vq_updUsage (& (vqval->gvqval), space); vq_updLimit (& (vqval->gvqval), limit); } else if (! urv && ! grv) { vq_updUsage (& (vqval->uvqval), space); vq_updLimit (& (vqval->uvqval), limit); vq_updUsage (& (vqval->gvqval), space); vq_updLimit (& (vqval->gvqval), limit); } } } prop_object_iterator_release (iter); prop_object_release (args); prop_object_release (res); return 0; } #endif /* _lib_vquotactl */ #if _lib_quota_open static int quota_open_get (struct quotahandle *qh, int idtype, Uid_t id, struct qval *qval) { struct quotakey qkey; int rc; rc = -3; if (qh != (struct quotahandle *) NULL) { memset (&qkey, 0, sizeof (struct quotakey)); qkey.qk_idtype = idtype; qkey.qk_id = (id_t) id; qkey.qk_objtype = QUOTA_OBJTYPE_BLOCKS; rc = quota_get (qh, &qkey, & (qval->qbval)); if (rc == 0) { qkey.qk_objtype = QUOTA_OBJTYPE_FILES; rc = quota_get (qh, &qkey, & (qval->qival)); } } return rc; } #endif #if _has_std_quotas && ! _lib_quota_open && ! _lib_vquotactl static int quotactl_get (di_data_t *di_data, di_quota_t *diqinfo, int cmd, Uid_t id, qdata_t *qdata) { int rc; di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; rc = -4; # if defined (__FreeBSD__) && __FreeBSD__ == 5 /* quotactl on devfs fs panics the system (FreeBSD 5.1) */ if (strcmp (diqinfo->fstype, "ufs") != 0) { return -4; } # endif if (diopts->optval [DI_OPT_DEBUG] > 5) { printf ("quota: quotactl on %s (%d %d)\n", diqinfo->mountpt, _quotactl_pos_1, _quotactl_pos_2); } /* AIX 7 has quotactl position 1 */ # if _lib_quotactl && _quotactl_pos_1 rc = quotactl (diqinfo->mountpt, cmd, (int) id, (caddr_t) & (qdata->qinfo)); # endif # if _lib_quotactl && ! _quotactl_pos_1 && (_quotactl_pos_2 || defined (_AIX)) # if defined (_AIX) /* AIX has linux compatibility routine, */ /* but needs mount-pt rather than dev-name */ rc = quotactl (cmd, diqinfo->mountpt, (int) id, (caddr_t) & (qdata->qinfo)); # else rc = quotactl (cmd, (_c_arg_2_quotactl) diqinfo->filesystem, (int) id, (caddr_t) & (qdata->qinfo)); # endif # endif # if _has_std_quotas && _sys_fs_ufs_quota && ! _lib_vquotactl /* Solaris */ { int fd; struct quotctl qop; char tname [DI_MOUNTPT_LEN]; char *p; qop.op = Q_GETQUOTA; qop.uid = id; qop.addr = (caddr_t) & (qdata->qinfo); p = stpecpy (tname, tname + DI_MOUNTPT_LEN, diqinfo->mountpt); stpecpy (p, tname + DI_MOUNTPT_LEN, "/quotas"); fd = open (tname, O_RDONLY | O_NOCTTY); if (fd >= 0) { rc = ioctl (fd, Q_QUOTACTL, &qop); close (fd); } else { rc = fd; } } # endif /* _sys_fs_ufs_quota */ return rc; } #endif /* ! _lib_quota_open */ void diquota (di_data_t *di_data, di_quota_t *diqinfo) { int rc; int xfsflag; #if _has_std_quotas qdata_t qdata; #endif #if _lib_quota_open struct quotahandle *qh; #endif #if _has_std_quotas && ! _lib_quota_open && ! _lib_vquotactl int ucmd = 0; int gcmd = 0; #endif di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; rc = -1; xfsflag = false; dinum_set_u (&diqinfo->values [DI_QUOTA_LIMIT], (di_ui_t) 0); dinum_set_u (&diqinfo->values [DI_QUOTA_USED], (di_ui_t) 0); dinum_set_u (&diqinfo->values [DI_QUOTA_ILIMIT], (di_ui_t) 0); dinum_set_u (&diqinfo->values [DI_QUOTA_IUSED], (di_ui_t) 0); #if _lib_vquotactl rc = vquotactl_get (diqinfo, &qdata.vqval); qdata.vqval.vqvalptr = &qdata.vqval.uvqval; #endif #if _lib_quota_open qh = quota_open (diqinfo->mountpt); rc = quota_open_get (qh, QUOTA_IDTYPE_USER, diqinfo->uid, &qdata.qval); #endif #if ! _lib_quota_open if (strncmp (diqinfo->fstype, "nfs", (Size_t) 3) == 0 && strcmp (diqinfo->fstype, "nfsd") != 0) { # if _has_std_nfs_quotas diquota_nfs (di_data, diqinfo); # endif return; } #endif #if _has_std_quotas && ! _lib_quota_open && ! _lib_vquotactl if (strcmp (diqinfo->fstype, "xfs") == 0) { # if _hdr_linux_dqblk_xfs ucmd = QCMD (Q_XGETQUOTA, USRQUOTA); gcmd = QCMD (Q_XGETQUOTA, GRPQUOTA); xfsflag = true; # endif ; } else { # if _define_QCMD ucmd = QCMD (Q_GETQUOTA, USRQUOTA); gcmd = QCMD (Q_GETQUOTA, GRPQUOTA); # else /* hp-ux doesn't have QCMD */ ucmd = Q_GETQUOTA; gcmd = Q_GETQUOTA; # endif } rc = quotactl_get (di_data, diqinfo, ucmd, diqinfo->uid, &qdata); #endif /* _has_std_quotas && ! _lib_quota_open && ! _lib_vquotactl */ #if _has_std_quotas di_process_quotas (di_data, "usr", diqinfo, rc, xfsflag, &qdata); #if _lib_vquotactl qdata.vqval.vqvalptr = &qdata.vqval.gvqval; #endif # if _lib_quota_open rc = quota_open_get (qh, QUOTA_IDTYPE_GROUP, diqinfo->uid, &qdata.qval); # endif # if ! _lib_quota_open && ! _lib_vquotactl # ifdef GRPQUOTA if (rc == 0 || errno != ESRCH) { rc = quotactl_get (di_data, diqinfo, gcmd, diqinfo->gid, &qdata); } # endif /* ifdef GRPQUOTA */ # endif /* ! _lib_quota_open && ! _lib_vquotactl */ # if _lib_quota_open if (qh != (struct quotahandle *) NULL) { quota_close (qh); } # endif # if defined (GRPQUOTA) || _lib_quota_open || _lib_vquotactl di_process_quotas (di_data, "grp", diqinfo, rc, xfsflag, &qdata); # endif #endif /* _has_std_quotas */ } #if _has_std_nfs_quotas && ! _lib_quota_open #ifdef RQ_PATHLEN # define DI_RQ_PATHLEN RQ_PATHLEN #else # define DI_RQ_PATHLEN 1024 #endif static bool_t xdr_quota_get (XDR *xp, struct getquota_args *args) { if (! xdr_string (xp, &args->gqa_pathp, DI_RQ_PATHLEN)) { return 0; } if (! xdr_gqa_uid (xp, &args->gqa_uid)) { return 0; } return 1; } static bool_t xdr_quota_rslt (XDR *xp, struct getquota_rslt *rslt) { int quotastat; struct rquota *rptr; if (! xdr_int (xp, "astat)) { return 0; } # if _mem_struct_getquota_rslt_gqr_status rslt->gqr_status = quotastat; # else # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wsign-conversion" rslt->status = (gqr_status) quotastat; # pragma clang diagnostic pop # endif # if _mem_struct_getquota_rslt_gqr_rquota rptr = &rslt->gqr_rquota; # else rptr = &rslt->getquota_rslt_u.gqr_rquota; # endif if (! xdr_int (xp, &rptr->rq_bsize)) { return 0; } if (! xdr_bool (xp, &rptr->rq_active)) { return 0; } if (! xdr_rq_bhardlimit (xp, &rptr->rq_bhardlimit)) { return 0; } if (! xdr_rq_bsoftlimit (xp, &rptr->rq_bsoftlimit)) { return 0; } if (! xdr_rq_curblocks (xp, &rptr->rq_curblocks)) { return 0; } if (! xdr_rq_fhardlimit (xp, &rptr->rq_fhardlimit)) { return 0; } if (! xdr_rq_fsoftlimit (xp, &rptr->rq_fsoftlimit)) { return 0; } if (! xdr_rq_curfiles (xp, &rptr->rq_curfiles)) { return 0; } return (1); } static void diquota_nfs (di_data_t *di_data, di_quota_t *diqinfo) { CLIENT *rqclnt; enum clnt_stat clnt_stat; struct timeval timeout; char host [DI_FILESYSTEM_LEN]; char *ptr; char *path; struct getquota_args args; struct getquota_rslt result; struct rquota *rptr; int quotastat; dinum_t tsize; di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; dinum_init (&tsize); if (diopts->optval [DI_OPT_DEBUG] > 5) { printf ("quota: diquota_nfs\n"); } timeout.tv_sec = 2; timeout.tv_usec = 0; stpecpy (host, host + DI_FILESYSTEM_LEN, diqinfo->filesystem); path = host; ptr = strchr (host, ':'); if (ptr != (char *) NULL) { *ptr = '\0'; path = ptr + 1; } if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("quota: nfs: host: %s path: %s\n", host, path); } args.gqa_pathp = path; args.gqa_uid = (int) diqinfo->uid; rqclnt = clnt_create (host, (unsigned long) RQUOTAPROG, (unsigned long) RQUOTAVERS, "udp"); if (rqclnt == (CLIENT *) NULL) { if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("quota: nfs: create failed %d\n", errno); } return; } rqclnt->cl_auth = authunix_create_default (); if (diopts->optval [DI_OPT_DEBUG] > 5) { printf ("quota: xdr_quota_get/rslt\n"); } #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunknown-warning-option" /* how many ways does clang complain about sort-of-valid code? */ #pragma clang diagnostic ignored "-Wincompatible-function-pointer-types" #pragma clang diagnostic ignored "-Wcast-function-type-strict" #pragma clang diagnostic ignored "-Wcast-function-type" #pragma gcc diagnostic push #pragma gcc diagnostic ignored "-Wcast-function-type" /* works? */ /* gcc14 on macos complains also, but the pragma maybe does not work */ /* it's an old interface and xdrproc_t isn't quite defined correctly */ /* i will attempt to clean this up at a later date */ clnt_stat = clnt_call (rqclnt, (unsigned long) RQUOTAPROC_GETQUOTA, (xdrproc_t) xdr_quota_get, (caddr_t) &args, (xdrproc_t) xdr_quota_rslt, (caddr_t) &result, timeout); #pragma clang diagnostic pop #pragma gcc diagnostic pop if (clnt_stat != RPC_SUCCESS) { if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("quota: nfs: not success\n"); } if (rqclnt->cl_auth) { /* MacOS does not declare ah_destroy with modern function signatures */ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunknown-warning-option" #pragma clang diagnostic ignored "-Wdeprecated-non-prototype" auth_destroy (rqclnt->cl_auth); #pragma clang diagnostic pop } clnt_destroy (rqclnt); return; } # if _mem_struct_getquota_rslt_gqr_status quotastat = (int) result.gqr_status; # else quotastat = (int) result.status; # endif if (quotastat == 1) { # if _mem_struct_getquota_rslt_gqr_rquota rptr = &result.gqr_rquota; # else rptr = &result.getquota_rslt_u.gqr_rquota; # endif if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("quota: nfs: status 1\n"); printf ("quota: nfs: rq_bsize: %d\n", rptr->rq_bsize); printf ("quota: nfs: rq_active: %d\n", rptr->rq_active); } dinum_mul_uu (&diqinfo->values [DI_QUOTA_LIMIT], (di_ui_t) rptr->rq_bhardlimit, (di_ui_t) rptr->rq_bsize); dinum_mul_uu (&tsize, (di_ui_t) rptr->rq_bsoftlimit, (di_ui_t) rptr->rq_bsize); if (dinum_cmp_s (&tsize, (di_si_t) 0) != 0 && dinum_cmp (&tsize, &diqinfo->values [DI_QUOTA_LIMIT]) < 0) { dinum_set (&diqinfo->values [DI_QUOTA_LIMIT], &tsize); } if (dinum_cmp_s (&diqinfo->values [DI_QUOTA_LIMIT], (di_si_t) 0) != 0) { dinum_mul_uu (&diqinfo->values [DI_QUOTA_USED], (di_ui_t) rptr->rq_curblocks, (di_ui_t) rptr->rq_bsize); } dinum_set_u (&diqinfo->values [DI_QUOTA_ILIMIT], (di_ui_t) rptr->rq_fhardlimit); dinum_set_s (&tsize, (di_si_t) rptr->rq_fsoftlimit); if (dinum_cmp_s (&tsize, (di_si_t) 0) != 0 && dinum_cmp (&tsize, &diqinfo->values [DI_QUOTA_ILIMIT]) < 0) { dinum_set (&diqinfo->values [DI_QUOTA_ILIMIT], &tsize); } if (dinum_cmp_s (&diqinfo->values [DI_QUOTA_ILIMIT], (di_si_t) 0) != 0) { dinum_set_u (&diqinfo->values [DI_QUOTA_IUSED], (di_ui_t) rptr->rq_curfiles); } } if (rqclnt->cl_auth) { /* MacOS does not declare ah_destroy with modern function signatures */ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunknown-warning-option" #pragma clang diagnostic ignored "-Wdeprecated-non-prototype" auth_destroy (rqclnt->cl_auth); #pragma clang diagnostic pop } clnt_destroy (rqclnt); dinum_clear (&tsize); } #endif /* have std nfs quotas */ #if _has_std_quotas static void di_process_quotas (di_data_t *di_data, const char *tag, di_quota_t *diqinfo, int rc, int xfsflag, qdata_t *qdata) { dinum_t quot_block_sz; dinum_t qspace_block_sz; dinum_t tsize; dinum_t tlimit; di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; dinum_init ("_block_sz); dinum_set_u ("_block_sz, (di_ui_t) DI_QUOT_BLOCK_SIZE); dinum_init (&qspace_block_sz); dinum_set_u (&qspace_block_sz, (di_ui_t) DI_QUOT_BLOCK_SIZE); dinum_init (&tsize); dinum_init (&tlimit); if (diopts->optval [DI_OPT_DEBUG] > 5) { printf ("quota: di_process_quotas\n"); } # if _lib_vquotactl dinum_set_u ("_block_sz, (di_ui_t) 1); dinum_set_u (&qspace_block_sz, (di_ui_t) 1); # endif # if _mem_struct_dqblk_dqb_curspace dinum_set_u (&qspace_block_sz, (di_ui_t) 1); # endif if (xfsflag) { dinum_set_u ("_block_sz, (di_ui_t) 512); dinum_set_u (&qspace_block_sz, (di_ui_t) 512); } if (rc == 0) { dinum_set_u (&tsize, (di_ui_t) 0); dinum_set_u (&tlimit, (di_ui_t) 0); if (diopts->optval [DI_OPT_DEBUG] > 1) { char tbuff [100]; dinum_str ("_block_sz, tbuff, sizeof (tbuff)); printf ("# diquota: blocksize: %s\n", tbuff); } if (xfsflag) { # if _typ_fs_disk_quota_t if (diopts->optval [DI_OPT_DEBUG] > 1) { printf ("# diquota: fs_disk_quota_t\n"); } dinum_set_u (&tsize, (di_ui_t) qdata->xfsqinfo.d_blk_hardlimit); # endif ; } else { # if _lib_vquotactl if (diopts->optval [DI_OPT_DEBUG] > 1) { printf ("# diquota: vquotactl\n"); } dinum_set_u (&tsize, (di_ui_t) qdata->vqval.vqvalptr->values [DI_QUOTA_LIMIT]); # endif # if _typ_struct_quotaval if (diopts->optval [DI_OPT_DEBUG] > 1) { printf ("# diquota: struct quotaval\n"); } dinum_set_u (&tsize, (di_ui_t) qdata->qval.qbval.qv_hardlimit); # endif # if _typ_struct_dqblk && ! _lib_vquotactl if (diopts->optval [DI_OPT_DEBUG] > 1) { printf ("# diquota: struct dqblk\n"); } dinum_set_u (&tsize, (di_ui_t) qdata->qinfo.dqb_bhardlimit); # endif } if (diopts->optval [DI_OPT_DEBUG] > 2) { char tbuff [100]; dinum_str (&tsize, tbuff, sizeof (tbuff)); printf ("quota: %s %s b hard: %s\n", tag, diqinfo->mountpt, tbuff); } if (dinum_cmp_s (&tsize, (di_si_t) 0) > 0) { dinum_mul (&tsize, "_block_sz); if (dinum_cmp_s (&tsize, (di_si_t) 0) > 0 && (dinum_cmp (&tsize, &diqinfo->values [DI_QUOTA_LIMIT]) < 0 || dinum_cmp_s (&diqinfo->values [DI_QUOTA_LIMIT], (di_si_t) 0) == 0)) { if (diopts->optval [DI_OPT_DEBUG] > 2) { char tbuffa [100]; char tbuffb [100]; dinum_str ("_block_sz, tbuffa, sizeof (tbuffa)); dinum_str (&tsize, tbuffb, sizeof (tbuffb)); printf ("quota: using b hard: %s (%s)\n", tbuffb, tbuffa); } dinum_set (&diqinfo->values [DI_QUOTA_LIMIT], &tsize); dinum_set (&tlimit, &tsize); } } if (xfsflag) { # if _typ_fs_disk_quota_t dinum_set_u (&tsize, (di_ui_t) qdata->xfsqinfo.d_blk_softlimit); # endif ; } else { # if _lib_vquotactl /* no soft limit, use hard */ dinum_set_u (&tsize, (di_ui_t) qdata->vqval.vqvalptr->values [DI_QUOTA_LIMIT]); # endif # if _typ_struct_quotaval dinum_set_u (&tsize, (di_ui_t) qdata->qval.qbval.qv_softlimit); # endif # if _typ_struct_dqblk && ! _lib_vquotactl dinum_set_u (&tsize, (di_ui_t) qdata->qinfo.dqb_bsoftlimit); # endif } if (diopts->optval [DI_OPT_DEBUG] > 2) { char tbuffa [100]; dinum_str ("_block_sz, tbuffa, sizeof (tbuffa)); printf ("quota: %s %s b soft: %s\n", tag, diqinfo->mountpt, tbuffa); } if (dinum_cmp_s (&tsize, (di_si_t) 0) > 0) { dinum_mul (&tsize, "_block_sz); if (dinum_cmp_s (&tsize, (di_si_t) 0) > 0 && (dinum_cmp (&tsize, &diqinfo->values [DI_QUOTA_LIMIT]) < 0 || dinum_cmp_s (&diqinfo->values [DI_QUOTA_LIMIT], (di_si_t) 0) == 0)) { if (diopts->optval [DI_OPT_DEBUG] > 2) { char tbuffa [100]; char tbuffb [100]; dinum_str ("_block_sz, tbuffa, sizeof (tbuffa)); dinum_str (&tsize, tbuffb, sizeof (tbuffb)); printf ("quota: using b soft: %s (%s)\n", tbuffb, tbuffa); } dinum_set (&diqinfo->values [DI_QUOTA_LIMIT], &tsize); dinum_set (&tlimit, &tsize); } } /* any quota set? */ if (dinum_cmp_s (&tlimit, (di_si_t) 0) == 0) { if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("quota: %s %s no quota\n", tag, diqinfo->mountpt); } return; } if (diopts->optval [DI_OPT_DEBUG] > 1) { char tbuff [100]; dinum_str (&qspace_block_sz, tbuff, sizeof (tbuff)); printf ("# diquota: space block size: %s\n", tbuff); } dinum_set_u (&tlimit, (di_ui_t) 0); if (xfsflag) { # if _typ_fs_disk_quota_t if (diopts->optval [DI_OPT_DEBUG] > 1) { printf ("# diquota: fs_disk_quota_t\n"); } dinum_set_u (&tsize, (di_ui_t) qdata->xfsqinfo.d_bcount); # endif ; } else { # if _lib_vquotactl if (diopts->optval [DI_OPT_DEBUG] > 1) { printf ("# diquota: vquotactl\n"); } dinum_set_u (&tsize, (di_ui_t) qdata->vqval.vqvalptr->usage); # endif # if _typ_struct_quotaval if (diopts->optval [DI_OPT_DEBUG] > 1) { printf ("# diquota: struct quotaval\n"); } dinum_set_u (&tsize, (di_ui_t) qdata->qval.qbval.qv_usage); # endif # if _mem_struct_dqblk_dqb_curspace if (diopts->optval [DI_OPT_DEBUG] > 1) { printf ("# diquota: dqb_curspace\n"); } dinum_set_u (&tsize, (di_ui_t) qdata->qinfo.dqb_curspace); # endif # if _mem_struct_dqblk_dqb_curblocks && ! _lib_vquotactl if (diopts->optval [DI_OPT_DEBUG] > 1) { printf ("# diquota: dqb_curblocks\n"); } dinum_set_u (&tsize, (di_ui_t) qdata->qinfo.dqb_curblocks); # endif } dinum_mul (&tsize, &qspace_block_sz); if (dinum_cmp (&tsize, &diqinfo->values [DI_QUOTA_USED]) > 0 || dinum_cmp_s (&diqinfo->values [DI_QUOTA_USED], (di_si_t) 0) == 0) { dinum_set (&diqinfo->values [DI_QUOTA_USED], &tsize); } if (diopts->optval [DI_OPT_DEBUG] > 2) { char tbuffa [100]; char tbuffb [100]; dinum_str (&diqinfo->values [DI_QUOTA_USED], tbuffa, sizeof (tbuffa)); dinum_str (&diqinfo->values [DI_QUOTA_LIMIT], tbuffb, sizeof (tbuffb)); printf ("quota: %s %s used: %s limit: %s\n", tag, diqinfo->mountpt, tbuffa, tbuffb); } # if ! _lib_vquotactl /* no inode limits */ if (xfsflag) { # if _typ_fs_disk_quota_t dinum_set_u (&tsize, (di_ui_t) qdata->xfsqinfo.d_ino_hardlimit); # endif ; } else { # if _typ_struct_quotaval dinum_set_u (&tsize, (di_ui_t) qdata->qval.qival.qv_hardlimit); # endif # if _typ_struct_dqblk && ! _lib_vquotactl dinum_set_u (&tsize, (di_ui_t) qdata->qinfo.dqb_ihardlimit); # endif } if (dinum_cmp_s (&tsize, (di_si_t) 0) > 0 && (dinum_cmp (&tsize, &diqinfo->values [DI_QUOTA_ILIMIT]) < 0 || dinum_cmp_s (&diqinfo->values [DI_QUOTA_ILIMIT], (di_si_t) 0) == 0)) { dinum_set (&diqinfo->values [DI_QUOTA_ILIMIT], &tsize); dinum_set (&tlimit, &tsize); } if (diopts->optval [DI_OPT_DEBUG] > 2) { char tbuffa [100]; dinum_str ("_block_sz, tbuffa, sizeof (tbuffa)); printf ("quota: %s %s i hard: %s\n", tag, diqinfo->mountpt, tbuffa); } if (xfsflag) { # if _typ_fs_disk_quota_t dinum_set_u (&tsize, (di_ui_t) qdata->xfsqinfo.d_ino_softlimit); # endif ; } else { # if _typ_struct_quotaval dinum_set_u (&tsize, (di_ui_t) qdata->qval.qival.qv_softlimit); # endif # if _typ_struct_dqblk && ! _lib_vquotactl dinum_set_u (&tsize, (di_ui_t) qdata->qinfo.dqb_isoftlimit); # endif } if (dinum_cmp_s (&tsize, (di_si_t) 0) > 0 && (dinum_cmp (&tsize, &diqinfo->values [DI_QUOTA_ILIMIT]) < 0 || dinum_cmp_s (&diqinfo->values [DI_QUOTA_ILIMIT], (di_si_t) 0) == 0)) { dinum_set (&diqinfo->values [DI_QUOTA_ILIMIT], &tsize); dinum_set (&tlimit, &tsize); } if (diopts->optval [DI_OPT_DEBUG] > 2) { char tbuffa [100]; dinum_str (&tsize, tbuffa, sizeof (tbuffa)); printf ("quota: %s %s i soft: %s\n", tag, diqinfo->mountpt, tbuffa); } /* any quota set? */ if (dinum_cmp_s (&tlimit, (di_si_t) 0) == 0) { if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("quota: %s %s no inode quota\n", tag, diqinfo->mountpt); } return; } if (xfsflag) { # if _typ_fs_disk_quota_t dinum_set_u (&tsize, (di_ui_t) qdata->xfsqinfo.d_icount); # endif ; } else { # if _typ_struct_quotaval dinum_set_u (&tsize, (di_ui_t) qdata->qval.qival.qv_usage); # endif # if ! _lib_quota_open && ! _lib_vquotactl dinum_set_u (&tsize, (di_ui_t) qdata->qinfo.dqb_curinodes); # endif } if (dinum_cmp (&tsize, &diqinfo->values [DI_QUOTA_IUSED]) > 0 || dinum_cmp_s (&diqinfo->values [DI_QUOTA_IUSED], (di_si_t) 0) == 0) { dinum_set (&diqinfo->values [DI_QUOTA_IUSED], &tsize); } if (diopts->optval [DI_OPT_DEBUG] > 2) { char tbuffa [100]; dinum_str (&tsize, tbuffa, sizeof (tbuffa)); printf ("quota: %s %s i used: %s\n", tag, diqinfo->mountpt, tbuffa); } # endif /* ! _lib_vquotactl */ } else { if (diopts->optval [DI_OPT_DEBUG] > 2) { printf ("quota: %s %s errno %d\n", tag, diqinfo->mountpt, errno); } } dinum_clear ("_block_sz); dinum_clear (&qspace_block_sz); dinum_clear (&tsize); dinum_clear (&tlimit); } #endif /* _has_std_quotas */ di-6.0.0/dioptions.c0000644000175000017500000006450214761620475012414 0ustar bllbll/* * Copyright 1994-2018 Brad Lanam, Walnut Creek, CA * Copyright 2023-2025 Brad Lanam, Pleasant Hill, CA */ #include "config.h" #if _hdr_stdio # include #endif #if _hdr_stdlib # include #endif #if _hdr_stdbool # include #endif #if _sys_types \ && ! defined (DI_INC_SYS_TYPES_H) /* xenix */ # define DI_INC_SYS_TYPES_H # include #endif #if _hdr_ctype # include #endif #if _hdr_errno # include #endif #if _hdr_string # include #endif #if _hdr_strings # include #endif #if _hdr_libintl # include #endif #include "di.h" #include "disystem.h" #include "diinternal.h" // DI_DEFAULT_FORMAT #include "distrutils.h" #include "getoptn.h" #include "dioptions.h" struct pa_tmp { di_opt_t *diopts; char *scalestr; Size_t scalestrsz; }; typedef struct { const char uc; const char lc; } di_valid_scale_t; static di_valid_scale_t validscale [] = { { 'B', 'b' }, /* "Byte", "Byte" */ { 'K', 'k' }, /* "Kilo", "Kibi" */ { 'M', 'm' }, /* "Mega", "Mebi" */ { 'G', 'g' }, /* "Giga", "Gibi" */ { 'T', 't' }, /* "Tera", "Tebi" */ { 'P', 'p' }, /* "Peta", "Pebi" */ { 'E', 'e' }, /* "Exa", "Exbi" */ { 'Z', 'z' }, /* "Zetta", "Zebi" */ { 'Y', 'y' }, /* "Yotta", "Yobi" */ { 'R', 'r' }, /* "Ronna", "Ronni" */ { 'Q', 'q' } /* "Quetta", "Quetti" */ }; #define DI_VALID_SCALE_SZ ((int) (sizeof (validscale) / sizeof (di_valid_scale_t))) #define OPT_IDX_A 0 #define OPT_IDX_a 1 #define OPT_IDX_B 2 #define OPT_IDX_c 3 #define OPT_IDX_C 4 #define OPT_IDX_d 5 #define OPT_IDX_f 6 #define OPT_IDX_g 7 #define OPT_IDX_h 8 #define OPT_IDX_H 9 #define OPT_IDX_help 10 #define OPT_IDX_I 11 #define OPT_IDX_j 12 #define OPT_IDX_k 13 #define OPT_IDX_l 14 #define OPT_IDX_L 15 #define OPT_IDX_m 16 #define OPT_IDX_n 17 #define OPT_IDX_P 18 #define OPT_IDX_q 19 #define OPT_IDX_R 20 #define OPT_IDX_s 21 #define OPT_IDX_si 22 #define OPT_IDX_t 23 #define OPT_IDX_version 24 #define OPT_IDX_x 25 #define OPT_IDX_X 26 #define OPT_IDX_z 27 #define OPT_IDX_Z 28 #define OPT_IDX_MAX_NAMED 29 #define OPT_IDX_MAX 53 static int scaleids [] = { OPT_IDX_d, OPT_IDX_g, OPT_IDX_h, OPT_IDX_H, OPT_IDX_k, OPT_IDX_m }; static int paidb [] = { OPT_IDX_a, OPT_IDX_help, OPT_IDX_P, OPT_IDX_si, OPT_IDX_version }; static int paidv [] = { OPT_IDX_B, OPT_IDX_I, OPT_IDX_s, OPT_IDX_x, OPT_IDX_X }; #define DI_ARGV_SEP " " /* space, tab */ #define DI_MAX_ARGV 50 #define DI_LIST_SEP "," #define DI_POSIX_FORMAT "sbuvpm" #define DI_ALL_FORMAT "mts\n\tO\n\tbuf13\n\tbcvpa\n\tBuv2\n\tiUFP" static void processStringArgs (char *, di_opt_t *, int offset, char *, Size_t); static int processArgs (int, const char * argv [], di_opt_t *, int offset, char *, Size_t); static int parseList (di_strarr_t *, char *); static void parseScaleValue (di_opt_t *diopts, char *ptr); static void processOptions (const char *, char *); static void processOptionsVal (const char *, void *, char *); static void setExitFlag (di_opt_t *, int); static void diopt_init (di_opt_t *diopts, struct pa_tmp *); static void processStringArgs (char *ptr, di_opt_t *diopts, int offset, char *scalestr, Size_t scalestrsz) { char *dptr; char *tptr; int nargc; char *nargv [DI_MAX_ARGV]; if (ptr == (char *) NULL || strcmp (ptr, "") == 0) { return; } dptr = (char *) NULL; dptr = strdup (ptr); if (dptr == (char *) NULL) { fprintf (stderr, "strdup failed in main () (1). errno %d\n", errno); setExitFlag (diopts, DI_EXIT_FAIL); return; } if (dptr != (char *) NULL) { int optidx; char *tokstr = NULL; tptr = di_strtok (dptr, DI_ARGV_SEP, &tokstr); nargc = 0; while (tptr != (char *) NULL) { if (nargc >= DI_MAX_ARGV) { break; } nargv [nargc++] = tptr; tptr = di_strtok ((char *) NULL, DI_ARGV_SEP, &tokstr); } #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wcast-qual" optidx = processArgs (nargc, (const char **) nargv, diopts, 0, scalestr, scalestrsz); #pragma clang diagnostic pop if (optidx < nargc) { fprintf (stderr, "unknown data found in DI_ARGS %s\n", nargv [optidx]); diopts->errorCount += 1; if (diopts->errorCount > 0) { setExitFlag (diopts, DI_EXIT_WARN); } } free ((char *) dptr); } } di_opt_t * di_init_options (void) { di_opt_t *diopts; int i; diopts = (di_opt_t *) malloc (sizeof (di_opt_t)); if (diopts == NULL) { return diopts; } diopts->opts = NULL; diopts->optinit = false; diopts->formatString = DI_DEFAULT_FORMAT; diopts->formatLen = (int) strlen (diopts->formatString); diopts->zoneDisplay [0] = '\0'; diopts->exclude_list.count = 0; diopts->exclude_list.list = (char **) NULL; diopts->include_list.count = 0; diopts->include_list.list = (char **) NULL; diopts->scale = DI_SCALE_GIGA; diopts->blockSize = DI_BLKSZ_1024; for (i = 0; i < DI_OPT_MAX; ++i) { diopts->optval [i] = false; } diopts->optval [DI_OPT_DISP_HEADER] = true; diopts->optval [DI_OPT_EXCL_LOOPBACK] = true; diopts->optval [DI_OPT_QUOTA_CHECK] = true; diopts->optval [DI_OPT_DEBUG] = 0; /* default - by mount point*/ stpecpy (diopts->sortType, diopts->sortType + sizeof (diopts->sortType), "m"); diopts->exitFlag = DI_EXIT_NORM; diopts->errorCount = 0; return diopts; } void di_opt_cleanup (di_opt_t *diopts) { if (diopts == NULL) { return; } if (diopts->exclude_list.count > 0 && diopts->exclude_list.list != (char **) NULL) { free ( (void *) diopts->exclude_list.list); diopts->exclude_list.count = 0; } if (diopts->include_list.count > 0 && diopts->include_list.list != (char **) NULL) { free (diopts->include_list.list); diopts->include_list.count = 0; } if (diopts->opts != NULL) { free (diopts->opts); } free (diopts); } int di_get_options (int argc, const char * argv [], di_opt_t *diopts, int offset) { char * ptr; char scalestr [30]; int optidx; if (diopts == NULL) { return DI_EXIT_FAIL; } diopts->argc = argc; diopts->argv = argv; stpecpy (scalestr, scalestr + sizeof (scalestr), DI_DEFAULT_DISP_SIZE); /* gnu df */ if ( (ptr = getenv ("POSIXLY_CORRECT")) != (char *) NULL) { stpecpy (scalestr, scalestr + sizeof (scalestr), "k"); diopts->formatString = DI_POSIX_FORMAT; diopts->optval [DI_OPT_POSIX_COMPAT] = true; diopts->optval [DI_OPT_DISP_CSV] = false; diopts->optval [DI_OPT_DISP_JSON] = false; } /* bsd df */ if ( (ptr = getenv ("BLOCKSIZE")) != (char *) NULL) { stpecpy (scalestr, scalestr + sizeof (scalestr), ptr); } /* gnu df */ if ( (ptr = getenv ("DF_BLOCK_SIZE")) != (char *) NULL) { stpecpy (scalestr, scalestr + sizeof (scalestr), ptr); } if ( (ptr = getenv ("DI_ARGS")) != (char *) NULL) { processStringArgs (ptr, diopts, offset, scalestr, sizeof (scalestr)); } optidx = processArgs (argc, argv, diopts, offset, scalestr, sizeof (scalestr)); if (diopts->optval [DI_OPT_DEBUG] > 0) { int j; printf ("# ARGS:"); for (j = 0; j < argc; ++j) { printf (" %s", argv [j]); } printf ("\n"); printf ("# blocksize: %d\n", diopts->blockSize); printf ("# scale: %s\n", scalestr); if ( (ptr = getenv ("POSIXLY_CORRECT")) != (char *) NULL) { printf ("# POSIXLY_CORRECT: %s\n", ptr); } if ( (ptr = getenv ("BLOCKSIZE")) != (char *) NULL) { printf ("# BLOCKSIZE: %s\n", ptr); } if ( (ptr = getenv ("DF_BLOCK_SIZE")) != (char *) NULL) { printf ("# DF_BLOCK_SIZE: %s\n", ptr); } if ( (ptr = getenv ("DI_ARGS")) != (char *) NULL) { printf ("# DI_ARGS: %s\n", ptr); } } parseScaleValue (diopts, scalestr); diopts->formatLen = (int) strlen (diopts->formatString); diopts->optidx = optidx; return diopts->exitFlag; } void di_opt_format_iter_init (di_opt_t *diopts) { if (diopts == NULL) { return; } diopts->optiteridx = 0; } int di_opt_format_iterate (di_opt_t *diopts) { int val; if (diopts == NULL) { return DI_FMT_ITER_STOP; } if (diopts->optiteridx < 0 || diopts->optiteridx >= diopts->formatLen) { return DI_FMT_ITER_STOP; } val = diopts->formatString [diopts->optiteridx]; ++diopts->optiteridx; return val; } int di_opt_check_option (di_opt_t *diopts, int optidx) { if (diopts == NULL) { return 0; } if (optidx == DI_OPT_FMT_STR_LEN) { return diopts->formatLen; } if (optidx == DI_OPT_SCALE) { return diopts->scale; } if (optidx == DI_OPT_BLOCK_SZ) { return diopts->blockSize; } if (optidx < 0 || optidx >= DI_OPT_MAX) { return 0; } return diopts->optval [optidx]; } static int processArgs (int argc, const char * argv [], di_opt_t *diopts, int offset, char *scalestr, Size_t scalestrsz) { int i; int optidx; int errorCount; struct pa_tmp padata; diopt_init (diopts, &padata); for (i = 0; i < (int) (sizeof (scaleids) / sizeof (int)); ++i) { diopts->opts [scaleids [i]].valptr = (void *) scalestr; diopts->opts [scaleids [i]].valsiz = scalestrsz; } for (i = 0; i < (int) (sizeof (paidb) / sizeof (int)); ++i) { if (diopts->exitFlag != DI_EXIT_NORM) { break; } diopts->opts [paidb [i]].valptr = (void *) &padata; diopts->opts [paidb [i]].value2 = (void *) processOptions; } for (i = 0; i < (int) (sizeof (paidv) / sizeof (int)); ++i) { if (diopts->exitFlag != DI_EXIT_NORM) { break; } diopts->opts [paidv [i]].valptr = (void *) &padata; diopts->opts [paidv [i]].value2 = (void *) processOptionsVal; } optidx = -1; if (diopts->exitFlag != DI_EXIT_NORM) { return optidx; } padata.diopts = diopts; padata.scalestr = scalestr; padata.scalestrsz = scalestrsz; optidx = getoptn (GETOPTN_LEGACY, argc, argv, OPT_IDX_MAX, diopts->opts, offset, &errorCount); diopts->errorCount += errorCount; if (diopts->errorCount > 0) { setExitFlag (diopts, DI_EXIT_WARN); } if (diopts->optval [DI_OPT_DISP_CSV_TAB]) { diopts->optval [DI_OPT_DISP_CSV] = true; } if (diopts->optval [DI_OPT_DISP_JSON]) { diopts->optval [DI_OPT_DISP_HEADER] = false; } return optidx; } static void processOptions (const char *arg, char *valptr) { struct pa_tmp *padata; padata = (struct pa_tmp *) valptr; if (strcmp (arg, "-a") == 0) { padata->diopts->optval [DI_OPT_DISP_ALL] = true; stpecpy (padata->diopts->zoneDisplay, padata->diopts->zoneDisplay + sizeof (padata->diopts->zoneDisplay), "all"); } else if (strcmp (arg, "--help") == 0 || strcmp (arg, "-?") == 0) { setExitFlag (padata->diopts, DI_EXIT_HELP); } else if (strcmp (arg, "-P") == 0) { /* always use -k option, 512 is not supported */ stpecpy (padata->scalestr, padata->scalestr + padata->scalestrsz, "k"); padata->diopts->formatString = DI_POSIX_FORMAT; padata->diopts->optval [DI_OPT_POSIX_COMPAT] = true; padata->diopts->optval [DI_OPT_DISP_CSV] = false; padata->diopts->optval [DI_OPT_DISP_JSON] = false; } else if (strcmp (arg, "--si") == 0) { stpecpy (padata->scalestr, padata->scalestr + padata->scalestrsz, "h"); padata->diopts->blockSize = DI_BLKSZ_1000; } else if (strcmp (arg, "--version") == 0) { setExitFlag (padata->diopts, DI_EXIT_VERS); } else { fprintf (stderr, "di_panic: bad option setup\n"); } return; } static void processOptionsVal (const char *arg, void *valptr, char *value) { struct pa_tmp *padata; int rc; padata = (struct pa_tmp *) valptr; if (strcmp (arg, "-B") == 0) { if (isdigit ((int) (*value))) { int val; val = atoi (value); if (val == DI_BLKSZ_1000 || val == DI_BLKSZ_1024 ) { padata->diopts->blockSize = val; } } else if (strcmp (value, "k") == 0) { padata->diopts->blockSize = DI_BLKSZ_1024; } else if (strcmp (value, "d") == 0 || strcmp (value, "si") == 0) { padata->diopts->blockSize = DI_BLKSZ_1000; } } else if (strcmp (arg, "-I") == 0) { rc = parseList (&padata->diopts->include_list, value); if (rc != 0) { setExitFlag (padata->diopts, DI_EXIT_FAIL); return; } } else if (strcmp (arg, "-s") == 0) { char *stend = padata->diopts->sortType + sizeof (padata->diopts->sortType); stpecpy (padata->scalestr, padata->scalestr + padata->scalestrsz, "H"); stpecpy (padata->diopts->sortType, stend, value); /* for backwards compatibility */ /* reverse by itself - change to reverse mount point */ if (strcmp (padata->diopts->sortType, "r") == 0) { stpecpy (padata->diopts->sortType, stend, "rm"); } /* add some sense to the sort order */ if (strcmp (padata->diopts->sortType, "t") == 0) { stpecpy (padata->diopts->sortType, stend, "tm"); } } else if (strcmp (arg, "-x") == 0) { parseList (&padata->diopts->exclude_list, value); } else if (strcmp (arg, "-X") == 0) { padata->diopts->optval [DI_OPT_DEBUG] = atoi (value); padata->diopts->optval [DI_OPT_DISP_HEADER] = true; } else { fprintf (stderr, "di_panic: bad option setup\n"); } return; } static int parseList (di_strarr_t *list, char *str) { char *dstr; char *ptr; char *lptr; Size_t count; Size_t ocount; Size_t ncount; Size_t i; char *tokstr = NULL; dstr = strdup (str); if (dstr == (char *) NULL) { fprintf (stderr, "strdup failed in parseList () (1). errno %d\n", errno); return 1; } ptr = di_strtok (dstr, DI_LIST_SEP, &tokstr); count = 0; while (ptr != (char *) NULL) { ++count; // fprintf (stderr, "%ld : %s\n", count, ptr); ptr = di_strtok ( (char *) NULL, DI_LIST_SEP, &tokstr); } ocount = list->count; // fprintf (stderr, "ocount: %ld\n", ocount); list->count += count; ncount = list->count; // fprintf (stderr, "ncount: %ld\n", ncount); list->list = (char **) di_realloc ( (char *) list->list, ncount * sizeof (char *)); if (list->list == (char **) NULL) { fprintf (stderr, "realloc failed in parseList () (2). errno %d\n", errno); free ( (char *) dstr); return 1; } ptr = dstr; for (i = ocount; i < ncount; ++i) { Size_t len; lptr = strdup (ptr); if (lptr == (char *) NULL) { fprintf (stderr, "strdup failed in parseList () (3). errno %d\n", errno); free ( (char *) dstr); return 1; } list->list [i] = lptr; // fprintf (stderr, "b: %ld : %s\n", i, lptr); len = (unsigned int) strlen (ptr); ptr += len + 1; } free ( (char *) dstr); return 0; } static void parseScaleValue (di_opt_t *diopts, char *ptr) { unsigned int len; int i; int val; char *tptr; /* if a numeric value is specified, only 1, 1000 and 1024 are allowed */ /* bad values will default to 1024 */ if (isdigit ((int) *ptr)) { val = atoi (ptr); if (val != DI_BLKSZ_1 && val != DI_BLKSZ_1000 && val != DI_BLKSZ_1024) { val = DI_BLKSZ_1024; } if (val == DI_BLKSZ_1) { diopts->scale = DI_SCALE_BYTE; } if (val == DI_BLKSZ_1000) { diopts->scale = DI_SCALE_KILO; diopts->blockSize = DI_BLKSZ_1000; } if (val == DI_BLKSZ_1024) { diopts->scale = DI_SCALE_KILO; diopts->blockSize = DI_BLKSZ_1024; } } tptr = ptr; len = (unsigned int) strlen (ptr); if (! isdigit ((int) *tptr)) { int idx; idx = -1; for (i = 0; i < DI_VALID_SCALE_SZ; ++i) { if (*tptr == validscale [i].uc || *tptr == validscale [i].lc) { idx = i; break; } } if (idx == -1) { if (*tptr == 'h') { idx = DI_SCALE_HR; } if (*tptr == 'H') { idx = DI_SCALE_HR_ALT; } } if (idx == -1) { if (strncmp (ptr, "HUMAN", (Size_t) 5) == 0) { idx = DI_SCALE_HR; } else { /* some unknown string value */ idx = DI_SCALE_GIGA; } } if (idx >= 0) { if (len > 1) { ++tptr; if (*tptr == 'i') { /* gnu df allows MiB, etc. */ diopts->blockSize = DI_BLKSZ_1024; } if (*tptr == 'B') { diopts->blockSize = DI_BLKSZ_1000; } } } /* known size multiplier */ diopts->scale = idx; } } static void setExitFlag (di_opt_t *diopts, int exitFlag) { if (exitFlag > diopts->exitFlag) { diopts->exitFlag = exitFlag; } } static void diopt_init (di_opt_t *diopts, struct pa_tmp *padata) { int i; int c; if (diopts->optinit) { return; } diopts->opts = (getoptn_opt_t *) malloc (sizeof (getoptn_opt_t) * OPT_IDX_MAX); if (diopts->opts == NULL) { fprintf (stderr, "malloc failed in diopt_init. errno %d\n", errno); exit (1); } for (i = 0; i < OPT_IDX_MAX; ++i) { diopts->opts [i].option = NULL; diopts->opts [i].option_type = GETOPTN_BOOL; diopts->opts [i].valptr = NULL; diopts->opts [i].valsiz = 0; diopts->opts [i].value2 = NULL; } diopts->opts [OPT_IDX_A].option = "-A"; diopts->opts [OPT_IDX_A].option_type = GETOPTN_STRPTR; diopts->opts [OPT_IDX_A].valptr = &diopts->formatString; diopts->opts [OPT_IDX_A].value2 = (void *) DI_ALL_FORMAT; diopts->opts [OPT_IDX_a].option = "-a"; diopts->opts [OPT_IDX_a].option_type = GETOPTN_FUNC_BOOL; /* valptr : padata */ /* value2 : processOptions */ diopts->opts [OPT_IDX_B].option = "-B"; diopts->opts [OPT_IDX_B].option_type = GETOPTN_FUNC_VALUE; /* valptr : padata */ /* value2 : processOptionsVal */ diopts->opts [OPT_IDX_c].option = "-c"; diopts->opts [OPT_IDX_c].option_type = GETOPTN_BOOL; diopts->opts [OPT_IDX_c].valptr = &diopts->optval [DI_OPT_DISP_CSV]; diopts->opts [OPT_IDX_c].valsiz = sizeof (diopts->optval [DI_OPT_DISP_CSV]); diopts->opts [OPT_IDX_C].option = "-C"; diopts->opts [OPT_IDX_C].option_type = GETOPTN_BOOL; diopts->opts [OPT_IDX_C].valptr = &diopts->optval [DI_OPT_DISP_CSV_TAB]; diopts->opts [OPT_IDX_C].valsiz = sizeof (diopts->optval [DI_OPT_DISP_CSV_TAB]); diopts->opts [OPT_IDX_d].option = "-d"; diopts->opts [OPT_IDX_d].option_type = GETOPTN_STRING; /* valptr : scalestr */ /* valsiz : scalestrsz */ diopts->opts [OPT_IDX_f].option = "-f"; diopts->opts [OPT_IDX_f].option_type = GETOPTN_STRPTR; diopts->opts [OPT_IDX_f].valptr = &diopts->formatString; diopts->opts [OPT_IDX_g].option = "-g"; diopts->opts [OPT_IDX_g].option_type = GETOPTN_STRING; /* valptr : scalestr */ /* valsiz : scalestrsz */ diopts->opts [OPT_IDX_g].value2 = (void *) "g"; diopts->opts [OPT_IDX_h].option = "-h"; diopts->opts [OPT_IDX_h].option_type = GETOPTN_STRING; /* valptr : scalestr */ /* valsiz : scalestrsz */ diopts->opts [OPT_IDX_h].value2 = (void *) "h"; diopts->opts [OPT_IDX_H].option = "-H"; diopts->opts [OPT_IDX_H].option_type = GETOPTN_STRING; /* valptr : scalestr */ /* valsiz : scalestrsz */ diopts->opts [OPT_IDX_H].value2 = (void *) "H"; diopts->opts [OPT_IDX_help].option = "--help"; diopts->opts [OPT_IDX_help].option_type = GETOPTN_FUNC_BOOL; /* value2 : processOptions */ diopts->opts [OPT_IDX_I].option = "-I"; diopts->opts [OPT_IDX_I].option_type = GETOPTN_FUNC_VALUE; /* valptr : padata */ /* value2 : processOptionsVal */ diopts->opts [OPT_IDX_j].option = "-j"; diopts->opts [OPT_IDX_j].option_type = GETOPTN_BOOL; diopts->opts [OPT_IDX_j].valptr = &diopts->optval [DI_OPT_DISP_JSON]; diopts->opts [OPT_IDX_j].valsiz = sizeof (diopts->optval [DI_OPT_DISP_JSON]); diopts->opts [OPT_IDX_k].option = "-k"; diopts->opts [OPT_IDX_k].option_type = GETOPTN_STRING; /* valptr : scalestr */ /* valsiz : scalestrsz */ diopts->opts [OPT_IDX_k].value2 = (void *) "k"; diopts->opts [OPT_IDX_l].option = "-l"; diopts->opts [OPT_IDX_l].option_type = GETOPTN_BOOL; diopts->opts [OPT_IDX_l].valptr = &diopts->optval [DI_OPT_LOCAL_ONLY]; diopts->opts [OPT_IDX_l].valsiz = sizeof (diopts->optval [DI_OPT_LOCAL_ONLY]); diopts->opts [OPT_IDX_L].option = "-L"; diopts->opts [OPT_IDX_L].option_type = GETOPTN_BOOL; diopts->opts [OPT_IDX_L].valptr = &diopts->optval [DI_OPT_EXCL_LOOPBACK]; diopts->opts [OPT_IDX_L].valsiz = sizeof (diopts->optval [DI_OPT_EXCL_LOOPBACK]); diopts->opts [OPT_IDX_m].option = "-m"; diopts->opts [OPT_IDX_m].option_type = GETOPTN_STRING; /* valptr : scalestr */ /* valsiz : scalestrsz */ diopts->opts [OPT_IDX_m].value2 = (void *) "m"; diopts->opts [OPT_IDX_n].option = "-n"; diopts->opts [OPT_IDX_n].option_type = GETOPTN_BOOL; diopts->opts [OPT_IDX_n].valptr = &diopts->optval [DI_OPT_DISP_HEADER]; diopts->opts [OPT_IDX_n].valsiz = sizeof (diopts->optval [DI_OPT_DISP_HEADER]); diopts->opts [OPT_IDX_P].option = "-P"; diopts->opts [OPT_IDX_P].option_type = GETOPTN_FUNC_BOOL; /* valptr : padata */ /* value2 : processOptions */ diopts->opts [OPT_IDX_q].option = "-q"; diopts->opts [OPT_IDX_q].option_type = GETOPTN_BOOL; diopts->opts [OPT_IDX_q].valptr = &diopts->optval [DI_OPT_QUOTA_CHECK]; diopts->opts [OPT_IDX_q].valsiz = sizeof (diopts->optval [DI_OPT_QUOTA_CHECK]); diopts->opts [OPT_IDX_R].option = "-R"; diopts->opts [OPT_IDX_R].option_type = GETOPTN_BOOL; diopts->opts [OPT_IDX_R].valptr = &diopts->optval [DI_OPT_NO_SYMLINK]; diopts->opts [OPT_IDX_R].valsiz = sizeof (diopts->optval [DI_OPT_NO_SYMLINK]); diopts->opts [OPT_IDX_s].option = "-s"; diopts->opts [OPT_IDX_s].option_type = GETOPTN_FUNC_VALUE; /* valptr : padata */ /* value2 : processOptionsVal */ diopts->opts [OPT_IDX_si].option = "--si"; diopts->opts [OPT_IDX_si].option_type = GETOPTN_FUNC_BOOL; /* valptr : padata */ /* value2 : processOptions */ diopts->opts [OPT_IDX_t].option = "-t"; diopts->opts [OPT_IDX_t].option_type = GETOPTN_BOOL; diopts->opts [OPT_IDX_t].valptr = &diopts->optval [DI_OPT_DISP_TOTALS] ; diopts->opts [OPT_IDX_t].valsiz = sizeof (diopts->optval [DI_OPT_DISP_TOTALS]); diopts->opts [OPT_IDX_version].option = "--version"; diopts->opts [OPT_IDX_version].option_type = GETOPTN_FUNC_BOOL; /* value2 : processOptions */ diopts->opts [OPT_IDX_x].option = "-x"; diopts->opts [OPT_IDX_x].option_type = GETOPTN_FUNC_VALUE; /* valptr : padata */ /* value2 : processOptionsVal */ diopts->opts [50].option = "--exclude-type"; diopts->opts [50].option_type = GETOPTN_ALIAS; diopts->opts [50].valptr = (void *) "-x"; diopts->opts [OPT_IDX_X].option = "-X"; diopts->opts [OPT_IDX_X].option_type = GETOPTN_FUNC_VALUE; /* valptr : padata */ /* value2 : processOptionsVal */ diopts->opts [OPT_IDX_z].option = "-z"; diopts->opts [OPT_IDX_z].option_type = GETOPTN_STRING; diopts->opts [OPT_IDX_z].valptr = (void *) diopts->zoneDisplay; diopts->opts [OPT_IDX_z].valsiz = sizeof (diopts->zoneDisplay); diopts->opts [OPT_IDX_Z].option = "-Z"; diopts->opts [OPT_IDX_Z].option_type = GETOPTN_STRING; diopts->opts [OPT_IDX_Z].valptr = (void *) diopts->zoneDisplay; diopts->opts [OPT_IDX_Z].valsiz = sizeof (diopts->zoneDisplay); diopts->opts [OPT_IDX_Z].value2 = (void *) "all"; c = OPT_IDX_MAX_NAMED; diopts->opts [c].option = "--all"; diopts->opts [c].option_type = GETOPTN_ALIAS; diopts->opts [c].valptr = (void *) "-a"; ++c; diopts->opts [c].option = "-b"; diopts->opts [c].option_type = GETOPTN_ALIAS; diopts->opts [c].valptr = (void *) "-B"; ++c; diopts->opts [c].option = "--block-size"; diopts->opts [c].option_type = GETOPTN_ALIAS; diopts->opts [c].valptr = (void *) "-B"; ++c; diopts->opts [c].option = "--display-size"; diopts->opts [c].option_type = GETOPTN_ALIAS; diopts->opts [c].valptr = (void *) "-d"; ++c; diopts->opts [c].option = "--dont-resolve-symlink"; diopts->opts [c].option_type = GETOPTN_ALIAS; diopts->opts [c].valptr = (void *) "-R"; ++c; diopts->opts [c].option = "--csv-output"; diopts->opts [c].option_type = GETOPTN_ALIAS; diopts->opts [c].valptr = (void *) "-c"; ++c; diopts->opts [c].option = "--csv-tabs"; diopts->opts [c].option_type = GETOPTN_ALIAS; diopts->opts [c].valptr = (void *) "-C"; ++c; diopts->opts [c].option = "--format-string"; diopts->opts [c].option_type = GETOPTN_ALIAS; diopts->opts [c].valptr = (void *) "-f"; ++c; diopts->opts [c].option = "-F"; diopts->opts [c].option_type = GETOPTN_ALIAS; diopts->opts [c].valptr = (void *) "-I"; ++c; diopts->opts [c].option = "--human-readable"; diopts->opts [c].option_type = GETOPTN_ALIAS; diopts->opts [c].valptr = (void *) "-H"; ++c; diopts->opts [c].option = "-?"; diopts->opts [c].option_type = GETOPTN_ALIAS; diopts->opts [c].valptr = (void *) "--help"; ++c; diopts->opts [c].option = "-i"; diopts->opts [c].option_type = GETOPTN_ALIAS; diopts->opts [c].valptr = (void *) "-x"; ++c; diopts->opts [c].option = "--inodes"; diopts->opts [c].option_type = GETOPTN_IGNORE; ++c; diopts->opts [c].option = "--json-output"; diopts->opts [c].option_type = GETOPTN_ALIAS; diopts->opts [c].valptr = (void *) "-j"; ++c; diopts->opts [c].option = "--local"; diopts->opts [c].option_type = GETOPTN_ALIAS; diopts->opts [c].valptr = (void *) "-l"; ++c; diopts->opts [c].option = "--no-sync"; diopts->opts [c].option_type = GETOPTN_IGNORE; ++c; diopts->opts [c].option = "--portability"; diopts->opts [c].option_type = GETOPTN_ALIAS; diopts->opts [c].valptr = (void *) "-P"; ++c; diopts->opts [c].option = "--print-type"; diopts->opts [c].option_type = GETOPTN_IGNORE; ++c; diopts->opts [c].option = "--sync"; diopts->opts [c].option_type = GETOPTN_IGNORE; ++c; diopts->opts [c].option = "--total"; diopts->opts [c].option_type = GETOPTN_ALIAS; diopts->opts [c].valptr = (void *) "-t"; ++c; diopts->opts [c].option = "--type"; diopts->opts [c].option_type = GETOPTN_ALIAS; diopts->opts [c].valptr = (void *) "-I"; ++c; diopts->opts [c].option = "-v"; diopts->opts [c].option_type = GETOPTN_IGNORE; ++c; diopts->opts [c].option = "-w"; diopts->opts [c].option_type = GETOPTN_IGNORE_ARG; ++c; diopts->opts [c].option = "-W"; diopts->opts [c].option_type = GETOPTN_IGNORE_ARG; ++c; if (c != OPT_IDX_MAX) { fprintf (stderr, "incorrect option initialization %d/%d\n", c, OPT_IDX_MAX); exit (1); } diopts->optinit = true; } di-6.0.0/getoptn.c0000644000175000017500000010352614751704412012055 0ustar bllbll/* * Copyright 2011-2018 Brad Lanam, Walnut Creek, CA * Copyright 2023-2025 Brad Lanam, Pleasant Hill, CA */ /* * A new version of getopt () * Boolean short flags: -a -b (a, b) * With values: -c 123 -d=abcdef -ef * (-c = 123, -d = abcdef, -e = f) * Long options: --a --b --c 123 --d=abcdef * LEGACY: * Boolean short flags: -ab (a, b) * short flags: -version (-v = ersion) * MODERN: * Boolean long name: -ab (ab) * long flags: -version (-version) * */ #include "config.h" #if _hdr_stdio # include #endif #if _hdr_stdlib # include #endif #if _hdr_stdbool # include #endif #if _hdr_string # include #endif #if _hdr_strings # include #endif #if _sys_types \ && ! defined (DI_INC_SYS_TYPES_H) /* xenix */ # define DI_INC_SYS_TYPES_H # include #endif #if defined (TEST_GETOPTN) # include #endif #include "disystem.h" #include "distrutils.h" #include "getoptn.h" typedef struct { Size_t optionlen; int idx; } getoptn_optinfo_t; typedef struct { int style; int optidx; int optcount; getoptn_opt_t *opts; getoptn_optinfo_t *optinfo; int argc; const char **argv; const char *arg; /* current arg we're processing */ Size_t arglen; /* and the length of it */ int hasvalue; /* does this arg have a value attached? */ Size_t argidx; /* index to the value */ Size_t optionlen; /* length of the option for this arg */ Size_t reprocess; /* -ab legacy form? must be 0 or 1 */ Size_t offset; /* reprocessing offset */ } getoptn_info_t; typedef void (*getoptn_func_bool_t) (const char *option, void * valptr); typedef void (*getoptn_func_value_t) (const char *option, void * valptr, const char *value); static int find_option (getoptn_info_t *info, const char *arg, const char *oarg, Size_t *argidx) { int i; Size_t junk; for (i = 0; i < info->optcount; ++i) { if (strncmp (arg + info->offset, info->opts [i].option + info->reprocess, info->optinfo [i].optionlen - info->reprocess) == 0) { info->hasvalue = false; /* info->argidx == 0 indicates top level of recursion */ if (info->argidx == 0) { info->optionlen = info->optinfo [i].optionlen; } if (info->style == GETOPTN_LEGACY) { if (info->arglen - info->offset > info->optionlen - info->reprocess) { if (info->opts [i].option_type == GETOPTN_BOOL) { info->reprocess = true; if (info->offset == 0) { ++info->offset; } ++info->offset; if (info->offset >= info->arglen) { info->offset = 0; info->reprocess = false; } } else { info->hasvalue = true; } } else { info->offset = 0; info->reprocess = false; } } if (info->style == GETOPTN_MODERN) { if (info->arglen > info->optionlen) { if (info->arg [info->optionlen] == '=') { info->hasvalue = true; } else { continue; /* partial match */ } } } *argidx = info->optinfo [i].optionlen; if (info->opts [i].option_type == GETOPTN_ALIAS) { return find_option (info, (const char *) info->opts [i].valptr, oarg, &junk); } return i; } } info->reprocess = false; info->offset = 0; return GETOPTN_NOTFOUND; } static const char * getoption_value (getoptn_info_t *info, getoptn_opt_t *opt) { const char *ptr; ptr = (char *) NULL; if (opt->option_type != GETOPTN_FUNC_VALUE && opt->value2 != (void * ) NULL) { ptr = (const char *) opt->value2; return ptr; } if (info->hasvalue && info->arg [info->argidx] == '=') { ptr = &info->arg [info->argidx + 1]; } else if (info->hasvalue) { ptr = &info->arg [info->argidx]; } else if (info->optidx + 1 < info->argc) { ++info->optidx; ptr = info->argv [info->optidx]; } return ptr; } static int dooptchecks (getoptn_info_t *info, getoptn_opt_t *opt, getoptn_optinfo_t *optinfo, const char *tag, Size_t sz) { if (sz != 0 && opt->valsiz != sz) { fprintf (stderr, "%s: %s: invalid size (line %d)\n", info->argv [0], tag, optinfo->idx); return 1; } if (opt->valptr == NULL) { fprintf (stderr, "%s: %s: invalid pointer (line %d)\n", info->argv [0], tag, optinfo->idx); return 1; } return 0; } static int process_opt (getoptn_info_t *info, getoptn_opt_t *opt, getoptn_optinfo_t *optinfo) { const char *ptr; ptr = (char *) NULL; if (opt->option_type == GETOPTN_INT || opt->option_type == GETOPTN_LONG || opt->option_type == GETOPTN_SIZET || opt->option_type == GETOPTN_DOUBLE || opt->option_type == GETOPTN_STRING || opt->option_type == GETOPTN_STRPTR || opt->option_type == GETOPTN_FUNC_VALUE) { ptr = getoption_value (info, opt); if (ptr == (char *) NULL) { fprintf (stderr, "%s: %s argument missing\n", info->argv [0], info->arg); return 1; } } if (opt->option_type == GETOPTN_BOOL) { int *v; if (dooptchecks (info, opt, optinfo, "bool", sizeof (int)) != 0) { return 1; } v = (int *) opt->valptr; *v = 1 - *v; /* flip it */ } else if (opt->option_type == GETOPTN_INT) { int *v; if (dooptchecks (info, opt, optinfo, "int", sizeof (int)) != 0) { return 1; } v = (int *) opt->valptr; *v = atoi (ptr); } else if (opt->option_type == GETOPTN_LONG) { long *v; if (dooptchecks (info, opt, optinfo, "long", sizeof (long)) != 0) { return 1; } v = (long *) opt->valptr; *v = atol (ptr); } else if (opt->option_type == GETOPTN_SIZET) { Size_t *v; if (dooptchecks (info, opt, optinfo, "Size_t", sizeof (Size_t)) != 0) { return 1; } v = (Size_t *) opt->valptr; *v = (Size_t) atol (ptr); } else if (opt->option_type == GETOPTN_DOUBLE) { double *v; if (dooptchecks (info, opt, optinfo, "double", sizeof (double)) != 0) { return 1; } v = (double *) opt->valptr; *v = atof (ptr); } else if (opt->option_type == GETOPTN_STRING) { char *v; if (dooptchecks (info, opt, optinfo, "string", 0) != 0) { return 1; } v = (char *) opt->valptr; stpecpy (v, v + opt->valsiz, ptr); } else if (opt->option_type == GETOPTN_STRPTR) { const char **v; if (dooptchecks (info, opt, optinfo, "strptr", 0) != 0) { return 1; } v = (const char **) opt->valptr; *v = strdup (ptr); /* memory leak (one time) */ } else if (opt->option_type == GETOPTN_FUNC_BOOL) { getoptn_func_bool_t f; if (opt->value2 == (void * ) NULL) { fprintf (stderr, "%s: %s: invalid function ptr (line %d)\n", info->argv [0], "func_bool", optinfo->idx); return 1; } f = (getoptn_func_bool_t) opt->value2; (f) (opt->option, opt->valptr); } else if (opt->option_type == GETOPTN_FUNC_VALUE) { getoptn_func_value_t f; if (opt->value2 == (void * ) NULL) { fprintf (stderr, "%s: %s: invalid function ptr (line %d)\n", info->argv [0], "func_val", optinfo->idx); return 1; } f = (getoptn_func_value_t) opt->value2; (f) (opt->option, opt->valptr, ptr); } else { info->reprocess = false; info->offset = 0; fprintf (stderr, "%s: unknown option type %d\n", info->argv [0], opt->option_type); return 1; } return 0; } int getoptn (int style, int argc, const char * argv [], int optcount, getoptn_opt_t opts [], int offset, int *errorCount) { int i; int rc; const char *arg; getoptn_opt_t *opt; getoptn_info_t info; int ignorenext; info.style = style; info.argc = argc; info.argv = argv; info.optcount = optcount; info.opts = opts; info.optinfo = (getoptn_optinfo_t *) NULL; *errorCount = 0; if (optcount > 0) { info.optinfo = (getoptn_optinfo_t *) malloc (sizeof (getoptn_optinfo_t) * (Size_t) optcount); for (i = 0; i < info.optcount; ++i) { if (info.opts [i].option == NULL) { fprintf (stderr, "fatal error: null option\n"); exit (1); } info.optinfo [i].optionlen = strlen (info.opts [i].option); info.optinfo [i].idx = i; } } else { return 1 < argc ? 1 : -1; } for (info.optidx = offset; info.optidx < argc; info.optidx++) { arg = argv [info.optidx]; if (*arg != '-') { if (info.optinfo != (getoptn_optinfo_t *) NULL) { free (info.optinfo); } return info.optidx; } if (strcmp (arg, "--") == 0) { info.optidx++; if (info.optinfo != (getoptn_optinfo_t *) NULL) { free (info.optinfo); } return info.optidx; } info.argidx = 0; info.arg = arg; info.arglen = strlen (arg); info.reprocess = false; info.offset = 0; ignorenext = false; do { if (ignorenext) { ignorenext = false; continue; } i = find_option (&info, arg, arg, &info.argidx); if (opts [i].option_type == GETOPTN_IGNORE) { continue; } if (opts [i].option_type == GETOPTN_IGNORE_ARG) { ignorenext = true; continue; } if (i == GETOPTN_NOTFOUND) { if (info.reprocess == false) { fprintf (stderr, "%s: unknown option %s\n", argv [0], arg); ++*errorCount; } continue; } opt = &opts [i]; rc = process_opt (&info, opt, &info.optinfo [i]); if (rc) { ++*errorCount; } } while (info.reprocess); } if (info.optinfo != (getoptn_optinfo_t *) NULL) { free (info.optinfo); } return argc; } #if defined (TEST_GETOPTN) int main (int argc, char * argv []) { char tmp [40]; char s [40]; char s2 [5]; const char *sp; long l; double d; int i; int j; int k; int ec; int optidx; int ac; const char *av [20]; int grc = 0; int testno = 0; getoptn_opt_t opts [] = { { "-D", GETOPTN_STRING, &s, sizeof (s), (void * ) "abc123" }, { "-b", GETOPTN_BOOL, &i, sizeof (i), NULL }, { "--b", GETOPTN_BOOL, &i, sizeof (i), NULL }, { "-c", GETOPTN_BOOL, &j, sizeof (j), NULL }, { "--c", GETOPTN_ALIAS, (void * ) "-c", 0, NULL }, { "-bc", GETOPTN_BOOL, &k, sizeof (k), NULL }, { "-d", GETOPTN_DOUBLE, &d, sizeof (d), NULL }, { "-f1", GETOPTN_INT, &i, 8, NULL }, { "-f2", GETOPTN_LONG, &i, 2, NULL }, { "-f3", GETOPTN_LONG, &l, 12, NULL }, { "--i", GETOPTN_INT, &i, sizeof (i), NULL }, { "-i", GETOPTN_INT, &i, sizeof (i), NULL }, { "-i15",GETOPTN_INT, &j, sizeof (j), NULL }, { "-i17",GETOPTN_INT, &j, sizeof (j), NULL }, { "-l", GETOPTN_LONG, &l, sizeof (l), NULL }, { "-s", GETOPTN_STRING, &s, sizeof (s), NULL }, { "-sabcd", GETOPTN_BOOL, &i, sizeof (i), NULL }, { "-sp", GETOPTN_STRPTR, &sp, 0, NULL }, { "-p", GETOPTN_STRPTR, &sp, 0, NULL }, { "-S", GETOPTN_STRPTR, &sp, 0, (void * ) "abc1234" }, { "-s2", GETOPTN_STRING, &s2, sizeof (s2), NULL }, { "-np1", GETOPTN_STRING, NULL, sizeof (s2), NULL }, { "-np2", GETOPTN_FUNC_BOOL, NULL, sizeof (s2), NULL }, { "-np3", GETOPTN_FUNC_VALUE, NULL, sizeof (s2), NULL }, { "-z1", GETOPTN_ALIAS, (void * ) "--c", 0, NULL }, { "-z2", GETOPTN_ALIAS, (void * ) "-z1", 0, NULL }, { "-z3", GETOPTN_ALIAS, (void * ) "-z2", 0, NULL }, { "-w", GETOPTN_IGNORE, NULL, 0, NULL }, { "-W", GETOPTN_IGNORE_ARG, NULL, 0, NULL } }; /* test 1 */ ++testno; memset (s, '\0', sizeof (s)); ac = 2; Snprintf1 (tmp, sizeof (tmp), "test: %d", testno); av [0] = tmp; av [1] = "-D"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (strcmp (s, "abc123") != 0 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 2 */ ++testno; i = 0; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-b"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 1 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 3 */ ++testno; i = 0; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "--b"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 1 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 4 */ ++testno; i = 0; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "--i=13"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 13 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 5 */ ++testno; i = 0; ac = 3; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "--i"; av [2] = "14"; av [3] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 14 || optidx != 3 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 6 */ ++testno; i = 0; j = 0; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-i15"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 15 || j != 0 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 7 */ ++testno; i = 0; ac = 3; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-i"; av [2] = "16"; av [3] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 16 || optidx != 3 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 8 */ ++testno; i = 0; j = 0; ac = 3; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-i17"; av [2] = "5"; av [3] = NULL; ec = 0; optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 0 || j != 5 || optidx != 3 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 9 */ ++testno; i = 0; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-i=17"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 17 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 10 */ ++testno; i = 0; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-i7"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 7 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 11 */ ++testno; l = 0L; ac = 3; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-l"; av [2] = "19"; av [3] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (l != 19 || optidx != 3 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 12 */ ++testno; i = 0; j = 0; ac = 3; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-b"; av [2] = "-c"; av [3] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 1 || j != 1 || optidx != 3 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 13 */ ++testno; i = 0; j = 0; k = 0; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-bc"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 1 || j != 1 || k != 0 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 14 */ ++testno; i = 0; j = 0; k = 0; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-bc"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 0 || j != 0 || k != 1 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 15 */ ++testno; memset (s, '\0', sizeof (s)); ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-s=abc"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (strcmp (s, "abc") != 0 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 16 */ ++testno; d = 0.0; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-d=1.2"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (fabs (d - 1.2) > 0.00001 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d: %.2g %d\n", testno, d, optidx); grc = 1; } /* test 17 */ ++testno; memset (s, '\0', sizeof (s)); i = 0; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-sabcd"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (strcmp (s, "abcd") != 0 || i != 0 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 18 */ ++testno; memset (s, '\0', sizeof (s)); ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-s=abcde"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (strcmp (s, "abcde") != 0 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 19 */ ++testno; memset (s, '\0', sizeof (s)); ac = 3; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-s"; av [2] = "abcdef"; av [3] = NULL; ec = 0; optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (strcmp (s, "abcdef") != 0 || optidx != 3 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 20 */ ++testno; sp = ""; ac = 3; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-sp"; av [2] = "0123"; av [3] = NULL; ec = 0; optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (strcmp (sp, "0123") != 0 || optidx != 3 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 21 */ ++testno; sp = ""; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-sp=01234"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (strcmp (sp, "01234") != 0 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 22 */ ++testno; sp = ""; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-p012345"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (strcmp (sp, "012345") != 0 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 23 */ ++testno; sp = ""; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-S"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (strcmp (sp, "abc1234") != 0 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 24 */ ++testno; sp = ""; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-p=0123456"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (strcmp (sp, "0123456") != 0 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 25 */ ++testno; memset (s, '\0', sizeof (s)); i = 0; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-sabcd"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (strcmp (s, "") != 0 || i != 1 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 26 */ ++testno; i = 1; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-b"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 0 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 27 */ ++testno; i = 1; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "--b"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 0 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 28 */ ++testno; i = 1; j = 1; ac = 3; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-b"; av [2] = "-c"; av [3] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 0 || j != 0 || optidx != 3 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 29 */ ++testno; i = 1; j = 1; k = 1; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-bc"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 0 || j != 0 || k != 1 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d / i:%d j:%d k:%d optidx:%d ec:%d\n", testno, i, j, k, optidx, ec); grc = 1; } /* test 30 */ ++testno; i = 1; j = 1; k = 1; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-bc"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 1 || j != 1 || k != 0 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d / i:%d j:%d k:%d optidx:%d ec:%d\n", testno, i, j, k, optidx, ec); grc = 1; } /* test 31 - empty value */ ++testno; i = 0; j = 0; k = 0; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-i="; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 0 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d / i:%d optidx:%d ec:%d\n", testno, i, optidx, ec); grc = 1; } /* test 32 - no value; should print error */ ++testno; i = 0; j = 0; k = 0; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-i"; av [2] = NULL; ec = 0; fprintf (stderr, "** expect argument missing\n"); optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 0 || optidx != 2 || ec != 1) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 33 - wrong size; should print error */ ++testno; i = 0; j = 0; k = 0; l = 0L; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-f1=7"; av [2] = NULL; ec = 0; fprintf (stderr, "** expect invalid size\n"); optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 0 || l != 0 || optidx != 2 || ec != 1) { fprintf (stderr, "fail test %d; %d %ld %d\n", testno, i, l, optidx); grc = 1; } /* test 34 - wrong size; should print error */ ++testno; i = 0; j = 0; k = 0; l = 0L; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-f2=7"; av [2] = NULL; ec = 0; fprintf (stderr, "** expect invalid size\n"); optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 0 || l != 0 || optidx != 2 || ec != 1) { fprintf (stderr, "fail test %d; %d %ld %d\n", testno, i, l, optidx); grc = 1; } /* test 35 - wrong size; should print error */ ++testno; i = 0; j = 0; k = 0; l = 0L; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-f3=7"; av [2] = NULL; ec = 0; fprintf (stderr, "** expect invalid size\n"); optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 0 || l != 0 || optidx != 2 || ec != 1) { fprintf (stderr, "fail test %d; %d %ld %d\n", testno, i, l, optidx); grc = 1; } /* test 36 - end of options */ ++testno; i = 0; j = 0; k = 0; l = 0L; ac = 4; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-i=7"; av [2] = "--"; av [3] = "abc"; av [4] = NULL; ec = 0; optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 7 || optidx != 3 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 37 - no more options */ ++testno; i = 0; j = 0; k = 0; l = 0L; ac = 3; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-i=7"; av [2] = "abc"; av [3] = NULL; ec = 0; optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 7 || optidx != 2 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 38 - empty value followed by another option; returns the option */ ++testno; i = 0; j = 0; k = 0; memset (s, '\0', sizeof (s)); ac = 3; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-s"; av [2] = "-s"; av [3] = NULL; ec = 0; optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (strcmp (s, "-s") != 0 || optidx != 3 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 39 - unknown options */ ++testno; i = 0; j = 0; k = 0; memset (s, '\0', sizeof (s)); ac = 5; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-b"; av [2] = "-c"; av [3] = "-s"; av [4] = "abc"; av [5] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (strcmp (s, "abc") != 0 || i != 1 || j != 1 || optidx != 5 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 40 - legacy: mixed boolean + arg */ ++testno; i = 0; j = 0; k = 0; memset (s, '\0', sizeof (s)); ac = 3; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-bcs"; av [2] = "abc"; av [3] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (strcmp (s, "abc") != 0 || i != 1 || j != 1 || optidx != 3 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 41 */ ++testno; memset (s2, '\0', sizeof (s2)); ac = 3; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-s2"; av [2] = "abc"; av [3] = NULL; ec = 0; optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (strcmp (s2, "abc") != 0 || optidx != 3 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 42 - short string */ ++testno; memset (s2, '\0', sizeof (s2)); ac = 3; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-s2"; av [2] = "abcd"; av [3] = NULL; ec = 0; optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (strcmp (s2, "abcd") != 0 || optidx != 3 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 43 - short string */ ++testno; memset (s2, '\0', sizeof (s2)); ac = 3; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-s2"; av [2] = "abcde"; av [3] = NULL; ec = 0; optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (strcmp (s2, "abcd") != 0 || optidx != 3 || ec != 0) { fprintf (stderr, "fail test %d: %s\n", testno, s2); grc = 1; } /* test 44 - short string */ ++testno; memset (s2, '\0', sizeof (s2)); ac = 3; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-s2"; av [2] = "abcdef"; av [3] = NULL; ec = 0; optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (strcmp (s2, "abcd") != 0 || optidx != 3 || ec != 0) { fprintf (stderr, "fail test %d: %s\n", testno, s2); grc = 1; } /* test 45 - null ptr */ ++testno; memset (s2, '\0', sizeof (s2)); ac = 3; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-np1"; av [2] = "abcdef"; av [3] = NULL; ec = 0; fprintf (stderr, "** expect invalid pointer\n"); optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (strcmp (s2, "") != 0 || ec != 1) { fprintf (stderr, "fail test %d: %s %d\n", testno, s2, optidx); grc = 1; } /* test 46 - null ptr */ ++testno; memset (s2, '\0', sizeof (s2)); ac = 3; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-np2"; av [2] = "abcdef"; av [3] = NULL; ec = 0; fprintf (stderr, "** expect invalid function pointer\n"); optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (strcmp (s2, "") != 0 || ec != 1) { fprintf (stderr, "fail test %d: %s %d\n", testno, s2, optidx); grc = 1; } /* test 47 - null ptr */ ++testno; memset (s2, '\0', sizeof (s2)); ac = 3; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-np3"; av [2] = "abcdef"; av [3] = NULL; ec = 0; fprintf (stderr, "** expect invalid function pointer\n"); optidx = getoptn (GETOPTN_MODERN, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (strcmp (s2, "") != 0 || ec != 1) { fprintf (stderr, "fail test %d: %s %d\n", testno, s2, optidx); grc = 1; } /* test 48 - alias chain */ ++testno; i = 0; j = 0; k = 0; memset (s2, '\0', sizeof (s2)); ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-z3"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 0 || j != 1 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 49 - test boolean initial value */ ++testno; i = 0; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-c"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 0 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 50 - ignore */ ++testno; i = 0; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-w"; av [2] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 0 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 51 - ignore args */ ++testno; i = 0; ac = 4; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-w"; av [2] = "20"; av [3] = "-c"; av [4] = NULL; ec = 0; optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (i != 0 || ec != 0) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } /* test 52 - unknown argument */ ++testno; i = 0; ac = 2; Snprintf1 (tmp, sizeof (tmp), "test %d", testno); av [0] = tmp; av [1] = "-G"; av [2] = NULL; ec = 0; fprintf (stderr, "** expect unknown option\n"); optidx = getoptn (GETOPTN_LEGACY, ac, av, sizeof (opts) / sizeof (getoptn_opt_t), opts, 1, &ec); if (ec != 1) { fprintf (stderr, "fail test %d\n", testno); grc = 1; } return grc; } #endif /* TEST_GETOPTN */ di-6.0.0/digetinfo.c0000644000175000017500000003531614751661603012352 0ustar bllbll/* * Copyright 1994-2018 Brad Lanam, Walnut Creek, CA * Copyright 2023-2025 Brad Lanam, Pleasant Hill, CA */ /* * * In the cases where di_get_disk_entries () does not * get the volume information, di_get_disk_info () is used * to fetch the info. * * di_get_disk_info () * Gets the disk space used/available on the * partitions we want displayed. * */ #include "config.h" #if _hdr_stdio # include #endif #if _hdr_stdlib # include #endif #if _sys_types \ && ! defined (DI_INC_SYS_TYPES_H) /* xenix */ # define DI_INC_SYS_TYPES_H # include #endif #if _sys_param # include #endif #if _hdr_errno # include #endif #if _hdr_string # include #endif #if _hdr_strings # include #endif /* FreeBSD, OpenBSD, old NetBSD, HP-UX, MacOS */ #if _sys_mount && ! defined (DI_INC_SYS_MOUNT) # define DI_INC_SYS_MOUNT 1 # include /* statfs (); struct statfs; getfsstat () */ #endif #if _sys_statvfs /* Linux, Solaris, FreeBSD, NetBSD, HP-UX */ # include /* statvfs (); struct statvfs */ #endif #if _sys_vfs /* Linux, HP-UX, BSD 4.3 */ # include /* struct statfs */ #endif #if _sys_statfs && ! _sys_statvfs /* Linux, SysV.3 */ # include /* statfs (); struct statfs */ #endif #if _sys_fstyp /* SysV.3 */ # include /* sysfs () */ #endif #if _hdr_windows /* windows */ # include /* GetDiskFreeSpace (); GetVolumeInformation () */ #endif #include "di.h" #include "disystem.h" #include "diinternal.h" #include "dimntopt.h" #include "distrutils.h" #if defined (__cplusplus) || defined (c_plusplus) extern "C" { #endif #if ! _lib_statvfs \ && _lib_statfs \ && _npt_statfs # if _lib_statfs && _args_statfs == 2 extern int statfs (char *, struct statfs *); # endif # if _lib_statfs && _args_statfs == 3 extern int statfs (char *, struct statfs *, int); # endif # if _lib_statfs && _args_statfs == 4 extern int statfs (char *, struct statfs *, int, int); # endif #endif #if defined (__cplusplus) || defined (c_plusplus) } #endif #if _lib_statvfs \ && ! _lib_fs_stat_dev \ && ! _lib_getmntinfo \ && ! (_lib_getfsstat && (_getfsstat_type_int || _getfsstat_type_long)) \ && ! _lib_getvfsstat \ && ! _lib_GetVolumeInformation /* * di_get_disk_info * * SysV.4. statvfs () returns both the free and available blocks. * Solaris, Linux * */ # define DI_GETDISKINFO_DEF 1 void di_get_disk_info (di_data_t *di_data, int *diCount) { di_disk_info_t *diptr; int i; Statvfs_t statBuf; di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; if (diopts->optval [DI_OPT_DEBUG] > 0) { printf ("# di_get_disk_info: statvfs\n"); } for (i = 0; i < *diCount; ++i) { diptr = di_data->diskInfo + i; if (diptr->printFlag == DI_PRNT_OK || diptr->printFlag == DI_PRNT_SKIP || diptr->printFlag == DI_PRNT_FORCE) { di_ui_t tblocksz; if (statvfs (diptr->strdata [DI_DISP_MOUNTPT], &statBuf) == 0) { /* data general DG/UX 5.4R3.00 sometime returns 0 */ /* in the fragment size field. */ if (statBuf.f_frsize == 0 && statBuf.f_bsize != 0) { tblocksz = statBuf.f_bsize; } else { tblocksz = statBuf.f_frsize; } /* Linux! statvfs () returns values in f_bsize rather f_frsize. Bleah. */ /* Non-POSIX! Linux manual pages are incorrect. */ # if defined (linux) tblocksz = statBuf.f_bsize; # endif /* linux */ di_save_block_sizes (diptr, tblocksz, (di_ui_t) statBuf.f_blocks, (di_ui_t) statBuf.f_bfree, (di_ui_t) statBuf.f_bavail); di_save_inode_sizes (diptr, (di_ui_t) statBuf.f_files, (di_ui_t) statBuf.f_ffree, (di_ui_t) statBuf.f_favail); # if _mem_struct_statvfs_f_basetype if (! *diptr->strdata [DI_DISP_FSTYPE]) { stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, statBuf.f_basetype); } # endif if (diopts->optval [DI_OPT_DEBUG] > 1) { printf ("%s: %s\n", diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_FSTYPE]); printf ("\tbsize:%ld frsize:%ld\n", (long) statBuf.f_bsize, (long) statBuf.f_frsize); # if _siz_long_long >= 8 printf ("\tblocks: tot:%llu free:%lld avail:%llu\n", (unsigned long long) statBuf.f_blocks, (long long) statBuf.f_bfree, (unsigned long long) statBuf.f_bavail); printf ("\tinodes: tot:%llu free:%llu avail:%llu\n", (unsigned long long) statBuf.f_files, (unsigned long long) statBuf.f_ffree, (unsigned long long) statBuf.f_favail); # else printf ("\tblocks: tot:%lu free:%lu avail:%lu\n", (unsigned long) statBuf.f_blocks, (unsigned long) statBuf.f_bfree, (unsigned long) statBuf.f_bavail); printf ("\tinodes: tot:%lu free:%lu avail:%lu\n", (unsigned long) statBuf.f_files, (unsigned long) statBuf.f_ffree, (unsigned long) statBuf.f_favail); # endif } } else { diptr->printFlag = DI_PRNT_BAD; if (errno != EACCES && errno != EPERM) { fprintf (stderr, "statvfs: %s ", diptr->strdata [DI_DISP_MOUNTPT]); perror (""); } } } } /* for each entry */ } #endif /* _lib_statvfs */ #if _lib_statfs && _args_statfs == 4 \ && ! _lib_statvfs \ && ! _lib_getmntinfo \ && ! (_lib_getfsstat && (_getfsstat_type_int || _getfsstat_type_long)) \ && ! _lib_getvfsstat \ && ! _lib_getmnt /* xenix reports a block size of 1024 bytes, but the blocks reported */ /* are based on a 512 byte block size. */ # if defined (M_XENIX) # define UBSIZE 512 # else # if ! defined (UBSIZE) # if defined (BSIZE) # define UBSIZE BSIZE # else # define UBSIZE 512 # endif # endif # endif /* * di_get_disk_info * * SysV.3. We don't have available blocks; just set it to free blocks. * The sysfs () call is used to get the disk type name. * */ # define DI_GETDISKINFO_DEF 1 void di_get_disk_info (di_data_t *di_data, int *diCount) { di_disk_info_t *diptr; int i; struct statfs statBuf; di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; if (diopts->optval [DI_OPT_DEBUG] > 0) { printf ("# di_get_disk_info: sysv-statfs 4arg\n"); } for (i = 0; i < *diCount; ++i) { diptr = di_data->diskInfo + i; if (diptr->printFlag == DI_PRNT_OK || diptr->printFlag == DI_PRNT_SKIP || diptr->printFlag == DI_PRNT_FORCE) { dinum_t tblocksz; if (statfs (diptr->strdata [DI_DISP_MOUNTPT], &statBuf, sizeof (statBuf), 0) == 0) { # if _mem_struct_statfs_f_frsize if (statBuf.f_frsize == 0 && statBuf.f_bsize != 0) { tblocksz = (dinum_t) statBuf.f_bsize; } else { tblocksz = (dinum_t) statBuf.f_frsize; } # else tblocksz = UBSIZE; # endif di_save_block_sizes (diptr, tblocksz, statBuf.f_blocks, statBuf.f_bfree, statBuf.f_bfree); di_save_inode_sizes (diptr, statBuf.f_files, statBuf.f_ffree, statBuf.f_ffree); # if _lib_sysfs && _mem_struct_statfs_f_fstyp sysfs (GETFSTYP, statBuf.f_fstyp, diptr->strdata [DI_DISP_FSTYPE]); # endif if (diopts->optval [DI_OPT_DEBUG] > 1) { printf ("%s: %s\n", diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_FSTYPE]); # if _mem_struct_statfs_f_frsize printf ("\tbsize:%ld\n", statBuf.f_bsize); printf ("\tfrsize:%ld\n", statBuf.f_frsize); # else printf ("\tUBSIZE:%ld\n", UBSIZE); # endif printf ("\tblocks: tot:%ld free:%ld\n", statBuf.f_blocks, statBuf.f_bfree); printf ("\tinodes: tot:%ld free:%ld\n", statBuf.f_files, statBuf.f_ffree); } } /* if we got the info */ else { diptr->printFlag = DI_PRNT_BAD; if (errno != EACCES && errno != EPERM) { fprintf (stderr, "statfs: %s ", diptr->strdata [DI_DISP_MOUNTPT]); perror (""); } } } } /* for each entry */ } #endif /* _args_statfs == 4 */ #if _lib_statfs && (_args_statfs == 2 || _args_statfs == 3) \ && ! _lib_statvfs \ && ! _lib_getmntinfo \ && ! (_lib_getfsstat && (_getfsstat_type_int || _getfsstat_type_long)) \ && ! _lib_getmnt \ && ! _lib_GetDiskFreeSpace \ && ! _lib_GetDiskFreeSpaceEx /* * di_get_disk_info * * SunOS/BSD/Pyramid/Some Linux * */ # define DI_GETDISKINFO_DEF 1 void di_get_disk_info (di_data_t *di_data, int *diCount) { di_disk_info_t *diptr; int i; struct statfs statBuf; di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; if (diopts->optval [DI_OPT_DEBUG] > 0) { printf ("# di_get_disk_info: bsd-statfs 2/3arg\n"); } for (i = 0; i < *diCount; ++i) { diptr = di_data->diskInfo + i; if (diptr->printFlag == DI_PRNT_OK || diptr->printFlag == DI_PRNT_SKIP || diptr->printFlag == DI_PRNT_FORCE) { if (statfs (diptr->strdata [DI_DISP_MOUNTPT], &statBuf) == 0) { di_save_block_sizes (diptr, statBuf.f_bsize, statBuf.f_blocks, statBuf.f_bfree, statBuf.f_bavail); di_save_inode_sizes (diptr, statBuf.f_files, statBuf.f_ffree, statBuf.f_ffree); # if _lib_sysfs && _mem_struct_statfs_f_fstyp sysfs (GETFSTYP, statBuf.f_fstyp, diptr->strdata [DI_DISP_FSTYPE]); # endif if (diopts->optval [DI_OPT_DEBUG] > 1) { printf ("%s: %s\n", diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_FSTYPE]); printf ("\tbsize:%ld\n", (long) statBuf.f_bsize); printf ("\tblocks: tot:%ld free:%ld avail:%ld\n", (long) statBuf.f_blocks, (long) statBuf.f_bfree, (long) statBuf.f_bavail); printf ("\tinodes: tot:%ld free:%ld\n", (long) statBuf.f_files, (long) statBuf.f_ffree); } } /* if we got the info */ else { diptr->printFlag = DI_PRNT_BAD; if (errno != EACCES && errno != EPERM) { fprintf (stderr, "statfs: %s ", diptr->strdata [DI_DISP_MOUNTPT]); perror (""); } } } } /* for each entry */ } #endif /* _args_statfs == 2 or 3 */ #if _lib_GetVolumeInformation /* * di_get_disk_info * * Windows * */ # define DI_GETDISKINFO_DEF 1 # define MSDOS_BUFFER_SIZE 256 void di_get_disk_info (di_data_t *di_data, int *diCount) { di_disk_info_t *diptr; int i; int rc; char volName [MSDOS_BUFFER_SIZE]; char fsName [MSDOS_BUFFER_SIZE]; DWORD serialNo; DWORD maxCompLen; DWORD fsFlags; di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; # if _lib_GetDiskFreeSpaceEx if (diopts->optval [DI_OPT_DEBUG] > 0) { printf ("# di_get_disk_info: GetDiskFreeSpaceEx\n"); } # endif # if _lib_GetDiskFreeSpace if (diopts->optval [DI_OPT_DEBUG] > 0) { printf ("# di_get_disk_info: GetDiskFreeSpace\n"); } # endif if (diopts->optval [DI_OPT_DEBUG] > 0) { printf ("# di_get_disk_info: GetVolumeInformation\n"); } for (i = 0; i < *diCount; ++i) { diptr = di_data->diskInfo + i; if (diptr->printFlag == DI_PRNT_OK || diptr->printFlag == DI_PRNT_SKIP || diptr->printFlag == DI_PRNT_FORCE) { rc = GetVolumeInformation (diptr->strdata [DI_DISP_MOUNTPT], volName, MSDOS_BUFFER_SIZE, &serialNo, &maxCompLen, &fsFlags, fsName, MSDOS_BUFFER_SIZE); stpecpy (diptr->strdata [DI_DISP_FSTYPE], diptr->strdata [DI_DISP_FSTYPE] + DI_FSTYPE_LEN, fsName); stpecpy (diptr->strdata [DI_DISP_FILESYSTEM], diptr->strdata [DI_DISP_FILESYSTEM] + DI_FILESYSTEM_LEN, volName); # if _lib_GetDiskFreeSpaceEx { ULONGLONG bytesAvail; ULONGLONG bytesTotal; ULONGLONG bytesFree; rc = GetDiskFreeSpaceEx (diptr->strdata [DI_DISP_MOUNTPT], (PULARGE_INTEGER) &bytesAvail, (PULARGE_INTEGER) &bytesTotal, (PULARGE_INTEGER) &bytesFree); if (rc > 0) { di_save_block_sizes (diptr, 1, bytesTotal, bytesFree, bytesAvail); di_save_inode_sizes (diptr, 0, 0, 0); } else { diptr->printFlag = DI_PRNT_BAD; if (diopts->optval [DI_OPT_DEBUG]) { printf ("disk %s; could not get disk space\n", diptr->strdata [DI_DISP_MOUNTPT]); } } if (diopts->optval [DI_OPT_DEBUG] > 1) { printf ("%s: %s\n", diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_FSTYPE]); printf ("\ttot:%llu free:%llu\n", bytesTotal, bytesFree); printf ("\tavail:%llu\n", bytesAvail); } } # else # if _lib_GetDiskFreeSpace { unsigned long sectorspercluster; unsigned long bytespersector; unsigned long totalclusters; unsigned long freeclusters; rc = GetDiskFreeSpace (diptr->strdata [DI_DISP_MOUNTPT], (LPDWORD) §orspercluster, (LPDWORD) &bytespersector, (LPDWORD) &freeclusters, (LPDWORD) &totalclusters); if (rc > 0) { di_save_block_sizes (diptr, (sectorspercluster * bytespersector), totalclusters, freeclusters, freeclusters); di_save_inode_sizes (diptr, 0, 0, 0); } else { diptr->printFlag = DI_PRNT_BAD; if (diopts->optval [DI_OPT_DEBUG]) { printf ("disk %s; could not get disk space\n", diptr->strdata [DI_DISP_MOUNTPT]); } } if (diopts->optval [DI_OPT_DEBUG] > 1) { printf ("%s: %s\n", diptr->strdata [DI_DISP_MOUNTPT], diptr->strdata [DI_DISP_FSTYPE]); printf ("\ts/c:%ld b/s:%ld\n", sectorspercluster, bytespersector); printf ("\tclusters: tot:%ld free:%ld\n", totalclusters, freeclusters); } } # endif # endif } /* if printable drive */ } /* for each mounted drive */ } #endif /* _lib_GetVolumeInformation */ #if ! defined (DI_GETDISKINFO_DEF) void di_get_disk_info (di_data_t *di_data, int *diCount) { di_opt_t *diopts; diopts = (di_opt_t *) di_data->options; if (diopts->optval [DI_OPT_DEBUG] > 0) { printf ("# di_get_disk_info: empty\n"); } return; } #endif di-6.0.0/didiskutil.c0000644000175000017500000002625114761620460012542 0ustar bllbll/* * Copyright 1994-2018 Brad Lanam, Walnut Creek, CA * Copyright 2023-2025 Brad Lanam, Pleasant Hill, CA */ #include "config.h" #if _hdr_stdio # include #endif #if _hdr_stdlib # include #endif #if _hdr_stdbool # include #endif #if _hdr_string # include #endif #if _hdr_strings # include #endif #if _hdr_memory # include #endif #if _hdr_malloc # include #endif #if _hdr_errno # include #endif #include "di.h" #include "disystem.h" #include "diinternal.h" #include "distrutils.h" #include "dimath.h" #include "dimntopt.h" /* * This module contains utility routines for conversion * and checking the data. * * di_initialize_disk_info () * initialize disk info structure * di_save_block_sizes () * save the block sizes in the diskinfo structure. * di_save_inode_sizes () * save the inode sizes in the diskinfo structure. * convertMountOptions () * converts mount options to text format. * convertNFSMountOptions () * converts NFS mount options to text format. * chkMountOptions () * Checks to see if the mount option is set. * Used if hasmntopt () is not present. * di_is_remote_disk () * test a disk to see if it is remote (nfs, nfs3). * */ void di_initialize_disk_info (di_disk_info_t *diptr, int idx) { int i; memset ( (char *) diptr, '\0', sizeof (di_disk_info_t)); diptr->sortIndex [DI_SORT_MAIN] = idx; diptr->sortIndex [DI_SORT_TOTAL] = idx; for (i = 0; i < DI_VALUE_MAX; ++i) { dinum_init (&diptr->values [i]); } diptr->doPrint = 0; diptr->printFlag = DI_PRNT_OK; diptr->isLocal = true; diptr->isReadOnly = false; diptr->isLoopback = false; diptr->strdata [DI_DISP_MOUNTPT] = (char *) malloc (DI_MOUNTPT_LEN); diptr->strdata [DI_DISP_FILESYSTEM] = (char *) malloc (DI_FILESYSTEM_LEN); diptr->strdata [DI_DISP_MOUNTOPT] = (char *) malloc (DI_MOUNTOPT_LEN); diptr->strdata [DI_DISP_FSTYPE] = (char *) malloc (DI_FSTYPE_LEN); for (i = 0; i < DI_DISP_MAX; ++i) { diptr->strdata [i][0] = '\0'; } } void di_free_disk_info (di_disk_info_t *diptr) { int i; if (diptr == NULL) { return; } for (i = 0; i < DI_VALUE_MAX; ++i) { dinum_clear (&diptr->values [i]); } if (diptr->strdata [DI_DISP_MOUNTPT] != NULL) { free (diptr->strdata [DI_DISP_MOUNTPT]); } if (diptr->strdata [DI_DISP_FILESYSTEM] != NULL) { free (diptr->strdata [DI_DISP_FILESYSTEM]); } if (diptr->strdata [DI_DISP_FSTYPE] != NULL) { free (diptr->strdata [DI_DISP_FSTYPE]); } if (diptr->strdata [DI_DISP_MOUNTOPT] != NULL) { free (diptr->strdata [DI_DISP_MOUNTOPT]); } } void di_save_block_sizes (di_disk_info_t *diptr, di_ui_t block_size, di_ui_t total_blocks, di_ui_t free_blocks, di_ui_t avail_blocks) { dinum_mul_uu (&diptr->values [DI_SPACE_TOTAL], total_blocks, block_size); dinum_mul_uu (&diptr->values [DI_SPACE_FREE], free_blocks, block_size); dinum_mul_uu (&diptr->values [DI_SPACE_AVAIL], avail_blocks, block_size); } void di_save_inode_sizes (di_disk_info_t *diptr, di_ui_t total_nodes, di_ui_t free_nodes, di_ui_t avail_nodes) { dinum_set_u (&diptr->values [DI_INODE_TOTAL], total_nodes); dinum_set_u (&diptr->values [DI_INODE_FREE], free_nodes); dinum_set_u (&diptr->values [DI_INODE_AVAIL], avail_nodes); } void convertMountOptions (unsigned long flags, di_disk_info_t *diptr) { char *p; char *end; p = diptr->strdata [DI_DISP_MOUNTOPT]; end = diptr->strdata [DI_DISP_MOUNTOPT] + DI_MOUNTOPT_LEN; #if defined (MNT_RDONLY) if ((flags & MNT_RDONLY) == MNT_RDONLY) { p = stpecpy (p, end, "ro,"); } else { p = stpecpy (p, end, "rw,"); } #endif #if defined (MNT_EXRDONLY) if ((flags & MNT_EXRDONLY) == MNT_EXRDONLY) { p = stpecpy (p, end, "expro,"); } #endif #if defined (MNT_DEFEXPORTED) if ((flags & MNT_DEFEXPORTED) == MNT_DEFEXPORTED) { p = stpecpy (p, end, "exprwany,"); } #endif #if defined (MNT_EXPORTANON) if ((flags & MNT_EXPORTANON) == MNT_EXPORTANON) { p = stpecpy (p, end, "expanon,"); } #endif #if defined (MNT_EXKERB) if ((flags & MNT_EXKERB) == MNT_EXKERB) { p = stpecpy (p, end, "expkerb,"); } #endif #if defined (MNT_FORCE) if ((flags & MNT_FORCE) == MNT_FORCE) { p = stpecpy (p, end, "force,"); } #endif #if defined (MNT_GRPID) if ((flags & MNT_GRPID) == MNT_GRPID) { p = stpecpy (p, end, "grpid,"); } #endif #if defined (MNT_MAGICLINKS) if ((flags & MNT_MAGICLINKS) == MNT_MAGICLINKS) { p = stpecpy (p, end, "magiclinks,"); } #endif #if defined (MNT_MLSD) if ((flags & MNT_MLSD) == MNT_MLSD) { p = stpecpy (p, end, "mlsd,"); } #endif #if defined (MNT_NOATIMES) if ((flags & MNT_NOATIMES) == MNT_NOATIMES) { p = stpecpy (p, end, "noatime,"); } #endif #if defined (MNT_NOCACHE) if ((flags & MNT_NOCACHE) == MNT_NOCACHE) { p = stpecpy (p, end, "nocache,"); } #endif #if defined (MNT_NOCOREDUMP) if ((flags & MNT_NOCOREDUMP) == MNT_NOCOREDUMP) { p = stpecpy (p, end, "nocoredump,"); } #endif #if defined (MNT_NODEV) if ((flags & MNT_NODEV) == MNT_NODEV) { p = stpecpy (p, end, "nodev,"); } #endif #if defined (MNT_NODEVMTIME) if ((flags & MNT_NODEVMTIME) == MNT_NODEVMTIME) { p = stpecpy (p, end, "nodevmtime,"); } #endif #if defined (MNT_NOEXEC) if ((flags & MNT_NOEXEC) == MNT_NOEXEC) { p = stpecpy (p, end, "noexec,"); } #endif #if defined (MNT_NOSUID) if ((flags & MNT_NOSUID) == MNT_NOSUID) { p = stpecpy (p, end, "nosuid,"); } #endif #if defined (MNT_QUOTA) if ((flags & MNT_QUOTA) == MNT_QUOTA) { p = stpecpy (p, end, "quota,"); } #endif #if defined (MNT_SECURE) if ((flags & MNT_SECURE) == MNT_SECURE) { p = stpecpy (p, end, "secure,"); } #endif #if defined (MNT_SMSYNC2) if ((flags & MNT_SMSYNC2) == MNT_SMSYNC2) { p = stpecpy (p, end, "smsync2,"); } #endif #if defined (MNT_SOFTDEP) if ((flags & MNT_SOFTDEP) == MNT_SOFTDEP) { p = stpecpy (p, end, "softdep,"); } #endif #if defined (MNT_SYMPERM) if ((flags & MNT_SYMPERM) == MNT_SYMPERM) { p = stpecpy (p, end, "symperm,"); } #endif #if defined (MNT_SYNC) if ((flags & MNT_SYNC) == MNT_SYNC) { p = stpecpy (p, end, "sync,"); } #endif #if defined (MNT_SYNCHRONOUS) if ((flags & MNT_SYNCHRONOUS) == MNT_SYNCHRONOUS) { p = stpecpy (p, end, "sync,"); } #endif #if defined (MNT_THROTTLE) if ((flags & MNT_THROTTLE) == MNT_THROTTLE) { p = stpecpy (p, end, "throttle,"); } #endif #if defined (MNT_UNION) if ((flags & MNT_UNION) == MNT_UNION) { p = stpecpy (p, end, "union,"); } #endif #if defined (MNT_UNION) if ((flags & MNT_UNION) == MNT_UNION) { p = stpecpy (p, end, "union,"); } #endif #if defined (MNT_REMOVABLE) if ((flags & MNT_REMOVABLE) == MNT_REMOVABLE) { p = stpecpy (p, end, "removable,"); } #endif #if defined (MNT_PERSISTENT) if ((flags & MNT_PERSISTENT) == MNT_PERSISTENT) { p = stpecpy (p, end, "persistent,"); } #endif #if defined (MNT_SHARED) if ((flags & MNT_SHARED) == MNT_SHARED) { p = stpecpy (p, end, "shared,"); } #endif #if defined (MNT_BLOCKBASED) if ((flags & MNT_BLOCKBASED) == MNT_BLOCKBASED) { p = stpecpy (p, end, "blockbased,"); } #endif #if defined (MNT_HAS_MIME) if ((flags & MNT_HAS_MIME) == MNT_HAS_MIME) { p = stpecpy (p, end, "mime,"); } #endif #if defined (MNT_HAS_QUERY) if ((flags & MNT_HAS_QUERY) == MNT_HAS_QUERY) { p = stpecpy (p, end, "query,"); } #endif #if defined (MNT_HAS_ATTR) if ((flags & MNT_HAS_ATTR) == MNT_HAS_ATTR) { p = stpecpy (p, end, "attr,"); } #endif return; } void convertNFSMountOptions (long flags, long wsize, long rsize, di_disk_info_t *diptr) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunknown-warning-option" #pragma clang diagnostic ignored "-Wunused-but-set-variable" char *p; char *end; p = diptr->strdata [DI_DISP_MOUNTOPT]; end = diptr->strdata [DI_DISP_MOUNTOPT] + DI_MOUNTOPT_LEN; #pragma clang diagnostic pop #if defined (NFSMNT_SOFT) if ((flags & NFSMNT_SOFT) != NFSMNT_SOFT) { p = stpecpy (p, end, "hard,"); } #endif #if defined (NFSMNT_WSIZE) if ((flags & NFSMNT_WSIZE) == NFSMNT_WSIZE) { char tmp [64]; Snprintf1 (tmp, sizeof (tmp), "wsize=%ld,", wsize); p = stpecpy (p, end, tmp); } #endif #if defined (NFSMNT_RSIZE) if ((flags & NFSMNT_RSIZE) == NFSMNT_RSIZE) { char tmp [64]; Snprintf1 (tmp, sizeof (tmp), "rsize=%ld,", rsize); p = stpecpy (p, end, tmp); } #endif #if defined (NFSMNT_INT) && defined (NFSMNT_SOFT) if ((flags & NFSMNT_SOFT) != NFSMNT_SOFT && (flags & NFSMNT_INT) == NFSMNT_INT) { p = stpecpy (p, end, "intr,"); } #endif #if defined (NFSMNT_TCP) if ((flags & NFSMNT_TCP) != NFSMNT_TCP) { p = stpecpy (p, end, "udp,"); } #endif return; } #if _lib_getmntent \ && ! _lib_getmntinfo \ && ! _lib_getfsstat \ && ! _lib_getvfsstat \ && ! _lib_mntctl char * chkMountOptions (const char *mntopts, const char *str) { char *ptr; char *tstr; char *tokstr = NULL; tstr = strdup (mntopts); if (tstr == (char *) NULL) { fprintf (stderr, "strdup failed in chkMountOptions (1). errno %d\n", errno); exit (1); } ptr = di_strtok (tstr, ",", &tokstr); while (ptr != (char *) NULL) { if (strcmp (ptr, str) == 0) { free (tstr); return ptr; } ptr = di_strtok ((char *) NULL, ",", &tokstr); } free (tstr); return (char *) NULL; } #endif /* _lib_getmntent */ void di_is_remote_disk (di_disk_info_t *diskInfo) { if (strncmp (diskInfo->strdata [DI_DISP_FSTYPE], "nfs", 3) == 0) { diskInfo->isLocal = false; } } int di_isPooledFs (di_disk_info_t *diskInfo) { if (strcmp (diskInfo->strdata [DI_DISP_FSTYPE], "zfs") == 0 || strcmp (diskInfo->strdata [DI_DISP_FSTYPE], "advfs") == 0 || strcmp (diskInfo->strdata [DI_DISP_FSTYPE], "apfs") == 0 || (strcmp (diskInfo->strdata [DI_DISP_FSTYPE], "null") == 0 && strstr (diskInfo->strdata [DI_DISP_FILESYSTEM], "/@@-") != (char *) NULL)) { return true; } return false; } int di_isLoopbackFs (di_disk_info_t *diskInfo) { if ((strcmp (diskInfo->strdata [DI_DISP_FSTYPE], "lofs") == 0 && diskInfo->sp_rdev != 0) || (strcmp (diskInfo->strdata [DI_DISP_FSTYPE], "nullfs") == 0 && strstr (diskInfo->strdata [DI_DISP_FILESYSTEM], "/@@-") == (char *) NULL) || strcmp (diskInfo->strdata [DI_DISP_FSTYPE], "none") == 0) { return true; } return false; } Size_t di_mungePoolName (char *poolname) { char *ptr; ptr = strchr (poolname, '#'); /* advfs */ if (ptr != (char *) NULL) { *ptr = '\0'; } else { ptr = strchr (poolname, ':'); /* dragonflybsd */ if (ptr != (char *) NULL) { *ptr = '\0'; } else { if (strncmp (poolname, "/dev/disk", 9) == 0) { /* apfs uses a standard /dev/diskNsN format */ ptr = strchr (poolname, 's'); if (ptr != (char *) NULL) { ++ptr; if (ptr != (char *) NULL) { ptr = strchr (ptr, 's'); if (ptr != (char *) NULL) { *ptr = '\0'; } } } } else { ptr = strchr (poolname, '/'); /* zfs */ if (ptr != (char *) NULL) { *ptr = '\0'; } } } } return strlen (poolname); } di-6.0.0/utils/0000755000175000017500000000000014763624477011401 5ustar bllblldi-6.0.0/utils/instman.sh0000755000175000017500000000162414756220103013370 0ustar bllbll#!/bin/sh prefix=$1 mandir=$2 grc=0 if [ "x${prefix}" = x ]; then echo "prefix is not set" exit 1 fi if [ "x${mandir}" = x ]; then echo "mandir is not set" exit 1 fi systype=`uname -s` case ${systype} in NetBSD) # netbsd uses /usr/pkg/man mandir="${prefix}/man" ;; OpenBSD) # openbsd cmake puts the man pages at the top level. # match what cmake does. # I don't know why there is a mis-match between cmake and where # the os puts the system manual pages. mandir="${prefix}/man" ;; esac instmandir="${mandir}" if [ ! "x${DESTDIR}" = x ]; then instmandir="${DESTDIR}/${mandir}" fi test -d ${instmandir}/man1 || mkdir -p ${instmandir}/man1 cp -f man/di.1 ${instmandir}/man1/ rc=$? if [ $rc -ne 0 ]; then grc=1 fi test -d ${instmandir}/man3 || mkdir -p ${instmandir}/man3 cp -f man/libdi.3 ${instmandir}/man3/ rc=$? if [ $rc -ne 0 ]; then grc=1 fi exit $grc di-6.0.0/utils/chkcmake.sh0000755000175000017500000000336214755124417013500 0ustar bllbll#!/bin/sh # # Copyright 2025 Brad Lanam Pleasant Hill CA # CMAKE_REQ_MAJ_VERSION=$1 CMAKE_REQ_MIN_VERSION=$2 export CMAKE_REQ_MAJ_VERSION export CMAKE_REQ_MIN_VERSION if [ x"$CMAKE_REQ_MAJ_VERSION" = x ]; then echo "chkcmake.sh: no max version specified" exit 1 fi if [ x"$CMAKE_REQ_MIN_VERSION" = x ]; then echo "chkcmake.sh: no min version specified" exit 1 fi cmvers=`cmake --version 2>/dev/null` if [ x"$cmvers" = x ]; then echo "mkc" exit 0 fi PATH=/opt/local/bin:/opt/homebrew/bin:/usr/local/bin:/usr/pkg/bin:$PATH # need a more modern version of awk... awkcmd=`which gawk 2>/dev/null` rc=$? if [ $rc -ne 0 -o "x$awkcmd" = x ]; then awkcmd=`which nawk 2>/dev/null` rc=$? if [ $rc -ne 0 -o "x$awkcmd" = x ]; then awkcmd=`which awk 2>/dev/null` rc=$? if [ $rc -ne 0 -o "x$awkcmd" = x ]; then # maybe the which command is not there... # try some common spots if [ -f /usr/bin/gawk ]; then awkcmd=gawk fi if [ "x$awkcmd" = x -a -f /usr/bin/nawk ]; then awkcmd=nawk fi if [ "x$awkcmd" = x -a -f /usr/bin/awk ]; then awkcmd=awk fi fi fi fi # no good awk, assume cmake is ng as well. if [ "x$awkcmd" = x ]; then echo "mkc" exit 0 fi echo "$cmvers" | ${awkcmd} ' BEGIN { reqmaj = ENVIRON["CMAKE_REQ_MAJ_VERSION"]; reqmin = ENVIRON["CMAKE_REQ_MIN_VERSION"]; } /version/ { gsub (/^[^0-9]*/, ""); gsub (/[^0-9.].*$/, ""); maj = $0; min = $0; gsub (/\..*$/, "", maj); gsub (/^[0-9]*/, "", min); gsub (/^\./, "", min); gsub (/\..*$/, "", min); rc = 1; # have to make sure it is a numeric comparison if (maj+0 >= reqmaj+0 && min+0 >= reqmin+0) { rc = 0; } exit rc; } ' rc=$? if [ $rc -eq 0 ]; then echo "cmake" else echo "mkc" fi di-6.0.0/utils/instpo.sh0000755000175000017500000000367214754723473013260 0ustar bllbll#!/bin/sh # # Copyright 2025 Brad Lanam Pleasant Hill CA # PODIR=$1 INST_LOCALEDIR=$2 TMPPODIR=$3 if [ "x${PODIR}" = x ]; then echo "instpo.sh: No po/ dir specified" exit 1 fi if [ ! -d "${PODIR}" ]; then echo "instpo.sh: po/ dir does not exist" exit 1 fi if [ "x${INST_LOCALEDIR}" = x ]; then echo "instpo.sh: No locale dir specified" exit 1 fi if [ "x${TMPPODIR}" = x ]; then echo "instpo.sh: No temporary dir specified" exit 1 fi if [ ! "x${DESTDIR}" = x ]; then INST_LOCALEDIR="${DESTDIR}/${INST_LOCALEDIR}" fi msgfmtcmd=`which gmsgfmt 2>/dev/null` rc=$? if [ $rc -ne 0 -o "x$msgfmtcmd" = x ]; then msgfmtcmd=`which msgfmt 2>/dev/null` rc=$? if [ $rc -ne 0 -o "x$msgfmtcmd" = x ]; then # maybe the which command is not there... # try some common spots if [ "x$msgfmtcmd" = x -a -f /usr/bin/msgfmt ]; then msgfmtcmd=/usr/bin/msgfmt fi if [ "x$msgfmtcmd" = x -a -f /opt/local/bin/msgfmt ]; then msgfmtcmd=/opt/local/bin/msgfmt fi if [ "x$msgfmtcmd" = x -a -f /opt/homebrew/bin/msgfmt ]; then msgfmtcmd=/opt/homebrew/bin/msgfmt fi if [ "x$msgfmtcmd" = x -a -f /usr/local/bin/msgfmt ]; then msgfmtcmd=/usr/local/bin/msgfmt fi fi fi if [ "x$msgfmtcmd" = x ]; then echo "instpo.sh: Unable to locate msgfmt command" exit 1 fi cd "${PODIR}" rc=$? if [ $rc -ne 0 ]; then echo "No po/ directory." exit 0 fi test -d "${INST_LOCALEDIR}" || mkdir -p "${INST_LOCALEDIR}" test -d "${TMPPODIR}" || mkdir -p "${TMPPODIR}" for i in *.po; do j=`echo $i | sed 's,\\.po$,,'` ${msgfmtcmd} -o "${TMPPODIR}/$j.mo" $i 2> /dev/null rc=$? if [ $rc -ne 0 ]; then echo "instpo.sh: msgfmt failed for $i" continue fi if [ ! -f "${TMPPODIR}/$j.mo" ]; then continue fi test -d ${INST_LOCALEDIR}/$j/LC_MESSAGES || mkdir -p ${INST_LOCALEDIR}/$j/LC_MESSAGES cp -pf "${TMPPODIR}/$j.mo" ${INST_LOCALEDIR}/$j/LC_MESSAGES/di.mo rm -f "${TMPPODIR}/$j.mo" done exit 0 di-6.0.0/utils/chklibnm.sh0000755000175000017500000000124314755500057013513 0ustar bllbll#!/bin/sh # # Copyright 2025 Brad Lanam Pleasant Hill CA # libnm=lib rc=1 if [ -f /etc/os-release ]; then grep -l openSUSE /etc/os-release > /dev/null 2>&1 rc=$? # there is another os that uses lib64, but I don't recall which one # at the moment... if [ $rc -ne 0 ]; then grep -l 'Calculate Linux' /etc/os-release > /dev/null 2>&1 rc=$? fi if [ $rc -ne 0 ]; then grep -l 'Arch Linux' /etc/os-release > /dev/null 2>&1 rc=$? fi fi if [ $rc -eq 0 ]; then libnm=lib64 fi # HP-UX ia64 uses lib/hpux64 case `uname -s` in HP-UX) case `uname -m` in ia64) libnm=lib/hpux64 ;; esac ;; esac echo $libnm exit 0 di-6.0.0/utils/instlibdi.sh0000755000175000017500000000264414756147264013723 0ustar bllbll#!/bin/sh INST_LIBDIR=$1 INST_BINDIR=$2 DI_LIBVERSION=$3 DI_SOVERSION=$4 # SHLIB_EXT is in the environment grc=0 if [ "x${INST_LIBDIR}" = x ]; then echo "INST_LIBDIR is not set" exit 1 fi if [ "x${INST_BINDIR}" = x ]; then echo "INST_BINDIR is not set" exit 1 fi if [ "x${DI_LIBVERSION}" = x ]; then echo "DI_LIBVERSION is not set" exit 1 fi if [ "x${DI_SOVERSION}" = x ]; then echo "DI_SOVERSION is not set" exit 1 fi if [ ! -d "${INST_LIBDIR}" ]; then echo "INST_LIBDIR does not exist" exit 1 fi sym=T instdest=${INST_LIBDIR} case `uname -s` in Darwin) libnm=libdi.${DI_LIBVERSION}${SHLIB_EXT} libnmso=libdi.${DI_SOVERSION}${SHLIB_EXT} ;; CYGWIN*|MSYS*|MINGW*) instdest=${INST_BINDIR} libnm=libdi${SHLIB_EXT} sym=F ;; OpenBSD) libnm=libdi${SHLIB_EXT}.${DI_LIBVERSION} libnmso=libdi${SHLIB_EXT}.${DI_SOVERSION} sym=O ;; *) libnm=libdi${SHLIB_EXT}.${DI_LIBVERSION} libnmso=libdi${SHLIB_EXT}.${DI_SOVERSION} ;; esac cp -f libdi${SHLIB_EXT} ${instdest}/${libnm} rc=$? if [ $rc -ne 0 ]; then grc=1 fi if [ $grc -eq 0 -a \( $sym = T -o $sym = O \) ]; then ( cd "${instdest}" ln -sf ${libnm} ${libnmso} rc=$? if [ $rc -ne 0 ]; then grc=1 fi ) fi if [ $grc -eq 0 -a $sym = T ]; then ( cd "${instdest}" ln -sf ${libnmso} libdi${SHLIB_EXT} rc=$? if [ $rc -ne 0 ]; then grc=1 fi ) fi exit $grc di-6.0.0/di.c0000644000175000017500000007456114763621357011010 0ustar bllbll/* * Copyright 1994-2018 Brad Lanam, Walnut Creek, CA * Copyright 2023-2025 Brad Lanam, Pleasant Hill, CA */ /* * di.c * * Warning: Do not replace your system's 'df' command with this program. * You will in all likelihood break your installation procedures. * * Display sizes: * 1 - bytes * 512 - posix (512 bytes) * k - kilo * m - mega * g - giga * t - tera * p - peta * e - exa * z - zetta * r - ronna * q - quetta * h - "human readable" scaled alternative 1 * H - "human readable" scaled alternative 2 * * Sort types: * N - name (default) * n - none (mount order) * s - special * a - avail * t - type * r - reverse sort * * Format string values: * Strings * m - mount point * s - filesystem (device name / special) * t - disk partition type * O - mount options. * Disk Space * b - total space * B - total space available for use by the user. * [ (tot - (free - avail)) ] * u - space used (actual number of space used) [ (tot - free) ] * c - calculated number of space used [ (tot - avail) ] * f - space free * v - space available * Disk Space Percentages * p - percentage not available for use. * (space not available for use / total disk space) * [ (tot - avail) / tot ] * 1 - percentage used. * (actual space used / total disk space) * [ (tot - free) / tot ] * 2 - percentage of user-available space in use (bsd style). * Note that values over 100% are possible. * (actual space used / disk space available to user) * [ (tot - free) / (tot - (free - avail)) ] * Inodes * i - total i-nodes (files) * U - used i-nodes * F - free i-nodes * P - percent i-nodes used [ (tot - avail) / tot ] * * System V.4 `/usr/bin/df -v` Has format: msbuf1 * System V.4 `/usr/bin/df -k` Has format: sbcvpm * System V.4 `/usr/ucb/df` Has format: sbuv2m * * The default format string for this program is: smbuvpT * * Environment variables: * DI_ARGS: specifies any arguments to di. * POSIXLY_CORRECT: forces posix mode. * BLOCKSIZE: BSD df block size. * DF_BLOCK_SIZE: GNU df block size. * * Note that for filesystems that do not have, or systems (SysV.3) * that do not report, available space, the amount of available space is * set to the free space. * */ #include "config.h" #if _hdr_stdio # include #endif #if _hdr_stddef # include #endif #if _hdr_stdlib # include #endif #if _hdr_string # include #endif #if _hdr_strings # include #endif #if _hdr_libintl # include #endif #if _hdr_locale # include #endif #if _hdr_wchar # include #endif #include "di.h" #include "disystem.h" #include "distrutils.h" typedef struct { int *maxlen; int *printdiff; int *scaleidx; const char **suffix; int *leftjust; const char **jsonident; char **strdata; } di_disp_info_t; typedef struct { const char *si_suffix; const char *si_name; const char *suffix; const char *name; } di_disp_text_t; static di_disp_text_t disptext [] = { { "", "Byte", "", "Byte" }, { "k", "Kilo", "ki", "Kibi" }, { "M", "Mega", "Mi", "Mebi" }, { "G", "Giga", "Gi", "Gibi" }, { "T", "Tera", "Ti", "Tebi" }, { "P", "Peta", "Pi", "Pebi" }, { "E", "Exa", "Ei", "Exbi" }, { "Z", "Zetta", "Zi", "Zebi" }, { "Y", "Yotta", "Yi", "Yobi" }, { "R", "Ronna", "Ri", "Robi" }, { "Q", "Quetta", "Qi", "Quebi" } }; static void processExitFlag (void *di_data, int exitflag); static void di_display_data (void *); static void di_display_header (void *, di_disp_info_t *); static void usage (void); static Size_t istrlen (const char *str); static void updateScaleValues (void *di_data, int iterval, di_disp_info_t *dispinfo); static void determineMaxScaleValue (void *di_data, int iterval, di_disp_info_t *dispinfo); static void initLocale (void); int main (int argc, const char * argv []) { void *di_data; int exitflag; initLocale (); di_data = di_initialize (); exitflag = di_process_options (di_data, argc, argv, 1); processExitFlag (di_data, exitflag); exitflag = di_get_all_disk_info (di_data); processExitFlag (di_data, exitflag); di_display_data (di_data); di_cleanup (di_data); return 0; } static void processExitFlag (void *di_data, int exitflag) { switch (exitflag) { case DI_EXIT_FAIL: case DI_EXIT_WARN: { di_cleanup (di_data); exit (exitflag); } case DI_EXIT_HELP: case DI_EXIT_VERS: { if (exitflag == DI_EXIT_HELP) { usage (); } if (exitflag == DI_EXIT_VERS) { fprintf (stdout, "%s %s %s\n", DI_GT ("di version"), DI_VERSION, DI_RELEASE_STATUS); } di_cleanup (di_data); exit (0); } case DI_EXIT_NORM: { break; } default: { break; } } } static void usage (void) { fprintf (stdout, "%s %s\n", DI_GT ("di version"), DI_VERSION); /* 12345678901234567890123456789012345678901234567890123456789012345678901234567890 */ fprintf (stdout, "%s\n", DI_GT ("Usage: di [-ajnt] [-d display-size] [-f format] [-x exclude-fstype-list]")); fprintf (stdout, "%s\n", DI_GT (" [-I include-fstype-list] [file [...]]")); fprintf (stdout, "%s\n", DI_GT (" -a : print all mounted devices")); fprintf (stdout, "%s\n", DI_GT (" -d x : size to print blocks in (k,m,g,t,...)")); fprintf (stdout, "%s\n", DI_GT (" h - human readable.")); fprintf (stdout, "%s\n", DI_GT (" -j : output JSON format")); fprintf (stdout, "%s\n", DI_GT (" -f x : use format string ")); fprintf (stdout, "%s\n", DI_GT (" -I x : include only file system types in ")); fprintf (stdout, "%s\n", DI_GT (" -x x : exclude file system types in ")); fprintf (stdout, "%s\n", DI_GT (" -l : display local filesystems only")); fprintf (stdout, "%s\n", DI_GT (" -n : do not print header")); fprintf (stdout, "%s\n", DI_GT (" -t : print totals")); fprintf (stdout, "%s\n", DI_GT (" Format string values:")); fprintf (stdout, "%s\n", DI_GT (" m - mount point")); fprintf (stdout, "%s\n", DI_GT (" s - filesystem")); fprintf (stdout, "%s\n", DI_GT (" t - filesystem type")); fprintf (stdout, "%s\n", DI_GT (" b - total space B - space available for use")); fprintf (stdout, "%s\n", DI_GT (" u - used space c - calculated space in use")); fprintf (stdout, "%s\n", DI_GT (" f - space free v - space available")); fprintf (stdout, "%s\n", DI_GT (" p - percentage not avail. for use 1 - percentage used")); fprintf (stdout, "%s\n", DI_GT (" 2 - percentage of user-available space in use.")); fprintf (stdout, "%s\n", DI_GT (" i - total file slots (i-nodes) U - used file slots")); fprintf (stdout, "%s\n", DI_GT (" F - free file slots P - percentage file slots used")); fprintf (stdout, "%s\n", DI_GT ("See manual page for more options.")); } static void di_display_data (void *di_data) { const di_pub_disk_info_t *pub; int i; int iterval; int fmtstrlen; int displinecount; int totline = -1; int dispcount; int csvout; int csvtabs; int jsonout; int scaleidx; int scalehr; int blksz; char temp [MAXPATHLEN * 2]; di_disp_info_t dispinfo; char **strdata; csvout = di_check_option (di_data, DI_OPT_DISP_CSV); csvtabs = di_check_option (di_data, DI_OPT_DISP_CSV_TAB); jsonout = di_check_option (di_data, DI_OPT_DISP_JSON); fmtstrlen = di_check_option (di_data, DI_OPT_FMT_STR_LEN); blksz = di_check_option (di_data, DI_OPT_BLOCK_SZ); scaleidx = di_check_option (di_data, DI_OPT_SCALE); scalehr = 0; if (scaleidx == DI_SCALE_HR || scaleidx == DI_SCALE_HR_ALT) { scalehr = 1; } iterval = di_check_option (di_data, DI_OPT_DISP_ALL); displinecount = di_iterate_init (di_data, iterval); if (di_check_option (di_data, DI_OPT_DISP_HEADER)) { ++displinecount; } if (di_check_option (di_data, DI_OPT_DISP_TOTALS)) { totline = displinecount - 1; } dispinfo.maxlen = (int *) malloc (sizeof (int) * (Size_t) fmtstrlen); dispinfo.printdiff = (int *) malloc (sizeof (int) * (Size_t) displinecount * (Size_t) fmtstrlen); dispinfo.scaleidx = (int *) malloc (sizeof (int) * (Size_t) displinecount * (Size_t) fmtstrlen); dispinfo.suffix = (const char **) malloc (sizeof (char *) * (Size_t) displinecount * (Size_t) fmtstrlen); dispinfo.leftjust = (int *) malloc (sizeof (int) * (Size_t) fmtstrlen); dispinfo.jsonident = (const char **) malloc (sizeof (char *) * (Size_t) fmtstrlen); dispinfo.strdata = (char **) malloc (sizeof (char *) * (Size_t) displinecount * (Size_t) fmtstrlen); strdata = dispinfo.strdata; for (i = 0; i < fmtstrlen; ++i) { dispinfo.maxlen [i] = 0; dispinfo.printdiff [i] = 0; dispinfo.leftjust [i] = 0; dispinfo.jsonident [i] = NULL; } for (i = 0; i < displinecount; ++i) { int j; for (j = 0; j < fmtstrlen; ++j) { int idx; idx = i * fmtstrlen + j; dispinfo.scaleidx [idx] = scaleidx; dispinfo.suffix [idx] = ""; dispinfo.strdata [idx] = NULL; } } dispcount = 0; if (di_check_option (di_data, DI_OPT_DISP_HEADER)) { di_display_header (di_data, &dispinfo); dispcount = 1; } if (jsonout) { fprintf (stdout, "{\n"); if (scalehr) { fprintf (stdout, " \"scaling\" : \"human\",\n"); } else { fprintf (stdout, " \"scaling\" : \"%s\",\n", disptext [scaleidx].si_suffix); } fprintf (stdout, " \"blocksize\" : \"%d\",\n", blksz); fprintf (stdout, " \"partitions\" : [\n"); } if (scalehr) { updateScaleValues (di_data, iterval, &dispinfo); if (scaleidx == DI_SCALE_HR_ALT) { determineMaxScaleValue (di_data, iterval, &dispinfo); } } di_iterate_init (di_data, iterval); while ( (pub = di_iterate (di_data)) != NULL) { int fmt; int fmtcount; int dataidx; fmtcount = 0; di_format_iter_init (di_data); while ( (fmt = di_format_iterate (di_data)) != DI_FMT_ITER_STOP) { dataidx = dispcount * fmtstrlen + fmtcount; switch (fmt) { /* string values */ case DI_FMT_MOUNT: case DI_FMT_MOUNT_FULL: { dispinfo.jsonident [fmtcount] = "mount"; dispinfo.leftjust [fmtcount] = 1; if (dispcount == totline) { strdata [dataidx] = strdup (DI_GT ("Total")); } else { strdata [dataidx] = strdup (pub->strdata [DI_DISP_MOUNTPT]); } break; } case DI_FMT_FILESYSTEM: case DI_FMT_FILESYSTEM_FULL: { dispinfo.leftjust [fmtcount] = 1; dispinfo.jsonident [fmtcount] = "filesystem"; if (dispcount == totline) { strdata [dataidx] = strdup (""); } else { strdata [dataidx] = strdup (pub->strdata [DI_DISP_FILESYSTEM]); } break; } case DI_FMT_FSTYPE: case DI_FMT_FSTYPE_FULL: { dispinfo.leftjust [fmtcount] = 1; dispinfo.jsonident [fmtcount] = "fstype"; if (dispcount == totline) { strdata [dataidx] = strdup (""); } else { strdata [dataidx] = strdup (pub->strdata [DI_DISP_FSTYPE]); } break; } case DI_FMT_MOUNT_OPTIONS: { dispinfo.leftjust [fmtcount] = 1; dispinfo.jsonident [fmtcount] = "options"; if (dispcount == totline) { strdata [dataidx] = strdup (""); } else { strdata [dataidx] = strdup (pub->strdata [DI_DISP_MOUNTOPT]); } break; } /* disk space values */ case DI_FMT_BTOT: { dispinfo.jsonident [fmtcount] = "size"; if (scalehr) { dispinfo.suffix [dataidx] = disptext [dispinfo.scaleidx [dataidx]].si_suffix; } di_disp_scaled (di_data, temp, sizeof (temp), pub->index, dispinfo.scaleidx [dataidx], DI_SPACE_TOTAL, DI_VALUE_NONE, DI_VALUE_NONE); strdata [dataidx] = strdup (temp); break; } case DI_FMT_BTOT_AVAIL: { dispinfo.jsonident [fmtcount] = "size"; if (scalehr) { dispinfo.suffix [dataidx] = disptext [dispinfo.scaleidx [dataidx]].si_suffix; } di_disp_scaled (di_data, temp, sizeof (temp), pub->index, dispinfo.scaleidx [dataidx], DI_SPACE_TOTAL, DI_SPACE_FREE, DI_SPACE_AVAIL); strdata [dataidx] = strdup (temp); break; } case DI_FMT_BUSED: { dispinfo.jsonident [fmtcount] = "used"; if (scalehr) { dispinfo.suffix [dataidx] = disptext [dispinfo.scaleidx [dataidx]].si_suffix; } di_disp_scaled (di_data, temp, sizeof (temp), pub->index, dispinfo.scaleidx [dataidx], DI_SPACE_TOTAL, DI_SPACE_FREE, DI_VALUE_NONE); strdata [dataidx] = strdup (temp); break; } case DI_FMT_BCUSED: { dispinfo.jsonident [fmtcount] = "used"; if (scalehr) { dispinfo.suffix [dataidx] = disptext [dispinfo.scaleidx [dataidx]].si_suffix; } di_disp_scaled (di_data, temp, sizeof (temp), pub->index, dispinfo.scaleidx [dataidx], DI_SPACE_TOTAL, DI_SPACE_AVAIL, DI_VALUE_NONE); strdata [dataidx] = strdup (temp); break; } case DI_FMT_BFREE: { dispinfo.jsonident [fmtcount] = "free"; if (scalehr) { dispinfo.suffix [dataidx] = disptext [dispinfo.scaleidx [dataidx]].si_suffix; } di_disp_scaled (di_data, temp, sizeof (temp), pub->index, dispinfo.scaleidx [dataidx], DI_SPACE_FREE, DI_VALUE_NONE, DI_VALUE_NONE); strdata [dataidx] = strdup (temp); break; } case DI_FMT_BAVAIL: { dispinfo.jsonident [fmtcount] = "available"; if (scalehr) { dispinfo.suffix [dataidx] = disptext [dispinfo.scaleidx [dataidx]].si_suffix; } di_disp_scaled (di_data, temp, sizeof (temp), pub->index, dispinfo.scaleidx [dataidx], DI_SPACE_AVAIL, DI_VALUE_NONE, DI_VALUE_NONE); strdata [dataidx] = strdup (temp); break; } /* disk space percentages */ case DI_FMT_BPERC_NAVAIL: { dispinfo.jsonident [fmtcount] = "percused"; di_disp_perc (di_data, temp, sizeof (temp), pub->index, DI_SPACE_TOTAL, DI_SPACE_AVAIL, DI_SPACE_TOTAL, DI_VALUE_NONE, DI_VALUE_NONE); strdata [dataidx] = strdup (temp); dispinfo.suffix [dataidx] = "%"; break; } case DI_FMT_BPERC_USED: { dispinfo.jsonident [fmtcount] = "percused"; di_disp_perc (di_data, temp, sizeof (temp), pub->index, DI_SPACE_TOTAL, DI_SPACE_FREE, DI_SPACE_TOTAL, DI_VALUE_NONE, DI_VALUE_NONE); strdata [dataidx] = strdup (temp); dispinfo.suffix [dataidx] = "%"; break; } case DI_FMT_BPERC_BSD: { dispinfo.jsonident [fmtcount] = "percused"; di_disp_perc (di_data, temp, sizeof (temp), pub->index, DI_SPACE_TOTAL, DI_SPACE_FREE, DI_SPACE_TOTAL, DI_SPACE_FREE, DI_SPACE_AVAIL); strdata [dataidx] = strdup (temp); dispinfo.suffix [dataidx] = "%"; break; } case DI_FMT_BPERC_AVAIL: { dispinfo.jsonident [fmtcount] = "percfree"; di_disp_perc (di_data, temp, sizeof (temp), pub->index, DI_SPACE_AVAIL, DI_VALUE_NONE, DI_SPACE_TOTAL, DI_VALUE_NONE, DI_VALUE_NONE); strdata [dataidx] = strdup (temp); dispinfo.suffix [dataidx] = "%"; break; } case DI_FMT_BPERC_FREE: { dispinfo.jsonident [fmtcount] = "percfree"; di_disp_perc (di_data, temp, sizeof (temp), pub->index, DI_SPACE_FREE, DI_VALUE_NONE, DI_SPACE_TOTAL, DI_VALUE_NONE, DI_VALUE_NONE); strdata [dataidx] = strdup (temp); dispinfo.suffix [dataidx] = "%"; break; } /* inode information */ case DI_FMT_ITOT: { dispinfo.jsonident [fmtcount] = "inodes"; di_disp_scaled (di_data, temp, sizeof (temp), pub->index, DI_SCALE_BYTE, DI_INODE_TOTAL, DI_VALUE_NONE, DI_VALUE_NONE); strdata [dataidx] = strdup (temp); break; } case DI_FMT_IUSED: { dispinfo.jsonident [fmtcount] = "inodesused"; di_disp_scaled (di_data, temp, sizeof (temp), pub->index, DI_SCALE_BYTE, DI_INODE_TOTAL, DI_INODE_FREE, DI_VALUE_NONE); strdata [dataidx] = strdup (temp); break; } case DI_FMT_IFREE: { dispinfo.jsonident [fmtcount] = "inodesfree"; di_disp_scaled (di_data, temp, sizeof (temp), pub->index, DI_SCALE_BYTE, DI_INODE_FREE, DI_VALUE_NONE, DI_VALUE_NONE); strdata [dataidx] = strdup (temp); break; } case DI_FMT_IPERC: { dispinfo.jsonident [fmtcount] = "percinodesused"; di_disp_perc (di_data, temp, sizeof (temp), pub->index, DI_INODE_TOTAL, DI_INODE_AVAIL, DI_INODE_TOTAL, DI_VALUE_NONE, DI_VALUE_NONE); strdata [dataidx] = strdup (temp); dispinfo.suffix [dataidx] = "%"; break; } default: { dispinfo.leftjust [fmtcount] = 1; dispinfo.jsonident [fmtcount] = NULL; temp [0] = (char) fmt; temp [1] = '\0'; strdata [dataidx] = strdup (temp); dispinfo.suffix [dataidx] = ""; break; } } ++fmtcount; } ++dispcount; } if (! csvout && ! jsonout) { for (i = 0; i < displinecount; ++i) { int j; for (j = 0; j < fmtstrlen; ++j) { int dataidx; Size_t len; Size_t printdiff; Size_t clen; dataidx = i * fmtstrlen + j; if (strdata [dataidx] != NULL) { clen = strlen (strdata [dataidx]); len = istrlen (strdata [dataidx]); printdiff = clen - len; /* this is an assumption */ /* if the non-si suffixes are implemented, this needs to change */ if (* (dispinfo.suffix [dataidx])) { ++len; } if ((int) len > dispinfo.maxlen [j]) { dispinfo.maxlen [j] = (int) len; } dispinfo.printdiff [dataidx] = (int) printdiff; } } } } for (i = 0; i < displinecount; ++i) { int j; const char *comma; int fmtchar; if (jsonout) { fprintf (stdout, " {\n"); } comma = ","; for (j = 0; j < fmtstrlen; ++j) { int dataidx; const char *tmp; if (j == fmtstrlen - 1) { comma = ""; } dataidx = i * fmtstrlen + j; tmp = strdata [dataidx]; if (tmp == NULL) { tmp = "n/a"; } fmtchar = 1; if (dispinfo.jsonident [j] == NULL) { fmtchar = 0; } if (fmtchar && (csvout || jsonout)) { if (csvout) { if (csvtabs) { fprintf (stdout, "%s", tmp); } else { fprintf (stdout, "\"%s\"", tmp); } } else if (jsonout) { fprintf (stdout, " \"%s\" : \"%s%s\"%s", dispinfo.jsonident [j], tmp, dispinfo.suffix [dataidx], comma); } } if (! csvout && ! jsonout) { int len; int printdiff; len = dispinfo.maxlen [j]; printdiff = dispinfo.printdiff [dataidx]; if (*dispinfo.suffix [dataidx]) { --len; } if (j == fmtstrlen - 1 && dispinfo.leftjust [j]) { fprintf (stdout, "%s%s", tmp, dispinfo.suffix [dataidx]); } else { len += printdiff; if (dispinfo.leftjust [j]) { fprintf (stdout, "%-*s%s", len, tmp, dispinfo.suffix [dataidx]); } else { fprintf (stdout, "%*s%s", len, tmp, dispinfo.suffix [dataidx]); } } } if (fmtchar) { if (jsonout) { fprintf (stdout, "\n"); } else { if (j != fmtstrlen - 1) { if (csvout) { if (csvtabs) { fprintf (stdout, "\t"); } else { fprintf (stdout, ","); } } else { fprintf (stdout, " "); } } /* not the last format character */ } /* not json, json output is per-line */ } /* is a standard format character */ } /* for each format character */ if (jsonout) { fprintf (stdout, " }"); if (i != displinecount - 1) { fprintf (stdout, ","); } } fprintf (stdout, "\n"); } if (jsonout) { fprintf (stdout, " ]\n"); fprintf (stdout, "}\n"); } for (i = 0; i < displinecount; ++i) { int j; for (j = 0; j < fmtstrlen; ++j) { int dataidx; dataidx = i * fmtstrlen + j; if (strdata [dataidx] != NULL) { free (strdata [dataidx]); } } } free (dispinfo.maxlen); free (dispinfo.printdiff); free (dispinfo.scaleidx); free (dispinfo.suffix); free (dispinfo.leftjust); free (dispinfo.jsonident); free (strdata); } static void di_display_header (void *di_data, di_disp_info_t *dispinfo) { int fmt; int fmtcount; int csvout; int scaleidx; int scalehr; int posixcompat; char **strdata = dispinfo->strdata; csvout = di_check_option (di_data, DI_OPT_DISP_CSV); posixcompat = di_check_option (di_data, DI_OPT_POSIX_COMPAT); fmtcount = 0; scaleidx = di_check_option (di_data, DI_OPT_SCALE); scalehr = 0; if (scaleidx == DI_SCALE_HR || scaleidx == DI_SCALE_HR_ALT) { scalehr = 1; } di_format_iter_init (di_data); while ( (fmt = di_format_iterate (di_data)) != DI_FMT_ITER_STOP) { const char *temp; char tbuff [2]; int dataidx; int fmtchar; temp = ""; dataidx = fmtcount; if (csvout) { tbuff [0] = (char) fmt; tbuff [1] = '\0'; temp = tbuff; } fmtchar = 1; if (! csvout) { switch (fmt) { /* string values */ case DI_FMT_MOUNT: case DI_FMT_MOUNT_FULL: { if (posixcompat) { temp = DI_GT ("Mounted On"); } else { temp = DI_GT ("Mount"); } break; } case DI_FMT_FILESYSTEM: case DI_FMT_FILESYSTEM_FULL: { temp = DI_GT ("Filesystem"); break; } case DI_FMT_FSTYPE: case DI_FMT_FSTYPE_FULL: { temp = DI_GT ("Type"); break; } case DI_FMT_MOUNT_OPTIONS: { temp = DI_GT ("Options"); break; } /* disk space values */ case DI_FMT_BTOT: case DI_FMT_BTOT_AVAIL: { int blksz; blksz = di_check_option (di_data, DI_OPT_BLOCK_SZ); if (posixcompat) { temp = DI_GT ("1024-blocks"); } else if (scalehr || blksz == 1) { temp = DI_GT ("Size"); } else { if (blksz == 1000) { temp = disptext [scaleidx].si_name; } else if (blksz == 1024) { temp = disptext [scaleidx].name; } } break; } case DI_FMT_BUSED: case DI_FMT_BCUSED: { temp = DI_GT ("Used"); break; } case DI_FMT_BFREE: { temp = DI_GT ("Free"); break; } case DI_FMT_BAVAIL: { if (posixcompat) { temp = DI_GT ("Available"); } else { temp = DI_GT ("Avail"); } break; } /* disk space percentages */ case DI_FMT_BPERC_NAVAIL: case DI_FMT_BPERC_USED: case DI_FMT_BPERC_BSD: { if (posixcompat) { temp = DI_GT ("Capacity"); } else { temp = DI_GT ("%Used"); } break; } case DI_FMT_BPERC_AVAIL: case DI_FMT_BPERC_FREE: { temp = DI_GT ("%Free"); break; } /* inode information */ case DI_FMT_ITOT: { temp = DI_GT ("Inodes"); break; } case DI_FMT_IUSED: { temp = DI_GT ("IUsed"); break; } case DI_FMT_IFREE: { temp = DI_GT ("IFree"); break; } case DI_FMT_IPERC: { temp = DI_GT ("%IUsed"); break; } default: { fmtchar = 0; tbuff [0] = (char) fmt; tbuff [1] = '\0'; temp = tbuff; break; } } } if (fmtchar) { /* force proper display processing for heading */ /* the display loop checks for jsonident == null */ dispinfo->jsonident [fmtcount] = "header"; } strdata [dataidx] = strdup (temp); ++fmtcount; } return; } static Size_t istrlen (const char *str) { Size_t len; #if _lib_mbrlen Size_t mlen; Size_t slen; mbstate_t ps; const char *tstr; len = 0; memset (&ps, 0, sizeof (mbstate_t)); slen = strlen (str); tstr = str; while (slen > 0) { mlen = mbrlen (tstr, slen, &ps); if ( (int) mlen <= 0) { return strlen (str); } ++len; tstr += mlen; slen -= mlen; } #else len = strlen (str); #endif return len; } static void updateScaleValues (void *di_data, int iterval, di_disp_info_t *dispinfo) { const di_pub_disk_info_t *pub; int dispcount; int fmtstrlen; dispcount = 0; if (di_check_option (di_data, DI_OPT_DISP_HEADER)) { dispcount = 1; } fmtstrlen = di_check_option (di_data, DI_OPT_FMT_STR_LEN); di_iterate_init (di_data, iterval); while ((pub = di_iterate (di_data)) != NULL) { int fmt; int fmtcount; int dataidx; fmtcount = 0; di_format_iter_init (di_data); while ((fmt = di_format_iterate (di_data)) != DI_FMT_ITER_STOP) { dataidx = dispcount * fmtstrlen + fmtcount; switch (fmt) { /* disk space values */ case DI_FMT_BTOT: { dispinfo->scaleidx [dataidx] = di_get_scale_max (di_data, pub->index, DI_SPACE_TOTAL, DI_VALUE_NONE, DI_VALUE_NONE); break; } case DI_FMT_BTOT_AVAIL: { dispinfo->scaleidx [dataidx] = di_get_scale_max (di_data, pub->index, DI_SPACE_TOTAL, DI_SPACE_FREE, DI_SPACE_AVAIL); break; } case DI_FMT_BUSED: { dispinfo->scaleidx [dataidx] = di_get_scale_max (di_data, pub->index, DI_SPACE_TOTAL, DI_SPACE_FREE, DI_VALUE_NONE); break; } case DI_FMT_BCUSED: { dispinfo->scaleidx [dataidx] = di_get_scale_max (di_data, pub->index, DI_SPACE_TOTAL, DI_SPACE_AVAIL, DI_VALUE_NONE); break; } case DI_FMT_BFREE: { dispinfo->scaleidx [dataidx] = di_get_scale_max (di_data, pub->index, DI_SPACE_FREE, DI_VALUE_NONE, DI_VALUE_NONE); break; } case DI_FMT_BAVAIL: { dispinfo->scaleidx [dataidx] = di_get_scale_max (di_data, pub->index, DI_SPACE_AVAIL, DI_VALUE_NONE, DI_VALUE_NONE); break; } default: { break; } } ++fmtcount; } ++dispcount; } } static void determineMaxScaleValue (void *di_data, int iterval, di_disp_info_t *dispinfo) { const di_pub_disk_info_t *pub; int dispcount; int fmtstrlen; dispcount = 0; if (di_check_option (di_data, DI_OPT_DISP_HEADER)) { dispcount = 1; } fmtstrlen = di_check_option (di_data, DI_OPT_FMT_STR_LEN); di_iterate_init (di_data, iterval); while ((pub = di_iterate (di_data)) != NULL) { int fmt; int fmtcount; int dataidx; int maxscaleidx; int scaleidx; fmtcount = 0; maxscaleidx = DI_SCALE_BYTE; di_format_iter_init (di_data); while ((fmt = di_format_iterate (di_data)) != DI_FMT_ITER_STOP) { dataidx = dispcount * fmtstrlen + fmtcount; switch (fmt) { /* disk space values */ case DI_FMT_BTOT: case DI_FMT_BTOT_AVAIL: case DI_FMT_BUSED: case DI_FMT_BCUSED: case DI_FMT_BFREE: case DI_FMT_BAVAIL: { scaleidx = dispinfo->scaleidx [dataidx]; break; } default: { scaleidx = DI_SCALE_BYTE; break; } } if (scaleidx > maxscaleidx) { maxscaleidx = scaleidx; } ++fmtcount; } /* and loop through again, and set the scaleidx to the max scaleidx */ fmtcount = 0; di_format_iter_init (di_data); while ((fmt = di_format_iterate (di_data)) != DI_FMT_ITER_STOP) { dataidx = dispcount * fmtstrlen + fmtcount; switch (fmt) { /* disk space values */ case DI_FMT_BTOT: case DI_FMT_BTOT_AVAIL: case DI_FMT_BUSED: case DI_FMT_BCUSED: case DI_FMT_BFREE: case DI_FMT_BAVAIL: { dispinfo->scaleidx [dataidx] = maxscaleidx; break; } default: { break; } } ++fmtcount; } ++dispcount; } } static void initLocale (void) { #if _enable_nls const char *localeptr; #endif #if _lib_setlocale && defined (LC_ALL) setlocale (LC_ALL, ""); #endif #if _enable_nls if ( (localeptr = getenv ("DI_LOCALE_DIR")) == (char *) NULL) { localeptr = DI_LOCALE_DIR; } bindtextdomain ("di", localeptr); textdomain ("di"); #endif } di-6.0.0/VERSION.txt0000644000175000017500000000024514763623115012114 0ustar bllbllDI_VERSION=6.0.0 DI_LIBVERSION=6.0.0 DI_SOVERSION=6 DI_RELEASE_STATUS=production export DI_VERSION export DI_LIBVERSION export DI_SOVERSION export DI_RELEASE_STATUS di-6.0.0/dizone.c0000644000175000017500000000630514746007475011673 0ustar bllbll/* Copyright 2025 Brad Lanam Pleasant Hill CA */ #include "config.h" #if _hdr_stdlib # include #endif #if _hdr_string # include #endif #if _hdr_strings # include #endif #if _hdr_memory # include #endif #if _hdr_errno # include #endif #if _hdr_unistd # include #endif #if _hdr_zone # include #endif #include "di.h" #include "dizone.h" #include "distrutils.h" #include "dioptions.h" di_zone_info_t * di_initialize_zones (di_opt_t *diopts) { di_zone_info_t *zinfo; zinfo = (di_zone_info_t *) malloc (sizeof (di_zone_info_t)); zinfo->zoneCount = 0; zinfo->zones = (di_zone_summ_t *) NULL; #if _lib_zone_list && _lib_getzoneid && _lib_zone_getattr zinfo->uid = geteuid (); { int i; zoneid_t *zids = (zoneid_t *) NULL; char *rpp; char *rpend; zinfo->myzoneid = getzoneid (); if (zone_list (zids, &zinfo->zoneCount) == 0) { if (zinfo->zoneCount > 0) { zids = (zoneid_t *) malloc (sizeof (zoneid_t) * zinfo->zoneCount); if (zids == (zoneid_t *) NULL) { fprintf (stderr, "malloc failed in main () (1). errno %d\n", errno); return zinfo; } zone_list (zids, &zinfo->zoneCount); zinfo->zones = (di_zone_summ_t *) malloc (sizeof (di_zone_summ_t) * zinfo->zoneCount); if (zinfo->zones == (di_zone_summ_t *) NULL) { fprintf (stderr, "malloc failed in main () (2). errno %d\n", errno); return zinfo; } } } zinfo->globalIdx = 0; for (i = 0; i < (int) zinfo->zoneCount; ++i) { int len; zinfo->zones [i].zoneid = zids [i]; len = (int) zone_getattr (zids [i], ZONE_ATTR_ROOT, zinfo->zones [i].rootpath, MAXPATHLEN); /* solaris: the length returned includes the null byte */ if (len >= 0) { len -= 1; zinfo->zones [i].rootpathlen = (Size_t) len; if (zinfo->zones [i].zoneid != 0) { rpp = zinfo->zones [i].rootpath + len; rpend = zinfo->zones [i].rootpath + MAXPATHLEN; rpp = stpecpy (rpp, rpend, "/"); } if (zinfo->zones [i].zoneid == 0) { zinfo->globalIdx = i; } len = (int) zone_getattr (zids [i], ZONE_ATTR_NAME, zinfo->zones [i].name, ZONENAME_MAX); if (*diopts->zoneDisplay == '\0' && zinfo->myzoneid == zinfo->zones [i].zoneid) { stpecpy (diopts->zoneDisplay, diopts->zoneDisplay + MAXPATHLEN, zinfo->zones [i].name); } if (diopts->optval [DI_OPT_DEBUG] > 4) { printf ("zone:%d:%s:%s:%d\n", (int) zinfo->zones [i].zoneid, zinfo->zones [i].name, zinfo->zones [i].rootpath, (int) zinfo->zones [i].rootpathlen); } } } free ((void *) zids); } if (diopts->optval [DI_OPT_DEBUG] > 4) { printf ("zone:my:%d:%s:glob:%d:\n", (int) zinfo->myzoneid, diopts->zoneDisplay, zinfo->globalIdx); } #endif return zinfo; } void di_free_zones (di_zone_info_t *zinfo) { if (zinfo == NULL) { return; } if (zinfo->zones != (di_zone_summ_t *) NULL) { free (zinfo->zones); } free (zinfo); } di-6.0.0/diquota.h0000644000175000017500000000143614745774260012060 0ustar bllbll/* Copyright 2025 Brad Lanam Pleasant Hill CA */ #ifndef INC_DIQUOTA_H #define INC_DIQUOTA_H #include "config.h" #include "disystem.h" #include "dimath.h" #include "diinternal.h" # if defined (__cplusplus) || defined (c_plusplus) extern "C" { # endif /* quota value identifiers */ #define DI_QUOTA_BLOCK_SZ 0 #define DI_QUOTA_LIMIT 1 #define DI_QUOTA_USED 2 #define DI_QUOTA_ILIMIT 3 #define DI_QUOTA_IUSED 4 #define DI_QVAL_MAX 5 typedef struct { char *filesystem; char *mountpt; char *fstype; Uid_t uid; Gid_t gid; dinum_t values [DI_QVAL_MAX]; } di_quota_t; extern void diquota (di_data_t *di_data, di_quota_t *); # if defined (__cplusplus) || defined (c_plusplus) } # endif #endif /* INC_DIQUOTA_H */ di-6.0.0/getoptn.h0000644000175000017500000000274214751225202012053 0ustar bllbll/* * Copyright 2011-2018 Brad Lanam, Walnut Creek, CA * Copyright 2023-2025 Brad Lanam, Pleasant Hill, CA */ #ifndef INC_GETOPTN_H #define INC_GETOPTN_H #include "config.h" #if _hdr_stddef # include #endif #if _sys_types \ && ! defined (DI_INC_SYS_TYPES_H) /* xenix */ # define DI_INC_SYS_TYPES_H # include #endif # if defined (__cplusplus) || defined (c_plusplus) extern "C" { # endif #define GETOPTN_NOTFOUND -1 /* option style */ /* GETOPTN_LEGACY: * -ab processes both -a and -b flags. * GETOPTN_MODERN: * -ab processes -ab flag. */ #define GETOPTN_LEGACY (1 >> 0) #define GETOPTN_MODERN (1 >> 1) #define GETOPTN_HAS_ARGV0 (1 >> 2) /* option types */ #define GETOPTN_BOOL 0 /* flips the value */ #define GETOPTN_INT 1 #define GETOPTN_LONG 2 #define GETOPTN_DOUBLE 3 #define GETOPTN_STRING 4 #define GETOPTN_STRPTR 5 #define GETOPTN_FUNC_BOOL 6 #define GETOPTN_FUNC_VALUE 7 #define GETOPTN_ALIAS 8 #define GETOPTN_IGNORE 9 #define GETOPTN_IGNORE_ARG 10 #define GETOPTN_SIZET 11 typedef struct { const char *option; int option_type; void * valptr; Size_t valsiz; void *value2; } getoptn_opt_t; extern int getoptn (int style, int argc, const char * argv [], int optcount, getoptn_opt_t opts [], int offset, int *errorCount); # if defined (__cplusplus) || defined (c_plusplus) } # endif #endif /* INC_GETOPTN_H */ di-6.0.0/disystem.h0000644000175000017500000000437614750225777012261 0ustar bllbll/* Copyright 2025 Brad Lanam Pleasant Hill CA */ #ifndef INC_DISYSTEM_H #define INC_DISYSTEM_H #include "config.h" /* first some system stuff to get various sizes */ #if _hdr_stddef # include #endif #if _hdr_stdint # include #endif #if _hdr_string # include #endif #if _hdr_strings # include #endif #if _sys_file # include #endif #if _sys_types \ && ! defined (DI_INC_SYS_TYPES_H) /* xenix */ # define DI_INC_SYS_TYPES_H # include #endif #if _hdr_limits # include /* PATH_MAX */ #endif #if _sys_param # include /* MAXPATHLEN */ #endif #if ! defined (MAXPATHLEN) # if defined (_POSIX_PATH_MAX) # define MAXPATHLEN _POSIX_PATH_MAX # else # if defined (PATH_MAX) # define MAXPATHLEN PATH_MAX # endif # if defined (LPNMAX) # define MAXPATHLEN LPNMAX # endif # endif #endif #if ! defined (MAXPATHLEN) # define MAXPATHLEN 255 #endif #if _sys_fstyp /* HP-UX, Solaris */ # include /* FSTYPSZ */ # if defined (FSTYPSZ) # define DI_FSTYPE_LEN FSTYPSZ # endif #endif /* FreeBSD, OpenBSD, NetBSD, HP-UX, MacOS */ #if _sys_mount && ! defined (DI_INC_SYS_MOUNT) # define DI_INC_SYS_MOUNT 1 # include /* MFSNAMELEN */ #endif #if _sys_mount # if ! defined (DI_FSTYPE_LEN) && defined (MFSNAMELEN) # define DI_FSTYPE_LEN MFSNAMELEN # endif #endif #if _sys_vfstab /* FSTYPSZ sco open server */ # include # include # if ! defined (DI_FSTYPE_LEN) && defined (FSTYPSZ) # define DI_FSTYPE_LEN FSTYPSZ # endif #endif #if ! defined (DI_FSTYPE_LEN) # define DI_FSTYPE_LEN 65 #endif #if ! _lib_memcpy && ! defined (memcpy) # if ! _lib_bcopy && ! defined (bcopy) # error No_memcpy/bcopy_available. # else # define memcpy (dst, src, cnt) (bcopy ( (src), (dst), (cnt)), dst) # endif #endif #if ! _lib_memset && ! _define_memset # if ! _lib_bzero && ! _define_bzero #error No_memset/bzero_available. # else # define memset (s,c,n) (bzero ( (s), (n)), s) # endif #endif #if ! _hdr_stdbool # ifndef false # define false 0 # endif # ifndef true # define true 1 # endif #endif #endif /* INC_DISYSTEM_H */ di-6.0.0/di.pc.in0000644000175000017500000000041514756663632011564 0ustar bllbllprefix=@CMAKE_INSTALL_PREFIX@ includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ libdir=@CMAKE_INSTALL_FULL_LIBDIR@ Name: libdi Description: Disk Information Library Version: @DI_VERSION@ URL: https://sourceforge.net/project/di/ Libs: -L${libdir} -ldi Cflags: -I${includedir} di-6.0.0/dimntopt.h0000644000175000017500000000714714745732670012254 0ustar bllbll/* * Copyright 2011-2018 Brad Lanam, Walnut Creek, CA * Copyright 2023-2025 Brad Lanam, Pleasant Hill, CA */ #ifndef INC_DIMNTOPT_H #define INC_DIMNTOPT_H #include "config.h" #if _hdr_mntent \ && ! defined (DI_INC_MNTENT) /* Linux, kFreeBSD, HP-UX */ # define DI_INC_MNTENT 1 # include /* MNTOPT_... */ #endif /* FreeBSD, OpenBSD, NetBSD, HP-UX, MacOS */ #if _sys_mount && ! defined (DI_INC_SYS_MOUNT) # define DI_INC_SYS_MOUNT 1 # include /* MNT_...; M_... (hp-ux) */ #endif #if _sys_mnttab /* SCO_SV, UnixWare */ # include /* required for mntent.h */ #endif #if _sys_mntent /* Solaris, SCO_SV, UnixWare */ # include /* MNTOPT_... */ #endif #if _sys_fstypes /* NetBSD */ # include #endif #if _sys_vmount /* AIX */ # include /* MNT_... */ #endif #if _hdr_mnttab /* SysV.3 */ # include #endif # if defined (__cplusplus) || defined (c_plusplus) extern "C" { # endif /********************************************************/ /* remap mount flags */ #if defined (B_FS_IS_READONLY) # define MNT_RDONLY B_FS_IS_READONLY #endif #if defined (FS_IS_READONLY) # define MNT_RDONLY FS_IS_READONLY #endif #if defined (M_RDONLY) # define MNT_RDONLY M_RDONLY #endif #if defined (MNT_READONLY) # define MNT_RDONLY MNT_READONLY #endif #if defined (M_RONLY) # define MNT_RDONLY M_RONLY #endif #if defined (M_SYNCHRONOUS) # define MNT_SYNCHRONOUS M_SYNCHRONOUS #endif #if defined (M_NOEXEC) # define MNT_NOEXEC M_NOEXEC #endif #if defined (M_NOSUID) # define MNT_NOSUID M_NOSUID #endif #if defined (M_NODEV) # define MNT_NODEV M_NODEV #endif #if defined (M_NOATIMES) # define MNT_NOATIMES M_NOATIMES #endif #if defined (M_GRPID) # define MNT_GRPID M_GRPID #endif #if defined (M_SECURE) # define MNT_SECURE M_SECURE #endif #if defined (M_MLSD) # define MNT_MLSD M_MLSD #endif #if defined (M_SMSYNC2) # define MNT_SMSYNC2 M_SMSYNC2 #endif #if defined (M_LOCAL) # define MNT_LOCAL M_LOCAL #endif #if defined (M_FORCE) # define MNT_FORCE M_FORCE #endif #if defined (M_SYNC) # define MNT_SYNC M_SYNC #endif #if defined (M_NOCACHE) # define MNT_NOCACHE M_NOCACHE #endif #if defined (B_FS_IS_REMOVABLE) # define MNT_REMOVABLE B_FS_IS_REMOVABLE #endif #if defined (FS_IS_REMOVABLE) # define MNT_REMOVABLE FS_IS_REMOVABLE #endif #if defined (B_FS_IS_PERSISTENT) # define MNT_PERSISTENT B_FS_IS_PERSISTENT #endif #if defined (FS_IS_PERSISTENT) # define MNT_PERSISTENT FS_IS_PERSISTENT #endif #if defined (B_FS_IS_SHARED) # define MNT_SHARED B_FS_IS_SHARED #endif #if defined (FS_IS_SHARED) # define MNT_SHARED FS_IS_SHARED #endif #if defined (FS_IS_BLOCKBASED) # define MNT_BLOCKBASED FS_IS_BLOCKBASED #endif #if defined (B_FS_HAS_MIME) # define MNT_HAS_MIME B_FS_HAS_MIME #endif #if defined (FS_HAS_MIME) # define MNT_HAS_MIME FS_HAS_MIME #endif #if defined (B_FS_HAS_ATTR) # define MNT_HAS_ATTR B_FS_HAS_ATTR #endif #if defined (FS_HAS_ATTR) # define MNT_HAS_ATTR FS_HAS_ATTR #endif #if defined (B_FS_HAS_QUERY) # define MNT_HAS_QUERY B_FS_HAS_QUERY #endif #if defined (FS_HAS_QUERY) # define MNT_HAS_QUERY FS_HAS_QUERY #endif #if defined (MNTOPT_IGNORE) # define DI_MNTOPT_IGNORE MNTOPT_IGNORE #else # define DI_MNTOPT_IGNORE "ignore" #endif #if defined (MNTOPT_RO) # define DI_MNTOPT_RO MNTOPT_RO #else # define DI_MNTOPT_RO "ro" #endif #if defined (MNTOPT_DEV) # define DI_MNTOPT_DEV MNTOPT_DEV #else # define DI_MNTOPT_DEV "dev=" #endif # if defined (__cplusplus) || defined (c_plusplus) } # endif #endif /* INC_DIMNTOPT_H */ di-6.0.0/po/0000755000175000017500000000000014754214227010643 5ustar bllblldi-6.0.0/po/es.po0000644000175000017500000000657414745314232011623 0ustar bllbll# Español # msgid "" msgstr "" "Project-Id-Version: di 4.99.3\n" "Report-Msgid-Bugs-To: brad.lanam.di@gmail.com\n" "POT-Creation-Date: 2025-01-25\n" "PO-Revision-Date: 2025-01-25\n" "Last-Translator: Automatically generated\n" "Language-Team: spanish\n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid " h - human readable." msgstr " h - legible" msgid " [-I include-fstype-list] [file [...]]" msgstr " [-I incluir-lista-tipos-de-sf] [fichero [...]]" msgid " 2 - percentage of user-available space in use." msgstr " 2 - porcentaje de espacio disponible de usuario en uso." msgid " F - free file slots P - percentage file slots used" msgstr " F - inodos libres P - porcentaje de inodos usados" msgid " b - total space B - space available for use" msgstr "" msgid " f - space free v - space available" msgstr "" msgid " i - total file slots (i-nodes) U - used file slots" msgstr " i - total inodos (i-nodes) U - inodos usados" msgid " m - mount point" msgstr " m - punto de montaje" msgid " p - percentage not avail. for use 1 - percentage used" msgstr " p - porcentaje no disponible 1 - porcentaje usado" msgid " s - filesystem" msgstr " s - nombre de sistema de ficheros" msgid " t - filesystem type" msgstr " t - tipo de ficheros" msgid " u - used space c - calculated space in use" msgstr "" msgid " -I x : include only file system types in " msgstr " -I x : incluir sólo los tipos de sistemas de ficheros en " msgid " -a : print all mounted devices" msgstr " -a : mostrar todos los dispositivos montados" msgid " -d x : size to print blocks in (k,m,g,t,...)" msgstr " -d x : tamaño de bloque a mostrar (k,m,g,t,...)" msgid " -f x : use format string " msgstr " -f x : usar formato " msgid " -j : output JSON format" msgstr "" msgid " -l : display local filesystems only" msgstr " -l : mostrar sistemas de ficheros locales" msgid " -n : do not print header" msgstr " -n : no mostrar cabecera" msgid " -t : print totals" msgstr " -t : mostrar totales" msgid " -x x : exclude file system types in " msgstr " -x x : excluir tipos de sistemas de ficheros en " msgid " Format string values:" msgstr " Valores de formato de cadena:" #, c-format msgid "%Free" msgstr "%Libre" msgid "%IUsed" msgstr "%IUsado" msgid "%Used" msgstr "%Usado" msgid "1024-blocks" msgstr "1024-bloques" msgid "Avail" msgstr "Dispon" msgid "Available" msgstr "Disponible" msgid "Capacity" msgstr "Capacidad" msgid "Filesystem" msgstr "Sistema de ficheros" msgid "Free" msgstr "Libre" msgid "IFree" msgstr "ILibre" msgid "IUsed" msgstr "IUsado" msgid "Inodes" msgstr "Inodos" msgid "Mount" msgstr "Mountado" msgid "Mounted On" msgstr "Montado En" msgid "Options" msgstr "Opciones" msgid "See manual page for more options." msgstr "Vea página de manual para más opciones." msgid "Size" msgstr "Tamaño" msgid "Total" msgstr "Total" msgid "Type" msgstr "Tipo" msgid "" "Usage: di [-ajnt] [-d display-size] [-f format] [-x exclude-fstype-list]" msgstr "Uso: di [-ant] [-d tamaño-display] [-f formato] [-x excluir-lista-tipos-de-sf]" msgid "Used" msgstr "Usado" msgid "di version" msgstr "" di-6.0.0/po/en.po0000644000175000017500000000454614745311605011614 0ustar bllbll# English # msgid "" msgstr "" "Project-Id-Version: di 4.99.3\n" "Report-Msgid-Bugs-To: brad.lanam.di@gmail.com\n" "POT-Creation-Date: 2025-01-25\n" "PO-Revision-Date: 2025-01-25\n" "Last-Translator: Automatically generated\n" "Language-Team: english\n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid " h - human readable." msgstr "" msgid " [-I include-fstype-list] [file [...]]" msgstr "" msgid " 2 - percentage of user-available space in use." msgstr "" msgid " F - free file slots P - percentage file slots used" msgstr "" msgid " b - total space B - space available for use" msgstr "" msgid " f - space free v - space available" msgstr "" msgid " i - total file slots (i-nodes) U - used file slots" msgstr "" msgid " m - mount point" msgstr "" msgid " p - percentage not avail. for use 1 - percentage used" msgstr "" msgid " s - filesystem" msgstr "" msgid " t - filesystem type" msgstr "" msgid " u - used space c - calculated space in use" msgstr "" msgid " -I x : include only file system types in " msgstr "" msgid " -a : print all mounted devices" msgstr "" msgid " -d x : size to print blocks in (k,m,g,t,...)" msgstr "" msgid " -f x : use format string " msgstr "" msgid " -j : output JSON format" msgstr "" msgid " -l : display local filesystems only" msgstr "" msgid " -n : do not print header" msgstr "" msgid " -t : print totals" msgstr "" msgid " -x x : exclude file system types in " msgstr "" msgid " Format string values:" msgstr "" #, c-format msgid "%Free" msgstr "" msgid "%IUsed" msgstr "" msgid "%Used" msgstr "" msgid "1024-blocks" msgstr "" msgid "Avail" msgstr "" msgid "Available" msgstr "" msgid "Capacity" msgstr "" msgid "Filesystem" msgstr "" msgid "Free" msgstr "" msgid "IFree" msgstr "" msgid "IUsed" msgstr "" msgid "Inodes" msgstr "" msgid "Mount" msgstr "" msgid "Mounted On" msgstr "" msgid "Options" msgstr "" msgid "See manual page for more options." msgstr "" msgid "Size" msgstr "" msgid "Total" msgstr "" msgid "Type" msgstr "" msgid "" "Usage: di [-ajnt] [-d display-size] [-f format] [-x exclude-fstype-list]" msgstr "" msgid "Used" msgstr "" msgid "di version" msgstr "" di-6.0.0/po/de.po0000644000175000017500000000633614745315044011602 0ustar bllbll# English # msgid "" msgstr "" "Project-Id-Version: di 4.99.3\n" "Report-Msgid-Bugs-To: brad.lanam.di@gmail.com\n" "POT-Creation-Date: 2025-01-25\n" "PO-Revision-Date: 2025-01-25\n" "Last-Translator: Automatically generated\n" "Language-Team: english\n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid " h - human readable." msgstr " h - lesbar" msgid " [-I include-fstype-list] [file [...]]" msgstr " [-I include-fstyp-list] [Datei [...]]" msgid " 2 - percentage of user-available space in use." msgstr " 2 - Prozent des benutzten verfügbaren Platzes." msgid " F - free file slots P - percentage file slots used" msgstr " F - Dateislots freigeben P - Prozent der benutzten Dateislots" msgid " b - total space B - space available for use" msgstr "" msgid " f - space free v - space available" msgstr "" msgid " i - total file slots (i-nodes) U - used file slots" msgstr " i - Dateislots gesamt (i-nodes) U - benutzte Dateislots" msgid " m - mount point" msgstr " m - Mountpunkt" msgid " p - percentage not avail. for use 1 - percentage used" msgstr " p - Prozent nicht benutzbar 1 - Prozent benutzt" msgid " s - filesystem" msgstr " s - Dateisystemname" msgid " t - filesystem type" msgstr " t - Dateisystemtyp" msgid " u - used space c - calculated space in use" msgstr "" msgid " -I x : include only file system types in " msgstr " -I x : nur Dateisystemtypen in einfügen" msgid " -a : print all mounted devices" msgstr " -a : alle eingehängten Geräte auflisten" msgid " -d x : size to print blocks in (k,m,g,t,...)" msgstr " -d x : Größe der angezeigten Blöcke (k,m,g,t,...)" msgid " -f x : use format string " msgstr " -f x : benutze Formatzeichen " msgid " -j : output JSON format" msgstr "" msgid " -l : display local filesystems only" msgstr " -l : nur lokale Dateisysteme anzeigen" msgid " -n : do not print header" msgstr " -n : keine Kopf drucken" msgid " -t : print totals" msgstr " -t : Summen drucken" msgid " -x x : exclude file system types in " msgstr " -x x : Dateisystemtyp in ignorieren" msgid " Format string values:" msgstr " Formatzeichenkette:" #, c-format msgid "%Free" msgstr "%Frei" msgid "%IUsed" msgstr "%IBen." msgid "%Used" msgstr "%Ben." msgid "1024-blocks" msgstr "1024-Blöcke" msgid "Avail" msgstr "Verfügb." msgid "Available" msgstr "Verfübar" msgid "Capacity" msgstr "Benutzt%" msgid "Filesystem" msgstr "Dateisystem" msgid "Free" msgstr "Frei" msgid "IFree" msgstr "IFrei" msgid "IUsed" msgstr "IBenutzt" msgid "Inodes" msgstr "" msgid "Mount" msgstr "Mountpunkt" msgid "Mounted On" msgstr "Eingehängt auf" msgid "Options" msgstr "Optionen" msgid "See manual page for more options." msgstr "Siehe man-Seite für weitere Optionen." msgid "Size" msgstr "Größe" msgid "Total" msgstr "Gesamt" msgid "Type" msgstr "" msgid "" "Usage: di [-ajnt] [-d display-size] [-f format] [-x exclude-fstype-list]" msgstr "" msgid "Used" msgstr "Benutzt" msgid "di version" msgstr "" di-6.0.0/po/di.pot0000644000175000017500000000455514745311577012002 0ustar bllbllmsgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-01-25 17:44-0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" msgid " h - human readable." msgstr "" msgid " [-I include-fstype-list] [file [...]]" msgstr "" msgid " 2 - percentage of user-available space in use." msgstr "" msgid " F - free file slots P - percentage file slots used" msgstr "" msgid " b - total space B - space available for use" msgstr "" msgid " f - space free v - space available" msgstr "" msgid " i - total file slots (i-nodes) U - used file slots" msgstr "" msgid " m - mount point" msgstr "" msgid " p - percentage not avail. for use 1 - percentage used" msgstr "" msgid " s - filesystem" msgstr "" msgid " t - filesystem type" msgstr "" msgid " u - used space c - calculated space in use" msgstr "" msgid " -I x : include only file system types in " msgstr "" msgid " -a : print all mounted devices" msgstr "" msgid " -d x : size to print blocks in (k,m,g,t,...)" msgstr "" msgid " -f x : use format string " msgstr "" msgid " -j : output JSON format" msgstr "" msgid " -l : display local filesystems only" msgstr "" msgid " -n : do not print header" msgstr "" msgid " -t : print totals" msgstr "" msgid " -x x : exclude file system types in " msgstr "" msgid " Format string values:" msgstr "" #, c-format msgid "%Free" msgstr "" msgid "%IUsed" msgstr "" msgid "%Used" msgstr "" msgid "1024-blocks" msgstr "" msgid "Avail" msgstr "" msgid "Available" msgstr "" msgid "Capacity" msgstr "" msgid "Filesystem" msgstr "" msgid "Free" msgstr "" msgid "IFree" msgstr "" msgid "IUsed" msgstr "" msgid "Inodes" msgstr "" msgid "Mount" msgstr "" msgid "Mounted On" msgstr "" msgid "Options" msgstr "" msgid "See manual page for more options." msgstr "" msgid "Size" msgstr "" msgid "Total" msgstr "" msgid "Type" msgstr "" msgid "" "Usage: di [-ajnt] [-d display-size] [-f format] [-x exclude-fstype-list]" msgstr "" msgid "Used" msgstr "" msgid "di version" msgstr ""