diff --git a/install/install.php b/install/install.php
index 140db21a9f7f7a52cb3c5f989a175c30bea59caa..05fba1fd31b37be871360f6d6398ac76485ed0ee 100644
--- a/install/install.php
+++ b/install/install.php
@@ -115,17 +115,19 @@ calmd
spamd
*/
-exec("/etc/init.d/mysql restart");
-exec("/etc/init.d/postfix restart");
-exec("/etc/init.d/saslauthd restart");
-exec("/etc/init.d/amavis restart");
-exec("/etc/init.d/clamav-daemon restart");
-exec("/etc/init.d/courier-authdaemon restart");
-exec("/etc/init.d/courier-imap restart");
-exec("/etc/init.d/courier-imap-ssl restart");
-exec("/etc/init.d/courier-pop restart");
-exec("/etc/init.d/courier-pop-ssl restart");
-exec("/etc/init.d/apache2 restart");
+swriteln('Restarting services ...');
+system("/etc/init.d/mysql restart");
+system("/etc/init.d/postfix restart");
+system("/etc/init.d/saslauthd restart");
+system("/etc/init.d/amavis restart");
+system("/etc/init.d/clamav-daemon restart");
+system("/etc/init.d/courier-authdaemon restart");
+system("/etc/init.d/courier-imap restart");
+system("/etc/init.d/courier-imap-ssl restart");
+system("/etc/init.d/courier-pop restart");
+system("/etc/init.d/courier-pop-ssl restart");
+system("/etc/init.d/apache2 restart");
+system("/etc/init.d/pure-ftpd-mysql restart");
echo "Installation finished.\n";
diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php
index 00f60cb9add54f903fcb82497d46dc255471ac93..f97c4b4426eda0f984e237fbcd044d9d96daee8f 100644
--- a/install/lib/installer_base.lib.php
+++ b/install/lib/installer_base.lib.php
@@ -467,6 +467,8 @@ maildrop unix - n n - - pipe
wf($conf["dist_pureftpd_config_dir"].'/'.$configfile,$content);
exec('chmod 600 '.$conf["dist_pureftpd_config_dir"].'/'.$configfile);
exec('chown root:root '.$conf["dist_pureftpd_config_dir"].'/'.$configfile);
+ // enable chrooting
+ exec('echo "yes" > /etc/pure-ftpd/conf/ChrootEveryone');
}
diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql
index c80510db335f245e22ac3500220b4f1af52831cc..1e552beeeee89a7535f56094937a5eb946adce99 100644
--- a/install/sql/ispconfig3.sql
+++ b/install/sql/ispconfig3.sql
@@ -404,6 +404,8 @@ CREATE TABLE `server` (
-- Daten für Tabelle `server`
--
+INSERT INTO `server` (`server_id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_name`, `mail_server`, `web_server`, `dns_server`, `file_server`, `db_server`, `vserver_server`, `config`, `updated`, `active`) VALUES (1, 1, 1, 'riud', 'riud', 'r', 'Server 1', 1, 1, 1, 1, 1, 1, '[global]\nwebserver=apache\nmailserver=postfix\ndnsserver=mydns\n\n[mail]\nmodule=postfix_mysql\nmaildir_path=/home/vmail/[domain]/[localpart]/\nhomedir_path=/home/vmail/\nmailuser_uid=5000\nmailuser_gid=5000\nmailuser_name=vmail\nmailuser_group=vmail\n\n[getmail]\ngetmail_config_dir=/etc/getmail\n\n[web]\nwebsite_path=/var/clients/client[client_id]/web[website_id]\nwebsite_symlinks=/var/www/[website_domain]/:/var/clients/client[client_id]/[website_domain]/\n\n', 0, 1);
+
-- --------------------------------------------------------
--
diff --git a/install/update.php b/install/update.php
new file mode 100644
index 0000000000000000000000000000000000000000..0dc79198ca104f036b734e9ae27e636f4db2a5cb
--- /dev/null
+++ b/install/update.php
@@ -0,0 +1,155 @@
+request_language();
+
+// TODO: all other queries, for testing I will setup everything in $conf
+
+// Initialize the MySQL server connection
+include_once('lib/mysql.lib.php');
+$inst->db = new db();
+
+// Database update is a bit brute force and should be rebuild later ;)
+
+// export the current database data
+exec("mysqldump -h $conf[mysql_server_host] -u $conf[mysql_server_ispconfig_user] -p$conf[mysql_server_ispconfig_password] -c -t --add-drop-table --add-locks --all --quick --lock-tables $conf[mysql_server_database] > existing_db.sql &> /dev/null");
+
+// Delete the old database
+exec("/etc/init.d/mysql stop");
+exec("rm -rf /var/lib/mysql/".$conf["db_database"]);
+exec("/etc/init.d/mysql start");
+
+// Create the mysql database
+$inst->configure_database();
+
+// empty all databases
+$db_tables = $inst->db->getTables();
+foreach($db_tables as $table) {
+ $inst->db->query("TRUNCATE $table");
+}
+
+// load old data back into database
+exec("mysql -h $conf[mysql_server_host] -u $conf[mysql_server_ispconfig_user] -p$conf[mysql_server_ispconfig_password] $conf[mysql_server_database] < existing_db.sql &> /dev/null");
+
+// Configure postfix
+$inst->configure_postfix();
+
+// Configure saslauthd
+swriteln('Configuring SASL');
+$inst->configure_saslauthd();
+
+
+// Configure PAM
+swriteln('Configuring PAM');
+$inst->configure_pam();
+
+// Configure courier
+swriteln('Configuring Courier');
+$inst->configure_courier();
+
+// Configure Spamasassin
+swriteln('Configuring Spamassassin');
+$inst->configure_spamassassin();
+
+// Configure Amavis
+swriteln('Configuring Amavisd');
+$inst->configure_amavis();
+
+// Configure Getmail
+swriteln('Configuring Getmail');
+$inst->configure_getmail();
+
+// Configure Getmail
+swriteln('Configuring Pureftpd');
+$inst->configure_pureftpd();
+
+// Configure ISPConfig
+swriteln('Installing ISPConfig');
+$inst->install_ispconfig();
+
+// Configure ISPConfig
+swriteln('Installing Crontab');
+$inst->install_crontab();
+
+
+/*
+Restart services:
+*/
+
+swriteln('Restarting services ...');
+system("/etc/init.d/mysql restart");
+system("/etc/init.d/postfix restart");
+system("/etc/init.d/saslauthd restart");
+system("/etc/init.d/amavis restart");
+system("/etc/init.d/clamav-daemon restart");
+system("/etc/init.d/courier-authdaemon restart");
+system("/etc/init.d/courier-imap restart");
+system("/etc/init.d/courier-imap-ssl restart");
+system("/etc/init.d/courier-pop restart");
+system("/etc/init.d/courier-pop-ssl restart");
+system("/etc/init.d/apache2 restart");
+system("/etc/init.d/pure-ftpd-mysql restart");
+
+echo "Update finished.\n";
+
+
+?>
\ No newline at end of file
diff --git a/interface/lib/classes/tform.inc.php b/interface/lib/classes/tform.inc.php
index 81810b9cfc3bfd591dc339231d910c8db9e09b6a..e631e2309fe96faa1b7c164808bb6add9957e8f9 100644
--- a/interface/lib/classes/tform.inc.php
+++ b/interface/lib/classes/tform.inc.php
@@ -766,9 +766,7 @@ class tform {
$app->error("Primary ID fehlt!");
}
}
-
- // Daten in History tabelle speichern
- if($this->errorMessage == '' and $this->formDef['db_history'] == 'yes') $this->datalogSave($action,$primary_id,$record);
+
return $sql;
}
@@ -839,11 +837,16 @@ class tform {
// Set Wordbook for this form
$app->tpl->setVar($this->wordbook);
- }
-
+ }
+ function getDataRecord($primary_id) {
+ global $app;
+ $sql = "SELECT * FROM ".$escape.$this->formDef['db_table'].$escape." WHERE ".$this->formDef['db_table_idx']." = ".$primary_id;
+ return $app->db->queryOneRecord($sql);
+ }
+
- function datalogSave($action,$primary_id,$record_new) {
+ function datalogSave($action,$primary_id, $record_old, $record_new) {
global $app,$conf;
// Füge Backticks nur bei unvollständigen Tabellennamen ein
@@ -852,17 +855,19 @@ class tform {
} else {
$escape = '`';
}
-
- if($action == "UPDATE") {
+
+ /*
+ if($action == "UPDATE" or $action == "DELETE") {
$sql = "SELECT * FROM ".$escape.$this->formDef['db_table'].$escape." WHERE ".$this->formDef['db_table_idx']." = ".$primary_id;
$record_old = $app->db->queryOneRecord($sql);
} else {
$record_old = array();
}
+ */
$diffrec = array();
- if(is_array($record_new)) {
+ if(is_array($record_new) && count($record_new) > 0) {
foreach($record_new as $key => $val) {
if($record_old[$key] != $val) {
// Record has changed
@@ -870,13 +875,22 @@ class tform {
'new' => $val);
}
}
+ } elseif(is_array($record_old)) {
+ foreach($record_old as $key => $val) {
+ if($record_new[$key] != $val) {
+ // Record has changed
+ $diffrec[$key] = array('new' => $record_new[$key],
+ 'old' => $val);
+ }
+ }
}
$this->diffrec = $diffrec;
+
// Full diff records for ISPConfig, they have a different format then the simple diffrec
$diffrec_full = array();
- if(is_array($record_old)) {
+ if(is_array($record_old) && count($record_old) > 0) {
foreach($record_old as $key => $val) {
if(isset($record_new[$key]) && $record_new[$key] != $val) {
// Record has changed
@@ -887,6 +901,17 @@ class tform {
$diffrec_full['new'][$key] = $val;
}
}
+ } elseif(is_array($record_new)) {
+ foreach($record_new as $key => $val) {
+ if(isset($record_new[$key]) && $record_old[$key] != $val) {
+ // Record has changed
+ $diffrec_full['new'][$key] = $val;
+ $diffrec_full['old'][$key] = $record_old[$key];
+ } else {
+ $diffrec_full['new'][$key] = $val;
+ $diffrec_full['old'][$key] = $val;
+ }
+ }
}
/*
@@ -903,7 +928,11 @@ class tform {
$diffstr = $app->db->quote(serialize($diffrec_full));
$username = $app->db->quote($_SESSION["s"]["user"]["username"]);
$dbidx = $this->formDef['db_table_idx'].":".$primary_id;
- $action = ($action == 'INSERT')?'i':'u';
+ // $action = ($action == 'INSERT')?'i':'u';
+
+ if($action == 'INSERT') $action = 'i';
+ if($action == 'UPDATE') $action = 'u';
+ if($action == 'DELETE') $action = 'd';
$sql = "INSERT INTO sys_datalog (dbtable,dbidx,server_id,action,tstamp,user,data) VALUES ('".$this->formDef['db_table']."','$dbidx','$server_id','$action','".time()."','$username','$diffstr')";
$app->db->query($sql);
}
diff --git a/interface/lib/classes/tform_actions.inc.php b/interface/lib/classes/tform_actions.inc.php
index f228e541465689c147d38e905a1ebc34f0a4aae5..89d974abd7ef00d6f2c301fec8fe5085c578e5c8 100644
--- a/interface/lib/classes/tform_actions.inc.php
+++ b/interface/lib/classes/tform_actions.inc.php
@@ -102,9 +102,13 @@ class tform_actions {
$ext_where = '';
$sql = $app->tform->getSQL($this->dataRecord,$app->tform->getCurrentTab(),'UPDATE',$this->id,$ext_where);
if($app->tform->errorMessage == '') {
+
+ if($app->tform->formDef['db_history'] == 'yes') {
+ $old_data_record = $app->tform->getDataRecord($this->id);
+ }
if(!empty($sql)) {
- $app->db->query($sql);
+ $app->db->query($sql);
if($app->db->errorMessage != '') die($app->db->errorMessage);
}
@@ -118,6 +122,14 @@ class tform_actions {
}
$this->onAfterUpdate();
+
+ // Write data history (sys_datalog)
+ if($app->tform->formDef['db_history'] == 'yes') {
+ $new_data_record = $app->tform->getDataRecord($this->id);
+ $app->tform->datalogSave('UPDATE',$this->id,$old_data_record,$new_data_record);
+ unset($new_data_record);
+ unset($old_data_record);
+ }
if($_REQUEST["next_tab"] == '') {
$list_name = $_SESSION["s"]["form"]["return_to"];
@@ -176,6 +188,13 @@ class tform_actions {
$this->onAfterInsert();
+ // Write data history (sys_datalog)
+ if($app->tform->formDef['db_history'] == 'yes') {
+ $new_data_record = $app->tform->getDataRecord($this->id);
+ $app->tform->datalogSave('INSERT',$this->id,array(),$new_data_record);
+ unset($new_data_record);
+ }
+
if($_REQUEST["next_tab"] == '') {
$list_name = $_SESSION["s"]["form"]["return_to"];
@@ -260,20 +279,10 @@ class tform_actions {
$record_old = $app->db->queryOneRecord("SELECT * FROM ".$liste["table"]." WHERE ".$liste["table_idx"]." = ".$this->id);
// Saving record to datalog when db_history enabled
- if($form["db_history"] == 'yes') {
- $diffrec = array();
-
- foreach($record_old as $key => $val) {
- // Record has changed
- $diffrec[$key] = array('old' => $val,
- 'new' => '');
- }
-
- $diffstr = $app->db->quote(serialize($diffrec));
- $username = $app->db->quote($_SESSION["s"]["user"]["username"]);
- $dbidx = $app->tform->formDef['db_table_idx'].":".$this->id;
- $sql = "INSERT INTO sys_datalog (dbtable,dbidx,action,tstamp,user,data) VALUES ('".$app->tform->formDef['db_table']."','$dbidx','d','".time()."','$username','$diffstr')";
- $app->db->query($sql);
+ if($app->tform->formDef["db_history"] == 'yes') {
+ $old_data_record = $app->tform->getDataRecord($this->id);
+ $app->tform->datalogSave('DELETE',$this->id,$old_data_record,array());
+ unset($old_data_record);
}
$app->db->query("DELETE FROM ".$liste["table"]." WHERE ".$liste["table_idx"]." = ".$this->id);
diff --git a/interface/web/sites/form/ftp_user.tform.php b/interface/web/sites/form/ftp_user.tform.php
index 9c13991721c7b267795cb62d83cfd770919347f3..4950a1b2d649abc0206c2261aacb67661a5333d9 100644
--- a/interface/web/sites/form/ftp_user.tform.php
+++ b/interface/web/sites/form/ftp_user.tform.php
@@ -99,6 +99,7 @@ $form["tabs"]['ftp'] = array (
'password' => array (
'datatype' => 'VARCHAR',
'formtype' => 'PASSWORD',
+ 'encryption' => 'CRYPT',
'default' => '',
'value' => '',
'width' => '30',
@@ -138,26 +139,26 @@ $form["tabs"]['advanced'] = array (
# Begin Datatable fields
##################################
'uid' => array (
- 'datatype' => 'INTEGER',
+ 'datatype' => 'VARCHAR',
'formtype' => 'TEXT',
'validators' => array ( 0 => array ( 'type' => 'NOTEMPTY',
'errmsg'=> 'uid_error_empty'),
),
'default' => '0',
'value' => '',
- 'width' => '5',
- 'maxlength' => '5'
+ 'width' => '30',
+ 'maxlength' => '255'
),
'gid' => array (
- 'datatype' => 'INTEGER',
+ 'datatype' => 'VARCHAR',
'formtype' => 'TEXT',
'validators' => array ( 0 => array ( 'type' => 'NOTEMPTY',
'errmsg'=> 'uid_error_empty'),
),
'default' => '0',
'value' => '',
- 'width' => '5',
- 'maxlength' => '5'
+ 'width' => '30',
+ 'maxlength' => '255'
),
'dir' => array (
'datatype' => 'VARCHAR',
diff --git a/interface/web/sites/templates/ftp_user_advanced.htm b/interface/web/sites/templates/ftp_user_advanced.htm
index 97a09a468c0d516f2419fadc0e9d1ef45658578a..b77b1e0e5ead6fd27d730e00ac6f05750c830f01 100644
--- a/interface/web/sites/templates/ftp_user_advanced.htm
+++ b/interface/web/sites/templates/ftp_user_advanced.htm
@@ -1,11 +1,11 @@
{tmpl_var name='uid_txt'}: |
- |
+ |
{tmpl_var name='gid_txt'}: |
- |
+ |
{tmpl_var name='dir_txt'}: |
diff --git a/interface/web/sites/web_domain_edit.php b/interface/web/sites/web_domain_edit.php
index e912002cc55538eb764917678faa3c6874342521..5f208dbafc2d202182bd7f659c7c8cdf493b92f0 100644
--- a/interface/web/sites/web_domain_edit.php
+++ b/interface/web/sites/web_domain_edit.php
@@ -167,7 +167,8 @@ class page_action extends tform_actions {
// Get configuration for the web system
$app->uses("getconf");
- $web_config = $app->getconf->get_server_config(intval($this->dataRecord["server_id"]),'web');
+ $web_rec = $app->tform->getDataRecord($this->id);
+ $web_config = $app->getconf->get_server_config(intval($web_rec["server_id"]),'web');
$document_root = str_replace("[website_id]",$this->id,$web_config["website_path"]);
// get the ID of the client
@@ -202,7 +203,8 @@ class page_action extends tform_actions {
// Get configuration for the web system
$app->uses("getconf");
- $web_config = $app->getconf->get_server_config(intval($this->dataRecord["server_id"]),'web');
+ $web_rec = $app->tform->getDataRecord($this->id);
+ $web_config = $app->getconf->get_server_config(intval($web_rec["server_id"]),'web');
$document_root = str_replace("[website_id]",$this->id,$web_config["website_path"]);
// get the ID of the client
@@ -211,7 +213,7 @@ class page_action extends tform_actions {
$client = $app->db->queryOneRecord("SELECT client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id");
$client_id = intval($client["client_id"]);
} else {
- $client_id = intval($this->dataRecord["client_group_id"]);
+ $client_id = intval($web_rec["client_group_id"]);
$client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = ".intval($this->dataRecord["client_group_id"]));
$client_id = intval($client["client_id"]);
}
diff --git a/server/conf/vhost.conf.master b/server/conf/vhost.conf.master
index ca4aa341435446490d04554cb7655aa857490798..79ea7d724a1cfcb650a60538cec536ae1ed4398a 100644
--- a/server/conf/vhost.conf.master
+++ b/server/conf/vhost.conf.master
@@ -1,25 +1,26 @@
-NameVirtualHost *:80
+# NameVirtualHost *:80
:80>
DocumentRoot
ServerName
+ ServerAlias
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ # cgi enabled
+
+
+ # ssi enabled
+
+
+ # suexec enabled
+
+
+ # mod_php enabled
+
+
+ # suphp enabled
+
+
+ # php as cgi enabled
+
\ No newline at end of file
diff --git a/server/lib/classes/file.inc.php b/server/lib/classes/file.inc.php
new file mode 100644
index 0000000000000000000000000000000000000000..e0bd12f6b4ec38648b8ed9026505e952f7a8186a
--- /dev/null
+++ b/server/lib/classes/file.inc.php
@@ -0,0 +1,319 @@
+log("WARNING: could not open file ".$file, 2);
+ return false;
+ } else {
+ if(filesize($file) > 0){
+ $content = fread($fp, filesize($file));
+ } else {
+ $content = "";
+ }
+ fclose($fp);
+ return $content;
+ }
+}
+
+function wf($file, $content){
+ global $app;
+ $this->mkdirs(dirname($file));
+ if(!$fp = fopen ($file, "wb")){
+ $app->log("WARNING: could not open file ".$file, 2);
+ return false;
+ } else {
+ fwrite($fp,$content);
+ fclose($fp);
+ return true;
+ }
+}
+
+function af($file, $content){
+ global $app;
+ $this->mkdirs(dirname($file));
+ if(!$fp = fopen ($file, "ab")){
+ $app->log("WARNING: could not open file ".$file, 2);
+ return false;
+ } else {
+ fwrite($fp,$content);
+ fclose($fp);
+ return true;
+ }
+}
+
+function no_comments($file, $comment = '#'){
+ $content = $this->unix_nl($this->rf($file));
+ $lines = explode("\n", $content);
+ if(!empty($lines)){
+ foreach($lines as $line){
+ if(strstr($line, $comment)){
+ $pos = strpos($line, $comment);
+ if($pos != 0){
+ $new_lines[] = substr($line,0,$pos);
+ } else {
+ $new_lines[] = "";
+ }
+ } else {
+ $new_lines[] = $line;
+ }
+ }
+ }
+ if(is_array($new_lines)){
+ $content_without_comments = implode("\n", $new_lines);
+ $new_lines = NULL;
+ return $content_without_comments;
+ } else {
+ return "";
+ }
+}
+
+function manual_entries($file, $separator = '#### MAKE MANUAL ENTRIES BELOW THIS LINE! ####'){
+ if(is_file($file)){
+ $content = $this->rf($file);
+ $parts = explode($separator, $content);
+ $manual = "\n".trim($parts[1]);
+ return $manual;
+ } else {
+ return "";
+ }
+}
+
+function remove_blank_lines($input, $file = 1){
+ //Leerzeilen löschen
+ if($file){
+ $content = $this->unix_nl($this->rf($input));
+ } else {
+ $content = $input;
+ }
+ $lines = explode("\n", $content);
+ if(!empty($lines)){
+ foreach($lines as $line){
+ if(trim($line) != "") $new_lines[] = $line;
+ }
+ }
+ if(is_array($new_lines)){
+ $content = implode("\n", $new_lines);
+ } else {
+ $content = "";
+ }
+ if($file){
+ $this->wf($input, $content);
+ } else {
+ return $content;
+ }
+}
+
+function unix_nl($input){
+ $output = str_replace("\r\n", "\n", $input);
+ $output = str_replace("\r", "\n", $output);
+ return $output;
+}
+
+function fileowner($file){
+ $owner_id = fileowner($file);
+ clearstatcache();
+ return $owner_id;
+}
+
+function mkdirs($strPath, $mode = '0755'){
+ // Verzeichnisse rekursiv erzeugen
+ if(is_dir($strPath)) return true;
+ $pStrPath = dirname($strPath);
+ if(!$this->mkdirs($pStrPath, $mode)) return false;
+ $old_umask = umask(0);
+ $ret_val = mkdir($strPath, octdec($mode));
+ umask($old_umask);
+ return $ret_val;
+}
+
+function find_includes($file){
+ ob_start();
+ $httpd_root = system('httpd -V | awk -F"\"" \'$1==" -D HTTPD_ROOT="{print $2}\'');
+ ob_end_clean();
+ clearstatcache();
+ if(is_file($file) && filesize($file) > 0){
+ $includes[] = $file;
+ $inhalt = $this->unix_nl($this->no_comments($file));
+ $lines = explode("\n", $inhalt);
+ if(!empty($lines)){
+ foreach($lines as $line){
+ if(stristr($line, "include ")){
+ $include_file = str_replace("\n", "", trim(shell_exec("echo \"$line\" | awk '{print \$2}'")));
+ if(substr($include_file,0,1) != "/"){
+ $include_file = $httpd_root."/".$include_file;
+ }
+ if(is_file($include_file)){
+ if($further_includes = $this->find_includes($include_file)){
+ $includes = array_merge($includes, $further_includes);
+ }
+ } else {
+ if(strstr($include_file, "*")){
+ $more_files = explode("\n", shell_exec("ls -l $include_file | awk '{print \$9}'"));
+ if(!empty($more_files)){
+ foreach($more_files as $more_file){
+ if(is_file($more_file)){
+ if($further_includes = $this->find_includes($more_file)){
+ $includes = array_merge($includes, $further_includes);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if(is_array($includes)){
+ $includes = array_unique($includes);
+ return $includes;
+ } else {
+ return false;
+ }
+}
+
+function edit_dist($var, $val){
+ global $$var;
+ $files = array("/root/ispconfig/dist.inc.php");
+ foreach($files as $file){
+ if(is_file($file)){
+ $file_content = $this->unix_nl($this->rf($file));
+ $lines = explode("\n", $file_content);
+ for($i=0;$iwf($file, $file_content);
+ }
+ }
+}
+
+function getDirectoryListing($dirname, $sortorder = "a", $show_subdirs = 0, $show_subdirfiles = 0, $exts = "", $ext_save = 1){
+// This function will return an array with filenames based on the criteria you can set in the variables
+// @sortorder : a for ascending (the standard) or d for descending (you can use the "r" for reverse as well, works the same)
+// @show_subdirs : 0 for NO, 1 for YES - meaning it will show the names of subdirectories if there are any
+// Logically subdirnames will not be checked for the required extentions
+// @show_subdirfiles : 0 for NO, 1 for YES - meaning it will show files from the subdirs
+// Files from subdirs will be prefixed with the subdir name and checked for the required extentions.
+// @exts can be either a string or an array, if not passed to the function, then the default will be a check for common image files
+// If exts is set to "all" then all extentions are allowed
+// @ext_save : 1 for YES, 0 for NO - meaning it will filter out system files or not (such as .htaccess)
+
+ $dirname = realpath($dirname);
+ if (!$exts || empty($exts) || $exts == "") {
+ $exts = array("jpg", "gif", "jpeg", "png");
+ }
+ if ($handle = opendir($dirname)) {
+ $filelist = array();
+ while (false !== ($file = readdir($handle))) {
+
+ // Filter out higher directory references
+ if ($file != "." && $file != "..") {
+ // Only look at directories or files, filter out symbolic links
+ if ( filetype ($dirname."/".$file) != "link") {
+ // If it's a file, check against valid extentions and add to the list
+ if ( filetype ($dirname."/".$file) == "file" ) {
+ if ($this->checkFileExtension($file, $exts, $ext_save)) {
+ $filelist[] = $file;
+ }
+ }
+ // If it's a directory and either subdirs should be listed or files from subdirs add relevant names to the list
+ else if ( filetype ($dirname."/".$file) == "dir" && ($show_subdirs == 1 || $show_subdirfiles == 1)) {
+ if ($show_subdirs == 1) {
+ $filelist[] = $file;
+ }
+ if ($show_subdirfiles == 1) {
+ $subdirname = $file;
+ $subdirfilelist = $this->getDirectoryListing($dirname."/".$subdirname."/", $sortorder, $show_subdirs, $show_subdirfiles, $exts, $ext_save);
+ for ($i = 0 ; $i < count($subdirfilelist) ; $i++) {
+ $subdirfilelist[$i] = $subdirname."/".$subdirfilelist[$i];
+ }
+ $filelist = array_merge($filelist, $subdirfilelist);
+ }
+
+ }
+
+ }
+ }
+ }
+ closedir($handle);
+
+ // Sort the results
+ if (count($filelist) > 1) {
+ natcasesort($filelist);
+ if ($sortorder == "d" || $sortorder == "r" ) {
+ $filelist = array_reverse($filelist, TRUE);
+ }
+ }
+ return $filelist;
+ }
+ else {
+ return false;
+ }
+}
+
+function checkFileExtension($filename, $exts, $ext_save = 1){
+ $passed = FALSE;
+ if ($ext_save == 1) {
+ if (preg_match("/^\./", $filename)) {
+ return $passed;
+ }
+ }
+ if ($exts == "all") {
+ $passed = TRUE;
+ return $passed;
+ }
+ if (is_string($exts)) {
+ if (eregi("\.". $exts ."$", $filename)) {
+ $passed = TRUE;
+ return $passed;
+ }
+ } else if (is_array($exts)) {
+ foreach ($exts as $theExt) {
+ if (eregi("\.". $theExt ."$", $filename)) {
+ $passed = TRUE;
+ return $passed;
+ }
+ }
+ }
+ return $passed;
+}
+
+}
+?>
\ No newline at end of file
diff --git a/server/lib/classes/services.inc.php b/server/lib/classes/services.inc.php
new file mode 100644
index 0000000000000000000000000000000000000000..260d3f0ed0fcd13c6a03fc2db04d1e578ac2e13a
--- /dev/null
+++ b/server/lib/classes/services.inc.php
@@ -0,0 +1,79 @@
+registered_services[$service_name])) {
+ $this->delayed_restarts[$service_name] = $action;
+ } else {
+ $app->log("Unable to add a delayed restart for '$service_name'. Service '$service_name' is not registered.",LOGLEVEL_WARNING);
+ }
+
+ }
+
+ // This function restarts a service when the function is called
+ function restartService($service_name,$action = 'restart') {
+ global $app;
+
+ if(is_array($this->registered_services[$service_name])) {
+ $module_name = $this->registered_services[$service_name]["module"];
+ $function_name = $this->registered_services[$service_name]["function"];
+ $app->log("Call function '$function_name' in module '$module_name'.",LOGLEVEL_DEBUG);
+ call_user_method($function_name,$app->loaded_modules[$module_name],$action);
+ } else {
+ $app->log("Unable to restart $service_name. Service $service_name is not registered.",LOGLEVEL_WARNING);
+ }
+
+ }
+
+ // This function is used to register callback functions for services that can be restarted
+ function registerService($service_name,$module_name, $function_name) {
+ global $app;
+ $this->registered_services[$service_name] = array('module' => $module_name, 'function' => $function_name);
+ $app->log("Registered Service '$service_name' in module '$module_name' for processing function '$function_name'",LOGLEVEL_DEBUG);
+ }
+
+ // This function is called at the end of the server script to restart services.
+ function processDelayedActions() {
+ global $app;
+ foreach($this->delayed_restarts as $service_name => $action) {
+ $this->restartService($service_name,$action);
+ }
+ }
+
+}
+?>
\ No newline at end of file
diff --git a/server/lib/classes/system.inc.php b/server/lib/classes/system.inc.php
new file mode 100644
index 0000000000000000000000000000000000000000..977ed33cd9a9f383db79e5395473fa7b320a8577
--- /dev/null
+++ b/server/lib/classes/system.inc.php
@@ -0,0 +1,999 @@
+server_id = $go_info["isp"]["server_id"];
+ $this->server_conf = $go_info["isp"]["server_conf"];
+ $this->server_conf["passwd_datei"] = '/etc/passwd';
+ $this->server_conf["shadow_datei"] = '/etc/shadow';
+ $this->server_conf["group_datei"] = '/etc/group';
+}
+
+function hostname(){
+ $dist = $this->server_conf["dist"];
+
+ ob_start();
+ passthru("hostname");
+ $hostname = ob_get_contents();
+ ob_end_clean();
+ $hostname = trim($hostname);
+ ob_start();
+ if(!strstr($dist, "freebsd")){
+ passthru("dnsdomainname");
+ } else {
+ passthru("domainname");
+ }
+ $domainname = ob_get_contents();
+ ob_end_clean();
+ $domainname = trim($domainname);
+ if($domainname != ""){
+ if(!strstr($hostname, $domainname)) $hostname .= ".".$domainname;
+ }
+ return $hostname;
+}
+
+function adduser($user_username, $uid, $gid, $username, $homedir, $shell, $passwort = '*'){
+ global $app;
+ if($this->is_user($user_username)){
+ return false;
+ } else {
+ if(trim($user_username) != '') {
+ $user_datei = $this->server_conf["passwd_datei"];
+ $shadow_datei = $this->server_conf["shadow_datei"];
+ $shell = realpath($shell);
+ if(trim($passwort) == "") $passwort = '*';
+ $new_user = "\n$user_username:x:$uid:$gid:$username:$homedir:$shell\n";
+ $app->log->msg("USER: $new_user");
+ $app->file->af($user_datei, $new_user);
+ if($shadow_datei == "/etc/shadow"){
+ $datum = time();
+ $tage = floor($datum/86400);
+ $new_passwd = "\n$user_username:$passwort:$tage:0:99999:7:::\n";
+ } else {
+ $new_passwd = "\n$user_username:$passwort:$uid:$gid::0:0:$username:$homedir:$shell\n";
+ }
+ $app->file->af($shadow_datei, $new_passwd);
+
+ // TB: leere Zeilen entfernen
+ $app->file->remove_blank_lines($shadow_datei);
+ $app->file->remove_blank_lines($user_datei);
+ // TB: user Sortierung deaktiviert
+ //$this->order_users_groups();
+ if($shadow_datei != "/etc/shadow"){
+ $app->file->af($shadow_datei, "\n");
+
+ // TB: leere Zeilen entfernen
+ $app->file->remove_blank_lines($shadow_datei);
+
+ $app->log->caselog("pwd_mkdb $shadow_datei &> /dev/null", $this->FILE, __LINE__);
+ }
+
+ return true;
+ }
+ }
+}
+
+function updateuser($user_username, $uid, $gid, $username, $homedir, $shell, $passwort = '*'){
+ $this->deluser($user_username);
+ $this->adduser($user_username, $uid, $gid, $username, $homedir, $shell, $passwort);
+}
+
+function deactivateuser($user_username){
+ $passwort = str_rot13($this->getpasswd($user_username));
+ $user_attr = $this->get_user_attributes($user_username);
+ $uid = $user_attr["uid"];
+ $gid = $user_attr["gid"];
+ $username = $user_attr["name"];
+ $homedir = $user_attr["homedir"];
+ $shell = "/dev/null";
+ $this->deluser($user_username);
+ $this->adduser($user_username, $uid, $gid, $username, $homedir, $shell, $passwort);
+}
+
+function deluser($user_username){
+ global $app;
+ if($this->is_user($user_username)){
+ $user_datei = $this->server_conf["passwd_datei"];
+ $shadow_datei = $this->server_conf["shadow_datei"];
+ $users = $app->file->rf($user_datei);
+ $lines = explode("\n", $users);
+ if(is_array($lines)){
+ $num_lines = sizeof($lines);
+ for($i=0;$i<$num_lines;$i++){
+ if(trim($lines[$i]) != ""){
+ list($f1,) = explode(":", $lines[$i]);
+ if($f1 != $user_username) $new_lines[] = $lines[$i];
+ }
+ }
+ $new_users = implode("\n", $new_lines);
+ $app->file->wf($user_datei, $new_users);
+ unset($new_lines);
+ unset($lines);
+ unset($new_users);
+ }
+ $app->file->remove_blank_lines($user_datei);
+
+ $passwds = $app->file->rf($shadow_datei);
+ $lines = explode("\n", $passwds);
+ if(is_array($lines)){
+ $num_lines = sizeof($lines);
+ for($i=0;$i<$num_lines;$i++){
+ if(trim($lines[$i]) != ""){
+ list($f1,) = explode(":", $lines[$i]);
+ if($f1 != $user_username) $new_lines[] = $lines[$i];
+ }
+ }
+ $new_passwds = implode("\n", $new_lines);
+ $app->file->wf($shadow_datei, $new_passwds);
+ unset($new_lines);
+ unset($lines);
+ unset($new_passwds);
+ }
+ $app->file->remove_blank_lines($shadow_datei);
+
+ $group_file = $app->file->rf($this->server_conf["group_datei"]);
+ $group_file_lines = explode("\n", $group_file);
+ foreach($group_file_lines as $group_file_line){
+ if(trim($group_file_line) != ""){
+ list($f1, $f2, $f3, $f4) = explode(":", $group_file_line);
+ $group_users = explode(",", str_replace(" ", "", $f4));
+ if(in_array($user_username, $group_users)){
+ $g_users = array();
+ foreach($group_users as $group_user){
+ if($group_user != $user_username) $g_users[] = $group_user;
+ }
+ $f4 = implode(",", $g_users);
+ }
+ $new_group_file[] = $f1.":".$f2.":".$f3.":".$f4;
+ }
+ }
+ $new_group_file = implode("\n", $new_group_file);
+ $app->file->wf($this->server_conf["group_datei"], $new_group_file);
+ // TB: auskommentiert
+ //$this->order_users_groups();
+
+ if($shadow_datei != "/etc/shadow"){
+ $app->file->af($shadow_datei, "\n");
+ $app->log->caselog("pwd_mkdb $shadow_datei &> /dev/null", $this->FILE, __LINE__);
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+function addgroup($group, $gid, $members = ''){
+ global $app;
+ if($this->is_group($group)){
+ return false;
+ } else {
+ $group_datei = $this->server_conf["group_datei"];
+ $shadow_datei = $this->server_conf["shadow_datei"];
+ $new_group = "\n$group:x:$gid:$members\n";
+ $app->file->af($group_datei, $new_group);
+
+ // TB: auskommentiert
+ //$this->order_users_groups();
+ if($shadow_datei != "/etc/shadow"){
+ $app->log->caselog("pwd_mkdb $shadow_datei &> /dev/null", $this->FILE, __LINE__);
+ }
+ return true;
+ }
+}
+
+function updategroup($group, $gid, $members = ''){
+ $this->delgroup($group);
+ $this->addgroup($group, $gid, $members);
+}
+
+function delgroup($group){
+ global $app;
+ if($this->is_group($group)){
+ $group_datei = $this->server_conf["group_datei"];
+ $shadow_datei = $this->server_conf["shadow_datei"];
+ $groups = $app->file->rf($group_datei);
+ $lines = explode("\n", $groups);
+ if(is_array($lines)){
+ $num_lines = sizeof($lines);
+ for($i=0;$i<$num_lines;$i++){
+ if(trim($lines[$i]) != ""){
+ list($f1,) = explode(":", $lines[$i]);
+ if($f1 != $group) $new_lines[] = $lines[$i];
+ }
+ }
+ $new_groups = implode("\n", $new_lines);
+ $app->file->wf($group_datei, $new_groups);
+ unset($new_lines);
+ unset($lines);
+ unset($new_groups);
+ }
+ // TB: auskommentiert
+ //$this->order_users_groups();
+ if($shadow_datei != "/etc/shadow"){
+ $app->log->caselog("pwd_mkdb $shadow_datei &> /dev/null", $this->FILE, __LINE__);
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+function order_users_groups(){
+ global $app;
+ $user_datei = $this->server_conf["passwd_datei"];
+ $shadow_datei = $this->server_conf["shadow_datei"];
+ $group_datei = $this->server_conf["group_datei"];
+
+ $groups = $app->file->no_comments($group_datei);
+ $lines = explode("\n", $groups);
+ if(is_array($lines)){
+ foreach($lines as $line){
+ if(trim($line) != ""){
+ list($f1, $f2, $f3, $f4) = explode(":", $line);
+ $arr[$f3] = $line;
+ }
+ }
+ }
+ ksort($arr);
+ reset($arr);
+ if($shadow_datei != "/etc/shadow"){
+ $app->file->wf($group_datei, $app->file->remove_blank_lines(implode("\n", $arr), 0)."\n");
+ }else {
+ $app->file->wf($group_datei, $app->file->remove_blank_lines(implode("\n", $arr), 0));
+ }
+ unset($arr);
+
+ $users = $app->file->no_comments($user_datei);
+ $lines = explode("\n", $users);
+ if(is_array($lines)){
+ foreach($lines as $line){
+ if(trim($line) != ""){
+ list($f1, $f2, $f3,) = explode(":", $line);
+ if($f1 != "toor"){
+ $arr[$f3] = $line;
+ } else {
+ $arr[70000] = $line;
+ }
+ }
+ }
+ }
+ ksort($arr);
+ reset($arr);
+ $app->file->wf($user_datei, $app->file->remove_blank_lines(implode("\n", $arr), 0));
+ unset($arr);
+
+ $passwds = $app->file->no_comments($shadow_datei);
+ $lines = explode("\n", $passwds);
+ if(is_array($lines)){
+ foreach($lines as $line){
+ if(trim($line) != ""){
+ list($f1, $f2, $f3,) = explode(":", $line);
+ if($f1 != "toor"){
+ $uid = $this->getuid($f1);
+ if(!is_bool($uid)) $arr[$uid] = $line;
+ } else {
+ $arr[70000] = $line;
+ }
+ }
+ }
+ }
+ ksort($arr);
+ reset($arr);
+ $app->file->wf($shadow_datei, $app->file->remove_blank_lines(implode("\n", $arr), 0));
+ unset($arr);
+}
+
+function find_uid_gid($min, $max){
+ global $app;
+ if($min < $max && $min >= 0 && $max >= 0 && $min <= 65536 && $max <= 65536 && is_int($min) && is_int($max)){
+ for($i=$min;$i<=$max;$i++){
+ $uid_arr[$i] = $gid_arr[$i] = 1;
+ }
+ $user_datei = $this->server_conf["passwd_datei"];
+ $group_datei = $this->server_conf["group_datei"];
+
+ $users = $app->file->no_comments($user_datei);
+ $lines = explode("\n", $users);
+ if(is_array($lines)){
+ foreach($lines as $line){
+ if(trim($line) != ""){
+ list($f1, $f2, $f3, $f4, $f5, $f6, $f7) = explode(":", $line);
+ if($f3 >= $min && $f3 <= $max) unset($uid_arr[$f3]);
+ }
+ }
+ if(!empty($uid_arr)){
+ foreach($uid_arr as $key => $val){
+ $uids[] = $key;
+ }
+ $min_uid = min($uids);
+ unset($uid_arr);
+ } else {
+ return false;
+ }
+ }
+
+ $groups = $app->file->no_comments($group_datei);
+ $lines = explode("\n", $groups);
+ if(is_array($lines)){
+ foreach($lines as $line){
+ if(trim($line) != ""){
+ list($f1, $f2, $f3, $f4) = explode(":", $line);
+ if($f3 >= $min && $f3 <= $max) unset($gid_arr[$f3]);
+ }
+ }
+ if(!empty($gid_arr)){
+ foreach($gid_arr as $key => $val){
+ $gids[] = $key;
+ }
+ $min_gid = min($gids);
+ unset($gid_arr);
+ } else {
+ return false;
+ }
+ }
+
+ $result = array_intersect($uids, $gids);
+ $new_id = (max($result));
+ unset($uids);
+ unset($gids);
+ unset($result);
+ if($new_id <= $max){
+ return $new_id;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+}
+
+function is_user($user){
+ global $app;
+ $user_datei = $this->server_conf["passwd_datei"];
+ $users = $app->file->no_comments($user_datei);
+ $lines = explode("\n", $users);
+ if(is_array($lines)){
+ foreach($lines as $line){
+ if(trim($line) != ""){
+ list($f1, $f2, $f3, $f4, $f5, $f6, $f7) = explode(":", $line);
+ if($f1 == $user) return true;
+ }
+ }
+ }
+ return false;
+}
+
+function is_group($group){
+ global $app;
+ $group_datei = $this->server_conf["group_datei"];
+ $groups = $app->file->no_comments($group_datei);
+ $lines = explode("\n", $groups);
+ if(is_array($lines)){
+ foreach($lines as $line){
+ if(trim($line) != ""){
+ list($f1, $f2, $f3, $f4) = explode(":", $line);
+ if($f1 == $group) return true;
+ }
+ }
+ }
+ return false;
+}
+
+function root_group(){
+ global $app;
+ $group_datei = $this->server_conf["group_datei"];
+ $groups = $app->file->no_comments($group_datei);
+ $lines = explode("\n", $groups);
+ if(is_array($lines)){
+ foreach($lines as $line){
+ if(trim($line) != ""){
+ list($f1, $f2, $f3, $f4) = explode(":", $line);
+ if($f3 == 0) return $f1;
+ }
+ }
+ }
+ return false;
+}
+
+function get_user_groups($username){
+ global $app;
+ $user_groups = array();
+ $group_datei = $this->server_conf["group_datei"];
+ $groups = $app->file->no_comments($group_datei);
+ $lines = explode("\n", $groups);
+ if(is_array($lines)){
+ foreach($lines as $line){
+ if(trim($line) != ""){
+ list($f1, $f2, $f3, $f4) = explode(":", $line);
+ if(intval($f3) < intval($this->server_conf["groupid_von"]) && trim($f1) != 'users'){
+ $tmp_group_users = explode(',', str_replace(' ', '', $f4));
+ if(in_array($username, $tmp_group_users) && trim($f1) != '') $user_groups[] = $f1;
+ unset($tmp_group_users);
+ }
+ }
+ }
+ }
+ if(!empty($user_groups)) return implode(',', $user_groups);
+ return '';
+}
+
+function getpasswd($user){
+ global $app;
+ if($this->is_user($user)){
+ $shadow_datei = $this->server_conf["shadow_datei"];
+ $passwds = $app->file->no_comments($shadow_datei);
+ $lines = explode("\n", $passwds);
+ if(is_array($lines)){
+ foreach($lines as $line){
+ if(trim($line) != ""){
+ list($f1, $f2,) = explode(":", $line);
+ if($f1 == $user) return $f2;
+ }
+ }
+ }
+ } else {
+ return false;
+ }
+}
+
+function getuid($user){
+ global $app;
+ if($this->is_user($user)){
+ $user_datei = $this->server_conf["passwd_datei"];
+ $users = $app->file->no_comments($user_datei);
+ $lines = explode("\n", $users);
+ if(is_array($lines)){
+ foreach($lines as $line){
+ if(trim($line) != ""){
+ list($f1, $f2, $f3,) = explode(":", $line);
+ if($f1 == $user) return $f3;
+ }
+ }
+ }
+ } else {
+ return false;
+ }
+}
+
+function get_user_attributes($user){
+ global $app;
+ if($this->is_user($user)){
+ $user_datei = $this->server_conf["passwd_datei"];
+ $users = $app->file->no_comments($user_datei);
+ $lines = explode("\n", $users);
+ if(is_array($lines)){
+ foreach($lines as $line){
+ if(trim($line) != ""){
+ list($f1, $f2, $f3, $f4, $f5, $f6, $f7) = explode(":", $line);
+ if($f1 == $user){
+ $user_attr["username"] = $f1;
+ $user_attr["x"] = $f2;
+ $user_attr["uid"] = $f3;
+ $user_attr["gid"] = $f4;
+ $user_attr["name"] = $f5;
+ $user_attr["homedir"] = $f6;
+ $user_attr["shell"] = $f7;
+ return $user_attr;
+ }
+ }
+ }
+ }
+ } else {
+ return false;
+ }
+}
+
+function chown($file, $owner, $group = ''){
+ $owner_change = @chown($file, $owner);
+ if($group != ""){
+ $group_change = @chgrp($file, $group);
+ } else {
+ $group_change = 1;
+ }
+ if($owner_change && $group_change){
+ return true;
+ } else {
+ return false;
+ }
+}
+
+function add_user_to_group($group, $user = 'admispconfig'){
+ global $app;
+ $group_file = $app->file->rf($this->server_conf["group_datei"]);
+ $group_file_lines = explode("\n", $group_file);
+ foreach($group_file_lines as $group_file_line){
+ list($group_name,$group_x,$group_id,$group_users) = explode(":",$group_file_line);
+ if($group_name == $group){
+ $group_users = explode(",", str_replace(" ", "", $group_users));
+ if(!in_array($user, $group_users)){
+ $group_users[] = $user;
+ }
+ $group_users = implode(",", $group_users);
+ if(substr($group_users,0,1) == ",") $group_users = substr($group_users,1);
+ $group_file_line = $group_name.":".$group_x.":".$group_id.":".$group_users;
+ }
+ $new_group_file[] = $group_file_line;
+ }
+ $new_group_file = implode("\n", $new_group_file);
+ $app->file->wf($this->server_conf["group_datei"], $new_group_file);
+ $app->file->remove_blank_lines($this->server_conf["group_datei"]);
+ if($this->server_conf["shadow_datei"] != "/etc/shadow"){
+ $app->log->caselog("pwd_mkdb ".$this->server_conf["shadow_datei"]." &> /dev/null", $this->FILE, __LINE__);
+ }
+}
+
+function usermod($user, $groups){
+ global $app;
+ if($this->is_user($user)){
+ $groups = explode(",", str_replace(" ", "", $groups));
+ $group_file = $app->file->rf($this->server_conf["group_datei"]);
+ $group_file_lines = explode("\n", $group_file);
+ foreach($group_file_lines as $group_file_line){
+ if(trim($group_file_line) != ""){
+ list($f1, $f2, $f3, $f4) = explode(":", $group_file_line);
+ $group_users = explode(",", str_replace(" ", "", $f4));
+ if(!in_array($f1, $groups)){
+ if(in_array($user, $group_users)){
+ $g_users = array();
+ foreach($group_users as $group_user){
+ if($group_user != $user) $g_users[] = $group_user;
+ }
+ $f4 = implode(",", $g_users);
+ }
+ } else {
+ if(!in_array($user, $group_users)){
+ if(trim($group_users[0]) == "") unset($group_users);
+ $group_users[] = $user;
+ }
+ $f4 = implode(",", $group_users);
+ }
+ $new_group_file[] = $f1.":".$f2.":".$f3.":".$f4;
+ }
+ }
+ $new_group_file = implode("\n", $new_group_file);
+ $app->file->wf($this->server_conf["group_datei"], $new_group_file);
+ $app->file->remove_blank_lines($this->server_conf["group_datei"]);
+ if($this->server_conf["shadow_datei"] != "/etc/shadow"){
+ $app->log->caselog("pwd_mkdb ".$this->server_conf["shadow_datei"]." &> /dev/null", $this->FILE, __LINE__);
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+function rc_edit($service, $rl, $action){
+ // $action = "on|off";
+ global $app;
+ $dist_init_scripts = $app->system->server_conf["dist_init_scripts"];
+ $dist_runlevel = $app->system->server_conf["dist_runlevel"];
+ $dist = $app->system->server_conf["dist"];
+ if(trim($dist_runlevel) == ""){ // falls es keine runlevel gibt (FreeBSD)
+ if($action == "on"){
+ @symlink($dist_init_scripts."/".$service, $dist_init_scripts."/".$service.".sh");
+ }
+ if($action == "off"){
+ if(is_link($dist_init_scripts."/".$service.".sh")){
+ unlink($dist_init_scripts."/".$service.".sh");
+ } else {
+ exec("mv -f ".$dist_init_scripts."/".$service.".sh ".$dist_init_scripts."/".$service." &> /dev/null");
+ }
+ }
+ } else { // Linux
+ if(substr($dist, 0,4) == 'suse'){
+ if($action == "on"){
+ exec("chkconfig --add $service &> /dev/null");
+ }
+ if($action == "off"){
+ exec("chkconfig --del $service &> /dev/null");
+ }
+ } else {
+ $runlevels = explode(",", $rl);
+ foreach($runlevels as $runlevel){
+ $runlevel = trim($runlevel);
+ if($runlevel != "" && is_dir($dist_runlevel."/rc".$runlevel.".d")){
+ $handle=opendir($dist_runlevel."/rc".$runlevel.".d");
+ while($file = readdir($handle)){
+ if($file != "." && $file != ".."){
+ $target = @readlink($dist_runlevel."/rc".$runlevel.".d/".$file);
+ if(strstr($file, $service) && strstr($target, $service) && substr($file,0,1) == "S") $ln_arr[$runlevel][] = $dist_runlevel."/rc".$runlevel.".d/".$file;
+ }
+ }
+ closedir($handle);
+ }
+ if($action == "on"){
+ if(!is_array($ln_arr[$runlevel])) @symlink($dist_init_scripts."/".$service, $dist_runlevel."/rc".$runlevel.".d/S99".$service);
+ }
+ if($action == "off"){
+ if(is_array($ln_arr[$runlevel])){
+ foreach($ln_arr[$runlevel] as $link){
+ unlink($link);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+function grep($content, $string, $params = ''){
+ global $app;
+ // params: i, v, w
+ $content = $app->file->unix_nl($content);
+ $lines = explode("\n", $content);
+ foreach($lines as $line){
+ if(!strstr($params, 'w')){
+ if(strstr($params, 'i')){
+ if(strstr($params, 'v')){
+ if(!stristr($line, $string)) $find[] = $line;
+ } else {
+ if(stristr($line, $string)) $find[] = $line;
+ }
+ } else {
+ if(strstr($params, 'v')){
+ if(!strstr($line, $string)) $find[] = $line;
+ } else {
+ if(strstr($line, $string)) $find[] = $line;
+ }
+ }
+ } else {
+ if(strstr($params, 'i')){
+ if(strstr($params, 'v')){
+ if(!$app->string->is_word($string, $line, 'i')) $find[] = $line;
+ } else {
+ if($app->string->is_word($string, $line, 'i')) $find[] = $line;
+ }
+ } else {
+ if(strstr($params, 'v')){
+ if(!$app->string->is_word($string, $line)) $find[] = $line;
+ } else {
+ if($app->string->is_word($string, $line)) $find[] = $line;
+ }
+ }
+ }
+ }
+ if(is_array($find)){
+ $ret_val = implode("\n", $find);
+ if(substr($ret_val,-1) != "\n") $ret_val .= "\n";
+ $find = NULL;
+ return $ret_val;
+ } else {
+ return false;
+ }
+}
+
+function cut($content, $field, $delimiter = ':'){
+ global $app;
+ $content = $app->file->unix_nl($content);
+ $lines = explode("\n", $content);
+ foreach($lines as $line){
+ $elms = explode($delimiter, $line);
+ $find[] = $elms[($field-1)];
+ }
+ if(is_array($find)){
+ $ret_val = implode("\n", $find);
+ if(substr($ret_val,-1) != "\n") $ret_val .= "\n";
+ $find = NULL;
+ return $ret_val;
+ } else {
+ return false;
+ }
+}
+
+function cat($file){
+ global $app;
+ return $app->file->rf($file);
+}
+
+function daemon_init($daemon, $action){
+ // $action = start|stop|restart|reload
+ global $app;
+ $dist = $this->server_conf["dist"];
+ $dist_init_scripts = $this->server_conf["dist_init_scripts"];
+ if(!strstr($dist, "freebsd")){
+ $app->log->caselog("$dist_init_scripts/$daemon $action &> /dev/null", $this->FILE, __LINE__);
+ } else {
+ if(is_file($dist_init_scripts."/".$daemon.".sh") || is_link($dist_init_scripts."/".$daemon.".sh")){
+ if($action == "start" || $action == "stop"){
+ $app->log->caselog($dist_init_scripts."/".$daemon.".sh ".$action." &> /dev/null", $this->FILE, __LINE__);
+ } else {
+ $app->log->caselog($dist_init_scripts."/".$daemon.".sh stop &> /dev/null", $this->FILE, __LINE__);
+ sleep(3);
+ $app->log->caselog($dist_init_scripts."/".$daemon.".sh start &> /dev/null", $this->FILE, __LINE__);
+ }
+ } else {
+ if(is_file($dist_init_scripts."/".$daemon) || is_link($dist_init_scripts."/".$daemon)){
+ if($action == "start" || $action == "stop"){
+ $app->log->caselog($dist_init_scripts."/".$daemon." ".$action." &> /dev/null", $this->FILE, __LINE__);
+ } else {
+ $app->log->caselog($dist_init_scripts."/".$daemon." stop &> /dev/null", $this->FILE, __LINE__);
+ sleep(3);
+ $app->log->caselog($dist_init_scripts."/".$daemon." start &> /dev/null", $this->FILE, __LINE__);
+ }
+ } else {
+ if(is_file("/etc/rc.d/".$daemon) || is_link("/etc/rc.d/".$daemon)){
+ if($action == "start" || $action == "stop"){
+ $app->log->caselog("/etc/rc.d/".$daemon." ".$action." &> /dev/null", $this->FILE, __LINE__);
+ } else {
+ $app->log->caselog("/etc/rc.d/".$daemon." stop &> /dev/null", $this->FILE, __LINE__);
+ sleep(3);
+ $app->log->caselog("/etc/rc.d/".$daemon." start &> /dev/null", $this->FILE, __LINE__);
+ }
+ }
+ }
+ }
+ }
+}
+
+function netmask($netmask){
+ list($f1,$f2,$f3,$f4) = explode(".", trim($netmask));
+ $bin = str_pad(decbin($f1),8,"0",STR_PAD_LEFT).str_pad(decbin($f2),8,"0",STR_PAD_LEFT).str_pad(decbin($f3),8,"0",STR_PAD_LEFT).str_pad(decbin($f4),8,"0",STR_PAD_LEFT);
+ $parts = explode("0", $bin);
+ $bin = str_pad($parts[0], 32, "0", STR_PAD_RIGHT);
+ $bin = wordwrap($bin, 8, ".", 1);
+ list($f1,$f2,$f3,$f4) = explode(".", trim($bin));
+ return bindec($f1).".".bindec($f2).".".bindec($f3).".".bindec($f4);
+}
+
+function binary_netmask($netmask){
+ list($f1,$f2,$f3,$f4) = explode(".", trim($netmask));
+ $bin = str_pad(decbin($f1),8,"0",STR_PAD_LEFT).str_pad(decbin($f2),8,"0",STR_PAD_LEFT).str_pad(decbin($f3),8,"0",STR_PAD_LEFT).str_pad(decbin($f4),8,"0",STR_PAD_LEFT);
+ $parts = explode("0", $bin);
+ return substr_count($parts[0], "1");
+}
+
+function network($ip, $netmask){
+ $netmask = $this->netmask($netmask);
+ list($f1,$f2,$f3,$f4) = explode(".", $netmask);
+ $netmask_bin = str_pad(decbin($f1),8,"0",STR_PAD_LEFT).str_pad(decbin($f2),8,"0",STR_PAD_LEFT).str_pad(decbin($f3),8,"0",STR_PAD_LEFT).str_pad(decbin($f4),8,"0",STR_PAD_LEFT);
+ list($f1,$f2,$f3,$f4) = explode(".", $ip);
+ $ip_bin = str_pad(decbin($f1),8,"0",STR_PAD_LEFT).str_pad(decbin($f2),8,"0",STR_PAD_LEFT).str_pad(decbin($f3),8,"0",STR_PAD_LEFT).str_pad(decbin($f4),8,"0",STR_PAD_LEFT);
+ for($i=0;$i<32;$i++){
+ $network_bin .= substr($netmask_bin,$i,1) * substr($ip_bin,$i,1);
+ }
+ $network_bin = wordwrap($network_bin, 8, ".", 1);
+ list($f1,$f2,$f3,$f4) = explode(".", trim($network_bin));
+ return bindec($f1).".".bindec($f2).".".bindec($f3).".".bindec($f4);
+}
+
+function broadcast($ip, $netmask){
+ $netmask = $this->netmask($netmask);
+ $binary_netmask = $this->binary_netmask($netmask);
+ list($f1,$f2,$f3,$f4) = explode(".", $ip);
+ $ip_bin = str_pad(decbin($f1),8,"0",STR_PAD_LEFT).str_pad(decbin($f2),8,"0",STR_PAD_LEFT).str_pad(decbin($f3),8,"0",STR_PAD_LEFT).str_pad(decbin($f4),8,"0",STR_PAD_LEFT);
+ $broadcast_bin = str_pad(substr($ip_bin, 0, $binary_netmask),32,"1",STR_PAD_RIGHT);
+ $broadcast_bin = wordwrap($broadcast_bin, 8, ".", 1);
+ list($f1,$f2,$f3,$f4) = explode(".", trim($broadcast_bin));
+ return bindec($f1).".".bindec($f2).".".bindec($f3).".".bindec($f4);
+}
+
+function network_info(){
+ $dist = $this->server_conf["dist"];
+ ob_start();
+ passthru("ifconfig");
+ $output = ob_get_contents();
+ ob_end_clean();
+ $lines = explode("\n", $output);
+ foreach($lines as $line){
+ $elms = explode(" ", $line);
+ if(trim($elms[0]) != "" && substr($elms[0],0,1) != "\t"){
+ $elms[0] = trim($elms[0]);
+ if(strstr($dist, "freebsd")) $elms[0] = substr($elms[0],0,-1);
+ $interfaces[] = $elms[0];
+ }
+ }
+ if(!empty($interfaces)){
+ foreach($interfaces as $interface){
+ ob_start();
+ if(!strstr($dist, "freebsd")){
+ passthru("ifconfig ".$interface." | grep -iw 'inet' | cut -f2 -d: | cut -f1 -d' '");
+ }else {
+ passthru("ifconfig ".$interface." | grep -iw 'inet' | grep -iv 'inet6' | cut -f2 -d' '");
+ }
+ $output = trim(ob_get_contents());
+ ob_end_clean();
+ if($output != ""){
+ $ifconfig["INTERFACE"][$interface] = $output;
+ $ifconfig["IP"][$output] = $interface;
+ }
+ }
+ if(!empty($ifconfig)){
+ return $ifconfig;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+}
+
+function network_config(){
+ $ifconfig = $this->network_info();
+ if($ifconfig){
+ $main_interface = $ifconfig["IP"][$this->server_conf["server_ip"]];
+ if(strstr($main_interface, ":")){
+ $parts = explode(":", $main_interface);
+ $main_interface = trim($parts[0]);
+ }
+ if($main_interface != ""){
+ $ips = $this->data["isp_server_ip"];
+ if(!empty($ips)){
+ foreach($ips as $ip){
+ if(!isset($ifconfig["IP"][$ip["server_ip"]])){
+ $to_set[] = $ip["server_ip"];
+ } else {
+ unset($ifconfig["IP"][$ip["server_ip"]]);
+ }
+ }
+ if(!empty($ifconfig["IP"])){
+ foreach($ifconfig["IP"] as $key => $val){
+ if(!strstr($val, "lo") && !strstr($val, "lp") && strstr($val, $main_interface)){
+ exec("ifconfig ".$val." down &> /dev/null");
+ unset($ifconfig["INTERFACE"][$val]);
+ }
+ }
+ }
+ if(!empty($to_set)){
+ foreach($to_set as $to){
+ $i = 0;
+ while($i >= 0){
+ if(isset($ifconfig["INTERFACE"][$main_interface.":".$i])){
+ $i++;
+ } else {
+ $new_interface = $main_interface.":".$i;
+ $i = -1;
+ }
+ }
+ exec("ifconfig ".$new_interface." ".$to." netmask ".$this->server_conf["server_netzmaske"]." up &> /dev/null");
+ $ifconfig["INTERFACE"][$new_interface] = $to;
+ }
+ }
+ }
+ }
+ }
+}
+
+function quota_dirs(){
+ global $app;
+ $content = $app->file->unix_nl($app->file->no_comments("/etc/fstab"));
+ $lines = explode("\n", $content);
+ foreach($lines as $line){
+ $line = trim($line);
+ if($line != ""){
+ $elms = explode("\t", $line);
+ foreach($elms as $elm){
+ if(trim($elm) != "") $f[] = $elm;
+ }
+ if(!empty($f) && stristr($f[3], "userquota") && stristr($f[3], "groupquota")){
+ $q_dirs[] = trim($f[1]);
+ }
+ unset($f);
+ }
+ }
+ if(!empty($q_dirs)){
+ return $q_dirs;
+ } else {
+ return false;
+ }
+}
+
+function make_trashscan(){
+ global $app;
+ //trashscan erstellen
+ // Template Öffnen
+ $app->tpl->clear_all();
+ $app->tpl->define( array(table => "trashscan.master"));
+
+ if(!isset($this->server_conf["virusadmin"]) || trim($this->server_conf["virusadmin"]) == "") $this->server_conf["virusadmin"] = "admispconfig@localhost";
+ if(substr($this->server_conf["virusadmin"],0,1) == "#"){
+ $notify = "no";
+ } else {
+ $notify = "yes";
+ }
+
+ // Variablen zuweisen
+ $app->tpl->assign( array(VIRUSADMIN => $this->server_conf["virusadmin"],
+ NOTIFICATION => $notify));
+
+ $app->tpl->parse(TABLE, table);
+
+ $trashscan_text = $app->tpl->fetch();
+
+ $datei = "/home/admispconfig/ispconfig/tools/clamav/bin/trashscan";
+ $app->file->wf($datei, $trashscan_text);
+
+ exec("chown admispconfig:admispconfig $datei &> /dev/null");
+ exec("chmod 755 $datei");
+}
+
+function get_time(){
+ $addr = "http://www.ispconfig.org/";
+ $timeout = 1;
+ $url_parts = parse_url($addr);
+ $path = $url_parts["path"];
+ $port = 80;
+ $urlHandle = @fsockopen($url_parts["host"], $port, $errno, $errstr, $timeout);
+ if ($urlHandle){
+ socket_set_timeout($urlHandle, $timeout);
+
+ $urlString = "GET $path HTTP/1.0\r\nHost: ".$url_parts["host"]."\r\nConnection: Keep-Alive\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n";
+ if ($user) $urlString .= "Authorization: Basic ".base64_encode("$user:$pass")."\r\n";
+ $urlString .= "\r\n";
+ fputs($urlHandle, $urlString);
+
+ $month["Jan"] = "01";
+ $month["Feb"] = "02";
+ $month["Mar"] = "03";
+ $month["Apr"] = "04";
+ $month["May"] = "05";
+ $month["Jun"] = "06";
+ $month["Jul"] = "07";
+ $month["Aug"] = "08";
+ $month["Sep"] = "09";
+ $month["Oct"] = "10";
+ $month["Nov"] = "11";
+ $month["Dec"] = "12";
+ $c = 0;
+ $l = 0;
+ $startzeit = time();
+ while(!feof($urlHandle) && $c < 2 && $l == 0){
+ $line = trim(fgets($urlHandle,128));
+ $response .= $line;
+ $c = time() - $startzeit;
+ if($line == "" || substr($line, 0, 5) == "Date:") $l += 1; // nur den Header auslesen
+ if(substr($line, 0, 5) == "Date:"){
+ $parts = explode(" ", $line);
+ $tag = $parts[2];
+ $monat = $month[$parts[3]];
+ $jahr = $parts[4];
+ list($stunde, $minute, $sekunde) = explode(":", $parts[5]);
+ $timestamp = mktime($stunde,$minute,$sekunde,$monat,$tag,$jahr);
+ }
+ }
+
+ @fclose($urlHandle);
+
+ return $timestamp;
+ } else {
+ @fclose($urlHandle);
+ return false;
+ }
+}
+
+}
+?>
\ No newline at end of file
diff --git a/server/lib/classes/tpl.inc.php b/server/lib/classes/tpl.inc.php
new file mode 100644
index 0000000000000000000000000000000000000000..e16f0dcb1adc37d2e3e27ff4bf9347ef4c515a54
--- /dev/null
+++ b/server/lib/classes/tpl.inc.php
@@ -0,0 +1,1499 @@
+ |
+// +----------------------------------------------------------------------+
+//
+// $Id: class.tpl.inc.php,v 1.1 2003/07/08 12:31:10 platinum Exp $
+
+// check to avoid multiple including of class
+if (!defined('vlibTemplateClassLoaded')) {
+ define('vlibTemplateClassLoaded', 1);
+
+ include_once ($conf['classpath'].'/tpl_error.inc.php');
+ include_once ($conf['classpath'].'/tpl_ini.inc.php');
+
+ /**
+ * vlibTemplate is a class used to seperate PHP and HTML.
+ * For instructions on how to use vlibTemplate, see the
+ * vlibTemplate.html file, located in the 'docs' directory.
+ *
+ * @since 07/03/2002
+ * @author Kelvin Jones
+ * @package vLIB
+ * @access public
+ * @see vlibTemplate.html
+ */
+
+ class tpl {
+
+ /*-----------------------------------------------------------------------------\
+ | ATTENTION |
+ | Do not touch the following variables. vlibTemplate will not work otherwise. |
+ \-----------------------------------------------------------------------------*/
+
+ var $OPTIONS = array(
+ 'MAX_INCLUDES' => 10,
+ 'TEMPLATE_DIR' => null,
+ 'GLOBAL_VARS' => null,
+ 'GLOBAL_CONTEXT_VARS' => null,
+ 'LOOP_CONTEXT_VARS' => null,
+ 'SET_LOOP_VAR' => null,
+ 'DEFAULT_ESCAPE' => null,
+ 'STRICT' => null,
+ 'CASELESS' => null,
+ 'UNKNOWNS' => null,
+ 'TIME_PARSE' => null,
+ 'ENABLE_PHPINCLUDE' => null,
+ 'INCLUDE_PATHS' => array(),
+ 'CACHE_DIRECTORY' => null,
+ 'CACHE_LIFETIME' => null,
+ 'CACHE_EXTENSION' => null
+ );
+
+ /** open and close tags used for escaping */
+ var $ESCAPE_TAGS = array(
+ 'html' => array('open' => 'htmlspecialchars('
+ ,'close'=> ', ENT_QUOTES)'),
+ 'url' => array('open' => 'urlencode('
+ ,'close'=> ')'),
+ 'rawurl'=>array('open' => 'rawurlencode('
+ ,'close'=> ')'),
+ 'sq' => array('open' => 'addcslashes('
+ ,'close'=> ", \"'\")"),
+ 'dq' => array('open' => 'addcslashes('
+ ,'close'=> ", '\"')"),
+ '1' => array('open' => 'htmlspecialchars('
+ ,'close'=> ', ENT_QUOTES)'),
+ '0' => array('open' => ''
+ ,'close'=> ''),
+ 'none' => array('open' => ''
+ ,'close'=> ''),
+ 'hex' => array('open' => '$this->_escape_hex(',
+ 'close'=> ', false)'),
+ 'hexentity' => array('open' => '$this->_escape_hex(',
+ 'close'=> ', true)')
+ );
+
+ /** open and close tags used for formatting */
+ var $FORMAT_TAGS = array(
+ 'strtoupper' => array('open' => 'strtoupper(',
+ 'close'=> ')'),
+ 'uc' => array('open' => 'strtoupper(',
+ 'close'=> ')'),
+ 'strtolower' => array('open' => 'strtolower(',
+ 'close'=> ')'),
+ 'lc' => array('open' => 'strtolower(',
+ 'close'=> ')'),
+ 'ucfirst' => array('open' => 'ucfirst(',
+ 'close'=> ')'),
+ 'lcucfirst' => array('open' => 'ucfirst(strtolower(',
+ 'close'=> '))'),
+ 'ucwords' => array('open' => 'ucwords(',
+ 'close'=> ')'),
+ 'lcucwords' => array('open' => 'ucwords(strtolower(',
+ 'close'=> '))')
+ );
+
+ /** operators allowed when using extended TMPL_IF syntax */
+ var $allowed_if_ops = array('==','!=','<>','<','>','<=','>=');
+
+ /** dbs allowed by vlibTemplate::setDbLoop(). */
+ var $allowed_loop_dbs = array('MYSQL','POSTGRESQL','INFORMIX','INTERBASE','INGRES',
+ 'MSSQL','MSQL','OCI8','ORACLE','OVRIMOS','SYBASE');
+
+ /** root directory of vlibTemplate automagically filled in */
+ var $VLIBTEMPLATE_ROOT = null;
+
+ /** contains current directory used when doing recursive include */
+ var $_currentincludedir = array();
+
+ /** current depth of includes */
+ var $_includedepth = 0;
+
+ /** full path to tmpl file */
+ var $_tmplfilename = null;
+
+ /** file data before it's parsed */
+ var $_tmplfile = null;
+
+ /** parsed version of file, ready for eval()ing */
+ var $_tmplfilep = null;
+
+ /** eval()ed version ready for printing or whatever */
+ var $_tmploutput = null;
+
+ /** array for variables to be kept */
+ var $_vars = array();
+
+ /** array where loop variables are kept */
+ var $_arrvars = array();
+
+ /** array which holds the current namespace during parse */
+ var $_namespace = array();
+
+ /** variable is set to true once the template is parsed, to save re-parsing everything */
+ var $_parsed = false;
+
+ /** array holds all unknowns vars */
+ var $_unknowns = array();
+
+ /** microtime when template parsing began */
+ var $_firstparsetime = null;
+
+ /** total time taken to parse template */
+ var $_totalparsetime = null;
+
+ /** name of current loop being passed in */
+ var $_currloopname = null;
+
+ /** rows with the above loop */
+ var $_currloop = array();
+
+ /** define vars to avoid warnings */
+ var $_debug = null;
+ var $_cache = null;
+
+ /** array which holds the dynamic Includes */
+ var $_dyninclude = array();
+ /*-----------------------------------------------------------------------------\
+ | public functions |
+ \-----------------------------------------------------------------------------*/
+
+
+ /**
+ * FUNCTION: newTemplate
+ *
+ * Usually called by the class constructor.
+ * Stores the filename in $this->_tmplfilename.
+ * Raises an error if the template file is not found.
+ *
+ * @param string $tmplfile full path to template file
+ * @return boolean true
+ * @access public
+ */
+ function newTemplate ($tmplfile) {
+ if (!$tfile = $this->_fileSearch($tmplfile)) vlibTemplateError::raiseError('VT_ERROR_NOFILE',KILL,$tmplfile);
+
+ // make sure that any parsing vars are cleared for the new template
+ $this->_tmplfile = null;
+ $this->_tmplfilep = null;
+ $this->_tmploutput = null;
+ $this->_parsed = false;
+ $this->_unknowns = array();
+ $this->_firstparsetime = null;
+ $this->_totalparsetime = null;
+
+ // reset debug module
+ if ($this->_debug) $this->_debugReset();
+
+ $this->_tmplfilename = $tfile;
+ return true;
+ }
+
+ /**
+ * FUNCTION: setVar
+ *
+ * Sets variables to be used by the template
+ * If $k is an array, then it will treat it as an associative array
+ * using the keys as variable names and the values as variable values.
+ *
+ * @param mixed $k key to define variable name
+ * @param mixed $v variable to assign to $k
+ * @return boolean true/false
+ * @access public
+ */
+ function setVar ($k,$v=null) {
+ if (is_array($k)) {
+ foreach($k as $key => $value){
+ $key = ($this->OPTIONS['CASELESS']) ? strtolower(trim($key)) : trim($key);
+ if (preg_match('/^[A-Za-z_]+[A-Za-z0-9_]*$/', $key) && $value !== null ) {
+ $this->_vars[$key] = $value;
+ }
+ }
+ }
+ else {
+ if (preg_match('/^[A-Za-z_]+[A-Za-z0-9_]*$/', $k) && $v !== null) {
+ if ($this->OPTIONS['CASELESS']) $k = strtolower($k);
+ $this->_vars[trim($k)] = $v;
+ }
+ else {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * FUNCTION: setInclude
+ *
+ * Sets dynamic includes to be used by the template
+ * If $k is an array, then it will treat it as an associative array
+ * using the keys as variable names and the values as variable values.
+ *
+ * @param mixed $k key to define variable name
+ * @param mixed $v variable to assign to $k
+ * @return boolean true/false
+ * @access public
+ */
+
+ function setInclude($k, $v = null) {
+ if(is_array($k)) {
+ foreach($k as $key => $val) {
+ $this->_dyninclude[$key] = $val;
+ }
+ } else {
+ $this->_dyninclude[$k] = $v;
+ }
+
+ return true;
+ }
+
+ /**
+ * FUNCTION: unsetVar
+ *
+ * Unsets a variable which has already been set
+ * Parse in all vars wanted for deletion in seperate parametres
+ *
+ * @param string var name to remove use: vlibTemplate::unsetVar(var[, var..])
+ * @return boolean true/false returns true unless called with 0 params
+ * @access public
+ */
+ function unsetVar () {
+ $num_args = func_num_args();
+ if ($num_args < 1) return false;
+
+ for ($i = 0; $i < $num_args; $i++) {
+ $var = func_get_arg($i);
+ if ($this->OPTIONS['CASELESS']) $var = strtolower($var);
+ if (!preg_match('/^[A-Za-z_]+[A-Za-z0-9_]*$/', $var)) continue;
+ unset($this->_vars[$var]);
+ }
+ return true;
+ }
+
+ /**
+ * FUNCTION: getVars
+ *
+ * Gets all vars currently set in global namespace.
+ *
+ * @return array
+ * @access public
+ */
+ function getVars () {
+ if (empty($this->_vars)) return false;
+ return $this->_vars;
+ }
+
+ /**
+ * FUNCTION: getVar
+ *
+ * Gets a single var from the global namespace
+ *
+ * @return var
+ * @access public
+ */
+ function getVar ($var) {
+ if ($this->OPTIONS['CASELESS']) $var = strtolower($var);
+ if (empty($var) || !isset($this->_vars[$var])) return false;
+ return $this->_vars[$var];
+ }
+
+ /**
+ * FUNCTION: setContextVars
+ *
+ * sets the GLOBAL_CONTEXT_VARS
+ *
+ * @return true
+ * @access public
+ */
+ function setContextVars () {
+ $_phpself = @$GLOBALS['HTTP_SERVER_VARS']['PHP_SELF'];
+ $_pathinfo = @$GLOBALS['HTTP_SERVER_VARS']['PATH_INFO'];
+ $_request_uri = @$GLOBALS['HTTP_SERVER_VARS']['REQUEST_URI'];
+ $_qs = @$GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING'];
+
+ // the following fixes bug of $PHP_SELF on Win32 CGI and IIS.
+ $_self = (!empty($_pathinfo)) ? $_pathinfo : $_phpself;
+ $_uri = (!empty($_request_uri)) ? $_request_uri : $_self.'?'.$_qs;
+
+ $this->setvar('__SELF__', $_self);
+ $this->setvar('__REQUEST_URI__', $_uri);
+ return true;
+ }
+
+ /**
+ * FUNCTION: setLoop
+ *
+ * Builds the loop construct for use with .
+ *
+ * @param string $k string to define loop name
+ * @param array $v array to assign to $k
+ * @return boolean true/false
+ * @access public
+ */
+ function setLoop ($k,$v) {
+ if (is_array($v) && preg_match('/^[A-Za-z_]+[A-Za-z0-9_]*$/', $k)) {
+ $k = ($this->OPTIONS['CASELESS']) ? strtolower(trim($k)) : trim($k);
+ $this->_arrvars[$k] = array();
+ if ($this->OPTIONS['SET_LOOP_VAR'] && !empty($v)) $this->setvar($k, 1);
+ if (($this->_arrvars[$k] = $this->_arrayBuild($v)) == false) {
+ vlibTemplateError::raiseError('VT_WARNING_INVALID_ARR',WARNING,$k);
+ }
+ }
+ return true;
+ }
+
+ /**
+ * FUNCTION: setDbLoop [** EXPERIMENTAL **]
+ *
+ * Function to create a loop from a Db result resource link.
+ *
+ * @param string $loopname to commit loop. If not set, will use last loopname set using newLoop()
+ * @param string $result link to a Db result resource
+ * @param string $db_type, type of db that the result resource belongs to.
+ * @return boolean true/false
+ * @access public
+ */
+ function setDbLoop ($loopname, $result, $db_type='MYSQL') {
+ $db_type = strtoupper($db_type);
+ if (!in_array($db_type, $this->allowed_loop_dbs)) {
+ vlibTemplateError::raiseError('VT_WARNING_INVALID_LOOP_DB',WARNING, $db_type);
+ return false;
+ }
+
+ $loop_arr = array();
+ switch ($db_type) {
+
+ case 'MYSQL':
+ if (get_resource_type($result) != 'mysql result') {
+ vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE',WARNING, $db_type);
+ return false;
+ }
+ while($r = mysql_fetch_assoc($result)) {
+ $loop_arr[] = $r;
+ }
+ break;
+
+ case 'POSTGRESQL':
+ if (get_resource_type($result) != 'pgsql result') {
+ vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE',WARNING, $db_type);
+ return false;
+ }
+
+ $nr = (function_exists('pg_num_rows')) ? pg_num_rows($result) : pg_numrows($result);
+
+ for ($i=0; $i < $nr; $i++) {
+ $loop_arr[] = pg_fetch_array($result, $i, PGSQL_ASSOC);
+ }
+ break;
+
+ case 'INFORMIX':
+ if (!$result) {
+ vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE',WARNING, $db_type);
+ return false;
+ }
+ while($r = ifx_fetch_row($result, 'NEXT')) {
+ $loop_arr[] = $r;
+ }
+ break;
+
+ case 'INTERBASE':
+ if (get_resource_type($result) != 'interbase result') {
+ vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE',WARNING, $db_type);
+ return false;
+ }
+ while($r = ibase_fetch_row($result)) {
+ $loop_arr[] = $r;
+ }
+ break;
+
+ case 'INGRES':
+ if (!$result) {
+ vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE',WARNING, $db_type);
+ return false;
+ }
+ while($r = ingres_fetch_array(INGRES_ASSOC, $result)) {
+ $loop_arr[] = $r;
+ }
+ break;
+
+ case 'MSSQL':
+ if (get_resource_type($result) != 'mssql result') {
+ vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE',WARNING, $db_type);
+ return false;
+ }
+ while($r = mssql_fetch_array($result)) {
+ $loop_arr[] = $r;
+ }
+ break;
+
+ case 'MSQL':
+ if (get_resource_type($result) != 'msql result') {
+ vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE',WARNING, $db_type);
+ return false;
+ }
+ while($r = msql_fetch_array($result, MSQL_ASSOC)) {
+ $loop_arr[] = $r;
+ }
+ break;
+
+ case 'OCI8':
+ if (get_resource_type($result) != 'oci8 statement') {
+ vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE',WARNING, $db_type);
+ return false;
+ }
+ while(OCIFetchInto($result, &$r, OCI_ASSOC+OCI_RETURN_LOBS)) {
+ $loop_arr[] = $r;
+ }
+ break;
+
+ case 'ORACLE':
+ if (get_resource_type($result) != 'oracle Cursor') {
+ vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE',WARNING, $db_type);
+ return false;
+ }
+ while(ora_fetch_into($result, &$r, ORA_FETCHINTO_ASSOC)) {
+ $loop_arr[] = $r;
+ }
+ break;
+
+ case 'OVRIMOS':
+ if (!$result) {
+ vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE',WARNING, $db_type);
+ return false;
+ }
+ while(ovrimos_fetch_into($result, &$r, 'NEXT')) {
+ $loop_arr[] = $r;
+ }
+ break;
+
+ case 'SYBASE':
+ if (get_resource_type($result) != 'sybase-db result') {
+ vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE',WARNING, $db_type);
+ return false;
+ }
+
+ while($r = sybase_fetch_array($result)) {
+ $loop_arr[] = $r;
+ }
+ break;
+ }
+ $this->setLoop($loopname, $loop_arr);
+ return true;
+ }
+
+ /**
+ * FUNCTION: newLoop
+ *
+ * Sets the name for the curent loop in the 3 step loop process.
+ *
+ * @param string $name string to define loop name
+ * @return boolean true/false
+ * @access public
+ */
+ function newLoop ($loopname) {
+ if (preg_match('/^[a-z_]+[a-z0-9_]*$/i', $loopname)) {
+ $this->_currloopname[$loopname] = $loopname;
+ $this->_currloop[$loopname] = array();
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ /**
+ * FUNCTION: addRow
+ *
+ * Adds a row to the current loop in the 3 step loop process.
+ *
+ * @param array $row loop row to add to current loop
+ * @param string $loopname loop to which you want to add row, if not set will use last loop set using newLoop().
+ * @return boolean true/false
+ * @access public
+ */
+ function addRow ($row, $loopname=null) {
+ if (!$loopname) $loopname = $this->_currloopname[(count($this->_currloopname)-1)];
+
+ if (!isset($this->_currloop[$loopname]) || empty($this->_currloopname)) {
+ vlibTemplateError::raiseError('VT_WARNING_LOOP_NOT_SET',WARNING);
+ return false;
+ }
+ if (is_array($row)) {
+ $this->_currloop[$loopname][] = $row;
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ /**
+ * FUNCTION: addLoop
+ *
+ * Completes the 3 step loop process. This assigns the rows and resets
+ * the variables used.
+ *
+ * @param string $loopname to commit loop. If not set, will use last loopname set using newLoop()
+ * @return boolean true/false
+ * @access public
+ */
+ function addLoop ($loopname=null) {
+ if ($loopname == null) { // add last loop used
+ if (!empty($this->_currloop)) {
+ foreach ($this->_currloop as $k => $v) {
+ $this->setLoop($k, $v);
+ unset($this->_currloop[$k]);
+ }
+ $this->_currloopname = array();
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ elseif (!isset($this->_currloop[$loopname]) || empty($this->_currloopname)) { // newLoop not yet envoked
+ vlibTemplateError::raiseError('VT_WARNING_LOOP_NOT_SET',WARNING);
+ return false;
+ }
+ else { // add a specific loop
+ $this->setLoop($loopname, $this->_currloop[$loopname]);
+ unset($this->_currloopname[$loopname], $this->_currloop[$loopname]);
+ }
+ return true;
+ }
+
+ /**
+ * FUNCTION: unsetLoop
+ *
+ * Unsets a loop which has already been set.
+ * Can only unset top level loops.
+ *
+ * @param string loop to remove use: vlibTemplate::unsetLoop(loop[, loop..])
+ * @return boolean true/false returns true unless called with 0 params
+ * @access public
+ */
+ function unsetLoop () {
+ $num_args = func_num_args();
+ if ($num_args < 1) return false;
+
+ for ($i = 0; $i < $num_args; $i++) {
+ $var = func_get_arg($i);
+ if ($this->OPTIONS['CASELESS']) $var = strtolower($var);
+ if (!preg_match('/^[A-Za-z_]+[A-Za-z0-9_]*$/', $var)) continue;
+ unset($this->_arrvars[$var]);
+ }
+ return true;
+ }
+
+
+ /**
+ * FUNCTION: reset
+ *
+ * Resets the vlibTemplate object. After using vlibTemplate::reset() you must
+ * use vlibTemplate::newTemplate(tmpl) to reuse, not passing in the options array.
+ *
+ * @return boolean true
+ * @access public
+ */
+ function reset () {
+ $this->clearVars();
+ $this->clearLoops();
+ $this->_tmplfilename = null;
+ $this->_tmplfile = null;
+ $this->_tmplfilep = null;
+ $this->_tmploutput = null;
+ $this->_parsed = false;
+ $this->_unknowns = array();
+ $this->_firstparsetime = null;
+ $this->_totalparsetime = null;
+ $this->_currloopname = null;
+ $this->_currloop = array();
+ return true;
+ }
+
+ /**
+ * FUNCTION: clearVars
+ *
+ * Unsets all variables in the template
+ *
+ * @return boolean true
+ * @access public
+ */
+ function clearVars () {
+ $this->_vars = array();
+ return true;
+ }
+
+ /**
+ * FUNCTION: clearLoops
+ *
+ * Unsets all loops in the template
+ *
+ * @return boolean true
+ * @access public
+ */
+ function clearLoops () {
+ $this->_arrvars = array();
+ $this->_currloopname = null;
+ $this->_currloop = array();
+ return true;
+ }
+
+ /**
+ * FUNCTION: clearAll
+ *
+ * Unsets all variables and loops set using setVar/Loop()
+ *
+ * @return boolean true
+ * @access public
+ */
+ function clearAll () {
+ $this->clearVars();
+ $this->clearLoops();
+ return true;
+ }
+
+ /**
+ * FUNCTION: unknownsExist
+ *
+ * Returns true if unknowns were found after parsing.
+ * Function MUST be called AFTER one of the parsing functions to have any relevance.
+ *
+ * @return boolean true/false
+ * @access public
+ */
+ function unknownsExist () {
+ return (!empty($this->_unknowns));
+ }
+
+ /**
+ * FUNCTION: unknowns
+ *
+ * Alias for unknownsExist.
+ *
+ * @access public
+ */
+ function unknowns () {
+ return $this->unknownsExist();
+ }
+
+ /**
+ * FUNCTION: getUnknowns
+ *
+ * Returns an array of all unknown vars found when parsing.
+ * This function is only relevant after parsing a document.
+ *
+ * @return array
+ * @access public
+ */
+ function getUnknowns () {
+ return $this->_unknowns;
+ }
+
+ /**
+ * FUNCTION: setUnknowns
+ *
+ * Sets how you want to handle variables that were found in the
+ * template but not set in vlibTemplate using vlibTemplate::setVar().
+ *
+ * @param string $arg ignore, remove, print, leave or comment
+ * @return boolean
+ * @access public
+ */
+ function setUnknowns ($arg) {
+ $arg = strtolower(trim($arg));
+ if (preg_match('/^ignore|remove|print|leave|comment$/', $arg)) {
+ $this->OPTIONS['UNKNOWNS'] = $arg;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * FUNCTION: setPath
+ *
+ * function sets the paths to use when including files.
+ * Use of this function: vlibTemplate::setPath(string path [, string path, ..]);
+ * i.e. if $tmpl is your template object do: $tmpl->setPath('/web/htdocs/templates','/web/htdocs/www');
+ * with as many paths as you like.
+ * if this function is called without any arguments, it will just delete any previously set paths.
+ *
+ * @param string path (mulitple)
+ * @return bool success
+ * @access public
+ */
+ function setPath () {
+ $num_args = func_num_args();
+ if ($num_args < 1) {
+ $this->OPTIONS['INCLUDE_PATHS'] = array();
+ return true;
+ }
+ for ($i = 0; $i < $num_args; $i++) {
+ $thispath = func_get_arg($i);
+ array_push($this->OPTIONS['INCLUDE_PATHS'], realpath($thispath));
+ }
+ return true;
+ }
+
+ /**
+ * FUNCTION: getParseTime
+ *
+ * After using one of the parse functions, this will allow you
+ * access the time taken to parse the template.
+ * see OPTION 'TIME_PARSE'.
+ *
+ * @return float time taken to parse template
+ * @access public
+ */
+ function getParseTime () {
+ if ($this->OPTIONS['TIME_PARSE'] && $this->_parsed) {
+ return $this->_totalparsetime;
+ }
+ return false;
+ }
+
+
+ /**
+ * FUNCTION: fastPrint
+ *
+ * Identical to pparse() except that it uses output buffering w/ gz compression thus
+ * printing the output directly and compressed if poss.
+ * Will possibly if parsing a huge template.
+ *
+ * @access public
+ * @return boolean true/false
+ */
+ function fastPrint () {
+ $ret = $this->_parse('ob_gzhandler');
+ print($this->_tmploutput);
+ return $ret;
+ }
+
+
+ /**
+ * FUNCTION: pparse
+ *
+ * Calls parse, and then prints out $this->_tmploutput
+ *
+ * @access public
+ * @return boolean true/false
+ */
+ function pparse () {
+ if (!$this->_parsed) $this->_parse();
+ print($this->_tmploutput);
+ return true;
+ }
+
+ /**
+ * FUNCTION: pprint
+ *
+ * Alias for pparse()
+ *
+ * @access public
+ */
+ function pprint () {
+ return $this->pparse();
+ }
+
+
+ /**
+ * FUNCTION: grab
+ *
+ * Returns the parsed output, ready for printing, passing to mail() ...etc.
+ * Invokes $this->_parse() if template has not yet been parsed.
+ *
+ * @access public
+ * @return boolean true/false
+ */
+ function grab () {
+ if (!$this->_parsed) $this->_parse();
+ return $this->_tmploutput;
+ }
+
+ /*-----------------------------------------------------------------------------\
+ | private functions |
+ \-----------------------------------------------------------------------------*/
+
+ /**
+ * FUNCTION: vlibTemplate
+ *
+ * vlibTemplate constructor.
+ * if $tmplfile has been passed to it, it will send to $this->newTemplate()
+ *
+ * @param string $tmplfile full path to template file
+ * @param array $options see above
+ * @return boolean true/false
+ * @access private
+ */
+ function tpl ($tmplfile=null, $options=null) {
+ if (is_array($tmplfile) && $options == null) {
+ $options = $tmplfile;
+ unset($tmplfile);
+ }
+
+ $this->VLIBTEMPLATE_ROOT = dirname(realpath(__FILE__));
+
+ if (is_array(vlibIni::vlibTemplate())) {
+ foreach (vlibIni::vlibTemplate() as $name => $val) {
+ $this->OPTIONS[$name] = $val;
+ }
+ }
+
+ if (is_array($options)) {
+ foreach($options as $key => $val) {
+ $key = strtoupper($key);
+ if ($key == 'PATH') {
+ $this->setPath($val);
+ }
+ else {
+ $this->_setOption($key, strtolower($val));
+ }
+ }
+ }
+ if($tmplfile) $this->newTemplate($tmplfile);
+ if ($this->OPTIONS['GLOBAL_CONTEXT_VARS']) $this->setContextVars();
+ return true;
+ }
+
+ /** FUNCTION: _getData
+ *
+ * function returns the text from the file, or if we're using cache, the text
+ * from the cache file. MUST RETURN DATA.
+ * @param string tmplfile contains path to template file
+ * @param do_eval used for included files. If set then this function must do the eval()'ing.
+ * @access private
+ * @return mixed data/string or boolean
+ */
+ function _getData ($tmplfile, $do_eval=false) {
+ //check the current file depth
+ if ($this->_includedepth > $this->OPTIONS['MAX_INCLUDES'] || $tmplfile == false) {
+ return;
+ }
+ else {
+ if ($this->_debug) array_push ($this->_debugIncludedfiles, $tmplfile);
+ if ($do_eval) {
+ array_push($this->_currentincludedir, dirname($tmplfile));
+ $this->_includedepth++;
+ }
+ }
+
+
+ if($this->_cache && $this->_checkCache($tmplfile)) { // cache exists so lets use it
+ $data = fread($fp = fopen($this->_cachefile, 'r'), filesize($this->_cachefile));
+ fclose($fp);
+ }
+ else { // no cache lets parse the file
+ $data = fread($fp = fopen($tmplfile, 'r'), filesize($tmplfile));
+ fclose($fp);
+
+ $regex = '/(<|<\/|{|{\/|){1}';
+ $regex.= '/ie';
+ //$regex.= '([\r\n|\n|\r])?/ie';
+ $data = preg_replace($regex,"\$this->_parseTag(array('\\0','\\1','\\2','\\3','\\4','\\5','\\6','\\7','\\8','\\9'));",$data);
+
+ if ($this->_cache) { // add cache if need be
+ $this->_createCache($data);
+ }
+ }
+
+ // now we must parse the $data and check for any 's
+ if ($this->_debug) $this->doDebugWarnings(file($tmplfile), $tmplfile);
+
+ if ($do_eval) {
+ $success = @eval('?>'.$data.'_includedepth--;
+ array_pop($this->_currentincludedir);
+ return $success;
+ }
+ else {
+ return $data;
+ }
+
+ }
+
+ /**
+ * FUNCTION: _fileSearch
+ *
+ * Searches for all possible instances of file { $file }
+ *
+ * @param string $file path of file we're looking for
+ * @access private
+ * @return mixed fullpath to file or boolean false
+ */
+ function _fileSearch ($file) {
+ $filename = basename($file);
+ $filepath = dirname($file);
+
+ // check fullpath first..
+ $fullpath = $filepath.'/'.$filename;
+ if (is_file($fullpath)) return $fullpath;
+
+ // ..then check for relative path for current directory..
+ if (!empty($this->_currentincludedir)) {
+ $currdir = $this->_currentincludedir[(count($this->_currentincludedir) -1)];
+ $relativepath = realpath($currdir.'/'.$filepath.'/'.$filename);
+ if (is_file($relativepath)) {
+ array_push ($this->_currentincludedir, dirname($relativepath));
+ return $relativepath;
+ }
+ }
+
+ // ..then check for relative path for all additional given paths..
+ if (!empty($this->OPTIONS['INCLUDE_PATHS'])) {
+ foreach ($this->OPTIONS['INCLUDE_PATHS'] as $currdir) {
+ $relativepath = realpath($currdir.'/'.$filepath.'/'.$filename);
+ if (is_file($relativepath)) {
+ return $relativepath;
+ }
+ }
+ }
+
+ // ..then check path from TEMPLATE_DIR..
+ if (!empty($this->OPTIONS['TEMPLATE_DIR'])) {
+ $fullpath = realpath($this->OPTIONS['TEMPLATE_DIR'].'/'.$filepath.'/'.$filename);
+ if (is_file($fullpath)) return $fullpath;
+ }
+
+ // ..then check relative path from executing php script..
+ $fullpath = realpath($filepath.'/'.$filename);
+ if (is_file($fullpath)) return $fullpath;
+
+ // ..then check path from template file.
+ if (!empty($this->VLIBTEMPLATE_ROOT)) {
+ $fullpath = realpath($this->VLIBTEMPLATE_ROOT.'/'.$filepath.'/'.$filename);
+ if (is_file($fullpath)) return $fullpath;
+ }
+
+ return false; // uh oh, file not found
+ }
+
+ /**
+ * FUNCTION: _arrayBuild
+ *
+ * Modifies the array $arr to add Template variables, __FIRST__, __LAST__ ..etc
+ * if $this->OPTIONS['LOOP_CONTEXT_VARS'] is true.
+ * Used by $this->setloop().
+ *
+ * @param array $arr
+ * @return array new look array
+ * @access private
+ */
+ function _arrayBuild ($arr) {
+ if (is_array($arr) && !empty($arr)) {
+ $arr = array_values($arr); // to prevent problems w/ non sequential arrays
+ for ($i = 0; $i < count($arr); $i++) {
+ if(!is_array($arr[$i])) return false;
+ foreach ($arr[$i] as $k => $v) {
+ unset($arr[$i][$k]);
+ if ($this->OPTIONS['CASELESS']) $k = strtolower($k);
+ if (preg_match('/^[0-9]+$/', $k)) $k = '_'.$k;
+
+ if (is_array($v)) {
+ if (($arr[$i][$k] = $this->_arrayBuild($v)) == false) return false;
+ }
+ else { // reinsert the var
+ $arr[$i][$k] = $v;
+ }
+ }
+ if ($this->OPTIONS['LOOP_CONTEXT_VARS']) {
+ if ($i == 0) $arr[$i]['__FIRST__'] = true;
+ if (($i + 1) == count($arr)) $arr[$i]['__LAST__'] = true;
+ if ($i != 0 && (($i + 1) < count($arr))) $arr[$i]['__INNER__'] = true;
+ if (is_int(($i+1) / 2)) $arr[$i]['__EVEN__'] = true;
+ if (!is_int(($i+1) / 2)) $arr[$i]['__ODD__'] = true;
+ $arr[$i]['__ROWNUM__'] = ($i + 1);
+ }
+ }
+ return $arr;
+ }
+ elseif (empty($arr)) {
+ return true;
+ }
+ }
+
+ /**
+ * FUNCTION: _parseIf
+ * returns a string used for parsing in tmpl_if statements.
+ *
+ * @param string $varname
+ * @param string $value
+ * @param string $op
+ * @param string $namespace current namespace
+ * @access private
+ * @return string used for eval'ing
+ */
+ function _parseIf ($varname, $value=null, $op=null, $namespace=null) {
+ if (isset($namespace)) $namespace = substr($namespace, 0, -1);
+ $comp_str = ''; // used for extended if statements
+
+ // work out what to put on the end id value="whatever" is used
+ if (isset($value)) {
+
+ // add the correct operator depending on whether it's been specified or not
+ if (!empty($op)) {
+ if (in_array($op, $this->allowed_if_ops)) {
+ $comp_str .= $op;
+ }
+ else {
+ vlibTemplateError::raiseError('VT_WARNING_INVALID_IF_OP', WARNING, $op);
+ }
+ }
+ else {
+ $comp_str .= '==';
+ }
+
+ // now we add the value, if it's numeric, then we leave the quotes off
+ if (is_numeric($value)) {
+ $comp_str .= $value;
+ }
+ else {
+ $comp_str .= '\''.$value.'\'';
+ }
+ }
+
+ if (count($this->_namespace) == 0 || $namespace == 'global') return '$this->_vars[\''.$varname.'\']'.$comp_str;
+ $retstr = '$this->_arrvars';
+ $numnamespaces = count($this->_namespace);
+ for ($i=0; $i < $numnamespaces; $i++) {
+ if ($this->_namespace[$i] == $namespace || (($i + 1) == $numnamespaces && !empty($namespace))) {
+ $retstr .= "['".$namespace."'][\$_".$i."]";
+ break 1;
+ }
+ else {
+ $retstr .= "['".$this->_namespace[$i]."'][\$_".$i."]";
+ }
+ }
+ if ($this->OPTIONS['GLOBAL_VARS'] && empty($namespace)) {
+ return '(('.$retstr.'[\''.$varname.'\'] !== null) ? '.$retstr.'[\''.$varname.'\'] : $this->_vars[\''.$varname.'\'])'.$comp_str;
+ }
+ else {
+ return $retstr."['".$varname."']".$comp_str;
+ }
+ }
+
+
+ /**
+ * FUNCTION: _parseLoop
+ * returns a string used for parsing in tmpl_loop statements.
+ *
+ * @param string $varname
+ * @access private
+ * @return string used for eval'ing
+ */
+ function _parseLoop ($varname) {
+ array_push($this->_namespace, $varname);
+ $tempvar = count($this->_namespace) - 1;
+ $retstr = "for (\$_".$tempvar."=0 ; \$_".$tempvar." < count(\$this->_arrvars";
+ for ($i=0; $i < count($this->_namespace); $i++) {
+ $retstr .= "['".$this->_namespace[$i]."']";
+ if ($this->_namespace[$i] != $varname) $retstr .= "[\$_".$i."]";
+ }
+ return $retstr."); \$_".$tempvar."++) {";
+ }
+
+ /**
+ * FUNCTION: _parseVar
+ *
+ * returns a string used for parsing in tmpl_var statements.
+ *
+ * @param string $wholetag
+ * @param string $tag
+ * @param string $varname
+ * @param string $escape
+ * @param string $format
+ * @param string $namespace
+ * @access private
+ * @return string used for eval'ing
+ */
+ function _parseVar ($wholetag, $tag, $varname, $escape, $format, $namespace) {
+ if (!empty($namespace)) $namespace = substr($namespace, 0, -1);
+ $wholetag = stripslashes($wholetag);
+
+ if (count($this->_namespace) == 0 || $namespace == 'global') {
+ $var1 = '$this->_vars[\''.$varname.'\']';
+ }
+ else {
+ $var1build = "\$this->_arrvars";
+ $numnamespaces = count($this->_namespace);
+ for ($i=0; $i < $numnamespaces; $i++) {
+ if ($this->_namespace[$i] == $namespace || (($i + 1) == $numnamespaces && !empty($namespace))) {
+ $var1build .= "['".$namespace."'][\$_".$i."]";
+ break 1;
+ }
+ else {
+ $var1build .= "['".$this->_namespace[$i]."'][\$_".$i."]";
+ }
+ }
+ $var1 = $var1build . "['$varname']";
+ if ($this->OPTIONS['GLOBAL_VARS'] && empty($namespace)) {
+ $var2 = '$this->_vars[\''.$varname.'\']';
+ }
+ }
+
+ $beforevar = '';
+ $aftervar = '';
+ if (!empty($escape)&& isset($this->ESCAPE_TAGS[$escape])) {
+ $beforevar .= $this->ESCAPE_TAGS[$escape]['open'];
+ $aftervar = $this->ESCAPE_TAGS[$escape]['close'] . $aftervar;
+ }
+
+ if (!empty($format)&& isset($this->FORMAT_TAGS[$format])) {
+ $beforevar .= $this->FORMAT_TAGS[$format]['open'];
+ $aftervar = $this->FORMAT_TAGS[$format]['close'] . $aftervar;
+ }
+
+ // build return values
+ $retstr = 'if ('.$var1.' !== null) { ';
+ $retstr .= 'print('.$beforevar.$var1.$aftervar.'); ';
+ $retstr .= '}';
+
+ if (@$var2) {
+ $retstr .= ' elseif ('.$var2.' !== null) { ';
+ $retstr .= 'print('.$beforevar.$var2.$aftervar.'); ';
+ $retstr .= '}';
+ }
+
+ switch (strtolower($this->OPTIONS['UNKNOWNS'])) {
+ case 'comment':
+ $comment = addcslashes('', '', $wholetag).'//-->', '"');
+ $retstr .= ' else { print("'.$comment.'"); $this->_setUnknown("'.$varname.'"); }';
+ return $retstr;
+ break;
+ case 'leave':
+ $retstr .= ' else { print("'.addcslashes($wholetag, '"').'"); $this->_setUnknown("'.$varname.'"); }';
+ return $retstr;
+ break;
+ case 'print':
+ $retstr .= ' else { print("'.htmlspecialchars($wholetag, ENT_QUOTES).'"); $this->_setUnknown("'.$varname.'"); }';
+ return $retstr;
+ break;
+
+ case 'ignore':
+ return $retstr;
+ break;
+ case 'remove':
+ default:
+ $retstr .= ' else { $this->_setUnknown("'.$varname.'"); }';
+ return $retstr;
+ break;
+ }
+ }
+
+ /**
+ * FUNCTION: _parseTag
+ * takes values from preg_replace in $this->_intparse() and determines
+ * the replace string.
+ *
+ * @param array $args array of all matches found by preg_replace
+ * @access private
+ * @return string replace values
+ */
+ function _parseTag ($args) {
+ $wholetag = $args[0];
+ $openclose = $args[1];
+ $tag = strtolower($args[2]);
+ $newline = $args[9];
+ //echo "1#$newline#2";
+
+ if ($tag == 'else') return ''.$newline;
+ if ($tag == 'tmpl_include') return $wholetag; // ignore tmpl_include tags
+
+ if (preg_match("/^<\/|{\/|