package peer import "os" import "io/ioutil" import "net" import "net/url" import "src.eruta.nl/beoran/bdjncl/b1" import "src.eruta.nl/beoran/bdjncl/picol" import "src.eruta.nl/beoran/bdjncl/config" import "log" import "fmt" import "context" import "strconv" import "math/rand" import "time" const ( StateDisconnected = iota StateConnecting StateConnected StateIdle StateDisconnecting ) type Peer struct { Conf map[string]string context.Context Out chan b1.Message In chan b1.Message On *url.URL Cmd *url.URL Id int64 As *url.URL } type LocalPeer struct { config.Config Peer *picol.Interp Server net.Listener Command net.Listener Client net.Conn Peers []Peer } func (l LocalPeer) Start() error { var err error l.In = make(chan b1.Message) l.Out = make(chan b1.Message) l.Server, err = net.Listen("tcp", "0.0.0.0:8390") if err != nil { return err } go l.Serve() l.Command, err = net.Listen("unix", "/tmp/bdjncl") if err != nil { return err } go l.Commander() go l.Connect() return nil } func (l LocalPeer) Connect() { for { time.Sleep(1 * time.Second) conn, err := net.Dial("tcp", "localhost:8390") if err != nil { log.Printf("Could not accept connection: %s", err) } l.OnConnected(conn) } } func (l LocalPeer) Serve() { for { conn, err := l.Server.Accept() if err != nil { log.Printf("Could not accept connection: %s", err) time.Sleep(1 * time.Second) } else { go l.OnConnected(conn) } } } func (l LocalPeer) OnConnected(conn net.Conn) { for { log.Printf("Connected: %s", conn.RemoteAddr()) time.Sleep(1 * time.Second) } } func (l LocalPeer) Commander() { for { time.Sleep(1 * time.Second) } } func (p *Peer) PicolConfig(i *picol.Interp, argv []string, privdata interface{}) (string, error) { if len(argv) > 2 { p.Conf[argv[1]] = argv[2] } if len(argv) > 1 { return p.Conf[argv[1]], nil } return "", picol.ArityErr(i, argv[0], argv) } func (p *Peer) PicolEnv(i *picol.Interp, argv []string, privdata interface{}) (string, error) { if len(argv) > 2 { os.Setenv(argv[2], argv[3]) } if len(argv) > 1 { return os.Getenv(argv[1]), nil } return "", picol.ArityErr(i, argv[0], argv) } func picolLog(i *picol.Interp, argv []string, privdata interface{}) (string, error) { if len(argv) < 2 { return "", picol.ArityErr(i, argv[0], argv) } log.Printf(argv[1], argv[2:]) return "", nil } func (p *LocalPeer) PrepareInterp() { p.Interp = picol.InitInterp() p.Interp.RegisterCoreCommands() p.Interp.RegisterCommand("conf", p.PicolConfig, p) p.Interp.RegisterCommand("env", p.PicolEnv, p) p.Interp.RegisterCommand("log", picolLog, p) } func (p *LocalPeer) ReadConfigName(fileName string) error { p.Conf = map[string]string{} buf, err := ioutil.ReadFile(fileName) if err != nil { return err } result, err := p.Interp.Eval(string(buf)) if err != nil { return fmt.Errorf("ERROR: %s: %s", result, err) } return nil } func (p *Peer) UpdateFromConfig() error { var err error if val, ok := p.Conf["id"]; ok { p.Id, err = strconv.ParseInt(val, 0, 64) if err != nil { return err } } else { p.Id = rand.Int63() } if val, ok := p.Conf["on"]; ok { p.On, err = url.Parse(val) if err != nil { return err } } if val, ok := p.Conf["as"]; ok { p.As, err = url.Parse(val) if err != nil { return err } } return nil } /* func (p *Peer) WriteConfigName(fileName string) error { fout, err := os.Create(fileName string) if err != nil { return err } return nil } */