summaryrefslogtreecommitdiffstats
path: root/abs/core/LinHES-system/bin/library.sh
blob: 2049de3788bf8f428d7e8e56df6d1ac774f67432 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
msg () {  # A status reporting function
    [ "${VERBOSE:-0}" -gt 0 ] && echo "$*"
}

error () { # An error reporting function
    echo 1>&2 "$*"
}

fatal () { # Report an error and exit with a failure code
    error "$*"
    exit 1
}

# The only non builtin this uses is tr...
require () { # Check prerequisites
    e=0
    props="$1" ; shift
    for obj in "$@" ; do
        [ -z "$obj" ] && continue # Too late to do anything itelligent...
        problems=""
        for prop in $(/bin/tr '+,' ' ' <<<"$props") ; do
            case "$prop" in
            e|exists) # kind of useless...
                [ -e "$obj" ] || problems="$problems, does not exist" ;;
            f|file)
                [ -f "$obj" ] || problems="$problems, is not a file" ;;
            d|dir)
                [ -d "$obj" ] || problems="$problems, is not a directory" ;;
            l|symlink)
                [ -L "$obj" ] || problems="$problems, is not a symlink" ;;
            nosymlink)
                [ -L "$obj" ] && problems="$problems, is a symlink" ;;
            r|readable)
                [ -r "$obj" ] || problems="$problems, is not readable" ;;
            w|writable)
                [ -w "$obj" ] || problems="$problems, is not writable" ;;
            x|executable)
                [ -x "$obj" ] || problems="$problems, is not executable" ;;
            *)
                fatal "Programmer error, unknown property: '$prop'" ;;
            esac
        done
        if [ -n "$problems" ] ; then
            error "Error: '$obj'$problems."
            e=1
        fi
    done
    [ "$e" -ne 0 ] && fatal "Errors noted above are fatal."
}

require file+r+x /bin/bash /bin/grep /bin/rm /bin/tr \
                 /usr/bin/basename /usr/bin/env \
                 /usr/bin/mysql /usr/bin/sort

if [ -n "$DEBUG" ] ; then
    for debug_opt in $(/bin/tr ',' ' ' <<<"$DEBUG") ; do
        echo '============================================================'
        echo "==== $debug_opt"

        # Note that the order you specifiy these debug options in matters.
        # I recommend always listing log first. For example:
        #   export DEBUG=log,env,set,trace
        case "$debug_opt" in
        env)    /usr/bin/env | /usr/bin/sort ;;
        set)    set ;;
        trace)  set -vx ;;
        log)    logfile="/tmp/$(/usr/bin/basename $0).$$.debug"
                /bin/rm -f "$logfile" # Try to avoid privilege escalation bugs
                echo "Redirecting stdout and stderr to '$logfile'"
                exec >"$logfile" 2>&1 ;;
        *)      error "Unknown debug option '$debug_opt'" ;;
        esac
    done
    echo '============================================================'
fi

must_be_root () { # For things which must be run as root
    [ $(/usr/bin/id -u) -ne 0 ] && fatal "You must run this script as root!"
}

must_be_mythtv () { # For things which must be run as mythtv (su if possible)
    case $(/usr/bin/id -nu) in
    mythtv) ;; # Continue
    root)   /bin/su - mythtv -c "$0 $*" ; exit $? ;;
    *)      fatal "You must run this script at mythtv or root!" ;;
    esac
}

# Use a variable so you can override it.
DATABASE="mythconverg"

mysql_cmd () { # Execute SQL from the command line
    /usr/bin/mysql -u root "$DATABASE" -sBe "$*"
}

mysql_stdin () { # Execute SQL from stdin
    /usr/bin/mysql -u root "$DATABASE" -sB
}

machine_clause () { # Helper function 
    if [ -z "$1" ] ; then
        echo "(hostname = '' or hostname is null)"
    else
        echo "hostname = '$1'"
    fi
}

get_all_setting_names () { # List setting names
    case "$#" in
    0) MACHINE_CLAUSE="" ;;
    1) MACHINE_CLAUSE="where $(machine_clause "$1")" ;;
    *) fatal "Programmer error, get_all_names must be passed 0 or 1 args, got $#" ;;
    esac
    mysql_cmd "select distinct value from settings $MACHINE_CLAUSE order by value"
}

get_all_setting_values () { # List settings
    case "$#" in
    0) MACHINE_CLAUSE="" ;;
    1) MACHINE_CLAUSE="where $(machine_clause "$1")" ;;
    *) fatal "Programmer error, get_all_values must be passed 0 or 1 args, got $#" ;;
    esac
    mysql_cmd "select value, data, hostname from settings $MACHINE_CLAUSE order by hostname, value, data"
}

get_setting_value () { # Get the data for a setting (may return multiples!)
    case "$#" in
    1) MACHINE_CLAUSE="" ;;
    2) MACHINE_CLAUSE="and $(machine_clause "$2")" ;;
    *) fatal "Programmer error, get_value must be passed 1 or 2 args, got $#" ;;
    esac
    mysql_cmd "select data from settings where value = '$1' $MACHINE_CLAUSE"
}

set_setting_value () { # Insert or update aome setting
    case "$#" in
    2) RECORD_CNT=$(get_value "$1" | wc -l) ;;
    3) RECORD_CNT=$(get_value "$1" "$3" | wc -l) ;;
    *) fatal "Programmer error, set_value must be passed 2 or 3 args, got $#" ;;
    esac
    MACHINE_CLAUSE=""
    if [ "$RECORD_CNT" -eq 0 ] ; then
        [ -n "$3" ] && MACHINE_CLAUSE=", $(machine_clause "$3")"
        mysql_cmd "insert into settings set value = '$1', data = '$2' $MACHINE_CLAUSE"
    else
        [ "$#" -eq 3 ] && MACHINE_CLAUSE="and $(machine_clause "$3")"
        mysql_cmd "update settings set data = '$2' where value = '$1' $MACHINE_CLAUSE"
    fi
}

delete_setting_value () { # Totally remove some setting
    case "$#" in
    1) MACHINE_CLAUSE="" ;;
    2) MACHINE_CLAUSE="and $(machine_clause "$2")" ;;
    *) fatal "Programmer error, get_value must be passed 1 or 2 args, got $#" ;;
    esac
    mysql_cmd "delete from settings where value = '$1' $MACHINE_CLAUSE"
}

# Filter against a newline seperated exclude list
filter_list () {
    /bin/grep -vxF "$*" |
    /usr/bin/sort -u
}