door_nick_lookup_zmq written
authorBernhard Tittelbach <xro@realraum.at>
Wed, 25 Sep 2013 03:34:02 +0000 (03:34 +0000)
committerBernhard Tittelbach <xro@realraum.at>
Wed, 25 Sep 2013 03:34:02 +0000 (03:34 +0000)
go/door_daemon_zmq/main.go
go/door_daemon_zmq/make_deploy.zsh [new file with mode: 0644]
go/door_nick_lookup_zmq/keys_file.go [new file with mode: 0644]
go/door_nick_lookup_zmq/main.go [new file with mode: 0644]
go/door_nick_lookup_zmq/make_deploy.zsh [new file with mode: 0644]
go/door_nick_lookup_zmq/zeromq.go [new file with mode: 0644]

index facedac..e295c4e 100644 (file)
@@ -7,6 +7,8 @@ import (
     "os"
     "flag"
     "time"
+    "log/syslog"
+    "log"
 )
 
 //~ func StringArrayToByteArray(ss []string) [][]byte {
@@ -22,6 +24,9 @@ import (
 var (
     cmd_port_ string
     pub_port_ string
+    door_tty_path_ string
+    use_syslog_ bool
+    syslog_ *log.Logger
 )
 
 func usage() {
@@ -30,31 +35,34 @@ func usage() {
 }
 
 func init() {
-    flag.StringVar(&cmd_port_, "cmdport", "tcp://127.0.01:3232", "zmq command socket path")
-    flag.StringVar(&pub_port_, "pubport", "pgm://233.252.1.42:4242", "zmq public/listen socket path")
+    flag.StringVar(&cmd_port_, "cmdport", "ipc:///run/tuer/door_cmd.ipc", "zmq command socket path")
+    flag.StringVar(&pub_port_, "pubport", "tcp://*:4242", "zmq public/listen socket path")
+    flag.StringVar(&door_tty_path_, "device", "/dev/door", "door tty device path")
+    flag.BoolVar(&use_syslog_, "syslog", false, "log to syslog local1 facility")
     flag.Usage = usage
     flag.Parse()
 }
 
 func main() {
-    args := flag.Args()
-    if len(args) < 1 {
-        fmt.Fprintf(os.Stderr, "Input file is missing!\n");
-        usage()
-        os.Exit(1);
-    }
-
     zmqctx, cmd_chans, pub_chans := ZmqsInit(cmd_port_, pub_port_)
     defer cmd_chans.Close()
     defer pub_chans.Close()
     defer zmqctx.Close()
 
-    serial_wr, serial_rd, err := OpenAndHandleSerial(args[0])
+    serial_wr, serial_rd, err := OpenAndHandleSerial(door_tty_path_)
     defer close(serial_wr)
     if err != nil {
         panic(err)
     }
 
+    if use_syslog_ {
+        var logerr error
+        syslog_, logerr = syslog.NewLogger(syslog.LOG_INFO | syslog.LOG_LOCAL1, 0)
+        if logerr != nil { panic(logerr) }
+        syslog_.Print("started")
+        defer syslog_.Print("exiting")
+    }
+
     //~ serial_wr <- "f"
     //~ firmware_version := <- serial_rd
     //~ log.Print("Firmware version:", firmware_version)
@@ -65,12 +73,15 @@ func main() {
         select {
             case incoming_ser_line, is_notclosed := <- serial_rd:
                 if is_notclosed {
+                    //~ if syslog_ != nil { syslog_.Print(ByteArrayToString(incoming_ser_line)) }
+                    if syslog_ != nil { syslog_.Printf("%s",incoming_ser_line) }
                     if next_incoming_serial_is_client_reply {
                         next_incoming_serial_is_client_reply = false
                         cmd_chans.Out() <- incoming_ser_line
                     }
                     pub_chans.Out() <- incoming_ser_line
                 } else {
+                    syslog_.Print("serial device disappeared, exiting")
                     os.Exit(1)
                 }
             case tv, timeout_notclosed := <- timeout_chan:
@@ -79,7 +90,11 @@ func main() {
                         cmd_chans.Out() <- [][]byte{[]byte("ERROR"), []byte("No reply from firmware")}
                 }
             case incoming_request, ic_notclosed := <- cmd_chans.In():
-                if ! ic_notclosed {os.Exit(2)}
+                if ! ic_notclosed {
+                    syslog_.Print("zmq socket died, exiting")
+                    os.Exit(2)
+                }
+                if syslog_ != nil { syslog_.Printf("%s",incoming_request) }
                  if err := HandleCommand(incoming_request, serial_wr, serial_rd); err != nil {
                     out_msg := [][]byte{[]byte("ERROR"), []byte(err.Error())}
                     cmd_chans.Out() <- out_msg
diff --git a/go/door_daemon_zmq/make_deploy.zsh b/go/door_daemon_zmq/make_deploy.zsh
new file mode 100644 (file)
index 0000000..746215b
--- /dev/null
@@ -0,0 +1,7 @@
+#!/bin/zsh
+export GO386=387
+export CGO_ENABLED=1
+go-linux-386 clean
+#go-linux-386 build
+#strip ${PWD:t}
+go-linux-386 build -ldflags "-s" && rsync -v ${PWD:t} wuzzler.realraum.at:/flash/tuer/
diff --git a/go/door_nick_lookup_zmq/keys_file.go b/go/door_nick_lookup_zmq/keys_file.go
new file mode 100644 (file)
index 0000000..4cdb294
--- /dev/null
@@ -0,0 +1,54 @@
+// (c) Bernhard Tittelbach, 2013
+
+package main
+
+import (
+    "log"
+    "regexp"
+    "strconv"
+    "errors"
+    "os"
+    "bufio"
+)
+
+var re_keynickline *regexp.Regexp = regexp.MustCompile("^\\s*([0-9a-fA-F]+)\\s+((?:\\p{Latin}|\\d)+).*")
+
+type KeyNickStore map[uint64]string
+
+func (key_nick_map *KeyNickStore) LoadKeysFile(filename string) error {
+    keysfile, err := os.OpenFile(filename, os.O_RDONLY, 0400) // For read access.
+    defer keysfile.Close()
+    if err != nil {
+        return err
+    }
+    
+    //clear map
+    *key_nick_map = make(KeyNickStore)
+    
+    linescanner := bufio.NewScanner(keysfile)
+    linescanner.Split(bufio.ScanLines)
+    for linescanner.Scan() {
+        m := re_keynickline.FindStringSubmatch(linescanner.Text())
+        if len(m) > 2 {
+            if kuint, err := strconv.ParseUint(m[1], 16, 64); err == nil {
+                (*key_nick_map)[kuint] = m[2]
+            } else {
+                log.Print("Error converting hex-cardid:",m[0])
+            }
+        }
+    }
+    return nil
+}
+
+func (key_nick_map *KeyNickStore) LookupHexKeyNick( key string ) (string, error) {
+    kuint, err := strconv.ParseUint(key, 16, 64)
+    if err != nil {
+        return "", errors.New("Invalid Hex-Card-Id")
+    }
+    nick, present := (*key_nick_map)[kuint]
+    if present {
+        return nick, nil
+    } else {
+        return "", errors.New("Key Unknown")
+    }
+}
\ No newline at end of file
diff --git a/go/door_nick_lookup_zmq/main.go b/go/door_nick_lookup_zmq/main.go
new file mode 100644 (file)
index 0000000..fff2496
--- /dev/null
@@ -0,0 +1,94 @@
+// (c) Bernhard Tittelbach, 2013
+
+package main
+
+import (
+    "os"
+    "flag"
+    "fmt"
+    //~ "log/syslog"
+    //~ "log"
+)
+
+// ---------- Main Code -------------
+
+var (
+    zmqport_ string
+    door_keys_file_ string
+    use_syslog_ bool
+    start_server_ bool
+    //~ syslog_ *log.Logger
+)
+
+func usage() {
+    fmt.Fprintf(os.Stderr, "Usage: door_nick_lookup_zmq [options] [keyid1 [keyid2 [...]]]\n")
+    flag.PrintDefaults()
+}
+
+func init() {
+    flag.StringVar(&zmqport_, "zmqport", "ipc:///run/tuer/door_keyname.ipc", "zmq socket path")
+    flag.StringVar(&door_keys_file_, "keysfile", "/flash/keys", "door keys file")
+    //~ flag.BoolVar(&use_syslog_, "syslog", false, "log to syslog local2 facility")
+    flag.BoolVar(&start_server_, "server", false, "open 0mq socket and listen to requests")
+    flag.Usage = usage
+    flag.Parse()
+}
+
+func getFileMTime(filename string ) (int64, error) {
+    keysfile, err := os.Open(filename)
+    if err != nil { return 0, err }
+    defer keysfile.Close()
+    stat, err := keysfile.Stat()
+    if err != nil { return 0, err }
+    return stat.ModTime().Unix(), nil
+}
+
+func main() {
+    knstore := new(KeyNickStore)
+    err := knstore.LoadKeysFile(door_keys_file_)
+    if err != nil { panic(err) }
+    door_keys_mtime, err := getFileMTime(door_keys_file_)
+    if err != nil { panic(err) }
+    
+    for _, key := range(flag.Args()) {
+        nick, err := knstore.LookupHexKeyNick(key)
+        if err != nil {
+            fmt.Printf("ERROR: %s for key %s\n", err.Error(), key)
+        } else {
+            fmt.Println(key,nick)
+        }
+    }
+
+    if ! start_server_ {
+       os.Exit(0)
+    }
+
+    zmqctx, zmqchans := ZmqsInit(zmqport_)
+    if zmqchans == nil {
+        os.Exit(0)
+    }
+    defer zmqchans.Close()
+    defer zmqctx.Close()
+
+    //~ if use_syslog_ {
+        //~ var logerr error
+        //~ syslog_, logerr = syslog.NewLogger(syslog.LOG_INFO | syslog.LOG_LOCAL2, 0)
+        //~ if logerr != nil { panic(logerr) }
+        //~ syslog_.Print("started")
+        //~ defer syslog_.Print("exiting")
+    //~ }
+
+    for keybytes := range(zmqchans.In()) {
+        current_door_keys_mtime, err := getFileMTime(door_keys_file_)
+        if err == nil && current_door_keys_mtime > door_keys_mtime {
+            door_keys_mtime = current_door_keys_mtime
+            knstore.LoadKeysFile(door_keys_file_)
+        }
+        nick, err := knstore.LookupHexKeyNick(string(keybytes[0]))
+        if err != nil {
+            zmqchans.Out() <- [][]byte{[]byte("ERROR"), []byte(err.Error())}
+        } else {
+            zmqchans.Out() <- [][]byte{[]byte("RESULT"), keybytes[0], []byte(nick)}
+        }
+    }
+}
diff --git a/go/door_nick_lookup_zmq/make_deploy.zsh b/go/door_nick_lookup_zmq/make_deploy.zsh
new file mode 100644 (file)
index 0000000..746215b
--- /dev/null
@@ -0,0 +1,7 @@
+#!/bin/zsh
+export GO386=387
+export CGO_ENABLED=1
+go-linux-386 clean
+#go-linux-386 build
+#strip ${PWD:t}
+go-linux-386 build -ldflags "-s" && rsync -v ${PWD:t} wuzzler.realraum.at:/flash/tuer/
diff --git a/go/door_nick_lookup_zmq/zeromq.go b/go/door_nick_lookup_zmq/zeromq.go
new file mode 100644 (file)
index 0000000..9c28973
--- /dev/null
@@ -0,0 +1,45 @@
+// (c) Bernhard Tittelbach, 2013
+
+package main
+
+import (
+    zmq "github.com/vaughan0/go-zmq"
+ )
+
+// ---------- ZeroMQ Code -------------
+
+func ZmqsInit(addrport string)  (ctx *zmq.Context, chans *zmq.Channels) {
+    var err error
+    ctx, err = zmq.NewContext()
+    if err != nil {
+        panic(err)
+    }
+    //close only on later panic, otherwise leave open:
+    defer func(){ if r:= recover(); r != nil { ctx.Close(); panic(r) } }()
+
+    if len(addrport) > 0 {
+        sock, err := ctx.Socket(zmq.Rep)
+        if err != nil {
+            panic(err)
+        }
+        defer func() { if r:= recover(); r != nil { sock.Close(); panic(r) } }()
+
+           if err = sock.Bind(addrport); err != nil {
+            panic(err)
+        }
+
+        chans = sock.ChannelsBuffer(10)
+        go zmqsHandleError(chans)
+    } else {
+        chans = nil
+    }
+
+    return
+}
+
+func zmqsHandleError(chans *zmq.Channels) {
+    for error := range(chans.Errors()) {
+        chans.Close()
+        panic(error)
+    }
+}
\ No newline at end of file