new features for door daemon
[svn42.git] / door_daemon_go / unix_socket_server.go
1 package main
2 import "fmt"
3 import "net"
4 import "bufio"
5 import "strings"
6 import "os"
7 import "io"
8 import "termios"
9 import "flag"
10
11 var cmdHandler = map[string]func([]string,string,*bufio.ReadWriter ) {
12   "test":handleCmdTest,
13   "open":handleCmdController,
14   "close":handleCmdController,
15   "toggle":handleCmdController,
16 }
17
18
19 func readLineSafe(rw *bufio.Reader) (string, error) {
20   wasPrefix:=false
21   var line string
22   for isPrefix:=true;isPrefix; {
23     var lineBuf []byte 
24     var err error
25     lineBuf,isPrefix,err = rw.ReadLine()
26     if err != nil {
27         return "",err
28     }
29     if isPrefix {
30       wasPrefix=true
31     } else {
32       line=string(lineBuf)
33     }
34   }
35   if wasPrefix {
36       fmt.Println("line too long")
37       //fmt.Fprintf(rw,"line too long\n")
38       //rw.Flush()
39       return "",nil
40   }
41   return line,nil
42 }
43
44 func connToReadWriter(c io.Reader,cw io.Writer) (*bufio.ReadWriter) {
45     client_r := bufio.NewReaderSize(c,1024)
46     client_w := bufio.NewWriterSize(cw,1024)
47     return bufio.NewReadWriter(client_r,client_w)
48 }
49
50 func handleConnection(c net.Conn) () {
51     client:=connToReadWriter(c,c)
52     fmt.Println("new connection")
53     for {
54          line,err:=readLineSafe(bufio.NewReader(client))
55          if err != nil {
56           if err.Error() != "EOF" {
57             fmt.Printf("Error: readLineSafe returned %v\n",err.Error())
58           } else {
59             fmt.Printf("Connection closed by remote host\n");
60           }
61           c.Close()
62           return
63          }
64          if line == "" {
65            continue
66          }
67          fmt.Printf("Received: %v\n", line)
68          tokens:=strings.Fields(line)
69          remainStr:=strings.Join(tokens[1:]," ")
70          handleCmd(tokens,remainStr,client)
71     }
72 }
73
74 func handleCmd(tokens []string, remainStr string,client * bufio.ReadWriter) {
75   cmd:=tokens[0]
76   func_ptr,present := cmdHandler[cmd]
77   if present {
78     func_ptr(tokens, remainStr,client)
79   } else {
80     fmt.Printf("Error: unknown Cmd: %v\n", cmd)
81   }
82 }
83
84 func handleCmdTest(tokens []string, remainStr string, client * bufio.ReadWriter) {
85   //cmd:=tokens[0]
86   fmt.Printf("Test: %v\n", remainStr)
87 }
88
89 func handleCmdController(tokens []string, remainStr string, client * bufio.ReadWriter) {
90   cmd:=tokens[0]
91   s_r:=strings.NewReader(cmd)
92   char := make([]byte,1)
93   s_r.Read(char)
94   fmt.Println(string(char))
95 }
96
97
98 func openTTY(name string) *os.File {
99   file, err := os.OpenFile(name,os.O_RDWR  ,0600) // For read access.
100   if err != nil {
101     fmt.Println(err.Error())
102   }
103   termios.Ttyfd(file.Fd())
104   termios.SetRaw()
105   return file 
106 }
107 func usage() {
108     fmt.Fprintf(os.Stderr, "usage: myprog [inputfile]\n")
109     flag.PrintDefaults()
110     os.Exit(2)
111 }
112
113 func SerialWriter(c chan string, serial * os.File ) {
114   for {
115     serial.WriteString(<-c)
116     serial.Sync()
117   }
118 }
119
120 func SerialReader(c chan string , serial * bufio.Reader) {
121   for {
122     s,err := readLineSafe(serial)
123     if (s=="") {
124      continue
125     }
126     if (err!=nil) {
127      fmt.Printf("Error in read from serial: %v\n",err.Error())
128      os.Exit(1)
129     }
130     fmt.Printf("Serial: Read %v\n",s);
131     c<-s
132   }
133 }
134
135 func openSerial(filename string) (chan string,chan string) {
136   serial:=openTTY(filename)
137   in:=make(chan string)
138   out:=make(chan string)
139   //go SerialWriter(out,serial)
140   go SerialReader(in,bufio.NewReaderSize(serial,128))
141   return in,out
142 }
143
144 func SerialHandler(serial_i chan string) {
145   for {
146     fmt.Printf("Serial said: %v\n",<-serial_i);
147   }
148 }
149 func main() {
150     flag.Usage = usage
151     flag.Parse()
152
153     args := flag.Args()
154     if len(args) < 1 {
155         fmt.Println("Input file is missing.");
156         os.Exit(1);
157     }
158   ln, err := net.Listen("unix", "/tmp/test.sock")
159   if err != nil {
160     fmt.Printf("Error: %s\n",err.Error())
161     return
162   }
163   fmt.Printf("Listener started\n")
164
165   serial_i,serial_o:=openSerial(args[0]) 
166   go SerialHandler(serial_i)
167   serial_o<-"f"
168
169   for {
170     conn, err := ln.Accept()
171     if err != nil {
172       // handle error
173      continue
174     }
175     go handleConnection(conn)
176   }
177 }