diff --git a/.gitattributesdb b/.gitattributesdb index 36c3582..527b014 100644 --- a/.gitattributesdb +++ b/.gitattributesdb @@ -5,13 +5,13 @@ LmdpdGhvb2tzL2dpdGF0dHJpYnV0ZXNkYg== 1757608819 1757608819 root:root 0755 - - LmdpdGhvb2tzL3Bvc3QtY2hlY2tvdXQ= 1757519106 1757519106 root:root 0755 - - LmdpdGhvb2tzL3Bvc3QtbWVyZ2U= 1757519106 1757519106 root:root 0755 - - LmdpdGhvb2tzL3ByZS1jb21taXQ= 1757519106 1757519106 root:root 0755 - - -LmdpdGlnbm9yZQ== 1758124916 1757593248 root:root 0644 - - +LmdpdGlnbm9yZQ== 1757789404 1757593248 root:root 0644 - - LmdpdG1vZHVsZXM= 1757607701 1757607701 root:root 0644 - - -ZXRjLy5naXRpZ25vcmU= 1758218823 1757611781 root:root 0644 - - +ZXRjLy5naXRpZ25vcmU= 1758049461 1757611781 root:root 0644 - - ZXRjL2FwYWNoZTIvLmdpdGlnbm9yZQ== 1757775950 1757775932 root:root 0644 - - ZXRjL2FwYWNoZTIvaHR0cGQuY29uZg== 1758045891 1757785514 root:root 0644 - - ZXRjL2FwYWNoZTIvc2l0ZXMuZC9jb3JlLnNsYWNrd2FyZS51ay5uZXQuY29uZg== 1758045929 1757785113 root:root 0644 - - -ZXRjL2NvbmYuZC8uZ2l0aWdub3Jl 1758050750 1757609410 root:root 0644 - - +ZXRjL2NvbmYuZC8uZ2l0aWdub3Jl 1757609410 1757609410 root:root 0644 - - ZXRjL2NvbmYuZC9ib290bWlzYw== 1757591865 1757591865 root:root 0644 - - ZXRjL2NvbmYuZC9ub2RlLWV4cG9ydGVy 1757592526 1757592526 root:root 0644 - - ZXRjL2NvbmYuZC9zYW1iYQ== 1757592912 1757592912 root:root 0644 - - @@ -33,22 +33,17 @@ ZXRjL2hvc3RuYW1l 1757594311 1757594311 root:root 0644 - - ZXRjL2hvc3Rz 1757594362 1757594362 root:root 0644 - - ZXRjL2lwdGFibGVzL3J1bGVzLXNhdmU= 1757789154 1757789154 root:root 0600 - - ZXRjL2lwdGFibGVzL3J1bGVzNi1zYXZl 1757789154 1757789154 root:root 0600 - - -ZXRjL2tyYjUuY29uZg== 1758214709 1583171707 root:root 0644 - - ZXRjL2xvY2FsLmQvLmdpdGlnbm9yZQ== 1757595481 1757595481 root:root 0644 - - -ZXRjL2xvY2FsLmQvcHVzaG92ZXItYWxlcnQuc3RhcnQ= 1758225142 1758225089 root:root 0755 - - -ZXRjL2xvY2FsLmQvcHVzaG92ZXItYWxlcnQuc3RvcA== 1758225254 1758225155 root:root 0755 - - ZXRjL2xvY2FsLmQvdGVycmFmb3JtLWh0dHAtYmFja2VuZC5zdGFydA== 1757595926 1757595926 root:root 0755 - - ZXRjL21zbXRwLmFsaWFzZXM= 1758035451 1758035451 root:root 0644 - - ZXRjL21zbXRwcmMuZ3Bn 1758049424 1758049424 root:root 0644 - - ZXRjL25ldHdvcmsvLmdpdGlnbm9yZQ== 1757596572 1757596572 root:root 0644 - - ZXRjL25ldHdvcmsvaW50ZXJmYWNlcw== 1757759982 1757596330 root:root 0644 - - ZXRjL3Bhc3N3ZA== 1757873724 1757869538 root:root 0644 - - -ZXRjL3BlcmlvZGljL2RhaWx5LzAtcm90YXRlLWxvZ3Mtc3ltbGlua3M= 1758222266 1758222266 root:root 0777 - - -ZXRjL3BlcmlvZGljL2RhaWx5LzEwLWRlaHlkcmF0ZWQ= 1757708520 1757708520 root:root 0777 - - -ZXRjL3BlcmlvZGljL2RhaWx5LzUtdXBkYXRlLXBhY2thZ2VzLWxpc3Q= 1757708520 1757708520 root:root 0777 - - -ZXRjL3BlcmlvZGljL2RhaWx5Lzctd2Fybi1naXQtc3RhdHVz 1757708520 1757708520 root:root 0777 - - -ZXRjL3BrZ2xpc3Q= 1758211839 1757609913 root:root 0644 - - -ZXRjL3B1c2hvdmVyLWNsaWVudC9kZWZhdWx0 1758224985 1758224590 root:root 0600 - - +ZXRjL3BlcmlvZGljL2RhaWx5L2Nyb25qb2ItZGVoeWRyYXRlZA== 1757708520 1757708520 root:root 0777 - - +ZXRjL3BlcmlvZGljL2RhaWx5L2Nyb25qb2ItdXBkYXRlLXBhY2thZ2VzLWxpc3Q= 1757708520 1757708520 root:root 0777 - - +ZXRjL3BlcmlvZGljL2RhaWx5L2Nyb25qb2Itd2Fybi1naXQtc3RhdHVz 1757708520 1757708520 root:root 0777 - - +ZXRjL3BrZ2xpc3Q= 1758046586 1757609913 root:root 0644 - - ZXRjL3Jlc29sdi5jb25m 1757611605 1757611605 root:root 0644 - - ZXRjL3J1bmxldmVscy9ib290Ly5naXRpZ25vcmU= 1757769666 1757598667 root:root 0644 - - ZXRjL3J1bmxldmVscy9ib290L3JzeXNsb2c= 1757708520 1757708520 root:root 0777 - - @@ -64,14 +59,10 @@ ZXRjL3J1bmxldmVscy9kZWZhdWx0L3RlcnJhZm9ybS1odHRwLWJhY2tlbmQ= 1757772274 17577722 ZXRjL3J1bmxldmVscy9zaHV0ZG93bi9pcDZ0YWJsZXM= 1757770292 1757770292 root:root 0777 - - ZXRjL3J1bmxldmVscy9zaHV0ZG93bi9pcHRhYmxlcw== 1757770284 1757770284 root:root 0777 - - ZXRjL3J1bmxldmVscy9zaHV0ZG93bi9zYW1iYQ== 1757708520 1757708520 root:root 0777 - - -ZXRjL3NhbWJhL3NtYi5jb25m 1758215678 1758208516 root:root 0644 - - -ZXRjL3NhbWJhL3NtYnVzZXJz 1758121825 1758121586 root:root 0644 - - ZXRjL3NoYWRvdy5ncGc= 1757599010 1757599010 root:root 0644 - - ZXRjL3NzaC8uZ2l0aWdub3Jl 1757606957 1757606957 root:root 0644 - - ZXRjL3NzaC9zc2hfY29uZmln 1757606630 1757606630 root:root 0644 - - -ZXRjL3NzaC9zc2hkX2NvbmZpZw== 1758202229 1757606896 root:root 0644 - - -ZXRjL3NzaGd1YXJkLmNvbmY= 1758050700 1758050700 root:root 0644 - - -ZXRjL3NzaGd1YXJkLndoaXRlbGlzdA== 1758050235 1758050235 root:root 0644 - - +ZXRjL3NzaC9zc2hkX2NvbmZpZw== 1757606896 1757606896 root:root 0644 - - ZXRjL3N1ZG9lcnMuZC9kZWZhdWx0cw== 1757599359 1757599359 root:root 0640 - - ZXRjL3N1ZG9lcnMuZC9yb290LWFjY2Vzcw== 1757600157 1757600157 root:root 0640 - - aG9tZS8uZ2l0aWdub3Jl 1757762052 1757762052 root:root 0644 - - @@ -85,11 +76,9 @@ aG9tZS9zeXNhZG1pbi8ubmFub3Jj 1757585756 1757585756 sysadmin:users 0644 - - aG9tZS9zeXNhZG1pbi8uc3NoLy5naXRpZ25vcmU= 1757593349 1757593349 sysadmin:users 0644 - - aG9tZS9zeXNhZG1pbi8uc3NoL2F1dGhvcml6ZWRfa2V5cw== 1757763178 1757587611 sysadmin:users 0644 - - b3B0L3NiaW4vY3JvbmpvYi1kZWh5ZHJhdGVk 1758033093 1757531685 root:root 0755 - - -b3B0L3NiaW4vY3JvbmpvYi1yb3RhdGUtbG9ncy1zeW1saW5rcw== 1758224324 1758224324 root:root 0755 - - b3B0L3NiaW4vY3JvbmpvYi11cGRhdGUtcGFja2FnZXMtbGlzdA== 1757531121 1757531121 root:root 0755 - - -b3B0L3NiaW4vY3JvbmpvYi13YXJuLWdpdC1zdGF0dXM= 1758221607 1757591137 root:root 0755 - - +b3B0L3NiaW4vY3JvbmpvYi13YXJuLWdpdC1zdGF0dXM= 1757591137 1757591137 root:root 0755 - - b3B0L3NiaW4vZGVoeWRyYXRlZA== 1757531557 1757531557 root:root 0755 - - -b3B0L3NiaW4vcHVzaG92ZXItY2xpZW50 1758224526 1758224526 root:root 0755 - - b3B0L3NiaW4vdGVycmFmb3JtLWh0dHAtYmFja2VuZA== 1757590543 1757590543 root:root 0755 - - cm9vdC8uYmFzaF9sb2dvdXQ= 1757582867 1757582867 root:root 0644 - - cm9vdC8uYmFzaF9wcm9maWxl 1757584711 1757584711 root:root 0644 - - diff --git a/etc/.gitignore b/etc/.gitignore index 9927d65..fd56c6a 100644 --- a/etc/.gitignore +++ b/etc/.gitignore @@ -52,4 +52,3 @@ /sysctl.d/ /terminfo/ /udhcpc/ -/xattr.conf diff --git a/etc/conf.d/.gitignore b/etc/conf.d/.gitignore index c739a86..4a340c7 100644 --- a/etc/conf.d/.gitignore +++ b/etc/conf.d/.gitignore @@ -21,7 +21,6 @@ /ntpd /rdate /seedrng -/sshguard /staticroute /swap /swclock diff --git a/etc/krb5.conf b/etc/krb5.conf deleted file mode 100644 index ec9c27c..0000000 --- a/etc/krb5.conf +++ /dev/null @@ -1,24 +0,0 @@ -[logging] -# default = FILE:/var/log/krb5libs -# kdc = FILE:/var/log/krb5kdc -# admin_server = FILE:/var/log/kadmind - -[libdefaults] -default_realm = SLACKWARE.UK.NET -dns_lookup_realm = false -dns_lookup_kdc = false -rdns = true -forwardable = true -ticket_lifetime = 24h -renew_lifetime = 7d - -[realms] -SLACKWARE.UK.NET = { - default_domain = slackware.uk.net - admin_server = core.slackware.uk.net - kdc = core.slackware.uk.net -} - -[domain_realm] -.slackware.uk.net = SLACKWARE.UK.NET -core = SLACKWARE.UK.NET diff --git a/etc/local.d/pushover-alert.start b/etc/local.d/pushover-alert.start deleted file mode 100755 index 3b1f2ac..0000000 --- a/etc/local.d/pushover-alert.start +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -# Alert that this host is up. -( sleep 30; [[ -x /opt/sbin/pushover-client ]] && /opt/sbin/pushover-client -p -1 -m "Boot up: ${HOSTNAME%%.*}" ) & diff --git a/etc/local.d/pushover-alert.stop b/etc/local.d/pushover-alert.stop deleted file mode 100755 index ebfff6a..0000000 --- a/etc/local.d/pushover-alert.stop +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -# Alert that this host is going down. -[[ -x /opt/sbin/pushover-client ]] && /opt/sbin/pushover-client -p -1 -m "Shut down: ${HOSTNAME%%.*}" & diff --git a/etc/periodic/daily/0-rotate-logs-symlinks b/etc/periodic/daily/0-rotate-logs-symlinks deleted file mode 120000 index e26953b..0000000 --- a/etc/periodic/daily/0-rotate-logs-symlinks +++ /dev/null @@ -1 +0,0 @@ -/opt/sbin/cronjob-rotate-logs-symlinks \ No newline at end of file diff --git a/etc/periodic/daily/10-dehydrated b/etc/periodic/daily/cronjob-dehydrated similarity index 100% rename from etc/periodic/daily/10-dehydrated rename to etc/periodic/daily/cronjob-dehydrated diff --git a/etc/periodic/daily/5-update-packages-list b/etc/periodic/daily/cronjob-update-packages-list similarity index 100% rename from etc/periodic/daily/5-update-packages-list rename to etc/periodic/daily/cronjob-update-packages-list diff --git a/etc/periodic/daily/7-warn-git-status b/etc/periodic/daily/cronjob-warn-git-status similarity index 100% rename from etc/periodic/daily/7-warn-git-status rename to etc/periodic/daily/cronjob-warn-git-status diff --git a/etc/pkglist b/etc/pkglist index 3a35591..422db7e 100644 --- a/etc/pkglist +++ b/etc/pkglist @@ -16,7 +16,6 @@ apk-tools apr apr-util argon2-libs -attr avahi-libs bash bridge @@ -55,7 +54,6 @@ ldb libapk2 libarchive libassuan -libattr libauth-samba libbsd libbz2 @@ -104,7 +102,6 @@ lynx lz4-libs mailx mdev-conf -mpdecimal msmtp msmtp-openrc musl @@ -135,24 +132,6 @@ popt procps-ng prometheus-node-exporter prometheus-node-exporter-openrc -py3-cffi -py3-cffi-pyc -py3-cparser -py3-cparser-pyc -py3-cryptography -py3-cryptography-pyc -py3-dnspython -py3-dnspython-pyc -py3-ldb -py3-markdown -py3-markdown-pyc -py3-samba -py3-talloc -py3-tdb -pyc -python3 -python3-pyc -python3-pycache-pyc0 readline rsyslog rsyslog-openrc @@ -162,15 +141,10 @@ samba-client-libs samba-common samba-common-server-libs samba-common-tools -samba-dc -samba-dc-libs samba-libs -samba-libs-py3 samba-server -samba-server-libs samba-server-openrc samba-util-libs -samba-winbind scanelf skalibs-libs sqlite-libs @@ -179,7 +153,6 @@ sshguard-openrc ssl_client sudo talloc -tdb tdb-libs tevent utmps-libs diff --git a/etc/pushover-client/default b/etc/pushover-client/default deleted file mode 100644 index 73d5724..0000000 --- a/etc/pushover-client/default +++ /dev/null @@ -1,3 +0,0 @@ -QUIET="true" -TOKEN="a484bt3qn6d78noowrik1rwhk3beuk" -USER_KEYS="uscT77WKKzaNoLWXZDiBaECab3pE9z" diff --git a/etc/samba/smb.conf b/etc/samba/smb.conf deleted file mode 100644 index 4060f8a..0000000 --- a/etc/samba/smb.conf +++ /dev/null @@ -1,40 +0,0 @@ -[global] -realm = SLACKWARE.UK.NET -netbios name = CORE -workgroup = SLACKWAREUKNET -server string = "slackware.uk.net Domain Controller" -# dns forwarder = 5.101.171.216 5.101.171.217 185.176.90.169 -dns forwarder = 216.119.155.58 185.176.90.169 -allow dns updates = disabled -tls cafile = /etc/certificates/core.slackware.uk.net_fullchain.pem -tls certfile = /etc/certificates/core.slackware.uk.net_cert.pem -tls keyfile = /etc/certificates/core.slackware.uk.net_key.pem -tls verify peer = ca_and_name_if_available -log level = 1 -logging = syslog:local5 -idmap config * : backend = tdb -# There are only 568 IDs mapped into the container by TrueNAS, so limit the number that can be used. -idmap config * : range = 10000-10500 -idmap_ldb:use rfc2307 = yes -password hash userPassword schemes = CryptSHA512 -server role = active directory domain controller -username map = /etc/samba/smbusers -vfs objects = dfs_samba4 posixacl acl_xattr -nfs4acl_xattr:encoding = nfs -nfs4acl_xattr:version = 41 -nfs4acl_xattr:xattr_name = user.nfs4_acl -nfs4acl_xattr:default acl style = windows -acl_xattr:security_acl_name = user.NTACL -acl_xattr:default acl style = windows - -# [homes] - -# [printers] - -[sysvol] -path = /var/lib/samba/sysvol -write list = @'Domain Admins@slackware.uk.net' - -[netlogon] -path = /var/lib/samba/sysvol/slackware.uk.net/scripts -write list = @'Domain Admins@slackware.uk.net' diff --git a/etc/samba/smbusers b/etc/samba/smbusers deleted file mode 100644 index 6f2443b..0000000 --- a/etc/samba/smbusers +++ /dev/null @@ -1 +0,0 @@ -root = Administrator diff --git a/etc/ssh/sshd_config b/etc/ssh/sshd_config index b18599a..cba6121 100644 --- a/etc/ssh/sshd_config +++ b/etc/ssh/sshd_config @@ -8,4 +8,5 @@ MaxStartups 5 PermitRootLogin prohibit-password StreamLocalBindUnlink yes Subsystem sftp internal-sftp +UsePAM yes X11Forwarding no diff --git a/etc/sshguard.conf b/etc/sshguard.conf deleted file mode 100644 index 8dedc93..0000000 --- a/etc/sshguard.conf +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/sh -# sshguard.conf -- SSHGuard configuration - -# Full path to backend executable (required, no default) -BACKEND="/usr/libexec/sshg-fw-iptables" - -# Space-separated list of log files to monitor. (optional, no default) -FILES="/var/log/core.slackware.uk.net/auth" - -# Shell command that provides logs on standard output. (optional, no default) -# Example 1: ssh and sendmail from systemd journal: -#LOGREADER="LANG=C /usr/bin/journalctl -afb -p info -n1 -t sshd -t sendmail -o cat" -# Example 2: ssh from os_log (macOS 10.12+) -#LOGREADER="/usr/bin/log stream --style syslog --predicate '(processImagePath contains \"sshd\")'" - -# Block attackers when their cumulative attack score exceeds THRESHOLD. -# Most attacks have a score of 10. (optional, default 30) -THRESHOLD=10 - -# Block attackers for initially BLOCK_TIME seconds after exceeding THRESHOLD. -# Subsequent blocks increase by a factor of 1.5. (optional, default 120) -BLOCK_TIME=86400 - -# Remember potential attackers for up to DETECTION_TIME seconds before -# resetting their score. (optional, default 1800) -DETECTION_TIME=28800 - -# Size of IPv6 subnet to block. Defaults to a single address, CIDR notation. (optional, default to 128) -IPV6_SUBNET=128 - -# Size of IPv4 subnet to block. Defaults to a single address, CIDR notation. (optional, default to 32) -IPV4_SUBNET=32 - -# Full path to PID file (optional, no default) -PID_FILE=/run/sshguard.pid - -# Colon-separated blacklist threshold and full path to blacklist file. -# (optional, no default) -BLACKLIST_FILE=10:/var/lib/sshguard/blacklist - -# IP addresses listed in the WHITELIST_FILE are considered to be -# friendlies and will never be blocked. -WHITELIST_FILE=/etc/sshguard.whitelist - -# If PARSER is unset, SSHGuard will use the installed sshg-parser as its -# parser. Setting PARSER overrides this, so that you can use your own parser. -#PARSER= - -# Run POST_PARSER as a filter after the parser. POST_PARSER must read as input -# and produce as output lines in the format used by sshg-parser. This example -# implements primitive whitelisting, preventing sshg-blocker from seeing -# attacks from 1.2.3.4. Unlike whitelisting, attacks filtered by POST_PARSER -# are not logged by SSHGuard. -#POST_PARSER="grep -v 1.2.3.4" diff --git a/etc/sshguard.whitelist b/etc/sshguard.whitelist deleted file mode 100644 index 77a0c3d..0000000 --- a/etc/sshguard.whitelist +++ /dev/null @@ -1,19 +0,0 @@ -# Localhost. -127.0.0.1/8 -::1 - -# UK Servers -5.101.171.208/28 -2a01:a500:2981:1::/64 - -# Linode -172.236.16.105 -2600:3c13::2000:50ff:fef4:7f56 - -# Loveservers -185.176.90.169 -2a07:4580:b0d:57f::169 - -# Afterdark -afterdark.org.uk -2001:470:1f1c:58::/64 diff --git a/opt/sbin/cronjob-rotate-logs-symlinks b/opt/sbin/cronjob-rotate-logs-symlinks deleted file mode 100755 index aae8e1a..0000000 --- a/opt/sbin/cronjob-rotate-logs-symlinks +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash - -# Default configuration. -LOGS_DIR="/var/log" -DIR_MODE="0750" -UMASK="027" - -# Allow /etc/default/rotate-logs-symlinks to override default configuration. -[[ -e /etc/default/rotate-logs-symlinks ]] && { - # shellcheck disable=SC1091 - source /etc/default/rotate-logs-symlinks || { - printf "%s: %s\\n" "${0##*/}" "failed reading /etc/default/rotate-logs-symlinks" >&2 - exit 1 - } -} - -# Process the directories in the logs directory. -[[ -d "$LOGS_DIR" ]] && { - TODAY="$(printf "%(%Y/%m/%d)T")" - - umask "$UMASK" - - # Process all the directories in the logs directory. - for DIR in "$LOGS_DIR"/*; do - cd "$DIR" 2>/dev/null || { - printf "%s: %s\\n" "${0##*/}" "failed to change directory to '$DIR'" >&2 - continue - } - - # Create a new logs directory for today. - # shellcheck disable=SC2174 - mkdir -p -m "$DIR_MODE" "$TODAY" 2>/dev/null || { - printf "%s: %s\\n" "${0##*/}" "failed to create directory '$DIR/$TODAY'" >&2 - continue - } - - # Create a 'today' symlink to the new days' directory. - ( cd "$DIR" 2>/dev/null && ln -sf "$TODAY" "today" 2>/dev/null ) || { - printf "%s: %s\\n" "${0##*/}" "creating 'today' symlink failed" >&2 - continue - } - done -} - -exit 0 diff --git a/opt/sbin/cronjob-warn-git-status b/opt/sbin/cronjob-warn-git-status index c09f931..0dc904d 100755 --- a/opt/sbin/cronjob-warn-git-status +++ b/opt/sbin/cronjob-warn-git-status @@ -1,18 +1,8 @@ #!/bin/bash -# Default configuration. CHECK_DIRS=('/') EMAIL_TO=('sysadmin@slackware.uk') -EMAIL_FROM="\"Server: ${HOSTNAME%%.*}\" " - -# Allow /etc/default/warn-git-status to override default configuration. -[[ -e /etc/default/warn-git-status ]] && { - source /etc/default/warn-git-status || { - printf "%s: %s\\n" "${0##*/}" "failed reading /etc/default/warn-git-status" >&2 - exit 1 - } -} - +EMAIL_FROM="${HOSTNAME%%.*} " OUTPUT_FILE="/tmp/${0##*/}-$$-$RANDOM" # Remove the OUTPUT_FILE when done. @@ -32,8 +22,8 @@ done # Send the message. if [[ -n "${EMAIL_TO[*]}" ]]; then - mail -r "$EMAIL_FROM" -s "Git statuses" "${EMAIL_TO[@]}" <"$OUTPUT_FILE" >/dev/null 2>&1 || { - printf "%s: %s\\n" "${0##*/}" "mail command failed" >&2 + mailx "${MAILX_ARGS[@]}" -S "from=$EMAIL_FROM" -s "Git statuses" "${EMAIL_TO[@]}" <<<"$(cat "$OUTPUT_FILE")" 2>/dev/null || { + printf "%s: %s\\n" "${0##*/}" "mailx command failed" >&2 exit 1 } else diff --git a/opt/sbin/pushover-client b/opt/sbin/pushover-client deleted file mode 100755 index 1e86583..0000000 --- a/opt/sbin/pushover-client +++ /dev/null @@ -1,701 +0,0 @@ -#!/bin/bash -# Version: 0.1.0 -# Copyright (c) 2023: -# Darren 'Tadgy' Austin -# Licensed under the terms of the GNU General Public License version 3. -# -# A PushOver client to send alert messages. - -# Configuration. -CONFIG_API_URL="https://api.pushover.net/1/messages.json" -CONFIG_SOUNDS_API_URL="https://api.pushover.net/1/sounds.json" - -# Defaults. -DEFAULT_SYSTEM_DIR="/etc/pushover-client" -DEFAULT_USER_DIR="${HOME}/.pushover-client" -DEFAULT_CONFIG_FILE="default" -DEFAULT_EXPIRY="3600" -DEFAULT_RETRY="60" - -# Functions. -show_help() { - local SCRIPT="${0##*/}" - - #........1.........2.........3.........4.........5.........6.........7.........8 - cat <<-EOF - Usage: $SCRIPT [config file] [options] - Push notifications to your https://pushover.net registered devices. - - If [config_file] is specified it is used to read the default configuration. - If [config_file] is not specified, a custom user or system 'default' file will be - read to obtain the defaults. If no 'default' custom user or system config file - can be read, command line options are required for operation. - Command line [options] override any config file. - - Options: - -a, --attachment The picture to send with the alert. No default. - -A, --api-url The API URL to use for this submission. Default - is: $CONFIG_API_URL. - Quote if it contains shell special chars. - -c, --callback A URL which is accessed by API server when the - user acknowledges the alert. This option is - only used in priority 2 alerts. - Quote if it contains shell special chars. - -d, --devices A comma seperated list of the devices to receive - the alert. Default is to send to all devices. - -e, --expiry Set the expiration time for alerts sent with - priority 2. Default is 3600 (1 hour). The - maximum expiry time is 10800 (3 hours). - --examples Show extended example usage of this program. - -h, --help Show this help page. - -m, --message The plain text message to send. - Quote if it contains spaces. - This option or -M is required if a message is - not available from a config file. - -M, --html-message The HTML message to send. - Quote if it contains spaces. - This option or -m is required if a message is - not available from a config file. - --monospace Use a monospace font to display the message - given with -m. Default is to use regular font. - This option cannot be used with -M. - -p, --priority Set the priority of the message: - -2 Lowest priority - no alert/notification - will be generated. However, the app - badge or number will update on devices. - -1 Low priority - no alert sound is - emitted but a notification will appear. - During a user's configured quiet hours, - priority -1 is used for messages. - 0 Normal priority (the default) - an alert - sound and notification are generated. - 1 High priority - bypass the user's - configured quiet hours and generate an - alert and notification. - 2 Emergency - as priority 1, but the alert - and notification is repeated (subject to - the -r and -e options) until it is - acknowledged by the recipient. - -q, --quiet Do not print the API execution reply to stdout. - -r, --retry Set the retry interval for alerts sent with - priority 2. Default is 60 (1 minute). The - minimum retry time is 30 seconds. - -s, --subject The subject/title of the message. If unset, - the configured app name is used. - Quote if it contains spaces. - -S, --sound Set the alert sound to play with message: - none None/silent. - vibrate Vibrate only. - pushover Pushover (short, default). - bike Bike (short). - bugle Bugle (short). - cashregister Cash Register (short). - classical Classical (short). - cosmic Cosmic (short). - falling Falling (short). - gamelan Gamelan (short). - incoming Incoming (short). - intermission Intermission (short). - magic Magic (short). - mechanical Mechanical (short). - pianobar Piano Bar (short). - siren Siren (short). - spacealarm Space Alarm (short). - tugboat Tug Boat (short). - alien Alien Alarm (long). - climb Climb (long). - persistent Persistent (long). - echo Pushover Echo (long). - updown Up Down (long). - Or a sound uploaded to the user's account. - -t, --token The pushover.net API token/key for the specific - application. This option is required if not - available from a config file. - -T, --ttl The number of seconds the alert will live (or - be displayed) on a users device before being - automatically removed. The default is no ttl. - This option is ignored when alerts are sent with - priority (-p) 2. - --timestamp The number of seconds since the unix epoch to - use as the timestamp for the alert. - The default timestamp is the time the API - received the message. - -u, --user The pushover.net user key(s). If a single user - key is specified, that account's configuration - will be used for the alerts. If a comma - separated list (maximum 50) of user keys is - given, the alert is sent only to those users. - This option is required if not available from a - config file. - -U, --url Set the URL to send with the alert. - Quote if it contains shell special chars. - --url-title The title of the URL given with -U. Ignored - if -U is not used also. - Quote if it contains spaces. - Option processing ceases with "--". - - For example usage, use: $SCRIPT --examples - EOF -} - -show_examples() { - local SCRIPT="${0##*/}" - - #........1.........2.........3.........4.........5.........6.........7.........8 - cat <<-EOF - Basic usage is: $SCRIPT [config file] [options] - - [config file] configuration options are overridden by command line [options]. - All or part settings may be specified in the [config file], with the addition of - command line [options] to augment the [config file] settings. - [options] can be seen by running: $SCRIPT --help - - Command line examples: - Send a plain text message to all devices, showing all required [options]. - $SCRIPT -u -t -m "Test message" - - Same as the above, but do not show any response from the API server (an - appropriate error/return code is set). - $SCRIPT -q -u -t -m "Test message" - - Send a HTML message (which will be underlined) to all devices, showing all - required [options]. - $SCRIPT -u -t -M "Test message" - - Send a plain text message to all devices, with the addition of a subject/title - to the message. - $SCRIPT -u -t -s "Test subject" -m "..." - - Send a message to all devices, including a picture attachment. - $SCRIPT -u -t -a -m "..." - - Send a message to all devices, including a supplimentary URL with a title. - $SCRIPT -u -t -U "https://afterdark.org.uk" \\ - --url-title "Afterdark" -m "Check out the included URL!" - - Send a message to all devices, selecting an alternative sound alert. - $SCRIPT -u -t -s "magic" -m "..." - - Send a message to a specific list of devices. - $SCRIPT -u -t -d "iphone,ipad" -m "..." - - Send an emergency alert, repeated every minute for an 2 hours until it is - acknowledged by the user. - $SCRIPT -u -t -p 2 -r 60 -e 7200 -m "..." - - Read all configuration from path and use that for sending the - alert. If this path does not exist, search for a file matching the the - name in the user's private pushover directory (~/.pushover-client) - or the system wide pushover directory (/etc/pushover-client), in that order. - $SCRIPT - EOF -} - -# Pick out possible config file and '--' arguments of the command line. -ARGS=( "$@" ) -(( ${#ARGS[@]} >= 1 )) && FIRST_ARG="${ARGS[0]}" -(( ${#ARGS[@]} >= 2 )) && SECOND_ARG="${ARGS[1]}" - -# Get the config filename if it was given on the command line, or use the default. -[[ -z "$FIRST_ARG" ]] || [[ "$FIRST_ARG" =~ -[^-] ]] && FILENAME="$DEFAULT_CONFIG_FILE" && SKIP_CUSTOM=1 -[[ ! -v FILENAME ]] && [[ "$FIRST_ARG" != -* ]] && FILENAME="$FIRST_ARG" && unset "ARGS[0]" -[[ ! -v FILENAME ]] && [[ "$FIRST_ARG" == "--" ]] && [[ -n "$SECOND_ARG" ]] && FILENAME="$SECOND_ARG" && unset "ARGS[1]" - -# Find and validate the correct config filename. -if (( ${SKIP_CUSTOM:-0} == 1 )) && [[ -e "$DEFAULT_USER_DIR/$FILENAME" ]] && [[ ! -d "$DEFAULT_USER_DIR/$FILENAME" ]] && \ - [[ -r "$DEFAULT_USER_DIR/$FILENAME" ]]; then - FILENAME="$DEFAULT_USER_DIR/$FILENAME" -elif (( ${SKIP_CUSTOM:-0} == 1 )) && [[ -e "$DEFAULT_SYSTEM_DIR/$FILENAME" ]] && [[ ! -d "$DEFAULT_SYSTEM_DIR/$FILENAME" ]] && \ - [[ -r "$DEFAULT_SYSTEM_DIR/$FILENAME" ]]; then - FILENAME="$DEFAULT_SYSTEM_DIR/$FILENAME" -elif [[ "${FILENAME:0:1}" != "/" ]] && [[ -e "$FILENAME" ]] && [[ ! -d "$FILENAME" ]] && [[ -r "$FILENAME" ]]; then - : -elif [[ "${FILENAME:0:1}" != "/" ]] && [[ -e "$DEFAULT_USER_DIR/$FILENAME" ]] && [[ ! -d "$DEFAULT_USER_DIR/$FILENAME" ]] && \ - [[ -r "$DEFAULT_USER_DIR/$FILENAME" ]]; then - FILENAME="$DEFAULT_USER_DIR/$FILENAME" -elif [[ "${FILENAME:0:1}" != "/" ]] && [[ -e "$DEFAULT_SYSTEM_DIR/$FILENAME" ]] && [[ ! -d "$DEFAULT_SYSTEM_DIR/$FILENAME" ]] && \ - [[ -r "$DEFAULT_SYSTEM_DIR/$FILENAME" ]]; then - FILENAME="$DEFAULT_SYSTEM_DIR/$FILENAME" -elif [[ "${FILENAME:0:1}" == "/" ]] && [[ -e "$FILENAME" ]] && [[ ! -d "$FILENAME" ]] && [[ -r "$FILENAME" ]]; then - : -elif [[ -n "$FILENAME" ]]; then - printf "%s: '%s' %s\\n" "${0##*/}" "$FILENAME" "invalid config file name" >&2 - exit 1 -fi - -# Read the config file. -[[ -n "$FILENAME" ]] && { - eval "$(awk '!/^(#|$|[[:blank:]]*$)/ { print "CONFIG_"$0 }' "$FILENAME")" 2>/dev/null || { - printf "%s: %s '%s'\\n" "${0##*/}" "error in config file" "$FILENAME" >&2 - exit 1 - } -} - -# Parse command line options. -set -- "${ARGS[@]}" -while [[ -n "$1" ]]; do - case "$1" in - -a|-attachment|--attachment) - if [[ "$2" =~ ^[[:blank:]]*$ ]]; then - printf "%s: %s\\n" "${0##*/}" "attachment filename cannot be an empty value" >&2 - exit 1 - else - CONFIG_ATTACHMENT="$2" - fi - shift - ;; - -A|-api-url|--api-url) - # Setting is validated below. - CONFIG_API_URL="$2" - shift - ;; - -c|-callback|--callback) - if [[ "$2" =~ ^[[:blank:]]*$ ]]; then - printf "%s: %s\\n" "${0##*/}" "callback URL address cannot be empty" >&2 - exit 1 - else - CONFIG_CALLBACK_URL="$2" - fi - shift - ;; - -d|-devices|--devices) - if [[ "$2" =~ ^[[:blank:]]*$ ]]; then - printf "%s: %s\\n" "${0##*/}" "device list cannot be an empty value" >&2 - exit 1 - else - CONFIG_DEVICES="$2" - fi - shift - ;; - -e|-expiry|--expiry) - if [[ "$2" =~ ^[[:blank:]]*$ ]]; then - printf "%s: %s\\n" "${0##*/}" "expiry time cannot be an empty value" >&2 - exit 1 - else - CONFIG_EXPIRY="$2" - fi - shift - ;; - -examples|--examples) - show_examples - exit 0 - ;; - -h|-help|--help) - show_help - exit 0 - ;; - -m|-message|--message) - # Setting is validated below. - CONFIG_MESSAGE="$2" - shift - ;; - -M|-html-message|--html-message) - # Setting is validated below. - CONFIG_HTML_MESSAGE="$2" - shift - ;; - -monospace|--monospace) - # Setting is validated below. - CONFIG_MONOSPACE="1" - shift - ;; - -p|-priority|--priority) - if [[ "$2" =~ ^[[:blank:]]*$ ]]; then - printf "%s: %s\\n" "${0##*/}" "priority setting cannot be an empty value" >&2 - exit 1 - else - CONFIG_PRIORITY="$2" - fi - shift - ;; - -q|-quiet|--quiet) - CONFIG_QUIET=1 - shift - ;; - -r|-retry|--retry) - if [[ "$2" =~ ^[[:blank:]]*$ ]]; then - printf "%s: %s\\n" "${0##*/}" "retry time cannot be an empty value" >&2 - exit 1 - else - CONFIG_RETRY="$2" - fi - shift - ;; - -s|-subject|--subject) - if [[ "$2" =~ ^[[:blank:]]*$ ]]; then - printf "%s: %s\\n" "${0##*/}" "subject/title cannot be an empty value" >&2 - exit 1 - else - CONFIG_SUBJECT="$2" - fi - shift - ;; - -S|-sound|--sound) - if [[ "$2" =~ ^[[:blank:]]*$ ]]; then - printf "%s: %s\\n" "${0##*/}" "sound selection cannot be empty" >&2 - exit 1 - else - CONFIG_SOUND="$2" - fi - shift - ;; - -t|-token|--token) - if [[ "$2" =~ ^[[:blank:]]*$ ]]; then - printf "%s: %s\\n" "${0##*/}" "token key cannot be an empty value" >&2 - exit 1 - else - CONFIG_TOKEN="$2" - fi - shift - ;; - -T|-ttl|--ttl) - if [[ "$2" =~ ^[[:blank:]]*$ ]]; then - printf "%s: %s\\n" "${0##*/}" "ttl cannot be an empty value" >&2 - exit 1 - else - CONFIG_TTL="$2" - fi - shift - ;; - -timestamp|--timestamp) - if [[ "$2" =~ ^[[:blank:]]*$ ]]; then - printf "%s: %s\\n" "${0##*/}" "timestamp cannot be an empty value" >&2 - exit 1 - else - CONFIG_TIMESTAMP="$2" - fi - shift - ;; - -u|-user|--user) - # Setting is validated below. - CONFIG_USER_KEYS="$2" - shift - ;; - -U|-url|--url) - if [[ "$2" =~ ^[[:blank:]]*$ ]]; then - printf "%s: %s\\n" "${0##*/}" "URL address cannot be empty" >&2 - exit 1 - else - CONFIG_URL="$2" - fi - shift - ;; - -url-title|--url-title) - if [[ "$2" =~ ^[[:blank:]]*$ ]]; then - printf "%s: %s\\n" "${0##*/}" "URL title cannot be empty" >&2 - exit 1 - else - CONFIG_URL_TITLE="$2" - fi - shift - ;; - --) - shift - break - ;; - *) - printf "%s: %s: %s\\n" "${0##*/}" "invalid option" "$1" >&2 - printf "%s: %s %s\\n" "Try" "${0##*/}" "--help" >&2 - exit 1 - ;; - esac - shift -done - -# The options list should be empty if the correct syntax was used. -[[ -n "$1" ]] && { - printf "%s: %s\\n" "${0##*/}" "options cannot come after --" >&2 - exit 1 -} - -# Validate all the CONFIG_* settings. -[[ "$CONFIG_API_URL" =~ ^[[:blank:]]*$ ]] && { - printf "%s: %s\\n" "${0##*/}" "API URL (-A) cannot be an empty value" >&2 - exit 1 -} - -if [[ ! "$CONFIG_ATTACHMENT" =~ ^[[:blank:]]*$ ]]; then - if [[ ! -e "$CONFIG_ATTACHMENT" ]]; then - printf "%s: %s '%s' %s\\n" "${0##*/}" "attachment (-a)" "$CONFIG_ATTACHMENT" "does not exist" >&2 - exit 1 - elif [[ -d "$CONFIG_ATTACHMENT" ]]; then - printf "%s: %s '%s' %s\\n" "${0##*/}" "attachment (-a)" "$CONFIG_ATTACHMENT" "is a directory, not a file" >&2 - exit 1 - elif [[ ! -r "$CONFIG_ATTACHMENT" ]]; then - printf "%s: %s '%s' %s\\n" "${0##*/}" "attachment (-a)" "$CONFIG_ATTACHMENT" "is not readable by you" >&2 - exit 1 - elif (( $(stat --printf=%s "$CONFIG_ATTACHMENT") > 2621440 )); then - printf "%s: %s\\n" "${0##*/}" "attachment (-a) is too large (2.5MB maximum)" >&2 - exit 1 - fi -else - unset "CONFIG_ATTACHMENT" -fi - -if [[ ! "$CONFIG_CALLBACK_URL" =~ ^[[:blank:]]*$ ]]; then - (( ${#CONFIG_CALLBACK_URL} > 512 )) && { - printf "%s: %s\\n" "${0##*/}" "callback URL (-c) is too long (maximum 512 characters)" >&2 - exit 1 - } -else - unset "CONFIG_CALLBACK_URL" -fi - -if [[ ! "$CONFIG_DEVICES" =~ ^[[:blank:]]*$ ]]; then - while read -r -d , DEV; do - [[ -z "$DEV" ]] && continue - if (( "${#DEV}" > 25 )); then - printf "%s: %s\\n" "${0##*/}" "device IDs (-d) are 25 characters or less in length" >&2 - exit 1 - elif [[ ! "$DEV" =~ ^[[:alnum:]_-]*$ ]]; then - printf "%s: %s\\n" "${0##*/}" "device IDs (-d) can only be letters, numbers, _ and -" >&2 - exit 1 - else - if [[ -z "$LIST" ]]; then - LIST="$DEV" - else - LIST+=",$DEV" - fi - fi - done <<<"$CONFIG_DEVICES," # The , on the end is required. - CONFIG_DEVICES="$LIST" -else - unset "CONFIG_DEVICES" -fi - -if [[ ! "$CONFIG_EXPIRY" =~ ^[[:blank:]]*$ ]]; then - if [[ ! "$CONFIG_EXPIRY" =~ [[:digit:]] ]]; then - printf "%s: %s\\n" "${0##*/}" "expiry time (-e) must be a number" >&2 - exit 1 - elif (( CONFIG_EXPIRY < 30 )); then - printf "%s: %s\\n" "${0##*/}" "expiry time (-e) cannot be that short (30s minimum)" >&2 - exit 1 - elif (( CONFIG_EXPIRY > 10800 )); then - printf "%s: %s\\n" "${0##*/}" "expiry time (-e) cannot be that long (10800s/3h maximum)" >&2 - exit 1 - elif [[ -n "$CONFIG_RETRY" ]] && (( CONFIG_EXPIRY < CONFIG_RETRY )); then - printf "%s: %s\\n" "${0##*/}" "expiry time (-e) is less than retry time" >&2 - exit 1 - fi -else - unset "CONFIG_EXPIRY" -fi - -if [[ "$CONFIG_MONOSPACE" =~ ^[[:blank:]]*$ ]] || [[ "$CONFIG_MONOSPACE" =~ ^(false|0)$ ]]; then - CONFIG_MONOSPACE=0 -elif [[ "$CONFIG_MONOSPACE" =~ ^(true|1)$ ]]; then - CONFIG_MONOSPACE=1 -else - printf "%s: %s\\n" "${0##*/}" "monospace (--monospace) setting must be 'true', '1', 'false' or '0'" >&2 - exit 1 -fi - -if [[ ! "$CONFIG_MESSAGE" =~ ^[[:blank:]]*$ ]] && [[ ! "$CONFIG_HTML_MESSAGE" =~ ^[[:blank:]]*$ ]]; then - printf "%s: %s\\n" "${0##*/}" "cannot mix a plain text (-m) and HTML (-M) message setting" >&2 - exit 1 -elif [[ "$CONFIG_MESSAGE" =~ ^[[:blank:]]*$ ]] && [[ "$CONFIG_HTML_MESSAGE" =~ ^[[:blank:]]*$ ]]; then - printf "%s: %s\\n" "${0##*/}" "must set either a plain text (-m) or HTML (-M) message" >&2 - exit 1 -elif [[ ! "$CONFIG_HTML_MESSAGE" =~ ^[[:blank:]]*$ ]] && (( CONFIG_MONOSPACE == 1 )); then - printf "%s: %s\\n" "${0##*/}" "HTML messages (-M) cannot be used with a monospace font (--monospace)" >&2 - exit 1 -elif (( ${#CONFIG_MESSAGE} > 1024 )) || (( ${#CONFIG_HTML_MESSAGE} > 1024 )); then - printf "%s: %s\\n" "${0##*/}" "message (-m/-M) length is too long (maximum 1024 characters)" >&2 - exit 1 -fi - -if [[ ! "$CONFIG_PRIORITY" =~ ^[[:blank:]]*$ ]]; then - if [[ ! "$CONFIG_PRIORITY" =~ [[:digit:]] ]]; then - printf "%s: %s\\n" "${0##*/}" "priority (-p) setting must be a number" >&2 - exit 1 - elif (( CONFIG_PRIORITY < -2 )) || (( CONFIG_PRIORITY > 2 )); then - printf "%s: %s\\n" "${0##*/}" "priority (-p) setting must be in the range -2 - 2" >&2 - exit 1 - fi -else - unset "CONFIG_PRIORITY" -fi - -if [[ "$CONFIG_QUIET" =~ ^[[:blank:]]*$ ]] || [[ "$CONFIG_QUIET" =~ ^(false|0)$ ]]; then - CONFIG_QUIET=0 -elif [[ "$CONFIG_QUIET" =~ ^(true|1)$ ]]; then - CONFIG_QUIET=1 -else - printf "%s: %s\\n" "${0##*/}" "quiet (-q) setting must be 'true', '1', 'false' or '0'" >&2 - exit 1 -fi - -if [[ ! "$CONFIG_RETRY" =~ ^[[:blank:]]*$ ]]; then - if [[ ! "$CONFIG_RETRY" =~ [[:digit:]] ]]; then - printf "%s: %s\\n" "${0##*/}" "retry time (-r) must be a number" >&2 - exit 1 - elif (( CONFIG_RETRY < 30 )); then - printf "%s: %s\\n" "${0##*/}" "retry time (-r) cannot be that short (30s minimum)" >&2 - exit 1 - elif [[ -n "$CONFIG_EXPIRY" ]] && (( CONFIG_RETRY > CONFIG_EXPIRY )); then - printf "%s: %s\\n" "${0##*/}" "retry time (-r) exceeds expiry time" >&2 - exit 1 - fi -else - unset "CONFIG_RETRY" -fi - -if [[ ! "$CONFIG_SUBJECT" =~ ^[[:blank:]]*$ ]]; then - (( ${#CONFIG_SUBJECT} > 250 )) && { - printf "%s: %s\\n" "${0##*/}" "subject/title (-s) is too long (maximum 250 characters)" >&2 - exit 1 - } -else - unset "CONFIG_SUBJECT" -fi - -if [[ ! "$CONFIG_TOKEN" =~ ^[[:blank:]]*$ ]]; then - if (( "${#CONFIG_TOKEN}" != 30 )); then - printf "%s: %s\\n" "${0##*/}" "token key (-t) must be 30 characters in length" >&2 - exit 1 - elif [[ ! "$CONFIG_TOKEN" =~ ^[[:alnum:]]*$ ]]; then - printf "%s: %s\\n" "${0##*/}" "token key (-t) can only be letters and numbers" >&2 - exit 1 - fi -else - printf "%s: %s\\n" "${0##*/}" "token key (-t) cannot be an empty value" >&2 - exit 1 -fi - -if [[ ! "$CONFIG_SOUND" =~ ^[[:blank:]]*$ ]]; then - [[ ! "$CONFIG_SOUND" =~ ^(none|vibrate|pushover|bike|bugle|cashregister|classical|cosmic|falling|gamelan|incoming|intermission|magic|mechanical|pianobar|siren|spacealarm|tugboat|alien|climb|persistent|echo|updown)$ ]] && { - JSON="$(curl -s "$CONFIG_SOUNDS_API_URL?token=$CONFIG_TOKEN" 2>/dev/null)" - if [[ "$JSON" =~ \"status\":1, ]]; then - [[ ! "$JSON" =~ \"$CONFIG_SOUND\": ]] && { - printf "%s: %s\\n" "${0##*/}" "sound (-S) must be a built-in or user uploaded custom sound" >&2 - exit 1 - } - else - printf "%s: %s\\n" "${0##*/}" "failed to get list of custom sounds from API (invalid API token?)" >&2 - exit 1 - fi - } -else - unset "CONFIG_SOUND" -fi - -if [[ ! "$CONFIG_TTL" =~ ^[[:blank:]]*$ ]]; then - if [[ ! "$CONFIG_TTL" =~ [[:digit:]] ]]; then - printf "%s: %s\\n" "${0##*/}" "TTL (-T) must be a number" >&2 - exit 1 - elif (( CONFIG_TTL < 0 )); then - printf "%s: %s\\n" "${0##*/}" "TTL (-T) must be a positive number of seconds" >&2 - exit 1 - fi -else - unset "CONFIG_TTL" -fi - -if [[ ! "$CONFIG_TIMESTAMP" =~ ^[[:blank:]]*$ ]]; then - if [[ ! "$CONFIG_TIMESTAMP" =~ [[:digit:]] ]]; then - printf "%s: %s\\n" "${0##*/}" "timestamp (--timestamp) must be a number" >&2 - exit 1 - elif (( CONFIG_TIMESTAMP < 0 )); then - printf "%s: %s\\n" "${0##*/}" "timestamp (--timestamp) must be a positive number of seconds" >&2 - exit 1 - fi -else - unset "CONFIG_TIMESTAMP" -fi - -if [[ ! "$CONFIG_USER_KEYS" =~ ^[[:blank:]]*$ ]]; then - unset COUNT LIST - while read -r -d , KEY; do - [[ -z "$KEY" ]] && continue - if (( "${#KEY}" != 30 )); then - printf "%s: %s\\n" "${0##*/}" "user keys (-u) must be 30 characters in length" >&2 - exit 1 - elif [[ ! "$KEY" =~ ^[[:alnum:]]*$ ]]; then - printf "%s: %s\\n" "${0##*/}" "user keys (-u) can only be letters and numbers" >&2 - exit 1 - else - if [[ -z "$LIST" ]]; then - LIST="$KEY" - COUNT=1 - else - LIST+=",$KEY" - (( COUNT++ )) - fi - fi - done <<<"$CONFIG_USER_KEYS," # The , on the end is required. - (( COUNT > 50 )) && { - printf "%s: %s\\n" "${0##*/}" "too many user keys (-u) (maximum 50)" >&2 - exit 1 - } - CONFIG_USER_KEYS="$LIST" -else - printf "%s: %s\\n" "${0##*/}" "user keys (-u) cannot be an empty value" >&2 - exit 1 -fi - -if [[ ! "$CONFIG_URL" =~ ^[[:blank:]]*$ ]]; then - (( ${#CONFIG_URL} > 512 )) && { - printf "%s: %s\\n" "${0##*/}" "URL (-U) is too long (maximum 512 characters)" >&2 - exit 1 - } -else - unset "CONFIG_URL" -fi - -if [[ ! "$CONFIG_URL_TITLE" =~ ^[[:blank:]]*$ ]]; then - (( ${#CONFIG_URL_TITLE} > 100 )) && { - printf "%s: %s\\n" "${0##*/}" "URL title (--url-title) is too long (maximum 100 characters)" >&2 - exit 1 - } -else - unset "CONFIG_URL_TITLE" -fi - -# Build the curl command line. -COMMAND_LINE=('-s') -# Required API elements. -COMMAND_LINE+=('--form-string' user="$CONFIG_USER_KEYS") -COMMAND_LINE+=('--form-string' token="$CONFIG_TOKEN") -if [[ -v CONFIG_MESSAGE ]]; then - COMMAND_LINE+=('--form-string' message="$CONFIG_MESSAGE") - (( CONFIG_MONOSPACE == 1 )) && COMMAND_LINE+=('--form-string' 'monospace=1') -else - COMMAND_LINE+=('--form-string' message="$CONFIG_HTML_MESSAGE") - COMMAND_LINE+=('--form-string' 'html=1') -fi -# Optional API elements. -[[ -v CONFIG_ATTACHMENT ]] && COMMAND_LINE+=('--form' attachment="@$CONFIG_ATTACHMENT") -[[ -v CONFIG_DEVICES ]] && COMMAND_LINE+=('--form-string' device="$CONFIG_DEVICES") -[[ -v CONFIG_PRIORITY ]] && { - COMMAND_LINE+=('--form-string' priority="$CONFIG_PRIORITY") - (( CONFIG_PRIORITY == 2 )) && { - [[ -v CONFIG_CALLBACK_URL ]] && COMMAND_LINE+=('--form-string' callback="$CONFIG_CALLBACK_URL") - COMMAND_LINE+=('--form-string' expire="${CONFIG_EXPIRY:-$DEFAULT_EXPIRY}") - COMMAND_LINE+=('--form-string' retry="${CONFIG_RETRY:-$DEFAULT_RETRY}") - } -} -[[ -v CONFIG_SUBJECT ]] && COMMAND_LINE+=('--form-string' title="$CONFIG_SUBJECT") -[[ -v CONFIG_SOUND ]] && COMMAND_LINE+=('--form-string' sound="$CONFIG_SOUND") -[[ -v CONFIG_TTL ]] && COMMAND_LINE+=('--form-string' ttl="$CONFIG_TTL") -[[ -v CONFIG_TIMESTAMP ]] && COMMAND_LINE+=('--form-string' timestamp="$CONFIG_TIMESTAMP") -[[ -v CONFIG_URL ]] && COMMAND_LINE+=('--form-string' url="$CONFIG_URL") -[[ -v CONFIG_URL_TITLE ]] && COMMAND_LINE+=('--form-string' url_title="$CONFIG_URL_TITLE") - -# Make the call to the messaging API. -JSON="$(curl "${COMMAND_LINE[@]}" "$CONFIG_API_URL" 2>/dev/null)" || { - printf "%s: %s\\n" "${0##*/}" "API call failed" >&2 - exit 3 -} -if [[ "$JSON" =~ \"status\":1, ]]; then - (( CONFIG_QUIET == 0 )) && printf "%s\\n" "$JSON" -else - printf "%s: %s\\n" "${0##*/}" "API returned a non-success status code" >&2 - (( CONFIG_QUIET == 0 )) && printf "%s\\n" "$JSON" >&2 - exit 2 -fi - -# 0 = Request submitted OK. -# 1 = Usage error. -# 2 = Request status error from API -# 3 = Error accessing API -exit 0