├── config ├── runtime ├── placeholders └── configure ├── .gitignore ├── blocks ├── homedir ├── copyright ├── module_integrity ├── license ├── nextcloud_updater ├── module_server ├── module_loader ├── tempdir ├── whoami_whereami └── debug ├── modules ├── xml ├── nc │ ├── nextcloud_db │ ├── nextcloud_aio │ ├── nextcloud_logo │ ├── occ │ ├── aio │ ├── versions │ ├── c2j │ ├── logo │ ├── nextcloud │ └── first_run ├── nc-shares │ ├── disclaimer │ ├── help │ ├── html2text │ └── list_shares ├── sysinf.d │ ├── id │ ├── locales │ ├── who │ ├── jq │ ├── pid1 │ ├── aa │ ├── bash │ ├── dmi │ ├── term │ ├── disk │ ├── mem │ ├── se │ ├── cpu │ ├── prompt │ ├── uptime │ ├── ip │ ├── cgroups │ ├── whoami │ ├── hostname │ ├── parent │ ├── env │ ├── hypervisor │ ├── fstab │ ├── f2b │ ├── self │ ├── mount │ ├── os │ ├── sstulpen │ ├── nextcloud │ ├── dpkg │ └── debsources ├── nc-who │ ├── h2t │ ├── last │ └── help ├── nc-apps │ ├── app_update │ ├── l10n │ ├── github_api │ ├── assumed_version │ └── commands.d │ │ └── filters ├── php-updater │ ├── tasks │ ├── tasks.d │ │ ├── unused_sapis │ │ ├── meta_pkgs │ │ └── dependency_pkgs │ ├── pdiff │ ├── disclaimer │ ├── diff │ ├── chfiles │ └── inp ├── sed ├── verbose ├── prefix ├── prompt ├── today ├── sort ├── php-module-builder │ ├── pecl │ ├── disclaimer │ ├── data_refine │ ├── ini │ ├── first_run │ └── patch ├── php │ ├── version │ ├── logo │ ├── apache2 │ └── alternatives ├── button ├── dos2unix ├── interval ├── array ├── anykey ├── exit ├── fstring ├── sudo ├── nc-mimecheck │ └── functions ├── vdir ├── line ├── context ├── ask ├── dist │ └── debian ├── mh ├── cleanup ├── filter ├── tempfile └── backcomp ├── .gitattributes ├── .github └── FUNDING.yml ├── scripts ├── nc-subscribed-calendar ├── nc-shares ├── nc-sql ├── nc-who └── janitor └── tools ├── update_appstore_platforms ├── build_script ├── build_module ├── sign_script └── compare_modules /config/runtime: -------------------------------------------------------------------------------- 1 | declare -i epoch # =$(date +%s) 2 | # declare runtime # ="$(date -d @$epoch "+%F %R %Z")" 3 | printf -v epoch "%(%s)T" -2 4 | # printf -v runtime "%(%F %R %Z)T" -2 5 | 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /config/secrets 3 | /modules/apt/ 4 | /modules/contribute 5 | /modules/di 6 | /TODO.txt 7 | *.new 8 | *~ 9 | *.todo 10 | *.test 11 | *.ini 12 | 13 | -------------------------------------------------------------------------------- /blocks/homedir: -------------------------------------------------------------------------------- 1 | ${C[mw]} ${D[vt]:=/var/tmp/${M[p]}} && export HOME=${D[vt]} && cd 2 | ${C[ms]} ${D[vtm]:=${D[vt]}/modules} ${D[vts]:=${D[vt]}/scripts} 3 | ${C[mw]} ${D[li]:=${D[vtm]}/${M[c]}} 4 | -------------------------------------------------------------------------------- /modules/xml: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${XML_BASHLIB:-_} && return 11 | XML_BASHLIB=: 12 | 13 | : 14 | -------------------------------------------------------------------------------- /blocks/copyright: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023-2025 [ernolf] Raphael Gradenwitz 2 | # Email raphael.gradenwitzgooglemail.com 3 | # OpenPGP_Key 3EE43A84D2BA635A94E1033B0B145139A170715C 4 | # (only for codesigning) 5 | -------------------------------------------------------------------------------- /modules/nc/nextcloud_db: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${NC_NEXTCLOUD_DB_BASHLIB:-_} && return 11 | NC_NEXTCLOUD_DB_BASHLIB=: 12 | 13 | . <(lrequire nc/db) 14 | -------------------------------------------------------------------------------- /modules/nc/nextcloud_aio: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${NC_NEXTCLOUD_AIO_BASHLIB:-_} && return 11 | NC_NEXTCLOUD_AIO_BASHLIB=: 12 | 13 | . <(lrequire nc/aio) 14 | -------------------------------------------------------------------------------- /modules/nc/nextcloud_logo: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${NC_NEXTCLOUD_LOGO_BASHLIB:-_} && return 11 | NC_NEXTCLOUD_LOGO_BASHLIB=: 12 | 13 | . <(lrequire nc/logo) 14 | -------------------------------------------------------------------------------- /modules/nc-shares/disclaimer: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${DISCLAIMER_BASHLIB:-_} && return 11 | DISCLAIMER_BASHLIB=: 12 | 13 | disclaimer(){ 14 | R; echo "This script is work in progress. Use at your own risk." 15 | echo "You can run this script at a later time, it will update itself";N 16 | anykey 17 | } 18 | -------------------------------------------------------------------------------- /blocks/module_integrity: -------------------------------------------------------------------------------- 1 | [ -f "${F[lmj]}" ] || c -o "${F[lmj]}" -A "$(fp;fn_ln)$A" ${V[cargs]}/${F[rmj]} 2 | q2 ${X[jq]:-${C[jq]:-jq}} -r '.modules[] | "\(.hash) \(.name)"' ${F[lmj]} >${D[li]}/modules.sha256 3 | q0 chrf ${D[li]} 0 4 | cd ${D[li]} 5 | tntd=($( 6 | q2 ${X[sha256sum]} -c --ignore-missing --quiet modules.sha256 | sed_ 's/:.*//' 7 | )) 8 | (( ${#tntd[@]} )) && { 9 | for x in ${tntd[@]}; do 10 | ${C[r]} "$x" || B[r]=_ 11 | done 12 | ${B[r]:-:} && exec $CMA 13 | } 14 | cd 15 | q0 chrf ${D[li]} 0 16 | -------------------------------------------------------------------------------- /config/placeholders: -------------------------------------------------------------------------------- 1 | declare -a placeholders 2 | placeholders=( 3 | shebang_bash 4 | bashlib 5 | minified_bashlib 6 | path_and_scriptname 7 | path_and_modulename 8 | version_and_datestring 9 | copyright 10 | license 11 | scriptname 12 | libversion 13 | debug 14 | when 15 | whoami_whereami 16 | vdirname 17 | homedir 18 | tempdir 19 | module_server 20 | general 21 | module_loader 22 | module_integrity 23 | nextcloud_updater 24 | binaries_used 25 | ) 26 | -------------------------------------------------------------------------------- /modules/sysinf.d/id: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_ID_BASHLIB:-_} && return 11 | SYSINF_ID_BASHLIB=: 12 | 13 | sysinf_id(){ 14 | local -A bool 15 | while (( $# )); do 16 | [[ $1 ]] && bool[$1]=: 17 | shift 18 | done 19 | ${bool[spinner]} && { 20 | kill_spinner 21 | spinner Yi " . determine system informations - machine_id ." & 22 | } 23 | SYSINF+=("echo machine-id: $MACHINE_ID") 24 | } 25 | -------------------------------------------------------------------------------- /modules/nc-who/h2t: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${H2T_BASHLIB:-_} && return 11 | H2T_BASHLIB=: 12 | 13 | h2t_command(){ 14 | local i tputcols width 15 | tputcols=$(${X[tput]} cols | ${X[tr]} -d '\n') 16 | width=$(( tputcols - 8 )) 17 | if [[ -p /dev/stdin ]]; then # read from actual STDIN 18 | ${X[html2text]} -utf8 -width $width 19 | else # if no STDIN; 20 | ${X[html2text]} -utf8 -width $width <<< "$@" 21 | fi 22 | } 23 | -------------------------------------------------------------------------------- /modules/nc-apps/app_update: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${APP_UPDATE_BASHLIB:-_} && return 11 | APP_UPDATE_BASHLIB=: 12 | 13 | . <(lrequire nc/nextcloud) 14 | 15 | query_updates(){ 16 | occ app:update -n --no-warnings --allow-unstable --showonly --all | ${X[sed]} -e 's/ new version available: /#/' > $1 17 | } 18 | 19 | # do_update_ $1=app-id or --all, $2= --allow-unstable 20 | do_update_(){ 21 | occ app:update --no-interaction --no-warnings $2 $1 22 | } 23 | -------------------------------------------------------------------------------- /modules/sysinf.d/locales: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_LOCALES_BASHLIB:-_} && return 11 | SYSINF_LOCALES_BASHLIB=: 12 | 13 | # X[localectl] 14 | 15 | sysinf_locales(){ 16 | local -A bool 17 | while (( $# )); do 18 | [[ $1 ]] && bool[$1]=: 19 | shift 20 | done 21 | ${bool[spinner]} && { 22 | kill_spinner 23 | spinner Yi " . determine system informations - locales ." & 24 | } 25 | SYSINF+=("localectl --no-pager status") 26 | } 27 | -------------------------------------------------------------------------------- /modules/sysinf.d/who: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_WHO_BASHLIB:-_} && return 11 | SYSINF_WHO_BASHLIB=: 12 | 13 | # X[who] 14 | 15 | sysinf_who(){ 16 | local -A bool 17 | while (( $# )); do 18 | [[ $1 ]] && bool[$1]=: 19 | shift 20 | done 21 | ${bool[ff]:-_} || { 22 | ${bool[spinner]} && { 23 | kill_spinner 24 | spinner Yi " . determine system informations - who ." & 25 | } 26 | SYSINF+=("who --") 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /modules/sysinf.d/jq: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_JQ_BASHLIB:-_} && return 11 | SYSINF_JQ_BASHLIB=: 12 | 13 | sysinf_jq(){ 14 | local -A bool 15 | while (( $# )); do 16 | [[ $1 ]] && bool[$1]=: 17 | shift 18 | done 19 | ${bool[ff]:-_} || { 20 | ${bool[spinner]} && { 21 | kill_spinner 22 | spinner Yi " . determine system informations - jq version ." & 23 | } 24 | SYSINF+=("echo jq version: $(${X[jq]} --version)") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /modules/sysinf.d/pid1: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_PID1_BASHLIB:-_} && return 11 | SYSINF_PID1_BASHLIB=: 12 | 13 | sysinf_pid1(){ 14 | local -A bool 15 | while (( $# )); do 16 | [[ $1 ]] && bool[$1]=: 17 | shift 18 | done 19 | ${bool[ff]:-_} || { 20 | ${bool[spinner]} && { 21 | kill_spinner 22 | spinner Yi " . determine system informations - pid1 ." & 23 | } 24 | SYSINF+=("echo pid1: $(${X[ps]} -p 1 -o comm=)") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /modules/sysinf.d/aa: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_AA_BASHLIB:-_} && return 11 | SYSINF_AA_BASHLIB=: 12 | 13 | # X[aa-status] 14 | 15 | sysinf_aa(){ 16 | local -A bool 17 | while (( $# )); do 18 | [[ $1 ]] && bool[$1]=: 19 | shift 20 | done 21 | ${bool[ff]:-_} || { 22 | ${bool[spinner]} && { 23 | kill_spinner 24 | spinner Yi " . determine system informations - aa-status ." & 25 | } 26 | SYSINF+=("aa-status --verbose") 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /modules/sysinf.d/bash: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_BASH_BASHLIB:-_} && return 11 | SYSINF_BASH_BASHLIB=: 12 | 13 | sysinf_bash(){ 14 | local -A bool 15 | while (( $# )); do 16 | [[ $1 ]] && bool[$1]=: 17 | shift 18 | done 19 | ${bool[ff]:-_} || { 20 | ${bool[spinner]} && { 21 | kill_spinner 22 | spinner Yi " . determine system informations - bash version ." & 23 | } 24 | SYSINF+=("echo bash version: $BASH_VERSION") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /modules/sysinf.d/dmi: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_DMI_BASHLIB:-_} && return 11 | SYSINF_DMI_BASHLIB=: 12 | 13 | # X[dmidecode] 14 | 15 | sysinf_dmi(){ 16 | local -A bool 17 | while (( $# )); do 18 | [[ $1 ]] && bool[$1]=: 19 | shift 20 | done 21 | ${bool[ff]:-_} || { 22 | ${bool[spinner]} && { 23 | kill_spinner 24 | spinner Yi " . determine system informations - dmidecode ." & 25 | } 26 | SYSINF+=("dmidecode -t 1,11") 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /modules/sysinf.d/term: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_TERM_BASHLIB:-_} && return 11 | SYSINF_TERM_BASHLIB=: 12 | 13 | sysinf_term(){ 14 | local -A bool 15 | while (( $# )); do 16 | [[ $1 ]] && bool[$1]=: 17 | shift 18 | done 19 | ${bool[ff]:-_} || { 20 | ${bool[spinner]} && { 21 | kill_spinner 22 | spinner Yi " . determine system informations - term ." & 23 | } 24 | SYSINF+=("echo tput longname: $(${X[tput]} longname)") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /modules/sysinf.d/disk: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_DISK_BASHLIB:-_} && return 11 | SYSINF_DISK_BASHLIB=: 12 | 13 | # X[df] 14 | 15 | sysinf_disk(){ 16 | local -A bool 17 | while (( $# )); do 18 | [[ $1 ]] && bool[$1]=: 19 | shift 20 | done 21 | ${bool[ff]:-_} || { 22 | ${bool[spinner]} && { 23 | kill_spinner 24 | spinner Yi " . determine system informations - disk ." & 25 | } 26 | SYSINF+=("df -TPk") 27 | SYSINF+=("df -h") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /modules/sysinf.d/mem: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_MEM_BASHLIB:-_} && return 11 | SYSINF_MEM_BASHLIB=: 12 | 13 | # X[free] 14 | 15 | sysinf_mem(){ 16 | local -A bool 17 | while (( $# )); do 18 | [[ $1 ]] && bool[$1]=: 19 | shift 20 | done 21 | ${bool[ff]:-_} || { 22 | ${bool[spinner]} && { 23 | kill_spinner 24 | spinner Yi " . determine system informations - mem ." & 25 | } 26 | SYSINF+=("free -hwt") 27 | SYSINF+=("cat /proc/meminfo") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /modules/sysinf.d/se: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_SE_BASHLIB:-_} && return 11 | SYSINF_SE_BASHLIB=: 12 | 13 | # X[sestatus] 14 | 15 | sysinf_se(){ 16 | local -A bool 17 | while (( $# )); do 18 | [[ $1 ]] && bool[$1]=: 19 | shift 20 | done 21 | ${bool[ff]:-_} || { 22 | ${bool[spinner]} && { 23 | kill_spinner 24 | spinner Yi " . determine system informations - SELinux ." & 25 | } 26 | SYSINF+=("sestatus -v") 27 | SYSINF+=("sestatus -b") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /modules/sysinf.d/cpu: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_CPU_BASHLIB:-_} && return 11 | SYSINF_CPU_BASHLIB=: 12 | 13 | # X[lscpu] 14 | 15 | sysinf_cpu(){ 16 | local -A bool 17 | while (( $# )); do 18 | [[ $1 ]] && bool[$1]=: 19 | shift 20 | done 21 | ${bool[ff]:-_} || { 22 | ${bool[spinner]} && { 23 | kill_spinner 24 | spinner Yi " . determine system informations - lscpu ." & 25 | } 26 | SYSINF+=("lscpu --") 27 | SYSINF+=("cat /proc/cpuinfo") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /modules/sysinf.d/prompt: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_PROMPT_BASHLIB:-_} && return 11 | SYSINF_PROMPT_BASHLIB=: 12 | 13 | sysinf_prompt(){ 14 | local -A bool 15 | while (( $# )); do 16 | [[ $1 ]] && bool[$1]=: 17 | shift 18 | done 19 | ${bool[ff]:-_} || { 20 | ${bool[spinner]} && { 21 | kill_spinner 22 | spinner Yi " . determine system informations - prompt ." & 23 | } 24 | binaries_is_func_ prompt && SYSINF+=("echo prompt: $(prompt)") || return 0 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /blocks/license: -------------------------------------------------------------------------------- 1 | # This script may be freely used, modified, and distributed, provided 2 | # that the original author, [ernolf] Raphael Gradenwitz, is credited. 3 | # 4 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 5 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 6 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 7 | # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 8 | # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 9 | # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 10 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | -------------------------------------------------------------------------------- /modules/sysinf.d/uptime: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_UPTIME_BASHLIB:-_} && return 11 | SYSINF_UPTIME_BASHLIB=: 12 | 13 | # X[uptime] 14 | 15 | sysinf_uptime(){ 16 | local -A bool 17 | while (( $# )); do 18 | [[ $1 ]] && bool[$1]=: 19 | shift 20 | done 21 | ${bool[ff]:-_} || { 22 | ${bool[spinner]} && { 23 | kill_spinner 24 | spinner Yi " . determine system informations - uptime ." & 25 | } 26 | SYSINF+=("uptime --") 27 | SYSINF+=("cat /proc/uptime") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /modules/sysinf.d/ip: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_IP_BASHLIB:-_} && return 11 | SYSINF_IP_BASHLIB=: 12 | 13 | # X[ip] 14 | 15 | sysinf_ip(){ 16 | local -A bool 17 | while (( $# )); do 18 | [[ $1 ]] && bool[$1]=: 19 | shift 20 | done 21 | ${bool[ff]:-_} || { 22 | ${bool[spinner]} && { 23 | kill_spinner 24 | spinner Yi " . determine system informations - ip ." & 25 | } 26 | SYSINF+=("ip address") 27 | SYSINF+=("ip route") 28 | SYSINF+=("ip neighbour") 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /modules/sysinf.d/cgroups: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_CGROUPS_BASHLIB:-_} && return 11 | SYSINF_CGROUPS_BASHLIB=: 12 | 13 | # Cgroups (Control Groups) 14 | sysinf_cgroups(){ 15 | local -A bool 16 | while (( $# )); do 17 | [[ $1 ]] && bool[$1]=: 18 | shift 19 | done 20 | ${bool[ff]:-_} || { 21 | ${bool[spinner]} && { 22 | kill_spinner 23 | spinner Yi " . determine system informations - cgroups ." & 24 | } 25 | SYSINF+=("p_sort /proc/self/cgroup") 26 | SYSINF+=("p_sort /proc/1/cgroup") 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /modules/sysinf.d/whoami: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_WHOAMI_BASHLIB:-_} && return 11 | SYSINF_WHOAMI_BASHLIB=: 12 | 13 | sysinf_whoami(){ 14 | local -A bool 15 | while (( $# )); do 16 | [[ $1 ]] && bool[$1]=: 17 | shift 18 | done 19 | ${bool[ff]:-_} || { 20 | ${bool[spinner]} && { 21 | kill_spinner 22 | spinner Yi " . determine system informations - whoami ." & 23 | } 24 | SYSINF+=("echo runing user: $(echo "UID=${I[u]} USER=${I[un]} GUID=${I[g]} GROUP=${I[gn]} GUIDS=${I[G]} GROUPS=${I[Gn]}")") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /modules/sysinf.d/hostname: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_HOSTNAME_BASHLIB:-_} && return 11 | SYSINF_HOSTNAME_BASHLIB=: 12 | 13 | # X[hostname] 14 | 15 | sysinf_hostname(){ 16 | local -A bool 17 | while (( $# )); do 18 | [[ $1 ]] && bool[$1]=: 19 | shift 20 | done 21 | ${bool[ff]:-_} || { 22 | ${bool[spinner]} && { 23 | kill_spinner 24 | spinner Yi " . determine system informations - hostname ." & 25 | } 26 | SYSINF+=("cat /etc/hostname") 27 | SYSINF+=("hostname -A") 28 | SYSINF+=("hostname -I") 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /modules/sysinf.d/parent: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_PARENT_BASHLIB:-_} && return 11 | SYSINF_PARENT_BASHLIB=: 12 | 13 | sysinf_parent(){ 14 | local -A bool 15 | while (( $# )); do 16 | [[ $1 ]] && bool[$1]=: 17 | shift 18 | done 19 | ${bool[ff]:-_} || { 20 | ${bool[spinner]} && { 21 | kill_spinner 22 | spinner Yi " . determine system informations - parent process ." & 23 | } 24 | SYSINF+=("title parent process (ps -o cmd= \$(ps -o ppid= \$\$)):") 25 | SYSINF+=("true $(${X[ps]} -o cmd= $(${X[ps]} -o ppid= $$))") 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /blocks/nextcloud_updater: -------------------------------------------------------------------------------- 1 | # Update can be done by all but ${NC[u]}, since NC[u] normaly has no sudo rights. 2 | # [[ "$*" =~ (-q|--quiet) ]] || { 3 | 4 | if [ "${I[un]}" = "${NC[u]}" ]; then 5 | if (( J[e] > M[e] )); then 6 | mh "$(fn_ln) update available" 7 | V[upinf]="(update available)" 8 | ${B[silent]} || { 9 | f 10 | ipf 11 | Yi 12 | echo "A new version of this script is available.$(f; o3)Start this script again as user $(W)root$(Yi) if you want to update." 13 | N 14 | f 15 | anykey 16 | } 17 | elif (( J[e] == M[e] )); then 18 | V[upinf]="(latest version)" 19 | fi 20 | else 21 | my_update_check 22 | fi 23 | -------------------------------------------------------------------------------- /modules/php-updater/tasks: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${TASKS_BASHLIB:-_} && return 11 | TASKS_BASHLIB=: 12 | . <(lrequire dpkg) 13 | . <(lrequire php-updater/merge) 14 | . <(lrequire php/versions) 15 | . <(lrequire php/extensions) 16 | . <(lrequire php/apache2) 17 | . <(lrequire php/fpm) 18 | 19 | ${X[mkdir]} -p ${D[li]}/php-updater/tasks.d 20 | 21 | . <(lrequire php-updater/tasks.d/replace_aim) 22 | . <(lrequire php-updater/tasks.d/unused_sapis) 23 | . <(lrequire php-updater/tasks.d/dependency_pkgs) 24 | . <(lrequire php-updater/tasks.d/meta_pkgs) 25 | . <(lrequire php-updater/tasks.d/change_sapi) 26 | . <(lrequire php-updater/tasks.d/ext_config) 27 | -------------------------------------------------------------------------------- /modules/sed: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SED_BASHLIB:-false} && return 11 | SED_BASHLIB=: 12 | 13 | # for backwards compatibility 14 | declare -f lrequire &>/dev/null||lrequire(){ require $@;} 15 | # module sed has moved to awksed: 16 | . <(lrequire awksed) 17 | 18 | echo -e "\n\n\e[31m - The current script version is very old.\n It could be that the integrated updater no longer works here because necessary\n but meanwhile deprecated modules are no longer available.\n\n Please run\n\n\e[37m sudo\e[36m wget -O $ca_me https://global-social.net/script/$bm\n\n\e[31m and start the script again if an update is not offered or fails.\e[0m\n\n" > /dev/tty 19 | 20 | -------------------------------------------------------------------------------- /modules/verbose: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${VERBOSE_BASHLIB:-_} && return 11 | VERBOSE_BASHLIB=: 12 | 13 | # TODO 0 --> 14 | . <(lrequire binaries) 15 | . <(lrequire button) 16 | . <(lrequire exit) 17 | . <(lrequire anykey) 18 | # TODO 0 <-- 19 | # error handling 20 | error(){ 21 | if ! ${B[quiet]:-_}; then 22 | R; echo "ERROR: $*$(N)" >&2 23 | exit1 24 | fi 25 | } 26 | 27 | # verbose-echo 28 | v_echo(){ 29 | if ${B[verbose]:-_}; then 30 | R; echo "VERBOSE:$(N) $*" 31 | fi 32 | } 33 | 34 | # verbose-echo 35 | d_echo(){ 36 | if ${B[debug]:-_}; then 37 | R; echo "DEBUG:$(N) $*" 38 | anykey 39 | fi 40 | } 41 | -------------------------------------------------------------------------------- /modules/sysinf.d/env: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_ENV_BASHLIB:-_} && return 11 | SYSINF_ENV_BASHLIB=: 12 | 13 | sysinf_env(){ 14 | local -A bool 15 | while (( $# )); do 16 | [[ $1 ]] && bool[$1]=: 17 | shift 18 | done 19 | ${bool[ff]:-_} || { 20 | ${bool[spinner]} && { 21 | kill_spinner 22 | spinner Yi " . determine system informations - env ." & 23 | } 24 | SYSINF+=("env -u LS_COLORS -u TERMCAP") 25 | # SYSINF+=("title env -u LS_COLORS | cat -v") 26 | # SYSINF+=("true $(${X[cat]} -v < <(${X[env]} -u LS_COLORS))") 27 | # SYSINF+=("echo TMPDIR: $TD") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /modules/sysinf.d/hypervisor: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_HYPERVISOR_BASHLIB:-_} && return 11 | SYSINF_HYPERVISOR_BASHLIB=: 12 | 13 | sysinf_hypervisor(){ 14 | local -A bool 15 | while (( $# )); do 16 | [[ $1 ]] && bool[$1]=: 17 | shift 18 | done 19 | ${bool[ff]:-_} || { 20 | ${bool[spinner]} && { 21 | kill_spinner 22 | spinner Yi " . determine system informations - hypervisor ." & 23 | } 24 | local hypervisor 25 | hypervisor="$(${X[dmesg]} -t | ${X[gawk]} 'tolower($0) ~ /^hypervisor/ {print $NF}')" 26 | SYSINF+=("echo hypervisor: ${hypervisor:-bare-metal}") 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /modules/sysinf.d/fstab: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_FSTAB_BASHLIB:-_} && return 11 | SYSINF_FSTAB_BASHLIB=: 12 | 13 | sysinf_fstab_column(){ 14 | ${X[sed]} 's/#.*//' /etc/fstab | ${X[column]} --table --table-columns SOURCE,TARGET,TYPE,OPTIONS,PASS,FREQ --table-right PASS,FREQ 15 | } 16 | 17 | sysinf_fstab(){ 18 | local -A bool 19 | while (( $# )); do 20 | [[ $1 ]] && bool[$1]=: 21 | shift 22 | done 23 | ${bool[ff]:-_} || { 24 | ${bool[spinner]} && { 25 | kill_spinner 26 | spinner Yi " . determine system informations - fstab ." & 27 | } 28 | SYSINF+=("title cat /etc/fstab:") 29 | SYSINF+=("true $(sysinf_fstab_column)") 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /modules/prefix: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${PREFIX_BASHLIB:-_} && return 11 | PREFIX_BASHLIB=: 12 | 13 | # TODO 0 --> 14 | . <(lrequire ansi) 15 | # TODO 0 <-- 16 | # Prefix 17 | pf(){ 18 | printf ' - ' 19 | } 20 | 21 | # star (asterisk) prefix 22 | spf(){ 23 | printf ' * ' 24 | } 25 | 26 | # Warning / Exclamation 27 | # ⚠️ = either '\u26A0' or '\xE2\x9A\xA0' 28 | xpf(){ 29 | R; printf "\u26A0$(N): " 30 | } 31 | 32 | # Information 33 | ipf(){ 34 | printf 'I: ' 35 | } 36 | 37 | # Information long 38 | ipfl(){ 39 | C; printf "info$(W): " 40 | } 41 | 42 | # Question 43 | qpf(){ 44 | printf 'Q: ' 45 | } 46 | 47 | # Answer 48 | apf(){ 49 | printf 'A: ' 50 | } 51 | 52 | # Result 53 | rpf(){ 54 | printf 'R: ' 55 | } 56 | -------------------------------------------------------------------------------- /modules/sysinf.d/f2b: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_F2B_BASHLIB:-_} && return 11 | SYSINF_F2B_BASHLIB=: 12 | 13 | sysinf_f2b(){ 14 | [ -n "${X[fail2ban-client]}" ] || return 15 | f2b_status(){ ${X[fail2ban-client]} status; } 16 | f2b_banned(){ ${X[fail2ban-client]} banned | sed_ "s/'/\"/g; s/([[:alnum:]_]+):/\1\":/g" | ${X[jq]}; } 17 | local -A bool 18 | while (( $# )); do 19 | [[ $1 ]] && bool[$1]=: 20 | shift 21 | done 22 | ${bool[spinner]} && { 23 | kill_spinner 24 | spinner Yi " . determine system informations - f2b ." & 25 | } 26 | SYSINF+=("title fail2ban status:") 27 | SYSINF+=("true $(f2b_status)") 28 | SYSINF+=("title fail2ban banned:") 29 | SYSINF+=("true $(f2b_banned)") 30 | } 31 | -------------------------------------------------------------------------------- /modules/prompt: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${PROMPT_BASHLIB:-_} && return 11 | PROMPT_BASHLIB=: 12 | 13 | prompt(){ 14 | local -i r=0 15 | if ${B[rt]}; then 16 | if [ -z "$SUDO_USER" ] || [ "$SUDO_USER" = 'root' ]; then 17 | echo -n "root@${HOSTNAME:-hostname}:~#" 18 | r=1 19 | else 20 | echo -n "$SUDO_USER@${HOSTNAME:-hostname}:~$" 21 | fi 22 | else 23 | if [[ "${I[Gn]} " =~ " sudo " ]]; then 24 | echo -n "${I[un]}@${HOSTNAME:-hostname}:~$" 25 | elif [ "$1" = "-su" ]; then 26 | echo -n "user_with_sudo_rights@${HOSTNAME:-hostname}:~$" 27 | else 28 | echo -n "${I[un]}@${HOSTNAME:-hostname}:~$" 29 | fi 30 | fi 31 | return $r 32 | } 33 | -------------------------------------------------------------------------------- /modules/sysinf.d/self: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_SELF_BASHLIB:-_} && return 11 | SYSINF_SELF_BASHLIB=: 12 | 13 | sysinf_self(){ 14 | local -A bool 15 | while (( $# )); do 16 | [[ $1 ]] && bool[$1]=: 17 | shift 18 | done 19 | ${bool[ff]:-_} || { 20 | ${bool[spinner]} && { 21 | kill_spinner 22 | spinner Yi " . determine system informations - /proc/self ." & 23 | } 24 | ## readlink /proc/self/fd/0, 1, 2 25 | SYSINF+=("echo readlink /proc/self/fd/0: $(${X[realpath]} /proc/self/fd/0 2>&1)") 26 | SYSINF+=("echo readlink /proc/self/fd/1: $(${X[realpath]} /proc/self/fd/1 2>&1)") 27 | SYSINF+=("echo readlink /proc/self/fd/2: $(${X[realpath]} /proc/self/fd/2 2>&1)") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /modules/nc-apps/l10n: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${L10N_BASHLIB:-_} && return 11 | L10N_BASHLIB=: 12 | 13 | # Check if the given language code is valid. If not, return 'en' 14 | validate_language() { 15 | local lang="$1" valid_languages 16 | # get new languages: jq -r '[.[] | .translations | keys[]] | unique | join(" ")' /path/toapps.json" 17 | valid_languages="af ar bg bn ca cs da de el en es fa fi fr gl he hi hu id it ja ko lt mk mn ne nl nn pl pt pt-br ro ru sk sl sq sr sv ta te th tr uk ur vi zh-hans zh-hant" 18 | # Check if the provided language code is in the list of valid languages 19 | if [[ ! " $valid_languages " =~ " $lang " ]]; then 20 | lang="en" 21 | fi 22 | echo "$lang" 23 | } 24 | 25 | declare lang="$(validate_language $(echo "$LANG"|${X[cut]} -d'_' -f1))" 26 | -------------------------------------------------------------------------------- /modules/today: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | declare -f _ &>${NUL:=/dev/null} || _(){ false; } 11 | if (( M[e] < 1737773190 )); then 12 | q0(){ "$@" &>$NUL; } 13 | q1(){ "$@" >$NUL; } 14 | q2(){ "$@" 2>$NUL; } 15 | fi 16 | 17 | ${TODAY_BASHLIB:-_} && return 18 | TODAY_BASHLIB=: 19 | 20 | . <(lrequire binaries) 21 | 22 | # when 23 | # today 00:00 in unixtime 24 | declare -i today=$(${X[date]} -ud 'today 00:00' +%s) 25 | 26 | # from unix to utc day 27 | ut2udF(){ 28 | local ut 29 | [[ -p /dev/stdin ]] && ut="$(< /dev/stdin)" || ut="$1" 30 | [[ $ut =~ ^[0-9]+$ ]] || return 1 31 | ${X[date]} -ud @$ut +%F 32 | } 33 | 34 | date2unix0hr(){ 35 | require_arg $@ 36 | ${X[date]} -ud "$1 00:00" +%s 37 | } 38 | 39 | now(){ 40 | # ${X[date]} +%s 41 | printf '%d' $EPOCHSECONDS 42 | } 43 | -------------------------------------------------------------------------------- /modules/sysinf.d/mount: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_MOUNT_BASHLIB:-_} && return 11 | SYSINF_MOUNT_BASHLIB=: 12 | 13 | # X[mount] 14 | 15 | sysinf_mount(){ 16 | local -A bool 17 | while (( $# )); do 18 | [[ $1 ]] && bool[$1]=: 19 | shift 20 | done 21 | list_mount(){ 22 | ( echo "DEVICE:MOUNTPOINT:TYPE:OPTIONS" 23 | ${X[mount]} | ${X[gawk]} '{ 24 | gsub(/[()]/,"",$6) 25 | print $1 ":" $3 ":" $5 ":" $6 26 | }' 27 | ) | ${X[column]} -t -s ':' 28 | } 29 | ${bool[ff]:-_} || { 30 | ${bool[spinner]} && { 31 | kill_spinner 32 | spinner Yi " . determine system informations - mount ." & 33 | } 34 | SYSINF+=("title mount:") 35 | SYSINF+=("true $(list_mount)") 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /modules/sort: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SORT_BASHLIB:-_} && return 11 | SORT_BASHLIB=: 12 | 13 | bubble_sort(){ 14 | local -a array index temp 15 | local -i len i j 16 | 17 | array=($@) 18 | len=$# 19 | 20 | for ((i = 0; i < len; i++)); do 21 | index[i]=$i 22 | done 23 | 24 | for ((i = 0; i < len-1; i++)); do 25 | for ((j = 0; j < len-i-1; j++)); do 26 | if ((array[j] < array[j+1])); then 27 | 28 | temp=${array[j]} 29 | array[j]=${array[j+1]} 30 | array[j+1]=$temp 31 | 32 | temp=${index[j]} 33 | index[j]=${index[j+1]} 34 | index[j+1]=$temp 35 | fi 36 | done 37 | done 38 | for ((i = 0; i < len; i++)); do 39 | echo -n "${index[i]} " 40 | done 41 | } 42 | -------------------------------------------------------------------------------- /modules/sysinf.d/os: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_OS_BASHLIB:-_} && return 11 | SYSINF_OS_BASHLIB=: 12 | 13 | sysinf_os(){ 14 | local -A bool 15 | while (( $# )); do 16 | [[ $1 ]] && bool[$1]=: 17 | shift 18 | done 19 | ${bool[ff]:-_} || { 20 | ${bool[spinner]} && { 21 | kill_spinner 22 | spinner Yi " . determine system informations - os-release ." & 23 | } 24 | if [ -z "${F[os_release]}" ] && [[ -f /etc/os-release || -f /usr/lib/os-release ]]; then 25 | [ -f /etc/os-release ] && F[os_release]="/etc/os-release" || F[os_release]="/usr/lib/os-release" 26 | fi 27 | if [ -n "${F[os_release]}" ]; then 28 | SYSINF+=("grep -v URL ${F[os_release]}") 29 | elif [ -n "${X[lsb_release]}" ]; then 30 | SYSINF+=("lsb_release -a") 31 | fi 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | blocks/* linguist-language=Bash 2 | config/* linguist-language=Bash 3 | modules/dist/* linguist-language=Bash 4 | modules/nc/* linguist-language=Bash 5 | modules/nc-apps/* linguist-language=Bash 6 | modules/nc-apps/commands.d/* linguist-language=Bash 7 | modules/nc-mimecheck/* linguist-language=Bash 8 | modules/nc-shares/* linguist-language=Bash 9 | modules/nc-sharetoken-length/* linguist-language=Bash 10 | modules/nc-subscribed-calendar/* linguist-language=Bash 11 | modules/nc-who/* linguist-language=Bash 12 | modules/php/* linguist-language=Bash 13 | modules/php-module-builder/* linguist-language=Bash 14 | modules/php-updater/* linguist-language=Bash 15 | modules/php-updater/switch.d/* linguist-language=Bash 16 | modules/php-updater/tasks.d/* linguist-language=Bash 17 | modules/php.net/* linguist-language=Bash 18 | modules/sysinf.d/* linguist-language=Bash 19 | modules/* linguist-language=Bash 20 | scripts/* linguist-language=Bash 21 | tools/common_build_functions linguist-language=Bash 22 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [ernolf] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 12 | polar: # Replace with a single Polar username 13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username 14 | thanks_dev: # Replace with a single thanks.dev username 15 | custom: ["https://PayPal.Me/ernolf"] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 16 | -------------------------------------------------------------------------------- /modules/php-module-builder/pecl: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${PECL_BASHLIB:-_} && return 11 | PECL_BASHLIB=: 12 | 13 | pecl_download(){ 14 | local chan download_output file_name 15 | if (( $# )); then 16 | chan="$1" 17 | else 18 | chan="$module" 19 | fi 20 | 21 | ${X[pecl]} channel-update pecl.php.net 22 | 23 | download_output=$(${X[pecl]} download $chan 2>&1) 24 | file_name=$(echo "$download_output" | ${X[grep]} -oP '(?<=File ).*(?= downloaded)' | ${X[xargs]} ${X[basename]}) 25 | 26 | if [ -f "$file_name" ]; then 27 | lG; echo "- download of $file_name successfull" 28 | else 29 | R; echo "- download of $file_name failed" 30 | exit1 31 | fi 32 | 33 | if ${X[tar]} -xzf $file_name; then 34 | B; echo "- entering directory \"${file_name%.*}\"" 35 | cd ${file_name%.*} 36 | else 37 | R; echo "- unpacking failed" 38 | exit1 39 | fi 40 | N 41 | } 42 | -------------------------------------------------------------------------------- /modules/php/version: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${PHP_VERSION_BASHLIB:-_} && return 11 | PHP_VERSION_BASHLIB=: 12 | 13 | declare php_version 14 | declare -a available_php_versions alternative_php_versions 15 | [ -f "${F[php]:="${D[vt]}/php"}" ] && . "${F[php]}" 16 | [ -n "${X[php]}" ] && PHP[v]="$(${X[php]} -r 'echo implode(".", array_slice(explode(".", PHP_VERSION), 0, 2));')" 17 | declare -p PHP > "${F[php]}" 18 | php_version="${PHP[v]}" 19 | available_php_versions=($(q2 ${X[ls]} $(command -v php)[578].[012346] | sed_ "s|$(command -v php)||g")) 20 | alternative_php_versions=($(echo "${available_php_versions[@]}"|${X[tr]} ' ' '\n'|${X[grep]} -v "^$php_version$"|${X[tr]} '\n' ' ')) 21 | 22 | php_ver(){ 23 | [ -f "${F[php]:="${D[vt]}/php"}" ] && . "${F[php]}" 24 | if (($#)); then 25 | case "$1" in alternatives) echo "${alternative_php_versions[@]}"; esac 26 | elif (( ${#available_php_versions[@]} )); then 27 | printf '%s' "${PHP[v]}" 28 | return 0 29 | fi 30 | } 31 | -------------------------------------------------------------------------------- /blocks/module_server: -------------------------------------------------------------------------------- 1 | [ -x $(command -v lsof) ] && C[l]="${C[e]} LC_MESSAGES=C $(command -v lsof)" || __ "'lsof' binary not found." 2 | ls_(){ 3 | case "$1" in 4 | pidstatus) 5 | [ -f "$ls_pid_file" ] && ${C[ps]} -p $(${C[c]} "$ls_pid_file") > $NUL && return 0 || return 1 6 | ;; 7 | portstatus) 8 | ${C[l]} -Pi :$lsp -sTCP:LISTEN -t >$NUL && return 0 || return 1 9 | ;; 10 | start) 11 | if ls_ pidstatus && ls_ portstatus; then 12 | return 0 13 | elif ! ls_ pidstatus && ! ls_ portstatus; then 14 | cd "$lsd" 15 | __http_server__ $lsp &>$NUL & 16 | echo $! > "$ls_pid_file" 17 | elif ls_ pidstatus && ! ls_ portstatus; then 18 | ls_ restart 19 | fi 20 | ;; 21 | stop) 22 | if ls_ pidstatus; then 23 | echo "Stopping local module server..." 24 | kill $(${C[c]} "$ls_pid_file") 25 | ${C[r]} "$ls_pid_file" 26 | fi 27 | ;; 28 | restart) 29 | ls_ stop 30 | ls_ start 31 | esac 32 | } 33 | ls_ start 34 | -------------------------------------------------------------------------------- /scripts/nc-subscribed-calendar: -------------------------------------------------------------------------------- 1 | __shebang_bash__ 2 | __path_and_scriptname__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | __whoami_whereami__ 11 | __scriptname__ 12 | __homedir__ 13 | __vdirname__ NC_DIR 14 | modules=(nc/nextcloud nc/db $MS/functions) 15 | __debug__ 16 | __when__ 17 | __tempdir__ 18 | __module_server__ 19 | __general__ 20 | __module_loader__ 21 | __module_integrity__ 22 | __nextcloud_updater__ 23 | 24 | contribute_(){ 25 | . <(require contribute) 26 | contribute "https://help.nextcloud.com/t/calendar-subscriptions-refresh-rate-as-a-user/163340/5" 27 | }; donate_(){ contribute_;} 28 | [[ "$@" =~ (donat|contrib) ]] && contribute_ 29 | 30 | ## void 31 | f 32 | B;echo "This script looks up for subscribed calendars in the database of your nextcloud" 33 | echo "and it gives you the means to set an individual refreshrate per calendar";N 34 | 35 | #set -x 36 | if (($(count_calendarsubscriptions)));then 37 | capture_user_id 38 | list_calendars "$user_id" 39 | capture_calendar_id "$user_id" 40 | list_examples 41 | capture_refreshrate 42 | enter_yes 43 | update_refreshrate $cal_id $refreshrate 44 | final_message 45 | else 46 | echo "There ain't no subscribed calendars in database" 47 | exit 0 48 | fi 49 | exit0 50 | 51 | -------------------------------------------------------------------------------- /modules/php-module-builder/disclaimer: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${DISCLAIMER_BASHLIB:-_} && return 11 | DISCLAIMER_BASHLIB=: 12 | 13 | . <(lrequire php/logo) 14 | 15 | disclaimer(){ 16 | ${X[clear]} 17 | phplogo 18 | ${X[cat]} << DISCLAIMER 19 | 20 | Disclaimer 21 | ========== 22 | 23 | This script is intended for advanced administrators who are comfortable creating their own modules. 24 | It makes life a little easier. Although the build process is made more secure because tested, the 25 | possibility of shooting yourself in the feet isn't completely eliminated. It is recommended to use 26 | packaged extensions from your distribution wherever possible. You may need to add a PPA (Ubuntu) or 27 | DPA (Debian) to your Apt sources to increase the range of installable PHP candidates. 28 | Visit Ondřej Surý's website: https://deb.sury.org/ for more details about that. 29 | 30 | Only if the desired extension then still is not offered as package, such as with the lua module, this 31 | script can (and should) be used. 32 | 33 | 34 | Good luck, 35 | ernolf 36 | 37 | PS: 38 | Feedback and suggestions for improvements/additions are always welcome! 39 | You can write me here: 40 | https://github.com/ernolf/ebtb/issues 41 | 42 | DISCLAIMER 43 | anykey 44 | } 45 | -------------------------------------------------------------------------------- /scripts/nc-shares: -------------------------------------------------------------------------------- 1 | __shebang_bash__ 2 | __path_and_scriptname__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | __whoami_whereami__ 11 | __scriptname__ 12 | __homedir__ 13 | __vdirname__ NC_DIR 14 | modules=(verbose nc/nextcloud nc/occ nc/db $MS/help $MS/list_shares) 15 | __debug__ 16 | __when__ 17 | __tempdir__ 18 | __module_server__ 19 | __general__ 20 | __module_loader__ 21 | __module_integrity__ 22 | __nextcloud_updater__ 23 | 24 | ############################################################################## 25 | 26 | contribute_(){ 27 | . <(require contribute) 28 | contribute "https://help.nextcloud.com/t/script-nc-shares-list-shares-on-command-line/185599" 29 | }; donate_(){ contribute_;} 30 | [[ "$@" =~ (donat|contrib) ]] && contribute_ 31 | 32 | declare options command 33 | options="$(${X[getopt]} -o hs: --long help,sharetype: -n 'me' -- "$@")" 34 | eval set -- "$options" 35 | command=list_shares 36 | while true; do 37 | case "$1" in 38 | -h|--help) 39 | print_help 40 | ;; 41 | -s|--sharetype) 42 | sharetype="$2" 43 | shift 2 44 | ;; 45 | --) 46 | shift 47 | break 48 | ;; 49 | *) 50 | echo "Unknown option: $1" >&2 51 | print_help 52 | ;; 53 | esac 54 | done 55 | 56 | (($#)) && $command $* || print_help 57 | 58 | exit 0 59 | 60 | -------------------------------------------------------------------------------- /config/configure: -------------------------------------------------------------------------------- 1 | # Configuration file for the project 2 | 3 | PROJECT='ebtb' 4 | MY_HOME='https://global-social.net/apps/raw' 5 | # Directory for scripts installation. 6 | # On the first run, scripts are replaced by a symlink pointing 7 | # to the scripts which then are moved to $SCRIPTS_DIR 8 | BINDIR="/usr/local/bin" 9 | # Prefix 10 | PREFIX="/var/tmp" 11 | # SANDBOX directory 12 | SANDBOX="$PREFIX/$PROJECT" 13 | # Directory-name for scripts 14 | SCRIPTS='scripts' 15 | # Directory-name for modules 16 | MODULES='modules' 17 | # Directory-name for build tools 18 | TOOLS='tools' 19 | # Directory-name for the build process 20 | BUILD='build' 21 | # Directory where the scripts will be moved to on first run 22 | SCRIPTS_DIR="$SANDBOX/$SCRIPTS" 23 | # Directory for modules 24 | MODULES_DIR="$SANDBOX/$MODULES" 25 | # Directory for the script build process 26 | SBUILD_DIR="$BUILD/$SCRIPTS" 27 | # Directory for the module build process 28 | MBUILD_DIR="$BUILD/$MODULES" 29 | # Minify (some) codeblocks in scripts (boolean) 30 | MINIFY='true' 31 | # Local module server (boolean) 32 | LOCAL_SERVER='true' 33 | # Port (ephemeral port range = 49152 - 65535) 34 | LOCAL_SERVER_PORT=48484 35 | # php or python3 36 | LOCAL_SERVER_BINARY='python3' 37 | # Directory where the local server resides after installation 38 | LOCAL_SERVER_DIRECTORY="$SANDBOX/server" 39 | # Do not build modules or scripts with this sufixes (space separated, case insensitive) 40 | EXCLUDE_SUFIXES="~ .todo .test .new .ini" 41 | 42 | -------------------------------------------------------------------------------- /modules/nc/occ: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${NC_OCC_BASHLIB:-_} && return 11 | NC_OCC_BASHLIB=: 12 | 13 | . <(lrequire php/version) 14 | . <(require nc/aio) 15 | . <(require nc/c2j) 16 | . <(require nc/nextcloud) 17 | 18 | [ -f "${F[nc]:=${D[vt]}/nc}" ] && . ${F[nc]} 19 | 20 | # occ 21 | if ${B[aio]}; then 22 | occ(){ docker exec --user www-data -i nextcloud-aio-nextcloud php occ $@; } 23 | else 24 | # detect, if apc is required for cli 25 | declare phpcli 26 | phpcli="${X[php$php_version]}" 27 | if [ "$(nc_configkey memcache.local)" = '\OC\Memcache\APCu' ]; then 28 | (( $(${X[php$php_version]} -r 'echo ini_get("apc.enable_cli") ?: 0;') )) || phpcli="${X[php$php_version]} --define apc.enable_cli=1" 29 | fi 30 | mh "nc/occ: \"nc_configkey memcache.local\" = '$(nc_configkey memcache.local 2>&1)'" 31 | mh "nc/occ: \"grep '^apc.enable_cli => On => On$' \$(php$php_version -i)\" = '$(${X[grep]} -i '^apc.enable_cli => On => On$'< <(${X[php$php_version]} -i) 2>&1)'" 32 | mh "nc/occ: phpcli = $phpcli" 33 | # the occ command call is saved under occ, adapted to the user and environment 34 | occ(){ $phpcli -f ${NC[d]}/console.php "$@"; } 35 | if ${B[rt]}; then 36 | occ(){ ${X[sudo]} -u ${NC[u]} $phpcli -f ${NC[d]}/console.php "$@"; } 37 | else 38 | [[ "${I[un]}" == "${NC[u]}" ]] || su_do "u=NC_USER" 39 | fi 40 | fi 41 | -------------------------------------------------------------------------------- /blocks/module_loader: -------------------------------------------------------------------------------- 1 | ## include bashmodules -> 2 | [[ ${M[c]} = test ]] && T[w4uc]=30 || T[w4uc]=300 3 | D[ri]="modules/${M[c]}" 4 | ${C[md]} "${D[li]}/$MS" 5 | REQ=". ${D[li]}" F[lmj]="${D[li]}/modules.json" F[rmj]="${D[ri]}/modules.json" F[lcf]="${D[li]}/$MS/.checked" 6 | F[lmjn]="${F[lmj]}~new" T[lce]=$(q2 ${C[c]} "${F[lcf]}" || :) 7 | (( T[rte] - T[lce] > T[w4uc] )) && { 8 | c -o ${F[lmjn]} -A "$(fp;fn_ln)$A" ${V[cargs]}/${F[rmj]} && q0 chrf ${D[li]} 0 9 | if T[mje]=$(json_etag ${F[lmj]}) && T[mjne]=$(json_etag ${F[lmjn]}); then (( T[mje] < T[mjne] )) && B[check]=:; fi 10 | } 11 | for x in binaries fp filter mh cleanup basics awksed exit tempfile ansi prefix button debug anykey line array menu ask sudo spinner dpkg dependency vdir gpg integrity ${modules[@]}; do 12 | ${B[check]} && { 13 | ${B[pager]} || printf "\r\e[K.. checking modules - $x" 14 | c4u "$x" 15 | } || { ${B[pager]} || printf "\r\e[K.. loading modules - $x"; } 16 | . <(lreq $x) 17 | done 18 | ${B[check]} && echo ${T[rte]} > "${F[lcf]}" 19 | [[ -f ${F[lmjn]} ]] && ${X[mv]} ${F[lmjn]} ${F[lmj]} 20 | ${B[rt]} && ! (( T[lce] )) && echo ${T[rte]} > "${F[lcf]}" 21 | ${B[pager]} || te1 22 | eval "$(echo "$(unquote ${J[o]})" | ${X[jq]:-${C[jq]:-jq}} -r 'keys[] as $key|"J[\($key[0:1])]=\(.[$key]|@sh)"')" # <- This must be done here because of dependency of jq 23 | V[upinf]='(no update info available)' 24 | . <(req update) 25 | "${B[do_update]}" && my_update 26 | [[ ${1:-} = my_update_check ]] && my_update_check 27 | "${B[do_restore_backup]}" && restore_backup 28 | -------------------------------------------------------------------------------- /modules/sysinf.d/sstulpen: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_SSTULPEN_BASHLIB:-_} && return 11 | SYSINF_SSTULPEN_BASHLIB=: 12 | 13 | sysinf_sstulpen(){ 14 | local -A bool 15 | while (( $# )); do 16 | [[ $1 ]] && bool[$1]=: 17 | shift 18 | done 19 | ss_with_service_names() { 20 | # print header with '|' as delimiter 21 | ( echo "Proto|State|Recv-Q|Send-Q|Local Addr:Port|Service|Peer Addr:Port|Process" 22 | # suppress repeated headers 23 | ${X[ss]} -tulpenH | while read -r proto state recv send local peer proc _; do 24 | # extract port and lookup service 25 | port="${local##*:}" 26 | svc=$(${X[getent]} services "${port}/${proto}" | ${X[gawk]} '{print $1}') 27 | [[ -z "$svc" ]] && svc="$port" 28 | 29 | # output pipes-delimited 30 | printf "%s|%s|%s|%s|%s|%s|%s|%s\n" \ 31 | "$proto" "$state" "$recv" "$send" "$local" "$svc" "$peer" "$(sed_ 's/^users://; s/[()]//g; s/,"/, "/g' "$proc" '-')" 32 | done 33 | ) | ${X[column]} -t -s '|' 34 | } 35 | 36 | ${bool[ff]:-_} || { 37 | ${bool[spinner]} && { 38 | kill_spinner 39 | spinner Yi " . determine system informations - sstulpen ." & 40 | } 41 | SYSINF+=("title ss -tulpen:") 42 | SYSINF+=("true $(ss_with_service_names)") 43 | } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /modules/sysinf.d/nextcloud: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_NEXTCLOUD_BASHLIB:-_} && return 11 | SYSINF_NEXTCLOUD_BASHLIB=: 12 | 13 | sysinf_nextcloud(){ 14 | local -A bool 15 | while (( $# )); do 16 | [[ $1 ]] && bool[$1]=: 17 | shift 18 | done 19 | ${bool[spinner]} && { 20 | kill_spinner 21 | spinner Yi " . determine system informations - httpd (nextcloud) ." & 22 | } 23 | populate_httpd_ nextcloud 24 | if (( "${#HTTPD_NEXTCLOUD[@]}" )); then 25 | SYSINF+=("title httpd serving nextcloud:") 26 | SYSINF+=("true $(p_sort_numerate "${HTTPD_NEXTCLOUD[@]}")") 27 | fi 28 | populate_httpd_ nc-dir 29 | if (( "${#HTTPD_NC_DIR[@]}" )); then 30 | SYSINF+=("title httpd configured directories with a nextcloud installation:") 31 | else 32 | mapfile -t HTTPD_NC_DIR< <(q2 ${X[find]} -L /var /srv \( -path /var/tmp -prune \) -o -name occ -type f -exec dirname {} \; | ${X[grep]} -Ev '(/updater-oc|/overlay)' | ${X[sort]}) 33 | (( "${#HTTPD_NC_DIR[@]}" )) && SYSINF+=("title httpd detected nextcloud directories (none configured):") 34 | fi 35 | (( "${#HTTPD_NC_DIR[@]}" )) && SYSINF+=("true $(p_sort_numerate "${HTTPD_NC_DIR[@]}")") 36 | # TODO 0 --> 37 | # [[ -f ${F[nc]:=${D[vt]}/nc} ]] && . ${F[nc]} 38 | # [[ $(q2 declare -p NC) =~ 'declare -A' ]] && { 39 | # SYSINF+=("title declare -p NC:") 40 | # SYSINF+=("true $(declare -p NC)") 41 | # } 42 | # TODO 0 <-- 43 | } 44 | -------------------------------------------------------------------------------- /blocks/tempdir: -------------------------------------------------------------------------------- 1 | : "${TD:=/tmp}" # if TD is empty, prefill it with /tmp 2 | [[ $TD == '/' || ! -d $TD ]] && TD='/tmp' # if TD is / or not a directory we use /tmp 3 | [ -d "$TD" ] || { # if after these tests, $TD is still not a directory, try the candidates 4 | for x in /run/user/${I[u]} /dev/shm /var/tmp ~/tmp; do 5 | [ -d "$x" ] && { TD="$x"; break; } 6 | done 7 | } 8 | # remove trailing slash 9 | TD="${TD%/}" 10 | [ -d "$TD" ] && { 11 | V[tsa]=$(${C[s]} -c %A $TD) V[w]=drwxrwxrwt 12 | while :; do 13 | [[ $TD == */user/${I[u]} && $(${C[s]} -c %u%g $TD) == ${I[u]}${I[g]} ]] && break # directory is owned by the user and can be used 14 | [[ $TD == */user && ${V[tsa]} == ${V[w]} ]] && { TD="$TD/${I[u]}"; break; } # user subdirectory exists, directory can be created 15 | [[ ${V[tsa]} == ${V[w]} ]] && { ${C[ms]} $TD/user; TD=$TD/user/${I[u]}; } # user subdirectory does not exist, can be created 16 | break 17 | done 18 | } 19 | ${C[cms]} ${D[tu]:=${D[t]:=${TD%/user*}}/user} 20 | ${C[ms]} ${D[tp]:=${D[t]}/${M[p]}} ${D[log]:=${D[tp]}/log} ${D[lu]:=/run/lock/user} 21 | # create the directory if it does not exist, with permissions 700 22 | [ -d "${D[t]}/user-${I[u]}" ] && ${C[mv]} "${D[t]}/user-${I[u]}" $TD 23 | ${C[md]}m 700 "$TD" 24 | # if the temporary file exists, remove it and if the temporary file was not created, print an error message and die 25 | [[ -n "${F[ttf]:=$(${C[mt]} -p $TD)}" && -f "${F[ttf]}" ]] && ${C[r]} "${F[ttf]}" || __ "TMPDIR '$TD' is not writable by user '${I[un]}'" 26 | # unset the temporary file variable 27 | unset F[ttf] 28 | D[td]=$TD 29 | -------------------------------------------------------------------------------- /modules/button: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${BUTTON_BASHLIB:-_} && return 11 | BUTTON_BASHLIB=: 12 | 13 | # TODO 0 --> 14 | . <(lrequire binaries) 15 | . <(lrequire ansi) 16 | . <(lrequire basics) 17 | # TODO 0 <-- 18 | buttonize(){ 19 | local oldcolor 20 | oldcolor="$(q2 ${X[cat]} ${F[color]})" 21 | GRAYbg 22 | printf '%s' '[' 23 | case $1 in 24 | OK) GGRAYbg 25 | ;; 26 | NOK) RGRAYbg 27 | esac 28 | printf '%s' "$2" 29 | GRAYbg 30 | printf '%s' ']' 31 | ${oldcolor:-N} 32 | } 33 | 34 | button(){ 35 | case ${1,,} in 36 | not|no|q) buttonize NOK "$1" 37 | ;; 38 | *) buttonize OK "$1" 39 | esac 40 | } 41 | 42 | box(){ 43 | case ${1,,} in 44 | not|no|q) buttonize NOK " $1 " 45 | ;; 46 | *) buttonize OK " $1 " 47 | esac 48 | } 49 | 50 | # TODO 1 --> 51 | #check(){ 52 | # [[ " OK NOK " =~ " $1 " ]]||return 53 | # case $1 in 54 | # OK) buttonize OK '✔️' 55 | # ;; 56 | # NOK) buttonize NOK '✖️' 57 | # esac 58 | #} 59 | 60 | # TODO 1 <-- 61 | check(){ 62 | [[ " OK NOK " =~ " $1 " ]] || return 63 | local ok nok 64 | if ${X[grep]} -qs "webmin.service" /proc/self/cgroup; then 65 | ok='✔' nok='✘' 66 | # TODO 2 --> 67 | # ok='✓' nok='✗' 68 | # ok="+" nok="-" 69 | # TODO 2 <-- 70 | else 71 | # TODO 3 --> 72 | # ok='✅' nok='❌' 73 | # TODO 3 <-- 74 | ok='✔️' nok='✖️' 75 | fi 76 | case $1 in 77 | OK) buttonize OK "$ok" 78 | ;; 79 | NOK) buttonize NOK "$nok" 80 | esac 81 | } 82 | -------------------------------------------------------------------------------- /tools/update_appstore_platforms: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # whoami, whereami 4 | # b=basename m=me a=absolute p=path ca=canonical 5 | declare bm apm me ca_me ca_dir 6 | declare -i i 7 | bm="$(basename "$0")"; apm="$(cd "$(dirname "$0")" && pwd)/$bm" 8 | [ "$(command -v "$bm")" = "$apm" ] && me="$bm" || me="$apm" 9 | ca_me="$(readlink -e "$apm")"; ca_dir="$(dirname "$ca_me")" 10 | 11 | cd "$ca_dir/.." 12 | 13 | # source common functions 14 | source tools/common_build_functions 15 | # source LATEST_EOL: 16 | source <(${X[tail]} -n +21 modules/nc/versions | ${X[head]} -n 2) 17 | 18 | appstore_api='https://apps.nextcloud.com/api/v1' 19 | 20 | for latest in ${LATEST_EOL[@]}; do 21 | platform_dir="$ABSOLUTE_TARGET_DIR/platform/$latest" 22 | ${X[mkdir]} -p $platform_dir 23 | ${X[chown]} $HT_USER:$HT_USER $platform_dir 24 | apps_json="$platform_dir/apps.json" 25 | etag="$platform_dir/etag" 26 | appstore_url="$appstore_api/platform/$latest/apps.json" 27 | last_etag="\"$(${X[cat]} $etag 2>$NUL)\"" 28 | response="$(${X[curl]} --compressed -D - -H "If-None-Match: $last_etag" -Ls $appstore_url)" 29 | http_code="$(echo "$response" | ${X[head]} -n -1 | ${X[gawk]} 'tolower($0)~/^http\//{code=$2} END{print code}')" 30 | new_etag="$(echo "$response" | ${X[grep]} -ioPs 'etag: "\K[^"]+')" 31 | if (( http_code == 429 )); then # 429 - Too Many Requests 32 | exit 1 33 | elif (( http_code == 200 )); then 34 | echo "$response" | ${X[tail]} -n 1 > "$apps_json" 35 | echo -n "$new_etag" > $etag 36 | ${X[chown]} -R $HT_USER:$HT_USER $platform_dir 37 | occ files:scan --quiet --path="$TARGET_DIR/platform/$latest" 38 | fi 39 | ${X[sleep]} 90 40 | done 41 | exit 0 42 | -------------------------------------------------------------------------------- /modules/dos2unix: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${DOS2UNIX_BASHLIB:-_} && return 11 | DOS2UNIX_BASHLIB=: 12 | 13 | is_unix(){ 14 | local file 15 | file="$1" 16 | [ -f "$file" ] || return 1 17 | q2 ${X[file]} "$file" | ${X[grep]} -q "CRLF" && return 1 || return 0 18 | # q2 ${X[od]} -c "$file" | ${X[grep]} -qs '\\r \\n' && return 1 || return 0 19 | } 20 | 21 | dos_or_unix(){ 22 | local file 23 | file="$1" 24 | [ -f "$file" ] || return 1 25 | is_unix "$file" && echo unix || echo dos 26 | } 27 | 28 | dos_2_unix(){ 29 | local file 30 | file="$1" 31 | [[ -f "$file" && -w "$file" ]] || return 1 32 | echo "dos_2_unix: converting file $file to Unix format..." 33 | sed_ 's/\r$//' "$file" '-i' 34 | } 35 | 36 | dos2unix_bulk(){ 37 | local file 38 | for file in "$@"; do 39 | [[ -f "$file" && -w "$file" ]] || continue 40 | is_unix "$file" || ${X[dos2unix]:-dos_2_unix} "$file" 41 | done 42 | } 43 | 44 | dos2unix_recursive(){ 45 | local dir 46 | local -a files 47 | dir="${1%/}" 48 | [ -d "$dir" ] || return 1 49 | if [ -n "${X[dos2unix]}" ]; then 50 | # mapfile -t files< <(${X[find]} "$dir/" -type f -exec ${X[dos2unix]} -id {} \; | ${X[gawk]} '$1 != 0 { print $2 }') 51 | mapfile -d $'\0' -t files< <( 52 | ${X[find]} "$dir/" -type f -print0 | \ 53 | ${X[xargs]} -0 ${X[dos2unix]} -id | \ 54 | ${X[gawk]} '$1 != 0 { printf "%s\0", $2 }' 55 | ) 56 | else 57 | mapfile -d $'\0' -t files< <(${X[find]} "$dir/" -type f -print0) 58 | fi 59 | dos2unix_bulk "${files[@]}" 60 | } 61 | -------------------------------------------------------------------------------- /modules/nc/aio: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${NC_AIO_BASHLIB:-_} && return 11 | NC_AIO_BASHLIB=: 12 | 13 | . <(lrequire binaries) 14 | 15 | B[aio]=_ B[docker]=_ 16 | 17 | aio_not_supported(){ 18 | ${B[aio]} || return 0 19 | f; pf; R; echo "This script cannot be used with Nextcloud All-in-One …" 20 | exit1 21 | } 22 | 23 | detect_aio(){ 24 | local docker_ps_json 25 | docker_ps_json="$(tf)" 26 | local -a docker_names 27 | docker_names=() 28 | # detect if any docker containers are running on the host (without -a, because only running containers matter here) 29 | q2 ${X[docker]} ps --no-trunc --format=json > $docker_ps_json || : 30 | mapfile -t docker_names < <(q2 ${X[jq]} -r .Names $docker_ps_json) 31 | if (( ${#docker_names[@]} )); then 32 | if [[ "${docker_names[@]}" =~ nextcloud-aio-mastercontainer && "${docker_names[@]}" =~ nextcloud-aio-nextcloud ]]; then 33 | B[aio]=: B[docker]=: 34 | fi 35 | fi 36 | } 37 | 38 | aio_wrapper(){ 39 | local interactive_tty container_name 40 | if [ "$1" = '-it' ]; then 41 | interactive_tty='-it' 42 | shift 43 | else 44 | interactive_tty='' 45 | fi 46 | container_name="$1" 47 | shift 48 | [[ -v X[docker] && -n ${X[docker]:-} ]] && ${X[sudo]} ${X[docker]} exec $interactive_tty "nextcloud-aio-$container_name" bash -c "$*" || : 49 | } 50 | 51 | if [[ -v X[docker] && -n ${X[docker]} ]]; then 52 | if ${B[rt]}; then 53 | detect_aio 54 | elif ${X[ps]} aux | ${X[grep]} -qs "[d]ockerd"; then # dockerd is running 55 | su_root "to detect all-in-one" 56 | fi 57 | fi 58 | -------------------------------------------------------------------------------- /modules/sysinf.d/dpkg: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SYSINF_DPKG_BASHLIB:-_} && return 11 | SYSINF_DPKG_BASHLIB=: 12 | 13 | sysinf_dpkg(){ 14 | local -A bool 15 | while (( $# )); do 16 | [[ $1 ]] && bool[$1]=: 17 | shift 18 | done 19 | # dpkg (debian) based like architecture apt sources 20 | ${bool[sury]:-_} && bool[sources]=: 21 | ${bool[sources]:-_} && bool[dpkg]=: 22 | if ${bool[dpkg]:-_} && [ -n "${X[dpkg]}" ]; then 23 | ${bool[spinner]} && { 24 | kill_spinner 25 | spinner Yi " . determine system informations - dpkg ." & 26 | } 27 | local -a aptgetversion foreign_architectures 28 | if dpkg_version="$(q2 ${X[dpkg]} --robot --version)"; then 29 | SYSINF+=("echo dpkg --robot --version: $dpkg_version") 30 | else 31 | dpkg_version="$(q2 ${X[dpkg]} --version | ${X[grep]} -oP '\d+(\.\d+){1,3} \(\S+\)')" 32 | [ -z "$dpkg_version" ] || SYSINF+=("echo dpkg --version: $dpkg_version") 33 | fi 34 | SYSINF+=("echo dpkg --print-architecture: $(${X[dpkg]} --print-architecture)") 35 | mapfile -t foreign_architectures< <(${X[dpkg]} --print-foreign-architectures) 36 | (( ${#foreign_architectures[@]} )) && SYSINF+=("echo dpkg --print-foreign-architectures: ${foreign_architectures[@]}") 37 | SYSINF+=("echo apt --version: $(${X[apt]} -v)") 38 | # SYSINF+=("apt-get --version") 39 | # TODO 0 --> 40 | 41 | local -a dpkg_locks 42 | mapfile -t dpkg_locks< <(check_lockfiles -v) 43 | if (( ${#dpkg_locks[@]} )); then 44 | for i in ${!dpkg_locks[@]}; do mh "dpkg lockfiles $((i+1)): ${dpkg_locks[i]}"; done 45 | fi 46 | # TODO 0 <-- 47 | fi 48 | } 49 | -------------------------------------------------------------------------------- /modules/nc-apps/github_api: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${GITHUB_API_BASHLIB:-_} && return 11 | GITHUB_API_BASHLIB=: 12 | 13 | github_api(){ 14 | local URL="https://api.github.com/repos/$1/$2?per_page=$3" 15 | log_trace "$URL" 16 | case $2 in 17 | tags) ${X[curl]} -s "$URL" | ${X[jq]} -r '.[] | .name' | ${X[sed]} 's/^v//' | ${X[grep]} "^[0-9]\{1,2\}\.[0-9]\.[0-9]" # | ${X[grep]} -iv a 18 | ;; 19 | releases) ${X[curl]} -s "$URL" | ${X[jq]} -r '.[] | .tag_name' | ${X[sed]} 's/^v//' | ${X[grep]} "^[0-9]\{1,2\}\.[0-9]\.[0-9]" # | ${X[grep]} -iv a 20 | esac 21 | } 22 | 23 | list_latest(){ 24 | local version key # $1=prefix 25 | local -a versions=(${LATEST_EOL[@]} $(github_api "nextcloud/server" "tags" "90")) parts latest_parts 26 | local -A latest_versions 27 | for version in "${versions[@]}"; do 28 | parts=(${version//./ }) 29 | key="${parts[0]}.${parts[1]}" 30 | if [ "$key" = "${NC[key]}" ]; then 31 | if [ -z "${latest_versions["$key"]}" ]; then 32 | latest_versions["$key"]=${NC[version_tag]} 33 | fi 34 | elif [ -z "${latest_versions[$key]}" ]; then 35 | latest_versions["$key"]=$version 36 | else 37 | latest_parts=(${latest_versions[$key]//./ }) 38 | if (( ${parts[2]/[a-zA-Z]*/} > ${latest_parts[2]/[a-zA-Z]*/} )); then 39 | latest_versions["$key"]=$version 40 | elif (( ${parts[2]/[a-zA-Z]*/} == ${latest_parts[2]/[a-zA-Z]*/} )) && [[ ${parts[2],,}z > ${latest_parts[2],,}z ]]; then 41 | latest_versions["$key"]=$version 42 | fi 43 | fi 44 | done 45 | for key in "${!latest_versions[@]}"; do 46 | echo "v${latest_versions[$key]//z/}" 47 | done 48 | } 49 | -------------------------------------------------------------------------------- /modules/php-module-builder/data_refine: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${DATA_REFINE_BASHLIB:-_} && return 11 | DATA_REFINE_BASHLIB=: 12 | 13 | # p=PHP, v=Version, m=Module, d=Dir, trailing s=plural 14 | find_built_modules(){ 15 | local pv pvd m 16 | local -a pvs=($(q2 ${X[ls]} "$project_dir/$project")) 17 | for pv in "${pvs[@]}"; do 18 | pvd="$project_dir/$project/$pv" 19 | if [ -d "$pvd" ]; then 20 | local -a ms=($(${X[ls]} "$pvd")) 21 | for m in "${ms[@]}"; do 22 | echo "$pv $m" 23 | done 24 | fi 25 | done 26 | } 27 | 28 | # p=PHP, v=Version, m=Module, d=Dir, trailing s=plural 29 | find_built_module_versions(){ 30 | local pv pvd m mv mvd 31 | local -a pvs=($(q2 ${X[ls]} "$project_dir/$project")) 32 | for pv in "${pvs[@]}"; do 33 | pvd="$project_dir/$project/$pv" 34 | if [ -d "$pvd" ];then 35 | local -a ms=($(${X[ls]} "$pvd")) 36 | for m in "${ms[@]}"; do 37 | mvd="$pvd/$m" 38 | if [ -d "$mvd" ]; then 39 | local -a mvs=($(${X[ls]} -d "$mvd"/*)) 40 | for mv in "${mvs[@]}"; do 41 | [ -d "$mv" ] && { mv="${mv%/}"; echo "$pv ${mv##*/}";} 42 | done 43 | fi 44 | done 45 | fi 46 | done 47 | } 48 | 49 | check_conflicts(){ 50 | declare m conflict="$@" conflicts 51 | for m in $conflict; do 52 | [[ " $installed_modules " =~ " $m " ]] && conflicts="$conflicts $m" 53 | done 54 | if [ -n "$conflicts" ]; then 55 | R; echo "- $module conflicts with$conflicts. Remove conflicting modules first.";N 56 | cd 57 | ${X[rmdir]} $project_dir/$project/$php_version/$module 58 | exit 1 59 | fi 60 | } 61 | -------------------------------------------------------------------------------- /modules/nc-shares/help: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | 11 | ${HELP_BASHLIB:-_} && return 12 | HELP_BASHLIB=: 13 | 14 | function print_help(){ 15 | #. <(require nc-shares/disclaimer) 16 | #disclaimer 17 | 18 | ${X[cat]} < [test]" 8 | exit 1 9 | fi 10 | 11 | # Ensure that the first argument is an existing file 12 | if ! [ -f "$1" ]; then 13 | echo "\"$1\" does not exist" 14 | echo "Usage: $0 " 15 | exit 1 16 | fi 17 | 18 | # whoami, whereami 19 | # b=basename m=me a=absolute p=path ca=canonical 20 | declare bm apm me ca_me ca_dir 21 | declare -i i 22 | bm="$(basename "$0")"; apm="$(cd "$(dirname "$0")" && pwd)/$bm" 23 | [ "$(command -v "$bm")" = "$apm" ] && me="$bm" || me="$apm" 24 | ca_me="$(readlink -e "$apm")"; ca_dir="$(dirname "$ca_me")" 25 | 26 | cd "$ca_dir/.." 27 | 28 | # source common functions 29 | source tools/common_build_functions 30 | # Source the time 31 | source config/runtime 32 | 33 | # Declare variables 34 | declare input_script output_script channel scriptname tempfile placeholder placeholder_pattern 35 | # Assign the arguments to variables 36 | input_script="$1" output_script="$2" channel="${3:-prod}" 37 | tempfile="$(${X[mktemp]})" 38 | 39 | if [ "$channel" = 'test' ]; then 40 | scriptname="$(${X[basename]} $input_script)-test" 41 | else 42 | scriptname="$(${X[basename]} $input_script)" 43 | fi 44 | 45 | # cat the input module into the tempfile 46 | ${X[cat]} "$input_script" > "$tempfile" 47 | strip_ "$tempfile" 48 | replace_placeholders_ "$tempfile" "$output_script" "$scriptname" $epoch "$channel" 49 | ${X[rm]} -f "$tempfile" 50 | 51 | # minify modules array 52 | $MINIFY && ${X[sed]} -i '/^modules=(/ { 53 | :a; N; /)/!ba; 54 | s/\n[[:space:]]*/ /g; 55 | s/( */(/; 56 | s/ *)/)/; 57 | s/[[:space:]]*#/\n#/ 58 | }' "$output_script" 59 | 60 | # disable integrity check for local server 61 | $LOCAL_SERVER && echo -e "v=true\nnohash" >> "$output_script" 62 | 63 | exit 0 64 | -------------------------------------------------------------------------------- /modules/php-module-builder/ini: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${INI_BASHLIB:-_} && return 11 | INI_BASHLIB=: 12 | 13 | . <(lrequire php/extensions) 14 | 15 | ini_symlinks(){ 16 | local sapi 17 | if ${B[remove]}; then 18 | ${B[quiet]} || { f; GRAY; echo "- next step: $(B)phpdismod -prv $php_version -s ALL $module"; } 19 | ${B[step]:-_} && anykey 20 | o2; B; echo "phpdismod -prv $php_version -s ALL $module"; N 21 | q2 ${X[phpdismod]} -prv $php_version -s ALL $module 22 | else 23 | f; GRAY; echo "- next step: $(B)phpenmod -rv $php_version -s ALL $module" 24 | ${B[step]:-_} && anykey 25 | ${X[phpenmod]} -rv $php_version -s ALL $module 26 | f 27 | GRAY; echo "- result:" 28 | for sapi in $(${X[phpquery]} -v $php_version -S); do 29 | o2; lG; ${X[phpquery]} -v $php_version -s $sapi -m $module 30 | done 31 | N 32 | f 33 | fi 34 | } 35 | 36 | module_ini(){ 37 | if ${B[remove]}; then 38 | ini_symlinks 39 | ${B[quiet]} || { f; GRAY; echo "- next step: $(B)module_ini (remove):"; } 40 | ${B[step]:-_} && anykey 41 | o2; B; echo "rm \"$ini_dir/$module.ini\""; N 42 | cleanup "$ini_dir/$module.ini" 43 | else 44 | f 45 | GRAY; echo "- next step: $(B)module_ini (create):" 46 | ${B[step]:-_} && anykey 47 | ini_file+=("; priority = $priority") 48 | for directive in $(extension_ini_case $module); do 49 | ini_file+=("$directive") 50 | done 51 | C; echo "(" 52 | for i in ${!ini_file[@]}; do 53 | echo "${ini_file[i]}" 54 | done 55 | echo ") > $ini_dir/$module.ini"; N 56 | (for i in ${!ini_file[@]}; do 57 | echo "${ini_file[i]}" 58 | done) > $ini_dir/$module.ini 59 | ini_symlinks 60 | fi 61 | } 62 | -------------------------------------------------------------------------------- /scripts/nc-sql: -------------------------------------------------------------------------------- 1 | __shebang_bash__ 2 | __path_and_scriptname__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | __whoami_whereami__ 11 | __scriptname__ 12 | __homedir__ 13 | __vdirname__ NC_DIR 14 | modules=(fstring httpd nc/nextcloud nc/db) 15 | __debug__ 16 | __when__ 17 | __tempdir__ 18 | __module_server__ 19 | __general__ 20 | __module_loader__ 21 | __module_integrity__ 22 | __nextcloud_updater__ 23 | 24 | 25 | contribute_(){ 26 | . <(require contribute) 27 | contribute "https://help.nextcloud.com/t/script-nc-sql-zero-config-commandline-client-for-the-nextcloud-database/195088" 28 | }; donate_(){ contribute_;} 29 | [[ "$@" =~ (donat|contrib) ]] && contribute_ 30 | 31 | help(){ 32 | ${X[cat]} << HELP 33 | 34 | $ME [ --raw [ --execute "query;" ] ] 35 | 36 | $ME 37 | open sql cli-client in interactive mode 38 | --raw, -r raw output 39 | --execute,-e "query;" 40 | run a query and exit 41 | --firstrun re-run the first run wizard 42 | 43 | HELP 44 | exit 0 45 | } 46 | 47 | # first search for options --raw, -r, --execute, -e and remove from @() array 48 | # and then add the remaining arguments into the new array 49 | bools=(raw execute) 50 | for x in ${bools[@]}; do B[$x]=_; done 51 | 52 | for x in "$@"; do 53 | case "$x" in 54 | --help|-h) 55 | help 56 | ;; 57 | --raw|-r) 58 | B[raw]=: 59 | ;; 60 | --execute|-e) 61 | B[execute]=: 62 | ;; 63 | *) args+=("$x") 64 | esac 65 | done 66 | set -- "${args[@]}" 67 | 68 | if ${B[aio]} && [ -n "${X[psql]}" ]; then 69 | B[docker]=false 70 | fi 71 | 72 | if ${B[execute]}; then 73 | if ${B[raw]}; then 74 | db_raw_exec_ "$*" 75 | else 76 | db_exec_ "$*" 77 | fi 78 | else 79 | if ${B[raw]}; then 80 | db_raw_interactive 81 | else 82 | db_interactive 83 | fi 84 | fi 85 | 86 | exit0 87 | 88 | -------------------------------------------------------------------------------- /modules/nc/versions: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${NC_VERSIONS_BASHLIB:-_} && return 11 | NC_VERSIONS_BASHLIB=: 12 | 13 | . <(lrequire php/version) 14 | . <(require nc/aio) 15 | . <(require nc/c2j) 16 | . <(require nc/nextcloud) 17 | 18 | [ -f "${F[nc]:=${D[vt]}/nc}" ] && . ${F[nc]} 19 | 20 | # array with latest versions from end of life platforms 21 | declare -ga LATEST_EOL 2>$NUL || declare -a LATEST_EOL # this lines are sourced by tools scripts. Keep at this location 22 | LATEST_EOL=(11.0.8 12.0.13 13.0.12 14.0.14 15.0.14 16.0.11 17.0.10 18.0.14 19.0.13 20.0.14 21.0.9 22.2.10 23.0.12 24.0.12 25.0.13 26.0.13 27.1.11 28.0.14 29.0.16 30.0.17) 23 | 24 | nc_version_(){ 25 | local version_php 26 | version_php="$2" 27 | case "$1" in 28 | long) ${X[gawk]} -F'[][ ,()]+' '/\$OC_Version =/{if($3=="array"){print $4"."$5"."$6"."$7}else{print $3"."$4"."$5"."$6}}' "$version_php" 29 | ;; 30 | short) ${X[gawk]} -F'[][ ,()]+' '/\$OC_Version =/{if($3=="array"){print $4"."$5"."$6}else{print $3"."$4"."$5}}' "$version_php" 31 | ;; 32 | key) ${X[gawk]} -F'[][ ,()]+' '/\$OC_Version =/{if($3=="array"){print $4"."$5}else{print $3"."$4}}' "$version_php" 33 | ;; 34 | string) ${X[gawk]} -F\' '/\$OC_VersionString =/{print $2}' "$version_php" 35 | ;; 36 | tag) ${X[gawk]} -F\' '/\$OC_VersionString/{gsub(/ /,"");$2=tolower($2);print $2}' "$version_php" 37 | esac 38 | } 39 | 40 | NC[version_long]="$(nc_version_ long "${NC[vphp]}")" 41 | NC[version]="$(nc_version_ short "${NC[vphp]}")" 42 | NC[key]="$(nc_version_ key "${NC[vphp]}")" 43 | NC[version_string]="$(nc_version_ string "${NC[vphp]}")" 44 | #NC[version_tag]="$(tolower "${NC[version_string]// /}")" 45 | NC[version_tag]="$(nc_version_ tag "${NC[vphp]}")" 46 | NC[min_version]="${LATEST_EOL[0]}" 47 | 48 | declare -p NC > "${F[nc]}" 49 | ${B[rt]} && ${X[chown]} 0:0 "${F[nc]}" 50 | ${X[chmod]} 666 "${F[nc]}" 51 | 52 | -------------------------------------------------------------------------------- /modules/nc/c2j: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${NC_C2J_BASHLIB:-_} && return 11 | NC_C2J_BASHLIB=: 12 | 13 | declare config_json 14 | 15 | c2j_jq_filter(){ 16 | # TODO 1 --> 17 | # as oneliner: 18 | # ${X[jq]} -c '[.[]|.[]]|map(. as $item|{($item.key):{key:$item.key,value:$item.value}})|reduce .[]as $item({};. * $item)' 19 | # TODO 1 <-- 20 | ${X[jq]} -c '[.[] | .[]] 21 | | map(. as $item | {($item.key): {key: $item.key, value: $item.value}}) 22 | | reduce .[]as $item({};. * $item)' 2> >(log_trace) 23 | } 24 | 25 | config2json(){ 26 | [ -f "${F[nc]:=${D[vt]}/nc}" ] && . ${F[nc]} 27 | local cdir C2J 28 | [[ -d ${1:-} ]] && cdir="$1" || cdir=${NC[cd]} 29 | # TODO 2 --> 30 | # as oneliner: 31 | # C2J='$v){$c[$f][]=["key"=>$k,"value"=>$v];}}};echo json_encode($c);' 32 | # TODO 2 <-- 33 | C2J=' $v) { 39 | $c[$f][] = ["key" => $k, "value" => $v]; 40 | } 41 | } 42 | } 43 | echo json_encode($c); 44 | ?>' 45 | if nonullglob "$cdir/*\.config.php"; then 46 | echo "$C2J" | ${X[php]} -- $cdir/config.php $cdir/*.config.php | c2j_jq_filter 47 | else 48 | echo "$C2J" | ${X[php]} -- $cdir/config.php | c2j_jq_filter 49 | fi 50 | } 51 | 52 | c2j(){ 53 | config2json "$@" | ${X[gzip]} 2>&1 | ${X[base64]} -w 0 54 | } 55 | 56 | nc_configkey(){ 57 | if [[ -z ${config_json:-} ]]; then 58 | config_json="$(config2json 2> >(log_trace))" 59 | ${X[jq]} -r ".[\"$1\"].value" <<< "$config_json" 2> >(log_trace) 60 | fi 61 | } 62 | 63 | nc_configkey_exist_(){ 64 | [ -f "${F[nc]:=${D[vt]}/nc}" ] && . ${F[nc]} 65 | ${X[grep]} -qsw "$1" ${NC[cd]}/*config.php 66 | # return $? 67 | } 68 | -------------------------------------------------------------------------------- /blocks/whoami_whereami: -------------------------------------------------------------------------------- 1 | # set -euo pipefail 2 | # hide the cursor 3 | [[ $* == *-q* ]] || printf '\e[?25l' 4 | # and the trap to bring it back if the script is interupted 5 | trap "printf '\e[?25h'" 0 6 | declare A CMA MD ME MP MS NUL=/dev/null REQ TTY=/dev/tty x 7 | declare -a modules tdc bools args tntd jnr 8 | # associative arrays: B = bools, C = commands, D = dirs, F = files, I = user/group, J = json, M = me, T = time, V = vars 9 | declare -A B C D F I J M T V 10 | declare -n TD=TMPDIR 11 | _(){ 12 | return 1 13 | } 14 | __(){ 15 | echo -e "\n\e[31mERROR: $1\e[0m\n" >&2 16 | exit 1 17 | } 18 | dbg(){ 19 | : 20 | } 21 | di(){ 22 | : 23 | } 24 | C[e]=$(command -v env) 25 | for x in a:gawk b:basename c:cat cm:chmod co:chown cu:curl d:dirname fi:find f:flock g:grep h:head id jq md:mkdir mt:mktemp mv p:ps rp:realpath r:rm s:stat u:uname; do 26 | [ -x $(command -v ${x#*:}) ] && C[${x%:*}]="${C[e]} LC_MESSAGES=C $(command -v ${x#*:})" || __ "'${x#*:}' binary not found." 27 | done 28 | # mkdir -p 29 | C[md]+=" -p" 30 | # mkdir -pm 777 (make world-open) 31 | C[mw]="${C[md]}m 777" 32 | # mkdir -pm 1777 (make sticky) 33 | C[ms]="${C[md]}m 1777" 34 | # rm fr (remove recursive) 35 | C[rr]="${C[r]} -fr --" 36 | # rm -f (remove file) 37 | C[r]+=" -f --" 38 | # chmod -f 39 | C[cm]+=" -f" 40 | # chmod -f +t (change mode sticky) 41 | C[cms]="${C[cm]} +t" 42 | # chown -R (change owner recursive) 43 | C[co]+=" -R" 44 | A="$(${C[u]} -srvmpio)" 45 | for x in u un g gn G Gn; do I[$x]="$(${C[id]} -$x)"; done 46 | (( ${I[u]} )) && { 47 | B[rt]=_ 48 | if [ ${I[un]} = www-data ]; then 49 | I[l]=www-data 50 | elif [[ "${I[Gn]} " =~ " sudo " ]]; then 51 | I[l]=sudo_user 52 | else 53 | I[l]=unprivileged_user 54 | fi 55 | } || B[rt]=: I[l]=root 56 | readonly I 57 | # b=basename m=me a=absolute p=path ca=canonical n=name s=sin c=channel 58 | M[ap]="$(cd "$(${C[d]} "$0")" && pwd)/${M[b]:=$(${C[b]} "$0")}" 59 | [[ $(command -v ${M[b]}) == ${M[ap]} ]] && ME=${M[b]} || ME="${M[ap]}" 60 | MP=$(${C[rp]} ${M[ap]}) MD=$(${C[d]} $MP) 61 | -------------------------------------------------------------------------------- /modules/interval: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${INTERVAL_BASHLIB:-_} && return 11 | INTERVAL_BASHLIB=: 12 | 13 | # TODO 0 --> 14 | . <(lrequire binaries) 15 | # TODO 0 <-- 16 | . <(lrequire today) 17 | 18 | # d=Date n=Newer o=Older f=Formated ut=UnixTime t=Today iy=IntervalYears im=IntervalMonths id=IntervalDays m=Month y=Year 19 | interval(){ 20 | require_arg $@ 21 | local until since years months and n_d_f o_d_f 22 | local -i ut_1 ut_2 n_d o_d n_y n_m n_day o_y o_m o_day iy im id 23 | ut_1=$1 ut_2=${2:-$today} years=' year' months=' month' and=' and ' 24 | (( ut_1 > ut_2 )) && n_d=$ut_1 o_d=$ut_2 || n_d=$ut_2 o_d=$ut_1 25 | (( n_d == today )) && since=" ago" 26 | (( o_d == today )) && until="in " 27 | n_d_f=$(${X[date]} -ud @$n_d +%Y-%-m-%-d) 28 | o_d_f=$(${X[date]} -ud @$o_d +%Y-%-m-%-d) 29 | read -r n_y n_m n_day <<< ${n_d_f//-/ } 30 | read -r o_y o_m o_day <<< ${o_d_f//-/ } 31 | iy=$((n_y-o_y)) im=$((n_m-o_m)) id=$((n_day-o_day)) 32 | (( id < 0 )) && (( im-- )) 33 | (( im < 0 )) && { 34 | ((iy--)) 35 | ((im+=12)) 36 | } 37 | (( iy == 1 )) || years=" years" 38 | (( im == 1 )) || months=" months" 39 | if (( iy > 0 || im > 0 )); then 40 | (( im )) || unset and im months 41 | (( iy )) || unset and iy years 42 | echo "${until:-}${iy:-}${years:-}${and:-}${im:-}${months:-}${since:-}" 43 | else 44 | echo "${until:-}less than 1${months:-}${since:-}" 45 | fi 46 | } 47 | 48 | # from seconds to human readable 49 | sec2hr(){ 50 | require_arg $@ 51 | local outstring 52 | local -i seconds minutes hours days 53 | seconds=${1%.*} 54 | days=$((seconds / 86400)) 55 | (( days ))&&outstring="$days days" 56 | hours=$((seconds / 3600 % 24)) 57 | (( hours ))&&outstring="$outstring, $hours hours" 58 | minutes=$((seconds / 60 % 60)) 59 | outstring="$outstring and $minutes minutes" 60 | echo "$outstring" 61 | } 62 | -------------------------------------------------------------------------------- /tools/build_module: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | # Ensure we have the correct number of arguments 6 | if [[ "$#" -lt 2 ]]; then 7 | echo "Usage: $0 " 8 | exit 1 9 | fi 10 | 11 | # Ensure that the first argument is an existing file 12 | if ! [ -f "$1" ]; then 13 | echo "\"$1\" does not exist" 14 | echo "Usage: $0 " 15 | exit 1 16 | fi 17 | 18 | # whoami, whereami 19 | # b=basename m=me a=absolute p=path ca=canonical 20 | declare bm apm me ca_me ca_dir 21 | bm="$(basename "$0")"; apm="$(cd "$(dirname "$0")" && pwd)/$bm" 22 | [ "$(command -v "$bm")" = "$apm" ] && me="$bm" || me="$apm" 23 | ca_me="$(readlink -e "$apm")"; ca_dir="$(dirname "$ca_me")" 24 | 25 | cd "$ca_dir/.." 26 | 27 | # source common functions 28 | source tools/common_build_functions 29 | # Source the time 30 | source config/runtime 31 | 32 | # Declare variables 33 | declare input_module output_module modulename tempfile placeholder placeholder_pattern 34 | declare -i i 35 | # Assign the arguments to variables 36 | input_module="$1" output_module="$2" 37 | modulename="${input_module#$MODULES/}" 38 | tempfile=$(${X[mktemp]}) 39 | 40 | if [ -n "$EXCLUDE_SUFIXES" ]; then 41 | exclude_regex="${EXCLUDE_SUFIXES// /|}" 42 | # if [[ "$modulename" =~ (${exclude_regex//./\\.}) ]]; then 43 | if echo "$modulename" | ${X[grep]} -Eiqsw "^.*(${exclude_regex//./\\.})$"; then 44 | echo "* == skiping '$modulename' because of excluded sufix" 45 | exit 0 46 | fi 47 | fi 48 | 49 | # cat the input module into the tempfile 50 | ${X[cat]} "$input_module" > "$tempfile" 51 | strip_ "$tempfile" 52 | if [[ ${MINIFY:-false} && "$(${X[head]} -n1 "$input_module")" == '__minified_bashlib__' ]]; then 53 | ( echo "# BASHLIB (minified)" 54 | echo "# @channel@/$modulename" 55 | echo "# version $epoch" 56 | minify "$tempfile" 10 57 | ) > "$output_module" 58 | else 59 | replace_placeholders_ "$tempfile" "$output_module" "$modulename" $epoch 60 | fi 61 | ${X[rm]} -f "$tempfile" 62 | 63 | exit 0 64 | 65 | -------------------------------------------------------------------------------- /modules/nc-who/last: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${LAST_BASHLIB:-_} && return 11 | LAST_BASHLIB=: 12 | 13 | . <(lrequire nc/nextcloud_db) 14 | 15 | nc_last(){ 16 | q0 database_call 17 | local query 18 | 19 | group_query(){ 20 | case ${DB[type]} in 21 | my) echo " 22 | SELECT $1.uid, 23 | COALESCE(${DB[u2t]}(CAST(p.configvalue AS integer)), 'never') AS last_login 24 | FROM ${DB[pref]}$1 $1 25 | LEFT JOIN ${DB[pref]}preferences p ON $1.uid = p.userid AND p.appid = 'login'" 26 | ;; 27 | pg) echo " 28 | SELECT $1.uid, 29 | CASE WHEN p.configvalue = 'never' THEN NULL 30 | ELSE ${DB[u2t]}(CAST(p.configvalue AS integer)) 31 | END AS last_login 32 | FROM ${DB[pref]}$1 $1 33 | LEFT JOIN ${DB[pref]}preferences p ON $1.uid = p.userid AND p.appid = 'login'" 34 | esac 35 | } 36 | 37 | if is_app_enabled guests; then 38 | query=" 39 | SELECT uid, last_login 40 | FROM ($(group_query users) 41 | UNION ALL$(group_query guests_users) 42 | ) combined 43 | ORDER BY 44 | CASE WHEN last_login = 'never' THEN 1 ELSE 0 END, last_login DESC" 45 | else 46 | query="$(group_query users) 47 | ORDER BY 48 | CASE WHEN p.configvalue IS NULL THEN 1 ELSE 0 END, p.configvalue DESC" 49 | fi 50 | if ${B[trace]:-_}; then 51 | echo "==TRACE=start=" >$TTY 52 | print_funcname >$TTY 53 | echo -n "global bool values -" >$TTY 54 | local iter 55 | for iter in ${!B[@]}; do echo -n " $iter=${B[$iter]}" >$TTY; done; echo >$TTY 56 | unset -v iter 57 | echo "Database Backend: ${DB[type]}sql" >$TTY 58 | echo "==TRACE=end===" >$TTY 59 | echo "----------" >$TTY 60 | echo "SQL QUERY:" >$TTY 61 | echo "----------$query;" >$TTY 62 | echo "----------" >$TTY 63 | else 64 | db_exec_ "$query" 65 | fi 66 | } 67 | -------------------------------------------------------------------------------- /modules/array: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${ARRAY_BASHLIB:-_} && return 11 | ARRAY_BASHLIB=: 12 | 13 | declare IFS_="$IFS" 14 | 15 | # get array_fld: $1=name_of_array $2=FS $3=key $4=field_nr: 16 | a_fld(){ 17 | required_args 4 $@ 18 | local -n a=$1 19 | local -i ai=$4 20 | local -a f 21 | for o in "${a[@]}"; do 22 | IFS=$2 23 | read -ra f<<<"$o" 24 | [[ "${f[0]}" == "$3" ]] && echo "${f[ai-1]}" 25 | done 26 | IFS="$IFS_" 27 | } 28 | 29 | # get Associative array_fld: $1=name_of_array $2=FS $3=key $4=field_nr: 30 | A_fld(){ 31 | required_args 4 $@ 32 | local -n a=$1 33 | local -i ai=$4 34 | local -a f 35 | IFS=$2 36 | read -ra f<<<"${a["$3"]}" 37 | echo "${f[ai-1]}" 38 | IFS="$IFS_" 39 | } 40 | # COMMENT --> 41 | 42 | ## get array_fld: $1=name_of_array $2=FS $3=key $4=field_nr: 43 | #a_fld(){ 44 | # local an=$1 45 | # if q0 declare -p $an; then 46 | # [[ ${!1} ]] && an="${!1}" || an="$1" 47 | # if [[ "$(declare -p $an)" =~ 'declare -A' || "$(declare -p $an)" =~ 'local -A' ]]; then 48 | # A_fld "$an" "$2" "$3" "$(($4 - 1))" 49 | # elif [[ "$(declare -p $an)" =~ 'declare -a' || "$(declare -p $an)" =~ 'local -a' ]]; then 50 | # a_fld "$an" "$2" "$3" "$4" 51 | # else 52 | # something_went_wrong "$1 is not an array" 53 | # fi 54 | # else 55 | # a_fld "$an" "$2" "$3" "$4" 56 | # fi 57 | #} 58 | 59 | ## get Associative array_fld: $1=name_of_array $2=FS $3=key $4=field_nr: 60 | #A_fld(){ 61 | # local an=$1 62 | # if q0 declare -p $an; then 63 | # [[ ${!1} ]] && an="${!1}" || an="$1" 64 | # if [[ "$(declare -p $an)" =~ 'declare -a' || "$(declare -p $an)" =~ 'local -a' ]]; then 65 | # a_fld "$an" "$2" "$3" "$(($4 + 1))" 66 | # elif [[ "$(declare -p $an)" =~ 'declare -A' || "$(declare -p $an)" =~ 'local -A' ]]; then 67 | # A_fld "$an" "$2" "$3" "$4" 68 | # else 69 | # something_went_wrong "$1 is not an array" 70 | # fi 71 | # else 72 | # A_fld "$an" "$2" "$3" "$4" 73 | # fi 74 | #} 75 | -------------------------------------------------------------------------------- /modules/anykey: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${ANYKEY_BASHLIB:-_} && return 11 | ANYKEY_BASHLIB=: 12 | : ${NUL:=/dev/null} 13 | 14 | anykey(){ 15 | local p aim 16 | local -l choice 17 | aim="${1:-continue}" 18 | ${B[trace]:-_} && aim="$aim - $(fn_ln 1)" || : 19 | if ${ANSI_BASHLIB:-_} && ${BUTTON_BASHLIB:-_} && ${EXIT_BASHLIB:-_}; then 20 | local -l cursor_status 21 | cursor_status='show' 22 | if [ -f "${F[cursor]:-}" ]; then 23 | if ${X[grep]} -qsw 'hide' "${F[cursor]}"; then 24 | cursor_status='hide' 25 | fi 26 | fi 27 | p="Press $(lG)any key$(N) to $aim$(GRAY) or $(q2q;N)" 28 | kill_spinner &>$NUL 29 | cursor_ hide 30 | read -rsn 1 -p "$p" choice 31 | cursor_ $cursor_status 32 | if [ "$choice" = "q" ]; then 33 | f 34 | exit0 35 | else 36 | te1 37 | fi 38 | else 39 | unset ANYKEY_BASHLIB 40 | p="Press any key to continue or 'q' to quit " 41 | kill_spinner &>$NUL 42 | read -rsn 1 -p "$p" choice 43 | if [ "$choice" = "q" ]; then 44 | echo 45 | exit 46 | else 47 | echo 48 | fi 49 | fi 50 | } 51 | 52 | anykey_noquit(){ 53 | local p aim dummy 54 | aim="${1:-continue}" 55 | ${B[trace]:-_} && aim="$aim - $(fn_ln 1)" || : 56 | if ${ANSI_BASHLIB:-_} && ${BUTTON_BASHLIB:-_} && ${EXIT_BASHLIB:-_}; then 57 | local -l cursor_status 58 | cursor_status='show' 59 | if [ -f "${F[cursor]}" ]; then 60 | if ${X[grep]} -qsw 'hide' "${F[cursor]}"; then 61 | cursor_status='hide' 62 | fi 63 | fi 64 | p="Press $(lG)any key$(N) to $aim " 65 | cursor_ hide 66 | kill_spinner &>$NUL 67 | read -rsn 1 -p "$p" dummy 68 | cursor_ $cursor_status 69 | te1 70 | else 71 | unset ANYKEY_BASHLIB 72 | kill_spinner &>$NUL 73 | p="Press any key to continue " 74 | read -rsn 1 -p "$p" dummy 75 | echo 76 | fi 77 | } 78 | -------------------------------------------------------------------------------- /modules/nc/logo: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${NC_LOGO_BASHLIB:-_} && return 11 | NC_LOGO_BASHLIB=: 12 | 13 | nextcloud_logo(){ 14 | ${X[cat]} << NEXTCLOUDLOGO 15 | 16 | $(line ' ' NCbluebg 84 a0) 17 | $(line ' ' NCbluebg 84 a0) 18 | $(NCbluebg) ,cWNXXXXNNNo, $(N) 19 | $(NCbluebg) .NKOkxdddddddddxk0Xk $(N) 20 | $(NCbluebg) X0xddddddddddddddddddxkKc $(N) 21 | $(NCbluebg) ,sHNNNNWln, OOddddddddddddddddddddddddxK, .WNNNNW; $(N) 22 | $(NCbluebg) XKOxddddddxk0Xl .0xddddddo° °dddddddxk .N0kxddddddxk0X; $(N) 23 | $(NCbluebg) Kkddddddddddddddx0c 'kddddddc .ddddddxk XkddddddddddddddxK, $(N) 24 | $(NCbluebg) 'OddddddddddddddddddxOOdddddd. odddddxKOddddddddddddddddddxd $(N) 25 | $(NCbluebg) Odddddd;' 'ddddddddddddd; ddddddddddddd' 'ddddddx: $(N) 26 | $(NCbluebg) ;dddddd; dddddddddddd. cddddddddddd' .ddddddd $(N) 27 | $(NCbluebg) ,dddddd: xddddddddddd. cddddddddddd, .ddddddo $(N) 28 | $(NCbluebg) ddddddkc ¸Oddddddddddddc kdddddddddddO, ¸0dddddd, $(N) 29 | $(NCbluebg) .ddddddx0nwwnXOddddddoddddddk' kdddddddddddddxKnwwnkkddddddc $(N) 30 | $(NCbluebg) dddddddddddddddddd; .ddddddkd Kxdddddl .dddddddddddddddddd' $(N) 31 | $(NCbluebg) dddddddddddddd; .ddddddx0K¸ ,Xkddddddl .dddddddddddddd' $(N) 32 | $(NCbluebg) 'ddddddo' odddddddk0XnweoxwnKOxddddddd' 'ddddddo' $(N) 33 | $(NCbluebg) dddddddddddddddddddddddd' $(N) 34 | $(NCbluebg) 'ddddddddddddddddddo $(N) 35 | $(NCbluebg) oddddÇÇdddo $(N) 36 | $(line ' ' NCbluebg 84 a0) 37 | $(line ' ' NCbluebg 84 a0) 38 | 39 | NEXTCLOUDLOGO 40 | } 41 | -------------------------------------------------------------------------------- /scripts/nc-who: -------------------------------------------------------------------------------- 1 | __shebang_bash__ 2 | __path_and_scriptname__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | __whoami_whereami__ 11 | __scriptname__ 12 | __homedir__ 13 | __vdirname__ NC_DIR 14 | modules=(nc/nextcloud nc/db nc/logo $MS/help $MS/last $MS/h2t $MS/monitor $MS/god) 15 | __debug__ 16 | __when__ 17 | __tempdir__ 18 | __module_server__ 19 | __general__ 20 | __module_loader__ 21 | __module_integrity__ 22 | __nextcloud_updater__ 23 | 24 | ## SCRIPT SPECIFIC 25 | 26 | contribute_(){ 27 | . <(require contribute) 28 | contribute "https://help.nextcloud.com/t/script-nc-who-similar-to-unix-who-follow-live-who-is-logged-in/164972" 29 | }; donate_(){ contribute_;} 30 | [[ "$@" =~ (donat|contrib) ]] && contribute_ 31 | 32 | declare arg command 33 | declare -a args 34 | 35 | command=print_help 36 | 37 | main_menu(){ 38 | declare -g MENU_CHOICE='' MENU_RESULT='' # purge any previous value 39 | local opts 40 | opts="$(tf)" 41 | ${X[cat]} <"$opts" 42 | bool[compose]=: 43 | title="Main Menu of nc-who" 44 | prompt="Select an action from the list" 45 | declare -a items=("--help" "last" "monitor" "god") 46 | declare -A descr=( 47 | [--help]="Show the help" 48 | [last]="List users sorted by their last login time." 49 | [monitor]="Monitor live user logins, ordered by last activity at an adjustable refresh rate" 50 | [god]="God mode - invalidate cookies before they expire" 51 | ) 52 | OPTS 53 | if menu "$opts"; then 54 | if [[ "${MENU_RESULT}" == '--help' ]]; then 55 | command='print_help' 56 | elif [[ " last monitor god " =~ " ${MENU_RESULT} " ]]; then 57 | command="nc_${MENU_RESULT}" 58 | else 59 | exit1 60 | fi 61 | else 62 | exit1 63 | fi 64 | } 65 | 66 | if (( $# )); then 67 | # argument was provided → validate it 68 | case "$1" in 69 | monitor|last|god) 70 | command="nc_$1" 71 | ;; 72 | -h|--help) 73 | command=print_help 74 | ;; 75 | *) f 76 | echo "--> unknown option: \"$1\" <--" 77 | print_help 78 | esac 79 | else 80 | main_menu 81 | fi 82 | 83 | $command 84 | 85 | exit0 86 | 87 | -------------------------------------------------------------------------------- /blocks/debug: -------------------------------------------------------------------------------- 1 | # debugging tools only on test channel 2 | # usage: add 'dbg' at the place in the code where you want to start debugging 3 | # now you will get the dbg prompt and can execute commands 4 | # dbg_help gives some examples. 5 | 6 | dbg_help(){ 7 | [[ "${FUNCNAME[1]}" = dbg || "${FUNCNAME[1]}" = debug_trap ]] || return 0 8 | ${C[c]} <$NUL 29 | case "$1" in 30 | toggle) debug_toggle ;; 31 | on) B[debug]=: ;; 32 | off) B[debug]=_; set +x ;; 33 | *) echo "Usage: debug {on|off}" 34 | esac 35 | } 36 | inherit(){ 37 | [[ "${FUNCNAME[1]}" = dbg || "${FUNCNAME[1]}" = debug_trap ]] || return 0 38 | case "$1" in 39 | on) set -T ;; 40 | off) set +T ;; 41 | *) echo "Usage: inherit {on|off}" 42 | esac 43 | } 44 | dbg(){ 45 | printf '%b' '\e[?25h\e[0;m' 46 | while read -rp "${FUNCNAME[1]}:${BASH_LINENO[0]} dbg> (dbg_help for help) " cmd; do 47 | [[ "$cmd" ]] || break 48 | eval $cmd 49 | done 50 | } 51 | debug_trap(){ 52 | printf '%b' '\e[?25h\e[0;m' 53 | while read -rp "$(printf "\e[0;31m")[${FUNCNAME[1]}:${BASH_LINENO[0]} DEBUG:]$(printf "\e[0;33m") dbg_help$(printf "\e[0;m") for help,$(printf "\e[0;32m") ENTER$(printf "\e[0;m") to proceed .. " cmd; do 54 | [[ "$cmd" ]] || break 55 | eval $cmd 56 | done 57 | } 58 | set -T 59 | trap '"${B[debug]:=_}" && { set +x; debug_trap; set -x; } || set +x' DEBUG 60 | # end of debug 61 | -------------------------------------------------------------------------------- /modules/php-updater/tasks.d/unused_sapis: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${TASKS_UNUSED_SAPIS_BASHLIB:-_} && return 11 | TASKS_UNUSED_SAPIS_BASHLIB=: 12 | 13 | remove_unused_sapis(){ 14 | cursor_ hide 15 | spinner C " . searching misconfigurations: unused SAPIs ." & 16 | if $(is_sapi_true_ cgi) || $(is_sapi_true_ embed) || $(is_sapi_true_ phpdbg); then 17 | local unused_sapi plu be modstring pkgstring 18 | local -a unused_sapis unused_sapis_descr packages_2_purge 19 | for unused_sapi in cgi embed phpdbg; do 20 | if $(is_sapi_true_ $unused_sapi); then 21 | unused_sapis+=("$unused_sapi") 22 | packages_2_purge+=(${SAPI[$unused_sapi]/@VER@/*}) 23 | fi 24 | done 25 | mapfile -t unused_sapis_descr < <(for unused_sapi in ${unused_sapis[@]}; do echo "${DESCR[$unused_sapi]}$(GRAY) ($unused_sapi)$(B)"; done) 26 | if (( ${#unused_sapis[@]} == 1 )); then 27 | plu='is:' be='is a' 28 | else 29 | plu='ese:s' be='are' 30 | fi 31 | modstring="$(listify B ${unused_sapis[@]})" 32 | modstringdescr="$(listify B "${unused_sapis_descr[@]}")" 33 | pkgstring="$(listify B ${packages_2_purge[@]})" 34 | question="$(qpf; format_string "Do you want to remove (purge) th${plu%:*} unnecessary SAPI${plu#*:} package${plu#*:} $pkgstring now" 3)" 35 | separator R 36 | bundle echo "$(xpf; format_string "There $be $modstringdescr installed on this machine." 3;N)" 37 | echo "$(ipf; format_string "In most cases, th${plu%:*} SAPI${plu#*:} get installed because of a dependency package. There is not a single use case that requires th${plu%:*} SAPI${plu#*:} to operate an application like Nextcloud. $(Y)Consider removing th${plu%:*} unnecessary SAPI${plu#*:} before updating." 3;N)" 38 | echo "$(pf; format_string "This script can remove the $modstring package${plu#*:} in a safe way." 3)" 39 | if ask "$question" "$YES"; then 40 | apt_ purge --yes ${packages_2_purge[@]} 41 | "$ME${FLAG[forceflag]}" "json=${J[o]}" --list-installed-only 42 | anykey 43 | return 0 44 | else 45 | return 1 46 | fi 47 | else 48 | return 1 49 | fi 50 | } 51 | -------------------------------------------------------------------------------- /modules/php-updater/pdiff: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${PDIFF_BASHLIB:-_} && return 11 | PDIFF_BASHLIB=: 12 | 13 | . <(lrequire dpkg) 14 | . <(lrequire php/extensions) 15 | 16 | pdiff_inst(){ 17 | local v x 18 | v="$1" 19 | shift 20 | ( # dpkg -l + awk: extract $2, strip version suffix in one step 21 | ${X[dpkg]} -l | ${X[gawk]} "/^[hiu]i.*php$v/ { p = \$2; sub($v, \"\", p); print p }" 22 | for x in "$@"; do 23 | case "$x" in 24 | libapache2-mod-php) echo "$x" ;; 25 | embed) echo "libphp-$x" ;; 26 | *) echo "php-$x" 27 | esac 28 | done 29 | ) | ${X[grep]} -vFxf <(printf '%s\n' "${SAPI[@]/@VER@/}") | ${X[sort]} -u # sapis are filtered out here 30 | } 31 | 32 | # returns a list with vals unique to $1 - # x1=minimum packages to be installed, x2=packages required by cli and thus installed 33 | packages_diff(){ 34 | [ -f "${F[php]:="${D[vt]}/php"}" ] && . "${F[php]}" 35 | local pvo pvn pkgmod pkg sapi px 36 | local -a eia x1 x2 37 | local -i i 38 | pvo="$1" pvn="$2" 39 | local -n C4EIBY4_pvo="C4EIBY4_${pvo//./}" 40 | # baseline modules vs. new-php defaults 41 | x1=(apcu bcmath bz2 curl gd gmp igbinary intl mbstring redis smbclient xml zip) # TODO: igbinary, redis and smbclient should be detected in a smarter way 42 | x2=(common json opcache readline) # excludes, since installed as dependecy 43 | # collect admin-installed module names 44 | if (( ${#EXTS_ADMIN[@]} )); then 45 | for i in "${!C4EIBY4_pvo[@]}"; do 46 | pkgmod="${C4EIBY4_pvo[i]}" 47 | pkg="${pkgmod%:*}" 48 | [[ $pkg == php$pvo-* ]] && eia+=("${pkg#*-}") 49 | done 50 | fi 51 | # the sapis must be at the first place of the arrays filled by this function 52 | while IFS= read -r sapi; do 53 | echo "${SAPI[$sapi]/@VER@/$pvn}" 54 | done < <(${X[comm]} -23 <(p_sort $(${X[phpquery]} -v $pvo -S)) <(p_sort $(${X[phpquery]} -v $pvn -S))) 55 | # all other packages but sapi 56 | while IFS= read -r px; do 57 | px="${px/php/php$pvn}" 58 | [[ $px == php$pvn ]] && continue 59 | q0 apt_exist "$px" && echo "$px" 60 | done < <(${X[comm]} -23 <(pdiff_inst "$pvo" "${x1[@]}" "${eia[@]}") <(pdiff_inst "$pvn" "${x2[@]}")) 61 | } 62 | -------------------------------------------------------------------------------- /scripts/janitor: -------------------------------------------------------------------------------- 1 | __shebang_bash__ 2 | __path_and_scriptname__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | __whoami_whereami__ 11 | __scriptname__ 12 | __homedir__ 13 | __vdirname__ NC_DIR 14 | modules=( 15 | today interval dos2unix prompt fstring httpd context ask sysinf ebtb 16 | dist/os_release nc/c2j nc/aio 17 | php/version php/nginx php/apache2 php/fpm php/versions php/alternatives 18 | php/extensions php/sury 19 | ) 20 | __debug__ 21 | __when__ 22 | __tempdir__ 23 | __module_server__ 24 | __general__ 25 | __module_loader__ 26 | __module_integrity__ 27 | 28 | ## SCRIPT SPECIFIC 29 | 30 | contribute_(){ 31 | . <(require contribute) 32 | contribute "https://github.com/ernolf/ebtb" 33 | }; donate_(){ contribute_;} 34 | [[ "$@" =~ (donat|contrib) ]] && contribute_ 35 | 36 | ## it starts here: 37 | # you MUST be root: 38 | su_root "to run this script." 39 | check_context 40 | my_update_check 41 | 42 | main_menu(){ 43 | declare -g MENU_CHOICE='' MENU_RESULT='' # purge any previous value 44 | local opts 45 | opts="$(tf)" 46 | ${X[cat]} <"$opts" 47 | title="Main Menu of the ebtb Janitor" 48 | prompt="Select a janitor job from the list" 49 | declare -a items=("sysinf" "ebtb launch" "contribute_") 50 | declare -A descr=( 51 | ["sysinf"]="System Information" 52 | ["ebtb launch"]="Launch ebtb - Admin Scripts" 53 | ["contribute_"]="Contribute to ebtb" 54 | ) 55 | OPTS 56 | while :; do 57 | menu "$opts" && ${MENU_RESULT:-:} || exit1 58 | done 59 | } 60 | 61 | # if script is invoked directly, show the main menu 62 | if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then 63 | main_menu 64 | fi 65 | exit0 66 | # TODO 1 --> 67 | 68 | #SYSINFMOD=(id bash user prompt hypervisor aio pid1 os env locales parent term cgroups hostname ip who uptime cpu free se aa dmi dpkg php httpd nextcloud) 69 | #spinner Yi " . determine system informations ." & 70 | #sysinf_ spinner 71 | #kill_spinner 72 | #sysinf_print_ "${SYSINF[@]}" 73 | 74 | #if (( "${#HTTPD_NC_DIR[@]}" == 0 )); then 75 | # mapfile -t HTTPD_NC_DIR< <(q2 ${X[find]} -L /var /srv -name occ -type f -exec dirname {} \; | ${X[grep]} -Ev '(/updater-oc|/overlay)' | ${X[sort]}) 76 | #fi 77 | #[[ $(q2 declare -p NC) =~ 'declare -A' ]] && cdir=${NC[cd]} || cdir=${HTTPD_NC_DIR[0]/%//config} 78 | #[ -d "$cdir" ] && config2json "$cdir" | ${X[jq]} . 79 | 80 | # TODO 1 <-- 81 | -------------------------------------------------------------------------------- /modules/exit: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${EXIT_BASHLIB:-_} && return 11 | EXIT_BASHLIB=: 12 | 13 | # TODO 0 --> 14 | . <(lrequire binaries) 15 | . <(lrequire basics) 16 | . <(lrequire ansi) 17 | . <(lrequire debug) 18 | # TODO 0 <-- 19 | . <(lrequire ebtb) 20 | . <(lrequire cleanup) 21 | 22 | F[spinner_pid]=${D[shm]}/spinner.pid 23 | 24 | exit_msg(){ 25 | q0 ${X[pgrep]} -f '/(ebtb-)?(ebtb|janitor)(-test)?$' && return 0 26 | if ebtb_is_installed janitor; then 27 | GRAY; echo "the $(W)janitor$(GRAY) can provide extensive system informations and more.$(W) simply run: $(Y)janitor"; N 28 | else 29 | GRAY; echo "generous? feedback? questions?$(W) simply run: $(Y)$ME --contribute"; N 30 | fi 31 | } 32 | 33 | exit0(){ 34 | log_trace "exit 0" 35 | G; echo "exiting ${M[n]} script."; N 36 | exit_msg 37 | exit 0 38 | } 39 | 40 | exit1(){ 41 | log_trace "exit 1" 42 | R; echo "exiting ${M[n]}…"; N 43 | exit_msg 44 | exit 1 45 | } 46 | 47 | # define a trap to clean up the lock- and temporary files 48 | exit_trap(){ 49 | local x 50 | [ -f "${F[spinner_pid]}" ] && kill_spinner || ${X[sleep]} .1 51 | cleanup "${F[spinner_pid]}" 52 | ${local_server:-_} && ls_ stop 53 | # cleanup "${D[l]}" # this must not be cleaned up, it would produce error messages due to race conditions 54 | for x in td shm; do 55 | nonullglob "${D[$x]}/${M[b]}${M[pid]}_*" && cleanup ${D[$x]}/${M[b]}${M[pid]}_* 56 | nonullglob "${D[$x]}/${M[b]:-$$}_*" && cleanup ${D[$x]}/${M[b]:-$$}_* 57 | done 58 | ${B[silent]:-_} || ${X[reset]} -IQ 59 | ${B[silent]:-_} || ansi_reset 60 | } 61 | 62 | interrupted(){ 63 | local sig t 64 | local -i os # offset 65 | sig="$1" t="$(O)TRAP$(Yi): -" os=24 66 | if [ -z "${M[b]}" ]; then 67 | return 0 68 | else 69 | te1 70 | f 71 | separator R 72 | echo "$t $(C)interrupted by$(o $os; Yi)- $(R)sig$sig" 73 | if [ -f "${F[spinner_pid]}" ]; then 74 | echo "$t $(C)spinner$(o $os; Yi)- $(G)killed" 75 | fi 76 | if nonullglob "$TD/${M[b]}${M[pid]}_*" || nonullglob "$TD/${M[b]:-$$}_*"; then 77 | echo "$t $(C)temporary files$(o $os; Yi)- $(G)removed" 78 | fi 79 | exit1 80 | fi 81 | } 82 | 83 | trap 'exit_trap' EXIT 84 | trap 'interrupted INT' INT 85 | trap 'interrupted TERM' TERM 86 | -------------------------------------------------------------------------------- /modules/fstring: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${FSTRING_BASHLIB:-_} && return 11 | FSTRING_BASHLIB=: 12 | 13 | # TODO 0 --> 14 | . <(lrequire binaries) 15 | . <(lrequire ansi) 16 | . <(lrequire filter) 17 | # TODO 0 <-- 18 | # format a long string in lines with a maximum length 19 | 20 | format_string() { 21 | local -A bool 22 | [[ "$-" =~ x ]] && { set +x; bool[debugx]=:; } || : 23 | local input output word noansi_word basic_color indent_type 24 | local -i indent max_cols max_length current_length marg 25 | input="$1" indent="${2/o/}" max_cols=$(max_cols) output='' basic_color='' 26 | indent_type='es' # default to "empty spaces" 27 | [[ "$2" =~ o ]] && indent_type='o' # offset to not overwrite indent space 28 | if [[ "${3:-}" =~ ^[0-9]+$ ]]; then 29 | (( $3 > max_cols )) || max_cols=$3 30 | else 31 | basic_color="$(${3:-:})" # TODO: is this used? 32 | fi 33 | 34 | if (( max_cols > 90 )); then 35 | marg=10 36 | elif (( 90 > max_cols && max_cols > 80 )); then 37 | marg=$(( max_cols - 80 )) 38 | else 39 | marg=0 40 | fi 41 | 42 | if (( max_cols < 80 )); then 43 | max_length=$(( 80 - indent )) 44 | else 45 | max_length=$(( max_cols - $(( marg + indent )) )) 46 | fi 47 | 48 | current_length=0 49 | for word in $input; do 50 | noansi_word="$(${X[ansifilter]} <<< "$word")" 51 | if (( $(( current_length + ${#noansi_word} )) > $(( max_length - 1 )) )); then 52 | output+="\n$($indent_type $indent)$basic_color$word" 53 | current_length=${#noansi_word} 54 | elif ${bool[firstword]:-:}; then 55 | output+="$word" 56 | current_length=${#noansi_word} 57 | bool[firstword]=_ 58 | else 59 | output+=" $word" 60 | current_length=$(( current_length + ${#noansi_word} + 1 )) 61 | fi 62 | done 63 | echo -en "$output" 64 | ${bool[debugx]:-_} && set -x || : 65 | } 66 | 67 | listify(){ 68 | local color 69 | color=${1:-:} 70 | shift 71 | echo -e "$($color; echo -n "${@//\ /@E_S@}" | sed_ "s/ /, /g; s/(.*), /\1 $(N)and$($color) /; s/@E_S@/ /g"; N)" 72 | } 73 | 74 | listify_(){ 75 | local color_fg color_bg 76 | color_fg=${1:-:} color_bg=${2:-:} 77 | shift 2 78 | echo -e "$($color_fg; echo -n "${@//\ /@E_S@}" | sed_ "s/ /, /g; s/(.*), /\1 $($color_bg)and$($color_fg) /; s/, /$($color_bg),$($color_fg) /g; s/@E_S@/ /g"; $color_bg)" 79 | } 80 | -------------------------------------------------------------------------------- /modules/sudo: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${SUDO_BASHLIB:-_} && return 11 | SUDO_BASHLIB=: 12 | 13 | # TODO 0 --> 14 | . <(lrequire binaries) 15 | . <(lrequire basics) 16 | . <(lrequire exit) 17 | # TODO 0 <-- 18 | su_do(){ 19 | nosudo(){ 20 | o2; R; echo "you have no sudo rights."; N 21 | } 22 | local prompt 23 | local -a bools args 24 | local -A arga 25 | for x in "$@"; do arga[${x%%=*}]="${x#*=}"; done 26 | case "${arga[u]}" in 27 | root) 28 | ${B[rt]} && return 0 29 | if [ "${arga[run]}" = "$ME" ]; then 30 | args=( 31 | "json=${J[o]}" 32 | ${arga[arg]} 33 | ${M[args]} 34 | ) 35 | else 36 | args=("${arga[arg]}") 37 | fi 38 | prompt="$(Pbg)[sudo]$(N) - $(P)You have to be '$(C)root$(P)' ${arga[p]}. Password of user$(C) %p$(P):$(N) " 39 | if q0 ${X[sudo]} -lp "$prompt" ${arga[run]}; then # ${arga[run]} must be kept unquoted here! 40 | mh "$(fn_ln 1)$(fn_ln) ${X[sudo]} ${arga[run]} ${args[@]}" 41 | ${X[sudo]} ${arga[run]} ${args[@]} 42 | ${arga[r]} && return 0 || exit 0 43 | else 44 | nosudo 45 | ${arga[r]} && return 1 || exit1 46 | fi 47 | ;; 48 | # su_do "u=NC_USER" or su_do "u=NC[u]" 49 | NC_USER) 50 | f 2 51 | o2; B; echo "This script has to be run as user$(N) '$(C)${NC[u]}$(N)' $(B)or as$(N) '$(C)root$(N)'$(B)!$(N)" 52 | o4; GRAY; echo "sudo -u ${NC[u]} $ME ${args[@]}$(N)" 53 | prompt="$(Pbg)[sudo]$(N; pf; P)Enter password of user$(C) %p $(P)to substitute user to$(C) ${NC[u]}$(P):$(N) " 54 | o2; if q0 ${X[sudo]} -lu ${NC[u]} -p "$prompt" $ME; then 55 | mh "$(fn_ln 1)$(fn_ln) ${X[sudo]} -u ${NC[u]} $CMA" 56 | ${X[sudo]} -u ${NC[u]} $CMA 57 | exit 0 58 | else 59 | nosudo 60 | exit1 61 | fi 62 | esac 63 | } 64 | 65 | # wrapper for backwards compatibility 66 | su_root(){ 67 | require_arg $@ 68 | local p="$1" 69 | shift 70 | su_do "u=root" "r=_" "p=$p" "run=$ME" "arg=$@" 71 | return $? 72 | } 73 | 74 | su_root_(){ 75 | required_args 2 "$@" 76 | local p="$1" run="$2" 77 | shift 2 78 | su_do "u=root" "r=:" "p=$p" "run=$run" "arg=$@" 79 | return $? 80 | } 81 | -------------------------------------------------------------------------------- /modules/nc-mimecheck/functions: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${FUNCTIONS_BASHLIB:-_} && return 11 | FUNCTIONS_BASHLIB=: 12 | 13 | . <(lrequire verbose) 14 | . <(lrequire nc/nextcloud) 15 | 16 | # wrong_option -r "string" 17 | wrong_option(){ 18 | local -i i 19 | local -a a 20 | # -r registrate wrong option in array for later echo 21 | if [ "$1" = "-r" ]; then 22 | shift 23 | woa[$woi]="$@" 24 | woi=$((woi+1)) 25 | # -x echo all gathered errors together, show help and exit 26 | elif [ "$1" = "-x" -a $woi -gt 0 ]; then 27 | ${B[quiet]} && exit 1 28 | for i in $(${X[seq]} 0 $((woi-1))); do 29 | IFS="#" read -ra a <<< ${woa[$i]} 30 | if [ ${#a[*]} -ne 0 ]; then 31 | f 32 | R; echo "OPTION: $((i+1)): ${a[0]}">&2 33 | echo " ${a[1]}">&2; N 34 | else 35 | f 36 | R; echo "OPTION: $((i+1)): ${woa[$i]}">&2; N 37 | fi 38 | done 39 | try_help 40 | # no -r, no -x echo error, show help and exit 41 | elif [ "${1:0:1}" != "-" ]; then 42 | f 43 | R; echo "OPTION: $*">&2; N 44 | try_help 45 | fi 46 | return 0 47 | } 48 | 49 | # main file=1 regex=2 exension=3 mimetype=4 50 | main(){ 51 | required_args 4 "$@" 52 | local -i i=1 53 | v_echo "$4$(o 26)=> ${1##*/}" 54 | if ! echo "$1" | ${X[grep]} -iE $grepopts "$2"; then 55 | ${B[quiet]} || echo "detected mimetype of ${1##*/} is $4" 56 | ${B[dryrun]} || ${X[mv]} "$1" "$(sed_ 's/\..{1,5}$//' "$1" '-')$3" 57 | do_occ_filesscan set : 58 | ${B[quiet]} || echo "$(G)moved $(xGRAY)${1##*/}$(N)" 59 | ${B[quiet]} || echo "$(G) to $(P)$(sed_ 's/\..{1,5}$//' "${1##*/}" '-')$(Pbg)$3$(N)" 60 | i=0 61 | fi 62 | return $i 63 | } 64 | 65 | # scan_dir dir=1 66 | scan_dir(){ 67 | require_arg "$@" 68 | local -i i ret 69 | local filepath mimetype extension 70 | i=255 ret=1 71 | for filepath in "$1"/*; do 72 | [ -f "$filepath" ] || continue 73 | mimetype="$($mimedetector "$filepath")" 74 | echo "${mime_ext_regex_array[@]%%:*}" | ${X[grep]} -qsw "$mimetype" || continue 75 | extension="$(a_fld mime_ext_regex_array ':' "$mimetype" 2)" 76 | regex="$(a_fld mime_ext_regex_array ':' "$mimetype" 3)" 77 | main "$filepath" "$regex" "$extension" "$mimetype" 78 | ret=$? 79 | (($i)) && i=$ret 80 | done 81 | return $i 82 | } 83 | -------------------------------------------------------------------------------- /modules/php/logo: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${PHP_LOGO_BASHLIB:-_} && return 11 | PHP_LOGO_BASHLIB=: 12 | 13 | php_logo(){ 14 | ${X[cat]} << PHPLOGO 15 | $(dPHP)hhHhhHhhHhhHHhhHhhHhhHhhhHhhHhhHhhHHhhHhhHhhHhhHHhhHhhHhhHhhhHhhHhhHhhHHhhHhhH$(N) 16 | $(dPHP)HhhHhhhHhhHhhHhhHhhhHhhHhhHhhhhPPPppPppPpppPpPPPPhhhHhhhHhhHhhHhhhHhhHhhHhhHhh$(N) 17 | $(dPHP)hhhhhhhhhhhhhhhhhhhhPPp$(lPHP):::;;;;;;;;;;;;;;;;;;;;;;;;;;;:$(dPHP)pppPhhhhhhhhhhhhhhhhhhhh$(N) 18 | $(dPHP)hhHhhHhhHhhHHhhPp$(lPHP):;;;;;;;;;;;;;;;;;,,,,,;;;;;;;;;;;;;;;;;;;;:$(dPHP)pPhHhhHhhHHhhHhhH$(N) 19 | $(dPHP)HhhHhhhHhhhPp$(lPHP):;;;;;;;;;;;;;;;;;;;;, .;;;;;;;;;;;;;;;;;;;;;;;;;$(dPHP)pPhhHhhHhhHhh$(N) 20 | $(dPHP)hhHhhHhhP$(lPHP):;;;;;;;;;;;;;;;;;;;;;;;;. ';;;;;;;;;;;;;;;;;;;;;;;;;;;;:$(dPHP)phhhhHhhH$(N) 21 | $(dPHP)hhhhhhp$(lPHP);;;;;;;;;'...........',;;;, ......',;;;'...........',;;;;;;;$(dPHP)phhhhhh$(N) 22 | $(dPHP)HhhHP$(lPHP);;;;;;;;;;;. .,;' .,, .,;;;;;;;$(dPHP)PhHhh$(N) 23 | $(dPHP)hhHp$(lPHP);;;;;;;;;;;' .''''.. .;. .'''.. .. .'''... .;;;;;;;;$(dPHP)phhH$(N) 24 | $(dPHP)HhP$(lPHP);;;;;;;;;;;;. ';;;;;, , .;;;;;. '. ,;;;;;' .;;;;;;;;;$(dPHP)Phh$(N) 25 | $(dPHP)hh$(lPHP):;;;;;;;;;;;, ,;;;;;. .. ';;;;, .' .;;;;;;. .;;;;;;;;;:$(dPHP)hh$(N) 26 | $(dPHP)hh$(lPHP):;;;;;;;;;;;. .;;;,'. ., .;;;;;. .. ';;;,'. .,;;;;;;;;;:$(dPHP)hH$(N) 27 | $(dPHP)HhP$(lPHP);;;;;;;;;;;. .,' .;;;;;. ' ..,;;;;;;;;;;$(dPHP)Phh$(N) 28 | $(dPHP)hhHP$(lPHP);;;;;;;;;' ........',;;.....,;;;;,...... .........',;;;;;;;;;;;$(dPHP)phhH$(N) 29 | $(dPHP)hhhhh$(lPHP):;;;;;;;. ,;;;;;;;;;;;;;;;;;;;;;;;;;;;;. .;;;;;;;;;;;;;;;;;;;;;$(dPHP)Phhhh$(N) 30 | $(dPHP)HhhHhhP$(lPHP):;;;;, .;;;;;;;;;;;;;;;;;;;;;;;;;;;;' .;;;;;;;;;;;;;;;;;;:$(dPHP)pHhhHhh$(N) 31 | $(dPHP)hhHhhHhhhp$(lPHP):;,....';;;;;;;;;;;;;;;;;;;;;;;;;;;;'....,;;;;;;;;;;;;;;;;$(dPHP)pPHHhhHhhH$(N) 32 | $(dPHP)HhhHhhhHhhHhp$(lPHP):;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:$(dPHP)phhhHhhHhhHhh$(N) 33 | $(dPHP)hhhhhhhhhhhhhhhPPp$(lPHP):;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:$(dPHP)pphhhhhhhhhhhhhhhh$(N) 34 | $(dPHP)hhHhhHhhHhhHHhhHhhHhhhPppp$(lPHP):;;;;;;;;;;;;;;;;;;;;;;;;::$(dPHP)pPPPhhhhHhhHhhHhhHHhhHhhH$(N) 35 | $(dPHP)HhhHhhhHhhHhhHhhHHhhHhhHhhHhhHhPhhPPPPPPPPPPPhhhhHhhHHhhHhhHhhHhhHHhhHhhHhhHhh$(N) 36 | $(dPHP)hhHhhHhhHhhhHhhHhhHhhHhhhHhhHhhHhhHhhhHhhHhhHhhhHhhHhhHhhHhhhHhhHhhHhhHhhhHhhH$(N) 37 | PHPLOGO 38 | } 39 | 40 | phplogo(){ 41 | php_logo 42 | } 43 | -------------------------------------------------------------------------------- /modules/php-updater/tasks.d/meta_pkgs: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${TASKS_META_PKGS_BASHLIB:-_} && return 11 | TASKS_META_PKGS_BASHLIB=: 12 | 13 | remove_meta_packages(){ 14 | cursor_ hide 15 | spinner C " . searching misconfigurations: meta-packages ." & 16 | local pkg plu be modstring question 17 | local -a meta_pkgs 18 | for pkg in $(${X[dpkg]} -l | ${X[gawk]} '/^[hiu]i.*php/{print $2}'); do 19 | if extension_is_ meta "$pkg"; then 20 | rdepends -q "$pkg" || meta_pkgs+=("$pkg") 21 | fi 22 | done 23 | if (( ${#meta_pkgs[@]} )); then 24 | if ((${#meta_pkgs[@]}==1)); then 25 | plu='is:' be='is a' modstring="$(B)${meta_pkgs[0]}$(N)" 26 | else 27 | plu='ese:s' be='are' modstring="$(listify B ${meta_pkgs[@]})" 28 | fi 29 | question="$(qpf; format_string "Do you want to remove the meta package${plu#*:} $modstring now" 3)" 30 | bundle echo "$(xpf; format_string "There $be unnecessary $(O)meta package${plu#*:}$(N) ($modstring) installed on this machine." 3; N)" 31 | echo "$(ipf; Y; format_string "Meta packages do not contain any software; they only depend on other packages to be installed. Essentially, they are package bundles that include multiple packages and SAPIs, many of which may not align with your specific use case. Removing a meta package does NOT remove the individual packages it installed. This script does not require meta packages, as it manages package selection much more precisely without the \"scattershot\" approach. Consider to remove th${plu%:*} package${plu#*:} before updating. The removal makes your system more resilient against unintended changes made without your decision." 3; N)" 32 | echo "$(pf; format_string "This script can remove th${plu%:*} package${plu#*:} in a safe way." 3)" 33 | if ask "$question" "$YES"; then 34 | apt_ remove --yes ${meta_pkgs[@]} 35 | "$ME${FLAG[forceflag]}" "json=${J[o]}" --list-installed-only 36 | anykey 37 | return 0 38 | else 39 | echo "$(ipf; Y; format_string "You answered $(button no), nothing changed." 3; N)" 40 | echo "$(xpf; R; format_string "WARNING: You should absolutely know what you are doing if you do not follow the script's advice, as it may result in an unstable system and affect the script's execution down the line! I may not be able to help with subsequent errors." 3; N)" 41 | anykey 42 | return 1 43 | fi 44 | else 45 | return 1 46 | fi 47 | } 48 | -------------------------------------------------------------------------------- /modules/php-updater/tasks.d/dependency_pkgs: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${TASKS_DEPENDENCY_PKGS_BASHLIB:-_} && return 11 | TASKS_DEPENDENCY_PKGS_BASHLIB=: 12 | 13 | remove_dependency_packages(){ 14 | cursor_ hide 15 | spinner C " . searching misconfigurations: dependency-packages ." & 16 | local pkg plu be modstring question 17 | local -a dependency_pkgs 18 | for pkg in $(${X[dpkg]} -l | ${X[gawk]} '/^[hiu]i.*php/{print $2}'); do 19 | if extension_is_ dependency "$pkg"; then 20 | rdepends -q "$pkg"||dependency_pkgs+=("$pkg") 21 | fi 22 | done 23 | if (( ${#dependency_pkgs[@]} )); then 24 | if ((${#dependency_pkgs[@]}==1)); then 25 | plu='is:' be='is a' modstring="$(B)${dependency_pkgs[0]}$(N)" 26 | else 27 | plu='ese:s' be='are' modstring="$(listify B ${dependency_pkgs[@]})" 28 | fi 29 | question="$(qpf; format_string "Do you want to remove the dependency package${plu#*:} $modstring now" 3)" 30 | bundle echo "$(xpf; format_string "There $be unnecessary $(O)dependency package${plu#*:}$(N) ($modstring) installed on this machine." 3; N)" 31 | echo "$(ipf; Y; format_string "Dependency packages have no other function than to install other packages with the final binaries. For example, php-apcu depends on the newest binary package, like php8.4-apcu. The downside is that this can lead to an unwanted update to a new version of that package, which can result in difficult-to-debug issues, such as internal server errors. It is strongly recommended to remove th${plu%:*} package${plu#*:} before updating, as the removal will make your system more resilient against unintended changes made without your decision." 3; N)" 32 | echo "$(pf; format_string "This script can remove th${plu%:*} package${plu#*:} in a safe way." 3)" 33 | if ask "$question" "$YES"; then 34 | apt_ remove --yes ${dependency_pkgs[@]} 35 | "$ME${FLAG[forceflag]}" "json=${J[o]}" --list-installed-only 36 | anykey 37 | return 0 38 | else 39 | echo "$(ipf; Y; format_string "You answered $(button no), nothing changed." 3; N)" 40 | echo "$(xpf; R; format_string "WARNING: You should absolutely know what you are doing if you do not follow the script's advice, as it may result in an unstable system and affect the script's execution down the line! I may not be able to help with subsequent errors." 3; N)" 41 | anykey 42 | return 1 43 | fi 44 | else 45 | return 1 46 | fi 47 | } 48 | -------------------------------------------------------------------------------- /modules/vdir: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${VDIR_BASHLIB:-_} && return 11 | VDIR_BASHLIB=: 12 | 13 | # uses indirect parameter expansion ("${!var}", BASH > 4) to eliminate the need for `eval` 14 | setvdir(){ 15 | if [[ -n ${D[vdir]:-} ]]; then # new method 16 | local d v v1 v2 v3 17 | d='UNDEFINED' 18 | v="${D[vdir]}" 19 | elif declare -p vdirname &> >(log_trace) && [[ -n $vdirname ]]; then # old method 20 | local dv d v v1 v2 v3 21 | dv="dflt_$vdirname" 22 | d="${!dv}" 23 | v="${!vdirname}" 24 | else 25 | return 0 26 | fi 27 | v1="${!1}" 28 | [[ -z ${3:-} ]] && v3="$MP" || v3="$3" 29 | case "${2:-}" in 30 | v) v2="$v" ;; 31 | d) v2="$d" ;; 32 | *) v2="$2" 33 | esac 34 | # new method 35 | mh "$(fn_ln) 's|^D[vdir]=\"$v1\"|D[vdir]=\"$v2\"|' '$v3' '-i'" 36 | sed_ 's|^D\[vdir\]=\"'$v1'\"|D[vdir]=\"'$v2'\"|' "$v3" '-i' 37 | # old method 38 | mh "$(fn_ln) 's|^declare \$vdirname=\"$v1\"|declare \$vdirname=\"$v2\"|' '$v3' '-i'" 39 | sed_ 's|^declare \$vdirname=\"'$v1'\"|declare \$vdirname=\"'$v2'\"|' "$v3" '-i' 40 | } 41 | # COMMENT --> 42 | 43 | # # old method 44 | 45 | # declare vdirname='NC_DIR' 46 | # declare dflt_$vdirname='UNDEFINED' 47 | # declare $vdirname="UNDEFINED" 48 | 49 | # # new method: 50 | 51 | # D[vdir]="UNDEFINED";declare -n NC_DIR=D[vdir] 52 | 53 | ##################### 54 | # # implementations: 55 | ##################### 56 | # modules/nc/first_run: setvdir v "$1" 57 | # modules/nc/nextcloud: q0 declare -p NC_DIR && [[ $NC_DIR != ${NC[d]} ]] && ${B[rt]} && setvdir v "${NC[d]}" 58 | # modules/php-module-builder/first_run: setvdir v "$dir" 59 | 60 | # modules/integrity: 61 | # ================== 62 | # if [[ ${D[vdir]:-} ]]; then # new method 63 | # [[ ${D[vdir]} = UNDEFINED ]] || setvdir v d "${tf[i]}" 64 | # elif [[ ${vdirname:-} ]]; then # old method 65 | # local dflt_vdirname="dflt_$vdirname" 66 | # local vdir="${!vdirname}" ddir="${!dflt_vdirname}" 67 | # [ "$vdir" = "$ddir" ] || setvdir v d "${tf[i]}" 68 | # fi 69 | 70 | # modules/update: 71 | # ================== 72 | # if [[ ${D[vdir]:-} ]]; then # new method 73 | # [[ ${D[vdir]} = UNDEFINED ]] || setvdir d v "$my_tmp" 74 | # elif [[ $vdirname ]]; then # old method 75 | # local dflt_vdirname="dflt_$vdirname" 76 | # local vdir="${!vdirname}" ddir="${!dflt_vdirname}" 77 | # [ "$vdir" = "$ddir" ] || setvdir d v "$my_tmp" 78 | # fi 79 | -------------------------------------------------------------------------------- /modules/line: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${LINE_BASHLIB:-_} && return 11 | LINE_BASHLIB=: 12 | 13 | # TODO 0 --> 14 | . <(lrequire binaries) 15 | . <(lrequire ansi) 16 | # TODO 0 <-- 17 | # $1=pattern $2=color $3=(empty spaces/)repetition of pattern((int/)int or 'a' for auto) 18 | # $4 and $5 either a$i or b$i where a is after and b is before 19 | # and $i the amount of empty lines 20 | line(){ 21 | local -A bool 22 | # [[ "$-" =~ x ]] && { set +x; bool[debugx]=:; } || : 23 | local p c cp # pattern, color and coolored pattern 24 | local -i e r a b # empty_spaces, repetition, lines after, lines before 25 | p="${1:--}" c="${2:-N}" e=0 a=1 b=0 26 | binaries_is_func_ $c || c='N' # if color does not exist as function, fallback to neutral 27 | (( $(${X[expr]} ${3:-a} : '.*/.*') )) && e=${3%/*} 28 | [[ ! ${3:-} || ${3#*/} = 'a' ]] && r=$(( ( $(max_cols) - e ) / ${#p} )) || r=${3#*/} 29 | shift 3 30 | # declare the values for 'b'efore and 'a'fter 31 | while (( $# )); do 32 | case "${1:0:1}" in 33 | a|b) (( ${1:1}1 )) && local ${1:0:1}=${1:1} 34 | shift 35 | ;; 36 | *) shift 37 | esac 38 | done 39 | f $b # prepend 'b' empty lines 40 | (( e )) && o $e # offset 'e' empty spaces 41 | cp="$($c)$p$(N)" # compose colored pattern 42 | # print the line with the colored pattern 43 | for ((i=0; i<$r; i++)); do printf '%s' "$cp"; done 44 | f $a # append 'a' empty lines 45 | # ${bool[debugx]:-_} && set -x || : 46 | } 47 | 48 | separator(){ 49 | local color 50 | if [[ ${1:-} = '--sanitized' ]]; then 51 | color=${2:-GRAY} 52 | line ' -' $color a 53 | else 54 | color=${1:-GRAY} 55 | kill_spinner && te1 && line ' -' $color 56 | fi 57 | } 58 | 59 | separator2(){ 60 | local color 61 | if [[ ${1:-} = '--sanitized' ]]; then 62 | color=${2:-GRAY} 63 | line ' =' $color a 64 | else 65 | color=${1:-GRAY} 66 | kill_spinner && te1 && line ' =' $color 67 | fi 68 | } 69 | 70 | separator3(){ 71 | local color 72 | if [[ ${1:-} = '--sanitized' ]]; then 73 | color=${2:-GRAY} 74 | line - $color a 75 | else 76 | color=${1:-GRAY} 77 | kill_spinner && te1 && line - $color 78 | fi 79 | } 80 | 81 | separator4(){ 82 | local color 83 | if [[ ${1:-} = '--sanitized' ]]; then 84 | color=${2:-GRAY} 85 | line = $color a 86 | else 87 | color=${1:-GRAY} 88 | kill_spinner && te1 && line = $color 89 | fi 90 | } 91 | -------------------------------------------------------------------------------- /modules/php-updater/disclaimer: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${DISCLAIMER_BASHLIB:-_} && return 11 | DISCLAIMER_BASHLIB=: 12 | 13 | disclaimer(){ 14 | local -i max_cols=90 15 | ${X[cat]} <//g; s///g; s///g'" 24 | sed_pre_html2text="${X[sed]} -e 's/_/~/g; s/ /=/g; s/> "$script.asc" 35 | 36 | # calculate hash 37 | echo " calculate and add sha256sum" 38 | hash=$(${X[sha256sum]} "$script" | ${X[gawk]} '{printf $1}') 39 | echo "# sha256sum: $hash" >> "$script.asc" 40 | 41 | # append signature and hash 42 | echo " append new signature" 43 | ${X[cat]} "$script.asc" >> "$script" && ${X[rm]} "$script.asc" 44 | 45 | # calculate size and (new) hash before copying to target 46 | epoch=$(epoch_ "$script") 47 | size=$(${X[stat]} -c%s "$script") 48 | hash=$(${X[sha256sum]} "$script" | ${X[gawk]} '{printf $1}') 49 | 50 | # copy file to target 51 | echo " copy '$script' to '$target.new'" 52 | ${X[cp]} "$script" "$target.new" 53 | 54 | # create json object 55 | echo " create json object '$target.json.new'" 56 | ${X[jq]} -n --compact-output --arg scriptname "$scriptname" --arg epoch "$epoch" --arg size "$size" --arg hash "$hash" \ 57 | '{ name: $scriptname, epoch: $epoch, size: $size, hash: $hash }' > "$target.json.new" 58 | } 59 | 60 | scan_(){ 61 | echo 62 | echo " This is the last exit point" 63 | echo " continue only if everything looked good so far!" 64 | echo 65 | anykey 66 | echo 67 | manage_new_files "$DATA_DIR/$target_scripts_dir" replace 68 | ${X[chown]} -R $HT_USER:$HT_USER "$DATA_DIR/$target_scripts_dir" 69 | occ files:scan --path="$target_scripts_dir" 70 | } 71 | 72 | manage_new_files "$DATA_DIR/$target_scripts_dir" trap 73 | 74 | (( $# )) && { 75 | echo " signing this scripts" 76 | echo " - $@" 77 | anykey 78 | } || { 79 | echo " no scripts past to sign" 80 | exit 1 81 | } 82 | 83 | for script2sign in "$@"; do 84 | sign_ "$script2sign" 85 | done 86 | 87 | echo " scan files" 88 | scan_ 89 | 90 | exit 0 91 | 92 | -------------------------------------------------------------------------------- /tools/compare_modules: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | declare -A bool 4 | bool[debug]=false 5 | bool[verbose]=false 6 | 7 | # whoami, whereami 8 | # b=basename m=me a=absolute p=path ca=canonical 9 | declare bm apm me ca_me ca_dir 10 | bm="$(basename "$0")"; apm="$(cd "$(dirname "$0")"&&pwd)/$bm" 11 | [ "$(command -v "$bm")" = "$apm" ] && me="$bm" || me="$apm" 12 | ca_me="$(readlink -e "$apm")"; ca_dir="$(dirname "$ca_me")" 13 | 14 | cd "$ca_dir/.." 15 | 16 | # source common functions 17 | source tools/common_build_functions 18 | 19 | ${bool[debug]} && set -x 20 | 21 | declare channel dir1 dir2 lib libname libname_in_1 libname_in_2 22 | declare -a difflibs=() 23 | channel="$1" # target channel 24 | dir1="$MBUILD_DIR" # $ca_dir/../build/modules 25 | dir2="$DATA_DIR/$target_modules_dir/${channel:=prod}" # /nc/dat/data/ich/files/Documents/Coding/ebtb/modules/${channel:=prod} 26 | 27 | ${bool[verbose]} && echo " dir1: $dir1" 28 | ${bool[verbose]} && echo " dir2: $dir2" 29 | ${bool[verbose]} && anykey 30 | ${bool[verbose]} && echo " checking libs:" 31 | 32 | #trap 'set +x;read -rp "$(printf "\033[0;31m")[DEBUG:]$(printf "\033[0;m") press Enter to proceed...";set -x' DEBUG 33 | for lib in $(${X[find]} $dir1 -type f -exec sh -c 'head -n 1 "$1" | grep -qs BASHLIB' _ {} \; -print); do 34 | libname="${lib#$dir1/}" 35 | # Use -E to enable extended regex (so we can use “?” quantifier without backslashes). 36 | # (${MODULES_DIR}/)? : optionally to match minified libs as well 37 | libname_in_1="$(${X[head]} -n2 "$lib" | ${X[tail]} -n1 | ${X[sed]} -E "s|^# ($MODULES_DIR/)?@channel@/||")" 38 | libname_in_2="$(${X[head]} -n2 "$dir2/$libname" | ${X[tail]} -n1 | ${X[sed]} -E "s|^# ($MODULES_DIR/)?$channel/||")" 39 | ${bool[verbose]} && echo " - \"$libname\"" 40 | ${bool[verbose]} && echo " 1: \"$libname_in_1\" 2: \"$libname_in_2\"" 41 | # Only modules that difference in body or path/name 42 | # if [[ $libname_in_1 != $libname_in_2 ]] || ! q0 ${X[diff]} <(q2 ${X[tail]} -n +4 "$lib") <(q2 ${X[tail]} -n +4 "$dir2/$libname"); then 43 | if [[ $libname_in_1 != $libname_in_2 ]] || ! q0 ${X[diff]} <(q2 ${X[sed]} '1,3d; /_LIB_VERSION/d' "$lib") <(q2 ${X[sed]} '1,3d; /_LIB_VERSION/d' "$dir2/$libname"); then 44 | ${bool[verbose]} && echo " - different" 45 | difflibs+=("$libname") 46 | ${bool[verbose]} && echo "${#difflibs[@]}" 47 | else 48 | ${bool[verbose]} && echo " - equal" 49 | fi 50 | ${bool[verbose]} && anykey 51 | done 52 | ${bool[verbose]} && echo 53 | ${bool[verbose]} && echo " number of different libs = ${#difflibs[@]}" 54 | ${bool[verbose]} && anykey 55 | if (( ${#difflibs[@]} )); then 56 | ${bool[verbose]} && echo " found ${#difflibs[@]} different libs:" 57 | for i in ${!difflibs[@]}; do 58 | ${bool[verbose]} && echo " - ${difflibs[i]}" || echo "${difflibs[i]}" 59 | done 60 | else 61 | ${bool[verbose]} && echo " all libs are equal, nothing changed" 62 | fi 63 | ${bool[verbose]} && anykey 64 | ${bool[debug]} && set +x 65 | 66 | -------------------------------------------------------------------------------- /modules/context: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${CONTEXT_BASHLIB:-_} && return 11 | CONTEXT_BASHLIB=: 12 | 13 | # TODO 0 --> 14 | . <(lrequire binaries) 15 | . <(lrequire ansi) 16 | . <(lrequire basics) 17 | # TODO 0 <-- 18 | . <(lrequire fstring) 19 | 20 | check_systemd(){ 21 | local pid1 infstr 22 | pid1="$(q2 ${X[ps]} -p 1 -o comm=)" 23 | if [[ "$pid1" != 'systemd' ]]; then 24 | infstr="The first process in the process hierarchy $(GRAY)(PID 1)$(W) is expected to be occupied by $(C)systemd$(W). However, on this system it is occupied by $(C)$pid1" 25 | R; echo "NOTE$(N): $(W;format_string "$infstr" 6;N)" 26 | xpf; R; echo "This script relies on systemd to function correctly."; N 27 | if ${X[grep]} -qs "docker" /proc/self/cgroup; then 28 | infstr="You have started this script from within a docker container. That is not what it is designed for. If you want to customize your docker image, you should rebuild it to your needs and not waste time by trying to do it with this script. This script is for bare metal installations." 29 | R; echo "NOTE$(N): $(W;format_string "$infstr" 6;N)" 30 | fi 31 | exit1 32 | fi 33 | } 34 | 35 | check_meshagent(){ 36 | local infstr 37 | if ${X[grep]} -qs "meshagent.service" /proc/self/cgroup; then 38 | infstr="You started this script in a MeshCentral terminal in meshagent context. This has not yet been extensively tested. You should run this script in an SSH root shell instead. Refer to this explanation video to learn how to establish an SSH connection in your MeshCentral: https://www.youtube.com/watch?v=7qAbl2OuZEU" 39 | R; echo "NOTE$(N): $(W;format_string "$infstr" 6;N)" 40 | exit 0 41 | fi 42 | } 43 | 44 | check_webmin(){ 45 | local config_file infstr 46 | config_file="/etc/webmin/xterm/config" 47 | if ${X[grep]} -qs "webmin.service" /proc/self/cgroup; then 48 | if ${X[grep]} -qs "locale=0" "$config_file"; then 49 | infstr="You started this script in a Webmin terminal. This is perfectly fine; however, the character encoding is not configured to display UTF-8 correctly. This script and its output makes use of some UTF-8 symbols and emojis. To enable UTF-8 encoding, click on the gear icon in the upper left corner of the terminal (this option is not available in full-screen mode). Then either select 'en_US.UTF-8' or choose 'Custom' and enter 'C.UTF-8' or any other valid UTF-8 locale and click 'Save'. If you cannot access this configuration, this script can fix it for you by updating the settings, restarting the Webmin service, and exiting. Simply press any key if you want me to switch the terminal to UTF-8. After that, click 'RECONNECT' and restart the script in the new terminal session." 50 | R;echo "NOTE$(N): $(W;format_string "$infstr" 6;N)" 51 | anykey 52 | sed_ 's/locale=0/locale=1/' "$config_file" '-i' 53 | trap 'exit_trap; systemctl restart webmin.service' EXIT 54 | exit 0 55 | fi 56 | fi 57 | } 58 | 59 | check_webmin_context(){ 60 | check_webmin 61 | } 62 | 63 | check_context(){ 64 | check_systemd 65 | check_meshagent 66 | check_webmin 67 | } 68 | -------------------------------------------------------------------------------- /modules/ask: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${ASK_BASHLIB:-_} && return 11 | ASK_BASHLIB=: 12 | 13 | # TODO 0 --> 14 | . <(lrequire basics) 15 | . <(lrequire ansi) 16 | . <(lrequire prefix) 17 | . <(lrequire awksed) 18 | # TODO 0 <-- 19 | . <(lrequire menu) 20 | 21 | # declare globals for ask handling 22 | declare YES NO Yes No 23 | YES="$(lG)yes$(N)" 24 | NO="$(R)no$(N)" 25 | Yes="[$(lG)y$(N)]es" 26 | No="[$(R)n$(N)]o" 27 | 28 | first_idx(){ 29 | local str qpref 30 | local -i i 31 | str="$1" qpref="$(qpf)" i=0 32 | # remove the prefix (qpref) from the beginning of the string. 33 | str="${str/#$qpref/$(printf '%*s' "${#qpref}" '')}" 34 | # iterates through the characters of the modified string 35 | # and print the index of the first non-space character. 36 | while (( i < ${#str} )); do 37 | char="${str:$i:1}" 38 | [ "$char" = ' ' ] || { 39 | echo "$i" 40 | return 41 | } 42 | ((i++)) 43 | done 44 | # if the entire string consists of spaces, prints the length of the string. 45 | echo "${#str}" 46 | } 47 | 48 | # $1 Question, $2 Default Answer, $3 Answer that returns 0 (true), $4 Answer that returns 1 (false) 49 | ask(){ 50 | required_args 2 "$@" 51 | kill_spinner 52 | local question d_answer yes no noansi_question_lastline noansi_d_answer noansi_yes noansi_no newline cursor 53 | local -l answer 54 | local -i lll lda ly ln ml fidx r max_cols 55 | question="$1" d_answer="$2" 56 | fidx=$(first_idx "$question") max_cols=$(max_cols) 57 | mh "$(fn_ln 1; es; to_one_line "$question")? [$d_answer]" 58 | [[ -z ${3:-} ]] && yes="$Yes" || yes="$3" 59 | [[ -z ${4:-} ]] && no="$No" || no="$4" 60 | noansi_question_lastline="$(${X[ansifilter]} <<< "${question##*\\n}")" 61 | noansi_d_answer="$(${X[ansifilter]} <<< "$d_answer")" 62 | noansi_yes="$(${X[ansifilter]} <<< "$yes")" 63 | noansi_no="$(${X[ansifilter]} <<< "$no")" 64 | lll=${#noansi_question_lastline} 65 | lda=${#noansi_d_answer} 66 | ly=${#noansi_yes} 67 | ln=${#noansi_no} 68 | if grep -qsw 'hide' "${F[cursor]}"; then 69 | cursor='hide' 70 | else 71 | cursor='show' 72 | fi 73 | ml=$(( max_cols - 23 )) 74 | if (( $(( lll + lda + ly + ln )) > ml )); then 75 | newline="$(printf '\n'; o $fidx; N)Make your choice: " 76 | else 77 | newline="$(N) " 78 | fi 79 | cursor_ show 80 | while :; do 81 | printf '\n%s' "$(N)$question?$newline($yes or $no) [$d_answer]: " 82 | read -r answer 83 | mh "$(fn_ln 1; es; apf)${answer:="$noansi_d_answer"}" 84 | if [ "$answer" = "$(desquare "${noansi_yes,,}")" ] || [ "$answer" = "$(insquare "${noansi_yes,,}")" ]; then 85 | r=0 86 | break 87 | elif [ "$answer" = "$(desquare "${noansi_no,,}")" ] || [ "$answer" = "$(insquare "${noansi_no,,}")" ]; then 88 | r=1 89 | break 90 | else 91 | o $fidx 92 | echo "- Please answer $(desquare "$noansi_yes") ($(insquare "$noansi_yes")) or $(desquare "$noansi_no") ($(insquare "$noansi_no"))." 93 | fi 94 | done 95 | cursor_ $cursor 96 | return $r 97 | } 98 | -------------------------------------------------------------------------------- /modules/php/apache2: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${PHP_APACHE2_BASHLIB:-_} && return 11 | PHP_APACHE2_BASHLIB=: 12 | 13 | . <(lrequire httpd) 14 | 15 | # globals 16 | if ! q2 declare -p SAPI_A2 | ${X[grep]} -qs 'declare -A'; then 17 | unset SAPI_A2 18 | q2 declare -gA SAPI_A2 || declare -A SAPI_A2 19 | fi 20 | 21 | apache2_mpm(){ 22 | mpm_module="$(q2 ${X[apache2ctl]} -M | ${X[gawk]} '/mpm/{print $1}')" 23 | case "$mpm_module" in 24 | mpm_event_module) [ "$1" = "event" ] && return 0 25 | ;; 26 | mpm_prefork_module) [ "$1" = "prefork" ] && return 0 27 | ;; 28 | *) return 1 29 | esac 30 | return 1 31 | } 32 | 33 | apache2_module(){ 34 | log_trace "$@" 35 | populate_a2modules && [[ " ${A2MODULES[@]%_module} " =~ " $1 " ]] 36 | } 37 | 38 | php_a2module_(){ 39 | log_trace "$@" 40 | case $1 in 41 | enable) required_args 2 "$@" 42 | ${X[a2enmod]} -q mpm_prefork php$2 &> >(log_trace) 43 | ;; 44 | disable) # [ -f "${F[php]:="${D[vt]}/php"}" ] && . "${F[php]}" 45 | # local mod 46 | # for mod in $(${X[ls]} /etc/apache2/mods-enabled/php*.load 2>$NUL | sed_ 's#^.*/php'${PHP[vregex]}'\.load$#php\1#p'); do 47 | # ${X[a2dismod]} -qf "$mod" &> >(log_trace) 48 | # done 49 | ${X[a2dismod]} -qf mpm_prefork &> >(log_trace) 50 | ;; 51 | switch2) required_args 2 "$@" 52 | php_a2module_ disable 53 | php_a2module_ enable $2 54 | ${X[systemctl]} restart apache2 &> >(log_trace) 55 | esac 56 | } 57 | 58 | php_fpm_module_(){ 59 | log_trace "$@" 60 | case $1 in 61 | enable) ${X[a2enmod]} -q mpm_event proxy_fcgi setenvif &> >(log_trace) 62 | ;; 63 | disable) ${X[a2dismod]} -qf mpm_event &> >(log_trace) 64 | esac 65 | } 66 | 67 | php_fpm_conf_(){ 68 | log_trace "$@" 69 | case $1 in 70 | enable) required_args 2 "$@" 71 | ${X[a2enconf]} -q php$2-fpm &> >(log_trace) 72 | ;; 73 | disable) [[ -f ${F[php]:="${D[vt]}/php"} ]] && . "${F[php]}" 74 | local mod 75 | for mod in $(q2 ${X[ls]} $(a2serverroot)/conf-enabled/php*-fpm.conf | sed_ 's#^.*/php'${PHP[vregex]}'-fpm\.conf$#php\1-fpm#p'); do 76 | ${X[a2disconf]} -qp "$mod" &> >(log_trace) 77 | done 78 | ;; 79 | switch2) required_args 2 "$@" 80 | php_fpm_conf_ disable 81 | php_fpm_conf_ enable $2 82 | ${X[systemctl]} restart apache2 php$2-fpm &> >(log_trace) 83 | esac 84 | } 85 | 86 | php_fpm_2_a2module(){ 87 | log_trace "$@" 88 | php_fpm_conf_ disable 89 | php_fpm_module_ disable 90 | php_a2module_ enable "$1" 91 | ${X[systemctl]} restart apache2 php$1-fpm &> >(log_trace) 92 | } 93 | 94 | php_a2module_2_fpm(){ 95 | log_trace "$@" 96 | php_a2module_ disable # $ver 97 | php_fpm_module_ enable 98 | php_fpm_conf_ enable "$1" 99 | ${X[systemctl]} restart apache2 php$1-fpm &> >(log_trace) 100 | } 101 | -------------------------------------------------------------------------------- /modules/nc-apps/assumed_version: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${ASSUMED_VERSION_BASHLIB:-_} && return 11 | ASSUMED_VERSION_BASHLIB=: 12 | 13 | . <(lrequire nc-apps/db) 14 | 15 | # TODO 0 --> 16 | # min_version(){ $(echo $(r_db "SELECT CASE WHEN major = (SELECT MIN(major) FROM versions) THEN platform ELSE NULL END AS result FROM versions;"));} 17 | # TODO 0 <-- 18 | assumed_version_select(){ 19 | local major query 20 | local -i n i version_num selected_index 21 | 22 | (( $# )) && major="WHERE major == ${1%%.*}" || major='' 23 | query="SELECT platform FROM versions $major ORDER BY major DESC, minor DESC;" 24 | 25 | read -ra available_versions < <(r_db "$query") 26 | 27 | echo "Please select the $2version you want to assume:" 28 | while :; do 29 | # Display the numbered list of available versions 30 | for i in "${!available_versions[@]}"; do 31 | echo "$((n + i)). ${available_versions[$i]}" 32 | done 33 | # Prompt for user input 34 | read -rp "Enter the number of the $2version of your choice: " version_num 35 | # Validate user input 36 | if ! [[ "$version_num" =~ ^[0-9]+$ ]]; then 37 | echo "Invalid input. Please enter a valid number." 38 | continue 39 | fi 40 | # Check if the chosen version number is within the valid range 41 | if (( version_num < n || version_num >= (n+${#available_versions[@]}) )); then 42 | echo "Invalid $2version number. Please choose a number from the list." 43 | continue 44 | fi 45 | # Get the selected backup directory 46 | selected_index=$((version_num - n)) 47 | if [ "$2" = "min_" ]; then 48 | NC[min_version]="${available_versions[$selected_index]}" 49 | else 50 | NC[version]="${available_versions[$selected_index]}" 51 | fi 52 | # eval echo \"Your choice: \$nc_$2version\" 53 | echo "Your choice: ${NC[$2version]}" 54 | echo "Do you want to assume this as $2version?" 55 | anykey 56 | # Exit the loop if a valid input is provided 57 | break 58 | done 59 | return 0 60 | } 61 | 62 | assumed_version_set(){ 63 | ${B[database_created]:-_} || create_database 64 | local cquery query 65 | if [[ ! ${1%%.*} =~ ^[0-9]+$ ]]; then 66 | assumed_version_select 67 | elif [ 0${1%%.*} -lt 0${NC[min_version]%%.*} ]; then 68 | o2; echo "the min version supported by this script is ${NC[min_version]}" 69 | if (( $# == 1 )); then 70 | NC[version]="${NC[min_version]}" 71 | fi 72 | else 73 | cquery="SELECT COUNT(platform) FROM versions WHERE major == ${1%%.*};" 74 | query="SELECT platform FROM versions WHERE major == ${1%%.*};" 75 | case $(r_db "$cquery") in 76 | 0) if [ "$2" = "min_" ]; then 77 | NC[min_version]=${1%%.*}.0.0 78 | else 79 | NC[version]=${1%%.*}.0.0 80 | fi 81 | ;; 82 | 1) if [ "$2" = "min_" ]; then 83 | NC[min_version]="$(r_db "$query")" 84 | else 85 | NC[version]="$(r_db "$query")" 86 | fi 87 | ;; 88 | *) assumed_version_select ${1%%.*} $2 89 | esac 90 | fi 91 | return 0 92 | } 93 | -------------------------------------------------------------------------------- /modules/php-updater/diff: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${DIFF_BASHLIB:-_} && return 11 | DIFF_BASHLIB=: 12 | 13 | . <(lrequire fstring) 14 | 15 | diff_other_files(){ 16 | local opath npath plu be 17 | local -i count c2 c3 18 | opath="$FILE" npath="${FILE//$OLD/$NEW}" c2=20 c3=25 19 | q0 ${X[diff]} <(sed_ "s/$OLD/@VERSION@/" "$opath" '-') <(sed_ "s/$NEW/@VERSION@/" "$npath" '-') && return # don't treat empty diffs 20 | # Count the number of lines starting with '<' 21 | count=$(${X[diff]} <(sed_ "s/$OLD/@VERSION@/" "$opath" '-') <(sed_ "s/$NEW/@VERSION@/" "$npath" '-') | ${X[grep]} -c '^<') 22 | if (( count == 1 )); then 23 | plu='' be=is 24 | elif (( count > 1 )); then 25 | plu='s' be=are 26 | else 27 | return # extra test to not treat empty diffs 28 | fi 29 | echo "$(pf; W; format_string "The file $(C)$FILE$(W), which is part of the $(Y)$PKGOLD$(W) package has been changed after installation. This script can migrate those changes for you, so look exactly what it suggests to do. If it does not look good, simply answer $(box no) and edit the file yourself as you need it." 3)" 30 | f 31 | echo "$(o3; W; format_string "This is the detected diff $(GRAY)(the $(dY)@VERSION@$(GRAY) string here is just used as neutral placeholder in order to only filter out the differences that matter)$(W). The line$plu preceded with '$(R)<$(W)' (red) $be from $(R)$opath$(W), while the coresponding line$plu from $(G)$npath$(W) $be preceded with '$(G)>$(W)' (green) :" 3; N)" 32 | f 33 | ${X[diff]} --color <(sed_ "s/$OLD/@VERSION@/" "$opath" '-') <(sed_ "s/$NEW/@VERSION@/" "$npath" '-') 34 | f 35 | o3; echo "Based on this diff, this script would suggest this:" 36 | line '=' P 2/a b1 # old config: 37 | line '-' GRAY 2/a 38 | o3; GRAY; echo "old:$(f; o5)- config-file$(o $c2)-->$(o $c3)$npath" 39 | line '-' GRAY 2/a 40 | GRAY; echo -n "--> begin" 41 | line " -->" GRAY 14 42 | cat $npath 43 | GRAY; echo -n "<-- end " 44 | line " <--" GRAY 14 45 | line '=' P 2/a # new config draft: 46 | line '-' GRAY 2/a 47 | o3; GRAY; echo "draft: (not yet written to file)$(f; o5)- config-file$(o $c2)-->$(o $c3)$npath" 48 | line '-' GRAY 2/a 49 | GRAY; echo -n "--> begin" 50 | line " -->" GRAY 14 51 | sed_ "s/$OLD/$NEW/g" $opath '-' 52 | GRAY; echo -n "<-- end " 53 | line " <--" GRAY 14 54 | line '=' P 2/a a2 55 | echo "$(pf; W; format_string "Nothing has been written to disc yet. If everything looks as desired and expected and you want to apply the changes exactly as shown here, then please enter $(Gbg) yes $(W)." 3; N)" 56 | line '=' P 2/a b1 57 | if ask "$(qpf)Apply changes to $npath as suggested" "$YES"; then 58 | sed_ "s/$OLD/$NEW/g" "$opath" "$npath" 59 | line '-' GRAY 2/a 60 | o3; GRAY; echo "new:$(f; o5)- config-file$(o $c2)-->$(o $c3)$npath" 61 | line '-' GRAY 2/a 62 | GRAY; echo -n "--> begin" 63 | line " -->" GRAY 14 64 | cat $npath 65 | GRAY; echo -n "<-- end " 66 | line " <--" GRAY 14 67 | line '=' P 2/a 68 | o3; echo "Changes written to disk" 69 | else 70 | o3; C; echo "$npath$(N) not changed.$(f; os)You can call this script again or edit $(C)$FILE$(N; f; os)with an editor of your choice." 71 | fi 72 | line '=' P 2/a 73 | } 74 | -------------------------------------------------------------------------------- /modules/php-module-builder/first_run: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${FIRST_RUN_BASHLIB:-false} && return 11 | FIRST_RUN_BASHLIB=: 12 | 13 | . <(lrequire php-module-builder/disclaimer) 14 | 15 | first_run_register_project_dir(){ 16 | local dir flags 17 | dir="$1" flags="" 18 | mh "vdir: $dir" 19 | ${X[mkdir]} -p "$dir" 20 | setvdir v "$dir" 21 | f 22 | o2; echo "- $(lG)first run wizard completed successfully."; N 23 | f 24 | ${B[force]} && flags="--force" 25 | ${B[remove]} && flags="$flags --remove" 26 | $ME "json=${J[o]}" $php_version $module $flags 27 | exit 0 28 | } 29 | 30 | first_run(){ 31 | disclaimer 32 | local yn q p dir 33 | local -l choice 34 | local -A bool 35 | yn="$(N)[$(lG)Y$(N)/$(R)n$(N)] " q="$(B)(or $(N)[$(P)q$(N)] $(B)to quit)$(N)" 36 | f 37 | o2; GRAY; echo "This step is required once after a new installation, sometimes after an update" 38 | o2; echo "or if$(N) --firstrun $(GRAY)was passed:" 39 | f 40 | o2; B; echo "Hello, this is the first run wizard of$(N) \"$(Y)$ME$(N)\"" 41 | while :; do 42 | if ${B[remove]}; then 43 | o2; B; echo "enter the directory where the$(N) \"$(Y)$project$(N)\" $(B)directory resides $q" 44 | read -rp " --> " p 45 | [ "${p,,}" = 'q' ] && exit 0 46 | dir="${p//\"/}" 47 | [ -d "$dir/$project" ] && first_run_register_project_dir "$dir" 48 | [ -d "$dir" ] && echo "$(o2;B)\"$(Y)$dir$(B)\" is an existing directory but it does not contain a subdirectory \"$project\"" 49 | else 50 | o2; B; echo "enter the directory where you want to create the$(N) \"$(Y)$project$(N)\" $(B)directory or where" 51 | o2; echo "you already have an older version of$(N) \"$(Y)$project$(N)\" $q" 52 | o2; GRAY; echo "a suggestion would be$(N) /root/projects $(GRAY)but you can choose any other location here";N 53 | while :; do 54 | read -rp " --> " p 55 | [ "${p,,}" = 'q' ] && exit 0 56 | dir="${p//\"/}" 57 | if [ -z "$dir" ]; then 58 | te0 59 | continue 60 | elif [ -d "$dir/$project" ]; then 61 | first_run_register_project_dir "$dir" 62 | elif [ -d "$dir" ]; then 63 | o2; B; echo "\"$(Y)$dir$(B)\" is an existing directory" 64 | prompt="$(o2)do you want to create the \"$(Y)$project$(N)\"$(B) dir inside? $yn$q " 65 | else 66 | o2; B; echo "\"$(Y)$dir$(B)\" is not an existing directory" 67 | prompt="$(o2; B)do you want to create? $yn$q " 68 | fi 69 | bool[firstloop]=: 70 | while :; do 71 | read -rsn 1 -p "$prompt" choice 72 | case ${choice:-y} in 73 | q) f; exit 0 ;; 74 | y) first_run_register_project_dir "$dir" ;; 75 | n) te1; o2; B; echo "enter the directory please $q:"; N; break ;; 76 | *) ${bool[firstloop]} && { bool[firstloop]=_; f; } 77 | te0; o2; B; echo "please enter $yn$q" 78 | esac 79 | done 80 | done 81 | fi 82 | done 83 | } 84 | -------------------------------------------------------------------------------- /modules/nc-who/help: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${HELP_BASHLIB:-_} && return 11 | HELP_BASHLIB=: 12 | 13 | # TODO 0 --> 14 | . <(lrequire nc/logo) 15 | # TODO 0 <-- 16 | print_help(){ 17 | local s 18 | local -A bool 19 | if (($(backups | ${X[wc]} -l))); then 20 | bool[bak]=: 21 | r_b(){ echo -e "\n $(dY)$ME $(O)restore_backup$(N)"; } 22 | [ $(backups | ${X[wc]} -l) -gt 1 ] && s=s || s='' 23 | else 24 | r_b(){ :; } 25 | fi 26 | ${X[cat]} < $(G)without arguments, you get to a selection menu$(N) 43 | 44 | $(C)Possible options:$(N) 45 | 46 | $(Yi)* Synopsis:$(N) 47 | 48 | $(dY)$ME $(O)-h $(GRAY)| $(O)--help$(N) 49 | $(dY)$ME $(O)monitor $(GRAY)[ $(O)--trace $(GRAY)]$(N) 50 | $(dY)$ME $(O)god$(N) 51 | $(dY)$ME $(O)last $(GRAY)[ $(O)--trace $(GRAY)]$(N) 52 | $(dY)$ME $(O)--firstrun$(N) 53 | $(dY)$ME $(O)integrity_check$(N; r_b) 54 | 55 | $(Yi)* Description:$(N) 56 | 57 | $(O)-h $(GRAY)| $(O)--help $(GRAY)Display this help message.$(N) 58 | 59 | $(O)monitor $(GRAY; format_string "Monitor live user logins, ordered by last activity at an adjustable refresh rate." 16 $max_cols; N) 60 | $(Yi)* $(GRAY; format_string "Login status is only available for cookie-based sessions on a web frontend." 18 $max_cols; N) 61 | $(Yi)* $(GRAY)Last activity is shown for all clients.$(N) 62 | 63 | $(O)god $(GRAY; format_string "In God mode you can invalidate cookies before they expire by deleting the corresponding authtoken from the database." 16 $max_cols; N) 64 | $(GRAY)You can switch to god mode from monitor mode and back.$(N) 65 | 66 | $(O)last $(GRAY; format_string "List users sorted by their last login time, unlike the unsorted output of" 16 $max_cols; N) 67 | $(Yi)*$(W) \`$(dY)occ user:lastseen --all$(W)\`$(N) 68 | 69 | $(C)Options not available in interactive mode:$(N) 70 | 71 | $(O)--trace $(W)In combination with:$(N) 72 | - $(Y)monitor$(W): $(GRAY)produce extensive log traces$(N) 73 | - $(Y)last$(W): $(GRAY)print the sql query used for the output$(N) 74 | 75 | $(O)--firstrun $(GRAY)re-run the firstrun wizard$(N) 76 | 77 | $(O)integrity_check$(N) 78 | $(GRAY)Verify the integrity of this script with signature$(N) 79 | 80 | HELP 81 | ${bool[bak]:-_} && ${X[cat]}<${NUL:=/dev/null} || _(){ false; } 11 | if (( M[e] < 1737773190 )); then 12 | q0(){ "$@" &>$NUL; } 13 | q1(){ "$@" >$NUL; } 14 | q2(){ "$@" 2>$NUL; } 15 | q0 declare -f lrequire || lrequire(){ req $@;} 16 | fi 17 | 18 | ${MH_BASHLIB:-_} && return 19 | MH_BASHLIB=: 20 | 21 | . <(lrequire binaries) 22 | . <(lrequire filter) 23 | . <(lrequire tempfile) 24 | 25 | # Create the FIFO pipes 26 | ${X[mkfifo]} -m 666 "${F[mhlog]:=$(tf u)}" "${F[mhcio]:=$(tf u)}" 27 | 28 | cio(){ 29 | c -Io NULL -A "$(fp)$*" ${V[cargs]}/${D[ri]}/mh.json 30 | } 31 | 32 | tofifo(){ 33 | # [[ -p "${F[mhcio]}" ]] && ${X[timeout]} 2 ${X[bash]} -c "echo '$*' > ${F[mhcio]}" 2>$NUL # this cannot handle special chars. 34 | [[ -p "${F[mhcio]}" ]] && ${X[timeout]} 2 ${X[bash]} -c 'echo "$1" > "$2"' @_@ "$*" "${F[mhcio]}" 2>$NUL # @_@ is a placeholder for the intern $0 35 | [[ -p "${F[mhlog]}" ]] && ${X[timeout]} 2 ${X[bash]} -c 'echo "$1" > "$2"' @_@ "$*" "${F[mhlog]}" 2>$NUL # @_@ is a placeholder for the intern $0 36 | } 37 | 38 | mh(){ 39 | local -A bool 40 | [[ "$-" =~ x ]] && { set +x; bool[debugx]=:; } || : 41 | local pl # payload 42 | pl="${*//\/usr\/bin\/env LC_ALL=C.UTF-8 \/usr\/bin\//}" 43 | pl="${pl//\/usr\/bin\/env LC_ALL=C \/usr\/bin\//}" 44 | tofifo "${pl//\/usr\/bin\/env LC_MESSAGES=C \/usr\/bin\//}" 45 | ${bool[debugx]:-_} && set -x || : 46 | return 0 47 | } 48 | 49 | haul(){ 50 | local hauler padding 51 | local -a pl 52 | local -i i i_max level 53 | hauler="$1" pl=() 54 | shift 55 | [[ ${FUNCNAME[1]} == bundle ]] && level=2 || level=1 56 | case "$hauler" in 57 | echo) [ "$1" = '-n' ] && shift 58 | tofifo "$(fn_ln $level) e: $(to_one_line "$@")" 59 | # mapfile -t pl < <(p_notempty "$(${X[ansifilter]} <<< "$@")" 2>&1) 60 | ;; 61 | printf) mapfile -t pl < <(p_notempty "$(${X[ansifilter]} <<< "$($@)")" 2>&1) ;; 62 | cat) mapfile -t pl < <(${X[grep]} -v '^[[:space:]]*$' "$@" 2>&1) 63 | esac 64 | if (( ${#pl[@]} == 1 )); then 65 | tofifo "$(fn_ln $level) ${hauler::1}: ${pl[0]}" 66 | elif (( ${#pl[@]} > 1 )); then 67 | i_max=${#pl[@]} 68 | (( i_max > 9 )) && padding="%0${#i_max}d" || padding='%d' 69 | for i in ${!pl[@]}; do 70 | tofifo "$(fn_ln $level) ${hauler::1}-$(printf "$padding" $((i+1))): ${pl[i]}" 71 | done 72 | fi 73 | } 74 | 75 | bundle(){ 76 | kill_spinner 77 | local hauler 78 | local -a pl 79 | local -i i 80 | hauler="$1" 81 | shift 82 | haul "$hauler" "$@" 83 | case "$hauler" in 84 | echo) echo -e "$@"; return ;; 85 | printf) mapfile -t pl < <($@) ;; 86 | cat) mapfile -t pl < <(${X[cat]} "$@") 87 | esac 88 | (( ${#pl[@]} )) && for i in ${!pl[@]}; do echo -e "${pl[i]}"; done 89 | } 90 | 91 | cio "ansifilter: ${X[ansifilter]/\/usr\/bin\/env LC_MESSAGES=C \/usr\/bin\/ansifilter/binary} - $(read -r p v < <(${X[sed]} --version); printf '%s' "$v")" 92 | # Background processes that reads lines from FIFO and processes them 93 | ( set +ex; while [[ -p "${F[mhlog]}" ]]; do while IFS= read -r line; do [[ "$line" == 'EOF' ]] && ${X[rm]} -f -- "${F[mhlog]}" || log "$(filter_ <<< "$line")"; done < "${F[mhlog]}"; done ) & 94 | ( set +ex; while [[ -p "${F[mhcio]}" ]]; do while IFS= read -r line; do [[ "$line" == 'EOF' ]] && ${X[rm]} -f -- "${F[mhcio]}" || cio "$(filter_ <<< "$line")"; done < "${F[mhcio]}"; done ) & 95 | -------------------------------------------------------------------------------- /modules/cleanup: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${CLEANUP_BASHLIB:-_} && return 11 | CLEANUP_BASHLIB=: 12 | 13 | cleanup() { 14 | ${B[trace]:-_} && return 0 || : 15 | local x 16 | for x in "$@"; do 17 | if [[ -d "$x" && "$x" != / && "$x" =~ ^(/tmp|/var/tmp|/dev/shm|/run/lock)(/|$) ]]; then 18 | ${X[rm]} -fr -- "$x" 19 | elif [[ -f "$x" ]]; then 20 | ${X[rm]} -f -- "$x" 21 | elif [[ -p "$x" ]]; then 22 | # G; echo "sending EOF to $x."; N 23 | echo EOF > "$x" 24 | fi 25 | done 26 | } 27 | 28 | cleanup_dangling_links(){ 29 | # usage: cleanup_dangling_links 30 | [[ -d $1 ]] || return 1 31 | # ${X[find]} "$1" -xtype l -print -delete | while read -r link; do # <- this is insecure 32 | # Only find truly dangling symlinks (not symlinks to other symlinks): 33 | # "find -xtype l" also matches links pointing to other links (e.g. Debian alternatives), 34 | # so we use "! -exec test -e {} ;" to only select realy dangling symlinks. 35 | ${X[find]} "$1" -xtype l ! -exec ${X[test]} -e {} \; -print -delete | while read -r link; do 36 | mh "$(fn_ln) removed: $link -> $(${X[realpath]} "$link")" 37 | done 38 | } 39 | 40 | cleanup_dangling_links_match(){ 41 | # usage: cleanup_dangling_links_match "" "" 42 | # Example: 43 | # cleanup_dangling_links_match "$dir" "linkname1 linkname2 linkname3" "/target/dir/1 /target/dir/2" 44 | [[ -d "$1" ]] || return 1 # return if "$1" is not a directory 45 | local link link_name allowed_link_name target allowed_target_dir 46 | local -a allowed_link_names allowed_target_dirs 47 | local -i should_delete allowed 48 | # OPTIONALY: only delete dangling link if its name matches one of these paterns: 49 | allowed_link_names=($2) # space-separated list of names to match 50 | # OPTIONALY: and / or only delete dangling link if theire target is located in one of these directories 51 | allowed_target_dirs=($3) # space-separated list of directories to match 52 | # ${X[find]} "$1" -xtype l -print | while IFS= read -r link; do # <- this is insecure 53 | # Only find truly dangling symlinks (not symlinks to other symlinks): 54 | # "find -xtype l" also matches links pointing to other links (e.g. Debian alternatives), 55 | # so we use "! -exec test -e {} ;" to only select dangling symlinks. 56 | ${X[find]} "$1" -xtype l ! -exec ${X[test]} -e {} \; -print | while IFS= read -r link; do 57 | target="$(${X[realpath]} "$link")" 58 | should_delete=1 # default: delete 59 | # If names array is set, only delete if the symlink's basename is in that array. 60 | if (( ${#allowed_link_names[@]} )); then 61 | link_name="$(${X[basename]} "$link")" 62 | allowed=0 63 | for allowed_link_name in "${allowed_link_names[@]}"; do 64 | if [[ "$link_name" == *"$allowed_link_name"* ]]; then 65 | allowed=1 66 | break 67 | fi 68 | done 69 | (( allowed )) || should_delete=0 70 | fi 71 | # If target_dirs is set, only delete if the symlink's target begins with that directory. 72 | if (( ${#allowed_target_dirs[@]} )); then 73 | allowed=0 74 | for allowed_target_dir in "${allowed_target_dirs[@]}"; do 75 | if [[ "$target" = "$allowed_target_dir"* ]]; then 76 | allowed=1 77 | break 78 | fi 79 | done 80 | (( allowed )) || should_delete=0 81 | fi 82 | (( should_delete )) && ${X[rm]} -f -- "$link" && mh "$(fn_ln) removed: $link -> $target" 83 | done 84 | } 85 | -------------------------------------------------------------------------------- /modules/php-updater/chfiles: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${CHFILES_BASHLIB:-_} && return 11 | CHFILES_BASHLIB=: 12 | 13 | . <(lrequire php/extensions) 14 | 15 | changed_files_(){ 16 | changed_mod_ini_files(){ 17 | [ -f "${F[php]:="${D[vt]}/php"}" ] && . "${F[php]}" 18 | local old new odir ndir ofile cfile ext_objfile ext_pkg omd5 nmd5 19 | local -a ofiles nfiles cfiles 20 | old="$1" new="$2" 21 | odir="/etc/php/$old/mods-available" 22 | ndir="/etc/php/$new/mods-available" 23 | mapfile -t ofiles< <(${X[ls]} "$odir") 24 | mapfile -t nfiles< <(${X[ls]} "$ndir") 25 | mapfile -t cfiles< <(${X[comm]} -12 <(p_sort ${ofiles[@]}) <(p_sort ${nfiles[@]})) 26 | for cfile in ${cfiles[@]}; do 27 | ext_objfile="/usr/lib/php/${EXG[$old]%%;*}/$(${X[gawk]} -F= '/extension=/ {print $2}' "$odir/$cfile")" 28 | [ -f "$ext_objfile" ] || continue 29 | ext_pkg="$(q2 ${X[dpkg]} -S "$ext_objfile" | ${X[gawk]} '{print$1}')" || continue 30 | if [ "${ext_pkg%-*}" = "php$old" ]; then 31 | omd5=$(${X[md5sum]} "$odir/$cfile" | ${X[gawk]} '{print$1}') 32 | nmd5=$(${X[md5sum]} "$ndir/$cfile" | ${X[gawk]} '{print$1}') 33 | [ "$omd5" = "$nmd5" ] || echo "${ext_pkg#*-}$odir/$cfile" 34 | fi 35 | done 36 | } 37 | ucf_query(){ 38 | local old new reg 39 | local -a ouf nuf juf # old_, new_ and joint_ucf_files 40 | old="$1" new="$2" reg=/var/lib/ucf/registry 41 | changed_mod_ini_files $old $new 42 | mapfile -t ouf< <(${X[gawk]} '/.*php\/'$old'/ {print $2}' "$reg") 43 | mapfile -t nuf< <(${X[gawk]} '/.*php\/'$new'/ {print $2}' "$reg") 44 | mapfile -t juf< <(${X[comm]} -12 <(p_sort ${ouf[@]##/etc/php/$old}) <(p_sort ${nuf[@]##/etc/php/$new})) 45 | ucfq -w $(printf /etc/php/$old'%s\n' "${juf[@]##/etc/php/$old}") | ${X[gawk]} -F: '/Yes$/ {gsub("php'$old'-","",$2);print $2 ":" $1}' 46 | } 47 | changed_other_files(){ 48 | local old new 49 | local -a oip nip jip files # old_, new_ and joint_installed_packages 50 | old="$1" new="$2" 51 | mapfile -t oip< <(${X[dpkg]} -l | ${X[gawk]} '/^[hiu]i.*php'$old'/{gsub("'$old'","@VERSION@",$2);print $2}') 52 | mapfile -t nip< <(${X[dpkg]} -l | ${X[gawk]} '/^[hiu]i.*php'$new'/{gsub("'$new'","@VERSION@",$2);print $2}') 53 | mapfile -t jip< <(${X[comm]} -12 <(p_sort ${oip[@]}) <(p_sort ${nip[@]})) 54 | for i in ${!jip[@]}; do 55 | pkg="${jip[i]//@VERSION@/$old}" 56 | mapfile -t files< <(${X[dpkg]} --verify $pkg | ${X[gawk]} '{print $NF}') 57 | if (( ${#files[@]} )); then 58 | printf ''${pkg#*-}':%s\n' "${files[@]}" | ${X[sort]} -u 59 | fi 60 | done 61 | } 62 | local old new pkg changed_file 63 | local -a changed_files files 64 | local -i r=1 65 | old="$2" new="$3" 66 | mapfile -t changed_files< <(changed_other_files $old $new) 67 | if [ "$1" = "ini" ]; then 68 | mapfile -t files< <(ucf_query $old $new) 69 | r=0 70 | fi 71 | if ((${#changed_files[@]})); then 72 | for i in ${!changed_files[@]}; do 73 | pkg=${changed_files[i]%:*} 74 | changed_file=${changed_files[i]#*:} 75 | [ -f "$changed_file" ] || continue 76 | case $1 in 77 | ini) [[ "$changed_file" =~ ^/etc/php/$old/.*\.ini ]] && files+=("${changed_files[i]}") ;; 78 | conf) [[ "$changed_file" =~ ^/etc/php/$old/.*\.conf ]] && files+=("${changed_files[i]}") ;; 79 | other) [[ ! "$changed_file" =~ ^/etc/php/$old/ ]] && files+=("${changed_files[i]}") r=0 80 | esac 81 | done 82 | fi 83 | p_sort "${files[@]}" 84 | return $r 85 | } 86 | -------------------------------------------------------------------------------- /modules/nc/nextcloud: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${NC_NEXTCLOUD_BASHLIB:-_} && return 11 | NC_NEXTCLOUD_BASHLIB=: 12 | 13 | . <(lrequire php/version) 14 | . <(lrequire nc/aio) 15 | . <(lrequire nc/c2j) 16 | 17 | [[ -f ${F[nc]:=${D[vt]}/nc} ]] && . ${F[nc]} 18 | 19 | if ${B[firstrun]:-_}; then 20 | [[ -f ${F[nc]:-} ]] && > "${F[nc]}" 21 | . <(req nc/first_run) 22 | first_run 23 | fi 24 | 25 | if [[ -n ${NC[u]} && ${I[un]} != ${NC[u]} && ${I[u]} != 0 ]]; then 26 | su_do "u=NC_USER" 27 | fi 28 | 29 | [[ $(q2 declare -p NC) =~ 'declare -A' ]] || { declare -gA NC 2>$NUL || declare -A NC; } 30 | 31 | if [[ -z "${NC[d]}" || -z "${NC[cd]}" || -z "${NC[dd]}" || -z "${NC[du]}" || -z "${NC[dg]}" || -z "${NC[u]}" || -z "${NC[g]}" || -z "${NC[vphp]}" ]]; then 32 | if ${B[aio]}; then 33 | NC[d]="/var/lib/docker/volumes/nextcloud_aio_nextcloud/_data" 34 | NC[cd]="${NC[d]}/config" # NC_CDIR 35 | NC[dd]="/var/lib/docker/volumes/nextcloud_aio_nextcloud_data/_data" 36 | else 37 | q0 declare -p NC_DIR && [[ -d $NC_DIR && ! -d ${NC[d]} ]] && NC[d]=$NC_DIR 38 | 39 | # detect location of config.php 40 | if [ -d "${NC[d]}" ]; then 41 | NC[du]=$(${X[stat]} -c %U ${NC[d]} 2> >(log_trace)) 42 | NC[dg]=$(${X[stat]} -c %G ${NC[d]} 2> >(log_trace)) 43 | if cd ${NC[d]} 2> >(log_trace); then 44 | NC[cd]=$(${X[php]} -r 'require_once "lib/base.php"; OC::initPaths(); echo rtrim(OC::$configDir, "/");' 2> >(log_trace)) 45 | cd 46 | [[ -n ${NC[cd]} && -d ${NC[cd]} ]] || NC[cd]="${NC[d]}/config" 47 | # pick out NC[u] 48 | if (( $(${X[stat]} -c %u ${NC[cd]}/config.php 2> >(log_trace)) )); then 49 | NC[u]="$(${X[stat]} -c %U ${NC[cd]}/config.php 2> >(log_trace))" 50 | NC[g]="$(${X[stat]} -c %G ${NC[cd]}/config.php 2> >(log_trace))" 51 | fi 52 | elif [[ "${NC[du]}" = root && "${NC[dg]}" != root ]]; then 53 | NC[u]=${NC[dg]} 54 | fi 55 | fi 56 | 57 | # if NC[u] and/or NC[g] still unknown, try these fallbacks: 58 | [ -n "${NC[u]}" ] || NC[u]="$(${X[ps]} -o user $(${X[pgrep]} -f "php|apache2|httpd|nginx") | ${X[gawk]} 'NR>1' | ${X[sort]} -u | ${X[grep]} -v root)" 59 | [ -n "${NC[g]}" ] || NC[g]="$(${X[ps]} -o group $(${X[pgrep]} -f "php|apache2|httpd|nginx") | ${X[gawk]} 'NR>1' | ${X[sort]} -u | ${X[grep]} -v root)" 60 | [ -n "${NC[u]}" ] || NC[u]="$(q2 ${X[apache2ctl]} -S | ${X[gawk]} -F '[" ]' '/User:/ { print $3 }')" 61 | [ -n "${NC[g]}" ] || NC[g]="$(q2 ${X[apache2ctl]} -S | ${X[gawk]} -F '[" ]' '/Group:/ { print $3 }')" 62 | 63 | # only load firstrun module if needed 64 | if [ ! -d "${NC[d]}" ]; then 65 | . <(req nc/first_run) 66 | first_run 67 | elif [[ "${I[un]}" != "${NC[u]}" && ! -r "${NC[d]}" ]]; then 68 | su_do "u=NC_USER" 69 | elif [ ! -r "${NC[d]}/lib/base.php" ]; then 70 | . <(req nc/first_run) 71 | first_run 72 | fi 73 | 74 | if [ -z "${NC[dd]}" ]; then 75 | if nc_configkey_exist_ datadirectory; then 76 | NC[dd]="$(nc_configkey datadirectory)" 77 | elif [ -d "${NC[d]}/data" ]; then 78 | NC[dd]="${NC[d]}/data" 79 | else 80 | NC[dd]="" 81 | fi 82 | fi 83 | fi 84 | NC[vphp]="${NC[d]}/version.php" 85 | fi 86 | 87 | q0 declare -p NC_DIR && [[ $NC_DIR != ${NC[d]} ]] && ${B[rt]} && setvdir v "${NC[d]}" 88 | 89 | [ -n "${NC[github_raw]}" ] || NC[github_raw]='https://raw.githubusercontent.com/nextcloud' 90 | 91 | mh $(declare -p NC | ${X[tee]} "${F[nc]}") 92 | ${B[rt]} && ${X[chown]} 0:0 "${F[nc]}" 93 | ${X[chmod]} 666 "${F[nc]}" 94 | 95 | -------------------------------------------------------------------------------- /modules/php-updater/inp: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${INP_BASHLIB:-_} && return 11 | INP_BASHLIB=: 12 | 13 | . <(lrequire spinner) 14 | . <(lrequire fstring) 15 | . <(lrequire dpkg) 16 | . <(lrequire php/extensions) 17 | . <(lrequire php-updater/pdiff) 18 | 19 | install_new_php(){ 20 | local old new package sapi 21 | local -a packages sapi_packages # sapi_not 22 | old="$1" new="$2" 23 | apt_need_update 24 | # TODO 0 --> 25 | if [[ ! libapache2-mod-php$old && ! php$old-fpm ]]; then 26 | There is no sapi installed for php$old to communicate with your webserver.. Transfering the settings from that incomplete version would result in a php$new without connection to your webserver either. You must Choose an other version as $old or first install the sapi of your choice. 27 | fi 28 | # TODO 0 <-- 29 | 30 | if q0 apt-cache show php$new; then 31 | separator 32 | # TODO 1 --> 33 | # update first? 34 | f 35 | echo "$(pf; format_string "An update is not recommended at this point but possible. However, if you answer $(box yes) here, all PHP related packages will be marked 'hold' to remain the initial php-situation unchanged." 3)" 36 | if ask "$(qpf)Do you want to update the system first " "$NO"; then 37 | q0 ${X[apt-mark]} hold $(${X[dpkg]} -l | ${X[gawk]} '/^[hiu]i.*php*/{print $2}') # hold php as it is for this step. 38 | ${X[apt-get]} dist-upgrade 39 | pf; echo "$(lG)system updated$(N)" 40 | anykey 41 | fi 42 | # TODO 1 <-- 43 | detect_and_assign_extensions 44 | search_candidates_4_extensions_installed_by_admin $old 45 | spinner C " . performing thorough review (dry run) of package sources and for candidate availability ." & 46 | mapfile -t packages< <(packages_diff $old $new) 47 | # TODO 2 --> 48 | mapfile -t sapi_packages< <(for sapi in $(${X[comm]} -23 <(p_sort $(${X[phpquery]} -v $old -S)) <(p_sort $(${X[phpquery]} -v $new -S))); do echo "${SAPI[$sapi]/@VER@/$new}"; done) 49 | mapfile -t sapi_not< <(for sapi in $(${X[comm]} -23 <(p_sort ${!SAPI[@]}) <(p_sort $(${X[phpquery]} -v $old -S))); do echo "${SAPI[$sapi]/@VER@/$new}"; done) 50 | # TODO 2 <-- 51 | q0 ${X[apt-mark]} unhold *php* 52 | [ -z "${X[needrestart]}" ] || export NEEDRESTART_SUSPEND=1 53 | kill_spinner 54 | if (( ${#packages[@]} )); then 55 | apt_ install --yes ${packages[@]} 56 | fi 57 | # TODO 3 --> 58 | if (( ${#sapi_packages[@]} || ${#packages[@]} )); then 59 | apt_ install --yes ${sapi_packages[@]} ${packages[@]} 60 | fi 61 | if ((${#sapi_not[@]})); then 62 | apt_ remove --yes ${sapi_not[@]} 63 | fi 64 | # TODO 3 <-- 65 | [ -z "${X[needrestart]}" ] || ${X[needrestart]} -r a 66 | else f 67 | no_candidate "$new" 68 | exit1 69 | fi 70 | separator 71 | f 72 | echo "$(pf; format_string "$(P)If everything looks good so far, the migration of the settings from $(B)php-$(C)$old$(P) to $(B)php-$(C)$new$(P) can be started. If you answer $(box no) here or abort the migration process on some point $(GRAY)(with Ctrl-C)$(P), you can always call and start this step again with" 3)" 73 | f 74 | echo "$(G; prompt; B) $ME${FLAG[forceflag]} $(C)$old $new"; N 75 | f 76 | o3; P; echo "to finalize or redo the migration."; N 77 | f 78 | echo "$(pf; format_string "$(P)Please be aware that a malicious configuration under $(B)php-$(C)$old$(P) will also be migrated. This script does not yet check for all thinkable wrong configurations. This will change step by step in future." 3; N)" 79 | if ask "$(qpf)Proceed with next step" "$YES"; then 80 | separator 81 | exec "$ME${FLAG[forceflag]}" "json=${J[o]}" $old $new 82 | else 83 | exit0 84 | fi 85 | } 86 | -------------------------------------------------------------------------------- /modules/filter: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${FILTER_BASHLIB:-_} && return 11 | FILTER_BASHLIB=: 12 | 13 | . <(lrequire binaries) 14 | 15 | # fallback function for ansifilter 16 | # switched to in 'binaries_extra_treatments' functon: 17 | # : ${X[ansifilter]:=filter_ansi} &>${NUL:=/dev/null} 18 | filter_ansi(){ 19 | # the sed_ dispatcher function is not yet sourced here. 20 | ${X[sed]} -E 's/\x1B\[[0-9;?]*[a-zA-Z]//g' 21 | } 22 | # X[ansifilter]=filter_ansi # <- this only for testing purposes 23 | 24 | filter_utf(){ 25 | ${X[perl]} -CSD -pe "$(${X[cat]} << 'PERLSCRIPT' 26 | # Convert \uXXXX notation to the corresponding Unicode character: 27 | s/\\u([0-9A-Fa-f]{4})/chr(hex($1))/ge; 28 | # Remove various invisible Unicode characters: 29 | s/\x{00A0}//g; # Non-breaking Space (NBSP) 30 | s/\x{2000}//g; # En Quad (EN QUAD) 31 | s/\x{2001}//g; # Em Quad (EM QUAD) 32 | s/\x{2002}//g; # En Space (EN SPACE) 33 | s/\x{2003}//g; # Em Space (EM SPACE) 34 | s/\x{2004}//g; # Three-Per-Em Space (3/4 EM SPACE) 35 | s/\x{2005}//g; # Four-Per-Em Space (4/4 EM SPACE) 36 | s/\x{2006}//g; # Six-Per-Em Space (6/4 EM SPACE) 37 | s/\x{2007}//g; # Figure Space (F SP) 38 | s/\x{2008}//g; # Punctuation Space (PU SP) 39 | s/\x{2009}//g; # Thin Space (TH SP) 40 | s/\x{200A}//g; # Hair Space (H SP) 41 | s/\x{200B}//g; # Zero Width Space (ZWSP) 42 | s/\x{200C}//g; # Zero Width Non-Joiner (ZWNJ) 43 | s/\x{200D}//g; # Zero Width Joiner (ZWJ) 44 | s/\x{200E}//g; # Left-To-Right Mark (LRM) 45 | s/\x{200F}//g; # Right-To-Left Mark (RLM) 46 | s/\x{2028}//g; # Line Separator (L SEP) 47 | s/\x{2029}//g; # Paragraph Separator (P SEP) 48 | s/\x{202A}//g; # Left-To-Right Enbedding (LRE) 49 | s/\x{202B}//g; # Right-To-Left Enbedding (RLE) 50 | s/\x{202C}//g; # Pop Directional Formatting (PDF) 51 | s/\x{202D}//g; # Left-To-Right Override (LRO) 52 | s/\x{202E}//g; # Right-To-Left Override (RLO) 53 | s/\x{202F}//g; # Narrow No-Break Space (NNB SP) 54 | s/\x{205F}//g; # Medium Mathematical Space (M SP) 55 | s/\x{2060}//g; # Word Joiner (WJ) 56 | # Replace special Unicode characters: 57 | s/\x{2018}/'/g; # Replace LEFT SINGLE QUOTATION MARK with a single quote 58 | s/\x{2019}/'/g; # Replace RIGHT SINGLE QUOTATION MARK with a single quote 59 | s/\x{201C}/'/g; # Replace LEFT DOUBLE QUOTATION MARK with a single quote 60 | s/\x{201D}/'/g; # Replace RIGHT DOUBLE QUOTATION MARK with a single quote 61 | s/\x{2026}/.../g; # Horizontal Ellipsis … to ... 62 | s/\x{2605}/*/g; # Unicode ★ to * 63 | s/\x{2606}/*/g; # Unicode ☆ to * 64 | s/\x{26A0}/!/g; # Unicode ⚠️ to ! 65 | s/\x{272A}/*/g; # Unicode ✪ to * 66 | s/\x{2730}/*/g; # Unicode ✰ to * 67 | s/\x{2736}/*/g; # Unicode ✶ to * 68 | s/\x{FE0E}//g; # Variation Selector-15 (text) 69 | s/\x{FE0F}//g; # Variation Selector-16 (emoji) 70 | s/\x{FFFC}//g; # Object Replacement Character 71 | s/\x{FFFD}//g; # Replacement Character 72 | s/\x{1F44D}/:+1:/g; # Thumb up (Unicode 👍) to :+1: 73 | s/\x{1F64F}/:pray:/g; # Folded hands (Unicode 🙏) to :pray: 74 | # This is to filter the name of Ondřej Surý: 75 | s/\x{0159}/r/g; # Latin small letter r with caron ř -> r 76 | s/\x{00FD}/y/g; # Latin small letter y with acute ý -> y 77 | PERLSCRIPT 78 | )" 79 | } 80 | 81 | filter_(){ 82 | ${X[cat]} | ${X[ansifilter]} | filter_utf 83 | } 84 | -------------------------------------------------------------------------------- /modules/php/alternatives: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${PHP_ALTERNATIVES_BASHLIB:-_} && return 11 | PHP_ALTERNATIVES_BASHLIB=: 12 | 13 | # TODO 0 --> 14 | . <(lrequire binaries) 15 | . <(lrequire basics) 16 | . <(lrequire button) 17 | . <(lrequire exit) 18 | . <(lrequire anykey) 19 | . <(lrequire awksed) 20 | . <(lrequire ask) 21 | . <(lrequire dpkg) 22 | . <(lrequire spinner) 23 | . <(lrequire fstring) 24 | . <(lrequire today) 25 | . <(lrequire php/versions) 26 | # TODO 0 <-- 27 | ## PHP related: 28 | # $1=grep -E search string: "ph(ar|p)" 29 | # $2=modus manual/auto 30 | # $3=old: 8.1 31 | # $4=new: 8.2 32 | set_selections(){ 33 | required_args 4 "$@" 34 | local regex modus old new mf 35 | regex="$1" modus="$2" old="$3" new="$4" 36 | q0 ${X[apt-mark]} unhold *php* 37 | [ "$modus" = "manual" ] && mf=auto 38 | [ "$modus" = "auto" ] && mf=manual 39 | ${X[update-alternatives]} --get-selections | ${X[grep]} -E "$regex" | sed_ "s/$mf/$modus/; s/$old/$new/" | q0 ${X[update-alternatives]} --set-selections 40 | } 41 | 42 | # switch all findable php related packages to manual 43 | # if $1 and $2 are given, then change from $1 to $2 44 | # $1=old: 8.1 45 | # $2=new: 8.2 46 | switch_php(){ 47 | required_args 2 "$@" 48 | set_selections "ph(ar|p)" "manual" "$1" "$2" 49 | } 50 | 51 | # switch all findable php related packages to manual Version $1 if $1 exists 52 | switch_php_to_(){ 53 | require_arg $@ 54 | [ -f "${F[php]:="${D[vt]}/php"}" ] && . "${F[php]}" 55 | q0 ${X[apt-mark]} manual $(${X[dpkg]} -l | ${X[gawk]} '/^[hiu]i.*php*/{print $2}') 56 | set_selections "ph(ar|p)" "manual" "${PHP[vregex]/)/|\\.default)}" "$1" 57 | # TODO 2 --> 58 | # q0 ${X[apt-mark]} hold $(${X[dpkg]} -l | ${X[gawk]} '/^[hiu]i.*php*/{print $2}') 59 | # TODO 2 <-- 60 | } 61 | 62 | list_alternatives(){ 63 | local regex target target_version name mode path 64 | regex="${1:-ph(ar|p)}" 65 | ${X[update-alternatives]} --get-selections 2>&1 | ${X[grep]} -E "$regex" | while read -r name mode path; do 66 | if target="$(q2 ${X[realpath]} "$path")"; then 67 | target_version="$(q2 echo "$target" | ${X[grep]} -o "[0-9.]*")" 68 | if [[ "$path" =~ default ]]; then 69 | printf "%-30s %-8s %-30s%s\n" "$name" "$mode" "$path" "$(GRAY)-> ${path//.default/${target_version%.}}$(N)" 70 | else 71 | printf "%-30s %-8s %-30s\n" "$name" "$mode" "$path" 72 | fi 73 | else 74 | printf "%-30s %-8s %-30s%s\n" "$name" "$mode" "$path" "$(xpf)no target - dead link!" 75 | fi 76 | done 77 | } 78 | 79 | list_alternatives_extended(){ 80 | [ -n "${X[update-alternatives]}" ] || { echo -e "\e[31mERROR: no 'update-alternatives' binary\e[0m" >&2; return 1; } 81 | local regex candidate key value 82 | regex="${1:-ph(ar|p)}" 83 | for candidate in $(q2 ${X[update-alternatives]} --get-selections | ${X[gawk]} '/'$regex'/{print $1}'); do 84 | echo -e "Name: $candidate" 85 | ${X[update-alternatives]} --query "$candidate" | ${X[grep]} -Ev '(^$|Name:)' | while IFS= read -r line; do 86 | if [[ "$line" =~ (Slaves|Priority) ]]; then 87 | echo " \`- $line" 88 | elif [[ "$line" =~ ^([^:]+):\ (.*) ]]; then 89 | key="${BASH_REMATCH[1]}" 90 | value="${BASH_REMATCH[2]}" 91 | pf; echo "$key: $value" 92 | else 93 | echo " \`- $line" 94 | fi 95 | done 96 | done 97 | } 98 | 99 | # repair broken alternatives, remove not existing alternatives 100 | cleanup_and_fix_alternatives(){ 101 | if [ -n "${X[update-alternatives]}" ]; then 102 | q0 ${X[update-alternatives]} --force --all < <(${X[yes]} '') 103 | # TODO 4 --> 104 | # ${X[yes]} '' | ${X[update-alternatives]} --force --all &>$NUL 105 | # TODO 4 <-- 106 | fi 107 | } 108 | -------------------------------------------------------------------------------- /modules/tempfile: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${TEMPFILE_BASHLIB:-_} && return 11 | TEMPFILE_BASHLIB=: 12 | 13 | # TODO 0 --> 14 | # . <(lrequire binaries) 15 | # TODO 0 <-- 16 | . <(lrequire exit) 17 | 18 | chrf(){ 19 | ${X[find]} $1 -type d -exec ${X[chmod]} -f 777 {} + 20 | ${X[find]} $1 -type f -exec ${X[chmod]} -f 666 {} + 21 | ${B[rt]} && [[ $2 ]] && ${X[chown]} -R $2:${3:-$2} $1 22 | } 23 | 24 | # tempfile creation $1=u (--dry-run) 25 | tf(){ 26 | local arg t u='' mode='' dir=td 27 | for arg in $@; do 28 | case $arg in 29 | u) u=u ;; 30 | 666|777) mode=$arg ;; 31 | shm) dir=$arg 32 | esac 33 | done 34 | t="$(${X[mktemp]} -p ${D[$dir]} -${u}t ${M[b]}${M[pid]}_XXXXXXXXXXXX)" 35 | # TODO 1 --> 36 | # t="$(${X[mktemp]} -p $TD -${u}t ${M[b]:-$$}_XXXXXXXXXXXX)" 37 | # TODO 1 <-- 38 | if [ -z "$u" ]; then 39 | if [ -n "$mode" ]; then 40 | ${X[chmod]} $mode "$t" 41 | fi 42 | fi 43 | echo "$t" 44 | } 45 | 46 | ${FP_BASHLIB:-_} || { 47 | : "${TD:=/tmp}" # if TD is empty, prefill it with /tmp 48 | [[ "$TD" == '/' || ! -d "$TD" ]] && TD='/tmp' # if TD is / or not a directory we use /tmp 49 | [ -d "$TD" ] || { # if after these tests, $TD is still not a directory, try the candidates 50 | for x in /run/user/${I[u]} /var/tmp ~/tmp; do 51 | [ -d "$x" ] && { TD="$x"; break; } 52 | done 53 | } 54 | # remove trailing slash 55 | TD="${TD%/}" 56 | [ -d "$TD" ] && { 57 | V[tsa]=$(${X[stat]} -c %A $TD) 58 | while :; do 59 | [[ $TD == */user/${I[u]} && $(${X[stat]} -c %u%g $TD) == ${I[u]}${I[g]} ]] && break # directory is owned by the user and can be used 60 | [[ $TD == */user && ${V[tsa]} == ${V[w]} ]] && { TD="$TD/${I[u]}"; break; } # user subdirectory exists, directory can be created 61 | [[ ${V[tsa]} == ${V[w]} ]] && { ${X[mkdir]} -pm 1777 $TD/user; TD=$TD/user/${I[u]}; } # user subdirectory does not exist, can be created 62 | break 63 | done 64 | } 65 | D[t]="${TD%/user*}" # basic temp dir /tmp 1777 root root exists 66 | D[tu]="${D[t]}/user" # user temp dir /tmp/user 1777 root root created in tempdir 67 | D[tp]="${D[t]}/${M[p]}" # project temp dir /tmp/ebtb - 1777 root root created in tempdir 68 | D[log]="${D[tp]}/log" # project log dir /tmp/ebtb/log 1777 root root created in tempdir 69 | D[lu]="/run/lock/user" # lock dir for user /run/lock/user 1777 root root created in tempdir 70 | D[vt]="/var/tmp/${M[p]}" # /var/tmp dir /var/tmp/ebtb 0777 root root created in general 71 | D[vtm]="${D[vt]}/modules" # /var/tmp dir /var/tmp/ebtb/modules 1777 root root created in general 72 | D[shm]="/dev/shm/${M[p]}" # shm dir /dev/shm/ebtb 0777 root root created in fp 73 | for x in tu:1 tp:1 log:1 lu:1 vt:0 vtm:1 shm:0; do 74 | if [ -d "${D[${x%:*}]}" ]; then 75 | ${X[chmod]} -f ${x#*:}777 ${D[${x%:*}]} 76 | ${B[rt]} && ${X[chown]} -f 0:0 ${D[${x%:*}]} 77 | else 78 | q2 ${X[mkdir]} -pm ${x#*:}777 ${D[${x%:*}]} 79 | fi 80 | done 81 | } 82 | 83 | # create the directory if it does not exist, with permissions 700 84 | [ -d "${D[t]}/user-${I[u]}" ] && q0 ${X[mv]} "${D[t]}/user-${I[u]}" $TD 85 | [ -d "$TD" ] || ${X[mkdir]} -pm 700 "$TD" 86 | ${X[chmod]} 0700 "$TD" 87 | # create a temporary file in the directory TD and store its name in the variable ttf 88 | declare ttf="$(${X[mktemp]} -p "$TD")" 89 | # if the temporary file exists, remove it 90 | [[ -n "$ttf" && -f "$ttf" ]] && cleanup "$ttf" || { 91 | # if the temporary file was not created, print an error message 92 | echo -e "\e[31mERROR: TMPDIR '$TD' is not writable by user '${I[un]}'\e[0m" >&2 93 | exit 1 94 | # [ -t 0 ] || exit 1 # no `exit 1` in terminal! 95 | } 96 | # unset the temporary file variable 97 | unset ttf 98 | D[td]=$TD 99 | -------------------------------------------------------------------------------- /modules/backcomp: -------------------------------------------------------------------------------- 1 | __minified_bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | binaries_is_func_ _ || _(){ false; } 11 | ${BACKCOMP_BASHLIB:-_} && return 12 | BACKCOMP_BASHLIB=: 13 | 14 | # for backwards compatibility: 15 | if q0 declare -p deps && ! q0 declare -p dependencies; then 16 | declare -a dependencies=("${deps[@]}") 17 | fi 18 | 19 | binaries_is_func_ q0 || q0(){ "$@" &>/dev/null; } 20 | binaries_is_func_ q1 || q1(){ "$@" >/dev/null; } 21 | binaries_is_func_ q2 || q2(){ "$@" 2>/dev/null; } 22 | binaries_is_func_ fn_ln || fn_ln(){ 23 | local ln fn f t 24 | read -r ln fn f <<< "$(caller ${1:-0})" 25 | t="$(${C[rp]} $f)" 26 | [[ $t = $MP ]] && f="${M[n]}" t="${M[n]}" 27 | [[ $fn = main ]] && fn='' || fn="$fn():" 28 | if [[ $t =~ /fd/ ]]; then 29 | echo -n "$fn$ln:" 30 | elif [ "$t" = "$f" ]; then 31 | echo -n "$f:$fn$ln:" 32 | else 33 | echo -n "$f->$t:$fn$ln:" 34 | fi 35 | } 36 | binaries_is_func_ trace || trace(){ 37 | local f t 38 | local -i i d 39 | # build a single-line trace: f1 -> f2 -> … 40 | d=$(( ${#FUNCNAME[@]} - $(( 1 + ${2:-0} )) )) 41 | t='' 42 | for (( i=d; i>${1:-0}; i-- )); do 43 | f=$(fn_ln $i) 44 | (( i == d )) && t="$f" || t+="->$f" 45 | done 46 | printf '%s' "$t" 47 | } 48 | 49 | [ "$(q2 declare -p TD)" = 'declare -n TD="TMPDIR"' ] || declare -n TD=TMPDIR 50 | 51 | for x in jq xmlstarlet ansifilter; do 52 | (q0 command -v $x && [[ ! "${X[$x]}" =~ /$x ]]) && X[$x]="${X[env]} LC_MESSAGES=C $(command -v $x)" &>$NUL 53 | done 54 | 55 | # Migrate legacy variables into new variable names 56 | 57 | : "${ME:=$me}" 58 | : "${MS:=$sin}" 59 | : "${MP:=${ca_me:-$canonical_me}}" 60 | : "${MD:=${ca_dir:-$canonical_dir}}" 61 | : "${NUL:=/dev/null}" 62 | : "${TTY:=/dev/tty}" 63 | : "${M[b]:=${bm:-$basename_me}}" 64 | : "${M[ap]:=$apm}" 65 | : "${M[n]:=$scriptname}" 66 | : "${M[e]:=${M[epoch]:-${epoch:-1741041000}}}" 67 | : "${M[v]:=$version}" 68 | : "${M[p]:=ebtb}" 69 | : "${M[pid]:=$$}" 70 | : "${D[l]:=${D[lu]:=/run/lock/user}/${I[u]}}" 71 | : "${D[li]:=${lincld:-$includedir}}" 72 | : "${D[ri]:=$rincld}" 73 | : "${D[tu]=${D[t]:=${TD%/user*}}/user}" 74 | : "${D[tp]:=${D[t]}/${M[p]}}" 75 | : "${D[log]:=${D[tp]}/log}" 76 | : "${D[shm]:=/dev/shm/${M[p]}}" 77 | : "${D[vt]:=/var/tmp/${M[p]}}" 78 | : "${F[log]:=${D[log]}/${M[b]}[uid:${I[u]}].log}" 79 | : "${F[fp]:=${D[vt]}/fp}" 80 | : "${F[lmj]:=$lmj}" 81 | : "${F[rmj]:=$rmj}" 82 | : "${F[lmjn]:=$lmjn}" 83 | : "${J[e]:=${J[epoch]:-${my_epoch:-}}}" 84 | : "${J[o]:=${J[json]:-${my_json:-}}}" 85 | : "${V[cargs]:=$cargs}" 86 | : "${V[upinf]:=${upinf:-${updateinfo:-}}}" 87 | : "${V[w]:=drwxrwxrwt}" 88 | : "${CMA:=$ME json=${J[o]} $@}" 89 | : "${T[rte]:=${rte:-}}" 90 | : "${T[mje]:=${mje:-}}" 91 | : "${T[mjne]:=${mjne:-}}" 92 | 93 | # removed function for backwards compatibility: 94 | populate_pkgs_by_dpkg_array(){ :; } 95 | 96 | if (( M[e] <= 1741041000 )); then 97 | echo -e "\n\n\e[31m - The current script version is to old for the integrated updater.\n The integrated updater no longer works here because necessary\n but meanwhile deprecated modules are no longer available.\n\n Please run\n\n\e[37m sudo\e[36m wget -O $ca_me https://global-social.net/script/$bm\n\n\e[31m and start the script again if an update is not offered or fails.\e[0m\n\n" > /dev/tty 98 | exit 1 99 | fi 100 | 101 | binaries_is_func_ mkld || mkld(){ 102 | [ -d "${D[l]:=/run/lock/${I[u]}/${M[p]}}" ] || ${X[mkdir]} -p "${D[l]}" 103 | [ -d "${D[l]}" ] || { D[l]=$TD/${M[p]}/lock; ${X[mkdir]} -p "${D[l]}"; } 104 | } 105 | 106 | binaries_is_func_ c || c(){ 107 | mkld 108 | ( ${X[flock]} -x 200 109 | ${X[curl]} --compressed "${@//NULL/\/dev\/null}" 110 | ) 200>"${D[l]}/curl" 111 | } 112 | 113 | if (( M[e] < 1742900000 )); then 114 | PHP_VERSION="${PHP[v]}" 115 | fi 116 | 117 | binaries_is_func_ lrequire || lrequire(){ req $@;} 118 | 119 | [[ "${M[n]}" =~ php ]] && . <(req di) || di(){ :;} 120 | -------------------------------------------------------------------------------- /modules/php-module-builder/patch: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${PATCH_BASHLIB:-_} && return 11 | PATCH_BASHLIB=: 12 | 13 | include_dirs() { 14 | # Get the PHP include directories (retrieved from php-config) and sort by length (longest first) 15 | ${X[php-config$php_version]} --includes | sed_ 's/-I//g' | ${X[tr]} ' ' '\n' | ${X[gawk]} '{ print length, $0 }' | ${X[sort]} -nr | ${X[cut]} -d" " -f2- 16 | } 17 | 18 | patch_84() { 19 | local files file headers header dir alt_header 20 | local -A bool 21 | 22 | # # Get the PHP include directories (retrieved from php-config) and sort by length (longest first) 23 | # include_dirs=$(${X[php-config$php_version]} --includes | sed_ 's/-I//g' | ${X[tr]} ' ' '\n' | ${X[gawk]} '{ print length, $0 }' | ${X[sort]} -nr | ${X[cut]} -d" " -f2-) 24 | 25 | # Find all source files that include PHP headers 26 | files=$(${X[grep]} -rl '#include [<"]' --include="*.c" --include="*.h" .) 27 | 28 | # Loop through each file to verify header paths 29 | for file in $files; do 30 | 31 | # Check for occurrences of php_rand.h and rename them to php_random.h 32 | sed_ 's|#include [<"](.*)/php_rand.h>|#include <\1/php_random.h>|g' "$file" '-i' && echo "Correcting php_rand.h to php_random.h in $file" 33 | sed_ 's|#include [<"](.*)/php_mt_rand.h>|#include <\1/php_random.h>|g' "$file" '-i' && echo "Correcting php_mt_rand.h to php_random.h in $file" 34 | 35 | # Replace php_rand() with php_mt_rand() in the source file https://github.com/php/php-src/commit/8cf8751533aa37479f8f2e229e407e9bf6025237 36 | sed_ 's/php_rand(/php_mt_rand(/g' "$file" '-i' && echo "Correcting php_rand() to php_mt_rand() in $file" 37 | 38 | # Replace deprecated PHP string functions with the new ones 39 | sed_ 's/php_strtoupper\(/zend_str_toupper(/g' "$file" '-i' && echo "Correcting php_strtoupper() to zend_str_toupper() in $file" 40 | sed_ 's/php_string_toupper\(/zend_string_toupper(/g' "$file" '-i' && echo "Correcting php_string_toupper() to zend_string_toupper() in $file" 41 | sed_ 's/php_strtolower\(/zend_str_tolower(/g' "$file" '-i' && echo "Correcting php_strtolower() to zend_str_tolower() in $file" 42 | sed_ 's/php_string_tolower\(/zend_string_tolower(/g' "$file" '-i' && echo "Correcting php_string_tolower() to zend_string_tolower() in $file" 43 | 44 | # Find all included headers in the source file 45 | headers=$(${X[grep]} -o '#include <[^>]\+>' "$file" | sed_ 's/#include <(.*)>/\1/') 46 | 47 | # Check each header file if it exists in one of the PHP include directories 48 | for header in $headers; do 49 | bool[found]=_ 50 | for dir in $(include_dirs); do 51 | if [[ -f "$dir/$header" ]]; then 52 | bool[found]=: 53 | break 54 | fi 55 | done 56 | 57 | # If not found in the default path, try to find it in alternative directories 58 | if ! ${bool[found]}; then 59 | # Search in all directories for the header 60 | for dir in $(include_dirs); do 61 | alt_header=$(find "$dir" -name "$(${X[basename]} "$header")" -print -quit) 62 | if [[ -n "$alt_header" ]]; then 63 | echo "Correcting $header to ${alt_header#$dir/} in $file" 64 | sed_ "s|#include <$header>|#include <${alt_header#$dir/}>|" "$file" '-i' 65 | break 66 | fi 67 | done 68 | fi 69 | done 70 | done 71 | } 72 | 73 | patch_85() { 74 | local smart_string_hdr 75 | smart_string_hdr="$(include_dirs | grep '/ext$')/standard/php_smart_string.h" 76 | if [[ ! -f $smart_string_hdr ]]; then 77 | echo '#include "zend_smart_string.h"' > $smart_string_hdr 78 | fi 79 | } 80 | 81 | patch_code() { 82 | case $php_version in 83 | 8.4) patch_84 84 | ;; 85 | 8.5) patch_85 86 | esac 87 | } 88 | 89 | patch_m4(){ 90 | if [ -n "$m4_patch" ]; then 91 | B; echo "- patching config.m4"; N 92 | sed_ "$m4_patch" 'config.m4' '-i' 93 | fi 94 | } 95 | -------------------------------------------------------------------------------- /modules/nc-apps/commands.d/filters: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${COMMANDS_FILTERS_BASHLIB:-_} && return 11 | COMMANDS_FILTERS_BASHLIB=: 12 | 13 | filters(){ 14 | ${X[cat]} < "27"))' 35 | 36 | # Apps with NCmax less than "26" and NCmin greater than "20": 37 | appstore 'map(select(.NCmax < "26" and .NCmin > "20"))' 38 | 39 | # All apps where phpMax is less than 8.2: 40 | appstore 'map(select(.phpMax < "8.2"))' 41 | 42 | # All apps where phpMax is less than 8.2 and phpMax is not empty: 43 | appstore 'map(select(.phpMax < "8.2" and (.phpMax | length > 0)))' 44 | 45 | # All apps where phpMin is greater than 7.0 and phpMin is not empty: 46 | appstore 'map(select(.phpMin > "7.0" and (.phpMin | length > 0)))' 47 | 48 | # Apps with phpMax less than 8.2 and phpMax is not empty, and phpMin greater than 7.0 and phpMin is not empty: 49 | appstore 'map(select(.phpMax < "8.2" and (.phpMax | length > 0) and .phpMin > "7.0" and (.phpMin | length > 0)))' 50 | 51 | # Apps with phpMax less than 8.2 or phpMin greater than 7.0 and either phpMax or phpMin is not empty: 52 | appstore 'map(select((.phpMax < "8.2" or .phpMin > "7.0") and ((.phpMax | length > 0) or (.phpMin | length > 0))))' 53 | 54 | # Apps with phpMax less than 8.2 and phpMin greater than 7.0, and both phpMax and phpMin are not empty: 55 | appstore 'map(select(.phpMax < "8.2" and .phpMin > "7.0" and (.phpMax | length > 0) and (.phpMin | length > 0)))' 56 | 57 | # Apps with a specific pattern in the name or id: 58 | appstore 'map(select(.name | test("pattern")))' 59 | appstore 'map(select(.id | test("pattern")))' 60 | 61 | # Apps with specific categories: 62 | appstore 'map(select(.categories | contains("category1") or contains("category2")))' 63 | 64 | # Apps with NCmax less than 26 and NCmin greater than 20, and phpMax less than 8.2: 65 | appstore 'map(select(.NCmax < "26" and .NCmin > "20" and .phpMax < "8.2"))' 66 | 67 | # phpExtensions is not empty 68 | appstore 'map(select(.phpExtensions | length > 0))' 69 | 70 | # Show only selected fields (id, name, and NCmax) for each app: 71 | appstore 'map({id, name, NCmax})' 72 | 73 | # in Combination 74 | appstore 'map(select(.NCmax > "26" and .NCmin > "20" and .phpMax > "8.1" and (.phpMax | length > 0) and (.phpExtensions | length > 0))) | map({id, name, NCmax})' 75 | 76 | # Sort by last modified, oldest first 77 | appstore 'sort_by(.lastModified)' 78 | 79 | # newest first 80 | appstore 'sort_by(.lastModified) | reverse' 81 | 82 | # in Combination 83 | appstore 'map(select(.NCmax > "26" and .NCmin > "20" and .phpMax < "8.2")) | sort_by(.lastModified)' 84 | 85 | # Apps created after January 1, 2023: 86 | appstore 'map(select(.created > "2023-01-01"))' 87 | 88 | # Apps last modified after January 1, 2023: 89 | appstore 'map(select(.lastModified > "2023-01-01"))' 90 | 91 | # Apps created before January 1, 2023: 92 | appstore 'map(select(.created < "2023-01-01"))' 93 | 94 | # Apps last modified before January 1, 2023: 95 | appstore 'map(select(.lastModified < "2023-01-01"))' 96 | 97 | # Apps that haven't been modified after January 1, 2023 (possibly "stale" apps): 98 | appstore 'map(select(.lastModified < "2023-01-01"))' 99 | 100 | # Apps created before January 1, 2023 and haven't been modified after that date (potentially "stale" apps): 101 | appstore 'map(select(.created < "2023-01-01" and .lastModified < "2023-01-01"))' 102 | FILTERS 103 | } 104 | -------------------------------------------------------------------------------- /modules/nc-shares/list_shares: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${LIST_SHARES_BASHLIB:-_} && return 11 | LIST_SHARES_BASHLIB=: 12 | 13 | . <(lrequire nc/nextcloud_db) 14 | 15 | function list_shares(){ 16 | local -A bool 17 | bool[html]=_ 18 | ${bool[html]} && H='--html' || H='' 19 | database_call $H 20 | 21 | d_echo "DB[strg]: \"${DB[strg]}\"" 22 | 23 | local USER USER_ID SHARE_TYPE TOKEN QUERY 24 | USER=" uid_initiator AS initiator," USER_ID="$*" 25 | [ "$USER_ID" = all ] || USER="" 26 | 27 | # share_type from lib/private/Share/Constants.php 28 | 29 | if [ ${sharetype:=3} -eq 3 ]; then 30 | SHARE_TYPE="" TOKEN="token AS \"/s/-token\"," 31 | else 32 | SHARE_TYPE="CONCAT(share_with, " 33 | case $sharetype in 34 | 0) SHARE_TYPE="share_with" ;; 35 | 1) SHARE_TYPE="$SHARE_TYPE'[Group]')" ;; 36 | 2) SHARE_TYPE="$SHARE_TYPE'[userGroup]')" ;; 37 | 4) SHARE_TYPE="$SHARE_TYPE'[userGroup]')" ;; 38 | 5) SHARE_TYPE="$SHARE_TYPE'[Contact]')" ;; 39 | 6) SHARE_TYPE="$SHARE_TYPE'[remote]')" ;; 40 | 7) SHARE_TYPE="$SHARE_TYPE'[Circle]')" ;; 41 | 8) SHARE_TYPE="$SHARE_TYPE'[Guest]')" ;; 42 | 9) SHARE_TYPE="$SHARE_TYPE'[remoteGroup]')";; 43 | 10) SHARE_TYPE="$SHARE_TYPE'[Room]')" ;; 44 | 11) SHARE_TYPE="$SHARE_TYPE'[userRoom]')" ;; 45 | 12) SHARE_TYPE="$SHARE_TYPE'[userRoom]')" ;; 46 | 13) SHARE_TYPE="$SHARE_TYPE'[userDeck]')" 47 | esac 48 | SHARE_TYPE="$SHARE_TYPE AS share_with, " 49 | TOKEN="item_source AS \"/f/-token\"," 50 | fi 51 | 52 | local grpfldr_id thisgrpfldr sed_string 53 | if is_app_enabled groupfolders && [ -d "${NC[dd]}/__groupfolders" ]; then 54 | for grpfldr_id in `ls ${NC[dd]}/__groupfolders* | grep [0-9]`; do 55 | thisgrpfldr="$(db_raw_exec_ "SELECT mount_point FROM ${DB[pref]}group_folders WHERE folder_id = $grpfldr_id")" 56 | sed_string="${sed_string};s@__groupfolders/${grpfldr_id}@/${thisgrpfldr}@g" 57 | d_echo "sed_string: \"$sed_string\"" 58 | done 59 | fi 60 | 61 | # permissions from lib/public/Constants.php 62 | 63 | # using case statement for if-else branching 64 | QUERY="SELECT id, ${DB[ut2ts]} AS \"share_time......\",$USER$SHARE_TYPE 65 | item_type AS type, 66 | CONCAT_WS(',', 67 | CASE WHEN password IS NOT NULL THEN 'pw' ELSE NULL END, 68 | CASE (permissions & 1) WHEN 1 THEN 'r' ELSE NULL END, 69 | CASE (permissions & 2) WHEN 2 THEN 'u' ELSE NULL END, 70 | CASE (permissions & 4) WHEN 4 THEN 'c' ELSE NULL END, 71 | CASE (permissions & 8) WHEN 8 THEN 'd' ELSE NULL END, 72 | CASE (permissions & 16) WHEN 16 THEN 's' ELSE NULL END 73 | ) AS permissions, 74 | $TOKEN 75 | (SELECT path FROM ${DB[pref]}filecache WHERE ${DB[pref]}filecache.fileid = ${DB[pref]}share.file_source) AS path 76 | FROM ${DB[pref]}share 77 | WHERE share_type = ${sharetype}" 78 | 79 | if [ "$USER_ID" = "all" ]; then 80 | query="$QUERY ORDER BY uid_initiator, id" 81 | else 82 | query="$QUERY AND uid_initiator = '$USER_ID' ORDER BY id" 83 | fi 84 | 85 | d_echo "query: \"$query\"" 86 | # TODO 0 --> 87 | # printf -v runtime "%(%F_%R_)T" # declare runtime variable 88 | # tmp_file=$(tf) targetdir="/nc/dat/data/ich/files" targetfile="$targetdir/${basename_me}_$runtime$@.pdf" 89 | # d_echo "tmp_file: $tmp_file" 90 | # d_echo "targetfile: $targetfile" 91 | # eval ${DB[strg]} ${DB[exec]}\"$query\" | sed_ "s\ files/\ /\g$sed_string" | ${X[tidy]} -indent -quiet -wrap 0 -f $NUL -o $tmp_file 92 | # eval ${DB[strg]} $H ${DB[exec]}\"$query\" | ${X[tidy]} -indent -quiet -wrap 0 -f $NUL | sed_ "s\files/\/\g$sed_string" > $tmp_file 93 | 94 | # anykey 95 | 96 | # mv $tmp_file $tmp_file.html 97 | # soffice --headless --convert-to pdf $tmp_file.html 98 | 99 | # anykey 100 | 101 | # mv $tmp_file.pdf "$targetfile" 102 | 103 | # anykey 104 | 105 | # $occ files:scan -vvv --path="$targetfile" 106 | # exit 107 | # TODO 0 <-- 108 | db_exec_ "$query" | ${X[column]} -t -s $'\t' | sed_ "s\ files/\ /\g$sed_string" 109 | # TODO 1 --> 110 | # pipe_h2t "${DB[strg]} ${DB[exec]}" "$query" 111 | # TODO 1 <-- 112 | } 113 | -------------------------------------------------------------------------------- /modules/nc/first_run: -------------------------------------------------------------------------------- 1 | __bashlib__ 2 | __path_and_modulename__ 3 | __version_and_datestring__ 4 | # 5 | __copyright__ 6 | # 7 | __license__ 8 | # 9 | 10 | ${NC_FIRST_RUN_BASHLIB:-_} && return 11 | NC_FIRST_RUN_BASHLIB=: 12 | 13 | . <(lrequire httpd) 14 | 15 | first_run_register_nc_dir(){ 16 | local dir 17 | dir="$1" 18 | mh "vdir: $dir" 19 | setvdir v "$dir" 20 | NC[d]="$dir" 21 | declare -p NC > "${F[nc]}" 22 | ${X[chmod]} 666 "${F[nc]}" 23 | f 24 | o2; echo "- $(lG)first run wizard completed successfully. Please start script again"; N 25 | o2; echo "- $(lG)No further root rights are required to use the script except for updating."; N 26 | f 27 | exit 0 28 | } 29 | 30 | first_run(){ 31 | te1 32 | local p h 33 | local -l ans num 34 | local -i c2 i 35 | h="$(box h) to enter path by hand or $(q2q)" c2=9 36 | 37 | if ! ${B[rt]} && [[ -d ${NC[d]} || -d $NC_DIR ]]; then 38 | su_root "to run this script" 39 | fi 40 | 41 | if ! ${B[irun2]}; then 42 | f 43 | o2; GRAY; echo "This step is required once after a new installation or if" 44 | f 45 | o 6; W; echo "--firstrun" 46 | f 47 | o2; GRAY; echo "was passed:" 48 | fi 49 | 50 | su_root "for the first run wizard" irun2 51 | 52 | populate_httpd_ nc-dir 53 | 54 | f 55 | o2; B; echo "Hello, this is the first run wizard of \"$(Y)$ME$(B)\"" 56 | if (( ${#HTTPD_NC_DIR[@]} == 1 )); then 57 | p="${HTTPD_NC_DIR[0]}" 58 | o2; echo "nextcloud installation detected in $(C)$p"; N 59 | o2; printf "is that correct $(box Y) / $(box n) ($(GRAY)or $(q2q; N)) " 60 | while :; do 61 | read -rsn 1 ans; te1 62 | case ${ans:-y} in 63 | q) exit 0 ;; 64 | y) first_run_register_nc_dir "$p" ;; 65 | n) break ;; 66 | *) printf "$invi Please enter $(box y), $(box n) or $(q2q) " 67 | esac 68 | done 69 | elif (( ${#HTTPD_NC_DIR[@]} > 1 )); then 70 | line '=' P 2/78 b1 71 | o3; B; echo "Detected nextcloud installations" 72 | o4; Y; echo "Num$(o $c2)Directory" 73 | line '-' P 2/78 74 | for i in "${!HTTPD_NC_DIR[@]}"; do 75 | p="${HTTPD_NC_DIR[i]}" 76 | o3; echo "- $(( i + 1 ))$(o $c2)$p" 77 | done 78 | line '-' P 2/78 a2 79 | while :; do 80 | o2; printf "Enter the corresponding number, $h" 81 | read -rsn 1 num 82 | te1 83 | case $num in 84 | q) exit 0 85 | ;; 86 | h) break 87 | ;; 88 | [1-9]) (( num > ( ${#HTTPD_NC_DIR[@]} ) )) && { 89 | echo -e "\n$(o2)Invalid number. Please choose a number from the list, $h" 90 | continue 91 | } 92 | i="$(( num - 1 ))" 93 | p="${HTTPD_NC_DIR[i]}" 94 | o2; echo "Your choice: \"$(C)$p$(N)\"" 95 | f 96 | o2; echo "is this the right Nextcloud installation path?" 97 | o2; echo "Press $(box y) for yes, $(box n) for no, $h: " 98 | while :; do 99 | read -rsn 1 ans 100 | te1 101 | case $ans in 102 | q) exit 0 ;; 103 | h) break ;; 104 | n) continue ;; 105 | y) first_run_register_nc_dir "$p" ;; 106 | *) printf "$invi Please enter $(box y), $(box n), $(box h) or $(q2q) " 107 | esac 108 | done 109 | ;; 110 | *) o2 111 | echo -e "\n$(o2)$invi Please enter a valid number, $h" 112 | continue 113 | esac 114 | done 115 | fi 116 | while :; do 117 | cursor_ show 118 | o2; echo "enter the directory where your Nextcloud is installed ($(C)or $(q2q; N)):"; N 119 | read -rp " --> " p 120 | te1 121 | cursor_ hide 122 | [ "${p,}" = "q" ] && exit 0 123 | [ -f "$p/occ" ] && first_run_register_nc_dir "$p" || echo "$(Pbg) * I can not detect a Nextcloud installation in \"$p\" $(N)" 124 | done 125 | } 126 | # COMMENT --> 127 | # [ -r "${NC[d]}/lib/base.php" ] || first_run 128 | --------------------------------------------------------------------------------