Guest User

Untitled

a guest
Mar 8th, 2013
11,563
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

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×