tbrehm
2010-07-01 49029cc4c2cdaa7505430f77e0492d2c91cd1da2
commit | author | age
313e33 1 <?php
T 2
3 /*
4 Copyright (c) 2007, Till Brehm, projektfarm Gmbh
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without modification,
8 are permitted provided that the following conditions are met:
9
10     * Redistributions of source code must retain the above copyright notice,
11       this list of conditions and the following disclaimer.
12     * Redistributions in binary form must reproduce the above copyright notice,
13       this list of conditions and the following disclaimer in the documentation
14       and/or other materials provided with the distribution.
15     * Neither the name of ISPConfig nor the names of its contributors
16       may be used to endorse or promote products derived from this software without
17       specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26 OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 require("lib/config.inc.php");
32 require("lib/app.inc.php");
33
34 set_time_limit(0);
35
36 // make sure server_id is always an int
37 $conf["server_id"] = intval($conf["server_id"]);
38
695825 39
313e33 40 // Load required base-classes
58c210 41 $app->uses('ini_parser,file,services,getconf');
313e33 42
T 43
44 #######################################################################################################
45 // store the mailbox statistics in the database
46 #######################################################################################################
47
48 $sql = "SELECT mailuser_id,maildir FROM mail_user WHERE server_id = ".$conf["server_id"];
49 $records = $app->db->queryAllRecords($sql);
50 foreach($records as $rec) {
d1489c 51     if(@is_file($rec["maildir"].'/ispconfig_mailsize')) {
695825 52
313e33 53         // rename file
d1489c 54         rename($rec["maildir"].'/ispconfig_mailsize',$rec["maildir"].'/ispconfig_mailsize_save');
695825 55
313e33 56         // Read the file
d1489c 57         $lines = file($rec["maildir"].'/ispconfig_mailsize_save');
313e33 58         $mail_traffic = 0;
T 59         foreach($lines as $line) {
60             $mail_traffic += intval($line);
61         }
62         unset($lines);
695825 63
313e33 64         // Delete backup file
d1489c 65         if(@is_file($rec["maildir"].'/ispconfig_mailsize_save')) unlink($rec["maildir"].'/ispconfig_mailsize_save');
695825 66
313e33 67         // Save the traffic stats in the sql database
T 68         $tstamp = date("Y-m");
695825 69
313e33 70         $sql = "SELECT * FROM mail_traffic WHERE month = '$tstamp' AND mailuser_id = ".$rec["mailuser_id"];
a73335 71         $tr = $app->dbmaster->queryOneRecord($sql);
695825 72
313e33 73         $mail_traffic += $tr["traffic"];
T 74         if($tr["traffic_id"] > 0) {
75             $sql = "UPDATE mail_traffic SET traffic = $mail_traffic WHERE traffic_id = ".$tr["traffic_id"];
76         } else {
77             $sql = "INSERT INTO mail_traffic (month,mailuser_id,traffic) VALUES ('$tstamp',".$rec["mailuser_id"].",$mail_traffic)";
78         }
a73335 79         $app->dbmaster->query($sql);
313e33 80         echo $sql;
695825 81
313e33 82     }
695825 83
313e33 84 }
T 85
86 #######################################################################################################
87 // Create webalizer statistics
88 #######################################################################################################
89
035886 90 function setConfigVar( $filename, $varName, $varValue ) {
T 91     if($lines = @file($filename)) {
92         $out = '';
93         $found = 0;
94         foreach($lines as $line) {
4cc356 95             list($key, $value) = preg_split("/[\t= ]+/", $line, 2);
035886 96             if($key == $varName) {
T 97                 $out .= $varName." ".$varValue."\n";
98                 $found = 1;
99             } else {
100                 $out .= $line;
101             }
102         }
103         if($found == 0) {
104             //* add \n if the last line does not end with \n or \r
105             if(substr($out,-1) != "\n" && substr($out,-1) != "\r") $out .= "\n";
106             //* add the new line at the end of the file
107             if($append == 1) $out .= $varName." ".$varValue."\n";
108         }
109
110         file_put_contents($filename,$out);
111     }
112 }
113
313e33 114
58c210 115 $sql = "SELECT domain_id, domain, document_root FROM web_domain WHERE stats_type = 'webalizer' AND server_id = ".$conf["server_id"];
313e33 116 $records = $app->db->queryAllRecords($sql);
035886 117
313e33 118 foreach($records as $rec) {
641cb3 119     $yesterday = date("Ymd",time() - 86400);
313e33 120     $logfile = escapeshellcmd($rec["document_root"].'/log/'.$yesterday.'-access.log');
8c034e 121     if(!@is_file($logfile)) {
T 122         $logfile = escapeshellcmd($rec["document_root"].'/log/'.$yesterday.'-access.log.gz');
58c210 123         if(!@is_file($logfile)) {
T 124             continue;
125         }
313e33 126     }
035886 127
58c210 128     $domain = escapeshellcmd($rec["domain"]);
T 129     $statsdir = escapeshellcmd($rec["document_root"].'/web/stats');
130     $webalizer = '/usr/bin/webalizer';
131     $webalizer_conf_main = '/etc/webalizer/webalizer.conf';
132     $webalizer_conf = escapeshellcmd($rec["document_root"].'/log/webalizer.conf');
035886 133
58c210 134     if(!@is_file($webalizer_conf)) {
T 135         exec("cp $webalizer_conf_main $webalizer_conf");
136     }
035886 137
58c210 138     if(@is_file($webalizer_conf)) {
T 139         setConfigVar($webalizer_conf, 'Incremental', 'yes');
140         setConfigVar($webalizer_conf, 'IncrementalName', $statsdir.'/webalizer.current');
141         setConfigVar($webalizer_conf, 'HistoryName', $statsdir.'/webalizer.hist');
142     }
8388ae 143
T 144
58c210 145     if(!@is_dir($statsdir)) mkdir($statsdir);
8c034e 146     exec("$webalizer -c $webalizer_conf -n $domain -s $domain -r $domain -q -T -p -o $statsdir $logfile");
313e33 147 }
T 148
149 #######################################################################################################
58c210 150 // Create awstats statistics
T 151 #######################################################################################################
152
153 $sql = "SELECT domain_id, domain, document_root FROM web_domain WHERE stats_type = 'awstats' AND server_id = ".$conf["server_id"];
154 $records = $app->db->queryAllRecords($sql);
155
156 $web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
157
158 foreach($records as $rec) {
159     $yesterday = date("Ymd",time() - 86400);
160     $logfile = escapeshellcmd($rec["document_root"].'/log/'.$yesterday.'-access.log');
161     if(!@is_file($logfile)) {
162         $logfile = escapeshellcmd($rec["document_root"].'/log/'.$yesterday.'-access.log.gz');
163         if(!@is_file($logfile)) {
164             continue;
165         }
166     }
167     
168     $domain = escapeshellcmd($rec["domain"]);
169     $statsdir = escapeshellcmd($rec["document_root"].'/web/stats');
170     $awstats_pl = $web_config['awstats_pl'];
2a6eac 171     $awstats_buildstaticpages_pl = $web_config['awstats_buildstaticpages_pl'];
58c210 172     
T 173     
174     if(!@is_dir($statsdir)) mkdir($statsdir);
175     
176     // awstats_buildstaticpages.pl -update -config=mydomain.com -lang=en -dir=/var/www/domain.com/web/stats -awstatsprog=/path/to/awstats.pl
2a6eac 177     $command = "$awstats_buildstaticpages_pl -update -config='$domain' -lang=en -dir='$statsdir' -awstatsprog='$awstats_pl'";
58c210 178     
2a6eac 179     if($awstats_pl != '' && $awstats_buildstaticpages_pl != '' && fileowner($awstats_pl) == 0 && fileowner($awstats_buildstaticpages_pl) == 0) {
58c210 180         exec($command);
2a6eac 181         rename($rec["document_root"].'/web/stats/awstats.'.$domain.'.html',$rec["document_root"].'/web/stats/index.html');
58c210 182         $app->log("Created awstats statistics with command: $command",LOGLEVEL_DEBUG);
T 183     } else {
2a6eac 184         $app->log("No awstats statistics created. Either $awstats_pl or $awstats_buildstaticpages_pl is not owned by root user.",LOGLEVEL_WARN);
58c210 185     }
T 186     
187 }
188
189
190 #######################################################################################################
033c80 191 // Make the web logfiles directories world readable to enable ftp access
T 192 #######################################################################################################
193
194 exec('chmod +r /var/log/ispconfig/httpd/*');
195
196 #######################################################################################################
313e33 197 // Manage and compress web logfiles
T 198 #######################################################################################################
199
200 $sql = "SELECT domain_id, domain, document_root FROM web_domain WHERE server_id = ".$conf["server_id"];
201 $records = $app->db->queryAllRecords($sql);
202 foreach($records as $rec) {
641cb3 203     $yesterday = date("Ymd",time() - 86400);
313e33 204     $logfile = escapeshellcmd($rec["document_root"].'/log/'.$yesterday.'-access.log');
T 205     if(@is_file($logfile)) {
206         // Compress yesterdays logfile
207         exec("gzip -c $logfile > $logfile.gz");
b28db4 208         unlink($logfile);
313e33 209     }
3e0034 210     
T 211     // rotate and compress the error.log when it exceeds a size of 10 MB
212     $logfile = escapeshellcmd($rec["document_root"].'/log/error.log');
213     if(is_file($logfile) && filesize($logfile) > 10000000) {
214         exec("gzip -c $logfile > $logfile.1.gz");
215         exec("cat /dev/null > $logfile");
216     }
695825 217
313e33 218     // delete logfiles after 30 days
641cb3 219     $month_ago = date("Ymd",time() - 86400 * 30);
b28db4 220     $logfile = escapeshellcmd($rec["document_root"].'/log/'.$month_ago.'-access.log.gz');
313e33 221     if(@is_file($logfile)) {
T 222         unlink($logfile);
223     }
224 }
225
d7f14d 226 #######################################################################################################
3e0034 227 // Rotate the ispconfig.log file
T 228 #######################################################################################################
229
230 // rotate the ispconfig.log when it exceeds a size of 10 MB
c211f7 231 $logfile = '/var/log/ispconfig/ispconfig.log';
3e0034 232 if(is_file($logfile) && filesize($logfile) > 10000000) {
T 233     exec("gzip -c $logfile > $logfile.1.gz");
234     exec("cat /dev/null > $logfile");
235 }
236
237 #######################################################################################################
2155fb 238 // Cleanup website tmp directories
T 239 #######################################################################################################
240
241 $sql = "SELECT domain_id, domain, document_root, system_user FROM web_domain WHERE server_id = ".$conf["server_id"];
242 $records = $app->db->queryAllRecords($sql);
ab6140 243 $app->uses('system');
2155fb 244 if(is_array($records)) {
T 245     foreach($records as $rec){
246         $tmp_path = realpath(escapeshellcmd($rec["document_root"].'/tmp'));
ab6140 247         if($tmp_path != '' && strlen($tmp_path) > 10 && is_dir($tmp_path) && $app->system->is_user($rec['system_user'])){
54396b 248             exec("cd ".$tmp_path."; find -mtime +1 -name 'sess_*' | grep -v -w .no_delete | xargs rm > /dev/null 2> /dev/null");
2b849b 249         }
T 250     }
251 }
2155fb 252
T 253 #######################################################################################################
e265dc 254 // Cleanup logs in master database (only the "master-server")
d7f14d 255 #######################################################################################################
313e33 256
e265dc 257 if ($app->dbmaster == $app->db) {
V 258     /** 7 days */
259     $tstamp = time() - (60*60*24*7);
313e33 260
e265dc 261     /*
V 262      *  Keep 7 days in sys_log
263      * (we can delete the old items, because if they are OK, they don't interrest anymore
264      * if they are NOT ok, the server will try to process them in 1 minute and so the
265      * error appears again after 1 minute. So it is no problem to delete the old one!
266      */
45841f 267     $sql = "DELETE FROM sys_log WHERE tstamp < " . $tstamp . " AND server_id != 0";
V 268     $app->dbmaster->query($sql);
269
270     /*
9db145 271      * Delete all remote-actions "done" and older than 7 days
V 272      * ATTENTION: We have the same problem as described in cleaning the datalog. We must not
273      * delete the last entry
45841f 274      */
9db145 275     $sql = "SELECT max(action_id) FROM sys_remoteaction";
V 276     $res = $app->dbmaster->queryOneRecord($sql);
277     $maxId = $res['max(action_id)'];
278     $sql =  "DELETE FROM sys_remoteaction " .
279             "WHERE tstamp < " . $tstamp . " " .
280             " AND action_status = 'ok' " .
281             " AND action_id <" . intval($maxId);
e265dc 282     $app->dbmaster->query($sql);
V 283
284     /*
285      * The sys_datalog is more difficult.
286      * 1) We have to keet ALL entries with
287      *    server_id=0, because they depend on ALL servers (even if they are not
288      *    actually in the system (and will be insered in 3 days or so).
289      * 2) We have to keey ALL entries which are not actually precessed by the
290      *    server never mind how old they are!
0061e0 291      * 3) We have to keep the entry with the highest autoinc-id, because mysql calculates the
V 292      *    autoinc-id as "new value = max(row) +1" and does not store this in a separate table.
293      *    This means, if we delete to entry with the highest autoinc-value then this value is
294      *    reused as autoinc and so there are more than one entries with the same value (over
295      *    for example 4 Weeks). This is confusing for our system.
296      *    ATTENTION 2) and 3) is in some case NOT the same! so we have to check both!
e265dc 297      */
V 298
299     /* First we need all servers and the last sys_datalog-id they processed */
300     $sql = "SELECT server_id, updated FROM server ORDER BY server_id";
301     $records = $app->dbmaster->queryAllRecords($sql);
302
0061e0 303     /* Then we need the highest value ever */
V 304     $sql = "SELECT max(datalog_id) FROM sys_datalog";
305     $res = $app->dbmaster->queryOneRecord($sql);
306     $maxId = $res['max(datalog_id)'];
307
e265dc 308     /* Then delete server by server */
V 309     foreach($records as $server) {
942538 310         $tmp_server_id = intval($server['server_id']);
T 311         if($tmp_server_id > 0) {
0061e0 312             $sql =     "DELETE FROM sys_datalog " .
V 313                     "WHERE tstamp < " . $tstamp .
942538 314                     " AND server_id = " . intval($server['server_id']) .
0061e0 315                     " AND datalog_id < " . intval($server['updated']) .
V 316                     " AND datalog_id < " . intval($maxId);
942538 317         }
e265dc 318 //        echo $sql . "\n";
V 319         $app->dbmaster->query($sql);
320     }
321 }
313e33 322
8d0c6b 323 #######################################################################################################
942538 324 // enforce traffic quota (run only on the "master-server")
8d0c6b 325 #######################################################################################################
T 326
327 if ($app->dbmaster == $app->db) {
328
329     $current_month = date('Y-m');
695825 330
8d0c6b 331     //* Check website traffic quota
T 332     $sql = "SELECT sys_groupid,domain_id,domain,traffic_quota,traffic_quota_lock FROM web_domain WHERE traffic_quota > 0 and type = 'vhost'";
333     $records = $app->db->queryAllRecords($sql);
334     if(is_array($records)) {
335         foreach($records as $rec) {
695825 336
8d0c6b 337             $web_traffic_quota = $rec['traffic_quota'];
b0ebbd 338             $domain = $rec['domain'];
695825 339
8d0c6b 340             // get the client
T 341             /*
342             $client_group_id = $rec["sys_groupid"];
343             $client = $app->db->queryOneRecord("SELECT limit_traffic_quota,parent_client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id");
344             $reseller = $app->db->queryOneRecord("SELECT limit_traffic_quota FROM client WHERE client_id = ".intval($client['parent_client_id']));
695825 345
8d0c6b 346             $client_traffic_quota = intval($client['limit_traffic_quota']);
T 347             $reseller_traffic_quota = intval($reseller['limit_traffic_quota']);
348             */
695825 349
8d0c6b 350             //* get the traffic
695825 351             $tmp = $app->db->queryOneRecord("SELECT SUM(traffic_bytes) As total_traffic_bytes FROM web_traffic WHERE traffic_date like '$current_month%' AND hostname = '$domain'");
M 352             $web_traffic = (int)$tmp['total_traffic_bytes']/1024/1024;
353
8d0c6b 354             //* Website is over quota, we will disable it
T 355             /*if( ($web_traffic_quota > 0 && $web_traffic > $web_traffic_quota) ||
356                 ($client_traffic_quota > 0 && $web_traffic > $client_traffic_quota) ||
357                 ($reseller_traffic_quota > 0 && $web_traffic > $reseller_traffic_quota)) {*/
358             if($web_traffic_quota > 0 && $web_traffic > $web_traffic_quota) {
b0ebbd 359                 $app->dbmaster->datalogUpdate('web_domain', "traffic_quota_lock = 'y',active = 'n'", 'domain_id', $rec['domain_id']);
8d0c6b 360                 $app->log("Traffic quota for ".$rec['domain_id']." Exceeded. Disabling website.",LOGLEVEL_DEBUG);
T 361             } else {
362                 //* unlock the website, if traffic is lower then quota
363                 if($rec['traffic_quota_lock'] == 'y') {
b0ebbd 364                     $app->dbmaster->datalogUpdate('web_domain', "traffic_quota_lock = 'n',active = 'y'", 'domain_id', $rec['domain_id']);
8d0c6b 365                     $app->log("Traffic quota for ".$rec['domain_id']." ok again. Enabling website.",LOGLEVEL_DEBUG);
T 366                 }
367             }
368         }
369     }
695825 370
M 371
8d0c6b 372 }
T 373
49029c 374 #######################################################################################################
T 375 // Create website backups
376 #######################################################################################################
377
378 $server_config = $app->getconf->get_server_config($conf["server_id"], 'server');
379 $backup_dir = trim($server_config['backup_dir']);
380
381 if($backup_dir != '') {
382     
383     if(!is_dir($backup_dir)) {
384         exec("mkdir -p ".escapeshellarg($backup_dir));
385     }
386     
387     $sql = "SELECT * FROM web_domain WHERE type = 'vhost'";
388     $records = $app->db->queryAllRecords($sql);
389     if(is_array($records)) {
390         foreach($records as $rec) {
391             
392             // Create a backup
393             if($rec['backup_interval'] == 'daily' or ($rec['backup_interval'] == 'daily' && date('w') == 0) or ($rec['backup_interval'] == 'monthly' && date('d') == '01')) {
394                 
395                 $web_path = $rec['document_root'];
396                 $web_user = $rec['system_user'];
397                 $web_group = $rec['system_group'];
398                 $web_id = $rec['domain_id'];
399                 $web_backup_dir = $backup_dir.'/web'.$web_id;
400                 if(!is_dir($web_backup_dir)) mkdir($web_backup_dir);
401                 
402                 exec('chown root:root '.$web_backup_dir);
403                 exec('chmod 755 '.$web_backup_dir);
404                 exec("cd ".escapeshellarg($web_path)." && sudo -u ".escapeshellarg($web_user)." find . -group ".escapeshellarg($web_group)." -print | zip -y ".escapeshellarg($web_backup_dir."/web.zip")." -@");
405                 
406                 // Rename or remove old backups
407                 $backup_copies = intval($rec['backup_copies']);
408             
409                 if(is_file($web_backup_dir."/web.".$backup_copies.".zip")) unlink($web_backup_dir."/web.".$backup_copies.".zip");
410             
411                 for($n = $backup_copies - 1; $n >= 1; $n--) {
412                     if(is_file($web_backup_dir."/web.".$n.".zip")) {
413                         rename($web_backup_dir."/web.".$n.".zip",$web_backup_dir."/web.".($n+1).".zip");
414                     }
415                 }
416             
417                 if(is_file($web_backup_dir."/web.zip")) rename($web_backup_dir."/web.zip",$web_backup_dir."/web.1.zip");
418             
419                 // Create backupdir symlink
420                 if(is_link($web_path.'/backup')) unlink($web_path.'/backup');
421                 symlink($web_backup_dir,$web_path.'/backup');
422                 
423             }
424             
425             /* If backup_interval is set to none and we have a 
426             backup directory for the website, then remove the backups */
427             
428             if($rec['backup_interval'] == 'none') {
429                 $web_id = $rec['domain_id'];
430                 $web_user = $rec['system_user'];
431                 $web_backup_dir = realpath($backup_dir.'/web'.$web_id);
432                 if(is_dir($web_backup_dir)) {
433                     exec("sudo -u ".escapeshellarg($web_user)." rm -f ".escapeshellarg($web_backup_dir.'/*'));
434                 }
435             }
436         }
437     }
438 }
439
8d0c6b 440
313e33 441 die("finished.\n");
T 442 ?>