Initial checkin.
This commit is contained in:
commit
d5e15641fd
|
@ -0,0 +1,72 @@
|
||||||
|
# Overview
|
||||||
|
|
||||||
|
Script to manage custom./etc/services entries.
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
# Show usage
|
||||||
|
rpearce@crom:serv$ ./serv.sh -h
|
||||||
|
usage: ./serv.sh [OPTIONS] command [command_args]
|
||||||
|
|
||||||
|
Manage custom /etc/services entries.
|
||||||
|
|
||||||
|
Valid commands are: diff sync init add del query cat
|
||||||
|
|
||||||
|
-f Force removal of service even if multiple match.
|
||||||
|
-w Update system services file (/etc/services)
|
||||||
|
-y Same as -w
|
||||||
|
|
||||||
|
# Create working area in ~/.serv/
|
||||||
|
rpearce@crom:serv$ ./serv.sh init
|
||||||
|
Initialisation of /Users/rpearce/.serv complete.
|
||||||
|
|
||||||
|
# Add a custom service
|
||||||
|
rpearce@crom:serv$ ./serv.sh add myservice 34777/udp
|
||||||
|
Added 'myservice' (34777/udp) to custom services file.
|
||||||
|
|
||||||
|
NOTE: /etc/services not touched - use -w to update it.
|
||||||
|
The following changes were NOT made:
|
||||||
|
13921a13922,13924
|
||||||
|
>
|
||||||
|
> # custom services from serv.sh
|
||||||
|
> myservice 34777/udp
|
||||||
|
|
||||||
|
# Look up a custom service
|
||||||
|
rpearce@crom:serv$ ./serv.sh query myservice
|
||||||
|
Found in custom services file:
|
||||||
|
myservice 34777/udp
|
||||||
|
|
||||||
|
# Update system /etc/services with custom services
|
||||||
|
rpearce@crom:serv$ ./serv.sh -w sync
|
||||||
|
|
||||||
|
(using sudo - you may be prompted for your password)
|
||||||
|
Password:
|
||||||
|
/etc/services updated:
|
||||||
|
13921a13922,13924
|
||||||
|
>
|
||||||
|
> # custom services from serv.sh
|
||||||
|
> myservice 34777/udp
|
||||||
|
|
||||||
|
rpearce@crom:serv$ tail -5 /etc/services
|
||||||
|
# 48557-49150 Unassigned
|
||||||
|
# 49151 IANA Reserved
|
||||||
|
|
||||||
|
# custom services from serv.sh
|
||||||
|
myservice 34777/udp
|
||||||
|
rpearce@crom:serv$
|
||||||
|
|
||||||
|
# Remove a custom service, and also update /etc/services
|
||||||
|
rpearce@crom:serv$ ./serv.sh -w rm myservice
|
||||||
|
Removed 'myservice' from custom services file (1 line).
|
||||||
|
|
||||||
|
(using sudo - you may be prompted for your password)
|
||||||
|
/etc/services updated:
|
||||||
|
13924d13923
|
||||||
|
< myservice 34777/udp
|
||||||
|
|
||||||
|
rpearce@crom:serv$ tail -5 /etc/services
|
||||||
|
com-bardac-dw 48556/udp # com-bardac-dw
|
||||||
|
com-bardac-dw 48556/tcp # com-bardac-dw
|
||||||
|
# Nicholas J Howes <nick@ghostwood.org>
|
||||||
|
# 48557-49150 Unassigned
|
||||||
|
# 49151 IANA Reserved
|
||||||
|
rpearce@crom:serv$
|
|
@ -0,0 +1,320 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
function lookup() { # lookup where_var res_var what to lookup ...
|
||||||
|
local all what found rv localres where_var res_var
|
||||||
|
where_var="$1" ; shift
|
||||||
|
res_var="$1" ; shift
|
||||||
|
all="${*}"
|
||||||
|
what=${all// /|}
|
||||||
|
found=""
|
||||||
|
localres=$(egrep -i "$what" $SRVFILE_CUSTOM)
|
||||||
|
if [[ ! -z $localres ]]; then
|
||||||
|
found="custom"
|
||||||
|
else
|
||||||
|
localres=$(egrep -i "$what" $SRVFILE_BASE)
|
||||||
|
[[ ! -z $localres ]] && found="system"
|
||||||
|
fi
|
||||||
|
eval "$where_var=${found}"
|
||||||
|
eval "$res_var='${localres}'"
|
||||||
|
if [[ -z $found ]]; then
|
||||||
|
rv=1
|
||||||
|
else
|
||||||
|
rv=0
|
||||||
|
fi
|
||||||
|
return $rv
|
||||||
|
echo "$found"
|
||||||
|
}
|
||||||
|
|
||||||
|
function usage() {
|
||||||
|
echo "usage: $0 [OPTIONS] command [command_args]"
|
||||||
|
echo
|
||||||
|
echo "Manage custom /etc/services entries."
|
||||||
|
echo
|
||||||
|
echo " Valid commands are: $VALIDMODES"
|
||||||
|
echo
|
||||||
|
echo " -f Force removal of service even if multiple match."
|
||||||
|
echo " -w Update system services file ($SRVFILE_ACTIVE)"
|
||||||
|
echo " -y Same as -w"
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
function getalt() {
|
||||||
|
local newmode
|
||||||
|
newmode="$1"
|
||||||
|
case $1 in
|
||||||
|
a)
|
||||||
|
newmode="add";
|
||||||
|
;;
|
||||||
|
q)
|
||||||
|
newmode="query";
|
||||||
|
;;
|
||||||
|
rm)
|
||||||
|
newmode="del";
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
echo "$newmode"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeboth() {
|
||||||
|
local n p both
|
||||||
|
n="$1"
|
||||||
|
p="$2"
|
||||||
|
both="$n"
|
||||||
|
if [[ ! -z $p ]]; then
|
||||||
|
if [[ ! -z $n ]]; then
|
||||||
|
both="$both ("
|
||||||
|
fi
|
||||||
|
both="$both$p"
|
||||||
|
if [[ ! -z $n ]]; then
|
||||||
|
both="$both)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "$both"
|
||||||
|
}
|
||||||
|
|
||||||
|
function stageforsync() {
|
||||||
|
cp -fp "$SRVFILE_BASE" "$SRVFILE_STAGE"
|
||||||
|
echo >> "$SRVFILE_STAGE"
|
||||||
|
echo "# custom services from serv.sh" >> "$SRVFILE_STAGE"
|
||||||
|
cat "$SRVFILE_CUSTOM" >> "$SRVFILE_STAGE"
|
||||||
|
}
|
||||||
|
|
||||||
|
function synctoactive() {
|
||||||
|
local perm dres
|
||||||
|
|
||||||
|
stageforsync
|
||||||
|
dres=$(diff "$SRVFILE_ACTIVE" "$SRVFILE_STAGE")
|
||||||
|
|
||||||
|
echo
|
||||||
|
if [[ $DOIT -eq 1 ]]; then
|
||||||
|
perm=$(stat -f "%p" "$SRVFILE_ACTIVE")
|
||||||
|
if [[ $UID -ne 0 && $EUID -ne 0 ]]; then
|
||||||
|
echo "(using sudo - you may be prompted for your password)"
|
||||||
|
sudo cp -fp "$SRVFILE_ACTIVE" "$SRVFILE_ACTIVE.orig"
|
||||||
|
sudo cp -fp "$SRVFILE_STAGE" "$SRVFILE_ACTIVE"
|
||||||
|
sudo chmod $perm "$SRVFILE_ACTIVE"
|
||||||
|
else
|
||||||
|
cp -fp "$SRVFILE_ACTIVE" "$SRVFILE_ACTIVE.orig"
|
||||||
|
cp -fp "$SRVFILE_STAGE" "$SRVFILE_ACTIVE"
|
||||||
|
chmod $perm "$SRVFILE_ACTIVE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z $dres ]]; then
|
||||||
|
echo "No changes required to $SRVFILE_ACTIVE."
|
||||||
|
else
|
||||||
|
echo "$SRVFILE_ACTIVE updated:"
|
||||||
|
echo "$dres" | sed -e 's/^/ /'
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "NOTE: $SRVFILE_ACTIVE not touched - use -w to update it."
|
||||||
|
echo "The following changes were NOT made:"
|
||||||
|
if [[ -z $dres ]]; then
|
||||||
|
echo " (none)"
|
||||||
|
else
|
||||||
|
echo "$dres" | sed -e 's/^/ /'
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Handle args
|
||||||
|
VALIDPROTOS="tcp udp"
|
||||||
|
VALIDMODES="diff sync init add del query cat"
|
||||||
|
MODE=""
|
||||||
|
SRVFILE_ACTIVE="/etc/services"
|
||||||
|
SRVDIR="${HOME}/.serv"
|
||||||
|
SRVFILE_BASE="${SRVDIR}/base"
|
||||||
|
SRVFILE_CUSTOM="${SRVDIR}/custom"
|
||||||
|
SRVFILE_STAGE="${SRVDIR}/stage"
|
||||||
|
PROTOFILE=/etc/protocols
|
||||||
|
FORCE=0
|
||||||
|
DOIT=0
|
||||||
|
|
||||||
|
ARGS="fhwy"
|
||||||
|
while getopts "$ARGS" i; do
|
||||||
|
case "$i" in
|
||||||
|
f)
|
||||||
|
FORCE=1
|
||||||
|
;;
|
||||||
|
h)
|
||||||
|
usage;
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
w)
|
||||||
|
DOIT=1;
|
||||||
|
;;
|
||||||
|
y)
|
||||||
|
DOIT=1;
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: invalid argument: $i";
|
||||||
|
usage;
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $((OPTIND - 1))
|
||||||
|
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
echo "Error - no mode provided."
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
MODE="$1"
|
||||||
|
shift 1
|
||||||
|
MODE=$(getalt $MODE)
|
||||||
|
|
||||||
|
if [[ $VALIDMODES != *$MODE* ]]; then
|
||||||
|
echo "Error - invalid mode '$MODE'"
|
||||||
|
echo "Valid modes are: $VALIDMODES"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [[ $MODE == "cat" ]]; then
|
||||||
|
echo "Current custom services (from $SRVFILE_CUSTOM):"
|
||||||
|
cat "$SRVFILE_CUSTOM" | sed -e 's/^/ /'
|
||||||
|
exit 0
|
||||||
|
elif [[ $MODE == "diff" ]]; then
|
||||||
|
stageforsync
|
||||||
|
dres=$(diff "$SRVFILE_ACTIVE" "$SRVFILE_STAGE")
|
||||||
|
echo "Changes to be synced into $SRVFILE_ACTIVE:"
|
||||||
|
if [[ -z $dres ]]; then
|
||||||
|
echo " (none)"
|
||||||
|
else
|
||||||
|
echo "$dres" | sed -e 's/^/ /'
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
elif [[ $MODE == "sync" ]]; then
|
||||||
|
# just update /etc/services
|
||||||
|
synctoactive
|
||||||
|
exit 0
|
||||||
|
elif [[ $MODE == "init" ]]; then
|
||||||
|
wantargs=0
|
||||||
|
elif [[ $MODE == "add" ]]; then
|
||||||
|
wantargs=2
|
||||||
|
else
|
||||||
|
wantargs=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $# -lt $wantargs ]]; then
|
||||||
|
echo "Bad arguments - want $wantargs, got $#"
|
||||||
|
echo
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
name="$1"
|
||||||
|
protoport="$2"
|
||||||
|
if [[ -z $protoport ]]; then
|
||||||
|
proto=""
|
||||||
|
port=""
|
||||||
|
else
|
||||||
|
if [[ $protoport != */* ]]; then
|
||||||
|
echo "Error - bad service specification '$protoport'"
|
||||||
|
echo "Must use the format: port/protocol"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
proto="${protoport#*/}"
|
||||||
|
port="${protoport%/*}"
|
||||||
|
re='^[0-9]+$'
|
||||||
|
if [[ ! $port =~ $re ]]; then
|
||||||
|
echo "Error - port '$port' is not a number."
|
||||||
|
echo "Must use the format: port/protocol"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ $port -lt 0 || $port -gt 65535 ]]; then
|
||||||
|
echo "Error - port '$port' must be in the range 0-65535."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ $VALIDPROTOS != *$proto* ]]; then
|
||||||
|
echo "Error - invalid protocol '$proto'."
|
||||||
|
echo "Valid protocols are: $VALIDPROTOS"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
shift 2
|
||||||
|
comment="$*"
|
||||||
|
fi
|
||||||
|
both=$(makeboth $name $protoport)
|
||||||
|
|
||||||
|
if [[ $MODE == "init" ]]; then
|
||||||
|
if [[ -d $SRVDIR ]]; then
|
||||||
|
echo "error -i $SRVDIR already exists."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
mkdir -p "$SRVDIR"
|
||||||
|
cp -p "$SRVFILE_ACTIVE" "$SRVFILE_BASE"
|
||||||
|
cp /dev/null "$SRVFILE_CUSTOM"
|
||||||
|
echo "Initialisation of $SRVDIR complete."
|
||||||
|
exit 0
|
||||||
|
elif [[ ! -d $SRVDIR ]]; then
|
||||||
|
echo "Error - $SRVDIR is missing."
|
||||||
|
echo "Use -i to initialise it."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [[ $MODE == "query" ]]; then
|
||||||
|
lookup whichfile res $name $protoport
|
||||||
|
if [[ ! -z $whichfile ]]; then
|
||||||
|
echo "Found in $whichfile services file:"
|
||||||
|
echo "$res" | sed -e 's/^/ /'
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "'$both' not found."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
elif [[ $MODE == "add" ]]; then
|
||||||
|
lookup whichfile res $name $protoport
|
||||||
|
if [[ ! -z $whichfile ]]; then
|
||||||
|
echo "Error - this already exists in $whichfile services file:"
|
||||||
|
echo "$res" | sed -e 's/^/ /'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ ${#name} -gt 15 ]]; then
|
||||||
|
echo "Error - service name '$name' exceeds 15 characters."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ -z $comment ]]; then
|
||||||
|
printf "%-16s%s\n" "$name" "$protoport" >> $SRVFILE_CUSTOM
|
||||||
|
else
|
||||||
|
printf "%-16s%s # %s\n" "$name" "$protoport" "$comment" >> $SRVFILE_CUSTOM
|
||||||
|
fi
|
||||||
|
echo "Added '$name' ($protoport) to custom services file."
|
||||||
|
synctoactive
|
||||||
|
elif [[ $MODE == "del" ]]; then
|
||||||
|
lookup whichfile res $name $protoport
|
||||||
|
if [[ $whichfile != "custom" ]]; then
|
||||||
|
echo "Error - can't find service '$both' in custom file."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
re="$name"
|
||||||
|
if [[ ! -z $protoport ]]; then
|
||||||
|
if [[ ! -z $re ]]; then
|
||||||
|
re="$re|"
|
||||||
|
fi
|
||||||
|
re="$re${protoport}"
|
||||||
|
fi
|
||||||
|
re="${re/\//\\\/}" # escape the slash
|
||||||
|
count=$(egrep -c "$re" $SRVFILE_CUSTOM)
|
||||||
|
[[ $count -eq 1 ]] && ess="" || ess="s"
|
||||||
|
if [[ $count -gt 1 && $FORCE -ne 1 ]]; then
|
||||||
|
echo "Error: '$both' matches multiple lines for removal, use -f to confirm:"
|
||||||
|
echo "$res" | sed -e 's/^/ /'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sed -ibak "/$re/d" $SRVFILE_CUSTOM
|
||||||
|
sedrv=$?
|
||||||
|
if [[ $sedrv -eq 0 ]]; then
|
||||||
|
echo "Removed '$both' from custom services file ($count line$ess)."
|
||||||
|
rv=0
|
||||||
|
else
|
||||||
|
echo "Error failed to remove '$both' from custom services file using sed."
|
||||||
|
rv=1
|
||||||
|
fi
|
||||||
|
synctoactive
|
||||||
|
exit $rv
|
||||||
|
fi
|
||||||
|
|
||||||
|
# TODO: sync to real serviceafile
|
||||||
|
exit 0
|
Loading…
Reference in New Issue