3 # Copyright (c) 1996-2002 Jesse Vincent <jesse@bestpractical.com>
5 # (Except where explictly superceded by other copyright notices)
7 # This work is made available to you under the terms of Version 2 of
8 # the GNU General Public License. A copy of that license should have
9 # been provided with this software, but in any event can be snarfed
12 # This work is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 # General Public License for more details.
18 # Unless otherwise specified, all modifications, corrections or
19 # extensions to this work which alter its source code become the
20 # property of Best Practical Solutions, LLC when submitted for
21 # inclusion in the work.
33 use vars qw($VERSION $System $SystemUser $Nobody $Handle $Logger
45 $MasonLocalComponentRoot
51 $CORE_CONFIG_FILE = "/opt/rt3/etc/RT_Config.pm";
52 $SITE_CONFIG_FILE = "/opt/rt3/etc/RT_SiteConfig.pm";
54 $BasePath = '/opt/rt3';
56 $EtcPath = '/opt/rt3/etc';
57 $VarPath = '/opt/rt3/var';
58 $LocalPath = '/opt/rt3/local';
59 $LocalEtcPath = '/opt/rt3/local/etc';
60 $LocalLexiconPath = '/opt/rt3/local/po';
62 # $MasonComponentRoot is where your rt instance keeps its mason html files
64 $MasonComponentRoot = '/opt/rt3/share/html';
66 # $MasonLocalComponentRoot is where your rt instance keeps its site-local
69 $MasonLocalComponentRoot = '/opt/rt3/local/html';
71 # $MasonDataDir Where mason keeps its datafiles
73 $MasonDataDir = '/opt/rt3/var/mason_data';
75 # RT needs to put session data (for preserving state between connections
76 # via the web interface)
77 $MasonSessionDir = '/opt/rt3/var/session_data';
87 A fully featured request tracker package
96 Load RT's config file. First, go after the core config file.
97 After that, try to load the vendor config.
98 After that, go after the site config.
103 local *Set = sub { $_[0] = $_[1] unless defined $_[0] };
104 if ( -f "$SITE_CONFIG_FILE" ) {
105 require $SITE_CONFIG_FILE
106 || die ("Couldn't load RT config file '$SITE_CONFIG_FILE'\n$@");
108 require $CORE_CONFIG_FILE
109 || die ("Couldn't load RT config file '$CORE_CONFIG_FILE'\n$@");
115 Conenct to the database, set up logging.
121 #Get a database connection
122 unless ($Handle && $Handle->dbh->ping) {
123 $Handle = RT::Handle->new();
127 #RT's system user is a genuine database user. its id lives here
128 $SystemUser = new RT::CurrentUser();
129 $SystemUser->LoadByName('RT_System');
131 #RT's "nobody user" is a genuine database user. its ID lives here.
132 $Nobody = new RT::CurrentUser();
133 $Nobody->LoadByName('Nobody');
135 $System = RT::System->new();
142 Create the RT::Logger object.
147 # We have to set the record seperator ($, man perlvar)
148 # or Log::Dispatch starts getting
149 # really pissy, as some other module we use unsets it.
152 use Log::Dispatch 1.6;
154 unless ($RT::Logger) {
156 $RT::Logger=Log::Dispatch->new();
158 if ($RT::LogToFile) {
160 unless (-d $RT::LogDir && -w $RT::LogDir) {
161 # localizing here would be hard when we don't have a current user yet
162 # die $self->loc("Log directory [_1] not found or couldn't be written.\n RT can't run.", $RT::LogDir);
163 die ("Log directory $RT::LogDir not found or couldn't be written.\n RT can't run.");
167 if ($RT::LogToFileNamed =~ m![/\\]!) {
168 # looks like an absolute path.
169 $filename = $RT::LogToFileNamed;
172 $filename = "$RT::LogDir/$RT::LogToFileNamed";
174 require Log::Dispatch::File;
177 $RT::Logger->add(Log::Dispatch::File->new
179 min_level=> $RT::LogToFile,
180 filename=> $filename,
182 callbacks => sub { my %p = @_;
183 my ($package, $filename, $line) = caller(5);
184 return "[".gmtime(time)."] [".$p{level}."]: $p{message} ($filename:$line)\n"}
190 if ($RT::LogToScreen) {
191 require Log::Dispatch::Screen;
192 $RT::Logger->add(Log::Dispatch::Screen->new
194 min_level => $RT::LogToScreen,
195 callbacks => sub { my %p = @_;
196 my ($package, $filename, $line) = caller(5);
197 return "[".gmtime(time)."] [".$p{level}."]: $p{message} ($filename:$line)\n"
203 if ($RT::LogToSyslog) {
204 require Log::Dispatch::Syslog;
205 $RT::Logger->add(Log::Dispatch::Syslog->new
208 min_level => $RT::LogToSyslog,
209 callbacks => sub { my %p = @_;
210 my ($package, $filename, $line) = caller(5);
212 # syswrite() cannot take utf8; turn it off here.
213 Encode::_utf8_off($p{message});
215 if ($p{level} eq 'debug') {
217 return "$p{message}\n" }
219 return "$p{message} ($filename:$line)\n"}
228 # {{{ Signal handlers
230 ## This is the default handling of warnings and die'ings in the code
231 ## (including other used modules - maybe except for errors catched by
232 ## Mason). It will log all problems through the standard logging
233 ## mechanism (see above).
235 $SIG{__WARN__} = sub {$RT::Logger->warning($_[0])};
237 #When we call die, trap it and log->crit with the value of the die.
239 $SIG{__DIE__} = sub {
240 unless ($^S || !defined $^S ) {
241 $RT::Handle->Rollback();
242 $RT::Logger->crit("$_[0]");
246 #Get out of here if we're in an eval
267 =head2 DropSetGIDPermissions
269 Drops setgid permissions.
273 sub DropSetGIDPermissions {
274 # Now that we got the config read in, we have the database
275 # password and don't need to be setgid
276 # make the effective group the real group
291 ok ($RT::Nobody->Name() eq 'Nobody', "Nobody is nobody");
292 ok ($RT::Nobody->Name() ne 'root', "Nobody isn't named root");
293 ok ($RT::SystemUser->Name() eq 'RT_System', "The system user is RT_System");
294 ok ($RT::SystemUser->Name() ne 'noname', "The system user isn't noname");
301 eval "require RT_Local";
302 die $@ if ($@ && $@ !~ qr{^Can't locate RT_Local.pm});