• R/O
  • HTTP
  • SSH
  • HTTPS

shogi-server:

shogi-server source


File Info

Rev. 6e9f2816b581e6b6100b3df25700cd3b28ee9a7c
Size 4,503 bytes
Time 2020-10-04 11:33:03
Author Daigo Moriwaki
Log Message

Bump up revision

Content

#!/usr/bin/ruby

## Copyright (C) 2007-2012 Daigo Moriwaki <daigo at debian dot org>
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

require 'getoptlong'
require 'timeout'
require 'thread'
require 'webrick'
require 'socket'
require 'fileutils'

def write_pid_file(file)
  open(file, "w") do |fh|
    fh.puts "#{$$}"
  end
end

class ShogiClient
  CLIENT_NAME     = "web"
  CLIENT_PASSWORD = "web1235"

  def initialize(config = {})
    @@mutex = Mutex.new
    config[:host] ||= "localhost"
    config[:port] ||= 4081
    @socket = TCPSocket.open(config[:host], config[:port])
  end

  def login
    @socket.puts "LOGIN #{CLIENT_NAME} #{CLIENT_PASSWORD} x1"
    gets_ok do |s|
      /OK x1/ =~ s
    end
  end

  def logout
    @socket.puts "LOGOUT"
    gets_ok
  end

  def who
    @@mutex.synchronize do
      @socket.puts "%%WHO"
      gets_ok
    end
  end

  def list
    @@mutex.synchronize do
      @socket.puts "%%LIST"
      gets_ok
    end
  end

  private

  def gets_ok
    buf = ""
    timeout(5) do
      loop do
        s = @socket.gets
        break unless s
        buf << s
        if block_given?
          break if yield(s)
        else
          break if /OK$/ =~ s
        end
      end
    end
    return buf
  rescue Timeout::Error
    return buf
  end
end


class ListServlet < WEBrick::HTTPServlet::AbstractServlet
  def do_GET(req, res)
    res.body = $client.list
    res['Content-Type'] = "text/plain"
  end
end

class WhoServlet < WEBrick::HTTPServlet::AbstractServlet
  def do_GET(req, res)
    res.body = $client.who
    res['Content-Type'] = "text/plain"
  end
end

def usage
  $stderr.puts <<-EOF
USAGE: #{$0} [--daemon dir] [--port port] [--pid-file file]
  --daemon dir    Run as a daemon. Log files are put in dir
  --port port     Listening port for HTTP server (default 4080) 
  --pid-file file Write the process id to the file
  EOF
end

def parse_command_line
  options = Hash::new
  parser = GetoptLong.new( ["--daemon",   GetoptLong::REQUIRED_ARGUMENT],
                           ["--port",     GetoptLong::REQUIRED_ARGUMENT],
                           ["--pid-file", GetoptLong::REQUIRED_ARGUMENT])
  parser.quiet = true
  begin
    parser.each_option do |name, arg|
      name.sub!(/^--/, '')
      options[name] = arg.dup
    end
  rescue
    usage
    raise parser.error_message
  end

  dir = options["daemon"]
  dir = File.expand_path(dir) if dir
  if dir && ! File.exist?(dir)
    FileUtils.mkdir(dir)
  end
  options["dir"] = dir || File.dirname(__FILE__)
  options["port"] ||= 4080
  options["port"] = options["port"].to_i
  options["pid-file"] = File.expand_path(options["pid-file"]) if options["pid-file"]

  return options
end


def main
  $options = parse_command_line

  $client = ShogiClient.new
  $client.login

  http_log_file            = File.join($options["dir"], "shogi-server-httpd.log")
  http_access_log_file     = File.join($options["dir"], "shogi-server-access.log")
  http_config = {}
  http_config[:BindAddress] = "0.0.0.0"
  http_config[:Port]       = $options["port"]
  http_config[:ServerType] = WEBrick::Daemon if $options["daemon"]
  http_config[:Logger]     = WEBrick::Log.new(http_log_file)
  http_config[:AccessLog]  = 
          [[ WEBrick::Log.new(http_access_log_file), WEBrick::AccessLog::COMMON_LOG_FORMAT ]]
  if $options["pid-file"]
    http_config[:StartCallback] = Proc.new do
      write_pid_file($options["pid-file"])
    end
    http_config[:StopCallback] = Proc.new do
      FileUtils.rm($options["pid-file"], :force => true)
    end
  end

  
  
  server = WEBrick::HTTPServer.new(http_config)
  ["INT", "TERM"].each {|signal| trap(signal){ server.shutdown; $client.logout } }
  server.mount("/list", ListServlet)
  server.mount("/who",  WhoServlet)
  server.start
end

if __FILE__ == $0
  TCPSocket.do_not_reverse_lookup = true
  main
end
Show on old repository browser