diff --git a/daemon.sh b/daemon.sh
new file mode 100755
index 0000000000000000000000000000000000000000..59d8948d67a32a75eb63fd72098bc16a8b906c3b
--- /dev/null
+++ b/daemon.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+[[ $1 == '' ]] && echo "usage: $0 sign/ans/all" && exit 1
+
+[[ $_openid == "" ]] && echo 'Give openid or url please:' && read _openid
+_openid=$(echo "$_openid" | sed 's/^.*openid=//g')
+echo "Set openid to $_openid"
+
+_url="https://www.teachermate.com.cn/wechat/wechat/guide/answer?openid=$_openid"
+
+_audio_player="mpg123"
+#_audio_player="cvlc --play-and-exit"
+
+function _segfault_detected () {
+    echo "WARNING: segfault captured!"
+    while true; do
+        $_audio_player error.mp3
+        [[ $? == 127 ]] && exit 127
+        sleep 2
+    done
+}
+
+if [[ $1 == all ]]; then
+    _openid="$_openid" $0 sign &
+    _openid="$_openid" $0 ans
+    exit 0
+fi
+
+cd impl
+
+if [[ $1 == sign ]]; then
+    _url="$_url" _audio_player="$_audio_player" ./daemon-signin.fish
+    [[ $? == 127 ]] && exit 127
+    _segfault_detected
+fi
+if [[ $1 == ans ]]; then
+    _url="$_url" _audio_player="$_audio_player" ./daemon-answer.fish
+    [[ $? == 127 ]] && exit 127
+    _segfault_detected
+fi
+
+cd ..
diff --git a/answer.mp3 b/impl/answer.mp3
similarity index 100%
rename from answer.mp3
rename to impl/answer.mp3
diff --git a/badid.mp3 b/impl/badid.mp3
similarity index 100%
rename from badid.mp3
rename to impl/badid.mp3
diff --git a/daemon-answer.fish b/impl/daemon-answer.fish
similarity index 86%
rename from daemon-answer.fish
rename to impl/daemon-answer.fish
index 684e0551fa5f9a7e93c5d8c56cf4f18c1f59c3d7..66d305f9e37b96d9c373747d2a372603e91a8412 100755
--- a/daemon-answer.fish
+++ b/impl/daemon-answer.fish
@@ -1,17 +1,6 @@
 #!/usr/bin/fish
 #Usage: fill _openid with openid from url of the page "学生->答题".
 
-set _openid ''
-
-test "$_openid" = ""; and echo 'Give openid or url please:'; and read _openid
-set _openid (echo "$_openid" | sed 's/^.*openid=//g')
-echo "Set openid to $_openid"
-
-set _url "https://www.teachermate.com.cn/wechat/wechat/guide/answer?openid=$_openid"
-
-set _audio_player "mpg123"
-#set _audio_player "cvlc --play-and-exit"
-
 function _check_and_warn
     if _all_answered
         echo "LOG> exit because all question answered."
diff --git a/daemon-signin.fish b/impl/daemon-signin.fish
similarity index 57%
rename from daemon-signin.fish
rename to impl/daemon-signin.fish
index 40e83854256129091fbf5105341f05e1c7e42e43..dc5f1b4ba711b9a920711f9ce521b8785f02f9ff 100755
--- a/daemon-signin.fish
+++ b/impl/daemon-signin.fish
@@ -1,20 +1,10 @@
 #!/usr/bin/fish
 
-set _openid ''
-
-test "$_openid" = ""; and echo 'Give openid or url please:'; and read _openid
-set _openid (echo "$_openid" | sed 's/^.*openid=//g')
-echo "Set openid to $_openid"
-
-set _url "https://www.teachermate.com.cn/wechat/wechat/guide/signin?openid=$_openid"
-
-set _audio_player "mpg123"
-#set _audio_player "cvlc --play-and-exit"
-
 set tmpfl (mktemp)
+rm $tmpfl
 
 while true
-    sleep 5
+    test -f $tmpfl; and sleep 5
     date
     curl -L "$_url" 2>/dev/null > $tmpfl
     if grep '{"data":\[\],"msg":"unauthorized"}' $tmpfl
diff --git a/error.mp3 b/impl/error.mp3
similarity index 100%
rename from error.mp3
rename to impl/error.mp3
diff --git a/isopen.awk b/impl/isopen.awk
similarity index 100%
rename from isopen.awk
rename to impl/isopen.awk
diff --git a/signin.mp3 b/impl/signin.mp3
similarity index 100%
rename from signin.mp3
rename to impl/signin.mp3