eibgrad

tomato-installer.sh

May 16th, 2019 (edited)
556
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 7.02 KB | None | 0 0
  1. #!/bin/sh
  2. #set -x # uncomment/comment to enable/disable debug mode
  3.  
  4. #     name: tomato-installer.sh
  5. #  version: 2.5.2, 24-jul-2022, by eibgrad
  6. #  purpose: install pastebin script into tomato router
  7.  
  8. # function usage()
  9. usage() {
  10.     echo 'Usage: tomato-installer.sh [options] pastebin-id [ext=sh]'
  11.     echo
  12.     echo '  Install pastebin script into tomato router.'
  13.     echo
  14.     echo '  Installation directory hierarchy:'
  15.     echo '    </path> (from --dir option)'
  16.     echo '    /jffs/etc/config'
  17.     echo '    /opt/etc/config'
  18.     echo '    /tmp'
  19.     echo
  20.     echo '  Options:'
  21.     echo '    --dir PATH  installation directory (created as necessary)'
  22.     echo "    --pre NUM   add prefix to filename (e.g., '01')"
  23.     echo '    --wrap      split configuration into wrapper & wrapped scripts'
  24.     echo '    --nocom     remove blank and comment-only lines'
  25.     echo '    --comp      same as --nocom, plus remove leading whitespace'
  26.     echo '    --noprompt  overwrite existing file(s) without prompting'
  27.     echo '    -h,--help   this usage information'
  28.     echo
  29.     echo '  # e.g., install script w/o comments and w/ bash (sh) extension'
  30.     echo '  tomato-installer.sh --nocom nRtRhKf3'
  31.     echo
  32. }
  33.  
  34. # function query( message [default-reply] )
  35. query() {
  36.     local reply
  37.  
  38.     read -p "$1 " reply < /dev/tty
  39.     [ "$reply" ] && echo "$reply" || echo "$2"
  40. }
  41.  
  42. # function is_mounted()
  43. is_mounted() { df | grep -Eq "\s+${1}\$"; }
  44.  
  45. # function wraptize()
  46. wraptize() {
  47.     local wrapper="$file"
  48.     local wrapped args
  49.  
  50.     # configure proper extension for wrapped
  51.     if [ "$ext" != 'sh' ]; then
  52.         # replace extension w/ .sh
  53.         wrapped="$(echo $file | sed 's/\.[^.]*$/.sh/')"
  54.     else
  55.         # strip extension
  56.         wrapped="$(echo $file | sed 's/\.[^.]*$//')"
  57.     fi
  58.  
  59.     # add preferred command-line arguments (optional)
  60.     case "$pbid" in
  61.         'zkDfbTEJ') args="--ip $(nvram get lan_ipaddr) --port 80 --debug";;
  62.     esac
  63.  
  64.     # move script to wrapped
  65.     mv $file $wrapped
  66.  
  67.     # create and configure wrapper (which calls wrapped)
  68.     echo '#!/bin/sh' > $wrapper
  69.     echo "$wrapped$([ "$args" ] && echo " $args")" >> $wrapper
  70.     chmod +x $wrapper
  71.  
  72.     echo "info: script installed (wrapper): $wrapper"
  73.     echo "info: script installed (wrapped): $wrapped"
  74. }
  75.  
  76. # function customize()
  77. customize() {
  78.     _tomato_pia_port_forward() {
  79.         local url='pastebin.com/raw/Xi2JGkne'
  80.         local file="${file%.*}.callback"
  81.  
  82.         if [ ! -f $file ]; then
  83.             # download sample callback script
  84.             $GET_URL $url | tr -d '\r' > "$file"; echo >> "$file"
  85.  
  86.             # verify file is bash script by locating shebang
  87.             if ! head -n1 "$file" | grep -Eq '^#!/bin/sh($|\s+)'; then
  88.                 rm "$file"
  89.                 echo "error: file not found: $file"
  90.             fi
  91.  
  92.             # mark file executable
  93.             chmod +x "$file"
  94.  
  95.             echo "info: script installed: $file"
  96.         fi
  97.     }
  98.  
  99.     # script-specific customization (optional)
  100.     case "$pbid" in
  101.         'zkDfbTEJ') _tomato_pia_port_forward;;
  102.     esac
  103. }
  104.  
  105. # function exit_1( [message] )
  106. exit_1() { [ "$1" ] && echo "$1"; exit 1; }
  107.  
  108. # handle help/usage requests
  109. for opt; do case $opt in -h|--help) usage; exit 0;; esac; done
  110.  
  111. # try curl, fallback to wget
  112. which curl >/dev/null 2>&1 && GET_URL='curl -sLk' || GET_URL='wget -qO -'
  113.  
  114. # process command line options/arguments
  115. while [ $# -gt 0 ]; do
  116.     case $1 in
  117.              --dir ) shift; file_dir="${1//[[:space:]]/}";;
  118.              --pre ) shift; file_pre="${1//[[:space:]]/}";;
  119.             --wrap ) wrap=;;
  120.            --nocom ) nocom=;;
  121.             --comp ) comp=;;
  122.         --noprompt ) noprompt=;;
  123.                   *) break 2;;
  124.     esac
  125.     shift
  126. done
  127.  
  128. # set pastebin-id
  129. [ "$1" ] && pbid="$1" || exit_1 'error: nothing to do'
  130.  
  131. # set and verify extension
  132. ext="$([ "$2" ] && echo "${2//[[:space:]]/}" || echo sh)"
  133. echo $ext | grep -q '\.' && exit_1 "error: extension cannot contain '.'"
  134.  
  135. # construct pastebin url for retrieving raw file
  136. url="pastebin.com/raw/$pbid"
  137.  
  138. if [ ! "$file_dir" ]; then
  139.     # locate storage
  140.     if is_mounted '/jffs'; then
  141.         file_dir='/jffs/etc/config'
  142.     elif is_mounted '/opt'; then
  143.         file_dir='/opt/etc/config'
  144.     else
  145.         file_dir='/tmp'
  146.         echo 'warning: /jffs and /opt not mounted; using /tmp'
  147.     fi
  148. fi
  149.  
  150. # convert cryptic pastebin id to common name
  151. case "$1" in
  152.     'Yp0ptsjh') file='tomato-ovpn-client-killswitch';;
  153.     'MPnU5WrK') file='tomato-ovpn-client-watchdog';;
  154.     'UUUT8GiW') file='tomato-ovpn-remote-access';;
  155.     'GMUbEtGj') file='tomato-ovpn-split-advanced';;
  156.     'xEziw8Pq') file='tomato-ovpn-split-basic';;
  157.     'zkDfbTEJ') file='tomato-pia-port-forward';;
  158.     '9csaJiUc') file='tomato-routing-policy-fix-v2';;
  159.     'CnjxdGtU') file='tomato-wol-port-forward';;
  160.              *) file="pastebin-$1";;
  161. esac
  162.  
  163. # check for existing files
  164. efiles="$(echo $file_dir/*$file*)"
  165.  
  166. if [ "$efiles" != "$file_dir/*$file*" ]; then
  167.     _is_callback() {
  168.         echo "$1" | grep -q '\.callback$'
  169.     }
  170.  
  171.     if [ ! ${noprompt+x} ]; then
  172.         efile_count=0
  173.  
  174.         for efile in $efiles; do
  175.             # ignore callback scripts
  176.             _is_callback "$efile" || \
  177.                 { echo "warning: existing file: $efile"; let efile_count++; }
  178.         done
  179.  
  180.         if [ $efile_count -gt 0 ]; then
  181.             # obtain permission to overwrite existing file(s)
  182.             while :; do
  183.                 case $(query 'Overwrite existing file(s) (yes/[no])?' no) in
  184.                     yes) break;;
  185.                      no) exit_1 'info: installation aborted';;
  186.                 esac
  187.             done
  188.  
  189.             # delete existing files
  190.             for efile in $efiles; do
  191.                 _is_callback "$efile" || rm -rf $efile
  192.             done
  193.         fi
  194.     fi
  195. fi
  196.  
  197. # option pre: add prefix to filename
  198. [ "$file_pre" ] && file="${file_pre}-$file"
  199.  
  200. # create directory
  201. if ! mkdir -p "$file_dir" 2>/dev/null; then
  202.     exit_1 "error: cannot create directory: $file_dir"
  203. fi
  204.  
  205. # construct full path + filename + extension
  206. file="$file_dir/$file.$ext"
  207.  
  208. # confirm file can be created through initialization
  209. if ! (> "$file") 2>/dev/null; then
  210.     exit_1 "error: cannot create file: $file"
  211. fi
  212.  
  213. # retrieve raw file from pastebin
  214. $GET_URL $url | tr -d '\r' > "$file"; echo >> "$file"
  215.  
  216. # verify file is bash script by locating shebang
  217. if ! head -n1 "$file" | grep -Eq '^#!/bin/sh($|\s+)'; then
  218.     rm "$file"
  219.     exit_1 "error: file not found: $pbid"
  220. fi
  221.  
  222. # mark file executable
  223. chmod +x "$file"
  224.  
  225. # option nocom: remove blank lines and non-functional comments
  226. [ ${nocom+x} ] && sed -ri '/^[[:space:]]*($|#([[:space:]]|$))/d' "$file"
  227.  
  228. # option comp: same as --nocom, plus remove leading whitespace
  229. [ ${comp+x} ] && sed -ri 's/^[[:space:]]*//;/^($|#([[:space:]]|$))/d' "$file"
  230.  
  231. # option wrap: split configuration into wrapper & wrapped scripts
  232. [ ${wrap+x} ] && wraptize || echo "info: script installed: $file"
  233.  
  234. # check for any script-specific customization
  235. customize
  236.  
  237. exit 0
Add Comment
Please, Sign In to add comment