<!DOCTYPE html> <html>
<head> <link rel="stylesheet" href="index.css" type="text/css" media="screen" /> <script src="jquery-1.6.min.js" type="text/javascript"></script> <script src="../dist/jquery.syntax.js" type="text/javascript"></script> <script src="../dist/jquery.syntax.cache.js" type="text/javascript"></script> <script type="text/javascript"> $(function() { jQuery.syntax(); }); </script> </head> <body> <h1>Syntax: Ruby</h1> <h2>Ruby Script #1</h2> <pre><code class="syntax brush-ruby">#!/usr/bin/env ruby
# Copyright © 2009 Samuel Williams. Released under the GNU GPLv3. # # 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 3 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, see <www.gnu.org/licenses/>.
require 'rubygems'
require 'rexec' require 'rexec/daemon'
require 'rubygems' require 'rubydns'
# To run this command, use the standard daemon syntax as root # ./daemon2.rb start
# You should be able to see that the server has dropped priviledges # # ps aux | grep daemon2.rb # daemon 16555 0.4 0.0 81392 2024 ?? S 3:35am 0:00.28 ruby ../test/daemon2.rb start
# Test using the following command # dig @localhost test.mydomain.org
# You might need to change the user name "daemon". This can be a user name or a user id. RUN_AS = "daemon"
# UDP Socket does per packet reverse lookups unless this is set. UDPSocket.do_not_reverse_lookup = true
# We need to be root in order to bind to privileged port if RExec.current_user != "root"
$stderr.puts "Sorry, this command needs to be run as root!" exit 1
end
# The Daemon itself class Server < RExec::Daemon::Base
@@var_directory = File.dirname(__FILE__) def self.run # Bind to port 53 (UDP) socket = UDPSocket.new socket.bind("0.0.0.0", 53) # Drop priviledges RExec.change_user(RUN_AS) # Don't buffer output (for debug purposes) $stderr.sync = true # Use upstream DNS for name resolution (These ones are Orcon DNS in NZ) $R = Resolv::DNS.new(:nameserver => ["60.234.1.1", "60.234.2.2"]) # Start the RubyDNS server RubyDNS::run_server(:listen => [socket]) do match("test.mydomain.org", :A) do |transaction| transaction.respond!("10.0.0.80") end # Default DNS handler otherwise do |transaction| logger.info "Passthrough: #{transaction}" transaction.passthrough!($R) end end end
end
# RExec daemon runner Server.daemonize</code></pre>
<h2>Ruby Script #2</h2> <pre><code class="syntax brush-ruby">#!/usr/bin/env ruby
# Simple Operator Expression Parser
require 'set'
DEBUG = false
class Array
def map_to(with) r = {} each_with_index { |v,i| r[v] = with[i] } return r end
end
module Expression
class Context def initialize(operators, values) @values = values @operators = operators end def value_of (key) @values[key] end def call (op, args) @operators.call(op, args) end end class Constant def initialize(value) @value = value end def evaluate (ctx) return @value end end class Identifier def initialize(name) @name = name end def evaluate (ctx) ctx.value_of(@name) end end class Operator def initialize(name, args = []) @name = name @args = args end def name @name end def evaluate (ctx) ctx.call(@name, @args.collect { |a| a.evaluate(ctx) }) end def args @args end end class Brackets def initialize(node) @node = node end def evaluate (ctx) @node.evaluate(ctx) end end class Parser def initialize(ops, expr) @identifiers = [] @operators = ops # Tokens and expressions line up @expressions = [] @tokens = [] @top = nil parse(expr) end def evaluate (ctx) @expressions.collect do |expr| expr != nil ? expr.evaluate(ctx) : nil end end def identifiers @identifiers end def tokens @tokens end private def parse(expr) symbols = @operators.keys + ["(", ")"] tokenizer = Regexp.union(Regexp.union(*symbols), /[A-Z]+/) @tokens = expr.scan(tokenizer) @expressions = [nil] * @tokens.size @identifiers = Set.new(expr.scan(/[A-Z]+/)) @top, i = process_expression if DEBUG puts "Processed #{i} tokens..." puts "Tokens: " + @tokens.join(" ") puts @top.inspect puts @expressions.inspect end end def process_expression(i = 0) ast = [] ops = {} while i < @tokens.size t = @tokens[i] if t == "(" result, i = process_expression(i+1) ast += result elsif t == ")" break else result = process_token(i) ast << result end if result.class == Operator ops[result.name] ||= [] # Store the index ops[result.name] << (ast.size - 1) end i += 1 end #puts ast.inspect # We need to sort the list of operators now # [c, infix, prefix, c] @operators.order.each do |name| op_kind = @operators.kind(name) next unless ops[name] ops[name].each do |loc| op = ast[loc] if op_kind == :prefix rhs = find_subexpression(ast, loc, RHS_SEARCH) op.args << ast[rhs] ast[rhs] = nil elsif op_kind == :infix lhs = find_subexpression(ast, loc, LHS_SEARCH) rhs = find_subexpression(ast, loc, RHS_SEARCH) op.args << ast[lhs] op.args << ast[rhs] ast[lhs] = ast[rhs] = nil elsif op_kind == :postfix lhs = find_subexpression(ast, loc, LHS_SEARCH) op.args << ast[lhs] ast[rhs] = nil end end end return [ast.uniq, i] end RHS_SEARCH = 1 LHS_SEARCH = -1 def find_subexpression(ast, loc, dir) while loc >= 0 && loc < ast.size loc += dir return loc if ast[loc] != nil end return nil end def process_token(i) t = @tokens[i] if @operators.key? t tok = Operator.new(t) elsif t.match /[A-Z]+/ tok = Identifier.new(t) else tok = Constant.new(t) end @expressions[i] = tok return tok end end TYPE = 0 FUNC = 1 class Operators def initialize @operators = {} @order = [] end def add(sym, kind, &block) @operators[sym] = [kind, block] @order << sym end def order @order end def keys @operators.keys end def key? k @operators.key? k end def kind k @operators[k][0] end def call(k, args) @operators[k][1].call(*args) end end
end</code></pre>
</body>
</html>