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