plumb (5665B)
1 #!/bin/sh 2 3 echo(){ 4 printf '%s\n' "$*" 5 } 6 7 matches(){ 8 echo "$arg" | grep -Ei "$@" >/dev/null 9 } 10 11 fmatches(){ 12 file "$arg" | grep -Ei "$@" >/dev/null 13 } 14 15 fmagic(){ 16 isfile "$arg" || return 1 17 grep "$1" < "$arg" >/dev/null 18 } 19 20 _envsubst(){ 21 str="$*" 22 23 env | 24 while read -r line 25 do 26 str=$(echo "$str" | awk -v "var=${line%%=*}" -v "val=${line#*=}" ' 27 { 28 regex = sprintf("\\$%s", var) 29 gsub(regex, val) 30 print 31 }' 32 ) 33 echo "$str" 34 done | tail -n 1 35 } 36 37 plumb(){ 38 t="$1"; shift 39 [ $norun -eq 1 ] && return 40 export norun=1 41 case "$t" in 42 gui) 43 >/dev/null 2>/dev/null nohup sh -c "$*; rm '$file'" & 44 ;; 45 terminal) 46 >/dev/null 2>/dev/null nohup ${TERMINAL:-st} sh -c "$*; rm '$file'" & 47 ;; 48 prompt) 49 >/dev/null 2>/dev/null nohup ${TERMINAL:-st} sh -c "$(dmenu -i -p "$*"); rm '$file'" & 50 ;; 51 matchlater) 52 export norun=0 53 >/dev/null 2>/dev/null nohup sh -c "$*" & 54 ;; 55 *) 56 herbe "No such plumb-type: $t" 57 ;; 58 esac 59 } 60 61 replace(){ 62 arg=$(echo "$arg" | sed "$*") 63 } 64 65 isfile(){ 66 [ -z "$1" ] && { 67 [ -f "$arg" ] 68 return $? 69 } 70 [ -n "$1" ] && { 71 [ -f "$1" ] 72 return $? 73 } 74 } 75 76 hascmd(){ 77 command -v "$*" >/dev/null 78 } 79 80 wasfetched(){ 81 [ -n "$orig" ] 82 } 83 84 fetch(){ 85 file="/tmp/plumb.$(basename "$arg")" 86 while [ -f $file ] 87 do 88 file="/tmp/plumb.$(base64 </dev/urandom | tr -d / | head -c10).$(basename "$arg")" 89 done 90 $proxy curl $([ "$verbose" != "y" ] && echo -s) "$(echo "$arg" | sed -E 's/]|\[|}|\{/\\&/g')" > "$file" 91 export orig="$arg" 92 export arg="$file" 93 removelater "$file" 94 } 95 96 removelater(){ 97 [ -z "$exittrap" ] && exittrap="$*" 98 exittrap="$exittrap; rm -rf \"$*\"" 99 trap "$exittrap" EXIT 100 } 101 102 mime(){ 103 mime=$($proxy curl -Li$([ "$verbose" != "y" ] && echo s) "$(echo "$arg" | sed -E 's/]|\[|}|\{/\\&/g')" | 104 awk '/^HTTP/ && $2 != "200" {s=1}; /^HTTP/ && $2 == "200" {p=1}; /^[[:space:]]*$/ {if (s) s=0; else exit 1}; p' | 105 tr '[:upper:]' '[:lower:]' | awk '$1 == "content-type:" {print $2}') 106 echo "$mime" | tee /dev/stderr | grep -i "$1" >/dev/null 107 } 108 109 case "$1" in 110 -v) 111 verbose=y 112 shift 113 ;; 114 esac 115 116 [ -n "$PLUMB" ] && exit 117 export PLUMB="$$" 118 119 for arg in "$@" 120 do 121 export norun=0 122 export gui=0 123 export proxy="" 124 export arg 125 export orig="" 126 127 # remove file:// 128 matches "^file://" && 129 replace 's~^file://~~' 130 131 # network 132 matches "://.*\.onion" && 133 export proxy="torsocks" 134 135 matches "^magnet:" && 136 plumb terminal 'addtorrent "$arg"' 137 138 matches "^(gopher|http)s?://.*\.(ogg|mp3|opus|flac|pls)$" && 139 plumb terminal '$proxy mpv --pause $arg' 140 141 matches "^(gopher|http)s?://.*\.gif$" && 142 plumb gui '$proxy mpv --loop-file $arg' 143 144 matches "(youtu.be|youtube.com).*/feeds/" && 145 plumb gui 'sfeed_addfeed "$arg"' 146 147 matches "^(gopher|http)s?://.*\.(mkv|mp4|avi|webm|ogv|gifv|mp4|ape|m3u|m3u8)$" || 148 matches "^https?://(www\.|m\.)?(youtube.com|youtu.be)" && 149 plumb gui '$proxy mpv --pause "$arg"' 150 151 matches "^https?://" && 152 ! mime "text/html" && 153 fetch 154 155 matches "^https?://" || 156 matches "\.html?$" || 157 fmatches "HTML" && 158 plumb gui 'qutebrowser $arg' 159 160 matches "^gophers?://(.*/[17+0](/|$)|[^/]*$)" && 161 plumb terminal '$proxy zygo $arg' 162 163 matches "^gophers?://" && 164 fetch 165 166 matches "^mailto:" && 167 plumb terminal 'neomutt $(echo "$arg" | sed "s~^mailto:~~")' 168 169 matches "^finger://" && 170 plumb terminal '$proxy finger $(echo "$arg" | sed "s~^finger://~~"); cat' 171 172 matches "^ssh://" && 173 plumb terminal '$proxy ssh $(echo "$arg" | sed "s~^ssh://~~;s~:[0-9]*~~")' 174 175 matches "^git://" && 176 plumb terminal '$proxy git clone $arg' 177 178 # local files now 179 fmatches "gzip" && 180 isfile && 181 plumb matchlater 'gunzip < $arg > $arg.new && mv $arg.new $arg' && 182 removelater "$arg.new" 183 184 fmatches "zip.*archive" && 185 isfile 186 plumb matchlater 'unzip -p $arg > $arg.new && mv $arg.new $arg' && 187 removelater "$arg.new" 188 189 fmatches "PGP.*public.*key|PGP.*ring" && 190 isfile && 191 plumb terminal 'gpg --import $arg; sleep 5' 192 193 fmatches "PGP.*signature" && 194 isfile && 195 plumb terminal 'gpg --verify $arg; sleep 5' 196 197 fmatches "PGP.*message|PGP.*encrypted" && 198 isfile && 199 plumb terminal 'gpg -d $arg; sleep 5' 200 201 matches ".*\.(epub|ps|eps|pdf|dvi|djvu)$" || 202 fmatches "pdf|postscript" && 203 isfile && 204 plumb gui 'zathura $arg' 205 206 matches ".*\.gif$" && 207 isfile && 208 plumb gui 'mpv --loop-file $arg' 209 210 matches ".*\.(mkv|mp4|avi|webm|ogg|ogv|gifv|mp3|mp4|opus|flac|ape|m3u|m3u8)$" || 211 fmatches "video|matroska|audio|sound" && 212 isfile && 213 plumb terminal 'mpv --pause $arg' 214 215 matches ".*\.(jpe?g|gif|tiff?|ppm|bit|bmp|png|xpm)$" || 216 fmatches "image" && 217 isfile && 218 plumb gui 'sxiv $arg' 219 220 matches "\.?/.*\.[0-9]p?$" && 221 fmatches "(roff|preprocessor)" && 222 isfile && 223 plumb terminal 'man $arg' 224 225 matches "\.(gph|gophermap)$|(^|/)gophermap$" && 226 isfile && 227 plumb terminal 'cgo -f $arg' 228 229 matches "\.(atom|rss)$|rss\.xml$|atom\.xml$" || 230 fmatches "atom|rss" || 231 fmagic "<feed.*xmlns.*http://www.w3.org/2005/Atom" || 232 fmagic "<rss" && 233 wasfetched && 234 plumb gui 'sfeed_addfeed $orig' 235 236 matches "\.(atom|rss)$|rss\.xml$" || 237 fmatches "atom|rss" || 238 fmagic "<feed.*xmlns.*http://www.w3.org/2005/Atom" || 239 fmagic "<rss" && 240 ! wasfetched && 241 plumb terminal 'sfeed < $arg | sort -rn | sfeed_curses' 242 243 # dmarc reports 244 fmagic "<feedback" && 245 fmagic "<policy_published" && 246 fmagic "<dkim" && 247 plumb terminal 'dmarc < $arg; cat' 248 249 # numbered file 250 matches ":[0-9][0-9]*$" && 251 isfile ${arg%:*} && 252 plumb terminal 'vim +${arg##*:} ${arg%:*}' 253 254 # catch all for files 255 matches ".*" && 256 isfile && 257 plumb terminal 'vim $arg' 258 259 # include files 260 matches ".*\.h$" && 261 isfile "/usr/include/$arg" && 262 plumb terminal 'vim /usr/include/$arg' 263 264 matches ".*\.h$" && 265 isfile "/usr/local/include/$arg" && 266 plumb terminal 'vim /usr/local/include/$arg' 267 268 # catch-all for non-files 269 matches ".*" && 270 plumb prompt 'Plumb to (use $arg): ' 271 done 272 wait