#!/bin/sh -e # manage files in a webroot # needs: # - sh: cp, rm, mv, echo, basename, dirname # - openssh: ssh, scp # - coreutils: chmod, sed, tail # - archivers: gzip, tar # - xclip ### ### CONFIGURATION ### # remote patch uploaded files should go _rpath="/home/www/htdocs/ptrace/paste" # web url where the uploaded files can be accessed _weburi="https://ptrace.org" # ssh user@host _sshhost="sdk@codevoid.de" # permissions (for the fixl command) _chown="sdk:www" _chmod="u+rw,g+r" ### ### SET ARGUMENT SWITCHES ### for arg in "$@" do case "$arg" in # extensions sh) _ext=".sh" ;; ksh) _ext=".ksh" ;; txt) _ext=".txt" ;; log) _ext=".log" ;; # archive mode gz) _gz=1 ;; tgz) _tgz=1 ;; # commands rm) _rm=1 ;; rml) _rmlast=1 ;; ls) _ls=1 ;; l|last) _last="-1" ;; -[0-9]*) _last="$arg" ;; fixl) _fixperm=1 ;; ren|mv) _mv=1 ;; renl|mvl) _mvlast=1 ;; -h) ;; # swallow *) break; ;; esac shift; done ### ### FUNCTIONS ### # fetches remote file list remote_list() { ssh $_sshhost \ "cd $_rpath/ \ && ls -1tr" } # formats file list output remote_list_print() { while read f do echo "$_weburi/$(echo "$f" \ | sed 's/ /%20/g') ($f)" done } copy_and_print() { echo "$_weburi/$(basename "$1")" \ | sed 's/ /%20/g' \ | xclip -f -r echo } ### ### MAIN PROGRAM ### # HANDLE CASE: "standard input" # upload with provided or generated filename if [[ ! -t 0 ]] then fname="$1" [ -z "$fname" ] \ && fname="$(date +"%Y-%m-%d_%H%M%S").txt" cat - | ssh $_sshhost "cat - > \"$_rpath/$fname\"" copy_and_print "$fname" exit 0 fi # HANDLE CASE: "list all remote files" if [ -n "$_ls" ] then remote_list \ | remote_list_print exit 0 fi # HANDLE CASE: "list last N files" if [ -n "$_last" ] then remote_list \ | tail $_last \ | remote_list_print exit 0 fi # HANDLE CASE: rename remote file if [ -n "$_mv" ] then ssh $_sshhost \ "cd $_rpath/ \ && mv -v \"$1\" \"$2\"" echo "$2" | remote_list_print exit 0 fi # HANDLE CASE: rename the last uploaded remote file if [ -n "$_mvlast" ] then lastfile="$(remote_list | tail -1)" ssh $_sshhost \ "cd $_rpath/ \ && mv -v \"$lastfile\" \"$1\"" echo "$1" | remote_list_print exit 0 fi # HANDLE CASE: delete remote file if [ -n "$_rm" ] then for file in "$@" do ssh $_sshhost \ "cd $_rpath/ \ && rm -v \"$(basename "$file")\"" \ || true done exit 0 fi # HANDLE CASE: delete last uploaded remote file if [ -n "$_rmlast" ] then lastfile="$(remote_list | tail -1)" echo "rm $lastfile" ssh $_sshhost \ "cd $_rpath/ \ && rm -f \"$lastfile\"" \ || true exit 0 fi # HANDLE CASE: fix permission of last file if [ -n "$_fixperm" ] then lastfile="$(remote_list | tail -1)" echo "Fixing: $lastfile" ssh $_sshhost "cd $_rpath/; \ chown $_chown \"$lastfile\"; \ chmod $_chmod \"$lastfile\"; \ ls -lh \"$lastfile\"" exit 0 fi # HANDLE CASE: upload of files and folders if [ $# -gt 0 ] then for item in "$@" do # the whole handling shall run in a subshell so all variables # are reset when we leave the scope. Note, that this requires # us to "return", instead of "continue" skip to the next loop # iteration ( [ ! -e "$item" ] \ && echo "File or directory not found: $item" \ && return # target filename file="$(basename "$item")$_ext" # CASE "file" "no archive mode" if [ -f "$item" ] && [ -z "$_tgz" ] && [ -z "$_gz" ] then echo "Uploading $item as $file" scp -q "$item" $_sshhost:"$_rpath/$file" copy_and_print "$file" return fi # CASE "folder" [ -d "$item" ] && _tgz=1 # CASE "tgz archive mode" if [ -n "$_tgz" ] then file="$file.tgz" echo "Uploading $item as $file" # moving closer to the item to not archive the whole path cd $(dirname "$item") tar czf - "$(basename "$item")" \ | ssh $_sshhost "cat - > \"$_rpath/$file\"" copy_and_print "$file" return fi # CASE "gz archive mode" if [ -f "$item" ] && [ -n "$_gz" ] then file="$file.gz" echo "Uploading \"$item\" as \"$file\"" cat "$item" | gzip \ | ssh $_sshhost "cat - > \"$_rpath/$file\"" copy_and_print "$file" return fi # hopefully never reached echo "Unhandled situation for: $item" ) # leave scope & reset variables done fi # USAGE if [ $# -eq 0 ] then echo "usage: upload [command] [ext] []" echo " upload [filename] < file" echo " cat file | upload [filename]" echo echo " Commands:" echo " rm - remove files" echo " rml - remove last upload" echo " ls - list files" echo " l|last - list last file" echo " -0..N - list N last files" echo " mv|ren - rename file" echo " mvl|renl - rename last uploaded file" echo " fixl - fix permission of last uploaded file" echo echo " Extensions:" echo " sh, ksh, txt, log - add extension to file" echo " gz, tgz - uploads file as archive (tgz is always used for folders)" echo echo " - files or directories to upload (needs to be the last argument)" echo echo "Special Case:" echo " When data is piped to the script it expects only one" echo " optional argument, which would be the target filename." echo exit 2 fi