URI:
       plumb: plan9 plumber-like script - scripts - various script and utils
  HTML git clone git://z3bra.org/scripts
   DIR Log
   DIR Files
   DIR Refs
       ---
   DIR commit 6ca2b5c87e6b9b8603995b3db4968f6e67f3b2f0
   DIR parent 25f6018d03344905687619e01ec5091dd949d83c
  HTML Author: Willy Goiffon <dev@z3bra.org>
       Date:   Thu, 20 Aug 2026 23:06:10 +0000
       
       plumb: plan9 plumber-like script
       
       Diffstat:
         A plumb                               |     128 +++++++++++++++++++++++++++++++
       
       1 file changed, 128 insertions(+), 0 deletions(-)
       ---
   DIR diff --git a/plumb b/plumb
       @@ -0,0 +1,128 @@
       +#!/bin/sh
       +
       +# all these have the same result:
       +#
       +# plumb -u https://z3bra.org/z3bra.png
       +# echo https://z3bra.org/z3bra.png | wl-copy; plumb
       +# echo https://z3bra.org/z3bra.png | plumb -s
       +# curl -s https://z3bra.org/z3bra.png | plumb -
       +
       +usage() {
       +        echo "usage: $(basename $0) [-hs] [-u uri]" >&2
       +}
       +
       +justtype() {
       +        dos2unix -q | tr -d ' ' |cut -d: -f2 | cut -d\; -f1
       +}
       +
       +gophertype() {
       +        file=$(basename "$1")
       +        type=$(echo "$1" | cut -d/ -f4)
       +        case $type in
       +        9) printf 'application/octet-stream\n' ;;
       +        I) printf 'image/%s\n' "${file##*.}" ;;
       +        g) printf 'image/gif\n' ;;
       +        *) printf 'text/plain\n' ;;
       +        esac
       +}
       +
       +pipe() {
       +        [ -n "$proto" ] && curl -sSkL "$1" -o -
       +        [ -z "$proto" ] && cat "$1"
       +}
       +
       +getclip() {
       +        wl-paste -p 2>/dev/null
       +}
       +
       +# default mimetype
       +mime=''
       +clip="$(getclip)" # get uri from clipboard by default
       +
       +while getopts "hsu:v-" OPT; do
       +        case $OPT in
       +        s) input="$(cat)" ;; # read uri from stdin
       +        u) input="$OPTARG" ;; # pass uri as argument
       +        v) verbose=1 ;;
       +        h) usage; exit 0 ;;
       +        *) usage; exit 1 ;;
       +        esac
       +done
       +
       +shift $((OPTIND-1))
       +
       +[ $# -gt 0 ] && input="$1"
       +
       +# read file *content* to stdin when uri is -
       +[ "$1" = "-" ] && {
       +        input=$(mktemp -p /tmp plumb.XXXXXXXX)
       +        cat > $input
       +}
       +
       +uri="${input:-$clip}"
       +
       +[ -z "$uri" ] && exit 1
       +
       +proto="$(echo "$uri" | sed -n 's,^\([^:]*\)://.*,\1,p')"
       +
       +if [ -z "$proto" ]; then
       +        if [ -e "$uri" ]; then
       +                mime=$(file -i "$uri" | justtype)
       +        elif getent hosts "$uri" >/dev/null; then
       +                # assume website if name is resolvable
       +                mime="text/html"
       +        else
       +                uri="https://duckduckgo.com/?q=$uri"
       +        fi
       +else
       +        case $proto in
       +        vmrc)       mime=application/x-vmrc ;;
       +        https|http) mime=$(curl -skI "$uri" | grep -ioE 'content-type:[^;]*' | justtype) ;;
       +        gopher) 
       +                mime=$(gophertype "$uri")
       +                uri=$(echo $uri | sed 's,gopher://,http://phroxy.z3bra.org/,')
       +                ;;
       +        telnet|ssh)
       +                mime="$proto"
       +                uri="${uri#${proto}://}"
       +                host="${uri%%:*}"
       +                port="${uri##*:}"
       +                ;;
       +        esac
       +
       +        [ -z "$mime" ] && mime=$(curl -sk "$uri" | cut -b 1-100 | file -i - | justtype)
       +fi
       +
       +# verbose mode
       +[ -n "$verbose" ] && printf 'uri: %s\nproto: %s\nmime: "%s"\n' "$uri" "$proto" "$mime"
       +
       +case "$mime" in
       +        text/html) exec ${BROWSER:-firefox-nightly} "$uri" ;;
       +        text/xml)  exec ${BROWSER:-firefox-nightly} "$uri" ;;
       +        image/gif) exec mplayer -loop 0 "$uri" ;;
       +        audio/*)   exec mpv -cache 512 "$uri" ;;
       +        video/*)   exec mpv -cache 512 "$uri" ;;
       +        image/*)
       +                   if [ -n "$proto" ]; then
       +                           tmp=$(mktemp -p /tmp plumb.XXXXXXXX)
       +                           pipe "$uri" > $tmp
       +                           uri=$tmp
       +                   fi
       +                   imv-wayland "$uri"
       +                   ;;
       +        text/*)
       +                   if [ -n "$proto" ]; then
       +                           tmp=$(mktemp -p /tmp plumb.XXXXXXXX)
       +                           pipe "$uri" > $tmp
       +                           uri=$tmp
       +                   fi
       +                   tty -s && exec less "$uri" || exec st -e less "$uri"
       +                   ;;
       +        application/octet-stream) exec $(tofi-run) "$uri" ;;
       +        application/x-vmrc) exec vmrc "$uri" ;;
       +        application/x-java-jnlp-file) exec javaws "$uri" ;;
       +        application/vnd.openxmlformats-*) libreoffice "$uri" ;;
       +        telnet) exec st -e telnet "$host" "${port:-proto}" ;;
       +        ssh) exec st -e ssh -P "${port:-$proto}" "$host" ;;
       +        *) exec ${BROWSER:-surf} "$uri" ;;
       +esac