This commit was generated by cvs2svn to compensate for changes in r4407,
[freeside.git] / rt / lib / RT.pm
1 # BEGIN LICENSE BLOCK
2
3 # Copyright (c) 1996-2002 Jesse Vincent <jesse@bestpractical.com>
4
5 # (Except where explictly superceded by other copyright notices)
6
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
10 # from www.gnu.org
11
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.
16
17
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.
22
23
24 # END LICENSE BLOCK
25
26
27 package RT;
28 use strict;
29 use RT::I18N;
30 use RT::CurrentUser;
31 use RT::System;
32
33 use vars qw($VERSION $System $SystemUser $Nobody $Handle $Logger
34         $CORE_CONFIG_FILE
35         $SITE_CONFIG_FILE
36         $VENDOR_CONFIG_FILE
37         $BasePath
38         $EtcPath
39         $VarPath
40         $LocalPath
41         $LocalEtcPath
42         $LocalLexiconPath
43         $LogDir
44         $MasonComponentRoot
45         $MasonLocalComponentRoot
46         $MasonDataDir
47         $MasonSessionDir
48 );
49
50 $VERSION = '3.0.4';
51 $CORE_CONFIG_FILE = "/opt/rt3/etc/RT_Config.pm";
52 $SITE_CONFIG_FILE = "/opt/rt3/etc/RT_SiteConfig.pm";
53
54 $BasePath = '/opt/rt3';
55
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';
61
62 # $MasonComponentRoot is where your rt instance keeps its mason html files
63
64 $MasonComponentRoot = '/opt/rt3/share/html';
65
66 # $MasonLocalComponentRoot is where your rt instance keeps its site-local
67 # mason html files.
68
69 $MasonLocalComponentRoot = '/opt/rt3/local/html';
70
71 # $MasonDataDir Where mason keeps its datafiles
72
73 $MasonDataDir = '/opt/rt3/var/mason_data';
74
75 # RT needs to put session data (for preserving state between connections
76 # via the web interface)
77 $MasonSessionDir = '/opt/rt3/var/session_data';
78
79
80
81 =head1 NAME
82
83         RT - Request Tracker
84
85 =head1 SYNOPSIS
86
87         A fully featured request tracker package
88
89 =head1 DESCRIPTION
90
91
92 =cut
93
94 =item LoadConfig
95
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.
99
100 =cut
101
102 sub LoadConfig {
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$@");
107     }
108     require $CORE_CONFIG_FILE
109       || die ("Couldn't load RT config file '$CORE_CONFIG_FILE'\n$@");
110     RT::I18N->Init;
111 }
112
113 =item Init
114
115     Conenct to the database, set up logging.
116     
117 =cut
118
119 sub Init {
120     require RT::Handle;
121     #Get a database connection
122         unless ($Handle && $Handle->dbh->ping) {
123     $Handle = RT::Handle->new();
124         } 
125     $Handle->Connect();
126     
127     #RT's system user is a genuine database user. its id lives here
128     $SystemUser = new RT::CurrentUser();
129     $SystemUser->LoadByName('RT_System');
130     
131     #RT's "nobody user" is a genuine database user. its ID lives here.
132     $Nobody = new RT::CurrentUser();
133     $Nobody->LoadByName('Nobody');
134   
135     $System = RT::System->new();
136
137    InitLogging(); 
138 }
139
140 =head2 InitLogging
141
142 Create the RT::Logger object. 
143
144 =cut
145 sub InitLogging {
146
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.
150
151     $, = '';
152     use Log::Dispatch 1.6;
153
154     unless ($RT::Logger) {
155
156     $RT::Logger=Log::Dispatch->new();
157     
158     if ($RT::LogToFile) {
159
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.");
164     }
165
166         my $filename;
167         if ($RT::LogToFileNamed =~ m![/\\]!) {
168             # looks like an absolute path.
169             $filename = $RT::LogToFileNamed;
170         }
171         else {
172             $filename = "$RT::LogDir/$RT::LogToFileNamed";
173         }
174     require Log::Dispatch::File;
175
176
177           $RT::Logger->add(Log::Dispatch::File->new
178                        ( name=>'rtlog',
179                          min_level=> $RT::LogToFile,
180                          filename=> $filename,
181                          mode=>'append',
182                          callbacks => sub { my %p = @_;
183                                 my ($package, $filename, $line) = caller(5);
184                                 return "[".gmtime(time)."] [".$p{level}."]: $p{message} ($filename:$line)\n"}
185              
186              
187              
188                        ));
189     }
190     if ($RT::LogToScreen) {
191         require Log::Dispatch::Screen;
192         $RT::Logger->add(Log::Dispatch::Screen->new
193                      ( name => 'screen',
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"
198                                 },
199              
200                        stderr => 1
201                      ));
202     }
203     if ($RT::LogToSyslog) {
204         require Log::Dispatch::Syslog;
205         $RT::Logger->add(Log::Dispatch::Syslog->new
206                      ( name => 'syslog',
207                        ident => 'RT',
208                        min_level => $RT::LogToSyslog,
209                          callbacks => sub { my %p = @_;
210                                 my ($package, $filename, $line) = caller(5);
211
212                                 # syswrite() cannot take utf8; turn it off here.
213                                 Encode::_utf8_off($p{message});
214
215                                 if ($p{level} eq 'debug') {
216
217                                 return "$p{message}\n" }
218                                 else {
219                                 return "$p{message} ($filename:$line)\n"}
220                                 },
221              
222                        stderr => 1
223                      ));
224     }
225
226     }
227
228 # {{{ Signal handlers
229
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).
234
235 $SIG{__WARN__} = sub {$RT::Logger->warning($_[0])};
236
237 #When we call die, trap it and log->crit with the value of the die.
238
239 $SIG{__DIE__}  = sub {
240     unless ($^S || !defined $^S ) {
241         $RT::Handle->Rollback();
242         $RT::Logger->crit("$_[0]");
243         exit(-1);
244     }
245     else {
246         #Get out of here if we're in an eval
247         die $_[0];
248     }
249 };
250
251 # }}}
252
253 }
254
255 # }}}
256
257
258 sub SystemUser {
259     return($SystemUser);
260 }       
261
262 sub Nobody {
263     return ($Nobody);
264 }
265
266
267 =head2 DropSetGIDPermissions
268
269 Drops setgid permissions.
270
271 =cut
272
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
277     $) = $(;
278 }
279
280
281 =head1 SYNOPSIS
282
283 =head1 BUGS
284
285 =head1 SEE ALSO
286
287
288 =begin testing
289
290
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");
295
296
297 =end testing
298
299 =cut
300
301 eval "require RT_Local";
302 die $@ if ($@ && $@ !~ qr{^Can't locate RT_Local.pm});
303
304 1;