Tag: linux
Froxlor IPv6 Patch
Dec. 28, 2013, 9:56 p.m.

Ein Patch für Froxlor, welches IPv6 im Management-Interface erweitert, um z.B Domains mit IPv6 Adressen zu versehen.
Update:
Dieser Patch wird seit der Version 0.9.31.2 nicht mehr benötigt. Falls dieser Patch eingesetzt wurde, dann ist es notwendig manuell die Domains aus der Datenbank zu entfernen, welche die IPv6 Adresse genutzt haben und keine Standardsubdomain sind.

                    After applying this patch do following on the froxlor database:
alter table panel_domains change ipandport ipandport varchar(32);
alter table panel_settings change value value mediumtext not null;

diff -rupN froxlor/actions/admin/settings/120.system.php /var/www/froxlor/actions/admin/settings/120.system.php
--- froxlor/actions/admin/settings/120.system.php	2013-04-12 10:48:26.000000000 +0200
+++ /var/www/froxlor/actions/admin/settings/120.system.php	2013-05-18 14:30:10.341585387 +0200
@@ -55,7 +55,7 @@ return array(
 					'settinggroup' => 'system',
 					'varname' => 'defaultip',
 					'type' => 'option',
-					'option_mode' => 'one',
+					'option_mode' => 'multiple',
 					'option_options_method' => 'getIpPortCombinations',
 					'default' => '',
 					'save_method' => 'storeSettingDefaultIp',
diff -rupN froxlor/admin_customers.php /var/www/froxlor/admin_customers.php
--- froxlor/admin_customers.php	2013-04-12 10:48:26.000000000 +0200
+++ /var/www/froxlor/admin_customers.php	2013-05-18 14:41:12.245308801 +0200
@@ -807,24 +807,31 @@ if($page == 'customers'
 							$_stdsubdomain = $loginname . '.' . $settings['system']['hostname'];
 						}
 
-						$db->query("INSERT INTO `" . TABLE_PANEL_DOMAINS . "` SET " .
-							"`domain` = '". $db->escape($_stdsubdomain) . "', " .
-							"`customerid` = '" . (int)$customerid . "', " .
-							"`adminid` = '" . (int)$userinfo['adminid'] . "', " .
-							"`parentdomainid` = '-1', " .
-							"`ipandport` = '" . $db->escape($settings['system']['defaultip']) . "', " .
-							"`documentroot` = '" . $db->escape($documentroot) . "', " .
-							"`zonefile` = '', " .
-							"`isemaildomain` = '0', " .
-							"`caneditdomain` = '0', " .
-							"`openbasedir` = '1', " .
-							"`speciallogfile` = '0', " .
-							"`specialsettings` = '', " .
-							"`add_date` = '".date('Y-m-d')."'");
-						$domainid = $db->insert_id();
-						$db->query('UPDATE `' . TABLE_PANEL_CUSTOMERS . '` SET `standardsubdomain`=\'' . (int)$domainid . '\' WHERE `customerid`=\'' . (int)$customerid . '\'');
-						$log->logAction(ADM_ACTION, LOG_NOTICE, "automatically added standardsubdomain for user '" . $loginname . "'");
-						inserttask('1');
+						/*Modification for IPv4 and IPv6 Sebastian Kricner - September 2011*/
+						$ipandports = explode(',', $settings['system']['defaultip']);
+						foreach($ipandports as $ipandport)
+						{
+							$db->query("INSERT INTO `" . TABLE_PANEL_DOMAINS . "` SET " .
+								"`domain` = '". $db->escape($_stdsubdomain) . "', " .
+								"`customerid` = '" . (int)$customerid . "', " .
+								"`adminid` = '" . (int)$userinfo['adminid'] . "', " .
+								"`parentdomainid` = '-1', " .
+								"`ipandport` = '" .  $db->escape($ipandport) . "', " .
+								"`documentroot` = '" . $db->escape($documentroot) . "', " .
+								"`zonefile` = '', " .
+								"`isemaildomain` = '0', " .
+								"`caneditdomain` = '0', " .
+								"`openbasedir` = '1', " .
+								"`safemode` = '1', " .
+								"`speciallogfile` = '0', " .
+								"`specialsettings` = '', " .
+								"`add_date` = '".date('Y-m-d')."'");
+							$domainid = $db->insert_id();
+							$db->query('UPDATE `' . TABLE_PANEL_CUSTOMERS . '` SET `standardsubdomain`=\'' . (int)$domainid . '\' WHERE `customerid`=\'' . (int)$customerid . '\'');
+							$log->logAction(ADM_ACTION, LOG_NOTICE, "automatically added standardsubdomain for user '" . $loginname . "'");
+							inserttask('1');
+						}
+						/*End modification*/
 					}
 
 					if($sendpassword == '1')
@@ -1168,11 +1175,16 @@ if($page == 'customers'
 							$_stdsubdomain = $result['loginname'] . '.' . $settings['system']['hostname'];
 						}
 
-						$db->query("INSERT INTO `" . TABLE_PANEL_DOMAINS . "` " . "(`domain`, `customerid`, `adminid`, `parentdomainid`, `ipandport`, `documentroot`, `zonefile`, `isemaildomain`, `caneditdomain`, `openbasedir`, `speciallogfile`, `specialsettings`, `add_date`) " . "VALUES ('" . $db->escape($_stdsubdomain) . "', '" . (int)$result['customerid'] . "', '" . (int)$userinfo['adminid'] . "', '-1', '" . $db->escape($settings['system']['defaultip']) . "', '" . $db->escape($result['documentroot']) . "', '', '0', '0', '1', '0', '', '".date('Y-m-d')."')");
-						$domainid = $db->insert_id();
-						$db->query('UPDATE `' . TABLE_PANEL_CUSTOMERS . '` SET `standardsubdomain`=\'' . (int)$domainid . '\' WHERE `customerid`=\'' . (int)$result['customerid'] . '\'');
-						$log->logAction(ADM_ACTION, LOG_NOTICE, "automatically added standardsubdomain for user '" . $result['loginname'] . "'");
-						inserttask('1');
+						/*Modification for IPv4 and IPv6 Sebastian Kricner - September 2011*/
+						$ipandports = explode(',', $settings['system']['defaultip']);
+						foreach($ipandports as $ipandport)
+						{
+							$db->query("INSERT INTO `" . TABLE_PANEL_DOMAINS . "` " . "(`domain`, `customerid`, `adminid`, `parentdomainid`, `ipandport`, `documentroot`, `zonefile`, `isemaildomain`, `caneditdomain`, `openbasedir`, `safemode`, `speciallogfile`, `specialsettings`, `add_date`) " . "VALUES ('" .  $db->escape($_stdsubdomain) . "', '" .  (int)$result['customerid'] . "', '" .  (int)$userinfo['adminid'] . "', '-1', '" .  $db->escape($ipandport) . "', '" . $db->escape($result['documentroot']) . "', '', '0', '0', '1', '1', '0', '', '".date('Y-m-d')."')"); $domainid = $db->insert_id();
+							$db->query('UPDATE `' . TABLE_PANEL_CUSTOMERS . '` SET `standardsubdomain`=\'' . (int)$domainid . '\' WHERE `customerid`=\'' . (int)$result['customerid'] . '\'');
+							$log->logAction(ADM_ACTION, LOG_NOTICE, "automatically added standardsubdomain for user '" . $result['loginname'] . "'");
+							inserttask('1');
+						}
+						/*End modification*/
 					}
 
 					if($createstdsubdomain == '0'
diff -rupN froxlor/admin_domains.php /var/www/froxlor/admin_domains.php
--- froxlor/admin_domains.php	2013-04-12 10:48:26.000000000 +0200
+++ /var/www/froxlor/admin_domains.php	2013-05-18 14:30:10.341585387 +0200
@@ -73,6 +73,7 @@ if($page == 'domains'
 			if(filter_var($row['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))
 			{
 				$row['ipandport'] = '[' . $row['ip'] . ']:' . $row['port'];
+				$row['domain'] = $row['domain']." (IPv6)";
 			}
 			else
 			{
@@ -517,10 +518,12 @@ if($page == 'domains'
 				{
 					standard_error('adduserfirst');
 				}
+				/*
 				elseif(strtolower($domain_check['domain']) == strtolower($domain))
 				{
 					standard_error('domainalreadyexists', $idna_convert->decode($domain));
 				}
+				*/
 				elseif($aliasdomain_check['id'] != $aliasdomain)
 				{
 					standard_error('domainisaliasorothercustomer');
@@ -666,19 +669,39 @@ if($page == 'domains'
 				}
 
 				$domains = makeoption($lng['domains']['noaliasdomain'], 0, NULL, true);
-				$result_domains = $db->query("SELECT `d`.`id`, `d`.`domain`, `c`.`loginname` FROM `" . TABLE_PANEL_DOMAINS . "` `d`, `" . TABLE_PANEL_CUSTOMERS . "` `c` WHERE `d`.`aliasdomain` IS NULL AND `d`.`parentdomainid`=0 " . $standardsubdomains . ($userinfo['customers_see_all'] ? '' : " AND `d`.`adminid` = '" . (int)$userinfo['adminid'] . "'") . " AND `d`.`customerid`=`c`.`customerid` ORDER BY `loginname`, `domain` ASC");
+				$result_domains = $db->query("SELECT `d`.`id`, `d`.`domain`, `d`.`ipandport`, `c`.`loginname` FROM `" . TABLE_PANEL_DOMAINS . "` `d`, `" . TABLE_PANEL_CUSTOMERS . "` `c` WHERE `d`.`aliasdomain` IS NULL AND `d`.`parentdomainid`=0 " . $standardsubdomains . ($userinfo['customers_see_all'] ? '' : " AND `d`.`adminid` = '" . (int)$userinfo['adminid'] . "'") . " AND `d`.`customerid`=`c`.`customerid` ORDER BY `loginname`, `domain` ASC");
 
 				while($row_domain = $db->fetch_array($result_domains))
 				{
-					$domains.= makeoption($idna_convert->decode($row_domain['domain']) . ' (' . $row_domain['loginname'] . ')', $row_domain['id']);
+					/*Fix IPv6 by Sebastian Kricner - September 2011*/
+					$domain = $idna_convert->decode($row_domain['domain']);
+					$query = "SELECT * FROM " .
+					TABLE_PANEL_IPSANDPORTS . " WHERE id=" .  $row_domain['ipandport'];
+					$ipandport = $db->query_first($query);
+					if(filter_var($ipandport['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))
+					{
+						$domain .= ' (IPv6)';
+					}
+					/*End Fix*/
+					$domains.= makeoption($domain . ' (' . $row_domain['loginname'] . ')', $row_domain['id']);
 				}
 
 				$subtodomains = makeoption($lng['domains']['nosubtomaindomain'], 0, NULL, true);
-				$result_domains = $db->query("SELECT `d`.`id`, `d`.`domain`, `c`.`loginname` FROM `" . TABLE_PANEL_DOMAINS . "` `d`, `" . TABLE_PANEL_CUSTOMERS . "` `c` WHERE `d`.`aliasdomain` IS NULL AND `d`.`parentdomainid`=0 AND `d`.`ismainbutsubto`=0 " . $standardsubdomains . ($userinfo['customers_see_all'] ? '' : " AND `d`.`adminid` = '" . (int)$userinfo['adminid'] . "'") . " AND `d`.`customerid`=`c`.`customerid` ORDER BY `loginname`, `domain` ASC");
+				$result_domains = $db->query("SELECT `d`.`id`, `d`.`domain`, `d`.`ipandport`, `c`.`loginname` FROM `" . TABLE_PANEL_DOMAINS . "` `d`, `" . TABLE_PANEL_CUSTOMERS . "` `c` WHERE `d`.`aliasdomain` IS NULL AND `d`.`parentdomainid`=0 AND `d`.`ismainbutsubto`=0 " . $standardsubdomains . ($userinfo['customers_see_all'] ? '' : " AND `d`.`adminid` = '" . (int)$userinfo['adminid'] . "'") . " AND `d`.`customerid`=`c`.`customerid` ORDER BY `loginname`, `domain` ASC");
 
 				while($row_domain = $db->fetch_array($result_domains))
 				{
-					$subtodomains.= makeoption($idna_convert->decode($row_domain['domain']) . ' (' . $row_domain['loginname'] . ')', $row_domain['id']);
+					/*Fix IPv6 by Sebastian Kricner - September 2011*/
+					$domain = $idna_convert->decode($row_domain['domain']);
+					$query = "SELECT * FROM " .
+					TABLE_PANEL_IPSANDPORTS . " WHERE id=" .  $row_domain['ipandport'];
+					$ipandport = $db->query_first($query);
+					if(filter_var($ipandport['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))
+					{
+						$domain .= ' (IPv6)';
+					}
+					/*End Fix*/
+					$subtodomains.= makeoption($domain . ' (' . $row_domain['loginname'] . ')', $row_domain['id']);
 				}
 
 				$phpconfigs = '';
diff -rupN froxlor/customer_domains.php /var/www/froxlor/customer_domains.php
--- froxlor/customer_domains.php	2013-04-12 10:48:26.000000000 +0200
+++ /var/www/froxlor/customer_domains.php	2013-05-18 14:30:10.385585368 +0200
@@ -50,7 +50,7 @@ elseif($page == 'domains')
 			'd.aliasdomain' => $lng['domains']['aliasdomain']
 		);
 		$paging = new paging($userinfo, $db, TABLE_PANEL_DOMAINS, $fields, $settings['panel']['paging'], $settings['panel']['natsorting']);
-		$result = $db->query("SELECT `d`.`id`, `d`.`customerid`, `d`.`domain`, `d`.`documentroot`, `d`.`isemaildomain`, `d`.`caneditdomain`, `d`.`iswildcarddomain`, `d`.`parentdomainid`, `ad`.`id` AS `aliasdomainid`, `ad`.`domain` AS `aliasdomain`, `da`.`id` AS `domainaliasid`, `da`.`domain` AS `domainalias` FROM `" . TABLE_PANEL_DOMAINS . "` `d` LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `ad` ON `d`.`aliasdomain`=`ad`.`id` LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `da` ON `da`.`aliasdomain`=`d`.`id` WHERE `d`.`customerid`='" . (int)$userinfo['customerid'] . "' AND `d`.`email_only`='0' AND `d`.`id` <> " . (int)$userinfo['standardsubdomain'] . " " . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit());
+		$result = $db->query("SELECT `d`.`id`, `d`.`customerid`, `d`.`domain`, `d`.`documentroot`, `d`.`isemaildomain`, `d`.`caneditdomain`, `d`.`iswildcarddomain`, `d`.`parentdomainid`, `d`.`ipandport`, `ad`.`id` AS `aliasdomainid`, `ad`.`domain` AS `aliasdomain`, `da`.`id` AS `domainaliasid`, `da`.`domain` AS `domainalias` FROM `" . TABLE_PANEL_DOMAINS . "` `d` LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `ad` ON `d`.`aliasdomain`=`ad`.`id` LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `da` ON `da`.`aliasdomain`=`d`.`id` WHERE `d`.`customerid`='" . (int)$userinfo['customerid'] . "' AND `d`.`email_only`='0' AND `d`.`id` <> " . (int)$userinfo['standardsubdomain'] . " " . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit());
 		$paging->setEntries($db->num_rows($result));
 		$sortcode = $paging->getHtmlSortCode($lng);
 		$arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s);
@@ -64,6 +64,14 @@ elseif($page == 'domains')
 		while($row = $db->fetch_array($result))
 		{
 			$row['domain'] = $idna_convert->decode($row['domain']);
+			/*Fix IPv6 by Sebastian Kricner - September 2011*/
+			$query = "SELECT * FROM " . TABLE_PANEL_IPSANDPORTS . " WHERE `id`=" . $row['ipandport'];
+			$ipandport = $db->query_first($query);
+			if(filter_var($ipandport['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))
+			{
+				$row['domain'] .= ' (IPv6)';
+			}
+			/*End Fix*/
 			$row['aliasdomain'] = $idna_convert->decode($row['aliasdomain']);
 			$row['domainalias'] = $idna_convert->decode($row['domainalias']);
 
@@ -221,8 +229,17 @@ elseif($page == 'domains')
 			   && $_POST['send'] == 'send')
 			{
 				$subdomain = $idna_convert->encode(preg_replace(Array('/\:(\d)+$/', '/^https?\:\/\//'), '', validate($_POST['subdomain'], 'subdomain', '', 'subdomainiswrong')));
+				/*Fix IPv6 - Sebastian Kricner September 2011*/
+				$ipv6flag = False;
+				if(preg_match("/\(IPv6\)/", $_POST['domain']))
+				{
+					$ipv6flag = True;
+					$_POST['domain'] = preg_replace("/\(IPv6\)/", '', $_POST["domain"]);
+				}
 				$domain = $idna_convert->encode($_POST['domain']);
-				$domain_check = $db->query_first("SELECT * FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `domain`='" . $db->escape($domain) . "' AND `customerid`='" . (int)$userinfo['customerid'] . "' AND `parentdomainid`='0' AND `email_only`='0' AND `caneditdomain`='1' ");
+				/*End Fix*/
+
+				if($domain_check = $db->query_first("SELECT * FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `domain`='" . $db->escape($domain) . "' AND `customerid`='" . (int)$userinfo['customerid'] .  "' AND `parentdomainid`='0' AND `email_only`='0' AND `caneditdomain`='1' "));
 				$completedomain = $subdomain . '.' . $domain;
 				$completedomain_check = $db->query_first("SELECT * FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `domain`='" . $db->escape($completedomain) . "' AND `customerid`='" . (int)$userinfo['customerid'] . "' AND `email_only`='0' AND `caneditdomain` = '1'");
 				$aliasdomain = intval($_POST['alias']);
@@ -231,6 +248,24 @@ elseif($page == 'domains')
 				);
 				$_doredirect = false;
 
+				/*Fix IPv6 by Sebastian Kricner - September 2011*/
+				$domain_ipandport = $domain_check['ipandport'];
+				if($ipv6flag)
+				{
+					$query = "SELECT ipandport FROM " .  TABLE_PANEL_DOMAINS . " WHERE domain='" .  $domain . "'";
+					$result = $db->query($query);
+					while($row = $db->fetch_array($result))
+					{
+						$query = "SELECT * FROM " . TABLE_PANEL_IPSANDPORTS . " WHERE id=" . $row['ipandport'];
+						$ipandport = $db->query_first($query);
+						if(filter_var($ipandport['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))
+						{
+							$domain_ipandport = $row['ipandport'];
+						}
+					}
+				}
+				/*End Fix*/
+
 				if($aliasdomain != 0)
 				{
 					// also check ip/port combination to be the same, #176
@@ -309,10 +344,12 @@ elseif($page == 'domains')
 				{
 					standard_error('domaincantbeempty');
 				}
+				/*
 				elseif(strtolower($completedomain_check['domain']) == strtolower($completedomain))
 				{
 					standard_error('domainexistalready', $completedomain);
 				}
+				*/
 				elseif(strtolower($domain_check['domain']) != strtolower($domain))
 				{
 					standard_error('maindomainnonexist', $domain);
@@ -336,7 +373,7 @@ elseif($page == 'domains')
 								`customerid` = '" . (int)$userinfo['customerid'] . "',
 								`domain` = '" . $db->escape($completedomain) . "', 
 								`documentroot` = '" . $db->escape($path) . "', 
-								`ipandport` = '" . $db->escape($domain_check['ipandport']) . "', 
+								`ipandport` = '" .  $db->escape($domain_ipandport). "', 
 								`aliasdomain` = ".(($aliasdomain != 0) ? "'" . $db->escape($aliasdomain) . "'" : "NULL") .", 
 								`parentdomainid` = '" . (int)$domain_check['id'] . "', 
 								`isemaildomain` = '" . ($domain_check['subcanemaildomain'] == '3' ? '1' : '0') . "', 
@@ -366,20 +403,38 @@ elseif($page == 'domains')
 			}
 			else
 			{
-				$result = $db->query("SELECT `id`, `domain`, `documentroot`, `ssl_redirect`,`isemaildomain` FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid`='" . (int)$userinfo['customerid'] . "' AND `parentdomainid`='0' AND `email_only`='0' AND `caneditdomain`='1' ORDER BY `domain` ASC");
+				$result = $db->query("SELECT `id`, `domain`, `documentroot`, `ssl_redirect`,`isemaildomain`, `ipandport` FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid`='" . (int)$userinfo['customerid'] . "' AND `parentdomainid`='0' AND `email_only`='0' AND `caneditdomain`='1' ORDER BY `domain` ASC");
 				$domains = '';
 
 				while($row = $db->fetch_array($result))
 				{
-					$domains.= makeoption($idna_convert->decode($row['domain']), $row['domain']);
+					/*Fix IPv6 by Sebastian Kricner - September 2011*/
+					$domain = $idna_convert->decode($row['domain']);
+					$query = "SELECT * FROM " . TABLE_PANEL_IPSANDPORTS . " WHERE id=" . $row['ipandport'];
+					$ipandport = $db->query_first($query);
+					if(filter_var($ipandport['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))
+					{
+						$domain .= ' (IPv6)';
+					}
+					$domains .= makeoption($domain, $domain);
+					/*End Fix*/
 				}
 
 				$aliasdomains = makeoption($lng['domains']['noaliasdomain'], 0, NULL, true);
-				$result_domains = $db->query("SELECT `d`.`id`, `d`.`domain` FROM `" . TABLE_PANEL_DOMAINS . "` `d`, `" . TABLE_PANEL_CUSTOMERS . "` `c` WHERE `d`.`aliasdomain` IS NULL AND `d`.`id` <> `c`.`standardsubdomain` AND `d`.`customerid`=`c`.`customerid` AND `d`.`email_only`='0' AND `d`.`customerid`=" . (int)$userinfo['customerid'] . " ORDER BY `d`.`domain` ASC");
+				$result_domains = $db->query("SELECT `d`.`id`, `d`.`domain`, `d`.`ipandport` FROM `" . TABLE_PANEL_DOMAINS . "` `d`, `" . TABLE_PANEL_CUSTOMERS . "` `c` WHERE `d`.`aliasdomain` IS NULL AND `d`.`id` <> `c`.`standardsubdomain` AND `d`.`customerid`=`c`.`customerid` AND `d`.`email_only`='0' AND `d`.`customerid`=" . (int)$userinfo['customerid'] . " ORDER BY `d`.`domain` ASC");
 
 				while($row_domain = $db->fetch_array($result_domains))
 				{
-					$aliasdomains.= makeoption($idna_convert->decode($row_domain['domain']), $row_domain['id']);
+					/*Fix IPv6 by Sebastian Kricner - September 2011*/
+					$domain = $idna_convert->decode($row_domain['domain']);
+					$query = "SELECT * FROM " .  TABLE_PANEL_IPSANDPORTS . " WHERE id='" . $row_domain['ipandport'] . "'";
+					$ipandport = $db->query_first($query);
+					if(filter_var($ipandport['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))
+					{
+						$domain .= ' (IPv6)';
+					}
+					$aliasdomains.= makeoption($domain, $row_domain['id']);
+					/*End Fix*/
 				}
 
 				$redirectcode = '';
diff -rupN froxlor/scripts/jobs/cron_tasks.inc.dns.10.bind.php /var/www/froxlor/scripts/jobs/cron_tasks.inc.dns.10.bind.php
--- froxlor/scripts/jobs/cron_tasks.inc.dns.10.bind.php	2013-04-12 10:48:26.000000000 +0200
+++ /var/www/froxlor/scripts/jobs/cron_tasks.inc.dns.10.bind.php	2013-05-22 01:49:52.925865250 +0200
@@ -94,8 +94,40 @@ class bind
 		$bindconf_file = '# ' . $this->settings['system']['bindconf_directory'] . 'froxlor_bind.conf' . "\n" . '# Created ' . date('d.m.Y H:i') . "\n" . '# Do NOT manually edit this file, all changes will be deleted after the next domain change at the panel.' . "\n" . "\n";
 		$result_domains = $this->db->query("SELECT `d`.`id`, `d`.`domain`, `d`.`iswildcarddomain`, `d`.`customerid`, `d`.`zonefile`, `d`.`bindserial`, `d`.`dkim`, `d`.`dkim_id`, `d`.`dkim_pubkey`, `d`.`wwwserveralias`, `ip`.`ip`, `c`.`loginname`, `c`.`guid` FROM `" . TABLE_PANEL_DOMAINS . "` `d` LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` `c` USING(`customerid`) LEFT JOIN `" . TABLE_PANEL_IPSANDPORTS . "` AS `ip` ON(`d`.`ipandport`=`ip`.`id`) WHERE `d`.`isbinddomain` = '1' ORDER BY `d`.`domain` ASC");
 
+
+		//Modification by Sebastian Kricner
+		$fetched_result_domains = array();
+		$fetched_result_domains_temp = array();
 		while($domain = $this->db->fetch_array($result_domains))
 		{
+			$fetched_result_domains[] = $domain;
+		}
+		foreach($fetched_result_domains as $domain_index => &$domain)
+		{
+			$found = 0;
+			foreach($fetched_result_domains_temp as $cmp_domain_index => &$cmp_domain)
+			{
+				if(($cmp_domain['domain'] == $domain['domain']) && ($cmp_domain['ip'] != $domain['ip']))
+				{
+					$cmp_domain['ip'] .= ',' . $domain['ip'];
+					$found=1;
+				}
+			}
+			if(!$found)
+			{
+				$fetched_result_domains_temp[] = $domain;
+			}
+		}
+		$fetched_result_domains = $fetched_result_domains_temp;
+		unset($fetched_result_domains_temp);
+		foreach($fetched_result_domains as $domain)
+		{
+			fwrite($this->debugHandler, $domain['domain'] . ' ' .  $domain['ip']  . "\n");
+		}
+		//End of modification
+
+		foreach($fetched_result_domains as $domain)
+		{
 			fwrite($this->debugHandler, '  cron_tasks: Task4 - Writing ' . $domain['id'] . '::' . $domain['domain'] . "\n");
 			$this->logger->logAction(CRON_ACTION, LOG_INFO, 'Writing ' . $domain['id'] . '::' . $domain['domain']);
 
@@ -111,7 +143,7 @@ class bind
 				fwrite($this->debugHandler, '  cron_tasks: Task4 - `' . $zonefile_name . '` zone written' . "\n");
 			}
 
-			$bindconf_file.= '# Domain ID: ' . $domain['id'] . ' - CustomerID: ' . $domain['customerid'] . ' - CustomerLogin: ' . $domain['loginname'] . "\n";
+			$bindconf_file.= '#CustomerID: ' . $domain['customerid'] . ' - CustomerLogin: ' . $domain['loginname'] . "\n";
 			$bindconf_file.= 'zone "' . $domain['domain'] . '" in {' . "\n";
 			$bindconf_file.= '	type master;' . "\n";
 			$bindconf_file.= '	file "' . makeCorrectFile($this->settings['system']['bindconf_directory'] . '/' . $domain['zonefile']) . '";' . "\n";
@@ -167,67 +199,62 @@ class bind
 
 	protected function generateZone($domain)
 	{
-		if(filter_var($domain['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4))
-		{
-			$ip_a_record = 'A	' . $domain['ip'];
-		}
-		elseif(filter_var($domain['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))
-		{
-			$ip_a_record = 'AAAA	' . $domain['ip'];
-		}
-		else
+		$ip_addresses = explode(',', $domain['ip']);
+		$soa_written = 0;
+		$zonefile = '';
+		foreach($ip_addresses as $ip_address)
 		{
-			return '';
-		}
-
-		$date = date('Ymd');
-		$bindserial = (preg_match('/^' . $date . '/', $domain['bindserial']) ? $domain['bindserial'] + 1 : $date . '00');
-		$this->db->query('UPDATE `' . TABLE_PANEL_DOMAINS . '` SET `bindserial`=\'' . $bindserial . '\' WHERE `id`=\'' . $domain['id'] . '\'');
-		$zonefile = '$TTL ' . (int)$this->settings['system']['defaultttl'] . "\n";
+			$domain['ip'] = $ip_address;
 
-		if(count($this->nameservers) == 0)
-		{
-			$zonefile.= '@ IN SOA ns ' . str_replace('@', '.', $this->settings['panel']['adminmail']) . '. (' . "\n";
-		}
-		else
-		{
-			$zonefile.= '@ IN SOA ' . $this->nameservers[0]['hostname'] . ' ' . str_replace('@', '.', $this->settings['panel']['adminmail']) . '. (' . "\n";
-		}
-
-		$zonefile.= '	' . $bindserial . ' ; serial' . "\n" . '	8H ; refresh' . "\n" . '	2H ; retry' . "\n" . '	1W ; expiry' . "\n" . '	11h) ; minimum' . "\n";
-
-		if(count($this->nameservers) == 0)
-		{
-			$zonefile.= '@	IN	NS	ns' . "\n" . 'ns	IN	' . $ip_a_record . "\n";
-		}
-		else
-		{
-			foreach($this->nameservers as $nameserver)
+			if(filter_var($domain['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4))
 			{
-				$zonefile.= '@	IN	NS	' . trim($nameserver['hostname']) . "\n";
+				$ip_a_record = 'A	' . $domain['ip'];
 			}
-		}
-
-		if(count($this->mxservers) == 0)
-		{
-			$zonefile.= '@	IN	MX	10 mail' . "\n";
-			$zonefile.= 'mail	IN	' . $ip_a_record . "\n";
-			if($domain['iswildcarddomain'] != '1')
+			elseif(filter_var($domain['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))
 			{
-				$zonefile.= 'imap	IN	' . $ip_a_record . "\n";
-				$zonefile.= 'smtp	IN	' . $ip_a_record . "\n";
-				$zonefile.= 'pop3	IN	' . $ip_a_record . "\n";
+				$ip_a_record = 'AAAA	' . $domain['ip'];
 			}
-		}
-		else
-		{
-			foreach($this->mxservers as $mxserver)
+			else
 			{
-				$zonefile.= '@	IN	MX	' . trim($mxserver) . "\n";
+				return '';
 			}
-			
-			if($this->settings['system']['dns_createmailentry'] == '1')
+
+			$date = date('Ymd');
+			$bindserial = (preg_match('/^' . $date . '/', $domain['bindserial']) ? $domain['bindserial'] + 1 : $date . '00');
+			$this->db->query('UPDATE `' . TABLE_PANEL_DOMAINS . '` SET `bindserial`=\'' . $bindserial . '\' WHERE `id`=\'' . $domain['id'] . '\'');
+
+			if(!$soa_written)
 			{
+				$zonefile .= '$TTL ' . (int)$this->settings['system']['defaultttl'] . "\n";
+				if(count($this->nameservers) == 0)
+				{
+					$zonefile.= '@ IN SOA ns ' . str_replace('@', '.', $this->settings['panel']['adminmail']) . '. (' . "\n";
+				}
+				else
+				{
+					$zonefile.= '@ IN SOA ' . $this->nameservers[0]['hostname'] . ' ' . str_replace('@', '.', $this->settings['panel']['adminmail']) . '. (' . "\n";
+				}
+
+				$zonefile.= '	' . $bindserial . ' ; serial' . "\n" . '	8H ; refresh' . "\n" . '	2H ; retry' . "\n" . '	1W ; expiry' . "\n" . '	11h) ; minimum' . "\n";
+
+				$soa_written = 1;
+			}
+
+				if(count($this->nameservers) == 0)
+				{
+					$zonefile.= '@	IN	NS	ns' . "\n" . 'ns	IN	' . $ip_a_record . "\n";
+				}
+				else
+				{
+					foreach($this->nameservers as $nameserver)
+					{
+						$zonefile.= '@	IN	NS	' . trim($nameserver['hostname']) . "\n";
+					}
+				}
+
+			if(count($this->mxservers) == 0)
+			{
+				$zonefile.= '@	IN	MX	10 mail' . "\n";
 				$zonefile.= 'mail	IN	' . $ip_a_record . "\n";
 				if($domain['iswildcarddomain'] != '1')
 				{
@@ -236,78 +263,95 @@ class bind
 					$zonefile.= 'pop3	IN	' . $ip_a_record . "\n";
 				}
 			}
-		}
+			else
+			{
+				foreach($this->mxservers as $mxserver)
+				{
+					$zonefile.= '@	IN	MX	' . trim($mxserver) . "\n";
+				}
+				
+				if($this->settings['system']['dns_createmailentry'] == '1')
+				{
+					$zonefile.= 'mail	IN	' . $ip_a_record . "\n";
+					if($domain['iswildcarddomain'] != '1')
+					{
+						$zonefile.= 'imap	IN	' . $ip_a_record . "\n";
+						$zonefile.= 'smtp	IN	' . $ip_a_record . "\n";
+						$zonefile.= 'pop3	IN	' . $ip_a_record . "\n";
+					}
+				}
+			}
 
-		/*
-		 * @TODO domain-based spf-settings
-		 */
-		if($this->settings['spf']['use_spf'] == '1'
-		   /*&& $domain['spf'] == '1' */)
-		{
-			$zonefile.= $this->settings['spf']['spf_entry'] . "\n";
-		}
+			/*
+			 * @TODO domain-based spf-settings
+			 */
+			if($this->settings['spf']['use_spf'] == '1'
+			   /*&& $domain['spf'] == '1' */)
+			{
+				$zonefile.= $this->settings['spf']['spf_entry'] . "\n";
+			}
 
-		/**
-		 * generate dkim-zone-entries
-		 */
-		$zonefile.= $this->generateDkim($domain);
+			/**
+			 * generate dkim-zone-entries
+			 */
+			$zonefile.= $this->generateDkim($domain);
 
-		$nssubdomains = $this->db->query('SELECT `domain` FROM `' . TABLE_PANEL_DOMAINS . '` WHERE `isbinddomain`=\'1\' AND `domain` LIKE \'%.' . $domain['domain'] . '\'');
+			$nssubdomains = $this->db->query('SELECT `domain` FROM `' . TABLE_PANEL_DOMAINS . '` WHERE `isbinddomain`=\'1\' AND `domain` LIKE \'%.' . $domain['domain'] . '\'');
 
-		while($nssubdomain = $this->db->fetch_array($nssubdomains))
-		{
-			if(preg_match('/^[^\.]+\.' . preg_quote($domain['domain'], '/') . '/', $nssubdomain['domain']))
+			while($nssubdomain = $this->db->fetch_array($nssubdomains))
 			{
-				$nssubdomain = str_replace('.' . $domain['domain'], '', $nssubdomain['domain']);
-
-				if(count($this->nameservers) == 0)
-				{
-					$zonefile.= $nssubdomain . '	IN	NS	ns.' . $nssubdomain . "\n";
-				}
-				else
+				if(preg_match('/^[^\.]+\.' . preg_quote($domain['domain'], '/') . '/', $nssubdomain['domain']))
 				{
-					foreach($this->nameservers as $nameserver)
+					$nssubdomain = str_replace('.' . $domain['domain'], '', $nssubdomain['domain']);
+
+					if(count($this->nameservers) == 0)
+					{
+						$zonefile.= $nssubdomain . '	IN	NS	ns.' . $nssubdomain . "\n";
+					}
+					else
 					{
-						$zonefile.= $nssubdomain . '	IN	NS	' . trim($nameserver['hostname']) . "\n";
+						foreach($this->nameservers as $nameserver)
+						{
+							$zonefile.= $nssubdomain . '	IN	NS	' . trim($nameserver['hostname']) . "\n";
+						}
 					}
 				}
 			}
-		}
 
-		$zonefile.= '@	IN	' . $ip_a_record . "\n";
-		$zonefile.= 'www	IN	' . $ip_a_record . "\n";
+			$zonefile.= '@	IN	' . $ip_a_record . "\n";
+			$zonefile.= 'www	IN	' . $ip_a_record . "\n";
 
-		if($domain['iswildcarddomain'] == '1')
-		{
-			$zonefile.= '*	IN      ' . $ip_a_record . "\n";
-		}
+			if($domain['iswildcarddomain'] == '1')
+			{
+				$zonefile.= '*	IN      ' . $ip_a_record . "\n";
+			}
 
-		$subdomains = $this->db->query('SELECT `d`.`domain`, `ip`.`ip` AS `ip` FROM `' . TABLE_PANEL_DOMAINS . '` `d`, `' . TABLE_PANEL_IPSANDPORTS . '` `ip` WHERE `parentdomainid`=\'' . $domain['id'] . '\' AND `d`.`ipandport`=`ip`.`id`');
-
-		while($subdomain = $this->db->fetch_array($subdomains))
-		{
-                        if(filter_var($subdomain['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4))
-                        {
-                                $zonefile.= str_replace('.' . $domain['domain'], '', $subdomain['domain']) . '  IN      A       ' . $subdomain['ip'] . "\n";
-                                
-                                /* Check whether to add a www.-prefix */
-                                if($domain['wwwserveralias'] == '1')
-								{
-									$zonefile.= str_replace('www.' . $domain['domain'], '', $subdomain['domain']) . '  IN      A       ' . $subdomain['ip'] . "\n";
-								}
-                        }
-                        elseif(filter_var($domain['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))
-                        {
-                                $zonefile.= str_replace('.' . $domain['domain'], '', $subdomain['domain']) . '  IN      AAAA    ' . $subdomain['ip'] . "\n";
-                                
-								/* Check whether to add a www.-prefix */
-                                if($domain['wwwserveralias'] == '1')
-								{
-									$zonefile.= str_replace('www.' . $domain['domain'], '', $subdomain['domain']) . '  IN      AAAA       ' . $subdomain['ip'] . "\n";
-								}
-                        }
-		}
+			$subdomains = $this->db->query('SELECT `d`.`domain`, `ip`.`ip` AS `ip` FROM `' . TABLE_PANEL_DOMAINS . '` `d`, `' . TABLE_PANEL_IPSANDPORTS . '` `ip` WHERE `parentdomainid`=\'' . $domain['id'] . '\' AND `d`.`ipandport`=`ip`.`id`');
 
+			while($subdomain = $this->db->fetch_array($subdomains))
+			{
+				if(filter_var($subdomain['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4))
+				{
+					$zonefile.= str_replace('.' . $domain['domain'], '', $subdomain['domain']) . '  IN      A       ' . $subdomain['ip'] . "\n";
+					
+					/* Check whether to add a www.-prefix */
+					if($domain['wwwserveralias'] == '1')
+									{
+										$zonefile.= str_replace('www.' . $domain['domain'], '', $subdomain['domain']) . '  IN      A       ' . $subdomain['ip'] . "\n";
+									}
+				}
+				elseif(filter_var($domain['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))
+				{
+					$zonefile.= str_replace('.' . $domain['domain'], '', $subdomain['domain']) . '  IN      AAAA    ' . $subdomain['ip'] . "\n";
+					
+									/* Check whether to add a www.-prefix */
+					if($domain['wwwserveralias'] == '1')
+									{
+										$zonefile.= str_replace('www.' . $domain['domain'], '', $subdomain['domain']) . '  IN      AAAA       ' . $subdomain['ip'] . "\n";
+									}
+				}
+			}
+		}
 		return $zonefile;
 	}
 	
diff -rupN froxlor/scripts/jobs/cron_tasks.inc.http.10.apache.php /var/www/froxlor/scripts/jobs/cron_tasks.inc.http.10.apache.php
--- froxlor/scripts/jobs/cron_tasks.inc.http.10.apache.php	2013-04-12 10:48:26.000000000 +0200
+++ /var/www/froxlor/scripts/jobs/cron_tasks.inc.http.10.apache.php	2013-05-18 14:30:10.389585367 +0200
@@ -669,6 +669,31 @@ class apache
 			$vhost_no = '20';
 		}
 
+		/*IPv6 Fix - http://forum.froxlor.org/index.php?/topic/246-host-site-on-ipv4-and-ipv6/ - Sebastian Kricner September 2011*/
+		if(filter_var($domain['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))
+		{
+			if((int)$domain['parentdomainid'] == 0
+			&& isCustomerStdSubdomain((int)$domain['id']) == false
+			&& ((int)$domain['ismainbutsubto'] == 0
+			|| domainMainToSubExists($domain['ismainbutsubto']) == false)
+			)
+			{
+				$vhost_no = '27';
+			}
+			elseif((int)$domain['parentdomainid'] == 0
+			&& isCustomerStdSubdomain((int)$domain['id']) == false
+			&& (int)$domain['ismainbutsubto'] > 0
+			)
+			{
+				$vhost_no = '26';
+			}
+			else
+			{
+				$vhost_no = '25';
+			}
+		}
+		/*End Fix*/
+
 		if($ssl_vhost === true)
 		{
 			$vhost_filename = makeCorrectFile($this->settings['system']['apacheconf_vhost'] . '/'.$vhost_no.'_froxlor_ssl_vhost_' . $domain['domain'] . '.conf');
@@ -842,6 +867,20 @@ class apache
 		{
 			fwrite($this->debugHandler, '  apache::createVirtualHosts: creating vhost container for domain ' . $domain['id'] . ', customer ' . $domain['loginname'] . "\n");
 			$this->logger->logAction(CRON_ACTION, LOG_INFO, 'creating vhost container for domain ' . $domain['id'] . ', customer ' . $domain['loginname']);
+
+			/*Fix for IPv6 - http://forum.froxlor.org/index.php?/topic/246-host-site-on-ipv4-and-ipv6/ - September 2011 Sebastian Kricner*/
+			if($domain['ssl'] == '1')
+			{
+				$query = "SELECT * FROM " . TABLE_PANEL_IPSANDPORTS . " WHERE `id`='" . $domain['ssl_ipandport'] . "'";
+			}
+			else
+			{
+				$query = "SELECT * FROM " . TABLE_PANEL_IPSANDPORTS . " WHERE `id`='" . $domain['ipandport'] . "'";
+			}
+			$ipandport = $this->db->query_first($query);
+			$domain['ip'] = $ipandport['ip'];
+			/*End Fix*/
+
 			$vhosts_filename = $this->getVhostFilename($domain);
 
 			// Apply header
@@ -1256,7 +1295,7 @@ class apache
 				if($vhost_filename != '.'
 				   && $vhost_filename != '..'
 				   && !in_array($vhost_filename, $this->known_vhostfilenames)
-				   && preg_match('/^(05|10|20|21|22|30|50|51)_(froxlor|syscp)_(dirfix|ipandport|normal_vhost|wildcard_vhost|ssl_vhost)_(.+)\.conf$/', $vhost_filename)
+				   && preg_match('/^(05|10|20|21|22|25|26|27|30|50|51)_(froxlor|syscp)_(dirfix|ipandport|normal_vhost|wildcard_vhost|ssl_vhost)_(.+)\.conf$/', $vhost_filename)
 				   && file_exists(makeCorrectFile($this->settings['system']['apacheconf_vhost'] . '/' . $vhost_filename)))
 				{
 					fwrite($this->debugHandler, '  apache::wipeOutOldVhostConfigs: unlinking ' . $vhost_filename . "\n");
diff -rupN froxlor/templates/Froxlor/footer.tpl /var/www/froxlor/templates/Froxlor/footer.tpl
--- froxlor/templates/Froxlor/footer.tpl	2013-04-12 10:48:26.000000000 +0200
+++ /var/www/froxlor/templates/Froxlor/footer.tpl	2013-05-18 15:07:18.716395933 +0200
@@ -4,7 +4,7 @@
 		<if ($settings['admin']['show_version_login'] == '1' && $filename == 'index.php') || ($filename != 'index.php' && $settings['admin']['show_version_footer'] == '1')>
 			{$version}{$branding}
 		</if>
-		&copy; 2009-{$current_year} by <a href="http://www.froxlor.org/" rel="external">the Froxlor Team</a>
+		&copy; by <a href="http://www.froxlor.org">the Froxlor Team</a> - IPv6 support modified by <a href="http://tuxwave.net" target="_blank">tuxwave.net</a>
 	</span>
 	<if $lng['translator'] != ''>
 		<br /><span>{$lng['panel']['translator']}: {$lng['translator']}
diff -rupN froxlor/templates/misc/standardcustomer/index.html /var/www/froxlor/templates/misc/standardcustomer/index.html
--- froxlor/templates/misc/standardcustomer/index.html	2013-04-12 10:48:26.000000000 +0200
+++ /var/www/froxlor/templates/misc/standardcustomer/index.html	2013-05-18 15:08:26.876361339 +0200
@@ -54,7 +54,7 @@
 		</article>
 		<footer>
 				<p>This site was created using <a href="http://www.froxlor.org">Froxlor</a>.<br />
-				&copy; 2009-2012 by <a href="http://www.froxlor.org">the Froxlor Team</a>
+				&copy; by <a href="http://www.froxlor.org">the Froxlor Team</a> - IPv6 support modified by <a href="http://tuxwave.net" target="_blank">tuxwave.net</a>
 			</p>
 		</footer>
 	</body>

                    
        
Download
fswebcam flock & src_open Patch
June 8, 2013, 9:08 p.m.

Ein Patch für fswebcam.
Es wird unter Verwendung von flock() verhindert, dass noch nicht vollständig auf Platte geschriebene Bilder auf der Webseite angezeigt werden. flock() muss ebenfalls im jeweiligen Script verwendet werden, welches die Bilddatei ausliefert (PHP, CGI etc.).
Zusätzlich wird die Webcam nur noch einmal geöffnet, sollte fswebcam im loop Modus betrieben werden.

                    December 2012 tuxwave.net
Sebastian Kricner

Implement file locking with flock() syscall.
This is to prevent delivery of broken images for live webcams.
This also needs a flock() LOCK_SH call in the script (PHP, CGI etc.) which delivers
the webcam image.

Additionally open the webcam only once when using the loop mode of fswebcam.

diff -rupN fswebcam-20110717.orig//fswebcam.c fswebcam-20110717/fswebcam.c
--- fswebcam-20110717.orig//fswebcam.c	2011-07-17 14:27:16.000000000 +0200
+++ fswebcam-20110717/fswebcam.c	2013-02-25 18:08:03.302774107 +0100
@@ -21,6 +21,7 @@
 #include <errno.h>
 #include <signal.h>
 #include <sys/types.h>
+#include <sys/file.h>
 #include <sys/stat.h>
 #include "fswebcam.h"
 #include "log.h"
@@ -482,8 +483,15 @@ int fswc_output(fswebcam_config_t *confi
 	fswc_draw_overlay(config, config->overlay, im);
 	
 	/* Write to a file if a filename was given, otherwise stdout. */
-	if(strncmp(name, "-", 2)) f = fopen(filename, "wb");
-	else f = stdout;
+	if(strncmp(name, "-", 2))
+	{
+		f = fopen(filename, "wb");
+		flock(fileno(f), LOCK_EX);
+	}
+	else
+	{
+		f = stdout;
+	}
 	
 	if(!f)
 	{
@@ -506,7 +514,12 @@ int fswc_output(fswebcam_config_t *confi
 		break;
 	}
 	
-	if(f != stdout) fclose(f);
+	if(f != stdout)
+	{
+		fflush(f);
+		flock(fileno(f), LOCK_UN);
+		fclose(f);
+	}
 	
 	gdImageDestroy(im);
 	
@@ -557,29 +570,41 @@ int fswc_grab(fswebcam_config_t *config)
 	avgbmp_t *abitmap, *pbitmap;
 	gdImage *image, *original;
 	uint8_t modified;
-	src_t src;
+
+	static src_t src;
+    static uint8_t src_assigned = 0;
 	
 	/* Record the start time. */
 	config->start = time(NULL);
 	
 	/* Set source options... */
-	memset(&src, 0, sizeof(src));
-	src.input      = config->input;
-	src.tuner      = config->tuner;
-	src.frequency  = config->frequency;
-	src.delay      = config->delay;
-	src.timeout    = 10; /* seconds */
-	src.use_read   = config->use_read;
-	src.list       = config->list;
-	src.palette    = config->palette;
-	src.width      = config->width;
-	src.height     = config->height;
-	src.fps        = config->fps;
-	src.option     = config->option;
-	
-	HEAD("--- Opening %s...", config->device);
-	
-	if(src_open(&src, config->device) == -1) return(-1);
+    if(!src_assigned)
+    {
+        memset(&src, 0, sizeof(src));
+        src.input      = config->input;
+        src.tuner      = config->tuner;
+        src.frequency  = config->frequency;
+        src.delay      = config->delay;
+        src.timeout    = 10; /* seconds */
+        src.use_read   = config->use_read;
+        src.list       = config->list;
+        src.palette    = config->palette;
+        src.width      = config->width;
+        src.height     = config->height;
+        src.fps        = config->fps;
+        src.option     = config->option;
+    }
+	
+	
+    if(!src_assigned)
+    {
+        HEAD("--- Opening %s...", config->device);
+        if(src_open(&src, config->device) == -1)
+        {
+            return(-1);
+        }
+        src_assigned = 1;
+    }
 	
 	/* The source may have adjusted the width and height we passed
 	 * to it. Update the main config to match. */
@@ -684,7 +709,10 @@ int fswc_grab(fswebcam_config_t *config)
 	}
 	
 	/* We are now finished with the capture card. */
-	src_close(&src);
+    if(!config->loop || !frame)
+    {
+        src_close(&src);
+    }
 	
 	/* Fail if no frames where captured. */
 	if(!frame)

                    
        
Download