Created
July 7, 2009 16:54
-
-
Save rsayers/142211 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/bin/ruby | |
require 'socket' | |
class File | |
def self.binary?(name) | |
myStat = stat(name) | |
return false unless myStat.file? | |
open(name) { |file| | |
blk = file.read(myStat.blksize) | |
return blk.size == 0 || | |
blk.count("^ -~", "^\r\n") / blk.size > 0.3 || | |
blk.count("\x00") > 0 | |
} | |
end | |
end | |
class GopherServer | |
def initialize(config='/etc/gopherd.conf') | |
tmp={} | |
File.open(config).readlines.each do |l| | |
k,v = l.chomp.split('=') if l !~ /^#|^\n/ | |
tmp[k.strip]=v.strip if k&&v | |
end | |
@port = (tmp['port'] || 70).to_i | |
@dir = tmp['gopherdocs'] | |
@host = tmp['hostname'] || `hostname` | |
@routes=[] | |
@client_addr='' | |
@logfile=tmp['logfile'] | |
end | |
def log(msg) | |
File.open(@logfile,"a").sprintf("%s - - [%s] \"%s\"",@client_addr,time,msg) | |
end | |
def defroute(key, function) | |
@routes << {key=>function} | |
end | |
def handle_request(url) | |
url,param = url.split('?') | |
path = @dir + ( url || "" ) | |
@routes.each do |r| | |
k=r.keys.first | |
if k.class==String && k==url then | |
return r[k].call(param) | |
elsif k.class == Regexp && url=~k then | |
return r[k].call(param,url.match(k)) | |
end | |
end | |
if url =~ /^URL\:/ then | |
return weburl(url.sub('URL:','')) | |
end | |
notfound(url) if !File.exist?(path) | |
result = case gettype(path) | |
when "1" then readdir(url) | |
else display(path,param) | |
end | |
result | |
end | |
def display(path,param='') | |
if File.executable?(path) then | |
%x{ #{path} #{param} } | |
else | |
File.open(path).read | |
end | |
end | |
def weburl(url) | |
"<html><body>Leaving gopherspace, we will miss you :(<br><a href='#{url}'>Click here to visit the site</a>" | |
end | |
def readdir(path) | |
dir = "#{@dir}/#{path}" | |
lines=[] | |
if File.exist?(dir+'/gophermap') then | |
File.open(dir+'/gophermap').readlines.map { |line| | |
line.chop! | |
iteminfo = line.split(/\t/) | |
if iteminfo.length < 2 then | |
lines << "i#{line}\t\terror.host\t1" | |
else | |
#iteminfo[1] = "/#{path}/"+iteminfo[1] if iteminfo[1][0] != "/" || iteminfo[1] !~ /^URL/ | |
iteminfo[2] = @host if !iteminfo[2] | |
iteminfo[3] = @port if !iteminfo[3] | |
lines << iteminfo.join("\t") | |
end | |
} | |
else | |
lines = [] | |
Dir.entries(dir).each do |item| | |
lines << "#{gettype(@dir+'/'+item)}#{item}\t/#{item}\t#{@host}\t70" if !['.','..'].include?(item) | |
end | |
end | |
lines.join("\r\n") | |
end | |
def notfound(url) | |
"3 '#{url}' doesn't exist!\terror.host1\yi This resource cannot be located.error.host1\n." | |
end | |
def gettype(file) | |
#if anyone sees cameron, don't tell him I stole his code | |
File.directory?(file) ? "1" : | |
file =~ /\.txt$/i ? "0" : | |
file =~ /\.gif$/i ? "g" : | |
file =~ /\.gz$/i ? "9" : | |
file =~ /\.zip$/i ? "5" : | |
file =~ /\.jpe?g$/i ? "I" : | |
file =~ /\.png$/i ? "p" : | |
file =~ /\.pdf$/i ? "d" : | |
file =~ /\.css$/i ? "c" : | |
file =~ /\.xml$/i ? "x" : | |
file =~ /\.html?$/i ? "h" : | |
file =~ /\.hqx$/i ? "4" : | |
File.binary?(file) ? "9" : | |
"0"; | |
end | |
def socket_listen | |
server = TCPServer.new('localhost', @port) | |
while (session = server.accept) | |
@client_addr = session.getpeeraddr.last | |
session.puts handle_request(session.readline.chop) | |
session.close | |
end | |
end | |
def stdin_listen | |
@client_addr = ENV['REMOTE_HOST'] | |
print handle_request(STDIN.readline.chop) | |
end | |
end | |
s=GopherServer.new | |
s.stdin_listen |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment