From 441541ad3b5df76929e4d8a5ad8781e6b73aac8d Mon Sep 17 00:00:00 2001 From: Bernhard Tittelbach Date: Wed, 25 Sep 2013 03:34:02 +0000 Subject: [PATCH] door_nick_lookup_zmq written --- go/door_daemon_zmq/main.go | 37 ++++++++---- go/door_daemon_zmq/make_deploy.zsh | 7 +++ go/door_nick_lookup_zmq/keys_file.go | 54 ++++++++++++++++++ go/door_nick_lookup_zmq/main.go | 94 +++++++++++++++++++++++++++++++ go/door_nick_lookup_zmq/make_deploy.zsh | 7 +++ go/door_nick_lookup_zmq/zeromq.go | 45 +++++++++++++++ 6 files changed, 233 insertions(+), 11 deletions(-) create mode 100644 go/door_daemon_zmq/make_deploy.zsh create mode 100644 go/door_nick_lookup_zmq/keys_file.go create mode 100644 go/door_nick_lookup_zmq/main.go create mode 100644 go/door_nick_lookup_zmq/make_deploy.zsh create mode 100644 go/door_nick_lookup_zmq/zeromq.go diff --git a/go/door_daemon_zmq/main.go b/go/door_daemon_zmq/main.go index facedac..e295c4e 100644 --- a/go/door_daemon_zmq/main.go +++ b/go/door_daemon_zmq/main.go @@ -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 index 0000000..746215b --- /dev/null +++ b/go/door_daemon_zmq/make_deploy.zsh @@ -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 index 0000000..4cdb294 --- /dev/null +++ b/go/door_nick_lookup_zmq/keys_file.go @@ -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 index 0000000..fff2496 --- /dev/null +++ b/go/door_nick_lookup_zmq/main.go @@ -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 index 0000000..746215b --- /dev/null +++ b/go/door_nick_lookup_zmq/make_deploy.zsh @@ -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 index 0000000..9c28973 --- /dev/null +++ b/go/door_nick_lookup_zmq/zeromq.go @@ -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 -- 1.7.10.4