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
124 #RT's system user is a genuine database user. its id lives here
125 $SystemUser = new RT::CurrentUser();
126 $SystemUser->LoadByName('RT_System');
128 #RT's "nobody user" is a genuine database user. its ID lives here.
129 $Nobody = new RT::CurrentUser();
130 $Nobody->LoadByName('Nobody');
132 $System = RT::System->new();
138 =head2 ConnectToDatabase
140 Get a database connection
144 sub ConnectToDatabase {
146 unless ($Handle && $Handle->dbh && $Handle->dbh->ping) {
147 $Handle = RT::Handle->new();
154 Create the RT::Logger object.
159 # We have to set the record seperator ($, man perlvar)
160 # or Log::Dispatch starts getting
161 # really pissy, as some other module we use unsets it.
164 use Log::Dispatch 1.6;
166 unless ($RT::Logger) {
168 $RT::Logger=Log::Dispatch->new();
170 if ($RT::LogToFile) {
172 unless (-d $RT::LogDir && -w $RT::LogDir) {
173 # localizing here would be hard when we don't have a current user yet
174 # die $self->loc("Log directory [_1] not found or couldn't be written.\n RT can't run.", $RT::LogDir);
175 die ("Log directory $RT::LogDir not found or couldn't be written.\n RT can't run.");
179 if ($RT::LogToFileNamed =~ m![/\\]!) {
180 # looks like an absolute path.
181 $filename = $RT::LogToFileNamed;
184 $filename = "$RT::LogDir/$RT::LogToFileNamed";
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"}
240 # {{{ Signal handlers
242 ## This is the default handling of warnings and die'ings in the code
243 ## (including other used modules - maybe except for errors catched by
244 ## Mason). It will log all problems through the standard logging
245 ## mechanism (see above).
247 $SIG{__WARN__} = sub {$RT::Logger->warning($_[0])};
249 #When we call die, trap it and log->crit with the value of the die.
251 $SIG{__DIE__} = sub {
252 unless ($^S || !defined $^S ) {
253 $RT::Handle->Rollback();
254 $RT::Logger->crit("$_[0]");
258 #Get out of here if we're in an eval
279 =head2 DropSetGIDPermissions
281 Drops setgid permissions.
285 sub DropSetGIDPermissions {
286 # Now that we got the config read in, we have the database
287 # password and don't need to be setgid
288 # make the effective group the real group
297 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.
298 If you're not sure what's going on, report them rt-devel@lists.fsck.com.
303 L<DBIx::SearchBuilder>
310 ok ($RT::Nobody->Name() eq 'Nobody', "Nobody is nobody");
311 ok ($RT::Nobody->Name() ne 'root', "Nobody isn't named root");
312 ok ($RT::SystemUser->Name() eq 'RT_System', "The system user is RT_System");
313 ok ($RT::SystemUser->Name() ne 'noname', "The system user isn't noname");
320 eval "require RT_Local";
321 die $@ if ($@ && $@ !~ qr{^Can't locate RT_Local.pm});