diff --git a/s4-funcs.sh b/s4-funcs.sh index f193e06..821c251 100755 --- a/s4-funcs.sh +++ b/s4-funcs.sh @@ -1448,6 +1448,7 @@ exit 0 } dologin() { + test -n "$S4WORLD" && syncaccount checkauth st=$? if [ $st != 0 ]; then diff --git a/s4-newworld.sh b/s4-newworld.sh index d0c1243..9ad10b8 100755 --- a/s4-newworld.sh +++ b/s4-newworld.sh @@ -5,11 +5,6 @@ # $1 = World Display Name in UTF-8 # $2 = World ShortName in alpha-numeric # $3 = World Description in UTF-8 -. `dirname $0`/s4-config.sh -if ! type htmlescape >/dev/null 2>&1; then - . `dirname $0`/s4-funcs.sh ### > /dev/null 2>&1 - trap 'exit 1' INT QUIT -fi dispname=$1 shortname=$2 desc=$3 @@ -19,8 +14,7 @@ read $1 } -echo db=$db URL=$URL isCGI=$isCGI -if ! $isCGI; then +if [ -z "$HTTP_HOST" ]; then while true; do dispname=`echo $dispname | tr -d ': \t\n"' | fold -w 28 | head -1` test -n "$dispname" && break @@ -39,17 +33,30 @@ fi echo "wl=$S4WORLDLIST" echo "$dispname:$shortname:$desc" +# Create config +DB=db/$shortname.sq3; export DB +`dirname $0`/s4-init.sh +. `dirname $0`/s4-config.sh +if ! type htmlescape >/dev/null 2>&1; then + . `dirname $0`/s4-funcs.sh ### > /dev/null 2>&1 + trap 'exit 1' INT QUIT +fi + newworld=$( - { echo "$S4WORLDLIST" | tr ' ' '\n' \ + { echo $S4WORLDLIST | tr ' ' '\n' \ | awk -F: "\$2 != \"$shortname\"{print}" echo "$dispname:$shortname:$desc" - } | tr '\n' ' ' | tr -d '"' + } | tr '\n' ' ' | sed 's/ $//' | tr -d '"' ) if [ -z "$newworld" ]; then exit fi -# Create config +masterdb=`(unset DB; . ./s4-config.sh; echo $DB)` +S4MASTERDB=${masterdb:-db/cgi.sq3} +echo Synching account: db=$db URL=$URL isCGI=$isCGI mas=$S4MASTERDB +. ./s4-world.sh && syncaccount 'force' +echo Synching done bgcolor=$( od -An -tu1 -N3 < /dev/urandom \ | { read r g b @@ -75,12 +82,9 @@ # Update s4-config.sh cat<<-EOF | ed s4-config.sh g/^S4WORLDLIST=/d - \$a - S4WORLDLIST="`echo $newworld`" - . wq EOF -DB=db/$shortname.sq3 `dirname $0`/s4-init.sh -(S4MASTERDB=$db; db=db/$shortname.sq3; . ./s4-world.sh) +echo "S4WORLDLIST=\"$newworld\"" >> s4-config.sh + (cd `dirname $0`; ln -s s4$cgiext s4-world-$shortname$cgiext) echo $newworld added diff --git a/s4-world.sh b/s4-world.sh index b7c6fc3..3e88423 100755 --- a/s4-world.sh +++ b/s4-world.sh @@ -1,5 +1,7 @@ #!/bin/sh +autoremovestop=2 + # Setup variables for running time if $isCGI; then case "$S4WORLDLIST" in @@ -53,48 +55,32 @@ esac fi -err "db=$db mas=$S4MASTERDB sessdb=$sessdb" -# If in parent world, no need to do rest of jobs -if [ -z "$S4MASTERDB" -o ! -s "$S4MASTERDB" ]; then - return -fi -# Confim child -if [ "$db" -ef "$S4MASTERDB" ]; then - return # Points to the same file -fi -# Now Another world is ACTIVE -# sessdb=`dirname $S4MASTERDB`/sess.sq3 -## skey="skey-`basename $mydir`" -syncflag=${db%.*}.synctime -runflag=${db%.*}.run -userupdateflag=`dirname $S4MASTERDB`/`basename $userupdateflag` -test ! -e "$userupdateflag" && return -test "$syncflag" -nt "$userupdateflag" && return -if [ -s "$runflag" ]; then - limit=`cat $runflag|tr -c -d 0-9` - if [ -n "$limit" -a "$limit" -gt `date +%s` ]; then - err "World $S4WORLD account sync withholded by process $$" - return # Running sync by other process not leaching timeout +syncaccount_1() { + + n_m=`query "SELECT printf('%d:%d',\ + (SELECT count(*) FROM m.user), \ + (SELECT count(*) FROM user));"` + n=${n_m%:*}; m=${n_m#*:} # n:m + if [ -z "$n" -o "$n" -lt 2 ]; then + err "Skipping account sync because m.user cannot be reached[n=$n]." + return -3 fi -fi -echo $((`date +%s` + 10)) > $runflag # Setting running flag by timeout 10s + if [ -z "$forceusersync" -a ! -f db/forceusersync ]; then + if [ $((m-n)) -le $((autoremovestop+0)) ]; then + # If if-condition evaluation fails, fall through to else-caluse + rm -f db/forceusersync + else + err "More than $autoremovestop users vanished($((m-n)))." + err "Automatic removal canceled. If you want to sync user accounts" + err "forcibly, touch db/forceusersync file each time of world update." + return -4 + fi + fi + err "`gdate +%S.%3N` Starting account synchronization[$$]" -# for sub.sq3 -# -# main: user: 'taro', 'hanako', 'shige' -# sub: user: 'taro', 'hanako', 'shige' -# sub2: user_s: ('taro', 't'), ('hanako', 'h'), ('shige', 's') -# then update -# - -## sqlite3 -cmd '.timer 1' -cmd '.echo 1' $db < tmp/sql <> $syncflag -else - err "Account synch[$$] failed or bailed with num=[$num]" -fi -test -e "$runflag" && rm -f "$runflag" -return $num + ) + if [ -n "$num" -a "$num" -eq 0 ]; then + err "`gdate +%S.%3N` Account synchronization[$$] done in difference $num" + echo "`date '+%F %T'`: Sync done by process $$" >> $syncflag + else + err "Account synch[$$] failed or bailed with num=[$num]" + fi + return $num +} + +syncaccount() { + forceusersync=$1 + err "db=$db mas=$S4MASTERDB sessdb=$sessdb" + # If in parent world, no need to do rest of jobs + if [ -z "$S4MASTERDB" -o ! -s "$S4MASTERDB" ]; then + return + fi + # Confim child + if [ "$db" -ef "$S4MASTERDB" ]; then + return # Points to the same file + fi + # File based sync check precedes to DB count check for performance issue + syncflag=${db%.*}.synctime + runflag=${db%.*}.run + userupdateflag=`dirname $S4MASTERDB`/`basename $userupdateflag` + test ! -e "$userupdateflag" && return + [ -z "$forceusersync" -a "$syncflag" -nt "$userupdateflag" ] && return + if [ -s "$runflag" ]; then + limit=`cat $runflag|tr -c -d 0-9` + if [ -n "$limit" -a "$limit" -gt `date +%s` ]; then + err "World $S4WORLD account sync withholded by process $$" + return # Running sync by other process not leaching timeout + fi + fi + echo $((`date +%s` + 10)) > $runflag # Setting running flag by timeout 10s + query<<-EOF + .bail ON + ATTACH DATABASE "$S4MASTERDB" AS m; + EOF + syncaccount_1 + rc=$? + test -e "$runflag" && rm -f "$runflag" + query<<-EOF + DETACH DATABASE m; + .bail OFF + EOF + return $rc +}