diff options
author | merakor <cem@ckyln.com> | 2020-12-21 11:13:51 +0000 |
---|---|---|
committer | merakor <cem@ckyln.com> | 2020-12-21 11:13:51 +0000 |
commit | 440af4f3ebfecd68dabf8ce5524fd3f953e81c71 (patch) | |
tree | d7ceaf1d040bad60822c87ad78ca30de76df1342 | |
parent | 36308f68ddd95984c1909c5ca00a6ab70544d15b (diff) | |
download | cpt-440af4f3ebfecd68dabf8ce5524fd3f953e81c71.tar.gz |
cpt: remove cpt-stat and cpt-readlink, add _stat() and _readlinkf
cpt-readlink and cpt-stat were unnecessary additions for mundane tasks. Since
they were binaries instead of scripts, they added an extra layer of complexity
to the library.
These functions are now included inside the package manager library with the names
_readlinkf() and _stat().
FossilOrigin-Name: 7e15e2b57ddcb834c4286c8d1ac0a28031ae4f5d39f3c6a99f5b3aa0e9a83d43
-rw-r--r-- | .gitignore | 6 | ||||
-rw-r--r-- | README | 8 | ||||
-rw-r--r-- | bin/all.do | 2 | ||||
-rw-r--r-- | bin/clean.do | 2 | ||||
-rw-r--r-- | bin/cpt-readlink.c | 47 | ||||
-rw-r--r-- | bin/cpt-stat.c | 41 | ||||
-rw-r--r-- | bin/test.do | 11 | ||||
-rw-r--r-- | clean.do | 2 | ||||
-rw-r--r-- | config.rc | 2 | ||||
-rwxr-xr-x | contrib/cpt-owns | 3 | ||||
-rw-r--r-- | default.do | 13 | ||||
-rw-r--r-- | man/cpt-contrib.1 | 10 | ||||
-rwxr-xr-x | src/cpt | 4 | ||||
-rwxr-xr-x | src/cpt-checksum | 3 | ||||
-rw-r--r-- | src/cpt-lib.in | 64 | ||||
-rwxr-xr-x | src/cpt-list | 12 |
16 files changed, 74 insertions, 156 deletions
@@ -1,9 +1,3 @@ -### Binaries/Objects ### -cpt-lib -cpt-stat -cpt-readlink -*.o - ### Emacs ### \#*\# *~ @@ -19,22 +19,20 @@ Dependencies To build and use cpt, you need the following software. -MAKE DEPENDS -- C compiler -- redo (the repository contains minimal/do) - RUNTIME DEPENDS - rsync - curl - POSIX base utilities [coreutils, busybox, sbase, etc.] - tar [GNU tar, busybox, toybox, libarchive, etc.] +MAKE DEPENDS +- redo (optional, the repository contains minimal/do) + Directory Structure -------------------------------------------------------------------------------- / -- README, LICENSE, CHANGELOG - bin/ -- for C programs. contrib/ -- for Shell scripts that wrap around cpt. docs/ -- for documentation. man/ -- for manual pages. diff --git a/bin/all.do b/bin/all.do deleted file mode 100644 index aceda74..0000000 --- a/bin/all.do +++ /dev/null @@ -1,2 +0,0 @@ -. ../config.rc -redo-ifchange cpt-readlink cpt-stat diff --git a/bin/clean.do b/bin/clean.do deleted file mode 100644 index 6234248..0000000 --- a/bin/clean.do +++ /dev/null @@ -1,2 +0,0 @@ -. ../config.rc -rm -f -- ./*.o cpt-readlink cpt-stat .dep.* diff --git a/bin/cpt-readlink.c b/bin/cpt-readlink.c deleted file mode 100644 index e7cfe50..0000000 --- a/bin/cpt-readlink.c +++ /dev/null @@ -1,47 +0,0 @@ -/* cpt-readlink --- a utility replacement for readlink - * See LICENSE for copyright information. - * - * This is basically a 'readlink -f' command. - */ -#include <stdio.h> -#include <stdlib.h> -#include <libgen.h> -#include <string.h> -#include <limits.h> - -#define DIR_MAX PATH_MAX - NAME_MAX - 1 - - -char *realpath(const char *path, char *resolved_path); - -int -main(int argc, char *argv[]) -{ - - char buf[PATH_MAX]; - - /* We are going to use these if the file doesn't exist, but we can still - * use directories above the file. We are using dname and bname so that - * they don't clash with the functions with the same name. - */ - char dname[DIR_MAX]; /* directory name */ - char bname[NAME_MAX]; /* base name */ - sprintf(bname, "%s", (basename(argv[1]))); - - if (argc != 2 || strcmp(argv[1], "--help") == 0) { - fprintf(stderr, "usage: %s [file]\n", argv[0]); - return 1; - } - - if (!realpath(argv[1], buf)) { - - if (!realpath(dirname(argv[1]), dname)) { - perror(argv[0]); - return 1; - } - sprintf(buf, "%s/%s", dname, bname); - } - - printf("%s\n", buf); - return 0; -} diff --git a/bin/cpt-stat.c b/bin/cpt-stat.c deleted file mode 100644 index 584c2df..0000000 --- a/bin/cpt-stat.c +++ /dev/null @@ -1,41 +0,0 @@ -/* cpt-stat --- a utility for getting the user name of file owner - * See LICENSE for copyright information - * - * The reason this simple tool exists is because 'stat' is not - * portable and ls is not exactly stable enough for scripting. - * This program is for outputting the owner name, and that's it. - */ - -#include <pwd.h> -#include <sys/stat.h> -#include <stdio.h> -#include <string.h> - -struct passwd *pw; -struct stat sb; - -int -main (int argc, char *argv[]) -{ - /* Exit if no or multiple arguments are given. */ - if (argc != 2 || strcmp(argv[1], "--help") == 0) { - fprintf(stderr, "Usage: %s [pathname]\n", argv[0]); - return 1; - } - - /* Exit if file stat cannot be obtained. */ - if (lstat(argv[1], &sb) == -1) { - perror(argv[0]); - return 1; - } - - /* Exit if name of the owner cannot be retrieved. */ - if (!getpwuid(sb.st_uid)) { - return 1; - } - - /* Print the user name of file owner. */ - pw = getpwuid(sb.st_uid); - printf("%s\n", pw->pw_name); - return 0; -} diff --git a/bin/test.do b/bin/test.do deleted file mode 100644 index 4794751..0000000 --- a/bin/test.do +++ /dev/null @@ -1,11 +0,0 @@ -. ../config.rc -redo all -exec >&2 - -./cpt-readlink . -./cpt-readlink .. -./cpt-readlink /bin -./cpt-stat /bin -./cpt-stat cpt-readlink.o - -PHONY @@ -1,5 +1,5 @@ . ./config.rc -redo bin/clean src/clean +redo src/clean redo_clean rm -f "cpt-$VERSION.tar.xz" find docs -name '*.info' -exec rm -f -- {} + @@ -76,7 +76,7 @@ PHONY() { getbin() { # Function to get all executables - find src contrib bin -name 'cpt-*' ! -name '*.in' ! -name '*.[coh]' + find src contrib -name 'cpt-*' ! -name '*.in' } diff --git a/contrib/cpt-owns b/contrib/cpt-owns index 5f73674..9e3cccb 100755 --- a/contrib/cpt-owns +++ b/contrib/cpt-owns @@ -1,5 +1,6 @@ #!/bin/sh -e # Check which package owns a file +. cpt-lib case "$1" in ''|--help|-h) printf '%s\n' "usage: ${0##*/} [file]" ; exit 0 ; esac @@ -17,7 +18,7 @@ esac # Strip 'CPT_ROOT' from the file path if passed and # follow symlinks. file="${1#$CPT_ROOT}" -dirname=$(cpt-readlink "$CPT_ROOT/${file%/*}") +dirname=$(_readlinkf "$CPT_ROOT/${file%/*}") file="$dirname/${file##*/}" # Check if the file exists and exit if it is not. @@ -4,7 +4,7 @@ fn="${1%.*}" case "$1" in - all) redo-ifchange src/cpt-lib bin/all docs/all ;; + all) redo-ifchange src/cpt-lib docs/all ;; dist) redo clean redo "cpt-$VERSION.tar.xz" @@ -13,15 +13,6 @@ case "$1" in redo-ifchange "$1.in" sed "s|@VERSION@|$VERSION|g" < "$1.in" > "$3" ;; - bin/cpt-readlink|bin/cpt-stat) - redo-ifchange "$1.o" - "$CC" -o "$3" $LDFLAGS "$1.o" $LIBS - ;; - *.o) - [ -f "${1%.o}.c" ] || exit 99 - redo-ifchange "$fn.c" - "$CC" -c -o "$3" $CFLAGS "$fn.c" - ;; "cpt-$VERSION.tar.xz") redo docs/cpt.info rm -rf -- "cpt-$VERSION" @@ -38,7 +29,7 @@ case "$1" in mv "$1" "$3" ;; test) - redo src/test bin/test + redo src/test ;; src/clean) rm -f src/cpt-lib diff --git a/man/cpt-contrib.1 b/man/cpt-contrib.1 index 8a34364..ffc5e54 100644 --- a/man/cpt-contrib.1 +++ b/man/cpt-contrib.1 @@ -88,11 +88,6 @@ can be used to check if personal packages are outdated. <file> Checks which package has installed the given file. -.SH CPT-READLINK -.B cpt-readlink -<file> - -A 'readlink -f' replacement to be used inside the package manager. .SH CPT-REPODEPENDS .B cpt-repodepends <pkg> @@ -112,11 +107,6 @@ Prints the packages that depend on the given package. (Reverse dependencies) <pkg> Prints the given package's size, and its individual files. -.SH CPT-STAT -.B cpt-stat -<file> - -Outputs the owner name of a file/directory .SH CPT-WHICH .B cpt-which <pkg> @@ -16,8 +16,8 @@ case "$arg" in done for path; do - # These are the files to be ignored. - contains "lib readlink stat" "$path" && continue + # Ignore the library. + [ lib = "$path" ] && continue printf "%b->%b %-${max}s " "$colorb" "$colre" "${path#*/cpt-}" sed -n 's/^# *//;2p' "$(command -v "cpt-$path")" diff --git a/src/cpt-checksum b/src/cpt-checksum index 0a83ae0..cd1fa4e 100755 --- a/src/cpt-checksum +++ b/src/cpt-checksum @@ -22,8 +22,7 @@ for pkg; do tee "$repo_dir/checksums" else log "$pkg" "Need permissions to generate checksums" - - user=$(cpt-stat "$repo_dir") as_root tee "$repo_dir/checksums" + user=$(_stat "$repo_dir") as_root tee "$repo_dir/checksums" fi } diff --git a/src/cpt-lib.in b/src/cpt-lib.in index 3d2b2f4..34af54b 100644 --- a/src/cpt-lib.in +++ b/src/cpt-lib.in @@ -44,6 +44,48 @@ trap_set() { esac } +_stat() ( + _user=; eval set -- "$(ls -ld "$1")" + id -u "${_user:=$3}" >/dev/null 2>&1 || _user=root + printf '%s' "$_user" +) + +_readlinkf() ( + # Public domain POSIX sh readlink function by Koichi Nakashima + [ "${1:-}" ] || return 1 + max_symlinks=40 + CDPATH='' # to avoid changing to an unexpected directory + + target=$1 + [ -e "${target%/}" ] || target=${1%"${1##*[!/]}"} # trim trailing slashes + [ -d "${target:-/}" ] && target="$target/" + + cd -P . 2>/dev/null || return 1 + while [ "$max_symlinks" -ge 0 ] && max_symlinks=$((max_symlinks - 1)); do + if [ ! "$target" = "${target%/*}" ]; then + case $target in + /*) cd -P "${target%/*}/" 2>/dev/null || break ;; + *) cd -P "./${target%/*}" 2>/dev/null || break ;; + esac + target=${target##*/} + fi + + if [ ! -L "$target" ]; then + target="${PWD%/}${target:+/}${target}" + printf '%s\n' "${target:-/}" + return 0 + fi + + # `ls -dl` format: "%s %u %s %s %u %s %s -> %s\n", + # <file mode>, <number of links>, <owner name>, <group name>, + # <size>, <date and time>, <pathname of link>, <contents of link> + # https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html + link=$(ls -dl -- "$target" 2>/dev/null) || break + target=${link#*" $target -> "} + done + return 1 +) + # This is the public domain getoptions shell library. It also forms a usage # function. # URL: https://github.com/ko1nksm/getoptions (v2.0.1) @@ -1145,14 +1187,11 @@ pkg_conflicts() { # Use $CPT_ROOT in filename so that we follow its symlinks. file=$CPT_ROOT/${file#/} - # We will only follow the symlinks of the directories, so we - # reserve the directory name in this 'dirname' value. cpt-readlink - # functions in a similar fashion to 'readlink -f', it makes sure - # every component except for the first one to be available on - # the directory structure. If we cannot find it in the system, - # we don't need to make this much more complex by trying so - # hard to find it. Simply use the original directory name. - dirname="$(cpt-readlink "${file%/*}" 2>/dev/null)" || + # We will only follow the symlinks of the directories, so we reserve the + # directory name in this 'dirname' value. If we cannot find it in the + # system, we don't need to make this much more complex by trying so hard + # to find it. Simply use the original directory name. + dirname="$(_readlinkf "${file%/*}" 2>/dev/null)" || dirname="${file%/*}" @@ -1577,8 +1616,7 @@ pkg_fetch() { # ownership of files and directories in the rare # case that the repository is owned by a 3rd user. ( - user=$(cpt-stat "$PWD") || user=root - id -u "$user" >/dev/null 2>&1 || user=root + user=$(_stat "$PWD") [ "$user" = root ] || log "Dropping permissions to $user for pull" @@ -1614,8 +1652,7 @@ pkg_fetch() { # We are going to do the same operation as above, to # find the owner of the repository. ( - user=$(cpt-stat "$PWD") || user=root - id -u "$user" >/dev/null 2>&1 || user=root + user=$(_stat "$PWD") [ "$user" = root ] || log "Dropping permissions to $user for pull" @@ -1647,8 +1684,7 @@ pkg_fetch() { # Similar to the git update, we find the owner of # the repository and spawn rsync as that user. ( - user=$(cpt-stat "$PWD") || user=root - id -u "$user" >/dev/null 2>&1 || user=root + user=$(_stat "$PWD") [ "$user" = root ] || log "Dropping permissions to $user for pull" diff --git a/src/cpt-list b/src/cpt-list index a161abf..363e22f 100755 --- a/src/cpt-list +++ b/src/cpt-list @@ -5,11 +5,23 @@ parser_definition() { setup REST help:usage -- "usage: ${0##*/} [-c] [pkg...]" msg -- '' 'Options:' flag CURRENT -c --current -- "Use the current directory as a package" + param PKG --check label:" --check PKG TRUE FALSE" -- \ + "Check if PKG exists and return the string of TRUE if"\ + "it exists, and the string of FALSE if it doesn't." \ + "Useful for optional packaging." global_options } if [ -f ./cpt-lib ]; then . ./cpt-lib; else . cpt-lib; fi +if [ "$PKG" ]; then + if pkg_list "$PKG" >/dev/null 2>&1; then + printf %s "$1" + else + printf %s "$2" + fi +else [ "$CURRENT" ] && set -- "${PWD##*/}" pkg_list "$@" +fi |