194 lines
4 KiB
Text
194 lines
4 KiB
Text
|
|
"#stream.spl" import
|
|
"#time.spl" import
|
|
"#json.spl" import
|
|
|
|
def state, network, connections
|
|
|
|
[ ^bring-up ] =state
|
|
"johlg" =network
|
|
6 =connections
|
|
|
|
include json:_StringyJSON in array
|
|
|
|
func panic-handler { |
|
|
catch IO {
|
|
"status" StreamTypes:file:create<1>
|
|
dup :write-exact<[ ^dead [ ^panic ] ] :sjson<0> "\n" concat :to-bytes>
|
|
:close;
|
|
} { with e ;
|
|
"fuck.";
|
|
}
|
|
}
|
|
|
|
func main { exitcode | with args ;
|
|
start-timer =>? ^ok not if {
|
|
"error " print :sjson<0> print " in state: " state:sjson<0> concat println
|
|
"error in timers" panic
|
|
}
|
|
0
|
|
}
|
|
|
|
func start-timer { result |
|
|
def sa time:unixms =sa
|
|
1 while { } {
|
|
1000 time:unixms sa - - dup 0 lt if { pop 0 } time:sleep;
|
|
time:unixms =sa
|
|
|
|
def v
|
|
timer-run
|
|
dup :sjson<0>
|
|
dup println
|
|
=v
|
|
catch IO {
|
|
"status" StreamTypes:file:create<1>
|
|
dup :write-exact<v "\n" concat :to-bytes>
|
|
:close;
|
|
} {
|
|
[ ^err "no fs access" "status" ] 3 stop
|
|
}
|
|
dup => [ ^reboot &=v ] if {
|
|
"" println
|
|
"reboot requested because " v concat "." concat println
|
|
catch IO {
|
|
"deny-reboot" read-file "no" eq not if {
|
|
"reboot denied because deny-reboot is set. need manual help"
|
|
pop [ ^err "reboot denied" ] 3 stop
|
|
}
|
|
} { pop }
|
|
catch IO {
|
|
"deny-reboot" StreamTypes:file:create<1>
|
|
dup :write-exact<"yes" :to-bytes>
|
|
:close;
|
|
} {
|
|
[ ^err "no fs access" "deny-reboot" ] 3 stop
|
|
}
|
|
while { 1 } {
|
|
fork<|
|
|
"status" StreamTypes:file:create<1>
|
|
dup :write-exact<[ ^dead v ] :sjson<0> "\n" concat :to-bytes>
|
|
:close;
|
|
catch {
|
|
[ "sudo" "reboot" ] command-wait;
|
|
} { pop }
|
|
>
|
|
5000 time:sleep;
|
|
}
|
|
}
|
|
=>? [ ^ok &pop ]
|
|
}
|
|
}
|
|
|
|
func timer-run { result |
|
|
def wait-time
|
|
|
|
device-present not if {
|
|
[ ^reboot "device not present" ]
|
|
2 stop
|
|
}
|
|
|
|
state => [ ^fix-device ] if {
|
|
fix-device
|
|
2 stop
|
|
}
|
|
|
|
state => [ ^bring-up ] if {
|
|
switch-networks =>? [ ^err "nmcli failed" ] if {
|
|
[ ^fix-device ] =state
|
|
[ ^ok state ] 3 stop
|
|
} dup => [ ^ok &pop ] if {
|
|
3 stop
|
|
}
|
|
}
|
|
|
|
is-network-up not if {
|
|
[ ^bring-up ] =state
|
|
[ ^ok state ] 2 stop
|
|
}
|
|
|
|
state => [ ^waiting &=wait-time ] if {
|
|
wait-time 0 eq if {
|
|
[ ^bring-up ] =state
|
|
[ ^ok state ] 3 stop
|
|
}
|
|
[ ^waiting wait-time 1 - ] =state
|
|
[ ^ok state ] 2 stop
|
|
}
|
|
|
|
state => [ ^connecting &=wait-time ] if {
|
|
is-network-up if {
|
|
[ ^waiting 60 20 * ] =state
|
|
catch IO {
|
|
"deny-reboot" StreamTypes:file:create<1>
|
|
dup :write-exact<"no" :to-bytes>
|
|
:close;
|
|
} {
|
|
[ ^err "no fs access" "deny-reboot" ] 4 stop
|
|
}
|
|
[ ^ok ^connected ] 3 stop
|
|
}
|
|
wait-time 0 eq if {
|
|
[ ^bring-up ] =state
|
|
[ ^ok state ] 3 stop
|
|
}
|
|
[ ^connecting wait-time -- ] =state
|
|
[ ^ok state ] 2 stop
|
|
}
|
|
|
|
[ ^err "unknown state" state ]
|
|
}
|
|
|
|
func switch-networks { result |
|
|
[ ^connecting 10 ] =state
|
|
|
|
def b
|
|
random-byte =>? [ ^ok &=b ] not if { 2 stop }
|
|
|
|
b connections % =b
|
|
|
|
def conn, hostname
|
|
network b _str concat =conn
|
|
conn "-hostname" concat read-file :replace<"\n" ""> =hostname
|
|
|
|
"connecting to " conn concat " with hostname " concat hostname concat println
|
|
|
|
[ "sudo" "hostnamectl" "set-hostname" hostname ] command-wait
|
|
[ "sudo" "nmcli" "c" "up" conn ] command-wait or
|
|
if {
|
|
[ ^err "nmcli failed" ] 2 stop
|
|
}
|
|
|
|
[ ^ok ^connected ]
|
|
}
|
|
|
|
func device-present { bool |
|
|
[ "lsusb" ] StreamTypes:cmd:create
|
|
dup :read-to-end<1024>:to-str
|
|
dup :contains<"0bda:c811"> swap:contains<"0bda:1a2b"> or swap
|
|
:close
|
|
}
|
|
|
|
func fix-device { result |
|
|
[ ^bring-up ] =state
|
|
[ "sudo" "usb_modeswitch" "-v" "0bda" "-p" "1a2b" "-K" ] command-wait;
|
|
[ ^ok ^fixing-device ]
|
|
}
|
|
|
|
func is-network-up { |
|
|
def done 0 =done
|
|
fork<| 1000 time:sleep; done not if { "ping unsuccessful" println [ "killall" "ping" ] command-wait; } >
|
|
[ "ping" "-c" "1" "1.1.1.1" ] command-wait 0 _int eq
|
|
1 =done
|
|
}
|
|
|
|
func random-byte { [result,byte] |
|
|
catch IO {
|
|
def b
|
|
"/dev/urandom" StreamTypes:file:create<0>
|
|
dup :read-one =b
|
|
:close;
|
|
[ ^ok b ]
|
|
} { with err ;
|
|
[ ^err err ]
|
|
}
|
|
}
|