From 175cc7c95b2c7f36ac461b633673de18d531f205 Mon Sep 17 00:00:00 2001 From: Jonas Date: Fri, 21 May 2010 19:46:53 +0200 Subject: Fork and extend localsmsadmin from localkannel-dispatch. --- localsmsadmin | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100755 localsmsadmin (limited to 'localsmsadmin') diff --git a/localsmsadmin b/localsmsadmin new file mode 100755 index 0000000..7b6c8d1 --- /dev/null +++ b/localsmsadmin @@ -0,0 +1,189 @@ +#!/bin/sh + +set -e + +exit0() { + echo "$1" + exit 0 +} + +exit1() { +# FIXME: pass error messages via stderr (not stdout) +# echo >&2 "Error: $1" + [ -z "$1" ] || echo "$1" + exit 1 +} + +vardir="/var/lib/kannel/hello" +findobjects() { + set -e + type="$1"; [ -n "$type" ] || return1 "Internal error (findobjects: empty type)!"; shift + limit="$@" + regex="$(echo "$limit" | perl -ne '/^\/(.+)\/$/ and print $1')" + args="$(echo "$limit" | perl -ne 's/.*?([a-z0-9]+).*?/ $1/g and print')" + [ -d "$vardir/$type" ] || exit0 + if [ -z "$*" ]; then + cd "$vardir/$type" && find -mindepth 1 -maxdepth 1 -type d -printf '%f\n' + elif [ -n "$regex" ]; then + cd "$vardir/$type" && find -mindepth 1 -maxdepth 1 -type d -regex "$regex" + elif [ -n $args ]; then + args_multiline="$(echo "$args" | perl -pe 's/[[:space:]]+/\n/g')" + cd "$vardir/$type" && ! find -mindepth 1 -maxdepth 1 -type d -printf '%f\n' \ + | grep -Fx "$args_multiline" || true + else + exit1 "Internal error (findobjects: illegal limit)!" + fi +} +finditems() { + set -e + type="$1"; [ -n "$type" ] || exit1 "Internal error (finditems: empty type)!"; shift + name="$1"; [ -n "$name" ] || exit1 "Internal error (finditems: empty name)!"; shift + limit="$@" + regex="$(echo "$limit" | perl -ne '/^\/(.+)\/$/ and print $1')" + args="$(echo "$limit" | perl -ne 's/.*?([a-z0-9]+).*?/ $1/g and print')" + dir="$type/$name" + [ -d "$vardir/$dir" ] || exit0 + if [ -z "$*" ]; then + cd "$vardir/$dir" && find -mindepth 1 -maxdepth 1 -type f -printf '%f\n' + elif [ -n "$regex" ]; then + cd "$vardir/$dir" && find -mindepth 1 -maxdepth 1 -type f -regex "$regex" + elif [ -n $args ]; then + args_multiline="$(echo "$args" | perl -pe 's/[[:space:]]+/\n/g')" + cd "$vardir/$dir" && ! find -mindepth 1 -maxdepth 1 -type f -printf '%f\n' \ + | grep -Fx "$args_multiline" || true + else + exit1 "Internal error (finditems: illegal limit)!" + fi +} +getitem() { + set -e + type="$1"; [ -n "$type" ] || exit1 "Internal error (getitem: empty type)!"; shift + name="$1"; [ -n "$name" ] || exit1 "Internal error (getitem: empty name)!"; shift + item="$1"; [ -n "$item" ] || exit1 "Internal error (getitem: empty item)!"; shift + file="$type/$name/$item" + [ ! -s "$vardir/$file" ] || cat "$vardir/$file" +} +additem() { + set -e + type="$1"; [ -n "$type" ] || exit1 "Internal error (additem: empty type)!"; shift + name="$1"; [ -n "$name" ] || exit1 "Internal error (additem: empty name)!"; shift + item="$1"; [ -n "$item" ] || exit1 "Internal error (additem: empty item)!"; shift + data="$*"; [ -n "$data" ] || exit1 "Internal error (additem: empty data)!"; shift + data="$(echo "$data" | perl -0 -pe 's/\s+/ /g; s/^\s+//; s/\s+$//')" + 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)}" +} +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!" + + 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" + ;; + [[: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" + ;; + [[:alpha:]][[:alnum:]]*) + [ -z "$nick" ] || exit1 "Multiple nick names (use only a single nick name)!" + nick="$chunk" + ;; + *) + 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" +} + +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." + ;; + *) + exit1 "Cannot add \"$1\" (try \"add user\" or \"add group\" instead)!" + ;; + esac + ;; + del|delete|remove) + case "$1" in + user|group) + type="$1"; shift + response="$(delobject "$type" "$@")" || exit1 "Failed deleting $type${response+: $response}" + exit0 "Deleted $type: $response." + ;; + *) + exit1 "Cannot delete \"$1\" (try \"del user\" or \"del group\" instead)!" + ;; + esac + ;; + list|show|view) + case "$1" in + user|group) + 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)!" + ;; + esac + ;; + status) + msg="$(/usr/local/sbin/localshowkannelstatus)" + exit0 "$msg" + ;; + *) + exit1 "unknown command \"$cmd\"!" + ;; +esac -- cgit v1.2.3