lib/ezmlm/listdaemon.rb
changeset 6 66beb495a861
equal deleted inserted replaced
5:804e1c2b9a40 6:66beb495a861
       
     1 #!/usr/bin/ruby
       
     2 #
       
     3 # A DRb interface to one or more ezmlm-idx mailing lists.
       
     4 #
       
     5 # == Version
       
     6 #
       
     7 #  $Id$
       
     8 #
       
     9 # == Authors
       
    10 #
       
    11 # * Michael Granger <mgranger@laika.com>
       
    12 # * Jeremiah Jordan <jjordan@laika.com>
       
    13 #
       
    14 # :include: LICENSE
       
    15 # 
       
    16 #---
       
    17 #
       
    18 # Please see the file LICENSE in the base directory for licensing details.
       
    19 #
       
    20 
       
    21 require 'pathname'
       
    22 require 'ezmlm'
       
    23 require 'ezmlm/list'
       
    24 require 'drb'
       
    25 require 'ostruct'
       
    26 
       
    27 
       
    28 ### A DRb interface to one or more ezmlm-idx mailing lists
       
    29 class Ezmlm::ListDaemon
       
    30 	
       
    31 	# The default port to listen on
       
    32 	DEFAULT_PORT = 32315
       
    33 	
       
    34 	# The default address to bind to
       
    35 	DEFAULT_ADDRESS = '127.0.0.1'
       
    36 	
       
    37 	
       
    38 	### The interface that is presented to DRb
       
    39 	class Service
       
    40 		include Enumerable
       
    41 		
       
    42 		### Create a new service endpoint for the specified +listsdir+, which is a directory
       
    43 		### which contains ezmlm-idx list directories.
       
    44 		def initialize( listsdir )
       
    45 			listsdir = Pathname.new( listsdir )
       
    46 			@listsdir = listsdir
       
    47 		end
       
    48 
       
    49 
       
    50 		######
       
    51 		public
       
    52 		######
       
    53 
       
    54 		# The directory which contains the list directories that should be served.
       
    55 		attr_reader :listsdir
       
    56 		
       
    57 		
       
    58 		### Create a new Ezmlm::List object for the list directory with the specified +name+.
       
    59 		def get_list( name )
       
    60 			name = validate_listdir_name( name )
       
    61 			return Ezmlm::List.new( self.listsdir + name )
       
    62 		end
       
    63 
       
    64 
       
    65 		### Iterate over each current list in the Service's listsdir, yielding an Ezmlm::List object
       
    66 		### for each one.
       
    67 		def each_list( &block ) # :yields: list_object
       
    68 			Ezmlm.each_list( self.listsdir, &block )
       
    69 		end
       
    70 		alias_method :each, :each_list
       
    71 		
       
    72 
       
    73 		#######
       
    74 		private
       
    75 		#######
       
    76 
       
    77 		VALID_LISTNAME_PATTERN = /^[a-z0-9.-]+$/i
       
    78 
       
    79 		### Ensure that the given +name+ is a valid list name, raising an exception if not. Returns
       
    80 		### an untainted copy of +name+.
       
    81 		def validate_listdir_name( name )
       
    82 			unless match = VALID_LISTNAME_PATTERN.match( name )
       
    83 				raise ArgumentError, "invalid list name %p" % [ name ]
       
    84 			end
       
    85 			
       
    86 			return match[0].untaint
       
    87 		end
       
    88 		
       
    89 	end # class Service
       
    90 	
       
    91 	
       
    92 
       
    93 	### Return an OpenStruct that contains the default options
       
    94 	def self::default_options
       
    95 		opts = OpenStruct.new
       
    96 
       
    97 		opts.bind_addr  = DEFAULT_ADDRESS
       
    98 		opts.bind_port  = DEFAULT_PORT
       
    99 		opts.debugmode  = false
       
   100 		opts.helpmode   = false
       
   101 		opts.foreground = false
       
   102 
       
   103 		return opts
       
   104 	end
       
   105 	
       
   106 	
       
   107 	#################################################################
       
   108 	###	I N S T A N C E   M E T H O D S
       
   109 	#################################################################
       
   110 
       
   111 	### Create a new Ezmlm::ListDaemon that will serve objects for the list directories
       
   112 	### contained in +listsdir+. The +options+ argument, if given, is an object (such as the one
       
   113 	### returned from ::default_options) that contains values for the following methods:
       
   114 	### 
       
   115 	### bind_addr::
       
   116 	###   The address to bind to. Defaults to DEFAULT_ADDRESS.
       
   117 	### bind_port::
       
   118 	###   The port to listen on. Defaults to DEFAULT_PORT.
       
   119 	### debugmode:: 
       
   120 	###   Whether to run in debugging mode, which causes the daemon to run in the foreground
       
   121 	###   and send any output to STDERR. Defaults to +false+.
       
   122 	### foreground::
       
   123 	###   Don't go into the background.
       
   124 	def initialize( listsdir, options=nil )
       
   125 		@service = Service.new( listsdir )
       
   126 		@options = options || self.class.default_options
       
   127 	end
       
   128 
       
   129 
       
   130 	######
       
   131 	public
       
   132 	######
       
   133 
       
   134 	# The daemon's configuration options
       
   135 	attr_reader :options
       
   136 	
       
   137 	# The Ezmlm::ListDaemon::Service object that serves as the DRb interface
       
   138 	attr_reader :service
       
   139 
       
   140 
       
   141 	### Daemonize unless configured otherwise, start the DRb service and return the listening 
       
   142 	### Thread object
       
   143 	def start
       
   144 		uri = "druby://%s:%d" % [ self.options.bind_addr, self.options.bind_port ]
       
   145 		DRb.start_service( uri, @service )
       
   146 		
       
   147 		return DRb.thread
       
   148 	end
       
   149 	
       
   150 
       
   151 end # class Ezmlm::ListDaemon
       
   152 
       
   153 # vim: set nosta noet ts=4 sw=4: