monotone-commits-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Monotone-commits-diffs] net.venge.monotone.contrib.usher: 200716ad68df


From: code
Subject: [Monotone-commits-diffs] net.venge.monotone.contrib.usher: 200716ad68df60ea4de9b92bf20d8acd1cf20283
Date: Wed, 19 Jan 2011 13:57:01 GMT

revision:            200716ad68df60ea4de9b92bf20d8acd1cf20283
date:                2011-01-18T13:41:58
author:              Timothy Brownawell  <address@hidden>
branch:              net.venge.monotone.contrib.usher
changelog:
merge of 'b16eb174a9d756580969379e1bf9db896e555373'
     and 'e2a50b5003a2d6a87380c1343d01e1d32a5c3395'

manifest:
format_version "1"

new_manifest [16e7c0040863c26c4671bc137142d6a1eeac5419]

old_revision [b16eb174a9d756580969379e1bf9db896e555373]

add_file "doc/usherctl.html"
 content [fffd09c2ad2cb1724f7f602d5a9910c49fc896fa]

patch "doc/documentation.html"
 from [a83704fce2015f082c1268099432353a6bf60f56]
   to [428368437a2f078716e183d140dd58c2532cf147]

patch "utils/usherctl"
 from [af585016af49ef0233e6df6210b6bf1e513dfb39]
   to [f6f4d53eb56bdec130b464c53a5c14060c248dec]

old_revision [e2a50b5003a2d6a87380c1343d01e1d32a5c3395]

add_file "release-checklist.txt"
 content [305136c17d554f0b16fdab39873c5814cc64691a]

patch "NEWS"
 from [a9b8cb5b3dc0ec686519bbb81dc1058d30fb1099]
   to [41f6acc0681f23e164e7d8dc6be0738de13a8bf1]

patch "README"
 from [b968eb93f8b8ce88d822e9ddc52b563f1742a147]
   to [84610efd11606729230d94fb905e5e4695328c7b]

patch "src/channel.cc"
 from [7e6b6bbae6a84041ec840bedf5816bd6e116e5ea]
   to [28d584b7185308aeab9297b3c9ceae03718a9e65]

patch "src/channel.hh"
 from [3a97687c17a68c983872de2792defd9e48028168]
   to [21231cc383b16935ac33a349718e5aa775341c45]

patch "src/server.hh"
 from [dd153b5671f0b9560be8b817849731419e5b8fe4]
   to [6a57214c24d5c35c705276dcae8415dfcabf6c6e]

patch "src/server_manager.cc"
 from [0abe47e13dd931c522aa1a7fb828502d63531a6e]
   to [f4a5b6fe2d917f24ce56c133ee347b9b3e91e50b]

patch "src/server_manager.hh"
 from [fc8ad29b28f82cae3b26955995afdad8f1276a5a]
   to [1d1f3a16329bdf11b69fb7593d048d95c65edc8d]

patch "src/sock.hh"
 from [0917e736d673fa6d15fcefea8f1f0e16a63b9bc2]
   to [b077f32cc61674e13b9c3bc138c924c41b23ceb1]
============================================================
--- doc/documentation.html	a83704fce2015f082c1268099432353a6bf60f56
+++ doc/documentation.html	428368437a2f078716e183d140dd58c2532cf147
@@ -108,8 +108,8 @@ connections on the specified address:por
 If the <span style="font-family: monospace;">adminaddr</span> directive
 is given in the config file, the usher will listen for administrative
 connections on the specified address:port. The connecting client can
-give commands of the form<br>
-<div style="margin-left: 40px;">COMMAND [arg] ... &lt;newline&gt;<br>
+give commands of the following form, ending with a newline:<br>
+<div style="margin-left: 40px;">COMMAND [arg] ...<br>
 </div>
 After any command except USERPASS the usher will send a reply and close the connection. The reply will end with a newline.<br>
 <h3>Administrative commands</h3>
@@ -238,12 +238,12 @@ the named server doesn't exist.<br>
 file and giving the "RELOAD" command. Returns "ok", or "not found" if
 the named server doesn't exist.<br>
   </dd>
-  <dt>ADD_SERVER name { remote | local } args<br>
+  <dt>ADD_SERVER name { remote | local } arg ...<br>
   </dt>
   <dd>Add a server with the given name and startup arguments (or name and address for remote servers).
-"args" is either "hostname port" for remote servers, or "arg 'arg' ..."
-for local servers. Quotes are treated the same as for RUN. Returns
-"ok", or an error message.<br>
+"arg ..." is either "hostname port" for remote servers, or arguments
+to the underlying monotone server for local servers. Quotes are
+treated the same as for RUN. Returns "ok", or an error message.<br>
   </dd>
 
 </dl>
============================================================
--- utils/usherctl	af585016af49ef0233e6df6210b6bf1e513dfb39
+++ utils/usherctl	f6f4d53eb56bdec130b464c53a5c14060c248dec
@@ -27,13 +27,28 @@ MTN=/usr/bin/mtn
 #			(default: /var/log/usher)
 # USHER_PROJECTDIR	Usher projects directory.
 #			(default: /var/lib/usher/projects)
+#
+# The following variables are only useful for the system administrator
+# that wants to set up a system wide usher.
+# USHER_SYSTEM_STARTUP  a non-empty string if usher should be started
+#			and stopped with the script /etc/init.d/usher.
+#			(default: (unset))
+# USHER_USER		User to run usher as.  Only useful if
+#			usher is started with /etc/init.d/usher.
+#			MUST match the user usher is started as!
+# USHER_GROUP		Group to run usher as.  Only useful if
+#			usher is started with /etc/init.d/usher.
+#			MUST match the group usher is started as!
+
+config_file="/etc/usher/usherctl.conf"
+
 TEMP=`POSIXLY_CORRECT=yes getopt -o c: -n usherctl -- "$@"`
 eval set -- "$TEMP"
 while true; do
     case "$1" in
 	-c )
 	    if [ -r "$2" ]; then
-		. "$2"
+		config_file="$2"
 	    fi
 	    shift 2
 	    ;;
@@ -44,11 +59,13 @@ done
     esac
 done
 
+. "$config_file"
+
 # Apply default where nothing is set.
 USHER_CONFDIR=${USHER_CONFDIR:-/etc/usher}
-USHER_CONF=${USHER_CONF:-$USHER_CONFDIR/usher.conf}
-USHER_GLOBALCONF=${USHER_GLOBALCONF:-$USHER_CONFDIR/global.conf}
-USHER_CONFD=${USHER_CONFD:-$USHER_CONFDIR/conf.d}
+USHER_CONF=${USHER_CONF:-"$USHER_CONFDIR/usher.conf"}
+USHER_GLOBALCONF=${USHER_GLOBALCONF:-"$USHER_CONFDIR/global.conf"}
+USHER_CONFD=${USHER_CONFD:-"$USHER_CONFDIR/conf.d"}
 USHER_PIDFILE=${USHER_PIDFILE:-/var/run/usher.pid}
 USHER_LOGDIR=${USHER_LOGDIR:-/var/log/usher}
 USHER_PROJECTDIR=${USHER_PROJECTDIR:-/var/lib/usher/projects}
@@ -56,9 +73,9 @@ _read_pid_file () {
 THIS="$0"
 
 _read_pid_file () {
-    if [ -r $USHER_PIDFILE ]; then
-	cat $USHER_PIDFILE
-    elif [ -f $USHER_PIDFILE ]; then
+    if [ -r "$USHER_PIDFILE" ]; then
+	cat "$USHER_PIDFILE"
+    elif [ -f "$USHER_PIDFILE" ]; then
 	echo >&2 "There is a pid file you aren't allowed to read: $USHER_PIDFILE"
 	echo >&2 "This means there may be a usher process running, and that"
 	echo >&2 "you don't have permission to change that."
@@ -69,63 +86,116 @@ status () {
 }
 
 status () {
-    pid=`_read_pid_file`
-    if [ -n "$pid" ]; then
-	if kill -0 $pid 2>/dev/null; then
-	    echo "The usher process is up and running: $pid"
+    if [ -z $USHER_SYSTEM_STARTUP ]; then
+	pid=`_read_pid_file`
+	if [ -n "$pid" ]; then
+	    if kill -0 $pid 2>/dev/null; then
+		echo "The usher process is up and running: $pid"
+		return 0
+	    else
+		echo "The usher process is down, but there's a PID file."
+		return 1
+	    fi
 	else
-	    echo "The usher process is down, but there's a PID file."
+	    echo "The usher process is down."
+	    return 2
 	fi
     else
-	echo "The usher process is down."
+	/etc/init.d/usher status
     fi
 }
 
 start () {
-    pid=`_read_pid_file`
-    if [ -n "$pid" ]; then
-	if kill -0 $pid 2>/dev/null; then
-	    echo >&2 "Usher process already up: $pid"
-	    exit 1
+    if [ -z $USHER_SYSTEM_STARTUP ]; then
+	pid=`_read_pid_file`
+	if [ -n "$pid" ]; then
+	    if kill -0 $pid 2>/dev/null; then
+		echo >&2 "Usher process already up: $pid"
+		exit 1
+	    fi
 	fi
+	rm -f "$USHER_PIDFILE"
+	$USHER -p "$USHER_PIDFILE" "$USHER_CONF" \
+	    < /dev/null > /dev/null 2> /dev/null &
+    else
+	/etc/init.d/usher start
     fi
-    rm -f $USHER_PIDFILE
-    $USHER -p $USHER_PIDFILE $USHER_CONF < /dev/null > /dev/null 2> /dev/null &
 }
 
 stop () {
-    pid=`_read_pid_file`
-    if [ -n "$pid" ]; then
-	kill $pid
+    if [ -z $USHER_SYSTEM_STARTUP ]; then
+	pid=`_read_pid_file`
+	if [ -n "$pid" ]; then
+	    kill $pid
+	fi
+    else
+	/etc/init.d/usher stop
     fi
 }
 
 reload () {
-    pid=`_read_pid_file`
-    if [ -z "$pid" ]; then
-	echo >&2 No usher process present.
-	exit 1
+    if [ -z $USHER_SYSTEM_STARTUP ]; then
+	pid=`_read_pid_file`
+	if [ -z "$pid" ]; then
+	    echo >&2 "No usher process present."
+	    exit 1
+	else
+	    kill -1 $pid
+	fi
     else
-	kill -1 $pid
+	/etc/init.d/usher reload
     fi
 }
 
 restart () {
-    stop && start
+    if [ -z $USHER_SYSTEM_STARTUP ]; then
+	stop && start
+    else
+	/etc/init.d/usher restart
+    fi
 }
 
+restart_if_started () {
+    if [ -z $USHER_SYSTEM_STARTUP ]; then
+	pid=`_read_pid_file`
+	if [ -n "$pid" ]; then
+	    restart
+	fi
+    elif /etc/init.c/usher status >/dev/null 2>/dev/null; then
+	/etc/init.d/usher restart
+    fi
+}
 
-_mkconf () {
-    if [ -f $USHER_CONF ]; then
-	cp $USHER_CONF $USHER_CONF~ || exit 1
+
+_maybe_set_file_owner() {
+    for file in "$@"; do
+	if [ -n "$USHER_USER" -a -n "$USHER_GROUP" ]; then
+	    chown ${USHER_USER}:${USHER_GROUP} "$file"
+	fi
+    done
+}
+
+_maybe_set_directory_owner() {
+    for dir in "$@"; do
+	if [ -n "$USHER_USER" -a -n "$USHER_GROUP" ]; then
+	    chown -R ${USHER_USER}:${USHER_GROUP} "$dir"
+	fi
+    done
+}
+
+rebuild () {
+    if [ -f "$USHER_CONF" ]; then
+	cp "$USHER_CONF" "$USHER_CONF~" || exit 1
     fi
     (
-	cat $USHER_GLOBALCONF
-	for x in $USHER_CONFD/*.conf; do
+	if [ -f "$USHER_GLOBALCONF" ]; then cat "$USHER_GLOBALCONF"; fi
+	ls "$USHER_CONFD"/*.conf 2>/dev/null | while read x; do
 	    echo
 	    cat $x
 	done
-    ) > $USHER_CONF 2>/dev/null
+    ) > "$USHER_CONF"
+    _maybe_set_file_owner "$USHER_CONF"
+    chmod 640 "$USHER_CONF"
 }
 
 # $1	operation
@@ -142,14 +212,20 @@ writesrv () {
     type="$1"; shift
 
     if [ -z "$name" ]; then
-	echo >&2 Server must have a name.
+	echo >&2 "Server must have a name."
 	exit 1
     fi
 
-    ( set -x
+    (
 	echo "server \"$name\""
-	[ -n "$host" ] && echo "host \"$host\""
-	[ -n "$pattern" ] && echo "pattern \"$pattern\""
+	if [ -n "$host" ]; then echo "host \"$host\""; fi
+	if [ -n "$pattern" ]; then
+	    if [ "$pattern" = ";" ]; then
+		echo "pattern \"\""
+	    else
+		echo "pattern \"$pattern\""
+	    fi
+	fi
 	case "$type" in
 	    local )
 		argslist=
@@ -162,13 +238,15 @@ writesrv () {
 		echo "remote \"$1\""
 		;;
 	    * )
-		echo >&2 Unknown type \'$type\'.
+		echo >&2 "Unknown type '$type'."
 		exit 1
 		;;
 	esac
-    ) > $USHER_CONFD/$name.conf
-    _mkconf
-    echo >&2 Server $name $op, please reload usher to activate.
+    ) > "$USHER_CONFD/$name.conf"
+    _maybe_set_file_owner "$USHER_CONFD/$name.conf"
+    chmod 640 "$USHER_CONFD/$name.conf"
+    rebuild
+    echo >&2 "Server '$name' $op, please reload usher to activate."
 }
 
 # $1	server name
@@ -177,8 +255,8 @@ addsrv () {
 # $4	type (remote local)
 # $5-	args
 addsrv () {
-    if [ -f $USHER_CONFD/$1.conf ]; then
-	echo >&2 There is already a server named $1, not changing.
+    if [ -f "$USHER_CONFD/$1.conf" ]; then
+	echo >&2 "There is already a server named '$1', not changing."
 	exit 1
     fi
 
@@ -196,8 +274,8 @@ modsrv () {
     opattern="$1"; pattern="$1"; shift
     otype="$1"
     
-    if [ ! -f $USHER_CONFD/$name.conf ]; then
-	echo >&2 There is no server configuration named $name, nothing to modify.
+    if [ ! -f "$USHER_CONFD/$name.conf" ]; then
+	echo >&2 "There is no server configuration named '$name', nothing to modify."
 	exit 1
     fi
 
@@ -207,7 +285,14 @@ modsrv () {
 		if [ -z "$ohost" ];  then eval "host=$A"; fi
 		;;
 	    pattern )
-		if [ -z "$opattern" ];  then eval "pattern=$A"; fi
+		if [ -z "$opattern" ];  then
+		    eval "pattern=$A";
+		    # Because a pattern prefix can be empty, but there's
+		    # no way to distinguish that from an unset value, let's
+		    # use a forbidden branch character as an internal marker
+		    # for the empty pattern.
+		    if [ -z "$pattern" ]; then pattern=";"; fi
+		fi
 		;;
 	    remote | local )
 		if [ -z "$otype" ];  then eval "set -- $K $A"; fi
@@ -215,8 +300,8 @@ modsrv () {
 	    * )
 		;;
 	esac
-    done < $USHER_CONFD/$name.conf
-    mv $USHER_CONFD/$name.conf $USHER_CONFD/$name.conf~
+    done < "$USHER_CONFD/$name.conf"
+    mv "$USHER_CONFD/$name.conf" "$USHER_CONFD/$name.conf~"
     writesrv modified "$name" "$host" "$pattern" "$@"
 }
 
@@ -224,14 +309,14 @@ delsrv () {
 delsrv () {
     name="$1"
     
-    if [ ! -f $USHER_CONFD/$name.conf ]; then
-	echo >&2 There is no server configuration named $name, nothing to delete.
+    if [ ! -f "$USHER_CONFD/$name.conf" ]; then
+	echo >&2 "There is no server configuration named '$name', nothing to delete."
 	exit 1
     fi
 
-    rm -f $USHER_CONFD/$name.conf $USHER_CONFD/$name.conf~
-    _mkconf
-    echo >&2 Server $name deleted, please reload usher to activate.
+    rm -f "$USHER_CONFD/$name.conf" "$USHER_CONFD/$name.conf~"
+    rebuild
+    echo >&2 "Server '$name' deleted, please reload usher to activate."
 }
 
 # $1 type
@@ -241,7 +326,7 @@ mkproject () {
     name="$1"; shift
 
     if [ -e "$USHER_PROJECTDIR/$name" ]; then
-	echo >&2 There already is a project named "$name".
+	echo >&2 "There already is a project named '$name'."
 	exit 1
     fi
 
@@ -251,6 +336,7 @@ mkproject () {
     mkdir "$confdir/hooks.d"
     set +e
 
+    _maybe_set_directory_owner "$confdir"
     chmod 0750 "$confdir"
 
     # Generate name and password for the server key
@@ -258,31 +344,43 @@ mkproject () {
     skp=`dd if=/dev/random ibs=8 count=1 2>/dev/null | \
 	perl -e 'my $string=""; while (<STDIN>) { $string .= $_; } print unpack("H*",$string),"\n";'`
     echo "$skn \"$skp\"" > $confdir/passphrases
+    _maybe_set_file_owner "$confdir/passphrases"
     chmod 400 $confdir/passphrases
 
+    # Generate database
     mtn="$MTN -d \"$confdir/database.mtn\" --confdir \"$confdir\" --no-standard-rcfiles --ticker=dot"
     eval $mtn db init
+    _maybe_set_file_owner "$confdir/database.mtn"
+    chmod 0600 "$confdir/database.mtn"
+
+    # Generate key
     (echo "$skp"; echo "$skp") | \
 	eval $mtn genkey "$skn" > /dev/null 2> /dev/null
     skid=`eval $mtn ls keys | grep "$skn\$" | tail -1 | cut -f1 -d' '`
-    chmod 0600 "$confdir/database.mtn"
+    _maybe_set_directory_owner "$confdir/keys"
 
     sed -e '1,/^# -----BEGIN monotonerc-----$/d' \
 	-e '/^# -----END monotonerc-----$/,$d' \
 	-e 's/^# //' \
 	< "$THIS" > "$confdir/monotonerc"
+    _maybe_set_file_owner "$confdir/monotonerc"
     chmod 0640 "$confdir/monotonerc"
 
     aconfdir="$confdir/admin"
     mkdir "$aconfdir"
+    _maybe_set_directory_owner "$aconfdir"
     chmod 700 "$aconfdir"
 
     amtn="$MTN -d \"$aconfdir/database.mtn\" --confdir \"$aconfdir\" --no-standard-rcfiles --ticker=dot"
     eval $amtn db init
-    (echo; echo) | eval $amtn genkey ".$name-admin" > /dev/null 2> /dev/null
+    _maybe_set_file_owner "$aconfdir/database.mtn"
+    chmod 0600 "$aconfdir/database.mtn"
+
+    (echo; echo) | eval $amtn genkey "$name-admin" > /dev/null 2> /dev/null
     akid=`eval $amtn ls keys | grep "$akn\$" | tail -1 | cut -f1 -d' '`
+    _maybe_set_directory_owner "$aconfdir/keys"
 
-    listenport=`cat $USHER_CONF | grep '^ *listenaddr' | tail -1 | \
+    listenport=`cat "$USHER_CONF" | grep '^ *listenaddr' | tail -1 | \
 	cut -f2 -d'"' | cut -f2 -d:`
 
     case $type in
@@ -298,6 +396,8 @@ mkproject () {
 		-e "s|%confdir%|$confdir|g" \
 		-e "s|%listenport%|$listenport|g" \
 		-e "s|%name%|$name|g" \
+		-e "s|%user%|$USHER_USER|g" \
+		-e "s|%group%|$USHER_GROUP|g" \
 		-e 's/^# //' \
 		< "$THIS" > "$confdir/addclientkeys"
 	    ;;
@@ -312,64 +412,90 @@ mkproject () {
 		-e "s|%confdir%|$confdir|g" \
 		-e "s|%listenport%|$listenport|g" \
 		-e "s|%name%|$name|g" \
+		-e "s|%user%|$USHER_USER|g" \
+		-e "s|%group%|$USHER_GROUP|g" \
 		-e 's/^# //' \
 		< "$THIS" > "$confdir/addclientkeys"
 	    ;;
     esac
 
+    _maybe_set_file_owner "$confdir/read-permissions"
+    _maybe_set_file_owner "$confdir/write-permissions"
+    _maybe_set_file_owner "$confdir/addclientkeys"
     chmod 0640 $confdir/read-permissions
     chmod 0640 $confdir/write-permissions
     chmod 0600 $confdir/addclientkeys
 
     # We need a quick bootstrap, otherwise addclientkeys won't work
-    eval $amtn pubkey ".$name-admin" | eval $mtn read 2> /dev/null
+    eval $amtn pubkey "$name-admin" | eval $mtn read 2> /dev/null
 
     addsrv "$name" "" "" \
 	local "--confdir" "$confdir" "-d" "$confdir/database.mtn" \
 	"--no-standard-rcfiles" "--rcfile" "$confdir/monotonerc" \
 	"--timestamps" "--ticker=dot" 2>/dev/null
-    restart
+    restart_if_started
 
+    _maybe_set_file_owner "$confdir/addclientkeys"
     chmod 700 "$confdir/addclientkeys"
-    eval $amtn pubkey ".$name-admin" | "$confdir/addclientkeys"
+    eval $amtn pubkey "$name-admin" | "$confdir/addclientkeys"
 
-    echo >&2 $type project $name created
+    echo >&2 "$type project '$name' created."
 }
 
 rmproject () {
     name="$1"; shift
 
     if [ ! -e "$USHER_PROJECTDIR/$name" ]; then
-	echo >&2 There is no project named "$name".
+	echo >&2 "There is no project named '$name'."
 	exit 1
     fi
 
-    delsrv $name 2>/dev/null
-    restart
-    rm -rf $USHER_PROJECTDIR/$name
-    echo >&2 project $name removed
-}    
+    delsrv "$name" 2>/dev/null
+    restart_if_started
+    rm -rf "$USHER_PROJECTDIR/$name"
+    echo >&2 "project '$name' removed."
+}
 
+list () {
+    grep '^ *server  *"' "$USHER_CONF" | cut -f2 -d'"' | while read name; do
+	text="$name"
+	extratext=" (WARNING: seems manually added, might get overwritten)"
+	if [ -f "$USHER_CONFD/$name.conf" ]; then
+	    extratext=" (managed with usherctl)"
+	fi
+	if [ -d "$USHER_PROJECTDIR/$name" ]; then
+	    extratext=" (project managed with usherctl)"
+	fi
+	echo "$text$extratext"
+    done
+}
+
 #----------------------------------------------------------------------
 case $1 in
     init )
 	shift
-	if [ -f $USHER_GLOBALCONF ]; then
-	    echo >&2 Usher is already initialised.
+	if [ -f "$USHER_GLOBALCONF" ]; then
+	    echo >&2 "Usher is already initialised."
 	    exit 1
 	fi
-	mkdir $USHER_CONFDIR $USHER_CONFD $USHER_LOGDIR
-	mkdir -p $USHER_PROJECTDIR
+	mkdir "$USHER_CONFDIR" "$USHER_CONFD" "$USHER_LOGDIR"
+	mkdir -p "$USHER_PROJECTDIR"
 	sed -e '1,/^# -----BEGIN globalconf-----$/d' \
 	    -e '/^# -----END globalconf-----$/,$d' \
 	    -e "s|%MTN%|$MTN|g" \
 	    -e "s|%USHER_LOGDIR%|$USHER_LOGDIR|g" \
 	    -e 's/^# //' \
-	    < "$THIS" > $USHER_GLOBALCONF
-	_mkconf
-	echo >&2 Global configuration file $USHER_GLOBALCONF generated.
-	echo >&2 You should probably edit it.
+	    < "$THIS" > "$USHER_GLOBALCONF"
+	_maybe_set_directory_owner "$USHER_CONFDIR" "$USHER_CONFD" \
+	    "$USHER_LOGDIR" "$USHER_PROJECTDIR"
+	rebuild
+	echo >&2 "Global configuration file $USHER_GLOBALCONF generated."
+	echo >&2 "You should probably edit it."
 	;;
+    rebuild )
+	shift
+	rebuild
+	;;
 
     add | mod )
 	op="$1"
@@ -385,6 +511,11 @@ case $1 in
 		    ;;
 		-p )
 		    pattern="$2"; shift 2
+		    # Because a pattern prefix can be empty, but there's
+		    # no way to distinguish that from an unset value, let's
+		    # use a forbidden branch character as an internal marker
+		    # for the empty pattern.
+		    if [ -z "$pattern" ]; then pattern=";"; fi
 		    ;;
 		--)
 		    shift
@@ -394,7 +525,7 @@ case $1 in
 	done
 	name="$1"; shift
 	if [ -z "$name" ]; then
-	    echo >&2 No name given.
+	    echo >&2 "No name given."
 	    exit 1
 	fi
 	case $1 in
@@ -402,7 +533,7 @@ case $1 in
 		${op}srv "$name" "$host" "$pattern" "$@"
 		;;
 	    * )
-		echo >&2 Unknown server type $1.
+		echo >&2 "Unknown server type $1."
 		exit 1
 		;;
 	esac
@@ -411,7 +542,7 @@ case $1 in
 	shift
 	name="$1"; shift
 	if [ -z "$name" ]; then
-	    echo >&2 No name given.
+	    echo >&2 "No name given."
 	    exit 1
 	fi
 	delsrv "$name"
@@ -422,7 +553,7 @@ case $1 in
 	shift
 	name="$1"
 	if [ -z "$name" ]; then
-	    echo >&2 You have to give your project a name.
+	    echo >&2 "You have to give your project a name."
 	    exit 1
 	fi
 
@@ -432,19 +563,19 @@ case $1 in
 	shift
 	name="$1"
 	if [ -z "$name" ]; then
-	    echo >&2 You have to give your project a name.
+	    echo >&2 "You have to give your project a name."
 	    exit 1
 	fi
 	
 	rmproject "$1"
 	;;
 
-    start | stop | restart | reload | status )
+    start | stop | restart | reload | status | list )
 	$1
 	;;
 	
     * )
-	echo >&2 Unknown command $1.
+	echo >&2 "Unknown command $1."
 	;;
 esac
 
@@ -535,7 +666,12 @@ exit
 # confdir='%confdir%'
 # listenport='%listenport%'
 # name='%name%'
+# user='%user%'
+# group='%group%'
 # 
+# set -e
+# cd "$confdir"
+# 
 # eval $mtn read 2> /dev/null
 # rm -f "$confdir/write-permissions"
 # touch "$confdir/write-permissions"
@@ -546,9 +682,18 @@ exit
 #     while read K; do
 #         echo $K >> "$confdir/write-permissions"
 #         echo "  allow \"$K\"" >> "$confdir/read-permissions"
-#         eval $mtn push mtn://127.0.0.1:$listenport/$name '"*"' \
-#             --key-to-push $K 2> /dev/null
+#         if /etc/init.c/usher status >/dev/null 2>/dev/null; then
+#             eval $mtn push mtn://127.0.0.1:$listenport/$name '"*"' \
+#                 --key-to-push $K 2> /dev/null
+#         else
+#             eval $mtn push file://$confdir/database.mtn '"*"' \
+#                 --key-to-push $K 2> /dev/null
+#         fi
 #     done
+# if [ -n "$user" -a -n "$group" ]; then
+#     chown ${user}:${group} "$confdir/write-permissions"
+#     chown ${user}:${group} "$confdir/read-permissions"
+# fi
 # -----END priv:addclientkeys-----
 
 # -----BEGIN pub:addclientkeys-----
@@ -558,6 +703,11 @@ exit
 # confdir='%confdir%'
 # listenport='%listenport%'
 # name='%name%'
+# user='%user%'
+# group='%group%'
+#
+# set -e
+# cd "$confdir"
 # 
 # eval $mtn read 2> /dev/null
 # rm -f "$confdir/write-permissions"
@@ -566,7 +716,15 @@ exit
 # eval $mtn ls keys | grep '^[0-9a-f]' | cut -f1 -d' ' | sort | uniq | \
 #     while read K; do
 #         echo $K >> "$confdir/write-permissions"
-#         eval $mtn push mtn://127.0.0.1:$listenport/$name '"*"' \
-#             --key-to-push $K 2> /dev/null
+#         if /etc/init.c/usher status >/dev/null 2>/dev/null; then
+#             eval $mtn push mtn://127.0.0.1:$listenport/$name '"*"' \
+#                 --key-to-push $K 2> /dev/null
+#         else
+#             eval $mtn push file://$confdir/database.mtn '"*"' \
+#                 --key-to-push $K 2> /dev/null
+#         fi
 #     done
+# if [ -n "$user" -a -n "$group" ]; then
+#     chown ${user}:${group} "$confdir/write-permissions"
+# fi
 # -----END pub:addclientkeys-----
============================================================
--- /dev/null	
+++ doc/usherctl.html	fffd09c2ad2cb1724f7f602d5a9910c49fc896fa
@@ -0,0 +1,147 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+  <head>
+    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+    <title>Usherctl Documentation</title>
+  </head>
+
+  <body>
+    <h1>Synopsis</h1>
+
+    <p><tt>usherctl [ -c <i>configfile</i> ] <i>command</i>
+	[ <i>commandoptions</i> ... ] [ <i>subcommand</i> ]
+	[ <i>args</i> ... ]</tt></p>
+
+    <h1>Description</h1>
+
+    <p><tt>usherctl</tt> is a program to control usher and manipulate
+      its configuration, as well as creating and removing entire
+      projects, through a simple command set.</p>
+
+    <p><tt>usherctl</tt> can be used to control the system usher
+      daemon, or a private daemon.  The difference is that when
+      controling the system usher daemon, it will make sure that
+      everything is owned by the daemon user.  This, as well as other
+      aspects of <tt>usherctl</tt>, is controlled with the
+      configuration file, either the default one or the one given with
+      <tt>-c</tt>.</p>
+
+    <p><tt>usherctl</tt> keeps track of two directory trees, one for
+      the configuration of usher, the other for the configuration and
+      data of the projects created.  They are refered to as "the usher
+      configuration" and "the project configuration".</p>
+
+    <h1>Commands</h1>
+
+    <dl>
+      <dt><tt>init</tt></dt>
+      <dd>This will simply initialise the usher configuration.</dd>
+      <dt><tt>rebuild</tt></dt>
+      <dd>This will rebuild the usher configuration from the global
+	configuration file and the configuration files for each
+	project.  This should be run at any time when the
+	configuration has been changed manually.</dd>
+      <dt><tt>add <i>name</i>
+	  [ -h <i>hostprefix</i> ] [ -p <i>patternprefix</i> ]
+	  <i>type</i> <i>args ..</i></tt></dt>
+      <dd>This adds a usher server named <tt><i>name</i></tt>, with a
+	possible host prefix or branch prefix, either of the
+	<tt>local</tt> or <tt>remote</tt> type.  The rest of the
+	arguments are according to the type, please read the
+	<a href="">usher documentation</a> for
+	further information on these.</dd>
+      <dt><tt>mod <i>name</i>
+	  [ -h <i>hostprefix</i> ] [ -p <i>patternprefix</i> ]
+	  <i>type</i> <i>args ..</i></tt></dt>
+      <dd>Like <tt>add</tt>, but modifies an already existing usher
+	server instead of adding it.</dd>
+      <dt><tt>del <i>name</i></tt></dt>
+      <dd>Removes the usher server <tt><i>name</i></tt></dd>
+      <dt><tt>mkpubproject <i>name</i></tt></dt>
+      <dd>Creates a project set up so anyone can read from it,
+	anonymously.  This also creates the usher server
+	<tt><i>name</i></tt>, of type <tt>local</tt>.</dd>
+      <dt><tt>mkprivproject <i>name</i></tt></dt>
+      <dd>Creates a project set up so only registered key owners can
+	read from it.  This also creates the usher server
+	<tt><i>name</i></tt>, of type <tt>local</tt>.</dd>
+      <dt><tt>rmproject <i>name</i></tt></dt>
+      <dd>Removes the project <tt><i>name</i></tt>.  This destroys
+	everything associated with that project, including the usher
+	server and server database.</dd>
+      <dt><tt>start</tt></dt>
+      <dd>Starts the usher daemon if it's not already started.</dd>
+      <dt><tt>stop</tt></dt>
+      <dd>Stops the usher daemon if it's started.</dd>
+      <dt><tt>restart</tt></dt>
+      <dd>Restarts a running usher daemon.</dd>
+      <dt><tt>reload</tt></dt>
+      <dd>Has the usher daemon reload its configuration.</dd>
+      <dt><tt>status</tt></dt>
+      <dd>Checks if the usher daemon is up or not.</dd>
+      <dt><tt>list</tt></dt>
+      <dd>Lists the configured usher servers, and says if they are a
+	project controlled by <tt>usherctl</tt>.</dd>
+    </dl>
+
+    <h1>Configuration</h1>
+
+    <p>Configuration is done with simple shell variable assignments
+    in a configuration file.  The variables to be used are:</p>
+
+    <dl>
+      <dt><tt>USHER</tt></dt>
+      <dd>Usher binary.<br />
+	(default: /usr/bin/usher)</dd>
+      <dt><tt>MTN</tt></dt>
+      <dd>Monotone binary.<br />
+	(default: /usr/bin/mtn)</dd>
+      <dt><tt>USHER_CONFDIR</tt></dt>
+      <dd>Configuration directory.<br />
+	(default: /etc/usher)</dd>
+      <dt><tt>USHER_CONF</tt></dt>
+      <dd>Actual configuration file.<br />
+	(default: $USHER_CONFDIR/usher.conf)</dd>
+      <dt><tt>USHER_GLOBALCONF</tt></dt>
+      <dd>Global configuration template.<br />
+	(default: $USHER_CONFDIR/global.conf)</dd>
+      <dt><tt>USHER_CONFD</tt></dt>
+      <dd>Directory for project specific configuration files.<br />
+	(default: $USHER_CONFDIR/conf.d)</dd>
+      <dt><tt>USHER_PIDFILE</tt></dt>
+      <dd>Usher PID file.<br />
+	(default: /var/run/usher.pid)</dd>
+      <dt><tt>USHER_LOGDIR</tt></dt>
+      <dd>Usher log directory.<br />
+	(default: /var/log/usher)</dd>
+      <dt><tt>USHER_PROJECTDIR</tt></dt>
+      <dd>Usher projects directory.<br />
+	(default: /var/lib/usher/projects)</dd>
+    </dl>
+
+    <p>The following variables are only useful for the system
+    administrator that wants to set up a system wide usher:</p>
+
+    <dl>
+      <dt><tt>USHER_SYSTEM_STARTUP</tt></dt>
+      <dd>a non-empty string if usher should be started and stopped with the
+	script /etc/init.d/usher.<br />
+	(default: (unset))</dd>
+      <dt><tt>USHER_USER</tt></dt>
+      <dd>User to run usher as.  Only useful if usher is started with
+	/etc/init.d/usher.<br />
+	MUST match the user usher is started as!</dd>
+      <dt><tt>USHER_GROUP</tt></dt>
+      <dd>Group to run usher as.  Only useful if usher is started with
+	/etc/init.d/usher.<br />
+	MUST match the group usher is started as!</dd>
+    </dl>
+
+    <hr>
+    <address><a href="">Richard Levitte</a></address>
+<!-- Created: Wed Dec  1 09:50:50 CET 2010 -->
+<!-- hhmts start -->
+Last modified: Tue Jan 18 13:00:06 CET 2011
+<!-- hhmts end -->
+  </body>
+</html>
============================================================
--- src/channel.cc	7e6b6bbae6a84041ec840bedf5816bd6e116e5ea
+++ src/channel.cc	28d584b7185308aeab9297b3c9ceae03718a9e65
@@ -24,7 +24,7 @@ channel::channel(sock & c, server_manage
 
 channel::channel(sock & c, server_manager &sm)
  : num(++counter),
-  cli(c), srv(-1),
+   cli(c),
   have_routed(false), no_server(false),
   manager(sm)
 {
@@ -45,7 +45,7 @@ channel::~channel()
 
 channel::~channel()
 {
-  if (srv && !no_server)
+  if (srv != -1 && !no_server)
     manager.disconnect_from_server(srv, name);
 }
 
============================================================
--- src/channel.hh	3a97687c17a68c983872de2792defd9e48028168
+++ src/channel.hh	21231cc383b16935ac33a349718e5aa775341c45
@@ -17,7 +17,7 @@ using boost::shared_ptr;
 #include <boost/shared_ptr.hpp>
 using boost::shared_ptr;
 
-struct server_manager;
+class server_manager;
 
 struct channel
 {
============================================================
--- src/server.hh	dd153b5671f0b9560be8b817849731419e5b8fe4
+++ src/server.hh	6a57214c24d5c35c705276dcae8415dfcabf6c6e
@@ -24,7 +24,7 @@ using boost::weak_ptr;
 #include <boost/weak_ptr.hpp>
 using boost::weak_ptr;
 
-struct server_manager;
+class server_manager;
 
 struct serverstate
 {
@@ -38,8 +38,9 @@ std::ostream & operator<<(std::ostream &
 };
 std::ostream & operator<<(std::ostream & os, serverstate const & ss);
 
-struct server
+class server
 {
+  friend class server_manager;
   bool enabled;
   bool local;
   int pid;
@@ -51,6 +52,7 @@ struct server
   int last_conn_time;
   server_manager &manager;
   weak_ptr<server> me;
+public:
   server(server_manager &sm);
   ~server();
   serverstate get_state();
============================================================
--- src/server_manager.cc	0abe47e13dd931c522aa1a7fb828502d63531a6e
+++ src/server_manager.cc	f4a5b6fe2d917f24ce56c133ee347b9b3e91e50b
@@ -20,8 +20,9 @@ using std::make_pair;
 #include <boost/lexical_cast.hpp>
 //#include <iostream>
 
-serversock::serversock(sock const &o)
- : sock(o)
+serversock::serversock() : sock(-1) { }
+serversock::serversock(sock const &o, string s)
+  : sock(o), srv(s)
 {
 }
 
@@ -309,11 +310,10 @@ server_manager::connect_to_server(string
   if (!srv)
     throw std::logic_error("usher internal error");
   sock s = srv->connect(name);
-  serversock ss(s);
   map<shared_ptr<server>, serverdata>::iterator i = servers.find(srv);
   if (i == servers.end())
     throw std::logic_error("server_manager is inconsistent");
-  ss.srv = i->second.name;
+  serversock ss(s, i->second.name);
   ++total_connections;
   if (srv->local && srv->connection_count == 1)
     {
@@ -325,7 +325,7 @@ server_manager::disconnect_from_server(s
 server_manager::disconnect_from_server(serversock const &s,
                                        string const &name)
 {
-  map<string, shared_ptr<server> >::iterator i = by_name.find(s.srv);
+  map<string, shared_ptr<server> >::iterator i = by_name.find(s.servername());
   if (i == by_name.end())
     return;
   i->second->disconnect(name);
============================================================
--- src/server_manager.hh	fc8ad29b28f82cae3b26955995afdad8f1276a5a
+++ src/server_manager.hh	1d1f3a16329bdf11b69fb7593d048d95c65edc8d
@@ -27,11 +27,13 @@ struct serverlist_reader;
 
 struct serverlist_reader;
 
-struct serversock : public sock
+class serversock : public sock
 {
   string srv;
-  serversock(sock const &o);
-  operator bool() {return !srv.empty();}
+public:
+  serversock();
+  serversock(sock const &o, string s);
+  string const & servername() const { return srv; }
 };
 
 class server_manager
============================================================
--- src/sock.hh	0917e736d673fa6d15fcefea8f1f0e16a63b9bc2
+++ src/sock.hh	b077f32cc61674e13b9c3bc138c924c41b23ceb1
@@ -15,10 +15,11 @@ struct buffer;
 
 struct buffer;
 
-struct sock
+class sock
 {
   int *s;
   static std::set<int*> all_socks;
+public:
   operator int();
   sock(int ss);
   sock(sock const & ss);
============================================================
--- README	b968eb93f8b8ce88d822e9ddc52b563f1742a147
+++ README	84610efd11606729230d94fb905e5e4695328c7b
@@ -13,4 +13,4 @@
 use your new subclass instead of basic_io_serverlist_reader.
 
 The tests use 'socat', and assume the monotone in your $PATH is at least
-version 0.45.
\ No newline at end of file
+version 0.45.
============================================================
--- NEWS	a9b8cb5b3dc0ec686519bbb81dc1058d30fb1099
+++ NEWS	41f6acc0681f23e164e7d8dc6be0738de13a8bf1
@@ -1,5 +1,13 @@
-Xxx Xxx 99 99:99:99 UTC 2010
+Xxx Xxx 99 99:99:99 UTC 2011
 
+        1.0 release.
+
+        General
+
+        - [put stuff here]
+
+Sat Nov 06 03:04:58 UTC 2010
+
         0.99 release.
 
         General
============================================================
--- /dev/null	
+++ release-checklist.txt	305136c17d554f0b16fdab39873c5814cc64691a
@@ -0,0 +1,16 @@
+* test 'make check' or 'make distcheck' on a couple different systems
+
+* look at what's changed since the last release, and make sure there are documentation
+  updates where appropriate
+
+* make sure NEWS is filled out and presentable
+
+* make sure the date at the top of NEWS is filled out
+
+* take the "~dev" out of the version in configure.in
+
+* commit; run autoreconf -i, configure, and "make distcheck" in a clean checkout
+
+* add a tag, post the tarball, and email monotone-devel
+
+* add a new blank release date at the top of NEWS, increment the version number and add "~dev"

reply via email to

[Prev in Thread] Current Thread [Next in Thread]