Commit c529ef37 authored by Yuanle Song's avatar Yuanle Song
Browse files

WIP to conform Dyn.com policies

- do not update when fatal error is not cleared by user.
- only update when IP is different from last successful update.
- send email to EMAIL and FATAL_ERROR_EMAIL

bugfix: do not "exit 0" after curl command.
bugfix: fix bug 175 use "cat" to get file content.
parent 10dddcd6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ it does not report errors.
  make
  python
  egrep
  mail

* start to use bugzilla to track feature requests and bugs.
  for open bugs see
+5 −2
Original line number Diff line number Diff line
@@ -3,9 +3,12 @@ Date: 2012-05-27
Time-stamp: <2012-05-27>

* 
* v0.1.1
* v0.1.1dev
  - split config from executable.
  - update app according to Dyn policies and guidelines.
  - 
    - do not update when fatal error is not cleared by user.
    - use IP from local router.
    - only update when IP is different from last successful update.
    - send email to EMAIL and FATAL_ERROR_EMAIL
* v0.1.0
  - init version. was used to update sylecn01.dnsd.me.
+8 −0
Original line number Diff line number Diff line
@@ -13,6 +13,14 @@ HOSTNAME=
# using printf syntax, with %s being the new IP.
UPDATE_URL="https://$USERNAME:$PASSWORD@members.dyndns.org/nic/update?hostname=$HOSTNAME&myip=%s&wildcard=NOCHG&mx=NOCHG&backmx=NOCHG"

# send email to this mail address when there are errors.
# default is root@localhost
EMAIL=
# In addition to previous line, also send email to this address when
# FATAL_ERROR occurs.
FATAL_ERROR_EMAIL=


# get_ip_command function, if defined, should set MYIP variable to the IP
# address. It should return non 0 exit code on failure.

+53 −14
Original line number Diff line number Diff line
@@ -6,11 +6,15 @@
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
CONFIG_FILE="$HOME/.ddclient-http"

VERSION="v0.1.1dev"

# exit codes
GET_MYIP_FAILED=1
DIG_FAILED=2
UPDATE_REQUEST_FAILED=3
UPDATE_REJECTED=4
UPDATE_NOCHG=5
FATAL_ERROR_EXISTS=6
NO_CONF=50

# stores responses from remote DDNS provider's server.  usually it will be
@@ -18,6 +22,14 @@ NO_CONF=50
# long.
HTTP_RESPONSE=/tmp/ddclient-http-api.html

RUNTIME_DIR=/var/run/ddclient-http
LAST_IP_FILE="$RUNTIME_DIR/last_ip"
FATAL_ERROR_FILE="$RUNTIME_DIR/fatal_error"

if [ ! -d "$RUNTIME_DIR" ]; then
	mkdir -p "$RUNTIME_DIR"
fi

# Usage: log [MESSAGE..]
log() {
	logger -t ddclient_http "$@"
@@ -26,6 +38,15 @@ log() {
# Usage: err [MESSAGE..]
err() {
	logger -t ddclient_http -p user.err "$@"
	echo "$@" | mail -s "ddclient-http Error" ${EMAIL:-root@localhost}
}

# Usage: fatal_err [MESSAGE..]
# This is the same as err, but it also send email to $FATAL_ERROR_EMAIL if
# it's set in config file.
fatal_err() {
	err "$@"
	test -z "$FATAL_ERROR_EMAIL" || echo "$@" | mail -s "ddclient-http FATAL Error" "$FATAL_ERROR_EMAIL"
}

# which host to update and it's credentials.
@@ -66,15 +87,18 @@ get_myip() {

# returns true if domain is outdated. returns false otherwise.
require_update() {
	if [ ! -f "$LAST_IP_FILE" ]; then
		OLDIP=`dig +short $HOSTNAME`
	# TODO dig can fail when network is down or DNS server is blocked by
	# GFW. check dig command's exit code.
	#
	# dig always return 0! if no A record is found, OLDIP will be empty.
		# dig always return 0. if no A record is found, OLDIP will be
		# empty.
		if [ -z "$OLDIP" ]; then
			err "Can't get current binding IP. dig failed."
			exit $DIG_FAILED
		fi
	else
		OLDIP=`cat $LAST_IP_FILE`
	fi

	if [ "$OLDIP" = "$MYIP" ]; then
		log "$HOSTNAME is up-to-date. IP is $OLDIP."
		return 1
@@ -86,10 +110,13 @@ require_update() {

do_update() {
	log "update $HOSTNAME using IP $MYIP"
	if [ -f "$FATAL_ERROR_FILE" ]; then
		err "Error: previous fatal error is not cleared. \
Delete $FATAL_ERROR_FILE when you cleared the issue."
		exit $FATAL_ERROR_EXISTS
	fi
	URL=`printf $UPDATE_URL $MYIP`
	curl -s -o "$HTTP_RESPONSE" "$URL"
	exit 0

	# check curl EXIT CODES
	CURL_EXIT_CODE=$?
	case $CURL_EXIT_CODE in
@@ -104,21 +131,33 @@ do_update() {
	fi

	# check HTTP_RESPONSE
	KEYWORD=`echo $HTTP_RESPONSE|cut -d' ' -f1`
	KEYWORD=`cat $HTTP_RESPONSE|cut -d' ' -f1`
	case "$KEYWORD" in
		good) log "good: update accepted."
			return 0 ;;
		nochg) err "nochg: IP not changed." ;;
		good)
			log "good: update accepted."
			echo $MYIP > "$LAST_IP_FILE"
			return 0
			;;
		nochg) err "nochg: IP not changed."
			echo $MYIP > "$LAST_IP_FILE"
			return $UPDATE_NOCHG
			;;
		badauth) err "badauth: user or password incorrect." ;;
		abuse) err "abuse: hostname is blocked for update abuse." ;;
		dnserr) err "dnserr: DNS error encountered." ;;
		911) err "911: server problem." ;;
		*) err "Error: return code is ${HTTP_RESPONSE}." ;;
	esac
	cp "$HTTP_RESPONSE" "$FATAL_ERROR_FILE"
	fatal_err "FATAL_ERROR: server returns $HTTP_RESPONSE"
	exit $UPDATE_REJECTED
}

# main
if [ "$1" = "clear" ]; then
	test -f "$FATAL_ERROR_FILE" && rm "$FATAL_ERROR_FILE"
	exit 0
fi
if get_myip; then
	if require_update; then
		do_update