installJRMC 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319
  1. #!/usr/bin/env bash
  2. shopt -s extglob
  3. #######################################
  4. # This script will download, build, and install JRiver Media Center with optional systemd services
  5. # on Fedora, CentOS, Debian, and Ubuntu
  6. #
  7. # Run installJRMC --help to see available options
  8. #
  9. # To-dos:
  10. # 1. Raspberry Pi OS support
  11. # 2. Interactive installation (ncurses?)
  12. #
  13. #######################################
  14. _scriptversion="1.0.0a2"
  15. _boardurl="https://yabb.jriver.com/interact/index.php/board,71.0.html"
  16. _outputdir="$PWD/output"
  17. _createrepo_webroot="/srv/jriver"
  18. _exec_user="$(whoami)"
  19. _printHelpAndExit() {
  20. debug "Running: ${FUNCNAME[0]}"
  21. cat <<- 'EOF'
  22. USAGE:
  23. installJRMC [[OPTION] [VALUE]]...
  24. If no options (besides -d) are provided, the script will default to '--install repo'
  25. OPTIONS
  26. --install, -i repo|rpm
  27. repo: Install MC from repository, future updates will be handled by the system package manager
  28. rpm: Build and install MC locally (RPM-based OSes only)
  29. --build
  30. Build RPM from source DEB (no installation)
  31. --mcversion VERSION
  32. Build or install a specific MC version, ex. "28.0.25" (Default: scrape latest version from Interact)
  33. --outputdir PATH
  34. Generate rpmbuild output in this directory (Default: $PWD/output)
  35. --restorefile RESTOREFILE
  36. Restore file location for automatic license registration (Default: skip registration)
  37. --betapass PASSWORD
  38. Enter beta team password for access to beta builds
  39. --service-user USER
  40. Install systemd services and containers for USER (Default: current user)
  41. --service, -s SERVICE
  42. See SERVICES section below for a list of possible services to install
  43. --container, -c CONTAINER (TODO: Under construction)
  44. See CONTAINERS section below for a list of possible services to install
  45. --createrepo
  46. Build rpm, copy to webroot, and run createrepo
  47. --createrepo-webroot PATH
  48. The webroot directory to install the repo (Default: /srv/jriver/)
  49. --createrepo-user USER
  50. The web server user (Default: current user)
  51. --version, -v
  52. Print this script version and exit
  53. --debug, -d
  54. Print debug output
  55. --help, -h
  56. Print help dialog and exit
  57. --uninstall, -u
  58. Uninstall JRiver MC, cleanup service files, and remove firewall rules (does not remove library files)
  59. SERVICES
  60. jriver-mediaserver
  61. Enable and start a mediaserver systemd service (requires an existing X server)
  62. jriver-mediacenter
  63. Enable and start a mediacenter systemd service (requires an existing X server)
  64. jriver-x11vnc
  65. Enable and start x11vnc for the local desktop (requires an existing X server)
  66. Usually combined with jriver-mediaserver or jriver-mediacenter services
  67. --vncpass and --display are also valid options (see below)
  68. jriver-xvnc-mediacenter
  69. Enable and start a new Xvnc session running JRiver Media Center
  70. --vncpass PASSWORD
  71. Set vnc password for x11vnc/Xvnc access. If no password is set, the script
  72. will either use existing password stored in ~/.vnc/jrmc_passwd or use no password
  73. --display DISPLAY
  74. Display to start x11vnc/Xvnc (Default: The current display (x11vnc) or the
  75. current display incremented by 1 (Xvnc))
  76. jriver-createrepo
  77. Install hourly service to build latest MC RPM and run createrepo
  78. CONTAINERS (TODO: Under construction)
  79. mediacenter-xvnc
  80. createrepo
  81. EOF
  82. # Exit using passed exit code
  83. [[ ! -v 1 ]] && exit 0 || exit "$1"
  84. }
  85. _init() {
  86. debug "Running: ${FUNCNAME[0]}"
  87. _getOS
  88. _parseInput "$@"
  89. # Agnostic commands
  90. _bash_cmd(){ _ifSudo bash -c "$@"; }
  91. _rm_cmd(){ _ifSudo rm -rf "$@"; }
  92. _cp_cmd(){ _ifSudo cp -n "$@"; }
  93. _mkdir_cmd(){ _ifSudo mkdir -p "$@"; }
  94. _ln_cmd(){ _ifSudo ln -s "$@"; }
  95. _systemctl_reload(){ _ifSudo systemctl daemon-reload; }
  96. _systemctl_enable(){ _ifSudo systemctl enable --now "$@"; }
  97. _systemctl_disable(){ _ifSudo systemctl disable --now "$@"; }
  98. # OS-specific commands
  99. if [[ "$ID" =~ ^(fedora|centos)$ ]]; then
  100. _pkg_install(){ _ifSudo dnf install -y "$@"; }
  101. _pkg_reinstall(){ _ifSudo dnf reinstall -y "$@"; }
  102. _pkg_install_nogpg(){ _ifSudo dnf install --nogpgcheck -y "$@"; }
  103. _pkg_remove(){ _ifSudo dnf remove -y "$@"; }
  104. _pkg_update(){ _ifSudo dnf makecache; }
  105. _pkg_query(){ _ifSudo rpm -q "$@"; }
  106. _firewall_cmd(){ _ifSudo firewall-cmd "$@"; }
  107. elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then
  108. _pkg_install(){ _ifSudo apt-get install -y -q0 "$@"; }
  109. _pkg_reinstall(){ _ifSudo apt-get reinstall -y -q0 "$@"; }
  110. _pkg_install_nogpg(){ _ifSudo apt-get install -y -q0 "$@"; }
  111. _pkg_remove(){ _ifSudo apt-get remove -y -q0 "$@"; }
  112. _pkg_update(){ _ifSudo apt-get update -y -q0; }
  113. _pkg_query(){ _ifSudo dpkg -s "$@"; }
  114. _firewall_cmd(){ _ifSudo ufw "$@"; }
  115. fi
  116. # Set defaults
  117. if [[ $# -eq 0 ]] || [[ $# -eq 1 && "$1" =~ ^(--debug|-d)$ ]]; then
  118. debug "No options passed, defaulting to repo installation method"
  119. _install="repo"
  120. fi
  121. _service_user="${_service_user:-$_exec_user}"
  122. _createrepo_user="${_createrepo_user:-$_exec_user}"
  123. # Set package aliases
  124. if [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then
  125. declare -Ag PKG_ALIASES
  126. PKG_ALIASES["xorg-x11-utils"]="xorg-x11"
  127. PKG_ALIASES["rpm-build"]="rpm"
  128. PKG_ALIASES["createrepo_c"]="createrepo"
  129. PKG_ALIASES["tigervnc-server"]="tigervnc-standalone-server"
  130. fi
  131. # Install script dependencies
  132. [[ "$ID" == "centos" ]] && _installPackage epel-release
  133. [[ ! -v _mcversion ]] && [[ ! -x $(command -v wget) ]] && _installPackage wget
  134. # Set MC version
  135. _setVersion
  136. }
  137. _main() {
  138. _init "$@"
  139. # Uninstall and exit
  140. if [[ -v _uninstall ]]; then
  141. _uninstall
  142. exit $?
  143. fi
  144. # Install MC using package manager
  145. if [[ -v _install && "$_install" == "repo" ]]; then
  146. _installMCFromRepo
  147. _symlinkCerts
  148. _restoreLicense
  149. _openFirewall "jriver"
  150. fi
  151. # Build RPM from source deb package
  152. if [[ -v _build ]]; then
  153. _acquireDeb
  154. _buildRPM
  155. fi
  156. # Run createrepo
  157. if [[ -v _createrepo ]]; then
  158. _runCreaterepo "$_mcrpm"
  159. fi
  160. # Install the rpm
  161. if [[ -v _install && "$_install" == "rpm" ]]; then
  162. _installPackage --noquery "$_mcrpm"
  163. _symlinkCerts
  164. _restoreLicense
  165. _openFirewall "jriver"
  166. fi
  167. # Install services
  168. _setDisplay
  169. for _service in "${_services[@]}"; do
  170. _servicePrep "$_service"
  171. if ! "_service_$_service"; then
  172. if [[ $? -eq 127 ]]; then
  173. err "Service $_service does not exist, check your service name"
  174. else
  175. err "Failed to create service: $_service"
  176. fi
  177. fi
  178. done
  179. # Install containers
  180. for _container in "${_containers[@]}"; do
  181. if ! "_container_$_container"; then
  182. if [[ $? -eq 127 ]]; then
  183. err "Container $_container does not exist, check your container name"
  184. else
  185. err "Failed to create container: $_container"
  186. fi
  187. fi
  188. done
  189. }
  190. #######################################
  191. # Helper functions
  192. #######################################
  193. err() { echo "Error: $*" >&2; }
  194. debug() {
  195. if [[ -v _debug ]]; then
  196. if [[ $# -gt 0 ]]; then
  197. echo "Debug: $*"
  198. fi
  199. else
  200. return 1
  201. fi
  202. }
  203. #######################################
  204. # Prepend this to any command that you wish to execute with sudo
  205. # Requires:
  206. # _exec_user
  207. #######################################
  208. _ifSudo() {
  209. if [[ "$_exec_user" != "root" ]]; then
  210. sudo "$@"
  211. else
  212. "$@"
  213. fi
  214. }
  215. #######################################
  216. # Parse CLI input from the user w/ getopt
  217. #######################################
  218. _parseInput() {
  219. debug "Running: ${FUNCNAME[0]}"
  220. if _input=$(getopt -o +i:vdhus:c: -l install:,build,outputdir:,mcversion:,restorefile:,betapass:,service-user:,service:,version,debug,help,uninstall,createrepo,createrepo-webroot:,createrepo-user:,vncpass:,display:,container: -- "$@"); then
  221. eval set -- "$_input"
  222. while true; do
  223. case "$1" in
  224. --install|-i)
  225. shift
  226. _install="$1"
  227. if [[ "$_install" == "rpm" ]]; then
  228. if [[ ! "$ID" =~ ^(fedora|centos)$ ]]; then
  229. err "RPM install method not available on $ID"
  230. _printHelpAndExit 1
  231. fi
  232. _build="true"
  233. fi
  234. ;;
  235. --build)
  236. _build="true"
  237. ;;
  238. --outputdir)
  239. shift && _outputdir="$1"
  240. ;;
  241. --mcversion)
  242. shift && _mcversion="$1"
  243. ;;
  244. --restorefile)
  245. shift && _restorefile="$1"
  246. ;;
  247. --betapass)
  248. shift && _betapass="$1"
  249. ;;
  250. --service-user)
  251. shift && _service_user="$1"
  252. ;;
  253. --service|-s)
  254. shift && _services+=("$1")
  255. ;;
  256. --createrepo)
  257. _build="true"
  258. _createrepo="true"
  259. ;;
  260. --createrepo-webroot)
  261. shift && _createrepo_webroot="$1"
  262. ;;
  263. --createrepo-user)
  264. shift && _createrepo_user="$1"
  265. ;;
  266. --vncpass)
  267. shift && _vncpass="$1"
  268. ;;
  269. --display)
  270. shift && _display="$1"
  271. ;;
  272. --container|-c)
  273. shift && _containers+=("$1")
  274. ;;
  275. --version|-v)
  276. echo "Version: $_scriptversion"
  277. exit 0
  278. ;;
  279. --debug|-d)
  280. echo "Debugging on"
  281. echo "installJRMC version: $_scriptversion"
  282. _debug="true"
  283. ;;
  284. --help|-h)
  285. _printHelpAndExit 0
  286. ;;
  287. --uninstall|-u)
  288. _uninstall="true"
  289. ;;
  290. --)
  291. shift
  292. break
  293. ;;
  294. esac
  295. shift
  296. done
  297. else
  298. err "Incorrect options provided"
  299. _printHelpAndExit 1
  300. fi
  301. }
  302. #######################################
  303. # Get host OS from /etc/os-release
  304. #######################################
  305. _getOS() {
  306. debug "Running: ${FUNCNAME[0]}"
  307. if [[ -e "/etc/os-release" ]]; then
  308. source "/etc/os-release"
  309. else
  310. err "/etc/os-release not found"
  311. err "Your OS is unsupported"
  312. _printHelpAndExit 1
  313. fi
  314. debug "Platform: $ID $VERSION_ID"
  315. }
  316. #######################################
  317. # Get our MC working version from input argument or scraping Interact
  318. # Requires:
  319. # _boardurl
  320. #######################################
  321. _setVersion() {
  322. debug "Running: ${FUNCNAME[0]}"
  323. # If user does not specify a version, scrape the latest from Interact
  324. if [[ ! -v _mcversion ]]; then
  325. echo "Scraping latest MC version number from Interact..."
  326. if ! _mcversion=$(wget -qO- "$_boardurl" | grep -o "[0-9][0-9]\.[0-9]\.[0-9]\+" | head -n 1); then
  327. err "MC version could not be scraped. Please recheck the boardurl: $_boardurl or specify a version manually using --mcversion"
  328. _printHelpAndExit 1
  329. fi
  330. fi
  331. echo "Using version: $_mcversion"
  332. # Extract major version number
  333. _mversion="${_mcversion%%.*}"
  334. # Saving this substituion in case it's needed in the future
  335. #_variation="${_mcversion##*.}"
  336. }
  337. #######################################
  338. # Installs a package using the system package manager
  339. # Arguments:
  340. # One or more package names
  341. # Options:
  342. # --noquery, -n: Do not query the package state (useful if installing a local RPM)
  343. # Returns:
  344. # Will exit 1 if failed
  345. #######################################
  346. _installPackage() {
  347. debug "Running: ${FUNCNAME[0]}" "$@"
  348. if _input=$(getopt -o +n -l noquery -- "$@"); then
  349. eval set -- "$_input"
  350. while true; do
  351. case "$1" in
  352. --noquery|-n)
  353. local _noquery="true"
  354. ;;
  355. --)
  356. shift
  357. break
  358. ;;
  359. esac
  360. shift
  361. done
  362. else
  363. err "Incorrect options provided"
  364. _printHelpAndExit 1
  365. fi
  366. # We will add packages to this array if their command is not available
  367. local -a _pkg_array
  368. local -a _url_pkg_array
  369. # Parse packages
  370. for _pkg in "$@"; do
  371. [[ -v PKG_ALIASES && -v PKG_ALIASES["$_pkg"] ]] && _pkg=PKG_ALIASES["$_pkg"]
  372. # Insert the package name to test if already installed
  373. if [[ -v _noquery ]] || ! _pkg_query "$_pkg" > /dev/null 2>&1; then
  374. if [[ -v _url_pkg ]]; then
  375. _url_pkg_array+=("$_url_pkg")
  376. else
  377. _pkg_array+=("$_pkg")
  378. fi
  379. fi
  380. done
  381. # Install from package name (with gpg check)
  382. if [[ ${#_pkg_array[@]} -ge 1 ]]; then
  383. echo "Installing:" "${_pkg_array[@]}"
  384. if debug; then
  385. if ! _pkg_install "${_pkg_array[@]}"; then
  386. err "Failed to install package. Attempting to continue..."
  387. return 1
  388. fi
  389. elif ! _pkg_install "${_pkg_array[@]}" > /dev/null 2>&1; then
  390. err "Failed to install package. Attempting to continue..."
  391. return 1
  392. fi
  393. fi
  394. # Install from package url (without gpg check)
  395. if [[ ${#_url_pkg_array[@]} -ge 1 ]]; then
  396. echo "Installing:" "${_url_pkg_array[@]}"
  397. if debug; then
  398. if ! _pkg_install_nogpg "${_url_pkg_array[@]}"; then
  399. err "Failed to install package. Attempting to continue..."
  400. return 1
  401. fi
  402. elif ! _pkg_install_nogpg "${_url_pkg_array[@]}" > /dev/null 2>&1; then
  403. err "Failed to install package. Attempting to continue..."
  404. return 1
  405. fi
  406. fi
  407. }
  408. #######################################
  409. # Installs JRiver Media Center from a repository
  410. # Returns:
  411. # 0 if JRiver Media Center installed sucessfully
  412. #######################################
  413. _installMCFromRepo() {
  414. debug "Running: ${FUNCNAME[0]}"
  415. echo "Installing JRiver Media Center from repo..."
  416. ! debug && \
  417. echo "This may take a few minutes to complete"; \
  418. echo "Use --debug for verbose output"
  419. local _mcpkg
  420. # Add repository files
  421. _addRepo() {
  422. debug "Running: ${FUNCNAME[0]}"
  423. if [[ "$ID" =~ ^(fedora|centos)$ ]]; then
  424. _bash_cmd 'cat <<- EOF > /etc/yum.repos.d/jriver.repo
  425. [jriver]
  426. name=JRiver Media Center repo by BryanC
  427. baseurl=https://repos.bryanroessler.com/jriver
  428. gpgcheck=0
  429. EOF'
  430. elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then
  431. _installPackage wget
  432. wget -q "http://dist.jriver.com/mediacenter@jriver.com.gpg.key" -O- | _ifSudo apt-key add - > /dev/null 2>&1
  433. _ifSudo wget "http://dist.jriver.com/latest/mediacenter/mediacenter$_mversion.list" -O "/etc/apt/sources.list.d/mediacenter$_mversion.list"
  434. fi
  435. }
  436. _addRepo
  437. # Update package list
  438. debug "Updating package list"
  439. if ! _pkg_update > /dev/null 2>&1; then
  440. err "Package update failed!"
  441. exit 1
  442. fi
  443. local _mcpkg
  444. # Fedora/CentOS use a universal package name -- easy
  445. if [[ "$ID" =~ ^(fedora|centos)$ ]]; then
  446. _mcpkg="MediaCenter"
  447. # Ubuntu/Debian incorporate the mversion into the package name -- more fun!
  448. elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then
  449. if [[ ! -v _mversion ]]; then
  450. # Try parsing the latest mversion from the repo
  451. if _mcpkg=$(apt-get install mediacenter?? -s -q0 | grep "selecting" | tail -1| awk '{print $3}'); then
  452. _mcpkg="${_mcpkg%\'}"
  453. _mcpkg="${_mcpkg#\'}"
  454. # Scrape Interact
  455. else
  456. _mcpkg="mediacenter$_mversion"
  457. fi
  458. else
  459. _mcpkg="mediacenter$_mversion"
  460. fi
  461. # Sanity check
  462. if [[ ! "$_mcpkg" =~ ^mediacenter[0-9][0-9]$ ]]; then
  463. err "Could not parse MC package name"
  464. exit 1
  465. fi
  466. fi
  467. if [[ -v _specific_version ]]; then
  468. if [[ "$ID" =~ ^(fedora|centos)$ ]]; then
  469. if debug; then
  470. _installPackage "$_mcpkg-$_mcversion"
  471. else
  472. _installPackage "$_mcpkg-$_mcversion" > /dev/null 2>&1
  473. fi
  474. elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then
  475. if debug; then
  476. _installPackage "$_mcpkg=$_mcversion"
  477. else
  478. _installPackage "$_mcpkg=$_mcversion" > /dev/null 2>&1
  479. fi
  480. fi
  481. else
  482. if debug; then
  483. _installPackage "$_mcpkg"
  484. else
  485. _installPackage "$_mcpkg" > /dev/null 2>&1
  486. fi
  487. fi
  488. # shellcheck disable=SC2181
  489. if [[ $? -ne 0 ]]; then
  490. err "JRiver Media Center installation failed"
  491. exit 1
  492. fi
  493. echo "JRiver Media Center installed successfully"
  494. }
  495. #######################################
  496. # Acquire the source DEB package from JRiver's servers
  497. # Returns:
  498. # 0 if DEB file downloaded successfully, 1 if failed
  499. #######################################
  500. _acquireDeb() {
  501. debug "Running: ${FUNCNAME[0]}"
  502. local _debfilename="$_outputdir/SOURCES/MediaCenter-$_mcversion-amd64.deb"
  503. # If necessary, create SOURCES dir
  504. [[ ! -d "$_outputdir/SOURCES" ]] && mkdir -p "$_outputdir/SOURCES"
  505. # If deb file already exists, skip download
  506. if [[ -f "$_debfilename" ]]; then
  507. echo "Using local DEB file: $_debfilename"
  508. # Else check beta repo
  509. elif [[ -v _betapass ]]; then
  510. if wget -q -O "$_debfilename" \
  511. "https://files.jriver.com/mediacenter/channels/v$_mversion/beta/$_betapass/MediaCenter-$_mcversion-amd64.deb"; then
  512. true
  513. fi
  514. # Else check test repo
  515. elif wget -q -O "$_debfilename" \
  516. "https://files.jriver.com/mediacenter/test/MediaCenter-$_mcversion-amd64.deb"; then
  517. true
  518. # Else check latest repo
  519. elif wget -q -O "$_debfilename" \
  520. "https://files.jriver.com/mediacenter/channels/v$_mversion/latest/MediaCenter-$_mcversion-amd64.deb"; then
  521. true
  522. else
  523. err "Cannot find DEB file. Exiting..."
  524. exit 1
  525. fi
  526. if [[ ! -f "$_debfilename" ]]; then
  527. err "Downloaded DEB file missing or corrupted, exiting..."
  528. exit 1
  529. fi
  530. }
  531. #######################################
  532. # Creates a SPEC file and builds the RPM from the source DEB using rpmbuild
  533. # Requires:
  534. # _outputdir
  535. # ID
  536. # _mcversion
  537. # _mversion
  538. # _installPackage
  539. # Globals:
  540. # _mcrpm
  541. # Returns:
  542. # 0 if rpmbuild is successful, 1 if not
  543. #######################################
  544. _buildRPM() {
  545. debug "Running: ${FUNCNAME[0]}"
  546. # install build dependencies
  547. _installPackage wget dpkg rpm-build
  548. # If necessary, make build directories
  549. [[ ! -d "$_outputdir/SPECS" ]] && mkdir -p "$_outputdir/SPECS"
  550. # rpmbuild uses rpm to check for build dependencies
  551. # this will fail on non-rpm distros
  552. if [[ "$ID" =~ ^(fedora|centos)$ ]]; then
  553. local _build_requires=$'BuildRequires: rpm >= 4.11.0\nBuildRequires: dpkg'
  554. fi
  555. # Create spec file
  556. cat <<- EOF > "$_outputdir/SPECS/mediacenter.spec"
  557. Name: MediaCenter
  558. Version: $_mcversion
  559. Release: 1
  560. Summary: JRiver Media Center
  561. Group: Applications/Media
  562. Source0: http://files.jriver.com/mediacenter/channels/v$_mversion/latest/MediaCenter-$_mcversion-amd64.deb
  563. ${_build_requires:-}
  564. BuildArch: x86_64
  565. %define _rpmfilename %%{ARCH}/%%{NAME}-%%{version}.%%{ARCH}.rpm
  566. AutoReq: 0
  567. Requires: glibc >= 2.19
  568. Requires: alsa-lib >= 1.0.28
  569. Requires: libuuid >= 2.25
  570. Requires: libX11 >= 1.6
  571. Requires: libX11-common >= 1.6
  572. Requires: libXext >= 1.3
  573. Requires: libxcb >= 1.1
  574. Requires: libXdmcp >= 1.1
  575. Requires: libstdc++ >= 4.9
  576. Requires: gtk3 >= 3.14
  577. Requires: mesa-libGL
  578. Requires: libglvnd-glx
  579. Requires: pango >= 1.36
  580. Requires: libXScrnSaver
  581. Requires: xdg-utils
  582. Requires: libgomp >= 4.9
  583. Requires: nss >= 3.26
  584. Requires: nspr >= 4.12
  585. Requires: ca-certificates
  586. Requires: python3
  587. Recommends: vorbis-tools >= 1.4.0
  588. Recommends: lame >= 3.0
  589. Provides: mediacenter$_mversion
  590. License: Copyright 1998-2021, JRiver, Inc. All rights reserved. Protected by U.S. patents #7076468 and #7062468
  591. URL: http://www.jriver.com/
  592. %define __provides_exclude_from ^%{_libdir}/jriver/.*/.*\\.so.*$
  593. %description
  594. Media Center is more than a world class player.
  595. %global __os_install_post %{nil}
  596. %prep
  597. %build
  598. %install
  599. dpkg -x %{S:0} %{buildroot}
  600. %post -p /sbin/ldconfig
  601. %postun -p /sbin/ldconfig
  602. %files
  603. %{_bindir}/mediacenter$_mversion
  604. %{_libdir}/jriver
  605. %{_datadir}
  606. %exclude %{_datadir}/applications/media_center_packageinstaller_$_mversion.desktop
  607. /etc/security/limits.d/*
  608. EOF
  609. declare -g _mcrpm="$_outputdir/RPMS/x86_64/MediaCenter-$_mcversion.x86_64.rpm"
  610. # skip rebuilding the rpm if it already exists
  611. if [[ -f "$_mcrpm" ]]; then
  612. echo "$_mcrpm already exists. Skipping build step..."
  613. return 0
  614. fi
  615. # Run rpmbuild
  616. echo "Building version $_mcversion, please wait..."
  617. if debug; then
  618. rpmbuild --define="%_topdir $_outputdir" --define="%_libdir /usr/lib" -bb "$_outputdir/SPECS/mediacenter.spec"
  619. else
  620. rpmbuild --quiet --define="%_topdir $_outputdir" --define="%_libdir /usr/lib" -bb "$_outputdir/SPECS/mediacenter.spec" > /dev/null 2>&1
  621. fi
  622. # Check return code
  623. # shellcheck disable=SC2181
  624. if [[ $? -ne 0 || ! -f "$_mcrpm" ]]; then
  625. err "Build failed. Exiting..."
  626. exit 1
  627. else
  628. echo "Build successful. The RPM file is located at: $_mcrpm"
  629. fi
  630. }
  631. #######################################
  632. # Copy the RPM to createrepo-webroot and runs createrepo as the createrepo-user
  633. # Arguments:
  634. # Requires one argument, the path to the RPM file (typically _mcrpm)
  635. # Requires:
  636. # _createrepo_webroot
  637. # Returns:
  638. # 0 if createrepo is successful, 1 if not
  639. #######################################
  640. _runCreaterepo() {
  641. debug "Running: ${FUNCNAME[0]}"
  642. # Some additional commands specifically for createrepo (primarily to handle user rights)
  643. if [[ $_createrepo_user != "root" ]]; then
  644. if [[ -d "$_createrepo_webroot/repodata" ]]; then
  645. _createrepo_cmd(){ sudo -u "$_createrepo_user" createrepo -q --update "$@"; }
  646. else
  647. _createrepo_cmd(){ sudo -u "$_createrepo_user" createrepo -q "$@"; }
  648. fi
  649. _cr_mkdir_cmd(){ sudo -u "$_createrepo_user" mkdir -p "$@"; }
  650. _cr_cp_cmd(){ sudo -u "$_createrepo_user" cp -n "$@"; }
  651. else
  652. if [[ -d "$_createrepo_webroot/repodata" ]]; then
  653. _createrepo_cmd(){ createrepo -q --update "$@"; }
  654. else
  655. _createrepo_cmd(){ createrepo -q "$@"; }
  656. fi
  657. fi
  658. _installPackage createrepo_c
  659. local _rpmfile="$1"
  660. # If the webroot does not exist, create it
  661. if [[ ! -d "$_createrepo_webroot" ]]; then
  662. if ! _cr_mkdir_cmd "$_createrepo_webroot"; then
  663. err "Could not create the createrepo-webroot path!"
  664. err "Make sure that the createrepo-webroot is writeable by createrepo-user: $_createrepo_user"
  665. return 1
  666. fi
  667. fi
  668. # Copy built rpms to webroot
  669. if ! _cr_cp_cmd -f "$_rpmfile" "$_createrepo_webroot"; then
  670. err "Could not copy the RPM to the createrepo-webroot path"
  671. err "Make sure that the createrepo-webroot path is writeable by createrepo-user: $_createrepo_user"
  672. return 1
  673. fi
  674. # Run createrepo
  675. if _createrepo_cmd "$_createrepo_webroot"; then
  676. echo "Successfully updated repo"
  677. return 0
  678. else
  679. err "Update repo failed"
  680. return 1
  681. fi
  682. }
  683. #######################################
  684. # Symlink certificates where JRiver Media Center expects them to be on Fedora/CentOS
  685. # Returns:
  686. # 0 if symlinking is unecessary or successful, 1 if not
  687. #######################################
  688. _symlinkCerts() {
  689. debug "Running: ${FUNCNAME[0]}"
  690. if [[ ! -f /etc/ssl/certs/ca-certificates.crt && \
  691. -f /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem ]]; then
  692. if ! _ln_cmd /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem /etc/ssl/certs/ca-certificates.crt; then
  693. err "Symlinking certificates failed"
  694. return 1
  695. fi
  696. fi
  697. }
  698. #######################################
  699. # Automatically restore the mjr license file if it is found next to installJRMC or _restorefile
  700. # is set
  701. # Requires:
  702. # _restorefile OR _basedir
  703. # _mversion
  704. # Returns:
  705. # 0 if license restored successfully or skipped, 1 if unsuccessful
  706. #######################################
  707. _restoreLicense() {
  708. debug "Running: ${FUNCNAME[0]}"
  709. local _mjr
  710. # Allow user to drop an mjr file next to installJRMC
  711. if [[ ! -v _restorefile ]]; then
  712. for _mjr in "$PWD"/*.mjr; do
  713. [[ $_mjr -nt $_restorefile ]] && _restorefile="$_mjr"
  714. done
  715. fi
  716. # Restore license
  717. if [[ -f "$_restorefile" ]]; then
  718. if ! "mediacenter$_mversion" /RestoreFromFile "$_restorefile"; then
  719. err "Automatic license restore failed"
  720. return 1
  721. fi
  722. fi
  723. }
  724. #######################################
  725. # Opens ports using the system firewall tool
  726. # Arguments
  727. # Service to enable (pre-defined)
  728. # Requires:
  729. # ID
  730. # _bash_cmd
  731. # _firewall_cmd
  732. # _port
  733. # Returns:
  734. # 0 if ports opened sucessfully, 1 if not
  735. #######################################
  736. _openFirewall() {
  737. debug "Running: ${FUNCNAME[0]}" "$@"
  738. # Create OS-specific port rules based on argument (service) name
  739. local -a _f_ports # for firewall-cmd
  740. local _u_ports # for ufw
  741. if [[ "$1" == "jriver" ]]; then
  742. _f_ports=("52100-52200/tcp" "1900/udp")
  743. _u_ports="52100:52200/tcp|1900/udp"
  744. elif [[ "$1" =~ ^(jriver-x11vnc|jriver-xvnc)$ ]]; then
  745. _f_ports=("$_port/tcp" "1900/udp")
  746. _u_ports="$_port/tcp|1900/udp"
  747. fi
  748. # Open the ports
  749. if [[ "$ID" =~ ^(fedora|centos)$ ]]; then
  750. [[ ! -x $(command -v firewall-cmd) ]] && _installPackage firewalld
  751. if ! _firewall_cmd --get-services | grep -q "$1"; then
  752. _firewall_cmd --permanent --new-service="$1" > /dev/null 2>&1
  753. _firewall_cmd --permanent --service="$1" --set-description="$1 installed by installJRMC" > /dev/null 2>&1
  754. _firewall_cmd --permanent --service="$1" --set-short="$1" > /dev/null 2>&1
  755. for _f_port in "${_f_ports[@]}"; do
  756. _firewall_cmd --permanent --service="$1" --add-port="$_f_port" > /dev/null 2>&1
  757. done
  758. _firewall_cmd --add-service "$1" --permanent > /dev/null 2>&1
  759. _firewall_cmd --reload > /dev/null 2>&1
  760. fi
  761. elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then
  762. # Debian ufw package state is broken on fresh installations
  763. [[ ! -x $(command -v ufw) ]] && _installPackage ufw
  764. if [[ ! -f "/etc/ufw/applications.d/$1" ]]; then
  765. _bash_cmd "cat <<- EOF > /etc/ufw/applications.d/$1
  766. [$1]
  767. title=$1
  768. description=$1 installed by installJRMC
  769. ports=$_u_ports
  770. EOF"
  771. fi
  772. _firewall_cmd app update "$1"
  773. _firewall_cmd allow "$1" > /dev/null 2>&1
  774. fi
  775. # shellcheck disable=SC2181
  776. # Rationale: much more concise to check exit codes at the end
  777. if [[ $? -ne 0 ]]; then
  778. err "Firewall ports could not be opened"
  779. return 1
  780. fi
  781. }
  782. #######################################
  783. # Create the x11vnc password file
  784. # Globals:
  785. # _novncauth
  786. # Returns:
  787. # 0 if password created sucessfully, 1 if not
  788. #######################################
  789. _setX11VNCPass() {
  790. debug "Running: ${FUNCNAME[0]}"
  791. _vncpassfile="$HOME/.vnc/jrmc_passwd"
  792. [[ ! -d "${_vncpassfile%/*}" ]] && mkdir -p "${_vncpassfile%/*}"
  793. if [[ -f "$_vncpassfile" ]]; then
  794. if [[ ! -v _vncpass ]]; then
  795. err "Refusing to overwrite existing $_vncpassfile with an empty password"
  796. err "Remove existing $_vncpassfile or set --vncpass to use an empty password"
  797. exit 1
  798. else
  799. rm -f "$_vncpassfile"
  800. fi
  801. fi
  802. if [[ -v _vncpass ]]; then
  803. if ! x11vnc -storepasswd "$_vncpass" "$_vncpassfile"; then
  804. err "Could not create VNC password file"
  805. return 1
  806. fi
  807. else
  808. _novncauth="true"
  809. fi
  810. }
  811. #######################################
  812. # Create the Xvnc password file
  813. # Returns:
  814. # 0 if password created sucessfully, 1 if not
  815. #######################################
  816. _setVNCPass() {
  817. debug "Running: ${FUNCNAME[0]}"
  818. _vncpassfile="$HOME/.vnc/jrmc_passwd"
  819. [[ ! -d "${_vncpassfile%/*}" ]] && mkdir -p "${_vncpassfile%/*}"
  820. if [[ -f "$_vncpassfile" ]]; then
  821. if [[ ! -v _vncpass ]]; then
  822. err "Refusing to overwrite existing $_vncpassfile with an empty password"
  823. err "Remove existing $_vncpassfile or set --vncpass to use an empty password"
  824. exit 1
  825. else
  826. rm -f "$_vncpassfile"
  827. fi
  828. fi
  829. if [[ -v _vncpass ]]; then
  830. if ! echo "$_vncpass" | vncpasswd -f > "$_vncpassfile"; then
  831. err "Could not create VNC password file"
  832. return 1
  833. fi
  834. else
  835. _novncauth="true"
  836. fi
  837. }
  838. #######################################
  839. # Set display and port variables
  840. # Globals:
  841. # _display
  842. # _displaynum
  843. # _next_display
  844. # _next_displaynum
  845. #######################################
  846. _setDisplay() {
  847. debug "Running: ${FUNCNAME[0]}"
  848. # Check _display, else DISPLAY, else set to :0 by default
  849. if [[ -v _display ]]; then
  850. _next_display="$_display"
  851. elif [[ -v DISPLAY ]]; then
  852. _display="${DISPLAY}"
  853. _displaynum="${_display#:}" # strip colon
  854. _displaynum="${_displaynum%.*}" # strip suffix
  855. _next_displaynum=$(( _displaynum + 1 ))
  856. _next_display=":$_next_displaynum"
  857. else
  858. _display=":0"
  859. _next_display=":1"
  860. fi
  861. _displaynum="${_display#:}" # strip colon
  862. _displaynum="${_displaynum%.*}" # strip suffix
  863. _next_displaynum=$(( _displaynum + 1 ))
  864. }
  865. #######################################
  866. # Create associated service variables based on service name
  867. # Requires:
  868. # _service_user
  869. # Globals:
  870. # _service_fname
  871. # _timer_fname
  872. # _service_name
  873. # _timer_name
  874. # _user_specifier
  875. #######################################
  876. _servicePrep() {
  877. debug "Running: ${FUNCNAME[0]}"
  878. if [[ "$_service_user" == "root" ]]; then
  879. _service_fname="/usr/lib/systemd/system/${1}.service"
  880. _timer_fname="/usr/lib/systemd/system/${1}.timer"
  881. _service_name="jriver-${1}.service"
  882. _timer_name="jriver-${1}}.timer"
  883. _user_specifier=""
  884. else
  885. _service_fname="/usr/lib/systemd/system/${1}@.service"
  886. _timer_fname="/usr/lib/systemd/system/${1}@.timer"
  887. _service_name="${1}@$_service_user.service"
  888. _timer_name="${1}@$_service_user.timer"
  889. _user_specifier="User=%I"
  890. fi
  891. }
  892. #######################################
  893. # Starts and enables (at startup) a JRiver Media Center service
  894. # Arguments:
  895. # Passes arguments as startup options to /usr/bin/mediacenter26
  896. # Requires:
  897. # XAUTHORITY
  898. #######################################
  899. _service_jriver-mediacenter() {
  900. debug "Running: ${FUNCNAME[0]}"
  901. _bash_cmd "cat <<- EOF > $_service_fname
  902. [Unit]
  903. Description=JRiver Media Center $_mversion
  904. After=graphical.target
  905. [Service]
  906. $_user_specifier
  907. Type=simple
  908. Environment=DISPLAY=$_display
  909. Environment=XAUTHORITY=$XAUTHORITY
  910. ExecStart=/usr/bin/mediacenter$_mversion $*
  911. Restart=always
  912. RestartSec=10
  913. KillSignal=SIGHUP
  914. TimeoutStopSec=30
  915. [Install]
  916. WantedBy=graphical.target
  917. EOF"
  918. _systemctl_reload && \
  919. _systemctl_enable "$_service_name" && \
  920. _openFirewall "jriver"
  921. }
  922. #######################################
  923. # Starts and enables (at startup) a JRiver Media Server service
  924. #######################################
  925. _service_jriver-mediaserver() {
  926. debug "Running: ${FUNCNAME[0]}"
  927. _service_jriver-mediacenter "/MediaServer"
  928. }
  929. #######################################
  930. # Starts and enables (at startup) JRiver Media Center in a new Xvnc session
  931. #######################################
  932. _service_jriver-xvnc-mediacenter() {
  933. debug "Running: ${FUNCNAME[0]}"
  934. _installPackage tigervnc-server
  935. _setVNCPass
  936. local _port=$(( _next_displaynum + 5900 ))
  937. if [[ -v _novncauth ]]; then
  938. _exec_start_cmd="/usr/bin/vncserver $_next_display -geometry 1440x900 -alwaysshared -name jriver$_next_display -SecurityTypes None -autokill -xstartup /usr/bin/mediacenter$_mversion"
  939. else
  940. _exec_start_cmd="/usr/bin/vncserver $_next_display -geometry 1440x900 -alwaysshared -rfbauth $HOME/.vnc/jrmc_passwd -autokill -xstartup /usr/bin/mediacenter$_mversion"
  941. fi
  942. _bash_cmd "cat <<- EOF > $_service_fname
  943. [Unit]
  944. Description=Remote desktop service (VNC)
  945. After=syslog.target network.target
  946. [Service]
  947. Type=simple
  948. $_user_specifier
  949. ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill $_next_display > /dev/null 2>&1 || :'
  950. ExecStart=$_exec_start_cmd
  951. ExecStop=/usr/bin/vncserver -kill $_next_display
  952. Restart=always
  953. [Install]
  954. WantedBy=multi-user.target
  955. EOF"
  956. _systemctl_reload && \
  957. _systemctl_enable "$_service_name" && \
  958. echo "Xvnc running on localhost:$_port" && \
  959. _openFirewall "jriver-xvnc" && \
  960. _openFirewall "jriver"
  961. }
  962. #######################################
  963. # Starts and enables (at startup) JRiver Media Server and x11vnc sharing the local desktop
  964. #######################################
  965. _service_jriver-x11vnc() {
  966. debug "Running: ${FUNCNAME[0]}"
  967. _installPackage x11vnc
  968. _setX11VNCPass
  969. local _port=$(( _displaynum + 5900 ))
  970. # Get current desktop resolution
  971. # TODO: may need to break this out into its own function and get smarter at identifying multi-monitors
  972. _getResolution() {
  973. debug "Running: ${FUNCNAME[0]}"
  974. _installPackage xorg-x11-utils
  975. _res=$(xdpyinfo | grep dimensions | awk '{print $2}')
  976. }
  977. _getResolution
  978. if [[ -v _novncauth ]]; then
  979. _exec_start_cmd="/usr/bin/x11vnc -display $_display -noscr -geometry $_res -auth guess -forever -bg -nopw"
  980. else
  981. _exec_start_cmd="/usr/bin/x11vnc -display $_display -noscr -geometry $_res -auth guess -forever -bg -rfbauth $HOME/.vnc/jrmc_passwd"
  982. fi
  983. _bash_cmd "cat <<-EOF > $_service_fname
  984. [Unit]
  985. Description=x11vnc
  986. After=multi.service
  987. [Service]
  988. $_user_specifier
  989. Type=forking
  990. Environment=DISPLAY=$_display
  991. ExecStart=$_exec_start_cmd
  992. Restart=always
  993. RestartSec=10
  994. [Install]
  995. WantedBy=multi-user.target
  996. EOF"
  997. _systemctl_reload && \
  998. _systemctl_enable "$_service_name" && \
  999. echo "x11vnc running on localhost:$_port" && \
  1000. _openFirewall "jriver-x11vnc"
  1001. }
  1002. #######################################
  1003. # Starts and enables (at startup) an hourly service to build the latest version of JRiver Media
  1004. # Center RPM from the source DEB and create/update an RPM repository
  1005. #######################################
  1006. _service_jriver-createrepo() {
  1007. debug "Running: ${FUNCNAME[0]}"
  1008. _bash_cmd "cat <<-EOF > $_service_fname
  1009. [Unit]
  1010. Description=Builds JRiver Media Center RPM file, moves it to the repo dir, and runs createrepo
  1011. [Service]
  1012. $_user_specifier
  1013. ExecStart=$PWD/installJRMC --outputdir $_outputdir --createrepo --createrepo-webroot $_createrepo_webroot --createrepo-user $_createrepo_user
  1014. [Install]
  1015. WantedBy=default.target
  1016. EOF"
  1017. _bash_cmd "cat <<-EOF > $_timer_fname
  1018. [Unit]
  1019. Description=Run JRiver MC rpmbuild hourly
  1020. [Timer]
  1021. OnCalendar=hourly
  1022. Persistent=true
  1023. [Install]
  1024. WantedBy=timers.target
  1025. EOF"
  1026. _systemctl_reload && \
  1027. _systemctl_enable "$_timer_name"
  1028. }
  1029. #######################################
  1030. # CONTAINERS
  1031. #######################################
  1032. # _containerCreaterepo() {
  1033. # :
  1034. # }
  1035. # _containerVNC() {
  1036. # :
  1037. # }
  1038. # _containerMC() {
  1039. # _installPackage buildah podman
  1040. # cnt=$(buildah from docker.io/jlesage/baseimage-gui:debian-10)
  1041. # podman_create_cmd=("podman" "create" "--name" "$CNAME")
  1042. # buildah_config_cmd=("buildah" "config" \
  1043. # "--author" "bryanroessler@gmail.com" \
  1044. # "--label" "maintainer=$MAINTAINER" \
  1045. # "--env" "TZ=$TZ" \
  1046. # "--workingdir" "/app" \
  1047. # "--cmd" "mediacenter$_mversion")
  1048. # mkcdirs() {
  1049. # local dir
  1050. # for dir in "$@"; do
  1051. # if [[ ! -d "$dir" ]]; then
  1052. # if ! mkdir -p "$dir"; then
  1053. # err "Could not create directory $dir, check your permissions"
  1054. # fi
  1055. # fi
  1056. # if ! chcon -t container_file_t -R "$dir"; then
  1057. # err "Could not set container_file_t attribute for $dir, check your permissions"
  1058. # fi
  1059. # done
  1060. # }
  1061. # mkcdirs "$HOME/.jriver"
  1062. # podman_create_cmd+=("-v" "$HOME/.jriver:/root/.jriver")
  1063. # podman_create_cmd+=("-v" "$DOWNLOAD_ROOT:/downloads:z")
  1064. # podman_create_cmd+=("-v" "$MONITOR_ROOT/nzbs:/nzbs")
  1065. # podman_create_cmd+=("-p" "${CONTAINER[HOST_PORT]}:${CONTAINER[CONTAINER_PORT]}")
  1066. # brc() { buildah run "$1" "${@:2}" || return 1; }
  1067. # brc add-pkg gnupg2 libxss1 wmctrl xdotool ca-certificates inotify-tools libgbm1
  1068. # brc add-pkg --virtual .build-deps wget
  1069. # brc sh -s <<- EOF
  1070. # wget -q "http://dist.jriver.com/mediacenter@jriver.com.gpg.key" -O- | apt-key add - > /dev/null 2>&1
  1071. # EOF
  1072. # brc wget "http://dist.jriver.com/latest/mediacenter/mediacenter$_mversion.list" -O "/etc/apt/sources.list.d/mediacenter$_mversion.list"
  1073. # brc apt-get update -y -q0
  1074. # brc add-pkg "mediacenter$_mversion"
  1075. # brc del-pkg .build-deps
  1076. # }
  1077. #######################################
  1078. # Complete uninstall
  1079. #######################################
  1080. _uninstall() {
  1081. debug "Running: ${FUNCNAME[0]}"
  1082. read -r -p "Do you really want to uninstall JRiver Media Center? [y/N] " _response
  1083. _response=${_response,,} # tolower
  1084. [[ ! "$_response" =~ ^(yes|y)$ ]] && echo "Cancelling uninstall..." && exit 0
  1085. # Uninstall services
  1086. echo "Stopping and removing all associated Media Center services"
  1087. for _service in $(compgen -A "function" "_service"); do
  1088. _servicePrep "$_service"
  1089. _systemctl_disable "$_service_name"
  1090. _systemctl_disable "$_timer_name"
  1091. [[ -f "$_service_fname" ]] && _rm_cmd "$_service_fname"
  1092. [[ -f "$_timer_fname" ]] && _rm_cmd "$_timer_fname"
  1093. done
  1094. echo "Removing repo files"
  1095. [[ -f "/etc/yum.repos.d/jriver.repo" ]] \
  1096. && _rm_cmd "/etc/yum.repos.d/jriver.repo"
  1097. [[ -f "/etc/apt/sources.list.d/jriver.list" ]] \
  1098. && _rm_cmd "/etc/apt/sources.list.d/jriver.list"
  1099. echo "Removing firewall rules"
  1100. if [[ -x $(command -v firewall-cmd) ]]; then
  1101. _firewall_cmd --permanent --remove-service=jriver
  1102. _firewall_cmd --permanent --delete-service=jriver
  1103. _firewall_cmd --reload
  1104. elif [[ -x $(command -v ufw) ]]; then
  1105. _firewall_cmd delete allow jriver
  1106. [[ -f "/etc/ufw/applications.d/jriver" ]] \
  1107. && _rm_cmd /etc/ufw/applications.d/jriver
  1108. fi
  1109. echo "Uninstalling Media Center"
  1110. if [[ "$ID" =~ ^(fedora|centos)$ ]]; then
  1111. _pkg_remove MediaCenter
  1112. elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then
  1113. _pkg_remove "mediacenter$_mversion"
  1114. fi
  1115. echo "JRiver Media Center has been completely uninstalled"
  1116. echo "If you wish to remove your library files: rm -rf $HOME/.jriver"
  1117. echo "If you wish to remove your rpmbuild output files: rm -rf $_outputdir"
  1118. }
  1119. _main "$@"