/[meteor]/googlecode.com/svn/trunk/Meteor/Config.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /googlecode.com/svn/trunk/Meteor/Config.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 48 - (hide annotations)
Mon Feb 4 22:23:52 2008 UTC (11 years, 10 months ago) by knops.gerd
File size: 11364 byte(s)
• Added simple UDP broadcast abilities

1 knops.gerd 11 #!/usr/bin/perl -w
2     ###############################################################################
3     # Meteor
4     # An HTTP server for the 2.0 web
5     # Copyright (c) 2006 contributing authors
6     #
7     # Subscriber.pm
8     #
9     # Description:
10     # Meteor Configuration handling.
11     #
12     # Main program should call Meteor::Config::setCommandLineParameters(@ARGV),.
13     # Afterwards anybody can access $::CONF{<parameterName>}, where
14     # <parameterName> is any valid parameter (except 'Help') listed in the
15     # @DEFAULTS array below.
16     #
17     ###############################################################################
18     #
19     # This program is free software; you can redistribute it and/or modify it
20     # under the terms of the GNU General Public License as published by the Free
21     # Software Foundation; either version 2 of the License, or (at your option)
22     # any later version.
23     #
24     # This program is distributed in the hope that it will be useful, but WITHOUT
25     # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
26     # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
27     # more details.
28     #
29     # You should have received a copy of the GNU General Public License along
30     # with this program; if not, write to the Free Software Foundation, Inc.,
31     # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32     #
33     # For more information visit www.meteorserver.org
34     #
35     ###############################################################################
36    
37     package Meteor::Config;
38     ###############################################################################
39     # Configuration
40     ###############################################################################
41    
42     use strict;
43    
44     our @DEFAULTS=(
45     'Configuration file location on disk (if any)',
46     ConfigFileLocation => '/etc/meteord.conf',
47    
48     'IP address for controller server (leave empty for all local addresses)',
49     ControllerIP => '',
50    
51     'Port number for controller connections',
52     ControllerPort => 4671,
53    
54     'Controller Shutdown message, sent when the controller server shuts down (leave empty for no message)',
55     ControllerShutdownMsg => '',
56    
57     'Debug Flag, when set daemon will run in foreground and emit debug messages',
58     Debug => 0,
59    
60     'Name of index file to serve when a directory is requested from the static file web server',
61     DirectoryIndex => 'index.html',
62    
63     'Header template, ~server~, ~servertime~ and ~status~ will be replaced by the appropriate values. **NOTE**: It is possible to define more than one HeaderTemplate by appending a number at the end, for example *HeaderTemplate42*. Clients can request a specific header to be used by adding the parameter template=<number> to their GET request. If *HeaderTemplate<number>* is not found, the system will use the default HeaderTemplate (no number)',
64 andrew.betts 26 HeaderTemplate => 'HTTP/1.1 ~status~\r\nServer: ~server~\r\nContent-Type: text/html; charset=utf-8\r\nPragma: no-cache\r\nCache-Control: no-cache, no-store, must-revalidate\r\nExpires: Thu, 1 Jan 1970 00:00:00 GMT\r\n\r\n<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8">\r\n<meta http-equiv="Cache-Control" content="no-store">\r\n<meta http-equiv="Cache-Control" content="no-cache">\r\n<meta http-equiv="Pragma" content="no-cache">\r\n<meta http-equiv="Expires" content="Thu, 1 Jan 1970 00:00:00 GMT">\r\n<script type="text/javascript">\r\nwindow.onError = null;\r\nvar domainparts = document.domain.split(".");\r\ndocument.domain = domainparts[domainparts.length-2]+"."+domainparts[domainparts.length-1];\r\nparent.Meteor.register(this);\r\n</script>\r\n</head>\r\n<body onload="try { parent.Meteor.reset(this) } catch (e) {}">\r\n',
65 knops.gerd 11
66 knops.gerd 45 'Template for each line in channelinfo',
67    
68 knops.gerd 46 ChannelInfoTemplate => '~name~ ~messageCount~ ~lastMsgID~\r\n',
69 knops.gerd 45
70 knops.gerd 11 'Print out this help message',
71     Help => '',
72    
73     'Maximum age of a message in seconds',
74     MaxMessageAge => 7200,
75    
76     'Maximum number of messages to send to a subscriber before forcing their connection to close. Use 0 to disable',
77     MaxMessages => 0,
78    
79     'Maximum number of stored messages per channel',
80     MaxMessagesPerChannel => 250,
81    
82     'Maximum duration in seconds for a subscriber connection to exist before forcing a it to close. Note that the server checks for expired connections in 60 second intervals, so small changes to this value will not have much of an effect. Use 0 to disable',
83     MaxTime => 0,
84    
85 andrew.betts 20 'Message template, ~text~, ~id~, ~channel~ and ~timestamp~ will be replaced by the appropriate values',
86     MessageTemplate => '<script>p(~id~,"~channel~","~text~");</script>\r\n',
87 knops.gerd 11
88     'Interval at which PingMessage is sent to all persistent and identified subscriber connections (ie those including id=someuniqueidentifier in their request, and not specifying persist=0). Must be at least 3 if set higher than zero. Set to zero to disable.',
89     PingInterval => 5,
90    
91 knops.gerd 45 'Persistence of a connection. Note: some modes have this hardcoded!',
92    
93     Persist => 0,
94    
95 knops.gerd 11 'Message to be sent to all persistent and identified subscriber connections (see above) every PingInterval seconds',
96     PingMessage => '<script>p(-1,"");</script>\r\n',
97    
98     'IP address for subscriber server (leave empty for all local addresses)',
99     SubscriberIP => '',
100    
101     'Port number for subscriber connections',
102     SubscriberPort => 4670,
103    
104     'Subscriber Shutdown message, sent when the subscriber server shuts down (leave empty for no message)',
105     SubscriberShutdownMsg => '<script>eof();</script>\r\n',
106    
107     'An absolute filesystem path, to be used as the document root for Meteor\'s static file web server. If left empty, no documents will be served.',
108     SubscriberDocumentRoot => '/usr/local/meteor/public_html',
109    
110     'Since Meteor is capable of serving static pages from a document root as well as streaming events to subscribers, this paramter is used to specify the URI at which the event server can be reached. If set to the root, Meteor will lose the ability to serve static pages.',
111     SubscriberDynamicPageAddress => '/push',
112    
113     'The syslog facility to use',
114     SyslogFacility => 'daemon',
115 knops.gerd 48
116     'IP address for udp server (leave empty for all local addresses)',
117     UDPIP => '',
118    
119     'Port number for udp connections, set to 0 to disable',
120     UDPPort => 0,
121    
122 knops.gerd 11 );
123    
124     our %ConfigFileData=();
125     our %CommandLine=();
126     our %Defaults=();
127     our %ExtraKeys=();
128 knops.gerd 45 our %Modes=();
129 knops.gerd 11
130     for(my $i=0;$i<scalar(@DEFAULTS);$i+=3)
131     {
132     $Defaults{$DEFAULTS[$i+1]}=$DEFAULTS[$i+2];
133     }
134    
135     ###############################################################################
136     # Class methods
137     ###############################################################################
138     sub updateConfig {
139     my $class=shift;
140    
141     %::CONF=();
142    
143     my $debug=$class->valueForKey('Debug');
144    
145     print STDERR '-'x79 ."\nParamters:\nSource \tName and Value\n".'-'x79 ."\n" if($debug);
146    
147     my @keys=();
148    
149     for(my $i=0;$i<scalar(@DEFAULTS);$i+=3)
150     {
151     next if($DEFAULTS[$i+1] eq 'Help');
152     push(@keys,$DEFAULTS[$i+1]);
153     }
154     push(@keys,keys %ExtraKeys);
155    
156 knops.gerd 45
157     foreach my $mode ('',keys %Modes)
158     {
159     foreach my $baseKey (@keys)
160 knops.gerd 11 {
161 knops.gerd 45 my $foundValue=0;
162     my $key=$baseKey.$mode;
163    
164     if(exists($CommandLine{$key}))
165 knops.gerd 11 {
166 knops.gerd 45 print STDERR "CmdLine" if($debug);
167     $::CONF{$key}=$CommandLine{$key};
168     $foundValue=1;
169 knops.gerd 11 }
170 knops.gerd 45 elsif(exists($ConfigFileData{$key}))
171 knops.gerd 11 {
172 knops.gerd 45 print STDERR "CnfFile" if($debug);
173     $::CONF{$key}=$ConfigFileData{$key};
174     $foundValue=1;
175 knops.gerd 11 }
176 knops.gerd 45 elsif(exists($Defaults{$key}))
177 knops.gerd 11 {
178 knops.gerd 45 print STDERR "Default" if($debug);
179     $::CONF{$key}=$Defaults{$key};
180     $foundValue=1;
181 knops.gerd 11 }
182 knops.gerd 45
183     next unless($foundValue);
184    
185     print STDERR "\t$key\t$::CONF{$key}\n" if($debug);
186    
187     # Take care of escapes
188     $::CONF{$key}=~s/\\(.)/
189     if($1 eq 'r')
190     {
191     "\r";
192     }
193     elsif($1 eq 'n')
194     {
195     "\n";
196     }
197     elsif($1 eq 's')
198     {
199     ' ';
200     }
201     elsif($1 eq 't')
202     {
203     "\t";
204     }
205     else
206     {
207     $1;
208     }
209     /gex;
210     }
211 knops.gerd 11 }
212     print STDERR '-'x79 ."\n" if($debug);
213     }
214    
215     sub valueForKey {
216     my $class=shift;
217     my $key=shift;
218    
219     return $CommandLine{$key} if(exists($CommandLine{$key}));
220     return $ConfigFileData{$key} if(exists($ConfigFileData{$key}));
221    
222     $Defaults{$key};
223     }
224    
225     sub setCommandLineParameters {
226     my $class=shift;
227    
228 knops.gerd 42 #
229     # Quick check if we should show the version, if so ignore everything else
230     # Accept -v, -version, and everything in between
231     #
232     foreach my $p (@_)
233     {
234     if(index($p,'-v')==0 && index('-version',$p)==0)
235     {
236     print "$::PGM $::VERSION\n";
237     exit(0);
238     }
239     }
240    
241 knops.gerd 11 while(my $cnt=scalar(@_))
242     {
243     my $k=shift(@_);
244     &usage("'$k' invalid") unless($k=~s/^\-(?=.+)//);
245    
246     $k='Debug' if($k eq 'd');
247    
248 knops.gerd 45 my $mode='';
249    
250     if($k=~s/(\..+)$//)
251     {
252     $mode=$1;
253     $Modes{$mode}=1;
254     }
255    
256 knops.gerd 11 my $key=undef;
257     my $kl=length($k);
258     my $kOrig=$k;
259     $k=lc($k);
260    
261     for(my $i=0;$i<scalar(@DEFAULTS);$i+=3)
262     {
263     my $p=$DEFAULTS[$i+1];
264     my $pl=length($p);
265    
266     next if($kl>$pl);
267    
268     #print "$kl $pl $k $p\n";
269    
270     if($kl==$pl && $k eq lc($p))
271     {
272     $key=$p;
273     last;
274     }
275    
276     my $ps=lc(substr($p,0,$kl));
277    
278     if($k eq $ps)
279     {
280     if(defined($key))
281     {
282     &usage("Ambigous parameter name '$kOrig'");
283     }
284     $key=$p;
285     }
286     }
287    
288     if($k=~/^HeaderTemplate(\d+)$/i)
289     {
290     $key="HeaderTemplate$1";
291     $ExtraKeys{$key}=1;
292     }
293    
294     &usage("Unknown parameter name '$kOrig'") unless(defined($key));
295    
296     &usage() if($key eq 'Help');
297    
298     #print "$kOrig: $key\n";
299    
300 knops.gerd 45 $CommandLine{"$key$mode"}=1;
301 knops.gerd 11
302     if($cnt>1 && $_[0]!~/^\-(?!\-)/)
303     {
304     my $param=shift;
305     $param=~s/^\-\-/\-/;
306 knops.gerd 45 $CommandLine{"$key$mode"}=$param;
307 knops.gerd 11 }
308     }
309    
310     $class->readConfig();
311    
312     $class->updateConfig();
313     }
314    
315     sub readConfig {
316     my $class=shift;
317    
318     %ConfigFileData=();
319    
320     my $path=$class->valueForKey('ConfigFileLocation');
321     return unless(defined($path) && -f $path);
322    
323 knops.gerd 45 my $mode='';
324    
325 knops.gerd 11 open(CONFIG,"$path") or &usage("Config file '$path' for read: $!\n");
326     while(<CONFIG>)
327     {
328     next if(/^\s*#/);
329     next if(/^\s*$/);
330    
331     s/[\r\n]*$//;
332    
333 knops.gerd 45 if(/^\s*\[\s*([^\]\s]+)\s*\]\s*$/)
334     {
335     $Modes{".$1"}=1;
336     next;
337     }
338    
339 knops.gerd 11 unless(/^(\S+)\s*(.*)/)
340     {
341     &usage("Invalid configuration file parameter line '$_'");
342     }
343    
344     my $key=$1;
345     my $val=$2;
346     $val='' unless(defined($val));
347    
348     if($key=~/^HeaderTemplate\d+$/)
349     {
350     $ExtraKeys{$key}=1;
351     }
352     else
353     {
354     unless(exists($Defaults{$key}))
355     {
356 knops.gerd 45 &usage("Unknown configuration file parameter name '$key$mode'");
357 knops.gerd 11 }
358     if($key eq 'ConfigFileLocation')
359     {
360     &usage("'ConfigFileLocation' parameter not allowed in configuration file!");
361     }
362     }
363    
364     $val=~s/^--/-/;
365    
366 knops.gerd 45 $ConfigFileData{"$key$mode"}=$val;
367 knops.gerd 11 }
368     close(CONFIG);
369     }
370    
371     sub usage {
372     my $msg=shift || '';
373    
374     if($msg) {
375     print STDERR <<"EOT";
376     $msg;
377     For further help type $::PGM -help
378     or consult docs at http://www.meteorserver.org/
379     EOT
380    
381     } else {
382    
383    
384     print STDERR <<"EOT";
385    
386 knops.gerd 45 Meteor server v$::VERSION (release date: $::RELEASE_DATE)
387 knops.gerd 11 Licensed under the terms of the GNU General Public Licence (2.0)
388    
389     Usage:
390    
391     $::PGM [-parameter [value] [-parameter [value]...]]
392    
393     Accepted command-line parameters:
394    
395     EOT
396    
397     for(my $i=0;$i<scalar(@DEFAULTS);$i+=3)
398     {
399     print STDERR "-$DEFAULTS[$i+1]\n$DEFAULTS[$i].\n\n";
400     }
401    
402     print STDERR <<"EOT";
403    
404     Any of the parameters listed above can also be configured in the
405     configuration file. The default location for this file is:
406    
407     $Defaults{'ConfigFileLocation'}
408    
409     For more information and complete documentation, see the Meteor
410     website at http://www.meteorserver.org/
411     EOT
412    
413     }
414     exit(1);
415     }
416    
417     1;
418 andrew.betts 3 ############################################################################EOF

  ViewVC Help
Powered by ViewVC 1.1.26