Guest User

Untitled

a guest
Mar 8th, 2013
11,454
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package main
  2.  
  3. import (
  4.     "bufio"
  5.     "io"
  6.     "log"
  7.     "math"
  8.     "math/big"
  9.     "math/rand"
  10.     "net"
  11.     "os"
  12.     "strconv"
  13.     "strings"
  14.     "time"
  15. )
  16.  
  17. const (
  18.     msgdir  = "./msg/"
  19.     koandir = "./koans/"
  20. )
  21.  
  22. var (
  23.     procedures = map[string]func(*Processor, []string){
  24.         "rand": func(p *Processor, c []string) {
  25.             if len(c) == 0 {
  26.                 p.WriteFlush("02 ERROR NO NUMBER SPECIFIED")
  27.                 return
  28.             }
  29.  
  30.             n, err := strconv.ParseUint(c[0], 10, 64)
  31.             if err != nil {
  32.                 p.WriteFlush("02 ERROR " + c[0] + " INVALID")
  33.                 return
  34.             }
  35.             p.Write("01 OK")
  36.             var i uint64
  37.             for i = 0; i < n; i++ {
  38.                 p.Write(strconv.Itoa(int(rand.Int31n(256))))
  39.             }
  40.             p.WriteFlush(".")
  41.         },
  42.         "quine": func(p *Processor, c []string) {
  43.             p.Write("01 OK")
  44.             f, err := os.OpenFile("quine.go", os.O_RDONLY, 0600)
  45.             if err != nil {
  46.                 p.WriteFlush("02 ERROR QUINE NOT AVAILABLE")
  47.                 return
  48.             }
  49.             defer f.Close()
  50.             io.Copy(p.Bout, f)
  51.             p.WriteFlush(".")
  52.         },
  53.         "base29": func(p *Processor, c []string) {
  54.             if len(c) == 0 {
  55.                 p.WriteFlush("02 ERROR NO NUMBER SPECIFIED")
  56.                 return
  57.             }
  58.  
  59.             n, err := strconv.ParseUint(c[0], 10, 64)
  60.             if err != nil {
  61.                 p.WriteFlush("02 ERROR " + c[0] + " INVALID")
  62.                 return
  63.             }
  64.  
  65.             s := ""
  66.             for {
  67.                 r := n % 29
  68.                 s = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[r:r+1] + s
  69.                 n = n / 29
  70.                 if n == 0 {
  71.                     break
  72.                 }
  73.             }
  74.             p.WriteFlush("01 OK " + s)
  75.         },
  76.         "code": func(p *Processor, c []string) {
  77.             p.Write("01 OK")
  78.             f, err := os.OpenFile("c3301serv.go", os.O_RDONLY, 0600)
  79.             if err != nil {
  80.                 p.WriteFlush("02 ERROR SOURCE NOT AVAILABLE")
  81.                 return
  82.             }
  83.             defer f.Close()
  84.             io.Copy(p.Bout, f)
  85.             p.WriteFlush(".")
  86.         },
  87.         "koan": func(p *Processor, c []string) {
  88.             d, err := os.Open(koandir)
  89.             if err != nil {
  90.                 p.WriteFlush("02 ERROR KOAN NOT AVAILABLE")
  91.                 return
  92.             }
  93.             defer d.Close()
  94.             fs, err := d.Readdirnames(-1)
  95.             if err != nil {
  96.                 p.WriteFlush("02 ERROR KOAN NOT AVAILABLE")
  97.                 return
  98.             }
  99.             f, err := os.OpenFile(koandir+fs[rand.Intn(len(fs))], os.O_RDONLY, 0600)
  100.             if err != nil {
  101.                 p.WriteFlush("02 ERROR KOAN NOT AVAILABLE")
  102.                 return
  103.             }
  104.             defer f.Close()
  105.             p.Write("01 OK")
  106.             io.Copy(p.Bout, f)
  107.             p.WriteFlush(".")
  108.         },
  109.         "dh": func(p *Processor, c []string) {
  110.             if len(c) == 0 {
  111.                 p.WriteFlush("02 ERROR NO PRIME MODULUS")
  112.                 return
  113.             }
  114.  
  115.             m, ok := big.NewInt(0).SetString(c[0], 10)
  116.             if !ok {
  117.                 p.WriteFlush("02 ERROR " + c[0] + " INVALID")
  118.                 return
  119.             }
  120.             b := big.NewInt(rand.Int63n(23) + 3)
  121.             s := big.NewInt(rand.Int63n(math.MaxInt64-3301) + 3301)
  122.             e := big.NewInt(0).Exp(b, s, m)
  123.             p.WriteFlush("01 OK " + b.String() + " " + e.String())
  124.  
  125.             p.C.SetReadDeadline(time.Now().Add(time.Second * 15))
  126.             l, err := p.ReadLine()
  127.             if err != nil {
  128.                 p.WriteFlush("02 ERROR TIMEOUT")
  129.                 return
  130.             }
  131.             e2, ok := big.NewInt(0).SetString(l, 10)
  132.             if !ok {
  133.                 p.WriteFlush("02 ERROR " + l + " INVALID")
  134.                 return
  135.             }
  136.             k := big.NewInt(0).Exp(e2, s, m)
  137.             p.WriteFlush("03 DATA " + k.String())
  138.         },
  139.         "next": func(p *Processor, c []string) {
  140.             fn := strconv.FormatUint(uint64(time.Now().Unix()), 10)
  141.             f, err := os.OpenFile(msgdir+fn, os.O_WRONLY|os.O_CREATE, 0700)
  142.             if err != nil {
  143.                 p.WriteFlush("02 ERROR INTERNAL PROBLEM")
  144.                 return
  145.             }
  146.             defer f.Close()
  147.  
  148.             p.WriteFlush("01 OK")
  149.             for {
  150.                 p.C.SetReadDeadline(time.Now().Add(time.Second * 15))
  151.                 l, err := p.ReadLine()
  152.                 if err != nil {
  153.                     p.WriteFlush("02 ERROR TIMEOUT")
  154.                     return
  155.                 }
  156.  
  157.                 if l == "." {
  158.                     break
  159.                 }
  160.  
  161.                 f.Write([]byte(l))
  162.                 f.Write([]byte{'\n'})
  163.             }
  164.             p.WriteFlush("01 OK")
  165.         },
  166.         "goodbye": func(p *Processor, c []string) {
  167.             p.WriteFlush("99 GOODBYE")
  168.             p.Stop()
  169.         },
  170.     }
  171. )
  172.  
  173. type Processor struct {
  174.     C    *net.TCPConn
  175.     Bout *bufio.Writer
  176.     Bin  *bufio.Reader
  177.     Log  *log.Logger
  178.     R    bool
  179. }
  180.  
  181. func NewProcessor(c *net.TCPConn, l *log.Logger) *Processor {
  182.     return &Processor{c, bufio.NewWriter(c), bufio.NewReader(c), l, false}
  183. }
  184.  
  185. func (this *Processor) Start() {
  186.     this.R = true
  187.     this.WriteFlush("00 WELCOME TO CICADA SERVICE WRITTEN IN GO")
  188.     for this.R {
  189.         this.C.SetReadDeadline(time.Now().Add(time.Minute))
  190.         l, err := this.ReadLine()
  191.         if err != nil {
  192.             this.WriteFlush("02 ERROR TIMEOUT")
  193.             this.Stop()
  194.             break
  195.         }
  196.  
  197.         c := strings.Split(strings.ToLower(l), " ")
  198.         if len(c) == 0 {
  199.             this.WriteFlush("02 ERROR NO COMMAND")
  200.             continue
  201.         }
  202.  
  203.         p, ok := procedures[c[0]]
  204.         if !ok {
  205.             this.WriteFlush("02 ERROR COMMAND " + c[0] + " INVALID")
  206.             continue
  207.         }
  208.         this.Log.Print("executing '" + strings.Join(c, " ") + "' for " + this.C.RemoteAddr().String())
  209.         this.C.SetReadDeadline(time.Unix(0, 0))
  210.         p(this, c[1:])
  211.     }
  212. }
  213.  
  214. func (this *Processor) WriteFlush(data string) {
  215.     this.Bout.WriteString(data + "\r\n")
  216.     this.Bout.Flush()
  217. }
  218.  
  219. func (this *Processor) Write(data string) {
  220.     this.Bout.WriteString(data + "\r\n")
  221. }
  222.  
  223. func (this *Processor) Flush() {
  224.     this.Bout.Flush()
  225. }
  226.  
  227. func (this *Processor) Stop() {
  228.     this.Log.Print("closing connection to " + this.C.RemoteAddr().String())
  229.     this.C.Close()
  230.     this.R = false
  231. }
  232.  
  233. func (this *Processor) ReadLine() (string, error) {
  234.     l, err := this.Bin.ReadString('\n')
  235.     if err != nil {
  236.         return "", err
  237.     }
  238.     if len(l) >= 2 {
  239.         l = l[:len(l)-2]
  240.     }
  241.     return l, nil
  242. }
  243.  
  244. type Server struct {
  245.     L   *net.TCPListener
  246.     Log *log.Logger
  247. }
  248.  
  249. func NewServer(laddr *net.TCPAddr) (*Server, error) {
  250.     l, err := net.ListenTCP("tcp", laddr)
  251.     if err != nil {
  252.         return nil, err
  253.     }
  254.     return &Server{l, log.New(os.Stdout, "", log.LstdFlags)}, nil
  255. }
  256.  
  257. func (this *Server) Run() {
  258.     this.Log.Println("server is running under address " + this.L.Addr().String())
  259.     for {
  260.         c, err := this.L.AcceptTCP()
  261.         if err != nil {
  262.             this.Log.Print(err)
  263.             continue
  264.         }
  265.  
  266.         raddr := c.RemoteAddr().(*net.TCPAddr)
  267.         if !raddr.IP.IsLoopback() {
  268.             c.Close()
  269.             continue
  270.         }
  271.  
  272.         this.Log.Println("got connection from " + c.RemoteAddr().String())
  273.         p := NewProcessor(c, this.Log)
  274.         go p.Start()
  275.     }
  276. }
  277.  
  278. func main() {
  279.     laddr, err := net.ResolveTCPAddr("tcp", ":3307")
  280.     if err != nil {
  281.         log.Fatal(err)
  282.     }
  283.     s, err := NewServer(laddr)
  284.     if err != nil {
  285.         log.Fatal(err)
  286.     }
  287.     s.Run()
  288. }
RAW Paste Data