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