fixed minor bugs in demo scripts and run_stem
[urisagit/Stem.git] / bin / run_stem
1 #!/usr/bin/perl -w
2
3 eval 'exec /usr/bin/perl -w -S $0 ${1+"$@"}'
4     if 0; # not running under some shell
5 #  File: bin/run_stem
6
7 #  This file is part of Stem.
8 #  Copyright (C) 1999, 2000, 2001 Stem Systems, Inc.
9
10 #  Stem is free software; you can redistribute it and/or modify
11 #  it under the terms of the GNU General Public License as published by
12 #  the Free Software Foundation; either version 2 of the License, or
13 #  (at your option) any later version.
14
15 #  Stem is distributed in the hope that it will be useful,
16 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
17 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 #  GNU General Public License for more details.
19
20 #  You should have received a copy of the GNU General Public License
21 #  along with Stem; if not, write to the Free Software
22 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
24 #  For a license to use the Stem under conditions other than those
25 #  described here, to purchase support for this software, or to purchase a
26 #  commercial warranty contract, please contact Stem Systems at:
27
28 #       Stem Systems, Inc.              781-643-7504
29 #       79 Everett St.                  info@stemsystems.com
30 #       Arlington, MA 02474
31 #       USA
32
33
34 eval { use lib 'blib/lib' } if -d 'blib/lib';
35
36 $Data::Dumper::Indent = 1 ;
37 $Data::Dumper::Purity = 1 ;
38 $Data::Dumper::Useqq = 1 ;
39
40 $| = 1 ;
41
42 #print "RUN STEM $0\n" ;
43
44 my @conf_args ;
45
46 # we set Stem's default environment before we load any Stem modules so
47 # they can use those values
48
49 use Stem::InstallConfig ;
50
51 BEGIN {
52         my $env_text ;
53         my $stem_lib_dir = $Stem::InstallConfig::Config{'conf_path'} ;
54
55         my $is_win32 = $^O =~ /Win32/i ;
56
57 # get the site env and home env files
58
59         my @env_files = "$stem_lib_dir/env" ;
60
61         unless ( $is_win32 ) {
62
63                 push @env_files, ( $ENV{HOME} ||
64                                    $ENV{LOGDIR} ||
65                                    (getpwuid($>))[7] ) . '/.stem_env' ;
66         }
67
68         foreach my $env_file ( @env_files ) {
69
70                 next unless -r $env_file ;
71
72 # shut up a dumb warning
73                 use vars '*ARGVOUT' ;
74                 $env_text .= 
75                         do { local( @ARGV, $/ ) = $env_file ; <> } ;
76         }
77
78
79 # set the starting %env from the files
80
81         %Stem::Vars::Env = $env_text =~ /^([^=]+)=(.+)$/mg if $env_text ;
82
83
84 # set the %Stem::Vars::Env from %ENV any %ENV name starting with STEM_
85 # is used. the STEM_ is deleted and the rest of the lower case name is
86 # used with the %ENV value
87
88         /^STEM_(\w+)/ and $Stem::Vars::Env{ lc $1 } = $ENV{ $_ } for keys %ENV ;
89
90 # set %Stem::Vars::Env from 'name=value' command line args
91 # all other args are assumed to be conf file names.
92 # we do this after we process %ENV so the command line args can override
93 # any shell environment values
94
95         while( @ARGV ) {
96
97                 my $arg = shift ;
98
99                 if ( $arg =~ /([^=]+)=(.*)/ ) {
100
101                         $Stem::Vars::Env{ $1 } = $2 ;
102                         next ;
103                 }
104
105                 push @conf_args, $arg ;
106         }
107
108 # set the default config search path. this will be changed by the install
109 # script.
110
111         $Stem::Vars::Env{ 'conf_path' } ||= 'conf:.' ;
112
113 # set the trace levels
114
115 #       $Stem::Vars::Env{ 'MainTraceStatus'    } ||= 1 ;
116 #       $Stem::Vars::Env{ 'MainTraceError'     } ||= 1 ;
117 #       $Stem::Vars::Env{ 'ProcTraceStatus'    } ||= 1 ;
118 #       $Stem::Vars::Env{ 'ProcTraceError'     } ||= 1 ;
119 #       $Stem::Vars::Env{ 'PortalTraceStatus'  } ||= 1 ;
120 #       $Stem::Vars::Env{ 'PortalTraceError'   } ||= 1 ;
121 #       $Stem::Vars::Env{ 'SockMsgTraceStatus' } ||= 1 ;
122 #       $Stem::Vars::Env{ 'SockMsgTraceError'  } ||= 1 ;
123 #       $Stem::Vars::Env{ 'ConfTraceStatus'    } ||= 1 ;
124 #       $Stem::Vars::Env{ 'ConfTraceError'     } ||= 1 ;
125 #       $Stem::Vars::Env{ 'LogTraceStatus'     } ||= 1 ;
126 #       $Stem::Vars::Env{ 'LogTraceError'      } ||= 1 ;
127 #       $Stem::Vars::Env{ 'CellTraceStatus'    } ||= 0 ;
128 #       $Stem::Vars::Env{ 'CronTraceStatus'    } ||= 1 ;
129 #       $Stem::Vars::Env{ 'CronTraceError'     } ||= 1 ;
130 #       $Stem::Vars::Env{ 'EventTraceStatus'   } ||= 0 ;
131 #       $Stem::Vars::Env{ 'EventTraceError'    } ||= 0 ;
132 #       $Stem::Vars::Env{ 'GatherTraceStatus'  } ||= 1 ;
133 #       $Stem::Vars::Env{ 'GatherTraceError'   } ||= 1 ;
134 #       $Stem::Vars::Env{ 'HubTraceStatus'     } ||= 1 ;
135 #       $Stem::Vars::Env{ 'HubTraceError'      } ||= 1 ;
136 #       $Stem::Vars::Env{ 'TailTraceStatus'    } ||= 1 ;
137 #       $Stem::Vars::Env{ 'TailTraceError'     } ||= 1 ;
138 #       $Stem::Vars::Env{ 'MsgTraceError'      } ||= 1 ;
139 #       $Stem::Vars::Env{ 'MsgTraceStatus'     } ||= 1 ;
140 #       $Stem::Vars::Env{ 'MsgTraceMsg'        } ||= 1 ;
141 #       $Stem::Vars::Env{ 'SwitchTraceStatus'  } ||= 1 ;
142 #       $Stem::Vars::Env{ 'SwitchTraceError'   } ||= 1 ;
143 #       $Stem::Vars::Env{ 'AsynchIOTraceStatus'} ||= 1 ;
144 #       $Stem::Vars::Env{ 'AsynchIOTraceError' } ||= 1 ;
145 #       $Stem::Vars::Env{ 'TtyMsgTraceStatus'  } ||= 1 ;
146 #       $Stem::Vars::Env{ 'TtyMsgTraceError'   } ||= 1 ;
147
148 }
149
150 # we load Stem after we process the command line args and %ENV so the
151 # modules can use those values
152
153 use Stem ;
154
155 use Stem::Trace 'log' => 'stem_status',
156                 'sub' => 'TraceStatus',
157                 'env' => 'MainTraceStatus' ;
158
159 my $prog_name = $0 ;
160
161 $prog_name =~ s|.+/|| ;
162
163 unless ( @conf_args ) {
164
165         $prog_name eq 'run_stem' &&
166                         die "run_stem must be passed a stem config file" ;
167
168         @conf_args = $prog_name ;
169 }
170
171 # always start with the site config file
172 # this defines site wide configuration settings that are internal
173 # to Stem
174
175 my $err = Stem::Conf::load_confs( 'site' ) ;
176
177 # ignore a missing site config
178
179 die $err if defined $err && $err !~ /Can't find config/ ;
180
181 $err = Stem::Conf::load_confs( @conf_args ) ;
182
183 TraceStatus "Stem startup" ;
184
185 TraceStatus $err if $err;
186
187 die $err if $err ;
188
189 ###############
190 # this should use Stem::Event
191 ###############
192 $SIG{ 'INT' } = sub {
193         TraceStatus "INT signal received" ;
194         Stem::Event::stop_loop()
195 } ;
196
197 Stem::Event::start_loop() ;
198
199 TraceStatus "Stem shutdown" ;
200
201 exit;
202
203 =head1 run_stem - Start up Stem and load configuration files
204
205 =head2 Synopsis
206
207         run_stem foo=bar stem_conf_file
208
209 This script is the way most Stem applications are started. It does
210 several important things so you don't have to create your own top
211 level scripts. It is not required to execute run_stem to use Stem but
212 it makes it much easier to get it going in most cases. The following
213 are the steps that 'run_stem' does when bringing up Stem.
214
215 =head2 * Load Stem Environment
216
217 Many Stem modules and cells look at the Stem environment for default
218 configuration values or global flags. This allows you to control how
219 many of the cells and modules behave when loaded and instantiated.  If
220 a Stem attribute in a specification has its 'env' name description
221 set, it will use that name (optionally prefixed with the cell's
222 registration name) as a key to lookup in the Stem Environement. If
223 found there, that value becomes is used and overrides the default and
224 any value set in a configuration file. This allows the user to
225 override default setting from the outside without modifying Stem
226 configuration files. See Stem::Class for more on this.  The Stem
227 environment is set from these sources in the following order:
228
229 =over 4
230
231 =item Global Site Environment File
232
233 'run_stem' initially looks for a file named 'env' in the first
234 configuration directory (set at install time) and loads it if
235 found. These site and user files both have a simple key=value format
236 with one entry per line.
237
238 =item User Environment File
239
240 'run_stem' then will look in your home directory (not supported on
241 windows) for a file named .stem_env and loads it if found.
242
243 =item Shell Environment
244
245 Any shell environment variable with the form 'STEM_*' will
246 have the 'STEM_' part deleted and the rest of its name
247 converted to lower case. That will become the key in the Stem
248 environment with the value set to the shell variable's value.
249
250 =item Command Line
251
252 Any command line arguments of the form key=value will be
253 parsed out and used to set a Stem environment variable.
254
255 =back
256
257 =head2 * Load Stem Core Modules
258
259         'run_stem' then loads all the core Stem modules with a use
260         Stem line.
261
262 =head2 * Load Configuration Files
263
264 Any arguments left in @ARGV are assumed to be Stem configuration
265 files. Typically there is only one configuration file but you can have
266 pass in as many as you want.  The config file arguments can have a
267 .stem suffix or no suffix. The configuration directory list is
268 searched in order for the file and it is loaded and all of its entries
269 are constructed.
270
271 You can override the default configuration directory list (set at
272 install time) by setting the 'conf_path' Stem environment variable
273 from the shell environment or on the 'run_stem' command line. The
274 following are equivilent:
275
276         export STEM_CONF_PATH=/etc/stem/conf:/home/foo/.stem
277         run_stem bar
278
279         run_stem conf_path=/etc/stem/conf:/home/foo/.stem bar
280
281 =head2 * Start Event Loop
282
283 The final operation 'run_stem' does is start the main event
284 loop. If no events were created by the loaded configuration
285 files, this will fail and 'run_stem will exit immediately. If
286 all the created events eventually get canceled, the event loop
287 will exit and 'run_stem' will exit too.
288
289 =cut