rev |
line source |
yuuji@734
|
1 #!/bin/sh
|
yuuji@734
|
2
|
yuuji@817
|
3 autoremovestop=2
|
yuuji@817
|
4
|
yuuji@791
|
5 # Setup variables for running time
|
yuuji@791
|
6 if $isCGI; then
|
yuuji@791
|
7 case "$S4WORLDLIST" in
|
yuuji@791
|
8 *:*:*)
|
yuuji@791
|
9 worldlistfile=cache/worldlist
|
yuuji@797
|
10 worldgrpfile=cache/worldgrps
|
yuuji@791
|
11 worldoptionfile=cache/worldoption
|
yuuji@791
|
12 worldnamefile=cache/worldname
|
yuuji@791
|
13 if [ ! -e $worldlistfile -o $worldlistfile -ot s4-config.sh \
|
yuuji@791
|
14 -o ! -e $worldoptionfile -o $worldoptionfile -ot s4-config.sh \
|
yuuji@794
|
15 -o s4-world.sh -nt $worldoptionfile ]
|
yuuji@791
|
16 then
|
yuuji@791
|
17 echo S4MASTERURL=$S4MASTERURL >> tmp/debug.out
|
yuuji@791
|
18 cat <<-EOF > $worldlistfile
|
yuuji@797
|
19 <div><table>
|
yuuji@791
|
20 <tr><th>World List</th></tr>
|
yuuji@794
|
21 <tr><td title="Base World$nl拠点となるWorldです">⇒
|
yuuji@794
|
22 <a href="${S4MASTERURL:-$URL}">Base</a></td></tr>
|
yuuji@791
|
23 EOF
|
yuuji@791
|
24 true > $worldoptionfile
|
yuuji@791
|
25 for i in $S4WORLDLIST; do
|
yuuji@791
|
26 echo $i | {
|
yuuji@791
|
27 IFS=: read name short d
|
yuuji@791
|
28 cgi="s4-world-$short$cgiext"
|
yuuji@791
|
29 conf="s4-config-$short.sh"
|
yuuji@791
|
30 cat<<-EOF >>$worldlistfile
|
yuuji@791
|
31 <tr><td title="$d">⇒ <a href="$cgi">$name</a></td></tr>
|
yuuji@791
|
32 EOF
|
yuuji@791
|
33 cat<<-EOF >>$worldoptionfile
|
yuuji@791
|
34 <option title="$d" value="$conf">$name</option>
|
yuuji@791
|
35 EOF
|
yuuji@791
|
36 echo "$name" > $worldnamefile.$short
|
yuuji@791
|
37 }
|
yuuji@791
|
38 done
|
yuuji@791
|
39 if [ -s "$worldoptionfile" ]; then
|
yuuji@791
|
40 echo "<option value=\"s4-config.sh\">Base</option>" >> $worldoptionfile
|
yuuji@791
|
41 echo "</table>$nl</div>" >> $worldlistfile
|
yuuji@797
|
42 sed 's/href="\([^>]*\)"/href="\1?grps"/' $worldlistfile \
|
yuuji@797
|
43 > $worldgrpfile
|
yuuji@791
|
44 else
|
yuuji@791
|
45 true > $worldoptionfile; true > $worldlistfile # Remove contents
|
yuuji@791
|
46 rm -f ${worldnamefile}.*
|
yuuji@791
|
47 fi
|
yuuji@791
|
48 fi
|
yuuji@791
|
49 if [ -s "$worldlistfile" ]; then
|
yuuji@797
|
50 S4WORLDS="▼spaste(\`$worldlistfile')"
|
yuuji@791
|
51 S4WORLDNAME=${S4WORLD:+`cat $worldnamefile.$S4WORLD`}
|
yuuji@797
|
52 S4WORLDGRPS="▼spaste(\`$worldgrpfile')"
|
yuuji@791
|
53 fi
|
yuuji@791
|
54 ;;
|
yuuji@791
|
55 esac
|
yuuji@791
|
56 fi
|
yuuji@791
|
57
|
yuuji@734
|
58
|
yuuji@817
|
59 syncaccount_1() {
|
yuuji@817
|
60
|
yuuji@817
|
61 n_m=`query "SELECT printf('%d:%d',\
|
yuuji@817
|
62 (SELECT count(*) FROM m.user), \
|
yuuji@817
|
63 (SELECT count(*) FROM user));"`
|
yuuji@817
|
64 n=${n_m%:*}; m=${n_m#*:} # n:m
|
yuuji@817
|
65 if [ -z "$n" -o "$n" -lt 2 ]; then
|
yuuji@817
|
66 err "Skipping account sync because m.user cannot be reached[n=$n]."
|
yuuji@817
|
67 return -3
|
yuuji@794
|
68 fi
|
yuuji@817
|
69 if [ -z "$forceusersync" -a ! -f db/forceusersync ]; then
|
yuuji@817
|
70 if [ $((m-n)) -le $((autoremovestop+0)) ]; then
|
yuuji@817
|
71 # If if-condition evaluation fails, fall through to else-caluse
|
yuuji@817
|
72 rm -f db/forceusersync
|
yuuji@817
|
73 else
|
yuuji@817
|
74 err "More than $autoremovestop users vanished($((m-n)))."
|
yuuji@817
|
75 err "Automatic removal canceled. If you want to sync user accounts"
|
yuuji@817
|
76 err "forcibly, touch db/forceusersync file each time of world update."
|
yuuji@817
|
77 return -4
|
yuuji@817
|
78 fi
|
yuuji@966
|
79 else
|
yuuji@966
|
80 rm -f db/forceusersync # Remove flag file for future
|
yuuji@817
|
81 fi
|
yuuji@885
|
82 err "`gdate +%S.%3N` Starting account synchronization"
|
yuuji@887
|
83 SYNC_M=1
|
yuuji@742
|
84
|
yuuji@965
|
85 if [ -s "$syncflag" ]; then
|
yuuji@965
|
86 prevsync=`tail -1 $syncflag|colrm 20` # 2020-06-21 12:30:00 = 19cols
|
yuuji@965
|
87 else
|
yuuji@965
|
88 prevsync="2000-01-01 00:00:00"
|
yuuji@965
|
89 fi
|
yuuji@835
|
90 syncall=${db%.*}.syncall
|
yuuji@835
|
91 err syncallfile=$syncall
|
yuuji@835
|
92 if [ -e $syncall ]; then
|
yuuji@835
|
93 rm -f "$syncall"
|
yuuji@835
|
94 err "Force update user_m for all users"
|
yuuji@835
|
95 else
|
yuuji@835
|
96 case "$prevsync" in
|
yuuji@835
|
97 [2-9][0-9][0-9][0-9]-[01][0-9]-[0-3][0-9]\ [012][0-9]:??:??)
|
yuuji@881
|
98 SYNCCOND="WHERE name in (SELECT name FROM m.user_s WHERE key='profupdate' AND val > '$prevsync')"
|
yuuji@880
|
99 err "prevsync=$prevsync"
|
yuuji@880
|
100 limited=`query "SELECT DISTINCT name FROM m.user_s $SYNCCOND;"`
|
yuuji@880
|
101 if [ -n "$limited" ]; then
|
yuuji@880
|
102 err synccond limited to "$limited"
|
yuuji@880
|
103 else
|
yuuji@880
|
104 err synccond canceled for user_m
|
yuuji@880
|
105 SYNCCOND="WHERE NULL"
|
yuuji@887
|
106 SYNC_M=
|
yuuji@880
|
107 fi
|
yuuji@835
|
108 err "Touch $syncall (owner=`id -un`) to update all user_m."
|
yuuji@835
|
109 ;;
|
yuuji@835
|
110 *)
|
yuuji@835
|
111 echo arere ;;
|
yuuji@835
|
112 esac
|
yuuji@835
|
113 fi
|
yuuji@817
|
114 ## num=$(sqlite3 -bail -cmd 'PRAGMA FOREIGN_KEYS=on' $db <<EOF
|
yuuji@903
|
115 result=$(query <<EOF
|
yuuji@734
|
116 BEGIN;
|
yuuji@734
|
117 DElETE FROM main.user WHERE rowid NOT IN (SELECT rowid FROM m.user);
|
yuuji@734
|
118 INSERT INTO main.user(rowid, name)
|
yuuji@734
|
119 SELECT rowid, name FROM m.user
|
yuuji@734
|
120 WHERE m.user.rowid NOT IN (SELECT rowid FROM user);
|
yuuji@904
|
121 /* PrimaryKey:name cannot be changed, but ensure the integrity of user */
|
yuuji@904
|
122 UPDATE user SET name = (SELECT name FROM m.user WHERE main.user.rowid=m.user.rowid) WHERE name != (SELECT name from m.user WHERE main.user.rowid=m.user.rowid);
|
yuuji@742
|
123 DELETE FROM main.user_s WHERE rowid NOT IN (SELECT rowid FROM m.user_s);
|
yuuji@742
|
124 REPLACE INTO main.user_s(rowid, name, key, type, val, bin)
|
yuuji@734
|
125 SELECT rowid,* FROM m.user_s;
|
yuuji@887
|
126 ${SYNC_M:+
|
yuuji@742
|
127 DELETE FROM main.user_m WHERE rowid NOT IN (SELECT rowid FROM m.user_m);
|
yuuji@742
|
128 REPLACE INTO main.user_m(rowid, name, key, type, val, bin)
|
yuuji@835
|
129 SELECT rowid,* FROM m.user_m $SYNCCOND
|
yuuji@834
|
130 EXCEPT
|
yuuji@835
|
131 SELECT rowid,* FROM main.user_m $SYNCCOND
|
yuuji@887
|
132 ;} /* SYNC_M closed here */
|
yuuji@903
|
133 SELECT 'OK';
|
yuuji@734
|
134 END;
|
yuuji@903
|
135 EOF
|
yuuji@903
|
136 )
|
yuuji@903
|
137 err "`gdate +%S.%3N` Update account tables finished with result=[$result]"
|
yuuji@903
|
138 test x"$result" = x"OK" && num=$(query <<EOF
|
yuuji@734
|
139 /* Compare user tables */
|
yuuji@734
|
140 WITH master AS (
|
yuuji@734
|
141 SELECT p.rowid,* FROM m.user p
|
yuuji@887
|
142 NATURAL LEFT JOIN m.user_s
|
yuuji@887
|
143 ${SYNC_M:+ NATURAL LEFT JOIN m.user_m}
|
yuuji@903
|
144 $SYNCCOND
|
yuuji@743
|
145 ), thisworld AS (
|
yuuji@734
|
146 SELECT p.rowid,* FROM user p
|
yuuji@887
|
147 NATURAL LEFT JOIN user_s
|
yuuji@887
|
148 ${SYNC_M:+ NATURAL LEFT JOIN user_m}
|
yuuji@903
|
149 $SYNCCOND
|
yuuji@734
|
150 ), m_a AS (
|
yuuji@743
|
151 SELECT * FROM master EXCEPT SELECT * FROM thisworld
|
yuuji@734
|
152 ), a_m AS (
|
yuuji@743
|
153 SELECT * FROM thisworld EXCEPT SELECT * FROM master
|
yuuji@734
|
154 ) SELECT (SELECT count(*) FROM m_a) + (SELECT count(*) FROM a_m);
|
yuuji@734
|
155 EOF
|
yuuji@817
|
156 )
|
yuuji@817
|
157 if [ -n "$num" -a "$num" -eq 0 ]; then
|
yuuji@885
|
158 err "`gdate +%S.%3N` Account synchronization done in difference $num"
|
yuuji@817
|
159 echo "`date '+%F %T'`: Sync done by process $$" >> $syncflag
|
yuuji@817
|
160 else
|
yuuji@885
|
161 err "Account synch failed or bailed with num=[$num]"
|
yuuji@817
|
162 fi
|
yuuji@817
|
163 return $num
|
yuuji@817
|
164 }
|
yuuji@817
|
165
|
yuuji@817
|
166 syncaccount() {
|
yuuji@817
|
167 forceusersync=$1
|
yuuji@859
|
168 ## err "db=$db mas=$S4MASTERDB sessdb=$sessdb"
|
yuuji@817
|
169 # If in parent world, no need to do rest of jobs
|
yuuji@817
|
170 if [ -z "$S4MASTERDB" -o ! -s "$S4MASTERDB" ]; then
|
yuuji@817
|
171 return
|
yuuji@817
|
172 fi
|
yuuji@817
|
173 # Confim child
|
yuuji@817
|
174 if [ "$db" -ef "$S4MASTERDB" ]; then
|
yuuji@817
|
175 return # Points to the same file
|
yuuji@817
|
176 fi
|
yuuji@817
|
177 # File based sync check precedes to DB count check for performance issue
|
yuuji@817
|
178 syncflag=${db%.*}.synctime
|
yuuji@817
|
179 runflag=${db%.*}.run
|
yuuji@817
|
180 userupdateflag=`dirname $S4MASTERDB`/`basename $userupdateflag`
|
yuuji@817
|
181 test ! -e "$userupdateflag" && return
|
yuuji@965
|
182 [ -z "$forceusersync" -a -f "$syncflag" -a \
|
yuuji@965
|
183 "$syncflag" -nt "$userupdateflag" ] && return
|
yuuji@817
|
184 if [ -s "$runflag" ]; then
|
yuuji@817
|
185 limit=`cat $runflag|tr -c -d 0-9`
|
yuuji@892
|
186 err syncaccount: limit=$limit
|
yuuji@817
|
187 if [ -n "$limit" -a "$limit" -gt `date +%s` ]; then
|
yuuji@817
|
188 err "World $S4WORLD account sync withholded by process $$"
|
yuuji@817
|
189 return # Running sync by other process not leaching timeout
|
yuuji@817
|
190 fi
|
yuuji@817
|
191 fi
|
yuuji@817
|
192 echo $((`date +%s` + 10)) > $runflag # Setting running flag by timeout 10s
|
yuuji@892
|
193 err syncaccount: setrunflag[$runflag]=`cat $runflag`
|
yuuji@817
|
194 query<<-EOF
|
yuuji@817
|
195 .bail ON
|
yuuji@817
|
196 ATTACH DATABASE "$S4MASTERDB" AS m;
|
yuuji@817
|
197 EOF
|
yuuji@817
|
198 syncaccount_1
|
yuuji@817
|
199 rc=$?
|
yuuji@817
|
200 test -e "$runflag" && rm -f "$runflag"
|
yuuji@817
|
201 query<<-EOF
|
yuuji@817
|
202 DETACH DATABASE m;
|
yuuji@817
|
203 .bail OFF
|
yuuji@817
|
204 EOF
|
yuuji@817
|
205 return $rc
|
yuuji@817
|
206 }
|
yuuji@825
|
207
|
yuuji@825
|
208 getworldDB() { # $1=conf
|
yuuji@825
|
209 (unset DB; . "$1"; echo ${DB:-$defaultdb})
|
yuuji@825
|
210 }
|
yuuji@825
|
211
|
yuuji@825
|
212 worldnameDBlist() {
|
yuuji@825
|
213 echo Base:Base:`getworldDB ./s4-config.sh`
|
yuuji@825
|
214 for w in $S4WORLDLIST; do
|
yuuji@825
|
215 case "$w" in
|
yuuji@825
|
216 *:*:*:*) continue ;;
|
yuuji@825
|
217 *:*:*) w=${w%:*}; name=${w%:*}; world=${w#*:} ;;
|
yuuji@825
|
218 *) continue ;;
|
yuuji@825
|
219 esac
|
yuuji@825
|
220 d=`getworldDB "./s4-config-$world.sh"`
|
yuuji@825
|
221 test -s "$d" && echo ${world}:${name}:$d
|
yuuji@825
|
222 done
|
yuuji@825
|
223 }
|
yuuji@825
|
224
|
yuuji@828
|
225 grepgrpworld() {
|
yuuji@828
|
226 world=$1; wname=$2; exp=$3; tdb=$4
|
yuuji@825
|
227 case $world in
|
yuuji@827
|
228 Base) cgi=${S4MASTERURL:-$URL} ;;
|
yuuji@825
|
229 *) cgi=s4-world-$world$cgiext ;;
|
yuuji@825
|
230 esac
|
yuuji@827
|
231 case $exp in
|
yuuji@828
|
232 mem:*)
|
yuuji@828
|
233 arg=${exp#*:}
|
yuuji@828
|
234 cond="user = '$arg'"
|
yuuji@828
|
235 guide="「${S4WORLDNAME:-Base}」以外の世界の所属グループ"
|
yuuji@828
|
236 s="(<a href=\"$cgi?stage=grps&kwd=mem:$arg\">所属絞</a>)" ;;
|
yuuji@828
|
237 *)
|
yuuji@828
|
238 arg=`sqlquote "%$3%"`
|
yuuji@828
|
239 cond="gname LIKE $arg"
|
yuuji@828
|
240 guide="$exp を含むグループは別世界にもあります"
|
yuuji@828
|
241 s="(<a href=\"$cgi?stage=grps&kwd=$exp\">絞込</a>)" ;;
|
yuuji@827
|
242 esac
|
yuuji@825
|
243 query <<-EOF |
|
yuuji@828
|
244 ATTACH DATABASE "$tdb" AS td;
|
yuuji@825
|
245 SELECT DISTINCT td.grp.rowid,hex(gname)
|
yuuji@825
|
246 FROM td.grp NATURAL JOIN td.grp_mem
|
yuuji@825
|
247 WHERE $cond;
|
yuuji@825
|
248 DETACH DATABASE td;
|
yuuji@825
|
249 EOF
|
yuuji@825
|
250 while IFS='|' read rowid hgname; do
|
yuuji@825
|
251 # echo rowid=$rowid - `echo "$hgname"|unhexize|htmlescape`
|
yuuji@825
|
252 htmlgn=`echo $hgname|unhexize|htmlescape`
|
yuuji@825
|
253 printf '<a href="%s?grp+%d">%s</a> ' "$cgi" "$rowid" "$htmlgn"
|
yuuji@825
|
254 done | {
|
yuuji@825
|
255 read ans
|
yuuji@825
|
256 if [ -n "$ans" ]; then
|
yuuji@825
|
257 w=`echo $wname|htmlescape`
|
yuuji@826
|
258 u="<a href=\"$cgi?grps\"><span class=\"pre\">$w</span></a>"
|
yuuji@825
|
259 cat<<-EOF
|
yuuji@828
|
260 GUIDE:<h2>`echo "$guide"|htmlescape`</h2>
|
yuuji@825
|
261 <tr>
|
yuuji@826
|
262 <tr><td>$u $s</td>
|
yuuji@825
|
263 <td>$ans</td>
|
yuuji@825
|
264 </dl>
|
yuuji@825
|
265 EOF
|
yuuji@825
|
266 fi
|
yuuji@825
|
267 }
|
yuuji@828
|
268 }
|
yuuji@825
|
269
|
yuuji@825
|
270 peekgrpworlds() (
|
yuuji@828
|
271 # $1=(Pattern|mem:User)
|
yuuji@828
|
272 # err "pgw-1=[$1]"
|
yuuji@825
|
273 for wd in `worldnameDBlist`; do
|
yuuji@825
|
274 world=${wd%%:*}; wd=${wd#*:}
|
yuuji@825
|
275 worldname=${wd%:*}
|
yuuji@825
|
276 d=${wd#*:}
|
yuuji@825
|
277 if [ ! $db -ef $d -a -s $d ]; then
|
yuuji@827
|
278 grepgrpworld "$world" "$worldname" "$1" "$d"
|
yuuji@825
|
279 fi
|
yuuji@825
|
280 done | {
|
yuuji@825
|
281 result=`cat`
|
yuuji@825
|
282 if [ -n "$result" ]; then
|
yuuji@828
|
283 cat<<-EOF
|
yuuji@828
|
284 `echo "$result"|sed 's/^GUIDE://;2q'`
|
yuuji@828
|
285 <table class="b">
|
yuuji@828
|
286 `echo "$result"|grep -v '^GUIDE:'`
|
yuuji@828
|
287 </table>
|
yuuji@828
|
288 EOF
|
yuuji@825
|
289 fi
|
yuuji@825
|
290 }
|
yuuji@825
|
291 )
|