1
0

imgcat 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #!/bin/bash
  2. # tmux requires unrecognized OSC sequences to be wrapped with DCS tmux;
  3. # <sequence> ST, and for all ESCs in <sequence> to be replaced with ESC ESC. It
  4. # only accepts ESC backslash for ST. We use TERM instead of TMUX because TERM
  5. # gets passed through ssh.
  6. function print_osc() {
  7. if [[ $TERM == screen* ]] ; then
  8. printf "\033Ptmux;\033\033]"
  9. else
  10. printf "\033]"
  11. fi
  12. }
  13. # More of the tmux workaround described above.
  14. function print_st() {
  15. if [[ $TERM == screen* ]] ; then
  16. printf "\a\033\\"
  17. else
  18. printf "\a"
  19. fi
  20. }
  21. function load_version() {
  22. if [ -z ${IMGCAT_BASE64_VERSION+x} ]; then
  23. export IMGCAT_BASE64_VERSION=$(base64 --version 2>&1)
  24. fi
  25. }
  26. function b64_encode() {
  27. load_version
  28. if [[ "$IMGCAT_BASE64_VERSION" =~ GNU ]]; then
  29. # Disable line wrap
  30. base64 -w0
  31. else
  32. base64
  33. fi
  34. }
  35. function b64_decode() {
  36. load_version
  37. if [[ "$IMGCAT_BASE64_VERSION" =~ fourmilab ]]; then
  38. BASE64ARG=-d
  39. elif [[ "$IMGCAT_BASE64_VERSION" =~ GNU ]]; then
  40. BASE64ARG=-di
  41. else
  42. BASE64ARG=-D
  43. fi
  44. base64 $BASE64ARG
  45. }
  46. # print_image filename inline base64contents print_filename
  47. # filename: Filename to convey to client
  48. # inline: 0 or 1
  49. # base64contents: Base64-encoded contents
  50. # print_filename: If non-empty, print the filename
  51. # before outputting the image
  52. function print_image() {
  53. print_osc
  54. printf '1337;File='
  55. if [[ -n "$1" ]]; then
  56. printf 'name='`printf "%s" "$1" | b64_encode`";"
  57. fi
  58. printf "%s" "$3" | b64_decode | wc -c | awk '{printf "size=%d",$1}'
  59. printf ";inline=$2"
  60. printf ":"
  61. printf "%s" "$3"
  62. print_st
  63. printf '\n'
  64. if [[ -n "$4" ]]; then
  65. echo $1
  66. fi
  67. }
  68. function error() {
  69. echo "ERROR: $*" 1>&2
  70. }
  71. function show_help() {
  72. echo "Usage: imgcat [-p] filename ..." 1>& 2
  73. echo " or: cat filename | imgcat" 1>& 2
  74. }
  75. function check_dependency() {
  76. if ! (builtin command -V "$1" > /dev/null 2>& 1); then
  77. echo "imgcat: missing dependency: can't find $1" 1>& 2
  78. exit 1
  79. fi
  80. }
  81. ## Main
  82. if [ -t 0 ]; then
  83. has_stdin=f
  84. else
  85. has_stdin=t
  86. fi
  87. # Show help if no arguments and no stdin.
  88. if [ $has_stdin = f -a $# -eq 0 ]; then
  89. show_help
  90. exit
  91. fi
  92. check_dependency awk
  93. check_dependency base64
  94. check_dependency wc
  95. # Look for command line flags.
  96. while [ $# -gt 0 ]; do
  97. case "$1" in
  98. -h|--h|--help)
  99. show_help
  100. exit
  101. ;;
  102. -p|--p|--print)
  103. print_filename=1
  104. ;;
  105. -u|--u|--url)
  106. check_dependency curl
  107. encoded_image=$(curl -s "$2" | b64_encode) || (error "No such file or url $2"; exit 2)
  108. has_stdin=f
  109. print_image "$2" 1 "$encoded_image" "$print_filename"
  110. set -- ${@:1:1} "-u" ${@:3}
  111. if [ "$#" -eq 2 ]; then
  112. exit
  113. fi
  114. ;;
  115. -*)
  116. error "Unknown option flag: $1"
  117. show_help
  118. exit 1
  119. ;;
  120. *)
  121. if [ -r "$1" ] ; then
  122. has_stdin=f
  123. print_image "$1" 1 "$(b64_encode < "$1")" "$print_filename"
  124. else
  125. error "imgcat: $1: No such file or directory"
  126. exit 2
  127. fi
  128. ;;
  129. esac
  130. shift
  131. done
  132. # Read and print stdin
  133. if [ $has_stdin = t ]; then
  134. print_image "" 1 "$(cat | b64_encode)" ""
  135. fi
  136. exit 0