diff --git a/bin/cclip b/bin/cclip new file mode 120000 index 0000000..68ba3b8 --- /dev/null +++ b/bin/cclip @@ -0,0 +1 @@ +../files/cclip \ No newline at end of file diff --git a/files/cclip b/files/cclip new file mode 100755 index 0000000..342d176 --- /dev/null +++ b/files/cclip @@ -0,0 +1,198 @@ +#!/bin/bash + +set -e +_help() { + SELF=$( basename "$0" ) + echo "Console Clipboard manager + + Usage: $SELF [command] [name] [filename] + + Commands: + (r)ead + (w)rite + (d)elete + (l)ist [default] + + Name: Any string for the clipboard name. default: 0 + Filename: + When reading from clipboard: + File or folder to write the clipboard contents. If omitted: stdout + When writing to clipboard:g/ + File or folder to read from. If omitted: stdin + + Shorthand: + echo my data | $SELF 1 # writes data with name: 1 + $SELF 1 | cat - # prints the contents of file: 1 +" + exit +} + + +_load_config(){ + STORAGE=~/.cache/qclip + + [[ -f ~/.config/qclip/config ]] || { + mkdir -p ~/.config/qclip + echo STORAGE=$STORAGE > ~/.config/qclip/config + _msg "created config in ~/.config/qclip/config" + } + [[ -f ~/.config/qclip/config ]] && . ~/.config/qclip/config + # TODO, run line by line for security, get only lines with matching config item + mkdir -p "$STORAGE" + [[ -e "$STORAGE"/0 ]] || { + echo Sample data | _write_stdin 0 + } +} + +_list() { + cd "$STORAGE" + [[ $(ls -A) ]] || { + _msg "No clipboard entries" + return + } + printf " %30s %8s %-19s %s\n" Type Size Date Name + for n in *; do + size=$( du -k -h -s --apparent-size "$n" | awk '{ print $1 }' ) + type=$( file -b "$n" ) + date=$( date -r "$n" -Iseconds ) + printf " %30s %8s %-19s %s\n" \ + "${type:0:30}" \ + "$size" \ + "${date::-6}" \ + "$n" + done +} + +_write() { + # no file mentioned, use stdin + [[ -z "$FILE" ]] && stream_in=1 + # stdin is open, use stdin + [ -t 0 ] || stream_in=1 + + [ -t 0 ] && [[ -z "$FILE" ]] && { + _msg File to read needed, or use stdin + exit 1 + } + + # sure to write something, delete target first + rm -rf "$STORAGE/$NAME" + + [[ "$stream_in" -eq 1 ]] && { + _write_stdin "$NAME" + } || { + _write_files "$NAME" "$FILE" + } +} + +_write_files() { # name, file + cp -av "$2" "$STORAGE/$1" +} +_write_stdin() { # name + cat - > "$STORAGE/$1" +} + +_read() { + [[ -e "$STORAGE/$NAME" ]] || { + _msg "No such clipboard" + return + } + [[ -z "$FILE" ]] && stream_out=1 + [ -t 1 ] || stream_out=1 + + [[ "$stream_out" -eq 1 ]] && { + [[ -d "$STORAGE/$NAME" ]] && { + _msg "$NAME is a directory, needs target [file]" + exit 1 + } + _read_stdout "$NAME" + } || { + _read_files "$NAME" "$FILE" + } +} + +_read_files() { # name, file + cp -av "$STORAGE/$1" "$2" +} +_read_stdout() { # name + cat "$STORAGE/$1" +} + +_delete() { # name + [[ -e "$STORAGE/$1" ]] || { + _msg No such clipboard + exit 1 + } + [[ "$FORCE" -ne 1 ]] && { + read -p "Really delete $1 ? Break to cancel. " foo + } + rm -vrf "$STORAGE/$1" +} + +_msg() { + echo "$@" >&2 +} + +_get_name() { + [[ "$ARG1" = "$CMD" ]] && { + NAME="$ARG2" + } || { + NAME="$ARG1" + } + [[ -z "$NAME" ]] && NAME=0 + return 0 +} + +_get_file() { + [[ "$ARG1" = "$NAME" ]] && { + FILE="$ARG2" + } + [[ "$ARG2" = "$NAME" ]] && { + FILE="$ARG3" + } + return 0 +} + +for (( i=1; i<=$#; i++ )); do + [[ "${!i}" = "-h" ]] && _help + [[ "${!i}" = "--help" ]] && _help +done +_load_config +ARG1="$1" +ARG2="$2" +ARG3="$3" +CMD=list +[[ "$1" = "r" || "$1" = "read" ]] && { CMD=read; ARG1=$CMD; } +[[ "$1" = "w" || "$1" = "write" ]] && { CMD=write; ARG1=$CMD; } +[[ "$1" = "d" || "$1" = "delete" || "$1" = "del" ]] && { CMD=delete; ARG1=$CMD; } +[[ "$1" = "l" || "$1" = "list" ]] && { CMD=list; ARG1=$CMD; } +[[ "$1" = "h" || "$1" = "help" ]] && _help +[[ -n "$1" ]] && [[ -e "$STORAGE"/"$1" ]] && CMD=read +# if stdout redirected, default to read +[ -t 1 ] || CMD=read +# if stdin comes from stream, default to write +[ -t 0 ] || CMD=write + +[[ "$CMD" = list ]] && { + _list + exit $? +} +_get_name +_get_file +[[ "$CMD" = read ]] && { + _read + exit $? +} +[[ "$CMD" = delete ]] && { + _delete "$NAME" + exit $? +} +[[ "$CMD" = write ]] && { + _write + exit $? +} + + +# TODO: +# folders written as TAR +# content encrypted with conf variable? +