diff options
| author | Manuel Bentele | 2020-10-23 15:18:01 +0200 |
|---|---|---|
| committer | Manuel Bentele | 2020-10-23 15:18:01 +0200 |
| commit | dbb41ce2b7f309d394054a6bd1e33afd578798a5 (patch) | |
| tree | 6a31092063d9f2fb5ac5720ec6759040e793c3d5 /utils | |
| parent | Set Linux kernel version to unknown if it is not detectable (diff) | |
| download | xloop-dbb41ce2b7f309d394054a6bd1e33afd578798a5.tar.gz xloop-dbb41ce2b7f309d394054a6bd1e33afd578798a5.tar.xz xloop-dbb41ce2b7f309d394054a6bd1e33afd578798a5.zip | |
Move the source code of all xloop components to the common 'src' directory
Diffstat (limited to 'utils')
133 files changed, 0 insertions, 29578 deletions
diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt deleted file mode 100644 index cfc5548..0000000 --- a/utils/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -cmake_minimum_required(VERSION 3.10) - -# set the project name -project(xloop-utils) - -# include global headers -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - -# prepare date for configuring config.h -string(TIMESTAMP DATE "%d-%b-%Y") - -# configure configuration config.h and add it to each source file -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) -add_compile_options(-include ${CMAKE_CURRENT_BINARY_DIR}/config.h) - -# add xloop specific compile options -add_definitions(-DCONFIG_BLK_DEV_XLOOP_MIN_COUNT=${BLK_DEV_XLOOP_MIN_COUNT} -DXLOOP_MAJOR=${XLOOP_MAJOR}) - -add_subdirectory(lib) -add_subdirectory(libsmartcols) -add_subdirectory(sys-utils) - -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/bash-completion/xlosetup - DESTINATION share/bash-completion/completions - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ - COMPONENT main) diff --git a/utils/bash-completion/xlosetup b/utils/bash-completion/xlosetup deleted file mode 100644 index cdf75f1..0000000 --- a/utils/bash-completion/xlosetup +++ /dev/null @@ -1,85 +0,0 @@ -_xlosetup_module() -{ - local cur prev OPTS ARG - COMPREPLY=() - cur="${COMP_WORDS[COMP_CWORD]}" - prev="${COMP_WORDS[COMP_CWORD-1]}" - case $prev in - '-d'|'--detach') - ARG="$($1 --output NAME | awk '{if (1 < NR) {print}}')" - COMPREPLY=( $(compgen -W "$ARG" -- $cur) ) - return 0 - ;; - '-j'|'--associated') - ARG="$($1 --output BACK-FILE | awk '{if (1 < NR) {print}}')" - COMPREPLY=( $(compgen -W "$ARG" -- $cur) ) - return 0 - ;; - '-c'|'--set-capacity') - ARG="$(for I in /dev/xloop[0-9]*; do if [ -e $I ]; then echo $I; fi; done)" - COMPREPLY=( $(compgen -W "$ARG" -- $cur) ) - return 0 - ;; - '-o'|'--offset'|'--sizelimit') - COMPREPLY=( $(compgen -W "number" -- $cur) ) - return 0 - ;; - '-t'|'--type') - ARG="RAW QCOW VDI VMDK" - COMPREPLY=( $(compgen -W "$ARG" -- $cur) ) - return 0 - ;; - '-O'|'--output') - local prefix realcur OUTPUT_ALL OUTPUT - realcur="${cur##*,}" - prefix="${cur%$realcur}" - OUTPUT_ALL="NAME AUTOCLEAR BACK-FILE BACK-INO - BACK-MAJ:MIN FILE-FORMAT MAJ:MIN OFFSET PARTSCAN RO - SIZELIMIT DIO" - for WORD in $OUTPUT_ALL; do - if ! [[ $prefix == *"$WORD"* ]]; then - OUTPUT="$WORD ${OUTPUT:-""}" - fi - done - compopt -o nospace - COMPREPLY=( $(compgen -P "$prefix" -W "$OUTPUT" -S ',' -- $realcur) ) - return 0 - ;; - '-h'|'--help'|'-V'|'--version') - return 0 - ;; - esac - case $cur in - -*) - OPTS="--all - --detach - --detach-all - --find - --set-capacity - --associated - --nooverlap - --offset - --sizelimit - --partscan - --read-only - --show - --type - --verbose - --json - --list - --noheadings - --output - --output-all - --raw - --help - --version" - COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) ) - return 0 - ;; - esac - local IFS=$'\n' - compopt -o filenames - COMPREPLY=( $(compgen -f -- $cur) ) - return 0 -} -complete -F _xlosetup_module xlosetup diff --git a/utils/config.h.in b/utils/config.h.in deleted file mode 100644 index 40b8d34..0000000 --- a/utils/config.h.in +++ /dev/null @@ -1,897 +0,0 @@ -/* config.h. Generated from config.h.in by configure. */ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define if building universal (internal helper macro) */ -/* #undef AC_APPLE_UNIVERSAL_BUILD */ - -/* Enable agetty --reload feature */ -#define AGETTY_RELOAD 1 - -/* Should chfn and chsh require the user to enter the password? */ -#define CHFN_CHSH_PASSWORD 1 - -/* Path to hwclock adjtime file */ -#define CONFIG_ADJTIME_PATH "/etc/adjtime" - -/* Define if cryptsetup is to be loaded via dlopen */ -/* #undef CRYPTSETUP_VIA_DLOPEN */ - -/* Define to 1 if translation of program messages to the user's native - language is requested. */ -#define ENABLE_NLS 1 - -/* search path for fs helpers */ -#define FS_SEARCH_PATH "/sbin:/sbin/fs.d:/sbin/fs" - -/* Define to 1 if you have the <asm/io.h> header file. */ -/* #undef HAVE_ASM_IO_H */ - -/* Define if btrfs stuff is available */ -#define HAVE_BTRFS_SUPPORT 1 - -/* Define to 1 if you have the <byteswap.h> header file. */ -#define HAVE_BYTESWAP_H 1 - -/* Define to 1 if you have the Mac OS X function CFLocaleCopyCurrent in the - CoreFoundation framework. */ -/* #undef HAVE_CFLOCALECOPYCURRENT */ - -/* Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in - the CoreFoundation framework. */ -/* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */ - -/* Define to 1 if you have the `clearenv' function. */ -#define HAVE_CLEARENV 1 - -/* Define to 1 if you have the `clock_gettime' function. */ -#define HAVE_CLOCK_GETTIME 1 - -/* Define to 1 if the system has the type `cpu_set_t'. */ -#define HAVE_CPU_SET_T 1 - -/* Define if cryptsetup is available */ -/* #undef HAVE_CRYPTSETUP */ - -/* Define if crypt_activate_by_signed_key exist in -lcryptsetup */ -/* #undef HAVE_CRYPT_ACTIVATE_BY_SIGNED_KEY */ - -/* Define to 1 if you have the <crypt.h> header file. */ -#define HAVE_CRYPT_H 1 - -/* Define if the GNU dcgettext() function is already present or preinstalled. - */ -#define HAVE_DCGETTEXT 1 - -/* Define to 1 if you have the declaration of `BLK_ZONE_REP_CAPACITY', and to - 0 if you don't. */ -#define HAVE_DECL_BLK_ZONE_REP_CAPACITY 0 - -/* Define to 1 if you have the declaration of `CPU_ALLOC', and to 0 if you - don't. */ -#define HAVE_DECL_CPU_ALLOC 1 - -/* Define to 1 if you have the declaration of `dirfd', and to 0 if you don't. - */ -/* #undef HAVE_DECL_DIRFD */ - -/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't. - */ -/* #undef HAVE_DECL_TZNAME */ - -/* Define to 1 if you have the declaration of `_NL_TIME_WEEK_1STDAY', and to 0 - if you don't. */ -#define HAVE_DECL__NL_TIME_WEEK_1STDAY 1 - -/* Define to 1 if you have the `dirfd' function. */ -#define HAVE_DIRFD 1 - -/* Define to 1 if `dd_fd' is a member of `DIR'. */ -/* #undef HAVE_DIR_DD_FD */ - -/* Define to 1 if you have the <dlfcn.h> header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the `eaccess' function. */ -#define HAVE_EACCESS 1 - -/* Define to 1 if you have the <endian.h> header file. */ -#define HAVE_ENDIAN_H 1 - -/* Define to 1 if have **environ prototype */ -#define HAVE_ENVIRON_DECL 1 - -/* Define to 1 if you have the `err' function. */ -#define HAVE_ERR 1 - -/* Define to 1 if you have the <errno.h> header file. */ -#define HAVE_ERRNO_H 1 - -/* Define to 1 if you have the `errx' function. */ -#define HAVE_ERRX 1 - -/* Define to 1 if you have the <err.h> header file. */ -#define HAVE_ERR_H 1 - -/* Define to 1 if you have the `explicit_bzero' function. */ -#define HAVE_EXPLICIT_BZERO 1 - -/* Have valid fallocate() function */ -#define HAVE_FALLOCATE 1 - -/* Define to 1 if you have the <fcntl.h> header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have the `fpurge' function. */ -/* #undef HAVE_FPURGE */ - -/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ -#define HAVE_FSEEKO 1 - -/* Define to 1 if you have the `fstatat' function. */ -#define HAVE_FSTATAT 1 - -/* Define to 1 if you have the `fsync' function. */ -#define HAVE_FSYNC 1 - -/* Define to 1 if you have the `futimens' function. */ -#define HAVE_FUTIMENS 1 - -/* Define to 1 if you have the `getdomainname' function. */ -#define HAVE_GETDOMAINNAME 1 - -/* Define to 1 if you have the `getdtablesize' function. */ -#define HAVE_GETDTABLESIZE 1 - -/* Define to 1 if you have the `getexecname' function. */ -/* #undef HAVE_GETEXECNAME */ - -/* Define to 1 if you have the `getmntinfo' function. */ -/* #undef HAVE_GETMNTINFO */ - -/* Define to 1 if you have the <getopt.h> header file. */ -#define HAVE_GETOPT_H 1 - -/* Define to 1 if you have the `getrandom' function. */ -#define HAVE_GETRANDOM 1 - -/* Define to 1 if you have the `getrlimit' function. */ -#define HAVE_GETRLIMIT 1 - -/* Define to 1 if you have the `getsgnam' function. */ -#define HAVE_GETSGNAM 1 - -/* Define if the GNU gettext() function is already present or preinstalled. */ -#define HAVE_GETTEXT 1 - -/* Define to 1 if you have the `getusershell' function. */ -#define HAVE_GETUSERSHELL 1 - -/* Define if you have the iconv() function and it works. */ -/* #undef HAVE_ICONV */ - -/* Define to 1 if you have the `inotify_init' function. */ -#define HAVE_INOTIFY_INIT 1 - -/* Define to 1 if you have the `inotify_init1' function. */ -#define HAVE_INOTIFY_INIT1 1 - -/* Define to 1 if you have the <inttypes.h> header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the `ioperm' function. */ -#define HAVE_IOPERM 1 - -/* Define to 1 if you have the `iopl' function. */ -#define HAVE_IOPL 1 - -/* Define to 1 if you have the `isnan' function. */ -#define HAVE_ISNAN 1 - -/* Define to 1 if you have the `jrand48' function. */ -#define HAVE_JRAND48 1 - -/* Define if langinfo.h defines ALTMON_x constants */ -#define HAVE_LANGINFO_ALTMON 1 - -/* Define to 1 if you have the <langinfo.h> header file. */ -#define HAVE_LANGINFO_H 1 - -/* Define if langinfo.h defines _NL_ABALTMON_x constants */ -#define HAVE_LANGINFO_NL_ABALTMON 1 - -/* Define to 1 if you have the <lastlog.h> header file. */ -#define HAVE_LASTLOG_H 1 - -/* Define to 1 if you have the `lchown' function. */ -#define HAVE_LCHOWN 1 - -/* Define to 1 if you have the `audit' library (-laudit). */ -/* #undef HAVE_LIBAUDIT */ - -/* Define to 1 if you have the -lblkid. */ -#define HAVE_LIBBLKID 1 - -/* Define to 1 if you have the `cap-ng' library (-lcap-ng). */ -#define HAVE_LIBCAP_NG 1 - -/* Do we need -lcrypt? */ -#define HAVE_LIBCRYPT 1 - -/* Define if libeconf is available */ -/* #undef HAVE_LIBECONF */ - -/* Define if libmount available. */ -#define HAVE_LIBMOUNT 1 - -/* Define if ncurses library available */ -/* #undef HAVE_LIBNCURSES */ - -/* Define if ncursesw library available */ -#define HAVE_LIBNCURSESW 1 - -/* Define to 1 if you have the `readline' library (-lreadline). */ -#define HAVE_LIBREADLINE 1 - -/* Define if librtas exists */ -/* #undef HAVE_LIBRTAS */ - -/* Define if SELinux is available */ -/* #undef HAVE_LIBSELINUX */ - -/* Define if libsystemd is available */ -#define HAVE_LIBSYSTEMD 1 - -/* Define if libtinfo or libtinfow available. */ -#define HAVE_LIBTINFO 1 - -/* Define to 1 if you have the `udev' library (-ludev). */ -#define HAVE_LIBUDEV 1 - -/* Define if libuser is available */ -/* #undef HAVE_LIBUSER */ - -/* Define to 1 if you have the `utempter' library (-lutempter). */ -/* #undef HAVE_LIBUTEMPTER */ - -/* Define to 1 if you have the `util' library (-lutil). */ -#define HAVE_LIBUTIL 1 - -/* Define to 1 if you have the <libutil.h> header file. */ -/* #undef HAVE_LIBUTIL_H */ - -/* Define to 1 if you have the -luuid. */ -#define HAVE_LIBUUID 1 - -/* Define to 1 if you have the <linux/blkpg.h> header file. */ -#define HAVE_LINUX_BLKPG_H 1 - -/* Define to 1 if you have the <linux/blkzoned.h> header file. */ -#define HAVE_LINUX_BLKZONED_H 1 - -/* Define to 1 if you have the <linux/btrfs.h> header file. */ -#define HAVE_LINUX_BTRFS_H 1 - -/* Define to 1 if you have the <linux/capability.h> header file. */ -#define HAVE_LINUX_CAPABILITY_H 1 - -/* Define to 1 if you have the <linux/cdrom.h> header file. */ -#define HAVE_LINUX_CDROM_H 1 - -/* Define to 1 if you have the <linux/compiler.h> header file. */ -/* #undef HAVE_LINUX_COMPILER_H */ - -/* Define to 1 if you have the <linux/falloc.h> header file. */ -#define HAVE_LINUX_FALLOC_H 1 - -/* Define to 1 if you have the <linux/fd.h> header file. */ -#define HAVE_LINUX_FD_H 1 - -/* Define to 1 if you have the <linux/fs.h> header file. */ -/* #undef HAVE_LINUX_FS_H */ - -/* Define to 1 if you have the <linux/gsmmux.h> header file. */ -#define HAVE_LINUX_GSMMUX_H 1 - -/* Define to 1 if you have the <linux/major.h> header file. */ -#define HAVE_LINUX_MAJOR_H 1 - -/* Define to 1 if you have the <linux/net_namespace.h> header file. */ -#define HAVE_LINUX_NET_NAMESPACE_H 1 - -/* Define to 1 if you have the <linux/raw.h> header file. */ -#define HAVE_LINUX_RAW_H 1 - -/* Define to 1 if you have the <linux/securebits.h> header file. */ -#define HAVE_LINUX_SECUREBITS_H 1 - -/* Define to 1 if you have the <linux/tiocl.h> header file. */ -#define HAVE_LINUX_TIOCL_H 1 - -/* Define to 1 if you have the <linux/version.h> header file. */ -#define HAVE_LINUX_VERSION_H 1 - -/* Define to 1 if you have the <linux/watchdog.h> header file. */ -#define HAVE_LINUX_WATCHDOG_H 1 - -/* Define to 1 if you have the `llseek' function. */ -/* #undef HAVE_LLSEEK */ - -/* Define to 1 if you have the <locale.h> header file. */ -#define HAVE_LOCALE_H 1 - -/* Define to 1 if the system has the type `loff_t'. */ -#define HAVE_LOFF_T 1 - -/* Define to 1 if you have the libmagic present. */ -#define HAVE_MAGIC 1 - -/* Define to 1 if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `mempcpy' function. */ -#define HAVE_MEMPCPY 1 - -/* Define to 1 if you have the `mkostemp' function. */ -#define HAVE_MKOSTEMP 1 - -/* Define to 1 if you have the <mntent.h> header file. */ -#define HAVE_MNTENT_H 1 - -/* Define to 1 if you have the `nanosleep' function. */ -#define HAVE_NANOSLEEP 1 - -/* Define to 1 if you have the <ncursesw/ncurses.h> header file. */ -/* #undef HAVE_NCURSESW_NCURSES_H */ - -/* Define to 1 if you have the <ncursesw/term.h> header file. */ -/* #undef HAVE_NCURSESW_TERM_H */ - -/* Define to 1 if you have the <ncurses.h> header file. */ -#define HAVE_NCURSES_H 1 - -/* Define to 1 if you have the <ncurses/ncurses.h> header file. */ -/* #undef HAVE_NCURSES_NCURSES_H */ - -/* Define to 1 if you have the <ncurses/term.h> header file. */ -/* #undef HAVE_NCURSES_TERM_H */ - -/* Define to 1 if you have the <netinet/in.h> header file. */ -#define HAVE_NETINET_IN_H 1 - -/* Define to 1 if you have the <net/if_dl.h> header file. */ -/* #undef HAVE_NET_IF_DL_H */ - -/* Define to 1 if you have the <net/if.h> header file. */ -#define HAVE_NET_IF_H 1 - -/* Define to 1 if you have the `ntp_gettime' function. */ -#define HAVE_NTP_GETTIME 1 - -/* Define to 1 if you have the `openat' function. */ -#define HAVE_OPENAT 1 - -/* Define to 1 if you have the `open_memstream' function. */ -#define HAVE_OPEN_MEMSTREAM 1 - -/* Define to 1 if you have the <paths.h> header file. */ -#define HAVE_PATHS_H 1 - -/* Define if libpcre2 is available */ -#define HAVE_PCRE 1 - -/* Define to 1 if you have the `personality' function. */ -#define HAVE_PERSONALITY 1 - -/* Define to 1 if you have the `pidfd_open' function. */ -/* #undef HAVE_PIDFD_OPEN */ - -/* Define to 1 if you have the `pidfd_send_signal' function. */ -/* #undef HAVE_PIDFD_SEND_SIGNAL */ - -/* Define to 1 if you have the `posix_fadvise' function. */ -#define HAVE_POSIX_FADVISE 1 - -/* Have valid posix_fallocate() function */ -#define HAVE_POSIX_FALLOCATE 1 - -/* Define to 1 if you have the `prctl' function. */ -#define HAVE_PRCTL 1 - -/* Define to 1 if you have the `prlimit' function. */ -#define HAVE_PRLIMIT 1 - -/* Define if program_invocation_short_name is defined */ -#define HAVE_PROGRAM_INVOCATION_SHORT_NAME 1 - -/* have PTY support */ -#define HAVE_PTY 1 - -/* Define to 1 if you have the <pty.h> header file. */ -#define HAVE_PTY_H 1 - -/* Define to 1 if you have the `qsort_r' function. */ -#define HAVE_QSORT_R 1 - -/* Define to 1 if you have the `reboot' function. */ -#define HAVE_REBOOT 1 - -/* Define if curses library has the resizeterm(). */ -#define HAVE_RESIZETERM 1 - -/* Define to 1 if you have the `rpmatch' function. */ -#define HAVE_RPMATCH 1 - -/* Define if struct sockaddr contains sa_len */ -/* #undef HAVE_SA_LEN */ - -/* Define to 1 if you have the `scandirat' function. */ -#define HAVE_SCANDIRAT 1 - -/* Define to 1 if you have the `sched_setattr' function. */ -/* #undef HAVE_SCHED_SETATTR */ - -/* Define to 1 if you have the `sched_setscheduler' function. */ -#define HAVE_SCHED_SETSCHEDULER 1 - -/* Define to 1 if you have the `secure_getenv' function. */ -#define HAVE_SECURE_GETENV 1 - -/* Define to 1 if you have the `security_get_initial_context' function. */ -/* #undef HAVE_SECURITY_GET_INITIAL_CONTEXT */ - -/* Define to 1 if you have the <security/openpam.h> header file. */ -/* #undef HAVE_SECURITY_OPENPAM_H */ - -/* Define to 1 if you have the <security/pam_appl.h> header file. */ -#define HAVE_SECURITY_PAM_APPL_H 1 - -/* Define to 1 if you have the <security/pam_misc.h> header file. */ -#define HAVE_SECURITY_PAM_MISC_H 1 - -/* Define to 1 if you have the `setitimer' function. */ -/* #undef HAVE_SETITIMER */ - -/* Define to 1 if you have the `setns' function. */ -#define HAVE_SETNS 1 - -/* Define to 1 if you have the `setprogname' function. */ -/* #undef HAVE_SETPROGNAME */ - -/* Define to 1 if you have the `setresgid' function. */ -#define HAVE_SETRESGID 1 - -/* Define to 1 if you have the `setresuid' function. */ -#define HAVE_SETRESUID 1 - -/* Define to 1 if you have the <shadow.h> header file. */ -#define HAVE_SHADOW_H 1 - -/* Define to 1 if the system has the type `sighandler_t'. */ -#define HAVE_SIGHANDLER_T 1 - -/* Define to 1 if you have the `sigqueue' function. */ -#define HAVE_SIGQUEUE 1 - -/* Define to 1 if you have the <slang.h> header file. */ -/* #undef HAVE_SLANG_H */ - -/* Define to 1 if you have the <slang/slang.h> header file. */ -/* #undef HAVE_SLANG_SLANG_H */ - -/* Define to 1 if you have the <slang/slcurses.h> header file. */ -/* #undef HAVE_SLANG_SLCURSES_H */ - -/* Define to 1 if you have the <slcurses.h> header file. */ -/* #undef HAVE_SLCURSES_H */ - -/* Add SMACK support */ -/* #undef HAVE_SMACK */ - -/* Define to 1 if you have the `srandom' function. */ -#define HAVE_SRANDOM 1 - -/* Define to 1 if you have the <stdint.h> header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the <stdio_ext.h> header file. */ -#define HAVE_STDIO_EXT_H 1 - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the <strings.h> header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the `strnchr' function. */ -/* #undef HAVE_STRNCHR */ - -/* Define to 1 if you have the `strndup' function. */ -#define HAVE_STRNDUP 1 - -/* Define to 1 if you have the `strnlen' function. */ -#define HAVE_STRNLEN 1 - -/* Define to 1 if have strsignal function prototype */ -#define HAVE_STRSIGNAL_DECL 1 - -/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */ -#define HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 1 - -/* Define to 1 if `c_line' is a member of `struct termios'. */ -#define HAVE_STRUCT_TERMIOS_C_LINE 1 - -/* Define to 1 if `tm_zone' is a member of `struct tm'. */ -#define HAVE_STRUCT_TM_TM_ZONE 1 - -/* Define to 1 if you have the `swapoff' function. */ -#define HAVE_SWAPOFF 1 - -/* Define to 1 if you have the `swapon' function. */ -#define HAVE_SWAPON 1 - -/* Define to 1 if you have the `sysconf' function. */ -#define HAVE_SYSCONF 1 - -/* Define to 1 if you have the `sysinfo' function. */ -#define HAVE_SYSINFO 1 - -/* Define to 1 if you have the <sys/disklabel.h> header file. */ -/* #undef HAVE_SYS_DISKLABEL_H */ - -/* Define to 1 if you have the <sys/disk.h> header file. */ -/* #undef HAVE_SYS_DISK_H */ - -/* Define to 1 if you have the <sys/endian.h> header file. */ -/* #undef HAVE_SYS_ENDIAN_H */ - -/* Define to 1 if you have the <sys/file.h> header file. */ -#define HAVE_SYS_FILE_H 1 - -/* Define to 1 if you have the <sys/ioccom.h> header file. */ -/* #undef HAVE_SYS_IOCCOM_H */ - -/* Define to 1 if you have the <sys/ioctl.h> header file. */ -#define HAVE_SYS_IOCTL_H 1 - -/* Define to 1 if you have the <sys/io.h> header file. */ -#define HAVE_SYS_IO_H 1 - -/* Define to 1 if you have the <sys/mkdev.h> header file. */ -/* #undef HAVE_SYS_MKDEV_H */ - -/* Define to 1 if you have the <sys/mount.h> header file. */ -#define HAVE_SYS_MOUNT_H 1 - -/* Define to 1 if you have the <sys/param.h> header file. */ -#define HAVE_SYS_PARAM_H 1 - -/* Define to 1 if you have the <sys/prctl.h> header file. */ -#define HAVE_SYS_PRCTL_H 1 - -/* Define to 1 if you have the <sys/resource.h> header file. */ -#define HAVE_SYS_RESOURCE_H 1 - -/* Define to 1 if you have the <sys/signalfd.h> header file. */ -#define HAVE_SYS_SIGNALFD_H 1 - -/* Define to 1 if you have the <sys/socket.h> header file. */ -#define HAVE_SYS_SOCKET_H 1 - -/* Define to 1 if you have the <sys/sockio.h> header file. */ -/* #undef HAVE_SYS_SOCKIO_H */ - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the <sys/swap.h> header file. */ -#define HAVE_SYS_SWAP_H 1 - -/* Define to 1 if you have the <sys/syscall.h> header file. */ -#define HAVE_SYS_SYSCALL_H 1 - -/* Define to 1 if you have the <sys/sysmacros.h> header file. */ -#define HAVE_SYS_SYSMACROS_H 1 - -/* Define to 1 if you have the <sys/timex.h> header file. */ -#define HAVE_SYS_TIMEX_H 1 - -/* Define to 1 if you have the <sys/time.h> header file. */ -#define HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the <sys/ttydefaults.h> header file. */ -#define HAVE_SYS_TTYDEFAULTS_H 1 - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the <sys/ucred.h> header file. */ -/* #undef HAVE_SYS_UCRED_H */ - -/* Define to 1 if you have the <sys/un.h> header file. */ -#define HAVE_SYS_UN_H 1 - -/* Define to 1 if you have the <term.h> header file. */ -#define HAVE_TERM_H 1 - -/* Define to 1 if you have the `timegm' function. */ -#define HAVE_TIMEGM 1 - -/* Define if timer_create exist in -lrt -lpthread */ -#define HAVE_TIMER_CREATE 1 - -/* Define to 1 if the target supports thread-local storage. */ -#define HAVE_TLS 1 - -/* Does struct tm have a field tm_gmtoff? */ -#define HAVE_TM_GMTOFF 1 - -/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use - `HAVE_STRUCT_TM_TM_ZONE' instead. */ -#define HAVE_TM_ZONE 1 - -/* Define to 1 if you don't have `tm_zone' but do have the external array - `tzname'. */ -/* #undef HAVE_TZNAME */ - -/* Define to 1 if the system has the type `union semun'. */ -/* #undef HAVE_UNION_SEMUN */ - -/* Define to 1 if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the `unlinkat' function. */ -#define HAVE_UNLINKAT 1 - -/* Define to 1 if you have the `unshare' function. */ -#define HAVE_UNSHARE 1 - -/* Define to 1 if you have the `updwtmpx' function. */ -#define HAVE_UPDWTMPX 1 - -/* Define if curses library has the use_default_colors(). */ -#define HAVE_USE_DEFAULT_COLORS 1 - -/* Define to 1 if you have the `usleep' function. */ -#define HAVE_USLEEP 1 - -/* Define to 1 if you have the `utimensat' function. */ -#define HAVE_UTIMENSAT 1 - -/* Define to 1 if you have the <utmpx.h> header file. */ -#define HAVE_UTMPX_H 1 - -/* Define to 1 if you have the <utmp.h> header file. */ -#define HAVE_UTMP_H 1 - -/* Define to 1 if you want to use uuid daemon. */ -#define HAVE_UUIDD 1 - -/* Define to 1 if you have the `vwarnx' function. */ -#define HAVE_VWARNX 1 - -/* Define to 1 if you have the `warn' function. */ -#define HAVE_WARN 1 - -/* Define to 1 if you have the `warnx' function. */ -#define HAVE_WARNX 1 - -/* Do we have wide character support? */ -#define HAVE_WIDECHAR 1 - -/* Define to 1 if you have the `__fpending' function. */ -#define HAVE___FPENDING 1 - -/* Define to 1 if you have the `__fpurge' function. */ -#define HAVE___FPURGE 1 - -/* Define if __progname is defined */ -#define HAVE___PROGNAME 1 - -/* Define to 1 if you have the `__secure_getenv' function. */ -/* #undef HAVE___SECURE_GETENV */ - -/* libblkid date string */ -#define LIBBLKID_DATE "@DATE@" - -/* libblkid version string */ -#define LIBBLKID_VERSION "@VERSION@" - -/* libfdisk version string */ -#define LIBFDISK_VERSION "@VERSION@" - -/* libmount version string */ -#define LIBMOUNT_VERSION "@VERSION@" - -/* libsmartcols version string */ -#define LIBSMARTCOLS_VERSION "@VERSION@" - -/* Should login chown /dev/vcsN? */ -/* #undef LOGIN_CHOWN_VCS */ - -/* Should login stat() the mailbox? */ -/* #undef LOGIN_STAT_MAIL */ - -/* Define to the sub-directory where libtool stores uninstalled libraries. */ -#define LT_OBJDIR ".libs/" - -/* "Multi-arch triplet for whereis library search path" */ -/* #undef MULTIARCHTRIPLET */ - -/* Define to 1 if assertions should be disabled. */ -/* #undef NDEBUG */ - -/* Should chsh allow only shells in /etc/shells? */ -#define ONLY_LISTED_SHELLS 1 - -/* Name of package */ -#define PACKAGE "util-linux" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "kzak@redhat.com" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "util-linux" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "util-linux @VERSION@" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "util-linux" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "http://www.kernel.org/pub/linux/utils/util-linux/" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "@VERSION@" - -/* Should pg ring the bell on invalid keys? */ -#define PG_BELL 1 - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Fallback syscall number for fallocate */ -/* #undef SYS_fallocate */ - -/* Fallback syscall number for ioprio_get */ -/* #undef SYS_ioprio_get */ - -/* Fallback syscall number for ioprio_set */ -/* #undef SYS_ioprio_set */ - -/* Fallback syscall number for pidfd_open */ -/* #undef SYS_pidfd_open */ - -/* Fallback syscall number for pidfd_send_signal */ -/* #undef SYS_pidfd_send_signal */ - -/* Fallback syscall number for pivot_root */ -/* #undef SYS_pivot_root */ - -/* Fallback syscall number for prlimit64 */ -/* #undef SYS_prlimit64 */ - -/* Fallback syscall number for sched_getaffinity */ -/* #undef SYS_sched_getaffinity */ - -/* Fallback syscall number for sched_setattr */ -/* #undef SYS_sched_setattr */ - -/* Fallback syscall number for setns */ -/* #undef SYS_setns */ - -/* Fallback syscall number for swapoff */ -/* #undef SYS_swapoff */ - -/* Fallback syscall number for swapon */ -/* #undef SYS_swapon */ - -/* Fallback syscall number for unshare */ -/* #undef SYS_unshare */ - -/* Define to 1 if your <sys/time.h> declares `struct tm'. */ -/* #undef TM_IN_SYS_TIME */ - -/* Enables colorized output from utils by default */ -#define USE_COLORS_BY_DEFAULT 1 - -/* Define to 1 if want to use CMOS clock. */ -#define USE_HWCLOCK_CMOS 1 - -/* use datetime parsing GPLv3 code to hwclock */ -#define USE_HWCLOCK_GPLv3_DATETIME 1 - -/* Define to 1 if want to support mtab. */ -/* #undef USE_LIBMOUNT_SUPPORT_MTAB */ - -/* Define to 1 if want to support namepaces. */ -#define USE_LIBMOUNT_SUPPORT_NAMESPACES 1 - -/* Enable plymouth support feature for sulogin and aggety */ -#define USE_PLYMOUTH_SUPPORT 1 - -/* Should sulogin use a emergency mount of /dev and /proc? */ -/* #undef USE_SULOGIN_EMERGENCY_MOUNT */ - -/* Enable extensions on AIX 3, Interix. */ -#ifndef _ALL_SOURCE -# define _ALL_SOURCE 1 -#endif -/* Enable GNU extensions on systems that have them. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif -/* Enable threading extensions on Solaris. */ -#ifndef _POSIX_PTHREAD_SEMANTICS -# define _POSIX_PTHREAD_SEMANTICS 1 -#endif -/* Enable extensions on HP NonStop. */ -#ifndef _TANDEM_SOURCE -# define _TANDEM_SOURCE 1 -#endif -/* Enable general extensions on Solaris. */ -#ifndef __EXTENSIONS__ -# define __EXTENSIONS__ 1 -#endif - - -/* Should wall and write be installed setgid tty? */ -#define USE_TTY_GROUP 1 - -/* Define to 1 to remove /bin and /sbin from PATH env.variable */ -/* #undef USE_USRDIR_PATHS_ONLY */ - -/* Define to 1 to use vendordir */ -/* #undef USE_VENDORDIR */ - -/* Version number of package */ -#define VERSION "@VERSION@" - -/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel). */ -#if defined AC_APPLE_UNIVERSAL_BUILD -# if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -# endif -#else -# ifndef WORDS_BIGENDIAN -/* # undef WORDS_BIGENDIAN */ -# endif -#endif - -/* Enable MAP_ANON in sys/mman.h on Mac OS X */ -/* #undef _DARWIN_C_SOURCE */ - -/* Enable large inode numbers on Mac OS X 10.5. */ -#ifndef _DARWIN_USE_64_BIT_INODE -# define _DARWIN_USE_64_BIT_INODE 1 -#endif - -/* Number of bits in a file offset, on hosts where this is settable. */ -/* #undef _FILE_OFFSET_BITS */ - -/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ -/* #undef _LARGEFILE_SOURCE */ - -/* Define for large files, on AIX-style hosts. */ -/* #undef _LARGE_FILES */ - -/* Define to 1 if on MINIX. */ -/* #undef _MINIX */ - -/* Define to 2 if the system does not provide POSIX.1 features except with - this defined. */ -/* #undef _POSIX_1_SOURCE */ - -/* Define to 1 if you need to in order for `stat' and other things to work. */ -/* #undef _POSIX_SOURCE */ - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Define to empty if the keyword `volatile' does not work. Warning: valid - code using `volatile' can become incorrect without. Disable with care. */ -/* #undef volatile */ diff --git a/utils/include/all-io.h b/utils/include/all-io.h deleted file mode 100644 index 8ffa9cf..0000000 --- a/utils/include/all-io.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * No copyright is claimed. This code is in the public domain; do with - * it what you wish. - * - * Written by Karel Zak <kzak@redhat.com> - * Petr Uzel <petr.uzel@suse.cz> - */ - -#ifndef UTIL_LINUX_ALL_IO_H -#define UTIL_LINUX_ALL_IO_H - -#include <string.h> -#include <unistd.h> -#include <errno.h> - -#include "c.h" - -static inline int write_all(int fd, const void *buf, size_t count) -{ - while (count) { - ssize_t tmp; - - errno = 0; - tmp = write(fd, buf, count); - if (tmp > 0) { - count -= tmp; - if (count) - buf = (const void *) ((const char *) buf + tmp); - } else if (errno != EINTR && errno != EAGAIN) - return -1; - if (errno == EAGAIN) /* Try later, *sigh* */ - xusleep(250000); - } - return 0; -} - -static inline int fwrite_all(const void *ptr, size_t size, - size_t nmemb, FILE *stream) -{ - while (nmemb) { - size_t tmp; - - errno = 0; - tmp = fwrite(ptr, size, nmemb, stream); - if (tmp > 0) { - nmemb -= tmp; - if (nmemb) - ptr = (const void *) ((const char *) ptr + (tmp * size)); - } else if (errno != EINTR && errno != EAGAIN) - return -1; - if (errno == EAGAIN) /* Try later, *sigh* */ - xusleep(250000); - } - return 0; -} - -static inline ssize_t read_all(int fd, char *buf, size_t count) -{ - ssize_t ret; - ssize_t c = 0; - int tries = 0; - - memset(buf, 0, count); - while (count > 0) { - ret = read(fd, buf, count); - if (ret <= 0) { - if (ret < 0 && (errno == EAGAIN || errno == EINTR) && (tries++ < 5)) { - xusleep(250000); - continue; - } - return c ? c : -1; - } - tries = 0; - count -= ret; - buf += ret; - c += ret; - } - return c; -} - -#endif /* UTIL_LINUX_ALL_IO_H */ diff --git a/utils/include/bitops.h b/utils/include/bitops.h deleted file mode 100644 index 287d4af..0000000 --- a/utils/include/bitops.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * No copyright is claimed. This code is in the public domain; do with - * it what you wish. - * - * Written by Karel Zak <kzak@redhat.com> - */ -#ifndef BITOPS_H -#define BITOPS_H - -#include <stdint.h> -#include <sys/param.h> - -#if defined(HAVE_BYTESWAP_H) -# include <byteswap.h> -#endif - -#if defined(HAVE_ENDIAN_H) -# include <endian.h> -#elif defined(HAVE_SYS_ENDIAN_H) /* BSDs have them here */ -# include <sys/endian.h> -#endif - -#if defined(__OpenBSD__) -# include <sys/types.h> -# define be16toh(x) betoh16(x) -# define be32toh(x) betoh32(x) -# define be64toh(x) betoh64(x) -#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) -# define bswap_16(x) bswap16(x) -# define bswap_32(x) bswap32(x) -# define bswap_64(x) bswap64(x) -#elif defined(__APPLE__) -# include <libkern/OSByteOrder.h> -# define htobe16(x) OSSwapHostToBigInt16(x) -# define htole16(x) OSSwapHostToLittleInt16(x) -# define be16toh(x) OSSwapBigToHostInt16(x) -# define le16toh(x) OSSwapLittleToHostInt16(x) -# define htobe32(x) OSSwapHostToBigInt32(x) -# define htole32(x) OSSwapHostToLittleInt32(x) -# define be32toh(x) OSSwapBigToHostInt32(x) -# define le32toh(x) OSSwapLittleToHostInt32(x) -# define htobe64(x) OSSwapHostToBigInt64(x) -# define htole64(x) OSSwapHostToLittleInt64(x) -# define be64toh(x) OSSwapBigToHostInt64(x) -# define le64toh(x) OSSwapLittleToHostInt64(x) -# define bswap_16(x) OSSwapInt16(x) -# define bswap_32(x) OSSwapInt32(x) -# define bswap_64(x) OSSwapInt64(x) -#endif - -/* - * Fallbacks - * casts are necessary for constants, because we never know how for sure - * how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way. - */ -#ifndef bswap_16 -# define bswap_16(x) ((uint16_t)( \ - (((uint16_t)(x) & 0x00FF) << 8) | \ - (((uint16_t)(x) & 0xFF00) >> 8))) -#endif - -#ifndef bswap_32 -# define bswap_32(x) ((uint32_t)( \ - (((uint32_t)(x) & 0x000000FF) << 24) | \ - (((uint32_t)(x) & 0x0000FF00) << 8) | \ - (((uint32_t)(x) & 0x00FF0000) >> 8) | \ - (((uint32_t)(x) & 0xFF000000) >> 24))) -#endif - -#ifndef bswap_64 -# define bswap_64(x) ((uint64_t)( \ - (((uint64_t)(x) & 0x00000000000000FFULL) << 56) | \ - (((uint64_t)(x) & 0x000000000000FF00ULL) << 40) | \ - (((uint64_t)(x) & 0x0000000000FF0000ULL) << 24) | \ - (((uint64_t)(x) & 0x00000000FF000000ULL) << 8) | \ - (((uint64_t)(x) & 0x000000FF00000000ULL) >> 8) | \ - (((uint64_t)(x) & 0x0000FF0000000000ULL) >> 24) | \ - (((uint64_t)(x) & 0x00FF000000000000ULL) >> 40) | \ - (((uint64_t)(x) & 0xFF00000000000000ULL) >> 56))) -#endif - -#ifndef htobe16 -# if !defined(WORDS_BIGENDIAN) -# define htobe16(x) bswap_16 (x) -# define htole16(x) (x) -# define be16toh(x) bswap_16 (x) -# define le16toh(x) (x) -# define htobe32(x) bswap_32 (x) -# define htole32(x) (x) -# define be32toh(x) bswap_32 (x) -# define le32toh(x) (x) -# define htobe64(x) bswap_64 (x) -# define htole64(x) (x) -# define be64toh(x) bswap_64 (x) -# define le64toh(x) (x) -# else -# define htobe16(x) (x) -# define htole16(x) bswap_16 (x) -# define be16toh(x) (x) -# define le16toh(x) bswap_16 (x) -# define htobe32(x) (x) -# define htole32(x) bswap_32 (x) -# define be32toh(x) (x) -# define le32toh(x) bswap_32 (x) -# define htobe64(x) (x) -# define htole64(x) bswap_64 (x) -# define be64toh(x) (x) -# define le64toh(x) bswap_64 (x) -# endif -#endif - -/* - * Byte swab macros (based on linux/byteorder/swab.h) - */ -#define swab16(x) bswap_16(x) -#define swab32(x) bswap_32(x) -#define swab64(x) bswap_64(x) - -#define cpu_to_le16(x) ((uint16_t) htole16(x)) -#define cpu_to_le32(x) ((uint32_t) htole32(x)) -#define cpu_to_le64(x) ((uint64_t) htole64(x)) - -#define cpu_to_be16(x) ((uint16_t) htobe16(x)) -#define cpu_to_be32(x) ((uint32_t) htobe32(x)) -#define cpu_to_be64(x) ((uint64_t) htobe64(x)) - -#define le16_to_cpu(x) ((uint16_t) le16toh(x)) -#define le32_to_cpu(x) ((uint32_t) le32toh(x)) -#define le64_to_cpu(x) ((uint64_t) le64toh(x)) - -#define be16_to_cpu(x) ((uint16_t) be16toh(x)) -#define be32_to_cpu(x) ((uint32_t) be32toh(x)) -#define be64_to_cpu(x) ((uint64_t) be64toh(x)) - -/* - * Bit map related macros. Usually provided by libc. - */ -#ifndef NBBY -# define NBBY CHAR_BIT -#endif - -#ifndef setbit -# define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY)) -# define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) -# define isset(a,i) ((a)[(i)/NBBY] & (1<<((i)%NBBY))) -# define isclr(a,i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) -#endif - -#endif /* BITOPS_H */ - diff --git a/utils/include/blkdev.h b/utils/include/blkdev.h deleted file mode 100644 index 6cbecbb..0000000 --- a/utils/include/blkdev.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * No copyright is claimed. This code is in the public domain; do with - * it what you wish. - * - * Written by Karel Zak <kzak@redhat.com> - */ -#ifndef BLKDEV_H -#define BLKDEV_H - -#include <sys/types.h> -#include <sys/ioctl.h> -#ifdef HAVE_SYS_IOCCOM_H -# include <sys/ioccom.h> /* for _IO macro on e.g. Solaris */ -#endif -#include <fcntl.h> -#include <unistd.h> -#include <sys/stat.h> - -#ifdef HAVE_SYS_MKDEV_H -# include <sys/mkdev.h> /* major and minor on Solaris */ -#endif - -#define DEFAULT_SECTOR_SIZE 512 - -#ifdef __linux__ -/* very basic ioctls, should be available everywhere */ -# ifndef BLKROSET -# define BLKROSET _IO(0x12,93) /* set device read-only (0 = read-write) */ -# define BLKROGET _IO(0x12,94) /* get read-only status (0 = read_write) */ -# define BLKRRPART _IO(0x12,95) /* re-read partition table */ -# define BLKGETSIZE _IO(0x12,96) /* return device size /512 (long *arg) */ -# define BLKFLSBUF _IO(0x12,97) /* flush buffer cache */ -# define BLKRASET _IO(0x12,98) /* set read ahead for block device */ -# define BLKRAGET _IO(0x12,99) /* get current read ahead setting */ -# define BLKFRASET _IO(0x12,100) /* set filesystem (mm/filemap.c) read-ahead */ -# define BLKFRAGET _IO(0x12,101) /* get filesystem (mm/filemap.c) read-ahead */ -# define BLKSECTSET _IO(0x12,102) /* set max sectors per request (ll_rw_blk.c) */ -# define BLKSECTGET _IO(0x12,103) /* get max sectors per request (ll_rw_blk.c) */ -# define BLKSSZGET _IO(0x12,104) /* get block device sector size */ - -/* ioctls introduced in 2.2.16, removed in 2.5.58 */ -# define BLKELVGET _IOR(0x12,106,size_t) /* elevator get */ -# define BLKELVSET _IOW(0x12,107,size_t) /* elevator set */ - -# define BLKBSZGET _IOR(0x12,112,size_t) -# define BLKBSZSET _IOW(0x12,113,size_t) -# endif /* !BLKROSET */ - -# ifndef BLKGETSIZE64 -# define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size in bytes (u64 *arg) */ -# endif - -/* block device topology ioctls, introduced in 2.6.32 (commit ac481c20) */ -# ifndef BLKIOMIN -# define BLKIOMIN _IO(0x12,120) -# define BLKIOOPT _IO(0x12,121) -# define BLKALIGNOFF _IO(0x12,122) -# define BLKPBSZGET _IO(0x12,123) -# endif - -/* discard zeroes support, introduced in 2.6.33 (commit 98262f27) */ -# ifndef BLKDISCARDZEROES -# define BLKDISCARDZEROES _IO(0x12,124) -# endif - -/* filesystem freeze, introduced in 2.6.29 (commit fcccf502) */ -# ifndef FIFREEZE -# define FIFREEZE _IOWR('X', 119, int) /* Freeze */ -# define FITHAW _IOWR('X', 120, int) /* Thaw */ -# endif - -/* uniform CD-ROM information */ -# ifndef CDROM_GET_CAPABILITY -# define CDROM_GET_CAPABILITY 0x5331 -# endif - -#endif /* __linux */ - - -#ifdef APPLE_DARWIN -# define BLKGETSIZE DKIOCGETBLOCKCOUNT32 -#endif - -#ifndef HDIO_GETGEO -# ifdef __linux__ -# define HDIO_GETGEO 0x0301 -# endif - -struct hd_geometry { - unsigned char heads; - unsigned char sectors; - unsigned short cylinders; /* truncated */ - unsigned long start; -}; -#endif /* HDIO_GETGEO */ - - -/* are we working with block device? */ -int is_blkdev(int fd); - -/* open block device or file */ -int open_blkdev_or_file(const struct stat *st, const char *name, const int oflag); - -/* Determine size in bytes */ -off_t blkdev_find_size (int fd); - -/* get size in bytes */ -int blkdev_get_size(int fd, unsigned long long *bytes); - -/* get 512-byte sector count */ -int blkdev_get_sectors(int fd, unsigned long long *sectors); - -/* get hardware sector size */ -int blkdev_get_sector_size(int fd, int *sector_size); - -/* specifies whether or not the device is misaligned */ -int blkdev_is_misaligned(int fd); - -/* get physical block device size */ -int blkdev_get_physector_size(int fd, int *sector_size); - -/* is the device cdrom capable? */ -int blkdev_is_cdrom(int fd); - -/* get device's geometry - legacy */ -int blkdev_get_geometry(int fd, unsigned int *h, unsigned int *s); - -/* SCSI device types. Copied almost as-is from kernel header. - * http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/scsi/scsi.h */ -#define SCSI_TYPE_DISK 0x00 -#define SCSI_TYPE_TAPE 0x01 -#define SCSI_TYPE_PRINTER 0x02 -#define SCSI_TYPE_PROCESSOR 0x03 /* HP scanners use this */ -#define SCSI_TYPE_WORM 0x04 /* Treated as ROM by our system */ -#define SCSI_TYPE_ROM 0x05 -#define SCSI_TYPE_SCANNER 0x06 -#define SCSI_TYPE_MOD 0x07 /* Magneto-optical disk - treated as SCSI_TYPE_DISK */ -#define SCSI_TYPE_MEDIUM_CHANGER 0x08 -#define SCSI_TYPE_COMM 0x09 /* Communications device */ -#define SCSI_TYPE_RAID 0x0c -#define SCSI_TYPE_ENCLOSURE 0x0d /* Enclosure Services Device */ -#define SCSI_TYPE_RBC 0x0e -#define SCSI_TYPE_OSD 0x11 -#define SCSI_TYPE_NO_LUN 0x7f - -/* convert scsi type code to name */ -const char *blkdev_scsi_type_to_name(int type); - -int blkdev_lock(int fd, const char *devname, const char *lockmode); - -#endif /* BLKDEV_H */ diff --git a/utils/include/c.h b/utils/include/c.h deleted file mode 100644 index ae08131..0000000 --- a/utils/include/c.h +++ /dev/null @@ -1,427 +0,0 @@ -/* - * Fundamental C definitions. - * - * No copyright is claimed. This code is in the public domain; do with - * it what you wish. - */ -#ifndef UTIL_LINUX_C_H -#define UTIL_LINUX_C_H - -#include <limits.h> -#include <stddef.h> -#include <stdint.h> -#include <stdio.h> -#include <unistd.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -#include <assert.h> - -#ifdef HAVE_ERR_H -# include <err.h> -#endif - -#ifdef HAVE_SYS_SYSMACROS_H -# include <sys/sysmacros.h> /* for major, minor */ -#endif - -#ifndef LOGIN_NAME_MAX -# define LOGIN_NAME_MAX 256 -#endif - -#ifndef NAME_MAX -# define NAME_MAX PATH_MAX -#endif - -/* - * __GNUC_PREREQ is deprecated in favour of __has_attribute() and - * __has_feature(). The __has macros are supported by clang and gcc>=5. - */ -#ifndef __GNUC_PREREQ -# if defined __GNUC__ && defined __GNUC_MINOR__ -# define __GNUC_PREREQ(maj, min) \ - ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) -# else -# define __GNUC_PREREQ(maj, min) 0 -# endif -#endif - -#ifdef __GNUC__ - -/* &a[0] degrades to a pointer: a different type from an array */ -# define __must_be_array(a) \ - UL_BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(__typeof__(a), __typeof__(&a[0]))) - -# define ignore_result(x) __extension__ ({ \ - __typeof__(x) __dummy __attribute__((__unused__)) = (x); (void) __dummy; \ -}) - -#else /* !__GNUC__ */ -# define __must_be_array(a) 0 -# define __attribute__(_arg_) -# define ignore_result(x) ((void) (x)) -#endif /* !__GNUC__ */ - -/* - * It evaluates to 1 if the attribute/feature is supported by the current - * compilation target. Fallback for old compilers. - */ -#ifndef __has_attribute - #define __has_attribute(x) 0 -#endif - -#ifndef __has_feature - #define __has_feature(x) 0 -#endif - -/* - * Function attributes - */ -#ifndef __ul_alloc_size -# if (__has_attribute(alloc_size) && __has_attribute(warn_unused_result)) || __GNUC_PREREQ (4, 3) -# define __ul_alloc_size(s) __attribute__((alloc_size(s), warn_unused_result)) -# else -# define __ul_alloc_size(s) -# endif -#endif - -#ifndef __ul_calloc_size -# if (__has_attribute(alloc_size) && __has_attribute(warn_unused_result)) || __GNUC_PREREQ (4, 3) -# define __ul_calloc_size(n, s) __attribute__((alloc_size(n, s), warn_unused_result)) -# else -# define __ul_calloc_size(n, s) -# endif -#endif - -#if __has_attribute(returns_nonnull) || __GNUC_PREREQ (4, 9) -# define __ul_returns_nonnull __attribute__((returns_nonnull)) -#else -# define __ul_returns_nonnull -#endif - -/* - * Force a compilation error if condition is true, but also produce a - * result (of value 0 and type size_t), so the expression can be used - * e.g. in a structure initializer (or wherever else comma expressions - * aren't permitted). - */ -#define UL_BUILD_BUG_ON_ZERO(e) __extension__ (sizeof(struct { int:-!!(e); })) -#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); })) - -#ifndef ARRAY_SIZE -# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) -#endif - -#ifndef PATH_MAX -# define PATH_MAX 4096 -#endif - -#ifndef TRUE -# define TRUE 1 -#endif - -#ifndef FALSE -# define FALSE 0 -#endif - -#ifndef min -# define min(x, y) __extension__ ({ \ - __typeof__(x) _min1 = (x); \ - __typeof__(y) _min2 = (y); \ - (void) (&_min1 == &_min2); \ - _min1 < _min2 ? _min1 : _min2; }) -#endif - -#ifndef max -# define max(x, y) __extension__ ({ \ - __typeof__(x) _max1 = (x); \ - __typeof__(y) _max2 = (y); \ - (void) (&_max1 == &_max2); \ - _max1 > _max2 ? _max1 : _max2; }) -#endif - -#ifndef cmp_numbers -# define cmp_numbers(x, y) __extension__ ({ \ - __typeof__(x) _a = (x); \ - __typeof__(y) _b = (y); \ - (void) (&_a == &_b); \ - _a == _b ? 0 : _a > _b ? 1 : -1; }) -#endif - -#ifndef offsetof -#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) -#endif - -/* - * container_of - cast a member of a structure out to the containing structure - * @ptr: the pointer to the member. - * @type: the type of the container struct this is embedded in. - * @member: the name of the member within the struct. - */ -#ifndef container_of -#define container_of(ptr, type, member) __extension__ ({ \ - const __typeof__( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) -#endif - -#ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME -# ifdef HAVE___PROGNAME -extern char *__progname; -# define program_invocation_short_name __progname -# else -# ifdef HAVE_GETEXECNAME -# define program_invocation_short_name \ - prog_inv_sh_nm_from_file(getexecname(), 0) -# else -# define program_invocation_short_name \ - prog_inv_sh_nm_from_file(__FILE__, 1) -# endif -static char prog_inv_sh_nm_buf[256]; -static inline char * -prog_inv_sh_nm_from_file(char *f, char stripext) -{ - char *t; - - if ((t = strrchr(f, '/')) != NULL) - t++; - else - t = f; - - strncpy(prog_inv_sh_nm_buf, t, sizeof(prog_inv_sh_nm_buf) - 1); - prog_inv_sh_nm_buf[sizeof(prog_inv_sh_nm_buf) - 1] = '\0'; - - if (stripext && (t = strrchr(prog_inv_sh_nm_buf, '.')) != NULL) - *t = '\0'; - - return prog_inv_sh_nm_buf; -} -# endif -#endif - - -#ifndef HAVE_ERR_H -static inline void -errmsg(char doexit, int excode, char adderr, const char *fmt, ...) -{ - fprintf(stderr, "%s: ", program_invocation_short_name); - if (fmt != NULL) { - va_list argp; - va_start(argp, fmt); - vfprintf(stderr, fmt, argp); - va_end(argp); - if (adderr) - fprintf(stderr, ": "); - } - if (adderr) - fprintf(stderr, "%m"); - fprintf(stderr, "\n"); - if (doexit) - exit(excode); -} - -#ifndef HAVE_ERR -# define err(E, FMT...) errmsg(1, E, 1, FMT) -#endif - -#ifndef HAVE_ERRX -# define errx(E, FMT...) errmsg(1, E, 0, FMT) -#endif - -#ifndef HAVE_WARN -# define warn(FMT...) errmsg(0, 0, 1, FMT) -#endif - -#ifndef HAVE_WARNX -# define warnx(FMT...) errmsg(0, 0, 0, FMT) -#endif -#endif /* !HAVE_ERR_H */ - - -/* Don't use inline function to avoid '#include "nls.h"' in c.h - */ -#define errtryhelp(eval) __extension__ ({ \ - fprintf(stderr, _("Try '%s --help' for more information.\n"), \ - program_invocation_short_name); \ - exit(eval); \ -}) - -/* After failed execvp() */ -#define EX_EXEC_FAILED 126 /* Program located, but not usable. */ -#define EX_EXEC_ENOENT 127 /* Could not find program to exec. */ -#define errexec(name) err(errno == ENOENT ? EX_EXEC_ENOENT : EX_EXEC_FAILED, \ - _("failed to execute %s"), name) - - -static inline __attribute__((const)) int is_power_of_2(unsigned long num) -{ - return (num != 0 && ((num & (num - 1)) == 0)); -} - -#ifndef HAVE_LOFF_T -typedef int64_t loff_t; -#endif - -#if !defined(HAVE_DIRFD) && (!defined(HAVE_DECL_DIRFD) || HAVE_DECL_DIRFD == 0) && defined(HAVE_DIR_DD_FD) -#include <sys/types.h> -#include <dirent.h> -static inline int dirfd(DIR *d) -{ - return d->dd_fd; -} -#endif - -/* - * Fallback defines for old versions of glibc - */ -#include <fcntl.h> - -#ifdef O_CLOEXEC -#define UL_CLOEXECSTR "e" -#else -#define UL_CLOEXECSTR "" -#endif - -#ifndef O_CLOEXEC -#define O_CLOEXEC 0 -#endif - -#ifdef __FreeBSD_kernel__ -#ifndef F_DUPFD_CLOEXEC -#define F_DUPFD_CLOEXEC 17 /* Like F_DUPFD, but FD_CLOEXEC is set */ -#endif -#endif - - -#ifndef AI_ADDRCONFIG -#define AI_ADDRCONFIG 0x0020 -#endif - -#ifndef IUTF8 -#define IUTF8 0040000 -#endif - -/* - * MAXHOSTNAMELEN replacement - */ -static inline size_t get_hostname_max(void) -{ - long len = sysconf(_SC_HOST_NAME_MAX); - - if (0 < len) - return len; - -#ifdef MAXHOSTNAMELEN - return MAXHOSTNAMELEN; -#elif HOST_NAME_MAX - return HOST_NAME_MAX; -#endif - return 64; -} - -/* - * The usleep function was marked obsolete in POSIX.1-2001 and was removed - * in POSIX.1-2008. It was replaced with nanosleep() that provides more - * advantages (like no interaction with signals and other timer functions). - */ -#include <time.h> - -static inline int xusleep(useconds_t usec) -{ -#ifdef HAVE_NANOSLEEP - struct timespec waittime = { - .tv_sec = usec / 1000000L, - .tv_nsec = (usec % 1000000L) * 1000 - }; - return nanosleep(&waittime, NULL); -#elif defined(HAVE_USLEEP) - return usleep(usec); -#else -# error "System with usleep() or nanosleep() required!" -#endif -} - -/* - * Constant strings for usage() functions. For more info see - * Documentation/{howto-usage-function.txt,boilerplate.c} - */ -#define USAGE_HEADER _("\nUsage:\n") -#define USAGE_OPTIONS _("\nOptions:\n") -#define USAGE_FUNCTIONS _("\nFunctions:\n") -#define USAGE_COMMANDS _("\nCommands:\n") -#define USAGE_ARGUMENTS _("\nArguments:\n") -#define USAGE_COLUMNS _("\nAvailable output columns:\n") -#define USAGE_SEPARATOR "\n" - -#define USAGE_OPTSTR_HELP _("display this help") -#define USAGE_OPTSTR_VERSION _("display version") - -#define USAGE_HELP_OPTIONS(marg_dsc) \ - "%-" #marg_dsc "s%s\n" \ - "%-" #marg_dsc "s%s\n" \ - , " -h, --help", USAGE_OPTSTR_HELP \ - , " -V, --version", USAGE_OPTSTR_VERSION - -#define USAGE_ARG_SEPARATOR "\n" -#define USAGE_ARG_SIZE(_name) \ - _(" %s arguments may be followed by the suffixes for\n" \ - " GiB, TiB, PiB, EiB, ZiB, and YiB (the \"iB\" is optional)\n"), _name - -#define USAGE_MAN_TAIL(_man) _("\nFor more details see %s.\n"), _man - -#define UTIL_LINUX_VERSION _("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING - -#define print_version(eval) __extension__ ({ \ - printf(UTIL_LINUX_VERSION); \ - exit(eval); \ -}) - -/* - * seek stuff - */ -#ifndef SEEK_DATA -# define SEEK_DATA 3 -#endif -#ifndef SEEK_HOLE -# define SEEK_HOLE 4 -#endif - - -/* - * Macros to convert #define'itions to strings, for example - * #define XYXXY 42 - * printf ("%s=%s\n", stringify(XYXXY), stringify_value(XYXXY)); - */ -#define stringify_value(s) stringify(s) -#define stringify(s) #s - -/* - * UL_ASAN_BLACKLIST is a macro to tell AddressSanitizer (a compile-time - * instrumentation shipped with Clang and GCC) to not instrument the - * annotated function. Furthermore, it will prevent the compiler from - * inlining the function because inlining currently breaks the blacklisting - * mechanism of AddressSanitizer. - */ -#if __has_feature(address_sanitizer) && __has_attribute(no_sanitize_memory) && __has_attribute(no_sanitize_address) -# define UL_ASAN_BLACKLIST __attribute__((noinline)) __attribute__((no_sanitize_memory)) __attribute__((no_sanitize_address)) -#else -# define UL_ASAN_BLACKLIST /* nothing */ -#endif - -/* - * Note that sysconf(_SC_GETPW_R_SIZE_MAX) returns *initial* suggested size for - * pwd buffer and in some cases it is not large enough. See POSIX and - * getpwnam_r man page for more details. - */ -#define UL_GETPW_BUFSIZ (16 * 1024) - -/* - * Darwin or other BSDs may only have MAP_ANON. To get it on Darwin we must - * define _DARWIN_C_SOURCE before including sys/mman.h. We do this in config.h. - */ -#if !defined MAP_ANONYMOUS && defined MAP_ANON -# define MAP_ANONYMOUS (MAP_ANON) -#endif - -#endif /* UTIL_LINUX_C_H */ diff --git a/utils/include/canonicalize.h b/utils/include/canonicalize.h deleted file mode 100644 index ff6ef0d..0000000 --- a/utils/include/canonicalize.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library Public License for more details. - */ -#ifndef CANONICALIZE_H -#define CANONICALIZE_H - -#include "c.h" /* for PATH_MAX */ -#include "strutils.h" - -extern char *canonicalize_path(const char *path); -extern char *canonicalize_path_restricted(const char *path); -extern char *canonicalize_dm_name(const char *ptname); -extern char *__canonicalize_dm_name(const char *prefix, const char *ptname); - -extern char *absolute_path(const char *path); - -static inline int is_relative_path(const char *path) -{ - if (!path || *path == '/') - return 0; - return 1; -} - -#endif /* CANONICALIZE_H */ diff --git a/utils/include/caputils.h b/utils/include/caputils.h deleted file mode 100644 index 852903a..0000000 --- a/utils/include/caputils.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef CAPUTILS_H -#define CAPUTILS_H - -#include <linux/capability.h> - -#ifndef PR_CAP_AMBIENT -# define PR_CAP_AMBIENT 47 -# define PR_CAP_AMBIENT_IS_SET 1 -# define PR_CAP_AMBIENT_RAISE 2 -# define PR_CAP_AMBIENT_LOWER 3 -#endif - -extern int capset(cap_user_header_t header, cap_user_data_t data); -extern int capget(cap_user_header_t header, const cap_user_data_t data); - -extern int cap_last_cap(void); - -#endif /* CAPUTILS_H */ diff --git a/utils/include/carefulputc.h b/utils/include/carefulputc.h deleted file mode 100644 index f1c0356..0000000 --- a/utils/include/carefulputc.h +++ /dev/null @@ -1,155 +0,0 @@ -#ifndef UTIL_LINUX_CAREFULPUTC_H -#define UTIL_LINUX_CAREFULPUTC_H - -/* - * A putc() for use in write and wall (that sometimes are sgid tty). - * It avoids control characters in our locale, and also ASCII control - * characters. Note that the locale of the recipient is unknown. -*/ -#include <stdio.h> -#include <string.h> -#include <ctype.h> - -#include "cctype.h" - -static inline int fputc_careful(int c, FILE *fp, const char fail) -{ - int ret; - - if (isprint(c) || c == '\a' || c == '\t' || c == '\r' || c == '\n') - ret = putc(c, fp); - else if (!c_isascii(c)) - ret = fprintf(fp, "\\%3o", (unsigned char)c); - else { - ret = putc(fail, fp); - if (ret != EOF) - ret = putc(c ^ 0x40, fp); - } - return (ret < 0) ? EOF : 0; -} - -/* - * Requirements enumerated via testing (V8, Firefox, IE11): - * - * var charsToEscape = []; - * for (var i = 0; i < 65535; i += 1) { - * try { - * JSON.parse('{"sample": "' + String.fromCodePoint(i) + '"}'); - * } catch (e) { - * charsToEscape.push(i); - * } - * } - */ -static inline void fputs_quoted_case_json(const char *data, FILE *out, int dir) -{ - const char *p; - - fputc('"', out); - for (p = data; p && *p; p++) { - - const unsigned char c = (unsigned char) *p; - - /* From http://www.json.org - * - * The double-quote and backslashes would break out a string or - * init an escape sequence if not escaped. - * - * Note that single-quotes and forward slashes, while they're - * in the JSON spec, don't break double-quoted strings. - */ - if (c == '"' || c == '\\') { - fputc('\\', out); - fputc(c, out); - continue; - } - - /* All non-control characters OK; do the case swap as required. */ - if (c >= 0x20) { - fputc(dir == 1 ? toupper(c) : - dir == -1 ? tolower(c) : *p, out); - continue; - } - - /* In addition, all chars under ' ' break Node's/V8/Chrome's, and - * Firefox's JSON.parse function - */ - switch (c) { - /* Handle short-hand cases to reduce output size. C - * has most of the same stuff here, so if there's an - * "Escape for C" function somewhere in the STL, we - * should probably be using it. - */ - case '\b': - fputs("\\b", out); - break; - case '\t': - fputs("\\t", out); - break; - case '\n': - fputs("\\n", out); - break; - case '\f': - fputs("\\f", out); - break; - case '\r': - fputs("\\r", out); - break; - default: - /* Other assorted control characters */ - fprintf(out, "\\u00%02x", c); - break; - } - } - fputc('"', out); -} - - -static inline void fputs_quoted_case(const char *data, FILE *out, int dir) -{ - const char *p; - - fputc('"', out); - for (p = data; p && *p; p++) { - if ((unsigned char) *p == 0x22 || /* " */ - (unsigned char) *p == 0x5c || /* \ */ - (unsigned char) *p == 0x60 || /* ` */ - (unsigned char) *p == 0x24 || /* $ */ - !isprint((unsigned char) *p) || - iscntrl((unsigned char) *p)) { - - fprintf(out, "\\x%02x", (unsigned char) *p); - } else - fputc(dir == 1 ? toupper(*p) : - dir == -1 ? tolower(*p) : - *p, out); - } - fputc('"', out); -} - -#define fputs_quoted(_d, _o) fputs_quoted_case(_d, _o, 0) -#define fputs_quoted_upper(_d, _o) fputs_quoted_case(_d, _o, 1) -#define fputs_quoted_lower(_d, _o) fputs_quoted_case(_d, _o, -1) - -#define fputs_quoted_json(_d, _o) fputs_quoted_case_json(_d, _o, 0) -#define fputs_quoted_json_upper(_d, _o) fputs_quoted_case_json(_d, _o, 1) -#define fputs_quoted_json_lower(_d, _o) fputs_quoted_case_json(_d, _o, -1) - -static inline void fputs_nonblank(const char *data, FILE *out) -{ - const char *p; - - for (p = data; p && *p; p++) { - if (isblank((unsigned char) *p) || - (unsigned char) *p == 0x5c || /* \ */ - !isprint((unsigned char) *p) || - iscntrl((unsigned char) *p)) { - - fprintf(out, "\\x%02x", (unsigned char) *p); - - } else - fputc(*p, out); - } -} - - -#endif /* _CAREFULPUTC_H */ diff --git a/utils/include/cctype.h b/utils/include/cctype.h deleted file mode 100644 index 6ab644c..0000000 --- a/utils/include/cctype.h +++ /dev/null @@ -1,325 +0,0 @@ -/** - * Character handling in C locale. - * - * This file is based on gnulib c-ctype.h-dd7a871 with the - * other gnulib dependencies removed for use in util-linux. - * - * These functions work like the corresponding functions in <ctype.h>, - * except that they have the C (POSIX) locale hardwired, whereas the - * <ctype.h> functions' behaviour depends on the current locale set via - * setlocale. - * - * Copyright (C) 2000-2003, 2006, 2008-2017 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef UTIL_LINUX_CCTYPE_H -#define UTIL_LINUX_CCTYPE_H - -/** - * The functions defined in this file assume the "C" locale and a character - * set without diacritics (ASCII-US or EBCDIC-US or something like that). - * Even if the "C" locale on a particular system is an extension of the ASCII - * character set (like on BeOS, where it is UTF-8, or on AmigaOS, where it - * is ISO-8859-1), the functions in this file recognize only the ASCII - * characters. - */ - -#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ - && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ - && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ - && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ - && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ - && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ - && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ - && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ - && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ - && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ - && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ - && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ - && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ - && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ - && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ - && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ - && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ - && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ - && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ - && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ - && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ - && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ - && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126) - -/* - * The character set is ASCII or one of its variants or extensions, not EBCDIC. - * Testing the value of '\n' and '\r' is not relevant. - */ -# define C_CTYPE_ASCII 1 -#elif ! (' ' == '\x40' && '0' == '\xf0' \ - && 'A' == '\xc1' && 'J' == '\xd1' && 'S' == '\xe2' \ - && 'a' == '\x81' && 'j' == '\x91' && 's' == '\xa2') -# error "Only ASCII and EBCDIC are supported" -#endif - -#if 'A' < 0 -# error "EBCDIC and char is signed -- not supported" -#endif - -/* Cases for control characters. */ -#define _C_CTYPE_CNTRL \ - case '\a': case '\b': case '\f': case '\n': \ - case '\r': case '\t': case '\v': \ - _C_CTYPE_OTHER_CNTRL - -/* ASCII control characters other than those with \-letter escapes. */ -#if C_CTYPE_ASCII -# define _C_CTYPE_OTHER_CNTRL \ - case '\x00': case '\x01': case '\x02': case '\x03': \ - case '\x04': case '\x05': case '\x06': case '\x0e': \ - case '\x0f': case '\x10': case '\x11': case '\x12': \ - case '\x13': case '\x14': case '\x15': case '\x16': \ - case '\x17': case '\x18': case '\x19': case '\x1a': \ - case '\x1b': case '\x1c': case '\x1d': case '\x1e': \ - case '\x1f': case '\x7f' -#else - -/* - * Use EBCDIC code page 1047's assignments for ASCII control chars; - * assume all EBCDIC code pages agree about these assignments. - */ -# define _C_CTYPE_OTHER_CNTRL \ - case '\x00': case '\x01': case '\x02': case '\x03': \ - case '\x07': case '\x0e': case '\x0f': case '\x10': \ - case '\x11': case '\x12': case '\x13': case '\x18': \ - case '\x19': case '\x1c': case '\x1d': case '\x1e': \ - case '\x1f': case '\x26': case '\x27': case '\x2d': \ - case '\x2e': case '\x32': case '\x37': case '\x3c': \ - case '\x3d': case '\x3f' -#endif - -/* Cases for lowercase hex letters, and lowercase letters, all offset by N. */ -#define _C_CTYPE_LOWER_A_THRU_F_N(N) \ - case 'a' + (N): case 'b' + (N): case 'c' + (N): case 'd' + (N): \ - case 'e' + (N): case 'f' + (N) -#define _C_CTYPE_LOWER_N(N) \ - _C_CTYPE_LOWER_A_THRU_F_N(N): \ - case 'g' + (N): case 'h' + (N): case 'i' + (N): case 'j' + (N): \ - case 'k' + (N): case 'l' + (N): case 'm' + (N): case 'n' + (N): \ - case 'o' + (N): case 'p' + (N): case 'q' + (N): case 'r' + (N): \ - case 's' + (N): case 't' + (N): case 'u' + (N): case 'v' + (N): \ - case 'w' + (N): case 'x' + (N): case 'y' + (N): case 'z' + (N) - -/* Cases for hex letters, digits, lower, punct, and upper. */ -#define _C_CTYPE_A_THRU_F \ - _C_CTYPE_LOWER_A_THRU_F_N (0): \ - _C_CTYPE_LOWER_A_THRU_F_N ('A' - 'a') -#define _C_CTYPE_DIGIT \ - case '0': case '1': case '2': case '3': \ - case '4': case '5': case '6': case '7': \ - case '8': case '9' -#define _C_CTYPE_LOWER _C_CTYPE_LOWER_N (0) -#define _C_CTYPE_PUNCT \ - case '!': case '"': case '#': case '$': \ - case '%': case '&': case '\'': case '(': \ - case ')': case '*': case '+': case ',': \ - case '-': case '.': case '/': case ':': \ - case ';': case '<': case '=': case '>': \ - case '?': case '@': case '[': case '\\': \ - case ']': case '^': case '_': case '`': \ - case '{': case '|': case '}': case '~' -#define _C_CTYPE_UPPER _C_CTYPE_LOWER_N ('A' - 'a') - -/** - * Function definitions. - * - * Unlike the functions in <ctype.h>, which require an argument in the range - * of the 'unsigned char' type, the functions here operate on values that are - * in the 'unsigned char' range or in the 'char' range. In other words, - * when you have a 'char' value, you need to cast it before using it as - * argument to a <ctype.h> function: - * - * const char *s = ...; - * if (isalpha ((unsigned char) *s)) ... - * - * but you don't need to cast it for the functions defined in this file: - * - * const char *s = ...; - * if (c_isalpha (*s)) ... - */ - -static inline int c_isalnum (int c) -{ - switch (c) { - _C_CTYPE_DIGIT: - _C_CTYPE_LOWER: - _C_CTYPE_UPPER: - return 1; - default: - return 0; - } -} - -static inline int c_isalpha (int c) -{ - switch (c) { - _C_CTYPE_LOWER: - _C_CTYPE_UPPER: - return 1; - default: - return 0; - } -} - -/* The function isascii is not locale dependent. - * Its use in EBCDIC is questionable. - */ -static inline int c_isascii (int c) -{ - switch (c) { - case ' ': - _C_CTYPE_CNTRL: - _C_CTYPE_DIGIT: - _C_CTYPE_LOWER: - _C_CTYPE_PUNCT: - _C_CTYPE_UPPER: - return 1; - default: - return 0; - } -} - -static inline int c_isblank (int c) -{ - return c == ' ' || c == '\t'; -} - -static inline int c_iscntrl (int c) -{ - switch (c) { - _C_CTYPE_CNTRL: - return 1; - default: - return 0; - } -} - -static inline int c_isdigit (int c) -{ - switch (c) { - _C_CTYPE_DIGIT: - return 1; - default: - return 0; - } -} - -static inline int c_isgraph (int c) -{ - switch (c) { - _C_CTYPE_DIGIT: - _C_CTYPE_LOWER: - _C_CTYPE_PUNCT: - _C_CTYPE_UPPER: - return 1; - default: - return 0; - } -} - -static inline int c_islower (int c) -{ - switch (c) { - _C_CTYPE_LOWER: - return 1; - default: - return 0; - } -} - -static inline int c_isprint (int c) -{ - switch (c) { - case ' ': - _C_CTYPE_DIGIT: - _C_CTYPE_LOWER: - _C_CTYPE_PUNCT: - _C_CTYPE_UPPER: - return 1; - default: - return 0; - } -} - -static inline int c_ispunct (int c) -{ - switch (c) { - _C_CTYPE_PUNCT: - return 1; - default: - return 0; - } -} - -static inline int c_isspace (int c) -{ - switch (c) { - case ' ': case '\t': case '\n': case '\v': case '\f': case '\r': - return 1; - default: - return 0; - } -} - -static inline int c_isupper (int c) -{ - switch (c) { - _C_CTYPE_UPPER: - return 1; - default: - return 0; - } -} - -static inline int c_isxdigit (int c) -{ - switch (c) { - _C_CTYPE_DIGIT: - _C_CTYPE_A_THRU_F: - return 1; - default: - return 0; - } -} - -static inline int c_tolower (int c) -{ - switch (c) { - _C_CTYPE_UPPER: - return c - 'A' + 'a'; - default: - return c; - } -} - -static inline int c_toupper (int c) -{ - switch (c) { - _C_CTYPE_LOWER: - return c - 'a' + 'A'; - default: - return c; - } -} - -#endif /* UTIL_LINUX_CCTYPE_H */ diff --git a/utils/include/closestream.h b/utils/include/closestream.h deleted file mode 100644 index 41afbe2..0000000 --- a/utils/include/closestream.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef UTIL_LINUX_CLOSESTREAM_H -#define UTIL_LINUX_CLOSESTREAM_H - -#include <stdio.h> -#ifdef HAVE_STDIO_EXT_H -#include <stdio_ext.h> -#endif -#include <unistd.h> - -#include "c.h" -#include "nls.h" - -#ifndef CLOSE_EXIT_CODE -# define CLOSE_EXIT_CODE EXIT_FAILURE -#endif - -static inline int -close_stream(FILE * stream) -{ -#ifdef HAVE___FPENDING - const int some_pending = (__fpending(stream) != 0); -#endif - const int prev_fail = (ferror(stream) != 0); - const int fclose_fail = (fclose(stream) != 0); - - if (prev_fail || (fclose_fail && ( -#ifdef HAVE___FPENDING - some_pending || -#endif - errno != EBADF))) { - if (!fclose_fail && !(errno == EPIPE)) - errno = 0; - return EOF; - } - return 0; -} - -static inline int -flush_standard_stream(FILE *stream) -{ - int fd; - - errno = 0; - - if (ferror(stream) != 0 || fflush(stream) != 0) - goto error; - - /* - * Calling fflush is not sufficient on some filesystems - * like e.g. NFS, which may defer the actual flush until - * close. Calling fsync would help solve this, but would - * probably result in a performance hit. Thus, we work - * around this issue by calling close on a dup'd file - * descriptor from the stream. - */ - if ((fd = fileno(stream)) < 0 || (fd = dup(fd)) < 0 || close(fd) != 0) - goto error; - - return 0; -error: - return (errno == EBADF) ? 0 : EOF; -} - -/* Meant to be used atexit(close_stdout); */ -static inline void -close_stdout(void) -{ - if (flush_standard_stream(stdout) != 0 && !(errno == EPIPE)) { - if (errno) - warn(_("write error")); - else - warnx(_("write error")); - _exit(CLOSE_EXIT_CODE); - } - - if (flush_standard_stream(stderr) != 0) - _exit(CLOSE_EXIT_CODE); -} - -static inline void -close_stdout_atexit(void) -{ - /* - * Note that close stdout at exit disables ASAN to report memory leaks - */ -#if !defined(__SANITIZE_ADDRESS__) - atexit(close_stdout); -#endif -} - -#ifndef HAVE_FSYNC -static inline int -fsync(int fd __attribute__((__unused__))) -{ - return 0; -} -#endif - -static inline int -close_fd(int fd) -{ - const int fsync_fail = (fsync(fd) != 0); - const int close_fail = (close(fd) != 0); - - if (fsync_fail || close_fail) - return EOF; - return 0; -} - -#endif /* UTIL_LINUX_CLOSESTREAM_H */ diff --git a/utils/include/color-names.h b/utils/include/color-names.h deleted file mode 100644 index 42f6f8f..0000000 --- a/utils/include/color-names.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2012-2015 Karel Zak <kzak@redhat.com> - * - * This file may be distributed under the terms of the - * GNU Lesser General Public License. - */ -#ifndef UTIL_LINUX_COLOR_NAMES_H -#define UTIL_LINUX_COLOR_NAMES_H - -#define UL_COLOR_RESET "\033[0m" -#define UL_COLOR_BOLD "\033[1m" -#define UL_COLOR_HALFBRIGHT "\033[2m" -#define UL_COLOR_UNDERSCORE "\033[4m" -#define UL_COLOR_BLINK "\033[5m" -#define UL_COLOR_REVERSE "\033[7m" - -/* Standard colors */ -#define UL_COLOR_BLACK "\033[30m" -#define UL_COLOR_RED "\033[31m" -#define UL_COLOR_GREEN "\033[32m" -#define UL_COLOR_BROWN "\033[33m" /* well, brown */ -#define UL_COLOR_BLUE "\033[34m" -#define UL_COLOR_MAGENTA "\033[35m" -#define UL_COLOR_CYAN "\033[36m" -#define UL_COLOR_GRAY "\033[37m" - -/* Bold variants */ -#define UL_COLOR_DARK_GRAY "\033[1;30m" -#define UL_COLOR_BOLD_RED "\033[1;31m" -#define UL_COLOR_BOLD_GREEN "\033[1;32m" -#define UL_COLOR_BOLD_YELLOW "\033[1;33m" -#define UL_COLOR_BOLD_BLUE "\033[1;34m" -#define UL_COLOR_BOLD_MAGENTA "\033[1;35m" -#define UL_COLOR_BOLD_CYAN "\033[1;36m" - -#define UL_COLOR_WHITE "\033[1;37m" - - -/* maximal length of human readable name of ESC seq. */ -#define UL_COLORNAME_MAXSZ 32 - -extern const char *color_sequence_from_colorname(const char *str); - -#endif /* UTIL_LINUX_COLOR_NAMES_H */ diff --git a/utils/include/colors.h b/utils/include/colors.h deleted file mode 100644 index d4ae4e4..0000000 --- a/utils/include/colors.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2012 Ondrej Oprala <ooprala@redhat.com> - * Copyright (C) 2012-2014 Karel Zak <kzak@redhat.com> - * - * This file may be distributed under the terms of the - * GNU Lesser General Public License. - */ -#ifndef UTIL_LINUX_COLORS_H -#define UTIL_LINUX_COLORS_H - -#include <stdio.h> -#include <unistd.h> - -#include "color-names.h" - -/* --color[=WHEN] */ -enum colortmode { - UL_COLORMODE_AUTO = 0, - UL_COLORMODE_NEVER, - UL_COLORMODE_ALWAYS, - UL_COLORMODE_UNDEF, - - __UL_NCOLORMODES /* last */ -}; - -#ifdef USE_COLORS_BY_DEFAULT -# define USAGE_COLORS_DEFAULT _("colors are enabled by default") -#else -# define USAGE_COLORS_DEFAULT _("colors are disabled by default") -#endif - -extern int colormode_from_string(const char *str); -extern int colormode_or_err(const char *str, const char *errmsg); - -/* Initialize the global variable UL_COLOR_TERM_OK */ -extern int colors_init(int mode, const char *util_name); - -/* Returns 1 or 0 */ -extern int colors_wanted(void); - -/* Returns UL_COLORMODE_* */ -extern int colors_mode(void); - -/* temporary enable/disable colors */ -extern void colors_off(void); -extern void colors_on(void); - - -/* Set the color */ -extern void color_fenable(const char *seq, FILE *f); - -extern void color_scheme_fenable(const char *name, const char *dflt, FILE *f); -extern const char *color_scheme_get_sequence(const char *name, const char *dflt); - -static inline void color_enable(const char *seq) -{ - color_fenable(seq, stdout); -} - -static inline void color_scheme_enable(const char *name, const char *dflt) -{ - color_scheme_fenable(name, dflt, stdout); -} - -/* Reset colors to default */ -extern void color_fdisable(FILE *f); - -static inline void color_disable(void) -{ - color_fdisable(stdout); -} - -#endif /* UTIL_LINUX_COLORS_H */ diff --git a/utils/include/cpuset.h b/utils/include/cpuset.h deleted file mode 100644 index 5a531bf..0000000 --- a/utils/include/cpuset.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#ifndef UTIL_LINUX_CPUSET_H -#define UTIL_LINUX_CPUSET_H - -#include <sched.h> - -/* - * Fallback for old or obscure libcs without dynamically allocated cpusets - * - * The following macros are based on code from glibc. - * - * The GNU C Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - */ -#if !HAVE_DECL_CPU_ALLOC - -# define CPU_ZERO_S(setsize, cpusetp) \ - do { \ - size_t __i; \ - size_t __imax = (setsize) / sizeof (__cpu_mask); \ - __cpu_mask *__bits = (cpusetp)->__bits; \ - for (__i = 0; __i < __imax; ++__i) \ - __bits[__i] = 0; \ - } while (0) - -# define CPU_SET_S(cpu, setsize, cpusetp) \ - ({ size_t __cpu = (cpu); \ - __cpu < 8 * (setsize) \ - ? (((__cpu_mask *) ((cpusetp)->__bits))[__CPUELT (__cpu)] \ - |= __CPUMASK (__cpu)) \ - : 0; }) - -# define CPU_ISSET_S(cpu, setsize, cpusetp) \ - ({ size_t __cpu = (cpu); \ - __cpu < 8 * (setsize) \ - ? ((((__cpu_mask *) ((cpusetp)->__bits))[__CPUELT (__cpu)] \ - & __CPUMASK (__cpu))) != 0 \ - : 0; }) - -# define CPU_EQUAL_S(setsize, cpusetp1, cpusetp2) \ - ({ __cpu_mask *__arr1 = (cpusetp1)->__bits; \ - __cpu_mask *__arr2 = (cpusetp2)->__bits; \ - size_t __imax = (setsize) / sizeof (__cpu_mask); \ - size_t __i; \ - for (__i = 0; __i < __imax; ++__i) \ - if (__arr1[__i] != __arr2[__i]) \ - break; \ - __i == __imax; }) - -extern int __cpuset_count_s(size_t setsize, const cpu_set_t *set); -# define CPU_COUNT_S(setsize, cpusetp) __cpuset_count_s(setsize, cpusetp) - -# define CPU_ALLOC_SIZE(count) \ - ((((count) + __NCPUBITS - 1) / __NCPUBITS) * sizeof (__cpu_mask)) -# define CPU_ALLOC(count) (malloc(CPU_ALLOC_SIZE(count))) -# define CPU_FREE(cpuset) (free(cpuset)) - -#endif /* !HAVE_DECL_CPU_ALLOC */ - - -#define cpuset_nbits(setsize) (8 * (setsize)) - -/* - * The @idx parameter returns an index of the first mask from @ary array where - * the @cpu is set. - * - * Returns: 0 if found, otherwise 1. - */ -static inline int cpuset_ary_isset(size_t cpu, cpu_set_t **ary, size_t nmemb, - size_t setsize, size_t *idx) -{ - size_t i; - - for (i = 0; i < nmemb; i++) { - if (CPU_ISSET_S(cpu, setsize, ary[i])) { - *idx = i; - return 0; - } - } - return 1; -} - -extern int get_max_number_of_cpus(void); - -extern cpu_set_t *cpuset_alloc(int ncpus, size_t *setsize, size_t *nbits); -extern void cpuset_free(cpu_set_t *set); - -extern char *cpulist_create(char *str, size_t len, cpu_set_t *set, size_t setsize); -extern int cpulist_parse(const char *str, cpu_set_t *set, size_t setsize, int fail); - -extern char *cpumask_create(char *str, size_t len, cpu_set_t *set, size_t setsize); -extern int cpumask_parse(const char *str, cpu_set_t *set, size_t setsize); - -#endif /* UTIL_LINUX_CPUSET_H */ diff --git a/utils/include/crc32.h b/utils/include/crc32.h deleted file mode 100644 index 2551f50..0000000 --- a/utils/include/crc32.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef UL_NG_CRC32_H -#define UL_NG_CRC32_H - -#include <sys/types.h> -#include <stdint.h> - -extern uint32_t ul_crc32(uint32_t seed, const unsigned char *buf, size_t len); -extern uint32_t ul_crc32_exclude_offset(uint32_t seed, const unsigned char *buf, size_t len, - size_t exclude_off, size_t exclude_len); - -#endif - diff --git a/utils/include/crc32c.h b/utils/include/crc32c.h deleted file mode 100644 index 1c50839..0000000 --- a/utils/include/crc32c.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef UL_NG_CRC32C_H -#define UL_NG_CRC32C_H - -#include <sys/types.h> -#include <stdint.h> - -extern uint32_t crc32c(uint32_t crc, const void *buf, size_t size); - -#endif /* UL_NG_CRC32C_H */ diff --git a/utils/include/debug.h b/utils/include/debug.h deleted file mode 100644 index 39c21d5..0000000 --- a/utils/include/debug.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2014 Ondrej Oprala <ooprala@redhat.com> - * Copyright (C) 2014 Karel Zak <kzak@redhat.com> - * - * This file may be distributed under the terms of the - * GNU Lesser General Public License. - */ -#ifndef UTIL_LINUX_DEBUG_H -#define UTIL_LINUX_DEBUG_H - - -/* - * util-linux debug macros - * - * The debug stuff is based on <name>_debug_mask that controls what outputs is - * expected. The mask is usually initialized by <NAME>_DEBUG= env.variable - * - * After successful initialization the flag <PREFIX>_DEBUG_INIT is always set - * to the mask (this flag is required). The <PREFIX> is usually library API - * prefix (e.g. MNT_) or program name (e.g. CFDISK_) - * - * In the code is possible to use - * - * DBG(FOO, ul_debug("this is output for foo")); - * - * where for the FOO has to be defined <PREFIX>_DEBUG_FOO. - * - * It's possible to initialize the mask by comma delimited strings with - * subsystem names (e.g. "LIBMOUNT_DEBUG=options,tab"). In this case is - * necessary to define mask names array. This functionality is optional. - * - * It's strongly recommended to use UL_* macros to define/declare/use - * the debug stuff. - * - * See disk-utils/cfdisk.c: cfdisk_init_debug() for programs debug - * or libmount/src/init.c: mnt_init_debug() for library debug - * - */ - -#include <stdarg.h> -#include <string.h> - -struct ul_debug_maskname { - const char *name; - int mask; - const char *help; -}; -#define UL_DEBUG_EMPTY_MASKNAMES {{ NULL, 0, NULL }} -#define UL_DEBUG_DEFINE_MASKNAMES(m) static const struct ul_debug_maskname m ## _masknames[] -#define UL_DEBUG_MASKNAMES(m) m ## _masknames - -#define UL_DEBUG_MASK(m) m ## _debug_mask -#define UL_DEBUG_DEFINE_MASK(m) int UL_DEBUG_MASK(m) -#define UL_DEBUG_DECLARE_MASK(m) extern UL_DEBUG_DEFINE_MASK(m) - -/* - * Internal mask flags (above 0xffffff) - */ -#define __UL_DEBUG_FL_NOADDR (1 << 24) /* Don't print object address */ - - -/* l - library name, p - flag prefix, m - flag postfix, x - function */ -#define __UL_DBG(l, p, m, x) \ - do { \ - if ((p ## m) & l ## _debug_mask) { \ - fprintf(stderr, "%d: %s: %8s: ", getpid(), # l, # m); \ - x; \ - } \ - } while (0) - -#define __UL_DBG_CALL(l, p, m, x) \ - do { \ - if ((p ## m) & l ## _debug_mask) { \ - x; \ - } \ - } while (0) - -#define __UL_DBG_FLUSH(l, p) \ - do { \ - if (l ## _debug_mask && \ - l ## _debug_mask != p ## INIT) { \ - fflush(stderr); \ - } \ - } while (0) - -#define __UL_INIT_DEBUG_FROM_STRING(lib, pref, mask, str) \ - do { \ - if (lib ## _debug_mask & pref ## INIT) \ - ; \ - else if (!mask && str) { \ - lib ## _debug_mask = ul_debug_parse_mask(lib ## _masknames, str); \ - } else \ - lib ## _debug_mask = mask; \ - if (lib ## _debug_mask) { \ - if (getuid() != geteuid() || getgid() != getegid()) { \ - lib ## _debug_mask |= __UL_DEBUG_FL_NOADDR; \ - fprintf(stderr, "%d: %s: don't print memory addresses (SUID executable).\n", getpid(), # lib); \ - } \ - } \ - lib ## _debug_mask |= pref ## INIT; \ - } while (0) - - -#define __UL_INIT_DEBUG_FROM_ENV(lib, pref, mask, env) \ - do { \ - const char *envstr = mask ? NULL : getenv(# env); \ - __UL_INIT_DEBUG_FROM_STRING(lib, pref, mask, envstr); \ - } while (0) - - - -static inline void __attribute__ ((__format__ (__printf__, 1, 2))) -ul_debug(const char *mesg, ...) -{ - va_list ap; - va_start(ap, mesg); - vfprintf(stderr, mesg, ap); - va_end(ap); - fputc('\n', stderr); -} - -static inline int ul_debug_parse_mask( - const struct ul_debug_maskname flagnames[], - const char *mask) -{ - int res; - char *ptr; - - /* let's check for a numeric mask first */ - res = strtoul(mask, &ptr, 0); - - /* perhaps it's a comma-separated string? */ - if (ptr && *ptr && flagnames && flagnames[0].name) { - char *msbuf, *ms, *name; - res = 0; - - ms = msbuf = strdup(mask); - if (!ms) - return res; - - while ((name = strtok_r(ms, ",", &ptr))) { - const struct ul_debug_maskname *d; - ms = ptr; - - for (d = flagnames; d && d->name; d++) { - if (strcmp(name, d->name) == 0) { - res |= d->mask; - break; - } - } - /* nothing else we can do by OR-ing the mask */ - if (res == 0xffff) - break; - } - free(msbuf); - } else if (ptr && strcmp(ptr, "all") == 0) - res = 0xffff; - - return res; -} - -static inline void ul_debug_print_masks( - const char *env, - const struct ul_debug_maskname flagnames[]) -{ - const struct ul_debug_maskname *d; - - if (!flagnames) - return; - - fprintf(stderr, "Available \"%s=<name>[,...]|<mask>\" debug masks:\n", - env); - for (d = flagnames; d && d->name; d++) { - if (!d->help) - continue; - fprintf(stderr, " %-8s [0x%04x] : %s\n", - d->name, d->mask, d->help); - } -} - -#endif /* UTIL_LINUX_DEBUG_H */ diff --git a/utils/include/debugobj.h b/utils/include/debugobj.h deleted file mode 100644 index 73b70b8..0000000 --- a/utils/include/debugobj.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef UTIL_LINUX_DEBUGOBJ_H -#define UTIL_LINUX_DEBUGOBJ_H - -/* - * Include *after* debug.h and after UL_DEBUG_CURRENT_MASK define. - */ - -static inline void __attribute__ ((__format__ (__printf__, 2, 3))) -ul_debugobj(const void *handler, const char *mesg, ...) -{ - va_list ap; - - if (handler && !(UL_DEBUG_CURRENT_MASK & __UL_DEBUG_FL_NOADDR)) - fprintf(stderr, "[%p]: ", handler); - - va_start(ap, mesg); - vfprintf(stderr, mesg, ap); - va_end(ap); - fputc('\n', stderr); -} - -#endif /* UTIL_LINUX_DEBUGOBJ_H */ diff --git a/utils/include/encode.h b/utils/include/encode.h deleted file mode 100644 index b259ab5..0000000 --- a/utils/include/encode.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef UTIL_LINUX_ENCODE_H -#define UTIL_LINUX_ENCODE_H - -extern size_t ul_encode_to_utf8(int enc, unsigned char *dest, size_t len, - const unsigned char *src, size_t count) - __attribute__((nonnull)); - -enum { - UL_ENCODE_UTF16BE = 0, - UL_ENCODE_UTF16LE, - UL_ENCODE_LATIN1 -}; - -#endif diff --git a/utils/include/env.h b/utils/include/env.h deleted file mode 100644 index c2caecb..0000000 --- a/utils/include/env.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef UTIL_LINUX_ENV_H -#define UTIL_LINUX_ENV_H - -#include "c.h" -#include "nls.h" - -struct ul_env_list; - -extern void sanitize_env(void); -extern void __sanitize_env(struct ul_env_list **org); - -extern int env_list_setenv(struct ul_env_list *ls); -extern void env_list_free(struct ul_env_list *ls); - -extern char *safe_getenv(const char *arg); - - -#ifndef XSETENV_EXIT_CODE -# define XSETENV_EXIT_CODE EXIT_FAILURE -#endif - -static inline void xsetenv(char const *name, char const *val, int overwrite) -{ - if (setenv(name, val, overwrite) != 0) - err(XSETENV_EXIT_CODE, _("failed to set the %s environment variable"), name); -} - -static inline int remote_entry(char **argv, int remove, int last) -{ - memmove(argv + remove, argv + remove + 1, sizeof(char *) * (last - remove)); - return last - 1; -} - -#endif /* UTIL_LINUX_ENV_H */ - diff --git a/utils/include/exec_shell.h b/utils/include/exec_shell.h deleted file mode 100644 index 04aa089..0000000 --- a/utils/include/exec_shell.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef UTIL_LINUX_EXEC_SHELL_H -#define UTIL_LINUX_EXEC_SHELL_H - -extern void exec_shell(void) __attribute__((__noreturn__)); - -#endif /* UTIL_LINUX_EXEC_SHELL_H */ diff --git a/utils/include/exitcodes.h b/utils/include/exitcodes.h deleted file mode 100644 index f28f68e..0000000 --- a/utils/include/exitcodes.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef UTIL_LINUX_EXITCODES_H -#define UTIL_LINUX_EXITCODES_H -/* - * BE CAREFUL - * - * These exit codes are part of the official interface for mount, - * fsck, mkfs, etc. wrappers. - */ - -/* Exit codes used by mkfs-type programs */ -#define MKFS_EX_OK 0 /* No errors */ -#define MKFS_EX_ERROR 8 /* Operational error */ -#define MKFS_EX_USAGE 16 /* Usage or syntax error */ - -/* Exit codes used by fsck-type programs */ -#define FSCK_EX_OK 0 /* No errors */ -#define FSCK_EX_NONDESTRUCT 1 /* File system errors corrected */ -#define FSCK_EX_REBOOT 2 /* System should be rebooted */ -#define FSCK_EX_DESTRUCT FSCK_EX_REBOOT /* Alias */ -#define FSCK_EX_UNCORRECTED 4 /* File system errors left uncorrected */ -#define FSCK_EX_ERROR 8 /* Operational error */ -#define FSCK_EX_USAGE 16 /* Usage or syntax error */ -#define FSCK_EX_LIBRARY 128 /* Shared library error */ - -#endif /* UTIL_LINUX_EXITCODES_H */ diff --git a/utils/include/fileutils.h b/utils/include/fileutils.h deleted file mode 100644 index 479ad15..0000000 --- a/utils/include/fileutils.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef UTIL_LINUX_FILEUTILS -#define UTIL_LINUX_FILEUTILS - -#include <stdio.h> -#include <fcntl.h> -#include <unistd.h> -#include <dirent.h> -#include <sys/stat.h> - -#include "c.h" - -extern int mkstemp_cloexec(char *template); - -extern int xmkstemp(char **tmpname, const char *dir, const char *prefix); - -static inline FILE *xfmkstemp(char **tmpname, const char *dir, const char *prefix) -{ - int fd; - FILE *ret; - - fd = xmkstemp(tmpname, dir, prefix); - if (fd == -1) - return NULL; - - if (!(ret = fdopen(fd, "w+" UL_CLOEXECSTR))) { - close(fd); - return NULL; - } - return ret; -} - -#ifdef HAVE_OPENAT -static inline FILE *fopen_at(int dir, const char *filename, - int flags, const char *mode) -{ - int fd = openat(dir, filename, flags); - if (fd < 0) - return NULL; - - return fdopen(fd, mode); -} -#endif - -static inline int is_same_inode(const int fd, const struct stat *st) -{ - struct stat f; - - if (fstat(fd, &f) < 0) - return 0; - else if (f.st_dev != st->st_dev || f.st_ino != st->st_ino) - return 0; - return 1; -} - -extern int dup_fd_cloexec(int oldfd, int lowfd); -extern int get_fd_tabsize(void); - -extern int mkdir_p(const char *path, mode_t mode); -extern char *stripoff_last_component(char *path); - -/* This is readdir()-like function, but skips "." and ".." directory entries */ -static inline struct dirent *xreaddir(DIR *dp) -{ - struct dirent *d; - - while ((d = readdir(dp))) { - if (!strcmp(d->d_name, ".") || - !strcmp(d->d_name, "..")) - continue; - break; - } - return d; -} - -extern void close_all_fds(const int exclude[], size_t exsz); - -#endif /* UTIL_LINUX_FILEUTILS */ diff --git a/utils/include/fuzz.h b/utils/include/fuzz.h deleted file mode 100644 index 1b0dbd2..0000000 --- a/utils/include/fuzz.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef UTIL_LINUX_FUZZ_H -#define UTIL_LINUX_FUZZ_H - -#include <stddef.h> -#include <stdint.h> - -int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); - -#endif /* UTIL_LINUX_FUZZ_H */ diff --git a/utils/include/idcache.h b/utils/include/idcache.h deleted file mode 100644 index 912edd5..0000000 --- a/utils/include/idcache.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef UTIL_LINUX_IDCACHE_H -#define UTIL_LINUX_IDCACHE_H - -#include <sys/types.h> -#include <pwd.h> - -#define IDCACHE_FLAGS_NAMELEN (1 << 1) - -struct identry { - unsigned long int id; - char *name; - struct identry *next; -}; - -struct idcache { - struct identry *ent; /* first entry */ - int width; /* name width */ -}; - - -extern struct idcache *new_idcache(void); -extern void add_gid(struct idcache *cache, unsigned long int id); -extern void add_uid(struct idcache *cache, unsigned long int id); - -extern void free_idcache(struct idcache *ic); -extern struct identry *get_id(struct idcache *ic, unsigned long int id); - -#endif /* UTIL_LINUX_IDCACHE_H */ diff --git a/utils/include/ismounted.h b/utils/include/ismounted.h deleted file mode 100644 index 57918cb..0000000 --- a/utils/include/ismounted.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef IS_MOUNTED_H -#define IS_MOUNTED_H - -#define MF_MOUNTED 1 -#define MF_ISROOT 2 -#define MF_READONLY 4 -#define MF_SWAP 8 -#define MF_BUSY 16 - -extern int is_mounted(const char *file); -extern int check_mount_point(const char *device, int *mount_flags, - char *mtpt, int mtlen); - -#endif /* IS_MOUNTED_H */ diff --git a/utils/include/iso9660.h b/utils/include/iso9660.h deleted file mode 100644 index 73decd9..0000000 --- a/utils/include/iso9660.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef UTIL_LINUX_ISO_H -#define UTIL_LINUX_ISO_H - -#include <stdbool.h> - -#include "c.h" - -static inline int isonum_721(unsigned char *p) -{ - return ((p[0] & 0xff) - | ((p[1] & 0xff) << 8)); -} - -static inline int isonum_722(unsigned char *p) -{ - return ((p[1] & 0xff) - | ((p[0] & 0xff) << 8)); -} - -static inline int isonum_723(unsigned char *p, bool check_match) -{ - int le = isonum_721(p); - int be = isonum_722(p + 2); - - if (check_match && le != be) - /* translation is useless */ - warnx("723error: le=%d be=%d", le, be); - return (le); -} - -static inline int isonum_731(unsigned char *p) -{ - return ((p[0] & 0xff) - | ((p[1] & 0xff) << 8) - | ((p[2] & 0xff) << 16) - | ((p[3] & 0xff) << 24)); -} - -static inline int isonum_732(unsigned char *p) -{ - return ((p[3] & 0xff) - | ((p[2] & 0xff) << 8) - | ((p[1] & 0xff) << 16) - | ((p[0] & 0xff) << 24)); -} - -static inline int isonum_733(unsigned char *p, bool check_match) -{ - int le = isonum_731(p); - int be = isonum_732(p + 4); - - if (check_match && le != be) - /* translation is useless */ - warnx("733error: le=%d be=%d", le, be); - return(le); -} - -#endif diff --git a/utils/include/linux_version.h b/utils/include/linux_version.h deleted file mode 100644 index a6a1e99..0000000 --- a/utils/include/linux_version.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef LINUX_VERSION_H -#define LINUX_VERSION_H - -#ifdef HAVE_LINUX_VERSION_H -# include <linux/version.h> -#endif - -#ifndef KERNEL_VERSION -# define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) -#endif - -int get_linux_version(void); - -#endif /* LINUX_VERSION_H */ diff --git a/utils/include/list.h b/utils/include/list.h deleted file mode 100644 index 96c84e5..0000000 --- a/utils/include/list.h +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Copyright (C) 2008 Karel Zak <kzak@redhat.com> - * Copyright (C) 1999-2008 by Theodore Ts'o - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * - * (based on list.h from e2fsprogs) - * Merge sort based on kernel's implementation. - */ - -#ifndef UTIL_LINUX_LIST_H -#define UTIL_LINUX_LIST_H - -#include "c.h" - -/* TODO: use AC_C_INLINE */ -#ifdef __GNUC__ -#define _INLINE_ static __inline__ -#else /* For Watcom C */ -#define _INLINE_ static inline -#endif - -/* - * Simple doubly linked list implementation. - * - * Some of the internal functions ("__xxx") are useful when - * manipulating whole lists rather than single entries, as - * sometimes we already know the next/prev entries and we can - * generate better code by using them directly rather than - * using the generic single-entry routines. - */ - -struct list_head { - struct list_head *next, *prev; -}; - -#define INIT_LIST_HEAD(ptr) do { \ - (ptr)->next = (ptr); (ptr)->prev = (ptr); \ -} while (0) - -/* - * Insert a new entry between two known consecutive entries. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -_INLINE_ void __list_add(struct list_head * add, - struct list_head * prev, - struct list_head * next) -{ - next->prev = add; - add->next = next; - add->prev = prev; - prev->next = add; -} - -/** - * list_add - add a new entry - * @add: new entry to be added - * @head: list head to add it after - * - * Insert a new entry after the specified head. - * This is good for implementing stacks. - */ -_INLINE_ void list_add(struct list_head *add, struct list_head *head) -{ - __list_add(add, head, head->next); -} - -/** - * list_add_tail - add a new entry - * @add: new entry to be added - * @head: list head to add it before - * - * Insert a new entry before the specified head. - * This is useful for implementing queues. - */ -_INLINE_ void list_add_tail(struct list_head *add, struct list_head *head) -{ - __list_add(add, head->prev, head); -} - -/* - * Delete a list entry by making the prev/next entries - * point to each other. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -_INLINE_ void __list_del(struct list_head * prev, - struct list_head * next) -{ - next->prev = prev; - prev->next = next; -} - -/** - * list_del - deletes entry from list. - * @entry: the element to delete from the list. - * - * list_empty() on @entry does not return true after this, @entry is - * in an undefined state. - */ -_INLINE_ void list_del(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); -} - -/** - * list_del_init - deletes entry from list and reinitialize it. - * @entry: the element to delete from the list. - */ -_INLINE_ void list_del_init(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - INIT_LIST_HEAD(entry); -} - -/** - * list_empty - tests whether a list is empty - * @head: the list to test. - */ -_INLINE_ int list_empty(struct list_head *head) -{ - return head->next == head; -} - -/** - * list_entry_is_last - tests whether is entry last in the list - * @entry: the entry to test. - * @head: the list to test. - */ -_INLINE_ int list_entry_is_last(struct list_head *entry, struct list_head *head) -{ - return head->prev == entry; -} - -/** - * list_entry_is_first - tests whether is entry first in the list - * @entry: the entry to test. - * @head: the list to test. - */ -_INLINE_ int list_entry_is_first(struct list_head *entry, struct list_head *head) -{ - return head->next == entry; -} - -/** - * list_splice - join two lists - * @list: the new list to add. - * @head: the place to add it in the first list. - */ -_INLINE_ void list_splice(struct list_head *list, struct list_head *head) -{ - struct list_head *first = list->next; - - if (first != list) { - struct list_head *last = list->prev; - struct list_head *at = head->next; - - first->prev = head; - head->next = first; - - last->next = at; - at->prev = last; - } -} - -/** - * list_entry - get the struct for this entry - * @ptr: the &struct list_head pointer. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - */ -#define list_entry(ptr, type, member) container_of(ptr, type, member) - -#define list_first_entry(head, type, member) \ - ((head) && (head)->next != (head) ? list_entry((head)->next, type, member) : NULL) - -#define list_last_entry(head, type, member) \ - ((head) && (head)->prev != (head) ? list_entry((head)->prev, type, member) : NULL) - -/** - * list_for_each - iterate over elements in a list - * @pos: the &struct list_head to use as a loop counter. - * @head: the head for your list. - */ -#define list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) - -/** - * list_for_each_backwardly - iterate over elements in a list in reverse - * @pos: the &struct list_head to use as a loop counter. - * @head: the head for your list. - */ -#define list_for_each_backwardly(pos, head) \ - for (pos = (head)->prev; pos != (head); pos = pos->prev) - -/** - * list_for_each_safe - iterate over elements in a list, but don't dereference - * pos after the body is done (in case it is freed) - * @pos: the &struct list_head to use as a loop counter. - * @pnext: the &struct list_head to use as a pointer to the next item. - * @head: the head for your list (not included in iteration). - */ -#define list_for_each_safe(pos, pnext, head) \ - for (pos = (head)->next, pnext = pos->next; pos != (head); \ - pos = pnext, pnext = pos->next) - -_INLINE_ size_t list_count_entries(struct list_head *head) -{ - struct list_head *pos; - size_t ct = 0; - - list_for_each(pos, head) - ct++; - - return ct; -} - -#define MAX_LIST_LENGTH_BITS 20 - -/* - * Returns a list organized in an intermediate format suited - * to chaining of merge() calls: null-terminated, no reserved or - * sentinel head node, "prev" links not maintained. - */ -_INLINE_ struct list_head *merge(int (*cmp)(struct list_head *a, - struct list_head *b, - void *data), - void *data, - struct list_head *a, struct list_head *b) -{ - struct list_head head, *tail = &head; - - while (a && b) { - /* if equal, take 'a' -- important for sort stability */ - if ((*cmp)(a, b, data) <= 0) { - tail->next = a; - a = a->next; - } else { - tail->next = b; - b = b->next; - } - tail = tail->next; - } - tail->next = a ? a : b; - return head.next; -} - -/* - * Combine final list merge with restoration of standard doubly-linked - * list structure. This approach duplicates code from merge(), but - * runs faster than the tidier alternatives of either a separate final - * prev-link restoration pass, or maintaining the prev links - * throughout. - */ -_INLINE_ void merge_and_restore_back_links(int (*cmp)(struct list_head *a, - struct list_head *b, - void *data), - void *data, - struct list_head *head, - struct list_head *a, struct list_head *b) -{ - struct list_head *tail = head; - - while (a && b) { - /* if equal, take 'a' -- important for sort stability */ - if ((*cmp)(a, b, data) <= 0) { - tail->next = a; - a->prev = tail; - a = a->next; - } else { - tail->next = b; - b->prev = tail; - b = b->next; - } - tail = tail->next; - } - tail->next = a ? a : b; - - do { - /* - * In worst cases this loop may run many iterations. - * Continue callbacks to the client even though no - * element comparison is needed, so the client's cmp() - * routine can invoke cond_resched() periodically. - */ - (*cmp)(tail->next, tail->next, data); - - tail->next->prev = tail; - tail = tail->next; - } while (tail->next); - - tail->next = head; - head->prev = tail; -} - - -/** - * list_sort - sort a list - * @head: the list to sort - * @cmp: the elements comparison function - * - * This function implements "merge sort", which has O(nlog(n)) - * complexity. - * - * The comparison function @cmp must return a negative value if @a - * should sort before @b, and a positive value if @a should sort after - * @b. If @a and @b are equivalent, and their original relative - * ordering is to be preserved, @cmp must return 0. - */ -_INLINE_ void list_sort(struct list_head *head, - int (*cmp)(struct list_head *a, - struct list_head *b, - void *data), - void *data) -{ - struct list_head *part[MAX_LIST_LENGTH_BITS+1]; /* sorted partial lists - -- last slot is a sentinel */ - size_t lev; /* index into part[] */ - size_t max_lev = 0; - struct list_head *list; - - if (list_empty(head)) - return; - - memset(part, 0, sizeof(part)); - - head->prev->next = NULL; - list = head->next; - - while (list) { - struct list_head *cur = list; - list = list->next; - cur->next = NULL; - - for (lev = 0; part[lev]; lev++) { - cur = merge(cmp, data, part[lev], cur); - part[lev] = NULL; - } - if (lev > max_lev) { - /* list passed to list_sort() too long for efficiency */ - if (lev >= ARRAY_SIZE(part) - 1) - lev--; - max_lev = lev; - } - part[lev] = cur; - } - - for (lev = 0; lev < max_lev; lev++) - if (part[lev]) - list = merge(cmp, data, part[lev], list); - - merge_and_restore_back_links(cmp, data, head, part[max_lev], list); -} - -#undef _INLINE_ - -#endif /* UTIL_LINUX_LIST_H */ diff --git a/utils/include/loopdev.h b/utils/include/loopdev.h deleted file mode 100644 index 0221e6b..0000000 --- a/utils/include/loopdev.h +++ /dev/null @@ -1,222 +0,0 @@ -#ifndef UTIL_LINUX_LOOPDEV_H -#define UTIL_LINUX_LOOPDEV_H - -#include "sysfs.h" - -/* - * loop_info.lo_encrypt_type - */ -#define LO_CRYPT_NONE 0 -#define LO_CRYPT_XOR 1 -#define LO_CRYPT_DES 2 -#define LO_CRYPT_CRYPTOAPI 18 - -/* - * loop_info.lo_file_fmt_type - */ -#define LO_FILE_FMT_RAW 0 -#define LO_FILE_FMT_QCOW 1 -#define LO_FILE_FMT_VDI 2 -#define LO_FILE_FMT_VMDK 3 - -#define LOOP_SET_FD 0x4C00 -#define LOOP_CLR_FD 0x4C01 -/* - * Obsolete (kernel < 2.6) - * - * #define LOOP_SET_STATUS 0x4C02 - * #define LOOP_GET_STATUS 0x4C03 - */ -#define LOOP_SET_STATUS64 0x4C04 -#define LOOP_GET_STATUS64 0x4C05 -/* #define LOOP_CHANGE_FD 0x4C06 */ -#define LOOP_SET_CAPACITY 0x4C07 -#define LOOP_SET_DIRECT_IO 0x4C08 -#define LOOP_SET_BLOCK_SIZE 0x4C09 - -/* /dev/loop-control interface */ -#ifndef LOOP_CTL_ADD -# define LOOP_CTL_ADD 0x4C80 -# define LOOP_CTL_REMOVE 0x4C81 -# define LOOP_CTL_GET_FREE 0x4C82 -#endif - -/* - * loop_info.lo_flags - */ -enum { - LO_FLAGS_READ_ONLY = 1, - LO_FLAGS_USE_AOPS = 2, - LO_FLAGS_AUTOCLEAR = 4, /* kernel >= 2.6.25 */ - LO_FLAGS_PARTSCAN = 8, /* kernel >= 3.2 */ - LO_FLAGS_DIRECT_IO = 16, /* kernel >= 4.2 */ -}; - -#define LO_NAME_SIZE 64 -#define LO_KEY_SIZE 32 - -/* - * Linux LOOP_{SET,GET}_STATUS64 ioctl struct - */ -struct loop_info64 { - uint64_t lo_device; - uint64_t lo_inode; - uint64_t lo_rdevice; - uint64_t lo_offset; - uint64_t lo_sizelimit; /* bytes, 0 == max available */ - uint32_t lo_number; - uint32_t lo_encrypt_type; - uint32_t lo_encrypt_key_size; - uint32_t lo_flags; - uint8_t lo_file_name[LO_NAME_SIZE]; - uint8_t lo_crypt_name[LO_NAME_SIZE]; - uint8_t lo_encrypt_key[LO_KEY_SIZE]; - uint64_t lo_init[2]; - uint32_t lo_file_fmt_type; -}; - -#define LOOPDEV_MAJOR XLOOP_MAJOR /* loop major number */ -#define LOOPDEV_DEFAULT_NNODES CONFIG_BLK_DEV_XLOOP_MIN_COUNT /* default number of loop devices */ - -struct loopdev_iter { - FILE *proc; /* /proc/partitions */ - DIR *sysblock; /* /sys/block */ - int ncur; /* current position */ - int *minors; /* ary of minor numbers (when scan whole /dev) */ - int nminors; /* number of items in *minors */ - int ct_perm; /* count permission problems */ - int ct_succ; /* count number of detected devices */ - - unsigned int done:1; /* scanning done */ - unsigned int default_check:1;/* check first LOOPDEV_NLOOPS */ - int flags; /* LOOPITER_FL_* flags */ -}; - -enum { - LOOPITER_FL_FREE = (1 << 0), - LOOPITER_FL_USED = (1 << 1) -}; - -/* - * handler for work with loop devices - */ -struct loopdev_cxt { - char device[128]; /* device path (e.g. /dev/loop<N>) */ - char *filename; /* backing file for loopcxt_set_... */ - int fd; /* open(/dev/looo<N>) */ - int mode; /* fd mode O_{RDONLY,RDWR} */ - uint64_t blocksize; /* used by loopcxt_setup_device() */ - - int flags; /* LOOPDEV_FL_* flags */ - unsigned int has_info:1; /* .info contains data */ - unsigned int extra_check:1; /* unusual stuff for iterator */ - unsigned int info_failed:1; /* LOOP_GET_STATUS ioctl failed */ - unsigned int control_ok:1; /* /dev/loop-control success */ - - struct path_cxt *sysfs; /* pointer to /sys/dev/block/<maj:min>/ */ - struct loop_info64 info; /* for GET/SET ioctl */ - struct loopdev_iter iter; /* scans /sys or /dev for used/free devices */ -}; - -#define UL_LOOPDEVCXT_EMPTY { .fd = -1 } - -/* - * loopdev_cxt.flags - */ -enum { - LOOPDEV_FL_RDONLY = (1 << 0), /* open(/dev/loop) mode; default */ - LOOPDEV_FL_RDWR = (1 << 1), /* necessary for loop setup only */ - LOOPDEV_FL_OFFSET = (1 << 4), - LOOPDEV_FL_NOSYSFS = (1 << 5), - LOOPDEV_FL_NOIOCTL = (1 << 6), - LOOPDEV_FL_DEVSUBDIR = (1 << 7), - LOOPDEV_FL_CONTROL = (1 << 8), /* system with /dev/loop-control */ - LOOPDEV_FL_SIZELIMIT = (1 << 9) -}; - -/* - * High-level - */ -extern int loopmod_supports_partscan(void); - -extern int is_loopdev(const char *device); -extern int loopdev_is_autoclear(const char *device); - -extern char *loopdev_get_backing_file(const char *device); -extern int loopdev_is_used(const char *device, const char *filename, - uint64_t offset, uint64_t sizelimit, int flags); -extern char *loopdev_find_by_backing_file(const char *filename, - uint64_t offset, uint64_t sizelimit, int flags); -extern int loopcxt_find_unused(struct loopdev_cxt *lc); -extern int loopdev_delete(const char *device); -extern int loopdev_count_by_backing_file(const char *filename, char **loopdev); - -/* - * Low-level - */ -extern int loopcxt_init(struct loopdev_cxt *lc, int flags) - __attribute__ ((warn_unused_result)); -extern void loopcxt_deinit(struct loopdev_cxt *lc); - -extern int loopcxt_set_device(struct loopdev_cxt *lc, const char *device) - __attribute__ ((warn_unused_result)); -extern int loopcxt_has_device(struct loopdev_cxt *lc); -extern int loopcxt_add_device(struct loopdev_cxt *lc); -extern char *loopcxt_strdup_device(struct loopdev_cxt *lc); -extern const char *loopcxt_get_device(struct loopdev_cxt *lc); -extern struct loop_info64 *loopcxt_get_info(struct loopdev_cxt *lc); - -extern int loopcxt_get_fd(struct loopdev_cxt *lc); -extern int loopcxt_set_fd(struct loopdev_cxt *lc, int fd, int mode); - -extern int loopcxt_init_iterator(struct loopdev_cxt *lc, int flags); -extern int loopcxt_deinit_iterator(struct loopdev_cxt *lc); -extern int loopcxt_next(struct loopdev_cxt *lc); - -extern int loopcxt_setup_device(struct loopdev_cxt *lc); -extern int loopcxt_delete_device(struct loopdev_cxt *lc); - -extern int loopcxt_ioctl_status(struct loopdev_cxt *lc); -extern int loopcxt_ioctl_capacity(struct loopdev_cxt *lc); -extern int loopcxt_ioctl_dio(struct loopdev_cxt *lc, unsigned long use_dio); -extern int loopcxt_ioctl_blocksize(struct loopdev_cxt *lc, uint64_t blocksize); - -int loopcxt_set_offset(struct loopdev_cxt *lc, uint64_t offset); -int loopcxt_set_sizelimit(struct loopdev_cxt *lc, uint64_t sizelimit); -int loopcxt_set_blocksize(struct loopdev_cxt *lc, uint64_t blocksize); -int loopcxt_set_file_fmt_type(struct loopdev_cxt *lc, uint32_t file_fmt_type); -int loopcxt_set_flags(struct loopdev_cxt *lc, uint32_t flags); -int loopcxt_set_backing_file(struct loopdev_cxt *lc, const char *filename); - -extern char *loopcxt_get_backing_file(struct loopdev_cxt *lc); -extern int loopcxt_get_backing_devno(struct loopdev_cxt *lc, dev_t *devno); -extern int loopcxt_get_backing_inode(struct loopdev_cxt *lc, ino_t *ino); -extern int loopcxt_get_offset(struct loopdev_cxt *lc, uint64_t *offset); -extern int loopcxt_get_blocksize(struct loopdev_cxt *lc, uint64_t *blocksize); -extern int loopcxt_get_sizelimit(struct loopdev_cxt *lc, uint64_t *size); -extern int loopcxt_get_encrypt_type(struct loopdev_cxt *lc, uint32_t *type); -extern int loopcxt_get_file_fmt_type(struct loopdev_cxt *lc, uint32_t* file_fmt_type); -extern char *loopcxt_get_file_fmt_type_string(struct loopdev_cxt *lc); -extern const char *loopcxt_get_crypt_name(struct loopdev_cxt *lc); -extern int loopcxt_is_autoclear(struct loopdev_cxt *lc); -extern int loopcxt_is_readonly(struct loopdev_cxt *lc); -extern int loopcxt_is_dio(struct loopdev_cxt *lc); -extern int loopcxt_is_partscan(struct loopdev_cxt *lc); -extern int loopcxt_find_by_backing_file(struct loopdev_cxt *lc, - const char *filename, - uint64_t offset, uint64_t sizelimit, - int flags); -extern int loopcxt_find_overlap(struct loopdev_cxt *lc, - const char *filename, - uint64_t offset, uint64_t sizelimit); - -extern int loopcxt_is_used(struct loopdev_cxt *lc, - struct stat *st, - const char *backing_file, - uint64_t offset, - uint64_t sizelimit, - int flags); - -extern int parse_file_fmt_type(const char *file_fmt_type_str, uint32_t *file_fmt_type); - -#endif /* UTIL_LINUX_LOOPDEV_H */ diff --git a/utils/include/mangle.h b/utils/include/mangle.h deleted file mode 100644 index 08c66cb..0000000 --- a/utils/include/mangle.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef UTIL_LINUX_MANGLE_H -#define UTIL_LINUX_MANGLE_H - -/* - * Functions for \oct encoding used in mtab/fstab/swaps/etc. - */ - -extern char *mangle(const char *s); - -extern void unmangle_to_buffer(const char *s, char *buf, size_t len); -extern size_t unhexmangle_to_buffer(const char *s, char *buf, size_t len); - -extern char *unmangle(const char *s, const char **end); - -static inline void unmangle_string(char *s) -{ - if (s) - unmangle_to_buffer(s, s, strlen(s) + 1); -} - -static inline void unhexmangle_string(char *s) -{ - if (s) - unhexmangle_to_buffer(s, s, strlen(s) + 1); -} - -#endif /* UTIL_LINUX_MANGLE_H */ - diff --git a/utils/include/match.h b/utils/include/match.h deleted file mode 100644 index 94440c2..0000000 --- a/utils/include/match.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (C) 2011 Karel Zak <kzak@redhat.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#ifndef UTIL_LINUX_MATCH_H -#define UTIL_LINUX_MATCH_H - -extern int match_fstype(const char *type, const char *pattern); - -#endif /* UTIL_LINUX_MATCH_H */ diff --git a/utils/include/mbsalign.h b/utils/include/mbsalign.h deleted file mode 100644 index 4f5add8..0000000 --- a/utils/include/mbsalign.h +++ /dev/null @@ -1,66 +0,0 @@ -/* Align/Truncate a string in a given screen width - Copyright (C) 2009-2010 Free Software Foundation, Inc. - Copyright (C) 2010-2013 Karel Zak <kzak@redhat.com> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 2.1 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef UTIL_LINUX_MBSALIGN_H -# define UTIL_LINUX_MBSALIGN_H -# include <stddef.h> - -typedef enum { MBS_ALIGN_LEFT, MBS_ALIGN_RIGHT, MBS_ALIGN_CENTER } mbs_align_t; - -enum { - /* Use unibyte mode for invalid multibyte strings or - or when heap memory is exhausted. */ - MBA_UNIBYTE_FALLBACK = 0x0001, - -#if 0 /* Other possible options. */ - /* Skip invalid multibyte chars rather than failing */ - MBA_IGNORE_INVALID = 0x0002, - - /* Align multibyte strings using "figure space" (\u2007) */ - MBA_USE_FIGURE_SPACE = 0x0004, - - /* Don't add any padding */ - MBA_TRUNCATE_ONLY = 0x0008, - - /* Don't truncate */ - MBA_PAD_ONLY = 0x0010, -#endif -}; - -extern size_t mbs_truncate(char *str, size_t *width); - -extern size_t mbsalign (const char *src, char *dest, - size_t dest_size, size_t *width, - mbs_align_t align, int flags); - -extern size_t mbsalign_with_padding (const char *src, char *dest, size_t dest_size, - size_t *width, mbs_align_t align, int flags, - int padchar); - -extern size_t mbs_safe_nwidth(const char *buf, size_t bufsz, size_t *sz); -extern size_t mbs_safe_width(const char *s); - -extern size_t mbs_nwidth(const char *buf, size_t bufsz); -extern size_t mbs_width(const char *s); - -extern char *mbs_safe_encode(const char *s, size_t *width); -extern char *mbs_safe_encode_to_buffer(const char *s, size_t *width, char *buf, const char *safechars); -extern size_t mbs_safe_encode_size(size_t bytes); - -extern char *mbs_invalid_encode(const char *s, size_t *width); -extern char *mbs_invalid_encode_to_buffer(const char *s, size_t *width, char *buf); - -#endif /* UTIL_LINUX_MBSALIGN_H */ diff --git a/utils/include/mbsedit.h b/utils/include/mbsedit.h deleted file mode 100644 index 8d1c6c2..0000000 --- a/utils/include/mbsedit.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef UTIL_LINUX_MBSEDIT_H -# define UTIL_LINUX_MBSEDIT_H - -#include "mbsalign.h" -#include "widechar.h" - -struct mbs_editor { - char *buf; /* buffer */ - size_t max_bytes; /* size of the buffer */ - size_t max_cells; /* maximal allowed number of cells */ - size_t cur_cells; /* number of cells to print the buffer */ - size_t cur_bytes; /* number of chars in bytes */ - size_t cursor; /* cursor position in bytes */ - size_t cursor_cells; /* cursor position in cells */ -}; - -enum { - MBS_EDIT_LEFT, - MBS_EDIT_RIGHT, - MBS_EDIT_END, - MBS_EDIT_HOME -}; - -struct mbs_editor *mbs_new_edit(char *buf, size_t bufsz, size_t ncells); -char *mbs_free_edit(struct mbs_editor *edit); - -int mbs_edit_goto(struct mbs_editor *edit, int where); -int mbs_edit_delete(struct mbs_editor *edit); -int mbs_edit_backspace(struct mbs_editor *edit); -int mbs_edit_insert(struct mbs_editor *edit, wint_t c); - -#endif /* UTIL_LINUX_MBSEDIT_H */ diff --git a/utils/include/md5.h b/utils/include/md5.h deleted file mode 100644 index 02e627b..0000000 --- a/utils/include/md5.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef UTIL_LINUX_MD5_H -#define UTIL_LINUX_MD5_H - -#include <stdint.h> - -#define UL_MD5LENGTH 16 - -struct UL_MD5Context { - uint32_t buf[4]; - uint32_t bits[2]; - unsigned char in[64]; -}; - -void ul_MD5Init(struct UL_MD5Context *ctx); -void ul_MD5Update(struct UL_MD5Context *ctx, unsigned char const *buf, unsigned len); -void ul_MD5Final(unsigned char digest[UL_MD5LENGTH], struct UL_MD5Context *ctx); -void ul_MD5Transform(uint32_t buf[4], uint32_t const in[16]); - -/* - * This is needed to make RSAREF happy on some MS-DOS compilers. - */ -typedef struct UL_MD5Context UL_MD5_CTX; - -#endif /* !UTIL_LINUX_MD5_H */ diff --git a/utils/include/minix.h b/utils/include/minix.h deleted file mode 100644 index f28991c..0000000 --- a/utils/include/minix.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef UTIL_LINUX_MINIX_H -#define UTIL_LINUX_MINIX_H - -#include <stdint.h> - -struct minix_inode { - uint16_t i_mode; - uint16_t i_uid; - uint32_t i_size; - uint32_t i_time; - uint8_t i_gid; - uint8_t i_nlinks; - uint16_t i_zone[9]; -}; - -struct minix2_inode { - uint16_t i_mode; - uint16_t i_nlinks; - uint16_t i_uid; - uint16_t i_gid; - uint32_t i_size; - uint32_t i_atime; - uint32_t i_mtime; - uint32_t i_ctime; - uint32_t i_zone[10]; -}; - -struct minix_super_block { - uint16_t s_ninodes; - uint16_t s_nzones; - uint16_t s_imap_blocks; - uint16_t s_zmap_blocks; - uint16_t s_firstdatazone; - uint16_t s_log_zone_size; - uint32_t s_max_size; - uint16_t s_magic; - uint16_t s_state; - uint32_t s_zones; -}; - -/* V3 minix super-block data on disk */ -struct minix3_super_block { - uint32_t s_ninodes; - uint16_t s_pad0; - uint16_t s_imap_blocks; - uint16_t s_zmap_blocks; - uint16_t s_firstdatazone; - uint16_t s_log_zone_size; - uint16_t s_pad1; - uint32_t s_max_size; - uint32_t s_zones; - uint16_t s_magic; - uint16_t s_pad2; - uint16_t s_blocksize; - uint8_t s_disk_version; -}; - -/* - * Minix subpartitions are always within primary dos partition. - */ -#define MINIX_MAXPARTITIONS 4 - -#define MINIX_BLOCK_SIZE_BITS 10 -#define MINIX_BLOCK_SIZE (1 << MINIX_BLOCK_SIZE_BITS) - -#define MINIX_NAME_MAX 255 /* # chars in a file name */ -#define MINIX_MAX_INODES 65535 - -#define MINIX_INODES_PER_BLOCK ((MINIX_BLOCK_SIZE)/(sizeof (struct minix_inode))) -#define MINIX2_INODES_PER_BLOCK ((MINIX_BLOCK_SIZE)/(sizeof (struct minix2_inode))) - -/* minix_super_block.s_state */ -#define MINIX_VALID_FS 0x0001 /* Clean fs. */ -#define MINIX_ERROR_FS 0x0002 /* fs has errors. */ - - -#define MINIX_SUPER_MAGIC 0x137F /* minix V1 fs, 14 char names */ -#define MINIX_SUPER_MAGIC2 0x138F /* minix V1 fs, 30 char names */ - -#define MINIX2_SUPER_MAGIC 0x2468 /* minix V2 fs, 14 char names */ -#define MINIX2_SUPER_MAGIC2 0x2478 /* minix V2 fs, 30 char names */ - -#define MINIX3_SUPER_MAGIC 0x4d5a /* minix V3 fs (60 char names) */ - -#endif /* UTIL_LINUX_MINIX_H */ diff --git a/utils/include/monotonic.h b/utils/include/monotonic.h deleted file mode 100644 index 380e59c..0000000 --- a/utils/include/monotonic.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * No copyright is claimed. This code is in the public domain; do with - * it what you wish. - */ -#ifndef UTIL_LINUX_MONOTONIC_H -#define UTIL_LINUX_MONOTONIC_H - -# ifdef CLOCK_MONOTONIC_RAW -# define UL_CLOCK_MONOTONIC CLOCK_MONOTONIC_RAW -# else -# define UL_CLOCK_MONOTONIC CLOCK_MONOTONIC -# endif - -#include <sys/time.h> - -extern int get_boot_time(struct timeval *boot_time); - -extern time_t get_suspended_time(void); - -extern int gettime_monotonic(struct timeval *tv); - -#endif /* UTIL_LINUX_MONOTONIC_H */ diff --git a/utils/include/namespace.h b/utils/include/namespace.h deleted file mode 100644 index 2d0a56e..0000000 --- a/utils/include/namespace.h +++ /dev/null @@ -1,56 +0,0 @@ - -/* - * No copyright is claimed. This code is in the public domain; do with - * it what you wish. - * - * Compat code so unshare and setns can be used with older libcs - */ -#ifndef UTIL_LINUX_NAMESPACE_H -# define UTIL_LINUX_NAMESPACE_H - -# include <sched.h> - -# ifndef CLONE_NEWNS -# define CLONE_NEWNS 0x00020000 -# endif -# ifndef CLONE_NEWCGROUP -# define CLONE_NEWCGROUP 0x02000000 -# endif -# ifndef CLONE_NEWUTS -# define CLONE_NEWUTS 0x04000000 -# endif -# ifndef CLONE_NEWIPC -# define CLONE_NEWIPC 0x08000000 -# endif -# ifndef CLONE_NEWNET -# define CLONE_NEWNET 0x40000000 -# endif -# ifndef CLONE_NEWUSER -# define CLONE_NEWUSER 0x10000000 -# endif -# ifndef CLONE_NEWPID -# define CLONE_NEWPID 0x20000000 -# endif -# ifndef CLONE_NEWTIME -# define CLONE_NEWTIME 0x00000080 -# endif - -# if !defined(HAVE_UNSHARE) || !defined(HAVE_SETNS) -# include <sys/syscall.h> -# endif - -# if !defined(HAVE_UNSHARE) && defined(SYS_unshare) -static inline int unshare(int flags) -{ - return syscall(SYS_unshare, flags); -} -# endif - -# if !defined(HAVE_SETNS) && defined(SYS_setns) -static inline int setns(int fd, int nstype) -{ - return syscall(SYS_setns, fd, nstype); -} -# endif - -#endif /* UTIL_LINUX_NAMESPACE_H */ diff --git a/utils/include/nls.h b/utils/include/nls.h deleted file mode 100644 index 5566908..0000000 --- a/utils/include/nls.h +++ /dev/null @@ -1,153 +0,0 @@ -#ifndef UTIL_LINUX_NLS_H -#define UTIL_LINUX_NLS_H - -#ifndef LOCALEDIR -#define LOCALEDIR "/usr/share/locale" -#endif - -#ifdef HAVE_LOCALE_H -# include <locale.h> -#else -# undef setlocale -# define setlocale(Category, Locale) /* empty */ -struct lconv -{ - char *decimal_point; -}; -# undef localeconv -# define localeconv() NULL -#endif - - -#ifdef ENABLE_NLS -# include <libintl.h> -/* - * For NLS support in the public shared libraries we have to specify text - * domain name to be independent on the main program. For this purpose define - * UL_TEXTDOMAIN_EXPLICIT before you include nls.h to your shared library code. - */ -# ifdef UL_TEXTDOMAIN_EXPLICIT -# define _(Text) dgettext (UL_TEXTDOMAIN_EXPLICIT, Text) -# else -# define _(Text) gettext (Text) -# endif -# ifdef gettext_noop -# define N_(String) gettext_noop (String) -# else -# define N_(String) (String) -# endif -# define P_(Singular, Plural, n) ngettext (Singular, Plural, n) -#else -# undef bindtextdomain -# define bindtextdomain(Domain, Directory) /* empty */ -# undef textdomain -# define textdomain(Domain) /* empty */ -# define _(Text) (Text) -# define N_(Text) (Text) -# define P_(Singular, Plural, n) ((n) == 1 ? (Singular) : (Plural)) -#endif /* ENABLE_NLS */ - -#ifdef HAVE_LANGINFO_H -# include <langinfo.h> -#else - -typedef int nl_item; -extern char *langinfo_fallback(nl_item item); - -# define nl_langinfo langinfo_fallback - -enum { - CODESET = 1, - RADIXCHAR, - THOUSEP, - D_T_FMT, - D_FMT, - T_FMT, - T_FMT_AMPM, - AM_STR, - PM_STR, - - DAY_1, - DAY_2, - DAY_3, - DAY_4, - DAY_5, - DAY_6, - DAY_7, - - ABDAY_1, - ABDAY_2, - ABDAY_3, - ABDAY_4, - ABDAY_5, - ABDAY_6, - ABDAY_7, - - MON_1, - MON_2, - MON_3, - MON_4, - MON_5, - MON_6, - MON_7, - MON_8, - MON_9, - MON_10, - MON_11, - MON_12, - - ABMON_1, - ABMON_2, - ABMON_3, - ABMON_4, - ABMON_5, - ABMON_6, - ABMON_7, - ABMON_8, - ABMON_9, - ABMON_10, - ABMON_11, - ABMON_12, - - ERA_D_FMT, - ERA_D_T_FMT, - ERA_T_FMT, - ALT_DIGITS, - CRNCYSTR, - YESEXPR, - NOEXPR -}; - -#endif /* !HAVE_LANGINFO_H */ - -#ifndef HAVE_LANGINFO_ALTMON -# define ALTMON_1 MON_1 -# define ALTMON_2 MON_2 -# define ALTMON_3 MON_3 -# define ALTMON_4 MON_4 -# define ALTMON_5 MON_5 -# define ALTMON_6 MON_6 -# define ALTMON_7 MON_7 -# define ALTMON_8 MON_8 -# define ALTMON_9 MON_9 -# define ALTMON_10 MON_10 -# define ALTMON_11 MON_11 -# define ALTMON_12 MON_12 -#endif /* !HAVE_LANGINFO_ALTMON */ - -#ifndef HAVE_LANGINFO_NL_ABALTMON -# define _NL_ABALTMON_1 ABMON_1 -# define _NL_ABALTMON_2 ABMON_2 -# define _NL_ABALTMON_3 ABMON_3 -# define _NL_ABALTMON_4 ABMON_4 -# define _NL_ABALTMON_5 ABMON_5 -# define _NL_ABALTMON_6 ABMON_6 -# define _NL_ABALTMON_7 ABMON_7 -# define _NL_ABALTMON_8 ABMON_8 -# define _NL_ABALTMON_9 ABMON_9 -# define _NL_ABALTMON_10 ABMON_10 -# define _NL_ABALTMON_11 ABMON_11 -# define _NL_ABALTMON_12 ABMON_12 -#endif /* !HAVE_LANGINFO_NL_ABALTMON */ - -#endif /* UTIL_LINUX_NLS_H */ diff --git a/utils/include/optutils.h b/utils/include/optutils.h deleted file mode 100644 index 0dc127b..0000000 --- a/utils/include/optutils.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef UTIL_LINUX_OPTUTILS_H -#define UTIL_LINUX_OPTUTILS_H - -#include <assert.h> - -#include "c.h" -#include "nls.h" -#include "cctype.h" - -static inline const char *option_to_longopt(int c, const struct option *opts) -{ - const struct option *o; - - assert(!(opts == NULL)); - for (o = opts; o->name; o++) - if (o->val == c) - return o->name; - return NULL; -} - -#ifndef OPTUTILS_EXIT_CODE -# define OPTUTILS_EXIT_CODE EXIT_FAILURE -#endif - -/* - * Check collisions between options. - * - * The conflicts between options are described in ul_excl_t array. The - * array contains groups of mutually exclusive options. For example - * - * static const ul_excl_t excl[] = { - * { 'Z','b','c' }, // first group - * { 'b','x' }, // second group - * { 0 } - * }; - * - * int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT; - * - * while ((c = getopt_long(argc, argv, "Zbcx", longopts, NULL)) != -1) { - * - * err_exclusive_options(c, longopts, excl, excl_st); - * - * switch (c) { - * case 'Z': - * .... - * } - * } - * - * The array excl[] defines two groups of the mutually exclusive options. The - * option '-b' is in the both groups. - * - * Note that the options in the group have to be in ASCII order (ABC..abc..) and - * groups have to be also in ASCII order. - * - * The maximal number of the options in the group is 15 (size of the array is - * 16, last is zero). - * - * The current status of options is stored in excl_st array. The size of the array - * must be the same as number of the groups in the ul_excl_t array. - * - * If you're unsure then see sys-utils/mount.c or misc-utils/findmnt.c. - */ -#define UL_EXCL_STATUS_INIT { 0 } -typedef int ul_excl_t[16]; - -static inline void err_exclusive_options( - int c, - const struct option *opts, - const ul_excl_t *excl, - int *status) -{ - int e; - - for (e = 0; excl[e][0] && excl[e][0] <= c; e++) { - const int *op = excl[e]; - - for (; *op && *op <= c; op++) { - if (*op != c) - continue; - if (status[e] == 0) - status[e] = c; - else if (status[e] != c) { - size_t ct = 0; - - fprintf(stderr, _("%s: mutually exclusive " - "arguments:"), - program_invocation_short_name); - - for (op = excl[e]; - ct + 1 < ARRAY_SIZE(excl[0]) && *op; - op++, ct++) { - const char *n = option_to_longopt(*op, opts); - if (n) - fprintf(stderr, " --%s", n); - else if (c_isgraph(*op)) - fprintf(stderr, " -%c", *op); - } - fputc('\n', stderr); - exit(OPTUTILS_EXIT_CODE); - } - break; - } - } -} - -#endif - diff --git a/utils/include/pager.h b/utils/include/pager.h deleted file mode 100644 index 0a7140d..0000000 --- a/utils/include/pager.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef UTIL_LINUX_PAGER -#define UTIL_LINUX_PAGER - -void pager_redirect(void); - -void pager_open(void); -void pager_close(void); - -#endif diff --git a/utils/include/partx.h b/utils/include/partx.h deleted file mode 100644 index 618a0a4..0000000 --- a/utils/include/partx.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef UTIL_LINUX_PARTX_H -#define UTIL_LINUX_PARTX_H - -#include <sys/ioctl.h> -#include <linux/blkpg.h> -#include <stdint.h> - -#ifndef BLKPG_ADD_PARTITION -# define BLKPG_ADD_PARTITION 1 -#endif - -#ifndef BLKPG_DEL_PARTITION -# define BLKPG_DEL_PARTITION 2 -#endif - -#ifndef BLKPG_RESIZE_PARTITION -# define BLKPG_RESIZE_PARTITION 3 /* since Linux 3.6 */ -#endif - - -#define INIT_BLKPG_PARTITION(_partno, _start, _size) { \ - .pno = (_partno), \ - .start = (_start) << 9, \ - .length = (_size) << 9, \ - .devname[0] = 0, \ - .volname[0] = 0 \ -} - -#define INIT_BLKPG_ARG(_action, _part) { \ - .op = (_action), \ - .flags = 0, \ - .datalen = sizeof(*(_part)), \ - .data = (_part) \ -} - - -static inline int partx_del_partition(int fd, unsigned int partno) -{ - struct blkpg_partition p = INIT_BLKPG_PARTITION(partno, 0, 0); - struct blkpg_ioctl_arg a = INIT_BLKPG_ARG(BLKPG_DEL_PARTITION, &p); - - return ioctl(fd, BLKPG, &a); -} - -static inline int partx_add_partition(int fd, int partno, - uint64_t start, uint64_t size) -{ - struct blkpg_partition p = INIT_BLKPG_PARTITION(partno, start, size); - struct blkpg_ioctl_arg a = INIT_BLKPG_ARG(BLKPG_ADD_PARTITION, &p); - - return ioctl(fd, BLKPG, &a); -} - -static inline int partx_resize_partition(int fd, int partno, - uint64_t start, uint64_t size) -{ - struct blkpg_partition p = INIT_BLKPG_PARTITION(partno, start, size); - struct blkpg_ioctl_arg a = INIT_BLKPG_ARG(BLKPG_RESIZE_PARTITION, &p); - - return ioctl(fd, BLKPG, &a); -} - -#endif /* UTIL_LINUX_PARTX_H */ diff --git a/utils/include/path.h b/utils/include/path.h deleted file mode 100644 index 2a4f80e..0000000 --- a/utils/include/path.h +++ /dev/null @@ -1,135 +0,0 @@ -#ifndef UTIL_LINUX_PATH_H -#define UTIL_LINUX_PATH_H - -#include <stdio.h> -#include <stdint.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <dirent.h> - -#include "c.h" - -struct path_cxt { - int dir_fd; - char *dir_path; - - int refcount; - - char *prefix; - char path_buffer[PATH_MAX]; - - void *dialect; - void (*free_dialect)(struct path_cxt *); - int (*redirect_on_enoent)(struct path_cxt *, const char *, int *); -}; - -struct path_cxt *ul_new_path(const char *dir, ...); -void ul_unref_path(struct path_cxt *pc); -void ul_ref_path(struct path_cxt *pc); - -void ul_path_init_debug(void); - -int ul_path_set_prefix(struct path_cxt *pc, const char *prefix); -const char *ul_path_get_prefix(struct path_cxt *pc); - -int ul_path_set_dir(struct path_cxt *pc, const char *dir); -const char *ul_path_get_dir(struct path_cxt *pc); - -int ul_path_set_dialect(struct path_cxt *pc, void *data, void free_data(struct path_cxt *)); -void *ul_path_get_dialect(struct path_cxt *pc); - -int ul_path_set_enoent_redirect(struct path_cxt *pc, int (*func)(struct path_cxt *, const char *, int *)); -int ul_path_get_dirfd(struct path_cxt *pc); -void ul_path_close_dirfd(struct path_cxt *pc); -int ul_path_isopen_dirfd(struct path_cxt *pc); -int ul_path_is_accessible(struct path_cxt *pc); - -char *ul_path_get_abspath(struct path_cxt *pc, char *buf, size_t bufsz, const char *path, ...) - __attribute__ ((__format__ (__printf__, 4, 5))); - -int ul_path_stat(struct path_cxt *pc, struct stat *sb, const char *path); -int ul_path_access(struct path_cxt *pc, int mode, const char *path); -int ul_path_accessf(struct path_cxt *pc, int mode, const char *path, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); - -int ul_path_open(struct path_cxt *pc, int flags, const char *path); -int ul_path_openf(struct path_cxt *pc, int flags, const char *path, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); -int ul_path_vopenf(struct path_cxt *pc, int flags, const char *path, va_list ap); - -FILE *ul_path_fopen(struct path_cxt *pc, const char *mode, const char *path); -FILE *ul_path_fopenf(struct path_cxt *pc, const char *mode, const char *path, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); -FILE *ul_path_vfopenf(struct path_cxt *pc, const char *mode, const char *path, va_list ap); - -DIR *ul_path_opendir(struct path_cxt *pc, const char *path); -DIR *ul_path_vopendirf(struct path_cxt *pc, const char *path, va_list ap); -DIR *ul_path_opendirf(struct path_cxt *pc, const char *path, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); - -ssize_t ul_path_readlink(struct path_cxt *pc, char *buf, size_t bufsiz, const char *path); -ssize_t ul_path_readlinkf(struct path_cxt *pc, char *buf, size_t bufsiz, const char *path, ...) - __attribute__ ((__format__ (__printf__, 4, 5))); - -int ul_path_read(struct path_cxt *pc, char *buf, size_t len, const char *path); -int ul_path_vreadf(struct path_cxt *pc, char *buf, size_t len, const char *path, va_list ap); -int ul_path_readf(struct path_cxt *pc, char *buf, size_t len, const char *path, ...) - __attribute__ ((__format__ (__printf__, 4, 5))); - -int ul_path_read_string(struct path_cxt *pc, char **str, const char *path); -int ul_path_readf_string(struct path_cxt *pc, char **str, const char *path, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); - -int ul_path_read_buffer(struct path_cxt *pc, char *buf, size_t bufsz, const char *path); -int ul_path_readf_buffer(struct path_cxt *pc, char *buf, size_t bufsz, const char *path, ...) - __attribute__ ((__format__ (__printf__, 4, 5))); - -int ul_path_scanf(struct path_cxt *pc, const char *path, const char *fmt, ...); -int ul_path_scanff(struct path_cxt *pc, const char *path, va_list ap, const char *fmt, ...) - __attribute__ ((__format__ (__scanf__, 4, 5))); - -int ul_path_read_majmin(struct path_cxt *pc, dev_t *res, const char *path); -int ul_path_readf_majmin(struct path_cxt *pc, dev_t *res, const char *path, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); - -int ul_path_read_u32(struct path_cxt *pc, uint32_t *res, const char *path); -int ul_path_readf_u32(struct path_cxt *pc, uint32_t *res, const char *path, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); - -int ul_path_read_s32(struct path_cxt *pc, int32_t *res, const char *path); -int ul_path_readf_s32(struct path_cxt *pc, int32_t *res, const char *path, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); - -int ul_path_read_u64(struct path_cxt *pc, uint64_t *res, const char *path); -int ul_path_readf_u64(struct path_cxt *pc, uint64_t *res, const char *path, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); - -int ul_path_read_s64(struct path_cxt *pc, int64_t *res, const char *path); -int ul_path_readf_s64(struct path_cxt *pc, int64_t *res, const char *path, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); - -int ul_path_write_string(struct path_cxt *pc, const char *str, const char *path); -int ul_path_writef_string(struct path_cxt *pc, const char *str, const char *path, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); - -int ul_path_write_s64(struct path_cxt *pc, int64_t num, const char *path); -int ul_path_write_u64(struct path_cxt *pc, uint64_t num, const char *path); -int ul_path_writef_u64(struct path_cxt *pc, uint64_t num, const char *path, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); - -int ul_path_count_dirents(struct path_cxt *pc, const char *path); -int ul_path_countf_dirents(struct path_cxt *pc, const char *path, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); - -FILE *ul_prefix_fopen(const char *prefix, const char *path, const char *mode); - - -#ifdef HAVE_CPU_SET_T -# include "cpuset.h" -int ul_path_readf_cpuset(struct path_cxt *pc, cpu_set_t **set, int maxcpus, const char *path, ...) - __attribute__ ((__format__ (__printf__, 4, 5))); - -int ul_path_readf_cpulist(struct path_cxt *pc, cpu_set_t **set, int maxcpus, const char *path, ...) - __attribute__ ((__format__ (__printf__, 4, 5))); -#endif /* HAVE_CPU_SET_T */ -#endif /* UTIL_LINUX_PATH_H */ diff --git a/utils/include/pathnames.h b/utils/include/pathnames.h deleted file mode 100644 index 8f1bb56..0000000 --- a/utils/include/pathnames.h +++ /dev/null @@ -1,210 +0,0 @@ -/* - * No copyright is claimed. This code is in the public domain; do with - * it what you wish. - */ -#ifndef PATHNAMES_H -#define PATHNAMES_H - -#ifdef HAVE_PATHS_H -# include <paths.h> -#endif - -#ifndef __STDC__ -# error "we need an ANSI compiler" -#endif - -/* used by kernel in /proc (e.g. /proc/swaps) for deleted files */ -#define PATH_DELETED_SUFFIX " (deleted)" - -/* DEFPATHs from <paths.h> don't include /usr/local */ -#undef _PATH_DEFPATH - -#ifdef USE_USRDIR_PATHS_ONLY -# define _PATH_DEFPATH "/usr/local/bin:/usr/bin" -#else -# define _PATH_DEFPATH "/usr/local/bin:/bin:/usr/bin" -#endif - -#undef _PATH_DEFPATH_ROOT - -#ifdef USE_USRDIR_PATHS_ONLY -# define _PATH_DEFPATH_ROOT "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin" -#else -# define _PATH_DEFPATH_ROOT "/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin" -#endif - -#define _PATH_HUSHLOGIN ".hushlogin" -#define _PATH_HUSHLOGINS "/etc/hushlogins" - -#define _PATH_NOLOGIN_TXT "/etc/nologin.txt" - -#ifndef _PATH_MAILDIR -# define _PATH_MAILDIR "/var/spool/mail" -#endif -#define _PATH_MOTDFILE "/usr/share/misc/motd:/run/motd:/etc/motd" -#ifndef _PATH_NOLOGIN -# define _PATH_NOLOGIN "/etc/nologin" -#endif -#define _PATH_VAR_NOLOGIN "/var/run/nologin" - -#ifndef _PATH_LOGIN -# define _PATH_LOGIN "/bin/login" -#endif -#define _PATH_SHUTDOWN "/sbin/shutdown" -#define _PATH_POWEROFF "/sbin/poweroff" - -#define _PATH_TERMCOLORS_DIRNAME "terminal-colors.d" -#define _PATH_TERMCOLORS_DIR "/etc/" _PATH_TERMCOLORS_DIRNAME - -/* login paths */ -#define _PATH_PASSWD "/etc/passwd" -#define _PATH_GSHADOW "/etc/gshadow" -#define _PATH_GROUP "/etc/group" -#define _PATH_SHADOW_PASSWD "/etc/shadow" -#define _PATH_SHELLS "/etc/shells" - -#ifndef _PATH_TMP -# define _PATH_TMP "/tmp/" -#endif - -#ifndef _PATH_BTMP -# define _PATH_BTMP "/var/log/btmp" -#endif - -#define _PATH_ISSUE_FILENAME "issue" -#define _PATH_ISSUE_DIRNAME _PATH_ISSUE_FILENAME ".d" - -#define _PATH_ISSUE "/etc/" _PATH_ISSUE_FILENAME -#define _PATH_ISSUEDIR "/etc/" _PATH_ISSUE_DIRNAME - -#define _PATH_OS_RELEASE_ETC "/etc/os-release" -#define _PATH_OS_RELEASE_USR "/usr/lib/os-release" -#define _PATH_NUMLOCK_ON _PATH_RUNSTATEDIR "/numlock-on" -#define _PATH_LOGINDEFS "/etc/login.defs" - -/* misc paths */ -#define _PATH_WORDS "/usr/share/dict/words" -#define _PATH_WORDS_ALT "/usr/share/dict/web2" - -/* mount paths */ -#define _PATH_FILESYSTEMS "/etc/filesystems" -#define _PATH_PROC_SWAPS "/proc/swaps" -#define _PATH_PROC_FILESYSTEMS "/proc/filesystems" -#define _PATH_PROC_MOUNTS "/proc/mounts" -#define _PATH_PROC_PARTITIONS "/proc/partitions" -#define _PATH_PROC_DEVICES "/proc/devices" -#define _PATH_PROC_MOUNTINFO "/proc/self/mountinfo" -#define _PATH_PROC_LOCKS "/proc/locks" -#define _PATH_PROC_CDROMINFO "/proc/sys/dev/cdrom/info" - -#define _PATH_PROC_UIDMAP "/proc/self/uid_map" -#define _PATH_PROC_GIDMAP "/proc/self/gid_map" -#define _PATH_PROC_SETGROUPS "/proc/self/setgroups" - -#define _PATH_PROC_FDDIR "/proc/self/fd" - -#define _PATH_PROC_ATTR_CURRENT "/proc/self/attr/current" -#define _PATH_PROC_ATTR_EXEC "/proc/self/attr/exec" -#define _PATH_PROC_CAPLASTCAP "/proc/sys/kernel/cap_last_cap" - - -#define _PATH_SYS_BLOCK "/sys/block" -#define _PATH_SYS_DEVBLOCK "/sys/dev/block" -#define _PATH_SYS_DEVCHAR "/sys/dev/char" -#define _PATH_SYS_CLASS "/sys/class" -#define _PATH_SYS_SCSI "/sys/bus/scsi" - -#define _PATH_SYS_SELINUX "/sys/fs/selinux" -#define _PATH_SYS_APPARMOR "/sys/kernel/security/apparmor" - -#ifndef _PATH_MOUNTED -# ifdef MOUNTED /* deprecated */ -# define _PATH_MOUNTED MOUNTED -# else -# define _PATH_MOUNTED "/etc/mtab" -# endif -#endif - -#ifndef _PATH_MNTTAB -# ifdef MNTTAB /* deprecated */ -# define _PATH_MNTTAB MNTTAB -# else -# define _PATH_MNTTAB "/etc/fstab" -# endif -#endif - -#ifndef _PATH_DEV - /* - * The tailing '/' in _PATH_DEV is there for compatibility with libc. - */ -# define _PATH_DEV "/dev/" -#endif - -#define _PATH_DEV_MAPPER "/dev/mapper" - -#define _PATH_DEV_MEM "/dev/mem" - -#define _PATH_DEV_LOOP "/dev/xloop" -#define _PATH_DEV_LOOPCTL "/dev/xloop-control" - -/* udev paths */ -#define _PATH_DEV_BYLABEL "/dev/disk/by-label" -#define _PATH_DEV_BYUUID "/dev/disk/by-uuid" -#define _PATH_DEV_BYID "/dev/disk/by-id" -#define _PATH_DEV_BYPATH "/dev/disk/by-path" -#define _PATH_DEV_BYPARTLABEL "/dev/disk/by-partlabel" -#define _PATH_DEV_BYPARTUUID "/dev/disk/by-partuuid" - -/* hwclock paths */ -#ifdef CONFIG_ADJTIME_PATH -# define _PATH_ADJTIME CONFIG_ADJTIME_PATH -#else -# define _PATH_ADJTIME "/etc/adjtime" -#endif - -#ifdef __ia64__ -# define _PATH_RTC_DEV "/dev/efirtc" -#else -# define _PATH_RTC_DEV "/dev/rtc0" -#endif - -/* raw paths*/ -#define _PATH_RAWDEVDIR "/dev/raw/" -#define _PATH_RAWDEVCTL _PATH_RAWDEVDIR "rawctl" -/* deprecated */ -#define _PATH_RAWDEVCTL_OLD "/dev/rawctl" - -/* ipc paths */ -#define _PATH_PROC_SYSV_MSG "/proc/sysvipc/msg" -#define _PATH_PROC_SYSV_SEM "/proc/sysvipc/sem" -#define _PATH_PROC_SYSV_SHM "/proc/sysvipc/shm" -#define _PATH_PROC_IPC_MSGMAX "/proc/sys/kernel/msgmax" -#define _PATH_PROC_IPC_MSGMNB "/proc/sys/kernel/msgmnb" -#define _PATH_PROC_IPC_MSGMNI "/proc/sys/kernel/msgmni" -#define _PATH_PROC_IPC_SEM "/proc/sys/kernel/sem" -#define _PATH_PROC_IPC_SHMALL "/proc/sys/kernel/shmall" -#define _PATH_PROC_IPC_SHMMAX "/proc/sys/kernel/shmmax" -#define _PATH_PROC_IPC_SHMMNI "/proc/sys/kernel/shmmni" - -/* irqtop paths */ -#define _PATH_PROC_INTERRUPTS "/proc/interrupts" -#define _PATH_PROC_SOFTIRQS "/proc/softirqs" -#define _PATH_PROC_UPTIME "/proc/uptime" - -/* kernel command line */ -#define _PATH_PROC_CMDLINE "/proc/cmdline" - -/* logger paths */ -#define _PATH_DEVLOG "/dev/log" - -/* ctrlaltdel paths */ -#define _PATH_PROC_CTRL_ALT_DEL "/proc/sys/kernel/ctrl-alt-del" - -/* lscpu paths */ -#define _PATH_PROC_CPUINFO "/proc/cpuinfo" - -/* rfkill paths */ -#define _PATH_DEV_RFKILL "/dev/rfkill" -#define _PATH_SYS_RFKILL "/sys/class/rfkill" - -#endif /* PATHNAMES_H */ diff --git a/utils/include/pidfd-utils.h b/utils/include/pidfd-utils.h deleted file mode 100644 index 4a6c3a6..0000000 --- a/utils/include/pidfd-utils.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef UTIL_LINUX_PIDFD_UTILS -#define UTIL_LINUX_PIDFD_UTILS - -#if defined(__linux__) -# include <sys/syscall.h> -# if defined(SYS_pidfd_send_signal) && defined(SYS_pidfd_open) -# include <sys/types.h> - -# ifndef HAVE_PIDFD_SEND_SIGNAL -static inline int pidfd_send_signal(int pidfd, int sig, siginfo_t *info, - unsigned int flags) -{ - return syscall(SYS_pidfd_send_signal, pidfd, sig, info, flags); -} -# endif - -# ifndef HAVE_PIDFD_OPEN -static inline int pidfd_open(pid_t pid, unsigned int flags) -{ - return syscall(SYS_pidfd_open, pid, flags); -} -# endif - -# define UL_HAVE_PIDFD 1 - -# endif /* SYS_pidfd_send_signal */ -#endif /* __linux__ */ -#endif /* UTIL_LINUX_PIDFD_UTILS */ diff --git a/utils/include/plymouth-ctrl.h b/utils/include/plymouth-ctrl.h deleted file mode 100644 index b6f1299..0000000 --- a/utils/include/plymouth-ctrl.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * plymouth-ctrl.h Header file for communications with plymouthd - * - * Copyright (c) 2016 SUSE Linux GmbH, All rights reserved. - * Copyright (c) 2016 Werner Fink <werner@suse.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING); if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301, USA. - * - * Author: Werner Fink <werner@suse.de> - */ - -/* - * Taken from plymouth 0.9.0 src/ply-boot-protocol.h - */ - -#ifndef UTIL_LINUX_PLYMOUTH_CTRL_H -#define UTIL_LINUX_PLYMOUTH_CTRL_H - -#define PLYMOUTH_SOCKET_PATH "\0/org/freedesktop/plymouthd" -#define ANSWER_TYP '\x2' -#define ANSWER_ENQ '\x5' -#define ANSWER_ACK '\x6' -#define ANSWER_MLT '\t' -#define ANSWER_NCK '\x15' - -#define MAGIC_PRG_STOP 'A' -#define MAGIC_PRG_CONT 'a' -#define MAGIC_UPDATE 'U' -#define MAGIC_SYS_UPDATE 'u' -#define MAGIC_SYS_INIT 'S' -#define MAGIC_DEACTIVATE 'D' -#define MAGIC_REACTIVATE 'r' -#define MAGIC_SHOW_SPLASH '$' -#define MAGIC_HIDE_SPLASH 'H' -#define MAGIC_CHMOD 'C' -#define MAGIC_CHROOT 'R' -#define MAGIC_ACTIVE_VT 'V' -#define MAGIC_QUESTION 'W' -#define MAGIC_SHOW_MSG 'M' -#define MAGIC_HIDE_MSG 'm' -#define MAGIC_KEYSTROKE 'K' -#define MAGIC_KEYSTROKE_RM 'L' -#define MAGIC_PING 'P' -#define MAGIC_QUIT 'Q' -#define MAGIC_CACHED_PWD 'c' -#define MAGIC_ASK_PWD '*' -#define MAGIC_DETAILS '!' - -#define PLYMOUTH_TERMIOS_FLAGS_DELAY 30 -extern int plymouth_command(int cmd, ...); - -#endif /* UTIL_LINUX_PLYMOUTH_CTRL_H */ diff --git a/utils/include/procutils.h b/utils/include/procutils.h deleted file mode 100644 index 9f8dd76..0000000 --- a/utils/include/procutils.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef UTIL_LINUX_PROCUTILS -#define UTIL_LINUX_PROCUTILS - -#include <dirent.h> - -struct proc_tasks { - DIR *dir; -}; - -extern struct proc_tasks *proc_open_tasks(pid_t pid); -extern void proc_close_tasks(struct proc_tasks *tasks); -extern int proc_next_tid(struct proc_tasks *tasks, pid_t *tid); - -struct proc_processes { - DIR *dir; - - const char *fltr_name; - uid_t fltr_uid; - - unsigned int has_fltr_name : 1, - has_fltr_uid : 1; -}; - -extern struct proc_processes *proc_open_processes(void); -extern void proc_close_processes(struct proc_processes *ps); - -extern void proc_processes_filter_by_name(struct proc_processes *ps, const char *name); -extern void proc_processes_filter_by_uid(struct proc_processes *ps, uid_t uid); -extern int proc_next_pid(struct proc_processes *ps, pid_t *pid); - -extern char *proc_get_command(pid_t pid); -extern char *proc_get_command_name(pid_t pid); - -#endif /* UTIL_LINUX_PROCUTILS */ diff --git a/utils/include/pt-bsd.h b/utils/include/pt-bsd.h deleted file mode 100644 index 9bf47a5..0000000 --- a/utils/include/pt-bsd.h +++ /dev/null @@ -1,156 +0,0 @@ -#ifndef UTIL_LINUX_PT_BSD_H -#define UTIL_LINUX_PT_BSD_H - -#define BSD_MAXPARTITIONS 16 -#define BSD_FS_UNUSED 0 - -#ifndef BSD_DISKMAGIC -# define BSD_DISKMAGIC ((uint32_t) 0x82564557) -#endif - -#define BSD_LINUX_BOOTDIR "/usr/ucb/mdec" - -#if defined (__alpha__) || defined (__powerpc__) || \ - defined (__ia64__) || defined (__hppa__) -# define BSD_LABELSECTOR 0 -# define BSD_LABELOFFSET 64 -#else -# define BSD_LABELSECTOR 1 -# define BSD_LABELOFFSET 0 -#endif - -#define BSD_BBSIZE 8192 /* size of boot area, with label */ -#define BSD_SBSIZE 8192 /* max size of fs superblock */ - -struct bsd_disklabel { - uint32_t d_magic; /* the magic number */ - int16_t d_type; /* drive type */ - int16_t d_subtype; /* controller/d_type specific */ - char d_typename[16]; /* type name, e.g. "eagle" */ - char d_packname[16]; /* pack identifier */ - - /* disk geometry: */ - uint32_t d_secsize; /* # of bytes per sector */ - uint32_t d_nsectors; /* # of data sectors per track */ - uint32_t d_ntracks; /* # of tracks per cylinder */ - uint32_t d_ncylinders; /* # of data cylinders per unit */ - uint32_t d_secpercyl; /* # of data sectors per cylinder */ - uint32_t d_secperunit; /* # of data sectors per unit */ - - /* - * Spares (bad sector replacements) below - * are not counted in d_nsectors or d_secpercyl. - * Spare sectors are assumed to be physical sectors - * which occupy space at the end of each track and/or cylinder. - */ - uint16_t d_sparespertrack; /* # of spare sectors per track */ - uint16_t d_sparespercyl; /* # of spare sectors per cylinder */ - - /* - * Alternate cylinders include maintenance, replacement, - * configuration description areas, etc. - */ - uint32_t d_acylinders; /* # of alt. cylinders per unit */ - - /* hardware characteristics: */ - /* - * d_interleave, d_trackskew and d_cylskew describe perturbations - * in the media format used to compensate for a slow controller. - * Interleave is physical sector interleave, set up by the formatter - * or controller when formatting. When interleaving is in use, - * logically adjacent sectors are not physically contiguous, - * but instead are separated by some number of sectors. - * It is specified as the ratio of physical sectors traversed - * per logical sector. Thus an interleave of 1:1 implies contiguous - * layout, while 2:1 implies that logical sector 0 is separated - * by one sector from logical sector 1. - * d_trackskew is the offset of sector 0 on track N - * relative to sector 0 on track N-1 on the same cylinder. - * Finally, d_cylskew is the offset of sector 0 on cylinder N - * relative to sector 0 on cylinder N-1. - */ - uint16_t d_rpm; /* rotational speed */ - uint16_t d_interleave; /* hardware sector interleave */ - uint16_t d_trackskew; /* sector 0 skew, per track */ - uint16_t d_cylskew; /* sector 0 skew, per cylinder */ - uint32_t d_headswitch; /* head switch time, usec */ - uint32_t d_trkseek; /* track-to-track seek, usec */ - uint32_t d_flags; /* generic flags */ - uint32_t d_drivedata[5]; /* drive-type specific information */ - uint32_t d_spare[5]; /* reserved for future use */ - uint32_t d_magic2; /* the magic number (again) */ - uint16_t d_checksum; /* xor of data incl. partitions */ - - /* filesystem and partition information: */ - uint16_t d_npartitions; /* number of partitions in following */ - uint32_t d_bbsize; /* size of boot area at sn0, bytes */ - uint32_t d_sbsize; /* max size of fs superblock, bytes */ - - struct bsd_partition { /* the partition table */ - uint32_t p_size; /* number of sectors in partition */ - uint32_t p_offset; /* starting sector */ - uint32_t p_fsize; /* filesystem basic fragment size */ - uint8_t p_fstype; /* filesystem type, see below */ - uint8_t p_frag; /* filesystem fragments per block */ - uint16_t p_cpg; /* filesystem cylinders per group */ - } __attribute__((packed)) d_partitions[BSD_MAXPARTITIONS]; /* actually may be more */ -} __attribute__((packed)); - - -/* d_type values: */ -#define BSD_DTYPE_SMD 1 /* SMD, XSMD; VAX hp/up */ -#define BSD_DTYPE_MSCP 2 /* MSCP */ -#define BSD_DTYPE_DEC 3 /* other DEC (rk, rl) */ -#define BSD_DTYPE_SCSI 4 /* SCSI */ -#define BSD_DTYPE_ESDI 5 /* ESDI interface */ -#define BSD_DTYPE_ST506 6 /* ST506 etc. */ -#define BSD_DTYPE_HPIB 7 /* CS/80 on HP-IB */ -#define BSD_DTYPE_HPFL 8 /* HP Fiber-link */ -#define BSD_DTYPE_FLOPPY 10 /* floppy */ - -/* d_subtype values: */ -#define BSD_DSTYPE_INDOSPART 0x8 /* is inside dos partition */ -#define BSD_DSTYPE_DOSPART(s) ((s) & 3) /* dos partition number */ -#define BSD_DSTYPE_GEOMETRY 0x10 /* drive params in label */ - -/* - * Filesystem type and version. - * Used to interpret other filesystem-specific - * per-partition information. - */ -#define BSD_FS_UNUSED 0 /* unused */ -#define BSD_FS_SWAP 1 /* swap */ -#define BSD_FS_V6 2 /* Sixth Edition */ -#define BSD_FS_V7 3 /* Seventh Edition */ -#define BSD_FS_SYSV 4 /* System V */ -#define BSD_FS_V71K 5 /* V7 with 1K blocks (4.1, 2.9) */ -#define BSD_FS_V8 6 /* Eighth Edition, 4K blocks */ -#define BSD_FS_BSDFFS 7 /* 4.2BSD fast file system */ -#define BSD_FS_BSDLFS 9 /* 4.4BSD log-structured file system */ -#define BSD_FS_OTHER 10 /* in use, but unknown/unsupported */ -#define BSD_FS_HPFS 11 /* OS/2 high-performance file system */ -#define BSD_FS_ISO9660 12 /* ISO-9660 filesystem (cdrom) */ -#define BSD_FS_ISOFS BSD_FS_ISO9660 -#define BSD_FS_BOOT 13 /* partition contains bootstrap */ -#define BSD_FS_ADOS 14 /* AmigaDOS fast file system */ -#define BSD_FS_HFS 15 /* Macintosh HFS */ -#define BSD_FS_ADVFS 16 /* Digital Unix AdvFS */ - -/* this is annoying, but it's also the way it is :-( */ -#ifdef __alpha__ -#define BSD_FS_EXT2 8 /* ext2 file system */ -#else -#define BSD_FS_MSDOS 8 /* MS-DOS file system */ -#endif - -/* - * flags shared by various drives: - */ -#define BSD_D_REMOVABLE 0x01 /* removable media */ -#define BSD_D_ECC 0x02 /* supports ECC */ -#define BSD_D_BADSECT 0x04 /* supports bad sector forw. */ -#define BSD_D_RAMDISK 0x08 /* disk emulator */ -#define BSD_D_CHAIN 0x10 /* can do back-back transfers */ -#define BSD_D_DOSPART 0x20 /* within MSDOS partition */ - -#endif /* UTIL_LINUX_PT_BSD_H */ diff --git a/utils/include/pt-gpt-partnames.h b/utils/include/pt-gpt-partnames.h deleted file mode 100644 index 604f2c6..0000000 --- a/utils/include/pt-gpt-partnames.h +++ /dev/null @@ -1,160 +0,0 @@ - -/* - * No copyright is claimed. This code is in the public domain; do with - * it what you wish. - * - * Written by Karel Zak <kzak@redhat.com> - * - * Probably the most complete list of the GUIDs are at: - * https://wikipedia.org/wiki/GUID_Partition_Table - * - * The macro DEF_GUID() has to be defined in your code according to array where - * you want to include this file. - */ - -/* Generic OS */ -DEF_GUID("C12A7328-F81F-11D2-BA4B-00A0C93EC93B", N_("EFI System")), - -DEF_GUID("024DEE41-33E7-11D3-9D69-0008C781F39F", N_("MBR partition scheme")), -DEF_GUID("D3BFE2DE-3DAF-11DF-BA40-E3A556D89593", N_("Intel Fast Flash")), - -/* Hah!IdontneedEFI */ -DEF_GUID("21686148-6449-6E6F-744E-656564454649", N_("BIOS boot")), - -/* NIH syndrome */ -DEF_GUID("F4019732-066E-4E12-8273-346C5641494F", N_("Sony boot partition")), -DEF_GUID("BFBFAFE7-A34F-448A-9A5B-6213EB736C22", N_("Lenovo boot partition")), - -/* PowerPC reference platform boot partition */ -DEF_GUID("9E1A2D38-C612-4316-AA26-8B49521E5A8B", N_("PowerPC PReP boot")), - -/* Open Network Install Environment */ -DEF_GUID("7412F7D5-A156-4B13-81DC-867174929325", N_("ONIE boot")), -DEF_GUID("D4E6E2CD-4469-46F3-B5CB-1BFF57AFC149", N_("ONIE config")), - -/* Windows */ -DEF_GUID("E3C9E316-0B5C-4DB8-817D-F92DF00215AE", N_("Microsoft reserved")), -DEF_GUID("EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", N_("Microsoft basic data")), -DEF_GUID("5808C8AA-7E8F-42E0-85D2-E1E90434CFB3", N_("Microsoft LDM metadata")), -DEF_GUID("AF9B60A0-1431-4F62-BC68-3311714A69AD", N_("Microsoft LDM data")), -DEF_GUID("DE94BBA4-06D1-4D40-A16A-BFD50179D6AC", N_("Windows recovery environment")), -DEF_GUID("37AFFC90-EF7D-4E96-91C3-2D7AE055B174", N_("IBM General Parallel Fs")), -DEF_GUID("E75CAF8F-F680-4CEE-AFA3-B001E56EFC2D", N_("Microsoft Storage Spaces")), - -/* HP-UX */ -DEF_GUID("75894C1E-3AEB-11D3-B7C1-7B03A0000000", N_("HP-UX data")), -DEF_GUID("E2A1E728-32E3-11D6-A682-7B03A0000000", N_("HP-UX service")), - -/* Linux (https://systemd.io/DISCOVERABLE_PARTITIONS/) */ -DEF_GUID("0657FD6D-A4AB-43C4-84E5-0933C84B4F4F", N_("Linux swap")), -DEF_GUID("0FC63DAF-8483-4772-8E79-3D69D8477DE4", N_("Linux filesystem")), -DEF_GUID("3B8F8425-20E0-4F3B-907F-1A25A76F98E8", N_("Linux server data")), -DEF_GUID("44479540-F297-41B2-9AF7-D131D5F0458A", N_("Linux root (x86)")), -DEF_GUID("69DAD710-2CE4-4E3C-B16C-21A1D49ABED3", N_("Linux root (ARM)")), -DEF_GUID("4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709", N_("Linux root (x86-64)")), -DEF_GUID("B921B045-1DF0-41C3-AF44-4C6F280D3FAE", N_("Linux root (ARM-64)")), -DEF_GUID("993D8D3D-F80E-4225-855A-9DAF8ED7EA97", N_("Linux root (IA-64)")), -DEF_GUID("8DA63339-0007-60C0-C436-083AC8230908", N_("Linux reserved")), -DEF_GUID("933AC7E1-2EB4-4F13-B844-0E14E2AEF915", N_("Linux home")), -DEF_GUID("A19D880F-05FC-4D3B-A006-743F0F84911E", N_("Linux RAID")), -DEF_GUID("E6D6D379-F507-44C2-A23C-238F2A3DF928", N_("Linux LVM")), -DEF_GUID("4D21B016-B534-45C2-A9FB-5C16E091FD2D", N_("Linux variable data")), -DEF_GUID("7EC6F557-3BC5-4ACA-B293-16EF5DF639D1", N_("Linux temporary data")), -DEF_GUID("D13C5D3B-B5D1-422A-B29F-9454FDC89D76", N_("Linux root verity (x86)")), -DEF_GUID("7386CDF2-203C-47A9-A498-F2ECCE45A2D6", N_("Linux root verity (ARM)")), -DEF_GUID("2C7357ED-EBD2-46D9-AEC1-23D437EC2BF5", N_("Linux root verity (x86-64)")), -DEF_GUID("DF3300CE-D69F-4C92-978C-9BFB0F38D820", N_("Linux root verity (ARM-64)")), -DEF_GUID("86ED10D5-B607-45BB-8957-D350F23D0571", N_("Linux root verity (IA-64)")), -/* ... too crazy, ignore for now: -DEF_GUID("7FFEC5C9-2D00-49B7-8941-3EA10A5586B7", N_("Linux plain dm-crypt")), -DEF_GUID("CA7D7CCB-63ED-4C53-861C-1742536059CC", N_("Linux LUKS")), -*/ -/* Linux https://systemd.io/BOOT_LOADER_SPECIFICATION/ */ -DEF_GUID("BC13C2FF-59E6-4262-A352-B275FD6F7172", N_("Linux extended boot")), - -/* Linux https://systemd.io/HOME_DIRECTORY/ */ -DEF_GUID("773f91ef-66d4-49b5-bd83-d683bf40ad16", N_("Linux user's home")), - -/* FreeBSD */ -DEF_GUID("516E7CB4-6ECF-11D6-8FF8-00022D09712B", N_("FreeBSD data")), -DEF_GUID("83BD6B9D-7F41-11DC-BE0B-001560B84F0F", N_("FreeBSD boot")), -DEF_GUID("516E7CB5-6ECF-11D6-8FF8-00022D09712B", N_("FreeBSD swap")), -DEF_GUID("516E7CB6-6ECF-11D6-8FF8-00022D09712B", N_("FreeBSD UFS")), -DEF_GUID("516E7CBA-6ECF-11D6-8FF8-00022D09712B", N_("FreeBSD ZFS")), -DEF_GUID("516E7CB8-6ECF-11D6-8FF8-00022D09712B", N_("FreeBSD Vinum")), - -/* Apple OSX */ -DEF_GUID("48465300-0000-11AA-AA11-00306543ECAC", N_("Apple HFS/HFS+")), -DEF_GUID("7C3457EF-0000-11AA-AA11-00306543ECAC", N_("Apple APFS")), -DEF_GUID("55465300-0000-11AA-AA11-00306543ECAC", N_("Apple UFS")), -DEF_GUID("52414944-0000-11AA-AA11-00306543ECAC", N_("Apple RAID")), -DEF_GUID("52414944-5F4F-11AA-AA11-00306543ECAC", N_("Apple RAID offline")), -DEF_GUID("426F6F74-0000-11AA-AA11-00306543ECAC", N_("Apple boot")), -DEF_GUID("4C616265-6C00-11AA-AA11-00306543ECAC", N_("Apple label")), -DEF_GUID("5265636F-7665-11AA-AA11-00306543ECAC", N_("Apple TV recovery")), -DEF_GUID("53746F72-6167-11AA-AA11-00306543ECAC", N_("Apple Core storage")), - -/* Solaris */ -DEF_GUID("6A82CB45-1DD2-11B2-99A6-080020736631", N_("Solaris boot")), -DEF_GUID("6A85CF4D-1DD2-11B2-99A6-080020736631", N_("Solaris root")), -/* same as Apple ZFS */ -DEF_GUID("6A898CC3-1DD2-11B2-99A6-080020736631", N_("Solaris /usr & Apple ZFS")), -DEF_GUID("6A87C46F-1DD2-11B2-99A6-080020736631", N_("Solaris swap")), -DEF_GUID("6A8B642B-1DD2-11B2-99A6-080020736631", N_("Solaris backup")), -DEF_GUID("6A8EF2E9-1DD2-11B2-99A6-080020736631", N_("Solaris /var")), -DEF_GUID("6A90BA39-1DD2-11B2-99A6-080020736631", N_("Solaris /home")), -DEF_GUID("6A9283A5-1DD2-11B2-99A6-080020736631", N_("Solaris alternate sector")), -DEF_GUID("6A945A3B-1DD2-11B2-99A6-080020736631", N_("Solaris reserved 1")), -DEF_GUID("6A9630D1-1DD2-11B2-99A6-080020736631", N_("Solaris reserved 2")), -DEF_GUID("6A980767-1DD2-11B2-99A6-080020736631", N_("Solaris reserved 3")), -DEF_GUID("6A96237F-1DD2-11B2-99A6-080020736631", N_("Solaris reserved 4")), -DEF_GUID("6A8D2AC7-1DD2-11B2-99A6-080020736631", N_("Solaris reserved 5")), - -/* NetBSD */ -DEF_GUID("49F48D32-B10E-11DC-B99B-0019D1879648", N_("NetBSD swap")), -DEF_GUID("49F48D5A-B10E-11DC-B99B-0019D1879648", N_("NetBSD FFS")), -DEF_GUID("49F48D82-B10E-11DC-B99B-0019D1879648", N_("NetBSD LFS")), -DEF_GUID("2DB519C4-B10E-11DC-B99B-0019D1879648", N_("NetBSD concatenated")), -DEF_GUID("2DB519EC-B10E-11DC-B99B-0019D1879648", N_("NetBSD encrypted")), -DEF_GUID("49F48DAA-B10E-11DC-B99B-0019D1879648", N_("NetBSD RAID")), - -/* ChromeOS */ -DEF_GUID("FE3A2A5D-4F32-41A7-B725-ACCC3285A309", N_("ChromeOS kernel")), -DEF_GUID("3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC", N_("ChromeOS root fs")), -DEF_GUID("2E0A753D-9E48-43B0-8337-B15192CB1B5E", N_("ChromeOS reserved")), - -/* MidnightBSD */ -DEF_GUID("85D5E45A-237C-11E1-B4B3-E89A8F7FC3A7", N_("MidnightBSD data")), -DEF_GUID("85D5E45E-237C-11E1-B4B3-E89A8F7FC3A7", N_("MidnightBSD boot")), -DEF_GUID("85D5E45B-237C-11E1-B4B3-E89A8F7FC3A7", N_("MidnightBSD swap")), -DEF_GUID("0394EF8B-237E-11E1-B4B3-E89A8F7FC3A7", N_("MidnightBSD UFS")), -DEF_GUID("85D5E45D-237C-11E1-B4B3-E89A8F7FC3A7", N_("MidnightBSD ZFS")), -DEF_GUID("85D5E45C-237C-11E1-B4B3-E89A8F7FC3A7", N_("MidnightBSD Vinum")), - -/* Ceph */ -DEF_GUID("45B0969E-9B03-4F30-B4C6-B4B80CEFF106", N_("Ceph Journal")), -DEF_GUID("45B0969E-9B03-4F30-B4C6-5EC00CEFF106", N_("Ceph Encrypted Journal")), -DEF_GUID("4FBD7E29-9D25-41B8-AFD0-062C0CEFF05D", N_("Ceph OSD")), -DEF_GUID("4FBD7E29-9D25-41B8-AFD0-5EC00CEFF05D", N_("Ceph crypt OSD")), -DEF_GUID("89C57F98-2FE5-4DC0-89C1-F3AD0CEFF2BE", N_("Ceph disk in creation")), -DEF_GUID("89C57F98-2FE5-4DC0-89C1-5EC00CEFF2BE", N_("Ceph crypt disk in creation")), - -/* VMware */ -DEF_GUID("AA31E02A-400F-11DB-9590-000C2911D1B8", N_("VMware VMFS")), -DEF_GUID("9D275380-40AD-11DB-BF97-000C2911D1B8", N_("VMware Diagnostic")), -DEF_GUID("381CFCCC-7288-11E0-92EE-000C2911D0B2", N_("VMware Virtual SAN")), -DEF_GUID("77719A0C-A4A0-11E3-A47E-000C29745A24", N_("VMware Virsto")), -DEF_GUID("9198EFFC-31C0-11DB-8F78-000C2911D1B8", N_("VMware Reserved")), - -/* OpenBSD */ -DEF_GUID("824CC7A0-36A8-11E3-890A-952519AD3F61", N_("OpenBSD data")), - -/* QNX */ -DEF_GUID("CEF5A9AD-73BC-4601-89F3-CDEEEEE321A1", N_("QNX6 file system")), - -/* Plan 9 */ -DEF_GUID("C91818F9-8025-47AF-89D2-F030D7000C2C", N_("Plan 9 partition")), - -/* HiFive Unleased bootloaders */ -DEF_GUID("5B193300-FC78-40CD-8002-E86C45580B47", N_("HiFive Unleashed FSBL")), -DEF_GUID("2E54B353-1271-4842-806F-E436D6AF6985", N_("HiFive Unleashed BBL")), diff --git a/utils/include/pt-mbr-partnames.h b/utils/include/pt-mbr-partnames.h deleted file mode 100644 index 19a3450..0000000 --- a/utils/include/pt-mbr-partnames.h +++ /dev/null @@ -1,112 +0,0 @@ - {0x00, N_("Empty")}, - {0x01, N_("FAT12")}, - {0x02, N_("XENIX root")}, - {0x03, N_("XENIX usr")}, - {0x04, N_("FAT16 <32M")}, - {0x05, N_("Extended")}, /* DOS 3.3+ extended partition */ - {0x06, N_("FAT16")}, /* DOS 16-bit >=32M */ - {0x07, N_("HPFS/NTFS/exFAT")}, /* OS/2 IFS, eg, HPFS or NTFS or QNX or exFAT */ - {0x08, N_("AIX")}, /* AIX boot (AIX -- PS/2 port) or SplitDrive */ - {0x09, N_("AIX bootable")}, /* AIX data or Coherent */ - {0x0a, N_("OS/2 Boot Manager")},/* OS/2 Boot Manager */ - {0x0b, N_("W95 FAT32")}, - {0x0c, N_("W95 FAT32 (LBA)")},/* LBA really is `Extended Int 13h' */ - {0x0e, N_("W95 FAT16 (LBA)")}, - {0x0f, N_("W95 Ext'd (LBA)")}, - {0x10, N_("OPUS")}, - {0x11, N_("Hidden FAT12")}, - {0x12, N_("Compaq diagnostics")}, - {0x14, N_("Hidden FAT16 <32M")}, - {0x16, N_("Hidden FAT16")}, - {0x17, N_("Hidden HPFS/NTFS")}, - {0x18, N_("AST SmartSleep")}, - {0x1b, N_("Hidden W95 FAT32")}, - {0x1c, N_("Hidden W95 FAT32 (LBA)")}, - {0x1e, N_("Hidden W95 FAT16 (LBA)")}, - {0x24, N_("NEC DOS")}, - {0x27, N_("Hidden NTFS WinRE")}, - {0x39, N_("Plan 9")}, - {0x3c, N_("PartitionMagic recovery")}, - {0x40, N_("Venix 80286")}, - {0x41, N_("PPC PReP Boot")}, - {0x42, N_("SFS")}, - {0x4d, N_("QNX4.x")}, - {0x4e, N_("QNX4.x 2nd part")}, - {0x4f, N_("QNX4.x 3rd part")}, - {0x50, N_("OnTrack DM")}, - {0x51, N_("OnTrack DM6 Aux1")}, /* (or Novell) */ - {0x52, N_("CP/M")}, /* CP/M or Microport SysV/AT */ - {0x53, N_("OnTrack DM6 Aux3")}, - {0x54, N_("OnTrackDM6")}, - {0x55, N_("EZ-Drive")}, - {0x56, N_("Golden Bow")}, - {0x5c, N_("Priam Edisk")}, - {0x61, N_("SpeedStor")}, - {0x63, N_("GNU HURD or SysV")}, /* GNU HURD or Mach or Sys V/386 (such as ISC UNIX) */ - {0x64, N_("Novell Netware 286")}, - {0x65, N_("Novell Netware 386")}, - {0x70, N_("DiskSecure Multi-Boot")}, - {0x75, N_("PC/IX")}, - {0x80, N_("Old Minix")}, /* Minix 1.4a and earlier */ - {0x81, N_("Minix / old Linux")},/* Minix 1.4b and later */ - {0x82, N_("Linux swap / Solaris")}, - {0x83, N_("Linux")}, - {0x84, N_("OS/2 hidden or Intel hibernation")},/* OS/2 hidden C: drive, - hibernation type Microsoft APM - or hibernation Intel Rapid Start */ - {0x85, N_("Linux extended")}, - {0x86, N_("NTFS volume set")}, - {0x87, N_("NTFS volume set")}, - {0x88, N_("Linux plaintext")}, - {0x8e, N_("Linux LVM")}, - {0x93, N_("Amoeba")}, - {0x94, N_("Amoeba BBT")}, /* (bad block table) */ - {0x9f, N_("BSD/OS")}, /* BSDI */ - {0xa0, N_("IBM Thinkpad hibernation")}, - {0xa5, N_("FreeBSD")}, /* various BSD flavours */ - {0xa6, N_("OpenBSD")}, - {0xa7, N_("NeXTSTEP")}, - {0xa8, N_("Darwin UFS")}, - {0xa9, N_("NetBSD")}, - {0xab, N_("Darwin boot")}, - {0xaf, N_("HFS / HFS+")}, - {0xb7, N_("BSDI fs")}, - {0xb8, N_("BSDI swap")}, - {0xbb, N_("Boot Wizard hidden")}, - {0xbc, N_("Acronis FAT32 LBA")},/* hidden (+0xb0) Acronis Secure Zone (backup software) */ - {0xbe, N_("Solaris boot")}, - {0xbf, N_("Solaris")}, - {0xc1, N_("DRDOS/sec (FAT-12)")}, - {0xc4, N_("DRDOS/sec (FAT-16 < 32M)")}, - {0xc6, N_("DRDOS/sec (FAT-16)")}, - {0xc7, N_("Syrinx")}, - {0xda, N_("Non-FS data")}, - {0xdb, N_("CP/M / CTOS / ...")},/* CP/M or Concurrent CP/M or - Concurrent DOS or CTOS */ - {0xde, N_("Dell Utility")}, /* Dell PowerEdge Server utilities */ - {0xdf, N_("BootIt")}, /* BootIt EMBRM */ - {0xe1, N_("DOS access")}, /* DOS access or SpeedStor 12-bit FAT - extended partition */ - {0xe3, N_("DOS R/O")}, /* DOS R/O or SpeedStor */ - {0xe4, N_("SpeedStor")}, /* SpeedStor 16-bit FAT extended - partition < 1024 cyl. */ - - /* Linux https://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/ */ - {0xea, N_("Linux extended boot")}, - - {0xeb, N_("BeOS fs")}, - {0xee, N_("GPT")}, /* Intel EFI GUID Partition Table */ - {0xef, N_("EFI (FAT-12/16/32)")},/* Intel EFI System Partition */ - {0xf0, N_("Linux/PA-RISC boot")},/* Linux/PA-RISC boot loader */ - {0xf1, N_("SpeedStor")}, - {0xf4, N_("SpeedStor")}, /* SpeedStor large partition */ - {0xf2, N_("DOS secondary")}, /* DOS 3.3+ secondary */ - {0xfb, N_("VMware VMFS")}, - {0xfc, N_("VMware VMKCORE")}, /* VMware kernel dump partition */ - {0xfd, N_("Linux raid autodetect")},/* Linux raid partition with - autodetect using persistent - superblock */ - {0xfe, N_("LANstep")}, /* SpeedStor >1024 cyl. or LANstep */ - {0xff, N_("BBT")}, /* Xenix Bad Block Table */ - - { 0, NULL } diff --git a/utils/include/pt-mbr.h b/utils/include/pt-mbr.h deleted file mode 100644 index 1a38246..0000000 --- a/utils/include/pt-mbr.h +++ /dev/null @@ -1,187 +0,0 @@ -#ifndef UTIL_LINUX_PT_MBR_H -#define UTIL_LINUX_PT_MBR_H - -#include <assert.h> - -struct dos_partition { - unsigned char boot_ind; /* 0x80 - active */ - unsigned char bh, bs, bc; /* begin CHS */ - unsigned char sys_ind; - unsigned char eh, es, ec; /* end CHS */ - unsigned char start_sect[4]; - unsigned char nr_sects[4]; -} __attribute__((packed)); - -#define MBR_PT_OFFSET 0x1be -#define MBR_PT_BOOTBITS_SIZE 440 - -static inline struct dos_partition *mbr_get_partition(unsigned char *mbr, int i) -{ - return (struct dos_partition *) - (mbr + MBR_PT_OFFSET + (i * sizeof(struct dos_partition))); -} - -/* assemble badly aligned little endian integer */ -static inline uint32_t __dos_assemble_4le(const unsigned char *p) -{ - uint32_t last_byte = p[3]; - - return p[0] | (p[1] << 8) | (p[2] << 16) | (last_byte << 24); -} - -static inline void __dos_store_4le(unsigned char *p, unsigned int val) -{ - assert(!(p == NULL)); - p[0] = (val & 0xff); - p[1] = ((val >> 8) & 0xff); - p[2] = ((val >> 16) & 0xff); - p[3] = ((val >> 24) & 0xff); -} - -static inline unsigned int dos_partition_get_start(struct dos_partition *p) -{ - return __dos_assemble_4le(&(p->start_sect[0])); -} - -static inline void dos_partition_set_start(struct dos_partition *p, unsigned int n) -{ - __dos_store_4le(p->start_sect, n); -} - -static inline unsigned int dos_partition_get_size(struct dos_partition *p) -{ - return __dos_assemble_4le(&(p->nr_sects[0])); -} - -static inline void dos_partition_set_size(struct dos_partition *p, unsigned int n) -{ - __dos_store_4le(p->nr_sects, n); -} - -static inline int mbr_is_valid_magic(const unsigned char *mbr) -{ - return mbr[510] == 0x55 && mbr[511] == 0xaa ? 1 : 0; -} - -static inline void mbr_set_magic(unsigned char *b) -{ - b[510] = 0x55; - b[511] = 0xaa; -} - -static inline unsigned int mbr_get_id(const unsigned char *mbr) -{ - return __dos_assemble_4le(&mbr[440]); -} - -static inline void mbr_set_id(unsigned char *b, unsigned int id) -{ - __dos_store_4le(&b[440], id); -} - -enum { - MBR_EMPTY_PARTITION = 0x00, - MBR_FAT12_PARTITION = 0x01, - MBR_XENIX_ROOT_PARTITION = 0x02, - MBR_XENIX_USR_PARTITION = 0x03, - MBR_FAT16_LESS32M_PARTITION = 0x04, - MBR_DOS_EXTENDED_PARTITION = 0x05, - MBR_FAT16_PARTITION = 0x06, /* DOS 16-bit >=32M */ - MBR_HPFS_NTFS_PARTITION = 0x07, /* OS/2 IFS, eg, HPFS or NTFS or QNX */ - MBR_AIX_PARTITION = 0x08, /* AIX boot (AIX -- PS/2 port) or SplitDrive */ - MBR_AIX_BOOTABLE_PARTITION = 0x09, /* AIX data or Coherent */ - MBR_OS2_BOOTMNGR_PARTITION = 0x0a, /* OS/2 Boot Manager */ - MBR_W95_FAT32_PARTITION = 0x0b, - MBR_W95_FAT32_LBA_PARTITION = 0x0c, /* LBA really is `Extended Int 13h' */ - MBR_W95_FAT16_LBA_PARTITION = 0x0e, - MBR_W95_EXTENDED_PARTITION = 0x0f, - MBR_OPUS_PARTITION = 0x10, - MBR_HIDDEN_FAT12_PARTITION = 0x11, - MBR_COMPAQ_DIAGNOSTICS_PARTITION = 0x12, - MBR_HIDDEN_FAT16_L32M_PARTITION = 0x14, - MBR_HIDDEN_FAT16_PARTITION = 0x16, - MBR_HIDDEN_HPFS_NTFS_PARTITION = 0x17, - MBR_AST_SMARTSLEEP_PARTITION = 0x18, - MBR_HIDDEN_W95_FAT32_PARTITION = 0x1b, - MBR_HIDDEN_W95_FAT32LBA_PARTITION = 0x1c, - MBR_HIDDEN_W95_FAT16LBA_PARTITION = 0x1e, - MBR_NEC_DOS_PARTITION = 0x24, - MBR_PLAN9_PARTITION = 0x39, - MBR_PARTITIONMAGIC_PARTITION = 0x3c, - MBR_VENIX80286_PARTITION = 0x40, - MBR_PPC_PREP_BOOT_PARTITION = 0x41, - MBR_SFS_PARTITION = 0x42, - MBR_QNX_4X_PARTITION = 0x4d, - MBR_QNX_4X_2ND_PARTITION = 0x4e, - MBR_QNX_4X_3RD_PARTITION = 0x4f, - MBR_DM_PARTITION = 0x50, - MBR_DM6_AUX1_PARTITION = 0x51, /* (or Novell) */ - MBR_CPM_PARTITION = 0x52, /* CP/M or Microport SysV/AT */ - MBR_DM6_AUX3_PARTITION = 0x53, - MBR_DM6_PARTITION = 0x54, - MBR_EZ_DRIVE_PARTITION = 0x55, - MBR_GOLDEN_BOW_PARTITION = 0x56, - MBR_PRIAM_EDISK_PARTITION = 0x5c, - MBR_SPEEDSTOR_PARTITION = 0x61, - MBR_GNU_HURD_PARTITION = 0x63, /* GNU HURD or Mach or Sys V/386 (such as ISC UNIX) */ - MBR_UNIXWARE_PARTITION = MBR_GNU_HURD_PARTITION, - MBR_NETWARE_286_PARTITION = 0x64, - MBR_NETWARE_386_PARTITION = 0x65, - MBR_DISKSECURE_MULTIBOOT_PARTITION = 0x70, - MBR_PC_IX_PARTITION = 0x75, - MBR_OLD_MINIX_PARTITION = 0x80, /* Minix 1.4a and earlier */ - MBR_MINIX_PARTITION = 0x81, /* Minix 1.4b and later */ - MBR_LINUX_SWAP_PARTITION = 0x82, - MBR_SOLARIS_X86_PARTITION = MBR_LINUX_SWAP_PARTITION, - MBR_LINUX_DATA_PARTITION = 0x83, - MBR_OS2_HIDDEN_DRIVE_PARTITION = 0x84, /* also hibernation MS APM, Intel Rapid Start */ - MBR_INTEL_HIBERNATION_PARTITION = MBR_OS2_HIDDEN_DRIVE_PARTITION, - MBR_LINUX_EXTENDED_PARTITION = 0x85, - MBR_NTFS_VOL_SET1_PARTITION = 0x86, - MBR_NTFS_VOL_SET2_PARTITION = 0x87, - MBR_LINUX_PLAINTEXT_PARTITION = 0x88, - MBR_LINUX_LVM_PARTITION = 0x8e, - MBR_AMOEBA_PARTITION = 0x93, - MBR_AMOEBA_BBT_PARTITION = 0x94, /* (bad block table) */ - MBR_BSD_OS_PARTITION = 0x9f, /* BSDI */ - MBR_THINKPAD_HIBERNATION_PARTITION = 0xa0, - MBR_FREEBSD_PARTITION = 0xa5, /* various BSD flavours */ - MBR_OPENBSD_PARTITION = 0xa6, - MBR_NEXTSTEP_PARTITION = 0xa7, - MBR_DARWIN_UFS_PARTITION = 0xa8, - MBR_NETBSD_PARTITION = 0xa9, - MBR_DARWIN_BOOT_PARTITION = 0xab, - MBR_HFS_HFS_PARTITION = 0xaf, - MBR_BSDI_FS_PARTITION = 0xb7, - MBR_BSDI_SWAP_PARTITION = 0xb8, - MBR_BOOTWIZARD_HIDDEN_PARTITION = 0xbb, - MBR_ACRONIS_FAT32LBA_PARTITION = 0xbc, /* Acronis Secure Zone with ipl for loader F11.SYS */ - MBR_SOLARIS_BOOT_PARTITION = 0xbe, - MBR_SOLARIS_PARTITION = 0xbf, - MBR_DRDOS_FAT12_PARTITION = 0xc1, - MBR_DRDOS_FAT16_L32M_PARTITION = 0xc4, - MBR_DRDOS_FAT16_PARTITION = 0xc6, - MBR_SYRINX_PARTITION = 0xc7, - MBR_NONFS_DATA_PARTITION = 0xda, - MBR_CPM_CTOS_PARTITION = 0xdb, /* CP/M or Concurrent CP/M or Concurrent DOS or CTOS */ - MBR_DELL_UTILITY_PARTITION = 0xde, /* Dell PowerEdge Server utilities */ - MBR_BOOTIT_PARTITION = 0xdf, /* BootIt EMBRM */ - MBR_DOS_ACCESS_PARTITION = 0xe1, /* DOS access or SpeedStor 12-bit FAT extended partition */ - MBR_DOS_RO_PARTITION = 0xe3, /* DOS R/O or SpeedStor */ - MBR_SPEEDSTOR_EXTENDED_PARTITION = 0xe4, /* SpeedStor 16-bit FAT extended partition < 1024 cyl. */ - MBR_RUFUS_EXTRA_PARTITION = 0xea, /* Rufus extra partition for alignment */ - MBR_BEOS_FS_PARTITION = 0xeb, - MBR_GPT_PARTITION = 0xee, /* Intel EFI GUID Partition Table */ - MBR_EFI_SYSTEM_PARTITION = 0xef, /* Intel EFI System Partition */ - MBR_LINUX_PARISC_BOOT_PARTITION = 0xf0, /* Linux/PA-RISC boot loader */ - MBR_SPEEDSTOR1_PARTITION = 0xf1, - MBR_SPEEDSTOR2_PARTITION = 0xf4, /* SpeedStor large partition */ - MBR_DOS_SECONDARY_PARTITION = 0xf2, /* DOS 3.3+ secondary */ - MBR_VMWARE_VMFS_PARTITION = 0xfb, - MBR_VMWARE_VMKCORE_PARTITION = 0xfc, /* VMware kernel dump partition */ - MBR_LINUX_RAID_PARTITION = 0xfd, /* Linux raid partition with autodetect using persistent superblock */ - MBR_LANSTEP_PARTITION = 0xfe, /* SpeedStor >1024 cyl. or LANstep */ - MBR_XENIX_BBT_PARTITION = 0xff, /* Xenix Bad Block Table */ -}; - -#endif /* UTIL_LINUX_PT_MBR_H */ diff --git a/utils/include/pt-sgi.h b/utils/include/pt-sgi.h deleted file mode 100644 index 6d512ee..0000000 --- a/utils/include/pt-sgi.h +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef UTIL_LINUX_PT_SGI_H -#define UTIL_LINUX_PT_SGI_H - -#include <stdint.h> - -#define SGI_LABEL_MAGIC 0x0be5a941 - -#define SGI_MAXPARTITIONS 16 -#define SGI_MAXVOLUMES 15 - -/* partition types */ -enum { - SGI_TYPE_VOLHDR = 0x00, - SGI_TYPE_TRKREPL = 0x01, - SGI_TYPE_SECREPL = 0x02, - SGI_TYPE_SWAP = 0x03, - SGI_TYPE_BSD = 0x04, - SGI_TYPE_SYSV = 0x05, - SGI_TYPE_ENTIRE_DISK = 0x06, - SGI_TYPE_EFS = 0x07, - SGI_TYPE_LVOL = 0x08, - SGI_TYPE_RLVOL = 0x09, - SGI_TYPE_XFS = 0x0a, - SGI_TYPE_XFSLOG = 0x0b, - SGI_TYPE_XLV = 0x0c, - SGI_TYPE_XVM = 0x0d -}; - -struct sgi_device_parameter { - unsigned char skew; - unsigned char gap1; - unsigned char gap2; - unsigned char sparecyl; - - uint16_t pcylcount; - uint16_t head_vol0; - uint16_t ntrks; /* tracks in cyl 0 or vol 0 */ - - unsigned char cmd_tag_queue_depth; - unsigned char unused0; - - uint16_t unused1; - uint16_t nsect; /* sectors/tracks in cyl 0 or vol 0 */ - uint16_t bytes; - uint16_t ilfact; - uint32_t flags; /* SGI_DEVPARAM_* controller flags */ - uint32_t datarate; - uint32_t retries_on_error; - uint32_t ms_per_word; - uint16_t xylogics_gap1; - uint16_t xylogics_syncdelay; - uint16_t xylogics_readdelay; - uint16_t xylogics_gap2; - uint16_t xylogics_readgate; - uint16_t xylogics_writecont; -} __attribute__((packed)); - -enum { - SGI_DEVPARAM_SECTOR_SLIP = 0x01, - SGI_DEVPARAM_SECTOR_FWD = 0x02, - SGI_DEVPARAM_TRACK_FWD = 0x04, - SGI_DEVPARAM_TRACK_MULTIVOL = 0x08, - SGI_DEVPARAM_IGNORE_ERRORS = 0x10, - SGI_DEVPARAM_RESEEK = 0x20, - SGI_DEVPARAM_CMDTAGQ_ENABLE = 0x40 -}; - - -struct sgi_disklabel { - uint32_t magic; /* magic number */ - uint16_t root_part_num; /* # root partition */ - uint16_t swap_part_num; /* # swap partition */ - unsigned char boot_file[16]; /* name of boot file */ - - struct sgi_device_parameter devparam; /* not used now */ - - struct sgi_volume { - unsigned char name[8]; /* name of volume */ - uint32_t block_num; /* logical block number */ - uint32_t num_bytes; /* how big, in bytes */ - } __attribute__((packed)) volume[SGI_MAXVOLUMES]; - - struct sgi_partition { - uint32_t num_blocks; /* size in logical blocks */ - uint32_t first_block; /* first logical block */ - uint32_t type; /* type of this partition */ - } __attribute__((packed)) partitions[SGI_MAXPARTITIONS]; - - /* checksum is the 32bit 2's complement sum of the disklabel */ - uint32_t csum; /* disk label checksum */ - uint32_t padding; /* padding */ -} __attribute__((packed)); - -static inline uint32_t sgi_pt_checksum(struct sgi_disklabel *label) -{ - int count; - uint32_t sum = 0; - unsigned char *ptr = (unsigned char *) label; - - count = sizeof(*label) / sizeof(uint32_t); - ptr += sizeof(uint32_t) * (count - 1); - - while (count--) { - uint32_t val; - - memcpy(&val, ptr, sizeof(uint32_t)); - sum -= be32_to_cpu(val); - - ptr -= sizeof(uint32_t); - } - - return sum; -} - -#endif /* UTIL_LINUX_PT_SGI_H */ diff --git a/utils/include/pt-sun.h b/utils/include/pt-sun.h deleted file mode 100644 index 8bb5d95..0000000 --- a/utils/include/pt-sun.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef UTIL_LINUX_PT_SUN_H -#define UTIL_LINUX_PT_SUN_H - -#include <stdint.h> - -#define SUN_LABEL_MAGIC 0xDABE - -/* Supported VTOC setting */ -#define SUN_VTOC_SANITY 0x600DDEEE /* magic number */ -#define SUN_VTOC_VERSION 1 -#define SUN_MAXPARTITIONS 8 - -struct sun_disklabel { - unsigned char label_id[128]; /* Informative text string */ - - struct sun_vtoc { - uint32_t version; /* version */ - char volume_id[8];/* volume name */ - uint16_t nparts; /* num of partitions */ - - struct sun_info { /* partition information */ - uint16_t id; /* SUN_TAG_* */ - uint16_t flags; /* SUN_FLAG_* */ - } __attribute__ ((packed)) infos[8]; - - uint16_t padding; /* padding */ - uint32_t bootinfo[3]; /* info needed by mboot */ - uint32_t sanity; /* magic number */ - uint32_t reserved[10]; /* padding */ - uint32_t timestamp[8]; /* partition timestamp */ - } __attribute__ ((packed)) vtoc; - - uint32_t write_reinstruct; /* sectors to skip, writes */ - uint32_t read_reinstruct; /* sectors to skip, reads */ - unsigned char spare[148]; /* padding */ - uint16_t rpm; /* disk rotational speed */ - uint16_t pcyl; /* physical cylinder count */ - uint16_t apc; /* extra sects per cylinder */ - uint16_t obs1; - uint16_t obs2; - uint16_t intrlv; /* interleave factor */ - uint16_t ncyl; /* data cylinder count */ - uint16_t acyl; /* alt. cylinder count */ - uint16_t nhead; /* tracks per cylinder <---- */ - uint16_t nsect; /* sectors per track <---- */ - uint16_t obs3; - uint16_t obs4; - - struct sun_partition { /* partitions */ - uint32_t start_cylinder; - uint32_t num_sectors; - } __attribute__ ((packed)) partitions[8]; - - uint16_t magic; /* magic number */ - uint16_t csum; /* label xor'd checksum */ -} __attribute__ ((packed)); - - -#define SUN_TAG_UNASSIGNED 0x00 /* Unassigned partition */ -#define SUN_TAG_BOOT 0x01 /* Boot partition */ -#define SUN_TAG_ROOT 0x02 /* Root filesystem */ -#define SUN_TAG_SWAP 0x03 /* Swap partition */ -#define SUN_TAG_USR 0x04 /* /usr filesystem */ -#define SUN_TAG_WHOLEDISK 0x05 /* Full-disk slice */ -#define SUN_TAG_STAND 0x06 /* Stand partition */ -#define SUN_TAG_VAR 0x07 /* /var filesystem */ -#define SUN_TAG_HOME 0x08 /* /home filesystem */ -#define SUN_TAG_ALTSCTR 0x09 /* Alt sector partition */ -#define SUN_TAG_CACHE 0x0a /* Cachefs partition */ -#define SUN_TAG_RESERVED 0x0b /* SMI reserved data */ -#define SUN_TAG_LINUX_SWAP 0x82 /* Linux SWAP */ -#define SUN_TAG_LINUX_NATIVE 0x83 /* Linux filesystem */ -#define SUN_TAG_LINUX_LVM 0x8e /* Linux LVM */ -#define SUN_TAG_LINUX_RAID 0xfd /* LInux RAID */ - -#define SUN_FLAG_UNMNT 0x01 /* Unmountable partition*/ -#define SUN_FLAG_RONLY 0x10 /* Read only */ - -static inline uint16_t sun_pt_checksum(const struct sun_disklabel *label) -{ - const uint16_t *ptr = ((const uint16_t *) (label + 1)) - 1; - uint16_t sum; - - for (sum = 0; ptr >= ((const uint16_t *) label);) - sum ^= *ptr--; - - return sum; -} - -#endif /* UTIL_LINUX_PT_SUN_H */ diff --git a/utils/include/pty-session.h b/utils/include/pty-session.h deleted file mode 100644 index 0c9ccc6..0000000 --- a/utils/include/pty-session.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * This code is in the public domain; do with it what you wish. - * - * Written by Karel Zak <kzak@redhat.com> in Jul 2019 - */ -#ifndef UTIL_LINUX_PTY_SESSION_H -#define UTIL_LINUX_PTY_SESSION_H - -#include <pty.h> -#include <termios.h> -#include <signal.h> -#include <sys/time.h> - -#include <sys/signalfd.h> - -/* - * Callbacks -- the first argument is always callback data, see - * ul_pty_set_callback_data(). - */ -struct ul_pty_callbacks { - /* - * Optional. Executed on SIGCHLD when ssi_code is EXITED, KILLED or - * DUMPED; The callback has to call ul_pty_set_child(pty, (pid_t) -1) - * if child is no more alive. - */ - void (*child_wait)(void *, pid_t); - - /* - * Used when child_wait() undefined to informa about child status - */ - void (*child_die)(void *, pid_t, int); - - /* - * Executed on SIGCHLD when ssi_status is SIGSTOP - */ - void (*child_sigstop)(void *, pid_t); - - /* - * Executed in master loop before ul_pty enter poll() and in time set by - * ul_pty_set_mainloop_time(). The callback is no used when time is not set. - */ - int (*mainloop)(void *); - - /* - * Executed on master or stdin activity, arguments: - * 2nd - file descriptor - * 3rd - buffer with data - * 4th - size of the data - */ - int (*log_stream_activity)(void *, int, char *, size_t); - - /* - * Executed on signal, arguments: - * 2nd - signal info - * 3rd - NULL or signal specific data (e.g. struct winsize on SIGWINCH - */ - int (*log_signal)(void *, struct signalfd_siginfo *, void *); - - /* - * Executed on SIGUSR1 - */ - int (*flush_logs)(void *); -}; - -struct ul_pty { - struct termios stdin_attrs; /* stdin and slave terminal runtime attributes */ - int master; /* parent side */ - int slave; /* child side */ - int sigfd; /* signalfd() */ - int poll_timeout; - struct winsize win; /* terminal window size */ - sigset_t orgsig; /* original signal mask */ - - int delivered_signal; - - struct ul_pty_callbacks callbacks; - void *callback_data; - - pid_t child; - - struct timeval next_callback_time; - - unsigned int isterm:1, /* is stdin terminal? */ - slave_echo:1; /* keep ECHO on pty slave */ -}; - -void ul_pty_init_debug(int mask); -struct ul_pty *ul_new_pty(int is_stdin_tty); -void ul_free_pty(struct ul_pty *pty); - -void ul_pty_slave_echo(struct ul_pty *pty, int enable); -int ul_pty_get_delivered_signal(struct ul_pty *pty); - -void ul_pty_set_callback_data(struct ul_pty *pty, void *data); -void ul_pty_set_child(struct ul_pty *pty, pid_t child); - -struct ul_pty_callbacks *ul_pty_get_callbacks(struct ul_pty *pty); -int ul_pty_is_running(struct ul_pty *pty); -int ul_pty_setup(struct ul_pty *pty); -void ul_pty_cleanup(struct ul_pty *pty); -void ul_pty_init_slave(struct ul_pty *pty); -int ul_pty_proxy_master(struct ul_pty *pty); - -void ul_pty_set_mainloop_time(struct ul_pty *pty, struct timeval *tv); -int ul_pty_get_childfd(struct ul_pty *pty); -void ul_pty_wait_for_child(struct ul_pty *pty); -pid_t ul_pty_get_child(struct ul_pty *pty); -void ul_pty_write_eof_to_child(struct ul_pty *pty); - -#endif /* UTIL_LINUX_PTY_H */ diff --git a/utils/include/pwdutils.h b/utils/include/pwdutils.h deleted file mode 100644 index b58268d..0000000 --- a/utils/include/pwdutils.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef UTIL_LINUX_PWDUTILS_H -#define UTIL_LINUX_PWDUTILS_H - -#include <sys/types.h> -#include <pwd.h> -#include <grp.h> - -extern struct passwd *xgetpwnam(const char *username, char **pwdbuf); -extern struct group *xgetgrnam(const char *groupname, char **grpbuf); -extern struct passwd *xgetpwuid(uid_t uid, char **pwdbuf); -extern char *xgetlogin(void); - -#endif /* UTIL_LINUX_PWDUTILS_H */ - diff --git a/utils/include/randutils.h b/utils/include/randutils.h deleted file mode 100644 index 86e35f3..0000000 --- a/utils/include/randutils.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef UTIL_LINUX_RANDUTILS -#define UTIL_LINUX_RANDUTILS - -#ifdef HAVE_SRANDOM -#define srand(x) srandom(x) -#define rand() random() -#endif - -/* rand() based */ -extern int rand_get_number(int low_n, int high_n); - -/* /dev/urandom based with fallback to rand() */ -extern int random_get_fd(void); -extern void random_get_bytes(void *buf, size_t nbytes); -extern const char *random_tell_source(void); - -#endif diff --git a/utils/include/rpmatch.h b/utils/include/rpmatch.h deleted file mode 100644 index f64d52e..0000000 --- a/utils/include/rpmatch.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef UTIL_LINUX_RPMATCH_H -#define UTIL_LINUX_RPMATCH_H - -#ifndef HAVE_RPMATCH -#define rpmatch(r) \ - (*r == 'y' || *r == 'Y' ? 1 : *r == 'n' || *r == 'N' ? 0 : -1) -#endif - -#define RPMATCH_YES 1 -#define RPMATCH_NO 0 -#define RPMATCH_INVALID -1 - -#endif /* UTIL_LINUX_RPMATCH_H */ diff --git a/utils/include/setproctitle.h b/utils/include/setproctitle.h deleted file mode 100644 index 70a9efa..0000000 --- a/utils/include/setproctitle.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef UTIL_LINUX_SETPROCTITLE_H -#define UTIL_LINUX_SETPROCTITLE_H - -extern void initproctitle (int argc, char **argv); -extern void setproctitle (const char *prog, const char *txt); - -#endif diff --git a/utils/include/sha1.h b/utils/include/sha1.h deleted file mode 100644 index 62af1da..0000000 --- a/utils/include/sha1.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef UTIL_LINUX_SHA1_H -#define UTIL_LINUX_SHA1_H - -/* - SHA-1 in C - By Steve Reid <steve@edmweb.com> - 100% Public Domain - */ - -#include "stdint.h" - -#define UL_SHA1LENGTH 20 - -typedef struct -{ - uint32_t state[5]; - uint32_t count[2]; - unsigned char buffer[64]; -} UL_SHA1_CTX; - -void ul_SHA1Transform(uint32_t state[5], const unsigned char buffer[64]); -void ul_SHA1Init(UL_SHA1_CTX *context); -void ul_SHA1Update(UL_SHA1_CTX *context, const unsigned char *data, uint32_t len); -void ul_SHA1Final(unsigned char digest[UL_SHA1LENGTH], UL_SHA1_CTX *context); -void ul_SHA1(char *hash_out, const char *str, unsigned len); - -#endif /* UTIL_LINUX_SHA1_H */ diff --git a/utils/include/signames.h b/utils/include/signames.h deleted file mode 100644 index a4fd1bc..0000000 --- a/utils/include/signames.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef SIGNAMES_H -#define SIGNAMES_H - -int signame_to_signum(const char *sig); -const char *signum_to_signame(int signum); -int get_signame_by_idx(size_t idx, const char **signame, int *signum); - -#endif /* SIGNAMES_H */ diff --git a/utils/include/statfs_magic.h b/utils/include/statfs_magic.h deleted file mode 100644 index b6b0225..0000000 --- a/utils/include/statfs_magic.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef UTIL_LINUX_STATFS_MAGIC_H -#define UTIL_LINUX_STATFS_MAGIC_H - -#include <sys/statfs.h> - -/* - * If possible then don't depend on internal libc __SWORD_TYPE type. - */ -#ifdef __GNUC__ -#define F_TYPE_EQUAL(a, b) (a == (__typeof__(a)) b) -#else -#define F_TYPE_EQUAL(a, b) (a == (__SWORD_TYPE) b) -#endif - -/* - * Unfortunately, Linux kernel header file <linux/magic.h> is incomplete - * mess and kernel returns by statfs f_type many numbers that are nowhere - * specified (in API). - * - * This is collection of the magic numbers. - */ -#define STATFS_ADFS_MAGIC 0xadf5 -#define STATFS_AFFS_MAGIC 0xadff -#define STATFS_AFS_MAGIC 0x5346414F -#define STATFS_AUTOFS_MAGIC 0x0187 -#define STATFS_BDEVFS_MAGIC 0x62646576 -#define STATFS_BEFS_MAGIC 0x42465331 -#define STATFS_BFS_MAGIC 0x1BADFACE -#define STATFS_BINFMTFS_MAGIC 0x42494e4d -#define STATFS_BTRFS_MAGIC 0x9123683E -#define STATFS_CEPH_MAGIC 0x00c36400 -#define STATFS_CGROUP_MAGIC 0x27e0eb -#define STATFS_CGROUP2_MAGIC 0x63677270 -#define STATFS_CIFS_MAGIC 0xff534d42 -#define STATFS_CODA_MAGIC 0x73757245 -#define STATFS_CONFIGFS_MAGIC 0x62656570 -#define STATFS_CRAMFS_MAGIC 0x28cd3d45 -#define STATFS_DEBUGFS_MAGIC 0x64626720 -#define STATFS_DEVPTS_MAGIC 0x1cd1 -#define STATFS_ECRYPTFS_MAGIC 0xf15f -#define STATFS_EFIVARFS_MAGIC 0xde5e81e4 -#define STATFS_EFS_MAGIC 0x414A53 -#define STATFS_EXOFS_MAGIC 0x5DF5 -#define STATFS_EXT2_MAGIC 0xEF53 -#define STATFS_EXT3_MAGIC 0xEF53 -#define STATFS_EXT4_MAGIC 0xEF53 -#define STATFS_F2FS_MAGIC 0xF2F52010 -#define STATFS_FUSE_MAGIC 0x65735546 -#define STATFS_FUTEXFS_MAGIC 0xBAD1DEA -#define STATFS_GFS2_MAGIC 0x01161970 -#define STATFS_HFSPLUS_MAGIC 0x482b -#define STATFS_HOSTFS_MAGIC 0x00c0ffee -#define STATFS_HPFS_MAGIC 0xf995e849 -#define STATFS_HPPFS_MAGIC 0xb00000ee -#define STATFS_HUGETLBFS_MAGIC 0x958458f6 -#define STATFS_ISOFS_MAGIC 0x9660 -#define STATFS_JFFS2_MAGIC 0x72b6 -#define STATFS_JFS_MAGIC 0x3153464a -#define STATFS_LOGFS_MAGIC 0xc97e8168 -#define STATFS_MINIX2_MAGIC 0x2468 -#define STATFS_MINIX2_MAGIC2 0x2478 -#define STATFS_MINIX3_MAGIC 0x4d5a -#define STATFS_MINIX_MAGIC 0x137F -#define STATFS_MINIX_MAGIC2 0x138F -#define STATFS_MQUEUE_MAGIC 0x19800202 -#define STATFS_MSDOS_MAGIC 0x4d44 -#define STATFS_NCP_MAGIC 0x564c -#define STATFS_NFS_MAGIC 0x6969 -#define STATFS_NILFS_MAGIC 0x3434 -#define STATFS_NTFS_MAGIC 0x5346544e -#define STATFS_OCFS2_MAGIC 0x7461636f -#define STATFS_OMFS_MAGIC 0xC2993D87 -#define STATFS_OPENPROMFS_MAGIC 0x9fa1 -#define STATFS_PIPEFS_MAGIC 0x50495045 -#define STATFS_PROC_MAGIC 0x9fa0 -#define STATFS_PSTOREFS_MAGIC 0x6165676C -#define STATFS_QNX4_MAGIC 0x002f -#define STATFS_QNX6_MAGIC 0x68191122 -#define STATFS_RAMFS_MAGIC 0x858458f6 -#define STATFS_REISERFS_MAGIC 0x52654973 -#define STATFS_ROMFS_MAGIC 0x7275 -#define STATFS_SECURITYFS_MAGIC 0x73636673 -#define STATFS_SELINUXFS_MAGIC 0xf97cff8c -#define STATFS_SMACKFS_MAGIC 0x43415d53 -#define STATFS_SMB_MAGIC 0x517B -#define STATFS_SOCKFS_MAGIC 0x534F434B -#define STATFS_SQUASHFS_MAGIC 0x73717368 -#define STATFS_SYSFS_MAGIC 0x62656572 -#define STATFS_TMPFS_MAGIC 0x01021994 -#define STATFS_UBIFS_MAGIC 0x24051905 -#define STATFS_UDF_MAGIC 0x15013346 -#define STATFS_UFS2_MAGIC 0x19540119 -#define STATFS_UFS_MAGIC 0x00011954 -#define STATFS_V9FS_MAGIC 0x01021997 -#define STATFS_VXFS_MAGIC 0xa501FCF5 -#define STATFS_XENFS_MAGIC 0xabba1974 -#define STATFS_XFS_MAGIC 0x58465342 - -#endif /* UTIL_LINUX_STATFS_MAGIC_H */ - diff --git a/utils/include/strutils.h b/utils/include/strutils.h deleted file mode 100644 index 4b3182f..0000000 --- a/utils/include/strutils.h +++ /dev/null @@ -1,333 +0,0 @@ -#ifndef UTIL_LINUX_STRUTILS -#define UTIL_LINUX_STRUTILS - -#include <stdlib.h> -#include <inttypes.h> -#include <string.h> -#include <sys/types.h> -#include <ctype.h> -#include <stdio.h> -#include <errno.h> - -/* initialize a custom exit code for all *_or_err functions */ -extern void strutils_set_exitcode(int exit_code); - -extern int parse_size(const char *str, uintmax_t *res, int *power); -extern int strtosize(const char *str, uintmax_t *res); -extern uintmax_t strtosize_or_err(const char *str, const char *errmesg); - -extern int16_t strtos16_or_err(const char *str, const char *errmesg); -extern uint16_t strtou16_or_err(const char *str, const char *errmesg); -extern uint16_t strtox16_or_err(const char *str, const char *errmesg); - -extern int32_t strtos32_or_err(const char *str, const char *errmesg); -extern uint32_t strtou32_or_err(const char *str, const char *errmesg); -extern uint32_t strtox32_or_err(const char *str, const char *errmesg); - -extern int64_t strtos64_or_err(const char *str, const char *errmesg); -extern uint64_t strtou64_or_err(const char *str, const char *errmesg); -extern uint64_t strtox64_or_err(const char *str, const char *errmesg); - -extern double strtod_or_err(const char *str, const char *errmesg); - -extern long strtol_or_err(const char *str, const char *errmesg); -extern unsigned long strtoul_or_err(const char *str, const char *errmesg); - -extern void strtotimeval_or_err(const char *str, struct timeval *tv, - const char *errmesg); - -extern int isdigit_strend(const char *str, const char **end); -#define isdigit_string(_s) isdigit_strend(_s, NULL) - -extern int isxdigit_strend(const char *str, const char **end); -#define isxdigit_string(_s) isxdigit_strend(_s, NULL) - - -extern int parse_switch(const char *arg, const char *errmesg, ...); - -#ifndef HAVE_MEMPCPY -extern void *mempcpy(void *restrict dest, const void *restrict src, size_t n); -#endif -#ifndef HAVE_STRNLEN -extern size_t strnlen(const char *s, size_t maxlen); -#endif -#ifndef HAVE_STRNDUP -extern char *strndup(const char *s, size_t n); -#endif -#ifndef HAVE_STRNCHR -extern char *strnchr(const char *s, size_t maxlen, int c); -#endif - -/* caller guarantees n > 0 */ -static inline void xstrncpy(char *dest, const char *src, size_t n) -{ - strncpy(dest, src, n-1); - dest[n-1] = 0; -} - -/* This is like strncpy(), but based on memcpy(), so compilers and static - * analyzers do not complain when sizeof(destination) is the same as 'n' and - * result is not terminated by zero. - * - * Use this function to copy string to logs with fixed sizes (wtmp/utmp. ...) - * where string terminator is optional. - */ -static inline void *str2memcpy(void *dest, const char *src, size_t n) -{ - size_t bytes = strlen(src) + 1; - - if (bytes > n) - bytes = n; - - memcpy(dest, src, bytes); - return dest; -} - -static inline char *mem2strcpy(char *dest, const void *src, size_t n, size_t nmax) -{ - if (n + 1 > nmax) - n = nmax - 1; - - memcpy(dest, src, n); - dest[nmax-1] = '\0'; - return dest; -} - -/* Reallocate @str according to @newstr and copy @newstr to @str; returns new @str. - * The @str is not modified if reallocation failed (like classic realloc()). - */ -static inline char * __attribute__((warn_unused_result)) -strrealloc(char *str, const char *newstr) -{ - size_t nsz, osz; - - if (!str) - return newstr ? strdup(newstr) : NULL; - if (!newstr) - return NULL; - - osz = strlen(str); - nsz = strlen(newstr); - - if (nsz > osz) - str = realloc(str, nsz + 1); - if (str) - memcpy(str, newstr, nsz + 1); - return str; -} - -/* Copy string @str to struct @stru to member addressed by @offset */ -static inline int strdup_to_offset(void *stru, size_t offset, const char *str) -{ - char **o; - char *p = NULL; - - if (!stru) - return -EINVAL; - - o = (char **) ((char *) stru + offset); - if (str) { - p = strdup(str); - if (!p) - return -ENOMEM; - } - - free(*o); - *o = p; - return 0; -} - -/* Copy string __str to struct member _m of the struct _s */ -#define strdup_to_struct_member(_s, _m, _str) \ - strdup_to_offset((void *) _s, offsetof(__typeof__(*(_s)), _m), _str) - -/* Copy string addressed by @offset between two structs */ -static inline int strdup_between_offsets(void *stru_dst, void *stru_src, size_t offset) -{ - char **src; - char **dst; - char *p = NULL; - - if (!stru_src || !stru_dst) - return -EINVAL; - - src = (char **) ((char *) stru_src + offset); - dst = (char **) ((char *) stru_dst + offset); - - if (*src) { - p = strdup(*src); - if (!p) - return -ENOMEM; - } - - free(*dst); - *dst = p; - return 0; -} - -/* Copy string addressed by struct member between two instances of the same - * struct type */ -#define strdup_between_structs(_dst, _src, _m) \ - strdup_between_offsets((void *)_dst, (void *)_src, offsetof(__typeof__(*(_src)), _m)) - - -extern char *xstrmode(mode_t mode, char *str); - -/* Options for size_to_human_string() */ -enum -{ - SIZE_SUFFIX_1LETTER = 0, - SIZE_SUFFIX_3LETTER = (1 << 0), - SIZE_SUFFIX_SPACE = (1 << 1), - SIZE_DECIMAL_2DIGITS = (1 << 2) -}; - -extern char *size_to_human_string(int options, uint64_t bytes); - -extern int string_to_idarray(const char *list, int ary[], size_t arysz, - int (name2id)(const char *, size_t)); -extern int string_add_to_idarray(const char *list, int ary[], - size_t arysz, size_t *ary_pos, - int (name2id)(const char *, size_t)); - -extern int string_to_bitarray(const char *list, char *ary, - int (*name2bit)(const char *, size_t)); - -extern int string_to_bitmask(const char *list, - unsigned long *mask, - long (*name2flag)(const char *, size_t)); -extern int parse_range(const char *str, int *lower, int *upper, int def); - -extern int streq_paths(const char *a, const char *b); - -/* - * Match string beginning. - */ -static inline const char *startswith(const char *s, const char *prefix) -{ - size_t sz = prefix ? strlen(prefix) : 0; - - if (s && sz && strncmp(s, prefix, sz) == 0) - return s + sz; - return NULL; -} - -/* - * Case insensitive match string beginning. - */ -static inline const char *startswith_no_case(const char *s, const char *prefix) -{ - size_t sz = prefix ? strlen(prefix) : 0; - - if (s && sz && strncasecmp(s, prefix, sz) == 0) - return s + sz; - return NULL; -} - -/* - * Match string ending. - */ -static inline const char *endswith(const char *s, const char *postfix) -{ - size_t sl = s ? strlen(s) : 0; - size_t pl = postfix ? strlen(postfix) : 0; - - if (pl == 0) - return s + sl; - if (sl < pl) - return NULL; - if (memcmp(s + sl - pl, postfix, pl) != 0) - return NULL; - return s + sl - pl; -} - -/* - * Skip leading white space. - */ -static inline const char *skip_space(const char *p) -{ - while (isspace(*p)) - ++p; - return p; -} - -static inline const char *skip_blank(const char *p) -{ - while (isblank(*p)) - ++p; - return p; -} - - -/* Removes whitespace from the right-hand side of a string (trailing - * whitespace). - * - * Returns size of the new string (without \0). - */ -static inline size_t rtrim_whitespace(unsigned char *str) -{ - size_t i; - - if (!str) - return 0; - i = strlen((char *) str); - while (i) { - i--; - if (!isspace(str[i])) { - i++; - break; - } - } - str[i] = '\0'; - return i; -} - -/* Removes whitespace from the left-hand side of a string. - * - * Returns size of the new string (without \0). - */ -static inline size_t ltrim_whitespace(unsigned char *str) -{ - size_t len; - unsigned char *p; - - if (!str) - return 0; - for (p = str; *p && isspace(*p); p++); - - len = strlen((char *) p); - - if (p > str) - memmove(str, p, len + 1); - - return len; -} - -static inline void strrep(char *s, int find, int replace) -{ - while (s && *s && (s = strchr(s, find)) != NULL) - *s++ = replace; -} - -static inline void strrem(char *s, int rem) -{ - char *p; - - if (!s) - return; - for (p = s; *s; s++) { - if (*s != rem) - *p++ = *s; - } - *p = '\0'; -} - -extern char *strnappend(const char *s, const char *suffix, size_t b); -extern char *strappend(const char *s, const char *suffix); -extern char *strfappend(const char *s, const char *format, ...) - __attribute__ ((__format__ (__printf__, 2, 0))); -extern const char *split(const char **state, size_t *l, const char *separator, int quoted); - -extern int skip_fline(FILE *fp); - -#endif diff --git a/utils/include/strv.h b/utils/include/strv.h deleted file mode 100644 index 260ad12..0000000 --- a/utils/include/strv.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef UTIL_LINUX_STRV -#define UTIL_LINUX_STRV - -#include <stdarg.h> - -#include "c.h" - -char **strv_free(char **l); -void strv_clear(char **l); -char **strv_copy(char * const *l); -unsigned strv_length(char * const *l); - -int strv_extend_strv(char ***a, char **b); -int strv_extend_strv_concat(char ***a, char **b, const char *suffix); -int strv_extend(char ***l, const char *value); -int strv_extendv(char ***l, const char *format, va_list ap); -int strv_extendf(char ***l, const char *format, ...) - __attribute__ ((__format__ (__printf__, 2, 0))); -int strv_push(char ***l, char *value); -int strv_push_prepend(char ***l, char *value); -int strv_consume(char ***l, char *value); -int strv_consume_prepend(char ***l, char *value); - -char **strv_remove(char **l, const char *s); - -char **strv_new(const char *x, ...); -char **strv_new_ap(const char *x, va_list ap); - -static inline const char* STRV_IFNOTNULL(const char *x) { - return x ? x : (const char *) -1; -} - -static inline int strv_isempty(char * const *l) { - return !l || !*l; -} - -char **strv_split(const char *s, const char *separator); -char *strv_join(char **l, const char *separator); - -#define STRV_FOREACH(s, l) \ - for ((s) = (l); (s) && *(s); (s)++) - -#define STRV_FOREACH_BACKWARDS(s, l) \ - STRV_FOREACH(s, l) \ - ; \ - for ((s)--; (l) && ((s) >= (l)); (s)--) - - -#define STRV_MAKE_EMPTY ((char*[1]) { NULL }) - -char **strv_reverse(char **l); - -#endif /* UTIL_LINUX_STRV */ - - diff --git a/utils/include/swapheader.h b/utils/include/swapheader.h deleted file mode 100644 index 3fce0d0..0000000 --- a/utils/include/swapheader.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _SWAPHEADER_H -#define _SWAPHEADER_H - -#define SWAP_VERSION 1 -#define SWAP_UUID_LENGTH 16 -#define SWAP_LABEL_LENGTH 16 -#define SWAP_SIGNATURE "SWAPSPACE2" -#define SWAP_SIGNATURE_SZ (sizeof(SWAP_SIGNATURE) - 1) - -#include <stdint.h> - -struct swap_header_v1_2 { - char bootbits[1024]; /* Space for disklabel etc. */ - uint32_t version; - uint32_t last_page; - uint32_t nr_badpages; - unsigned char uuid[SWAP_UUID_LENGTH]; - char volume_name[SWAP_LABEL_LENGTH]; - uint32_t padding[117]; - uint32_t badpages[1]; -}; - -#endif /* _SWAPHEADER_H */ diff --git a/utils/include/swapprober.h b/utils/include/swapprober.h deleted file mode 100644 index 5107700..0000000 --- a/utils/include/swapprober.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef UTIL_LINUX_SWAP_PROBER_H -#define UTIL_LINUX_SWAP_PROBER_H - -#include <blkid.h> - -blkid_probe get_swap_prober(const char *devname); - -#endif /* UTIL_LINUX_SWAP_PROBER_H */ - diff --git a/utils/include/sysfs.h b/utils/include/sysfs.h deleted file mode 100644 index dcd2a14..0000000 --- a/utils/include/sysfs.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2011 Karel Zak <kzak@redhat.com> - */ -#ifndef UTIL_LINUX_SYSFS_H -#define UTIL_LINUX_SYSFS_H - - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <stdint.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <string.h> -#include <inttypes.h> -#include <dirent.h> - -#include "path.h" - -/** - * sysfs_devname_sys_to_dev: - * @name: devname to be converted in place - * - * Linux kernel linux/drivers/base/core.c: device_get_devnode() - * defines a replacement of '!' in the /sys device name by '/' in the - * /dev device name. This helper replaces all occurrences of '!' in - * @name by '/' to convert from /sys to /dev. - */ -static inline void sysfs_devname_sys_to_dev(char *name) -{ - char *c; - - if (name) - while ((c = strchr(name, '!'))) - c[0] = '/'; -} - -/** - * sysfs_devname_dev_to_sys: - * @name: devname to be converted in place - * - * See sysfs_devname_sys_to_dev(). - */ -static inline void sysfs_devname_dev_to_sys(char *name) -{ - char *c; - - if (name) - while ((c = strchr(name, '/'))) - c[0] = '!'; -} - -struct sysfs_blkdev { - dev_t devno; - struct path_cxt *parent; - - unsigned int scsi_host, - scsi_channel, - scsi_target, - scsi_lun; - - unsigned int has_hctl : 1, - hctl_error : 1 ; -}; - -void ul_sysfs_init_debug(void); - -struct path_cxt *ul_new_sysfs_path(dev_t devno, struct path_cxt *parent, const char *prefix); -int sysfs_blkdev_init_path(struct path_cxt *pc, dev_t devno, struct path_cxt *parent); - -int sysfs_blkdev_set_parent(struct path_cxt *pc, struct path_cxt *parent); -struct path_cxt *sysfs_blkdev_get_parent(struct path_cxt *pc); - -char *sysfs_blkdev_get_name(struct path_cxt *pc, char *buf, size_t bufsiz); -int sysfs_blkdev_is_partition_dirent(DIR *dir, struct dirent *d, const char *parent_name); -int sysfs_blkdev_count_partitions(struct path_cxt *pc, const char *devname); -dev_t sysfs_blkdev_partno_to_devno(struct path_cxt *pc, int partno); -char *sysfs_blkdev_get_slave(struct path_cxt *pc); -char *sysfs_blkdev_get_path(struct path_cxt *pc, char *buf, size_t bufsiz); -dev_t sysfs_blkdev_get_devno(struct path_cxt *pc); - -char *sysfs_blkdev_get_devchain(struct path_cxt *pc, char *buf, size_t bufsz); -int sysfs_blkdev_next_subsystem(struct path_cxt *pc __attribute__((unused)), char *devchain, char **subsys); - -int sysfs_blkdev_is_hotpluggable(struct path_cxt *pc); -int sysfs_blkdev_get_wholedisk( struct path_cxt *pc, - char *diskname, - size_t len, - dev_t *diskdevno); - -int sysfs_devno_to_wholedisk(dev_t dev, char *diskname, - size_t len, dev_t *diskdevno); -int sysfs_devno_is_dm_private(dev_t devno, char **uuid); -int sysfs_devno_is_wholedisk(dev_t devno); - -dev_t sysfs_devname_to_devno(const char *name); -dev_t __sysfs_devname_to_devno(const char *prefix, const char *name, const char *parent); -int sysfs_devname_is_hidden(const char *prefix, const char *name); - -char *sysfs_devno_to_devpath(dev_t devno, char *buf, size_t bufsiz); -char *sysfs_devno_to_devname(dev_t devno, char *buf, size_t bufsiz); -int sysfs_devno_count_partitions(dev_t devno); - -int sysfs_blkdev_scsi_get_hctl(struct path_cxt *pc, int *h, int *c, int *t, int *l); -char *sysfs_blkdev_scsi_host_strdup_attribute(struct path_cxt *pc, - const char *type, const char *attr); -int sysfs_blkdev_scsi_host_is(struct path_cxt *pc, const char *type); -int sysfs_blkdev_scsi_has_attribute(struct path_cxt *pc, const char *attr); -int sysfs_blkdev_scsi_path_contains(struct path_cxt *pc, const char *pattern); - - -#endif /* UTIL_LINUX_SYSFS_H */ diff --git a/utils/include/timer.h b/utils/include/timer.h deleted file mode 100644 index 70da1ba..0000000 --- a/utils/include/timer.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef UTIL_LINUX_TIMER_H -#define UTIL_LINUX_TIMER_H - -#include <signal.h> -#include <sys/time.h> - -#ifdef HAVE_TIMER_CREATE -struct ul_timer { - timer_t t_id; -}; -#else -struct ul_timer { - struct itimerval old_timer; - struct sigaction old_sa; -}; -#endif - -extern int setup_timer(struct ul_timer *timer, struct itimerval *timeout, - void (*timeout_handler)(int, siginfo_t *, void *)); -extern void cancel_timer(struct ul_timer *timer); - -#endif /* UTIL_LINUX_TIMER_H */ diff --git a/utils/include/timeutils.h b/utils/include/timeutils.h deleted file mode 100644 index e452e55..0000000 --- a/utils/include/timeutils.h +++ /dev/null @@ -1,92 +0,0 @@ -/*** - First set of functions in this file are part of systemd, and were - copied to util-linux at August 2013. - - Copyright 2010 Lennart Poettering - Copyright (C) 2014 Karel Zak <kzak@redhat.com> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ -#ifndef UTIL_LINUX_TIME_UTIL_H -#define UTIL_LINUX_TIME_UTIL_H - -#include <stdio.h> -#include <inttypes.h> -#include <sys/time.h> - -typedef uint64_t usec_t; -typedef uint64_t nsec_t; - -#define MSEC_PER_SEC 1000ULL -#define USEC_PER_SEC 1000000ULL -#define USEC_PER_MSEC 1000ULL -#define NSEC_PER_SEC 1000000000ULL -#define NSEC_PER_MSEC 1000000ULL -#define NSEC_PER_USEC 1000ULL - -#define USEC_PER_MINUTE (60ULL*USEC_PER_SEC) -#define NSEC_PER_MINUTE (60ULL*NSEC_PER_SEC) -#define USEC_PER_HOUR (60ULL*USEC_PER_MINUTE) -#define NSEC_PER_HOUR (60ULL*NSEC_PER_MINUTE) -#define USEC_PER_DAY (24ULL*USEC_PER_HOUR) -#define NSEC_PER_DAY (24ULL*NSEC_PER_HOUR) -#define USEC_PER_WEEK (7ULL*USEC_PER_DAY) -#define NSEC_PER_WEEK (7ULL*NSEC_PER_DAY) -#define USEC_PER_MONTH (2629800ULL*USEC_PER_SEC) -#define NSEC_PER_MONTH (2629800ULL*NSEC_PER_SEC) -#define USEC_PER_YEAR (31557600ULL*USEC_PER_SEC) -#define NSEC_PER_YEAR (31557600ULL*NSEC_PER_SEC) - -#define FORMAT_TIMESTAMP_MAX ((4*4+1)+11+9+4+1) /* weekdays can be unicode */ -#define FORMAT_TIMESTAMP_RELATIVE_MAX 256 -#define FORMAT_TIMESPAN_MAX 64 - -int parse_timestamp(const char *t, usec_t *usec); -int get_gmtoff(const struct tm *tp); - -/* flags and masks for strxxx_iso() functions */ -enum { - ISO_DATE = (1 << 0), - ISO_TIME = (1 << 1), - ISO_TIMEZONE = (1 << 2), - ISO_DOTUSEC = (1 << 3), - ISO_COMMAUSEC = (1 << 4), - ISO_T = (1 << 5), - ISO_GMTIME = (1 << 6), - ISO_TIMESTAMP = ISO_DATE | ISO_TIME | ISO_TIMEZONE, - ISO_TIMESTAMP_T = ISO_TIMESTAMP | ISO_T, - ISO_TIMESTAMP_DOT = ISO_TIMESTAMP | ISO_DOTUSEC, - ISO_TIMESTAMP_DOT_T = ISO_TIMESTAMP_DOT | ISO_T, - ISO_TIMESTAMP_COMMA = ISO_TIMESTAMP | ISO_COMMAUSEC, - ISO_TIMESTAMP_COMMA_T = ISO_TIMESTAMP_COMMA | ISO_T, - ISO_TIMESTAMP_COMMA_G = ISO_TIMESTAMP_COMMA | ISO_GMTIME, - ISO_TIMESTAMP_COMMA_GT = ISO_TIMESTAMP_COMMA_G | ISO_T -}; - -#define CTIME_BUFSIZ 26 -#define ISO_BUFSIZ 42 - -int strtimeval_iso(struct timeval *tv, int flags, char *buf, size_t bufsz); -int strtm_iso(struct tm *tm, int flags, char *buf, size_t bufsz); -int strtime_iso(const time_t *t, int flags, char *buf, size_t bufsz); - -#define UL_SHORTTIME_THISYEAR_HHMM (1 << 1) - -int strtime_short(const time_t *t, struct timeval *now, int flags, char *buf, size_t bufsz); - -#ifndef HAVE_TIMEGM -extern time_t timegm(struct tm *tm); -#endif - -#endif /* UTIL_LINUX_TIME_UTIL_H */ diff --git a/utils/include/ttyutils.h b/utils/include/ttyutils.h deleted file mode 100644 index f164a58..0000000 --- a/utils/include/ttyutils.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * No copyright is claimed. This code is in the public domain; do with - * it what you wish. - * - * Written by Karel Zak <kzak@redhat.com> - */ -#ifndef UTIL_LINUX_TTYUTILS_H -#define UTIL_LINUX_TTYUTILS_H - -#include <stdlib.h> -#include <termios.h> -#include <limits.h> -#ifdef HAVE_SYS_IOCTL_H -#include <sys/ioctl.h> -#endif -#ifdef HAVE_SYS_TTYDEFAULTS_H -#include <sys/ttydefaults.h> -#endif - -/* Some shorthands for control characters. */ -#define CTL(x) ((x) ^ 0100) /* Assumes ASCII dialect */ -#define CR CTL('M') /* carriage return */ -#define NL CTL('J') /* line feed */ -#define BS CTL('H') /* back space */ -#define DEL CTL('?') /* delete */ - -/* Defaults for line-editing etc. characters; you may want to change these. */ -#define DEF_ERASE DEL /* default erase character */ -#define DEF_INTR CTL('C') /* default interrupt character */ -#define DEF_QUIT CTL('\\') /* default quit char */ -#define DEF_KILL CTL('U') /* default kill char */ -#define DEF_EOF CTL('D') /* default EOF char */ -#define DEF_EOL 0 -#define DEF_SWITCH 0 /* default switch char */ - -/* Fallback for termios->c_cc[] */ -#ifndef CREPRINT -# define CREPRINT ('r' & 037) -#endif -#ifndef CDISCARD -# define CDISCARD ('o' & 037) -#endif - -/* Default termios->iflag */ -#ifndef TTYDEF_IFLAG -# define TTYDEF_IFLAG (BRKINT | ICRNL | IMAXBEL | IXON | IXANY) -#endif - -/* Default termios->oflag */ -#ifndef TTYDEF_OFLAG -# define TTYDEF_OFLAG (OPOST | ONLCR /*| OXTABS*/) -#endif - -/* Default termios->lflag */ -#ifndef TTYDEF_LFLAG -# define TTYDEF_LFLAG (ECHO | ICANON | ISIG | IEXTEN | ECHOE|ECHOKE|ECHOCTL) -#endif - -/* Default termios->cflag */ -#ifndef TTYDEF_CFLAG -# define TTYDEF_CFLAG (CREAD | CS8 | HUPCL) -#endif - -/* Storage for things detected while the login name was read. */ -struct chardata { - int erase; /* erase character */ - int kill; /* kill character */ - int eol; /* end-of-line character */ - int parity; /* what parity did we see */ - int capslock; /* upper case without lower case */ -}; - -#define INIT_CHARDATA(ptr) do { \ - (ptr)->erase = DEF_ERASE; \ - (ptr)->kill = DEF_KILL; \ - (ptr)->eol = CTRL('r'); \ - (ptr)->parity = 0; \ - (ptr)->capslock = 0; \ - } while (0) - -extern int get_terminal_dimension(int *cols, int *lines); -extern int get_terminal_width(int default_width); -extern int get_terminal_type(const char **type); -extern int get_terminal_stdfd(void); -extern int get_terminal_name(const char **path, const char **name, - const char **number); - -#define UL_TTY_KEEPCFLAGS (1 << 1) -#define UL_TTY_UTF8 (1 << 2) - -static inline void reset_virtual_console(struct termios *tp, int flags) -{ - /* Use defaults of <sys/ttydefaults.h> for base settings */ - tp->c_iflag |= TTYDEF_IFLAG; - tp->c_oflag |= TTYDEF_OFLAG; - tp->c_lflag |= TTYDEF_LFLAG; - - if ((flags & UL_TTY_KEEPCFLAGS) == 0) { -#ifdef CBAUD - tp->c_lflag &= ~CBAUD; -#endif - tp->c_cflag |= (B38400 | TTYDEF_CFLAG); - } - - /* Sane setting, allow eight bit characters, no carriage return delay - * the same result as `stty sane cr0 pass8' - */ -#ifndef IUCLC -# define IUCLC 0 -#endif -#ifndef NL0 -# define NL0 0 -#endif -#ifndef CR0 -# define CR0 0 -#endif -#ifndef BS0 -# define BS0 0 -#endif -#ifndef VT0 -# define VT0 0 -#endif -#ifndef FF0 -# define FF0 0 -#endif -#ifndef OLCUC -# define OLCUC 0 -#endif -#ifndef OFILL -# define OFILL 0 -#endif -#ifndef NLDLY -# define NLDLY 0 -#endif -#ifndef CRDLY -# define CRDLY 0 -#endif -#ifndef BSDLY -# define BSDLY 0 -#endif -#ifndef VTDLY -# define VTDLY 0 -#endif -#ifndef FFDLY -# define FFDLY 0 -#endif -#ifndef TAB0 -# define TAB0 0 -#endif -#ifndef TABDLY -# define TABDLY 0 -#endif - - tp->c_iflag |= (BRKINT | ICRNL | IMAXBEL); - tp->c_iflag &= ~(IGNBRK | INLCR | IGNCR | IXOFF | IUCLC | IXANY | ISTRIP); - tp->c_oflag |= (OPOST | ONLCR | NL0 | CR0 | TAB0 | BS0 | VT0 | FF0); - tp->c_oflag &= ~(OLCUC | OCRNL | ONOCR | ONLRET | OFILL | \ - NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY); - tp->c_lflag |= (ISIG | ICANON | IEXTEN | ECHO|ECHOE|ECHOK|ECHOKE|ECHOCTL); - tp->c_lflag &= ~(ECHONL|ECHOPRT | NOFLSH | TOSTOP); - - if ((flags & UL_TTY_KEEPCFLAGS) == 0) { - tp->c_cflag |= (CREAD | CS8 | HUPCL); - tp->c_cflag &= ~(PARODD | PARENB); - } -#ifdef OFDEL - tp->c_oflag &= ~OFDEL; -#endif -#ifdef XCASE - tp->c_lflag &= ~XCASE; -#endif -#ifdef IUTF8 - if (flags & UL_TTY_UTF8) - tp->c_iflag |= IUTF8; /* Set UTF-8 input flag */ - else - tp->c_iflag &= ~IUTF8; -#endif - /* VTIME and VMIN can overlap with VEOF and VEOL since they are - * only used for non-canonical mode. We just set the at the - * beginning, so nothing bad should happen. - */ - tp->c_cc[VTIME] = 0; - tp->c_cc[VMIN] = 1; - tp->c_cc[VINTR] = CINTR; - tp->c_cc[VQUIT] = CQUIT; - tp->c_cc[VERASE] = CERASE; /* ASCII DEL (0177) */ - tp->c_cc[VKILL] = CKILL; - tp->c_cc[VEOF] = CEOF; -#ifdef VSWTC - tp->c_cc[VSWTC] = _POSIX_VDISABLE; -#elif defined(VSWTCH) - tp->c_cc[VSWTCH] = _POSIX_VDISABLE; -#endif - tp->c_cc[VSTART] = CSTART; - tp->c_cc[VSTOP] = CSTOP; - tp->c_cc[VSUSP] = CSUSP; - tp->c_cc[VEOL] = _POSIX_VDISABLE; - tp->c_cc[VREPRINT] = CREPRINT; - tp->c_cc[VDISCARD] = CDISCARD; - tp->c_cc[VWERASE] = CWERASE; - tp->c_cc[VLNEXT] = CLNEXT; - tp->c_cc[VEOL2] = _POSIX_VDISABLE; -} - -#endif /* UTIL_LINUX_TTYUTILS_H */ diff --git a/utils/include/widechar.h b/utils/include/widechar.h deleted file mode 100644 index c1f2cf2..0000000 --- a/utils/include/widechar.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Declarations for wide characters */ -/* This file must be included last because the redefinition of wchar_t may - cause conflicts when system include files were included after it. */ - -#ifdef HAVE_WIDECHAR - -# include <wchar.h> -# include <wctype.h> - -#else /* !HAVE_WIDECHAR */ - -# include <ctype.h> - /* Fallback for types */ -# define wchar_t char -# define wint_t int -# ifndef WEOF -# define WEOF EOF -# endif - - /* Fallback for input operations */ -# define fgetwc fgetc -# define getwc getc -# define getwchar getchar -# define fgetws fgets - - /* Fallback for output operations */ -# define fputwc fputc -# define putwc putc -# define putwchar putchar -# define fputws fputs - - /* Fallback for character classification */ -# define iswgraph isgraph -# define iswprint isprint -# define iswspace isspace - - /* Fallback for string functions */ -# define wcschr strchr -# define wcsdup strdup -# define wcslen strlen -# define wcspbrk strpbrk - -# define wcwidth(c) (1) -# define wmemset memset -# define ungetwc ungetc - -#endif /* HAVE_WIDECHAR */ diff --git a/utils/include/xalloc.h b/utils/include/xalloc.h deleted file mode 100644 index c4124cb..0000000 --- a/utils/include/xalloc.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2010 Davidlohr Bueso <dave@gnu.org> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * - * General memory allocation wrappers for malloc, realloc, calloc and strdup - */ - -#ifndef UTIL_LINUX_XALLOC_H -#define UTIL_LINUX_XALLOC_H - -#include <stdlib.h> -#include <string.h> - -#include "c.h" - -#ifndef XALLOC_EXIT_CODE -# define XALLOC_EXIT_CODE EXIT_FAILURE -#endif - -static inline -__attribute__((__noreturn__)) -void __err_oom(const char *file, unsigned int line) -{ - err(XALLOC_EXIT_CODE, "%s: %u: cannot allocate memory", file, line); -} - -#define err_oom() __err_oom(__FILE__, __LINE__) - -static inline -__ul_alloc_size(1) -__ul_returns_nonnull -void *xmalloc(const size_t size) -{ - void *ret = malloc(size); - - if (!ret && size) - err(XALLOC_EXIT_CODE, "cannot allocate %zu bytes", size); - return ret; -} - -static inline -__ul_alloc_size(2) -__ul_returns_nonnull -void *xrealloc(void *ptr, const size_t size) -{ - void *ret = realloc(ptr, size); - - if (!ret && size) - err(XALLOC_EXIT_CODE, "cannot allocate %zu bytes", size); - return ret; -} - -static inline -__ul_calloc_size(1, 2) -__ul_returns_nonnull -void *xcalloc(const size_t nelems, const size_t size) -{ - void *ret = calloc(nelems, size); - - if (!ret && size && nelems) - err(XALLOC_EXIT_CODE, "cannot allocate %zu bytes", size); - return ret; -} - -static inline -__attribute__((warn_unused_result)) -__ul_returns_nonnull -char *xstrdup(const char *str) -{ - char *ret; - - assert(str); - ret = strdup(str); - if (!ret) - err(XALLOC_EXIT_CODE, "cannot duplicate string"); - return ret; -} - -static inline -__attribute__((warn_unused_result)) -__ul_returns_nonnull -char *xstrndup(const char *str, size_t size) -{ - char *ret; - - assert(str); - ret = strndup(str, size); - if (!ret) - err(XALLOC_EXIT_CODE, "cannot duplicate string"); - return ret; -} - - -static inline -__attribute__((__format__(printf, 2, 3))) -int xasprintf(char **strp, const char *fmt, ...) -{ - int ret; - va_list args; - - va_start(args, fmt); - ret = vasprintf(&(*strp), fmt, args); - va_end(args); - if (ret < 0) - err(XALLOC_EXIT_CODE, "cannot allocate string"); - return ret; -} - -static inline -__attribute__((__format__(printf, 2, 0))) -int xvasprintf(char **strp, const char *fmt, va_list ap) -{ - int ret = vasprintf(&(*strp), fmt, ap); - - if (ret < 0) - err(XALLOC_EXIT_CODE, "cannot allocate string"); - return ret; -} - - -static inline -__attribute__((warn_unused_result)) -char *xgethostname(void) -{ - char *name; - size_t sz = get_hostname_max() + 1; - - name = xmalloc(sizeof(char) * sz); - if (gethostname(name, sz) != 0) { - free(name); - return NULL; - } - name[sz - 1] = '\0'; - return name; -} - -#endif diff --git a/utils/lib/CMakeLists.txt b/utils/lib/CMakeLists.txt deleted file mode 100644 index e5fa459..0000000 --- a/utils/lib/CMakeLists.txt +++ /dev/null @@ -1,44 +0,0 @@ -cmake_minimum_required(VERSION 3.10) - -# set the project name -project(xloop-utils-lib) - -add_library(libcommon STATIC ${CMAKE_CURRENT_SOURCE_DIR}/blkdev.c - ${CMAKE_CURRENT_SOURCE_DIR}/canonicalize.c - ${CMAKE_CURRENT_SOURCE_DIR}/caputils.c - ${CMAKE_CURRENT_SOURCE_DIR}/color-names.c - ${CMAKE_CURRENT_SOURCE_DIR}/colors.c - ${CMAKE_CURRENT_SOURCE_DIR}/cpuset.c - ${CMAKE_CURRENT_SOURCE_DIR}/crc32.c - ${CMAKE_CURRENT_SOURCE_DIR}/crc32c.c - ${CMAKE_CURRENT_SOURCE_DIR}/encode.c - ${CMAKE_CURRENT_SOURCE_DIR}/env.c - ${CMAKE_CURRENT_SOURCE_DIR}/exec_shell.c - ${CMAKE_CURRENT_SOURCE_DIR}/fileutils.c - ${CMAKE_CURRENT_SOURCE_DIR}/idcache.c - ${CMAKE_CURRENT_SOURCE_DIR}/ismounted.c - ${CMAKE_CURRENT_SOURCE_DIR}/langinfo.c - ${CMAKE_CURRENT_SOURCE_DIR}/linux_version.c - ${CMAKE_CURRENT_SOURCE_DIR}/loopdev.c - ${CMAKE_CURRENT_SOURCE_DIR}/mangle.c - ${CMAKE_CURRENT_SOURCE_DIR}/match.c - ${CMAKE_CURRENT_SOURCE_DIR}/mbsalign.c - ${CMAKE_CURRENT_SOURCE_DIR}/mbsedit.c - ${CMAKE_CURRENT_SOURCE_DIR}/md5.c - ${CMAKE_CURRENT_SOURCE_DIR}/monotonic.c - ${CMAKE_CURRENT_SOURCE_DIR}/pager.c - ${CMAKE_CURRENT_SOURCE_DIR}/path.c - ${CMAKE_CURRENT_SOURCE_DIR}/plymouth-ctrl.c - ${CMAKE_CURRENT_SOURCE_DIR}/procutils.c - ${CMAKE_CURRENT_SOURCE_DIR}/pty-session.c - ${CMAKE_CURRENT_SOURCE_DIR}/pwdutils.c - ${CMAKE_CURRENT_SOURCE_DIR}/randutils.c - ${CMAKE_CURRENT_SOURCE_DIR}/setproctitle.c - ${CMAKE_CURRENT_SOURCE_DIR}/sha1.c - ${CMAKE_CURRENT_SOURCE_DIR}/signames.c - ${CMAKE_CURRENT_SOURCE_DIR}/strutils.c - ${CMAKE_CURRENT_SOURCE_DIR}/strv.c - ${CMAKE_CURRENT_SOURCE_DIR}/sysfs.c - ${CMAKE_CURRENT_SOURCE_DIR}/timer.c - ${CMAKE_CURRENT_SOURCE_DIR}/timeutils.c - ${CMAKE_CURRENT_SOURCE_DIR}/ttyutils.c) diff --git a/utils/lib/blkdev.c b/utils/lib/blkdev.c deleted file mode 100644 index c22853d..0000000 --- a/utils/lib/blkdev.c +++ /dev/null @@ -1,452 +0,0 @@ -/* - * No copyright is claimed. This code is in the public domain; do with - * it what you wish. - * - * Written by Karel Zak <kzak@redhat.com> - */ -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/file.h> -#include <sys/ioctl.h> -#include <unistd.h> -#include <stdint.h> - -#ifdef HAVE_LINUX_FD_H -#include <linux/fd.h> -#endif - -#ifdef HAVE_SYS_DISKLABEL_H -#include <sys/disklabel.h> -#endif - -#ifdef HAVE_SYS_DISK_H -# include <sys/disk.h> -#endif - -#ifndef EBADFD -# define EBADFD 77 /* File descriptor in bad state */ -#endif - -#include "blkdev.h" -#include "c.h" -#include "linux_version.h" -#include "fileutils.h" -#include "nls.h" - -static long -blkdev_valid_offset (int fd, off_t offset) { - char ch; - - if (lseek (fd, offset, 0) < 0) - return 0; - if (read (fd, &ch, 1) < 1) - return 0; - return 1; -} - -int is_blkdev(int fd) -{ - struct stat st; - return (fstat(fd, &st) == 0 && S_ISBLK(st.st_mode)); -} - -off_t -blkdev_find_size (int fd) { - uintmax_t high, low = 0; - - for (high = 1024; blkdev_valid_offset (fd, high); ) { - if (high == UINTMAX_MAX) - return -1; - - low = high; - - if (high >= UINTMAX_MAX/2) - high = UINTMAX_MAX; - else - high *= 2; - } - - while (low < high - 1) - { - uintmax_t mid = (low + high) / 2; - - if (blkdev_valid_offset (fd, mid)) - low = mid; - else - high = mid; - } - blkdev_valid_offset (fd, 0); - return (low + 1); -} - -/* get size in bytes */ -int -blkdev_get_size(int fd, unsigned long long *bytes) -{ -#ifdef DKIOCGETBLOCKCOUNT - /* Apple Darwin */ - if (ioctl(fd, DKIOCGETBLOCKCOUNT, bytes) >= 0) { - *bytes <<= 9; - return 0; - } -#endif - -#ifdef BLKGETSIZE64 - if (ioctl(fd, BLKGETSIZE64, bytes) >= 0) - return 0; -#endif - -#ifdef BLKGETSIZE - { - unsigned long size; - - if (ioctl(fd, BLKGETSIZE, &size) >= 0) { - *bytes = ((unsigned long long)size << 9); - return 0; - } - } - -#endif /* BLKGETSIZE */ - -#ifdef DIOCGMEDIASIZE - /* FreeBSD */ - if (ioctl(fd, DIOCGMEDIASIZE, bytes) >= 0) - return 0; -#endif - -#ifdef FDGETPRM - { - struct floppy_struct this_floppy; - - if (ioctl(fd, FDGETPRM, &this_floppy) >= 0) { - *bytes = ((unsigned long long) this_floppy.size) << 9; - return 0; - } - } -#endif /* FDGETPRM */ - -#if defined(HAVE_SYS_DISKLABEL_H) && defined(DIOCGDINFO) - { - /* - * This code works for FreeBSD 4.11 i386, except for the full device - * (such as /dev/ad0). It doesn't work properly for newer FreeBSD - * though. FreeBSD >= 5.0 should be covered by the DIOCGMEDIASIZE - * above however. - * - * Note that FreeBSD >= 4.0 has disk devices as unbuffered (raw, - * character) devices, so we need to check for S_ISCHR, too. - */ - int part = -1; - struct disklabel lab; - struct partition *pp; - struct stat st; - - if ((fstat(fd, &st) >= 0) && - (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode))) - part = st.st_rdev & 7; - - if (part >= 0 && (ioctl(fd, DIOCGDINFO, (char *)&lab) >= 0)) { - pp = &lab.d_partitions[part]; - if (pp->p_size) { - *bytes = pp->p_size << 9; - return 0; - } - } - } -#endif /* defined(HAVE_SYS_DISKLABEL_H) && defined(DIOCGDINFO) */ - - { - struct stat st; - - if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) { - *bytes = st.st_size; - return 0; - } - if (!S_ISBLK(st.st_mode)) - return -1; - } - - *bytes = blkdev_find_size(fd); - return 0; -} - -/* get 512-byte sector count */ -int -blkdev_get_sectors(int fd, unsigned long long *sectors) -{ - unsigned long long bytes; - - if (blkdev_get_size(fd, &bytes) == 0) { - *sectors = (bytes >> 9); - return 0; - } - - return -1; -} - -/* - * Get logical sector size. - * - * This is the smallest unit the storage device can - * address. It is typically 512 bytes. - */ -#ifdef BLKSSZGET -int blkdev_get_sector_size(int fd, int *sector_size) -{ - if (ioctl(fd, BLKSSZGET, sector_size) >= 0) - return 0; - return -1; -} -#else -int blkdev_get_sector_size(int fd __attribute__((__unused__)), int *sector_size) -{ - *sector_size = DEFAULT_SECTOR_SIZE; - return 0; -} -#endif - -/* - * Get physical block device size. The BLKPBSZGET is supported since Linux - * 2.6.32. For old kernels is probably the best to assume that physical sector - * size is the same as logical sector size. - * - * Example: - * - * rc = blkdev_get_physector_size(fd, &physec); - * if (rc || physec == 0) { - * rc = blkdev_get_sector_size(fd, &physec); - * if (rc) - * physec = DEFAULT_SECTOR_SIZE; - * } - */ -#ifdef BLKPBSZGET -int blkdev_get_physector_size(int fd, int *sector_size) -{ - if (ioctl(fd, BLKPBSZGET, §or_size) >= 0) - return 0; - return -1; -} -#else -int blkdev_get_physector_size(int fd __attribute__((__unused__)), int *sector_size) -{ - *sector_size = DEFAULT_SECTOR_SIZE; - return 0; -} -#endif - -/* - * Return the alignment status of a device - */ -#ifdef BLKALIGNOFF -int blkdev_is_misaligned(int fd) -{ - int aligned; - - if (ioctl(fd, BLKALIGNOFF, &aligned) < 0) - return 0; /* probably kernel < 2.6.32 */ - /* - * Note that kernel returns -1 as alignment offset if no compatible - * sizes and alignments exist for stacked devices - */ - return aligned != 0 ? 1 : 0; -} -#else -int blkdev_is_misaligned(int fd __attribute__((__unused__))) -{ - return 0; -} -#endif - -int open_blkdev_or_file(const struct stat *st, const char *name, const int oflag) -{ - int fd; - - if (S_ISBLK(st->st_mode)) { - fd = open(name, oflag | O_EXCL); - } else - fd = open(name, oflag); - if (-1 < fd && !is_same_inode(fd, st)) { - close(fd); - errno = EBADFD; - return -1; - } - if (-1 < fd && S_ISBLK(st->st_mode) && blkdev_is_misaligned(fd)) - warnx(_("warning: %s is misaligned"), name); - return fd; -} - -#ifdef CDROM_GET_CAPABILITY -int blkdev_is_cdrom(int fd) -{ - int ret; - - if ((ret = ioctl(fd, CDROM_GET_CAPABILITY, NULL)) < 0) - return 0; - - return ret; -} -#else -int blkdev_is_cdrom(int fd __attribute__((__unused__))) -{ - return 0; -} -#endif - -/* - * Get kernel's interpretation of the device's geometry. - * - * Returns the heads and sectors - but not cylinders - * as it's truncated for disks with more than 65535 tracks. - * - * Note that this is deprecated in favor of LBA addressing. - */ -#ifdef HDIO_GETGEO -int blkdev_get_geometry(int fd, unsigned int *h, unsigned int *s) -{ - struct hd_geometry geometry; - - if (ioctl(fd, HDIO_GETGEO, &geometry) == 0) { - *h = geometry.heads; - *s = geometry.sectors; - return 0; - } -#else -int blkdev_get_geometry(int fd __attribute__((__unused__)), - unsigned int *h, unsigned int *s) -{ - *h = 0; - *s = 0; -#endif - return -1; -} - -/* - * Convert scsi type to human readable string. - */ -const char *blkdev_scsi_type_to_name(int type) -{ - switch (type) { - case SCSI_TYPE_DISK: - return "disk"; - case SCSI_TYPE_TAPE: - return "tape"; - case SCSI_TYPE_PRINTER: - return "printer"; - case SCSI_TYPE_PROCESSOR: - return "processor"; - case SCSI_TYPE_WORM: - return "worm"; - case SCSI_TYPE_ROM: - return "rom"; - case SCSI_TYPE_SCANNER: - return "scanner"; - case SCSI_TYPE_MOD: - return "mo-disk"; - case SCSI_TYPE_MEDIUM_CHANGER: - return "changer"; - case SCSI_TYPE_COMM: - return "comm"; - case SCSI_TYPE_RAID: - return "raid"; - case SCSI_TYPE_ENCLOSURE: - return "enclosure"; - case SCSI_TYPE_RBC: - return "rbc"; - case SCSI_TYPE_OSD: - return "osd"; - case SCSI_TYPE_NO_LUN: - return "no-lun"; - default: - break; - } - return NULL; -} - -/* return 0 on success */ -int blkdev_lock(int fd, const char *devname, const char *lockmode) -{ - int oper, rc, msg = 0; - - if (!lockmode) - lockmode = getenv("LOCK_BLOCK_DEVICE"); - if (!lockmode) - return 0; - - if (strcasecmp(lockmode, "yes") == 0 || - strcmp(lockmode, "1") == 0) - oper = LOCK_EX; - - else if (strcasecmp(lockmode, "nonblock") == 0) - oper = LOCK_EX | LOCK_NB; - - else if (strcasecmp(lockmode, "no") == 0 || - strcmp(lockmode, "0") == 0) - return 0; - else { - warnx(_("unsupported lock mode: %s"), lockmode); - return -EINVAL; - } - - if (!(oper & LOCK_NB)) { - /* Try non-block first to provide message */ - rc = flock(fd, oper | LOCK_NB); - if (rc == 0) - return 0; - if (rc != 0 && errno == EWOULDBLOCK) { - fprintf(stderr, _("%s: %s: device already locked, waiting to get lock ... "), - program_invocation_short_name, devname); - msg = 1; - } - } - rc = flock(fd, oper); - if (rc != 0) { - switch (errno) { - case EWOULDBLOCK: /* LOCK_NB */ - warnx(_("%s: device already locked"), devname); - break; - default: - warn(_("%s: failed to get lock"), devname); - } - } else if (msg) - fprintf(stderr, _("OK\n")); - return rc; -} - - -#ifdef TEST_PROGRAM_BLKDEV -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -int -main(int argc, char **argv) -{ - unsigned long long bytes; - unsigned long long sectors; - int sector_size, phy_sector_size; - int fd; - - if (argc != 2) { - fprintf(stderr, "usage: %s device\n", argv[0]); - exit(EXIT_FAILURE); - } - - if ((fd = open(argv[1], O_RDONLY|O_CLOEXEC)) < 0) - err(EXIT_FAILURE, "open %s failed", argv[1]); - - if (blkdev_get_size(fd, &bytes) < 0) - err(EXIT_FAILURE, "blkdev_get_size() failed"); - if (blkdev_get_sectors(fd, §ors) < 0) - err(EXIT_FAILURE, "blkdev_get_sectors() failed"); - if (blkdev_get_sector_size(fd, §or_size) < 0) - err(EXIT_FAILURE, "blkdev_get_sector_size() failed"); - if (blkdev_get_physector_size(fd, &phy_sector_size) < 0) - err(EXIT_FAILURE, "blkdev_get_physector_size() failed"); - - printf(" bytes: %llu\n", bytes); - printf(" sectors: %llu\n", sectors); - printf(" sector size: %d\n", sector_size); - printf("phy-sector size: %d\n", phy_sector_size); - - return EXIT_SUCCESS; -} -#endif /* TEST_PROGRAM_BLKDEV */ diff --git a/utils/lib/canonicalize.c b/utils/lib/canonicalize.c deleted file mode 100644 index e101c5b..0000000 --- a/utils/lib/canonicalize.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * canonicalize.c -- canonicalize pathname by removing symlinks - * - * This file may be distributed under the terms of the - * GNU Lesser General Public License. - * - * Copyright (C) 2009-2013 Karel Zak <kzak@redhat.com> - */ -#include <stdio.h> -#include <string.h> -#include <ctype.h> -#include <unistd.h> -#include <errno.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/wait.h> - -#include "canonicalize.h" -#include "pathnames.h" -#include "all-io.h" - -/* - * Converts private "dm-N" names to "/dev/mapper/<name>" - * - * Since 2.6.29 (patch 784aae735d9b0bba3f8b9faef4c8b30df3bf0128) kernel sysfs - * provides the real DM device names in /sys/block/<ptname>/dm/name - */ -char *__canonicalize_dm_name(const char *prefix, const char *ptname) -{ - FILE *f; - size_t sz; - char path[256], name[sizeof(path) - sizeof(_PATH_DEV_MAPPER)], *res = NULL; - - if (!ptname || !*ptname) - return NULL; - - if (!prefix) - prefix = ""; - - snprintf(path, sizeof(path), "%s/sys/block/%s/dm/name", prefix, ptname); - if (!(f = fopen(path, "r" UL_CLOEXECSTR))) - return NULL; - - /* read "<name>\n" from sysfs */ - if (fgets(name, sizeof(name), f) && (sz = strlen(name)) > 1) { - name[sz - 1] = '\0'; - snprintf(path, sizeof(path), _PATH_DEV_MAPPER "/%s", name); - - if ((prefix && *prefix) || access(path, F_OK) == 0) - res = strdup(path); - } - fclose(f); - return res; -} - -char *canonicalize_dm_name(const char *ptname) -{ - return __canonicalize_dm_name(NULL, ptname); -} - -static int is_dm_devname(char *canonical, char **name) -{ - struct stat sb; - char *p = strrchr(canonical, '/'); - - *name = NULL; - - if (!p - || strncmp(p, "/dm-", 4) != 0 - || !isdigit(*(p + 4)) - || stat(canonical, &sb) != 0 - || !S_ISBLK(sb.st_mode)) - return 0; - - *name = p + 1; - return 1; -} - -/* - * This function does not canonicalize the path! It just prepends CWD before a - * relative path. If the path is no relative than returns NULL. The path does - * not have to exist. - */ -char *absolute_path(const char *path) -{ - char cwd[PATH_MAX], *res, *p; - size_t psz, csz; - - if (!is_relative_path(path)) { - errno = EINVAL; - return NULL; - } - if (!getcwd(cwd, sizeof(cwd))) - return NULL; - - /* simple clean up */ - if (startswith(path, "./")) - path += 2; - else if (strcmp(path, ".") == 0) - path = NULL; - - if (!path || !*path) - return strdup(cwd); - - csz = strlen(cwd); - psz = strlen(path); - - p = res = malloc(csz + 1 + psz + 1); - if (!res) - return NULL; - - memcpy(p, cwd, csz); - p += csz; - *p++ = '/'; - memcpy(p, path, psz + 1); - - return res; -} - -char *canonicalize_path(const char *path) -{ - char *canonical, *dmname; - - if (!path || !*path) - return NULL; - - canonical = realpath(path, NULL); - if (!canonical) - return strdup(path); - - if (is_dm_devname(canonical, &dmname)) { - char *dm = canonicalize_dm_name(dmname); - if (dm) { - free(canonical); - return dm; - } - } - - return canonical; -} - -char *canonicalize_path_restricted(const char *path) -{ - char *canonical = NULL; - int errsv = 0; - int pipes[2]; - ssize_t len; - pid_t pid; - - if (!path || !*path) - return NULL; - - if (pipe(pipes) != 0) - return NULL; - - /* - * To accurately assume identity of getuid() we must use setuid() - * but if we do that, we lose ability to reassume euid of 0, so - * we fork to do the check to keep euid intact. - */ - pid = fork(); - switch (pid) { - case -1: - close(pipes[0]); - close(pipes[1]); - return NULL; /* fork error */ - case 0: - close(pipes[0]); /* close unused end */ - pipes[0] = -1; - errno = 0; - - /* drop permissions */ - if (setgid(getgid()) < 0 || setuid(getuid()) < 0) - canonical = NULL; /* failed */ - else { - char *dmname = NULL; - - canonical = realpath(path, NULL); - if (canonical && is_dm_devname(canonical, &dmname)) { - char *dm = canonicalize_dm_name(dmname); - if (dm) { - free(canonical); - canonical = dm; - } - } - } - - len = canonical ? (ssize_t) strlen(canonical) : - errno ? -errno : -EINVAL; - - /* send length or errno */ - write_all(pipes[1], (char *) &len, sizeof(len)); - if (canonical) - write_all(pipes[1], canonical, len); - exit(0); - default: - break; - } - - close(pipes[1]); /* close unused end */ - pipes[1] = -1; - - /* read size or -errno */ - if (read_all(pipes[0], (char *) &len, sizeof(len)) != sizeof(len)) - goto done; - if (len < 0) { - errsv = -len; - goto done; - } - - canonical = malloc(len + 1); - if (!canonical) { - errsv = ENOMEM; - goto done; - } - /* read path */ - if (read_all(pipes[0], canonical, len) != len) { - errsv = errno; - goto done; - } - canonical[len] = '\0'; -done: - if (errsv) { - free(canonical); - canonical = NULL; - } - close(pipes[0]); - - /* We make a best effort to reap child */ - waitpid(pid, NULL, 0); - - errno = errsv; - return canonical; -} - - -#ifdef TEST_PROGRAM_CANONICALIZE -int main(int argc, char **argv) -{ - if (argc < 2) { - fprintf(stderr, "usage: %s <device>\n", argv[0]); - exit(EXIT_FAILURE); - } - - fprintf(stdout, "orig: %s\n", argv[1]); - fprintf(stdout, "real: %s\n", canonicalize_path(argv[1])); - exit(EXIT_SUCCESS); -} -#endif diff --git a/utils/lib/caputils.c b/utils/lib/caputils.c deleted file mode 100644 index 17e9c01..0000000 --- a/utils/lib/caputils.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <stdio.h> - -#include "caputils.h" -#include "pathnames.h" - -int cap_last_cap(void) -{ - /* CAP_LAST_CAP is untrustworthy. */ - static int ret = -1; - int matched; - FILE *f; - - if (ret != -1) - return ret; - - f = fopen(_PATH_PROC_CAPLASTCAP, "r"); - if (!f) { - ret = CAP_LAST_CAP; /* guess */ - return ret; - } - - matched = fscanf(f, "%d", &ret); - fclose(f); - - if (matched != 1) - ret = CAP_LAST_CAP; /* guess */ - - return ret; -} diff --git a/utils/lib/color-names.c b/utils/lib/color-names.c deleted file mode 100644 index 9b1505e..0000000 --- a/utils/lib/color-names.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * No copyright is claimed. This code is in the public domain; do with - * it what you wish. - * - * Written by Karel Zak <kzak@redhat.com> - */ -#include "c.h" -#include "color-names.h" - -struct ul_color_name { - const char *name; - const char *seq; -}; - -/* - * qsort/bsearch buddy - */ -static int cmp_color_name(const void *a0, const void *b0) -{ - const struct ul_color_name - *a = (const struct ul_color_name *) a0, - *b = (const struct ul_color_name *) b0; - return strcmp(a->name, b->name); -} - -/* - * Maintains human readable color names - */ -const char *color_sequence_from_colorname(const char *str) -{ - static const struct ul_color_name basic_schemes[] = { - { "black", UL_COLOR_BLACK }, - { "blink", UL_COLOR_BLINK }, - { "blue", UL_COLOR_BLUE }, - { "bold", UL_COLOR_BOLD }, - { "brown", UL_COLOR_BROWN }, - { "cyan", UL_COLOR_CYAN }, - { "darkgray", UL_COLOR_DARK_GRAY }, - { "gray", UL_COLOR_GRAY }, - { "green", UL_COLOR_GREEN }, - { "halfbright", UL_COLOR_HALFBRIGHT }, - { "lightblue", UL_COLOR_BOLD_BLUE }, - { "lightcyan", UL_COLOR_BOLD_CYAN }, - { "lightgray,", UL_COLOR_GRAY }, - { "lightgreen", UL_COLOR_BOLD_GREEN }, - { "lightmagenta", UL_COLOR_BOLD_MAGENTA }, - { "lightred", UL_COLOR_BOLD_RED }, - { "magenta", UL_COLOR_MAGENTA }, - { "red", UL_COLOR_RED }, - { "reset", UL_COLOR_RESET, }, - { "reverse", UL_COLOR_REVERSE }, - { "yellow", UL_COLOR_BOLD_YELLOW }, - { "white", UL_COLOR_WHITE } - }; - struct ul_color_name key = { .name = str }, *res; - - if (!str) - return NULL; - - res = bsearch(&key, basic_schemes, ARRAY_SIZE(basic_schemes), - sizeof(struct ul_color_name), - cmp_color_name); - return res ? res->seq : NULL; -} diff --git a/utils/lib/colors.c b/utils/lib/colors.c deleted file mode 100644 index e317519..0000000 --- a/utils/lib/colors.c +++ /dev/null @@ -1,907 +0,0 @@ -/* - * Copyright (C) 2012 Ondrej Oprala <ooprala@redhat.com> - * Copyright (C) 2012-2014 Karel Zak <kzak@redhat.com> - * - * This file may be distributed under the terms of the - * GNU Lesser General Public License. - */ -#include <assert.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <dirent.h> -#include <ctype.h> - -#if defined(HAVE_LIBNCURSES) || defined(HAVE_LIBNCURSESW) -# if defined(HAVE_NCURSESW_NCURSES_H) -# include <ncursesw/ncurses.h> -# elif defined(HAVE_NCURSES_NCURSES_H) -# include <ncurses/ncurses.h> -# elif defined(HAVE_NCURSES_H) -# include <ncurses.h> -# endif -# if defined(HAVE_NCURSESW_TERM_H) -# include <ncursesw/term.h> -# elif defined(HAVE_NCURSES_TERM_H) -# include <ncurses/term.h> -# elif defined(HAVE_TERM_H) -# include <term.h> -# endif -#endif - -#include "c.h" -#include "colors.h" -#include "pathnames.h" -#include "strutils.h" - -#include "debug.h" - -/* - * Default behavior, may be overridden by terminal-colors.d/{enable,disable}. - */ -#ifdef USE_COLORS_BY_DEFAULT -# define UL_COLORMODE_DEFAULT UL_COLORMODE_AUTO /* check isatty() */ -#else -# define UL_COLORMODE_DEFAULT UL_COLORMODE_NEVER /* no colors by default */ -#endif - -/* - * terminal-colors.d debug stuff - */ -static UL_DEBUG_DEFINE_MASK(termcolors); -UL_DEBUG_DEFINE_MASKNAMES(termcolors) = UL_DEBUG_EMPTY_MASKNAMES; - -#define TERMCOLORS_DEBUG_INIT (1 << 1) -#define TERMCOLORS_DEBUG_CONF (1 << 2) -#define TERMCOLORS_DEBUG_SCHEME (1 << 3) -#define TERMCOLORS_DEBUG_ALL 0xFFFF - -#define DBG(m, x) __UL_DBG(termcolors, TERMCOLORS_DEBUG_, m, x) -#define ON_DBG(m, x) __UL_DBG_CALL(termcolors, TERMCOLORS_DEBUG_, m, x) - -/* - * terminal-colors.d file types - */ -enum { - UL_COLORFILE_DISABLE, /* .disable */ - UL_COLORFILE_ENABLE, /* .enable */ - UL_COLORFILE_SCHEME, /* .scheme */ - - __UL_COLORFILE_COUNT -}; - -struct ul_color_scheme { - char *name; - char *seq; -}; - -/* - * Global colors control struct - * - * The terminal-colors.d/ evaluation is based on "scores": - * - * filename score - * --------------------------------------- - * type 1 - * @termname.type 10 + 1 - * utilname.type 20 + 1 - * utilname@termname.type 20 + 10 + 1 - * - * the match with higher score wins. The score is per type. - */ -struct ul_color_ctl { - const char *utilname; /* util name */ - const char *termname; /* terminal name ($TERM) */ - - char *sfile; /* path to scheme */ - - struct ul_color_scheme *schemes; /* array with color schemes */ - size_t nschemes; /* number of the items */ - size_t schemes_sz; /* number of the allocated items */ - - int mode; /* UL_COLORMODE_* */ - unsigned int has_colors : 1, /* based on mode and scores[] */ - disabled : 1, /* disable colors */ - cs_configured : 1, /* color schemes read */ - configured : 1; /* terminal-colors.d parsed */ - - int scores[__UL_COLORFILE_COUNT]; /* the best match */ -}; - -/* - * Control struct, globally shared. - */ -static struct ul_color_ctl ul_colors; - -static void colors_free_schemes(struct ul_color_ctl *cc); -static int colors_read_schemes(struct ul_color_ctl *cc); - -/* - * qsort/bsearch buddy - */ -static int cmp_scheme_name(const void *a0, const void *b0) -{ - const struct ul_color_scheme *a = (const struct ul_color_scheme *) a0, - *b = (const struct ul_color_scheme *) b0; - return strcmp(a->name, b->name); -} - -/* - * Resets control struct (note that we don't allocate the struct) - */ -static void colors_reset(struct ul_color_ctl *cc) -{ - if (!cc) - return; - - colors_free_schemes(cc); - - free(cc->sfile); - - cc->sfile = NULL; - cc->utilname = NULL; - cc->termname = NULL; - cc->mode = UL_COLORMODE_UNDEF; - - memset(cc->scores, 0, sizeof(cc->scores)); -} - -static void colors_debug(struct ul_color_ctl *cc) -{ - size_t i; - - if (!cc) - return; - - printf("Colors:\n"); - printf("\tutilname = '%s'\n", cc->utilname); - printf("\ttermname = '%s'\n", cc->termname); - printf("\tscheme file = '%s'\n", cc->sfile); - printf("\tmode = %s\n", - cc->mode == UL_COLORMODE_UNDEF ? "undefined" : - cc->mode == UL_COLORMODE_AUTO ? "auto" : - cc->mode == UL_COLORMODE_NEVER ? "never" : - cc->mode == UL_COLORMODE_ALWAYS ? "always" : "???"); - printf("\thas_colors = %d\n", cc->has_colors); - printf("\tdisabled = %d\n", cc->disabled); - printf("\tconfigured = %d\n", cc->configured); - printf("\tcs configured = %d\n", cc->cs_configured); - - fputc('\n', stdout); - - for (i = 0; i < ARRAY_SIZE(cc->scores); i++) - printf("\tscore %s = %d\n", - i == UL_COLORFILE_DISABLE ? "disable" : - i == UL_COLORFILE_ENABLE ? "enable" : - i == UL_COLORFILE_SCHEME ? "scheme" : "???", - cc->scores[i]); - - fputc('\n', stdout); - - for (i = 0; i < cc->nschemes; i++) { - printf("\tscheme #%02zu ", i); - color_scheme_enable(cc->schemes[i].name, NULL); - fputs(cc->schemes[i].name, stdout); - color_disable(); - fputc('\n', stdout); - } - fputc('\n', stdout); -} - -/* - * Parses [[<utilname>][@<termname>].]<type> - */ -static int filename_to_tokens(const char *str, - const char **name, size_t *namesz, - const char **term, size_t *termsz, - int *filetype) -{ - const char *type_start, *term_start, *p; - - if (!str || !*str || *str == '.' || strlen(str) > PATH_MAX) - return -EINVAL; - - /* parse .type */ - p = strrchr(str, '.'); - type_start = p ? p + 1 : str; - - if (strcmp(type_start, "disable") == 0) - *filetype = UL_COLORFILE_DISABLE; - else if (strcmp(type_start, "enable") == 0) - *filetype = UL_COLORFILE_ENABLE; - else if (strcmp(type_start, "scheme") == 0) - *filetype = UL_COLORFILE_SCHEME; - else { - DBG(CONF, ul_debug("unknown type '%s'", type_start)); - return 1; /* unknown type */ - } - - if (type_start == str) - return 0; /* "type" only */ - - /* parse @termname */ - p = strchr(str, '@'); - term_start = p ? p + 1 : NULL; - if (term_start) { - *term = term_start; - *termsz = type_start - term_start - 1; - if (term_start - 1 == str) - return 0; /* "@termname.type" */ - } - - /* parse utilname */ - p = term_start ? term_start : type_start; - *name = str; - *namesz = p - str - 1; - - return 0; -} - -/* - * Scans @dirname and select the best matches for UL_COLORFILE_* types. - * The result is stored to cc->scores. The path to the best "scheme" - * file is stored to cc->scheme. - */ -static int colors_readdir(struct ul_color_ctl *cc, const char *dirname) -{ - DIR *dir; - int rc = 0; - struct dirent *d; - char sfile[PATH_MAX] = { '\0' }; - size_t namesz, termsz; - - if (!dirname || !cc || !cc->utilname || !*cc->utilname) - return -EINVAL; - - DBG(CONF, ul_debug("reading dir: '%s'", dirname)); - - dir = opendir(dirname); - if (!dir) - return -errno; - - namesz = strlen(cc->utilname); - termsz = cc->termname ? strlen(cc->termname) : 0; - - while ((d = readdir(dir))) { - int type, score = 1; - const char *tk_name = NULL, *tk_term = NULL; - size_t tk_namesz = 0, tk_termsz = 0; - - if (*d->d_name == '.') - continue; -#ifdef _DIRENT_HAVE_D_TYPE - if (d->d_type != DT_UNKNOWN && d->d_type != DT_LNK && - d->d_type != DT_REG) - continue; -#endif - if (filename_to_tokens(d->d_name, - &tk_name, &tk_namesz, - &tk_term, &tk_termsz, &type) != 0) - continue; - - /* count theoretical score before we check names to avoid - * unnecessary strcmp() */ - if (tk_name) - score += 20; - if (tk_term) - score += 10; - - DBG(CONF, ul_debug("item '%s': score=%d " - "[cur: %d, name(%zu): %s, term(%zu): %s]", - d->d_name, score, cc->scores[type], - tk_namesz, tk_name, - tk_termsz, tk_term)); - - - if (score < cc->scores[type]) - continue; - - /* filter out by names */ - if (tk_namesz && (tk_namesz != namesz || - strncmp(tk_name, cc->utilname, namesz) != 0)) - continue; - - if (tk_termsz && (termsz == 0 || tk_termsz != termsz || - strncmp(tk_term, cc->termname, termsz) != 0)) - continue; - - DBG(CONF, ul_debug("setting '%s' from %d -to-> %d", - type == UL_COLORFILE_SCHEME ? "scheme" : - type == UL_COLORFILE_DISABLE ? "disable" : - type == UL_COLORFILE_ENABLE ? "enable" : "???", - cc->scores[type], score)); - cc->scores[type] = score; - if (type == UL_COLORFILE_SCHEME) - strncpy(sfile, d->d_name, sizeof(sfile)); - } - - if (*sfile) { - sfile[sizeof(sfile) - 1] = '\0'; - if (asprintf(&cc->sfile, "%s/%s", dirname, sfile) <= 0) - rc = -ENOMEM; - } - - closedir(dir); - return rc; -} - -/* atexit() wrapper */ -static void colors_deinit(void) -{ - colors_reset(&ul_colors); -} - -/* - * Returns path to $XDG_CONFIG_HOME/terminal-colors.d - */ -static char *colors_get_homedir(char *buf, size_t bufsz) -{ - char *p = getenv("XDG_CONFIG_HOME"); - - if (p) { - snprintf(buf, bufsz, "%s/" _PATH_TERMCOLORS_DIRNAME, p); - return buf; - } - - p = getenv("HOME"); - if (p) { - snprintf(buf, bufsz, "%s/.config/" _PATH_TERMCOLORS_DIRNAME, p); - return buf; - } - - return NULL; -} - -/* canonicalize sequence */ -static int cn_sequence(const char *str, char **seq) -{ - char *in, *out; - int len; - - if (!str) - return -EINVAL; - - *seq = NULL; - - /* convert logical names like "red" to the real sequence */ - if (*str != '\\' && isalpha(*str)) { - const char *s = color_sequence_from_colorname(str); - *seq = strdup(s ? s : str); - - return *seq ? 0 : -ENOMEM; - } - - /* convert xx;yy sequences to "\033[xx;yy" */ - if ((len = asprintf(seq, "\033[%sm", str)) < 1) - return -ENOMEM; - - for (in = *seq, out = *seq; in && *in; in++) { - if (*in != '\\') { - *out++ = *in; - continue; - } - switch(*(in + 1)) { - case 'a': - *out++ = '\a'; /* Bell */ - break; - case 'b': - *out++ = '\b'; /* Backspace */ - break; - case 'e': - *out++ = '\033'; /* Escape */ - break; - case 'f': - *out++ = '\f'; /* Form Feed */ - break; - case 'n': - *out++ = '\n'; /* Newline */ - break; - case 'r': - *out++ = '\r'; /* Carriage Return */ - break; - case 't': - *out++ = '\t'; /* Tab */ - break; - case 'v': - *out++ = '\v'; /* Vertical Tab */ - break; - case '\\': - *out++ = '\\'; /* Backslash */ - break; - case '_': - *out++ = ' '; /* Space */ - break; - case '#': - *out++ = '#'; /* Hash mark */ - break; - case '?': - *out++ = '?'; /* Question mark */ - break; - default: - *out++ = *in; - *out++ = *(in + 1); - break; - } - in++; - } - - if (out) { - assert ((out - *seq) <= len); - *out = '\0'; - } - - return 0; -} - - -/* - * Adds one color sequence to array with color scheme. - * When returning success (0) this function takes ownership of - * @seq and @name, which have to be allocated strings. - */ -static int colors_add_scheme(struct ul_color_ctl *cc, - char *name, - char *seq0) -{ - struct ul_color_scheme *cs = NULL; - char *seq = NULL; - int rc; - - if (!cc || !name || !*name || !seq0 || !*seq0) - return -EINVAL; - - DBG(SCHEME, ul_debug("add '%s'", name)); - - rc = cn_sequence(seq0, &seq); - if (rc) - return rc; - - rc = -ENOMEM; - - /* convert logical name (e.g. "red") to real ESC code */ - if (isalpha(*seq)) { - const char *s = color_sequence_from_colorname(seq); - char *p; - - if (!s) { - DBG(SCHEME, ul_debug("unknown logical name: %s", seq)); - rc = -EINVAL; - goto err; - } - - p = strdup(s); - if (!p) - goto err; - free(seq); - seq = p; - } - - /* enlarge the array */ - if (cc->nschemes == cc->schemes_sz) { - void *tmp = realloc(cc->schemes, (cc->nschemes + 10) - * sizeof(struct ul_color_scheme)); - if (!tmp) - goto err; - cc->schemes = tmp; - cc->schemes_sz = cc->nschemes + 10; - } - - /* add a new item */ - cs = &cc->schemes[cc->nschemes]; - cs->seq = seq; - cs->name = strdup(name); - if (!cs->name) - goto err; - - cc->nschemes++; - return 0; -err: - if (cs) { - free(cs->seq); - free(cs->name); - cs->seq = cs->name = NULL; - } else - free(seq); - return rc; -} - -/* - * Deallocates all regards to color schemes - */ -static void colors_free_schemes(struct ul_color_ctl *cc) -{ - size_t i; - - DBG(SCHEME, ul_debug("free scheme")); - - for (i = 0; i < cc->nschemes; i++) { - free(cc->schemes[i].name); - free(cc->schemes[i].seq); - } - - free(cc->schemes); - cc->schemes = NULL; - cc->nschemes = 0; - cc->schemes_sz = 0; -} - -/* - * The scheme configuration has to be sorted for bsearch - */ -static void colors_sort_schemes(struct ul_color_ctl *cc) -{ - if (!cc->nschemes) - return; - - DBG(SCHEME, ul_debug("sort scheme")); - - qsort(cc->schemes, cc->nschemes, - sizeof(struct ul_color_scheme), cmp_scheme_name); -} - -/* - * Returns just one color scheme - */ -static struct ul_color_scheme *colors_get_scheme(struct ul_color_ctl *cc, - const char *name) -{ - struct ul_color_scheme key = { .name = (char *) name}, *res; - - if (!cc || !name || !*name) - return NULL; - - if (!cc->cs_configured) { - int rc = colors_read_schemes(cc); - if (rc) - return NULL; - } - if (!cc->nschemes) - return NULL; - - DBG(SCHEME, ul_debug("search '%s'", name)); - - res = bsearch(&key, cc->schemes, cc->nschemes, - sizeof(struct ul_color_scheme), - cmp_scheme_name); - - return res && res->seq ? res : NULL; -} - -/* - * Parses filenames in terminal-colors.d - */ -static int colors_read_configuration(struct ul_color_ctl *cc) -{ - int rc = -ENOENT; - char *dirname, buf[PATH_MAX]; - - cc->termname = getenv("TERM"); - - dirname = colors_get_homedir(buf, sizeof(buf)); - if (dirname) - rc = colors_readdir(cc, dirname); /* ~/.config */ - if (rc == -EPERM || rc == -EACCES || rc == -ENOENT) - rc = colors_readdir(cc, _PATH_TERMCOLORS_DIR); /* /etc */ - - cc->configured = 1; - return rc; -} - -/* - * Reads terminal-colors.d/ scheme file into array schemes - */ -static int colors_read_schemes(struct ul_color_ctl *cc) -{ - int rc = 0; - FILE *f = NULL; - char buf[BUFSIZ], - cn[129], seq[129]; - - if (!cc->configured) - rc = colors_read_configuration(cc); - - cc->cs_configured = 1; - - if (rc || !cc->sfile) - goto done; - - DBG(SCHEME, ul_debug("reading file '%s'", cc->sfile)); - - f = fopen(cc->sfile, "r"); - if (!f) { - rc = -errno; - goto done; - } - - while (fgets(buf, sizeof(buf), f)) { - char *p = strchr(buf, '\n'); - - if (!p) { - if (feof(f)) - p = strchr(buf, '\0'); - else { - rc = -errno; - goto done; - } - } - *p = '\0'; - p = (char *) skip_blank(buf); - if (*p == '\0' || *p == '#') - continue; - - rc = sscanf(p, "%128[^ ] %128[^\n ]", cn, seq); - if (rc == 2 && *cn && *seq) { - rc = colors_add_scheme(cc, cn, seq); /* set rc=0 on success */ - if (rc) - goto done; - } - } - rc = 0; - -done: - if (f) - fclose(f); - colors_sort_schemes(cc); - - return rc; -} - - -static void termcolors_init_debug(void) -{ - __UL_INIT_DEBUG_FROM_ENV(termcolors, TERMCOLORS_DEBUG_, 0, TERMINAL_COLORS_DEBUG); -} - -static int colors_terminal_is_ready(void) -{ - int ncolors = -1; - -#if defined(HAVE_LIBNCURSES) || defined(HAVE_LIBNCURSESW) - { - int ret; - - if (setupterm(NULL, STDOUT_FILENO, &ret) == 0 && ret == 1) - ncolors = tigetnum("colors"); - } -#endif - if (1 < ncolors) { - DBG(CONF, ul_debug("terminal is ready (supports %d colors)", ncolors)); - return 1; - } - - DBG(CONF, ul_debug("terminal is NOT ready (no colors)")); - return 0; -} - -/** - * colors_init: - * @mode: UL_COLORMODE_* - * @name: util argv[0] - * - * Initialize private color control struct and initialize the colors - * status. The color schemes are parsed on demand by colors_get_scheme(). - * - * Returns: >0 on success. - */ -int colors_init(int mode, const char *name) -{ - int ready = -1; - struct ul_color_ctl *cc = &ul_colors; - - cc->utilname = name; - - termcolors_init_debug(); - - if (mode != UL_COLORMODE_ALWAYS && !isatty(STDOUT_FILENO)) - cc->mode = UL_COLORMODE_NEVER; - else - cc->mode = mode; - - if (cc->mode == UL_COLORMODE_UNDEF - && (ready = colors_terminal_is_ready())) { - int rc = colors_read_configuration(cc); - if (rc) - cc->mode = UL_COLORMODE_DEFAULT; - else { - - /* evaluate scores */ - if (cc->scores[UL_COLORFILE_DISABLE] > - cc->scores[UL_COLORFILE_ENABLE]) - cc->mode = UL_COLORMODE_NEVER; - else - cc->mode = UL_COLORMODE_DEFAULT; - - atexit(colors_deinit); - } - } - - switch (cc->mode) { - case UL_COLORMODE_AUTO: - cc->has_colors = ready == -1 ? colors_terminal_is_ready() : ready; - break; - case UL_COLORMODE_ALWAYS: - cc->has_colors = 1; - break; - case UL_COLORMODE_NEVER: - default: - cc->has_colors = 0; - } - - ON_DBG(CONF, colors_debug(cc)); - - return cc->has_colors; -} - -/* - * Temporary disable colors (this setting is independent on terminal-colors.d/) - */ -void colors_off(void) -{ - ul_colors.disabled = 1; -} - -/* - * Enable colors - */ -void colors_on(void) -{ - ul_colors.disabled = 0; -} - -/* - * Is terminal-colors.d/ configured to use colors? - */ -int colors_wanted(void) -{ - return ul_colors.has_colors; -} - -/* - * Returns mode - */ -int colors_mode(void) -{ - return ul_colors.mode; -} - -/* - * Enable @seq color - */ -void color_fenable(const char *seq, FILE *f) -{ - if (!ul_colors.disabled && ul_colors.has_colors && seq) - fputs(seq, f); -} - -/* - * Returns escape sequence by logical @name, if undefined then returns @dflt. - */ -const char *color_scheme_get_sequence(const char *name, const char *dflt) -{ - struct ul_color_scheme *cs; - - if (ul_colors.disabled || !ul_colors.has_colors) - return NULL; - - cs = colors_get_scheme(&ul_colors, name); - return cs && cs->seq ? cs->seq : dflt; -} - -/* - * Enable color by logical @name, if undefined enable @dflt. - */ -void color_scheme_fenable(const char *name, const char *dflt, FILE *f) -{ - const char *seq = color_scheme_get_sequence(name, dflt); - - if (!seq) - return; - color_fenable(seq, f); -} - - -/* - * Disable previously enabled color - */ -void color_fdisable(FILE *f) -{ - if (!ul_colors.disabled && ul_colors.has_colors) - fputs(UL_COLOR_RESET, f); -} - -/* - * Parses @str to return UL_COLORMODE_* - */ -int colormode_from_string(const char *str) -{ - size_t i; - static const char *modes[] = { - [UL_COLORMODE_AUTO] = "auto", - [UL_COLORMODE_NEVER] = "never", - [UL_COLORMODE_ALWAYS] = "always", - [UL_COLORMODE_UNDEF] = "" - }; - - if (!str || !*str) - return -EINVAL; - - assert(ARRAY_SIZE(modes) == __UL_NCOLORMODES); - - for (i = 0; i < ARRAY_SIZE(modes); i++) { - if (strcasecmp(str, modes[i]) == 0) - return i; - } - - return -EINVAL; -} - -/* - * Parses @str and exit(EXIT_FAILURE) on error - */ -int colormode_or_err(const char *str, const char *errmsg) -{ - const char *p = str && *str == '=' ? str + 1 : str; - int colormode; - - colormode = colormode_from_string(p); - if (colormode < 0) - errx(EXIT_FAILURE, "%s: '%s'", errmsg, p); - - return colormode; -} - -#ifdef TEST_PROGRAM_COLORS -# include <getopt.h> -int main(int argc, char *argv[]) -{ - static const struct option longopts[] = { - { "mode", required_argument, NULL, 'm' }, - { "color", required_argument, NULL, 'c' }, - { "color-scheme", required_argument, NULL, 'C' }, - { "name", required_argument, NULL, 'n' }, - { NULL, 0, NULL, 0 } - }; - int c, mode = UL_COLORMODE_UNDEF; /* default */ - const char *color = "red", *name = NULL, *color_scheme = NULL; - const char *seq = NULL; - - while ((c = getopt_long(argc, argv, "C:c:m:n:", longopts, NULL)) != -1) { - switch (c) { - case 'c': - color = optarg; - break; - case 'C': - color_scheme = optarg; - break; - case 'm': - mode = colormode_or_err(optarg, "unsupported color mode"); - break; - case 'n': - name = optarg; - break; - default: - fprintf(stderr, "usage: %s [options]\n" - " -m, --mode <auto|never|always> default is undefined\n" - " -c, --color <red|blue|...> color for the test message\n" - " -C, --color-scheme <name> color for the test message\n" - " -n, --name <utilname> util name\n", - program_invocation_short_name); - return EXIT_FAILURE; - } - } - - colors_init(mode, name ? name : program_invocation_short_name); - - seq = color_sequence_from_colorname(color); - - if (color_scheme) - color_scheme_enable(color_scheme, seq); - else - color_enable(seq); - printf("Hello World!"); - color_disable(); - fputc('\n', stdout); - - return EXIT_SUCCESS; -} -#endif /* TEST_PROGRAM_COLORS */ - diff --git a/utils/lib/cpuset.c b/utils/lib/cpuset.c deleted file mode 100644 index 2847db8..0000000 --- a/utils/lib/cpuset.c +++ /dev/null @@ -1,413 +0,0 @@ -/* - * Terminology: - * - * cpuset - (libc) cpu_set_t data structure represents set of CPUs - * cpumask - string with hex mask (e.g. "0x00000001") - * cpulist - string with CPU ranges (e.g. "0-3,5,7,8") - * - * Based on code from taskset.c and Linux kernel. - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * - * Copyright (C) 2010 Karel Zak <kzak@redhat.com> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sched.h> -#include <errno.h> -#include <string.h> -#include <ctype.h> -#include <sys/syscall.h> - -#include "cpuset.h" -#include "c.h" - -static inline int val_to_char(int v) -{ - if (v >= 0 && v < 10) - return '0' + v; - if (v >= 10 && v < 16) - return ('a' - 10) + v; - return -1; -} - -static inline int char_to_val(int c) -{ - int cl; - - if (c >= '0' && c <= '9') - return c - '0'; - cl = tolower(c); - if (cl >= 'a' && cl <= 'f') - return cl + (10 - 'a'); - return -1; -} - -static const char *nexttoken(const char *q, int sep) -{ - if (q) - q = strchr(q, sep); - if (q) - q++; - return q; -} - -/* - * Number of bits in a CPU bitmask on current system - */ -int get_max_number_of_cpus(void) -{ -#ifdef SYS_sched_getaffinity - int n, cpus = 2048; - size_t setsize; - cpu_set_t *set = cpuset_alloc(cpus, &setsize, NULL); - - if (!set) - return -1; /* error */ - - for (;;) { - CPU_ZERO_S(setsize, set); - - /* the library version does not return size of cpumask_t */ - n = syscall(SYS_sched_getaffinity, 0, setsize, set); - - if (n < 0 && errno == EINVAL && cpus < 1024 * 1024) { - cpuset_free(set); - cpus *= 2; - set = cpuset_alloc(cpus, &setsize, NULL); - if (!set) - return -1; /* error */ - continue; - } - cpuset_free(set); - return n * 8; - } -#endif - return -1; -} - -/* - * Allocates a new set for ncpus and returns size in bytes and size in bits - */ -cpu_set_t *cpuset_alloc(int ncpus, size_t *setsize, size_t *nbits) -{ - cpu_set_t *set = CPU_ALLOC(ncpus); - - if (!set) - return NULL; - if (setsize) - *setsize = CPU_ALLOC_SIZE(ncpus); - if (nbits) - *nbits = cpuset_nbits(CPU_ALLOC_SIZE(ncpus)); - return set; -} - -void cpuset_free(cpu_set_t *set) -{ - CPU_FREE(set); -} - -#if !HAVE_DECL_CPU_ALLOC -/* Please, use CPU_COUNT_S() macro. This is fallback */ -int __cpuset_count_s(size_t setsize, const cpu_set_t *set) -{ - int s = 0; - const __cpu_mask *p = set->__bits; - const __cpu_mask *end = &set->__bits[setsize / sizeof (__cpu_mask)]; - - while (p < end) { - __cpu_mask l = *p++; - - if (l == 0) - continue; -# if LONG_BIT > 32 - l = (l & 0x5555555555555555ul) + ((l >> 1) & 0x5555555555555555ul); - l = (l & 0x3333333333333333ul) + ((l >> 2) & 0x3333333333333333ul); - l = (l & 0x0f0f0f0f0f0f0f0ful) + ((l >> 4) & 0x0f0f0f0f0f0f0f0ful); - l = (l & 0x00ff00ff00ff00fful) + ((l >> 8) & 0x00ff00ff00ff00fful); - l = (l & 0x0000ffff0000fffful) + ((l >> 16) & 0x0000ffff0000fffful); - l = (l & 0x00000000fffffffful) + ((l >> 32) & 0x00000000fffffffful); -# else - l = (l & 0x55555555ul) + ((l >> 1) & 0x55555555ul); - l = (l & 0x33333333ul) + ((l >> 2) & 0x33333333ul); - l = (l & 0x0f0f0f0ful) + ((l >> 4) & 0x0f0f0f0ful); - l = (l & 0x00ff00fful) + ((l >> 8) & 0x00ff00fful); - l = (l & 0x0000fffful) + ((l >> 16) & 0x0000fffful); -# endif - s += l; - } - return s; -} -#endif - -/* - * Returns human readable representation of the cpuset. The output format is - * a list of CPUs with ranges (for example, "0,1,3-9"). - */ -char *cpulist_create(char *str, size_t len, - cpu_set_t *set, size_t setsize) -{ - size_t i; - char *ptr = str; - int entry_made = 0; - size_t max = cpuset_nbits(setsize); - - for (i = 0; i < max; i++) { - if (CPU_ISSET_S(i, setsize, set)) { - int rlen; - size_t j, run = 0; - entry_made = 1; - for (j = i + 1; j < max; j++) { - if (CPU_ISSET_S(j, setsize, set)) - run++; - else - break; - } - if (!run) - rlen = snprintf(ptr, len, "%zu,", i); - else if (run == 1) { - rlen = snprintf(ptr, len, "%zu,%zu,", i, i + 1); - i++; - } else { - rlen = snprintf(ptr, len, "%zu-%zu,", i, i + run); - i += run; - } - if (rlen < 0 || (size_t) rlen >= len) - return NULL; - ptr += rlen; - len -= rlen; - } - } - ptr -= entry_made; - *ptr = '\0'; - - return str; -} - -/* - * Returns string with CPU mask. - */ -char *cpumask_create(char *str, size_t len, - cpu_set_t *set, size_t setsize) -{ - char *ptr = str; - char *ret = NULL; - int cpu; - - for (cpu = cpuset_nbits(setsize) - 4; cpu >= 0; cpu -= 4) { - char val = 0; - - if (len == (size_t) (ptr - str)) - break; - - if (CPU_ISSET_S(cpu, setsize, set)) - val |= 1; - if (CPU_ISSET_S(cpu + 1, setsize, set)) - val |= 2; - if (CPU_ISSET_S(cpu + 2, setsize, set)) - val |= 4; - if (CPU_ISSET_S(cpu + 3, setsize, set)) - val |= 8; - - if (!ret && val) - ret = ptr; - *ptr++ = val_to_char(val); - } - *ptr = '\0'; - return ret ? ret : ptr - 1; -} - -/* - * Parses string with CPUs mask. - */ -int cpumask_parse(const char *str, cpu_set_t *set, size_t setsize) -{ - int len = strlen(str); - const char *ptr = str + len - 1; - int cpu = 0; - - /* skip 0x, it's all hex anyway */ - if (len > 1 && !memcmp(str, "0x", 2L)) - str += 2; - - CPU_ZERO_S(setsize, set); - - while (ptr >= str) { - char val; - - /* cpu masks in /sys uses comma as a separator */ - if (*ptr == ',') - ptr--; - - val = char_to_val(*ptr); - if (val == (char) -1) - return -1; - if (val & 1) - CPU_SET_S(cpu, setsize, set); - if (val & 2) - CPU_SET_S(cpu + 1, setsize, set); - if (val & 4) - CPU_SET_S(cpu + 2, setsize, set); - if (val & 8) - CPU_SET_S(cpu + 3, setsize, set); - ptr--; - cpu += 4; - } - - return 0; -} - -static int nextnumber(const char *str, char **end, unsigned int *result) -{ - errno = 0; - if (str == NULL || *str == '\0' || !isdigit(*str)) - return -EINVAL; - *result = (unsigned int) strtoul(str, end, 10); - if (errno) - return -errno; - if (str == *end) - return -EINVAL; - return 0; -} - -/* - * Parses string with list of CPU ranges. - * Returns 0 on success. - * Returns 1 on error. - * Returns 2 if fail is set and a cpu number passed in the list doesn't fit - * into the cpu_set. If fail is not set cpu numbers that do not fit are - * ignored and 0 is returned instead. - */ -int cpulist_parse(const char *str, cpu_set_t *set, size_t setsize, int fail) -{ - size_t max = cpuset_nbits(setsize); - const char *p, *q; - char *end = NULL; - - q = str; - CPU_ZERO_S(setsize, set); - - while (p = q, q = nexttoken(q, ','), p) { - unsigned int a; /* beginning of range */ - unsigned int b; /* end of range */ - unsigned int s; /* stride */ - const char *c1, *c2; - - if (nextnumber(p, &end, &a) != 0) - return 1; - b = a; - s = 1; - p = end; - - c1 = nexttoken(p, '-'); - c2 = nexttoken(p, ','); - - if (c1 != NULL && (c2 == NULL || c1 < c2)) { - if (nextnumber(c1, &end, &b) != 0) - return 1; - - c1 = end && *end ? nexttoken(end, ':') : NULL; - - if (c1 != NULL && (c2 == NULL || c1 < c2)) { - if (nextnumber(c1, &end, &s) != 0) - return 1; - if (s == 0) - return 1; - } - } - - if (!(a <= b)) - return 1; - while (a <= b) { - if (fail && (a >= max)) - return 2; - CPU_SET_S(a, setsize, set); - a += s; - } - } - - if (end && *end) - return 1; - return 0; -} - -#ifdef TEST_PROGRAM_CPUSET - -#include <getopt.h> - -int main(int argc, char *argv[]) -{ - cpu_set_t *set; - size_t setsize, buflen, nbits; - char *buf, *mask = NULL, *range = NULL; - int ncpus = 2048, rc, c; - - static const struct option longopts[] = { - { "ncpus", 1, NULL, 'n' }, - { "mask", 1, NULL, 'm' }, - { "range", 1, NULL, 'r' }, - { NULL, 0, NULL, 0 } - }; - - while ((c = getopt_long(argc, argv, "n:m:r:", longopts, NULL)) != -1) { - switch(c) { - case 'n': - ncpus = atoi(optarg); - break; - case 'm': - mask = strdup(optarg); - break; - case 'r': - range = strdup(optarg); - break; - default: - goto usage_err; - } - } - - if (!mask && !range) - goto usage_err; - - set = cpuset_alloc(ncpus, &setsize, &nbits); - if (!set) - err(EXIT_FAILURE, "failed to allocate cpu set"); - - /* - fprintf(stderr, "ncpus: %d, cpuset bits: %zd, cpuset bytes: %zd\n", - ncpus, nbits, setsize); - */ - - buflen = 7 * nbits; - buf = malloc(buflen); - if (!buf) - err(EXIT_FAILURE, "failed to allocate cpu set buffer"); - - if (mask) - rc = cpumask_parse(mask, set, setsize); - else - rc = cpulist_parse(range, set, setsize, 0); - - if (rc) - errx(EXIT_FAILURE, "failed to parse string: %s", mask ? : range); - - printf("%-15s = %15s ", mask ? : range, - cpumask_create(buf, buflen, set, setsize)); - printf("[%s]\n", cpulist_create(buf, buflen, set, setsize)); - - free(buf); - free(mask); - free(range); - cpuset_free(set); - - return EXIT_SUCCESS; - -usage_err: - fprintf(stderr, - "usage: %s [--ncpus <num>] --mask <mask> | --range <list>\n", - program_invocation_short_name); - exit(EXIT_FAILURE); -} -#endif diff --git a/utils/lib/crc32.c b/utils/lib/crc32.c deleted file mode 100644 index 824693d..0000000 --- a/utils/lib/crc32.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or - * code or tables extracted from it, as desired without restriction. - * - * First, the polynomial itself and its table of feedback terms. The - * polynomial is - * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 - * - * Note that we take it "backwards" and put the highest-order term in - * the lowest-order bit. The X^32 term is "implied"; the LSB is the - * X^31 term, etc. The X^0 term (usually shown as "+1") results in - * the MSB being 1. - * - * Note that the usual hardware shift register implementation, which - * is what we're using (we're merely optimizing it by doing eight-bit - * chunks at a time) shifts bits into the lowest-order term. In our - * implementation, that means shifting towards the right. Why do we - * do it this way? Because the calculated CRC must be transmitted in - * order from highest-order term to lowest-order term. UARTs transmit - * characters in order from LSB to MSB. By storing the CRC this way, - * we hand it to the UART in the order low-byte to high-byte; the UART - * sends each low-bit to high-bit; and the result is transmission bit - * by bit from highest- to lowest-order term without requiring any bit - * shuffling on our part. Reception works similarly. - * - * The feedback terms table consists of 256, 32-bit entries. Notes - * - * The table can be generated at runtime if desired; code to do so - * is shown later. It might not be obvious, but the feedback - * terms simply represent the results of eight shift/xor opera- - * tions for all combinations of data and CRC register values. - * - * The values must be right-shifted by eight bits by the "updcrc" - * logic; the shift must be unsigned (bring in zeroes). On some - * hardware you could probably optimize the shift in assembler by - * using byte-swap instructions. - * polynomial $edb88320 - * - */ - -#include <stdio.h> - -#include "crc32.h" - - -static const uint32_t crc32_tab[] = { - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, - 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, - 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, - 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, - 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, - 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, - 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, - 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, - 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, - 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, - 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, - 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, - 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, - 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, - 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, - 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, - 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, - 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, - 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, - 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, - 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, - 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, - 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, - 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, - 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, - 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, - 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, - 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, - 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, - 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, - 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, - 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, - 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, - 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, - 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, - 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, - 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, - 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, - 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, - 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, - 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, - 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, - 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, - 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, - 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, - 0x2d02ef8dL -}; - -static inline uint32_t crc32_add_char(uint32_t crc, unsigned char c) -{ - return crc32_tab[(crc ^ c) & 0xff] ^ (crc >> 8); -} - -/* - * This a generic crc32() function, it takes seed as an argument, - * and does __not__ xor at the end. Then individual users can do - * whatever they need. - */ -uint32_t ul_crc32(uint32_t seed, const unsigned char *buf, size_t len) -{ - uint32_t crc = seed; - const unsigned char *p = buf; - - while (len) { - crc = crc32_add_char(crc, *p++); - len--; - } - - return crc; -} - -uint32_t ul_crc32_exclude_offset(uint32_t seed, const unsigned char *buf, size_t len, - size_t exclude_off, size_t exclude_len) -{ - uint32_t crc = seed; - const unsigned char *p = buf; - size_t i; - - for (i = 0; i < len; i++) { - unsigned char x = *p++; - - if (i >= exclude_off && i < exclude_off + exclude_len) - x = 0; - - crc = crc32_add_char(crc, x); - } - - return crc; -} - diff --git a/utils/lib/crc32c.c b/utils/lib/crc32c.c deleted file mode 100644 index 49e7543..0000000 --- a/utils/lib/crc32c.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * This code is from freebsd/sys/libkern/crc32.c - * - * Simplest table-based crc32c. Performance is not important - * for checking crcs on superblocks - */ - -/*- - * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or - * code or tables extracted from it, as desired without restriction. - */ - -#include "crc32c.h" - -static const uint32_t crc32Table[256] = { - 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, - 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, - 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL, - 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L, - 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, - 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, - 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, - 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL, - 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL, - 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L, - 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, - 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, - 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L, - 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL, - 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, - 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, - 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, - 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L, - 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L, - 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L, - 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, - 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, - 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L, - 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L, - 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, - 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, - 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, - 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L, - 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L, - 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L, - 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, - 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, - 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL, - 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L, - 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, - 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, - 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, - 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL, - 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL, - 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L, - 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, - 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, - 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL, - 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L, - 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, - 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, - 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, - 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL, - 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L, - 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL, - 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, - 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, - 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL, - 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L, - 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, - 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, - 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, - 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L, - 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L, - 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL, - 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, - 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, - 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL, - 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L -}; - -/* - *This was singletable_crc32c() in bsd - * - * If you will not be passing crc back into this function to process more bytes, - * the answer is: - * - * crc = crc32c(~0L, buf, size); - * [ crc = crc32c(crc, buf, size); ] - * crc ^= ~0L - * - */ -uint32_t -crc32c(uint32_t crc, const void *buf, size_t size) -{ - const uint8_t *p = buf; - - while (size--) - crc = crc32Table[(crc ^ *p++) & 0xff] ^ (crc >> 8); - - return crc; -} diff --git a/utils/lib/encode.c b/utils/lib/encode.c deleted file mode 100644 index 10b5971..0000000 --- a/utils/lib/encode.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Based on code from libblkid, - * - * Copyright (C) 2008 Kay Sievers <kay.sievers@vrfy.org> - * Copyright (C) 2009 Karel Zak <kzak@redhat.com> - * Copyright (C) 2020 Pali Rohár <pali.rohar@gmail.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include "c.h" -#include "encode.h" - -size_t ul_encode_to_utf8(int enc, unsigned char *dest, size_t len, - const unsigned char *src, size_t count) -{ - size_t i, j; - uint32_t c; - uint16_t c2; - - for (j = i = 0; i < count; i++) { - if (enc == UL_ENCODE_UTF16LE) { - if (i+2 > count) - break; - c = (src[i+1] << 8) | src[i]; - i++; - } else if (enc == UL_ENCODE_UTF16BE) { - if (i+2 > count) - break; - c = (src[i] << 8) | src[i+1]; - i++; - } else if (enc == UL_ENCODE_LATIN1) { - c = src[i]; - } else { - return 0; - } - if ((enc == UL_ENCODE_UTF16LE || enc == UL_ENCODE_UTF16BE) && - c >= 0xD800 && c <= 0xDBFF && i+2 < count) { - if (enc == UL_ENCODE_UTF16LE) - c2 = (src[i+2] << 8) | src[i+1]; - else - c2 = (src[i+1] << 8) | src[i+2]; - if (c2 >= 0xDC00 && c2 <= 0xDFFF) { - c = 0x10000 + ((c - 0xD800) << 10) + (c2 - 0xDC00); - i += 2; - } - } - if (c == 0) { - dest[j] = '\0'; - break; - } - - if (c < 0x80) { - if (j+1 >= len) - break; - dest[j++] = (uint8_t) c; - } else if (c < 0x800) { - if (j+2 >= len) - break; - dest[j++] = (uint8_t) (0xc0 | (c >> 6)); - dest[j++] = (uint8_t) (0x80 | (c & 0x3f)); - } else if (c < 0x10000) { - if (j+3 >= len) - break; - dest[j++] = (uint8_t) (0xe0 | (c >> 12)); - dest[j++] = (uint8_t) (0x80 | ((c >> 6) & 0x3f)); - dest[j++] = (uint8_t) (0x80 | (c & 0x3f)); - } else { - if (j+4 >= len) - break; - dest[j++] = (uint8_t) (0xf0 | (c >> 18)); - dest[j++] = (uint8_t) (0x80 | ((c >> 12) & 0x3f)); - dest[j++] = (uint8_t) (0x80 | ((c >> 6) & 0x3f)); - dest[j++] = (uint8_t) (0x80 | (c & 0x3f)); - } - } - dest[j] = '\0'; - return j; -} diff --git a/utils/lib/env.c b/utils/lib/env.c deleted file mode 100644 index c26a5be..0000000 --- a/utils/lib/env.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Security checks of environment - * Added from shadow-utils package - * by Arkadiusz MiÅ›kiewicz <misiek@pld.ORG.PL> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#ifdef HAVE_SYS_PRCTL_H -#include <sys/prctl.h> -#else -#define PR_GET_DUMPABLE 3 -#endif -#if (!defined(HAVE_PRCTL) && defined(linux)) -#include <sys/syscall.h> -#endif -#include <unistd.h> -#include <sys/types.h> - -#include "env.h" - -#ifndef HAVE_ENVIRON_DECL -extern char **environ; -#endif - -static char * const forbid[] = { - "BASH_ENV=", /* GNU creeping featurism strikes again... */ - "ENV=", - "HOME=", - "IFS=", - "KRB_CONF=", - "LD_", /* anything with the LD_ prefix */ - "LIBPATH=", - "MAIL=", - "NLSPATH=", - "PATH=", - "SHELL=", - "SHLIB_PATH=", - (char *) 0 -}; - -/* these are allowed, but with no slashes inside - (to work around security problems in GNU gettext) */ -static char * const noslash[] = { - "LANG=", - "LANGUAGE=", - "LC_", /* anything with the LC_ prefix */ - (char *) 0 -}; - - -struct ul_env_list { - char *env; - struct ul_env_list *next; -}; - -/* - * Saves @name env.varable to @ls, returns pointer to the new head of the list. - */ -static struct ul_env_list *env_list_add(struct ul_env_list *ls0, const char *str) -{ - struct ul_env_list *ls; - char *p; - size_t sz = 0; - - if (!str || !*str) - return ls0; - - sz = strlen(str) + 1; - p = malloc(sizeof(struct ul_env_list) + sz); - - ls = (struct ul_env_list *) p; - p += sizeof(struct ul_env_list); - memcpy(p, str, sz); - ls->env = p; - - ls->next = ls0; - return ls; -} - -/* - * Use setenv() for all stuff in @ls. - * - * It would be possible to use putenv(), but we want to keep @ls free()-able. - */ -int env_list_setenv(struct ul_env_list *ls) -{ - int rc = 0; - - while (ls && rc == 0) { - if (ls->env) { - char *val = strchr(ls->env, '='); - if (!val) - continue; - *val = '\0'; - rc = setenv(ls->env, val + 1, 0); - *val = '='; - } - ls = ls->next; - } - return rc; -} - -void env_list_free(struct ul_env_list *ls) -{ - while (ls) { - struct ul_env_list *x = ls; - ls = ls->next; - free(x); - } -} - -/* - * Removes unwanted variables from environ[]. If @ls is not NULL than stores - * unwnated variables to the list. - */ -void __sanitize_env(struct ul_env_list **org) -{ - char **envp = environ; - char * const *bad; - char **cur; - int last = 0; - - for (cur = envp; *cur; cur++) - last++; - - for (cur = envp; *cur; cur++) { - for (bad = forbid; *bad; bad++) { - if (strncmp(*cur, *bad, strlen(*bad)) == 0) { - if (org) - *org = env_list_add(*org, *cur); - last = remote_entry(envp, cur - envp, last); - cur--; - break; - } - } - } - - for (cur = envp; *cur; cur++) { - for (bad = noslash; *bad; bad++) { - if (strncmp(*cur, *bad, strlen(*bad)) != 0) - continue; - if (!strchr(*cur, '/')) - continue; /* OK */ - if (org) - *org = env_list_add(*org, *cur); - last = remote_entry(envp, cur - envp, last); - cur--; - break; - } - } -} - -void sanitize_env(void) -{ - __sanitize_env(NULL); -} - -char *safe_getenv(const char *arg) -{ - uid_t ruid = getuid(); - - if (ruid != 0 || (ruid != geteuid()) || (getgid() != getegid())) - return NULL; -#ifdef HAVE_PRCTL - if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 0) - return NULL; -#else -#if (defined(linux) && defined(SYS_prctl)) - if (syscall(SYS_prctl, PR_GET_DUMPABLE, 0, 0, 0, 0) == 0) - return NULL; -#endif -#endif -#ifdef HAVE_SECURE_GETENV -return secure_getenv(arg); -#elif HAVE___SECURE_GETENV - return __secure_getenv(arg); -#else - return getenv(arg); -#endif -} - -#ifdef TEST_PROGRAM -int main(void) -{ - char *const *bad; - char copy[32]; - char *p; - int retval = EXIT_SUCCESS; - struct ul_env_list *removed = NULL; - - for (bad = forbid; *bad; bad++) { - strcpy(copy, *bad); - p = strchr(copy, '='); - if (p) - *p = '\0'; - setenv(copy, copy, 1); - } - - /* removed */ - __sanitize_env(&removed); - - /* check removal */ - for (bad = forbid; *bad; bad++) { - strcpy(copy, *bad); - p = strchr(copy, '='); - if (p) - *p = '\0'; - p = getenv(copy); - if (p) { - warnx("%s was not removed", copy); - retval = EXIT_FAILURE; - } - } - - /* restore removed */ - env_list_setenv(removed); - - /* check restore */ - for (bad = forbid; *bad; bad++) { - strcpy(copy, *bad); - p = strchr(copy, '='); - if (p) - *p = '\0'; - p = getenv(copy); - if (!p) { - warnx("%s was not restored", copy); - retval = EXIT_FAILURE; - } - } - - env_list_free(removed); - - return retval; -} -#endif diff --git a/utils/lib/exec_shell.c b/utils/lib/exec_shell.c deleted file mode 100644 index 18798eb..0000000 --- a/utils/lib/exec_shell.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * exec_shell() - launch a shell, else exit! - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <libgen.h> - -#include "nls.h" -#include "c.h" -#include "xalloc.h" - -#include "exec_shell.h" - -#define DEFAULT_SHELL "/bin/sh" - -void __attribute__((__noreturn__)) exec_shell(void) -{ - const char *shell = getenv("SHELL"); - char *shellc; - const char *shell_basename; - char *arg0; - - if (!shell) - shell = DEFAULT_SHELL; - - shellc = xstrdup(shell); - shell_basename = basename(shellc); - arg0 = xmalloc(strlen(shell_basename) + 2); - arg0[0] = '-'; - strcpy(arg0 + 1, shell_basename); - - execl(shell, arg0, NULL); - errexec(shell); -} diff --git a/utils/lib/fileutils.c b/utils/lib/fileutils.c deleted file mode 100644 index 3ca43c1..0000000 --- a/utils/lib/fileutils.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (C) 2012 Sami Kerola <kerolasa@iki.fi> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <sys/stat.h> -#include <unistd.h> -#include <sys/time.h> -#include <sys/resource.h> - -#include "c.h" -#include "fileutils.h" -#include "pathnames.h" - -int mkstemp_cloexec(char *template) -{ -#ifdef HAVE_MKOSTEMP - return mkostemp(template, O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC); -#else - int fd, old_flags, errno_save; - - fd = mkstemp(template); - if (fd < 0) - return fd; - - old_flags = fcntl(fd, F_GETFD, 0); - if (old_flags < 0) - goto unwind; - if (fcntl(fd, F_SETFD, old_flags | O_CLOEXEC) < 0) - goto unwind; - - return fd; - -unwind: - errno_save = errno; - unlink(template); - close(fd); - errno = errno_save; - - return -1; -#endif -} - -/* Create open temporary file in safe way. Please notice that the - * file permissions are -rw------- by default. */ -int xmkstemp(char **tmpname, const char *dir, const char *prefix) -{ - char *localtmp; - const char *tmpenv; - mode_t old_mode; - int fd, rc; - - /* Some use cases must be capable of being moved atomically - * with rename(2), which is the reason why dir is here. */ - tmpenv = dir ? dir : getenv("TMPDIR"); - if (!tmpenv) - tmpenv = _PATH_TMP; - - rc = asprintf(&localtmp, "%s/%s.XXXXXX", tmpenv, prefix); - if (rc < 0) - return -1; - - old_mode = umask(077); - fd = mkstemp_cloexec(localtmp); - umask(old_mode); - if (fd == -1) { - free(localtmp); - localtmp = NULL; - } - *tmpname = localtmp; - return fd; -} - -int dup_fd_cloexec(int oldfd, int lowfd) -{ - int fd, flags, errno_save; - -#ifdef F_DUPFD_CLOEXEC - fd = fcntl(oldfd, F_DUPFD_CLOEXEC, lowfd); - if (fd >= 0) - return fd; -#endif - - fd = dup(oldfd); - if (fd < 0) - return fd; - - flags = fcntl(fd, F_GETFD); - if (flags < 0) - goto unwind; - if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) - goto unwind; - - return fd; - -unwind: - errno_save = errno; - close(fd); - errno = errno_save; - - return -1; -} - -/* - * portable getdtablesize() - */ -int get_fd_tabsize(void) -{ - int m; - -#if defined(HAVE_GETDTABLESIZE) - m = getdtablesize(); -#elif defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE) - struct rlimit rl; - - getrlimit(RLIMIT_NOFILE, &rl); - m = rl.rlim_cur; -#elif defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX) - m = sysconf(_SC_OPEN_MAX); -#else - m = OPEN_MAX; -#endif - return m; -} - -static inline int in_set(int x, const int set[], size_t setsz) -{ - size_t i; - - for (i = 0; i < setsz; i++) { - if (set[i] == x) - return 1; - } - return 0; -} - -void close_all_fds(const int exclude[], size_t exsz) -{ - struct dirent *d; - DIR *dir; - - dir = opendir(_PATH_PROC_FDDIR); - if (dir) { - while ((d = xreaddir(dir))) { - char *end; - int fd; - - errno = 0; - fd = strtol(d->d_name, &end, 10); - - if (errno || end == d->d_name || !end || *end) - continue; - if (dirfd(dir) == fd) - continue; - if (in_set(fd, exclude, exsz)) - continue; - close(fd); - } - closedir(dir); - } else { - int fd, tbsz = get_fd_tabsize(); - - for (fd = 0; fd < tbsz; fd++) { - if (!in_set(fd, exclude, exsz)) - close(fd); - } - } -} - -#ifdef TEST_PROGRAM_FILEUTILS -int main(int argc, char *argv[]) -{ - if (argc < 2) - errx(EXIT_FAILURE, "Usage %s --{mkstemp,close-fds}", argv[0]); - - if (strcmp(argv[1], "--mkstemp") == 0) { - FILE *f; - char *tmpname; - f = xfmkstemp(&tmpname, NULL, "test"); - unlink(tmpname); - free(tmpname); - fclose(f); - - } else if (strcmp(argv[1], "--close-fds") == 0) { - static const int wanted_fds[] = { - STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO - }; - - ignore_result( dup(STDIN_FILENO) ); - ignore_result( dup(STDIN_FILENO) ); - ignore_result( dup(STDIN_FILENO) ); - - close_all_fds(wanted_fds, ARRAY_SIZE(wanted_fds)); - } - return EXIT_SUCCESS; -} -#endif - - -int mkdir_p(const char *path, mode_t mode) -{ - char *p, *dir; - int rc = 0; - - if (!path || !*path) - return -EINVAL; - - dir = p = strdup(path); - if (!dir) - return -ENOMEM; - - if (*p == '/') - p++; - - while (p && *p) { - char *e = strchr(p, '/'); - if (e) - *e = '\0'; - if (*p) { - rc = mkdir(dir, mode); - if (rc && errno != EEXIST) - break; - rc = 0; - } - if (!e) - break; - *e = '/'; - p = e + 1; - } - - free(dir); - return rc; -} - -/* returns basename and keeps dirname in the @path, if @path is "/" (root) - * then returns empty string */ -char *stripoff_last_component(char *path) -{ - char *p = path ? strrchr(path, '/') : NULL; - - if (!p) - return NULL; - *p = '\0'; - return p + 1; -} diff --git a/utils/lib/idcache.c b/utils/lib/idcache.c deleted file mode 100644 index 5550223..0000000 --- a/utils/lib/idcache.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * No copyright is claimed. This code is in the public domain; do with - * it what you wish. - * - * Written by Karel Zak <kzak@redhat.com> - */ -#include <wchar.h> -#include <pwd.h> -#include <grp.h> -#include <sys/types.h> - -#include "c.h" -#include "idcache.h" - -struct identry *get_id(struct idcache *ic, unsigned long int id) -{ - struct identry *ent; - - if (!ic) - return NULL; - - for (ent = ic->ent; ent; ent = ent->next) { - if (ent->id == id) - return ent; - } - - return NULL; -} - -struct idcache *new_idcache(void) -{ - return calloc(1, sizeof(struct idcache)); -} - -void free_idcache(struct idcache *ic) -{ - struct identry *ent = ic->ent; - - while (ent) { - struct identry *next = ent->next; - free(ent->name); - free(ent); - ent = next; - } - - free(ic); -} - -static void add_id(struct idcache *ic, char *name, unsigned long int id) -{ - struct identry *ent, *x; - int w = 0; - - ent = calloc(1, sizeof(struct identry)); - if (!ent) - return; - ent->id = id; - - if (name) { -#ifdef HAVE_WIDECHAR - wchar_t wc[LOGIN_NAME_MAX + 1]; - - if (mbstowcs(wc, name, LOGIN_NAME_MAX) > 0) { - wc[LOGIN_NAME_MAX] = '\0'; - w = wcswidth(wc, LOGIN_NAME_MAX); - } - else -#endif - w = strlen(name); - } - - /* note, we ignore names with non-printable widechars */ - if (w > 0) { - ent->name = strdup(name); - if (!ent->name) { - free(ent); - return; - } - } else { - if (asprintf(&ent->name, "%lu", id) < 0) { - free(ent); - return; - } - } - - for (x = ic->ent; x && x->next; x = x->next); - - if (x) - x->next = ent; - else - ic->ent = ent; - - if (w <= 0) - w = ent->name ? strlen(ent->name) : 0; - ic->width = ic->width < w ? w : ic->width; -} - -void add_uid(struct idcache *cache, unsigned long int id) -{ - struct identry *ent= get_id(cache, id); - - if (!ent) { - struct passwd *pw = getpwuid((uid_t) id); - add_id(cache, pw ? pw->pw_name : NULL, id); - } -} - -void add_gid(struct idcache *cache, unsigned long int id) -{ - struct identry *ent = get_id(cache, id); - - if (!ent) { - struct group *gr = getgrgid((gid_t) id); - add_id(cache, gr ? gr->gr_name : NULL, id); - } -} - diff --git a/utils/lib/ismounted.c b/utils/lib/ismounted.c deleted file mode 100644 index 9a20b23..0000000 --- a/utils/lib/ismounted.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - * ismounted.c --- Check to see if the filesystem was mounted - * - * Copyright (C) 1995,1996,1997,1998,1999,2000,2008 Theodore Ts'o. - * - * This file may be redistributed under the terms of the GNU Public - * License. - */ -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <errno.h> -#include <fcntl.h> -#ifdef HAVE_MNTENT_H -#include <mntent.h> -#endif -#include <string.h> -#include <sys/stat.h> -#include <ctype.h> -#include <sys/param.h> - -#ifndef __linux__ -# ifdef HAVE_SYS_UCRED_H -# include <sys/ucred.h> -# endif -# ifdef HAVE_SYS_MOUNT_H -# include <sys/mount.h> -# endif -#endif - -#include "pathnames.h" -#include "strutils.h" -#include "ismounted.h" -#include "c.h" -#ifdef __linux__ -# include "loopdev.h" -#endif - - - -#ifdef HAVE_MNTENT_H -/* - * Helper function which checks a file in /etc/mtab format to see if a - * filesystem is mounted. Returns an error if the file doesn't exist - * or can't be opened. - */ -static int check_mntent_file(const char *mtab_file, const char *file, - int *mount_flags, char *mtpt, int mtlen) -{ - struct mntent *mnt; - struct stat st_buf; - int retval = 0; - dev_t file_dev=0, file_rdev=0; - ino_t file_ino=0; - FILE *f; - int fd; - - *mount_flags = 0; - if ((f = setmntent (mtab_file, "r")) == NULL) - return errno; - - if (stat(file, &st_buf) == 0) { - if (S_ISBLK(st_buf.st_mode)) { -#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */ - file_rdev = st_buf.st_rdev; -#endif /* __GNU__ */ - } else { - file_dev = st_buf.st_dev; - file_ino = st_buf.st_ino; - } - } - - while ((mnt = getmntent (f)) != NULL) { - if (mnt->mnt_fsname[0] != '/') - continue; - if (strcmp(file, mnt->mnt_fsname) == 0) - break; - if (stat(mnt->mnt_fsname, &st_buf) != 0) - continue; - - if (S_ISBLK(st_buf.st_mode)) { -#ifndef __GNU__ - if (file_rdev && file_rdev == st_buf.st_rdev) - break; -#ifdef __linux__ - /* maybe the file is loopdev backing file */ - if (file_dev - && major(st_buf.st_rdev) == LOOPDEV_MAJOR - && loopdev_is_used(mnt->mnt_fsname, file, 0, 0, 0)) - break; -#endif /* __linux__ */ -#endif /* __GNU__ */ - } else { - if (file_dev && ((file_dev == st_buf.st_dev) && - (file_ino == st_buf.st_ino))) - break; - } - } - - if (mnt == NULL) { -#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */ - /* - * Do an extra check to see if this is the root device. We - * can't trust /etc/mtab, and /proc/mounts will only list - * /dev/root for the root filesystem. Argh. Instead we - * check if the given device has the same major/minor number - * as the device that the root directory is on. - */ - if (file_rdev && stat("/", &st_buf) == 0 && - st_buf.st_dev == file_rdev) { - *mount_flags = MF_MOUNTED; - if (mtpt) - xstrncpy(mtpt, "/", mtlen); - goto is_root; - } -#endif /* __GNU__ */ - goto errout; - } -#ifndef __GNU__ /* The GNU hurd is deficient; what else is new? */ - /* Validate the entry in case /etc/mtab is out of date */ - /* - * We need to be paranoid, because some broken distributions - * (read: Slackware) don't initialize /etc/mtab before checking - * all of the non-root filesystems on the disk. - */ - if (stat(mnt->mnt_dir, &st_buf) < 0) { - retval = errno; - if (retval == ENOENT) { -#ifdef DEBUG - printf("Bogus entry in %s! (%s does not exist)\n", - mtab_file, mnt->mnt_dir); -#endif /* DEBUG */ - retval = 0; - } - goto errout; - } - if (file_rdev && (st_buf.st_dev != file_rdev)) { -#ifdef DEBUG - printf("Bogus entry in %s! (%s not mounted on %s)\n", - mtab_file, file, mnt->mnt_dir); -#endif /* DEBUG */ - goto errout; - } -#endif /* __GNU__ */ - *mount_flags = MF_MOUNTED; - -#ifdef MNTOPT_RO - /* Check to see if the ro option is set */ - if (hasmntopt(mnt, MNTOPT_RO)) - *mount_flags |= MF_READONLY; -#endif - - if (mtpt) - xstrncpy(mtpt, mnt->mnt_dir, mtlen); - /* - * Check to see if we're referring to the root filesystem. - * If so, do a manual check to see if we can open /etc/mtab - * read/write, since if the root is mounted read/only, the - * contents of /etc/mtab may not be accurate. - */ - if (!strcmp(mnt->mnt_dir, "/")) { -is_root: -#define TEST_FILE "/.ismount-test-file" - *mount_flags |= MF_ISROOT; - fd = open(TEST_FILE, O_RDWR|O_CREAT|O_CLOEXEC, 0600); - if (fd < 0) { - if (errno == EROFS) - *mount_flags |= MF_READONLY; - } else - close(fd); - (void) unlink(TEST_FILE); - } - retval = 0; -errout: - endmntent (f); - return retval; -} - -static int check_mntent(const char *file, int *mount_flags, - char *mtpt, int mtlen) -{ - int retval; - -#ifdef DEBUG - retval = check_mntent_file("/tmp/mtab", file, mount_flags, - mtpt, mtlen); - if (retval == 0) - return 0; -#endif /* DEBUG */ -#ifdef __linux__ - retval = check_mntent_file("/proc/mounts", file, mount_flags, - mtpt, mtlen); - if (retval == 0 && (*mount_flags != 0)) - return 0; - if (access("/proc/mounts", R_OK) == 0) { - *mount_flags = 0; - return retval; - } -#endif /* __linux__ */ -#if defined(MOUNTED) || defined(_PATH_MOUNTED) -#ifndef MOUNTED -#define MOUNTED _PATH_MOUNTED -#endif /* MOUNTED */ - retval = check_mntent_file(MOUNTED, file, mount_flags, mtpt, mtlen); - return retval; -#else - *mount_flags = 0; - return 0; -#endif /* defined(MOUNTED) || defined(_PATH_MOUNTED) */ -} - -#else -#if defined(HAVE_GETMNTINFO) - -static int check_getmntinfo(const char *file, int *mount_flags, - char *mtpt, int mtlen) -{ - struct statfs *mp; - int len, n; - const char *s1; - char *s2; - - n = getmntinfo(&mp, MNT_NOWAIT); - if (n == 0) - return errno; - - len = sizeof(_PATH_DEV) - 1; - s1 = file; - if (strncmp(_PATH_DEV, s1, len) == 0) - s1 += len; - - *mount_flags = 0; - while (--n >= 0) { - s2 = mp->f_mntfromname; - if (strncmp(_PATH_DEV, s2, len) == 0) { - s2 += len - 1; - *s2 = 'r'; - } - if (strcmp(s1, s2) == 0 || strcmp(s1, &s2[1]) == 0) { - *mount_flags = MF_MOUNTED; - break; - } - ++mp; - } - if (mtpt) - xstrncpy(mtpt, mp->f_mntonname, mtlen); - return 0; -} -#endif /* HAVE_GETMNTINFO */ -#endif /* HAVE_MNTENT_H */ - -/* - * Check to see if we're dealing with the swap device. - */ -static int is_swap_device(const char *file) -{ - FILE *f; - char buf[1024], *cp; - dev_t file_dev; - struct stat st_buf; - int ret = 0; - - file_dev = 0; -#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */ - if ((stat(file, &st_buf) == 0) && - S_ISBLK(st_buf.st_mode)) - file_dev = st_buf.st_rdev; -#endif /* __GNU__ */ - - if (!(f = fopen("/proc/swaps", "r" UL_CLOEXECSTR))) - return 0; - /* Skip the first line */ - if (!fgets(buf, sizeof(buf), f)) - goto leave; - if (*buf && strncmp(buf, "Filename\t", 9) != 0) - /* Linux <=2.6.19 contained a bug in the /proc/swaps - * code where the header would not be displayed - */ - goto valid_first_line; - - while (fgets(buf, sizeof(buf), f)) { -valid_first_line: - if ((cp = strchr(buf, ' ')) != NULL) - *cp = 0; - if ((cp = strchr(buf, '\t')) != NULL) - *cp = 0; - if (strcmp(buf, file) == 0) { - ret++; - break; - } -#ifndef __GNU__ - if (file_dev && (stat(buf, &st_buf) == 0) && - S_ISBLK(st_buf.st_mode) && - file_dev == st_buf.st_rdev) { - ret++; - break; - } -#endif /* __GNU__ */ - } - -leave: - fclose(f); - return ret; -} - - -/* - * check_mount_point() fills determines if the device is mounted or otherwise - * busy, and fills in mount_flags with one or more of the following flags: - * MF_MOUNTED, MF_ISROOT, MF_READONLY, MF_SWAP, and MF_BUSY. If mtpt is - * non-NULL, the directory where the device is mounted is copied to where mtpt - * is pointing, up to mtlen characters. - */ -#ifdef __TURBOC__ - #pragma argsused -#endif -int check_mount_point(const char *device, int *mount_flags, - char *mtpt, int mtlen) -{ - int retval = 0; - - if (is_swap_device(device)) { - *mount_flags = MF_MOUNTED | MF_SWAP; - if (mtpt && mtlen) - xstrncpy(mtpt, "[SWAP]", mtlen); - } else { -#ifdef HAVE_MNTENT_H - retval = check_mntent(device, mount_flags, mtpt, mtlen); -#else -#ifdef HAVE_GETMNTINFO - retval = check_getmntinfo(device, mount_flags, mtpt, mtlen); -#else -#ifdef __GNUC__ - #warning "Can't use getmntent or getmntinfo to check for mounted filesystems!" -#endif - *mount_flags = 0; -#endif /* HAVE_GETMNTINFO */ -#endif /* HAVE_MNTENT_H */ - } - if (retval) - return retval; - -#ifdef __linux__ /* This only works on Linux 2.6+ systems */ - { - struct stat st_buf; - int fd; - if ((stat(device, &st_buf) != 0) || - !S_ISBLK(st_buf.st_mode)) - return 0; - fd = open(device, O_RDONLY|O_EXCL|O_CLOEXEC); - if (fd < 0) { - if (errno == EBUSY) - *mount_flags |= MF_BUSY; - } else - close(fd); - } -#endif - - return 0; -} - -int is_mounted(const char *file) -{ - int retval; - int mount_flags = 0; - - retval = check_mount_point(file, &mount_flags, NULL, 0); - if (retval) - return 0; - return mount_flags & MF_MOUNTED; -} - -#ifdef TEST_PROGRAM_ISMOUNTED -int main(int argc, char **argv) -{ - int flags = 0; - char devname[PATH_MAX]; - - if (argc < 2) { - fprintf(stderr, "Usage: %s device\n", argv[0]); - return EXIT_FAILURE; - } - - if (check_mount_point(argv[1], &flags, devname, sizeof(devname)) == 0 && - (flags & MF_MOUNTED)) { - if (flags & MF_SWAP) - printf("used swap device\n"); - else - printf("mounted on %s\n", devname); - return EXIT_SUCCESS; - } - - printf("not mounted\n"); - return EXIT_FAILURE; -} -#endif /* DEBUG */ diff --git a/utils/lib/langinfo.c b/utils/lib/langinfo.c deleted file mode 100644 index a200085..0000000 --- a/utils/lib/langinfo.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * This is callback solution for systems without nl_langinfo(), this function - * returns hardcoded and on locale setting indepndent value. - * - * See langinfo.h man page for more details. - * - * No copyright is claimed. This code is in the public domain; do with - * it what you wish. - * - * Copyright (C) 2010 Karel Zak <kzak@redhat.com> - */ -#include "nls.h" - -char *langinfo_fallback(nl_item item) -{ - switch (item) { - case CODESET: - return "ISO-8859-1"; - case THOUSEP: - return ","; - case D_T_FMT: - case ERA_D_T_FMT: - return "%a %b %e %H:%M:%S %Y"; - case D_FMT: - case ERA_D_FMT: - return "%m/%d/%y"; - case T_FMT: - case ERA_T_FMT: - return "%H:%M:%S"; - case T_FMT_AMPM: - return "%I:%M:%S %p"; - case AM_STR: - return "AM"; - case PM_STR: - return "PM"; - case DAY_1: - return "Sunday"; - case DAY_2: - return "Monday"; - case DAY_3: - return "Tuesday"; - case DAY_4: - return "Wednesday"; - case DAY_5: - return "Thursday"; - case DAY_6: - return "Friday"; - case DAY_7: - return "Saturday"; - case ABDAY_1: - return "Sun"; - case ABDAY_2: - return "Mon"; - case ABDAY_3: - return "Tue"; - case ABDAY_4: - return "Wed"; - case ABDAY_5: - return "Thu"; - case ABDAY_6: - return "Fri"; - case ABDAY_7: - return "Sat"; - case MON_1: - return "January"; - case MON_2: - return "February"; - case MON_3: - return "March"; - case MON_4: - return "April"; - case MON_5: - return "May"; - case MON_6: - return "June"; - case MON_7: - return "July"; - case MON_8: - return "August"; - case MON_9: - return "September"; - case MON_10: - return "October"; - case MON_11: - return "November"; - case MON_12: - return "December"; - case ABMON_1: - return "Jan"; - case ABMON_2: - return "Feb"; - case ABMON_3: - return "Mar"; - case ABMON_4: - return "Apr"; - case ABMON_5: - return "May"; - case ABMON_6: - return "Jun"; - case ABMON_7: - return "Jul"; - case ABMON_8: - return "Aug"; - case ABMON_9: - return "Sep"; - case ABMON_10: - return "Oct"; - case ABMON_11: - return "Nov"; - case ABMON_12: - return "Dec"; - case ALT_DIGITS: - return "\0\0\0\0\0\0\0\0\0\0"; - case CRNCYSTR: - return "-"; - case YESEXPR: - return "^[yY]"; - case NOEXPR: - return "^[nN]"; - default: - return ""; - } -} - diff --git a/utils/lib/linux_version.c b/utils/lib/linux_version.c deleted file mode 100644 index 137bbe7..0000000 --- a/utils/lib/linux_version.c +++ /dev/null @@ -1,71 +0,0 @@ -#include <stdio.h> -#include <sys/utsname.h> - -#include "c.h" -#include "linux_version.h" - -int get_linux_version (void) -{ - static int kver = -1; - struct utsname uts; - int x = 0, y = 0, z = 0; - int n; - - if (kver != -1) - return kver; - if (uname(&uts)) - return kver = 0; - - n = sscanf(uts.release, "%d.%d.%d", &x, &y, &z); - if (n < 1 || n > 3) - return kver = 0; - - return kver = KERNEL_VERSION(x, y, z); -} - -#ifdef TEST_PROGRAM_LINUXVERSION -# include <stdlib.h> -int main(int argc, char *argv[]) -{ - int rc = EXIT_FAILURE; - - if (argc == 1) { - printf("Linux version: %d\n", get_linux_version()); - rc = EXIT_SUCCESS; - - } else if (argc == 5) { - const char *oper = argv[1]; - - int x = atoi(argv[2]), - y = atoi(argv[3]), - z = atoi(argv[4]); - int kver = get_linux_version(); - int uver = KERNEL_VERSION(x, y, z); - - if (strcmp(oper, "==") == 0) - rc = kver == uver; - else if (strcmp(oper, "<=") == 0) - rc = kver <= uver; - else if (strcmp(oper, ">=") == 0) - rc = kver >= uver; - else - errx(EXIT_FAILURE, "unsupported operator"); - - if (rc) - printf("match\n"); - else - printf("not-match [%d %s %d, x.y.z: %d.%d.%d]\n", - kver, oper, uver, x, y, z); - - rc = rc ? EXIT_SUCCESS : EXIT_FAILURE; - - } else - fprintf(stderr, "Usage:\n" - " %s [<oper> <x> <y> <z>]\n" - "supported operators:\n" - " ==, <=, >=\n", - program_invocation_short_name); - - return rc; -} -#endif diff --git a/utils/lib/loopdev.c b/utils/lib/loopdev.c deleted file mode 100644 index be4e486..0000000 --- a/utils/lib/loopdev.c +++ /dev/null @@ -1,1914 +0,0 @@ - -/* - * No copyright is claimed. This code is in the public domain; do with - * it what you wish. - * - * Written by Karel Zak <kzak@redhat.com> - * - * -- based on mount/losetup.c - * - * Simple library for work with loop devices. - * - * - requires kernel 2.6.x - * - reads info from /sys/block/loop<N>/loop/<attr> (new kernels) - * - reads info by ioctl - * - supports *unlimited* number of loop devices - * - supports /dev/xloop<N> as well as /dev/xloop/<N> - * - minimize overhead (fd, loopinfo, ... are shared for all operations) - * - setup (associate device and backing file) - * - delete (dis-associate file) - * - old LOOP_{SET,GET}_STATUS (32bit) ioctls are unsupported - * - extendible - */ -#include <stdio.h> -#include <stdint.h> -#include <string.h> -#include <ctype.h> -#include <fcntl.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <sys/stat.h> -#include <sys/mman.h> -#include <inttypes.h> -#include <dirent.h> - -#include "linux_version.h" -#include "c.h" -#include "sysfs.h" -#include "pathnames.h" -#include "loopdev.h" -#include "canonicalize.h" -#include "blkdev.h" -#include "debug.h" - -/* - * Debug stuff (based on include/debug.h) - */ -static UL_DEBUG_DEFINE_MASK(loopdev); -UL_DEBUG_DEFINE_MASKNAMES(loopdev) = UL_DEBUG_EMPTY_MASKNAMES; - -#define XLOOPDEV_DEBUG_INIT (1 << 1) -#define XLOOPDEV_DEBUG_CXT (1 << 2) -#define XLOOPDEV_DEBUG_ITER (1 << 3) -#define XLOOPDEV_DEBUG_SETUP (1 << 4) - -#define DBG(m, x) __UL_DBG(loopdev, XLOOPDEV_DEBUG_, m, x) -#define ON_DBG(m, x) __UL_DBG_CALL(loopdev, XLOOPDEV_DEBUG_, m, x) - -#define UL_DEBUG_CURRENT_MASK UL_DEBUG_MASK(loopdev) -#include "debugobj.h" - -static void loopdev_init_debug(void) -{ - if (loopdev_debug_mask) - return; - __UL_INIT_DEBUG_FROM_ENV(loopdev, XLOOPDEV_DEBUG_, 0, XLOOPDEV_DEBUG); -} - -/* - * see loopcxt_init() - */ -#define loopcxt_ioctl_enabled(_lc) (!((_lc)->flags & LOOPDEV_FL_NOIOCTL)) -#define loopcxt_sysfs_available(_lc) (!((_lc)->flags & LOOPDEV_FL_NOSYSFS)) \ - && !loopcxt_ioctl_enabled(_lc) - -/* - * @lc: context - * @device: device name, absolute device path or NULL to reset the current setting - * - * Sets device, absolute paths (e.g. "/dev/xloop<N>") are unchanged, device - * names ("xloop<N>") are converted to the path (/dev/xloop<N> or to - * /dev/xloop/<N>) - * - * This sets the device name, but does not check if the device exists! - * - * Returns: <0 on error, 0 on success - */ -int loopcxt_set_device(struct loopdev_cxt *lc, const char *device) -{ - if (!lc) - return -EINVAL; - - if (lc->fd >= 0) { - close(lc->fd); - DBG(CXT, ul_debugobj(lc, "closing old open fd")); - } - lc->fd = -1; - lc->mode = 0; - lc->blocksize = 0; - lc->has_info = 0; - lc->info_failed = 0; - *lc->device = '\0'; - memset(&lc->info, 0, sizeof(lc->info)); - - /* set new */ - if (device) { - if (*device != '/') { - const char *dir = _PATH_DEV; - - /* compose device name for /dev/xloop<n> or /dev/xloop/<n> */ - if (lc->flags & LOOPDEV_FL_DEVSUBDIR) { - if (strlen(device) <= 5) - return -1; - device += 5; - dir = _PATH_DEV_LOOP "/"; /* _PATH_DEV uses tailing slash */ - } - snprintf(lc->device, sizeof(lc->device), "%s%s", - dir, device); - } else - xstrncpy(lc->device, device, sizeof(lc->device)); - - DBG(CXT, ul_debugobj(lc, "%s name assigned", device)); - } - - ul_unref_path(lc->sysfs); - lc->sysfs = NULL; - return 0; -} - -int loopcxt_has_device(struct loopdev_cxt *lc) -{ - return lc && *lc->device; -} - -/* - * @lc: context - * @flags: LOOPDEV_FL_* flags - * - * Initialize loop handler. - * - * We have two sets of the flags: - * - * * LOOPDEV_FL_* flags control loopcxt_* API behavior - * - * * LO_FLAGS_* are kernel flags used for LOOP_{SET,GET}_STAT64 ioctls - * - * Note about LOOPDEV_FL_{RDONLY,RDWR} flags. These flags are used for open(2) - * syscall to open loop device. By default is the device open read-only. - * - * The exception is loopcxt_setup_device(), where the device is open read-write - * if LO_FLAGS_READ_ONLY flags is not set (see loopcxt_set_flags()). - * - * Returns: <0 on error, 0 on success. - */ -int loopcxt_init(struct loopdev_cxt *lc, int flags) -{ - int rc; - struct stat st; - struct loopdev_cxt dummy = UL_LOOPDEVCXT_EMPTY; - - if (!lc) - return -EINVAL; - - loopdev_init_debug(); - DBG(CXT, ul_debugobj(lc, "initialize context")); - - memcpy(lc, &dummy, sizeof(dummy)); - lc->flags = flags; - - rc = loopcxt_set_device(lc, NULL); - if (rc) - return rc; - - if (stat(_PATH_SYS_BLOCK, &st) || !S_ISDIR(st.st_mode)) { - lc->flags |= LOOPDEV_FL_NOSYSFS; - lc->flags &= ~LOOPDEV_FL_NOIOCTL; - DBG(CXT, ul_debugobj(lc, "init: disable /sys usage")); - } - - if (!(lc->flags & LOOPDEV_FL_NOSYSFS) && - get_linux_version() >= KERNEL_VERSION(2,6,37)) { - /* - * Use only sysfs for basic information about loop devices - */ - lc->flags |= LOOPDEV_FL_NOIOCTL; - DBG(CXT, ul_debugobj(lc, "init: ignore ioctls")); - } - - if (!(lc->flags & LOOPDEV_FL_CONTROL) && !stat(_PATH_DEV_LOOPCTL, &st)) { - lc->flags |= LOOPDEV_FL_CONTROL; - DBG(CXT, ul_debugobj(lc, "init: xloop-control detected ")); - } - - return 0; -} - -/* - * @lc: context - * - * Deinitialize loop context - */ -void loopcxt_deinit(struct loopdev_cxt *lc) -{ - int errsv = errno; - - if (!lc) - return; - - DBG(CXT, ul_debugobj(lc, "de-initialize")); - - free(lc->filename); - lc->filename = NULL; - - ignore_result( loopcxt_set_device(lc, NULL) ); - loopcxt_deinit_iterator(lc); - - errno = errsv; -} - -/* - * @lc: context - * - * Returns newly allocated device path. - */ -char *loopcxt_strdup_device(struct loopdev_cxt *lc) -{ - if (!lc || !*lc->device) - return NULL; - return strdup(lc->device); -} - -/* - * @lc: context - * - * Returns pointer device name in the @lc struct. - */ -const char *loopcxt_get_device(struct loopdev_cxt *lc) -{ - return lc && *lc->device ? lc->device : NULL; -} - -/* - * @lc: context - * - * Returns pointer to the sysfs context (see lib/sysfs.c) - */ -static struct path_cxt *loopcxt_get_sysfs(struct loopdev_cxt *lc) -{ - if (!lc || !*lc->device || (lc->flags & LOOPDEV_FL_NOSYSFS)) - return NULL; - - if (!lc->sysfs) { - dev_t devno = sysfs_devname_to_devno(lc->device); - if (!devno) { - DBG(CXT, ul_debugobj(lc, "sysfs: failed devname to devno")); - return NULL; - } - - lc->sysfs = ul_new_sysfs_path(devno, NULL, NULL); - if (!lc->sysfs) - DBG(CXT, ul_debugobj(lc, "sysfs: init failed")); - } - - return lc->sysfs; -} - -/* - * @lc: context - * - * Returns: file descriptor to the open loop device or <0 on error. The mode - * depends on LOOPDEV_FL_{RDWR,RDONLY} context flags. Default is - * read-only. - */ -int loopcxt_get_fd(struct loopdev_cxt *lc) -{ - if (!lc || !*lc->device) - return -EINVAL; - - if (lc->fd < 0) { - lc->mode = lc->flags & LOOPDEV_FL_RDWR ? O_RDWR : O_RDONLY; - lc->fd = open(lc->device, lc->mode | O_CLOEXEC); - DBG(CXT, ul_debugobj(lc, "open %s [%s]: %m", lc->device, - lc->flags & LOOPDEV_FL_RDWR ? "rw" : "ro")); - } - return lc->fd; -} - -int loopcxt_set_fd(struct loopdev_cxt *lc, int fd, int mode) -{ - if (!lc) - return -EINVAL; - - lc->fd = fd; - lc->mode = mode; - return 0; -} - -/* - * @lc: context - * @flags: LOOPITER_FL_* flags - * - * Iterator can be used to scan list of the free or used loop devices. - * - * Returns: <0 on error, 0 on success - */ -int loopcxt_init_iterator(struct loopdev_cxt *lc, int flags) -{ - struct loopdev_iter *iter; - struct stat st; - - if (!lc) - return -EINVAL; - - - iter = &lc->iter; - DBG(ITER, ul_debugobj(iter, "initialize")); - - /* always zeroize - */ - memset(iter, 0, sizeof(*iter)); - iter->ncur = -1; - iter->flags = flags; - iter->default_check = 1; - - if (!lc->extra_check) { - /* - * Check for /dev/xloop/<N> subdirectory - */ - if (!(lc->flags & LOOPDEV_FL_DEVSUBDIR) && - stat(_PATH_DEV_LOOP, &st) == 0 && S_ISDIR(st.st_mode)) - lc->flags |= LOOPDEV_FL_DEVSUBDIR; - - lc->extra_check = 1; - } - return 0; -} - -/* - * @lc: context - * - * Returns: <0 on error, 0 on success - */ -int loopcxt_deinit_iterator(struct loopdev_cxt *lc) -{ - struct loopdev_iter *iter; - - if (!lc) - return -EINVAL; - - iter = &lc->iter; - DBG(ITER, ul_debugobj(iter, "de-initialize")); - - free(iter->minors); - if (iter->proc) - fclose(iter->proc); - if (iter->sysblock) - closedir(iter->sysblock); - - memset(iter, 0, sizeof(*iter)); - return 0; -} - -/* - * Same as loopcxt_set_device, but also checks if the device is - * associated with any file. - * - * Returns: <0 on error, 0 on success, 1 device does not match with - * LOOPITER_FL_{USED,FREE} flags. - */ -static int loopiter_set_device(struct loopdev_cxt *lc, const char *device) -{ - int rc = loopcxt_set_device(lc, device); - int used; - - if (rc) - return rc; - - if (!(lc->iter.flags & LOOPITER_FL_USED) && - !(lc->iter.flags & LOOPITER_FL_FREE)) - return 0; /* caller does not care about device status */ - - if (!is_loopdev(lc->device)) { - DBG(ITER, ul_debugobj(&lc->iter, "%s does not exist", lc->device)); - return -errno; - } - - DBG(ITER, ul_debugobj(&lc->iter, "%s exist", lc->device)); - - used = loopcxt_get_offset(lc, NULL) == 0; - - if ((lc->iter.flags & LOOPITER_FL_USED) && used) - return 0; - - if ((lc->iter.flags & LOOPITER_FL_FREE) && !used) - return 0; - - DBG(ITER, ul_debugobj(&lc->iter, "failed to use %s device", lc->device)); - - ignore_result( loopcxt_set_device(lc, NULL) ); - return 1; -} - -static int cmpnum(const void *p1, const void *p2) -{ - return (((* (const int *) p1) > (* (const int *) p2)) - - ((* (const int *) p1) < (* (const int *) p2))); -} - -/* - * The classic scandir() is more expensive and less portable. - * We needn't full loop device names -- loop numbers (loop<N>) - * are enough. - */ -static int loop_scandir(const char *dirname, int **ary, int hasprefix) -{ - DIR *dir; - struct dirent *d; - unsigned int n, count = 0, arylen = 0; - - if (!dirname || !ary) - return 0; - - DBG(ITER, ul_debug("scan dir: %s", dirname)); - - dir = opendir(dirname); - if (!dir) - return 0; - free(*ary); - *ary = NULL; - - while((d = readdir(dir))) { -#ifdef _DIRENT_HAVE_D_TYPE - if (d->d_type != DT_BLK && d->d_type != DT_UNKNOWN && - d->d_type != DT_LNK) - continue; -#endif - if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) - continue; - - if (hasprefix) { - /* /dev/xloop<N> */ - if (sscanf(d->d_name, "xloop%u", &n) != 1) - continue; - } else { - /* /dev/xloop/<N> */ - char *end = NULL; - - errno = 0; - n = strtol(d->d_name, &end, 10); - if (d->d_name == end || (end && *end) || errno) - continue; - } - if (n < LOOPDEV_DEFAULT_NNODES) - continue; /* ignore xloop<0..7> */ - - if (count + 1 > arylen) { - int *tmp; - - arylen += 1; - - tmp = realloc(*ary, arylen * sizeof(int)); - if (!tmp) { - free(*ary); - *ary = NULL; - closedir(dir); - return -1; - } - *ary = tmp; - } - if (*ary) - (*ary)[count++] = n; - } - if (count && *ary) - qsort(*ary, count, sizeof(int), cmpnum); - - closedir(dir); - return count; -} - -/* - * Set the next *used* loop device according to /proc/partitions. - * - * Loop devices smaller than 512 bytes are invisible for this function. - */ -static int loopcxt_next_from_proc(struct loopdev_cxt *lc) -{ - struct loopdev_iter *iter = &lc->iter; - char buf[BUFSIZ]; - - DBG(ITER, ul_debugobj(iter, "scan /proc/partitions")); - - if (!iter->proc) - iter->proc = fopen(_PATH_PROC_PARTITIONS, "r" UL_CLOEXECSTR); - if (!iter->proc) - return 1; - - while (fgets(buf, sizeof(buf), iter->proc)) { - unsigned int m; - char name[128 + 1]; - - - if (sscanf(buf, " %u %*s %*s %128[^\n ]", - &m, name) != 2 || m != LOOPDEV_MAJOR) - continue; - - DBG(ITER, ul_debugobj(iter, "checking %s", name)); - - if (loopiter_set_device(lc, name) == 0) - return 0; - } - - return 1; -} - -/* - * Set the next *used* loop device according to - * /sys/block/loopN/loop/backing_file (kernel >= 2.6.37 is required). - * - * This is preferred method. - */ -static int loopcxt_next_from_sysfs(struct loopdev_cxt *lc) -{ - struct loopdev_iter *iter = &lc->iter; - struct dirent *d; - int fd; - - DBG(ITER, ul_debugobj(iter, "scanning /sys/block")); - - if (!iter->sysblock) - iter->sysblock = opendir(_PATH_SYS_BLOCK); - - if (!iter->sysblock) - return 1; - - fd = dirfd(iter->sysblock); - - while ((d = readdir(iter->sysblock))) { - char name[NAME_MAX + 18 + 1]; - struct stat st; - - DBG(ITER, ul_debugobj(iter, "check %s", d->d_name)); - - if (strcmp(d->d_name, ".") == 0 - || strcmp(d->d_name, "..") == 0 - || strncmp(d->d_name, "xloop", 4) != 0) - continue; - - snprintf(name, sizeof(name), "%s/xloop/backing_file", d->d_name); - if (fstatat(fd, name, &st, 0) != 0) - continue; - - if (loopiter_set_device(lc, d->d_name) == 0) - return 0; - } - - return 1; -} - -/* - * @lc: context, has to initialized by loopcxt_init_iterator() - * - * Returns: 0 on success, -1 on error, 1 at the end of scanning. The details - * about the current loop device are available by - * loopcxt_get_{fd,backing_file,device,offset, ...} functions. - */ -int loopcxt_next(struct loopdev_cxt *lc) -{ - struct loopdev_iter *iter; - - if (!lc) - return -EINVAL; - - - iter = &lc->iter; - if (iter->done) - return 1; - - DBG(ITER, ul_debugobj(iter, "next")); - - /* A) Look for used loop devices in /proc/partitions ("losetup -a" only) - */ - if (iter->flags & LOOPITER_FL_USED) { - int rc; - - if (loopcxt_sysfs_available(lc)) - rc = loopcxt_next_from_sysfs(lc); - else - rc = loopcxt_next_from_proc(lc); - if (rc == 0) - return 0; - goto done; - } - - /* B) Classic way, try first eight loop devices (default number - * of loop devices). This is enough for 99% of all cases. - */ - if (iter->default_check) { - DBG(ITER, ul_debugobj(iter, "next: default check")); - for (++iter->ncur; iter->ncur < LOOPDEV_DEFAULT_NNODES; - iter->ncur++) { - char name[16]; - snprintf(name, sizeof(name), "xloop%d", iter->ncur); - - if (loopiter_set_device(lc, name) == 0) - return 0; - } - iter->default_check = 0; - } - - /* C) the worst possibility, scan whole /dev or /dev/xloop/<N> - */ - if (!iter->minors) { - DBG(ITER, ul_debugobj(iter, "next: scanning /dev")); - iter->nminors = (lc->flags & LOOPDEV_FL_DEVSUBDIR) ? - loop_scandir(_PATH_DEV_LOOP, &iter->minors, 0) : - loop_scandir(_PATH_DEV, &iter->minors, 1); - iter->ncur = -1; - } - for (++iter->ncur; iter->ncur < iter->nminors; iter->ncur++) { - char name[16]; - snprintf(name, sizeof(name), "xloop%d", iter->minors[iter->ncur]); - - if (loopiter_set_device(lc, name) == 0) - return 0; - } -done: - loopcxt_deinit_iterator(lc); - return 1; -} - -/* - * @device: path to device - */ -int is_loopdev(const char *device) -{ - struct stat st; - - if (device && stat(device, &st) == 0 && - S_ISBLK(st.st_mode) && - major(st.st_rdev) == LOOPDEV_MAJOR) - return 1; - - errno = ENODEV; - return 0; -} - -/* - * @lc: context - * - * Returns result from LOOP_GET_STAT64 ioctl or NULL on error. - */ -struct loop_info64 *loopcxt_get_info(struct loopdev_cxt *lc) -{ - int fd; - - if (!lc || lc->info_failed) { - errno = EINVAL; - return NULL; - } - errno = 0; - if (lc->has_info) - return &lc->info; - - fd = loopcxt_get_fd(lc); - if (fd < 0) - return NULL; - - if (ioctl(fd, LOOP_GET_STATUS64, &lc->info) == 0) { - lc->has_info = 1; - lc->info_failed = 0; - DBG(CXT, ul_debugobj(lc, "reading loop_info64 OK")); - return &lc->info; - } - - lc->info_failed = 1; - DBG(CXT, ul_debugobj(lc, "reading loop_info64 FAILED")); - - return NULL; -} - -/* - * @lc: context - * - * Returns (allocated) string with path to the file associated - * with the current loop device. - */ -char *loopcxt_get_backing_file(struct loopdev_cxt *lc) -{ - struct path_cxt *sysfs = loopcxt_get_sysfs(lc); - char *res = NULL; - - if (sysfs) - /* - * This is always preferred, the loop_info64 - * has too small buffer for the filename. - */ - ul_path_read_string(sysfs, &res, "xloop/backing_file"); - - if (!res && loopcxt_ioctl_enabled(lc)) { - struct loop_info64 *lo = loopcxt_get_info(lc); - - if (lo) { - lo->lo_file_name[LO_NAME_SIZE - 2] = '*'; - lo->lo_file_name[LO_NAME_SIZE - 1] = '\0'; - res = strdup((char *) lo->lo_file_name); - } - } - - DBG(CXT, ul_debugobj(lc, "get_backing_file [%s]", res)); - return res; -} - -/* - * @lc: context - * @offset: returns offset number for the given device - * - * Returns: <0 on error, 0 on success - */ -int loopcxt_get_offset(struct loopdev_cxt *lc, uint64_t *offset) -{ - struct path_cxt *sysfs = loopcxt_get_sysfs(lc); - int rc = -EINVAL; - - if (sysfs) - rc = ul_path_read_u64(sysfs, offset, "xloop/offset"); - - if (rc && loopcxt_ioctl_enabled(lc)) { - struct loop_info64 *lo = loopcxt_get_info(lc); - if (lo) { - if (offset) - *offset = lo->lo_offset; - rc = 0; - } else - rc = -errno; - } - - DBG(CXT, ul_debugobj(lc, "get_offset [rc=%d]", rc)); - return rc; -} - -/* - * @lc: context - * @blocksize: returns logical blocksize for the given device - * - * Returns: <0 on error, 0 on success - */ -int loopcxt_get_blocksize(struct loopdev_cxt *lc, uint64_t *blocksize) -{ - struct path_cxt *sysfs = loopcxt_get_sysfs(lc); - int rc = -EINVAL; - - if (sysfs) - rc = ul_path_read_u64(sysfs, blocksize, "queue/logical_block_size"); - - /* Fallback based on BLKSSZGET ioctl */ - if (rc) { - int fd = loopcxt_get_fd(lc); - int sz = 0; - - if (fd < 0) - return -EINVAL; - rc = blkdev_get_sector_size(fd, &sz); - if (rc) - return rc; - - *blocksize = sz; - } - - DBG(CXT, ul_debugobj(lc, "get_blocksize [rc=%d]", rc)); - return rc; -} - -/* - * @lc: context - * @sizelimit: returns size limit for the given device - * - * Returns: <0 on error, 0 on success - */ -int loopcxt_get_sizelimit(struct loopdev_cxt *lc, uint64_t *size) -{ - struct path_cxt *sysfs = loopcxt_get_sysfs(lc); - int rc = -EINVAL; - - if (sysfs) - rc = ul_path_read_u64(sysfs, size, "xloop/sizelimit"); - - if (rc && loopcxt_ioctl_enabled(lc)) { - struct loop_info64 *lo = loopcxt_get_info(lc); - if (lo) { - if (size) - *size = lo->lo_sizelimit; - rc = 0; - } else - rc = -errno; - } - - DBG(CXT, ul_debugobj(lc, "get_sizelimit [rc=%d]", rc)); - return rc; -} - -/* - * @lc: context - * @devno: returns encryption type - * - * Cryptoloop is DEPRECATED! - * - * Returns: <0 on error, 0 on success - */ -int loopcxt_get_encrypt_type(struct loopdev_cxt *lc, uint32_t *type) -{ - struct loop_info64 *lo = loopcxt_get_info(lc); - int rc; - - /* not provided by sysfs */ - if (lo) { - if (type) - *type = lo->lo_encrypt_type; - rc = 0; - } else - rc = -errno; - - DBG(CXT, ul_debugobj(lc, "get_encrypt_type [rc=%d]", rc)); - return rc; -} - -/* - * @file_fmt_type_str: file format type string. - * @file_fmt_type: returns file format type from the given file format string. - * - * Returns: <0 on error, 0 on success - */ -int parse_file_fmt_type(const char *file_fmt_type_str, uint32_t *file_fmt_type) -{ - int rc = 0; - - if (!strcmp(file_fmt_type_str, "RAW")) - *file_fmt_type = LO_FILE_FMT_RAW; - else if (!strcmp(file_fmt_type_str, "QCOW")) - *file_fmt_type = LO_FILE_FMT_QCOW; - else if (!strcmp(file_fmt_type_str, "VDI")) - *file_fmt_type = LO_FILE_FMT_VDI; - else if (!strcmp(file_fmt_type_str, "VMDK")) - *file_fmt_type = LO_FILE_FMT_VMDK; - else - rc = -EINVAL; - - return rc; -} - -/* - * @lc: context - * @file_fmt_type: returns file format type of the given device - * - * Returns: <0 on error, 0 on success - */ -int loopcxt_get_file_fmt_type(struct loopdev_cxt *lc, uint32_t* file_fmt_type) -{ - struct path_cxt *sysfs = loopcxt_get_sysfs(lc); - int rc = 0; - - if (sysfs) { - /* check if file_fmt_type is accessible and supported by the kernel module */ - char* file_fmt_str = NULL; - if (ul_path_read_string(sysfs, &file_fmt_str, "xloop/file_fmt_type") == 0) - rc = parse_file_fmt_type(file_fmt_str, file_fmt_type); - } else - rc = -errno; - - if (rc != 0 && loopcxt_ioctl_enabled(lc)) { - struct loop_info64 *lo = loopcxt_get_info(lc); - if (lo) - *file_fmt_type = lo->lo_file_fmt_type; - } - - return 0; -} - -/* - * @lc: context - * - * Returns (allocated) string with file format type of the current loop device. - */ -char *loopcxt_get_file_fmt_type_string(struct loopdev_cxt *lc) -{ - struct path_cxt *sysfs = loopcxt_get_sysfs(lc); - char *res = NULL; - - if (sysfs) - ul_path_read_string(sysfs, &res, "xloop/file_fmt_type"); - - DBG(CXT, ul_debugobj(lc, "xloopcxt_get_file_fmt_type_string [%s]", res)); - return res; -} - -/* - * @lc: context - * @devno: returns crypt name - * - * Cryptoloop is DEPRECATED! - * - * Returns: <0 on error, 0 on success - */ -const char *loopcxt_get_crypt_name(struct loopdev_cxt *lc) -{ - struct loop_info64 *lo = loopcxt_get_info(lc); - - if (lo) - return (char *) lo->lo_crypt_name; - - DBG(CXT, ul_debugobj(lc, "get_crypt_name failed")); - return NULL; -} - -/* - * @lc: context - * @devno: returns backing file devno - * - * Returns: <0 on error, 0 on success - */ -int loopcxt_get_backing_devno(struct loopdev_cxt *lc, dev_t *devno) -{ - struct loop_info64 *lo = loopcxt_get_info(lc); - int rc; - - if (lo) { - if (devno) - *devno = lo->lo_device; - rc = 0; - } else - rc = -errno; - - DBG(CXT, ul_debugobj(lc, "get_backing_devno [rc=%d]", rc)); - return rc; -} - -/* - * @lc: context - * @ino: returns backing file inode - * - * Returns: <0 on error, 0 on success - */ -int loopcxt_get_backing_inode(struct loopdev_cxt *lc, ino_t *ino) -{ - struct loop_info64 *lo = loopcxt_get_info(lc); - int rc; - - if (lo) { - if (ino) - *ino = lo->lo_inode; - rc = 0; - } else - rc = -errno; - - DBG(CXT, ul_debugobj(lc, "get_backing_inode [rc=%d]", rc)); - return rc; -} - -/* - * Check if the kernel supports partitioned loop devices. - * - * Notes: - * - kernels < 3.2 support partitioned loop devices and PT scanning - * only if max_part= module parameter is non-zero - * - * - kernels >= 3.2 always support partitioned loop devices - * - * - kernels >= 3.2 always support BLKPG_{ADD,DEL}_PARTITION ioctls - * - * - kernels >= 3.2 enable PT scanner only if max_part= is non-zero or if the - * LO_FLAGS_PARTSCAN flag is set for the device. The PT scanner is disabled - * by default. - * - * See kernel commit e03c8dd14915fabc101aa495828d58598dc5af98. - */ -int loopmod_supports_partscan(void) -{ - int rc, ret = 0; - FILE *f; - - if (get_linux_version() >= KERNEL_VERSION(3,2,0)) - return 1; - - f = fopen("/sys/module/loop/parameters/max_part", "r" UL_CLOEXECSTR); - if (!f) - return 0; - rc = fscanf(f, "%d", &ret); - fclose(f); - return rc == 1 ? ret : 0; -} - -/* - * @lc: context - * - * Returns: 1 if the partscan flags is set *or* (for old kernels) partitions - * scanning is enabled for all loop devices. - */ -int loopcxt_is_partscan(struct loopdev_cxt *lc) -{ - struct path_cxt *sysfs = loopcxt_get_sysfs(lc); - - if (sysfs) { - /* kernel >= 3.2 */ - int fl; - if (ul_path_read_s32(sysfs, &fl, "xloop/partscan") == 0) - return fl; - } - - /* old kernels (including kernels without loopN/loop/<flags> directory */ - return loopmod_supports_partscan(); -} - -/* - * @lc: context - * - * Returns: 1 if the autoclear flags is set. - */ -int loopcxt_is_autoclear(struct loopdev_cxt *lc) -{ - struct path_cxt *sysfs = loopcxt_get_sysfs(lc); - - if (sysfs) { - int fl; - if (ul_path_read_s32(sysfs, &fl, "xloop/autoclear") == 0) - return fl; - } - - if (loopcxt_ioctl_enabled(lc)) { - struct loop_info64 *lo = loopcxt_get_info(lc); - if (lo) - return lo->lo_flags & LO_FLAGS_AUTOCLEAR; - } - return 0; -} - -/* - * @lc: context - * - * Returns: 1 if the readonly flags is set. - */ -int loopcxt_is_readonly(struct loopdev_cxt *lc) -{ - struct path_cxt *sysfs = loopcxt_get_sysfs(lc); - - if (sysfs) { - int fl; - if (ul_path_read_s32(sysfs, &fl, "ro") == 0) - return fl; - } - - if (loopcxt_ioctl_enabled(lc)) { - struct loop_info64 *lo = loopcxt_get_info(lc); - if (lo) - return lo->lo_flags & LO_FLAGS_READ_ONLY; - } - return 0; -} - -/* - * @lc: context - * - * Returns: 1 if the dio flags is set. - */ -int loopcxt_is_dio(struct loopdev_cxt *lc) -{ - struct path_cxt *sysfs = loopcxt_get_sysfs(lc); - - if (sysfs) { - int fl; - if (ul_path_read_s32(sysfs, &fl, "xloop/dio") == 0) - return fl; - } - if (loopcxt_ioctl_enabled(lc)) { - struct loop_info64 *lo = loopcxt_get_info(lc); - if (lo) - return lo->lo_flags & LO_FLAGS_DIRECT_IO; - } - return 0; -} - -/* - * @lc: context - * @st: backing file stat or NULL - * @backing_file: filename - * @offset: offset (use LOOPDEV_FL_OFFSET if specified) - * @sizelimit: size limit (use LOOPDEV_FL_SIZELIMIT if specified) - * @flags: LOOPDEV_FL_{OFFSET,SIZELIMIT} - * - * Returns 1 if the current @lc loopdev is associated with the given backing - * file. Note that the preferred way is to use devno and inode number rather - * than filename. The @backing_file filename is poor solution usable in case - * that you don't have rights to call stat(). - * - * LOOPDEV_FL_SIZELIMIT requires LOOPDEV_FL_OFFSET being set as well. - * - * Don't forget that old kernels provide very restricted (in size) backing - * filename by LOOP_GET_STAT64 ioctl only. - */ -int loopcxt_is_used(struct loopdev_cxt *lc, - struct stat *st, - const char *backing_file, - uint64_t offset, - uint64_t sizelimit, - int flags) -{ - ino_t ino = 0; - dev_t dev = 0; - - if (!lc) - return 0; - - DBG(CXT, ul_debugobj(lc, "checking %s vs. %s", - loopcxt_get_device(lc), - backing_file)); - - if (st && loopcxt_get_backing_inode(lc, &ino) == 0 && - loopcxt_get_backing_devno(lc, &dev) == 0) { - - if (ino == st->st_ino && dev == st->st_dev) - goto found; - - /* don't use filename if we have devno and inode */ - return 0; - } - - /* poor man's solution */ - if (backing_file) { - char *name = loopcxt_get_backing_file(lc); - int rc = name && strcmp(name, backing_file) == 0; - - free(name); - if (rc) - goto found; - } - - return 0; -found: - if (flags & LOOPDEV_FL_OFFSET) { - uint64_t off = 0; - - int rc = loopcxt_get_offset(lc, &off) == 0 && off == offset; - - if (rc && flags & LOOPDEV_FL_SIZELIMIT) { - uint64_t sz = 0; - - return loopcxt_get_sizelimit(lc, &sz) == 0 && sz == sizelimit; - } - return rc; - } - return 1; -} - -/* - * The setting is removed by loopcxt_set_device() loopcxt_next()! - */ -int loopcxt_set_offset(struct loopdev_cxt *lc, uint64_t offset) -{ - if (!lc) - return -EINVAL; - lc->info.lo_offset = offset; - - DBG(CXT, ul_debugobj(lc, "set offset=%jd", offset)); - return 0; -} - -/* - * The setting is removed by loopcxt_set_device() loopcxt_next()! - */ -int loopcxt_set_sizelimit(struct loopdev_cxt *lc, uint64_t sizelimit) -{ - if (!lc) - return -EINVAL; - lc->info.lo_sizelimit = sizelimit; - - DBG(CXT, ul_debugobj(lc, "set sizelimit=%jd", sizelimit)); - return 0; -} - -/* - * The blocksize will be used by loopcxt_set_device(). For already exiting - * devices use loopcxt_ioctl_blocksize(). - * - * The setting is removed by loopcxt_set_device() loopcxt_next()! - */ -int loopcxt_set_blocksize(struct loopdev_cxt *lc, uint64_t blocksize) -{ - if (!lc) - return -EINVAL; - lc->blocksize = blocksize; - - DBG(CXT, ul_debugobj(lc, "set blocksize=%jd", blocksize)); - return 0; -} - -/* - * @lc: context - * @file_fmt_type: kernel LO_FILE_FMT_{RAW,QCOW,VDI,VMDK} flags - * - * The setting is removed by loopcxt_set_device() loopcxt_next()! - * - * Returns: 0 on success, <0 on error. - */ -int loopcxt_set_file_fmt_type(struct loopdev_cxt *lc, uint32_t file_fmt_type) { - if (!lc) - return -EINVAL; - lc->info.lo_file_fmt_type = file_fmt_type; - - DBG(CXT, ul_debugobj(lc, "set file_fmt_type=%u", (unsigned) file_fmt_type)); - return 0; -} - -/* - * @lc: context - * @flags: kernel LO_FLAGS_{READ_ONLY,USE_AOPS,AUTOCLEAR} flags - * - * The setting is removed by loopcxt_set_device() loopcxt_next()! - * - * Returns: 0 on success, <0 on error. - */ -int loopcxt_set_flags(struct loopdev_cxt *lc, uint32_t flags) -{ - if (!lc) - return -EINVAL; - lc->info.lo_flags = flags; - - DBG(CXT, ul_debugobj(lc, "set flags=%u", (unsigned) flags)); - return 0; -} - -/* - * @lc: context - * @filename: backing file path (the path will be canonicalized) - * - * The setting is removed by loopcxt_set_device() loopcxt_next()! - * - * Returns: 0 on success, <0 on error. - */ -int loopcxt_set_backing_file(struct loopdev_cxt *lc, const char *filename) -{ - if (!lc) - return -EINVAL; - - lc->filename = canonicalize_path(filename); - if (!lc->filename) - return -errno; - - xstrncpy((char *)lc->info.lo_file_name, lc->filename, LO_NAME_SIZE); - - DBG(CXT, ul_debugobj(lc, "set backing file=%s", lc->info.lo_file_name)); - return 0; -} - -/* - * In kernels prior to v3.9, if the offset or sizelimit options - * are used, the block device's size won't be synced automatically. - * blockdev --getsize64 and filesystems will use the backing - * file size until the block device has been re-opened or the - * LOOP_SET_CAPACITY ioctl is called to sync the sizes. - * - * Since mount -oloop uses the LO_FLAGS_AUTOCLEAR option and passes - * the open file descriptor to the mount system call, we need to use - * the ioctl. Calling losetup directly doesn't have this problem since - * it closes the device when it exits and whatever consumes the device - * next will re-open it, causing the resync. - */ -static int loopcxt_check_size(struct loopdev_cxt *lc, int file_fd) -{ - uint64_t size, expected_size; - int dev_fd; - struct stat st; - - if (!lc->info.lo_offset && !lc->info.lo_sizelimit) - return 0; - - if (fstat(file_fd, &st)) { - DBG(CXT, ul_debugobj(lc, "failed to fstat backing file")); - return -errno; - } - if (S_ISBLK(st.st_mode)) { - if (blkdev_get_size(file_fd, - (unsigned long long *) &expected_size)) { - DBG(CXT, ul_debugobj(lc, "failed to determine device size")); - return -errno; - } - } else - expected_size = st.st_size; - - if (expected_size == 0 || expected_size <= lc->info.lo_offset) { - DBG(CXT, ul_debugobj(lc, "failed to determine expected size")); - return 0; /* ignore this error */ - } - - if (lc->info.lo_offset > 0) - expected_size -= lc->info.lo_offset; - - if (lc->info.lo_sizelimit > 0 && lc->info.lo_sizelimit < expected_size) - expected_size = lc->info.lo_sizelimit; - - dev_fd = loopcxt_get_fd(lc); - if (dev_fd < 0) { - DBG(CXT, ul_debugobj(lc, "failed to get loop FD")); - return -errno; - } - - if (blkdev_get_size(dev_fd, (unsigned long long *) &size)) { - DBG(CXT, ul_debugobj(lc, "failed to determine loopdev size")); - return -errno; - } - - /* It's block device, so, align to 512-byte sectors */ - if (expected_size % 512) { - DBG(CXT, ul_debugobj(lc, "expected size misaligned to 512-byte sectors")); - expected_size = (expected_size >> 9) << 9; - } - - if (expected_size != size) { - DBG(CXT, ul_debugobj(lc, "warning: loopdev and expected " - "size mismatch (%ju/%ju)", - size, expected_size)); - - if (loopcxt_ioctl_capacity(lc)) { - /* ioctl not available */ - if (errno == ENOTTY || errno == EINVAL) - errno = ERANGE; - return -errno; - } - - if (blkdev_get_size(dev_fd, (unsigned long long *) &size)) - return -errno; - - if (expected_size != size) { - errno = ERANGE; - DBG(CXT, ul_debugobj(lc, "failed to set loopdev size, " - "size: %ju, expected: %ju", - size, expected_size)); - return -errno; - } - } - - return 0; -} - -/* - * @lc: context - * - * Associate the current device (see loopcxt_{set,get}_device()) with - * a file (see loopcxt_set_backing_file()). - * - * The device is initialized read-write by default. If you want read-only - * device then set LO_FLAGS_READ_ONLY by loopcxt_set_flags(). The LOOPDEV_FL_* - * flags are ignored and modified according to LO_FLAGS_*. - * - * If the device is already open by loopcxt_get_fd() then this setup device - * function will re-open the device to fix read/write mode. - * - * The device is also initialized read-only if the backing file is not - * possible to open read-write (e.g. read-only FS). - * - * Returns: <0 on error, 0 on success. - */ -int loopcxt_setup_device(struct loopdev_cxt *lc) -{ - int file_fd, dev_fd, mode = O_RDWR, rc = -1, cnt = 0, err, again; - int errsv = 0; - - if (!lc || !*lc->device || !lc->filename) - return -EINVAL; - - DBG(SETUP, ul_debugobj(lc, "device setup requested")); - - /* - * Open backing file and device - */ - if (lc->info.lo_flags & LO_FLAGS_READ_ONLY) - mode = O_RDONLY; - - if ((file_fd = open(lc->filename, mode | O_CLOEXEC)) < 0) { - if (mode != O_RDONLY && (errno == EROFS || errno == EACCES)) - file_fd = open(lc->filename, mode = O_RDONLY); - - if (file_fd < 0) { - DBG(SETUP, ul_debugobj(lc, "open backing file failed: %m")); - return -errno; - } - } - DBG(SETUP, ul_debugobj(lc, "backing file open: OK")); - - if (lc->fd != -1 && lc->mode != mode) { - DBG(SETUP, ul_debugobj(lc, "closing already open device (mode mismatch)")); - close(lc->fd); - lc->fd = -1; - lc->mode = 0; - } - - if (mode == O_RDONLY) { - lc->flags |= LOOPDEV_FL_RDONLY; /* open() mode */ - lc->info.lo_flags |= LO_FLAGS_READ_ONLY; /* kernel loopdev mode */ - } else { - lc->flags |= LOOPDEV_FL_RDWR; /* open() mode */ - lc->info.lo_flags &= ~LO_FLAGS_READ_ONLY; - lc->flags &= ~LOOPDEV_FL_RDONLY; - } - - do { - errno = 0; - dev_fd = loopcxt_get_fd(lc); - if (dev_fd >= 0 || lc->control_ok == 0) - break; - if (errno != EACCES && errno != ENOENT) - break; - /* We have permissions to open /dev/xloop-control, but open - * /dev/xloopN failed with EACCES, it's probably because udevd - * does not applied chown yet. Let's wait a moment. */ - xusleep(25000); - } while (cnt++ < 16); - - if (dev_fd < 0) { - rc = -errno; - goto err; - } - - DBG(SETUP, ul_debugobj(lc, "device open: OK")); - - /* - * Set FD - */ - if (ioctl(dev_fd, LOOP_SET_FD, file_fd) < 0) { - rc = -errno; - errsv = errno; - DBG(SETUP, ul_debugobj(lc, "LOOP_SET_FD failed: %m")); - goto err; - } - - DBG(SETUP, ul_debugobj(lc, "LOOP_SET_FD: OK")); - - if (lc->blocksize > 0 - && (rc = loopcxt_ioctl_blocksize(lc, lc->blocksize)) < 0) { - errsv = -rc; - goto err; - } - - do { - err = ioctl(dev_fd, LOOP_SET_STATUS64, &lc->info); - again = err && errno == EAGAIN; - if (again) - xusleep(250000); - } while (again); - if (err) { - rc = -errno; - errsv = errno; - DBG(SETUP, ul_debugobj(lc, "LOOP_SET_STATUS64 failed: %m")); - goto err; - } - - DBG(SETUP, ul_debugobj(lc, "LOOP_SET_STATUS64: OK")); - - if ((rc = loopcxt_check_size(lc, file_fd))) - goto err; - - close(file_fd); - - memset(&lc->info, 0, sizeof(lc->info)); - lc->has_info = 0; - lc->info_failed = 0; - - DBG(SETUP, ul_debugobj(lc, "success [rc=0]")); - return 0; -err: - if (file_fd >= 0) - close(file_fd); - if (dev_fd >= 0 && rc != -EBUSY) - ioctl(dev_fd, LOOP_CLR_FD, 0); - if (errsv) - errno = errsv; - - DBG(SETUP, ul_debugobj(lc, "failed [rc=%d]", rc)); - return rc; -} - -/* - * @lc: context - * - * Update status of the current device (see loopcxt_{set,get}_device()). - * - * Note that once initialized, kernel accepts only selected changes: - * LO_FLAGS_AUTOCLEAR and LO_FLAGS_PARTSCAN - * For more see linux/drivers/block/loop.c:loop_set_status() - * - * Returns: <0 on error, 0 on success. - */ -int loopcxt_ioctl_status(struct loopdev_cxt *lc) -{ - int dev_fd, rc = -1, err, again; - - errno = 0; - dev_fd = loopcxt_get_fd(lc); - - if (dev_fd < 0) { - rc = -errno; - return rc; - } - DBG(SETUP, ul_debugobj(lc, "device open: OK")); - - do { - err = ioctl(dev_fd, LOOP_SET_STATUS64, &lc->info); - again = err && errno == EAGAIN; - if (again) - xusleep(250000); - } while (again); - if (err) { - rc = -errno; - DBG(SETUP, ul_debugobj(lc, "LOOP_SET_STATUS64 failed: %m")); - return rc; - } - - DBG(SETUP, ul_debugobj(lc, "LOOP_SET_STATUS64: OK")); - return 0; -} - -int loopcxt_ioctl_capacity(struct loopdev_cxt *lc) -{ - int fd = loopcxt_get_fd(lc); - - if (fd < 0) - return -EINVAL; - - /* Kernels prior to v2.6.30 don't support this ioctl */ - if (ioctl(fd, LOOP_SET_CAPACITY, 0) < 0) { - int rc = -errno; - DBG(CXT, ul_debugobj(lc, "LOOP_SET_CAPACITY failed: %m")); - return rc; - } - - DBG(CXT, ul_debugobj(lc, "capacity set")); - return 0; -} - -int loopcxt_ioctl_dio(struct loopdev_cxt *lc, unsigned long use_dio) -{ - int fd = loopcxt_get_fd(lc); - - if (fd < 0) - return -EINVAL; - - /* Kernels prior to v4.4 don't support this ioctl */ - if (ioctl(fd, LOOP_SET_DIRECT_IO, use_dio) < 0) { - int rc = -errno; - DBG(CXT, ul_debugobj(lc, "LOOP_SET_DIRECT_IO failed: %m")); - return rc; - } - - DBG(CXT, ul_debugobj(lc, "direct io set")); - return 0; -} - -/* - * Kernel uses "unsigned long" as ioctl arg, but we use u64 for all sizes to - * keep loopdev internal API simple. - */ -int loopcxt_ioctl_blocksize(struct loopdev_cxt *lc, uint64_t blocksize) -{ - int fd = loopcxt_get_fd(lc); - - if (fd < 0) - return -EINVAL; - - /* Kernels prior to v4.14 don't support this ioctl */ - if (ioctl(fd, LOOP_SET_BLOCK_SIZE, (unsigned long) blocksize) < 0) { - int rc = -errno; - DBG(CXT, ul_debugobj(lc, "LOOP_SET_BLOCK_SIZE failed: %m")); - return rc; - } - - DBG(CXT, ul_debugobj(lc, "logical block size set")); - return 0; -} - -int loopcxt_delete_device(struct loopdev_cxt *lc) -{ - int fd = loopcxt_get_fd(lc); - - if (fd < 0) - return -EINVAL; - - if (ioctl(fd, LOOP_CLR_FD, 0) < 0) { - DBG(CXT, ul_debugobj(lc, "LOOP_CLR_FD failed: %m")); - return -errno; - } - - DBG(CXT, ul_debugobj(lc, "device removed")); - return 0; -} - -int loopcxt_add_device(struct loopdev_cxt *lc) -{ - int rc = -EINVAL; - int ctl, nr = -1; - const char *p, *dev = loopcxt_get_device(lc); - - if (!dev) - goto done; - - if (!(lc->flags & LOOPDEV_FL_CONTROL)) { - rc = -ENOSYS; - goto done; - } - - p = strrchr(dev, '/'); - if (!p || (sscanf(p, "/xloop%d", &nr) != 1 && sscanf(p, "/%d", &nr) != 1) - || nr < 0) - goto done; - - ctl = open(_PATH_DEV_LOOPCTL, O_RDWR|O_CLOEXEC); - if (ctl >= 0) { - DBG(CXT, ul_debugobj(lc, "add_device %d", nr)); - rc = ioctl(ctl, LOOP_CTL_ADD, nr); - close(ctl); - } - lc->control_ok = rc >= 0 ? 1 : 0; -done: - DBG(CXT, ul_debugobj(lc, "add_device done [rc=%d]", rc)); - return rc; -} - -/* - * Note that LOOP_CTL_GET_FREE ioctl is supported since kernel 3.1. In older - * kernels we have to check all loop devices to found unused one. - * - * See kernel commit 770fe30a46a12b6fb6b63fbe1737654d28e8484. - */ -int loopcxt_find_unused(struct loopdev_cxt *lc) -{ - int rc = -1; - - DBG(CXT, ul_debugobj(lc, "find_unused requested")); - - if (lc->flags & LOOPDEV_FL_CONTROL) { - int ctl; - - DBG(CXT, ul_debugobj(lc, "using xloop-control")); - - ctl = open(_PATH_DEV_LOOPCTL, O_RDWR|O_CLOEXEC); - if (ctl >= 0) - rc = ioctl(ctl, LOOP_CTL_GET_FREE); - if (rc >= 0) { - char name[16]; - snprintf(name, sizeof(name), "xloop%d", rc); - - rc = loopiter_set_device(lc, name); - } - lc->control_ok = ctl >= 0 && rc == 0 ? 1 : 0; - if (ctl >= 0) - close(ctl); - DBG(CXT, ul_debugobj(lc, "find_unused by xloop-control [rc=%d]", rc)); - } - - if (rc < 0) { - DBG(CXT, ul_debugobj(lc, "using loop scan")); - rc = loopcxt_init_iterator(lc, LOOPITER_FL_FREE); - if (rc) - return rc; - - rc = loopcxt_next(lc); - loopcxt_deinit_iterator(lc); - DBG(CXT, ul_debugobj(lc, "find_unused by scan [rc=%d]", rc)); - } - return rc; -} - - - -/* - * Return: TRUE/FALSE - */ -int loopdev_is_autoclear(const char *device) -{ - struct loopdev_cxt lc; - int rc; - - if (!device) - return 0; - - rc = loopcxt_init(&lc, 0); - if (!rc) - rc = loopcxt_set_device(&lc, device); - if (!rc) - rc = loopcxt_is_autoclear(&lc); - - loopcxt_deinit(&lc); - return rc; -} - -char *loopdev_get_backing_file(const char *device) -{ - struct loopdev_cxt lc; - char *res = NULL; - - if (!device) - return NULL; - if (loopcxt_init(&lc, 0)) - return NULL; - if (loopcxt_set_device(&lc, device) == 0) - res = loopcxt_get_backing_file(&lc); - - loopcxt_deinit(&lc); - return res; -} - -/* - * Returns: TRUE/FALSE - */ -int loopdev_is_used(const char *device, const char *filename, - uint64_t offset, uint64_t sizelimit, int flags) -{ - struct loopdev_cxt lc; - struct stat st; - int rc = 0; - - if (!device || !filename) - return 0; - - rc = loopcxt_init(&lc, 0); - if (!rc) - rc = loopcxt_set_device(&lc, device); - if (rc) - return rc; - - rc = !stat(filename, &st); - rc = loopcxt_is_used(&lc, rc ? &st : NULL, filename, offset, sizelimit, flags); - - loopcxt_deinit(&lc); - return rc; -} - -int loopdev_delete(const char *device) -{ - struct loopdev_cxt lc; - int rc; - - if (!device) - return -EINVAL; - - rc = loopcxt_init(&lc, 0); - if (!rc) - rc = loopcxt_set_device(&lc, device); - if (!rc) - rc = loopcxt_delete_device(&lc); - loopcxt_deinit(&lc); - return rc; -} - -/* - * Returns: 0 = success, < 0 error, 1 not found - */ -int loopcxt_find_by_backing_file(struct loopdev_cxt *lc, const char *filename, - uint64_t offset, uint64_t sizelimit, int flags) -{ - int rc, hasst; - struct stat st; - - if (!filename) - return -EINVAL; - - hasst = !stat(filename, &st); - - rc = loopcxt_init_iterator(lc, LOOPITER_FL_USED); - if (rc) - return rc; - - while ((rc = loopcxt_next(lc)) == 0) { - - if (loopcxt_is_used(lc, hasst ? &st : NULL, - filename, offset, sizelimit, flags)) - break; - } - - loopcxt_deinit_iterator(lc); - return rc; -} - -/* - * Returns: 0 = not found, < 0 error, 1 found, 2 found full size and offset match - */ -int loopcxt_find_overlap(struct loopdev_cxt *lc, const char *filename, - uint64_t offset, uint64_t sizelimit) -{ - int rc, hasst; - struct stat st; - - if (!filename) - return -EINVAL; - - DBG(CXT, ul_debugobj(lc, "find_overlap requested")); - hasst = !stat(filename, &st); - - rc = loopcxt_init_iterator(lc, LOOPITER_FL_USED); - if (rc) - return rc; - - while ((rc = loopcxt_next(lc)) == 0) { - uint64_t lc_sizelimit, lc_offset; - - rc = loopcxt_is_used(lc, hasst ? &st : NULL, - filename, offset, sizelimit, 0); - if (!rc) - continue; /* unused */ - if (rc < 0) - break; /* error */ - - DBG(CXT, ul_debugobj(lc, "found %s backed by %s", - loopcxt_get_device(lc), filename)); - - rc = loopcxt_get_offset(lc, &lc_offset); - if (rc) { - DBG(CXT, ul_debugobj(lc, "failed to get offset for device %s", - loopcxt_get_device(lc))); - break; - } - rc = loopcxt_get_sizelimit(lc, &lc_sizelimit); - if (rc) { - DBG(CXT, ul_debugobj(lc, "failed to get sizelimit for device %s", - loopcxt_get_device(lc))); - break; - } - - /* full match */ - if (lc_sizelimit == sizelimit && lc_offset == offset) { - DBG(CXT, ul_debugobj(lc, "overlapping loop device %s (full match)", - loopcxt_get_device(lc))); - rc = 2; - goto found; - } - - /* overlap */ - if (lc_sizelimit != 0 && offset >= lc_offset + lc_sizelimit) - continue; - if (sizelimit != 0 && offset + sizelimit <= lc_offset) - continue; - - DBG(CXT, ul_debugobj(lc, "overlapping loop device %s", - loopcxt_get_device(lc))); - rc = 1; - goto found; - } - - if (rc == 1) - rc = 0; /* not found */ -found: - loopcxt_deinit_iterator(lc); - DBG(CXT, ul_debugobj(lc, "find_overlap done [rc=%d]", rc)); - return rc; -} - -/* - * Returns allocated string with device name - */ -char *loopdev_find_by_backing_file(const char *filename, uint64_t offset, uint64_t sizelimit, int flags) -{ - struct loopdev_cxt lc; - char *res = NULL; - - if (!filename) - return NULL; - - if (loopcxt_init(&lc, 0)) - return NULL; - if (loopcxt_find_by_backing_file(&lc, filename, offset, sizelimit, flags) == 0) - res = loopcxt_strdup_device(&lc); - loopcxt_deinit(&lc); - - return res; -} - -/* - * Returns number of loop devices associated with @file, if only one loop - * device is associated with the given @filename and @loopdev is not NULL then - * @loopdev returns name of the device. - */ -int loopdev_count_by_backing_file(const char *filename, char **loopdev) -{ - struct loopdev_cxt lc; - int count = 0, rc; - - if (!filename) - return -1; - - rc = loopcxt_init(&lc, 0); - if (rc) - return rc; - if (loopcxt_init_iterator(&lc, LOOPITER_FL_USED)) - return -1; - - while(loopcxt_next(&lc) == 0) { - char *backing = loopcxt_get_backing_file(&lc); - - if (!backing || strcmp(backing, filename) != 0) { - free(backing); - continue; - } - - free(backing); - if (loopdev && count == 0) - *loopdev = loopcxt_strdup_device(&lc); - count++; - } - - loopcxt_deinit(&lc); - - if (loopdev && count > 1) { - free(*loopdev); - *loopdev = NULL; - } - return count; -} - diff --git a/utils/lib/mangle.c b/utils/lib/mangle.c deleted file mode 100644 index 1a3b89a..0000000 --- a/utils/lib/mangle.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Functions for \oct encoding used in mtab/fstab/swaps/etc. - * - * No copyright is claimed. This code is in the public domain; do with - * it what you wish. - * - * Copyright (C) 2010 Karel Zak <kzak@redhat.com> - */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> - -#include "mangle.h" -#include "c.h" - -#define isoctal(a) (((a) & ~7) == '0') - -#define from_hex(c) (isdigit(c) ? c - '0' : tolower(c) - 'a' + 10) - -#define is_unwanted_char(x) (strchr(" \t\n\\", (unsigned int) x) != NULL) - - -char *mangle(const char *s) -{ - char *ss, *sp; - - if (!s) - return NULL; - - ss = sp = malloc(4 * strlen(s) + 1); - if (!sp) - return NULL; - while(1) { - if (!*s) { - *sp = '\0'; - break; - } - if (is_unwanted_char(*s)) { - *sp++ = '\\'; - *sp++ = '0' + ((*s & 0300) >> 6); - *sp++ = '0' + ((*s & 070) >> 3); - *sp++ = '0' + (*s & 07); - } else - *sp++ = *s; - s++; - } - return ss; -} - - -void unmangle_to_buffer(const char *s, char *buf, size_t len) -{ - size_t sz = 0; - - if (!s) - return; - - while(*s && sz < len - 1) { - if (*s == '\\' && sz + 3 < len - 1 && isoctal(s[1]) && - isoctal(s[2]) && isoctal(s[3])) { - - *buf++ = 64*(s[1] & 7) + 8*(s[2] & 7) + (s[3] & 7); - s += 4; - sz += 4; - } else { - *buf++ = *s++; - sz++; - } - } - *buf = '\0'; -} - -size_t unhexmangle_to_buffer(const char *s, char *buf, size_t len) -{ - size_t sz = 0; - const char *buf0 = buf; - - if (!s) - return 0; - - while(*s && sz < len - 1) { - if (*s == '\\' && sz + 3 < len - 1 && s[1] == 'x' && - isxdigit(s[2]) && isxdigit(s[3])) { - - *buf++ = from_hex(s[2]) << 4 | from_hex(s[3]); - s += 4; - sz += 4; - } else { - *buf++ = *s++; - sz++; - } - } - *buf = '\0'; - return buf - buf0 + 1; -} - -static inline const char *skip_nonspaces(const char *s) -{ - while (s && *s && !(*s == ' ' || *s == '\t')) - s++; - return s; -} - -/* - * Returns mallocated buffer or NULL in case of error. - */ -char *unmangle(const char *s, const char **end) -{ - char *buf; - const char *e; - size_t sz; - - if (!s) - return NULL; - - e = skip_nonspaces(s); - sz = e - s + 1; - - if (end) - *end = e; - if (e == s) - return NULL; /* empty string */ - - buf = malloc(sz); - if (!buf) - return NULL; - - unmangle_to_buffer(s, buf, sz); - return buf; -} - -#ifdef TEST_PROGRAM_MANGLE -#include <errno.h> -int main(int argc, char *argv[]) -{ - char *p = NULL; - if (argc < 3) { - fprintf(stderr, "usage: %s --mangle|unmangle <string>\n", - program_invocation_short_name); - return EXIT_FAILURE; - } - - if (!strcmp(argv[1], "--mangle")) { - p = mangle(argv[2]); - printf("mangled: '%s'\n", p); - free(p); - } - - else if (!strcmp(argv[1], "--unmangle")) { - char *x = unmangle(argv[2], NULL); - - if (x) { - printf("unmangled: '%s'\n", x); - free(x); - } - - x = strdup(argv[2]); - if (x) { - unmangle_to_buffer(x, x, strlen(x) + 1); - - printf("self-unmangled: '%s'\n", x); - free(x); - } - } - - return EXIT_SUCCESS; -} -#endif /* TEST_PROGRAM_MANGLE */ diff --git a/utils/lib/match.c b/utils/lib/match.c deleted file mode 100644 index a286a19..0000000 --- a/utils/lib/match.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2011 Karel Zak <kzak@redhat.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -#include <string.h> - -#include "match.h" - -/* - * match_fstype: - * @type: filesystem type - * @pattern: filesystem name or comma delimited list of names - * - * The @pattern list of filesystem can be prefixed with a global - * "no" prefix to invert matching of the whole list. The "no" could - * also be used for individual items in the @pattern list. So, - * "nofoo,bar" has the same meaning as "nofoo,nobar". - */ -int match_fstype(const char *type, const char *pattern) -{ - int no = 0; /* negated types list */ - int len; - const char *p; - - if (!pattern && !type) - return 1; - if (!pattern) - return 0; - - if (!strncmp(pattern, "no", 2)) { - no = 1; - pattern += 2; - } - - /* Does type occur in types, separated by commas? */ - len = strlen(type); - p = pattern; - while(1) { - if (!strncmp(p, "no", 2) && !strncasecmp(p+2, type, len) && - (p[len+2] == 0 || p[len+2] == ',')) - return 0; - if (strncasecmp(p, type, len) == 0 && (p[len] == 0 || p[len] == ',')) - return !no; - p = strchr(p,','); - if (!p) - break; - p++; - } - return no; -} diff --git a/utils/lib/mbsalign.c b/utils/lib/mbsalign.c deleted file mode 100644 index e251202..0000000 --- a/utils/lib/mbsalign.c +++ /dev/null @@ -1,627 +0,0 @@ -/* Align/Truncate a string in a given screen width - Copyright (C) 2009-2010 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 2.1 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -/* Written by Pádraig Brady. */ - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <stdbool.h> -#include <limits.h> -#include <ctype.h> - -#include "c.h" -#include "mbsalign.h" -#include "strutils.h" -#include "widechar.h" - -/* - * Counts number of cells in multibyte string. All control and - * non-printable chars are ignored. - * - * Returns: number of cells. - */ -size_t mbs_nwidth(const char *buf, size_t bufsz) -{ - const char *p = buf, *last = buf; - size_t width = 0; - -#ifdef HAVE_WIDECHAR - mbstate_t st; - memset(&st, 0, sizeof(st)); -#endif - if (p && *p && bufsz) - last = p + (bufsz - 1); - - while (p && *p && p <= last) { - if (iscntrl((unsigned char) *p)) { - p++; - - /* try detect "\e[x;ym" and skip on success */ - if (*p && *p == '[') { - const char *e = p; - while (*e && e < last && *e != 'm') - e++; - if (*e == 'm') - p = e + 1; - } - continue; - } -#ifdef HAVE_WIDECHAR - wchar_t wc; - size_t len = mbrtowc(&wc, p, MB_CUR_MAX, &st); - - if (len == 0) - break; - if (len > 0 && iswprint(wc)) { - int x = wcwidth(wc); - if (x > 0) - width += x; - } else if (len == (size_t) -1 || len == (size_t) -2) - len = 1; - p += len; -#else - if (isprint((unsigned char) *p)) - width++; - p++; -#endif - } - - return width; -} - -size_t mbs_width(const char *s) -{ - if (!s || !*s) - return 0; - return mbs_nwidth(s, strlen(s)); -} - -/* - * Counts number of cells in multibyte string. For all control and - * non-printable chars is the result width enlarged to store \x?? hex - * sequence. See mbs_safe_encode(). - * - * Returns: number of cells, @sz returns number of bytes. - */ -size_t mbs_safe_nwidth(const char *buf, size_t bufsz, size_t *sz) -{ - const char *p = buf, *last = buf; - size_t width = 0, bytes = 0; - -#ifdef HAVE_WIDECHAR - mbstate_t st; - memset(&st, 0, sizeof(st)); -#endif - if (p && *p && bufsz) - last = p + (bufsz - 1); - - while (p && *p && p <= last) { - if ((p < last && *p == '\\' && *(p + 1) == 'x') - || iscntrl((unsigned char) *p)) { - width += 4, bytes += 4; /* *p encoded to \x?? */ - p++; - } -#ifdef HAVE_WIDECHAR - else { - wchar_t wc; - size_t len = mbrtowc(&wc, p, MB_CUR_MAX, &st); - - if (len == 0) - break; - - if (len == (size_t) -1 || len == (size_t) -2) { - len = 1; - if (isprint((unsigned char) *p)) - width += 1, bytes += 1; - else - width += 4, bytes += 4; - - } else if (!iswprint(wc)) { - width += len * 4; /* hex encode whole sequence */ - bytes += len * 4; - } else { - width += wcwidth(wc); /* number of cells */ - bytes += len; /* number of bytes */ - } - p += len; - } -#else - else if (!isprint((unsigned char) *p)) { - width += 4, bytes += 4; /* *p encoded to \x?? */ - p++; - } else { - width++, bytes++; - p++; - } -#endif - } - - if (sz) - *sz = bytes; - return width; -} - -size_t mbs_safe_width(const char *s) -{ - if (!s || !*s) - return 0; - return mbs_safe_nwidth(s, strlen(s), NULL); -} - -/* - * Copy @s to @buf and replace control and non-printable chars with - * \x?? hex sequence. The @width returns number of cells. The @safechars - * are not encoded. - * - * The @buf has to be big enough to store mbs_safe_encode_size(strlen(s))) - * bytes. - */ -char *mbs_safe_encode_to_buffer(const char *s, size_t *width, char *buf, const char *safechars) -{ - const char *p = s; - char *r; - size_t sz = s ? strlen(s) : 0; - -#ifdef HAVE_WIDECHAR - mbstate_t st; - memset(&st, 0, sizeof(st)); -#endif - if (!sz || !buf) - return NULL; - - r = buf; - *width = 0; - - while (p && *p) { - if (safechars && strchr(safechars, *p)) { - *r++ = *p++; - continue; - } - - if ((*p == '\\' && *(p + 1) == 'x') - || iscntrl((unsigned char) *p)) { - sprintf(r, "\\x%02x", (unsigned char) *p); - r += 4; - *width += 4; - p++; - } -#ifdef HAVE_WIDECHAR - else { - wchar_t wc; - size_t len = mbrtowc(&wc, p, MB_CUR_MAX, &st); - - if (len == 0) - break; /* end of string */ - - if (len == (size_t) -1 || len == (size_t) -2) { - len = 1; - /* - * Not valid multibyte sequence -- maybe it's - * printable char according to the current locales. - */ - if (!isprint((unsigned char) *p)) { - sprintf(r, "\\x%02x", (unsigned char) *p); - r += 4; - *width += 4; - } else { - (*width)++; - *r++ = *p; - } - } else if (!iswprint(wc)) { - size_t i; - for (i = 0; i < len; i++) { - sprintf(r, "\\x%02x", (unsigned char) p[i]); - r += 4; - *width += 4; - } - } else { - memcpy(r, p, len); - r += len; - *width += wcwidth(wc); - } - p += len; - } -#else - else if (!isprint((unsigned char) *p)) { - sprintf(r, "\\x%02x", (unsigned char) *p); - p++; - r += 4; - *width += 4; - } else { - *r++ = *p++; - (*width)++; - } -#endif - } - - *r = '\0'; - return buf; -} - -/* - * Copy @s to @buf and replace broken sequences to \x?? hex sequence. The - * @width returns number of cells. The @safechars are not encoded. - * - * The @buf has to be big enough to store mbs_safe_encode_size(strlen(s))) - * bytes. - */ -char *mbs_invalid_encode_to_buffer(const char *s, size_t *width, char *buf) -{ - const char *p = s; - char *r; - size_t sz = s ? strlen(s) : 0; - -#ifdef HAVE_WIDECHAR - mbstate_t st; - memset(&st, 0, sizeof(st)); -#endif - if (!sz || !buf) - return NULL; - - r = buf; - *width = 0; - - while (p && *p) { -#ifdef HAVE_WIDECHAR - wchar_t wc; - size_t len = mbrtowc(&wc, p, MB_CUR_MAX, &st); -#else - size_t len = 1; -#endif - - if (len == 0) - break; /* end of string */ - - if (len == (size_t) -1 || len == (size_t) -2) { - len = 1; - /* - * Not valid multibyte sequence -- maybe it's - * printable char according to the current locales. - */ - if (!isprint((unsigned char) *p)) { - sprintf(r, "\\x%02x", (unsigned char) *p); - r += 4; - *width += 4; - } else { - (*width)++; - *r++ = *p; - } - } else if (*p == '\\' && *(p + 1) == 'x') { - sprintf(r, "\\x%02x", (unsigned char) *p); - r += 4; - *width += 4; - } else { - memcpy(r, p, len); - r += len; - *width += wcwidth(wc); - } - p += len; - } - - *r = '\0'; - return buf; -} - -size_t mbs_safe_encode_size(size_t bytes) -{ - return (bytes * 4) + 1; -} - -/* - * Returns allocated string where all control and non-printable chars are - * replaced with \x?? hex sequence. - */ -char *mbs_safe_encode(const char *s, size_t *width) -{ - size_t sz = s ? strlen(s) : 0; - char *buf, *ret = NULL; - - if (!sz) - return NULL; - buf = malloc(mbs_safe_encode_size(sz)); - if (buf) - ret = mbs_safe_encode_to_buffer(s, width, buf, NULL); - if (!ret) - free(buf); - return ret; -} - -/* - * Returns allocated string where all broken widechars chars are - * replaced with \x?? hex sequence. - */ -char *mbs_invalid_encode(const char *s, size_t *width) -{ - size_t sz = s ? strlen(s) : 0; - char *buf, *ret = NULL; - - if (!sz) - return NULL; - buf = malloc(mbs_safe_encode_size(sz)); - if (buf) - ret = mbs_invalid_encode_to_buffer(s, width, buf); - if (!ret) - free(buf); - return ret; -} - -#ifdef HAVE_WIDECHAR - -static bool -wc_ensure_printable (wchar_t *wchars) -{ - bool replaced = false; - wchar_t *wc = wchars; - while (*wc) - { - if (!iswprint ((wint_t) *wc)) - { - *wc = 0xFFFD; /* L'\uFFFD' (replacement char) */ - replaced = true; - } - wc++; - } - return replaced; -} - -/* Truncate wchar string to width cells. - * Returns number of cells used. */ - -static size_t -wc_truncate (wchar_t *wc, size_t width) -{ - size_t cells = 0; - int next_cells = 0; - - while (*wc) - { - next_cells = wcwidth (*wc); - if (next_cells == -1) /* non printable */ - { - *wc = 0xFFFD; /* L'\uFFFD' (replacement char) */ - next_cells = 1; - } - if (cells + next_cells > width) - break; - - cells += next_cells; - wc++; - } - *wc = L'\0'; - return cells; -} - -static int -rpl_wcswidth (const wchar_t *s, size_t n) -{ - int ret = 0; - - while (n-- > 0 && *s != L'\0') - { - int nwidth = wcwidth (*s++); - if (nwidth == -1) /* non printable */ - return -1; - if (ret > (INT_MAX - nwidth)) /* overflow */ - return -1; - ret += nwidth; - } - - return ret; -} -#endif /* HAVE_WIDECHAR */ - -/* Truncate multi-byte string to @width and returns number of - * bytes of the new string @str, and in @width returns number - * of cells. - */ -size_t -mbs_truncate(char *str, size_t *width) -{ - ssize_t bytes = strlen(str); -#ifdef HAVE_WIDECHAR - ssize_t sz = mbstowcs(NULL, str, 0); - wchar_t *wcs = NULL; - - if (sz == (ssize_t) -1) - goto done; - - wcs = calloc(1, (sz + 1) * sizeof(wchar_t)); - if (!wcs) - goto done; - - if (!mbstowcs(wcs, str, sz)) - goto done; - *width = wc_truncate(wcs, *width); - bytes = wcstombs(str, wcs, bytes); -done: - free(wcs); -#else - if (bytes >= 0 && *width < (size_t) bytes) - bytes = *width; -#endif - if (bytes >= 0) - str[bytes] = '\0'; - return bytes; -} - -/* Write N_SPACES space characters to DEST while ensuring - nothing is written beyond DEST_END. A terminating NUL - is always added to DEST. - A pointer to the terminating NUL is returned. */ - -static char* -mbs_align_pad (char *dest, const char* dest_end, size_t n_spaces, int padchar) -{ - for (/* nothing */; n_spaces && (dest < dest_end); n_spaces--) - *dest++ = padchar; - *dest = '\0'; - return dest; -} - -size_t -mbsalign (const char *src, char *dest, size_t dest_size, - size_t *width, mbs_align_t align, int flags) -{ - return mbsalign_with_padding(src, dest, dest_size, width, align, flags, ' '); -} - -/* Align a string, SRC, in a field of *WIDTH columns, handling multi-byte - characters; write the result into the DEST_SIZE-byte buffer, DEST. - ALIGNMENT specifies whether to left- or right-justify or to center. - If SRC requires more than *WIDTH columns, truncate it to fit. - When centering, the number of trailing spaces may be one less than the - number of leading spaces. The FLAGS parameter is unused at present. - Return the length in bytes required for the final result, not counting - the trailing NUL. A return value of DEST_SIZE or larger means there - wasn't enough space. DEST will be NUL terminated in any case. - Return (size_t) -1 upon error (invalid multi-byte sequence in SRC, - or malloc failure), unless MBA_UNIBYTE_FALLBACK is specified. - Update *WIDTH to indicate how many columns were used before padding. */ - -size_t -mbsalign_with_padding (const char *src, char *dest, size_t dest_size, - size_t *width, mbs_align_t align, -#ifdef HAVE_WIDECHAR - int flags, -#else - int flags __attribute__((__unused__)), -#endif - int padchar) -{ - size_t ret = -1; - size_t src_size = strlen (src) + 1; - char *newstr = NULL; - wchar_t *str_wc = NULL; - const char *str_to_print = src; - size_t n_cols = src_size - 1; - size_t n_used_bytes = n_cols; /* Not including NUL */ - size_t n_spaces = 0, space_left; - -#ifdef HAVE_WIDECHAR - bool conversion = false; - bool wc_enabled = false; - - /* In multi-byte locales convert to wide characters - to allow easy truncation. Also determine number - of screen columns used. */ - if (MB_CUR_MAX > 1) - { - size_t src_chars = mbstowcs (NULL, src, 0); - if (src_chars == (size_t) -1) - { - if (flags & MBA_UNIBYTE_FALLBACK) - goto mbsalign_unibyte; - else - goto mbsalign_cleanup; - } - src_chars += 1; /* make space for NUL */ - str_wc = malloc (src_chars * sizeof (wchar_t)); - if (str_wc == NULL) - { - if (flags & MBA_UNIBYTE_FALLBACK) - goto mbsalign_unibyte; - else - goto mbsalign_cleanup; - } - if (mbstowcs (str_wc, src, src_chars) != 0) - { - str_wc[src_chars - 1] = L'\0'; - wc_enabled = true; - conversion = wc_ensure_printable (str_wc); - n_cols = rpl_wcswidth (str_wc, src_chars); - } - } - - /* If we transformed or need to truncate the source string - then create a modified copy of it. */ - if (wc_enabled && (conversion || (n_cols > *width))) - { - if (conversion) - { - /* May have increased the size by converting - \t to \uFFFD for example. */ - src_size = wcstombs(NULL, str_wc, 0) + 1; - } - newstr = malloc (src_size); - if (newstr == NULL) - { - if (flags & MBA_UNIBYTE_FALLBACK) - goto mbsalign_unibyte; - else - goto mbsalign_cleanup; - } - str_to_print = newstr; - n_cols = wc_truncate (str_wc, *width); - n_used_bytes = wcstombs (newstr, str_wc, src_size); - } - -mbsalign_unibyte: -#endif - - if (n_cols > *width) /* Unibyte truncation required. */ - { - n_cols = *width; - n_used_bytes = n_cols; - } - - if (*width > n_cols) /* Padding required. */ - n_spaces = *width - n_cols; - - /* indicate to caller how many cells needed (not including padding). */ - *width = n_cols; - - /* indicate to caller how many bytes needed (not including NUL). */ - ret = n_used_bytes + (n_spaces * 1); - - /* Write as much NUL terminated output to DEST as possible. */ - if (dest_size != 0) - { - char *dest_end = dest + dest_size - 1; - size_t start_spaces; - size_t end_spaces; - - switch (align) - { - case MBS_ALIGN_CENTER: - start_spaces = n_spaces / 2 + n_spaces % 2; - end_spaces = n_spaces / 2; - break; - case MBS_ALIGN_LEFT: - start_spaces = 0; - end_spaces = n_spaces; - break; - case MBS_ALIGN_RIGHT: - start_spaces = n_spaces; - end_spaces = 0; - break; - default: - abort(); - } - - dest = mbs_align_pad (dest, dest_end, start_spaces, padchar); - space_left = dest_end - dest; - dest = mempcpy (dest, str_to_print, min (n_used_bytes, space_left)); - mbs_align_pad (dest, dest_end, end_spaces, padchar); - } -#ifdef HAVE_WIDECHAR -mbsalign_cleanup: -#endif - free (str_wc); - free (newstr); - - return ret; -} diff --git a/utils/lib/mbsedit.c b/utils/lib/mbsedit.c deleted file mode 100644 index 8ce5901..0000000 --- a/utils/lib/mbsedit.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Very simple multibyte buffer editor. Allows to maintaine the current - * position in the string, add and remove chars on the current position. - * - * This file may be distributed under the terms of the - * GNU Lesser General Public License. - * - * Copyright (C) 2017 Karel Zak <kzak@redhat.com> - */ -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <stdio.h> - -#include "mbsalign.h" -#include "mbsedit.h" - -struct mbs_editor *mbs_new_edit(char *buf, size_t bufsz, size_t ncells) -{ - struct mbs_editor *edit = calloc(1, sizeof(*edit)); - - if (edit) { - edit->buf = buf; - edit->max_bytes = bufsz; - edit->max_cells = ncells; - edit->cur_cells = mbs_safe_width(buf); - edit->cur_bytes = strlen(buf); - } - return edit; -} - -char *mbs_free_edit(struct mbs_editor *edit) -{ - char *ret = edit ? edit->buf : NULL; - - free(edit); - return ret; -} - -static size_t mbs_next(const char *str, size_t *ncells) -{ -#ifdef HAVE_WIDECHAR - wchar_t wc; - size_t n = 0; - - if (!str || !*str) - return 0; - - n = mbrtowc(&wc, str, MB_CUR_MAX, NULL); - *ncells = wcwidth(wc); - return n; -#else - if (!str || !*str) - return 0; - *ncells = 1; - return 1; -#endif -} - -static size_t mbs_prev(const char *start, const char *end, size_t *ncells) -{ -#ifdef HAVE_WIDECHAR - wchar_t wc = 0; - const char *p, *prev; - size_t n = 0; - - if (!start || !end || start == end || !*start) - return 0; - - prev = p = start; - while (p < end) { - n = mbrtowc(&wc, p, MB_CUR_MAX, NULL); - prev = p; - - if (n == (size_t) -1 || n == (size_t) -2) - p++; - else - p += n; - } - - if (prev == end) - return 0; - *ncells = wcwidth(wc); - return n; -#else - if (!start || !end || start == end || !*start) - return 0; - *ncells = 1; - return 1; -#endif -} - -int mbs_edit_goto(struct mbs_editor *edit, int where) -{ - switch (where) { - case MBS_EDIT_LEFT: - if (edit->cursor == 0) - return 1; - else { - size_t n, cells; - n = mbs_prev(edit->buf, edit->buf + edit->cursor, &cells); - if (n) { - edit->cursor -= n; - edit->cursor_cells -= cells; - } - } - break; - case MBS_EDIT_RIGHT: - if (edit->cursor_cells >= edit->cur_cells) - return 1; - else { - size_t n, cells; - n = mbs_next(edit->buf + edit->cursor, &cells); - if (n) { - edit->cursor += n; - edit->cursor_cells += cells; - } - } - break; - case MBS_EDIT_HOME: - edit->cursor = 0; - edit->cursor_cells = 0; - break; - case MBS_EDIT_END: - edit->cursor = edit->cur_bytes; - edit->cursor_cells = edit->cur_cells; - break; - default: - return -EINVAL; - } - - return 0; -} - -/* Remove next MB from @str, returns number of removed bytes */ -static size_t remove_next(char *str, size_t *ncells) -{ - /* all in bytes! */ - size_t bytes, move_bytes, n; - - n = mbs_next(str, ncells); - bytes = strlen(str); - move_bytes = bytes - n; - - memmove(str, str + n, move_bytes); - str[bytes - n] = '\0'; - return n; -} - -static size_t mbs_insert(char *str, wint_t c, size_t *ncells) -{ - /* all in bytes! */ - size_t n = 1, bytes; - char *in; - -#ifdef HAVE_WIDECHAR - wchar_t wc = (wchar_t) c; - char in_buf[MB_CUR_MAX]; - - n = wctomb(in_buf, wc); - if (n == (size_t) -1) - return n; - *ncells = wcwidth(wc); - in = in_buf; -#else - *ncells = 1; - in = (char *) &c; -#endif - bytes = strlen(str); - - memmove(str + n, str, bytes); - memcpy(str, in, n); - str[bytes + n] = '\0'; - return n; -} - -static int mbs_edit_remove(struct mbs_editor *edit) -{ - size_t n, ncells; - - if (edit->cur_cells == 0 || edit->cursor >= edit->cur_bytes) - return 1; - - n = remove_next(edit->buf + edit->cursor, &ncells); - if (n == (size_t)-1) - return 1; - - edit->cur_bytes -= n; - edit->cur_cells = mbs_safe_width(edit->buf); - return 0; -} - -int mbs_edit_delete(struct mbs_editor *edit) -{ - if (edit->cursor >= edit->cur_bytes - && mbs_edit_goto(edit, MBS_EDIT_LEFT) == 1) - return 1; - - return mbs_edit_remove(edit); -} - -int mbs_edit_backspace(struct mbs_editor *edit) -{ - if (mbs_edit_goto(edit, MBS_EDIT_LEFT) == 0) - return mbs_edit_remove(edit); - return 1; -} - -int mbs_edit_insert(struct mbs_editor *edit, wint_t c) -{ - size_t n, ncells; - - if (edit->cur_bytes + MB_CUR_MAX > edit->max_bytes) - return 1; - - n = mbs_insert(edit->buf + edit->cursor, c, &ncells); - if (n == (size_t)-1) - return 1; - - edit->cursor += n; - edit->cursor_cells += ncells; - edit->cur_bytes += n; - edit->cur_cells = mbs_safe_width(edit->buf); - return 0; -} diff --git a/utils/lib/md5.c b/utils/lib/md5.c deleted file mode 100644 index 3765ab9..0000000 --- a/utils/lib/md5.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * This code implements the MD5 message-digest algorithm. - * The algorithm is due to Ron Rivest. This code was - * written by Colin Plumb in 1993, no copyright is claimed. - * This code is in the public domain; do with it what you wish. - * - * Equivalent code is available from RSA Data Security, Inc. - * This code has been tested against that, and is equivalent, - * except that you don't need to include two pages of legalese - * with every copy. - * - * To compute the message digest of a chunk of bytes, declare an - * MD5Context structure, pass it to MD5Init, call MD5Update as - * needed on buffers full of bytes, and then call MD5Final, which - * will fill a supplied 16-byte array with the digest. - */ -#include <string.h> /* for memcpy() */ - -#include "md5.h" - -#if !defined(WORDS_BIGENDIAN) -# define byteReverse(buf, len) /* Nothing */ -#else -static void byteReverse(unsigned char *buf, unsigned longs); - -#ifndef ASM_MD5 -/* - * Note: this code is harmless on little-endian machines. - */ -static void byteReverse(unsigned char *buf, unsigned longs) -{ - uint32_t t; - do { - t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 | - ((unsigned) buf[1] << 8 | buf[0]); - *(uint32_t *) buf = t; - buf += 4; - } while (--longs); -} -#endif /* !ASM_MD5 */ -#endif /* !WORDS_BIGENDIAN */ - -/* - * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious - * initialization constants. - */ -void ul_MD5Init(struct UL_MD5Context *ctx) -{ - ctx->buf[0] = 0x67452301; - ctx->buf[1] = 0xefcdab89; - ctx->buf[2] = 0x98badcfe; - ctx->buf[3] = 0x10325476; - - ctx->bits[0] = 0; - ctx->bits[1] = 0; -} - -/* - * Update context to reflect the concatenation of another buffer full - * of bytes. - */ -void ul_MD5Update(struct UL_MD5Context *ctx, unsigned char const *buf, unsigned len) -{ - uint32_t t; - - /* Update bitcount */ - - t = ctx->bits[0]; - if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) - ctx->bits[1]++; /* Carry from low to high */ - ctx->bits[1] += len >> 29; - - t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ - - /* Handle any leading odd-sized chunks */ - - if (t) { - unsigned char *p = (unsigned char *) ctx->in + t; - - t = 64 - t; - if (len < t) { - memcpy(p, buf, len); - return; - } - memcpy(p, buf, t); - byteReverse(ctx->in, 16); - ul_MD5Transform(ctx->buf, (uint32_t *) ctx->in); - buf += t; - len -= t; - } - /* Process data in 64-byte chunks */ - - while (len >= 64) { - memcpy(ctx->in, buf, 64); - byteReverse(ctx->in, 16); - ul_MD5Transform(ctx->buf, (uint32_t *) ctx->in); - buf += 64; - len -= 64; - } - - /* Handle any remaining bytes of data. */ - - memcpy(ctx->in, buf, len); -} - -/* - * Final wrapup - pad to 64-byte boundary with the bit pattern - * 1 0* (64-bit count of bits processed, MSB-first) - */ -void ul_MD5Final(unsigned char digest[UL_MD5LENGTH], struct UL_MD5Context *ctx) -{ - unsigned count; - unsigned char *p; - - /* Compute number of bytes mod 64 */ - count = (ctx->bits[0] >> 3) & 0x3F; - - /* Set the first char of padding to 0x80. This is safe since there is - always at least one byte free */ - p = ctx->in + count; - *p++ = 0x80; - - /* Bytes of padding needed to make 64 bytes */ - count = 64 - 1 - count; - - /* Pad out to 56 mod 64 */ - if (count < 8) { - /* Two lots of padding: Pad the first block to 64 bytes */ - memset(p, 0, count); - byteReverse(ctx->in, 16); - ul_MD5Transform(ctx->buf, (uint32_t *) ctx->in); - - /* Now fill the next block with 56 bytes */ - memset(ctx->in, 0, 56); - } else { - /* Pad block to 56 bytes */ - memset(p, 0, count - 8); - } - byteReverse(ctx->in, 14); - - /* Append length in bits and transform. - * Use memcpy to avoid aliasing problems. On most systems, - * this will be optimized away to the same code. - */ - memcpy(&ctx->in[14 * sizeof(uint32_t)], &ctx->bits[0], 4); - memcpy(&ctx->in[15 * sizeof(uint32_t)], &ctx->bits[1], 4); - - ul_MD5Transform(ctx->buf, (uint32_t *) ctx->in); - byteReverse((unsigned char *) ctx->buf, 4); - memcpy(digest, ctx->buf, UL_MD5LENGTH); - memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ -} - -#ifndef ASM_MD5 - -/* The four core functions - F1 is optimized somewhat */ - -/* #define F1(x, y, z) (x & y | ~x & z) */ -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -/* This is the central step in the MD5 algorithm. */ -#define MD5STEP(f, w, x, y, z, data, s) \ - ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) - -/* - * The core of the MD5 algorithm, this alters an existing MD5 hash to - * reflect the addition of 16 longwords of new data. MD5Update blocks - * the data and converts bytes into longwords for this routine. - */ -void ul_MD5Transform(uint32_t buf[4], uint32_t const in[16]) -{ - register uint32_t a, b, c, d; - - a = buf[0]; - b = buf[1]; - c = buf[2]; - d = buf[3]; - - MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); - MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); - MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); - MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); - MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); - MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); - MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); - MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); - MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); - MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); - - MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); - MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); - MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); - MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); - MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); - MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); - MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); - MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); - MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); - MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); - - MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); - MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); - MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); - MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); - MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); - MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); - MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); - MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); - MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); - MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); - - MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); - MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); - MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); - MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); - MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); - MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); - MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); - MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); - MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); - MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} - -#endif - diff --git a/utils/lib/monotonic.c b/utils/lib/monotonic.c deleted file mode 100644 index f0aeba6..0000000 --- a/utils/lib/monotonic.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Please, don't add this file to libcommon because clock_gettime() requires - * -lrt on systems with old libc. - * - * No copyright is claimed. This code is in the public domain; do with - * it what you wish. - */ -#include <time.h> -#include <signal.h> -#ifdef HAVE_SYSINFO -#include <sys/sysinfo.h> -#endif -#include <sys/time.h> - -#include "c.h" -#include "monotonic.h" - -int get_boot_time(struct timeval *boot_time) -{ -#ifdef CLOCK_BOOTTIME - struct timespec hires_uptime; - struct timeval lores_uptime; -#endif - struct timeval now; -#ifdef HAVE_SYSINFO - struct sysinfo info; -#endif - - if (gettimeofday(&now, NULL) != 0) - return -errno; -#ifdef CLOCK_BOOTTIME - if (clock_gettime(CLOCK_BOOTTIME, &hires_uptime) == 0) { - TIMESPEC_TO_TIMEVAL(&lores_uptime, &hires_uptime); - timersub(&now, &lores_uptime, boot_time); - return 0; - } -#endif -#ifdef HAVE_SYSINFO - /* fallback */ - if (sysinfo(&info) != 0) - return -errno; - - boot_time->tv_sec = now.tv_sec - info.uptime; - boot_time->tv_usec = 0; - return 0; -#else - return -ENOSYS; -#endif -} - -time_t get_suspended_time(void) -{ -#if defined(CLOCK_BOOTTIME) && defined(CLOCK_MONOTONIC) - struct timespec boot, mono; - - if (clock_gettime(CLOCK_BOOTTIME, &boot) == 0 && - clock_gettime(CLOCK_MONOTONIC, &mono) == 0) - return boot.tv_sec - mono.tv_sec; -#endif - return 0; -} - -int gettime_monotonic(struct timeval *tv) -{ -#ifdef CLOCK_MONOTONIC - /* Can slew only by ntp and adjtime */ - int ret; - struct timespec ts; - - /* Linux specific, can't slew */ - if (!(ret = clock_gettime(UL_CLOCK_MONOTONIC, &ts))) { - tv->tv_sec = ts.tv_sec; - tv->tv_usec = ts.tv_nsec / 1000; - } - return ret; -#else - return gettimeofday(tv, NULL); -#endif -} - - diff --git a/utils/lib/pager.c b/utils/lib/pager.c deleted file mode 100644 index b3cf6ee..0000000 --- a/utils/lib/pager.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Based on linux-perf/git scm - * - * Some modifications and simplifications for util-linux - * by Davidlohr Bueso <dave@xxxxxxx> - March 2012. - */ - -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <err.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <signal.h> - -#include "c.h" -#include "xalloc.h" -#include "nls.h" -#include "ttyutils.h" -#include "pager.h" - -#define NULL_DEVICE "/dev/null" - -static const char *pager_argv[] = { "sh", "-c", NULL, NULL }; - -struct child_process { - const char **argv; - pid_t pid; - int in; - int out; - int err; - - int org_err; - int org_out; - struct sigaction orig_sigint; - struct sigaction orig_sighup; - struct sigaction orig_sigterm; - struct sigaction orig_sigquit; - struct sigaction orig_sigpipe; - - unsigned no_stdin:1; - void (*preexec_cb)(void); -}; -static struct child_process pager_process; - -static inline void close_pair(int fd[2]) -{ - close(fd[0]); - close(fd[1]); -} - -static int start_command(struct child_process *cmd) -{ - int need_in; - int fdin[2]; - - /* - * In case of errors we must keep the promise to close FDs - * that have been passed in via ->in and ->out. - */ - need_in = !cmd->no_stdin && cmd->in < 0; - if (need_in) { - if (pipe(fdin) < 0) { - if (cmd->out > 0) - close(cmd->out); - return -1; - } - cmd->in = fdin[1]; - } - - fflush(NULL); - cmd->pid = fork(); - if (!cmd->pid) { - if (need_in) { - dup2(fdin[0], STDIN_FILENO); - close_pair(fdin); - } else if (cmd->in > 0) { - dup2(cmd->in, STDIN_FILENO); - close(cmd->in); - } - - cmd->preexec_cb(); - execvp(cmd->argv[0], (char *const*) cmd->argv); - errexec(cmd->argv[0]); - } - - if (cmd->pid < 0) { - if (need_in) - close_pair(fdin); - else if (cmd->in) - close(cmd->in); - return -1; - } - - if (need_in) - close(fdin[0]); - else if (cmd->in) - close(cmd->in); - return 0; -} - -static int wait_or_whine(pid_t pid) -{ - for (;;) { - int status, code; - pid_t waiting = waitpid(pid, &status, 0); - - if (waiting < 0) { - if (errno == EINTR) - continue; - err(EXIT_FAILURE, _("waitpid failed (%s)"), strerror(errno)); - } - if (waiting != pid) - return -1; - if (WIFSIGNALED(status)) - return -1; - - if (!WIFEXITED(status)) - return -1; - code = WEXITSTATUS(status); - switch (code) { - case 127: - return -1; - case 0: - return 0; - default: - return -1; - } - } -} - -static int finish_command(struct child_process *cmd) -{ - return wait_or_whine(cmd->pid); -} - -static void pager_preexec(void) -{ - /* - * Work around bug in "less" by not starting it until we - * have real input - */ - fd_set in, ex; - - FD_ZERO(&in); - FD_SET(STDIN_FILENO, &in); - ex = in; - - select(STDIN_FILENO + 1, &in, NULL, &ex, NULL); - - if (setenv("LESS", "FRSX", 0) != 0) - warn(_("failed to set the %s environment variable"), "LESS"); -} - -static void wait_for_pager(void) -{ - if (pager_process.pid == 0) - return; - - fflush(stdout); - fflush(stderr); - /* signal EOF to pager */ - close(STDOUT_FILENO); - close(STDERR_FILENO); - finish_command(&pager_process); -} - -static void wait_for_pager_signal(int signo) -{ - wait_for_pager(); - raise(signo); -} - -static int has_command(const char *cmd) -{ - const char *path; - char *p, *s; - int rc = 0; - - if (!cmd) - goto done; - if (*cmd == '/') { - rc = access(cmd, X_OK) == 0; - goto done; - } - - path = getenv("PATH"); - if (!path) - goto done; - p = xstrdup(path); - if (!p) - goto done; - - for(s = strtok(p, ":"); s; s = strtok(NULL, ":")) { - int fd = open(s, O_RDONLY|O_CLOEXEC); - if (fd < 0) - continue; - rc = faccessat(fd, cmd, X_OK, 0) == 0; - close(fd); - if (rc) - break; - } - free(p); -done: - /*fprintf(stderr, "has PAGER %s rc=%d\n", cmd, rc);*/ - return rc; -} - -static void __setup_pager(void) -{ - const char *pager = getenv("PAGER"); - struct sigaction sa; - - if (!isatty(STDOUT_FILENO)) - return; - - if (!pager) - pager = "less"; - else if (!*pager || !strcmp(pager, "cat")) - return; - - if (!has_command(pager)) - return; - - /* spawn the pager */ - pager_argv[2] = pager; - pager_process.argv = pager_argv; - pager_process.in = -1; - pager_process.preexec_cb = pager_preexec; - - if (start_command(&pager_process)) - return; - - /* original process continues, but writes to the pipe */ - dup2(pager_process.in, STDOUT_FILENO); - if (isatty(STDERR_FILENO)) - dup2(pager_process.in, STDERR_FILENO); - close(pager_process.in); - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = wait_for_pager_signal; - - /* this makes sure that the parent terminates after the pager */ - sigaction(SIGINT, &sa, &pager_process.orig_sigint); - sigaction(SIGHUP, &sa, &pager_process.orig_sighup); - sigaction(SIGTERM, &sa, &pager_process.orig_sigterm); - sigaction(SIGQUIT, &sa, &pager_process.orig_sigquit); - sigaction(SIGPIPE, &sa, &pager_process.orig_sigpipe); -} - -/* Setup pager and redirects output to the $PAGER. The pager is closed at exit. - */ -void pager_redirect(void) -{ - if (pager_process.pid) - return; /* already running */ - - __setup_pager(); - - atexit(wait_for_pager); -} - -/* Setup pager and redirect output, the pager may be closed by pager_close(). - */ -void pager_open(void) -{ - if (pager_process.pid) - return; /* already running */ - - pager_process.org_out = dup(STDOUT_FILENO); - pager_process.org_err = dup(STDERR_FILENO); - - __setup_pager(); -} - -/* Close pager and restore original std{out,err}. - */ -void pager_close(void) -{ - if (pager_process.pid == 0) - return; - - wait_for_pager(); - - /* restore original output */ - dup2(pager_process.org_out, STDOUT_FILENO); - dup2(pager_process.org_err, STDERR_FILENO); - - close(pager_process.org_out); - close(pager_process.org_err); - - /* restore original segnals setting */ - sigaction(SIGINT, &pager_process.orig_sigint, NULL); - sigaction(SIGHUP, &pager_process.orig_sighup, NULL); - sigaction(SIGTERM, &pager_process.orig_sigterm, NULL); - sigaction(SIGQUIT, &pager_process.orig_sigquit, NULL); - sigaction(SIGPIPE, &pager_process.orig_sigpipe, NULL); - - memset(&pager_process, 0, sizeof(pager_process)); -} - -#ifdef TEST_PROGRAM_PAGER - -#define MAX 255 - -int main(int argc __attribute__ ((__unused__)), - char *argv[] __attribute__ ((__unused__))) -{ - int i; - - pager_redirect(); - for (i = 0; i < MAX; i++) - printf("%d\n", i); - return EXIT_SUCCESS; -} -#endif /* TEST_PROGRAM_PAGER */ diff --git a/utils/lib/path.c b/utils/lib/path.c deleted file mode 100644 index 75fa853..0000000 --- a/utils/lib/path.c +++ /dev/null @@ -1,1248 +0,0 @@ -/* - * Simple functions to access files. Paths can be globally prefixed to read - * data from an alternative source (e.g. a /proc dump for regression tests). - * - * The paths is possible to format by printf-like way for functions with "f" - * postfix in the name (e.g. readf, openf, ... ul_path_readf_u64()). - * - * The ul_path_read_* API is possible to use without path_cxt handler. In this - * case is not possible to use global prefix and printf-like formatting. - * - * No copyright is claimed. This code is in the public domain; do with - * it what you wish. - * - * Written by Karel Zak <kzak@redhat.com> [February 2018] - */ -#include <stdarg.h> -#include <string.h> -#include <unistd.h> -#include <stdio.h> -#include <inttypes.h> -#include <errno.h> - -#include "c.h" -#include "fileutils.h" -#include "all-io.h" -#include "path.h" -#include "debug.h" -#include "strutils.h" - -/* - * Debug stuff (based on include/debug.h) - */ -static UL_DEBUG_DEFINE_MASK(ulpath); -UL_DEBUG_DEFINE_MASKNAMES(ulpath) = UL_DEBUG_EMPTY_MASKNAMES; - -#define ULPATH_DEBUG_INIT (1 << 1) -#define ULPATH_DEBUG_CXT (1 << 2) - -#define DBG(m, x) __UL_DBG(ulpath, ULPATH_DEBUG_, m, x) -#define ON_DBG(m, x) __UL_DBG_CALL(ulpath, ULPATH_DEBUG_, m, x) - -#define UL_DEBUG_CURRENT_MASK UL_DEBUG_MASK(ulpath) -#include "debugobj.h" - -void ul_path_init_debug(void) -{ - if (ulpath_debug_mask) - return; - __UL_INIT_DEBUG_FROM_ENV(ulpath, ULPATH_DEBUG_, 0, ULPATH_DEBUG); -} - -struct path_cxt *ul_new_path(const char *dir, ...) -{ - struct path_cxt *pc = calloc(1, sizeof(*pc)); - - if (!pc) - return NULL; - - DBG(CXT, ul_debugobj(pc, "alloc")); - - pc->refcount = 1; - pc->dir_fd = -1; - - if (dir) { - int rc; - va_list ap; - - va_start(ap, dir); - rc = vasprintf(&pc->dir_path, dir, ap); - va_end(ap); - - if (rc < 0 || !pc->dir_path) - goto fail; - } - return pc; -fail: - ul_unref_path(pc); - return NULL; -} - -void ul_ref_path(struct path_cxt *pc) -{ - if (pc) - pc->refcount++; -} - -void ul_unref_path(struct path_cxt *pc) -{ - if (!pc) - return; - - pc->refcount--; - - if (pc->refcount <= 0) { - DBG(CXT, ul_debugobj(pc, "dealloc")); - if (pc->dialect) - pc->free_dialect(pc); - ul_path_close_dirfd(pc); - free(pc->dir_path); - free(pc->prefix); - free(pc); - } -} - -int ul_path_set_prefix(struct path_cxt *pc, const char *prefix) -{ - char *p = NULL; - - assert(pc->dir_fd < 0); - - if (prefix) { - p = strdup(prefix); - if (!p) - return -ENOMEM; - } - - free(pc->prefix); - pc->prefix = p; - DBG(CXT, ul_debugobj(pc, "new prefix: '%s'", p)); - return 0; -} - -const char *ul_path_get_prefix(struct path_cxt *pc) -{ - return pc ? pc->prefix : NULL; -} - -int ul_path_set_dir(struct path_cxt *pc, const char *dir) -{ - char *p = NULL; - - if (dir) { - p = strdup(dir); - if (!p) - return -ENOMEM; - } - - if (pc->dir_fd >= 0) { - close(pc->dir_fd); - pc->dir_fd = -1; - } - - free(pc->dir_path); - pc->dir_path = p; - DBG(CXT, ul_debugobj(pc, "new dir: '%s'", p)); - return 0; -} - -const char *ul_path_get_dir(struct path_cxt *pc) -{ - return pc ? pc->dir_path : NULL; -} - -int ul_path_set_dialect(struct path_cxt *pc, void *data, void free_data(struct path_cxt *)) -{ - pc->dialect = data; - pc->free_dialect = free_data; - DBG(CXT, ul_debugobj(pc, "(re)set dialect")); - return 0; -} - -void *ul_path_get_dialect(struct path_cxt *pc) -{ - return pc ? pc->dialect : NULL; -} - -int ul_path_set_enoent_redirect(struct path_cxt *pc, int (*func)(struct path_cxt *, const char *, int *)) -{ - pc->redirect_on_enoent = func; - return 0; -} - -static const char *get_absdir(struct path_cxt *pc) -{ - int rc; - const char *dirpath; - - if (!pc->prefix) - return pc->dir_path; - - dirpath = pc->dir_path; - if (!dirpath) - return pc->prefix; - if (*dirpath == '/') - dirpath++; - - rc = snprintf(pc->path_buffer, sizeof(pc->path_buffer), "%s/%s", pc->prefix, dirpath); - if (rc < 0) - return NULL; - if ((size_t)rc >= sizeof(pc->path_buffer)) { - errno = ENAMETOOLONG; - return NULL; - } - - return pc->path_buffer; -} - -int ul_path_is_accessible(struct path_cxt *pc) -{ - const char *path; - assert(pc); - - if (pc->dir_fd >= 0) - return 1; - - path = get_absdir(pc); - if (!path) - return 0; - return access(path, F_OK) == 0; -} - -int ul_path_get_dirfd(struct path_cxt *pc) -{ - assert(pc); - assert(pc->dir_path); - - if (pc->dir_fd < 0) { - const char *path = get_absdir(pc); - if (!path) - return -errno; - - DBG(CXT, ul_debugobj(pc, "opening dir: '%s'", path)); - pc->dir_fd = open(path, O_RDONLY|O_CLOEXEC); - } - - return pc->dir_fd; -} - -/* Note that next ul_path_get_dirfd() will reopen the directory */ -void ul_path_close_dirfd(struct path_cxt *pc) -{ - assert(pc); - - if (pc->dir_fd >= 0) { - DBG(CXT, ul_debugobj(pc, "closing dir")); - close(pc->dir_fd); - pc->dir_fd = -1; - } -} - -int ul_path_isopen_dirfd(struct path_cxt *pc) -{ - return pc && pc->dir_fd >= 0; -} - -static const char *ul_path_mkpath(struct path_cxt *pc, const char *path, va_list ap) -{ - int rc; - - errno = 0; - - rc = vsnprintf(pc->path_buffer, sizeof(pc->path_buffer), path, ap); - if (rc < 0) { - if (!errno) - errno = EINVAL; - return NULL; - } - - if ((size_t)rc >= sizeof(pc->path_buffer)) { - errno = ENAMETOOLONG; - return NULL; - } - - return pc->path_buffer; -} - -char *ul_path_get_abspath(struct path_cxt *pc, char *buf, size_t bufsz, const char *path, ...) -{ - if (path) { - int rc; - va_list ap; - const char *tail = NULL, *dirpath = pc->dir_path; - - va_start(ap, path); - tail = ul_path_mkpath(pc, path, ap); - va_end(ap); - - if (dirpath && *dirpath == '/') - dirpath++; - if (tail && *tail == '/') - tail++; - - rc = snprintf(buf, bufsz, "%s/%s/%s", - pc->prefix ? pc->prefix : "", - dirpath ? dirpath : "", - tail ? tail : ""); - - if ((size_t)rc >= bufsz) { - errno = ENAMETOOLONG; - return NULL; - } - } else { - const char *tmp = get_absdir(pc); - - if (!tmp) - return NULL; - xstrncpy(buf, tmp, bufsz); - } - - return buf; -} - - -int ul_path_access(struct path_cxt *pc, int mode, const char *path) -{ - int rc; - - if (!pc) { - rc = access(path, mode); - DBG(CXT, ul_debug("access '%s' [no context, rc=%d]", path, rc)); - } else { - int dir = ul_path_get_dirfd(pc); - if (dir < 0) - return dir; - if (*path == '/') - path++; - - rc = faccessat(dir, path, mode, 0); - - if (rc && errno == ENOENT - && pc->redirect_on_enoent - && pc->redirect_on_enoent(pc, path, &dir) == 0) - rc = faccessat(dir, path, mode, 0); - - DBG(CXT, ul_debugobj(pc, "access: '%s' [rc=%d]", path, rc)); - } - return rc; -} - -int ul_path_accessf(struct path_cxt *pc, int mode, const char *path, ...) -{ - va_list ap; - const char *p; - - va_start(ap, path); - p = ul_path_mkpath(pc, path, ap); - va_end(ap); - - return !p ? -errno : ul_path_access(pc, mode, p); -} - -int ul_path_stat(struct path_cxt *pc, struct stat *sb, const char *path) -{ - int rc; - - if (!pc) { - rc = stat(path, sb); - DBG(CXT, ul_debug("stat '%s' [no context, rc=%d]", path, rc)); - } else { - int dir = ul_path_get_dirfd(pc); - if (dir < 0) - return dir; - if (*path == '/') - path++; - - rc = fstatat(dir, path, sb, 0); - - if (rc && errno == ENOENT - && pc->redirect_on_enoent - && pc->redirect_on_enoent(pc, path, &dir) == 0) - rc = fstatat(dir, path, sb, 0); - - DBG(CXT, ul_debugobj(pc, "stat '%s' [rc=%d]", path, rc)); - } - return rc; -} - -int ul_path_open(struct path_cxt *pc, int flags, const char *path) -{ - int fd; - - if (!pc) { - fd = open(path, flags); - DBG(CXT, ul_debug("opening '%s' [no context]", path)); - } else { - int fdx; - int dir = ul_path_get_dirfd(pc); - if (dir < 0) - return dir; - - if (*path == '/') - path++; - - fdx = fd = openat(dir, path, flags); - - if (fd < 0 && errno == ENOENT - && pc->redirect_on_enoent - && pc->redirect_on_enoent(pc, path, &dir) == 0) - fd = openat(dir, path, flags); - - DBG(CXT, ul_debugobj(pc, "opening '%s'%s", path, fdx != fd ? " [redirected]" : "")); - } - return fd; -} - -int ul_path_vopenf(struct path_cxt *pc, int flags, const char *path, va_list ap) -{ - const char *p = ul_path_mkpath(pc, path, ap); - - return !p ? -errno : ul_path_open(pc, flags, p); -} - -int ul_path_openf(struct path_cxt *pc, int flags, const char *path, ...) -{ - va_list ap; - int rc; - - va_start(ap, path); - rc = ul_path_vopenf(pc, flags, path, ap); - va_end(ap); - - return rc; -} - -/* - * Maybe stupid, but good enough ;-) - */ -static int mode2flags(const char *mode) -{ - int flags = 0; - const char *p; - - for (p = mode; p && *p; p++) { - if (*p == 'r' && *(p + 1) == '+') - flags |= O_RDWR; - else if (*p == 'r') - flags |= O_RDONLY; - - else if (*p == 'w' && *(p + 1) == '+') - flags |= O_RDWR | O_TRUNC; - else if (*p == 'w') - flags |= O_WRONLY | O_TRUNC; - - else if (*p == 'a' && *(p + 1) == '+') - flags |= O_RDWR | O_APPEND; - else if (*p == 'a') - flags |= O_WRONLY | O_APPEND; -#ifdef O_CLOEXEC - else if (*p == *UL_CLOEXECSTR) - flags |= O_CLOEXEC; -#endif - } - - return flags; -} - -FILE *ul_path_fopen(struct path_cxt *pc, const char *mode, const char *path) -{ - int flags = mode2flags(mode); - int fd = ul_path_open(pc, flags, path); - - if (fd < 0) - return NULL; - - return fdopen(fd, mode); -} - - -FILE *ul_path_vfopenf(struct path_cxt *pc, const char *mode, const char *path, va_list ap) -{ - const char *p = ul_path_mkpath(pc, path, ap); - - return !p ? NULL : ul_path_fopen(pc, mode, p); -} - -FILE *ul_path_fopenf(struct path_cxt *pc, const char *mode, const char *path, ...) -{ - FILE *f; - va_list ap; - - va_start(ap, path); - f = ul_path_vfopenf(pc, mode, path, ap); - va_end(ap); - - return f; -} - -/* - * Open directory @path in read-onl mode. If the path is NULL then duplicate FD - * to the directory addressed by @pc. - */ -DIR *ul_path_opendir(struct path_cxt *pc, const char *path) -{ - DIR *dir; - int fd = -1; - - if (path) - fd = ul_path_open(pc, O_RDONLY|O_CLOEXEC, path); - else if (pc->dir_path) { - int dirfd; - - DBG(CXT, ul_debugobj(pc, "duplicate dir path")); - dirfd = ul_path_get_dirfd(pc); - if (dirfd >= 0) - fd = dup_fd_cloexec(dirfd, STDERR_FILENO + 1); - } - - if (fd < 0) - return NULL; - - dir = fdopendir(fd); - if (!dir) { - close(fd); - return NULL; - } - if (!path) - rewinddir(dir); - return dir; -} - - -/* - * Open directory @path in read-onl mode. If the path is NULL then duplicate FD - * to the directory addressed by @pc. - */ -DIR *ul_path_vopendirf(struct path_cxt *pc, const char *path, va_list ap) -{ - const char *p = ul_path_mkpath(pc, path, ap); - - return !p ? NULL : ul_path_opendir(pc, p); -} - -/* - * Open directory @path in read-onl mode. If the path is NULL then duplicate FD - * to the directory addressed by @pc. - */ -DIR *ul_path_opendirf(struct path_cxt *pc, const char *path, ...) -{ - va_list ap; - DIR *dir; - - va_start(ap, path); - dir = ul_path_vopendirf(pc, path, ap); - va_end(ap); - - return dir; -} - -/* - * If @path is NULL then readlink is called on @pc directory. - */ -ssize_t ul_path_readlink(struct path_cxt *pc, char *buf, size_t bufsiz, const char *path) -{ - int dirfd; - - if (!path) { - const char *p = get_absdir(pc); - if (!p) - return -errno; - return readlink(p, buf, bufsiz); - } - - dirfd = ul_path_get_dirfd(pc); - if (dirfd < 0) - return dirfd; - - if (*path == '/') - path++; - - return readlinkat(dirfd, path, buf, bufsiz); -} - -/* - * If @path is NULL then readlink is called on @pc directory. - */ -ssize_t ul_path_readlinkf(struct path_cxt *pc, char *buf, size_t bufsiz, const char *path, ...) -{ - const char *p; - va_list ap; - - va_start(ap, path); - p = ul_path_mkpath(pc, path, ap); - va_end(ap); - - return !p ? -errno : ul_path_readlink(pc, buf, bufsiz, p); -} - -int ul_path_read(struct path_cxt *pc, char *buf, size_t len, const char *path) -{ - int rc, errsv; - int fd; - - fd = ul_path_open(pc, O_RDONLY|O_CLOEXEC, path); - if (fd < 0) - return -errno; - - DBG(CXT, ul_debug(" reading '%s'", path)); - rc = read_all(fd, buf, len); - - errsv = errno; - close(fd); - errno = errsv; - return rc; -} - -int ul_path_vreadf(struct path_cxt *pc, char *buf, size_t len, const char *path, va_list ap) -{ - const char *p = ul_path_mkpath(pc, path, ap); - - return !p ? -errno : ul_path_read(pc, buf, len, p); -} - -int ul_path_readf(struct path_cxt *pc, char *buf, size_t len, const char *path, ...) -{ - va_list ap; - int rc; - - va_start(ap, path); - rc = ul_path_vreadf(pc, buf, len, path, ap); - va_end(ap); - - return rc; -} - - -/* - * Returns newly allocated buffer with data from file. Maximal size is BUFSIZ - * (send patch if you need something bigger;-) - * - * Returns size of the string! - */ -int ul_path_read_string(struct path_cxt *pc, char **str, const char *path) -{ - char buf[BUFSIZ]; - int rc; - - if (!str) - return -EINVAL; - - *str = NULL; - rc = ul_path_read(pc, buf, sizeof(buf) - 1, path); - if (rc < 0) - return rc; - - /* Remove tailing newline (usual in sysfs) */ - if (rc > 0 && *(buf + rc - 1) == '\n') - --rc; - - buf[rc] = '\0'; - *str = strdup(buf); - if (!*str) - rc = -ENOMEM; - - return rc; -} - -int ul_path_readf_string(struct path_cxt *pc, char **str, const char *path, ...) -{ - const char *p; - va_list ap; - - va_start(ap, path); - p = ul_path_mkpath(pc, path, ap); - va_end(ap); - - return !p ? -errno : ul_path_read_string(pc, str, p); -} - -int ul_path_read_buffer(struct path_cxt *pc, char *buf, size_t bufsz, const char *path) -{ - int rc = ul_path_read(pc, buf, bufsz - 1, path); - if (rc < 0) - return rc; - - /* Remove tailing newline (usual in sysfs) */ - if (rc > 0 && *(buf + rc - 1) == '\n') - buf[--rc] = '\0'; - else - buf[rc - 1] = '\0'; - - return rc; -} - -int ul_path_readf_buffer(struct path_cxt *pc, char *buf, size_t bufsz, const char *path, ...) -{ - const char *p; - va_list ap; - - va_start(ap, path); - p = ul_path_mkpath(pc, path, ap); - va_end(ap); - - return !p ? -errno : ul_path_read_buffer(pc, buf, bufsz, p); -} - -int ul_path_scanf(struct path_cxt *pc, const char *path, const char *fmt, ...) -{ - FILE *f; - va_list fmt_ap; - int rc; - - f = ul_path_fopen(pc, "r" UL_CLOEXECSTR, path); - if (!f) - return -EINVAL; - - DBG(CXT, ul_debug(" fscanf [%s] '%s'", fmt, path)); - - va_start(fmt_ap, fmt); - rc = vfscanf(f, fmt, fmt_ap); - va_end(fmt_ap); - - fclose(f); - return rc; -} - -int ul_path_scanff(struct path_cxt *pc, const char *path, va_list ap, const char *fmt, ...) -{ - FILE *f; - va_list fmt_ap; - int rc; - - f = ul_path_vfopenf(pc, "r" UL_CLOEXECSTR, path, ap); - if (!f) - return -EINVAL; - - va_start(fmt_ap, fmt); - rc = vfscanf(f, fmt, fmt_ap); - va_end(fmt_ap); - - fclose(f); - return rc; -} - - -int ul_path_read_s64(struct path_cxt *pc, int64_t *res, const char *path) -{ - int64_t x = 0; - int rc; - - rc = ul_path_scanf(pc, path, "%"SCNd64, &x); - if (rc != 1) - return -1; - if (res) - *res = x; - return 0; -} - -int ul_path_readf_s64(struct path_cxt *pc, int64_t *res, const char *path, ...) -{ - const char *p; - va_list ap; - - va_start(ap, path); - p = ul_path_mkpath(pc, path, ap); - va_end(ap); - - return !p ? -errno : ul_path_read_s64(pc, res, p); -} - -int ul_path_read_u64(struct path_cxt *pc, uint64_t *res, const char *path) -{ - uint64_t x = 0; - int rc; - - rc = ul_path_scanf(pc, path, "%"SCNu64, &x); - if (rc != 1) - return -1; - if (res) - *res = x; - return 0; -} - -int ul_path_readf_u64(struct path_cxt *pc, uint64_t *res, const char *path, ...) -{ - const char *p; - va_list ap; - - va_start(ap, path); - p = ul_path_mkpath(pc, path, ap); - va_end(ap); - - return !p ? -errno : ul_path_read_u64(pc, res, p); -} - -int ul_path_read_s32(struct path_cxt *pc, int *res, const char *path) -{ - int rc, x = 0; - - rc = ul_path_scanf(pc, path, "%d", &x); - if (rc != 1) - return -1; - if (res) - *res = x; - return 0; -} - -int ul_path_readf_s32(struct path_cxt *pc, int *res, const char *path, ...) -{ - const char *p; - va_list ap; - - va_start(ap, path); - p = ul_path_mkpath(pc, path, ap); - va_end(ap); - - return !p ? -errno : ul_path_read_s32(pc, res, p); -} - -int ul_path_read_u32(struct path_cxt *pc, unsigned int *res, const char *path) -{ - int rc; - unsigned int x; - - rc = ul_path_scanf(pc, path, "%u", &x); - if (rc != 1) - return -1; - if (res) - *res = x; - return 0; -} - -int ul_path_readf_u32(struct path_cxt *pc, unsigned int *res, const char *path, ...) -{ - const char *p; - va_list ap; - - va_start(ap, path); - p = ul_path_mkpath(pc, path, ap); - va_end(ap); - - return !p ? -errno : ul_path_read_u32(pc, res, p); -} - -int ul_path_read_majmin(struct path_cxt *pc, dev_t *res, const char *path) -{ - int rc, maj, min; - - rc = ul_path_scanf(pc, path, "%d:%d", &maj, &min); - if (rc != 2) - return -1; - if (res) - *res = makedev(maj, min); - return 0; -} - -int ul_path_readf_majmin(struct path_cxt *pc, dev_t *res, const char *path, ...) -{ - const char *p; - va_list ap; - - va_start(ap, path); - p = ul_path_mkpath(pc, path, ap); - va_end(ap); - - return !p ? -errno : ul_path_read_majmin(pc, res, p); -} - -int ul_path_write_string(struct path_cxt *pc, const char *str, const char *path) -{ - int rc, errsv; - int fd; - - fd = ul_path_open(pc, O_WRONLY|O_CLOEXEC, path); - if (fd < 0) - return -errno; - - rc = write_all(fd, str, strlen(str)); - - errsv = errno; - close(fd); - errno = errsv; - return rc; -} - -int ul_path_writef_string(struct path_cxt *pc, const char *str, const char *path, ...) -{ - const char *p; - va_list ap; - - va_start(ap, path); - p = ul_path_mkpath(pc, path, ap); - va_end(ap); - - return !p ? -errno : ul_path_write_string(pc, str, p); -} - -int ul_path_write_s64(struct path_cxt *pc, int64_t num, const char *path) -{ - char buf[sizeof(stringify_value(LLONG_MAX))]; - int rc, errsv; - int fd, len; - - fd = ul_path_open(pc, O_WRONLY|O_CLOEXEC, path); - if (fd < 0) - return -errno; - - len = snprintf(buf, sizeof(buf), "%" PRId64, num); - if (len < 0 || (size_t) len >= sizeof(buf)) - rc = len < 0 ? -errno : -E2BIG; - else - rc = write_all(fd, buf, len); - - errsv = errno; - close(fd); - errno = errsv; - return rc; -} - -int ul_path_write_u64(struct path_cxt *pc, uint64_t num, const char *path) -{ - char buf[sizeof(stringify_value(ULLONG_MAX))]; - int rc, errsv; - int fd, len; - - fd = ul_path_open(pc, O_WRONLY|O_CLOEXEC, path); - if (fd < 0) - return -errno; - - len = snprintf(buf, sizeof(buf), "%" PRIu64, num); - if (len < 0 || (size_t) len >= sizeof(buf)) - rc = len < 0 ? -errno : -E2BIG; - else - rc = write_all(fd, buf, len); - - errsv = errno; - close(fd); - errno = errsv; - return rc; -} - -int ul_path_writef_u64(struct path_cxt *pc, uint64_t num, const char *path, ...) -{ - const char *p; - va_list ap; - - va_start(ap, path); - p = ul_path_mkpath(pc, path, ap); - va_end(ap); - - return !p ? -errno : ul_path_write_u64(pc, num, p); - -} - -int ul_path_count_dirents(struct path_cxt *pc, const char *path) -{ - DIR *dir; - int r = 0; - - dir = ul_path_opendir(pc, path); - if (!dir) - return 0; - - while (xreaddir(dir)) r++; - - closedir(dir); - return r; -} - -int ul_path_countf_dirents(struct path_cxt *pc, const char *path, ...) -{ - const char *p; - va_list ap; - - va_start(ap, path); - p = ul_path_mkpath(pc, path, ap); - va_end(ap); - - return !p ? -errno : ul_path_count_dirents(pc, p); -} - -/* - * Like fopen() but, @path is always prefixed by @prefix. This function is - * useful in case when ul_path_* API is overkill. - */ -FILE *ul_prefix_fopen(const char *prefix, const char *path, const char *mode) -{ - char buf[PATH_MAX]; - - if (!path) - return NULL; - if (!prefix) - return fopen(path, mode); - if (*path == '/') - path++; - - snprintf(buf, sizeof(buf), "%s/%s", prefix, path); - return fopen(buf, mode); -} - -#ifdef HAVE_CPU_SET_T -static int ul_path_cpuparse(struct path_cxt *pc, cpu_set_t **set, int maxcpus, int islist, const char *path, va_list ap) -{ - FILE *f; - size_t setsize, len = maxcpus * 7; - char buf[len]; - int rc; - - *set = NULL; - - f = ul_path_vfopenf(pc, "r" UL_CLOEXECSTR, path, ap); - if (!f) - return -errno; - - rc = fgets(buf, len, f) == NULL ? -errno : 0; - fclose(f); - - if (rc) - return rc; - - len = strlen(buf); - if (buf[len - 1] == '\n') - buf[len - 1] = '\0'; - - *set = cpuset_alloc(maxcpus, &setsize, NULL); - if (!*set) - return -ENOMEM; - - if (islist) { - if (cpulist_parse(buf, *set, setsize, 0)) { - cpuset_free(*set); - return -EINVAL; - } - } else { - if (cpumask_parse(buf, *set, setsize)) { - cpuset_free(*set); - return -EINVAL; - } - } - return 0; -} - -int ul_path_readf_cpuset(struct path_cxt *pc, cpu_set_t **set, int maxcpus, const char *path, ...) -{ - va_list ap; - int rc = 0; - - va_start(ap, path); - rc = ul_path_cpuparse(pc, set, maxcpus, 0, path, ap); - va_end(ap); - - return rc; -} - -int ul_path_readf_cpulist(struct path_cxt *pc, cpu_set_t **set, int maxcpus, const char *path, ...) -{ - va_list ap; - int rc = 0; - - va_start(ap, path); - rc = ul_path_cpuparse(pc, set, maxcpus, 1, path, ap); - va_end(ap); - - return rc; -} - -#endif /* HAVE_CPU_SET_T */ - - -#ifdef TEST_PROGRAM_PATH -#include <getopt.h> - -static void __attribute__((__noreturn__)) usage(void) -{ - fprintf(stdout, " %s [options] <dir> <command>\n\n", program_invocation_short_name); - fputs(" -p, --prefix <dir> redirect hardcoded paths to <dir>\n", stdout); - - fputs(" Commands:\n", stdout); - fputs(" read-u64 <file> read uint64_t from file\n", stdout); - fputs(" read-s64 <file> read int64_t from file\n", stdout); - fputs(" read-u32 <file> read uint32_t from file\n", stdout); - fputs(" read-s32 <file> read int32_t from file\n", stdout); - fputs(" read-string <file> read string from file\n", stdout); - fputs(" read-majmin <file> read devno from file\n", stdout); - fputs(" read-link <file> read symlink\n", stdout); - fputs(" write-string <file> <str> write string from file\n", stdout); - fputs(" write-u64 <file> <str> write uint64_t from file\n", stdout); - - exit(EXIT_SUCCESS); -} - -int main(int argc, char *argv[]) -{ - int c; - const char *prefix = NULL, *dir, *file, *command; - struct path_cxt *pc = NULL; - - static const struct option longopts[] = { - { "prefix", 1, NULL, 'p' }, - { "help", 0, NULL, 'h' }, - { NULL, 0, NULL, 0 }, - }; - - while((c = getopt_long(argc, argv, "p:h", longopts, NULL)) != -1) { - switch(c) { - case 'p': - prefix = optarg; - break; - case 'h': - usage(); - break; - default: - err(EXIT_FAILURE, "try --help"); - } - } - - if (optind == argc) - errx(EXIT_FAILURE, "<dir> not defined"); - dir = argv[optind++]; - - ul_path_init_debug(); - - pc = ul_new_path(dir); - if (!pc) - err(EXIT_FAILURE, "failed to initialize path context"); - if (prefix) - ul_path_set_prefix(pc, prefix); - - if (optind == argc) - errx(EXIT_FAILURE, "<command> not defined"); - command = argv[optind++]; - - if (strcmp(command, "read-u32") == 0) { - uint32_t res; - - if (optind == argc) - errx(EXIT_FAILURE, "<file> not defined"); - file = argv[optind++]; - - if (ul_path_read_u32(pc, &res, file) != 0) - err(EXIT_FAILURE, "read u64 failed"); - printf("read: %s: %u\n", file, res); - - if (ul_path_readf_u32(pc, &res, "%s", file) != 0) - err(EXIT_FAILURE, "readf u64 failed"); - printf("readf: %s: %u\n", file, res); - - } else if (strcmp(command, "read-s32") == 0) { - int32_t res; - - if (optind == argc) - errx(EXIT_FAILURE, "<file> not defined"); - file = argv[optind++]; - - if (ul_path_read_s32(pc, &res, file) != 0) - err(EXIT_FAILURE, "read u64 failed"); - printf("read: %s: %d\n", file, res); - - if (ul_path_readf_s32(pc, &res, "%s", file) != 0) - err(EXIT_FAILURE, "readf u64 failed"); - printf("readf: %s: %d\n", file, res); - - } else if (strcmp(command, "read-u64") == 0) { - uint64_t res; - - if (optind == argc) - errx(EXIT_FAILURE, "<file> not defined"); - file = argv[optind++]; - - if (ul_path_read_u64(pc, &res, file) != 0) - err(EXIT_FAILURE, "read u64 failed"); - printf("read: %s: %" PRIu64 "\n", file, res); - - if (ul_path_readf_u64(pc, &res, "%s", file) != 0) - err(EXIT_FAILURE, "readf u64 failed"); - printf("readf: %s: %" PRIu64 "\n", file, res); - - } else if (strcmp(command, "read-s64") == 0) { - int64_t res; - - if (optind == argc) - errx(EXIT_FAILURE, "<file> not defined"); - file = argv[optind++]; - - if (ul_path_read_s64(pc, &res, file) != 0) - err(EXIT_FAILURE, "read u64 failed"); - printf("read: %s: %" PRIu64 "\n", file, res); - - if (ul_path_readf_s64(pc, &res, "%s", file) != 0) - err(EXIT_FAILURE, "readf u64 failed"); - printf("readf: %s: %" PRIu64 "\n", file, res); - - } else if (strcmp(command, "read-majmin") == 0) { - dev_t res; - - if (optind == argc) - errx(EXIT_FAILURE, "<file> not defined"); - file = argv[optind++]; - - if (ul_path_read_majmin(pc, &res, file) != 0) - err(EXIT_FAILURE, "read maj:min failed"); - printf("read: %s: %d\n", file, (int) res); - - if (ul_path_readf_majmin(pc, &res, "%s", file) != 0) - err(EXIT_FAILURE, "readf maj:min failed"); - printf("readf: %s: %d\n", file, (int) res); - - } else if (strcmp(command, "read-string") == 0) { - char *res; - - if (optind == argc) - errx(EXIT_FAILURE, "<file> not defined"); - file = argv[optind++]; - - if (ul_path_read_string(pc, &res, file) < 0) - err(EXIT_FAILURE, "read string failed"); - printf("read: %s: %s\n", file, res); - - if (ul_path_readf_string(pc, &res, "%s", file) < 0) - err(EXIT_FAILURE, "readf string failed"); - printf("readf: %s: %s\n", file, res); - - } else if (strcmp(command, "read-link") == 0) { - char res[PATH_MAX]; - - if (optind == argc) - errx(EXIT_FAILURE, "<file> not defined"); - file = argv[optind++]; - - if (ul_path_readlink(pc, res, sizeof(res), file) < 0) - err(EXIT_FAILURE, "read symlink failed"); - printf("read: %s: %s\n", file, res); - - if (ul_path_readlinkf(pc, res, sizeof(res), "%s", file) < 0) - err(EXIT_FAILURE, "readf symlink failed"); - printf("readf: %s: %s\n", file, res); - - } else if (strcmp(command, "write-string") == 0) { - char *str; - - if (optind + 1 == argc) - errx(EXIT_FAILURE, "<file> <string> not defined"); - file = argv[optind++]; - str = argv[optind++]; - - if (ul_path_write_string(pc, str, file) != 0) - err(EXIT_FAILURE, "write string failed"); - if (ul_path_writef_string(pc, str, "%s", file) != 0) - err(EXIT_FAILURE, "writef string failed"); - - } else if (strcmp(command, "write-u64") == 0) { - uint64_t num; - - if (optind + 1 == argc) - errx(EXIT_FAILURE, "<file> <num> not defined"); - file = argv[optind++]; - num = strtoumax(argv[optind++], NULL, 0); - - if (ul_path_write_u64(pc, num, file) != 0) - err(EXIT_FAILURE, "write u64 failed"); - if (ul_path_writef_u64(pc, num, "%s", file) != 0) - err(EXIT_FAILURE, "writef u64 failed"); - } - - ul_unref_path(pc); - return EXIT_SUCCESS; -} -#endif /* TEST_PROGRAM_PATH */ - diff --git a/utils/lib/plymouth-ctrl.c b/utils/lib/plymouth-ctrl.c deleted file mode 100644 index 2d3deda..0000000 --- a/utils/lib/plymouth-ctrl.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * plymouth-ctrl.c Simply communications with plymouthd - * to avoid forked sub processes and/or - * missed plymouth send commands tool - * due a plymouthd replacement. - * - * Copyright (c) 2016 SUSE Linux GmbH, All rights reserved. - * Copyright (c) 2016 Werner Fink <werner@suse.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING); if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301, USA. - * - * Author: Werner Fink <werner@suse.de> - */ - -#include <errno.h> -#include <limits.h> -#include <poll.h> -#include <signal.h> -#include <stdarg.h> -#include <stdlib.h> -#include <sys/mman.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <sys/un.h> -#include <unistd.h> - -#include "all-io.h" -#include "c.h" -#include "nls.h" -#include "plymouth-ctrl.h" - -static int can_read(int fd, const long timeout) -{ - struct pollfd fds = { - .fd = fd, - .events = POLLIN|POLLPRI, - .revents = 0, - }; - int ret; - - do { - ret = poll(&fds, 1, timeout); - } while ((ret < 0) && (errno == EINTR)); - - return (ret == 1) && (fds.revents & (POLLIN|POLLPRI)); -} - -static int open_un_socket_and_connect(void) -{ - /* The abstract UNIX socket of plymouth */ - struct sockaddr_un su = { - .sun_family = AF_UNIX, - .sun_path = PLYMOUTH_SOCKET_PATH, - }; - const int one = 1; - int fd, ret; - - fd = socket(PF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); - if (fd < 0) { - warnx(_("cannot open UNIX socket")); - goto err; - } - - ret = setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)); - if (ret < 0) { - warnx(_("cannot set option for UNIX socket")); - close(fd); - fd = -1; - goto err; - } - - /* Note, the abstract PLYMOUTH_SOCKET_PATH has a leading NULL byte */ - ret = connect(fd, (struct sockaddr *) &su, - offsetof(struct sockaddr_un, sun_path) + 1 + strlen(su.sun_path+1)); - if (ret < 0) { - if (errno != ECONNREFUSED) - warnx(_("cannot connect on UNIX socket")); - close(fd); - fd = -1; - goto err; - } -err: - return fd; -} - -int plymouth_command(int cmd, ...) -{ - uint8_t answer[2], command[2]; - struct sigaction sp, op; - int fdsock = -1, ret = 0; - - sigemptyset (&sp.sa_mask); - sp.sa_handler = SIG_IGN; - sp.sa_flags = SA_RESTART; - sigaction(SIGPIPE, &sp, &op); - - /* The plymouthd does read at least two bytes. */ - command[1] = '\0'; - switch (cmd) { - case MAGIC_PING: - fdsock = open_un_socket_and_connect(); - if (fdsock >= 0) { - command[0] = cmd; - write_all(fdsock, command, sizeof(command)); - } - break; - case MAGIC_QUIT: - fdsock = open_un_socket_and_connect(); - if (fdsock >= 0) { - command[0] = cmd; - write_all(fdsock, command, sizeof(command)); - } - break; - default: - warnx(_("the plymouth request %c is not implemented"), cmd); - case '?': - goto err; - } - - answer[0] = '\0'; - if (fdsock >= 0) { - if (can_read(fdsock, 1000)) - read_all(fdsock, (char *) &answer[0], sizeof(answer)); - close(fdsock); - } - sigaction(SIGPIPE, &op, NULL); - ret = (answer[0] == ANSWER_ACK) ? 1 : 0; -err: - return ret; -} - diff --git a/utils/lib/procutils.c b/utils/lib/procutils.c deleted file mode 100644 index 8fb5d5c..0000000 --- a/utils/lib/procutils.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright (C) 2011 Davidlohr Bueso <dave@gnu.org> - * - * procutils.c: General purpose procfs parsing utilities - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library Public License for more details. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <dirent.h> -#include <ctype.h> - -#include "procutils.h" -#include "fileutils.h" -#include "all-io.h" -#include "c.h" - -/* - * @pid: process ID for which we want to obtain the threads group - * - * Returns: newly allocated tasks structure - */ -struct proc_tasks *proc_open_tasks(pid_t pid) -{ - struct proc_tasks *tasks; - char path[PATH_MAX]; - - sprintf(path, "/proc/%d/task/", pid); - - tasks = malloc(sizeof(struct proc_tasks)); - if (tasks) { - tasks->dir = opendir(path); - if (tasks->dir) - return tasks; - } - - free(tasks); - return NULL; -} - -/* - * @tasks: allocated tasks structure - * - * Returns: nothing - */ -void proc_close_tasks(struct proc_tasks *tasks) -{ - if (tasks && tasks->dir) - closedir(tasks->dir); - free(tasks); -} - -/* - * @tasks: allocated task structure - * @tid: [output] one of the thread IDs belonging to the thread group - * If when an error occurs, it is set to 0. - * - * Returns: 0 on success, 1 on end, -1 on failure or no more threads - */ -int proc_next_tid(struct proc_tasks *tasks, pid_t *tid) -{ - struct dirent *d; - char *end; - - if (!tasks || !tid) - return -EINVAL; - - *tid = 0; - errno = 0; - - do { - d = readdir(tasks->dir); - if (!d) - return errno ? -1 : 1; /* error or end-of-dir */ - - if (!isdigit((unsigned char) *d->d_name)) - continue; - errno = 0; - *tid = (pid_t) strtol(d->d_name, &end, 10); - if (errno || d->d_name == end || (end && *end)) - return -1; - - } while (!*tid); - - return 0; -} - -/* returns process command path, use free() for result */ -static char *proc_file_strdup(pid_t pid, const char *name) -{ - char buf[BUFSIZ], *res = NULL; - ssize_t sz = 0; - size_t i; - int fd; - - snprintf(buf, sizeof(buf), "/proc/%d/%s", (int) pid, name); - fd = open(buf, O_RDONLY); - if (fd < 0) - goto done; - - sz = read_all(fd, buf, sizeof(buf)); - if (sz <= 0) - goto done; - - for (i = 0; i < (size_t) sz; i++) { - - if (buf[i] == '\0') - buf[i] = ' '; - } - buf[sz - 1] = '\0'; - res = strdup(buf); -done: - if (fd >= 0) - close(fd); - return res; -} - -/* returns process command path, use free() for result */ -char *proc_get_command(pid_t pid) -{ - return proc_file_strdup(pid, "cmdline"); -} - -/* returns process command name, use free() for result */ -char *proc_get_command_name(pid_t pid) -{ - return proc_file_strdup(pid, "comm"); -} - -struct proc_processes *proc_open_processes(void) -{ - struct proc_processes *ps; - - ps = calloc(1, sizeof(struct proc_processes)); - if (ps) { - ps->dir = opendir("/proc"); - if (ps->dir) - return ps; - } - - free(ps); - return NULL; -} - -void proc_close_processes(struct proc_processes *ps) -{ - if (ps && ps->dir) - closedir(ps->dir); - free(ps); -} - -void proc_processes_filter_by_name(struct proc_processes *ps, const char *name) -{ - ps->fltr_name = name; - ps->has_fltr_name = name ? 1 : 0; -} - -void proc_processes_filter_by_uid(struct proc_processes *ps, uid_t uid) -{ - ps->fltr_uid = uid; - ps->has_fltr_uid = 1; -} - -int proc_next_pid(struct proc_processes *ps, pid_t *pid) -{ - struct dirent *d; - - if (!ps || !pid) - return -EINVAL; - - *pid = 0; - errno = 0; - - do { - char buf[BUFSIZ], *p; - - errno = 0; - d = readdir(ps->dir); - if (!d) - return errno ? -1 : 1; /* error or end-of-dir */ - - - if (!isdigit((unsigned char) *d->d_name)) - continue; - - /* filter out by UID */ - if (ps->has_fltr_uid) { - struct stat st; - - if (fstatat(dirfd(ps->dir), d->d_name, &st, 0)) - continue; - if (ps->fltr_uid != st.st_uid) - continue; - } - - /* filter out by NAME */ - if (ps->has_fltr_name) { - char procname[256]; - FILE *f; - - snprintf(buf, sizeof(buf), "%s/stat", d->d_name); - f = fopen_at(dirfd(ps->dir), buf, O_CLOEXEC|O_RDONLY, "r"); - if (!f) - continue; - - p = fgets(buf, sizeof(buf), f); - fclose(f); - if (!p) - continue; - - if (sscanf(buf, "%*d (%255[^)])", procname) != 1) - continue; - - /* ok, we got the process name. */ - if (strcmp(procname, ps->fltr_name) != 0) - continue; - } - - p = NULL; - errno = 0; - *pid = (pid_t) strtol(d->d_name, &p, 10); - if (errno || d->d_name == p || (p && *p)) - return errno ? -errno : -1; - - return 0; - } while (1); - - return 0; -} - -#ifdef TEST_PROGRAM_PROCUTILS - -static int test_tasks(int argc, char *argv[]) -{ - pid_t tid, pid; - struct proc_tasks *ts; - - if (argc != 2) - return EXIT_FAILURE; - - pid = strtol(argv[1], (char **) NULL, 10); - printf("PID=%d, TIDs:", pid); - - ts = proc_open_tasks(pid); - if (!ts) - err(EXIT_FAILURE, "open list of tasks failed"); - - while (proc_next_tid(ts, &tid) == 0) - printf(" %d", tid); - - printf("\n"); - proc_close_tasks(ts); - return EXIT_SUCCESS; -} - -static int test_processes(int argc, char *argv[]) -{ - pid_t pid; - struct proc_processes *ps; - - ps = proc_open_processes(); - if (!ps) - err(EXIT_FAILURE, "open list of processes failed"); - - if (argc >= 3 && strcmp(argv[1], "--name") == 0) - proc_processes_filter_by_name(ps, argv[2]); - - if (argc >= 3 && strcmp(argv[1], "--uid") == 0) - proc_processes_filter_by_uid(ps, (uid_t) atol(argv[2])); - - while (proc_next_pid(ps, &pid) == 0) - printf(" %d", pid); - - printf("\n"); - proc_close_processes(ps); - return EXIT_SUCCESS; -} - -int main(int argc, char *argv[]) -{ - if (argc < 2) { - fprintf(stderr, "usage: %1$s --tasks <pid>\n" - " %1$s --processes [---name <name>] [--uid <uid>]\n", - program_invocation_short_name); - return EXIT_FAILURE; - } - - if (strcmp(argv[1], "--tasks") == 0) - return test_tasks(argc - 1, argv + 1); - if (strcmp(argv[1], "--processes") == 0) - return test_processes(argc - 1, argv + 1); - - return EXIT_FAILURE; -} -#endif /* TEST_PROGRAM_PROCUTILS */ diff --git a/utils/lib/pty-session.c b/utils/lib/pty-session.c deleted file mode 100644 index 06b2a49..0000000 --- a/utils/lib/pty-session.c +++ /dev/null @@ -1,725 +0,0 @@ -/* - * This is pseudo-terminal container for child process where parent creates a - * proxy between the current std{in,out,etrr} and the child's pty. Advantages: - * - * - child has no access to parent's terminal (e.g. su --pty) - * - parent can log all traffic between user and child's terminal (e.g. script(1)) - * - it's possible to start commands on terminal although parent has no terminal - * - * This code is in the public domain; do with it what you wish. - * - * Written by Karel Zak <kzak@redhat.com> in Jul 2019 - */ -#include <stdio.h> -#include <stdlib.h> -#include <pty.h> -#include <poll.h> -#include <sys/signalfd.h> -#include <paths.h> -#include <sys/types.h> -#include <sys/wait.h> - -#include "c.h" -#include "all-io.h" -#include "ttyutils.h" -#include "pty-session.h" -#include "monotonic.h" -#include "debug.h" - -static UL_DEBUG_DEFINE_MASK(ulpty); -UL_DEBUG_DEFINE_MASKNAMES(ulpty) = UL_DEBUG_EMPTY_MASKNAMES; - -#define ULPTY_DEBUG_INIT (1 << 1) -#define ULPTY_DEBUG_SETUP (1 << 2) -#define ULPTY_DEBUG_SIG (1 << 3) -#define ULPTY_DEBUG_IO (1 << 4) -#define ULPTY_DEBUG_DONE (1 << 5) -#define ULPTY_DEBUG_ALL 0xFFFF - -#define DBG(m, x) __UL_DBG(ulpty, ULPTY_DEBUG_, m, x) -#define ON_DBG(m, x) __UL_DBG_CALL(ulpty, ULPTY_DEBUG_, m, x) - -#define UL_DEBUG_CURRENT_MASK UL_DEBUG_MASK(ulpty) -#include "debugobj.h" - -void ul_pty_init_debug(int mask) -{ - if (ulpty_debug_mask) - return; - __UL_INIT_DEBUG_FROM_ENV(ulpty, ULPTY_DEBUG_, mask, ULPTY_DEBUG); -} - -struct ul_pty *ul_new_pty(int is_stdin_tty) -{ - struct ul_pty *pty = calloc(1, sizeof(*pty)); - - if (!pty) - return NULL; - - DBG(SETUP, ul_debugobj(pty, "alloc handler")); - pty->isterm = is_stdin_tty; - pty->master = -1; - pty->slave = -1; - pty->sigfd = -1; - pty->child = (pid_t) -1; - - return pty; -} - -void ul_free_pty(struct ul_pty *pty) -{ - free(pty); -} - -void ul_pty_slave_echo(struct ul_pty *pty, int enable) -{ - assert(pty); - pty->slave_echo = enable ? 1 : 0; -} - -int ul_pty_get_delivered_signal(struct ul_pty *pty) -{ - assert(pty); - return pty->delivered_signal; -} - -struct ul_pty_callbacks *ul_pty_get_callbacks(struct ul_pty *pty) -{ - assert(pty); - return &pty->callbacks; -} - -void ul_pty_set_callback_data(struct ul_pty *pty, void *data) -{ - assert(pty); - pty->callback_data = data; -} - -void ul_pty_set_child(struct ul_pty *pty, pid_t child) -{ - assert(pty); - pty->child = child; -} - -int ul_pty_get_childfd(struct ul_pty *pty) -{ - assert(pty); - return pty->master; -} - -pid_t ul_pty_get_child(struct ul_pty *pty) -{ - assert(pty); - return pty->child; -} - -/* it's active when signals are redirected to sigfd */ -int ul_pty_is_running(struct ul_pty *pty) -{ - assert(pty); - return pty->sigfd >= 0; -} - -void ul_pty_set_mainloop_time(struct ul_pty *pty, struct timeval *tv) -{ - assert(pty); - if (!tv) { - DBG(IO, ul_debugobj(pty, "mainloop time: clear")); - timerclear(&pty->next_callback_time); - } else { - pty->next_callback_time.tv_sec = tv->tv_sec; - pty->next_callback_time.tv_usec = tv->tv_usec; - DBG(IO, ul_debugobj(pty, "mainloop time: %ld.%06ld", tv->tv_sec, tv->tv_usec)); - } -} - -static void pty_signals_cleanup(struct ul_pty *pty) -{ - if (pty->sigfd != -1) - close(pty->sigfd); - pty->sigfd = -1; - - /* restore original setting */ - sigprocmask(SIG_SETMASK, &pty->orgsig, NULL); -} - -/* call me before fork() */ -int ul_pty_setup(struct ul_pty *pty) -{ - struct termios attrs; - sigset_t ourset; - int rc = 0; - - assert(pty->sigfd == -1); - - /* save the current signals setting */ - sigprocmask(0, NULL, &pty->orgsig); - - if (pty->isterm) { - DBG(SETUP, ul_debugobj(pty, "create for terminal")); - - /* original setting of the current terminal */ - if (tcgetattr(STDIN_FILENO, &pty->stdin_attrs) != 0) { - rc = -errno; - goto done; - } - - attrs = pty->stdin_attrs; - if (pty->slave_echo) - attrs.c_lflag |= ECHO; - else - attrs.c_lflag &= ~ECHO; - - ioctl(STDIN_FILENO, TIOCGWINSZ, (char *)&pty->win); - /* create master+slave */ - rc = openpty(&pty->master, &pty->slave, NULL, &attrs, &pty->win); - if (rc) - goto done; - - /* set the current terminal to raw mode; pty_cleanup() reverses this change on exit */ - cfmakeraw(&attrs); - tcsetattr(STDIN_FILENO, TCSANOW, &attrs); - } else { - DBG(SETUP, ul_debugobj(pty, "create for non-terminal")); - - rc = openpty(&pty->master, &pty->slave, NULL, NULL, NULL); - if (rc) - goto done; - - tcgetattr(pty->slave, &attrs); - - if (pty->slave_echo) - attrs.c_lflag |= ECHO; - else - attrs.c_lflag &= ~ECHO; - - tcsetattr(pty->slave, TCSANOW, &attrs); - } - - sigfillset(&ourset); - if (sigprocmask(SIG_BLOCK, &ourset, NULL)) { - rc = -errno; - goto done; - } - - sigemptyset(&ourset); - sigaddset(&ourset, SIGCHLD); - sigaddset(&ourset, SIGWINCH); - sigaddset(&ourset, SIGALRM); - sigaddset(&ourset, SIGTERM); - sigaddset(&ourset, SIGINT); - sigaddset(&ourset, SIGQUIT); - - if (pty->callbacks.flush_logs) - sigaddset(&ourset, SIGUSR1); - - if ((pty->sigfd = signalfd(-1, &ourset, SFD_CLOEXEC)) < 0) - rc = -errno; -done: - if (rc) - ul_pty_cleanup(pty); - - DBG(SETUP, ul_debugobj(pty, "pty setup done [master=%d, slave=%d, rc=%d]", - pty->master, pty->slave, rc)); - return rc; -} - -/* cleanup in parent process */ -void ul_pty_cleanup(struct ul_pty *pty) -{ - struct termios rtt; - - pty_signals_cleanup(pty); - - if (pty->master == -1 || !pty->isterm) - return; - - DBG(DONE, ul_debugobj(pty, "cleanup")); - rtt = pty->stdin_attrs; - tcsetattr(STDIN_FILENO, TCSADRAIN, &rtt); -} - -/* call me in child process */ -void ul_pty_init_slave(struct ul_pty *pty) -{ - DBG(SETUP, ul_debugobj(pty, "initialize slave")); - - setsid(); - - ioctl(pty->slave, TIOCSCTTY, 1); - close(pty->master); - - dup2(pty->slave, STDIN_FILENO); - dup2(pty->slave, STDOUT_FILENO); - dup2(pty->slave, STDERR_FILENO); - - close(pty->slave); - - if (pty->sigfd >= 0) - close(pty->sigfd); - - pty->slave = -1; - pty->master = -1; - pty->sigfd = -1; - - sigprocmask(SIG_SETMASK, &pty->orgsig, NULL); - - DBG(SETUP, ul_debugobj(pty, "... initialize slave done")); -} - -static int write_output(char *obuf, ssize_t bytes) -{ - DBG(IO, ul_debug(" writing output")); - - if (write_all(STDOUT_FILENO, obuf, bytes)) { - DBG(IO, ul_debug(" writing output *failed*")); - return -errno; - } - - return 0; -} - -static int write_to_child(struct ul_pty *pty, char *buf, size_t bufsz) -{ - return write_all(pty->master, buf, bufsz); -} - -/* - * The pty is usually faster than shell, so it's a good idea to wait until - * the previous message has been already read by shell from slave before we - * write to master. This is necessary especially for EOF situation when we can - * send EOF to master before shell is fully initialized, to workaround this - * problem we wait until slave is empty. For example: - * - * echo "date" | su --pty - * - * Unfortunately, the child (usually shell) can ignore stdin at all, so we - * don't wait forever to avoid dead locks... - * - * Note that su --pty is primarily designed for interactive sessions as it - * maintains master+slave tty stuff within the session. Use pipe to write to - * pty and assume non-interactive (tee-like) behavior is NOT well supported. - */ -void ul_pty_write_eof_to_child(struct ul_pty *pty) -{ - unsigned int tries = 0; - struct pollfd fds[] = { - { .fd = pty->slave, .events = POLLIN } - }; - char c = DEF_EOF; - - DBG(IO, ul_debugobj(pty, " waiting for empty slave")); - while (poll(fds, 1, 10) == 1 && tries < 8) { - DBG(IO, ul_debugobj(pty, " slave is not empty")); - xusleep(250000); - tries++; - } - if (tries < 8) - DBG(IO, ul_debugobj(pty, " slave is empty now")); - - DBG(IO, ul_debugobj(pty, " sending EOF to master")); - write_to_child(pty, &c, sizeof(char)); -} - -static int mainloop_callback(struct ul_pty *pty) -{ - int rc; - - if (!pty->callbacks.mainloop) - return 0; - - DBG(IO, ul_debugobj(pty, "calling mainloop callback")); - rc = pty->callbacks.mainloop(pty->callback_data); - - DBG(IO, ul_debugobj(pty, " callback done [rc=%d]", rc)); - return rc; -} - -static int handle_io(struct ul_pty *pty, int fd, int *eof) -{ - char buf[BUFSIZ]; - ssize_t bytes; - int rc = 0; - - DBG(IO, ul_debugobj(pty, " handle I/O on fd=%d", fd)); - *eof = 0; - - /* read from active FD */ - bytes = read(fd, buf, sizeof(buf)); - if (bytes < 0) { - if (errno == EAGAIN || errno == EINTR) - return 0; - return -errno; - } - - if (bytes == 0) { - *eof = 1; - return 0; - } - - /* from stdin (user) to command */ - if (fd == STDIN_FILENO) { - DBG(IO, ul_debugobj(pty, " stdin --> master %zd bytes", bytes)); - - if (write_to_child(pty, buf, bytes)) - return -errno; - - /* without sync write_output() will write both input & - * shell output that looks like double echoing */ - fdatasync(pty->master); - - /* from command (master) to stdout */ - } else if (fd == pty->master) { - DBG(IO, ul_debugobj(pty, " master --> stdout %zd bytes", bytes)); - write_output(buf, bytes); - } - - if (pty->callbacks.log_stream_activity) - rc = pty->callbacks.log_stream_activity( - pty->callback_data, fd, buf, bytes); - - return rc; -} - -void ul_pty_wait_for_child(struct ul_pty *pty) -{ - int status; - pid_t pid; - int options = 0; - - if (pty->child == (pid_t) -1) - return; - - DBG(SIG, ul_debug("waiting for child [child=%d]", (int) pty->child)); - - if (ul_pty_is_running(pty)) { - /* wait for specific child */ - options = WNOHANG; - for (;;) { - pid = waitpid(pty->child, &status, options); - DBG(SIG, ul_debug(" waitpid done [rc=%d]", (int) pid)); - if (pid != (pid_t) - 1) { - if (pty->callbacks.child_die) - pty->callbacks.child_die( - pty->callback_data, - pty->child, status); - ul_pty_set_child(pty, (pid_t) -1); - } else - break; - } - } else { - /* final wait */ - while ((pid = wait3(&status, options, NULL)) > 0) { - DBG(SIG, ul_debug(" wait3 done [rc=%d]", (int) pid)); - if (pid == pty->child) { - if (pty->callbacks.child_die) - pty->callbacks.child_die( - pty->callback_data, - pty->child, status); - ul_pty_set_child(pty, (pid_t) -1); - } - } - } -} - -static int handle_signal(struct ul_pty *pty, int fd) -{ - struct signalfd_siginfo info; - ssize_t bytes; - int rc = 0; - - DBG(SIG, ul_debugobj(pty, " handle signal on fd=%d", fd)); - - bytes = read(fd, &info, sizeof(info)); - if (bytes != sizeof(info)) { - if (bytes < 0 && (errno == EAGAIN || errno == EINTR)) - return 0; - return -errno; - } - - switch (info.ssi_signo) { - case SIGCHLD: - DBG(SIG, ul_debugobj(pty, " get signal SIGCHLD")); - - if (info.ssi_code == CLD_EXITED - || info.ssi_code == CLD_KILLED - || info.ssi_code == CLD_DUMPED) { - - if (pty->callbacks.child_wait) - pty->callbacks.child_wait(pty->callback_data, - pty->child); - else - ul_pty_wait_for_child(pty); - - } else if (info.ssi_status == SIGSTOP && pty->child > 0) - pty->callbacks.child_sigstop(pty->callback_data, - pty->child); - - if (pty->child <= 0) { - DBG(SIG, ul_debugobj(pty, " no child, setting leaving timeout")); - pty->poll_timeout = 10; - timerclear(&pty->next_callback_time); - } - return 0; - case SIGWINCH: - DBG(SIG, ul_debugobj(pty, " get signal SIGWINCH")); - if (pty->isterm) { - ioctl(STDIN_FILENO, TIOCGWINSZ, (char *)&pty->win); - ioctl(pty->slave, TIOCSWINSZ, (char *)&pty->win); - - if (pty->callbacks.log_signal) - rc = pty->callbacks.log_signal(pty->callback_data, - &info, (void *) &pty->win); - } - break; - case SIGTERM: - /* fallthrough */ - case SIGINT: - /* fallthrough */ - case SIGQUIT: - DBG(SIG, ul_debugobj(pty, " get signal SIG{TERM,INT,QUIT}")); - pty->delivered_signal = info.ssi_signo; - /* Child termination is going to generate SIGCHLD (see above) */ - if (pty->child > 0) - kill(pty->child, SIGTERM); - - if (pty->callbacks.log_signal) - rc = pty->callbacks.log_signal(pty->callback_data, - &info, (void *) &pty->win); - break; - case SIGUSR1: - DBG(SIG, ul_debugobj(pty, " get signal SIGUSR1")); - if (pty->callbacks.flush_logs) - rc = pty->callbacks.flush_logs(pty->callback_data); - break; - default: - abort(); - } - - return rc; -} - -/* loop in parent */ -int ul_pty_proxy_master(struct ul_pty *pty) -{ - int rc = 0, ret, eof = 0; - enum { - POLLFD_SIGNAL = 0, - POLLFD_MASTER, - POLLFD_STDIN - - }; - struct pollfd pfd[] = { - [POLLFD_SIGNAL] = { .fd = -1, .events = POLLIN | POLLERR | POLLHUP }, - [POLLFD_MASTER] = { .fd = pty->master, .events = POLLIN | POLLERR | POLLHUP }, - [POLLFD_STDIN] = { .fd = STDIN_FILENO, .events = POLLIN | POLLERR | POLLHUP } - }; - - /* We use signalfd, and standard signals by handlers are completely blocked */ - assert(pty->sigfd >= 0); - - pfd[POLLFD_SIGNAL].fd = pty->sigfd; - pty->poll_timeout = -1; - - while (!pty->delivered_signal) { - size_t i; - int errsv, timeout; - - DBG(IO, ul_debugobj(pty, "--poll() loop--")); - - /* note, callback usually updates @next_callback_time */ - if (timerisset(&pty->next_callback_time)) { - struct timeval now; - - DBG(IO, ul_debugobj(pty, " callback requested")); - gettime_monotonic(&now); - if (timercmp(&now, &pty->next_callback_time, >)) { - rc = mainloop_callback(pty); - if (rc) - break; - } - } - - /* set timeout */ - if (timerisset(&pty->next_callback_time)) { - struct timeval now, rest; - - gettime_monotonic(&now); - timersub(&pty->next_callback_time, &now, &rest); - timeout = (rest.tv_sec * 1000) + (rest.tv_usec / 1000); - } else - timeout = pty->poll_timeout; - - /* wait for input, signal or timeout */ - DBG(IO, ul_debugobj(pty, "calling poll() [timeout=%dms]", timeout)); - ret = poll(pfd, ARRAY_SIZE(pfd), timeout); - - errsv = errno; - DBG(IO, ul_debugobj(pty, "poll() rc=%d", ret)); - - /* error */ - if (ret < 0) { - if (errsv == EAGAIN) - continue; - rc = -errno; - break; - } - - /* timeout */ - if (ret == 0) { - if (timerisset(&pty->next_callback_time)) { - rc = mainloop_callback(pty); - if (rc == 0) - continue; - } else - rc = 0; - - DBG(IO, ul_debugobj(pty, "leaving poll() loop [timeout=%d, rc=%d]", timeout, rc)); - break; - } - /* event */ - for (i = 0; i < ARRAY_SIZE(pfd); i++) { - rc = 0; - - if (pfd[i].revents == 0) - continue; - - DBG(IO, ul_debugobj(pty, " active pfd[%s].fd=%d %s %s %s %s", - i == POLLFD_STDIN ? "stdin" : - i == POLLFD_MASTER ? "master" : - i == POLLFD_SIGNAL ? "signal" : "???", - pfd[i].fd, - pfd[i].revents & POLLIN ? "POLLIN" : "", - pfd[i].revents & POLLHUP ? "POLLHUP" : "", - pfd[i].revents & POLLERR ? "POLLERR" : "", - pfd[i].revents & POLLNVAL ? "POLLNVAL" : "")); - - switch (i) { - case POLLFD_STDIN: - case POLLFD_MASTER: - /* data */ - if (pfd[i].revents & POLLIN) - rc = handle_io(pty, pfd[i].fd, &eof); - /* EOF maybe detected in two ways; they are as follows: - * A) poll() return POLLHUP event after close() - * B) read() returns 0 (no data) - * - * POLLNVAL means that fd is closed. - */ - if ((pfd[i].revents & POLLHUP) || (pfd[i].revents & POLLNVAL) || eof) { - DBG(IO, ul_debugobj(pty, " ignore FD")); - pfd[i].fd = -1; - if (i == POLLFD_STDIN) { - ul_pty_write_eof_to_child(pty); - DBG(IO, ul_debugobj(pty, " ignore STDIN")); - } - } - continue; - case POLLFD_SIGNAL: - rc = handle_signal(pty, pfd[i].fd); - break; - } - if (rc) - break; - } - } - - pty_signals_cleanup(pty); - - DBG(IO, ul_debug("poll() done [signal=%d, rc=%d]", pty->delivered_signal, rc)); - return rc; -} - -#ifdef TEST_PROGRAM_PTY -/* - * $ make test_pty - * $ ./test_pty - * - * ... and see for example tty(1) or "ps afu" - */ -static void child_sigstop(void *data __attribute__((__unused__)), pid_t child) -{ - kill(getpid(), SIGSTOP); - kill(child, SIGCONT); -} - -int main(int argc, char *argv[]) -{ - struct ul_pty_callbacks *cb; - const char *shell, *command = NULL, *shname = NULL; - int caught_signal = 0; - pid_t child; - struct ul_pty *pty; - - shell = getenv("SHELL"); - if (shell == NULL) - shell = _PATH_BSHELL; - if (argc == 2) - command = argv[1]; - - ul_pty_init_debug(0); - - pty = ul_new_pty(isatty(STDIN_FILENO)); - if (!pty) - err(EXIT_FAILURE, "failed to allocate PTY handler"); - - cb = ul_pty_get_callbacks(pty); - cb->child_sigstop = child_sigstop; - - if (ul_pty_setup(pty)) - err(EXIT_FAILURE, "failed to create pseudo-terminal"); - - fflush(stdout); /* ??? */ - - switch ((int) (child = fork())) { - case -1: /* error */ - ul_pty_cleanup(pty); - err(EXIT_FAILURE, "cannot create child process"); - break; - - case 0: /* child */ - ul_pty_init_slave(pty); - - signal(SIGTERM, SIG_DFL); /* because /etc/csh.login */ - - shname = strrchr(shell, '/'); - shname = shname ? shname + 1 : shell; - - if (command) - execl(shell, shname, "-c", command, NULL); - else - execl(shell, shname, "-i", NULL); - err(EXIT_FAILURE, "failed to execute %s", shell); - break; - - default: - break; - } - - /* parent */ - ul_pty_set_child(pty, child); - - /* this is the main loop */ - ul_pty_proxy_master(pty); - - /* all done; cleanup and kill */ - caught_signal = ul_pty_get_delivered_signal(pty); - - if (!caught_signal && ul_pty_get_child(pty) != (pid_t)-1) - ul_pty_wait_for_child(pty); /* final wait */ - - if (caught_signal && ul_pty_get_child(pty) != (pid_t)-1) { - fprintf(stderr, "\nSession terminated, killing shell..."); - kill(child, SIGTERM); - sleep(2); - kill(child, SIGKILL); - fprintf(stderr, " ...killed.\n"); - } - - ul_pty_cleanup(pty); - ul_free_pty(pty); - return EXIT_SUCCESS; -} - -#endif /* TEST_PROGRAM */ - diff --git a/utils/lib/pwdutils.c b/utils/lib/pwdutils.c deleted file mode 100644 index d5f4d2e..0000000 --- a/utils/lib/pwdutils.c +++ /dev/null @@ -1,156 +0,0 @@ -#include <stdlib.h> - -#include "c.h" -#include "pwdutils.h" -#include "xalloc.h" - -/* Returns allocated passwd and allocated pwdbuf to store passwd strings - * fields. In case of error returns NULL and set errno, for unknown user set - * errno to EINVAL - */ -struct passwd *xgetpwnam(const char *username, char **pwdbuf) -{ - struct passwd *pwd = NULL, *res = NULL; - int rc; - - if (!pwdbuf || !username) - return NULL; - - *pwdbuf = xmalloc(UL_GETPW_BUFSIZ); - pwd = xcalloc(1, sizeof(struct passwd)); - - errno = 0; - rc = getpwnam_r(username, pwd, *pwdbuf, UL_GETPW_BUFSIZ, &res); - if (rc != 0) { - errno = rc; - goto failed; - } - if (!res) { - errno = EINVAL; - goto failed; - } - return pwd; -failed: - free(pwd); - free(*pwdbuf); - return NULL; -} - -/* Returns allocated group and allocated grpbuf to store group strings - * fields. In case of error returns NULL and set errno, for unknown group set - * errno to EINVAL - */ -struct group *xgetgrnam(const char *groupname, char **grpbuf) -{ - struct group *grp = NULL, *res = NULL; - int rc; - - if (!grpbuf || !groupname) - return NULL; - - *grpbuf = xmalloc(UL_GETPW_BUFSIZ); - grp = xcalloc(1, sizeof(struct group)); - - errno = 0; - rc = getgrnam_r(groupname, grp, *grpbuf, UL_GETPW_BUFSIZ, &res); - if (rc != 0) { - errno = rc; - goto failed; - } - if (!res) { - errno = EINVAL; - goto failed; - } - return grp; -failed: - free(grp); - free(*grpbuf); - return NULL; -} - -struct passwd *xgetpwuid(uid_t uid, char **pwdbuf) -{ - struct passwd *pwd = NULL, *res = NULL; - int rc; - - if (!pwdbuf) - return NULL; - - *pwdbuf = xmalloc(UL_GETPW_BUFSIZ); - pwd = xcalloc(1, sizeof(struct passwd)); - - errno = 0; - rc = getpwuid_r(uid, pwd, *pwdbuf, UL_GETPW_BUFSIZ, &res); - if (rc != 0) { - errno = rc; - goto failed; - } - if (!res) { - errno = EINVAL; - goto failed; - } - return pwd; -failed: - free(pwd); - free(*pwdbuf); - return NULL; -} - -char *xgetlogin(void) -{ - struct passwd *pw = NULL; - uid_t ruid; - char *user; - - user = getlogin(); - if (user) - return xstrdup(user); - - /* GNU Hurd implementation has an extension where a process can exist in a - * non-conforming environment, and thus be outside the realms of POSIX - * process identifiers; on this platform, getuid() fails with a status of - * (uid_t)(-1) and sets errno if a program is run from a non-conforming - * environment. - * - * http://austingroupbugs.net/view.php?id=511 - */ - errno = 0; - ruid = getuid(); - - if (errno == 0) - pw = getpwuid(ruid); - if (pw && pw->pw_name && *pw->pw_name) - return xstrdup(pw->pw_name); - - return NULL; -} - -#ifdef TEST_PROGRAM -int main(int argc, char *argv[]) -{ - char *buf = NULL; - struct passwd *pwd = NULL; - - if (argc != 2) { - fprintf(stderr, "usage: %s <username>\n", argv[0]); - return EXIT_FAILURE; - } - - pwd = xgetpwnam(argv[1], &buf); - if (!pwd) - err(EXIT_FAILURE, "failed to get %s pwd entry", argv[1]); - - printf("Username: %s\n", pwd->pw_name); - printf("UID: %d\n", pwd->pw_uid); - printf("HOME: %s\n", pwd->pw_dir); - printf("GECO: %s\n", pwd->pw_gecos); - - free(pwd); - free(buf); - - printf("Current: %s\n", (buf = xgetlogin())); - free(buf); - - return EXIT_SUCCESS; -} -#endif /* TEST_PROGRAM */ diff --git a/utils/lib/randutils.c b/utils/lib/randutils.c deleted file mode 100644 index bd2a8f6..0000000 --- a/utils/lib/randutils.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * SPDX-License-Identifier: BSD-3-Clause - * - * General purpose random utilities. Based on libuuid code. - * - * This code is free software; you can redistribute it and/or modify it under - * the terms of the Modified BSD License. The complete text of the license is - * available in the Documentation/licenses/COPYING.BSD-3-Clause file. - */ -#include <stdio.h> -#include <unistd.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include <sys/time.h> - -#include <sys/syscall.h> - -#include "c.h" -#include "randutils.h" -#include "nls.h" - -#ifdef HAVE_TLS -#define THREAD_LOCAL static __thread -#else -#define THREAD_LOCAL static -#endif - -#ifdef HAVE_GETRANDOM -# include <sys/random.h> -#elif defined (__linux__) -# if !defined(SYS_getrandom) && defined(__NR_getrandom) - /* usable kernel-headers, but old glibc-headers */ -# define SYS_getrandom __NR_getrandom -# endif -#endif - -#if !defined(HAVE_GETRANDOM) && defined(SYS_getrandom) -/* libc without function, but we have syscal */ -#define GRND_NONBLOCK 0x01 -#define GRND_RANDOM 0x02 -static int getrandom(void *buf, size_t buflen, unsigned int flags) -{ - return (syscall(SYS_getrandom, buf, buflen, flags)); -} -# define HAVE_GETRANDOM -#endif - -#if defined(__linux__) && defined(__NR_gettid) && defined(HAVE_JRAND48) -#define DO_JRAND_MIX -THREAD_LOCAL unsigned short ul_jrand_seed[3]; -#endif - -int rand_get_number(int low_n, int high_n) -{ - return rand() % (high_n - low_n + 1) + low_n; -} - -static void crank_random(void) -{ - int i; - struct timeval tv; - unsigned int n_pid, n_uid; - - gettimeofday(&tv, NULL); - n_pid = getpid(); - n_uid = getuid(); - srand((n_pid << 16) ^ n_uid ^ tv.tv_sec ^ tv.tv_usec); - -#ifdef DO_JRAND_MIX - ul_jrand_seed[0] = getpid() ^ (tv.tv_sec & 0xFFFF); - ul_jrand_seed[1] = getppid() ^ (tv.tv_usec & 0xFFFF); - ul_jrand_seed[2] = (tv.tv_sec ^ tv.tv_usec) >> 16; -#endif - /* Crank the random number generator a few times */ - gettimeofday(&tv, NULL); - for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--) - rand(); -} - -int random_get_fd(void) -{ - int i, fd; - - fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC); - if (fd == -1) - fd = open("/dev/random", O_RDONLY | O_NONBLOCK | O_CLOEXEC); - if (fd >= 0) { - i = fcntl(fd, F_GETFD); - if (i >= 0) - fcntl(fd, F_SETFD, i | FD_CLOEXEC); - } - crank_random(); - return fd; -} - -/* - * Generate a stream of random nbytes into buf. - * Use /dev/urandom if possible, and if not, - * use glibc pseudo-random functions. - */ -#define UL_RAND_READ_ATTEMPTS 8 -#define UL_RAND_READ_DELAY 125000 /* microseconds */ - -void random_get_bytes(void *buf, size_t nbytes) -{ - unsigned char *cp = (unsigned char *)buf; - size_t i, n = nbytes; - int lose_counter = 0; - -#ifdef HAVE_GETRANDOM - while (n > 0) { - int x; - - errno = 0; - x = getrandom(cp, n, GRND_NONBLOCK); - if (x > 0) { /* success */ - n -= x; - cp += x; - lose_counter = 0; - - } else if (errno == ENOSYS) { /* kernel without getrandom() */ - break; - - } else if (errno == EAGAIN && lose_counter < UL_RAND_READ_ATTEMPTS) { - xusleep(UL_RAND_READ_DELAY); /* no entropy, wait and try again */ - lose_counter++; - } else - break; - } - - if (errno == ENOSYS) -#endif - /* - * We've been built against headers that support getrandom, but the - * running kernel does not. Fallback to reading from /dev/{u,}random - * as before - */ - { - int fd = random_get_fd(); - - lose_counter = 0; - if (fd >= 0) { - while (n > 0) { - ssize_t x = read(fd, cp, n); - if (x <= 0) { - if (lose_counter++ > UL_RAND_READ_ATTEMPTS) - break; - xusleep(UL_RAND_READ_DELAY); - continue; - } - n -= x; - cp += x; - lose_counter = 0; - } - - close(fd); - } - } - /* - * We do this all the time, but this is the only source of - * randomness if /dev/random/urandom is out to lunch. - */ - crank_random(); - for (cp = buf, i = 0; i < nbytes; i++) - *cp++ ^= (rand() >> 7) & 0xFF; - -#ifdef DO_JRAND_MIX - { - unsigned short tmp_seed[3]; - - memcpy(tmp_seed, ul_jrand_seed, sizeof(tmp_seed)); - ul_jrand_seed[2] = ul_jrand_seed[2] ^ syscall(__NR_gettid); - for (cp = buf, i = 0; i < nbytes; i++) - *cp++ ^= (jrand48(tmp_seed) >> 7) & 0xFF; - memcpy(ul_jrand_seed, tmp_seed, - sizeof(ul_jrand_seed)-sizeof(unsigned short)); - } -#endif -} - - -/* - * Tell source of randomness. - */ -const char *random_tell_source(void) -{ -#ifdef HAVE_GETRANDOM - return _("getrandom() function"); -#else - size_t i; - static const char *random_sources[] = { - "/dev/urandom", - "/dev/random" - }; - - for (i = 0; i < ARRAY_SIZE(random_sources); i++) { - if (!access(random_sources[i], R_OK)) - return random_sources[i]; - } -#endif - return _("libc pseudo-random functions"); -} - -#ifdef TEST_PROGRAM_RANDUTILS -#include <inttypes.h> - -int main(int argc, char *argv[]) -{ - size_t i, n; - int64_t *vp, v; - char *buf; - size_t bufsz; - - n = argc == 1 ? 16 : atoi(argv[1]); - - printf("Multiple random calls:\n"); - for (i = 0; i < n; i++) { - random_get_bytes(&v, sizeof(v)); - printf("#%02zu: %25"PRIu64"\n", i, v); - } - - - printf("One random call:\n"); - bufsz = n * sizeof(*vp); - buf = malloc(bufsz); - if (!buf) - err(EXIT_FAILURE, "failed to allocate buffer"); - - random_get_bytes(buf, bufsz); - for (i = 0; i < n; i++) { - vp = (int64_t *) (buf + (i * sizeof(*vp))); - printf("#%02zu: %25"PRIu64"\n", i, *vp); - } - - return EXIT_SUCCESS; -} -#endif /* TEST_PROGRAM_RANDUTILS */ diff --git a/utils/lib/setproctitle.c b/utils/lib/setproctitle.c deleted file mode 100644 index 7168e46..0000000 --- a/utils/lib/setproctitle.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * set process title for ps (from sendmail) - * - * Clobbers argv of our main procedure so ps(1) will display the title. - */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> - -#include "setproctitle.h" - -#ifndef SPT_BUFSIZE -# define SPT_BUFSIZE 2048 -#endif - -extern char **environ; - -static char **argv0; -static size_t argv_lth; - -void initproctitle (int argc, char **argv) -{ - int i; - char **envp = environ; - - /* - * Move the environment so we can reuse the memory. - * (Code borrowed from sendmail.) - * WARNING: ugly assumptions on memory layout here; - * if this ever causes problems, #undef DO_PS_FIDDLING - */ - for (i = 0; envp[i] != NULL; i++) - continue; - - environ = malloc(sizeof(char *) * (i + 1)); - if (environ == NULL) - return; - - for (i = 0; envp[i] != NULL; i++) - if ((environ[i] = strdup(envp[i])) == NULL) - return; - environ[i] = NULL; - - if (i > 0) - argv_lth = envp[i-1] + strlen(envp[i-1]) - argv[0]; - else - argv_lth = argv[argc-1] + strlen(argv[argc-1]) - argv[0]; - if (argv_lth > 1) - argv0 = argv; -} - -void setproctitle (const char *prog, const char *txt) -{ - size_t i; - char buf[SPT_BUFSIZE]; - - if (!argv0) - return; - - if (strlen(prog) + strlen(txt) + 5 > SPT_BUFSIZE) - return; - - sprintf(buf, "%s -- %s", prog, txt); - - i = strlen(buf); - if (i > argv_lth - 2) { - i = argv_lth - 2; - buf[i] = '\0'; - } - memset(argv0[0], '\0', argv_lth); /* clear the memory area */ - strcpy(argv0[0], buf); - - argv0[1] = NULL; -} diff --git a/utils/lib/sha1.c b/utils/lib/sha1.c deleted file mode 100644 index 22d33b3..0000000 --- a/utils/lib/sha1.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * SHA-1 in C by Steve Reid <steve@edmweb.com> - * 100% Public Domain - * - * Test Vectors (from FIPS PUB 180-1) - * 1) "abc": A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D - * 2) "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq": 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 - * 3) A million repetitions of "a": 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F - */ - -#define UL_SHA1HANDSOFF - -#include <stdio.h> -#include <string.h> -#include <stdint.h> - -#include "sha1.h" - -#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) - -/* blk0() and blk() perform the initial expand. */ -#ifdef WORDS_BIGENDIAN -# define blk0(i) block->l[i] -#else -# define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ - |(rol(block->l[i],8)&0x00FF00FF)) -#endif - -#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ - ^block->l[(i+2)&15]^block->l[i&15],1)) - -/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ -#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); -#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); -#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); -#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); -#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); - -/* Hash a single 512-bit block. This is the core of the algorithm. */ - -void ul_SHA1Transform(uint32_t state[5], const unsigned char buffer[64]) -{ - uint32_t a, b, c, d, e; - - typedef union { - unsigned char c[64]; - uint32_t l[16]; - } CHAR64LONG16; - -#ifdef UL_SHA1HANDSOFF - CHAR64LONG16 block[1]; /* use array to appear as a pointer */ - - memcpy(block, buffer, 64); -#else - /* The following had better never be used because it causes the - * pointer-to-const buffer to be cast into a pointer to non-const. - * And the result is written through. I threw a "const" in, hoping - * this will cause a diagnostic. - */ - CHAR64LONG16 *block = (const CHAR64LONG16 *)buffer; -#endif - /* Copy context->state[] to working vars */ - a = state[0]; - b = state[1]; - c = state[2]; - d = state[3]; - e = state[4]; - /* 4 rounds of 20 operations each. Loop unrolled. */ - R0(a, b, c, d, e, 0); - R0(e, a, b, c, d, 1); - R0(d, e, a, b, c, 2); - R0(c, d, e, a, b, 3); - R0(b, c, d, e, a, 4); - R0(a, b, c, d, e, 5); - R0(e, a, b, c, d, 6); - R0(d, e, a, b, c, 7); - R0(c, d, e, a, b, 8); - R0(b, c, d, e, a, 9); - R0(a, b, c, d, e, 10); - R0(e, a, b, c, d, 11); - R0(d, e, a, b, c, 12); - R0(c, d, e, a, b, 13); - R0(b, c, d, e, a, 14); - R0(a, b, c, d, e, 15); - R1(e, a, b, c, d, 16); - R1(d, e, a, b, c, 17); - R1(c, d, e, a, b, 18); - R1(b, c, d, e, a, 19); - R2(a, b, c, d, e, 20); - R2(e, a, b, c, d, 21); - R2(d, e, a, b, c, 22); - R2(c, d, e, a, b, 23); - R2(b, c, d, e, a, 24); - R2(a, b, c, d, e, 25); - R2(e, a, b, c, d, 26); - R2(d, e, a, b, c, 27); - R2(c, d, e, a, b, 28); - R2(b, c, d, e, a, 29); - R2(a, b, c, d, e, 30); - R2(e, a, b, c, d, 31); - R2(d, e, a, b, c, 32); - R2(c, d, e, a, b, 33); - R2(b, c, d, e, a, 34); - R2(a, b, c, d, e, 35); - R2(e, a, b, c, d, 36); - R2(d, e, a, b, c, 37); - R2(c, d, e, a, b, 38); - R2(b, c, d, e, a, 39); - R3(a, b, c, d, e, 40); - R3(e, a, b, c, d, 41); - R3(d, e, a, b, c, 42); - R3(c, d, e, a, b, 43); - R3(b, c, d, e, a, 44); - R3(a, b, c, d, e, 45); - R3(e, a, b, c, d, 46); - R3(d, e, a, b, c, 47); - R3(c, d, e, a, b, 48); - R3(b, c, d, e, a, 49); - R3(a, b, c, d, e, 50); - R3(e, a, b, c, d, 51); - R3(d, e, a, b, c, 52); - R3(c, d, e, a, b, 53); - R3(b, c, d, e, a, 54); - R3(a, b, c, d, e, 55); - R3(e, a, b, c, d, 56); - R3(d, e, a, b, c, 57); - R3(c, d, e, a, b, 58); - R3(b, c, d, e, a, 59); - R4(a, b, c, d, e, 60); - R4(e, a, b, c, d, 61); - R4(d, e, a, b, c, 62); - R4(c, d, e, a, b, 63); - R4(b, c, d, e, a, 64); - R4(a, b, c, d, e, 65); - R4(e, a, b, c, d, 66); - R4(d, e, a, b, c, 67); - R4(c, d, e, a, b, 68); - R4(b, c, d, e, a, 69); - R4(a, b, c, d, e, 70); - R4(e, a, b, c, d, 71); - R4(d, e, a, b, c, 72); - R4(c, d, e, a, b, 73); - R4(b, c, d, e, a, 74); - R4(a, b, c, d, e, 75); - R4(e, a, b, c, d, 76); - R4(d, e, a, b, c, 77); - R4(c, d, e, a, b, 78); - R4(b, c, d, e, a, 79); - /* Add the working vars back into context.state[] */ - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - state[4] += e; - /* Wipe variables */ - a = b = c = d = e = 0; -#ifdef UL_SHA1HANDSOFF - memset(block, '\0', sizeof(block)); -#endif -} - -/* SHA1Init - Initialize new context */ - -void ul_SHA1Init(UL_SHA1_CTX *context) -{ - /* SHA1 initialization constants */ - context->state[0] = 0x67452301; - context->state[1] = 0xEFCDAB89; - context->state[2] = 0x98BADCFE; - context->state[3] = 0x10325476; - context->state[4] = 0xC3D2E1F0; - context->count[0] = context->count[1] = 0; -} - -/* Run your data through this. */ - -void ul_SHA1Update(UL_SHA1_CTX *context, const unsigned char *data, uint32_t len) -{ - uint32_t i; - - uint32_t j; - - j = context->count[0]; - if ((context->count[0] += len << 3) < j) - context->count[1]++; - context->count[1] += (len >> 29); - j = (j >> 3) & 63; - if ((j + len) > 63) { - memcpy(&context->buffer[j], data, (i = 64 - j)); - ul_SHA1Transform(context->state, context->buffer); - for (; i + 63 < len; i += 64) { - ul_SHA1Transform(context->state, &data[i]); - } - j = 0; - } else - i = 0; - memcpy(&context->buffer[j], &data[i], len - i); -} - -/* Add padding and return the message digest. */ - -void ul_SHA1Final(unsigned char digest[20], UL_SHA1_CTX *context) -{ - unsigned i; - - unsigned char finalcount[8]; - - unsigned char c; - -#if 0 /* untested "improvement" by DHR */ - /* Convert context->count to a sequence of bytes - * in finalcount. Second element first, but - * big-endian order within element. - * But we do it all backwards. - */ - unsigned char *fcp = &finalcount[8]; - - for (i = 0; i < 2; i++) { - uint32_t t = context->count[i]; - - int j; - - for (j = 0; j < 4; t >>= 8, j++) - *--fcp = (unsigned char)t} -#else - for (i = 0; i < 8; i++) { - finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255); /* Endian independent */ - } -#endif - c = 0200; - ul_SHA1Update(context, &c, 1); - while ((context->count[0] & 504) != 448) { - c = 0000; - ul_SHA1Update(context, &c, 1); - } - ul_SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ - for (i = 0; i < 20; i++) { - digest[i] = (unsigned char) - ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255); - } - /* Wipe variables */ - memset(context, '\0', sizeof(*context)); - memset(&finalcount, '\0', sizeof(finalcount)); -} - -void ul_SHA1(char *hash_out, const char *str, unsigned len) -{ - UL_SHA1_CTX ctx; - unsigned int ii; - - ul_SHA1Init(&ctx); - for (ii = 0; ii < len; ii += 1) - ul_SHA1Update(&ctx, (const unsigned char *)str + ii, 1); - ul_SHA1Final((unsigned char *)hash_out, &ctx); - hash_out[20] = '\0'; -} diff --git a/utils/lib/signames.c b/utils/lib/signames.c deleted file mode 100644 index 316eec5..0000000 --- a/utils/lib/signames.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 1988, 1993, 1994, 2017 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/* - * 2017-10-14 Niklas Hambüchen <mail@nh2.me> - * - Extracted signal names mapping from kill.c - * - * Copyright (C) 2014 Sami Kerola <kerolasa@iki.fi> - * Copyright (C) 2014 Karel Zak <kzak@redhat.com> - * Copyright (C) 2017 Niklas Hambüchen <mail@nh2.me> - */ - -#include <ctype.h> /* for isdigit() */ -#include <signal.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> - -#include "c.h" -#include "strutils.h" -#include "signames.h" - -static const struct ul_signal_name { - const char *name; - int val; -} ul_signames[] = { - /* POSIX signals */ - { "HUP", SIGHUP }, /* 1 */ - { "INT", SIGINT }, /* 2 */ - { "QUIT", SIGQUIT }, /* 3 */ - { "ILL", SIGILL }, /* 4 */ -#ifdef SIGTRAP - { "TRAP", SIGTRAP }, /* 5 */ -#endif - { "ABRT", SIGABRT }, /* 6 */ -#ifdef SIGIOT - { "IOT", SIGIOT }, /* 6, same as SIGABRT */ -#endif -#ifdef SIGEMT - { "EMT", SIGEMT }, /* 7 (mips,alpha,sparc*) */ -#endif -#ifdef SIGBUS - { "BUS", SIGBUS }, /* 7 (arm,i386,m68k,ppc), 10 (mips,alpha,sparc*) */ -#endif - { "FPE", SIGFPE }, /* 8 */ - { "KILL", SIGKILL }, /* 9 */ - { "USR1", SIGUSR1 }, /* 10 (arm,i386,m68k,ppc), 30 (alpha,sparc*), 16 (mips) */ - { "SEGV", SIGSEGV }, /* 11 */ - { "USR2", SIGUSR2 }, /* 12 (arm,i386,m68k,ppc), 31 (alpha,sparc*), 17 (mips) */ - { "PIPE", SIGPIPE }, /* 13 */ - { "ALRM", SIGALRM }, /* 14 */ - { "TERM", SIGTERM }, /* 15 */ -#ifdef SIGSTKFLT - { "STKFLT", SIGSTKFLT }, /* 16 (arm,i386,m68k,ppc) */ -#endif - { "CHLD", SIGCHLD }, /* 17 (arm,i386,m68k,ppc), 20 (alpha,sparc*), 18 (mips) */ -#ifdef SIGCLD - { "CLD", SIGCLD }, /* same as SIGCHLD (mips) */ -#endif - { "CONT", SIGCONT }, /* 18 (arm,i386,m68k,ppc), 19 (alpha,sparc*), 25 (mips) */ - { "STOP", SIGSTOP }, /* 19 (arm,i386,m68k,ppc), 17 (alpha,sparc*), 23 (mips) */ - { "TSTP", SIGTSTP }, /* 20 (arm,i386,m68k,ppc), 18 (alpha,sparc*), 24 (mips) */ - { "TTIN", SIGTTIN }, /* 21 (arm,i386,m68k,ppc,alpha,sparc*), 26 (mips) */ - { "TTOU", SIGTTOU }, /* 22 (arm,i386,m68k,ppc,alpha,sparc*), 27 (mips) */ -#ifdef SIGURG - { "URG", SIGURG }, /* 23 (arm,i386,m68k,ppc), 16 (alpha,sparc*), 21 (mips) */ -#endif -#ifdef SIGXCPU - { "XCPU", SIGXCPU }, /* 24 (arm,i386,m68k,ppc,alpha,sparc*), 30 (mips) */ -#endif -#ifdef SIGXFSZ - { "XFSZ", SIGXFSZ }, /* 25 (arm,i386,m68k,ppc,alpha,sparc*), 31 (mips) */ -#endif -#ifdef SIGVTALRM - { "VTALRM", SIGVTALRM }, /* 26 (arm,i386,m68k,ppc,alpha,sparc*), 28 (mips) */ -#endif -#ifdef SIGPROF - { "PROF", SIGPROF }, /* 27 (arm,i386,m68k,ppc,alpha,sparc*), 29 (mips) */ -#endif -#ifdef SIGWINCH - { "WINCH", SIGWINCH }, /* 28 (arm,i386,m68k,ppc,alpha,sparc*), 20 (mips) */ -#endif -#ifdef SIGIO - { "IO", SIGIO }, /* 29 (arm,i386,m68k,ppc), 23 (alpha,sparc*), 22 (mips) */ -#endif -#ifdef SIGPOLL - { "POLL", SIGPOLL }, /* same as SIGIO */ -#endif -#ifdef SIGINFO - { "INFO", SIGINFO }, /* 29 (alpha) */ -#endif -#ifdef SIGLOST - { "LOST", SIGLOST }, /* 29 (arm,i386,m68k,ppc,sparc*) */ -#endif -#ifdef SIGPWR - { "PWR", SIGPWR }, /* 30 (arm,i386,m68k,ppc), 29 (alpha,sparc*), 19 (mips) */ -#endif -#ifdef SIGUNUSED - { "UNUSED", SIGUNUSED }, /* 31 (arm,i386,m68k,ppc) */ -#endif -#ifdef SIGSYS - { "SYS", SIGSYS }, /* 31 (mips,alpha,sparc*) */ -#endif -}; - -#ifdef SIGRTMIN -static int rtsig_to_signum(const char *sig) -{ - int num, maxi = 0; - char *ep = NULL; - - if (strncasecmp(sig, "min+", 4) == 0) - sig += 4; - else if (strncasecmp(sig, "max-", 4) == 0) { - sig += 4; - maxi = 1; - } - if (!isdigit(*sig)) - return -1; - errno = 0; - num = strtol(sig, &ep, 10); - if (!ep || sig == ep || errno || num < 0) - return -1; - num = maxi ? SIGRTMAX - num : SIGRTMIN + num; - if (num < SIGRTMIN || SIGRTMAX < num) - return -1; - return num; -} -#endif - -int signame_to_signum(const char *sig) -{ - size_t n; - - if (!strncasecmp(sig, "sig", 3)) - sig += 3; -#ifdef SIGRTMIN - /* RT signals */ - if (!strncasecmp(sig, "rt", 2)) - return rtsig_to_signum(sig + 2); -#endif - /* Normal signals */ - for (n = 0; n < ARRAY_SIZE(ul_signames); n++) { - if (!strcasecmp(ul_signames[n].name, sig)) - return ul_signames[n].val; - } - return -1; -} - -const char *signum_to_signame(int signum) -{ - size_t n; - - for (n = 0; n < ARRAY_SIZE(ul_signames); n++) { - if (ul_signames[n].val == signum) { - return ul_signames[n].name; - } - } - - return NULL; -} - -int get_signame_by_idx(size_t idx, const char **signame, int *signum) -{ - if (idx >= ARRAY_SIZE(ul_signames)) - return -1; - - if (signame) - *signame = ul_signames[idx].name; - if (signum) - *signum = ul_signames[idx].val; - return 0; - -} - diff --git a/utils/lib/strutils.c b/utils/lib/strutils.c deleted file mode 100644 index 304f314..0000000 --- a/utils/lib/strutils.c +++ /dev/null @@ -1,1135 +0,0 @@ -/* - * Copyright (C) 2010 Karel Zak <kzak@redhat.com> - * Copyright (C) 2010 Davidlohr Bueso <dave@gnu.org> - * - * No copyright is claimed. This code is in the public domain; do with - * it what you wish. - */ -#include <stdio.h> -#include <stdlib.h> -#include <inttypes.h> -#include <ctype.h> -#include <errno.h> -#include <sys/stat.h> -#include <string.h> -#include <assert.h> - -#include "c.h" -#include "nls.h" -#include "strutils.h" -#include "bitops.h" -#include "pathnames.h" - -static int STRTOXX_EXIT_CODE = EXIT_FAILURE; - -void strutils_set_exitcode(int ex) { - STRTOXX_EXIT_CODE = ex; -} - -static int do_scale_by_power (uintmax_t *x, int base, int power) -{ - while (power--) { - if (UINTMAX_MAX / base < *x) - return -ERANGE; - *x *= base; - } - return 0; -} - -/* - * strtosize() - convert string to size (uintmax_t). - * - * Supported suffixes: - * - * XiB or X for 2^N - * where X = {K,M,G,T,P,E,Z,Y} - * or X = {k,m,g,t,p,e} (undocumented for backward compatibility only) - * for example: - * 10KiB = 10240 - * 10K = 10240 - * - * XB for 10^N - * where X = {K,M,G,T,P,E,Z,Y} - * for example: - * 10KB = 10000 - * - * The optional 'power' variable returns number associated with used suffix - * {K,M,G,T,P,E,Z,Y} = {1,2,3,4,5,6,7,8}. - * - * The function also supports decimal point, for example: - * 0.5MB = 500000 - * 0.5MiB = 512000 - * - * Note that the function does not accept numbers with '-' (negative sign) - * prefix. - */ -int parse_size(const char *str, uintmax_t *res, int *power) -{ - const char *p; - char *end; - uintmax_t x, frac = 0; - int base = 1024, rc = 0, pwr = 0, frac_zeros = 0; - - static const char *suf = "KMGTPEZY"; - static const char *suf2 = "kmgtpezy"; - const char *sp; - - *res = 0; - - if (!str || !*str) { - rc = -EINVAL; - goto err; - } - - /* Only positive numbers are acceptable - * - * Note that this check is not perfect, it would be better to - * use lconv->negative_sign. But coreutils use the same solution, - * so it's probably good enough... - */ - p = str; - while (isspace((unsigned char) *p)) - p++; - if (*p == '-') { - rc = -EINVAL; - goto err; - } - - errno = 0, end = NULL; - x = strtoumax(str, &end, 0); - - if (end == str || - (errno != 0 && (x == UINTMAX_MAX || x == 0))) { - rc = errno ? -errno : -EINVAL; - goto err; - } - if (!end || !*end) - goto done; /* without suffix */ - p = end; - - /* - * Check size suffixes - */ -check_suffix: - if (*(p + 1) == 'i' && (*(p + 2) == 'B' || *(p + 2) == 'b') && !*(p + 3)) - base = 1024; /* XiB, 2^N */ - else if ((*(p + 1) == 'B' || *(p + 1) == 'b') && !*(p + 2)) - base = 1000; /* XB, 10^N */ - else if (*(p + 1)) { - struct lconv const *l = localeconv(); - const char *dp = l ? l->decimal_point : NULL; - size_t dpsz = dp ? strlen(dp) : 0; - - if (frac == 0 && *p && dp && strncmp(dp, p, dpsz) == 0) { - const char *fstr = p + dpsz; - - for (p = fstr; *p == '0'; p++) - frac_zeros++; - fstr = p; - if (isdigit(*fstr)) { - errno = 0, end = NULL; - frac = strtoumax(fstr, &end, 0); - if (end == fstr || - (errno != 0 && (frac == UINTMAX_MAX || frac == 0))) { - rc = errno ? -errno : -EINVAL; - goto err; - } - } else - end = (char *) p; - - if (frac && (!end || !*end)) { - rc = -EINVAL; - goto err; /* without suffix, but with frac */ - } - p = end; - goto check_suffix; - } - rc = -EINVAL; - goto err; /* unexpected suffix */ - } - - sp = strchr(suf, *p); - if (sp) - pwr = (sp - suf) + 1; - else { - sp = strchr(suf2, *p); - if (sp) - pwr = (sp - suf2) + 1; - else { - rc = -EINVAL; - goto err; - } - } - - rc = do_scale_by_power(&x, base, pwr); - if (power) - *power = pwr; - if (frac && pwr) { - int i; - uintmax_t frac_div = 10, frac_poz = 1, frac_base = 1; - - /* mega, giga, ... */ - do_scale_by_power(&frac_base, base, pwr); - - /* maximal divisor for last digit (e.g. for 0.05 is - * frac_div=100, for 0.054 is frac_div=1000, etc.) - * - * Reduce frac if too large. - */ - while (frac_div < frac) { - if (frac_div <= UINTMAX_MAX/10) - frac_div *= 10; - else - frac /= 10; - } - - /* 'frac' is without zeros (5 means 0.5 as well as 0.05) */ - for (i = 0; i < frac_zeros; i++) { - if (frac_div <= UINTMAX_MAX/10) - frac_div *= 10; - else - frac /= 10; - } - - /* - * Go backwardly from last digit and add to result what the - * digit represents in the frac_base. For example 0.25G - * - * 5 means 1GiB / (100/5) - * 2 means 1GiB / (10/2) - */ - do { - unsigned int seg = frac % 10; /* last digit of the frac */ - uintmax_t seg_div = frac_div / frac_poz; /* what represents the segment 1000, 100, .. */ - - frac /= 10; /* remove last digit from frac */ - frac_poz *= 10; - - if (seg && seg_div / seg) - x += frac_base / (seg_div / seg); - } while (frac); - } -done: - *res = x; -err: - if (rc < 0) - errno = -rc; - return rc; -} - -int strtosize(const char *str, uintmax_t *res) -{ - return parse_size(str, res, NULL); -} - -int isdigit_strend(const char *str, const char **end) -{ - const char *p; - - for (p = str; p && *p && isdigit((unsigned char) *p); p++); - - if (end) - *end = p; - return p && p > str && !*p; -} - -int isxdigit_strend(const char *str, const char **end) -{ - const char *p; - - for (p = str; p && *p && isxdigit((unsigned char) *p); p++); - - if (end) - *end = p; - - return p && p > str && !*p; -} - -/* - * parse_switch(argv[i], "on", "off", "yes", "no", NULL); - */ -int parse_switch(const char *arg, const char *errmesg, ...) -{ - const char *a, *b; - va_list ap; - - va_start(ap, errmesg); - do { - a = va_arg(ap, char *); - if (!a) - break; - b = va_arg(ap, char *); - if (!b) - break; - - if (strcmp(arg, a) == 0) { - va_end(ap); - return 1; - } - - if (strcmp(arg, b) == 0) { - va_end(ap); - return 0; - } - } while (1); - va_end(ap); - - errx(STRTOXX_EXIT_CODE, "%s: '%s'", errmesg, arg); -} - -#ifndef HAVE_MEMPCPY -void *mempcpy(void *restrict dest, const void *restrict src, size_t n) -{ - return ((char *)memcpy(dest, src, n)) + n; -} -#endif - -#ifndef HAVE_STRNLEN -size_t strnlen(const char *s, size_t maxlen) -{ - size_t i; - - for (i = 0; i < maxlen; i++) { - if (s[i] == '\0') - return i; - } - return maxlen; -} -#endif - -#ifndef HAVE_STRNCHR -char *strnchr(const char *s, size_t maxlen, int c) -{ - for (; maxlen-- && *s != '\0'; ++s) - if (*s == (char)c) - return (char *)s; - return NULL; -} -#endif - -#ifndef HAVE_STRNDUP -char *strndup(const char *s, size_t n) -{ - size_t len = strnlen(s, n); - char *new = malloc((len + 1) * sizeof(char)); - if (!new) - return NULL; - new[len] = '\0'; - return (char *) memcpy(new, s, len); -} -#endif - -static uint32_t _strtou32_or_err(const char *str, const char *errmesg, int base); -static uint64_t _strtou64_or_err(const char *str, const char *errmesg, int base); - -int16_t strtos16_or_err(const char *str, const char *errmesg) -{ - int32_t num = strtos32_or_err(str, errmesg); - - if (num < INT16_MIN || num > INT16_MAX) { - errno = ERANGE; - err(STRTOXX_EXIT_CODE, "%s: '%s'", errmesg, str); - } - return num; -} - -static uint16_t _strtou16_or_err(const char *str, const char *errmesg, int base) -{ - uint32_t num = _strtou32_or_err(str, errmesg, base); - - if (num > UINT16_MAX) { - errno = ERANGE; - err(STRTOXX_EXIT_CODE, "%s: '%s'", errmesg, str); - } - return num; -} - -uint16_t strtou16_or_err(const char *str, const char *errmesg) -{ - return _strtou16_or_err(str, errmesg, 10); -} - -uint16_t strtox16_or_err(const char *str, const char *errmesg) -{ - return _strtou16_or_err(str, errmesg, 16); -} - -int32_t strtos32_or_err(const char *str, const char *errmesg) -{ - int64_t num = strtos64_or_err(str, errmesg); - - if (num < INT32_MIN || num > INT32_MAX) { - errno = ERANGE; - err(STRTOXX_EXIT_CODE, "%s: '%s'", errmesg, str); - } - return num; -} - -static uint32_t _strtou32_or_err(const char *str, const char *errmesg, int base) -{ - uint64_t num = _strtou64_or_err(str, errmesg, base); - - if (num > UINT32_MAX) { - errno = ERANGE; - err(STRTOXX_EXIT_CODE, "%s: '%s'", errmesg, str); - } - return num; -} - -uint32_t strtou32_or_err(const char *str, const char *errmesg) -{ - return _strtou32_or_err(str, errmesg, 10); -} - -uint32_t strtox32_or_err(const char *str, const char *errmesg) -{ - return _strtou32_or_err(str, errmesg, 16); -} - -int64_t strtos64_or_err(const char *str, const char *errmesg) -{ - int64_t num; - char *end = NULL; - - errno = 0; - if (str == NULL || *str == '\0') - goto err; - num = strtoimax(str, &end, 10); - - if (errno || str == end || (end && *end)) - goto err; - - return num; -err: - if (errno == ERANGE) - err(STRTOXX_EXIT_CODE, "%s: '%s'", errmesg, str); - - errx(STRTOXX_EXIT_CODE, "%s: '%s'", errmesg, str); -} - -static uint64_t _strtou64_or_err(const char *str, const char *errmesg, int base) -{ - uintmax_t num; - char *end = NULL; - - errno = 0; - if (str == NULL || *str == '\0') - goto err; - num = strtoumax(str, &end, base); - - if (errno || str == end || (end && *end)) - goto err; - - return num; -err: - if (errno == ERANGE) - err(STRTOXX_EXIT_CODE, "%s: '%s'", errmesg, str); - - errx(STRTOXX_EXIT_CODE, "%s: '%s'", errmesg, str); -} - -uint64_t strtou64_or_err(const char *str, const char *errmesg) -{ - return _strtou64_or_err(str, errmesg, 10); -} - -uint64_t strtox64_or_err(const char *str, const char *errmesg) -{ - return _strtou64_or_err(str, errmesg, 16); -} - -double strtod_or_err(const char *str, const char *errmesg) -{ - double num; - char *end = NULL; - - errno = 0; - if (str == NULL || *str == '\0') - goto err; - num = strtod(str, &end); - - if (errno || str == end || (end && *end)) - goto err; - - return num; -err: - if (errno == ERANGE) - err(STRTOXX_EXIT_CODE, "%s: '%s'", errmesg, str); - - errx(STRTOXX_EXIT_CODE, "%s: '%s'", errmesg, str); -} - -long strtol_or_err(const char *str, const char *errmesg) -{ - long num; - char *end = NULL; - - errno = 0; - if (str == NULL || *str == '\0') - goto err; - num = strtol(str, &end, 10); - - if (errno || str == end || (end && *end)) - goto err; - - return num; -err: - if (errno == ERANGE) - err(STRTOXX_EXIT_CODE, "%s: '%s'", errmesg, str); - - errx(STRTOXX_EXIT_CODE, "%s: '%s'", errmesg, str); -} - -unsigned long strtoul_or_err(const char *str, const char *errmesg) -{ - unsigned long num; - char *end = NULL; - - errno = 0; - if (str == NULL || *str == '\0') - goto err; - num = strtoul(str, &end, 10); - - if (errno || str == end || (end && *end)) - goto err; - - return num; -err: - if (errno == ERANGE) - err(STRTOXX_EXIT_CODE, "%s: '%s'", errmesg, str); - - errx(STRTOXX_EXIT_CODE, "%s: '%s'", errmesg, str); -} - -uintmax_t strtosize_or_err(const char *str, const char *errmesg) -{ - uintmax_t num; - - if (strtosize(str, &num) == 0) - return num; - - if (errno) - err(STRTOXX_EXIT_CODE, "%s: '%s'", errmesg, str); - - errx(STRTOXX_EXIT_CODE, "%s: '%s'", errmesg, str); -} - - -void strtotimeval_or_err(const char *str, struct timeval *tv, const char *errmesg) -{ - double user_input; - - user_input = strtod_or_err(str, errmesg); - tv->tv_sec = (time_t) user_input; - tv->tv_usec = (long)((user_input - tv->tv_sec) * 1000000); -} - -/* - * Converts stat->st_mode to ls(1)-like mode string. The size of "str" must - * be 11 bytes. - */ -char *xstrmode(mode_t mode, char *str) -{ - unsigned short i = 0; - - if (S_ISDIR(mode)) - str[i++] = 'd'; - else if (S_ISLNK(mode)) - str[i++] = 'l'; - else if (S_ISCHR(mode)) - str[i++] = 'c'; - else if (S_ISBLK(mode)) - str[i++] = 'b'; - else if (S_ISSOCK(mode)) - str[i++] = 's'; - else if (S_ISFIFO(mode)) - str[i++] = 'p'; - else if (S_ISREG(mode)) - str[i++] = '-'; - - str[i++] = mode & S_IRUSR ? 'r' : '-'; - str[i++] = mode & S_IWUSR ? 'w' : '-'; - str[i++] = (mode & S_ISUID - ? (mode & S_IXUSR ? 's' : 'S') - : (mode & S_IXUSR ? 'x' : '-')); - str[i++] = mode & S_IRGRP ? 'r' : '-'; - str[i++] = mode & S_IWGRP ? 'w' : '-'; - str[i++] = (mode & S_ISGID - ? (mode & S_IXGRP ? 's' : 'S') - : (mode & S_IXGRP ? 'x' : '-')); - str[i++] = mode & S_IROTH ? 'r' : '-'; - str[i++] = mode & S_IWOTH ? 'w' : '-'; - str[i++] = (mode & S_ISVTX - ? (mode & S_IXOTH ? 't' : 'T') - : (mode & S_IXOTH ? 'x' : '-')); - str[i] = '\0'; - - return str; -} - -/* - * returns exponent (2^x=n) in range KiB..EiB (2^10..2^60) - */ -static int get_exp(uint64_t n) -{ - int shft; - - for (shft = 10; shft <= 60; shft += 10) { - if (n < (1ULL << shft)) - break; - } - return shft - 10; -} - -char *size_to_human_string(int options, uint64_t bytes) -{ - char buf[32]; - int dec, exp; - uint64_t frac; - const char *letters = "BKMGTPE"; - char suffix[sizeof(" KiB")], *psuf = suffix; - char c; - - if (options & SIZE_SUFFIX_SPACE) - *psuf++ = ' '; - - - exp = get_exp(bytes); - c = *(letters + (exp ? exp / 10 : 0)); - dec = exp ? bytes / (1ULL << exp) : bytes; - frac = exp ? bytes % (1ULL << exp) : 0; - - *psuf++ = c; - - if ((options & SIZE_SUFFIX_3LETTER) && (c != 'B')) { - *psuf++ = 'i'; - *psuf++ = 'B'; - } - - *psuf = '\0'; - - /* fprintf(stderr, "exp: %d, unit: %c, dec: %d, frac: %jd\n", - * exp, suffix[0], dec, frac); - */ - - /* round */ - if (frac) { - /* get 3 digits after decimal point */ - if (frac >= UINT64_MAX / 1000) - frac = ((frac / 1024) * 1000) / (1ULL << (exp - 10)) ; - else - frac = (frac * 1000) / (1ULL << (exp)) ; - - if (options & SIZE_DECIMAL_2DIGITS) { - /* round 4/5 and keep 2 digits after decimal point */ - frac = (frac + 5) / 10 ; - } else { - /* round 4/5 and keep 1 digit after decimal point */ - frac = ((frac + 50) / 100) * 10 ; - } - - /* rounding could have overflowed */ - if (frac == 100) { - dec++; - frac = 0; - } - } - - if (frac) { - struct lconv const *l = localeconv(); - char *dp = l ? l->decimal_point : NULL; - int len; - - if (!dp || !*dp) - dp = "."; - - len = snprintf(buf, sizeof(buf), "%d%s%02" PRIu64, dec, dp, frac); - if (len > 0 && (size_t) len < sizeof(buf)) { - /* remove potential extraneous zero */ - if (buf[len - 1] == '0') - buf[len--] = '\0'; - /* append suffix */ - xstrncpy(buf+len, suffix, sizeof(buf) - len); - } else - *buf = '\0'; /* snprintf error */ - } else - snprintf(buf, sizeof(buf), "%d%s", dec, suffix); - - return strdup(buf); -} - -/* - * Parses comma delimited list to array with IDs, for example: - * - * "aaa,bbb,ccc" --> ary[0] = FOO_AAA; - * ary[1] = FOO_BBB; - * ary[3] = FOO_CCC; - * - * The function name2id() provides conversion from string to ID. - * - * Returns: >= 0 : number of items added to ary[] - * -1 : parse error or unknown item - * -2 : arysz reached - */ -int string_to_idarray(const char *list, int ary[], size_t arysz, - int (name2id)(const char *, size_t)) -{ - const char *begin = NULL, *p; - size_t n = 0; - - if (!list || !*list || !ary || !arysz || !name2id) - return -1; - - for (p = list; p && *p; p++) { - const char *end = NULL; - int id; - - if (n >= arysz) - return -2; - if (!begin) - begin = p; /* begin of the column name */ - if (*p == ',') - end = p; /* terminate the name */ - if (*(p + 1) == '\0') - end = p + 1; /* end of string */ - if (!begin || !end) - continue; - if (end <= begin) - return -1; - - id = name2id(begin, end - begin); - if (id == -1) - return -1; - ary[ n++ ] = id; - begin = NULL; - if (end && !*end) - break; - } - return n; -} - -/* - * Parses the array like string_to_idarray but if format is "+aaa,bbb" - * it adds fields to array instead of replacing them. - */ -int string_add_to_idarray(const char *list, int ary[], size_t arysz, - size_t *ary_pos, int (name2id)(const char *, size_t)) -{ - const char *list_add; - int r; - - if (!list || !*list || !ary_pos || *ary_pos > arysz) - return -1; - - if (list[0] == '+') - list_add = &list[1]; - else { - list_add = list; - *ary_pos = 0; - } - - r = string_to_idarray(list_add, &ary[*ary_pos], arysz - *ary_pos, name2id); - if (r > 0) - *ary_pos += r; - return r; -} - -/* - * LIST ::= <item> [, <item>] - * - * The <item> is translated to 'id' by name2id() function and the 'id' is used - * as a position in the 'ary' bit array. It means that the 'id' has to be in - * range <0..N> where N < sizeof(ary) * NBBY. - * - * Returns: 0 on success, <0 on error. - */ -int string_to_bitarray(const char *list, - char *ary, - int (*name2bit)(const char *, size_t)) -{ - const char *begin = NULL, *p; - - if (!list || !name2bit || !ary) - return -EINVAL; - - for (p = list; p && *p; p++) { - const char *end = NULL; - int bit; - - if (!begin) - begin = p; /* begin of the level name */ - if (*p == ',') - end = p; /* terminate the name */ - if (*(p + 1) == '\0') - end = p + 1; /* end of string */ - if (!begin || !end) - continue; - if (end <= begin) - return -1; - - bit = name2bit(begin, end - begin); - if (bit < 0) - return bit; - setbit(ary, bit); - begin = NULL; - if (end && !*end) - break; - } - return 0; -} - -/* - * LIST ::= <item> [, <item>] - * - * The <item> is translated to 'id' by name2flag() function and the flags is - * set to the 'mask' -* - * Returns: 0 on success, <0 on error. - */ -int string_to_bitmask(const char *list, - unsigned long *mask, - long (*name2flag)(const char *, size_t)) -{ - const char *begin = NULL, *p; - - if (!list || !name2flag || !mask) - return -EINVAL; - - for (p = list; p && *p; p++) { - const char *end = NULL; - long flag; - - if (!begin) - begin = p; /* begin of the level name */ - if (*p == ',') - end = p; /* terminate the name */ - if (*(p + 1) == '\0') - end = p + 1; /* end of string */ - if (!begin || !end) - continue; - if (end <= begin) - return -1; - - flag = name2flag(begin, end - begin); - if (flag < 0) - return flag; /* error */ - *mask |= flag; - begin = NULL; - if (end && !*end) - break; - } - return 0; -} - -/* - * Parse the lower and higher values in a string containing - * "lower:higher" or "lower-higher" format. Note that either - * the lower or the higher values may be missing, and the def - * value will be assigned to it by default. - * - * Returns: 0 on success, <0 on error. - */ -int parse_range(const char *str, int *lower, int *upper, int def) -{ - char *end = NULL; - - if (!str) - return 0; - - *upper = *lower = def; - errno = 0; - - if (*str == ':') { /* <:N> */ - str++; - *upper = strtol(str, &end, 10); - if (errno || !end || *end || end == str) - return -1; - } else { - *upper = *lower = strtol(str, &end, 10); - if (errno || !end || end == str) - return -1; - - if (*end == ':' && !*(end + 1)) /* <M:> */ - *upper = def; - else if (*end == '-' || *end == ':') { /* <M:N> <M-N> */ - str = end + 1; - end = NULL; - errno = 0; - *upper = strtol(str, &end, 10); - - if (errno || !end || *end || end == str) - return -1; - } - } - return 0; -} - -static const char *next_path_segment(const char *str, size_t *sz) -{ - const char *start, *p; - - start = str; - *sz = 0; - while (start && *start == '/' && *(start + 1) == '/') - start++; - - if (!start || !*start) - return NULL; - - for (*sz = 1, p = start + 1; *p && *p != '/'; p++) { - (*sz)++; - } - - return start; -} - -int streq_paths(const char *a, const char *b) -{ - while (a && b) { - size_t a_sz, b_sz; - const char *a_seg = next_path_segment(a, &a_sz); - const char *b_seg = next_path_segment(b, &b_sz); - - /* - fprintf(stderr, "A>>>(%zu) '%s'\n", a_sz, a_seg); - fprintf(stderr, "B>>>(%zu) '%s'\n", b_sz, b_seg); - */ - - /* end of the path */ - if (a_sz + b_sz == 0) - return 1; - - /* ignore tailing slash */ - if (a_sz + b_sz == 1 && - ((a_seg && *a_seg == '/') || (b_seg && *b_seg == '/'))) - return 1; - - if (!a_seg || !b_seg) - break; - if (a_sz != b_sz || strncmp(a_seg, b_seg, a_sz) != 0) - break; - - a = a_seg + a_sz; - b = b_seg + b_sz; - }; - - return 0; -} - -char *strnappend(const char *s, const char *suffix, size_t b) -{ - size_t a; - char *r; - - if (!s && !suffix) - return strdup(""); - if (!s) - return strndup(suffix, b); - if (!suffix) - return strdup(s); - - assert(s); - assert(suffix); - - a = strlen(s); - if (b > ((size_t) -1) - a) - return NULL; - - r = malloc(a + b + 1); - if (!r) - return NULL; - - memcpy(r, s, a); - memcpy(r + a, suffix, b); - r[a+b] = 0; - - return r; -} - -char *strappend(const char *s, const char *suffix) -{ - return strnappend(s, suffix, suffix ? strlen(suffix) : 0); -} - -char *strfappend(const char *s, const char *format, ...) -{ - va_list ap; - char *val, *res; - int sz; - - va_start(ap, format); - sz = vasprintf(&val, format, ap); - va_end(ap); - - if (sz < 0) - return NULL; - - res = strnappend(s, val, sz); - free(val); - return res; -} - -static size_t strcspn_escaped(const char *s, const char *reject) -{ - int escaped = 0; - int n; - - for (n=0; s[n]; n++) { - if (escaped) - escaped = 0; - else if (s[n] == '\\') - escaped = 1; - else if (strchr(reject, s[n])) - break; - } - - /* if s ends in \, return index of previous char */ - return n - escaped; -} - -/* Split a string into words. */ -const char *split(const char **state, size_t *l, const char *separator, int quoted) -{ - const char *current; - - current = *state; - - if (!*current) { - assert(**state == '\0'); - return NULL; - } - - current += strspn(current, separator); - if (!*current) { - *state = current; - return NULL; - } - - if (quoted && strchr("\'\"", *current)) { - char quotechars[2] = {*current, '\0'}; - - *l = strcspn_escaped(current + 1, quotechars); - if (current[*l + 1] == '\0' || current[*l + 1] != quotechars[0] || - (current[*l + 2] && !strchr(separator, current[*l + 2]))) { - /* right quote missing or garbage at the end */ - *state = current; - return NULL; - } - *state = current++ + *l + 2; - } else if (quoted) { - *l = strcspn_escaped(current, separator); - if (current[*l] && !strchr(separator, current[*l])) { - /* unfinished escape */ - *state = current; - return NULL; - } - *state = current + *l; - } else { - *l = strcspn(current, separator); - *state = current + *l; - } - - return current; -} - -/* Rewind file pointer forward to new line. */ -int skip_fline(FILE *fp) -{ - int ch; - - do { - if ((ch = fgetc(fp)) == EOF) - return 1; - if (ch == '\n') - return 0; - } while (1); -} - -#ifdef TEST_PROGRAM_STRUTILS -struct testS { - char *name; - char *value; -}; - -static int test_strdup_to_member(int argc, char *argv[]) -{ - struct testS *xx; - - if (argc < 3) - return EXIT_FAILURE; - - xx = calloc(1, sizeof(*xx)); - if (!xx) - err(EXIT_FAILURE, "calloc() failed"); - - strdup_to_struct_member(xx, name, argv[1]); - strdup_to_struct_member(xx, value, argv[2]); - - if (strcmp(xx->name, argv[1]) != 0 && - strcmp(xx->value, argv[2]) != 0) - errx(EXIT_FAILURE, "strdup_to_struct_member() failed"); - - printf("1: '%s', 2: '%s'\n", xx->name, xx->value); - - free(xx->name); - free(xx->value); - free(xx); - return EXIT_SUCCESS; -} - -static int test_strutils_sizes(int argc, char *argv[]) -{ - uintmax_t size = 0; - char *hum1, *hum2, *hum3; - - if (argc < 2) - return EXIT_FAILURE; - - if (strtosize(argv[1], &size)) - errx(EXIT_FAILURE, "invalid size '%s' value", argv[1]); - - hum1 = size_to_human_string(SIZE_SUFFIX_1LETTER, size); - hum2 = size_to_human_string(SIZE_SUFFIX_3LETTER | - SIZE_SUFFIX_SPACE, size); - hum3 = size_to_human_string(SIZE_SUFFIX_3LETTER | - SIZE_SUFFIX_SPACE | - SIZE_DECIMAL_2DIGITS, size); - - printf("%25s : %20ju : %8s : %12s : %13s\n", argv[1], size, hum1, hum2, hum3); - free(hum1); - free(hum2); - free(hum3); - - return EXIT_SUCCESS; -} - -static int test_strutils_cmp_paths(int argc, char *argv[]) -{ - int rc = streq_paths(argv[1], argv[2]); - - if (argc < 3) - return EXIT_FAILURE; - - printf("%s: '%s' '%s'\n", rc == 1 ? "YES" : "NOT", argv[1], argv[2]); - return EXIT_SUCCESS; -} - -int main(int argc, char *argv[]) -{ - if (argc == 3 && strcmp(argv[1], "--size") == 0) - return test_strutils_sizes(argc - 1, argv + 1); - - if (argc == 4 && strcmp(argv[1], "--cmp-paths") == 0) - return test_strutils_cmp_paths(argc - 1, argv + 1); - - if (argc == 4 && strcmp(argv[1], "--strdup-member") == 0) - return test_strdup_to_member(argc - 1, argv + 1); - - fprintf(stderr, "usage: %1$s --size <number>[suffix]\n" - " %1$s --cmp-paths <path> <path>\n" - " %1$s --strdup-member <str> <str>\n", - argv[0]); - - return EXIT_FAILURE; -} -#endif /* TEST_PROGRAM_STRUTILS */ diff --git a/utils/lib/strv.c b/utils/lib/strv.c deleted file mode 100644 index ddc2a0c..0000000 --- a/utils/lib/strv.c +++ /dev/null @@ -1,403 +0,0 @@ -/* - * - * Copyright 2010 Lennart Poettering - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * - * Copyright (C) 2015 Karel Zak <kzak@redhat.com> - * Modified the original version from systemd project for util-linux. - */ - -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <errno.h> -#include <stdbool.h> -#include <assert.h> - -#include "strutils.h" -#include "strv.h" - -void strv_clear(char **l) { - char **k; - - if (!l) - return; - - for (k = l; *k; k++) - free(*k); - - *l = NULL; -} - -char **strv_free(char **l) { - strv_clear(l); - free(l); - return NULL; -} - -char **strv_copy(char * const *l) { - char **r, **k; - - k = r = malloc(sizeof(char *) * (strv_length(l) + 1)); - if (!r) - return NULL; - - if (l) - for (; *l; k++, l++) { - *k = strdup(*l); - if (!*k) { - strv_free(r); - return NULL; - } - } - - *k = NULL; - return r; -} - -unsigned strv_length(char * const *l) { - unsigned n = 0; - - if (!l) - return 0; - - for (; *l; l++) - n++; - - return n; -} - -char **strv_new_ap(const char *x, va_list ap) { - const char *s; - char **a; - unsigned n = 0, i = 0; - va_list aq; - - /* As a special trick we ignore all listed strings that equal - * (const char*) -1. This is supposed to be used with the - * STRV_IFNOTNULL() macro to include possibly NULL strings in - * the string list. */ - - if (x) { - n = x == (const char*) -1 ? 0 : 1; - - va_copy(aq, ap); - while ((s = va_arg(aq, const char*))) { - if (s == (const char*) -1) - continue; - - n++; - } - - va_end(aq); - } - - a = malloc(sizeof(char *) * (n + 1)); - if (!a) - return NULL; - - if (x) { - if (x != (const char*) -1) { - a[i] = strdup(x); - if (!a[i]) - goto fail; - i++; - } - - while ((s = va_arg(ap, const char*))) { - - if (s == (const char*) -1) - continue; - - a[i] = strdup(s); - if (!a[i]) - goto fail; - - i++; - } - } - - a[i] = NULL; - - return a; - -fail: - strv_free(a); - return NULL; -} - -char **strv_new(const char *x, ...) { - char **r; - va_list ap; - - va_start(ap, x); - r = strv_new_ap(x, ap); - va_end(ap); - - return r; -} - -int strv_extend_strv(char ***a, char **b) { - int r; - char **s; - - STRV_FOREACH(s, b) { - r = strv_extend(a, *s); - if (r < 0) - return r; - } - - return 0; -} - -int strv_extend_strv_concat(char ***a, char **b, const char *suffix) { - int r; - char **s; - - STRV_FOREACH(s, b) { - char *v; - - v = strappend(*s, suffix); - if (!v) - return -ENOMEM; - - r = strv_push(a, v); - if (r < 0) { - free(v); - return r; - } - } - - return 0; -} - - -#define _FOREACH_WORD(word, length, s, separator, quoted, state) \ - for ((state) = (s), (word) = split(&(state), &(length), (separator), (quoted)); (word); (word) = split(&(state), &(length), (separator), (quoted))) - -#define FOREACH_WORD_SEPARATOR(word, length, s, separator, state) \ - _FOREACH_WORD(word, length, s, separator, false, state) - - -char **strv_split(const char *s, const char *separator) { - const char *word, *state; - size_t l; - unsigned n, i; - char **r; - - assert(s); - - n = 0; - FOREACH_WORD_SEPARATOR(word, l, s, separator, state) - n++; - - r = malloc(sizeof(char *) * (n + 1)); - if (!r) - return NULL; - - i = 0; - FOREACH_WORD_SEPARATOR(word, l, s, separator, state) { - r[i] = strndup(word, l); - if (!r[i]) { - strv_free(r); - return NULL; - } - - i++; - } - - r[i] = NULL; - return r; -} - -char *strv_join(char **l, const char *separator) { - char *r, *e; - char **s; - size_t n, k; - - if (!separator) - separator = " "; - - k = strlen(separator); - - n = 0; - STRV_FOREACH(s, l) { - if (n != 0) - n += k; - n += strlen(*s); - } - - r = malloc(n + 1); - if (!r) - return NULL; - - e = r; - STRV_FOREACH(s, l) { - if (e != r) - e = stpcpy(e, separator); - - e = stpcpy(e, *s); - } - - *e = 0; - - return r; -} - -int strv_push(char ***l, char *value) { - char **c; - unsigned n, m; - - if (!value) - return 0; - - n = strv_length(*l); - - /* Increase and check for overflow */ - m = n + 2; - if (m < n) - return -ENOMEM; - - c = realloc(*l, sizeof(char *) * m); - if (!c) - return -ENOMEM; - - c[n] = value; - c[n+1] = NULL; - - *l = c; - return 0; -} - -int strv_push_prepend(char ***l, char *value) { - char **c; - unsigned n, m, i; - - if (!value) - return 0; - - n = strv_length(*l); - - /* increase and check for overflow */ - m = n + 2; - if (m < n) - return -ENOMEM; - - c = malloc(sizeof(char *) * m); - if (!c) - return -ENOMEM; - - for (i = 0; i < n; i++) - c[i+1] = (*l)[i]; - - c[0] = value; - c[n+1] = NULL; - - free(*l); - *l = c; - - return 0; -} - -int strv_consume(char ***l, char *value) { - int r; - - r = strv_push(l, value); - if (r < 0) - free(value); - - return r; -} - -int strv_consume_prepend(char ***l, char *value) { - int r; - - r = strv_push_prepend(l, value); - if (r < 0) - free(value); - - return r; -} - -int strv_extend(char ***l, const char *value) { - char *v; - - if (!value) - return 0; - - v = strdup(value); - if (!v) - return -ENOMEM; - - return strv_consume(l, v); -} - -char **strv_remove(char **l, const char *s) { - char **f, **t; - - if (!l) - return NULL; - - assert(s); - - /* Drops every occurrence of s in the string list, edits - * in-place. */ - - for (f = t = l; *f; f++) - if (strcmp(*f, s) == 0) - free(*f); - else - *(t++) = *f; - - *t = NULL; - return l; -} - -int strv_extendf(char ***l, const char *format, ...) { - va_list ap; - char *x; - int r; - - va_start(ap, format); - r = vasprintf(&x, format, ap); - va_end(ap); - - if (r < 0) - return -ENOMEM; - - return strv_consume(l, x); -} - -int strv_extendv(char ***l, const char *format, va_list ap) { - char *x; - int r; - - r = vasprintf(&x, format, ap); - if (r < 0) - return -ENOMEM; - - return strv_consume(l, x); -} - -char **strv_reverse(char **l) { - unsigned n, i; - - n = strv_length(l); - if (n <= 1) - return l; - - for (i = 0; i < n / 2; i++) { - char *t; - - t = l[i]; - l[i] = l[n-1-i]; - l[n-1-i] = t; - } - - return l; -} diff --git a/utils/lib/sysfs.c b/utils/lib/sysfs.c deleted file mode 100644 index 5b4de2c..0000000 --- a/utils/lib/sysfs.c +++ /dev/null @@ -1,1127 +0,0 @@ -/* - * No copyright is claimed. This code is in the public domain; do with - * it what you wish. - * - * Written by Karel Zak <kzak@redhat.com> - */ -#include <ctype.h> -#include <libgen.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <unistd.h> - -#include "c.h" -#include "pathnames.h" -#include "sysfs.h" -#include "fileutils.h" -#include "all-io.h" -#include "debug.h" -#include "strutils.h" - -static void sysfs_blkdev_deinit_path(struct path_cxt *pc); -static int sysfs_blkdev_enoent_redirect(struct path_cxt *pc, const char *path, int *dirfd); - -/* - * Debug stuff (based on include/debug.h) - */ -static UL_DEBUG_DEFINE_MASK(ulsysfs); -UL_DEBUG_DEFINE_MASKNAMES(ulsysfs) = UL_DEBUG_EMPTY_MASKNAMES; - -#define ULSYSFS_DEBUG_INIT (1 << 1) -#define ULSYSFS_DEBUG_CXT (1 << 2) - -#define DBG(m, x) __UL_DBG(ulsysfs, ULSYSFS_DEBUG_, m, x) -#define ON_DBG(m, x) __UL_DBG_CALL(ulsysfs, ULSYSFS_DEBUG_, m, x) - -#define UL_DEBUG_CURRENT_MASK UL_DEBUG_MASK(ulsysfs) -#include "debugobj.h" - -void ul_sysfs_init_debug(void) -{ - if (ulsysfs_debug_mask) - return; - __UL_INIT_DEBUG_FROM_ENV(ulsysfs, ULSYSFS_DEBUG_, 0, ULSYSFS_DEBUG); -} - -struct path_cxt *ul_new_sysfs_path(dev_t devno, struct path_cxt *parent, const char *prefix) -{ - struct path_cxt *pc = ul_new_path(NULL); - - if (!pc) - return NULL; - if (prefix) - ul_path_set_prefix(pc, prefix); - - if (sysfs_blkdev_init_path(pc, devno, parent) != 0) { - ul_unref_path(pc); - return NULL; - } - - DBG(CXT, ul_debugobj(pc, "alloc")); - return pc; -} - -/* - * sysfs_blkdev_* is sysfs extension to ul_path_* API for block devices. - * - * The function is possible to call in loop and without sysfs_blkdev_deinit_path(). - * The sysfs_blkdev_deinit_path() is automatically called by ul_unref_path(). - * - */ -int sysfs_blkdev_init_path(struct path_cxt *pc, dev_t devno, struct path_cxt *parent) -{ - struct sysfs_blkdev *blk; - int rc; - char buf[sizeof(_PATH_SYS_DEVBLOCK) - + sizeof(stringify_value(UINT32_MAX)) * 2 - + 3]; - - /* define path to devno stuff */ - snprintf(buf, sizeof(buf), _PATH_SYS_DEVBLOCK "/%d:%d", major(devno), minor(devno)); - rc = ul_path_set_dir(pc, buf); - if (rc) - return rc; - - /* make sure path exists */ - rc = ul_path_get_dirfd(pc); - if (rc < 0) - return rc; - - /* initialize sysfs blkdev specific stuff */ - blk = ul_path_get_dialect(pc); - if (!blk) { - DBG(CXT, ul_debugobj(pc, "alloc new sysfs handler")); - blk = calloc(1, sizeof(struct sysfs_blkdev)); - if (!blk) - return -ENOMEM; - - ul_path_set_dialect(pc, blk, sysfs_blkdev_deinit_path); - ul_path_set_enoent_redirect(pc, sysfs_blkdev_enoent_redirect); - } - - DBG(CXT, ul_debugobj(pc, "init sysfs stuff")); - - blk->devno = devno; - sysfs_blkdev_set_parent(pc, parent); - - return 0; -} - -static void sysfs_blkdev_deinit_path(struct path_cxt *pc) -{ - struct sysfs_blkdev *blk; - - if (!pc) - return; - - DBG(CXT, ul_debugobj(pc, "deinit")); - - blk = ul_path_get_dialect(pc); - if (!blk) - return; - - ul_unref_path(blk->parent); - free(blk); - - ul_path_set_dialect(pc, NULL, NULL); -} - -int sysfs_blkdev_set_parent(struct path_cxt *pc, struct path_cxt *parent) -{ - struct sysfs_blkdev *blk = ul_path_get_dialect(pc); - - if (!pc || !blk) - return -EINVAL; - - if (blk->parent) { - ul_unref_path(blk->parent); - blk->parent = NULL; - } - - if (parent) { - ul_ref_path(parent); - blk->parent = parent; - } else - blk->parent = NULL; - - DBG(CXT, ul_debugobj(pc, "new parent")); - return 0; -} - -struct path_cxt *sysfs_blkdev_get_parent(struct path_cxt *pc) -{ - struct sysfs_blkdev *blk = ul_path_get_dialect(pc); - return blk ? blk->parent : NULL; -} - -/* - * Redirects ENOENT errors to the parent, if the path is to the queue/ - * sysfs directory. For example - * - * /sys/dev/block/8:1/queue/logical_block_size redirects to - * /sys/dev/block/8:0/queue/logical_block_size - */ -static int sysfs_blkdev_enoent_redirect(struct path_cxt *pc, const char *path, int *dirfd) -{ - struct sysfs_blkdev *blk = ul_path_get_dialect(pc); - - if (blk && blk->parent && strncmp(path, "queue/", 6) == 0) { - *dirfd = ul_path_get_dirfd(blk->parent); - if (*dirfd >= 0) { - DBG(CXT, ul_debugobj(pc, "%s redirected to parent", path)); - return 0; - } - } - return 1; /* no redirect */ -} - -char *sysfs_blkdev_get_name(struct path_cxt *pc, char *buf, size_t bufsiz) -{ - char link[PATH_MAX]; - char *name; - ssize_t sz; - - /* read /sys/dev/block/<maj:min> link */ - sz = ul_path_readlink(pc, link, sizeof(link) - 1, NULL); - if (sz < 0) - return NULL; - link[sz] = '\0'; - - name = strrchr(link, '/'); - if (!name) - return NULL; - - name++; - sz = strlen(name); - if ((size_t) sz + 1 > bufsiz) - return NULL; - - memcpy(buf, name, sz + 1); - sysfs_devname_sys_to_dev(buf); - return buf; -} - -int sysfs_blkdev_is_partition_dirent(DIR *dir, struct dirent *d, const char *parent_name) -{ - char path[NAME_MAX + 6 + 1]; - -#ifdef _DIRENT_HAVE_D_TYPE - if (d->d_type != DT_DIR && - d->d_type != DT_LNK && - d->d_type != DT_UNKNOWN) - return 0; -#endif - if (parent_name) { - const char *p = parent_name; - size_t len; - - /* /dev/sda --> "sda" */ - if (*parent_name == '/') { - p = strrchr(parent_name, '/'); - if (!p) - return 0; - p++; - } - - len = strlen(p); - if (strlen(d->d_name) <= len) - return 0; - - /* partitions subdir name is - * "<parent>[:digit:]" or "<parent>p[:digit:]" - */ - return strncmp(p, d->d_name, len) == 0 && - ((*(d->d_name + len) == 'p' && isdigit(*(d->d_name + len + 1))) - || isdigit(*(d->d_name + len))); - } - - /* Cannot use /partition file, not supported on old sysfs */ - snprintf(path, sizeof(path), "%s/start", d->d_name); - - return faccessat(dirfd(dir), path, R_OK, 0) == 0; -} - -int sysfs_blkdev_count_partitions(struct path_cxt *pc, const char *devname) -{ - DIR *dir; - struct dirent *d; - int r = 0; - - dir = ul_path_opendir(pc, NULL); - if (!dir) - return 0; - - while ((d = xreaddir(dir))) { - if (sysfs_blkdev_is_partition_dirent(dir, d, devname)) - r++; - } - - closedir(dir); - return r; -} - -/* - * Converts @partno (partition number) to devno of the partition. - * The @pc handles wholedisk device. - * - * Note that this code does not expect any special format of the - * partitions devnames. - */ -dev_t sysfs_blkdev_partno_to_devno(struct path_cxt *pc, int partno) -{ - DIR *dir; - struct dirent *d; - dev_t devno = 0; - - dir = ul_path_opendir(pc, NULL); - if (!dir) - return 0; - - while ((d = xreaddir(dir))) { - int n; - - if (!sysfs_blkdev_is_partition_dirent(dir, d, NULL)) - continue; - - if (ul_path_readf_s32(pc, &n, "%s/partition", d->d_name)) - continue; - - if (n == partno) { - if (ul_path_readf_majmin(pc, &devno, "%s/dev", d->d_name) == 0) - break; - } - } - - closedir(dir); - DBG(CXT, ul_debugobj(pc, "partno (%d) -> devno (%d)", (int) partno, (int) devno)); - return devno; -} - - -/* - * Returns slave name if there is only one slave, otherwise returns NULL. - * The result should be deallocated by free(). - */ -char *sysfs_blkdev_get_slave(struct path_cxt *pc) -{ - DIR *dir; - struct dirent *d; - char *name = NULL; - - dir = ul_path_opendir(pc, "slaves"); - if (!dir) - return NULL; - - while ((d = xreaddir(dir))) { - if (name) - goto err; /* more slaves */ - name = strdup(d->d_name); - } - - closedir(dir); - return name; -err: - free(name); - closedir(dir); - return NULL; -} - - -#define SUBSYSTEM_LINKNAME "/subsystem" - -/* - * For example: - * - * chain: /sys/dev/block/../../devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/ \ - * 1-1.2:1.0/host65/target65:0:0/65:0:0:0/block/sdb - * - * The function check if <chain>/subsystem symlink exists, if yes then returns - * basename of the readlink result, and remove the last subdirectory from the - * <chain> path. - */ -static char *get_subsystem(char *chain, char *buf, size_t bufsz) -{ - size_t len; - char *p; - - if (!chain || !*chain) - return NULL; - - len = strlen(chain); - if (len + sizeof(SUBSYSTEM_LINKNAME) > PATH_MAX) - return NULL; - - do { - ssize_t sz; - - /* append "/subsystem" to the path */ - memcpy(chain + len, SUBSYSTEM_LINKNAME, sizeof(SUBSYSTEM_LINKNAME)); - - /* try if subsystem symlink exists */ - sz = readlink(chain, buf, bufsz - 1); - - /* remove last subsystem from chain */ - chain[len] = '\0'; - p = strrchr(chain, '/'); - if (p) { - *p = '\0'; - len = p - chain; - } - - if (sz > 0) { - /* we found symlink to subsystem, return basename */ - buf[sz] = '\0'; - return basename(buf); - } - - } while (p); - - return NULL; -} - -/* - * Returns complete path to the device, the patch contains all subsystems - * used for the device. - */ -char *sysfs_blkdev_get_devchain(struct path_cxt *pc, char *buf, size_t bufsz) -{ - /* read /sys/dev/block/<maj>:<min> symlink */ - ssize_t sz = ul_path_readlink(pc, buf, bufsz, NULL); - const char *prefix; - size_t psz = 0; - - if (sz <= 0 || sz + sizeof(_PATH_SYS_DEVBLOCK "/") > bufsz) - return NULL; - - buf[sz++] = '\0'; - prefix = ul_path_get_prefix(pc); - if (prefix) - psz = strlen(prefix); - - /* create absolute patch from the link */ - memmove(buf + psz + sizeof(_PATH_SYS_DEVBLOCK "/") - 1, buf, sz); - if (prefix) - memcpy(buf, prefix, psz); - - memcpy(buf + psz, _PATH_SYS_DEVBLOCK "/", sizeof(_PATH_SYS_DEVBLOCK "/") - 1); - return buf; -} - -/* - * The @subsys returns the next subsystem in the chain. Function modifies - * @devchain string. - * - * Returns: 0 in success, <0 on error, 1 on end of chain - */ -int sysfs_blkdev_next_subsystem(struct path_cxt *pc __attribute__((unused)), - char *devchain, char **subsys) -{ - char subbuf[PATH_MAX]; - char *sub; - - if (!subsys || !devchain) - return -EINVAL; - - *subsys = NULL; - - while ((sub = get_subsystem(devchain, subbuf, sizeof(subbuf)))) { - *subsys = strdup(sub); - if (!*subsys) - return -ENOMEM; - return 0; - } - - return 1; -} - - -static int is_hotpluggable_subsystem(const char *name) -{ - static const char * const hotplug_subsystems[] = { - "usb", - "ieee1394", - "pcmcia", - "mmc", - "ccw" - }; - size_t i; - - for (i = 0; i < ARRAY_SIZE(hotplug_subsystems); i++) - if (strcmp(name, hotplug_subsystems[i]) == 0) - return 1; - - return 0; -} - -int sysfs_blkdev_is_hotpluggable(struct path_cxt *pc) -{ - char buf[PATH_MAX], *chain, *sub; - int rc = 0; - - - /* check /sys/dev/block/<maj>:<min>/removable attribute */ - if (ul_path_read_s32(pc, &rc, "removable") == 0 && rc == 1) - return 1; - - chain = sysfs_blkdev_get_devchain(pc, buf, sizeof(buf)); - - while (chain && sysfs_blkdev_next_subsystem(pc, chain, &sub) == 0) { - rc = is_hotpluggable_subsystem(sub); - if (rc) { - free(sub); - break; - } - free(sub); - } - - return rc; -} - -static int get_dm_wholedisk(struct path_cxt *pc, char *diskname, - size_t len, dev_t *diskdevno) -{ - int rc = 0; - char *name; - - /* Note, sysfs_blkdev_get_slave() returns the first slave only, - * if there is more slaves, then return NULL - */ - name = sysfs_blkdev_get_slave(pc); - if (!name) - return -1; - - if (diskname && len) - xstrncpy(diskname, name, len); - - if (diskdevno) { - *diskdevno = __sysfs_devname_to_devno(ul_path_get_prefix(pc), name, NULL); - if (!*diskdevno) - rc = -1; - } - - free(name); - return rc; -} - -/* - * Returns by @diskdevno whole disk device devno and (optionally) by - * @diskname the whole disk device name. - */ -int sysfs_blkdev_get_wholedisk( struct path_cxt *pc, - char *diskname, - size_t len, - dev_t *diskdevno) -{ - int is_part = 0; - - if (!pc) - return -1; - - is_part = ul_path_access(pc, F_OK, "partition") == 0; - if (!is_part) { - /* - * Extra case for partitions mapped by device-mapper. - * - * All regular partitions (added by BLKPG ioctl or kernel PT - * parser) have the /sys/.../partition file. The partitions - * mapped by DM don't have such file, but they have "part" - * prefix in DM UUID. - */ - char *uuid = NULL, *tmp, *prefix; - - ul_path_read_string(pc, &uuid, "dm/uuid"); - tmp = uuid; - prefix = uuid ? strsep(&tmp, "-") : NULL; - - if (prefix && strncasecmp(prefix, "part", 4) == 0) - is_part = 1; - free(uuid); - - if (is_part && - get_dm_wholedisk(pc, diskname, len, diskdevno) == 0) - /* - * partitioned device, mapped by DM - */ - goto done; - - is_part = 0; - } - - if (!is_part) { - /* - * unpartitioned device - */ - if (diskname && !sysfs_blkdev_get_name(pc, diskname, len)) - goto err; - if (diskdevno) - *diskdevno = sysfs_blkdev_get_devno(pc); - - } else { - /* - * partitioned device - * - readlink /sys/dev/block/8:1 = ../../block/sda/sda1 - * - dirname ../../block/sda/sda1 = ../../block/sda - * - basename ../../block/sda = sda - */ - char linkpath[PATH_MAX]; - char *name; - ssize_t linklen; - - linklen = ul_path_readlink(pc, linkpath, sizeof(linkpath) - 1, NULL); - if (linklen < 0) - goto err; - linkpath[linklen] = '\0'; - - stripoff_last_component(linkpath); /* dirname */ - name = stripoff_last_component(linkpath); /* basename */ - if (!name) - goto err; - - sysfs_devname_sys_to_dev(name); - if (diskname && len) - xstrncpy(diskname, name, len); - - if (diskdevno) { - *diskdevno = __sysfs_devname_to_devno(ul_path_get_prefix(pc), name, NULL); - if (!*diskdevno) - goto err; - } - } - -done: - return 0; -err: - return -1; -} - -int sysfs_devno_to_wholedisk(dev_t devno, char *diskname, - size_t len, dev_t *diskdevno) -{ - struct path_cxt *pc; - int rc = 0; - - if (!devno) - return -EINVAL; - pc = ul_new_sysfs_path(devno, NULL, NULL); - if (!pc) - return -ENOMEM; - - rc = sysfs_blkdev_get_wholedisk(pc, diskname, len, diskdevno); - ul_unref_path(pc); - return rc; -} - -/* - * Returns 1 if the device is private device mapper device. The @uuid - * (if not NULL) returns DM device UUID, use free() to deallocate. - */ -int sysfs_devno_is_dm_private(dev_t devno, char **uuid) -{ - struct path_cxt *pc = NULL; - char *id = NULL; - int rc = 0; - - pc = ul_new_sysfs_path(devno, NULL, NULL); - if (!pc) - goto done; - if (ul_path_read_string(pc, &id, "dm/uuid") <= 0 || !id) - goto done; - - /* Private LVM devices use "LVM-<uuid>-<name>" uuid format (important - * is the "LVM" prefix and "-<name>" postfix). - */ - if (strncmp(id, "LVM-", 4) == 0) { - char *p = strrchr(id + 4, '-'); - - if (p && *(p + 1)) - rc = 1; - - /* Private Stratis devices prefix the UUID with "stratis-1-private" - */ - } else if (strncmp(id, "stratis-1-private", 17) == 0) { - rc = 1; - } -done: - ul_unref_path(pc); - if (uuid) - *uuid = id; - else - free(id); - return rc; -} - -/* - * Return 0 or 1, or < 0 in case of error - */ -int sysfs_devno_is_wholedisk(dev_t devno) -{ - dev_t disk; - - if (sysfs_devno_to_wholedisk(devno, NULL, 0, &disk) != 0) - return -1; - - return devno == disk; -} - - -int sysfs_blkdev_scsi_get_hctl(struct path_cxt *pc, int *h, int *c, int *t, int *l) -{ - char buf[PATH_MAX], *hctl; - struct sysfs_blkdev *blk; - ssize_t len; - - blk = ul_path_get_dialect(pc); - - if (!blk || blk->hctl_error) - return -EINVAL; - if (blk->has_hctl) - goto done; - - blk->hctl_error = 1; - len = ul_path_readlink(pc, buf, sizeof(buf) - 1, "device"); - if (len < 0) - return len; - - buf[len] = '\0'; - hctl = strrchr(buf, '/'); - if (!hctl) - return -1; - hctl++; - - if (sscanf(hctl, "%u:%u:%u:%u", &blk->scsi_host, &blk->scsi_channel, - &blk->scsi_target, &blk->scsi_lun) != 4) - return -1; - - blk->has_hctl = 1; -done: - if (h) - *h = blk->scsi_host; - if (c) - *c = blk->scsi_channel; - if (t) - *t = blk->scsi_target; - if (l) - *l = blk->scsi_lun; - - blk->hctl_error = 0; - return 0; -} - - -static char *scsi_host_attribute_path( - struct path_cxt *pc, - const char *type, - char *buf, - size_t bufsz, - const char *attr) -{ - int len; - int host; - const char *prefix; - - if (sysfs_blkdev_scsi_get_hctl(pc, &host, NULL, NULL, NULL)) - return NULL; - - prefix = ul_path_get_prefix(pc); - if (!prefix) - prefix = ""; - - if (attr) - len = snprintf(buf, bufsz, "%s%s/%s_host/host%d/%s", - prefix, _PATH_SYS_CLASS, type, host, attr); - else - len = snprintf(buf, bufsz, "%s%s/%s_host/host%d", - prefix, _PATH_SYS_CLASS, type, host); - - return (len < 0 || (size_t) len >= bufsz) ? NULL : buf; -} - -char *sysfs_blkdev_scsi_host_strdup_attribute(struct path_cxt *pc, - const char *type, const char *attr) -{ - char buf[1024]; - int rc; - FILE *f; - - if (!attr || !type || - !scsi_host_attribute_path(pc, type, buf, sizeof(buf), attr)) - return NULL; - - if (!(f = fopen(buf, "r" UL_CLOEXECSTR))) - return NULL; - - rc = fscanf(f, "%1023[^\n]", buf); - fclose(f); - - return rc == 1 ? strdup(buf) : NULL; -} - -int sysfs_blkdev_scsi_host_is(struct path_cxt *pc, const char *type) -{ - char buf[PATH_MAX]; - struct stat st; - - if (!type || !scsi_host_attribute_path(pc, type, - buf, sizeof(buf), NULL)) - return 0; - - return stat(buf, &st) == 0 && S_ISDIR(st.st_mode); -} - -static char *scsi_attribute_path(struct path_cxt *pc, - char *buf, size_t bufsz, const char *attr) -{ - int len, h, c, t, l; - const char *prefix; - - if (sysfs_blkdev_scsi_get_hctl(pc, &h, &c, &t, &l) != 0) - return NULL; - - prefix = ul_path_get_prefix(pc); - if (!prefix) - prefix = ""; - - if (attr) - len = snprintf(buf, bufsz, "%s%s/devices/%d:%d:%d:%d/%s", - prefix, _PATH_SYS_SCSI, - h,c,t,l, attr); - else - len = snprintf(buf, bufsz, "%s%s/devices/%d:%d:%d:%d", - prefix, _PATH_SYS_SCSI, - h,c,t,l); - return (len < 0 || (size_t) len >= bufsz) ? NULL : buf; -} - -int sysfs_blkdev_scsi_has_attribute(struct path_cxt *pc, const char *attr) -{ - char path[PATH_MAX]; - struct stat st; - - if (!scsi_attribute_path(pc, path, sizeof(path), attr)) - return 0; - - return stat(path, &st) == 0; -} - -int sysfs_blkdev_scsi_path_contains(struct path_cxt *pc, const char *pattern) -{ - char path[PATH_MAX], linkc[PATH_MAX]; - struct stat st; - ssize_t len; - - if (!scsi_attribute_path(pc, path, sizeof(path), NULL)) - return 0; - - if (stat(path, &st) != 0) - return 0; - - len = readlink(path, linkc, sizeof(linkc) - 1); - if (len < 0) - return 0; - - linkc[len] = '\0'; - return strstr(linkc, pattern) != NULL; -} - -static dev_t read_devno(const char *path) -{ - FILE *f; - int maj = 0, min = 0; - dev_t dev = 0; - - f = fopen(path, "r" UL_CLOEXECSTR); - if (!f) - return 0; - - if (fscanf(f, "%d:%d", &maj, &min) == 2) - dev = makedev(maj, min); - fclose(f); - return dev; -} - -int sysfs_devname_is_hidden(const char *prefix, const char *name) -{ - char buf[PATH_MAX]; - int rc = 0, hidden = 0, len; - FILE *f; - - if (strncmp("/dev/", name, 5) == 0) - return 0; - - if (!prefix) - prefix = ""; - /* - * Create path to /sys/block/<name>/hidden - */ - len = snprintf(buf, sizeof(buf), - "%s" _PATH_SYS_BLOCK "/%s/hidden", - prefix, name); - - if (len < 0 || (size_t) len + 1 > sizeof(buf)) - return 0; - - f = fopen(buf, "r" UL_CLOEXECSTR); - if (!f) - return 0; - - rc = fscanf(f, "%d", &hidden); - fclose(f); - - return rc == 1 ? hidden : 0; -} - - -dev_t __sysfs_devname_to_devno(const char *prefix, const char *name, const char *parent) -{ - char buf[PATH_MAX]; - char *_name = NULL; /* name as encoded in sysfs */ - dev_t dev = 0; - int len; - - if (!prefix) - prefix = ""; - - assert(name); - - if (strncmp("/dev/", name, 5) == 0) { - /* - * Read from /dev - */ - struct stat st; - - if (stat(name, &st) == 0) { - dev = st.st_rdev; - goto done; - } - name += 5; /* unaccessible, or not node in /dev */ - } - - _name = strdup(name); - if (!_name) - goto done; - sysfs_devname_dev_to_sys(_name); - - if (parent && strncmp("dm-", name, 3) != 0) { - /* - * Create path to /sys/block/<parent>/<name>/dev - */ - char *_parent = strdup(parent); - - if (!_parent) { - free(_parent); - goto done; - } - sysfs_devname_dev_to_sys(_parent); - len = snprintf(buf, sizeof(buf), - "%s" _PATH_SYS_BLOCK "/%s/%s/dev", - prefix, _parent, _name); - free(_parent); - if (len < 0 || (size_t) len >= sizeof(buf)) - goto done; - - /* don't try anything else for dm-* */ - dev = read_devno(buf); - goto done; - } - - /* - * Read from /sys/block/<sysname>/dev - */ - len = snprintf(buf, sizeof(buf), - "%s" _PATH_SYS_BLOCK "/%s/dev", - prefix, _name); - if (len < 0 || (size_t) len >= sizeof(buf)) - goto done; - dev = read_devno(buf); - - if (!dev) { - /* - * Read from /sys/block/<sysname>/device/dev - */ - len = snprintf(buf, sizeof(buf), - "%s" _PATH_SYS_BLOCK "/%s/device/dev", - prefix, _name); - if (len < 0 || (size_t) len >= sizeof(buf)) - goto done; - dev = read_devno(buf); - } -done: - free(_name); - return dev; -} - -dev_t sysfs_devname_to_devno(const char *name) -{ - return __sysfs_devname_to_devno(NULL, name, NULL); -} - -char *sysfs_blkdev_get_path(struct path_cxt *pc, char *buf, size_t bufsiz) -{ - const char *name = sysfs_blkdev_get_name(pc, buf, bufsiz); - char *res = NULL; - size_t sz; - struct stat st; - - if (!name) - goto done; - - sz = strlen(name); - if (sz + sizeof("/dev/") > bufsiz) - goto done; - - /* create the final "/dev/<name>" string */ - memmove(buf + 5, name, sz + 1); - memcpy(buf, "/dev/", 5); - - if (!stat(buf, &st) && S_ISBLK(st.st_mode) && st.st_rdev == sysfs_blkdev_get_devno(pc)) - res = buf; -done: - return res; -} - -dev_t sysfs_blkdev_get_devno(struct path_cxt *pc) -{ - return ((struct sysfs_blkdev *) ul_path_get_dialect(pc))->devno; -} - -/* - * Returns devname (e.g. "/dev/sda1") for the given devno. - * - * Please, use more robust blkid_devno_to_devname() in your applications. - */ -char *sysfs_devno_to_devpath(dev_t devno, char *buf, size_t bufsiz) -{ - struct path_cxt *pc = ul_new_sysfs_path(devno, NULL, NULL); - char *res = NULL; - - if (pc) { - res = sysfs_blkdev_get_path(pc, buf, bufsiz); - ul_unref_path(pc); - } - return res; -} - -char *sysfs_devno_to_devname(dev_t devno, char *buf, size_t bufsiz) -{ - struct path_cxt *pc = ul_new_sysfs_path(devno, NULL, NULL); - char *res = NULL; - - if (pc) { - res = sysfs_blkdev_get_name(pc, buf, bufsiz); - ul_unref_path(pc); - } - return res; -} - -int sysfs_devno_count_partitions(dev_t devno) -{ - struct path_cxt *pc = ul_new_sysfs_path(devno, NULL, NULL); - int n = 0; - - if (pc) { - char buf[PATH_MAX + 1]; - char *name = sysfs_blkdev_get_name(pc, buf, sizeof(buf)); - - n = sysfs_blkdev_count_partitions(pc, name); - ul_unref_path(pc); - } - return n; -} - - -#ifdef TEST_PROGRAM_SYSFS -#include <errno.h> -#include <err.h> -#include <stdlib.h> - -int main(int argc, char *argv[]) -{ - struct path_cxt *pc; - char *devname; - dev_t devno, disk_devno; - char path[PATH_MAX], *sub, *chain; - char diskname[32]; - int i, is_part, rc = EXIT_SUCCESS; - uint64_t u64; - - if (argc != 2) - errx(EXIT_FAILURE, "usage: %s <devname>", argv[0]); - - ul_sysfs_init_debug(); - - devname = argv[1]; - devno = sysfs_devname_to_devno(devname); - - if (!devno) - err(EXIT_FAILURE, "failed to read devno"); - - printf("non-context:\n"); - printf(" DEVNO: %u (%d:%d)\n", (unsigned int) devno, major(devno), minor(devno)); - printf(" DEVNAME: %s\n", sysfs_devno_to_devname(devno, path, sizeof(path))); - printf(" DEVPATH: %s\n", sysfs_devno_to_devpath(devno, path, sizeof(path))); - - sysfs_devno_to_wholedisk(devno, diskname, sizeof(diskname), &disk_devno); - printf(" WHOLEDISK-DEVNO: %u (%d:%d)\n", (unsigned int) disk_devno, major(disk_devno), minor(disk_devno)); - printf(" WHOLEDISK-DEVNAME: %s\n", diskname); - - pc = ul_new_sysfs_path(devno, NULL, NULL); - if (!pc) - goto done; - - printf("context based:\n"); - devno = sysfs_blkdev_get_devno(pc); - printf(" DEVNO: %u (%d:%d)\n", (unsigned int) devno, major(devno), minor(devno)); - printf(" DEVNAME: %s\n", sysfs_blkdev_get_name(pc, path, sizeof(path))); - printf(" DEVPATH: %s\n", sysfs_blkdev_get_path(pc, path, sizeof(path))); - - sysfs_devno_to_wholedisk(devno, diskname, sizeof(diskname), &disk_devno); - printf(" WHOLEDISK-DEVNO: %u (%d:%d)\n", (unsigned int) disk_devno, major(disk_devno), minor(disk_devno)); - printf(" WHOLEDISK-DEVNAME: %s\n", diskname); - - is_part = ul_path_access(pc, F_OK, "partition") == 0; - printf(" PARTITION: %s\n", is_part ? "YES" : "NOT"); - - if (is_part && disk_devno) { - struct path_cxt *disk_pc = ul_new_sysfs_path(disk_devno, NULL, NULL); - sysfs_blkdev_set_parent(pc, disk_pc); - - ul_unref_path(disk_pc); - } - - printf(" HOTPLUG: %s\n", sysfs_blkdev_is_hotpluggable(pc) ? "yes" : "no"); - printf(" SLAVES: %d\n", ul_path_count_dirents(pc, "slaves")); - - if (!is_part) { - printf("First 5 partitions:\n"); - for (i = 1; i <= 5; i++) { - dev_t dev = sysfs_blkdev_partno_to_devno(pc, i); - if (dev) - printf("\t#%d %d:%d\n", i, major(dev), minor(dev)); - } - } - - if (ul_path_read_u64(pc, &u64, "size") != 0) - printf(" (!) read SIZE failed\n"); - else - printf(" SIZE: %jd\n", u64); - - if (ul_path_read_s32(pc, &i, "queue/hw_sector_size")) - printf(" (!) read SECTOR failed\n"); - else - printf(" SECTOR: %d\n", i); - - - chain = sysfs_blkdev_get_devchain(pc, path, sizeof(path)); - printf(" SUBSUSTEMS:\n"); - - while (chain && sysfs_blkdev_next_subsystem(pc, chain, &sub) == 0) { - printf("\t%s\n", sub); - free(sub); - } - - rc = EXIT_SUCCESS; -done: - ul_unref_path(pc); - return rc; -} -#endif /* TEST_PROGRAM_SYSFS */ diff --git a/utils/lib/timer.c b/utils/lib/timer.c deleted file mode 100644 index c1ea54e..0000000 --- a/utils/lib/timer.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Please, don't add this file to libcommon because timers requires - * -lrt on systems with old libc (and probably also -lpthread for static - * build). - */ -#include <time.h> -#include <signal.h> -#include <sys/time.h> - -#include "c.h" -#include "timer.h" - -/* - * Note the timeout is used for the first signal, then the signal is send - * repeatedly in interval ~1% of the original timeout to avoid race in signal - * handling -- for example you want to use timer to define timeout for a - * syscall: - * - * setup_timer() - * syscall() - * cancel_timer() - * - * if the timeout is too short than it's possible that the signal is delivered - * before application enter the syscall function. For this reason timer send - * the signal repeatedly. - * - * The applications need to ensure that they can tolerate multiple signal - * deliveries. - */ -#ifdef HAVE_TIMER_CREATE -int setup_timer(struct ul_timer *timer, - struct itimerval *timeout, - void (*timeout_handler)(int, siginfo_t *, void *)) -{ - time_t sec = timeout->it_value.tv_sec; - long usec = timeout->it_value.tv_usec; - struct sigaction sig_a; - static struct sigevent sig_e = { - .sigev_notify = SIGEV_SIGNAL, - .sigev_signo = SIGALRM - }; - struct itimerspec val = { - .it_value.tv_sec = sec, - .it_value.tv_nsec = usec * 1000, - .it_interval.tv_sec = sec / 100, - .it_interval.tv_nsec = (sec ? sec % 100 : 1) * 10*1000*1000 - }; - - if (sigemptyset(&sig_a.sa_mask)) - return 1; - - sig_a.sa_flags = SA_SIGINFO; - sig_a.sa_sigaction = timeout_handler; - - if (sigaction(SIGALRM, &sig_a, NULL)) - return 1; - if (timer_create(CLOCK_MONOTONIC, &sig_e, &timer->t_id)) - return 1; - if (timer_settime(timer->t_id, 0, &val, NULL)) - return 1; - return 0; -} -void cancel_timer(struct ul_timer *timer) -{ - timer_delete(timer->t_id); -} - -#else /* !HAVE_TIMER_CREATE */ - -int setup_timer(struct ul_timer *timer, - struct itimerval *timeout, - void (*timeout_handler)(int, siginfo_t *, void *)) -{ - struct sigaction sa; - - memset(&sa, 0, sizeof sa); - memset(timer, 0, sizeof(*timer)); - - sa.sa_flags = SA_SIGINFO | SA_RESETHAND; - sa.sa_sigaction = timeout_handler; - - if (sigaction(SIGALRM, &sa, &timer->old_sa)) - return 1; - if (setitimer(ITIMER_REAL, timeout, &timer->old_timer) != 0) - return 1; - return 0; -} - -void cancel_timer(struct ul_timer *timer) -{ - setitimer(ITIMER_REAL, &timer->old_timer, NULL); - sigaction(SIGALRM, &timer->old_sa, NULL); - -} -#endif /* !HAVE_TIMER_CREATE */ diff --git a/utils/lib/timeutils.c b/utils/lib/timeutils.c deleted file mode 100644 index 8b443cd..0000000 --- a/utils/lib/timeutils.c +++ /dev/null @@ -1,611 +0,0 @@ -/*** - First set of functions in this file are part of systemd, and were - copied to util-linux at August 2013. - - Copyright 2010 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with util-linux; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <assert.h> -#include <ctype.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <sys/time.h> - -#include "c.h" -#include "nls.h" -#include "strutils.h" -#include "timeutils.h" - -#define WHITESPACE " \t\n\r" - -#define streq(a,b) (strcmp((a),(b)) == 0) - -static int parse_sec(const char *t, usec_t *usec) -{ - static const struct { - const char *suffix; - usec_t usec; - } table[] = { - { "seconds", USEC_PER_SEC }, - { "second", USEC_PER_SEC }, - { "sec", USEC_PER_SEC }, - { "s", USEC_PER_SEC }, - { "minutes", USEC_PER_MINUTE }, - { "minute", USEC_PER_MINUTE }, - { "min", USEC_PER_MINUTE }, - { "months", USEC_PER_MONTH }, - { "month", USEC_PER_MONTH }, - { "msec", USEC_PER_MSEC }, - { "ms", USEC_PER_MSEC }, - { "m", USEC_PER_MINUTE }, - { "hours", USEC_PER_HOUR }, - { "hour", USEC_PER_HOUR }, - { "hr", USEC_PER_HOUR }, - { "h", USEC_PER_HOUR }, - { "days", USEC_PER_DAY }, - { "day", USEC_PER_DAY }, - { "d", USEC_PER_DAY }, - { "weeks", USEC_PER_WEEK }, - { "week", USEC_PER_WEEK }, - { "w", USEC_PER_WEEK }, - { "years", USEC_PER_YEAR }, - { "year", USEC_PER_YEAR }, - { "y", USEC_PER_YEAR }, - { "usec", 1ULL }, - { "us", 1ULL }, - { "", USEC_PER_SEC }, /* default is sec */ - }; - - const char *p; - usec_t r = 0; - int something = FALSE; - - assert(t); - assert(usec); - - p = t; - for (;;) { - long long l, z = 0; - char *e; - unsigned i, n = 0; - - p += strspn(p, WHITESPACE); - - if (*p == 0) { - if (!something) - return -EINVAL; - - break; - } - - errno = 0; - l = strtoll(p, &e, 10); - - if (errno > 0) - return -errno; - - if (l < 0) - return -ERANGE; - - if (*e == '.') { - char *b = e + 1; - - errno = 0; - z = strtoll(b, &e, 10); - if (errno > 0) - return -errno; - - if (z < 0) - return -ERANGE; - - if (e == b) - return -EINVAL; - - n = e - b; - - } else if (e == p) - return -EINVAL; - - e += strspn(e, WHITESPACE); - - for (i = 0; i < ARRAY_SIZE(table); i++) - if (startswith(e, table[i].suffix)) { - usec_t k = (usec_t) z * table[i].usec; - - for (; n > 0; n--) - k /= 10; - - r += (usec_t) l *table[i].usec + k; - p = e + strlen(table[i].suffix); - - something = TRUE; - break; - } - - if (i >= ARRAY_SIZE(table)) - return -EINVAL; - - } - - *usec = r; - - return 0; -} - -int parse_timestamp(const char *t, usec_t *usec) -{ - static const struct { - const char *name; - const int nr; - } day_nr[] = { - { "Sunday", 0 }, - { "Sun", 0 }, - { "Monday", 1 }, - { "Mon", 1 }, - { "Tuesday", 2 }, - { "Tue", 2 }, - { "Wednesday", 3 }, - { "Wed", 3 }, - { "Thursday", 4 }, - { "Thu", 4 }, - { "Friday", 5 }, - { "Fri", 5 }, - { "Saturday", 6 }, - { "Sat", 6 }, - }; - - const char *k; - struct tm tm, copy; - time_t x; - usec_t plus = 0, minus = 0, ret; - int r, weekday = -1; - unsigned i; - - /* - * Allowed syntaxes: - * - * 2012-09-22 16:34:22 - * 2012-09-22T16:34:22 - * 2012-09-22 16:34 (seconds will be set to 0) - * 2012-09-22 (time will be set to 00:00:00) - * 16:34:22 (date will be set to today) - * 16:34 (date will be set to today, seconds to 0) - * now - * yesterday (time is set to 00:00:00) - * today (time is set to 00:00:00) - * tomorrow (time is set to 00:00:00) - * +5min - * -5days - * - */ - - assert(t); - assert(usec); - - x = time(NULL); - localtime_r(&x, &tm); - tm.tm_isdst = -1; - - if (streq(t, "now")) - goto finish; - - else if (streq(t, "today")) { - tm.tm_sec = tm.tm_min = tm.tm_hour = 0; - goto finish; - - } else if (streq(t, "yesterday")) { - tm.tm_mday--; - tm.tm_sec = tm.tm_min = tm.tm_hour = 0; - goto finish; - - } else if (streq(t, "tomorrow")) { - tm.tm_mday++; - tm.tm_sec = tm.tm_min = tm.tm_hour = 0; - goto finish; - - } else if (t[0] == '+') { - - r = parse_sec(t + 1, &plus); - if (r < 0) - return r; - - goto finish; - } else if (t[0] == '-') { - - r = parse_sec(t + 1, &minus); - if (r < 0) - return r; - - goto finish; - - } else if (endswith(t, " ago")) { - char *z; - - z = strndup(t, strlen(t) - 4); - if (!z) - return -ENOMEM; - - r = parse_sec(z, &minus); - free(z); - if (r < 0) - return r; - - goto finish; - } - - for (i = 0; i < ARRAY_SIZE(day_nr); i++) { - size_t skip; - - if (!startswith_no_case(t, day_nr[i].name)) - continue; - - skip = strlen(day_nr[i].name); - if (t[skip] != ' ') - continue; - - weekday = day_nr[i].nr; - t += skip + 1; - break; - } - - copy = tm; - k = strptime(t, "%y-%m-%d %H:%M:%S", &tm); - if (k && *k == 0) - goto finish; - - tm = copy; - k = strptime(t, "%Y-%m-%d %H:%M:%S", &tm); - if (k && *k == 0) - goto finish; - - tm = copy; - k = strptime(t, "%Y-%m-%dT%H:%M:%S", &tm); - if (k && *k == 0) - goto finish; - - tm = copy; - k = strptime(t, "%y-%m-%d %H:%M", &tm); - if (k && *k == 0) { - tm.tm_sec = 0; - goto finish; - } - - tm = copy; - k = strptime(t, "%Y-%m-%d %H:%M", &tm); - if (k && *k == 0) { - tm.tm_sec = 0; - goto finish; - } - - tm = copy; - k = strptime(t, "%y-%m-%d", &tm); - if (k && *k == 0) { - tm.tm_sec = tm.tm_min = tm.tm_hour = 0; - goto finish; - } - - tm = copy; - k = strptime(t, "%Y-%m-%d", &tm); - if (k && *k == 0) { - tm.tm_sec = tm.tm_min = tm.tm_hour = 0; - goto finish; - } - - tm = copy; - k = strptime(t, "%H:%M:%S", &tm); - if (k && *k == 0) - goto finish; - - tm = copy; - k = strptime(t, "%H:%M", &tm); - if (k && *k == 0) { - tm.tm_sec = 0; - goto finish; - } - - tm = copy; - k = strptime(t, "%Y%m%d%H%M%S", &tm); - if (k && *k == 0) { - tm.tm_sec = 0; - goto finish; - } - - return -EINVAL; - - finish: - x = mktime(&tm); - if (x == (time_t)-1) - return -EINVAL; - - if (weekday >= 0 && tm.tm_wday != weekday) - return -EINVAL; - - ret = (usec_t) x *USEC_PER_SEC; - - ret += plus; - if (ret > minus) - ret -= minus; - else - ret = 0; - - *usec = ret; - - return 0; -} - -/* Returns the difference in seconds between its argument and GMT. If if TP is - * invalid or no DST information is available default to UTC, that is, zero. - * tzset is called so, for example, 'TZ="UTC" hwclock' will work as expected. - * Derived from glibc/time/strftime_l.c - */ -int get_gmtoff(const struct tm *tp) -{ - if (tp->tm_isdst < 0) - return 0; - -#if HAVE_TM_GMTOFF - return tp->tm_gmtoff; -#else - struct tm tm; - struct tm gtm; - struct tm ltm = *tp; - time_t lt; - - tzset(); - lt = mktime(<m); - /* Check if mktime returning -1 is an error or a valid time_t */ - if (lt == (time_t) -1) { - if (! localtime_r(<, &tm) - || ((ltm.tm_sec ^ tm.tm_sec) - | (ltm.tm_min ^ tm.tm_min) - | (ltm.tm_hour ^ tm.tm_hour) - | (ltm.tm_mday ^ tm.tm_mday) - | (ltm.tm_mon ^ tm.tm_mon) - | (ltm.tm_year ^ tm.tm_year))) - return 0; - } - - if (! gmtime_r(<, >m)) - return 0; - - /* Calculate the GMT offset, that is, the difference between the - * TP argument (ltm) and GMT (gtm). - * - * Compute intervening leap days correctly even if year is negative. - * Take care to avoid int overflow in leap day calculations, but it's OK - * to assume that A and B are close to each other. - */ - int a4 = (ltm.tm_year >> 2) + (1900 >> 2) - ! (ltm.tm_year & 3); - int b4 = (gtm.tm_year >> 2) + (1900 >> 2) - ! (gtm.tm_year & 3); - int a100 = a4 / 25 - (a4 % 25 < 0); - int b100 = b4 / 25 - (b4 % 25 < 0); - int a400 = a100 >> 2; - int b400 = b100 >> 2; - int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400); - - int years = ltm.tm_year - gtm.tm_year; - int days = (365 * years + intervening_leap_days - + (ltm.tm_yday - gtm.tm_yday)); - - return (60 * (60 * (24 * days + (ltm.tm_hour - gtm.tm_hour)) - + (ltm.tm_min - gtm.tm_min)) + (ltm.tm_sec - gtm.tm_sec)); -#endif -} - -static int format_iso_time(struct tm *tm, suseconds_t usec, int flags, char *buf, size_t bufsz) -{ - char *p = buf; - int len; - - if (flags & ISO_DATE) { - len = snprintf(p, bufsz, "%4ld-%.2d-%.2d", - tm->tm_year + (long) 1900, - tm->tm_mon + 1, tm->tm_mday); - if (len < 0 || (size_t) len > bufsz) - goto err; - bufsz -= len; - p += len; - } - - if ((flags & ISO_DATE) && (flags & ISO_TIME)) { - if (bufsz < 1) - goto err; - *p++ = (flags & ISO_T) ? 'T' : ' '; - bufsz--; - } - - if (flags & ISO_TIME) { - len = snprintf(p, bufsz, "%02d:%02d:%02d", tm->tm_hour, - tm->tm_min, tm->tm_sec); - if (len < 0 || (size_t) len > bufsz) - goto err; - bufsz -= len; - p += len; - } - - if (flags & ISO_DOTUSEC) { - len = snprintf(p, bufsz, ".%06ld", (long) usec); - if (len < 0 || (size_t) len > bufsz) - goto err; - bufsz -= len; - p += len; - - } else if (flags & ISO_COMMAUSEC) { - len = snprintf(p, bufsz, ",%06ld", (long) usec); - if (len < 0 || (size_t) len > bufsz) - goto err; - bufsz -= len; - p += len; - } - - if (flags & ISO_TIMEZONE) { - int tmin = get_gmtoff(tm) / 60; - int zhour = tmin / 60; - int zmin = abs(tmin % 60); - len = snprintf(p, bufsz, "%+03d:%02d", zhour,zmin); - if (len < 0 || (size_t) len > bufsz) - goto err; - } - return 0; - err: - warnx(_("format_iso_time: buffer overflow.")); - return -1; -} - -/* timeval to ISO 8601 */ -int strtimeval_iso(struct timeval *tv, int flags, char *buf, size_t bufsz) -{ - struct tm tm; - struct tm *rc; - - if (flags & ISO_GMTIME) - rc = gmtime_r(&tv->tv_sec, &tm); - else - rc = localtime_r(&tv->tv_sec, &tm); - - if (rc) - return format_iso_time(&tm, tv->tv_usec, flags, buf, bufsz); - - warnx(_("time %ld is out of range."), tv->tv_sec); - return -1; -} - -/* struct tm to ISO 8601 */ -int strtm_iso(struct tm *tm, int flags, char *buf, size_t bufsz) -{ - return format_iso_time(tm, 0, flags, buf, bufsz); -} - -/* time_t to ISO 8601 */ -int strtime_iso(const time_t *t, int flags, char *buf, size_t bufsz) -{ - struct tm tm; - struct tm *rc; - - if (flags & ISO_GMTIME) - rc = gmtime_r(t, &tm); - else - rc = localtime_r(t, &tm); - - if (rc) - return format_iso_time(&tm, 0, flags, buf, bufsz); - - warnx(_("time %ld is out of range."), (long)t); - return -1; -} - -/* relative time functions */ -static inline int time_is_thisyear(struct tm const *const tm, - struct tm const *const tmnow) -{ - return tm->tm_year == tmnow->tm_year; -} - -static inline int time_is_today(struct tm const *const tm, - struct tm const *const tmnow) -{ - return (tm->tm_yday == tmnow->tm_yday && - time_is_thisyear(tm, tmnow)); -} - -int strtime_short(const time_t *t, struct timeval *now, int flags, char *buf, size_t bufsz) -{ - struct tm tm, tmnow; - int rc = 0; - - if (now->tv_sec == 0) - gettimeofday(now, NULL); - - localtime_r(t, &tm); - localtime_r(&now->tv_sec, &tmnow); - - if (time_is_today(&tm, &tmnow)) { - rc = snprintf(buf, bufsz, "%02d:%02d", tm.tm_hour, tm.tm_min); - if (rc < 0 || (size_t) rc > bufsz) - return -1; - rc = 1; - - } else if (time_is_thisyear(&tm, &tmnow)) { - if (flags & UL_SHORTTIME_THISYEAR_HHMM) - rc = strftime(buf, bufsz, "%b%d/%H:%M", &tm); - else - rc = strftime(buf, bufsz, "%b%d", &tm); - } else - rc = strftime(buf, bufsz, "%Y-%b%d", &tm); - - return rc <= 0 ? -1 : 0; -} - -#ifndef HAVE_TIMEGM -time_t timegm(struct tm *tm) -{ - const char *zone = getenv("TZ"); - time_t ret; - - setenv("TZ", "", 1); - tzset(); - ret = mktime(tm); - if (zone) - setenv("TZ", zone, 1); - else - unsetenv("TZ"); - tzset(); - return ret; -} -#endif /* HAVE_TIMEGM */ - -#ifdef TEST_PROGRAM_TIMEUTILS - -int main(int argc, char *argv[]) -{ - struct timeval tv = { 0 }; - char buf[ISO_BUFSIZ]; - - if (argc < 2) { - fprintf(stderr, "usage: %s [<time> [<usec>]] | [--timestamp <str>]\n", argv[0]); - exit(EXIT_FAILURE); - } - - if (strcmp(argv[1], "--timestamp") == 0) { - usec_t usec; - - parse_timestamp(argv[2], &usec); - tv.tv_sec = (time_t) (usec / 1000000); - tv.tv_usec = usec % 1000000; - } else { - tv.tv_sec = strtos64_or_err(argv[1], "failed to parse <time>"); - if (argc == 3) - tv.tv_usec = strtos64_or_err(argv[2], "failed to parse <usec>"); - } - - strtimeval_iso(&tv, ISO_DATE, buf, sizeof(buf)); - printf("Date: '%s'\n", buf); - - strtimeval_iso(&tv, ISO_TIME, buf, sizeof(buf)); - printf("Time: '%s'\n", buf); - - strtimeval_iso(&tv, ISO_DATE | ISO_TIME | ISO_COMMAUSEC | ISO_T, - buf, sizeof(buf)); - printf("Full: '%s'\n", buf); - - strtimeval_iso(&tv, ISO_TIMESTAMP_DOT, buf, sizeof(buf)); - printf("Zone: '%s'\n", buf); - - return EXIT_SUCCESS; -} - -#endif /* TEST_PROGRAM_TIMEUTILS */ diff --git a/utils/lib/ttyutils.c b/utils/lib/ttyutils.c deleted file mode 100644 index 7064565..0000000 --- a/utils/lib/ttyutils.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * No copyright is claimed. This code is in the public domain; do with - * it what you wish. - * - * Written by Karel Zak <kzak@redhat.com> - */ -#include <ctype.h> -#include <unistd.h> - -#include "c.h" -#include "ttyutils.h" - - -static int get_env_int(const char *name) -{ - const char *cp = getenv(name); - - if (cp) { - char *end = NULL; - long x; - - errno = 0; - x = strtol(cp, &end, 10); - - if (errno == 0 && end && *end == '\0' && end > cp && - x > 0 && x <= INT_MAX) - return x; - } - - return -1; -} - -int get_terminal_dimension(int *cols, int *lines) -{ - int c = 0, l = 0; - -#if defined(TIOCGWINSZ) - struct winsize w_win; - if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &w_win) == 0) { - c = w_win.ws_col; - l = w_win.ws_row; - } -#elif defined(TIOCGSIZE) - struct ttysize t_win; - if (ioctl (STDOUT_FILENO, TIOCGSIZE, &t_win) == 0) { - c = t_win.ts_cols; - l = t_win.ts_lines; - } -#endif - if (cols) { - if (c <= 0) - c = get_env_int("COLUMNS"); - *cols = c; - } - if (lines) { - if (l <= 0) - l = get_env_int("LINES"); - *lines = l; - } - return 0; -} - -int get_terminal_width(int default_width) -{ - int width = 0; - - get_terminal_dimension(&width, NULL); - - return width > 0 ? width : default_width; -} - -int get_terminal_stdfd(void) -{ - if (isatty(STDIN_FILENO)) - return STDIN_FILENO; - if (isatty(STDOUT_FILENO)) - return STDOUT_FILENO; - if (isatty(STDERR_FILENO)) - return STDERR_FILENO; - - return -EINVAL; -} - -int get_terminal_name(const char **path, - const char **name, - const char **number) -{ - const char *tty; - const char *p; - int fd; - - - if (name) - *name = NULL; - if (path) - *path = NULL; - if (number) - *number = NULL; - - fd = get_terminal_stdfd(); - if (fd < 0) - return fd; /* error */ - - tty = ttyname(fd); - if (!tty) - return -1; - - if (path) - *path = tty; - if (name || number) - tty = strncmp(tty, "/dev/", 5) == 0 ? tty + 5 : tty; - if (name) - *name = tty; - if (number) { - for (p = tty; p && *p; p++) { - if (isdigit(*p)) { - *number = p; - break; - } - } - } - return 0; -} - -int get_terminal_type(const char **type) -{ - *type = getenv("TERM"); - if (*type) - return -EINVAL; - return 0; -} - -#ifdef TEST_PROGRAM_TTYUTILS -# include <stdlib.h> -int main(void) -{ - const char *path, *name, *num; - int c, l; - - if (get_terminal_name(&path, &name, &num) == 0) { - fprintf(stderr, "tty path: %s\n", path); - fprintf(stderr, "tty name: %s\n", name); - fprintf(stderr, "tty number: %s\n", num); - } - get_terminal_dimension(&c, &l); - fprintf(stderr, "tty cols: %d\n", c); - fprintf(stderr, "tty lines: %d\n", l); - - - return EXIT_SUCCESS; -} -#endif /* TEST_PROGRAM_TTYUTILS */ diff --git a/utils/libsmartcols/CMakeLists.txt b/utils/libsmartcols/CMakeLists.txt deleted file mode 100644 index c8deb72..0000000 --- a/utils/libsmartcols/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -cmake_minimum_required(VERSION 3.10) - -# set the project name -project(xloop-utils-libsmartcols) - -add_library(libsmartcols STATIC ${CMAKE_CURRENT_SOURCE_DIR}/src/buffer.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/calculate.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/cell.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/column.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/fput.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/grouping.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/init.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/iter.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/line.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/print-api.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/print.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/symbols.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/table.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/version.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/walk.c) -target_include_directories(libsmartcols PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/../lib) -target_link_libraries(libsmartcols LINK_PUBLIC libcommon) diff --git a/utils/libsmartcols/src/buffer.c b/utils/libsmartcols/src/buffer.c deleted file mode 100644 index d376e8f..0000000 --- a/utils/libsmartcols/src/buffer.c +++ /dev/null @@ -1,152 +0,0 @@ - -#include "smartcolsP.h" -#include "mbsalign.h" - -/* This is private struct to work with output data */ -struct libscols_buffer { - char *begin; /* begin of the buffer */ - char *cur; /* current end of the buffer */ - char *encdata; /* encoded buffer mbs_safe_encode() */ - - size_t bufsz; /* size of the buffer */ - size_t art_idx; /* begin of the tree ascii art or zero */ -}; - -struct libscols_buffer *new_buffer(size_t sz) -{ - struct libscols_buffer *buf = malloc(sz + sizeof(struct libscols_buffer)); - - if (!buf) - return NULL; - - buf->cur = buf->begin = ((char *) buf) + sizeof(struct libscols_buffer); - buf->encdata = NULL; - buf->bufsz = sz; - - DBG(BUFF, ul_debugobj(buf, "alloc (size=%zu)", sz)); - return buf; -} - -void free_buffer(struct libscols_buffer *buf) -{ - if (!buf) - return; - DBG(BUFF, ul_debugobj(buf, "dealloc")); - free(buf->encdata); - free(buf); -} - -int buffer_reset_data(struct libscols_buffer *buf) -{ - if (!buf) - return -EINVAL; - - /*DBG(BUFF, ul_debugobj(buf, "reset data"));*/ - buf->begin[0] = '\0'; - buf->cur = buf->begin; - buf->art_idx = 0; - return 0; -} - -int buffer_append_data(struct libscols_buffer *buf, const char *str) -{ - size_t maxsz, sz; - - if (!buf) - return -EINVAL; - if (!str || !*str) - return 0; - - sz = strlen(str); - maxsz = buf->bufsz - (buf->cur - buf->begin); - - if (maxsz <= sz) - return -EINVAL; - memcpy(buf->cur, str, sz + 1); - buf->cur += sz; - return 0; -} - -int buffer_append_ntimes(struct libscols_buffer *buf, size_t n, const char *str) -{ - size_t i; - - for (i = 0; i < n; i++) { - int rc = buffer_append_data(buf, str); - if (rc) - return rc; - } - return 0; -} - -int buffer_set_data(struct libscols_buffer *buf, const char *str) -{ - int rc = buffer_reset_data(buf); - return rc ? rc : buffer_append_data(buf, str); -} - -/* save the current buffer position to art_idx */ -void buffer_set_art_index(struct libscols_buffer *buf) -{ - if (buf) { - buf->art_idx = buf->cur - buf->begin; - /*DBG(BUFF, ul_debugobj(buf, "art index: %zu", buf->art_idx));*/ - } -} - -char *buffer_get_data(struct libscols_buffer *buf) -{ - return buf ? buf->begin : NULL; -} - -size_t buffer_get_size(struct libscols_buffer *buf) -{ - return buf ? buf->bufsz : 0; -} - -/* encode data by mbs_safe_encode() to avoid control and non-printable chars */ -char *buffer_get_safe_data(struct libscols_table *tb, - struct libscols_buffer *buf, - size_t *cells, - const char *safechars) -{ - char *data = buffer_get_data(buf); - char *res = NULL; - - if (!data) - goto nothing; - - if (!buf->encdata) { - buf->encdata = malloc(mbs_safe_encode_size(buf->bufsz) + 1); - if (!buf->encdata) - goto nothing; - } - - if (scols_table_is_noencoding(tb)) { - *cells = mbs_width(data); - strcpy(buf->encdata, data); - res = buf->encdata; - } else { - res = mbs_safe_encode_to_buffer(data, cells, buf->encdata, safechars); - } - - if (!res || !*cells || *cells == (size_t) -1) - goto nothing; - return res; -nothing: - *cells = 0; - return NULL; -} - -/* returns size in bytes of the ascii art (according to art_idx) in safe encoding */ -size_t buffer_get_safe_art_size(struct libscols_buffer *buf) -{ - char *data = buffer_get_data(buf); - size_t bytes = 0; - - if (!data || !buf->art_idx) - return 0; - - mbs_safe_nwidth(data, buf->art_idx, &bytes); - return bytes; -} diff --git a/utils/libsmartcols/src/calculate.c b/utils/libsmartcols/src/calculate.c deleted file mode 100644 index b6137fd..0000000 --- a/utils/libsmartcols/src/calculate.c +++ /dev/null @@ -1,454 +0,0 @@ -#include "smartcolsP.h" -#include "mbsalign.h" - -static void dbg_column(struct libscols_table *tb, struct libscols_column *cl) -{ - if (scols_column_is_hidden(cl)) { - DBG(COL, ul_debugobj(cl, "%s (hidden) ignored", cl->header.data)); - return; - } - - DBG(COL, ul_debugobj(cl, "%15s seq=%zu, width=%zd, " - "hint=%d, avg=%zu, max=%zu, min=%zu, " - "extreme=%s %s", - - cl->header.data, cl->seqnum, cl->width, - cl->width_hint > 1 ? (int) cl->width_hint : - (int) (cl->width_hint * tb->termwidth), - cl->width_avg, - cl->width_max, - cl->width_min, - cl->is_extreme ? "yes" : "not", - cl->flags & SCOLS_FL_TRUNC ? "trunc" : "")); -} - -static void dbg_columns(struct libscols_table *tb) -{ - struct libscols_iter itr; - struct libscols_column *cl; - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_column(tb, &itr, &cl) == 0) - dbg_column(tb, cl); -} - -static int count_cell_width(struct libscols_table *tb, - struct libscols_line *ln, - struct libscols_column *cl, - struct libscols_buffer *buf) -{ - size_t len; - char *data; - int rc; - - rc = __cell_to_buffer(tb, ln, cl, buf); - if (rc) - return rc; - - data = buffer_get_data(buf); - if (!data) - len = 0; - else if (scols_column_is_customwrap(cl)) - len = cl->wrap_chunksize(cl, data, cl->wrapfunc_data); - else if (scols_table_is_noencoding(tb)) - len = mbs_width(data); - else - len = mbs_safe_width(data); - - if (len == (size_t) -1) /* ignore broken multibyte strings */ - len = 0; - cl->width_max = max(len, cl->width_max); - - if (cl->is_extreme && cl->width_avg && len > cl->width_avg * 2) - return 0; - - if (scols_column_is_noextremes(cl)) { - cl->extreme_sum += len; - cl->extreme_count++; - } - cl->width = max(len, cl->width); - if (scols_column_is_tree(cl)) { - size_t treewidth = buffer_get_safe_art_size(buf); - cl->width_treeart = max(cl->width_treeart, treewidth); - } - return 0; -} - - -static int walk_count_cell_width(struct libscols_table *tb, - struct libscols_line *ln, - struct libscols_column *cl, - void *data) -{ - return count_cell_width(tb, ln, cl, (struct libscols_buffer *) data); -} - -/* - * This function counts column width. - * - * For the SCOLS_FL_NOEXTREMES columns it is possible to call this function - * two times. The first pass counts the width and average width. If the column - * contains fields that are too large (a width greater than 2 * average) then - * the column is marked as "extreme". In the second pass all extreme fields - * are ignored and the column width is counted from non-extreme fields only. - */ -static int count_column_width(struct libscols_table *tb, - struct libscols_column *cl, - struct libscols_buffer *buf) -{ - int rc = 0, no_header = 0; - - assert(tb); - assert(cl); - - cl->width = 0; - if (!cl->width_min) { - const char *data; - - if (cl->width_hint < 1 && scols_table_is_maxout(tb) && tb->is_term) { - cl->width_min = (size_t) (cl->width_hint * tb->termwidth); - if (cl->width_min && !is_last_column(cl)) - cl->width_min--; - } - - data = scols_cell_get_data(&cl->header); - if (data) { - size_t len = scols_table_is_noencoding(tb) ? - mbs_width(data) : mbs_safe_width(data); - cl->width_min = max(cl->width_min, len); - } else - no_header = 1; - - if (!cl->width_min) - cl->width_min = 1; - } - - if (scols_table_is_tree(tb)) { - /* Count width for tree */ - rc = scols_walk_tree(tb, cl, walk_count_cell_width, (void *) buf); - if (rc) - goto done; - } else { - /* Count width for list */ - struct libscols_iter itr; - struct libscols_line *ln; - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_line(tb, &itr, &ln) == 0) { - rc = count_cell_width(tb, ln, cl, buf); - if (rc) - goto done; - } - } - - if (scols_column_is_tree(cl) && has_groups(tb)) { - /* We don't fill buffer with groups tree ascii art during width - * calculation. The print function only enlarge grpset[] and we - * calculate final width from grpset_size. - */ - size_t gprwidth = tb->grpset_size + 1; - cl->width_treeart += gprwidth; - cl->width_max += gprwidth; - cl->width += gprwidth; - if (cl->extreme_count) - cl->extreme_sum += gprwidth; - } - - if (cl->extreme_count && cl->width_avg == 0) { - cl->width_avg = cl->extreme_sum / cl->extreme_count; - if (cl->width_avg && cl->width_max > cl->width_avg * 2) - cl->is_extreme = 1; - } - - /* enlarge to minimal width */ - if (cl->width < cl->width_min && !scols_column_is_strict_width(cl)) - cl->width = cl->width_min; - - /* use absolute size for large columns */ - else if (cl->width_hint >= 1 && cl->width < (size_t) cl->width_hint - && cl->width_min < (size_t) cl->width_hint) - - cl->width = (size_t) cl->width_hint; - - - /* Column without header and data, set minimal size to zero (default is 1) */ - if (cl->width_max == 0 && no_header && cl->width_min == 1 && cl->width <= 1) - cl->width = cl->width_min = 0; - -done: - ON_DBG(COL, dbg_column(tb, cl)); - return rc; -} - -/* - * This is core of the scols_* voodoo... - */ -int __scols_calculate(struct libscols_table *tb, struct libscols_buffer *buf) -{ - struct libscols_column *cl; - struct libscols_iter itr; - size_t width = 0, width_min = 0; /* output width */ - int stage, rc = 0; - int extremes = 0, group_ncolumns = 0; - size_t colsepsz; - - - DBG(TAB, ul_debugobj(tb, "-----calculate-(termwidth=%zu)-----", tb->termwidth)); - tb->is_dummy_print = 1; - - colsepsz = scols_table_is_noencoding(tb) ? - mbs_width(colsep(tb)) : - mbs_safe_width(colsep(tb)); - - if (has_groups(tb)) - group_ncolumns = 1; - - /* set basic columns width - */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_column(tb, &itr, &cl) == 0) { - int is_last; - - if (scols_column_is_hidden(cl)) - continue; - - /* we print groups chart only for the for the first tree column */ - if (scols_column_is_tree(cl) && group_ncolumns == 1) { - cl->is_groups = 1; - group_ncolumns++; - } - - rc = count_column_width(tb, cl, buf); - if (rc) - goto done; - - is_last = is_last_column(cl); - - width += cl->width + (is_last ? 0 : colsepsz); /* separator for non-last column */ - width_min += cl->width_min + (is_last ? 0 : colsepsz); - if (cl->is_extreme) - extremes++; - } - - if (!tb->is_term) { - DBG(TAB, ul_debugobj(tb, " non-terminal output")); - goto done; - } - - /* be paranoid */ - if (width_min > tb->termwidth && scols_table_is_maxout(tb)) { - DBG(TAB, ul_debugobj(tb, " min width larger than terminal! [width=%zu, term=%zu]", width_min, tb->termwidth)); - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (width_min > tb->termwidth - && scols_table_next_column(tb, &itr, &cl) == 0) { - if (scols_column_is_hidden(cl)) - continue; - width_min--; - cl->width_min--; - } - DBG(TAB, ul_debugobj(tb, " min width reduced to %zu", width_min)); - } - - /* reduce columns with extreme fields */ - if (width > tb->termwidth && extremes) { - DBG(TAB, ul_debugobj(tb, " reduce width (extreme columns)")); - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_column(tb, &itr, &cl) == 0) { - size_t org_width; - - if (!cl->is_extreme || scols_column_is_hidden(cl)) - continue; - - org_width = cl->width; - rc = count_column_width(tb, cl, buf); - if (rc) - goto done; - - if (org_width > cl->width) - width -= org_width - cl->width; - else - extremes--; /* hmm... nothing reduced */ - } - } - - if (width < tb->termwidth) { - if (extremes) { - DBG(TAB, ul_debugobj(tb, " enlarge width (extreme columns)")); - - /* enlarge the first extreme column */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_column(tb, &itr, &cl) == 0) { - size_t add; - - if (!cl->is_extreme || scols_column_is_hidden(cl)) - continue; - - /* this column is too large, ignore? - if (cl->width_max - cl->width > - (tb->termwidth - width)) - continue; - */ - - add = tb->termwidth - width; - if (add && cl->width + add > cl->width_max) - add = cl->width_max - cl->width; - - cl->width += add; - width += add; - - if (width == tb->termwidth) - break; - } - } - - if (width < tb->termwidth && scols_table_is_maxout(tb)) { - DBG(TAB, ul_debugobj(tb, " enlarge width (max-out)")); - - /* try enlarging all columns */ - while (width < tb->termwidth) { - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_column(tb, &itr, &cl) == 0) { - if (scols_column_is_hidden(cl)) - continue; - cl->width++; - width++; - if (width == tb->termwidth) - break; - } - } - } else if (width < tb->termwidth) { - /* enlarge the last column */ - struct libscols_column *col = list_entry( - tb->tb_columns.prev, struct libscols_column, cl_columns); - - DBG(TAB, ul_debugobj(tb, " enlarge width (last column)")); - - if (!scols_column_is_right(col) && tb->termwidth - width > 0) { - col->width += tb->termwidth - width; - width = tb->termwidth; - } - } - } - - /* bad, we have to reduce output width, this is done in three stages: - * - * 1) trunc relative with trunc flag if the column width is greater than - * expected column width (it means "width_hint * terminal_width"). - * - * 2) trunc all with trunc flag - * - * 3) trunc relative without trunc flag - * - * Note that SCOLS_FL_WRAP (if no custom wrap function is specified) is - * interpreted as SCOLS_FL_TRUNC. - */ - for (stage = 1; width > tb->termwidth && stage <= 3; ) { - size_t org_width = width; - - DBG(TAB, ul_debugobj(tb, " reduce width - #%d stage (current=%zu, wanted=%zu)", - stage, width, tb->termwidth)); - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_column(tb, &itr, &cl) == 0) { - - int trunc_flag = 0; - - DBG(TAB, ul_debugobj(cl, " checking %s (width=%zu, treeart=%zu)", - cl->header.data, cl->width, cl->width_treeart)); - if (scols_column_is_hidden(cl)) - continue; - if (width <= tb->termwidth) - break; - - /* never truncate if already minimal width */ - if (cl->width == cl->width_min) - continue; - - /* never truncate the tree */ - if (scols_column_is_tree(cl) && width <= cl->width_treeart) - continue; - - /* nothing to truncate */ - if (cl->width == 0) - continue; - - trunc_flag = scols_column_is_trunc(cl) - || (scols_column_is_wrap(cl) && !scols_column_is_customwrap(cl)); - - switch (stage) { - /* #1 stage - trunc relative with TRUNC flag */ - case 1: - if (!trunc_flag) /* ignore: missing flag */ - break; - if (cl->width_hint <= 0 || cl->width_hint >= 1) /* ignore: no relative */ - break; - if (cl->width < (size_t) (cl->width_hint * tb->termwidth)) /* ignore: smaller than expected width */ - break; - - DBG(TAB, ul_debugobj(tb, " reducing (relative with flag)")); - cl->width--; - width--; - break; - - /* #2 stage - trunc all with TRUNC flag */ - case 2: - if (!trunc_flag) /* ignore: missing flag */ - break; - - DBG(TAB, ul_debugobj(tb, " reducing (all with flag)")); - cl->width--; - width--; - break; - - /* #3 stage - trunc relative without flag */ - case 3: - if (cl->width_hint <= 0 || cl->width_hint >= 1) /* ignore: no relative */ - break; - - DBG(TAB, ul_debugobj(tb, " reducing (relative without flag)")); - cl->width--; - width--; - break; - } - - /* hide zero width columns */ - if (cl->width == 0) - cl->flags |= SCOLS_FL_HIDDEN; - } - - /* the current stage is without effect, go to the next */ - if (org_width == width) - stage++; - } - - /* ignore last column(s) or force last column to be truncated if - * nowrap mode enabled */ - if (tb->no_wrap && width > tb->termwidth) { - scols_reset_iter(&itr, SCOLS_ITER_BACKWARD); - while (scols_table_next_column(tb, &itr, &cl) == 0) { - - if (scols_column_is_hidden(cl)) - continue; - if (width <= tb->termwidth) - break; - if (width - cl->width < tb->termwidth) { - size_t r = width - tb->termwidth; - - cl->flags |= SCOLS_FL_TRUNC; - cl->width -= r; - width -= r; - } else { - cl->flags |= SCOLS_FL_HIDDEN; - width -= cl->width + colsepsz; - } - } - } -done: - tb->is_dummy_print = 0; - DBG(TAB, ul_debugobj(tb, "-----final width: %zu (rc=%d)-----", width, rc)); - ON_DBG(TAB, dbg_columns(tb)); - - return rc; -} diff --git a/utils/libsmartcols/src/cell.c b/utils/libsmartcols/src/cell.c deleted file mode 100644 index 4cd6e59..0000000 --- a/utils/libsmartcols/src/cell.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * cell.c - functions for table handling at the cell level - * - * Copyright (C) 2014 Ondrej Oprala <ooprala@redhat.com> - * Copyright (C) 2014 Karel Zak <kzak@redhat.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -/** - * SECTION: cell - * @title: Cell - * @short_description: container for your data - * - * An API to access and modify per-cell data and information. Note that cell is - * always part of the line. If you destroy (un-reference) a line than it - * destroys all line cells too. - */ - - -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <ctype.h> - -#include "smartcolsP.h" - -/* - * The cell has no ref-counting, free() and new() functions. All is - * handled by libscols_line. - */ - -/** - * scols_reset_cell: - * @ce: pointer to a struct libscols_cell instance - * - * Frees the cell's internal data and resets its status. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_reset_cell(struct libscols_cell *ce) -{ - if (!ce) - return -EINVAL; - - /*DBG(CELL, ul_debugobj(ce, "reset"));*/ - free(ce->data); - free(ce->color); - memset(ce, 0, sizeof(*ce)); - return 0; -} - -/** - * scols_cell_set_data: - * @ce: a pointer to a struct libscols_cell instance - * @data: data (used for scols_print_table()) - * - * Stores a copy of the @str in @ce, the old data are deallocated by free(). - * - * Returns: 0, a negative value in case of an error. - */ -int scols_cell_set_data(struct libscols_cell *ce, const char *data) -{ - return strdup_to_struct_member(ce, data, data); -} - -/** - * scols_cell_refer_data: - * @ce: a pointer to a struct libscols_cell instance - * @data: data (used for scols_print_table()) - * - * Adds a reference to @str to @ce. The pointer is deallocated by - * scols_reset_cell() or scols_unref_line(). This function is mostly designed - * for situations when the data for the cell are already composed in allocated - * memory (e.g. asprintf()) to avoid extra unnecessary strdup(). - * - * Returns: 0, a negative value in case of an error. - */ -int scols_cell_refer_data(struct libscols_cell *ce, char *data) -{ - if (!ce) - return -EINVAL; - free(ce->data); - ce->data = data; - return 0; -} - -/** - * scols_cell_get_data: - * @ce: a pointer to a struct libscols_cell instance - * - * Returns: data in @ce or NULL. - */ -const char *scols_cell_get_data(const struct libscols_cell *ce) -{ - return ce ? ce->data : NULL; -} - -/** - * scols_cell_set_userdata: - * @ce: a pointer to a struct libscols_cell instance - * @data: private user data - * - * Returns: 0, a negative value in case of an error. - */ -int scols_cell_set_userdata(struct libscols_cell *ce, void *data) -{ - if (!ce) - return -EINVAL; - ce->userdata = data; - return 0; -} - -/** - * scols_cell_get_userdata - * @ce: a pointer to a struct libscols_cell instance - * - * Returns: user data - */ -void *scols_cell_get_userdata(struct libscols_cell *ce) -{ - return ce->userdata; -} - -/** - * scols_cmpstr_cells: - * @a: pointer to cell - * @b: pointer to cell - * @data: unused pointer to private data (defined by API) - * - * Compares cells data by strcmp(). The function is designed for - * scols_column_set_cmpfunc() and scols_sort_table(). - * - * Returns: follows strcmp() return values. - */ -int scols_cmpstr_cells(struct libscols_cell *a, - struct libscols_cell *b, - __attribute__((__unused__)) void *data) -{ - const char *adata, *bdata; - - if (a == b) - return 0; - - adata = scols_cell_get_data(a); - bdata = scols_cell_get_data(b); - - if (adata == NULL && bdata == NULL) - return 0; - if (adata == NULL) - return -1; - if (bdata == NULL) - return 1; - return strcmp(adata, bdata); -} - -/** - * scols_cell_set_color: - * @ce: a pointer to a struct libscols_cell instance - * @color: color name or ESC sequence - * - * Set the color of @ce to @color. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_cell_set_color(struct libscols_cell *ce, const char *color) -{ - if (color && isalpha(*color)) { - color = color_sequence_from_colorname(color); - if (!color) - return -EINVAL; - } - return strdup_to_struct_member(ce, color, color); -} - -/** - * scols_cell_get_color: - * @ce: a pointer to a struct libscols_cell instance - * - * Returns: the current color of @ce. - */ -const char *scols_cell_get_color(const struct libscols_cell *ce) -{ - return ce->color; -} - -/** - * scols_cell_set_flags: - * @ce: a pointer to a struct libscols_cell instance - * @flags: SCOLS_CELL_FL_* flags - * - * Note that cells in the table are always aligned by column flags. The cell - * flags are used for table title only (now). - * - * Returns: 0, a negative value in case of an error. - */ -int scols_cell_set_flags(struct libscols_cell *ce, int flags) -{ - if (!ce) - return -EINVAL; - ce->flags = flags; - return 0; -} - -/** - * scols_cell_get_flags: - * @ce: a pointer to a struct libscols_cell instance - * - * Returns: the current flags - */ -int scols_cell_get_flags(const struct libscols_cell *ce) -{ - return ce->flags; -} - -/** - * scols_cell_get_alignment: - * @ce: a pointer to a struct libscols_cell instance - * - * Since: 2.30 - * - * Returns: SCOLS_CELL_FL_{RIGHT,CELNTER,LEFT} - */ -int scols_cell_get_alignment(const struct libscols_cell *ce) -{ - if (ce->flags & SCOLS_CELL_FL_RIGHT) - return SCOLS_CELL_FL_RIGHT; - if (ce->flags & SCOLS_CELL_FL_CENTER) - return SCOLS_CELL_FL_CENTER; - - return SCOLS_CELL_FL_LEFT; /* default */ -} - -/** - * scols_cell_copy_content: - * @dest: a pointer to a struct libscols_cell instance - * @src: a pointer to an immutable struct libscols_cell instance - * - * Copy the contents of @src into @dest. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_cell_copy_content(struct libscols_cell *dest, - const struct libscols_cell *src) -{ - int rc; - - rc = scols_cell_set_data(dest, scols_cell_get_data(src)); - if (!rc) - rc = scols_cell_set_color(dest, scols_cell_get_color(src)); - if (!rc) - dest->userdata = src->userdata; - - DBG(CELL, ul_debugobj(src, "copy")); - return rc; -} diff --git a/utils/libsmartcols/src/column.c b/utils/libsmartcols/src/column.c deleted file mode 100644 index c11df69..0000000 --- a/utils/libsmartcols/src/column.c +++ /dev/null @@ -1,564 +0,0 @@ -/* - * column.c - functions for table handling at the column level - * - * Copyright (C) 2014 Ondrej Oprala <ooprala@redhat.com> - * Copyright (C) 2014 Karel Zak <kzak@redhat.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -/** - * SECTION: column - * @title: Column - * @short_description: defines output columns formats, headers, etc. - * - * An API to access and modify per-column data and information. - */ - - -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <ctype.h> - -#include "mbsalign.h" - -#include "smartcolsP.h" - -/** - * scols_new_column: - * - * Allocates space for a new column. - * - * Returns: a pointer to a new struct libscols_column instance, NULL in case of an ENOMEM error. - */ -struct libscols_column *scols_new_column(void) -{ - struct libscols_column *cl; - - cl = calloc(1, sizeof(*cl)); - if (!cl) - return NULL; - DBG(COL, ul_debugobj(cl, "alloc")); - cl->refcount = 1; - INIT_LIST_HEAD(&cl->cl_columns); - return cl; -} - -/** - * scols_ref_column: - * @cl: a pointer to a struct libscols_column instance - * - * Increases the refcount of @cl. - */ -void scols_ref_column(struct libscols_column *cl) -{ - if (cl) - cl->refcount++; -} - -/** - * scols_unref_column: - * @cl: a pointer to a struct libscols_column instance - * - * Decreases the refcount of @cl. When the count falls to zero, the instance - * is automatically deallocated. - */ -void scols_unref_column(struct libscols_column *cl) -{ - if (cl && --cl->refcount <= 0) { - DBG(COL, ul_debugobj(cl, "dealloc")); - list_del(&cl->cl_columns); - scols_reset_cell(&cl->header); - free(cl->color); - free(cl->safechars); - free(cl->pending_data_buf); - free(cl); - } -} - -/** - * scols_copy_column: - * @cl: a pointer to a struct libscols_column instance - * - * Creates a new column and copies @cl's data over to it. - * - * Returns: a pointer to a new struct libscols_column instance. - */ -struct libscols_column *scols_copy_column(const struct libscols_column *cl) -{ - struct libscols_column *ret; - - if (!cl) - return NULL; - ret = scols_new_column(); - if (!ret) - return NULL; - - DBG(COL, ul_debugobj(cl, "copy")); - - if (scols_column_set_color(ret, cl->color)) - goto err; - if (scols_cell_copy_content(&ret->header, &cl->header)) - goto err; - - ret->width = cl->width; - ret->width_min = cl->width_min; - ret->width_max = cl->width_max; - ret->width_avg = cl->width_avg; - ret->width_hint = cl->width_hint; - ret->flags = cl->flags; - ret->is_extreme = cl->is_extreme; - ret->is_groups = cl->is_groups; - - return ret; -err: - scols_unref_column(ret); - return NULL; -} - -/** - * scols_column_set_whint: - * @cl: a pointer to a struct libscols_column instance - * @whint: a width hint - * - * Sets the width hint of column @cl to @whint. See scols_table_new_column(). - * - * Returns: 0, a negative value in case of an error. - */ -int scols_column_set_whint(struct libscols_column *cl, double whint) -{ - if (!cl) - return -EINVAL; - - cl->width_hint = whint; - return 0; -} - -/** - * scols_column_get_whint: - * @cl: a pointer to a struct libscols_column instance - * - * Returns: The width hint of column @cl, a negative value in case of an error. - */ -double scols_column_get_whint(const struct libscols_column *cl) -{ - return cl->width_hint; -} - -/** - * scols_column_set_flags: - * @cl: a pointer to a struct libscols_column instance - * @flags: a flag mask - * - * Sets the flags of @cl to @flags. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_column_set_flags(struct libscols_column *cl, int flags) -{ - if (!cl) - return -EINVAL; - - if (cl->table) { - if (!(cl->flags & SCOLS_FL_TREE) && (flags & SCOLS_FL_TREE)) - cl->table->ntreecols++; - else if ((cl->flags & SCOLS_FL_TREE) && !(flags & SCOLS_FL_TREE)) - cl->table->ntreecols--; - } - - DBG(COL, ul_debugobj(cl, "setting flags from 0%x to 0%x", cl->flags, flags)); - cl->flags = flags; - return 0; -} - -/** - * scols_column_set_json_type: - * @cl: a pointer to a struct libscols_column instance - * @type: SCOLS_JSON_* type - * - * Sets the type used for JSON formatting, the default is SCOLS_JSON_STRING. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.33 - */ -int scols_column_set_json_type(struct libscols_column *cl, int type) -{ - if (!cl) - return -EINVAL; - - cl->json_type = type; - return 0; - -} - -/** - * scols_column_get_json_type: - * @cl: a pointer to a struct libscols_column instance - * - * Note that SCOLS_JSON_BOOLEAN interprets NULL, empty strings, '0', 'N' and - * 'n' as "false"; and everything else as "true". - * - * Returns: JSON type used for formatting or a negative value in case of an error. - * - * Since: 2.33 - */ -int scols_column_get_json_type(const struct libscols_column *cl) -{ - return cl ? cl->json_type : -EINVAL; -} - - -/** - * scols_column_get_table: - * @cl: a pointer to a struct libscols_column instance - * - * Returns: pointer to the table where columns is used - */ -struct libscols_table *scols_column_get_table(const struct libscols_column *cl) -{ - return cl->table; -} - -/** - * scols_column_get_flags: - * @cl: a pointer to a struct libscols_column instance - * - * Returns: The flag mask of @cl, a negative value in case of an error. - */ -int scols_column_get_flags(const struct libscols_column *cl) -{ - return cl->flags; -} - -/** - * scols_column_get_header: - * @cl: a pointer to a struct libscols_column instance - * - * Returns: A pointer to a struct libscols_cell instance, representing the - * header info of column @cl or NULL in case of an error. - */ -struct libscols_cell *scols_column_get_header(struct libscols_column *cl) -{ - return &cl->header; -} - -/** - * scols_column_set_color: - * @cl: a pointer to a struct libscols_column instance - * @color: color name or ESC sequence - * - * The default color for data cells and column header. - * - * If you want to set header specific color then use scols_column_get_header() - * and scols_cell_set_color(). - * - * If you want to set data cell specific color the use scols_line_get_cell() + - * scols_cell_set_color(). - * - * Returns: 0, a negative value in case of an error. - */ -int scols_column_set_color(struct libscols_column *cl, const char *color) -{ - if (color && isalpha(*color)) { - color = color_sequence_from_colorname(color); - if (!color) - return -EINVAL; - } - return strdup_to_struct_member(cl, color, color); -} - -/** - * scols_column_get_color: - * @cl: a pointer to a struct libscols_column instance - * - * Returns: The current color setting of the column @cl. - */ -const char *scols_column_get_color(const struct libscols_column *cl) -{ - return cl->color; -} - -/** - * scols_wrapnl_nextchunk: - * @cl: a pointer to a struct libscols_column instance - * @data: string - * @userdata: callback private data - * - * This is built-in function for scols_column_set_wrapfunc(). This function - * terminates the current chunk by \0 and returns pointer to the begin of - * the next chunk. The chunks are based on \n. - * - * For example for data "AAA\nBBB\nCCC" the next chunk is "BBB". - * - * Returns: next chunk - * - * Since: 2.29 - */ -char *scols_wrapnl_nextchunk(const struct libscols_column *cl __attribute__((unused)), - char *data, - void *userdata __attribute__((unused))) -{ - char *p = data ? strchr(data, '\n') : NULL; - - if (p) { - *p = '\0'; - return p + 1; - } - return NULL; -} - -/** - * scols_wrapnl_chunksize: - * @cl: a pointer to a struct libscols_column instance - * @data: string - * @userdata: callback private data - * - * Analyzes @data and returns size of the largest chunk. The chunks are based - * on \n. For example for data "AAA\nBBB\nCCCC" the largest chunk size is 4. - * - * Note that the size has to be based on number of terminal cells rather than - * bytes to support multu-byte output. - * - * Returns: size of the largest chunk. - * - * Since: 2.29 - */ -size_t scols_wrapnl_chunksize(const struct libscols_column *cl __attribute__((unused)), - const char *data, - void *userdata __attribute__((unused))) -{ - size_t sum = 0; - - while (data && *data) { - const char *p; - size_t sz; - - p = strchr(data, '\n'); - if (p) { - sz = cl->table && scols_table_is_noencoding(cl->table) ? - mbs_nwidth(data, p - data) : - mbs_safe_nwidth(data, p - data, NULL); - p++; - } else { - sz = cl->table && scols_table_is_noencoding(cl->table) ? - mbs_width(data) : - mbs_safe_width(data); - } - sum = max(sum, sz); - data = p; - } - - return sum; -} - -/** - * scols_column_set_cmpfunc: - * @cl: column - * @cmp: pointer to compare function - * @data: private data for cmp function - * - * Returns: 0, a negative value in case of an error. - */ -int scols_column_set_cmpfunc(struct libscols_column *cl, - int (*cmp)(struct libscols_cell *, - struct libscols_cell *, - void *), - void *data) -{ - if (!cl) - return -EINVAL; - - cl->cmpfunc = cmp; - cl->cmpfunc_data = data; - return 0; -} - -/** - * scols_column_set_wrapfunc: - * @cl: a pointer to a struct libscols_column instance - * @wrap_chunksize: function to return size of the largest chink of data - * @wrap_nextchunk: function to return next zero terminated data - * @userdata: optional stuff for callbacks - * - * Extends SCOLS_FL_WRAP and can be used to set custom wrap function. The default - * is to wrap by column size, but you can create functions to wrap for example - * after \n or after words, etc. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.29 - */ -int scols_column_set_wrapfunc(struct libscols_column *cl, - size_t (*wrap_chunksize)(const struct libscols_column *, - const char *, - void *), - char * (*wrap_nextchunk)(const struct libscols_column *, - char *, - void *), - void *userdata) -{ - if (!cl) - return -EINVAL; - - cl->wrap_nextchunk = wrap_nextchunk; - cl->wrap_chunksize = wrap_chunksize; - cl->wrapfunc_data = userdata; - return 0; -} - -/** - * scols_column_set_safechars: - * @cl: a pointer to a struct libscols_column instance - * @safe: safe characters (e.g. "\n\t") - * - * Use for bytes you don't want to encode on output. This is for example - * necessary if you want to use custom wrap function based on \n, in this case - * you have to set "\n" as a safe char. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.29 - */ -int scols_column_set_safechars(struct libscols_column *cl, const char *safe) -{ - return strdup_to_struct_member(cl, safechars, safe); -} - -/** - * scols_column_get_safechars: - * @cl: a pointer to a struct libscols_column instance - * - * Returns: safe chars - * - * Since: 2.29 - */ -const char *scols_column_get_safechars(const struct libscols_column *cl) -{ - return cl->safechars; -} - -/** - * scols_column_get_width: - * @cl: a pointer to a struct libscols_column instance - * - * Important note: the column width is unknown until library starts printing - * (width is calculated before printing). The function is usable for example in - * nextchunk() callback specified by scols_column_set_wrapfunc(). - * - * See also scols_column_get_whint(), it returns wanted size (!= final size). - * - * Returns: column width - * - * Since: 2.29 - */ -size_t scols_column_get_width(const struct libscols_column *cl) -{ - return cl->width; -} - -/** - * scols_column_is_hidden: - * @cl: a pointer to a struct libscols_column instance - * - * Gets the value of @cl's flag hidden. - * - * Returns: 0 or 1 - * - * Since: 2.27 - */ -int scols_column_is_hidden(const struct libscols_column *cl) -{ - return cl->flags & SCOLS_FL_HIDDEN ? 1 : 0; -} - -/** - * scols_column_is_trunc: - * @cl: a pointer to a struct libscols_column instance - * - * Gets the value of @cl's flag trunc. - * - * Returns: 0 or 1 - */ -int scols_column_is_trunc(const struct libscols_column *cl) -{ - return cl->flags & SCOLS_FL_TRUNC ? 1 : 0; -} -/** - * scols_column_is_tree: - * @cl: a pointer to a struct libscols_column instance - * - * Gets the value of @cl's flag tree. - * - * Returns: 0 or 1 - */ -int scols_column_is_tree(const struct libscols_column *cl) -{ - return cl->flags & SCOLS_FL_TREE ? 1 : 0; -} -/** - * scols_column_is_right: - * @cl: a pointer to a struct libscols_column instance - * - * Gets the value of @cl's flag right. - * - * Returns: 0 or 1 - */ -int scols_column_is_right(const struct libscols_column *cl) -{ - return cl->flags & SCOLS_FL_RIGHT ? 1 : 0; -} -/** - * scols_column_is_strict_width: - * @cl: a pointer to a struct libscols_column instance - * - * Gets the value of @cl's flag strict_width. - * - * Returns: 0 or 1 - */ -int scols_column_is_strict_width(const struct libscols_column *cl) -{ - return cl->flags & SCOLS_FL_STRICTWIDTH ? 1 : 0; -} -/** - * scols_column_is_noextremes: - * @cl: a pointer to a struct libscols_column instance - * - * Gets the value of @cl's flag no_extremes. - * - * Returns: 0 or 1 - */ -int scols_column_is_noextremes(const struct libscols_column *cl) -{ - return cl->flags & SCOLS_FL_NOEXTREMES ? 1 : 0; -} -/** - * scols_column_is_wrap: - * @cl: a pointer to a struct libscols_column instance - * - * Gets the value of @cl's flag wrap. - * - * Returns: 0 or 1 - * - * Since: 2.28 - */ -int scols_column_is_wrap(const struct libscols_column *cl) -{ - return cl->flags & SCOLS_FL_WRAP ? 1 : 0; -} -/** - * scols_column_is_customwrap: - * @cl: a pointer to a struct libscols_column instance - * - * Returns: 0 or 1 - * - * Since: 2.29 - */ -int scols_column_is_customwrap(const struct libscols_column *cl) -{ - return (cl->flags & SCOLS_FL_WRAP) - && cl->wrap_chunksize - && cl->wrap_nextchunk ? 1 : 0; -} diff --git a/utils/libsmartcols/src/fput.c b/utils/libsmartcols/src/fput.c deleted file mode 100644 index b00c3d8..0000000 --- a/utils/libsmartcols/src/fput.c +++ /dev/null @@ -1,97 +0,0 @@ -#include "carefulputc.h" -#include "smartcolsP.h" - -void fput_indent(struct libscols_table *tb) -{ - int i; - - for (i = 0; i <= tb->indent; i++) - fputs(" ", tb->out); -} - -void fput_table_open(struct libscols_table *tb) -{ - tb->indent = 0; - - if (scols_table_is_json(tb)) { - fputc('{', tb->out); - fputs(linesep(tb), tb->out); - - fput_indent(tb); - fputs_quoted(tb->name, tb->out); - fputs(": [", tb->out); - fputs(linesep(tb), tb->out); - - tb->indent++; - tb->indent_last_sep = 1; - } -} - -void fput_table_close(struct libscols_table *tb) -{ - tb->indent--; - - if (scols_table_is_json(tb)) { - fput_indent(tb); - fputc(']', tb->out); - tb->indent--; - fputs(linesep(tb), tb->out); - fputc('}', tb->out); - tb->indent_last_sep = 1; - } -} - -void fput_children_open(struct libscols_table *tb) -{ - if (scols_table_is_json(tb)) { - fputc(',', tb->out); - fputs(linesep(tb), tb->out); - fput_indent(tb); - fputs("\"children\": [", tb->out); - } - /* between parent and child is separator */ - fputs(linesep(tb), tb->out); - tb->indent_last_sep = 1; - tb->indent++; - tb->termlines_used++; -} - -void fput_children_close(struct libscols_table *tb) -{ - tb->indent--; - - if (scols_table_is_json(tb)) { - fput_indent(tb); - fputc(']', tb->out); - fputs(linesep(tb), tb->out); - tb->indent_last_sep = 1; - } -} - -void fput_line_open(struct libscols_table *tb) -{ - if (scols_table_is_json(tb)) { - fput_indent(tb); - fputc('{', tb->out); - tb->indent_last_sep = 0; - } - tb->indent++; -} - -void fput_line_close(struct libscols_table *tb, int last, int last_in_table) -{ - tb->indent--; - if (scols_table_is_json(tb)) { - if (tb->indent_last_sep) - fput_indent(tb); - fputs(last ? "}" : "},", tb->out); - if (!tb->no_linesep) - fputs(linesep(tb), tb->out); - - } else if (tb->no_linesep == 0 && last_in_table == 0) { - fputs(linesep(tb), tb->out); - tb->termlines_used++; - } - - tb->indent_last_sep = 1; -} diff --git a/utils/libsmartcols/src/grouping.c b/utils/libsmartcols/src/grouping.c deleted file mode 100644 index 0b27cb2..0000000 --- a/utils/libsmartcols/src/grouping.c +++ /dev/null @@ -1,575 +0,0 @@ -/* - * Copyright (C) 2018 Karel Zak <kzak@redhat.com> - */ -#include "smartcolsP.h" - -/** - * SECTION: grouping - * @title: Grouping - * @short_description: lines grouing - * - * Lines groups manipulation API. The grouping API can be used to create M:N - * relations between lines and on tree-like output it prints extra chart to - * visualize these relations. The group has unlimited number of members and - * group childs. See libsmartcols/sample/grouping* for more details. - */ - -/* Private API */ -void scols_ref_group(struct libscols_group *gr) -{ - if (gr) - gr->refcount++; -} - -void scols_group_remove_children(struct libscols_group *gr) -{ - if (!gr) - return; - - while (!list_empty(&gr->gr_children)) { - struct libscols_line *ln = list_entry(gr->gr_children.next, - struct libscols_line, ln_children); - - DBG(GROUP, ul_debugobj(gr, "remove child")); - list_del_init(&ln->ln_children); - scols_ref_group(ln->parent_group); - ln->parent_group = NULL; - scols_unref_line(ln); - } -} - -void scols_group_remove_members(struct libscols_group *gr) -{ - if (!gr) - return; - - while (!list_empty(&gr->gr_members)) { - struct libscols_line *ln = list_entry(gr->gr_members.next, - struct libscols_line, ln_groups); - - DBG(GROUP, ul_debugobj(gr, "remove member [%p]", ln)); - list_del_init(&ln->ln_groups); - - scols_unref_group(ln->group); - ln->group->nmembers++; - ln->group = NULL; - - scols_unref_line(ln); - } -} - -/* note group has to be already without members to deallocate */ -void scols_unref_group(struct libscols_group *gr) -{ - if (gr && --gr->refcount <= 0) { - DBG(GROUP, ul_debugobj(gr, "dealloc")); - scols_group_remove_children(gr); - list_del(&gr->gr_groups); - free(gr); - return; - } -} - - -static void groups_fix_members_order(struct libscols_line *ln) -{ - struct libscols_iter itr; - struct libscols_line *child; - - if (ln->group) { - INIT_LIST_HEAD(&ln->ln_groups); - list_add_tail(&ln->ln_groups, &ln->group->gr_members); - DBG(GROUP, ul_debugobj(ln->group, "fixing member line=%p [%zu/%zu]", - ln, ln->group->nmembers, - list_count_entries(&ln->group->gr_members))); - } - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_line_next_child(ln, &itr, &child) == 0) - groups_fix_members_order(child); - - /* - * We modify gr_members list, so is_last_group_member() does not have - * to provide reliable answer, we need to verify by list_count_entries(). - */ - if (ln->group - && is_last_group_member(ln) - && ln->group->nmembers == list_count_entries(&ln->group->gr_members)) { - - DBG(GROUP, ul_debugobj(ln->group, "fixing childs")); - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_line_next_group_child(ln, &itr, &child) == 0) - groups_fix_members_order(child); - } -} - -void scols_groups_fix_members_order(struct libscols_table *tb) -{ - struct libscols_iter itr; - struct libscols_line *ln; - struct libscols_group *gr; - - /* remove all from groups lists */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_group(tb, &itr, &gr) == 0) { - while (!list_empty(&gr->gr_members)) { - struct libscols_line *line = list_entry(gr->gr_members.next, - struct libscols_line, ln_groups); - list_del_init(&line->ln_groups); - } - } - - /* add again to the groups list in order we walk in tree */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_line(tb, &itr, &ln) == 0) { - if (ln->parent || ln->parent_group) - continue; - groups_fix_members_order(ln); - } - - /* If group child is member of another group * - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_group(tb, &itr, &gr) == 0) { - struct libscols_iter xitr; - struct libscols_line *child; - - scols_reset_iter(&xitr, SCOLS_ITER_FORWARD); - while (scols_line_next_group_child(ln, &xitr, &child) == 0) - groups_fix_members_order(child); - } - */ -} - -static inline const char *group_state_to_string(int state) -{ - static const char *grpstates[] = { - [SCOLS_GSTATE_NONE] = "none", - [SCOLS_GSTATE_FIRST_MEMBER] = "1st-member", - [SCOLS_GSTATE_MIDDLE_MEMBER] = "middle-member", - [SCOLS_GSTATE_LAST_MEMBER] = "last-member", - [SCOLS_GSTATE_MIDDLE_CHILD] = "middle-child", - [SCOLS_GSTATE_LAST_CHILD] = "last-child", - [SCOLS_GSTATE_CONT_MEMBERS] = "continue-members", - [SCOLS_GSTATE_CONT_CHILDREN] = "continue-children" - }; - - assert(state >= 0); - assert((size_t) state < ARRAY_SIZE(grpstates)); - - return grpstates[state]; -} -/* -static void grpset_debug(struct libscols_table *tb, struct libscols_line *ln) -{ - size_t i; - - for (i = 0; i < tb->grpset_size; i++) { - if (tb->grpset[i]) { - struct libscols_group *gr = tb->grpset[i]; - - if (ln) - DBG(LINE, ul_debugobj(ln, "grpset[%zu]: %p %s", i, - gr, group_state_to_string(gr->state))); - else - DBG(LINE, ul_debug("grpset[%zu]: %p %s", i, - gr, group_state_to_string(gr->state))); - } else if (ln) { - DBG(LINE, ul_debugobj(ln, "grpset[%zu]: free", i)); - } else - DBG(LINE, ul_debug("grpset[%zu]: free", i)); - } -} -*/ -static int group_state_for_line(struct libscols_group *gr, struct libscols_line *ln) -{ - if (gr->state == SCOLS_GSTATE_NONE && - (ln->group != gr || !is_first_group_member(ln))) - /* - * NONE is possible to translate to FIRST_MEMBER only, and only if - * line group matches with the current group. - */ - return SCOLS_GSTATE_NONE; - - if (ln->group != gr && ln->parent_group != gr) { - /* Not our line, continue */ - if (gr->state == SCOLS_GSTATE_FIRST_MEMBER || - gr->state == SCOLS_GSTATE_MIDDLE_MEMBER || - gr->state == SCOLS_GSTATE_CONT_MEMBERS) - return SCOLS_GSTATE_CONT_MEMBERS; - - if (gr->state == SCOLS_GSTATE_LAST_MEMBER || - gr->state == SCOLS_GSTATE_MIDDLE_CHILD || - gr->state == SCOLS_GSTATE_CONT_CHILDREN) - return SCOLS_GSTATE_CONT_CHILDREN; - - } else if (ln->group == gr && is_first_group_member(ln)) { - return SCOLS_GSTATE_FIRST_MEMBER; - - } else if (ln->group == gr && is_last_group_member(ln)) { - return SCOLS_GSTATE_LAST_MEMBER; - - } else if (ln->group == gr && is_group_member(ln)) { - return SCOLS_GSTATE_MIDDLE_MEMBER; - - } else if (ln->parent_group == gr && is_last_group_child(ln)) { - return SCOLS_GSTATE_LAST_CHILD; - - } else if (ln->parent_group == gr && is_group_child(ln)) { - return SCOLS_GSTATE_MIDDLE_CHILD; - } - - return SCOLS_GSTATE_NONE; -} - -/* - * apply new @state to the chunk (addressed by @xx) of grpset used for the group (@gr) - */ -static void grpset_apply_group_state(struct libscols_group **xx, int state, struct libscols_group *gr) -{ - size_t i; - - DBG(GROUP, ul_debugobj(gr, " applying state to grpset")); - - /* gr->state holds the old state, @state is the new state - */ - for (i = 0; i < SCOLS_GRPSET_CHUNKSIZ; i++) - xx[i] = state == SCOLS_GSTATE_NONE ? NULL : gr; - - gr->state = state; -} - -static struct libscols_group **grpset_locate_freespace(struct libscols_table *tb, int chunks, int prepend) -{ - size_t i, avail = 0; - struct libscols_group **tmp, **first = NULL; - const size_t wanted = chunks * SCOLS_GRPSET_CHUNKSIZ; - - if (!tb->grpset_size) - prepend = 0; - /* - DBG(TAB, ul_debugobj(tb, "orig grpset:")); - grpset_debug(tb, NULL); - */ - if (prepend) { - for (i = tb->grpset_size - 1; ; i--) { - if (tb->grpset[i] == NULL) { - first = &tb->grpset[i]; - avail++; - } else - avail = 0; - if (avail == wanted) - goto done; - if (i == 0) - break; - } - } else { - for (i = 0; i < tb->grpset_size; i++) { - if (tb->grpset[i] == NULL) { - if (avail == 0) - first = &tb->grpset[i]; - avail++; - } else - avail = 0; - if (avail == wanted) - goto done; - } - } - - DBG(TAB, ul_debugobj(tb, " realocate grpset [sz: old=%zu, new=%zu, new_chunks=%d]", - tb->grpset_size, tb->grpset_size + wanted, chunks)); - - tmp = realloc(tb->grpset, (tb->grpset_size + wanted) * sizeof(struct libscols_group *)); - if (!tmp) - return NULL; - - tb->grpset = tmp; - - if (prepend) { - DBG(TAB, ul_debugobj(tb, " prepending free space")); - char *dest = (char *) tb->grpset; - - memmove( dest + (wanted * sizeof(struct libscols_group *)), - tb->grpset, - tb->grpset_size * sizeof(struct libscols_group *)); - first = tb->grpset; - } else { - first = tb->grpset + tb->grpset_size; - } - - memset(first, 0, wanted * sizeof(struct libscols_group *)); - tb->grpset_size += wanted; - -done: - /* - DBG(TAB, ul_debugobj(tb, "new grpset:")); - grpset_debug(tb, NULL); - */ - return first; -} - -static struct libscols_group **grpset_locate_group(struct libscols_table *tb, struct libscols_group *gr) -{ - size_t i; - - for (i = 0; i < tb->grpset_size; i++) { - if (gr == tb->grpset[i]) - return &tb->grpset[i]; - } - - return NULL; -} - - -static int grpset_update(struct libscols_table *tb, struct libscols_line *ln, struct libscols_group *gr) -{ - struct libscols_group **xx; - int state; - - DBG(LINE, ul_debugobj(ln, " group [%p] grpset update [grpset size=%zu]", gr, tb->grpset_size)); - - /* new state, note that gr->state still holds the original state */ - state = group_state_for_line(gr, ln); - DBG(LINE, ul_debugobj(ln, " state %s --> %s", - group_state_to_string(gr->state), - group_state_to_string(state))); - - if (state == SCOLS_GSTATE_FIRST_MEMBER && gr->state != SCOLS_GSTATE_NONE) { - DBG(LINE, ul_debugobj(ln, "wrong group initialization (%s)", group_state_to_string(gr->state))); - abort(); - } - if (state != SCOLS_GSTATE_NONE && gr->state == SCOLS_GSTATE_LAST_CHILD) { - DBG(LINE, ul_debugobj(ln, "wrong group termination (%s)", group_state_to_string(gr->state))); - abort(); - } - if (gr->state == SCOLS_GSTATE_LAST_MEMBER && - !(state == SCOLS_GSTATE_LAST_CHILD || - state == SCOLS_GSTATE_CONT_CHILDREN || - state == SCOLS_GSTATE_MIDDLE_CHILD || - state == SCOLS_GSTATE_NONE)) { - DBG(LINE, ul_debugobj(ln, "wrong group member->child order")); - abort(); - } - - /* should not happen; probably wrong line... */ - if (gr->state == SCOLS_GSTATE_NONE && state == SCOLS_GSTATE_NONE) - return 0; - - /* locate place in grpset where we draw the group */ - if (!tb->grpset || gr->state == SCOLS_GSTATE_NONE) - xx = grpset_locate_freespace(tb, 1, 1); - else - xx = grpset_locate_group(tb, gr); - if (!xx) { - DBG(LINE, ul_debugobj(ln, "failed to locate group or reallocate grpset")); - return -ENOMEM; - } - - grpset_apply_group_state(xx, state, gr); - /*ON_DBG(LINE, grpset_debug(tb, ln));*/ - return 0; -} - -static int grpset_update_active_groups(struct libscols_table *tb, struct libscols_line *ln) -{ - int rc = 0; - size_t i; - struct libscols_group *last = NULL; - - DBG(LINE, ul_debugobj(ln, " update for active groups")); - - for (i = 0; i < tb->grpset_size; i++) { - struct libscols_group *gr = tb->grpset[i]; - - if (!gr || last == gr) - continue; - last = gr; - rc = grpset_update(tb, ln, gr); - if (rc) - break; - } - - DBG(LINE, ul_debugobj(ln, " <- active groups updated [rc=%d]", rc)); - return rc; -} - -int scols_groups_update_grpset(struct libscols_table *tb, struct libscols_line *ln) -{ - int rc = 0; - - DBG(LINE, ul_debugobj(ln, " grpset update [line: group=%p, parent_group=%p", - ln->group, ln->parent_group)); - - rc = grpset_update_active_groups(tb, ln); - if (!rc && ln->group && ln->group->state == SCOLS_GSTATE_NONE) { - DBG(LINE, ul_debugobj(ln, " introduce a new group")); - rc = grpset_update(tb, ln, ln->group); - } - return rc; -} - -void scols_groups_reset_state(struct libscols_table *tb) -{ - struct libscols_iter itr; - struct libscols_group *gr; - - DBG(TAB, ul_debugobj(tb, "reset groups states")); - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_group(tb, &itr, &gr) == 0) { - DBG(GROUP, ul_debugobj(gr, " reset to NONE")); - gr->state = SCOLS_GSTATE_NONE; - } - - if (tb->grpset) { - DBG(TAB, ul_debugobj(tb, " zeroize grpset")); - memset(tb->grpset, 0, tb->grpset_size * sizeof(struct libscols_group *)); - } - tb->ngrpchlds_pending = 0; -} - -static void add_member(struct libscols_group *gr, struct libscols_line *ln) -{ - DBG(GROUP, ul_debugobj(gr, "add member %p", ln)); - - ln->group = gr; - gr->nmembers++; - scols_ref_group(gr); - - INIT_LIST_HEAD(&ln->ln_groups); - list_add_tail(&ln->ln_groups, &gr->gr_members); - scols_ref_line(ln); -} - -/* - * Returns first group which is ready to print group children. - * - * This function scans grpset[] in backward order and returns first group - * with SCOLS_GSTATE_CONT_CHILDREN or SCOLS_GSTATE_LAST_MEMBER state. - */ -struct libscols_group *scols_grpset_get_printable_children(struct libscols_table *tb) -{ - size_t i; - - for (i = tb->grpset_size; i > 0; i -= SCOLS_GRPSET_CHUNKSIZ) { - struct libscols_group *gr = tb->grpset[i-1]; - - if (gr == NULL) - continue; - if (gr->state == SCOLS_GSTATE_CONT_CHILDREN || - gr->state == SCOLS_GSTATE_LAST_MEMBER) - return gr; - } - - return NULL; -} - - -/** - * scols_table_group_lines: - * @tb: a pointer to a struct libscols_table instance - * @ln: new group member - * @member: group member - * @id: group identifier (unused, not implemented yet), use zero. - * - * This function add line @ln to group of lines represented by @member. If the - * group is not yet defined (@member is not member of any group) than a new one - * is allocated. - * - * The @ln maybe a NULL -- in this case only a new group is allocated if not - * defined yet. - * - * Note that the same line cannot be member of more groups (not implemented - * yet). The child of any group can be member of another group. - * - * The @id is not used for now, use 0. The plan is to use it to support - * multi-group membership in future. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.34 - */ -int scols_table_group_lines( struct libscols_table *tb, - struct libscols_line *ln, - struct libscols_line *member, - __attribute__((__unused__)) int id) -{ - struct libscols_group *gr = NULL; - - if (!tb || !member) { - DBG(GROUP, ul_debugobj(gr, "failed group lines (no table or member)")); - return -EINVAL; - } - if (ln) { - if (ln->group && !member->group) { - DBG(GROUP, ul_debugobj(gr, "failed group lines (new group, line member of another)")); - return -EINVAL; - } - if (ln->group && member->group && ln->group != member->group) { - DBG(GROUP, ul_debugobj(gr, "failed group lines (groups mismatch bwteen member and line")); - return -EINVAL; - } - } - - gr = member->group; - - /* create a new group */ - if (!gr) { - gr = calloc(1, sizeof(*gr)); - if (!gr) - return -ENOMEM; - DBG(GROUP, ul_debugobj(gr, "alloc")); - gr->refcount = 1; - INIT_LIST_HEAD(&gr->gr_members); - INIT_LIST_HEAD(&gr->gr_children); - INIT_LIST_HEAD(&gr->gr_groups); - - /* add group to the table */ - list_add_tail(&gr->gr_groups, &tb->tb_groups); - - /* add the first member */ - add_member(gr, member); - } - - /* add to group */ - if (ln && !ln->group) - add_member(gr, ln); - - return 0; -} - -/** - * scols_line_link_group: - * @ln: line instance - * @member: group member - * @id: group identifier (unused, not implemented yet)) - * - * Define @ln as child of group represented by group @member. The line @ln - * cannot be child of any other line. It's possible to create group->child or - * parent->child relationship, but no both for the same line (child). - * - * The @id is not used for now, use 0. The plan is to use it to support - * multi-group membership in future. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.34 - */ -int scols_line_link_group(struct libscols_line *ln, struct libscols_line *member, - __attribute__((__unused__)) int id) -{ - if (!ln || !member || !member->group || ln->parent) - return -EINVAL; - - if (!list_empty(&ln->ln_children)) - return -EINVAL; - - DBG(GROUP, ul_debugobj(member->group, "add child")); - - list_add_tail(&ln->ln_children, &member->group->gr_children); - scols_ref_line(ln); - - ln->parent_group = member->group; - scols_ref_group(member->group); - - return 0; -} diff --git a/utils/libsmartcols/src/init.c b/utils/libsmartcols/src/init.c deleted file mode 100644 index dfd7510..0000000 --- a/utils/libsmartcols/src/init.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2014 Karel Zak <kzak@redhat.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -/** - * SECTION: init - * @title: Library initialization - * @short_description: initialize debugging - * - * The library debug stuff. - */ - -#include <stdarg.h> - -#include "smartcolsP.h" - -UL_DEBUG_DEFINE_MASK(libsmartcols); -UL_DEBUG_DEFINE_MASKNAMES(libsmartcols) = -{ - { "all", SCOLS_DEBUG_ALL, "info about all subsystems" }, - { "buff", SCOLS_DEBUG_BUFF, "output buffer utils" }, - { "cell", SCOLS_DEBUG_CELL, "table cell utils" }, - { "col", SCOLS_DEBUG_COL, "cols utils" }, - { "help", SCOLS_DEBUG_HELP, "this help" }, - { "group", SCOLS_DEBUG_GROUP, "lines grouping utils" }, - { "line", SCOLS_DEBUG_LINE, "table line utils" }, - { "tab", SCOLS_DEBUG_TAB, "table utils" }, - { NULL, 0, NULL } -}; - -/** - * scols_init_debug: - * @mask: debug mask (0xffff to enable full debugging) - * - * If the @mask is not specified, then this function reads - * the LIBSMARTCOLS_DEBUG environment variable to get the mask. - * - * Already initialized debugging stuff cannot be changed. Calling - * this function twice has no effect. - */ -void scols_init_debug(int mask) -{ - if (libsmartcols_debug_mask) - return; - - __UL_INIT_DEBUG_FROM_ENV(libsmartcols, SCOLS_DEBUG_, mask, LIBSMARTCOLS_DEBUG); - - if (libsmartcols_debug_mask != SCOLS_DEBUG_INIT - && libsmartcols_debug_mask != (SCOLS_DEBUG_HELP|SCOLS_DEBUG_INIT)) { - const char *ver = NULL; - - scols_get_library_version(&ver); - - DBG(INIT, ul_debug("library debug mask: 0x%04x", libsmartcols_debug_mask)); - DBG(INIT, ul_debug("library version: %s", ver)); - } - ON_DBG(HELP, ul_debug_print_masks("LIBSMARTCOLS_DEBUG", - UL_DEBUG_MASKNAMES(libsmartcols))); -} diff --git a/utils/libsmartcols/src/iter.c b/utils/libsmartcols/src/iter.c deleted file mode 100644 index 91cc080..0000000 --- a/utils/libsmartcols/src/iter.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2009-2014 Karel Zak <kzak@redhat.com> - * Copyright (C) 2014 Ondrej Oprala <ooprala@redhat.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -/** - * SECTION: iter - * @title: Iterator - * @short_description: unified iterator - * - * The iterator keeps the direction and the last position - * for access to the internal library tables/lists. - */ - -#include <string.h> -#include <stdlib.h> - -#include "smartcolsP.h" - -/** - * scols_new_iter: - * @direction: SCOLS_INTER_{FOR,BACK}WARD direction - * - * Returns: newly allocated generic libmount iterator. - */ -struct libscols_iter *scols_new_iter(int direction) -{ - struct libscols_iter *itr = calloc(1, sizeof(*itr)); - if (!itr) - return NULL; - itr->direction = direction; - return itr; -} - -/** - * scols_free_iter: - * @itr: iterator pointer - * - * Deallocates the iterator. - */ -void scols_free_iter(struct libscols_iter *itr) -{ - free(itr); -} - -/** - * scols_reset_iter: - * @itr: iterator pointer - * @direction: SCOLS_INTER_{FOR,BACK}WARD or -1 to keep the direction unchanged - * - * Resets the iterator. - */ -void scols_reset_iter(struct libscols_iter *itr, int direction) -{ - if (direction == -1) - direction = itr->direction; - - memset(itr, 0, sizeof(*itr)); - itr->direction = direction; -} - -/** - * scols_iter_get_direction: - * @itr: iterator pointer - * - * Returns: SCOLS_INTER_{FOR,BACK}WARD - */ -int scols_iter_get_direction(const struct libscols_iter *itr) -{ - return itr->direction; -} diff --git a/utils/libsmartcols/src/libsmartcols.h b/utils/libsmartcols/src/libsmartcols.h deleted file mode 100644 index 5714bfa..0000000 --- a/utils/libsmartcols/src/libsmartcols.h +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Prints table or tree. - * - * Copyright (C) 2014 Ondrej Oprala <ooprala@redhat.com> - * Copyright (C) 2014 Karel Zak <kzak@redhat.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#ifndef _LIBSMARTCOLS_H -#define _LIBSMARTCOLS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stdlib.h> -#include <stdio.h> -#include <sys/types.h> - -/** - * libscols_iter: - * - * Generic iterator - */ -struct libscols_iter; - -/** - * libscols_symbols: - * - * Symbol groups for printing tree hierarchies - */ -struct libscols_symbols; - -/** - * libscols_cell: - * - * A cell - the smallest library object - */ -struct libscols_cell; - -/** - * libscols_line: - * - * A line - an array of cells - */ -struct libscols_line; - -/** - * libscols_table: - * - * A table - The most abstract object, encapsulating lines, columns, symbols and cells - */ -struct libscols_table; - -/** - * libscols_column: - * - * A column - defines the number of columns and column names - */ -struct libscols_column; - -/* iter.c */ -enum { - - SCOLS_ITER_FORWARD = 0, - SCOLS_ITER_BACKWARD -}; - -/* - * Column flags - */ -enum { - SCOLS_FL_TRUNC = (1 << 0), /* truncate fields data if necessary */ - SCOLS_FL_TREE = (1 << 1), /* use tree "ascii art" */ - SCOLS_FL_RIGHT = (1 << 2), /* align to the right */ - SCOLS_FL_STRICTWIDTH = (1 << 3), /* don't reduce width if column is empty */ - SCOLS_FL_NOEXTREMES = (1 << 4), /* ignore extreme fields when count column width*/ - SCOLS_FL_HIDDEN = (1 << 5), /* maintain data, but don't print */ - SCOLS_FL_WRAP = (1 << 6) /* wrap long lines to multi-line cells */ -}; - -/* - * Column JSON types - */ -enum { - SCOLS_JSON_STRING = 0, /* default */ - SCOLS_JSON_NUMBER = 1, - SCOLS_JSON_BOOLEAN = 2 -}; - -/* - * Cell flags, see scols_cell_set_flags() before use - */ -enum { - /* alignment evaluated in order: right,center,left */ - SCOLS_CELL_FL_LEFT = 0, - SCOLS_CELL_FL_CENTER = (1 << 0), - SCOLS_CELL_FL_RIGHT = (1 << 1) -}; - -extern struct libscols_iter *scols_new_iter(int direction); -extern void scols_free_iter(struct libscols_iter *itr); -extern void scols_reset_iter(struct libscols_iter *itr, int direction); -extern int scols_iter_get_direction(const struct libscols_iter *itr); - -/* init.c */ -extern void scols_init_debug(int mask); - -/* version.c */ -extern int scols_parse_version_string(const char *ver_string); -extern int scols_get_library_version(const char **ver_string); - -/* symbols.c */ -extern struct libscols_symbols *scols_new_symbols(void); -extern void scols_ref_symbols(struct libscols_symbols *sy); -extern void scols_unref_symbols(struct libscols_symbols *sy); -extern struct libscols_symbols *scols_copy_symbols(const struct libscols_symbols *sy); -extern int scols_symbols_set_branch(struct libscols_symbols *sy, const char *str); -extern int scols_symbols_set_vertical(struct libscols_symbols *sy, const char *str); -extern int scols_symbols_set_right(struct libscols_symbols *sy, const char *str); -extern int scols_symbols_set_title_padding(struct libscols_symbols *sy, const char *str); -extern int scols_symbols_set_cell_padding(struct libscols_symbols *sy, const char *str); - -extern int scols_symbols_set_group_vertical(struct libscols_symbols *sy, const char *str); -extern int scols_symbols_set_group_horizontal(struct libscols_symbols *sy, const char *str); -extern int scols_symbols_set_group_first_member(struct libscols_symbols *sy, const char *str); -extern int scols_symbols_set_group_last_member(struct libscols_symbols *sy, const char *str); -extern int scols_symbols_set_group_middle_member(struct libscols_symbols *sy, const char *str); -extern int scols_symbols_set_group_last_child(struct libscols_symbols *sy, const char *str); -extern int scols_symbols_set_group_middle_child(struct libscols_symbols *sy, const char *str); - -/* cell.c */ -extern int scols_reset_cell(struct libscols_cell *ce); -extern int scols_cell_copy_content(struct libscols_cell *dest, - const struct libscols_cell *src); -extern int scols_cell_set_data(struct libscols_cell *ce, const char *data); -extern int scols_cell_refer_data(struct libscols_cell *ce, char *data); -extern const char *scols_cell_get_data(const struct libscols_cell *ce); -extern int scols_cell_set_color(struct libscols_cell *ce, const char *color); -extern const char *scols_cell_get_color(const struct libscols_cell *ce); - -extern int scols_cell_set_flags(struct libscols_cell *ce, int flags); -extern int scols_cell_get_flags(const struct libscols_cell *ce); -extern int scols_cell_get_alignment(const struct libscols_cell *ce); - -extern void *scols_cell_get_userdata(struct libscols_cell *ce); -extern int scols_cell_set_userdata(struct libscols_cell *ce, void *data); - -extern int scols_cmpstr_cells(struct libscols_cell *a, - struct libscols_cell *b, void *data); -/* column.c */ -extern int scols_column_is_tree(const struct libscols_column *cl); -extern int scols_column_is_trunc(const struct libscols_column *cl); -extern int scols_column_is_right(const struct libscols_column *cl); -extern int scols_column_is_strict_width(const struct libscols_column *cl); -extern int scols_column_is_hidden(const struct libscols_column *cl); -extern int scols_column_is_noextremes(const struct libscols_column *cl); -extern int scols_column_is_wrap(const struct libscols_column *cl); -extern int scols_column_is_customwrap(const struct libscols_column *cl); - -extern size_t scols_column_get_width(const struct libscols_column *cl); - -extern int scols_column_set_safechars(struct libscols_column *cl, const char *safe); -extern const char *scols_column_get_safechars(const struct libscols_column *cl); - -extern int scols_column_set_json_type(struct libscols_column *cl, int type); -extern int scols_column_get_json_type(const struct libscols_column *cl); - -extern int scols_column_set_flags(struct libscols_column *cl, int flags); -extern int scols_column_get_flags(const struct libscols_column *cl); -extern struct libscols_column *scols_new_column(void); -extern void scols_ref_column(struct libscols_column *cl); -extern void scols_unref_column(struct libscols_column *cl); -extern struct libscols_column *scols_copy_column(const struct libscols_column *cl); -extern int scols_column_set_whint(struct libscols_column *cl, double whint); -extern double scols_column_get_whint(const struct libscols_column *cl); -extern struct libscols_cell *scols_column_get_header(struct libscols_column *cl); -extern int scols_column_set_color(struct libscols_column *cl, const char *color); -extern const char *scols_column_get_color(const struct libscols_column *cl); -extern struct libscols_table *scols_column_get_table(const struct libscols_column *cl); - -extern int scols_column_set_cmpfunc(struct libscols_column *cl, - int (*cmp)(struct libscols_cell *a, - struct libscols_cell *b, void *), - void *data); - -extern int scols_column_set_wrapfunc(struct libscols_column *cl, - size_t (*wrap_chunksize)(const struct libscols_column *, - const char *, void *), - char * (*wrap_nextchunk)(const struct libscols_column *, - char *, void *), - void *userdata); - -extern char *scols_wrapnl_nextchunk(const struct libscols_column *cl, char *data, void *userdata); -extern size_t scols_wrapnl_chunksize(const struct libscols_column *cl, const char *data, void *userdata); - -/* line.c */ -extern struct libscols_line *scols_new_line(void); -extern void scols_ref_line(struct libscols_line *ln); -extern void scols_unref_line(struct libscols_line *ln); -extern int scols_line_alloc_cells(struct libscols_line *ln, size_t n); -extern void scols_line_free_cells(struct libscols_line *ln); -extern int scols_line_set_userdata(struct libscols_line *ln, void *data); -extern void *scols_line_get_userdata(struct libscols_line *ln); -extern int scols_line_remove_child(struct libscols_line *ln, struct libscols_line *child); -extern int scols_line_add_child(struct libscols_line *ln, struct libscols_line *child); -extern int scols_line_has_children(struct libscols_line *ln); -extern int scols_line_is_ancestor(struct libscols_line *ln, struct libscols_line *parent); -extern int scols_line_next_child(struct libscols_line *ln, - struct libscols_iter *itr, struct libscols_line **chld); -extern struct libscols_line *scols_line_get_parent(const struct libscols_line *ln); -extern int scols_line_set_color(struct libscols_line *ln, const char *color); -extern const char *scols_line_get_color(const struct libscols_line *ln); -extern size_t scols_line_get_ncells(const struct libscols_line *ln); -extern struct libscols_cell *scols_line_get_cell(struct libscols_line *ln, size_t n); -extern struct libscols_cell *scols_line_get_column_cell( - struct libscols_line *ln, - struct libscols_column *cl); -extern int scols_line_set_data(struct libscols_line *ln, size_t n, const char *data); -extern int scols_line_refer_data(struct libscols_line *ln, size_t n, char *data); -extern int scols_line_set_column_data(struct libscols_line *ln, struct libscols_column *cl, const char *data); -extern int scols_line_refer_column_data(struct libscols_line *ln, struct libscols_column *cl, char *data); -extern struct libscols_line *scols_copy_line(const struct libscols_line *ln); - -/* table */ -extern int scols_table_colors_wanted(const struct libscols_table *tb); -extern int scols_table_set_name(struct libscols_table *tb, const char *name); -extern const char *scols_table_get_name(const struct libscols_table *tb); -extern struct libscols_cell *scols_table_get_title(struct libscols_table *tb); -extern int scols_table_is_raw(const struct libscols_table *tb); -extern int scols_table_is_ascii(const struct libscols_table *tb); -extern int scols_table_is_json(const struct libscols_table *tb); -extern int scols_table_is_noheadings(const struct libscols_table *tb); -extern int scols_table_is_header_repeat(const struct libscols_table *tb); -extern int scols_table_is_empty(const struct libscols_table *tb); -extern int scols_table_is_export(const struct libscols_table *tb); -extern int scols_table_is_maxout(const struct libscols_table *tb); -extern int scols_table_is_minout(const struct libscols_table *tb); -extern int scols_table_is_nowrap(const struct libscols_table *tb); -extern int scols_table_is_nolinesep(const struct libscols_table *tb); -extern int scols_table_is_tree(const struct libscols_table *tb); -extern int scols_table_is_noencoding(const struct libscols_table *tb); - -extern int scols_table_enable_colors(struct libscols_table *tb, int enable); -extern int scols_table_enable_raw(struct libscols_table *tb, int enable); -extern int scols_table_enable_ascii(struct libscols_table *tb, int enable); -extern int scols_table_enable_json(struct libscols_table *tb, int enable); -extern int scols_table_enable_noheadings(struct libscols_table *tb, int enable); -extern int scols_table_enable_header_repeat(struct libscols_table *tb, int enable); -extern int scols_table_enable_export(struct libscols_table *tb, int enable); -extern int scols_table_enable_maxout(struct libscols_table *tb, int enable); -extern int scols_table_enable_minout(struct libscols_table *tb, int enable); -extern int scols_table_enable_nowrap(struct libscols_table *tb, int enable); -extern int scols_table_enable_nolinesep(struct libscols_table *tb, int enable); -extern int scols_table_enable_noencoding(struct libscols_table *tb, int enable); - -extern int scols_table_set_column_separator(struct libscols_table *tb, const char *sep); -extern int scols_table_set_line_separator(struct libscols_table *tb, const char *sep); - -extern struct libscols_table *scols_new_table(void); -extern void scols_ref_table(struct libscols_table *tb); -extern void scols_unref_table(struct libscols_table *tb); -extern int scols_table_add_column(struct libscols_table *tb, struct libscols_column *cl); -extern int scols_table_remove_column(struct libscols_table *tb, struct libscols_column *cl); -extern int scols_table_remove_columns(struct libscols_table *tb); -extern int scols_table_move_column(struct libscols_table *tb, struct libscols_column *pre, struct libscols_column *cl); -extern struct libscols_column *scols_table_new_column(struct libscols_table *tb, const char *name, double whint, int flags); -extern int scols_table_next_column(struct libscols_table *tb, struct libscols_iter *itr, struct libscols_column **cl); -extern int scols_table_set_columns_iter(struct libscols_table *tb, struct libscols_iter *itr, struct libscols_column *cl); -extern const char *scols_table_get_column_separator(const struct libscols_table *tb); -extern const char *scols_table_get_line_separator(const struct libscols_table *tb); -extern size_t scols_table_get_ncols(const struct libscols_table *tb); -extern size_t scols_table_get_nlines(const struct libscols_table *tb); -extern struct libscols_column *scols_table_get_column(struct libscols_table *tb, size_t n); -extern int scols_table_add_line(struct libscols_table *tb, struct libscols_line *ln); -extern int scols_table_remove_line(struct libscols_table *tb, struct libscols_line *ln); -extern void scols_table_remove_lines(struct libscols_table *tb); -extern int scols_table_next_line(struct libscols_table *tb, struct libscols_iter *itr, struct libscols_line **ln); -extern struct libscols_line *scols_table_new_line(struct libscols_table *tb, struct libscols_line *parent); -extern struct libscols_line *scols_table_get_line(struct libscols_table *tb, size_t n); -extern struct libscols_table *scols_copy_table(struct libscols_table *tb); -extern int scols_table_set_symbols(struct libscols_table *tb, struct libscols_symbols *sy); -extern int scols_table_set_default_symbols(struct libscols_table *tb); -extern struct libscols_symbols *scols_table_get_symbols(const struct libscols_table *tb); - -extern int scols_table_set_stream(struct libscols_table *tb, FILE *stream); -extern FILE *scols_table_get_stream(const struct libscols_table *tb); -extern int scols_table_reduce_termwidth(struct libscols_table *tb, size_t reduce); - -extern int scols_sort_table(struct libscols_table *tb, struct libscols_column *cl); -extern int scols_sort_table_by_tree(struct libscols_table *tb); -/* - * - */ -enum { - SCOLS_TERMFORCE_AUTO = 0, - SCOLS_TERMFORCE_NEVER, - SCOLS_TERMFORCE_ALWAYS -}; -extern int scols_table_set_termforce(struct libscols_table *tb, int force); -extern int scols_table_get_termforce(const struct libscols_table *tb); -extern int scols_table_set_termwidth(struct libscols_table *tb, size_t width); -extern size_t scols_table_get_termwidth(const struct libscols_table *tb); -extern int scols_table_set_termheight(struct libscols_table *tb, size_t height); -extern size_t scols_table_get_termheight(const struct libscols_table *tb); - - -/* table_print.c */ -extern int scols_print_table(struct libscols_table *tb); -extern int scols_print_table_to_string(struct libscols_table *tb, char **data); - -extern int scols_table_print_range( struct libscols_table *tb, - struct libscols_line *start, - struct libscols_line *end); -extern int scols_table_print_range_to_string( struct libscols_table *tb, - struct libscols_line *start, - struct libscols_line *end, - char **data); - -/* grouping.c */ -int scols_line_link_group(struct libscols_line *ln, struct libscols_line *member, int id); -int scols_table_group_lines(struct libscols_table *tb, struct libscols_line *ln, - struct libscols_line *member, int id); -#ifdef __cplusplus -} -#endif - -#endif /* _LIBSMARTCOLS_H */ diff --git a/utils/libsmartcols/src/line.c b/utils/libsmartcols/src/line.c deleted file mode 100644 index 351bed7..0000000 --- a/utils/libsmartcols/src/line.c +++ /dev/null @@ -1,540 +0,0 @@ -/* - * line.c - functions for table handling at the line level - * - * Copyright (C) 2014 Karel Zak <kzak@redhat.com> - * Copyright (C) 2014 Ondrej Oprala <ooprala@redhat.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -/** - * SECTION: line - * @title: Line - * @short_description: cells container, also keeps tree (parent->child) information - * - * An API to access and modify per-line data and information. - */ - - -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <ctype.h> - -#include "smartcolsP.h" - -/** - * scols_new_line: - * - * Note that the line is allocated without cells, the cells will be allocated - * later when you add the line to the table. If you want to use the line - * without table then you have to explicitly allocate the cells by - * scols_line_alloc_cells(). - * - * Returns: a pointer to a new struct libscols_line instance. - */ -struct libscols_line *scols_new_line(void) -{ - struct libscols_line *ln; - - ln = calloc(1, sizeof(*ln)); - if (!ln) - return NULL; - - DBG(LINE, ul_debugobj(ln, "alloc")); - ln->refcount = 1; - INIT_LIST_HEAD(&ln->ln_lines); - INIT_LIST_HEAD(&ln->ln_children); - INIT_LIST_HEAD(&ln->ln_branch); - INIT_LIST_HEAD(&ln->ln_groups); - return ln; -} - -/** - * scols_ref_line: - * @ln: a pointer to a struct libscols_line instance - * - * Increases the refcount of @ln. - */ -void scols_ref_line(struct libscols_line *ln) -{ - if (ln) - ln->refcount++; -} - -/** - * scols_unref_line: - * @ln: a pointer to a struct libscols_line instance - * - * Decreases the refcount of @ln. When the count falls to zero, the instance - * is automatically deallocated. - */ -void scols_unref_line(struct libscols_line *ln) -{ - if (ln && --ln->refcount <= 0) { - DBG(CELL, ul_debugobj(ln, "dealloc")); - list_del(&ln->ln_lines); - list_del(&ln->ln_children); - list_del(&ln->ln_groups); - scols_unref_group(ln->group); - scols_line_free_cells(ln); - free(ln->color); - free(ln); - return; - } -} - -/** - * scols_line_free_cells: - * @ln: a pointer to a struct libscols_line instance - * - * Frees the allocated cells referenced to by @ln. - */ -void scols_line_free_cells(struct libscols_line *ln) -{ - size_t i; - - if (!ln || !ln->cells) - return; - - DBG(LINE, ul_debugobj(ln, "free cells")); - - for (i = 0; i < ln->ncells; i++) - scols_reset_cell(&ln->cells[i]); - - free(ln->cells); - ln->ncells = 0; - ln->cells = NULL; -} - -/** - * scols_line_alloc_cells: - * @ln: a pointer to a struct libscols_line instance - * @n: the number of elements - * - * Allocates space for @n cells. This function is optional, - * and libsmartcols automatically allocates necessary cells - * according to number of columns in the table when you add - * the line to the table. See scols_table_add_line(). - * - * Returns: 0, a negative value in case of an error. - */ -int scols_line_alloc_cells(struct libscols_line *ln, size_t n) -{ - struct libscols_cell *ce; - - if (!ln) - return -EINVAL; - if (ln->ncells == n) - return 0; - - if (!n) { - scols_line_free_cells(ln); - return 0; - } - - DBG(LINE, ul_debugobj(ln, "alloc %zu cells", n)); - - ce = realloc(ln->cells, n * sizeof(struct libscols_cell)); - if (!ce) - return -errno; - - if (n > ln->ncells) - memset(ce + ln->ncells, 0, - (n - ln->ncells) * sizeof(struct libscols_cell)); - - ln->cells = ce; - ln->ncells = n; - return 0; -} - -int scols_line_move_cells(struct libscols_line *ln, size_t newn, size_t oldn) -{ - struct libscols_cell ce; - - if (!ln || newn >= ln->ncells || oldn >= ln->ncells) - return -EINVAL; - if (oldn == newn) - return 0; - - DBG(LINE, ul_debugobj(ln, "move cells[%zu] -> cells[%zu]", oldn, newn)); - - /* remember data from old position */ - memcpy(&ce, &ln->cells[oldn], sizeof(struct libscols_cell)); - - /* remove old position (move data behind oldn to oldn) */ - if (oldn + 1 < ln->ncells) - memmove(ln->cells + oldn, ln->cells + oldn + 1, - (ln->ncells - oldn - 1) * sizeof(struct libscols_cell)); - - /* create a space for new position */ - if (newn + 1 < ln->ncells) - memmove(ln->cells + newn + 1, ln->cells + newn, - (ln->ncells - newn - 1) * sizeof(struct libscols_cell)); - - /* copy original data to new position */ - memcpy(&ln->cells[newn], &ce, sizeof(struct libscols_cell)); - return 0; -} - -/** - * scols_line_set_userdata: - * @ln: a pointer to a struct libscols_line instance - * @data: user data - * - * Binds @data to @ln. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_line_set_userdata(struct libscols_line *ln, void *data) -{ - if (!ln) - return -EINVAL; - ln->userdata = data; - return 0; -} - -/** - * scols_line_get_userdata: - * @ln: a pointer to a struct libscols_line instance - * - * Returns: user data - */ -void *scols_line_get_userdata(struct libscols_line *ln) -{ - return ln->userdata; -} - -/** - * scols_line_remove_child: - * @ln: a pointer to a struct libscols_line instance - * @child: a pointer to a struct libscols_line instance - * - * Removes @child as a child of @ln. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_line_remove_child(struct libscols_line *ln, struct libscols_line *child) -{ - if (!ln || !child) - return -EINVAL; - - DBG(LINE, ul_debugobj(ln, "remove child")); - - list_del_init(&child->ln_children); - child->parent = NULL; - scols_unref_line(child); - - scols_unref_line(ln); - return 0; -} - -/** - * scols_line_add_child: - * @ln: a pointer to a struct libscols_line instance - * @child: a pointer to a struct libscols_line instance - * - * Sets @child as a child of @ln. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_line_add_child(struct libscols_line *ln, struct libscols_line *child) -{ - if (!ln || !child) - return -EINVAL; - - DBG(LINE, ul_debugobj(ln, "add child")); - scols_ref_line(child); - scols_ref_line(ln); - - /* unref old<->parent */ - if (child->parent) - scols_line_remove_child(child->parent, child); - - /* new reference from parent to child */ - list_add_tail(&child->ln_children, &ln->ln_branch); - - /* new reference from child to parent */ - child->parent = ln; - return 0; -} - -/** - * scols_line_get_parent: - * @ln: a pointer to a struct libscols_line instance - * - * Returns: a pointer to @ln's parent, NULL in case it has no parent or if there was an error. - */ -struct libscols_line *scols_line_get_parent(const struct libscols_line *ln) -{ - return ln ? ln->parent : NULL; -} - -/** - * scols_line_has_children: - * @ln: a pointer to a struct libscols_line instance - * - * Returns: 1 if @ln has any children, otherwise 0. - */ -int scols_line_has_children(struct libscols_line *ln) -{ - return ln ? !list_empty(&ln->ln_branch) : 0; -} - -/** - * scols_line_next_child: - * @ln: a pointer to a struct libscols_line instance - * @itr: a pointer to a struct libscols_iter instance - * @chld: a pointer to a pointer to a struct libscols_line instance - * - * Finds the next child and returns a pointer to it via @chld. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_line_next_child(struct libscols_line *ln, - struct libscols_iter *itr, - struct libscols_line **chld) -{ - int rc = 1; - - if (!ln || !itr || !chld) - return -EINVAL; - *chld = NULL; - - if (!itr->head) - SCOLS_ITER_INIT(itr, &ln->ln_branch); - if (itr->p != itr->head) { - SCOLS_ITER_ITERATE(itr, *chld, struct libscols_line, ln_children); - rc = 0; - } - - return rc; -} - -/* private API */ -int scols_line_next_group_child(struct libscols_line *ln, - struct libscols_iter *itr, - struct libscols_line **chld) -{ - int rc = 1; - - if (!ln || !itr || !chld || !ln->group) - return -EINVAL; - *chld = NULL; - - if (!itr->head) - SCOLS_ITER_INIT(itr, &ln->group->gr_children); - if (itr->p != itr->head) { - SCOLS_ITER_ITERATE(itr, *chld, struct libscols_line, ln_children); - rc = 0; - } - - return rc; -} - -/** - * scols_line_is_ancestor: - * @ln: line - * @parent: potential parent - * - * The function is designed to detect circular dependencies between @ln and - * @parent. It checks if @ln is not any (grand) parent in the @parent's tree. - * - * Since: 2.30 - * - * Returns: 0 or 1 - */ -int scols_line_is_ancestor(struct libscols_line *ln, struct libscols_line *parent) -{ - while (parent) { - if (parent == ln) - return 1; - parent = scols_line_get_parent(parent); - }; - return 0; -} - -/** - * scols_line_set_color: - * @ln: a pointer to a struct libscols_line instance - * @color: color name or ESC sequence - * - * Returns: 0, a negative value in case of an error. - */ -int scols_line_set_color(struct libscols_line *ln, const char *color) -{ - if (color && isalnum(*color)) { - color = color_sequence_from_colorname(color); - if (!color) - return -EINVAL; - } - return strdup_to_struct_member(ln, color, color); -} - -/** - * scols_line_get_color: - * @ln: a pointer to a struct libscols_line instance - * - * Returns: @ln's color string, NULL in case of an error. - */ -const char *scols_line_get_color(const struct libscols_line *ln) -{ - return ln->color; -} - -/** - * scols_line_get_ncells: - * @ln: a pointer to a struct libscols_line instance - * - * Returns: number of cells - */ -size_t scols_line_get_ncells(const struct libscols_line *ln) -{ - return ln->ncells; -} - -/** - * scols_line_get_cell: - * @ln: a pointer to a struct libscols_line instance - * @n: cell number to retrieve - * - * Returns: the @n-th cell in @ln, NULL in case of an error. - */ -struct libscols_cell *scols_line_get_cell(struct libscols_line *ln, - size_t n) -{ - if (!ln || n >= ln->ncells) - return NULL; - return &ln->cells[n]; -} - -/** - * scols_line_get_column_cell: - * @ln: a pointer to a struct libscols_line instance - * @cl: pointer to cell - * - * Like scols_line_get_cell() by cell is referenced by column. - * - * Returns: the @n-th cell in @ln, NULL in case of an error. - */ -struct libscols_cell *scols_line_get_column_cell( - struct libscols_line *ln, - struct libscols_column *cl) -{ - if (!ln || !cl) - return NULL; - - return scols_line_get_cell(ln, cl->seqnum); -} - -/** - * scols_line_set_data: - * @ln: a pointer to a struct libscols_line instance - * @n: number of the cell, whose data is to be set - * @data: actual data to set - * - * Returns: 0, a negative value in case of an error. - */ -int scols_line_set_data(struct libscols_line *ln, size_t n, const char *data) -{ - struct libscols_cell *ce = scols_line_get_cell(ln, n); - - if (!ce) - return -EINVAL; - return scols_cell_set_data(ce, data); -} - -/** - * scols_line_set_column_data: - * @ln: a pointer to a struct libscols_line instance - * @cl: column, whose data is to be set - * @data: actual data to set - * - * The same as scols_line_set_data() but cell is referenced by column object. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.28 - */ -int scols_line_set_column_data(struct libscols_line *ln, - struct libscols_column *cl, - const char *data) -{ - return scols_line_set_data(ln, cl->seqnum, data); -} - -/** - * scols_line_refer_data: - * @ln: a pointer to a struct libscols_line instance - * @n: number of the cell which will refer to @data - * @data: actual data to refer to - * - * Returns: 0, a negative value in case of an error. - */ -int scols_line_refer_data(struct libscols_line *ln, size_t n, char *data) -{ - struct libscols_cell *ce = scols_line_get_cell(ln, n); - - if (!ce) - return -EINVAL; - return scols_cell_refer_data(ce, data); -} - -/** - * scols_line_refer_column_data: - * @ln: a pointer to a struct libscols_line instance - * @cl: column, whose data is to be set - * @data: actual data to refer to - * - * The same as scols_line_refer_data() but cell is referenced by column object. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.28 - */ -int scols_line_refer_column_data(struct libscols_line *ln, - struct libscols_column *cl, - char *data) -{ - return scols_line_refer_data(ln, cl->seqnum, data); -} - -/** - * scols_copy_line: - * @ln: a pointer to a struct libscols_line instance - * - * Returns: A newly allocated copy of @ln, NULL in case of an error. - */ -struct libscols_line *scols_copy_line(const struct libscols_line *ln) -{ - struct libscols_line *ret; - size_t i; - - if (!ln) - return NULL; - - ret = scols_new_line(); - if (!ret) - return NULL; - if (scols_line_set_color(ret, ln->color)) - goto err; - if (scols_line_alloc_cells(ret, ln->ncells)) - goto err; - - ret->userdata = ln->userdata; - ret->ncells = ln->ncells; - ret->seqnum = ln->seqnum; - - DBG(LINE, ul_debugobj(ln, "copy")); - - for (i = 0; i < ret->ncells; ++i) { - if (scols_cell_copy_content(&ret->cells[i], &ln->cells[i])) - goto err; - } - - return ret; -err: - scols_unref_line(ret); - return NULL; -} diff --git a/utils/libsmartcols/src/print-api.c b/utils/libsmartcols/src/print-api.c deleted file mode 100644 index 9a9f2df..0000000 --- a/utils/libsmartcols/src/print-api.c +++ /dev/null @@ -1,211 +0,0 @@ -#include "smartcolsP.h" - -/** - * scola_table_print_range: - * @tb: table - * @start: first printed line or NULL to print from the begin of the table - * @end: last printed line or NULL to print all from start. - * - * If the start is the first line in the table than prints table header too. - * The header is printed only once. This does not work for trees. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_table_print_range( struct libscols_table *tb, - struct libscols_line *start, - struct libscols_line *end) -{ - struct libscols_buffer *buf = NULL; - struct libscols_iter itr; - int rc; - - if (scols_table_is_tree(tb)) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "printing range from API")); - - rc = __scols_initialize_printing(tb, &buf); - if (rc) - return rc; - - if (start) { - itr.direction = SCOLS_ITER_FORWARD; - itr.head = &tb->tb_lines; - itr.p = &start->ln_lines; - } else - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - - if (!start || itr.p == tb->tb_lines.next) { - rc = __scols_print_header(tb, buf); - if (rc) - goto done; - } - - rc = __scols_print_range(tb, buf, &itr, end); -done: - __scols_cleanup_printing(tb, buf); - return rc; -} - -/** - * scols_table_print_range_to_string: - * @tb: table - * @start: first printed line or NULL to print from the beginning of the table - * @end: last printed line or NULL to print all from start. - * @data: pointer to the beginning of a memory area to print to - * - * The same as scols_table_print_range(), but prints to @data instead of - * stream. - * - * Returns: 0, a negative value in case of an error. - */ -#ifdef HAVE_OPEN_MEMSTREAM -int scols_table_print_range_to_string( struct libscols_table *tb, - struct libscols_line *start, - struct libscols_line *end, - char **data) -{ - FILE *stream, *old_stream; - size_t sz; - int rc; - - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "printing range to string")); - - /* create a stream for output */ - stream = open_memstream(data, &sz); - if (!stream) - return -ENOMEM; - - old_stream = scols_table_get_stream(tb); - scols_table_set_stream(tb, stream); - rc = scols_table_print_range(tb, start, end); - fclose(stream); - scols_table_set_stream(tb, old_stream); - - return rc; -} -#else -int scols_table_print_range_to_string( - struct libscols_table *tb __attribute__((__unused__)), - struct libscols_line *start __attribute__((__unused__)), - struct libscols_line *end __attribute__((__unused__)), - char **data __attribute__((__unused__))) -{ - return -ENOSYS; -} -#endif - -static int do_print_table(struct libscols_table *tb, int *is_empty) -{ - int rc = 0; - struct libscols_buffer *buf = NULL; - - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "printing")); - if (is_empty) - *is_empty = 0; - - if (list_empty(&tb->tb_columns)) { - DBG(TAB, ul_debugobj(tb, "error -- no columns")); - return -EINVAL; - } - if (list_empty(&tb->tb_lines)) { - DBG(TAB, ul_debugobj(tb, "ignore -- no lines")); - if (scols_table_is_json(tb)) { - fput_table_open(tb); - fput_table_close(tb); - } else if (is_empty) - *is_empty = 1; - return 0; - } - - tb->header_printed = 0; - rc = __scols_initialize_printing(tb, &buf); - if (rc) - return rc; - - fput_table_open(tb); - - if (tb->format == SCOLS_FMT_HUMAN) - __scols_print_title(tb); - - rc = __scols_print_header(tb, buf); - if (rc) - goto done; - - if (scols_table_is_tree(tb)) - rc = __scols_print_tree(tb, buf); - else - rc = __scols_print_table(tb, buf); - - fput_table_close(tb); -done: - __scols_cleanup_printing(tb, buf); - return rc; -} - -/** - * scols_print_table: - * @tb: table - * - * Prints the table to the output stream and terminate by \n. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_print_table(struct libscols_table *tb) -{ - int empty = 0; - int rc = do_print_table(tb, &empty); - - if (rc == 0 && !empty) - fputc('\n', tb->out); - return rc; -} - -/** - * scols_print_table_to_string: - * @tb: table - * @data: pointer to the beginning of a memory area to print to - * - * Prints the table to @data. - * - * Returns: 0, a negative value in case of an error. - */ -#ifdef HAVE_OPEN_MEMSTREAM -int scols_print_table_to_string(struct libscols_table *tb, char **data) -{ - FILE *stream, *old_stream; - size_t sz; - int rc; - - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "printing to string")); - - /* create a stream for output */ - stream = open_memstream(data, &sz); - if (!stream) - return -ENOMEM; - - old_stream = scols_table_get_stream(tb); - scols_table_set_stream(tb, stream); - rc = do_print_table(tb, NULL); - fclose(stream); - scols_table_set_stream(tb, old_stream); - - return rc; -} -#else -int scols_print_table_to_string( - struct libscols_table *tb __attribute__((__unused__)), - char **data __attribute__((__unused__))) -{ - return -ENOSYS; -} -#endif diff --git a/utils/libsmartcols/src/print.c b/utils/libsmartcols/src/print.c deleted file mode 100644 index 1172533..0000000 --- a/utils/libsmartcols/src/print.c +++ /dev/null @@ -1,1089 +0,0 @@ -/* - * table.c - functions handling the data at the table level - * - * Copyright (C) 2010-2014 Karel Zak <kzak@redhat.com> - * Copyright (C) 2016 Igor Gnatenko <i.gnatenko.brain@gmail.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -/** - * SECTION: table_print - * @title: Table print - * @short_description: output functions - * - * Table output API. - */ - -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <termios.h> -#include <ctype.h> - -#include "mbsalign.h" -#include "carefulputc.h" -#include "smartcolsP.h" - -/* Fallback for symbols - * - * Note that by default library define all the symbols, but in case user does - * not define all symbols or if we extended the symbols struct then we need - * fallback to be more robust and backwardly compatible. - */ -#define titlepadding_symbol(tb) ((tb)->symbols->title_padding ? (tb)->symbols->title_padding : " ") -#define branch_symbol(tb) ((tb)->symbols->tree_branch ? (tb)->symbols->tree_branch : "|-") -#define vertical_symbol(tb) ((tb)->symbols->tree_vert ? (tb)->symbols->tree_vert : "| ") -#define right_symbol(tb) ((tb)->symbols->tree_right ? (tb)->symbols->tree_right : "`-") - -#define grp_vertical_symbol(tb) ((tb)->symbols->group_vert ? (tb)->symbols->group_vert : "|") -#define grp_horizontal_symbol(tb) ((tb)->symbols->group_horz ? (tb)->symbols->group_horz : "-") -#define grp_m_first_symbol(tb) ((tb)->symbols->group_first_member ? (tb)->symbols->group_first_member : ",->") -#define grp_m_last_symbol(tb) ((tb)->symbols->group_last_member ? (tb)->symbols->group_last_member : "\\->") -#define grp_m_middle_symbol(tb) ((tb)->symbols->group_middle_member ? (tb)->symbols->group_middle_member : "|->") -#define grp_c_middle_symbol(tb) ((tb)->symbols->group_middle_child ? (tb)->symbols->group_middle_child : "|-") -#define grp_c_last_symbol(tb) ((tb)->symbols->group_last_child ? (tb)->symbols->group_last_child : "`-") - -#define cellpadding_symbol(tb) ((tb)->padding_debug ? "." : \ - ((tb)->symbols->cell_padding ? (tb)->symbols->cell_padding: " ")) - -#define want_repeat_header(tb) (!(tb)->header_repeat || (tb)->header_next <= (tb)->termlines_used) - -static int is_next_columns_empty( - struct libscols_table *tb, - struct libscols_column *cl, - struct libscols_line *ln) -{ - struct libscols_iter itr; - - if (!tb || !cl) - return 0; - if (is_last_column(cl)) - return 1; - if (!ln) - return 0; - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - scols_table_set_columns_iter(tb, &itr, cl); - - /* skip current column */ - scols_table_next_column(tb, &itr, &cl); - - while (scols_table_next_column(tb, &itr, &cl) == 0) { - struct libscols_cell *ce; - const char *data = NULL; - - if (scols_column_is_hidden(cl)) - continue; - if (scols_column_is_tree(cl)) - return 0; - - ce = scols_line_get_cell(ln, cl->seqnum); - if (ce) - data = scols_cell_get_data(ce); - if (data && *data) - return 0; - } - return 1; -} - -/* returns pointer to the end of used data */ -static int tree_ascii_art_to_buffer(struct libscols_table *tb, - struct libscols_line *ln, - struct libscols_buffer *buf) -{ - const char *art; - int rc; - - assert(ln); - assert(buf); - - if (!ln->parent) - return 0; - - rc = tree_ascii_art_to_buffer(tb, ln->parent, buf); - if (rc) - return rc; - - if (is_last_child(ln)) - art = " "; - else - art = vertical_symbol(tb); - - return buffer_append_data(buf, art); -} - -static int grpset_is_empty( struct libscols_table *tb, - size_t idx, - size_t *rest) -{ - size_t i; - - for (i = idx; i < tb->grpset_size; i++) { - if (tb->grpset[i] == NULL) { - if (rest) - (*rest)++; - } else - return 0; - } - return 1; -} - -static int groups_ascii_art_to_buffer( struct libscols_table *tb, - struct libscols_line *ln, - struct libscols_buffer *buf) -{ - int filled = 0; - size_t i, rest = 0; - const char *filler = cellpadding_symbol(tb); - - if (!has_groups(tb)) - return 0; - - DBG(LINE, ul_debugobj(ln, "printing groups chart")); - - if (tb->is_dummy_print) - return 0; /* allocate grpset[] only */ - - for (i = 0; i < tb->grpset_size; i += SCOLS_GRPSET_CHUNKSIZ) { - struct libscols_group *gr = tb->grpset[i]; - - if (!gr) { - buffer_append_ntimes(buf, SCOLS_GRPSET_CHUNKSIZ, cellpadding_symbol(tb)); - continue; - } - - switch (gr->state) { - case SCOLS_GSTATE_FIRST_MEMBER: - buffer_append_data(buf, grp_m_first_symbol(tb)); - break; - case SCOLS_GSTATE_MIDDLE_MEMBER: - buffer_append_data(buf, grp_m_middle_symbol(tb)); - break; - case SCOLS_GSTATE_LAST_MEMBER: - buffer_append_data(buf, grp_m_last_symbol(tb)); - break; - case SCOLS_GSTATE_CONT_MEMBERS: - buffer_append_data(buf, grp_vertical_symbol(tb)); - buffer_append_ntimes(buf, 2, filler); - break; - case SCOLS_GSTATE_MIDDLE_CHILD: - buffer_append_data(buf, filler); - buffer_append_data(buf, grp_c_middle_symbol(tb)); - if (grpset_is_empty(tb, i + SCOLS_GRPSET_CHUNKSIZ, &rest)) { - buffer_append_ntimes(buf, rest+1, grp_horizontal_symbol(tb)); - filled = 1; - } - filler = grp_horizontal_symbol(tb); - break; - case SCOLS_GSTATE_LAST_CHILD: - buffer_append_data(buf, cellpadding_symbol(tb)); - buffer_append_data(buf, grp_c_last_symbol(tb)); - if (grpset_is_empty(tb, i + SCOLS_GRPSET_CHUNKSIZ, &rest)) { - buffer_append_ntimes(buf, rest+1, grp_horizontal_symbol(tb)); - filled = 1; - } - filler = grp_horizontal_symbol(tb); - break; - case SCOLS_GSTATE_CONT_CHILDREN: - buffer_append_data(buf, filler); - buffer_append_data(buf, grp_vertical_symbol(tb)); - buffer_append_data(buf, filler); - break; - } - - if (filled) - break; - } - - if (!filled) - buffer_append_data(buf, filler); - return 0; -} - -static int has_pending_data(struct libscols_table *tb) -{ - struct libscols_column *cl; - struct libscols_iter itr; - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_column(tb, &itr, &cl) == 0) { - if (scols_column_is_hidden(cl)) - continue; - if (cl->pending_data) - return 1; - } - return 0; -} - -/* print padding or ASCII-art instead of data of @cl */ -static void print_empty_cell(struct libscols_table *tb, - struct libscols_column *cl, - struct libscols_line *ln, /* optional */ - size_t bufsz) -{ - size_t len_pad = 0; /* in screen cells as opposed to bytes */ - - DBG(COL, ul_debugobj(cl, " printing empty cell")); - - /* generate tree ASCII-art rather than padding */ - if (ln && scols_column_is_tree(cl)) { - if (!ln->parent) { - /* only print symbols->vert if followed by child */ - if (!list_empty(&ln->ln_branch)) { - fputs(vertical_symbol(tb), tb->out); - len_pad = scols_table_is_noencoding(tb) ? - mbs_width(vertical_symbol(tb)) : - mbs_safe_width(vertical_symbol(tb)); - } - } else { - /* use the same draw function as though we were intending to draw an L-shape */ - struct libscols_buffer *art = new_buffer(bufsz); - char *data; - - if (art) { - /* whatever the rc, len_pad will be sensible */ - tree_ascii_art_to_buffer(tb, ln, art); - if (!list_empty(&ln->ln_branch) && has_pending_data(tb)) - buffer_append_data(art, vertical_symbol(tb)); - data = buffer_get_safe_data(tb, art, &len_pad, NULL); - if (data && len_pad) - fputs(data, tb->out); - free_buffer(art); - } - } - } - - /* minout -- don't fill */ - if (scols_table_is_minout(tb) && is_next_columns_empty(tb, cl, ln)) - return; - - /* default -- fill except last column */ - if (!scols_table_is_maxout(tb) && is_last_column(cl)) - return; - - /* fill rest of cell with space */ - for(; len_pad < cl->width; ++len_pad) - fputs(cellpadding_symbol(tb), tb->out); - - if (!is_last_column(cl)) - fputs(colsep(tb), tb->out); -} - - -static const char *get_cell_color(struct libscols_table *tb, - struct libscols_column *cl, - struct libscols_line *ln, /* optional */ - struct libscols_cell *ce) /* optional */ -{ - const char *color = NULL; - - if (tb && tb->colors_wanted) { - if (ce) - color = ce->color; - if (ln && !color) - color = ln->color; - if (!color) - color = cl->color; - } - return color; -} - -/* Fill the start of a line with padding (or with tree ascii-art). - * - * This is necessary after a long non-truncated column, as this requires the - * next column to be printed on the next line. For example (see 'DDD'): - * - * aaa bbb ccc ddd eee - * AAA BBB CCCCCCC - * DDD EEE - * ^^^^^^^^^^^^ - * new line padding - */ -static void print_newline_padding(struct libscols_table *tb, - struct libscols_column *cl, - struct libscols_line *ln, /* optional */ - size_t bufsz) -{ - size_t i; - - assert(tb); - assert(cl); - - DBG(LINE, ul_debugobj(ln, "printing newline padding")); - - fputs(linesep(tb), tb->out); /* line break */ - tb->termlines_used++; - - /* fill cells after line break */ - for (i = 0; i <= (size_t) cl->seqnum; i++) - print_empty_cell(tb, scols_table_get_column(tb, i), ln, bufsz); -} - -/* - * Pending data - * - * The first line in the multi-line cells (columns with SCOLS_FL_WRAP flag) is - * printed as usually and output is truncated to match column width. - * - * The rest of the long text is printed on next extra line(s). The extra lines - * don't exist in the table (not represented by libscols_line). The data for - * the extra lines are stored in libscols_column->pending_data_buf and the - * function print_line() adds extra lines until the buffer is not empty in all - * columns. - */ - -/* set data that will be printed by extra lines */ -static int set_pending_data(struct libscols_column *cl, const char *data, size_t sz) -{ - char *p = NULL; - - if (data && *data) { - DBG(COL, ul_debugobj(cl, "setting pending data")); - assert(sz); - p = strdup(data); - if (!p) - return -ENOMEM; - } - - free(cl->pending_data_buf); - cl->pending_data_buf = p; - cl->pending_data_sz = sz; - cl->pending_data = cl->pending_data_buf; - return 0; -} - -/* the next extra line has been printed, move pending data cursor */ -static int step_pending_data(struct libscols_column *cl, size_t bytes) -{ - DBG(COL, ul_debugobj(cl, "step pending data %zu -= %zu", cl->pending_data_sz, bytes)); - - if (bytes >= cl->pending_data_sz) - return set_pending_data(cl, NULL, 0); - - cl->pending_data += bytes; - cl->pending_data_sz -= bytes; - return 0; -} - -/* print next pending data for the column @cl */ -static int print_pending_data( - struct libscols_table *tb, - struct libscols_column *cl, - struct libscols_line *ln, /* optional */ - struct libscols_cell *ce) -{ - const char *color = get_cell_color(tb, cl, ln, ce); - size_t width = cl->width, bytes; - size_t len = width, i; - char *data; - char *nextchunk = NULL; - - if (!cl->pending_data) - return 0; - if (!width) - return -EINVAL; - - DBG(COL, ul_debugobj(cl, "printing pending data")); - - data = strdup(cl->pending_data); - if (!data) - goto err; - - if (scols_column_is_customwrap(cl) - && (nextchunk = cl->wrap_nextchunk(cl, data, cl->wrapfunc_data))) { - bytes = nextchunk - data; - - len = scols_table_is_noencoding(tb) ? - mbs_nwidth(data, bytes) : - mbs_safe_nwidth(data, bytes, NULL); - } else - bytes = mbs_truncate(data, &len); - - if (bytes == (size_t) -1) - goto err; - - if (bytes) - step_pending_data(cl, bytes); - - if (color) - fputs(color, tb->out); - fputs(data, tb->out); - if (color) - fputs(UL_COLOR_RESET, tb->out); - free(data); - - /* minout -- don't fill */ - if (scols_table_is_minout(tb) && is_next_columns_empty(tb, cl, ln)) - return 0; - - /* default -- fill except last column */ - if (!scols_table_is_maxout(tb) && is_last_column(cl)) - return 0; - - /* fill rest of cell with space */ - for(i = len; i < width; i++) - fputs(cellpadding_symbol(tb), tb->out); - - if (!is_last_column(cl)) - fputs(colsep(tb), tb->out); - - return 0; -err: - free(data); - return -errno; -} - -static int print_data(struct libscols_table *tb, - struct libscols_column *cl, - struct libscols_line *ln, /* optional */ - struct libscols_cell *ce, /* optional */ - struct libscols_buffer *buf) -{ - size_t len = 0, i, width, bytes; - const char *color = NULL; - char *data, *nextchunk; - int is_last; - - assert(tb); - assert(cl); - - data = buffer_get_data(buf); - if (!data) - data = ""; - - is_last = is_last_column(cl); - - switch (tb->format) { - case SCOLS_FMT_RAW: - fputs_nonblank(data, tb->out); - if (!is_last) - fputs(colsep(tb), tb->out); - return 0; - - case SCOLS_FMT_EXPORT: - fprintf(tb->out, "%s=", scols_cell_get_data(&cl->header)); - fputs_quoted(data, tb->out); - if (!is_last) - fputs(colsep(tb), tb->out); - return 0; - - case SCOLS_FMT_JSON: - fputs_quoted_json_lower(scols_cell_get_data(&cl->header), tb->out); - fputs(":", tb->out); - switch (cl->json_type) { - case SCOLS_JSON_STRING: - if (!*data) - fputs("null", tb->out); - else - fputs_quoted_json(data, tb->out); - break; - case SCOLS_JSON_NUMBER: - if (!*data) - fputs("null", tb->out); - else - fputs(data, tb->out); - break; - case SCOLS_JSON_BOOLEAN: - fputs(!*data ? "false" : - *data == '0' ? "false" : - *data == 'N' || *data == 'n' ? "false" : "true", - tb->out); - break; - } - if (!is_last) - fputs(", ", tb->out); - return 0; - - case SCOLS_FMT_HUMAN: - break; /* continue below */ - } - - color = get_cell_color(tb, cl, ln, ce); - - /* Encode. Note that 'len' and 'width' are number of cells, not bytes. - */ - data = buffer_get_safe_data(tb, buf, &len, scols_column_get_safechars(cl)); - if (!data) - data = ""; - bytes = strlen(data); - width = cl->width; - - /* custom multi-line cell based */ - if (*data && scols_column_is_customwrap(cl) - && (nextchunk = cl->wrap_nextchunk(cl, data, cl->wrapfunc_data))) { - set_pending_data(cl, nextchunk, bytes - (nextchunk - data)); - bytes = nextchunk - data; - - len = scols_table_is_noencoding(tb) ? - mbs_nwidth(data, bytes) : - mbs_safe_nwidth(data, bytes, NULL); - } - - if (is_last - && len < width - && !scols_table_is_maxout(tb) - && !scols_column_is_right(cl)) - width = len; - - /* truncate data */ - if (len > width && scols_column_is_trunc(cl)) { - len = width; - bytes = mbs_truncate(data, &len); /* updates 'len' */ - } - - /* standard multi-line cell */ - if (len > width && scols_column_is_wrap(cl) - && !scols_column_is_customwrap(cl)) { - set_pending_data(cl, data, bytes); - - len = width; - bytes = mbs_truncate(data, &len); - if (bytes != (size_t) -1 && bytes > 0) - step_pending_data(cl, bytes); - } - - if (bytes == (size_t) -1) { - bytes = len = 0; - data = NULL; - } - - if (data && *data) { - if (scols_column_is_right(cl)) { - if (color) - fputs(color, tb->out); - for (i = len; i < width; i++) - fputs(cellpadding_symbol(tb), tb->out); - fputs(data, tb->out); - if (color) - fputs(UL_COLOR_RESET, tb->out); - len = width; - - } else if (color) { - char *p = data; - size_t art = buffer_get_safe_art_size(buf); - - /* we don't want to colorize tree ascii art */ - if (scols_column_is_tree(cl) && art && art < bytes) { - fwrite(p, 1, art, tb->out); - p += art; - } - - fputs(color, tb->out); - fputs(p, tb->out); - fputs(UL_COLOR_RESET, tb->out); - } else - fputs(data, tb->out); - } - - /* minout -- don't fill */ - if (scols_table_is_minout(tb) && is_next_columns_empty(tb, cl, ln)) - return 0; - - /* default -- fill except last column */ - if (!scols_table_is_maxout(tb) && is_last) - return 0; - - /* fill rest of cell with space */ - for(i = len; i < width; i++) - fputs(cellpadding_symbol(tb), tb->out); - - if (len > width && !scols_column_is_trunc(cl)) { - DBG(COL, ul_debugobj(cl, "*** data len=%zu > column width=%zu", len, width)); - print_newline_padding(tb, cl, ln, buffer_get_size(buf)); /* next column starts on next line */ - - } else if (!is_last) - fputs(colsep(tb), tb->out); /* columns separator */ - - return 0; -} - -int __cell_to_buffer(struct libscols_table *tb, - struct libscols_line *ln, - struct libscols_column *cl, - struct libscols_buffer *buf) -{ - const char *data; - struct libscols_cell *ce; - int rc = 0; - - assert(tb); - assert(ln); - assert(cl); - assert(buf); - assert(cl->seqnum <= tb->ncols); - - buffer_reset_data(buf); - - ce = scols_line_get_cell(ln, cl->seqnum); - data = ce ? scols_cell_get_data(ce) : NULL; - - if (!scols_column_is_tree(cl)) - return data ? buffer_set_data(buf, data) : 0; - - /* - * Group stuff - */ - if (!scols_table_is_json(tb) && cl->is_groups) - rc = groups_ascii_art_to_buffer(tb, ln, buf); - - /* - * Tree stuff - */ - if (!rc && ln->parent && !scols_table_is_json(tb)) { - rc = tree_ascii_art_to_buffer(tb, ln->parent, buf); - - if (!rc && is_last_child(ln)) - rc = buffer_append_data(buf, right_symbol(tb)); - else if (!rc) - rc = buffer_append_data(buf, branch_symbol(tb)); - } - - if (!rc && (ln->parent || cl->is_groups) && !scols_table_is_json(tb)) - buffer_set_art_index(buf); - - if (!rc && data) - rc = buffer_append_data(buf, data); - return rc; -} - -/* - * Prints data. Data can be printed in more formats (raw, NAME=xxx pairs), and - * control and non-printable characters can be encoded in the \x?? encoding. - */ -static int print_line(struct libscols_table *tb, - struct libscols_line *ln, - struct libscols_buffer *buf) -{ - int rc = 0, pending = 0; - struct libscols_column *cl; - struct libscols_iter itr; - - assert(ln); - - DBG(LINE, ul_debugobj(ln, "printing line")); - - /* regular line */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (rc == 0 && scols_table_next_column(tb, &itr, &cl) == 0) { - if (scols_column_is_hidden(cl)) - continue; - rc = __cell_to_buffer(tb, ln, cl, buf); - if (rc == 0) - rc = print_data(tb, cl, ln, - scols_line_get_cell(ln, cl->seqnum), - buf); - if (rc == 0 && cl->pending_data) - pending = 1; - } - - /* extra lines of the multi-line cells */ - while (rc == 0 && pending) { - DBG(LINE, ul_debugobj(ln, "printing pending data")); - pending = 0; - fputs(linesep(tb), tb->out); - tb->termlines_used++; - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (rc == 0 && scols_table_next_column(tb, &itr, &cl) == 0) { - if (scols_column_is_hidden(cl)) - continue; - if (cl->pending_data) { - rc = print_pending_data(tb, cl, ln, scols_line_get_cell(ln, cl->seqnum)); - if (rc == 0 && cl->pending_data) - pending = 1; - } else - print_empty_cell(tb, cl, ln, buffer_get_size(buf)); - } - } - - return 0; -} - -int __scols_print_title(struct libscols_table *tb) -{ - int rc, color = 0; - mbs_align_t align; - size_t width, len = 0, bufsz, titlesz; - char *title = NULL, *buf = NULL; - - assert(tb); - - if (!tb->title.data) - return 0; - - DBG(TAB, ul_debugobj(tb, "printing title")); - - /* encode data */ - if (tb->no_encode) { - len = bufsz = strlen(tb->title.data) + 1; - buf = strdup(tb->title.data); - if (!buf) { - rc = -ENOMEM; - goto done; - } - } else { - bufsz = mbs_safe_encode_size(strlen(tb->title.data)) + 1; - if (bufsz == 1) { - DBG(TAB, ul_debugobj(tb, "title is empty string -- ignore")); - return 0; - } - buf = malloc(bufsz); - if (!buf) { - rc = -ENOMEM; - goto done; - } - - if (!mbs_safe_encode_to_buffer(tb->title.data, &len, buf, NULL) || - !len || len == (size_t) -1) { - rc = -EINVAL; - goto done; - } - } - - /* truncate and align */ - width = tb->is_term ? tb->termwidth : 80; - titlesz = width + bufsz; - - title = malloc(titlesz); - if (!title) { - rc = -EINVAL; - goto done; - } - - switch (scols_cell_get_alignment(&tb->title)) { - case SCOLS_CELL_FL_RIGHT: - align = MBS_ALIGN_RIGHT; - break; - case SCOLS_CELL_FL_CENTER: - align = MBS_ALIGN_CENTER; - break; - case SCOLS_CELL_FL_LEFT: - default: - align = MBS_ALIGN_LEFT; - /* - * Don't print extra blank chars after the title if on left - * (that's same as we use for the last column in the table). - */ - if (len < width - && !scols_table_is_maxout(tb) - && isblank(*titlepadding_symbol(tb))) - width = len; - break; - - } - - /* copy from buf to title and align to width with title_padding */ - rc = mbsalign_with_padding(buf, title, titlesz, - &width, align, - 0, (int) *titlepadding_symbol(tb)); - - if (rc == -1) { - rc = -EINVAL; - goto done; - } - - if (tb->colors_wanted && tb->title.color) - color = 1; - if (color) - fputs(tb->title.color, tb->out); - - fputs(title, tb->out); - - if (color) - fputs(UL_COLOR_RESET, tb->out); - - fputc('\n', tb->out); - rc = 0; -done: - free(buf); - free(title); - DBG(TAB, ul_debugobj(tb, "printing title done [rc=%d]", rc)); - return rc; -} - -int __scols_print_header(struct libscols_table *tb, struct libscols_buffer *buf) -{ - int rc = 0; - struct libscols_column *cl; - struct libscols_iter itr; - - assert(tb); - - if ((tb->header_printed == 1 && tb->header_repeat == 0) || - scols_table_is_noheadings(tb) || - scols_table_is_export(tb) || - scols_table_is_json(tb) || - list_empty(&tb->tb_lines)) - return 0; - - DBG(TAB, ul_debugobj(tb, "printing header")); - - /* set the width according to the size of the data */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (rc == 0 && scols_table_next_column(tb, &itr, &cl) == 0) { - if (scols_column_is_hidden(cl)) - continue; - - buffer_reset_data(buf); - - if (cl->is_groups - && scols_table_is_tree(tb) && scols_column_is_tree(cl)) { - size_t i; - for (i = 0; i < tb->grpset_size + 1; i++) { - rc = buffer_append_data(buf, " "); - if (rc) - break; - } - } - if (!rc) - rc = buffer_append_data(buf, scols_cell_get_data(&cl->header)); - if (!rc) - rc = print_data(tb, cl, NULL, &cl->header, buf); - } - - if (rc == 0) { - fputs(linesep(tb), tb->out); - tb->termlines_used++; - } - - tb->header_printed = 1; - tb->header_next = tb->termlines_used + tb->termheight; - if (tb->header_repeat) - DBG(TAB, ul_debugobj(tb, "\tnext header: %zu [current=%zu, rc=%d]", - tb->header_next, tb->termlines_used, rc)); - return rc; -} - - -int __scols_print_range(struct libscols_table *tb, - struct libscols_buffer *buf, - struct libscols_iter *itr, - struct libscols_line *end) -{ - int rc = 0; - struct libscols_line *ln; - - assert(tb); - DBG(TAB, ul_debugobj(tb, "printing range")); - - while (rc == 0 && scols_table_next_line(tb, itr, &ln) == 0) { - - int last = scols_iter_is_last(itr); - - fput_line_open(tb); - rc = print_line(tb, ln, buf); - fput_line_close(tb, last, last); - - if (end && ln == end) - break; - - if (!last && want_repeat_header(tb)) - __scols_print_header(tb, buf); - } - - return rc; - -} - -int __scols_print_table(struct libscols_table *tb, struct libscols_buffer *buf) -{ - struct libscols_iter itr; - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - return __scols_print_range(tb, buf, &itr, NULL); -} - -/* scols_walk_tree() callback to print tree line */ -static int print_tree_line(struct libscols_table *tb, - struct libscols_line *ln, - struct libscols_column *cl __attribute__((__unused__)), - void *data) -{ - struct libscols_buffer *buf = (struct libscols_buffer *) data; - int rc; - - DBG(LINE, ul_debugobj(ln, " printing tree line")); - - fput_line_open(tb); - rc = print_line(tb, ln, buf); - if (rc) - return rc; - - if (has_children(ln)) - fput_children_open(tb); - - else { - int last_in_tree = scols_walk_is_last(tb, ln); - int last; - - /* terminate all open last children for JSON */ - if (scols_table_is_json(tb)) { - do { - last = (is_child(ln) && is_last_child(ln)) || - (is_tree_root(ln) && is_last_tree_root(tb, ln)); - - fput_line_close(tb, last, last_in_tree); - if (last && is_child(ln)) - fput_children_close(tb); - - last_in_tree = 0; - ln = ln->parent; - } while(ln && last); - - } else { - /* standard output */ - last = (is_child(ln) && is_last_child(ln)) || - (is_group_child(ln) && is_last_group_child(ln)); - - fput_line_close(tb, last, last_in_tree); - } - } - - return 0; -} - -int __scols_print_tree(struct libscols_table *tb, struct libscols_buffer *buf) -{ - assert(tb); - DBG(TAB, ul_debugobj(tb, "----printing-tree-----")); - - return scols_walk_tree(tb, NULL, print_tree_line, (void *) buf); -} - -static size_t strlen_line(struct libscols_line *ln) -{ - size_t i, sz = 0; - - assert(ln); - - for (i = 0; i < ln->ncells; i++) { - struct libscols_cell *ce = scols_line_get_cell(ln, i); - const char *data = ce ? scols_cell_get_data(ce) : NULL; - - sz += data ? strlen(data) : 0; - } - - return sz; -} - -void __scols_cleanup_printing(struct libscols_table *tb, struct libscols_buffer *buf) -{ - if (!tb) - return; - - free_buffer(buf); - - if (tb->priv_symbols) { - scols_table_set_symbols(tb, NULL); - tb->priv_symbols = 0; - } -} - -int __scols_initialize_printing(struct libscols_table *tb, struct libscols_buffer **buf) -{ - size_t bufsz, extra_bufsz = 0; - struct libscols_line *ln; - struct libscols_iter itr; - int rc; - - DBG(TAB, ul_debugobj(tb, "initialize printing")); - *buf = NULL; - - if (!tb->symbols) { - rc = scols_table_set_default_symbols(tb); - if (rc) - goto err; - tb->priv_symbols = 1; - } else - tb->priv_symbols = 0; - - if (tb->format == SCOLS_FMT_HUMAN) - tb->is_term = tb->termforce == SCOLS_TERMFORCE_NEVER ? 0 : - tb->termforce == SCOLS_TERMFORCE_ALWAYS ? 1 : - isatty(STDOUT_FILENO); - - if (tb->is_term) { - size_t width = (size_t) scols_table_get_termwidth(tb); - - if (tb->termreduce > 0 && tb->termreduce < width) { - width -= tb->termreduce; - scols_table_set_termwidth(tb, width); - } - bufsz = width; - } else - bufsz = BUFSIZ; - - if (!tb->is_term || tb->format != SCOLS_FMT_HUMAN || scols_table_is_tree(tb)) - tb->header_repeat = 0; - - /* - * Estimate extra space necessary for tree, JSON or another output - * decoration. - */ - if (scols_table_is_tree(tb)) - extra_bufsz += tb->nlines * strlen(vertical_symbol(tb)); - - switch (tb->format) { - case SCOLS_FMT_RAW: - extra_bufsz += tb->ncols; /* separator between columns */ - break; - case SCOLS_FMT_JSON: - if (tb->format == SCOLS_FMT_JSON) - extra_bufsz += tb->nlines * 3; /* indentation */ - /* fallthrough */ - case SCOLS_FMT_EXPORT: - { - struct libscols_column *cl; - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - - while (scols_table_next_column(tb, &itr, &cl) == 0) { - if (scols_column_is_hidden(cl)) - continue; - extra_bufsz += strlen(scols_cell_get_data(&cl->header)); /* data */ - extra_bufsz += 2; /* separators */ - } - break; - } - case SCOLS_FMT_HUMAN: - break; - } - - /* - * Enlarge buffer if necessary, the buffer should be large enough to - * store line data and tree ascii art (or another decoration). - */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_line(tb, &itr, &ln) == 0) { - size_t sz; - - sz = strlen_line(ln) + extra_bufsz; - if (sz > bufsz) - bufsz = sz; - } - - *buf = new_buffer(bufsz + 1); /* data + space for \0 */ - if (!*buf) { - rc = -ENOMEM; - goto err; - } - - /* - * Make sure groups members are in the same orders as the tree - */ - if (has_groups(tb) && scols_table_is_tree(tb)) - scols_groups_fix_members_order(tb); - - if (tb->format == SCOLS_FMT_HUMAN) { - rc = __scols_calculate(tb, *buf); - if (rc != 0) - goto err; - } - - return 0; -err: - __scols_cleanup_printing(tb, *buf); - return rc; -} - diff --git a/utils/libsmartcols/src/smartcolsP.h b/utils/libsmartcols/src/smartcolsP.h deleted file mode 100644 index e36bb51..0000000 --- a/utils/libsmartcols/src/smartcolsP.h +++ /dev/null @@ -1,468 +0,0 @@ -/* - * smartcolsP.h - private library header file - * - * Copyright (C) 2014 Ondrej Oprala <ooprala@redhat.com> - * Copyright (C) 2014 Karel Zak <kzak@redhat.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -#ifndef _LIBSMARTCOLS_PRIVATE_H -#define _LIBSMARTCOLS_PRIVATE_H - -#include "c.h" -#include "list.h" -#include "strutils.h" -#include "color-names.h" -#include "debug.h" - -#include "libsmartcols.h" - -/* - * Debug - */ -#define SCOLS_DEBUG_HELP (1 << 0) -#define SCOLS_DEBUG_INIT (1 << 1) -#define SCOLS_DEBUG_CELL (1 << 2) -#define SCOLS_DEBUG_LINE (1 << 3) -#define SCOLS_DEBUG_TAB (1 << 4) -#define SCOLS_DEBUG_COL (1 << 5) -#define SCOLS_DEBUG_BUFF (1 << 6) -#define SCOLS_DEBUG_GROUP (1 << 7) -#define SCOLS_DEBUG_ALL 0xFFFF - -UL_DEBUG_DECLARE_MASK(libsmartcols); -#define DBG(m, x) __UL_DBG(libsmartcols, SCOLS_DEBUG_, m, x) -#define ON_DBG(m, x) __UL_DBG_CALL(libsmartcols, SCOLS_DEBUG_, m, x) -#define DBG_FLUSH __UL_DBG_FLUSH(libsmartcols, SCOLS_DEBUG_) - -#define UL_DEBUG_CURRENT_MASK UL_DEBUG_MASK(libsmartcols) -#include "debugobj.h" - -/* - * Generic iterator - */ -struct libscols_iter { - struct list_head *p; /* current position */ - struct list_head *head; /* start position */ - int direction; /* SCOLS_ITER_{FOR,BACK}WARD */ -}; - -/* - * Tree symbols - */ -struct libscols_symbols { - int refcount; - - char *tree_branch; - char *tree_vert; - char *tree_right; - - char *group_vert; - char *group_horz; - char *group_first_member; - char *group_last_member; - char *group_middle_member; - char *group_last_child; - char *group_middle_child; - - char *title_padding; - char *cell_padding; -}; - -/* - * Table cells - */ -struct libscols_cell { - char *data; - char *color; - void *userdata; - int flags; -}; - -extern int scols_line_move_cells(struct libscols_line *ln, size_t newn, size_t oldn); - -/* - * Table column - */ -struct libscols_column { - int refcount; /* reference counter */ - size_t seqnum; /* column index */ - - size_t width; /* real column width */ - size_t width_min; /* minimal width (usually header width) */ - size_t width_max; /* maximal width */ - size_t width_avg; /* average width, used to detect extreme fields */ - size_t width_treeart; /* size of the tree ascii art */ - double width_hint; /* hint (N < 1 is in percent of termwidth) */ - - size_t extreme_sum; - int extreme_count; - - int json_type; /* SCOLS_JSON_* */ - - int flags; - char *color; /* default column color */ - char *safechars; /* do not encode this bytes */ - - char *pending_data; - size_t pending_data_sz; - char *pending_data_buf; - - int (*cmpfunc)(struct libscols_cell *, - struct libscols_cell *, - void *); /* cells comparison function */ - void *cmpfunc_data; - - size_t (*wrap_chunksize)(const struct libscols_column *, - const char *, void *); - char *(*wrap_nextchunk)(const struct libscols_column *, - char *, void *); - void *wrapfunc_data; - - - struct libscols_cell header; - struct list_head cl_columns; - - struct libscols_table *table; - - unsigned int is_extreme : 1, /* extreme width in the column */ - is_groups : 1; /* print group chart */ - -}; - -#define colsep(tb) ((tb)->colsep ? (tb)->colsep : " ") -#define linesep(tb) ((tb)->linesep ? (tb)->linesep : "\n") - -enum { - SCOLS_GSTATE_NONE = 0, /* not activate yet */ - SCOLS_GSTATE_FIRST_MEMBER, - SCOLS_GSTATE_MIDDLE_MEMBER, - SCOLS_GSTATE_LAST_MEMBER, - SCOLS_GSTATE_MIDDLE_CHILD, - SCOLS_GSTATE_LAST_CHILD, - SCOLS_GSTATE_CONT_MEMBERS, - SCOLS_GSTATE_CONT_CHILDREN -}; - -/* - * Every group needs at least 3 columns - */ -#define SCOLS_GRPSET_CHUNKSIZ 3 - -struct libscols_group { - int refcount; - - size_t nmembers; - - struct list_head gr_members; /* head of line->ln_group */ - struct list_head gr_children; /* head of line->ln_children */ - struct list_head gr_groups; /* member of table->tb_groups */ - - int state; /* SCOLS_GSTATE_* */ -}; - -/* - * Table line - */ -struct libscols_line { - int refcount; - size_t seqnum; - - void *userdata; - char *color; /* default line color */ - - struct libscols_cell *cells; /* array with data */ - size_t ncells; /* number of cells */ - - struct list_head ln_lines; /* member of table->tb_lines */ - struct list_head ln_branch; /* head of line->ln_children */ - struct list_head ln_children; /* member of line->ln_children or group->gr_children */ - struct list_head ln_groups; /* member of group->gr_groups */ - - struct libscols_line *parent; - struct libscols_group *parent_group; /* for group childs */ - struct libscols_group *group; /* for group members */ -}; - -enum { - SCOLS_FMT_HUMAN = 0, /* default, human readable */ - SCOLS_FMT_RAW, /* space separated */ - SCOLS_FMT_EXPORT, /* COLNAME="data" ... */ - SCOLS_FMT_JSON /* http://en.wikipedia.org/wiki/JSON */ -}; - -/* - * The table - */ -struct libscols_table { - int refcount; - char *name; /* optional table name (for JSON) */ - size_t ncols; /* number of columns */ - size_t ntreecols; /* number of columns with SCOLS_FL_TREE */ - size_t nlines; /* number of lines */ - size_t termwidth; /* terminal width (number of columns) */ - size_t termheight; /* terminal height (number of lines) */ - size_t termreduce; /* extra blank space */ - int termforce; /* SCOLS_TERMFORCE_* */ - FILE *out; /* output stream */ - - char *colsep; /* column separator */ - char *linesep; /* line separator */ - - struct list_head tb_columns; - struct list_head tb_lines; - - struct list_head tb_groups; /* all defined groups */ - struct libscols_group **grpset; - size_t grpset_size; - - size_t ngrpchlds_pending; /* groups with not yet printed children */ - struct libscols_line *walk_last_tree_root; /* last root, used by scols_walk_() */ - - struct libscols_symbols *symbols; - struct libscols_cell title; /* optional table title (for humans) */ - - int indent; /* indentation counter */ - int indent_last_sep;/* last printed has been line separator */ - int format; /* SCOLS_FMT_* */ - - size_t termlines_used; /* printed line counter */ - size_t header_next; /* where repeat header */ - - /* flags */ - unsigned int ascii :1, /* don't use unicode */ - colors_wanted :1, /* enable colors */ - is_term :1, /* isatty() */ - padding_debug :1, /* output visible padding chars */ - is_dummy_print :1, /* printing used for width calculation only */ - maxout :1, /* maximize output */ - minout :1, /* minimize output (mutually exclusive to maxout) */ - header_repeat :1, /* print header after libscols_table->termheight */ - header_printed :1, /* header already printed */ - priv_symbols :1, /* default private symbols */ - walk_last_done :1, /* last tree root walked */ - no_headings :1, /* don't print header */ - no_encode :1, /* don't care about control and non-printable chars */ - no_linesep :1, /* don't print line separator */ - no_wrap :1; /* never wrap lines */ -}; - -#define IS_ITER_FORWARD(_i) ((_i)->direction == SCOLS_ITER_FORWARD) -#define IS_ITER_BACKWARD(_i) ((_i)->direction == SCOLS_ITER_BACKWARD) - -#define SCOLS_ITER_INIT(itr, list) \ - do { \ - (itr)->p = IS_ITER_FORWARD(itr) ? \ - (list)->next : (list)->prev; \ - (itr)->head = (list); \ - } while(0) - -#define SCOLS_ITER_ITERATE(itr, res, restype, member) \ - do { \ - res = list_entry((itr)->p, restype, member); \ - (itr)->p = IS_ITER_FORWARD(itr) ? \ - (itr)->p->next : (itr)->p->prev; \ - } while(0) - - -static inline int scols_iter_is_last(const struct libscols_iter *itr) -{ - if (!itr || !itr->head || !itr->p) - return 0; - - return itr->p == itr->head; -} - -/* - * line.c - */ -int scols_line_next_group_child(struct libscols_line *ln, - struct libscols_iter *itr, - struct libscols_line **chld); - - -/* - * table.c - */ -int scols_table_next_group(struct libscols_table *tb, - struct libscols_iter *itr, - struct libscols_group **gr); - -/* - * buffer.c - */ -struct libscols_buffer; -extern struct libscols_buffer *new_buffer(size_t sz); -extern void free_buffer(struct libscols_buffer *buf); -extern int buffer_reset_data(struct libscols_buffer *buf); -extern int buffer_append_data(struct libscols_buffer *buf, const char *str); -extern int buffer_append_ntimes(struct libscols_buffer *buf, size_t n, const char *str); -extern int buffer_set_data(struct libscols_buffer *buf, const char *str); -extern void buffer_set_art_index(struct libscols_buffer *buf); -extern char *buffer_get_data(struct libscols_buffer *buf); -extern size_t buffer_get_size(struct libscols_buffer *buf); -extern char *buffer_get_safe_data(struct libscols_table *tb, - struct libscols_buffer *buf, - size_t *cells, - const char *safechars); -extern size_t buffer_get_safe_art_size(struct libscols_buffer *buf); - -/* - * grouping.c - */ -void scols_ref_group(struct libscols_group *gr); -void scols_group_remove_children(struct libscols_group *gr); -void scols_group_remove_members(struct libscols_group *gr); -void scols_unref_group(struct libscols_group *gr); -void scols_groups_fix_members_order(struct libscols_table *tb); -int scols_groups_update_grpset(struct libscols_table *tb, struct libscols_line *ln); -void scols_groups_reset_state(struct libscols_table *tb); -struct libscols_group *scols_grpset_get_printable_children(struct libscols_table *tb); - -/* - * walk.c - */ -extern int scols_walk_tree(struct libscols_table *tb, - struct libscols_column *cl, - int (*callback)(struct libscols_table *, - struct libscols_line *, - struct libscols_column *, - void *), - void *data); -extern int scols_walk_is_last(struct libscols_table *tb, struct libscols_line *ln); - -/* - * calculate.c - */ -extern int __scols_calculate(struct libscols_table *tb, struct libscols_buffer *buf); - -/* - * print.c - */ -extern int __cell_to_buffer(struct libscols_table *tb, - struct libscols_line *ln, - struct libscols_column *cl, - struct libscols_buffer *buf); - -void __scols_cleanup_printing(struct libscols_table *tb, struct libscols_buffer *buf); -int __scols_initialize_printing(struct libscols_table *tb, struct libscols_buffer **buf); -int __scols_print_tree(struct libscols_table *tb, struct libscols_buffer *buf); -int __scols_print_table(struct libscols_table *tb, struct libscols_buffer *buf); -int __scols_print_header(struct libscols_table *tb, struct libscols_buffer *buf); -int __scols_print_title(struct libscols_table *tb); -int __scols_print_range(struct libscols_table *tb, - struct libscols_buffer *buf, - struct libscols_iter *itr, - struct libscols_line *end); - -/* - * fput.c - */ -extern void fput_indent(struct libscols_table *tb); -extern void fput_table_open(struct libscols_table *tb); -extern void fput_table_close(struct libscols_table *tb); -extern void fput_children_open(struct libscols_table *tb); -extern void fput_children_close(struct libscols_table *tb); -extern void fput_line_open(struct libscols_table *tb); -extern void fput_line_close(struct libscols_table *tb, int last, int last_in_table); - -static inline int is_tree_root(struct libscols_line *ln) -{ - return ln && !ln->parent && !ln->parent_group; -} - -static inline int is_last_tree_root(struct libscols_table *tb, struct libscols_line *ln) -{ - if (!ln || !tb || tb->walk_last_tree_root != ln) - return 0; - - return 1; -} - -static inline int is_child(struct libscols_line *ln) -{ - return ln && ln->parent; -} - -static inline int is_last_child(struct libscols_line *ln) -{ - if (!ln || !ln->parent) - return 0; - - return list_entry_is_last(&ln->ln_children, &ln->parent->ln_branch); -} - -static inline int is_first_child(struct libscols_line *ln) -{ - if (!ln || !ln->parent) - return 0; - - return list_entry_is_first(&ln->ln_children, &ln->parent->ln_branch); -} - - -static inline int is_last_column(struct libscols_column *cl) -{ - struct libscols_column *next; - - if (list_entry_is_last(&cl->cl_columns, &cl->table->tb_columns)) - return 1; - - next = list_entry(cl->cl_columns.next, struct libscols_column, cl_columns); - if (next && scols_column_is_hidden(next) && is_last_column(next)) - return 1; - return 0; -} - -static inline int is_last_group_member(struct libscols_line *ln) -{ - if (!ln || !ln->group) - return 0; - - return list_entry_is_last(&ln->ln_groups, &ln->group->gr_members); -} - -static inline int is_first_group_member(struct libscols_line *ln) -{ - if (!ln || !ln->group) - return 0; - - return list_entry_is_first(&ln->ln_groups, &ln->group->gr_members); -} - -static inline int is_group_member(struct libscols_line *ln) -{ - return ln && ln->group; -} - -static inline int is_last_group_child(struct libscols_line *ln) -{ - if (!ln || !ln->parent_group) - return 0; - - return list_entry_is_last(&ln->ln_children, &ln->parent_group->gr_children); -} - -static inline int is_group_child(struct libscols_line *ln) -{ - return ln && ln->parent_group; -} - -static inline int has_groups(struct libscols_table *tb) -{ - return tb && !list_empty(&tb->tb_groups); -} - -static inline int has_children(struct libscols_line *ln) -{ - return ln && !list_empty(&ln->ln_branch); -} - -static inline int has_group_children(struct libscols_line *ln) -{ - return ln && ln->group && !list_empty(&ln->group->gr_children); -} - -#endif /* _LIBSMARTCOLS_PRIVATE_H */ diff --git a/utils/libsmartcols/src/symbols.c b/utils/libsmartcols/src/symbols.c deleted file mode 100644 index 2fadfc7..0000000 --- a/utils/libsmartcols/src/symbols.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * symbols.c - routines for symbol handling - * - * Copyright (C) 2014 Ondrej Oprala <ooprala@redhat.com> - * Copyright (C) 2016 Igor Gnatenko <i.gnatenko.brain@gmail.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -/** - * SECTION: symbols - * @title: Symbols - * @short_description: can be used to overwrite default output chars (for ascii art) - * - * An API to access and modify data and information per symbol/symbol group. - */ - - -#include <stdlib.h> -#include <unistd.h> -#include <string.h> - -#include "smartcolsP.h" - -/** - * scols_new_symbols: - * - * Returns: a pointer to a newly allocated struct libscols_symbols instance. - */ -struct libscols_symbols *scols_new_symbols(void) -{ - struct libscols_symbols *sy = calloc(1, sizeof(struct libscols_symbols)); - - if (!sy) - return NULL; - sy->refcount = 1; - return sy; -} - -/** - * scols_ref_symbols: - * @sy: a pointer to a struct libscols_symbols instance - * - * Increases the refcount of @sy. - */ -void scols_ref_symbols(struct libscols_symbols *sy) -{ - if (sy) - sy->refcount++; -} - -/** - * scols_unref_symbols: - * @sy: a pointer to a struct libscols_symbols instance - * - * Decreases the refcount of @sy. - */ -void scols_unref_symbols(struct libscols_symbols *sy) -{ - if (sy && --sy->refcount <= 0) { - free(sy->tree_branch); - free(sy->tree_vert); - free(sy->tree_right); - free(sy->group_last_member); - free(sy->group_middle_member); - free(sy->group_first_member); - free(sy->group_vert); - free(sy->group_horz); - free(sy->group_last_child); - free(sy->group_middle_child); - free(sy->title_padding); - free(sy->cell_padding); - free(sy); - } -} - -/** - * scols_symbols_set_branch: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent the branch part of a tree output - * - * Returns: 0, a negative value in case of an error. - */ -int scols_symbols_set_branch(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, tree_branch, str); -} - -/** - * scols_symbols_set_vertical: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent the vertical part of a tree output - * - * Returns: 0, a negative value in case of an error. - */ -int scols_symbols_set_vertical(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, tree_vert, str); -} - -/** - * scols_symbols_set_right: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent the right part of a tree output - * - * Returns: 0, a negative value in case of an error. - */ -int scols_symbols_set_right(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, tree_right, str); -} - -/** - * scols_symbols_set_title_padding: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent the symbols which fill title output - * - * The current implementation uses only the first byte from the padding string. - * A multibyte chars are not supported yet. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.28 - */ -int scols_symbols_set_title_padding(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, title_padding, str); -} - -/** - * scols_symbols_set_cell_padding: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent the symbols which fill cells - * - * The padding char has to take up just one cell on the terminal. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.29 - */ -int scols_symbols_set_cell_padding(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, cell_padding, str); -} - - -/** - * scols_symbols_set_group_vertical: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent the vertival line - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.34 - */ -int scols_symbols_set_group_vertical(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, group_vert, str); -} - -/** - * scols_symbols_set_group_horizontal: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent the horizontal line - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.34 - */ -int scols_symbols_set_group_horizontal(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, group_horz, str); -} - -/** - * scols_symbols_set_group_first_member: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent first member - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.34 - */ -int scols_symbols_set_group_first_member(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, group_first_member, str); -} - -/** - * scols_symbols_set_group_last_member: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent last member - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.34 - */ -int scols_symbols_set_group_last_member(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, group_last_member, str); -} - -/** - * scols_symbols_set_group_middle: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent middle member - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.34 - */ -int scols_symbols_set_group_middle_member(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, group_middle_member, str); -} - -/** - * scols_symbols_set_group_last_child: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent last child - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.34 - */ -int scols_symbols_set_group_last_child(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, group_last_child, str); -} - -/** - * scols_symbols_set_group_middle_child: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent last child - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.34 - */ -int scols_symbols_set_group_middle_child(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, group_middle_child, str); -} - -/** - * scols_copy_symbols: - * @sy: a pointer to a struct libscols_symbols instance - * - * Returns: a newly allocated copy of the @sy symbol group or NULL in case of an error. - */ -struct libscols_symbols *scols_copy_symbols(const struct libscols_symbols *sy) -{ - struct libscols_symbols *ret; - int rc; - - assert(sy); - if (!sy) - return NULL; - - ret = scols_new_symbols(); - if (!ret) - return NULL; - - rc = scols_symbols_set_branch(ret, sy->tree_branch); - if (!rc) - rc = scols_symbols_set_vertical(ret, sy->tree_vert); - if (!rc) - rc = scols_symbols_set_right(ret, sy->tree_right); - if (!rc) - rc = scols_symbols_set_group_vertical(ret, sy->group_vert); - if (!rc) - rc = scols_symbols_set_group_horizontal(ret, sy->group_horz); - if (!rc) - rc = scols_symbols_set_group_first_member(ret, sy->group_first_member); - if (!rc) - rc = scols_symbols_set_group_last_member(ret, sy->group_last_member); - if (!rc) - rc = scols_symbols_set_group_middle_member(ret, sy->group_middle_member); - if (!rc) - rc = scols_symbols_set_group_middle_child(ret, sy->group_middle_child); - if (!rc) - rc = scols_symbols_set_group_last_child(ret, sy->group_last_child); - if (!rc) - rc = scols_symbols_set_title_padding(ret, sy->title_padding); - if (!rc) - rc = scols_symbols_set_cell_padding(ret, sy->cell_padding); - if (!rc) - return ret; - - scols_unref_symbols(ret); - return NULL; -} diff --git a/utils/libsmartcols/src/table.c b/utils/libsmartcols/src/table.c deleted file mode 100644 index a3ba21d..0000000 --- a/utils/libsmartcols/src/table.c +++ /dev/null @@ -1,1691 +0,0 @@ -/* - * table.c - functions handling the data at the table level - * - * Copyright (C) 2010-2014 Karel Zak <kzak@redhat.com> - * Copyright (C) 2014 Ondrej Oprala <ooprala@redhat.com> - * Copyright (C) 2016 Igor Gnatenko <i.gnatenko.brain@gmail.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -/** - * SECTION: table - * @title: Table - * @short_description: container for rows and columns - * - * Table data manipulation API. - */ - - -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <termios.h> -#include <ctype.h> - -#include "nls.h" -#include "ttyutils.h" -#include "smartcolsP.h" - -#ifdef HAVE_WIDECHAR -#define UTF_V "\342\224\202" /* U+2502, Vertical line drawing char | */ -#define UTF_VR "\342\224\234" /* U+251C, Vertical and right |- */ -#define UTF_H "\342\224\200" /* U+2500, Horizontal - */ -#define UTF_UR "\342\224\224" /* U+2514, Up and right '- */ - -#define UTF_V3 "\342\224\206" /* U+2506 Triple Dash Vertical | */ -#define UTF_H3 "\342\224\210" /* U+2504 Triple Dash Horizontal - */ -#define UTF_DR "\342\224\214" /* U+250C Down and Right ,- */ -#define UTF_DH "\342\224\254" /* U+252C Down and Horizontal |' */ - -#define UTF_TR "\342\226\266" /* U+25B6 Black Right-Pointing Triangle > */ -#endif /* !HAVE_WIDECHAR */ - -#define is_last_column(_tb, _cl) \ - list_entry_is_last(&(_cl)->cl_columns, &(_tb)->tb_columns) - - -static void check_padding_debug(struct libscols_table *tb) -{ - const char *str; - - assert(libsmartcols_debug_mask); /* debug has to be enabled! */ - - str = getenv("LIBSMARTCOLS_DEBUG_PADDING"); - if (!str || (strcmp(str, "on") != 0 && strcmp(str, "1") != 0)) - return; - - DBG(INIT, ul_debugobj(tb, "padding debug: ENABLE")); - tb->padding_debug = 1; -} - -/** - * scols_new_table: - * - * Returns: A newly allocated table. - */ -struct libscols_table *scols_new_table(void) -{ - struct libscols_table *tb; - int c, l; - - tb = calloc(1, sizeof(struct libscols_table)); - if (!tb) - return NULL; - - tb->refcount = 1; - tb->out = stdout; - - get_terminal_dimension(&c, &l); - tb->termwidth = c > 0 ? c : 80; - tb->termheight = l > 0 ? l : 24; - - INIT_LIST_HEAD(&tb->tb_lines); - INIT_LIST_HEAD(&tb->tb_columns); - INIT_LIST_HEAD(&tb->tb_groups); - - DBG(TAB, ul_debugobj(tb, "alloc")); - ON_DBG(INIT, check_padding_debug(tb)); - - return tb; -} - -/** - * scols_ref_table: - * @tb: a pointer to a struct libscols_table instance - * - * Increases the refcount of @tb. - */ -void scols_ref_table(struct libscols_table *tb) -{ - if (tb) - tb->refcount++; -} - -static void scols_table_remove_groups(struct libscols_table *tb) -{ - while (!list_empty(&tb->tb_groups)) { - struct libscols_group *gr = list_entry(tb->tb_groups.next, - struct libscols_group, gr_groups); - scols_group_remove_children(gr); - scols_group_remove_members(gr); - scols_unref_group(gr); - } -} - -/** - * scols_unref_table: - * @tb: a pointer to a struct libscols_table instance - * - * Decreases the refcount of @tb. When the count falls to zero, the instance - * is automatically deallocated. - */ -void scols_unref_table(struct libscols_table *tb) -{ - if (tb && (--tb->refcount <= 0)) { - DBG(TAB, ul_debugobj(tb, "dealloc <-")); - scols_table_remove_groups(tb); - scols_table_remove_lines(tb); - scols_table_remove_columns(tb); - scols_unref_symbols(tb->symbols); - scols_reset_cell(&tb->title); - free(tb->grpset); - free(tb->linesep); - free(tb->colsep); - free(tb->name); - free(tb); - DBG(TAB, ul_debug("<- done")); - } -} - -/* Private API */ -int scols_table_next_group(struct libscols_table *tb, - struct libscols_iter *itr, - struct libscols_group **gr) -{ - int rc = 1; - - if (!tb || !itr || !gr) - return -EINVAL; - *gr = NULL; - - if (!itr->head) - SCOLS_ITER_INIT(itr, &tb->tb_groups); - if (itr->p != itr->head) { - SCOLS_ITER_ITERATE(itr, *gr, struct libscols_group, gr_groups); - rc = 0; - } - - return rc; -} - -/** - * scols_table_set_name: - * @tb: a pointer to a struct libscols_table instance - * @name: a name - * - * The table name is used for example for JSON top level object name. - * - * Returns: 0, a negative number in case of an error. - * - * Since: 2.27 - */ -int scols_table_set_name(struct libscols_table *tb, const char *name) -{ - return strdup_to_struct_member(tb, name, name); -} - -/** - * scols_table_get_name: - * @tb: a pointer to a struct libscols_table instance - * - * Returns: The current name setting of the table @tb - * - * Since: 2.29 - */ -const char *scols_table_get_name(const struct libscols_table *tb) -{ - return tb->name; -} - -/** - * scols_table_get_title: - * @tb: a pointer to a struct libscols_table instance - * - * The returned pointer is possible to modify by cell functions. Note that - * title output alignment on non-tty is hardcoded to 80 output chars. For the - * regular terminal it's based on terminal width. - * - * Returns: Title of the table, or NULL in case of blank title. - * - * Since: 2.28 - */ -struct libscols_cell *scols_table_get_title(struct libscols_table *tb) -{ - return &tb->title; -} - -/** - * scols_table_add_column: - * @tb: a pointer to a struct libscols_table instance - * @cl: a pointer to a struct libscols_column instance - * - * Adds @cl to @tb's column list. The column cannot be shared between more - * tables. - * - * Returns: 0, a negative number in case of an error. - */ -int scols_table_add_column(struct libscols_table *tb, struct libscols_column *cl) -{ - struct libscols_iter itr; - struct libscols_line *ln; - int rc = 0; - - if (!tb || !cl || cl->table) - return -EINVAL; - - if (!list_empty(&cl->cl_columns)) - return -EINVAL; - - if (cl->flags & SCOLS_FL_TREE) - tb->ntreecols++; - - DBG(TAB, ul_debugobj(tb, "add column")); - list_add_tail(&cl->cl_columns, &tb->tb_columns); - cl->seqnum = tb->ncols++; - cl->table = tb; - scols_ref_column(cl); - - if (list_empty(&tb->tb_lines)) - return 0; - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - - /* Realloc line cell arrays - */ - while (scols_table_next_line(tb, &itr, &ln) == 0) { - rc = scols_line_alloc_cells(ln, tb->ncols); - if (rc) - break; - } - - return rc; -} - -/** - * scols_table_remove_column: - * @tb: a pointer to a struct libscols_table instance - * @cl: a pointer to a struct libscols_column instance - * - * Removes @cl from @tb. - * - * Returns: 0, a negative number in case of an error. - */ -int scols_table_remove_column(struct libscols_table *tb, - struct libscols_column *cl) -{ - if (!tb || !cl || !list_empty(&tb->tb_lines)) - return -EINVAL; - - if (cl->flags & SCOLS_FL_TREE) - tb->ntreecols--; - - DBG(TAB, ul_debugobj(tb, "remove column")); - list_del_init(&cl->cl_columns); - tb->ncols--; - cl->table = NULL; - scols_unref_column(cl); - return 0; -} - -/** - * scols_table_remove_columns: - * @tb: a pointer to a struct libscols_table instance - * - * Removes all of @tb's columns. - * - * Returns: 0, a negative number in case of an error. - */ -int scols_table_remove_columns(struct libscols_table *tb) -{ - if (!tb || !list_empty(&tb->tb_lines)) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "remove all columns")); - while (!list_empty(&tb->tb_columns)) { - struct libscols_column *cl = list_entry(tb->tb_columns.next, - struct libscols_column, cl_columns); - scols_table_remove_column(tb, cl); - } - return 0; -} - -/** - * scols_table_move_column: - * @tb: table - * @pre: column before the column - * @cl: column to move - * - * Move the @cl behind @pre. If the @pre is NULL then the @col is the first - * column in the table. - * - * Since: 2.30 - * - * Returns: 0, a negative number in case of an error. - */ -int scols_table_move_column(struct libscols_table *tb, - struct libscols_column *pre, - struct libscols_column *cl) -{ - struct list_head *head; - struct libscols_iter itr; - struct libscols_column *p; - struct libscols_line *ln; - size_t n = 0, oldseq; - - if (!tb || !cl) - return -EINVAL; - - if (pre && pre->seqnum + 1 == cl->seqnum) - return 0; - if (pre == NULL && cl->seqnum == 0) - return 0; - - DBG(TAB, ul_debugobj(tb, "move column %zu behind %zu", - cl->seqnum, pre? pre->seqnum : 0)); - - list_del_init(&cl->cl_columns); /* remove from old position */ - - head = pre ? &pre->cl_columns : &tb->tb_columns; - list_add(&cl->cl_columns, head); /* add to the new place */ - - oldseq = cl->seqnum; - - /* fix seq. numbers */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_column(tb, &itr, &p) == 0) - p->seqnum = n++; - - /* move data in lines */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_line(tb, &itr, &ln) == 0) - scols_line_move_cells(ln, cl->seqnum, oldseq); - return 0; -} - -/** - * scols_table_new_column: - * @tb: table - * @name: column header - * @whint: column width hint (absolute width: N > 1; relative width: 0 < N < 1) - * @flags: flags integer - * - * This is shortcut for - * - * cl = scols_new_column(); - * scols_column_set_....(cl, ...); - * scols_table_add_column(tb, cl); - * - * The column width is possible to define by: - * - * @whint: 0 < N < 1 : relative width, percent of terminal width - * - * @whint: N >= 1 : absolute width, empty column will be truncated to - * the column header width if no specified STRICTWIDTH flag - * - * Note that if table has disabled "maxout" flag (disabled by default) than - * relative width is used as a hint only. It's possible that column will be - * narrow if the specified size is too large for column data. - * - * - * If the width of all columns is greater than terminal width then library - * tries to reduce width of the individual columns. It's done in three stages: - * - * #1 reduce columns with SCOLS_FL_TRUNC flag and with relative width if the - * width is greater than width defined by @whint (@whint * terminal_width) - * - * #2 reduce all columns with SCOLS_FL_TRUNC flag - * - * #3 reduce all columns with relative width - * - * The next stage is always used if the previous stage is unsuccessful. Note - * that SCOLS_FL_WRAP is interpreted as SCOLS_FL_TRUNC when calculate column - * width (if custom wrap function is not specified), but the final text is not - * truncated, but wrapped to multi-line cell. - * - * - * The column is necessary to address by sequential number. The first defined - * column has the colnum = 0. For example: - * - * scols_table_new_column(tab, "FOO", 0.5, 0); // colnum = 0 - * scols_table_new_column(tab, "BAR", 0.5, 0); // colnum = 1 - * . - * . - * scols_line_get_cell(line, 0); // FOO column - * scols_line_get_cell(line, 1); // BAR column - * - * Returns: newly allocated column - */ -struct libscols_column *scols_table_new_column(struct libscols_table *tb, - const char *name, - double whint, - int flags) -{ - struct libscols_column *cl; - struct libscols_cell *hr; - - if (!tb) - return NULL; - - DBG(TAB, ul_debugobj(tb, "new column name=%s, whint=%g, flags=%d", - name, whint, flags)); - cl = scols_new_column(); - if (!cl) - return NULL; - - /* set column name */ - hr = scols_column_get_header(cl); - if (!hr) - goto err; - if (scols_cell_set_data(hr, name)) - goto err; - - scols_column_set_whint(cl, whint); - scols_column_set_flags(cl, flags); - - if (scols_table_add_column(tb, cl)) /* this increments column ref-counter */ - goto err; - - scols_unref_column(cl); - return cl; -err: - scols_unref_column(cl); - return NULL; -} - -/** - * scols_table_next_column: - * @tb: a pointer to a struct libscols_table instance - * @itr: a pointer to a struct libscols_iter instance - * @cl: a pointer to a pointer to a struct libscols_column instance - * - * Returns the next column of @tb via @cl. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_table_next_column(struct libscols_table *tb, - struct libscols_iter *itr, - struct libscols_column **cl) -{ - int rc = 1; - - if (!tb || !itr || !cl) - return -EINVAL; - *cl = NULL; - - if (!itr->head) - SCOLS_ITER_INIT(itr, &tb->tb_columns); - if (itr->p != itr->head) { - SCOLS_ITER_ITERATE(itr, *cl, struct libscols_column, cl_columns); - rc = 0; - } - - return rc; -} - -/** - * scols_table_set_columns_iter: - * @tb: tab pointer - * @itr: iterator - * @cl: tab entry - * - * Sets @iter to the position of @cl in the file @tb. - * - * Returns: 0 on success, negative number in case of error. - * - * Since: 2.35 - */ -int scols_table_set_columns_iter( - struct libscols_table *tb, - struct libscols_iter *itr, - struct libscols_column *cl) -{ - if (!tb || !itr || !cl) - return -EINVAL; - - if (cl->table != tb) - return -EINVAL; - - SCOLS_ITER_INIT(itr, &tb->tb_columns); - itr->p = &cl->cl_columns; - - return 0; -} - -/** - * scols_table_get_ncols: - * @tb: table - * - * Returns: the ncols table member. - */ -size_t scols_table_get_ncols(const struct libscols_table *tb) -{ - return tb->ncols; -} - -/** - * scols_table_get_nlines: - * @tb: table - * - * Returns: the nlines table member. - */ -size_t scols_table_get_nlines(const struct libscols_table *tb) -{ - return tb->nlines; -} - -/** - * scols_table_set_stream: - * @tb: table - * @stream: output stream - * - * Sets the output stream for table @tb. - * - * Returns: 0, a negative number in case of an error. - */ -int scols_table_set_stream(struct libscols_table *tb, FILE *stream) -{ - assert(tb); - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "setting alternative stream")); - tb->out = stream; - return 0; -} - -/** - * scols_table_get_stream: - * @tb: table - * - * Gets the output stream for table @tb. - * - * Returns: stream pointer, NULL in case of an error or an unset stream. - */ -FILE *scols_table_get_stream(const struct libscols_table *tb) -{ - return tb->out; -} - -/** - * scols_table_reduce_termwidth: - * @tb: table - * @reduce: width - * - * If necessary then libsmartcols use all terminal width, the @reduce setting - * provides extra space (for example for borders in ncurses applications). - * - * The @reduce must be smaller than terminal width, otherwise it's silently - * ignored. The reduction is not applied when STDOUT_FILENO is not terminal. - * - * Note that after output initialization (scols_table_print_* calls) the width - * will be reduced, this behavior affects subsequenced scols_table_get_termwidth() - * calls. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_table_reduce_termwidth(struct libscols_table *tb, size_t reduce) -{ - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "reduce terminal width: %zu", reduce)); - tb->termreduce = reduce; - return 0; -} - -/** - * scols_table_get_column: - * @tb: table - * @n: number of column (0..N) - * - * Returns: pointer to column or NULL - */ -struct libscols_column *scols_table_get_column(struct libscols_table *tb, - size_t n) -{ - struct libscols_iter itr; - struct libscols_column *cl; - - if (!tb) - return NULL; - if (n >= tb->ncols) - return NULL; - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_column(tb, &itr, &cl) == 0) { - if (cl->seqnum == n) - return cl; - } - return NULL; -} - -/** - * scols_table_add_line: - * @tb: table - * @ln: line - * - * Note that this function calls scols_line_alloc_cells() if number - * of the cells in the line is too small for @tb. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_table_add_line(struct libscols_table *tb, struct libscols_line *ln) -{ - if (!tb || !ln) - return -EINVAL; - - if (!list_empty(&ln->ln_lines)) - return -EINVAL; - - if (tb->ncols > ln->ncells) { - int rc = scols_line_alloc_cells(ln, tb->ncols); - if (rc) - return rc; - } - - DBG(TAB, ul_debugobj(tb, "add line")); - list_add_tail(&ln->ln_lines, &tb->tb_lines); - ln->seqnum = tb->nlines++; - scols_ref_line(ln); - return 0; -} - -/** - * scols_table_remove_line: - * @tb: table - * @ln: line - * - * Note that this function does not destroy the parent<->child relationship between lines. - * You have to call scols_line_remove_child() - * - * Returns: 0, a negative value in case of an error. - */ -int scols_table_remove_line(struct libscols_table *tb, - struct libscols_line *ln) -{ - if (!tb || !ln) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "remove line")); - list_del_init(&ln->ln_lines); - tb->nlines--; - scols_unref_line(ln); - return 0; -} - -/** - * scols_table_remove_lines: - * @tb: table - * - * This empties the table and also destroys all the parent<->child relationships. - */ -void scols_table_remove_lines(struct libscols_table *tb) -{ - if (!tb) - return; - - DBG(TAB, ul_debugobj(tb, "remove all lines")); - while (!list_empty(&tb->tb_lines)) { - struct libscols_line *ln = list_entry(tb->tb_lines.next, - struct libscols_line, ln_lines); - if (ln->parent) - scols_line_remove_child(ln->parent, ln); - scols_table_remove_line(tb, ln); - } -} - -/** - * scols_table_next_line: - * @tb: a pointer to a struct libscols_table instance - * @itr: a pointer to a struct libscols_iter instance - * @ln: a pointer to a pointer to a struct libscols_line instance - * - * Finds the next line and returns a pointer to it via @ln. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_table_next_line(struct libscols_table *tb, - struct libscols_iter *itr, - struct libscols_line **ln) -{ - int rc = 1; - - if (!tb || !itr || !ln) - return -EINVAL; - *ln = NULL; - - if (!itr->head) - SCOLS_ITER_INIT(itr, &tb->tb_lines); - if (itr->p != itr->head) { - SCOLS_ITER_ITERATE(itr, *ln, struct libscols_line, ln_lines); - rc = 0; - } - - return rc; -} - -/** - * scols_table_new_line: - * @tb: table - * @parent: parental line or NULL - * - * This is shortcut for - * - * ln = scols_new_line(); - * scols_table_add_line(tb, ln); - * scols_line_add_child(parent, ln); - * - * - * Returns: newly allocate line - */ -struct libscols_line *scols_table_new_line(struct libscols_table *tb, - struct libscols_line *parent) -{ - struct libscols_line *ln; - - if (!tb) - return NULL; - - ln = scols_new_line(); - if (!ln) - return NULL; - - if (scols_table_add_line(tb, ln)) - goto err; - if (parent) - scols_line_add_child(parent, ln); - - scols_unref_line(ln); /* ref-counter incremented by scols_table_add_line() */ - return ln; -err: - scols_unref_line(ln); - return NULL; -} - -/** - * scols_table_get_line: - * @tb: table - * @n: column number (0..N) - * - * Returns: a line or NULL - */ -struct libscols_line *scols_table_get_line(struct libscols_table *tb, - size_t n) -{ - struct libscols_iter itr; - struct libscols_line *ln; - - if (!tb) - return NULL; - if (n >= tb->nlines) - return NULL; - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_line(tb, &itr, &ln) == 0) { - if (ln->seqnum == n) - return ln; - } - return NULL; -} - -/** - * scols_copy_table: - * @tb: table - * - * Creates a new independent table copy, except struct libscols_symbols that - * are shared between the tables. - * - * Returns: a newly allocated copy of @tb - */ -struct libscols_table *scols_copy_table(struct libscols_table *tb) -{ - struct libscols_table *ret; - struct libscols_line *ln; - struct libscols_column *cl; - struct libscols_iter itr; - - if (!tb) - return NULL; - ret = scols_new_table(); - if (!ret) - return NULL; - - DBG(TAB, ul_debugobj(tb, "copy")); - - if (tb->symbols) - scols_table_set_symbols(ret, tb->symbols); - - /* columns */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_column(tb, &itr, &cl) == 0) { - cl = scols_copy_column(cl); - if (!cl) - goto err; - if (scols_table_add_column(ret, cl)) - goto err; - scols_unref_column(cl); - } - - /* lines */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_line(tb, &itr, &ln) == 0) { - struct libscols_line *newln = scols_copy_line(ln); - if (!newln) - goto err; - if (scols_table_add_line(ret, newln)) - goto err; - if (ln->parent) { - struct libscols_line *p = - scols_table_get_line(ret, ln->parent->seqnum); - if (p) - scols_line_add_child(p, newln); - } - scols_unref_line(newln); - } - - /* separators */ - if (scols_table_set_column_separator(ret, tb->colsep) || - scols_table_set_line_separator(ret, tb->linesep)) - goto err; - - return ret; -err: - scols_unref_table(ret); - return NULL; -} - -/** - * scols_table_set_default_symbols: - * @tb: table - * - * The library check the current environment to select ASCII or UTF8 symbols. - * This default behavior could be controlled by scols_table_enable_ascii(). - * - * Use scols_table_set_symbols() to unset symbols or use your own setting. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.29 - */ -int scols_table_set_default_symbols(struct libscols_table *tb) -{ - struct libscols_symbols *sy; - int rc; - - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "setting default symbols")); - - sy = scols_new_symbols(); - if (!sy) - return -ENOMEM; - -#if defined(HAVE_WIDECHAR) - if (!scols_table_is_ascii(tb) && - !strcmp(nl_langinfo(CODESET), "UTF-8")) { - /* tree chart */ - scols_symbols_set_branch(sy, UTF_VR UTF_H); - scols_symbols_set_vertical(sy, UTF_V " "); - scols_symbols_set_right(sy, UTF_UR UTF_H); - /* groups chart */ - scols_symbols_set_group_horizontal(sy, UTF_H3); - scols_symbols_set_group_vertical(sy, UTF_V3); - - scols_symbols_set_group_first_member(sy, UTF_DR UTF_H3 UTF_TR); - scols_symbols_set_group_last_member(sy, UTF_UR UTF_DH UTF_TR); - scols_symbols_set_group_middle_member(sy, UTF_VR UTF_H3 UTF_TR); - scols_symbols_set_group_last_child(sy, UTF_UR UTF_H3); - scols_symbols_set_group_middle_child(sy, UTF_VR UTF_H3); - } else -#endif - { - /* tree chart */ - scols_symbols_set_branch(sy, "|-"); - scols_symbols_set_vertical(sy, "| "); - scols_symbols_set_right(sy, "`-"); - /* groups chart */ - scols_symbols_set_group_horizontal(sy, "-"); - scols_symbols_set_group_vertical(sy, "|"); - - scols_symbols_set_group_first_member(sy, ",->"); - scols_symbols_set_group_last_member(sy, "'->"); - scols_symbols_set_group_middle_member(sy, "|->"); - scols_symbols_set_group_last_child(sy, "`-"); - scols_symbols_set_group_middle_child(sy, "|-"); - } - scols_symbols_set_title_padding(sy, " "); - scols_symbols_set_cell_padding(sy, " "); - - rc = scols_table_set_symbols(tb, sy); - scols_unref_symbols(sy); - return rc; -} - - -/** - * scols_table_set_symbols: - * @tb: table - * @sy: symbols or NULL - * - * Add a reference to @sy from the table. The symbols are used by library to - * draw tree output. If no symbols are used for the table then library creates - * default temporary symbols to draw output by scols_table_set_default_symbols(). - * - * If @sy is NULL then remove reference from the currently used symbols. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_table_set_symbols(struct libscols_table *tb, - struct libscols_symbols *sy) -{ - if (!tb) - return -EINVAL; - - /* remove old */ - if (tb->symbols) { - DBG(TAB, ul_debugobj(tb, "remove symbols reference")); - scols_unref_symbols(tb->symbols); - tb->symbols = NULL; - } - - /* set new */ - if (sy) { /* ref user defined */ - DBG(TAB, ul_debugobj(tb, "set symbols")); - tb->symbols = sy; - scols_ref_symbols(sy); - } - return 0; -} - -/** - * scols_table_get_symbols: - * @tb: table - * - * Returns: pointer to symbols table. - * - * Since: 2.29 - */ -struct libscols_symbols *scols_table_get_symbols(const struct libscols_table *tb) -{ - return tb->symbols; -} - -/** - * scols_table_enable_nolinesep: - * @tb: table - * @enable: 1 or 0 - * - * Enable/disable line separator printing. This is useful if you want to - * re-printing the same line more than once (e.g. progress bar). Don't use it - * if you're not sure. - * - * Note that for the last line in the table the separator is disabled at all. - * The library differentiate between table terminator and line terminator - * (although for standard output \n byte is used in both cases). - * - * Returns: 0 on success, negative number in case of an error. - */ -int scols_table_enable_nolinesep(struct libscols_table *tb, int enable) -{ - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "nolinesep: %s", enable ? "ENABLE" : "DISABLE")); - tb->no_linesep = enable ? 1 : 0; - return 0; -} - -/** - * scols_table_is_nolinesep: - * @tb: a pointer to a struct libscols_table instance - * - * Returns: 1 if line separator printing is disabled. - * - * Since: 2.29 - */ -int scols_table_is_nolinesep(const struct libscols_table *tb) -{ - return tb->no_linesep; -} - -/** - * scols_table_enable_colors: - * @tb: table - * @enable: 1 or 0 - * - * Enable/disable colors. - * - * Returns: 0 on success, negative number in case of an error. - */ -int scols_table_enable_colors(struct libscols_table *tb, int enable) -{ - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "colors: %s", enable ? "ENABLE" : "DISABLE")); - tb->colors_wanted = enable; - return 0; -} - -/** - * scols_table_enable_raw: - * @tb: table - * @enable: 1 or 0 - * - * Enable/disable raw output format. The parsable output formats - * (export, raw, JSON, ...) are mutually exclusive. - * - * Returns: 0 on success, negative number in case of an error. - */ -int scols_table_enable_raw(struct libscols_table *tb, int enable) -{ - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "raw: %s", enable ? "ENABLE" : "DISABLE")); - if (enable) - tb->format = SCOLS_FMT_RAW; - else if (tb->format == SCOLS_FMT_RAW) - tb->format = 0; - return 0; -} - -/** - * scols_table_enable_json: - * @tb: table - * @enable: 1 or 0 - * - * Enable/disable JSON output format. The parsable output formats - * (export, raw, JSON, ...) are mutually exclusive. - * - * Returns: 0 on success, negative number in case of an error. - * - * Since: 2.27 - */ -int scols_table_enable_json(struct libscols_table *tb, int enable) -{ - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "json: %s", enable ? "ENABLE" : "DISABLE")); - if (enable) - tb->format = SCOLS_FMT_JSON; - else if (tb->format == SCOLS_FMT_JSON) - tb->format = 0; - return 0; -} - -/** - * scols_table_enable_export: - * @tb: table - * @enable: 1 or 0 - * - * Enable/disable export output format (COLUMNAME="value" ...). - * The parsable output formats (export and raw) are mutually exclusive. - * - * Returns: 0 on success, negative number in case of an error. - */ -int scols_table_enable_export(struct libscols_table *tb, int enable) -{ - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "export: %s", enable ? "ENABLE" : "DISABLE")); - if (enable) - tb->format = SCOLS_FMT_EXPORT; - else if (tb->format == SCOLS_FMT_EXPORT) - tb->format = 0; - return 0; -} - -/** - * scols_table_enable_ascii: - * @tb: table - * @enable: 1 or 0 - * - * The ASCII-only output is relevant for tree-like outputs. The library - * checks if the current environment is UTF8 compatible by default. This - * function overrides this check and force the library to use ASCII chars - * for the tree. - * - * If a custom libcols_symbols are specified (see scols_table_set_symbols() - * then ASCII flag setting is ignored. - * - * Returns: 0 on success, negative number in case of an error. - */ -int scols_table_enable_ascii(struct libscols_table *tb, int enable) -{ - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "ascii: %s", enable ? "ENABLE" : "DISABLE")); - tb->ascii = enable ? 1 : 0; - return 0; -} - -/** - * scols_table_enable_noheadings: - * @tb: table - * @enable: 1 or 0 - * - * Enable/disable header line. - * - * Returns: 0 on success, negative number in case of an error. - */ -int scols_table_enable_noheadings(struct libscols_table *tb, int enable) -{ - if (!tb) - return -EINVAL; - DBG(TAB, ul_debugobj(tb, "noheading: %s", enable ? "ENABLE" : "DISABLE")); - tb->no_headings = enable ? 1 : 0; - return 0; -} - -/** - * scols_table_enable_header_repeat: - * @tb: table - * @enable: 1 or 0 - * - * Enable/disable header line repeat. The header line is printed only once by - * default. Note that the flag will be silently ignored and disabled if the - * output is not on terminal or output format is JSON, raw, etc. - * - * Returns: 0 on success, negative number in case of an error. - * - * Since: 2.31 - */ -int scols_table_enable_header_repeat(struct libscols_table *tb, int enable) -{ - if (!tb) - return -EINVAL; - DBG(TAB, ul_debugobj(tb, "header-repeat: %s", enable ? "ENABLE" : "DISABLE")); - tb->header_repeat = enable ? 1 : 0; - return 0; -} - -/** - * scols_table_enable_maxout: - * @tb: table - * @enable: 1 or 0 - * - * The extra space after last column is ignored by default. The output - * maximization add padding for all columns. - * - * This setting is mutually exclusive to scols_table_enable_minout(). - * - * Returns: 0 on success, negative number in case of an error. - */ -int scols_table_enable_maxout(struct libscols_table *tb, int enable) -{ - if (!tb || tb->minout) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "maxout: %s", enable ? "ENABLE" : "DISABLE")); - tb->maxout = enable ? 1 : 0; - return 0; -} - -/** - * scols_table_enable_minout: - * @tb: table - * @enable: 1 or 0 - * - * Force library to terminate line after last column with data. The extra - * padding is not added to the empty cells at the end of the line. The default is fill - * tailing empty cells except the last line cell. - * - * This setting is mutually exclusive to scols_table_enable_maxout(). - * - * Returns: 0 on success, negative number in case of an error. - * - * Since: 2.35 - */ -int scols_table_enable_minout(struct libscols_table *tb, int enable) -{ - if (!tb || tb->maxout) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "minout: %s", enable ? "ENABLE" : "DISABLE")); - tb->minout = enable ? 1 : 0; - return 0; -} - -/** - * scols_table_enable_nowrap: - * @tb: table - * @enable: 1 or 0 - * - * Never continue on next line, remove last column(s) when too large, truncate last column. - * - * Returns: 0 on success, negative number in case of an error. - * - * Since: 2.28 - */ -int scols_table_enable_nowrap(struct libscols_table *tb, int enable) -{ - if (!tb) - return -EINVAL; - DBG(TAB, ul_debugobj(tb, "nowrap: %s", enable ? "ENABLE" : "DISABLE")); - tb->no_wrap = enable ? 1 : 0; - return 0; -} - -/** - * scols_table_is_nowrap: - * @tb: a pointer to a struct libscols_table instance - * - * Returns: 1 if nowrap is enabled. - * - * Since: 2.29 - */ -int scols_table_is_nowrap(const struct libscols_table *tb) -{ - return tb->no_wrap; -} - -/** - * scols_table_enable_noencoding: - * @tb: table - * @enable: 1 or 0 - * - * The library encode non-printable and control chars by \xHEX by default. - * - * Returns: 0 on success, negative number in case of an error. - * - * Since: 2.31 - */ -int scols_table_enable_noencoding(struct libscols_table *tb, int enable) -{ - if (!tb) - return -EINVAL; - DBG(TAB, ul_debugobj(tb, "encoding: %s", enable ? "ENABLE" : "DISABLE")); - tb->no_encode = enable ? 1 : 0; - return 0; -} - -/** - * scols_table_is_noencoding: - * @tb: a pointer to a struct libscols_table instance - * - * Returns: 1 if encoding is disabled. - * - * Since: 2.31 - */ -int scols_table_is_noencoding(const struct libscols_table *tb) -{ - return tb->no_encode; -} - -/** - * scols_table_colors_wanted: - * @tb: table - * - * Returns: 1 if colors are enabled. - */ -int scols_table_colors_wanted(const struct libscols_table *tb) -{ - return tb->colors_wanted; -} - -/** - * scols_table_is_empty: - * @tb: table - * - * Returns: 1 if the table is empty. - */ -int scols_table_is_empty(const struct libscols_table *tb) -{ - return !tb->nlines; -} - -/** - * scols_table_is_ascii: - * @tb: table - * - * Returns: 1 if ASCII tree is enabled. - */ -int scols_table_is_ascii(const struct libscols_table *tb) -{ - return tb->ascii; -} - -/** - * scols_table_is_noheadings: - * @tb: table - * - * Returns: 1 if header output is disabled. - */ -int scols_table_is_noheadings(const struct libscols_table *tb) -{ - return tb->no_headings; -} - -/** - * scols_table_is_header_repeat - * @tb: table - * - * Returns: 1 if header repeat is enabled. - * - * Since: 2.31 - */ -int scols_table_is_header_repeat(const struct libscols_table *tb) -{ - return tb->header_repeat; -} - -/** - * scols_table_is_export: - * @tb: table - * - * Returns: 1 if export output format is enabled. - */ -int scols_table_is_export(const struct libscols_table *tb) -{ - return tb->format == SCOLS_FMT_EXPORT; -} - -/** - * scols_table_is_raw: - * @tb: table - * - * Returns: 1 if raw output format is enabled. - */ -int scols_table_is_raw(const struct libscols_table *tb) -{ - return tb->format == SCOLS_FMT_RAW; -} - -/** - * scols_table_is_json: - * @tb: table - * - * Returns: 1 if JSON output format is enabled. - * - * Since: 2.27 - */ -int scols_table_is_json(const struct libscols_table *tb) -{ - return tb->format == SCOLS_FMT_JSON; -} - -/** - * scols_table_is_maxout - * @tb: table - * - * Returns: 1 if output maximization is enabled or 0 - */ -int scols_table_is_maxout(const struct libscols_table *tb) -{ - return tb->maxout; -} - -/** - * scols_table_is_minout - * @tb: table - * - * Returns: 1 if output minimization is enabled or 0 - * - * Since: 2.35 - */ -int scols_table_is_minout(const struct libscols_table *tb) -{ - return tb->minout; -} - -/** - * scols_table_is_tree: - * @tb: table - * - * Returns: returns 1 tree-like output is expected. - */ -int scols_table_is_tree(const struct libscols_table *tb) -{ - return tb->ntreecols > 0; -} - -/** - * scols_table_set_column_separator: - * @tb: table - * @sep: separator - * - * Sets the column separator of @tb to @sep. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_table_set_column_separator(struct libscols_table *tb, const char *sep) -{ - return strdup_to_struct_member(tb, colsep, sep); -} - -/** - * scols_table_set_line_separator: - * @tb: table - * @sep: separator - * - * Sets the line separator of @tb to @sep. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_table_set_line_separator(struct libscols_table *tb, const char *sep) -{ - return strdup_to_struct_member(tb, linesep, sep); -} - -/** - * scols_table_get_column_separator: - * @tb: table - * - * Returns: @tb column separator, NULL in case of an error - */ -const char *scols_table_get_column_separator(const struct libscols_table *tb) -{ - return tb->colsep; -} - -/** - * scols_table_get_line_separator: - * @tb: table - * - * Returns: @tb line separator, NULL in case of an error - */ -const char *scols_table_get_line_separator(const struct libscols_table *tb) -{ - return tb->linesep; -} -/* for lines in the struct libscols_line->ln_lines list */ -static int cells_cmp_wrapper_lines(struct list_head *a, struct list_head *b, void *data) -{ - struct libscols_column *cl = (struct libscols_column *) data; - struct libscols_line *ra, *rb; - struct libscols_cell *ca, *cb; - - assert(a); - assert(b); - assert(cl); - - ra = list_entry(a, struct libscols_line, ln_lines); - rb = list_entry(b, struct libscols_line, ln_lines); - ca = scols_line_get_cell(ra, cl->seqnum); - cb = scols_line_get_cell(rb, cl->seqnum); - - return cl->cmpfunc(ca, cb, cl->cmpfunc_data); -} - -/* for lines in the struct libscols_line->ln_children list */ -static int cells_cmp_wrapper_children(struct list_head *a, struct list_head *b, void *data) -{ - struct libscols_column *cl = (struct libscols_column *) data; - struct libscols_line *ra, *rb; - struct libscols_cell *ca, *cb; - - assert(a); - assert(b); - assert(cl); - - ra = list_entry(a, struct libscols_line, ln_children); - rb = list_entry(b, struct libscols_line, ln_children); - ca = scols_line_get_cell(ra, cl->seqnum); - cb = scols_line_get_cell(rb, cl->seqnum); - - return cl->cmpfunc(ca, cb, cl->cmpfunc_data); -} - - -static int sort_line_children(struct libscols_line *ln, struct libscols_column *cl) -{ - struct list_head *p; - - if (!list_empty(&ln->ln_branch)) { - list_for_each(p, &ln->ln_branch) { - struct libscols_line *chld = - list_entry(p, struct libscols_line, ln_children); - sort_line_children(chld, cl); - } - - list_sort(&ln->ln_branch, cells_cmp_wrapper_children, cl); - } - - if (is_first_group_member(ln)) { - list_for_each(p, &ln->group->gr_children) { - struct libscols_line *chld = - list_entry(p, struct libscols_line, ln_children); - sort_line_children(chld, cl); - } - - list_sort(&ln->group->gr_children, cells_cmp_wrapper_children, cl); - } - - return 0; -} - -/** - * scols_sort_table: - * @tb: table - * @cl: order by this column - * - * Orders the table by the column. See also scols_column_set_cmpfunc(). If the - * tree output is enabled then children in the tree are recursively sorted too. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_sort_table(struct libscols_table *tb, struct libscols_column *cl) -{ - if (!tb || !cl || !cl->cmpfunc) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "sorting table")); - list_sort(&tb->tb_lines, cells_cmp_wrapper_lines, cl); - - if (scols_table_is_tree(tb)) { - struct libscols_line *ln; - struct libscols_iter itr; - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_line(tb, &itr, &ln) == 0) - sort_line_children(ln, cl); - } - - return 0; -} - -static struct libscols_line *move_line_and_children(struct libscols_line *ln, struct libscols_line *pre) -{ - if (pre) { - list_del_init(&ln->ln_lines); /* remove from old position */ - list_add(&ln->ln_lines, &pre->ln_lines); /* add to the new place (behind @pre) */ - } - pre = ln; - - if (!list_empty(&ln->ln_branch)) { - struct list_head *p; - - list_for_each(p, &ln->ln_branch) { - struct libscols_line *chld = - list_entry(p, struct libscols_line, ln_children); - pre = move_line_and_children(chld, pre); - } - } - - return pre; -} - -/** - * scols_sort_table_by_tree: - * @tb: table - * - * Reorders lines in the table by parent->child relation. Note that order of - * the lines in the table is independent on the tree hierarchy. - * - * Since: 2.30 - * - * Returns: 0, a negative value in case of an error. - */ -int scols_sort_table_by_tree(struct libscols_table *tb) -{ - struct libscols_line *ln; - struct libscols_iter itr; - - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "sorting table by tree")); - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_line(tb, &itr, &ln) == 0) { - if (ln->parent) - continue; - - move_line_and_children(ln, NULL); - } - - return 0; -} - - -/** - * scols_table_set_termforce: - * @tb: table - * @force: SCOLS_TERMFORCE_{NEVER,ALWAYS,AUTO} - * - * Forces library to use stdout as terminal, non-terminal or use automatic - * detection (default). - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.29 - */ -int scols_table_set_termforce(struct libscols_table *tb, int force) -{ - if (!tb) - return -EINVAL; - tb->termforce = force; - return 0; -} - -/** - * scols_table_get_termforce: - * @tb: table - * - * Returns: SCOLS_TERMFORCE_{NEVER,ALWAYS,AUTO} or a negative value in case of an error. - * - * Since: 2.29 - */ -int scols_table_get_termforce(const struct libscols_table *tb) -{ - return tb->termforce; -} - -/** - * scols_table_set_termwidth - * @tb: table - * @width: terminal width - * - * The library automatically detects terminal width or defaults to 80 chars if - * detections is unsuccessful. This function override this behaviour. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.29 - */ -int scols_table_set_termwidth(struct libscols_table *tb, size_t width) -{ - DBG(TAB, ul_debugobj(tb, "set terminatl width: %zu", width)); - tb->termwidth = width; - return 0; -} - -/** - * scols_table_get_termwidth - * @tb: table - * - * Returns: terminal width. - */ -size_t scols_table_get_termwidth(const struct libscols_table *tb) -{ - return tb->termwidth; -} - -/** - * scols_table_set_termheight - * @tb: table - * @height: terminal height (number of lines) - * - * The library automatically detects terminal height or defaults to 24 lines if - * detections is unsuccessful. This function override this behaviour. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.31 - */ -int scols_table_set_termheight(struct libscols_table *tb, size_t height) -{ - DBG(TAB, ul_debugobj(tb, "set terminatl height: %zu", height)); - tb->termheight = height; - return 0; -} - -/** - * scols_table_get_termheight - * @tb: table - * - * Returns: terminal height (number of lines). - * - * Since: 2.31 - */ -size_t scols_table_get_termheight(const struct libscols_table *tb) -{ - return tb->termheight; -} diff --git a/utils/libsmartcols/src/version.c b/utils/libsmartcols/src/version.c deleted file mode 100644 index e592ccc..0000000 --- a/utils/libsmartcols/src/version.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * version.c - Return the version of the library - * - * Copyright (C) 2014 Karel Zak <kzak@redhat.com> - * - * See COPYING.libmount for the License of this software. - */ - -/** - * SECTION: version-utils - * @title: Version functions - * @short_description: functions to get the library version. - * - * Note that library version is not the same thing as SONAME version. The - * libsmarcols uses symbols versioning and SONAME is not modified for releases. - * - * The library version and symbols version follow util-linux package versioning. - */ - -#include <ctype.h> - -#include "smartcolsP.h" - -static const char *lib_version = LIBSMARTCOLS_VERSION; - -/** - * scols_parse_version_string: - * @ver_string: version string (e.g "2.18.0") - * - * Returns: release version code. - */ -int scols_parse_version_string(const char *ver_string) -{ - const char *cp; - int version = 0; - - assert(ver_string); - - for (cp = ver_string; *cp; cp++) { - if (*cp == '.') - continue; - if (!isdigit(*cp)) - break; - version = (version * 10) + (*cp - '0'); - } - return version; -} - -/** - * scols_get_library_version: - * @ver_string: return pointer to the static library version string if not NULL - * - * Returns: release version number. - */ -int scols_get_library_version(const char **ver_string) -{ - if (ver_string) - *ver_string = lib_version; - - return scols_parse_version_string(lib_version); -} - diff --git a/utils/libsmartcols/src/walk.c b/utils/libsmartcols/src/walk.c deleted file mode 100644 index a75fde6..0000000 --- a/utils/libsmartcols/src/walk.c +++ /dev/null @@ -1,152 +0,0 @@ -#include "smartcolsP.h" - -static int walk_line(struct libscols_table *tb, - struct libscols_line *ln, - struct libscols_column *cl, - int (*callback)(struct libscols_table *, - struct libscols_line *, - struct libscols_column *, - void *), - void *data) -{ - int rc = 0; - - DBG(LINE, ul_debugobj(ln, " wall line")); - - /* we list group children in __scols_print_tree() after tree root node */ - if (is_group_member(ln) && is_last_group_member(ln) && has_group_children(ln)) - tb->ngrpchlds_pending++; - - if (has_groups(tb)) - rc = scols_groups_update_grpset(tb, ln); - if (rc == 0) - rc = callback(tb, ln, cl, data); - - /* children */ - if (rc == 0 && has_children(ln)) { - struct list_head *p; - - DBG(LINE, ul_debugobj(ln, " children walk")); - - list_for_each(p, &ln->ln_branch) { - struct libscols_line *chld = list_entry(p, - struct libscols_line, ln_children); - - rc = walk_line(tb, chld, cl, callback, data); - if (rc) - break; - } - } - - DBG(LINE, ul_debugobj(ln, "<- walk line done [rc=%d]", rc)); - return rc; -} - -/* last line in the tree? */ -int scols_walk_is_last(struct libscols_table *tb, struct libscols_line *ln) -{ - if (tb->walk_last_done == 0) - return 0; - if (tb->ngrpchlds_pending > 0) - return 0; - if (has_children(ln)) - return 0; - if (is_tree_root(ln) && !is_last_tree_root(tb, ln)) - return 0; - if (is_group_member(ln) && (!is_last_group_member(ln) || has_group_children(ln))) - return 0; - if (is_child(ln)) { - struct libscols_line *parent = ln->parent; - - if (!is_last_child(ln)) - return 0; - while (parent) { - if (is_child(parent) && !is_last_child(parent)) - return 0; - if (!parent->parent) - break; - parent = parent->parent; - } - if (is_tree_root(parent) && !is_last_tree_root(tb, parent)) - return 0; - } - if (is_group_child(ln) && !is_last_group_child(ln)) - return 0; - - DBG(LINE, ul_debugobj(ln, "last in table")); - return 1; -} - -int scols_walk_tree(struct libscols_table *tb, - struct libscols_column *cl, - int (*callback)(struct libscols_table *, - struct libscols_line *, - struct libscols_column *, - void *), - void *data) -{ - int rc = 0; - struct libscols_line *ln; - struct libscols_iter itr; - - assert(tb); - DBG(TAB, ul_debugobj(tb, ">> walk start")); - - /* init */ - tb->ngrpchlds_pending = 0; - tb->walk_last_tree_root = NULL; - tb->walk_last_done = 0; - - if (has_groups(tb)) - scols_groups_reset_state(tb); - - /* set pointer to last tree root */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_line(tb, &itr, &ln) == 0) { - if (!tb->walk_last_tree_root) - tb->walk_last_tree_root = ln; - if (is_child(ln) || is_group_child(ln)) - continue; - tb->walk_last_tree_root = ln; - } - - /* walk */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (rc == 0 && scols_table_next_line(tb, &itr, &ln) == 0) { - if (ln->parent || ln->parent_group) - continue; - - if (tb->walk_last_tree_root == ln) - tb->walk_last_done = 1; - rc = walk_line(tb, ln, cl, callback, data); - - /* walk group's children */ - while (rc == 0 && tb->ngrpchlds_pending) { - struct libscols_group *gr = scols_grpset_get_printable_children(tb); - struct list_head *p; - - DBG(LINE, ul_debugobj(ln, " walk group children [pending=%zu]", tb->ngrpchlds_pending)); - if (!gr) { - DBG(LINE, ul_debugobj(ln, " *** ngrpchlds_pending counter invalid")); - tb->ngrpchlds_pending = 0; - break; - } - - tb->ngrpchlds_pending--; - - list_for_each(p, &gr->gr_children) { - struct libscols_line *chld = - list_entry(p, struct libscols_line, ln_children); - - rc = walk_line(tb, chld, cl, callback, data); - if (rc) - break; - } - } - } - - tb->ngrpchlds_pending = 0; - tb->walk_last_done = 0; - DBG(TAB, ul_debugobj(tb, "<< walk end [rc=%d]", rc)); - return rc; -} diff --git a/utils/sys-utils/CMakeLists.txt b/utils/sys-utils/CMakeLists.txt deleted file mode 100644 index 01295d9..0000000 --- a/utils/sys-utils/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -cmake_minimum_required(VERSION 3.10) - -# set the project name -project(xloop-utils-sys-utils) - -# add xlosetup executable -add_executable(xlosetup ${CMAKE_CURRENT_SOURCE_DIR}/xlosetup.c) -target_link_libraries(xlosetup LINK_PUBLIC libcommon libsmartcols) -target_include_directories(xlosetup PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../lib ${CMAKE_CURRENT_SOURCE_DIR}/../libsmartcols) -install(TARGETS xlosetup DESTINATION bin - COMPONENT main) - -# install xlosetup man page -# NOTE: installation is done via a directory install with file matching pattern to support CPackRPM's automatic compression of man pages -install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ - DESTINATION share/man/man8 - COMPONENT main - USE_SOURCE_PERMISSIONS - FILES_MATCHING PATTERN *.8*) diff --git a/utils/sys-utils/xlosetup.8 b/utils/sys-utils/xlosetup.8 deleted file mode 100644 index 4e063e6..0000000 --- a/utils/sys-utils/xlosetup.8 +++ /dev/null @@ -1,215 +0,0 @@ -.TH XLOSETUP 8 "September 2020" "util-linux" "System Administration" -.SH NAME -xlosetup \- set up and control xloop devices -.SH SYNOPSIS -.ad l -Get info: -.sp -.in +5 -.B xlosetup -[\fIxloopdev\fP] -.sp -.B xlosetup \-l -.RB [ \-a ] -.sp -.B xlosetup \-j -.I file -.RB [ \-o -.IR offset ] -.sp -.in -5 -Detach a xloop device: -.sp -.in +5 -.B "xlosetup \-d" -.IR xloopdev ... -.sp -.in -5 -Detach all associated xloop devices: -.sp -.in +5 -.B "xlosetup \-D" -.sp -.in -5 -Set up a xloop device: -.sp -.in +5 -.B xlosetup -.RB [ \-o -.IR offset ] -.RB [ \-\-sizelimit -.IR size ] -.RB [ \-\-sector\-size -.IR size ] -.in +8 -.RB [ \-Pr ] -.RB [ \-\-show ] " \-f" | \fIxloopdev\fP -.I file -.sp -.in -13 -Resize a xloop device: -.sp -.in +5 -.B "xlosetup \-c" -.I xloopdev -.in -5 -.ad b -.SH DESCRIPTION -.B xlosetup -is used to associate xloop devices with regular files or block devices, -to detach xloop devices, and to query the status of a xloop device. If only the -\fIxloopdev\fP argument is given, the status of the corresponding xloop -device is shown. If no option is given, all xloop devices are shown. -.sp -Note that the old output format (i.e., \fBxlosetup \-a\fR) with comma-delimited -strings is deprecated in favour of the \fB\-\-list\fR output format. -.sp -It's possible to create more independent xloop devices for the same backing -file. -.B This setup may be dangerous, can cause data loss, corruption and overwrites. -Use \fB\-\-nooverlap\fR with \fB\-\-find\fR during setup to avoid this problem. - -.SH OPTIONS -The \fIsize\fR and \fIoffset\fR -arguments may be followed by the multiplicative suffixes KiB (=1024), -MiB (=1024*1024), and so on for GiB, TiB, PiB, EiB, ZiB and YiB (the "iB" is -optional, e.g., "K" has the same meaning as "KiB") or the suffixes -KB (=1000), MB (=1000*1000), and so on for GB, TB, PB, EB, ZB and YB. - -.TP -.BR \-a , " \-\-all" -Show the status of all xloop devices. Note that not all information is accessible -for non-root users. See also \fB\-\-list\fR. The old output format (as printed -without \fB\-\-list)\fR is deprecated. -.TP -.BR \-d , " \-\-detach " \fIxloopdev\fR... -Detach the file or device associated with the specified xloop device(s). Note -that since Linux v3.7 kernel uses "lazy device destruction". The detach -operation does not return EBUSY error anymore if device is actively used by -system, but it is marked by autoclear flag and destroyed later. -.TP -.BR \-D , " \-\-detach\-all" -Detach all associated xloop devices. -.TP -.BR \-f , " \-\-find " "\fR[\fIfile\fR]" -Find the first unused xloop device. If a \fIfile\fR argument is present, use -the found device as xloop device. Otherwise, just print its name. -.IP "\fB\-\-show\fP" -Display the name of the assigned xloop device if the \fB\-f\fP option and a -\fIfile\fP argument are present. -.TP -.BR \-L , " \-\-nooverlap" -Check for conflicts between xloop devices to avoid situation when the same -backing file is shared between more xloop devices. If the file is already used -by another device then re-use the device rather than a new one. The option -makes sense only with \fB\-\-find\fP. -.TP -.BR \-j , " \-\-associated " \fIfile\fR " \fR[\fB\-o \fIoffset\fR]" -Show the status of all xloop devices associated with the given \fIfile\fR. -.TP -.BR \-o , " \-\-offset " \fIoffset -The data start is moved \fIoffset\fP bytes into the specified file or device. The \fIoffset\fP -may be followed by the multiplicative suffixes; see above. -.IP "\fB\-\-sizelimit \fIsize\fP" -The data end is set to no more than \fIsize\fP bytes after the data start. The \fIsize\fP -may be followed by the multiplicative suffixes; see above. -.TP -.BR \-b , " \-\-sector-size " \fIsize -Set the logical sector size of the xloop device in bytes (since Linux 4.14). The -option may be used when create a new xloop device as well as stand-alone command -to modify sector size of the already existing xloop device. -.TP -.BR \-c , " \-\-set\-capacity " \fIxloopdev -Force the xloop driver to reread the size of the file associated with the -specified xloop device. -.TP -.BR \-P , " \-\-partscan" -Force the kernel to scan the partition table on a newly created xloop device. Note that the -partition table parsing depends on sector sizes. The default is sector size is 512 bytes, -otherwise you need to use the option \fB\-\-sector\-size\fR together with \fB\-\-partscan\fR. -.TP -.BR \-r , " \-\-read\-only" -Set up a read-only xloop device. -.TP -.BR \-\-direct\-io [ =on | off ] -Enable or disable direct I/O for the backing file. The optional argument -can be either \fBon\fR or \fBoff\fR. If the argument is omitted, it defaults -to \fBoff\fR. -.TP -.BR \-t , " \-\-type \fIformat\fR" -Set the file format type of the xloop device. If no file format type is specified, -the RAW file format is used by default. Valid file formats are: \fBRAW\fR, -\fBQCOW\fR, \fBVDI\fR, \fBVMDK\fR. -.TP -.BR \-v , " \-\-verbose" -Verbose mode. -.TP -.BR \-l , " \-\-list" -If a xloop device or the \fB\-a\fR option is specified, print the default columns -for either the specified xloop device or all xloop devices; the default is to -print info about all devices. See also \fB\-\-output\fP, \fB\-\-noheadings\fP, -\fB\-\-raw\fP, and \fB\-\-json\fP. -.TP -.BR \-O , " \-\-output " \fIcolumn\fR[,\fIcolumn\fR]... -Specify the columns that are to be printed for the \fB\-\-list\fP output. -Use \fB\-\-help\fR to get a list of all supported columns. -.TP -.B \-\-output\-all -Output all available columns. -.TP -.BR \-n , " \-\-noheadings" -Don't print headings for \fB\-\-list\fP output format. -.IP "\fB\-\-raw\fP" -Use the raw \fB\-\-list\fP output format. -.TP -.BR \-J , " \-\-json" -Use JSON format for \fB\-\-list\fP output. -.TP -.BR \-V , " \-\-version" -Display version information and exit. -.TP -.BR \-h , " \-\-help" -Display help text and exit. - -.SH ENCRYPTION -.B Cryptoloop is no longer supported in favor of dm-crypt. -.B For more details see cryptsetup(8). - -.SH EXIT STATUS -.B xlosetup -returns 0 on success, nonzero on failure. When -.B xlosetup -displays the status of a xloop device, it returns 1 if the device -is not configured and 2 if an error occurred which prevented -determining the status of the device. - -.SH ENVIRONMENT -.IP XLOOPDEV_DEBUG=all -enables debug output. - -.SH FILES -.TP -.I /dev/xloop[0..N] -xloop block devices -.TP -.I /dev/xloop-control -xloop control device -.SH EXAMPLE -The following commands can be used as an example of using the xloop device. -.nf -.IP -# dd if=/dev/zero of=~/file.img bs=1024k count=10 -# xlosetup \-\-find \-\-show ~/file.img -/dev/xloop0 -# mkfs \-t ext2 /dev/xloop0 -# mount /dev/xloop0 /mnt - ... -# umount /dev/xloop0 -# xlosetup \-\-detach /dev/xloop0 -.fi -.SH AUTHORS -Karel Zak <kzak@redhat.com>, based on the original version from -Theodore Ts'o <tytso@athena.mit.edu> -.SH AVAILABILITY -The xlosetup command is part of the util-linux package and is available from -https://www.kernel.org/pub/linux/utils/util-linux/. diff --git a/utils/sys-utils/xlosetup.c b/utils/sys-utils/xlosetup.c deleted file mode 100644 index 60fa0ba..0000000 --- a/utils/sys-utils/xlosetup.c +++ /dev/null @@ -1,931 +0,0 @@ -/* - * Copyright (C) 2011 Karel Zak <kzak@redhat.com> - * Originally from Ted's losetup.c - * - * xlosetup.c - setup and control xloop devices - */ -#include <assert.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <sys/stat.h> -#include <inttypes.h> -#include <getopt.h> - -#include <libsmartcols.h> - -#include "c.h" -#include "nls.h" -#include "strutils.h" -#include "loopdev.h" -#include "closestream.h" -#include "optutils.h" -#include "xalloc.h" -#include "canonicalize.h" -#include "pathnames.h" - -enum { - A_CREATE = 1, /* setup a new device */ - A_DELETE, /* delete given device(s) */ - A_DELETE_ALL, /* delete all devices */ - A_SHOW, /* list devices */ - A_SHOW_ONE, /* print info about one device */ - A_FIND_FREE, /* find first unused */ - A_SET_CAPACITY, /* set device capacity */ - A_SET_DIRECT_IO, /* set accessing backing file by direct io */ - A_SET_BLOCKSIZE, /* set logical block size of the xloop device */ -}; - -enum { - COL_NAME = 0, - COL_AUTOCLR, - COL_BACK_FILE, - COL_FILE_FMT_TYPE, - COL_BACK_INO, - COL_BACK_MAJMIN, - COL_MAJMIN, - COL_OFFSET, - COL_PARTSCAN, - COL_RO, - COL_SIZELIMIT, - COL_DIO, - COL_LOGSEC, -}; - -/* basic output flags */ -static int no_headings; -static int raw; -static int json; - -struct colinfo { - const char *name; - double whint; - int flags; - const char *help; - - int json_type; /* default is string */ -}; - -static struct colinfo infos[] = { - [COL_AUTOCLR] = { "AUTOCLEAR", 1, SCOLS_FL_RIGHT, N_("autoclear flag set"), SCOLS_JSON_BOOLEAN}, - [COL_BACK_FILE] = { "BACK-FILE", 0.3, 0, N_("device backing file")}, - [COL_FILE_FMT_TYPE] = { "FILE-FORMAT", 1, 0, N_("backing file format")}, - [COL_BACK_INO] = { "BACK-INO", 4, SCOLS_FL_RIGHT, N_("backing file inode number"), SCOLS_JSON_NUMBER}, - [COL_BACK_MAJMIN] = { "BACK-MAJ:MIN", 6, 0, N_("backing file major:minor device number")}, - [COL_NAME] = { "NAME", 0.25, 0, N_("xloop device name")}, - [COL_OFFSET] = { "OFFSET", 5, SCOLS_FL_RIGHT, N_("offset from the beginning"), SCOLS_JSON_NUMBER}, - [COL_PARTSCAN] = { "PARTSCAN", 1, SCOLS_FL_RIGHT, N_("partscan flag set"), SCOLS_JSON_BOOLEAN}, - [COL_RO] = { "RO", 1, SCOLS_FL_RIGHT, N_("read-only device"), SCOLS_JSON_BOOLEAN}, - [COL_SIZELIMIT] = { "SIZELIMIT", 5, SCOLS_FL_RIGHT, N_("size limit of the file in bytes"), SCOLS_JSON_NUMBER}, - [COL_MAJMIN] = { "MAJ:MIN", 3, 0, N_("xloop device major:minor number")}, - [COL_DIO] = { "DIO", 1, SCOLS_FL_RIGHT, N_("access backing file with direct-io"), SCOLS_JSON_BOOLEAN}, - [COL_LOGSEC] = { "LOG-SEC", 4, SCOLS_FL_RIGHT, N_("logical sector size in bytes"), SCOLS_JSON_NUMBER}, -}; - -static int columns[ARRAY_SIZE(infos) * 2] = {-1}; -static size_t ncolumns; - -static int get_column_id(int num) -{ - assert(num >= 0); - assert((size_t) num < ncolumns); - assert(columns[num] < (int) ARRAY_SIZE(infos)); - return columns[num]; -} - -static struct colinfo *get_column_info(int num) -{ - return &infos[ get_column_id(num) ]; -} - -static int column_name_to_id(const char *name, size_t namesz) -{ - size_t i; - - for (i = 0; i < ARRAY_SIZE(infos); i++) { - const char *cn = infos[i].name; - - if (!strncasecmp(name, cn, namesz) && !*(cn + namesz)) - return i; - } - warnx(_("unknown column: %s"), name); - return -1; -} - -static int printf_loopdev(struct loopdev_cxt *lc) -{ - uint64_t x; - dev_t dev = 0; - ino_t ino = 0; - char *fname; - uint32_t type; - char *file_fmt_str; - - fname = loopcxt_get_backing_file(lc); - if (!fname) - return -EINVAL; - - file_fmt_str = loopcxt_get_file_fmt_type_string(lc); - if (!file_fmt_str) - return -EINVAL; - - if (loopcxt_get_backing_devno(lc, &dev) == 0) - loopcxt_get_backing_inode(lc, &ino); - - if (!dev && !ino) { - /* - * Probably non-root user (no permissions to - * call LOOP_GET_STATUS ioctls). - */ - printf("%s: []: (%s)", - loopcxt_get_device(lc), fname); - - if (loopcxt_get_offset(lc, &x) == 0 && x) - printf(_(", offset %ju"), x); - - if (loopcxt_get_sizelimit(lc, &x) == 0 && x) - printf(_(", sizelimit %ju"), x); - - printf(_(", file-format %s"), file_fmt_str); - - goto done; - } - - printf("%s: [%04d]:%" PRIu64 " (%s)", - loopcxt_get_device(lc), (int) dev, ino, fname); - - if (loopcxt_get_offset(lc, &x) == 0 && x) - printf(_(", offset %ju"), x); - - if (loopcxt_get_sizelimit(lc, &x) == 0 && x) - printf(_(", sizelimit %ju"), x); - - if (loopcxt_get_encrypt_type(lc, &type) == 0) { - const char *e = loopcxt_get_crypt_name(lc); - - if ((!e || !*e) && type == 1) - e = "XOR"; - if (e && *e) - printf(_(", encryption %s (type %u)"), e, type); - } - - printf(_(", file-format %s"), file_fmt_str); - -done: - free(fname); - printf("\n"); - return 0; -} - -static int show_all_loops(struct loopdev_cxt *lc, const char *file, - uint64_t offset, int flags) -{ - struct stat sbuf, *st = &sbuf; - char *cn_file = NULL; - - if (loopcxt_init_iterator(lc, LOOPITER_FL_USED)) - return -1; - - if (!file || stat(file, st)) - st = NULL; - - while (loopcxt_next(lc) == 0) { - if (file) { - int used; - const char *bf = cn_file ? cn_file : file; - - used = loopcxt_is_used(lc, st, bf, offset, 0, flags); - if (!used && !cn_file) { - bf = cn_file = canonicalize_path(file); - used = loopcxt_is_used(lc, st, bf, offset, 0, flags); - } - if (!used) - continue; - } - printf_loopdev(lc); - } - loopcxt_deinit_iterator(lc); - free(cn_file); - return 0; -} - -static int delete_loop(struct loopdev_cxt *lc) -{ - if (loopcxt_delete_device(lc)) - warn(_("%s: detach failed"), loopcxt_get_device(lc)); - else - return 0; - - return -1; -} - -static int delete_all_loops(struct loopdev_cxt *lc) -{ - int res = 0; - - if (loopcxt_init_iterator(lc, LOOPITER_FL_USED)) - return -1; - - while (loopcxt_next(lc) == 0) - res += delete_loop(lc); - - loopcxt_deinit_iterator(lc); - return res; -} - -static int set_scols_data(struct loopdev_cxt *lc, struct libscols_line *ln) -{ - size_t i; - - for (i = 0; i < ncolumns; i++) { - const char *p = NULL; /* external data */ - char *np = NULL; /* allocated here */ - uint64_t x = 0; - int rc = 0; - - switch(get_column_id(i)) { - case COL_NAME: - p = loopcxt_get_device(lc); - break; - case COL_BACK_FILE: - p = loopcxt_get_backing_file(lc); - break; - case COL_FILE_FMT_TYPE: - p = loopcxt_get_file_fmt_type_string(lc); - break; - case COL_OFFSET: - if (loopcxt_get_offset(lc, &x) == 0) - xasprintf(&np, "%jd", x); - break; - case COL_SIZELIMIT: - if (loopcxt_get_sizelimit(lc, &x) == 0) - xasprintf(&np, "%jd", x); - break; - case COL_BACK_MAJMIN: - { - dev_t dev = 0; - if (loopcxt_get_backing_devno(lc, &dev) == 0 && dev) - xasprintf(&np, "%8u:%-3u", major(dev), minor(dev)); - break; - } - case COL_MAJMIN: - { - struct stat st; - - if (loopcxt_get_device(lc) - && stat(loopcxt_get_device(lc), &st) == 0 - && S_ISBLK(st.st_mode) - && major(st.st_rdev) == LOOPDEV_MAJOR) - xasprintf(&np, "%3u:%-3u", major(st.st_rdev), - minor(st.st_rdev)); - break; - } - case COL_BACK_INO: - { - ino_t ino = 0; - if (loopcxt_get_backing_inode(lc, &ino) == 0 && ino) - xasprintf(&np, "%ju", ino); - break; - } - case COL_AUTOCLR: - p = loopcxt_is_autoclear(lc) ? "1" : "0"; - break; - case COL_RO: - p = loopcxt_is_readonly(lc) ? "1" : "0"; - break; - case COL_DIO: - p = loopcxt_is_dio(lc) ? "1" : "0"; - break; - case COL_PARTSCAN: - p = loopcxt_is_partscan(lc) ? "1" : "0"; - break; - case COL_LOGSEC: - if (loopcxt_get_blocksize(lc, &x) == 0) - xasprintf(&np, "%jd", x); - break; - default: - return -EINVAL; - } - - - if (p) - rc = scols_line_set_data(ln, i, p); /* calls strdup() */ - else if (np) - rc = scols_line_refer_data(ln, i, np); /* only refers */ - - if (rc) - err(EXIT_FAILURE, _("failed to add output data")); - } - - return 0; -} - -static int show_table(struct loopdev_cxt *lc, - const char *file, - uint64_t offset, - int flags) -{ - struct stat sbuf, *st = &sbuf; - struct libscols_table *tb; - struct libscols_line *ln; - int rc = 0; - size_t i; - - scols_init_debug(0); - - if (!(tb = scols_new_table())) - err(EXIT_FAILURE, _("failed to allocate output table")); - scols_table_enable_raw(tb, raw); - scols_table_enable_json(tb, json); - scols_table_enable_noheadings(tb, no_headings); - - if (json) - scols_table_set_name(tb, "xloopdevices"); - - for (i = 0; i < ncolumns; i++) { - struct colinfo *ci = get_column_info(i); - struct libscols_column *cl; - - cl = scols_table_new_column(tb, ci->name, ci->whint, ci->flags); - if (!cl) - err(EXIT_FAILURE, _("failed to allocate output column")); - if (json) - scols_column_set_json_type(cl, ci->json_type); - } - - /* only one xloopdev requested (already assigned to loopdev_cxt) */ - if (loopcxt_get_device(lc)) { - ln = scols_table_new_line(tb, NULL); - if (!ln) - err(EXIT_FAILURE, _("failed to allocate output line")); - rc = set_scols_data(lc, ln); - - /* list all xloopdevs */ - } else { - char *cn_file = NULL; - - rc = loopcxt_init_iterator(lc, LOOPITER_FL_USED); - if (rc) - goto done; - if (!file || stat(file, st)) - st = NULL; - - while (loopcxt_next(lc) == 0) { - if (file) { - int used; - const char *bf = cn_file ? cn_file : file; - - used = loopcxt_is_used(lc, st, bf, offset, 0, flags); - if (!used && !cn_file) { - bf = cn_file = canonicalize_path(file); - used = loopcxt_is_used(lc, st, bf, offset, 0, flags); - } - if (!used) - continue; - } - - ln = scols_table_new_line(tb, NULL); - if (!ln) - err(EXIT_FAILURE, _("failed to allocate output line")); - rc = set_scols_data(lc, ln); - if (rc) - break; - } - - loopcxt_deinit_iterator(lc); - free(cn_file); - } -done: - if (rc == 0) - rc = scols_print_table(tb); - scols_unref_table(tb); - return rc; -} - -static void __attribute__((__noreturn__)) usage(void) -{ - FILE *out = stdout; - size_t i; - - fputs(USAGE_HEADER, out); - - fprintf(out, - _(" %1$s [options] [<xloopdev>]\n" - " %1$s [options] -f | <xloopdev> <file>\n"), - program_invocation_short_name); - - fputs(USAGE_SEPARATOR, out); - fputs(_("Set up and control xloop devices.\n"), out); - - /* commands */ - fputs(USAGE_OPTIONS, out); - fputs(_(" -a, --all list all used devices\n"), out); - fputs(_(" -d, --detach <xloopdev>... detach one or more devices\n"), out); - fputs(_(" -D, --detach-all detach all used devices\n"), out); - fputs(_(" -f, --find find first unused device\n"), out); - fputs(_(" -c, --set-capacity <xloopdev> resize the device\n"), out); - fputs(_(" -j, --associated <file> list all devices associated with <file>\n"), out); - fputs(_(" -L, --nooverlap avoid possible conflict between devices\n"), out); - - /* commands options */ - fputs(USAGE_SEPARATOR, out); - fputs(_(" -o, --offset <num> start at offset <num> into file\n"), out); - fputs(_(" --sizelimit <num> device is limited to <num> bytes of the file\n"), out); - fputs(_(" -b, --sector-size <num> set the logical sector size to <num>\n"), out); - fputs(_(" -P, --partscan create a partitioned xloop device\n"), out); - fputs(_(" -r, --read-only set up a read-only xloop device\n"), out); - fputs(_(" --direct-io[=<on|off>] open backing file with O_DIRECT\n"), out); - fputs(_(" --show print device name after setup (with -f)\n"), out); - fputs(_(" -t, --type set file format type of the loop device\n"), out); - fputs(_(" -v, --verbose verbose mode\n"), out); - - /* output options */ - fputs(USAGE_SEPARATOR, out); - fputs(_(" -J, --json use JSON --list output format\n"), out); - fputs(_(" -l, --list list info about all or specified (default)\n"), out); - fputs(_(" -n, --noheadings don't print headings for --list output\n"), out); - fputs(_(" -O, --output <cols> specify columns to output for --list\n"), out); - fputs(_(" --output-all output all columns\n"), out); - fputs(_(" --raw use raw --list output format\n"), out); - - fputs(USAGE_SEPARATOR, out); - printf(USAGE_HELP_OPTIONS(31)); - - fputs(USAGE_COLUMNS, out); - for (i = 0; i < ARRAY_SIZE(infos); i++) - fprintf(out, " %12s %s\n", infos[i].name, _(infos[i].help)); - - printf(USAGE_MAN_TAIL("xlosetup(8)")); - - exit(EXIT_SUCCESS); -} - -static int create_loop(struct loopdev_cxt *lc, - int nooverlap, int lo_flags, int flags, - const char *file, uint64_t offset, uint64_t sizelimit, - uint64_t blocksize, uint32_t file_fmt_type) -{ - int hasdev = loopcxt_has_device(lc); - int rc = 0; - - /* xlosetup --find --noverlap file.img */ - if (!hasdev && nooverlap) { - rc = loopcxt_find_overlap(lc, file, offset, sizelimit); - switch (rc) { - case 0: /* not found */ - break; - - case 1: /* overlap */ - loopcxt_deinit(lc); - errx(EXIT_FAILURE, _("%s: overlapping xloop device exists"), file); - - case 2: /* overlap -- full size and offset match (reuse) */ - { - uint32_t lc_encrypt_type; - - /* Once a xloop is initialized RO, there is no - * way to change its parameters. */ - if (loopcxt_is_readonly(lc) - && !(lo_flags & LO_FLAGS_READ_ONLY)) { - loopcxt_deinit(lc); - errx(EXIT_FAILURE, _("%s: overlapping read-only xloop device exists"), file); - } - - /* This is no more supported, but check to be safe. */ - if (loopcxt_get_encrypt_type(lc, &lc_encrypt_type) == 0 - && lc_encrypt_type != LO_CRYPT_NONE) { - loopcxt_deinit(lc); - errx(EXIT_FAILURE, _("%s: overlapping encrypted xloop device exists"), file); - } - - lc->info.lo_flags &= ~LO_FLAGS_AUTOCLEAR; - if (loopcxt_ioctl_status(lc)) { - loopcxt_deinit(lc); - errx(EXIT_FAILURE, _("%s: failed to re-use xloop device"), file); - } - return 0; /* success, re-use */ - } - default: /* error */ - loopcxt_deinit(lc); - errx(EXIT_FAILURE, _("failed to inspect xloop devices")); - return -errno; - } - } - - if (hasdev && !is_loopdev(loopcxt_get_device(lc))) - loopcxt_add_device(lc); - - /* xlosetup --noverlap /dev/xloopN file.img */ - if (hasdev && nooverlap) { - struct loopdev_cxt lc2; - - if (loopcxt_init(&lc2, 0)) { - loopcxt_deinit(lc); - err(EXIT_FAILURE, _("failed to initialize loopcxt")); - } - rc = loopcxt_find_overlap(&lc2, file, offset, sizelimit); - loopcxt_deinit(&lc2); - - if (rc) { - loopcxt_deinit(lc); - if (rc > 0) - errx(EXIT_FAILURE, _("%s: overlapping xloop device exists"), file); - err(EXIT_FAILURE, _("%s: failed to check for conflicting xloop devices"), file); - } - } - - /* Create a new device */ - do { - const char *errpre; - - /* Note that loopcxt_{find_unused,set_device}() resets - * loopcxt struct. - */ - if (!hasdev && (rc = loopcxt_find_unused(lc))) { - warnx(_("cannot find an unused xloop device")); - break; - } - if (flags & LOOPDEV_FL_OFFSET) - loopcxt_set_offset(lc, offset); - if (flags & LOOPDEV_FL_SIZELIMIT) - loopcxt_set_sizelimit(lc, sizelimit); - if (lo_flags) - loopcxt_set_flags(lc, lo_flags); - if (blocksize > 0) - loopcxt_set_blocksize(lc, blocksize); - - if ((rc = loopcxt_set_backing_file(lc, file))) { - warn(_("%s: failed to use backing file"), file); - break; - } - - if ((rc = loopcxt_set_file_fmt_type(lc, file_fmt_type))) { - warn(_("failed to use backing file format type")); - break; - } - - errno = 0; - rc = loopcxt_setup_device(lc); - if (rc == 0) - break; /* success */ - if (errno == EBUSY && !hasdev) - continue; - - /* errors */ - errpre = hasdev && loopcxt_get_fd(lc) < 0 ? - loopcxt_get_device(lc) : file; - warn(_("%s: failed to set up xloop device"), errpre); - break; - } while (hasdev == 0); - - return rc; -} - -int main(int argc, char **argv) -{ - struct loopdev_cxt lc; - int act = 0, flags = 0, no_overlap = 0, c; - char *file = NULL; - uint64_t offset = 0, sizelimit = 0, blocksize = 0; - int res = 0, showdev = 0, lo_flags = 0; - char *outarg = NULL; - int list = 0; - unsigned long use_dio = 0, set_dio = 0, set_blocksize = 0; - int use_file_fmt_type = 0; - uint32_t file_fmt_type = 0; - - enum { - OPT_SIZELIMIT = CHAR_MAX + 1, - OPT_SHOW, - OPT_RAW, - OPT_DIO, - OPT_OUTPUT_ALL - }; - static const struct option longopts[] = { - { "all", no_argument, NULL, 'a' }, - { "set-capacity", required_argument, NULL, 'c' }, - { "detach", required_argument, NULL, 'd' }, - { "detach-all", no_argument, NULL, 'D' }, - { "find", no_argument, NULL, 'f' }, - { "nooverlap", no_argument, NULL, 'L' }, - { "help", no_argument, NULL, 'h' }, - { "associated", required_argument, NULL, 'j' }, - { "json", no_argument, NULL, 'J' }, - { "list", no_argument, NULL, 'l' }, - { "sector-size", required_argument, NULL, 'b' }, - { "noheadings", no_argument, NULL, 'n' }, - { "offset", required_argument, NULL, 'o' }, - { "output", required_argument, NULL, 'O' }, - { "output-all", no_argument, NULL, OPT_OUTPUT_ALL }, - { "sizelimit", required_argument, NULL, OPT_SIZELIMIT }, - { "partscan", no_argument, NULL, 'P' }, - { "read-only", no_argument, NULL, 'r' }, - { "direct-io", optional_argument, NULL, OPT_DIO }, - { "raw", no_argument, NULL, OPT_RAW }, - { "show", no_argument, NULL, OPT_SHOW }, - { "type", required_argument, NULL, 't' }, - { "verbose", no_argument, NULL, 'v' }, - { "version", no_argument, NULL, 'V' }, - { NULL, 0, NULL, 0 } - }; - - static const ul_excl_t excl[] = { /* rows and cols in ASCII order */ - { 'D','a','c','d','f','j' }, - { 'D','c','d','f','l' }, - { 'D','c','d','f','O' }, - { 'J',OPT_RAW }, - { 0 } - }; - int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT; - - setlocale(LC_ALL, ""); - bindtextdomain(PACKAGE, LOCALEDIR); - textdomain(PACKAGE); - close_stdout_atexit(); - - if (loopcxt_init(&lc, 0)) - err(EXIT_FAILURE, _("failed to initialize loopcxt")); - - while ((c = getopt_long(argc, argv, "ab:c:d:Dfhj:JlLno:O:Prt:vV", - longopts, NULL)) != -1) { - - err_exclusive_options(c, longopts, excl, excl_st); - - switch (c) { - case 'a': - act = A_SHOW; - break; - case 'b': - set_blocksize = 1; - blocksize = strtosize_or_err(optarg, _("failed to parse logical block size")); - break; - case 'c': - act = A_SET_CAPACITY; - if (!is_loopdev(optarg) || - loopcxt_set_device(&lc, optarg)) - err(EXIT_FAILURE, _("%s: failed to use device"), - optarg); - break; - case 'r': - lo_flags |= LO_FLAGS_READ_ONLY; - break; - case 'd': - act = A_DELETE; - if (!is_loopdev(optarg) || - loopcxt_set_device(&lc, optarg)) - err(EXIT_FAILURE, _("%s: failed to use device"), - optarg); - break; - case 'D': - act = A_DELETE_ALL; - break; - case 'f': - act = A_FIND_FREE; - break; - case 'J': - json = 1; - break; - case 'j': - act = A_SHOW; - file = optarg; - break; - case 'l': - list = 1; - break; - case 'L': - no_overlap = 1; - break; - case 'n': - no_headings = 1; - break; - case OPT_RAW: - raw = 1; - break; - case 'o': - offset = strtosize_or_err(optarg, _("failed to parse offset")); - flags |= LOOPDEV_FL_OFFSET; - break; - case 'O': - outarg = optarg; - list = 1; - break; - case OPT_OUTPUT_ALL: - for (ncolumns = 0; ncolumns < ARRAY_SIZE(infos); ncolumns++) - columns[ncolumns] = ncolumns; - break; - case 'P': - lo_flags |= LO_FLAGS_PARTSCAN; - break; - case OPT_SHOW: - showdev = 1; - break; - case OPT_DIO: - use_dio = set_dio = 1; - if (optarg) - use_dio = parse_switch(optarg, _("argument error"), "on", "off", NULL); - break; - case 't': - if (optarg) { - if (parse_file_fmt_type(optarg, &file_fmt_type) == 0) - use_file_fmt_type = 1; - else - errx(EXIT_FAILURE, _("failed to parse file format type")); - } - break; - case 'v': - break; - case OPT_SIZELIMIT: /* --sizelimit */ - sizelimit = strtosize_or_err(optarg, _("failed to parse size")); - flags |= LOOPDEV_FL_SIZELIMIT; - break; - - case 'h': - usage(); - case 'V': - print_version(EXIT_SUCCESS); - default: - errtryhelp(EXIT_FAILURE); - } - } - - ul_path_init_debug(); - ul_sysfs_init_debug(); - - /* default is --list --all */ - if (argc == 1) { - act = A_SHOW; - list = 1; - } - - if (!act && argc == 2 && (raw || json)) { - act = A_SHOW; - list = 1; - } - - /* default --list output columns */ - if (list && !ncolumns) { - columns[ncolumns++] = COL_NAME; - columns[ncolumns++] = COL_SIZELIMIT; - columns[ncolumns++] = COL_OFFSET; - columns[ncolumns++] = COL_AUTOCLR; - columns[ncolumns++] = COL_RO; - columns[ncolumns++] = COL_BACK_FILE; - columns[ncolumns++] = COL_FILE_FMT_TYPE; - columns[ncolumns++] = COL_DIO; - columns[ncolumns++] = COL_LOGSEC; - } - - if (act == A_FIND_FREE && optind < argc) { - /* - * xlosetup -f <backing_file> - */ - act = A_CREATE; - file = argv[optind++]; - - if (optind < argc) - errx(EXIT_FAILURE, _("unexpected arguments")); - } - - if (list && !act && optind == argc) - /* - * xlosetup --list defaults to --all - */ - act = A_SHOW; - - if (!act && optind + 1 == argc) { - /* - * xlosetup [--list] <device> - * OR - * xlosetup {--direct-io[=off]|--logical-blocksize=size}... <device> - */ - if (!(set_dio || set_blocksize)) - act = A_SHOW_ONE; - if (set_dio) - act = A_SET_DIRECT_IO; - if (set_blocksize) - act = A_SET_BLOCKSIZE; - if (!is_loopdev(argv[optind]) || - loopcxt_set_device(&lc, argv[optind])) - err(EXIT_FAILURE, _("%s: failed to use device"), - argv[optind]); - optind++; - } - if (!act) { - /* - * xlosetup <xloopdev> <backing_file> - */ - act = A_CREATE; - - if (optind >= argc) - errx(EXIT_FAILURE, _("no xloop device specified")); - /* don't use is_loopdev() here, the device does not have exist yet */ - if (loopcxt_set_device(&lc, argv[optind])) - err(EXIT_FAILURE, _("%s: failed to use device"), - argv[optind]); - optind++; - - if (optind >= argc) - errx(EXIT_FAILURE, _("no file specified")); - file = argv[optind++]; - } - - if (act != A_CREATE && - (sizelimit || lo_flags || showdev || use_file_fmt_type)) - errx(EXIT_FAILURE, - _("the options %s are allowed during xloop device setup only"), - "--{sizelimit,partscan,read-only,show,type}"); - - if ((flags & LOOPDEV_FL_OFFSET) && - act != A_CREATE && (act != A_SHOW || !file)) - errx(EXIT_FAILURE, _("the option --offset is not allowed in this context")); - - if (outarg && string_add_to_idarray(outarg, columns, ARRAY_SIZE(columns), - &ncolumns, column_name_to_id) < 0) - return EXIT_FAILURE; - - switch (act) { - case A_CREATE: - res = create_loop(&lc, no_overlap, lo_flags, flags, file, - offset, sizelimit, blocksize, file_fmt_type); - if (res == 0) { - if (showdev) - printf("%s\n", loopcxt_get_device(&lc)); - if (set_dio) - goto lo_set_dio; - } - break; - case A_DELETE: - res = delete_loop(&lc); - while (optind < argc) { - if (!is_loopdev(argv[optind]) || - loopcxt_set_device(&lc, argv[optind])) - warn(_("%s: failed to use device"), - argv[optind]); - optind++; - res += delete_loop(&lc); - } - break; - case A_DELETE_ALL: - res = delete_all_loops(&lc); - break; - case A_FIND_FREE: - res = loopcxt_find_unused(&lc); - if (res) { - int errsv = errno; - - if (access(_PATH_DEV_LOOPCTL, F_OK) == 0 && - access(_PATH_DEV_LOOPCTL, W_OK) != 0) - ; - else - errno = errsv; - - warn(_("cannot find an unused xloop device")); - } else - printf("%s\n", loopcxt_get_device(&lc)); - break; - case A_SHOW: - if (list) - res = show_table(&lc, file, offset, flags); - else - res = show_all_loops(&lc, file, offset, flags); - break; - case A_SHOW_ONE: - if (list) - res = show_table(&lc, NULL, 0, 0); - else - res = printf_loopdev(&lc); - if (res) - warn("%s", loopcxt_get_device(&lc)); - break; - case A_SET_CAPACITY: - res = loopcxt_ioctl_capacity(&lc); - if (res) - warn(_("%s: set capacity failed"), - loopcxt_get_device(&lc)); - break; - case A_SET_DIRECT_IO: -lo_set_dio: - res = loopcxt_ioctl_dio(&lc, use_dio); - if (res) - warn(_("%s: set direct io failed"), - loopcxt_get_device(&lc)); - break; - case A_SET_BLOCKSIZE: - res = loopcxt_ioctl_blocksize(&lc, blocksize); - if (res) - warn(_("%s: set logical block size failed"), - loopcxt_get_device(&lc)); - break; - default: - warnx(_("bad usage")); - errtryhelp(EXIT_FAILURE); - break; - } - - loopcxt_deinit(&lc); - return res ? EXIT_FAILURE : EXIT_SUCCESS; -} - |
