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
44 $MasonLocalComponentRoot
49 $VERSION = '@RT_VERSION_MAJOR@.@RT_VERSION_MINOR@.@RT_VERSION_PATCH@';
50 $CORE_CONFIG_FILE = "@CONFIG_FILE_PATH@/RT_Config.pm";
51 $SITE_CONFIG_FILE = "@CONFIG_FILE_PATH@/RT_SiteConfig.pm";
53 $BasePath = '@RT_PATH@';
55 $EtcPath = '@RT_ETC_PATH@';
56 $VarPath = '@RT_VAR_PATH@';
57 $LocalPath = '@RT_LOCAL_PATH@';
58 $LocalEtcPath = '@LOCAL_ETC_PATH@';
59 $LocalLexiconPath = '@LOCAL_LEXICON_PATH@';
61 # $MasonComponentRoot is where your rt instance keeps its mason html files
63 $MasonComponentRoot = '@MASON_HTML_PATH@';
65 # $MasonLocalComponentRoot is where your rt instance keeps its site-local
68 $MasonLocalComponentRoot = '@MASON_LOCAL_HTML_PATH@';
70 # $MasonDataDir Where mason keeps its datafiles
72 $MasonDataDir = '@MASON_DATA_PATH@';
74 # RT needs to put session data (for preserving state between connections
75 # via the web interface)
76 $MasonSessionDir = '@MASON_SESSION_PATH@';
86 A fully featured request tracker package
95 Load RT's config file. First, go after the core config file.
96 After that, go after the site config.
101 local *Set = sub { $_[0] = $_[1] unless defined $_[0] };
102 if ( -f "$SITE_CONFIG_FILE" ) {
103 require $SITE_CONFIG_FILE
104 || die ("Couldn't load RT config file '$SITE_CONFIG_FILE'\n$@");
106 require $CORE_CONFIG_FILE
107 || die ("Couldn't load RT config file '$CORE_CONFIG_FILE'\n$@");
113 Conenct to the database, set up logging.
119 #Get a database connection
122 #RT's system user is a genuine database user. its id lives here
123 $SystemUser = new RT::CurrentUser();
124 $SystemUser->LoadByName('RT_System');
126 #RT's "nobody user" is a genuine database user. its ID lives here.
127 $Nobody = new RT::CurrentUser();
128 $Nobody->LoadByName('Nobody');
130 $System = RT::System->new();
136 =head2 ConnectToDatabase
138 Get a database connection
142 sub ConnectToDatabase {
144 unless ($Handle && $Handle->dbh && $Handle->dbh->ping) {
145 $Handle = RT::Handle->new();
152 Create the RT::Logger object.
157 # We have to set the record seperator ($, man perlvar)
158 # or Log::Dispatch starts getting
159 # really pissy, as some other module we use unsets it.
162 use Log::Dispatch 1.6;
164 unless ($RT::Logger) {
166 $RT::Logger=Log::Dispatch->new();
168 if ($RT::LogToFile) {
169 my ($filename, $logdir);
170 if ($RT::LogToFileNamed =~ m![/\\]!) {
171 # looks like an absolute path.
172 $filename = $RT::LogToFileNamed;
173 ($logdir) = $RT::LogToFileNamed =~ m!^(.*[/\\])!;
176 $filename = "$RT::LogDir/$RT::LogToFileNamed";
177 $logdir = $RT::LogDir;
180 unless ( -d $logdir && ( ( -f $filename && -w $filename ) || -w $logdir ) ) {
181 # localizing here would be hard when we don't have a current user yet
182 # die $self->loc("Log directory [_1] not found or couldn't be written.\n RT can't run.", $RT::LogDir);
183 die ("Log file $filename couldn't be written or created.\n RT can't run.");
186 require Log::Dispatch::File;
189 $RT::Logger->add(Log::Dispatch::File->new
191 min_level=> $RT::LogToFile,
192 filename=> $filename,
194 callbacks => sub { my %p = @_;
195 my ($package, $filename, $line) = caller(5);
196 return "[".gmtime(time)."] [".$p{level}."]: $p{message} ($filename:$line)\n"}
202 if ($RT::LogToScreen) {
203 require Log::Dispatch::Screen;
204 $RT::Logger->add(Log::Dispatch::Screen->new
206 min_level => $RT::LogToScreen,
207 callbacks => sub { my %p = @_;
208 my ($package, $filename, $line) = caller(5);
209 return "[".gmtime(time)."] [".$p{level}."]: $p{message} ($filename:$line)\n"
215 if ($RT::LogToSyslog) {
216 require Log::Dispatch::Syslog;
217 $RT::Logger->add(Log::Dispatch::Syslog->new
220 min_level => $RT::LogToSyslog,
221 callbacks => sub { my %p = @_;
222 my ($package, $filename, $line) = caller(5);
224 # syswrite() cannot take utf8; turn it off here.
225 Encode::_utf8_off($p{message});
227 if ($p{level} eq 'debug') {
229 return "$p{message}\n" }
231 return "$p{message} ($filename:$line)\n"}
241 # {{{ Signal handlers
243 ## This is the default handling of warnings and die'ings in the code
244 ## (including other used modules - maybe except for errors catched by
245 ## Mason). It will log all problems through the standard logging
246 ## mechanism (see above).
248 $SIG{__WARN__} = sub {$RT::Logger->warning($_[0])};
250 #When we call die, trap it and log->crit with the value of the die.
252 $SIG{__DIE__} = sub {
253 unless ($^S || !defined $^S ) {
254 $RT::Handle->Rollback();
255 $RT::Logger->crit("$_[0]");
259 #Get out of here if we're in an eval
280 =head2 DropSetGIDPermissions
282 Drops setgid permissions.
286 sub DropSetGIDPermissions {
287 # Now that we got the config read in, we have the database
288 # password and don't need to be setgid
289 # make the effective group the real group
298 Please report them to rt-3.0-bugs@fsck.com, if you know what's broken and have at least some idea of what needs to be fixed.
299 If you're not sure what's going on, report them rt-devel@lists.fsck.com.
304 L<DBIx::SearchBuilder>
311 ok ($RT::Nobody->Name() eq 'Nobody', "Nobody is nobody");
312 ok ($RT::Nobody->Name() ne 'root', "Nobody isn't named root");
313 ok ($RT::SystemUser->Name() eq 'RT_System', "The system user is RT_System");
314 ok ($RT::SystemUser->Name() ne 'noname', "The system user isn't noname");
321 eval "require RT_Local";
322 die $@ if ($@ && $@ !~ qr{^Can't locate RT_Local.pm});