summaryrefslogtreecommitdiff
path: root/localsmsadmin
diff options
context:
space:
mode:
authorJonas <dr@jones.dk>2010-05-31 09:24:55 +0200
committerJonas <dr@jones.dk>2010-05-31 09:24:55 +0200
commit3d80bf3353d786c759c3f454e3d13dfbd7ddd647 (patch)
treed8c903851f4980d967a93687a4cd9ed49d44674b /localsmsadmin
parent175cc7c95b2c7f36ac461b633673de18d531f205 (diff)
Major updates to localkannel-dispatch and localsmsadmin.
Diffstat (limited to 'localsmsadmin')
-rwxr-xr-xlocalsmsadmin284
1 files changed, 209 insertions, 75 deletions
diff --git a/localsmsadmin b/localsmsadmin
index 7b6c8d1..054db55 100755
--- a/localsmsadmin
+++ b/localsmsadmin
@@ -2,19 +2,25 @@
set -e
+# make data writable both from kannel and designated shell accounts
+umask 0007
+
+vardir=/var/lib/kannel/hello
+sbindir=/usr/local/sbin
+
exit0() {
- echo "$1"
+ [ -n "$1" ] && echo "$1"
exit 0
}
-
exit1() {
+ [ -z "$1" ] || echo "Error: $1" || echo "Internal error!"
+ response="${1+Error: $1}${-Internal error!}"
# FIXME: pass error messages via stderr (not stdout)
-# echo >&2 "Error: $1"
- [ -z "$1" ] || echo "$1"
+# echo >&2 "$response"
+ echo "$response"
exit 1
}
-vardir="/var/lib/kannel/hello"
findobjects() {
set -e
type="$1"; [ -n "$type" ] || return1 "Internal error (findobjects: empty type)!"; shift
@@ -73,115 +79,243 @@ additem() {
truename="$(findobjects "$type" "$name")" || exit1 "$truename"
[ -n "$truename" ] || exit1 "No $type named \"$name\"!"
file="$type/$truename/$item"
+# [ ! -s "$vardir/$file" ] || linecount="$(grep -c . "$vardir/$file")"
+# echo "$data" >> "$vardir/$file"
+# chgrp --reference="$vardir" "$vardir/$file"
+# echo "$data${linecount+ (on top of $linecount other values)}"
[ ! -s "$vardir/$file" ] || linecount="$(grep -c . "$vardir/$file")"
- echo "$data" >> "$vardir/$file"
- chgrp --reference="$vardir" "$vardir/$file"
- echo "$data${linecount+ (on top of $linecount other values)}"
+ echo "$data" > "$vardir/$file"
+# chgrp --reference="$vardir" "$vardir/$file"
+ echo "$data"
}
addobject() {
set -e
type="$1"; [ -n "$type" ] || exit1 "Internal error (addobject: empty type)!"; shift
name="$1"; [ -n "$name" ] || exit1 "Internal error (addobject: empty name)!"; shift
- oldname="$(findobjects "$type" "$name")" || exit1 "$oldname"
- [ -z "$oldname" ] || exit1 "$type \"$name\" already exist!"
+ fallback="$1"; [ -n "$fallback" ] || exit1 "Internal error (addobject: empty fallback)!"; shift
+ [ -z "$*" ] || exit1 "Internal error (addobject: too many options)!"
+ case "$fallback" in
+ keep|replace|fail) :;;
+ *) exit1 "Internal error (addobject: unknown fallback)!";;
+ esac
- case "$type" in
- user)
- session="$(findobjects "session" "default")" || exit1 "$truename"
- [ -z "$session" ] || phone_ccc="$(finditems "session" "$session" "phone_ccc")" || exit1 "$phone_ccc"
- for chunk in $@; do
- case $chunk in
- +[[:digit:]]*)
- [ -z "$phone" ] || exit1 "Multiple phone numbers (use only a single number, e.g. 40843136 or +4540843136)!"
- phone_ccc="$chunk"
+# if [ -e "$vardir/$type/$name" ]; then
+ oldname="$(findobjects "$type" "$name")" || exit1 "$oldname"
+ if [ -n "$oldname" ]; then
+ case "$fallback" in
+ keep)
+ action="kept"
;;
- [[:digit:]][[:digit:]][[:digit:]][[:digit:]]*)
- [ -n "$phone_ccc" ] || [ -n "$phone_ccc_default" ] || exit1 "Unknown country calling code (use international phone numbering, e.g. +4540843136)!"
- [ -z "$phone" ] || exit1 "Multiple phone numbers (use only a single number, e.g. 40843136 or +4540843136)!"
- # TODO: optionally validate $phone_min and $phone_max
- phone="$phone_ccc$chunk"
+ replace)
+ delopbject "$type" "$oldname"
;;
- [[:alpha:]][[:alnum:]]*)
- [ -z "$nick" ] || exit1 "Multiple nick names (use only a single nick name)!"
- nick="$chunk"
+# TODO rename)
+# TODO renameopbject "$type" "$oldname"
+# TODO ;;
+ fail)
+ exit1 "Adding $type failed ($name already exists)!"
;;
- *)
- exit1 "Internal error (additems: unknown item)!"
- ;;
- esac
- done
- [ -n "$phone" ] || exit1 "Missing phone number (use a single full number, e.g. 40843136 or +4540843136)!"
- [ -n "$nick" ] || exit1 "Missing nick name!"
- ;;
- esac
-
- mkdir -p "$vardir/$type/$name"
- chgrp --reference="$vardir" "$vardir/$type/$name"
- case "$type" in
- user)
- additem "$type" "$name" "nick" "$nick"
- additem "$type" "$name" "phone" "$phone"
- details="with nick and phone number"
- ;;
- esac
-
- echo "$name${details+: ($details)}"
-}
-delobject() {
- set -e
- type="$1"; [ -n "$type" ] || exit1 "Internal error (delobject: empty type)!"; shift
- name="$1"; [ -n "$name" ] || exit1 "Internal error (delobject: empty name)!"; shift
- oldname="$(findobjects "$type" "$name")" || exit1 "$oldname"
- [ -n "$oldname" ] || exit1 "No $type named \"$name\"!"
- items="$(finditems "$type" "$name")" || exit1 "$items"
- for item in $items; do
- rm "$vardir/$type/$name/$item" || exit1 "Internal error!"
- done
- rmdir "$vardir/$type/$name" || exit1 "Internal error!"
- echo "$name"
+ esac
+ else
+ mkdir -p "$vardir/$type/$name"
+# chgrp -R --reference="$vardir" "$vardir/$type"
+ fi
}
cmd="$1"; shift
case "$cmd" in
add|create)
- case "$1" in
- user|group)
- type="$1"; shift
- response="$(addobject "$type" "$@")" || exit1 "Failed adding $type${response+: $response}"
- exit0 "Added $type: $response."
+ type="$1"; [ -n "$type" ] || exit1 "Internal error (empty type)!"; shift
+ name="$1"; [ -n "$name" ] || exit1 "Internal error (empty name)!"; shift
+ oldname="$(findobjects "$type" "$name")" || exit1 "$oldname"
+
+ case "$type" in
+ default)
+ case "$name" in
+ session|prefix)
+ item="$name"
+ data="$1"
+ ;;
+ *)
+ exit1 "unknown default \"$1\""
+ ;;
+ esac
+ str=$(addobject "$type" "$name" keep) || exit1 "$str"
+ str=$(additem "$type" "$name" "$item" "$data") || exit1 "$str"
+ response="Added $type $name $data"
+ ;;
+ user)
+ session="$(getitem "default" "session" "session")" || exit1 "Internal error: $session"
+ [ -z "$session" ] || session_group="$(getitem "session" "$session" "group")" || exit1 "Internal error: $session_group"
+ plural=
+ for chunk in $@; do
+ case $chunk in
+ +[[:digit:]]*)
+ [ -z "$phone" ] || exit1 "Too many phone numbers (use only a single number, e.g. 40843136 or +4540843136)!"
+ phone="$chunk"
+ ;;
+ [[:digit:]][[:digit:]][[:digit:]][[:digit:]]*)
+ [ -z "$phone" ] || exit1 "Too many phone numbers (use only a single number, e.g. 40843136 or +4540843136)!"
+ [ -z "$session" ] || prefix="$(getitem "session" "$session" "prefix")" || exit1 "Internal error: $prefix"
+ [ -n "$prefix" ] || exit1 "Missing prefix (use international phone numbering, e.g. +4540843136${session+, or add default prefix to session $session})!"
+ # TODO: optionally validate $phone_min and $phone_max
+ phone="$prefix$chunk"
+ ;;
+ [[:alpha:]][[:alnum:]]*)
+ [ -z "$groups" ] || plural=true
+ groups="${groups+$groups }$chunk"
+ ;;
+ *)
+ exit1 "Internal error (unknown user item \"$1\")!"
+ ;;
+ esac
+ done
+ response="Added $type $name"
+ fallback=fail
+ if [ -z "$oldname" ]; then
+ [ -n "$phone" ] || exit1 "Missing phone number (required)!"
+ else
+ [ -n "$phone$groups" ] || exit1 "No items to update (include one or more of phone number and groups)!"
+ fallback=keep
+ response="Updated $type $name"
+ fi
+ str=$(addobject "$type" "$name" "$fallback") || exit1 "$str"
+ [ -z "$phone" ] || dummy="$(additem "$type" "$name" "phone" "$phone")"
+# TODO: distinguish session group from included ones (i.e. mention explicitly if added)
+ [ -z "$session_group" ] || groups="$session_group $groups"
+ for group in $groups; do
+# TODO: strip existing, duplicate and session groups, and mention stripping in response
+ dummy="$(additem "$type" "$name" "group" "$group")"
+ done
+ if [ -n "$phone" ]; then
+ if [ -n "$groups" ]; then
+ response="$response with phone $phone and group${plural+s} $groups"
+ else
+ response="$response with phone $phone"
+ fi
+ elif [ -n "$groups" ]; then
+ response="$response with group${plural+s} $groups"
+ fi
+ ;;
+ group)
+ for chunk in $@; do
+ case $chunk in
+ [[:alpha:]][[:alnum:]]*)
+ [ -z "$session" ] || exit1 "Too many sessions (a group can be only in a single session)!"
+ session="$chunk"
+ ;;
+ *)
+ exit1 "Internal error (unknown group item \"$1\")!"
+ ;;
+ esac
+ done
+ response="Added $type $name"
+ fallback=fail
+ if [ -n "$oldname" ]; then
+ [ -n "$session" ] || exit1 "Group already exists (and no session name to update was included)!"
+ fallback=keep
+ response="Updated $type $name"
+ fi
+ str=$(addobject "$type" "$name" "$fallback") || exit1 "$str"
+ [ -z "$session" ] || dummy="$(additem "$type" "$name" "session" "$session")"
+ [ -z "$session" ] || response="$response with session $session"
+ ;;
+ session)
+ for chunk in $@; do
+ case $chunk in
+ +[[:digit:]]*)
+ [ -z "$prefix" ] || exit1 "Too many country prefixes (use only one, e.g. +45)!"
+ prefix="$chunk"
+ ;;
+ [[:alpha:]][[:alnum:]]*)
+ [ -z "$group" ] || exit1 "Too many default groups (use only one)!"
+# FIXME: fail if group does not exist
+ group="$chunk"
+ ;;
+ *)
+ exit1 "Internal error (unknown session item \"$1\")!"
+ ;;
+ esac
+ done
+# TODO: distinguish default prefix from included one (i.e. mention explicitly if added)
+ [ -n "$prefix" ] || prefix="$(getitem "default" "prefix" "prefix")" || exit1 "Internal error: $prefix"
+ response="Added $type $name"
+ fallback=fail
+ if [ -n "$oldname" ]; then
+ [ -n "$prefix$group" ] || exit1 "Session already exists (and no default group or country prefix to add/update was included)!"
+ fallback=keep
+ response="Updated $type $name"
+ fi
+ str=$(addobject "$type" "$name" "$fallback") || exit1 "$str"
+ [ -z "$prefix" ] || dummy="$(additem "$type" "$name" "prefix" "$prefix")"
+ [ -z "$group" ] || dummy="$(additem "$type" "$name" "group" "$group")"
+ if [ -n "$prefix" ]; then
+ if [ -n "$group" ]; then
+ response="$response with default country prefix $prefix and default group $group"
+ else
+ response="$response with default country prefix $prefix"
+ fi
+ elif [ -n "$group" ]; then
+ response="$response with default group $group"
+ fi
;;
*)
- exit1 "Cannot add \"$1\" (try \"add user\" or \"add group\" instead)!"
+ exit1 "Cannot add \"$1\" (try \"/help\" to see supported commands)!"
;;
esac
+ exit0 "$response"
;;
del|delete|remove)
case "$1" in
- user|group)
+ default|user|group|session)
type="$1"; shift
- response="$(delobject "$type" "$@")" || exit1 "Failed deleting $type${response+: $response}"
- exit0 "Deleted $type: $response."
+ name="$1"; [ -n "$name" ] || exit1 "Internal error (empty name)!"; shift
+ [ -z "$*" ] || exit1 "Internal error (too many options)!"
+ oldname="$(findobjects "$type" "$name")" || exit1 "Internal error${oldname+: $oldname}"
+ [ -n "$oldname" ] || exit1 "No $type named \"$name\"!"
+ items="$(finditems "$type" "$name")" || exit1 "Internal error${items+: $items}"
+# TODO: find user by phone number
+ for item in $items; do
+ rm "$vardir/$type/$name/$item" || exit1 "Internal error during $type $name item removal!"
+ done
+# FIXME: remove items of other objects referencing this object
+ rmdir "$vardir/$type/$name" || exit1 "Internal error during $type $name object removal!"
+ exit0 "Deleted $type: $name."
;;
*)
- exit1 "Cannot delete \"$1\" (try \"del user\" or \"del group\" instead)!"
+ exit1 "Cannot delete \"$1\" (try \"/help\" to see supported commands)!"
;;
esac
;;
list|show|view)
case "$1" in
- user|group)
+ default|user|group|session)
type="$1"; shift
response="$(listobject "$type" "$@")" || exit1 "Failed listing $type${response+: $response}"
exit0 "Listing $type: $response."
;;
*)
- exit1 "Cannot list \"$1\" (try \"list user\" or \"list group\" instead)!"
+ exit1 "Cannot list \"$1\" (try \"/help\" to see supported commands)!"
;;
esac
;;
+ help)
+ cat <<EOF
+Admin commands:
+/add user NICK [+PREFIX]NUMBER [GROUP ...]
+/add group GROUP [USER ...]
+/add session SESSION [PREFIX] [GROUP]
+/add default prefix|session VALUE
+/del user NICK|NUMBER
+/del group GROUP
+/del session SESSION
+/del default prefix|session
+EOF
+ exit 0
+ ;;
status)
- msg="$(/usr/local/sbin/localshowkannelstatus)"
- exit0 "$msg"
+ response="$($sbindir/localshowkannelstatus)"
+ exit0 "$response"
;;
*)
exit1 "unknown command \"$cmd\"!"