Added usage of filesystem - quota to diskusage - calculation and added a new task to cron_tasks.php for setting the quota, refs #814
Signed-off-by: Florian Aders (EleRas) <eleras@froxlor.org>
This commit is contained in:
@@ -1877,3 +1877,10 @@ $lng['country']['EH'] = "Western Sahara";
|
|||||||
$lng['country']['YE'] = "Yemen";
|
$lng['country']['YE'] = "Yemen";
|
||||||
$lng['country']['ZM'] = "Zambia";
|
$lng['country']['ZM'] = "Zambia";
|
||||||
$lng['country']['ZW'] = "Zimbabwe";
|
$lng['country']['ZW'] = "Zimbabwe";
|
||||||
|
|
||||||
|
// ADDED IN FROXLOR 0.9.22-svn1
|
||||||
|
$lng['diskquota'] = 'Quota';
|
||||||
|
$lng['serversettings']['diskquota_enabled'] = 'Quota activated?';
|
||||||
|
$lng['serversettings']['diskquota_repquota_path']['description'] = 'Path to the repquota - tool';
|
||||||
|
$lng['serversettings']['diskquota_quotatool_path']['description'] = 'Path to quotatool';
|
||||||
|
$lng['serversettings']['diskquota_customer_partition']['description'] = 'Partition, on which the customer files are stored';
|
||||||
@@ -1608,3 +1608,10 @@ $lng['gender']['female'] = 'Frau';
|
|||||||
$lng['gender']['undef'] = '';
|
$lng['gender']['undef'] = '';
|
||||||
$lng['serversettings']['backup_ftp_passive_mode'] = 'Passiven Übertragungsmodus verwenden';
|
$lng['serversettings']['backup_ftp_passive_mode'] = 'Passiven Übertragungsmodus verwenden';
|
||||||
$lng['serversettings']['backup_bigfile'] = 'Backup von Kundenverzeichnissen und Datenbanken in eine Datei speichern, statt zu splitten?';
|
$lng['serversettings']['backup_bigfile'] = 'Backup von Kundenverzeichnissen und Datenbanken in eine Datei speichern, statt zu splitten?';
|
||||||
|
|
||||||
|
// ADDED IN FROXLOR 0.9.22-svn1
|
||||||
|
$lng['diskquota'] = 'Quota';
|
||||||
|
$lng['serversettings']['diskquota_enabled'] = 'Quota aktiviert?';
|
||||||
|
$lng['serversettings']['diskquota_repquota_path']['description'] = 'Pfad zu dem repquota - Tool';
|
||||||
|
$lng['serversettings']['diskquota_quotatool_path']['description'] = 'Pfad zu quotatool';
|
||||||
|
$lng['serversettings']['diskquota_customer_partition']['description'] = 'Partition, auf welcher die Kundendaten liegen';
|
||||||
@@ -64,7 +64,7 @@ while($row = $db->fetch_array($result_tasks))
|
|||||||
* (e.g. awstats not installed yet or whatever)
|
* (e.g. awstats not installed yet or whatever)
|
||||||
* fixes #45
|
* fixes #45
|
||||||
*/
|
*/
|
||||||
if (is_dir($awstatsclean['path']))
|
if (is_dir($awstatsclean['path']))
|
||||||
{
|
{
|
||||||
$awstatsclean['dir'] = dir($awstatsclean['path']);
|
$awstatsclean['dir'] = dir($awstatsclean['path']);
|
||||||
while($awstatsclean['entry'] = $awstatsclean['dir']->read()) {
|
while($awstatsclean['entry'] = $awstatsclean['dir']->read()) {
|
||||||
@@ -98,7 +98,7 @@ while($row = $db->fetch_array($result_tasks))
|
|||||||
{
|
{
|
||||||
$configdir = makeCorrectDir($settings['system']['mod_fcgid_configdir']);
|
$configdir = makeCorrectDir($settings['system']['mod_fcgid_configdir']);
|
||||||
|
|
||||||
if (is_dir($configdir))
|
if (is_dir($configdir))
|
||||||
{
|
{
|
||||||
$its = new RecursiveIteratorIterator(
|
$its = new RecursiveIteratorIterator(
|
||||||
new RecursiveDirectoryIterator($configdir)
|
new RecursiveDirectoryIterator($configdir)
|
||||||
@@ -108,14 +108,14 @@ while($row = $db->fetch_array($result_tasks))
|
|||||||
// look for php-fcgi-starter files
|
// look for php-fcgi-starter files
|
||||||
// and take immutable-flag away from them
|
// and take immutable-flag away from them
|
||||||
// so we can delete them :)
|
// so we can delete them :)
|
||||||
foreach ($its as $fullFileName => $it )
|
foreach ($its as $fullFileName => $it )
|
||||||
{
|
{
|
||||||
if ($it->isFile() && $it->getFilename() == 'php-fcgi-starter')
|
if ($it->isFile() && $it->getFilename() == 'php-fcgi-starter')
|
||||||
{
|
{
|
||||||
removeImmutable($its->getPathname());
|
removeImmutable($its->getPathname());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// now get rid of old stuff
|
// now get rid of old stuff
|
||||||
//(but append /* so we don't delete the directory)
|
//(but append /* so we don't delete the directory)
|
||||||
$configdir.='/*';
|
$configdir.='/*';
|
||||||
safe_exec('rm -rf '. makeCorrectFile($configdir));
|
safe_exec('rm -rf '. makeCorrectFile($configdir));
|
||||||
@@ -127,9 +127,9 @@ while($row = $db->fetch_array($result_tasks))
|
|||||||
{
|
{
|
||||||
$configdir = makeCorrectDir($settings['phpfpm']['configdir']);
|
$configdir = makeCorrectDir($settings['phpfpm']['configdir']);
|
||||||
|
|
||||||
if (is_dir($configdir))
|
if (is_dir($configdir))
|
||||||
{
|
{
|
||||||
// now get rid of old stuff
|
// now get rid of old stuff
|
||||||
//(but append /* so we don't delete the directory)
|
//(but append /* so we don't delete the directory)
|
||||||
$configdir.='/*';
|
$configdir.='/*';
|
||||||
safe_exec('rm -rf '. makeCorrectFile($configdir));
|
safe_exec('rm -rf '. makeCorrectFile($configdir));
|
||||||
@@ -211,7 +211,7 @@ while($row = $db->fetch_array($result_tasks))
|
|||||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: mkdir -p ' . escapeshellarg($userhomedir . 'webalizer'));
|
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: mkdir -p ' . escapeshellarg($userhomedir . 'webalizer'));
|
||||||
safe_exec('mkdir -p ' . escapeshellarg($userhomedir . 'webalizer'));
|
safe_exec('mkdir -p ' . escapeshellarg($userhomedir . 'webalizer'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// maildir
|
// maildir
|
||||||
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: mkdir -p ' . escapeshellarg($usermaildir));
|
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Running: mkdir -p ' . escapeshellarg($usermaildir));
|
||||||
safe_exec('mkdir -p ' . escapeshellarg($usermaildir));
|
safe_exec('mkdir -p ' . escapeshellarg($usermaildir));
|
||||||
@@ -318,8 +318,8 @@ while($row = $db->fetch_array($result_tasks))
|
|||||||
{
|
{
|
||||||
// e.g. /var/www/php-fcgi-starter/web1/
|
// e.g. /var/www/php-fcgi-starter/web1/
|
||||||
$configdir = makeCorrectDir($settings['system']['mod_fcgid_configdir'] . '/' . $row['data']['loginname'] . '/');
|
$configdir = makeCorrectDir($settings['system']['mod_fcgid_configdir'] . '/' . $row['data']['loginname'] . '/');
|
||||||
|
|
||||||
if (is_dir($configdir))
|
if (is_dir($configdir))
|
||||||
{
|
{
|
||||||
$its = new RecursiveIteratorIterator(
|
$its = new RecursiveIteratorIterator(
|
||||||
new RecursiveDirectoryIterator($configdir)
|
new RecursiveDirectoryIterator($configdir)
|
||||||
@@ -329,16 +329,16 @@ while($row = $db->fetch_array($result_tasks))
|
|||||||
// look for php-fcgi-starter files
|
// look for php-fcgi-starter files
|
||||||
// and take immutable-flag away from them
|
// and take immutable-flag away from them
|
||||||
// so we can delete them :)
|
// so we can delete them :)
|
||||||
foreach ($its as $fullFileName => $it )
|
foreach ($its as $fullFileName => $it )
|
||||||
{
|
{
|
||||||
if ($it->isFile() && $it->getFilename() == 'php-fcgi-starter')
|
if ($it->isFile() && $it->getFilename() == 'php-fcgi-starter')
|
||||||
{
|
{
|
||||||
removeImmutable($its->getPathname());
|
removeImmutable($its->getPathname());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// now get rid of old stuff
|
// now get rid of old stuff
|
||||||
safe_exec('rm -rf '. escapeshellarg($configdir));
|
safe_exec('rm -rf '. escapeshellarg($configdir));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -409,7 +409,7 @@ while($row = $db->fetch_array($result_tasks))
|
|||||||
*/
|
*/
|
||||||
elseif ($row['type'] == '9')
|
elseif ($row['type'] == '9')
|
||||||
{
|
{
|
||||||
|
|
||||||
fwrite($debugHandler, ' cron_tasks: Task9 started - creating backup dir protection' . "\n");
|
fwrite($debugHandler, ' cron_tasks: Task9 started - creating backup dir protection' . "\n");
|
||||||
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'Task9 started - creating backup dir protection');
|
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'Task9 started - creating backup dir protection');
|
||||||
|
|
||||||
@@ -457,7 +457,74 @@ while($row = $db->fetch_array($result_tasks))
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TYPE=10 Set the filesystem - quota
|
||||||
|
*/
|
||||||
|
elseif ($row['type'] == '10')
|
||||||
|
{
|
||||||
|
if ($settings['system']['diskquota_enabled'])
|
||||||
|
{
|
||||||
|
fwrite($debugHandler, ' cron_tasks: Task10 started - setting filesystem quota' . "\n");
|
||||||
|
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'Task10 started - setting filesystem quota');
|
||||||
|
|
||||||
|
# Fetch all quota in the desired partition
|
||||||
|
exec($settings['system']['diskquota_repquota_path'] . " -n " . escapeshellarg($settings['system']['diskquota_customer_partition']), $repquota);
|
||||||
|
|
||||||
|
$usedquota = array();
|
||||||
|
foreach ($repquota as $tmpquota)
|
||||||
|
{
|
||||||
|
# Let's see if the line matches a quota - line
|
||||||
|
if (preg_match('/^#([0-9]+)\s*[+-]{2}\s*(\d+)\s*(\d+)\s*(\d+)\s*(\ddays)?\s*(\d+)\s*(\d+)\s*(\d+)/i', $tmpquota, $matches))
|
||||||
|
{
|
||||||
|
# It matches - put it into an array with userid as key (for easy lookup later)
|
||||||
|
$usedquota[$matches[1]] = array(
|
||||||
|
'block' => array(
|
||||||
|
'used' => $matches[2],
|
||||||
|
'soft' => $matches[3],
|
||||||
|
'hard' => $matches[4],
|
||||||
|
'grace' => $matches[5]
|
||||||
|
),
|
||||||
|
'file' => array(
|
||||||
|
'used' => $matches[6],
|
||||||
|
'soft' => $matches[7],
|
||||||
|
'hard' => $matches[8],
|
||||||
|
'grace' => $matches[9]
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Select all customers Froxlor knows about
|
||||||
|
$result = $db->query("SELECT `guid`, `loginname`, `diskspace` FROM `" . TABLE_PANEL_CUSTOMERS . "`;");
|
||||||
|
while($row = $db->fetch_array($result))
|
||||||
|
{
|
||||||
|
# We do not want to set a quota for root by accident
|
||||||
|
if ($row['guid'] != 0)
|
||||||
|
{
|
||||||
|
# The user has no quota in Froxlor, but on the filesystem
|
||||||
|
if (($row['diskspace'] == 0 || $row['diskspace'] == -1024) && $usedquota[$row['guid']]['block']['hard'] != 0)
|
||||||
|
{
|
||||||
|
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, "Disabling quota for " . $row['loginname']);
|
||||||
|
safe_exec($settings['system']['diskquota_quotatool_path'] . " -u " . $row['guid'] . " -bl 0 -q 0 " . escapeshellarg($settings['system']['diskquota_customer_partition']));
|
||||||
|
}
|
||||||
|
|
||||||
|
# The user quota in Froxlor is different than on the filesystem
|
||||||
|
elseif($row['diskspace'] != $usedquota[$row['guid']]['block']['hard'] && $row['diskspace'] != -1024)
|
||||||
|
{
|
||||||
|
$cronlog->logAction(CRON_ACTION, LOG_NOTICE, "Setting quota for " . $row['loginname'] . " from " . $usedquota[$row['guid']]['block']['hard'] . " to " . $row['diskspace']);
|
||||||
|
safe_exec($settings['system']['diskquota_quotatool_path'] . " -u " . $row['guid'] . " -bl " . $row['diskspace'] . " -q " . $row['diskspace'] . " " . escapeshellarg($settings['system']['diskquota_customer_partition']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fwrite($debugHandler, ' cron_tasks: Task10 skipped - filesystem quota not enabled' . "\n");
|
||||||
|
$cronlog->logAction(CRON_ACTION, LOG_INFO, 'Task10 skipped - filesystem quota not enabled');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ while($row_database = $db->fetch_array($databases))
|
|||||||
$databases_list[] = strtolower($databases_list_row['Database']);
|
$databases_list[] = strtolower($databases_list_row['Database']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(in_array(strtolower($row_database['databasename']), $databases_list))
|
if(in_array(strtolower($row_database['databasename']), $databases_list))
|
||||||
{
|
{
|
||||||
$mysql_usage_result = $db_root->query("SHOW TABLE STATUS FROM `" . $db_root->escape($row_database['databasename']) . "`");
|
$mysql_usage_result = $db_root->query("SHOW TABLE STATUS FROM `" . $db_root->escape($row_database['databasename']) . "`");
|
||||||
@@ -102,7 +102,36 @@ while($row_database = $db->fetch_array($databases))
|
|||||||
|
|
||||||
$db_root->close();
|
$db_root->close();
|
||||||
|
|
||||||
|
# We are using the file-system quota, this will speed up the diskusage - collection
|
||||||
|
if ($settings['system']['diskquota_enabled'])
|
||||||
|
{
|
||||||
|
# Fetch all quota in the desired partition
|
||||||
|
exec("repquota -n " . $settings['system']['diskquota_customer_partition'], $repquota);
|
||||||
|
|
||||||
|
$usedquota = array();
|
||||||
|
foreach ($repquota as $tmpquota)
|
||||||
|
{
|
||||||
|
# Let's see if the line matches a quota - line
|
||||||
|
if (preg_match('/^#([0-9]+)\s*[+-]{2}\s*(\d+)\s*(\d+)\s*(\d+)\s*(\ddays)?\s*(\d+)\s*(\d+)\s*(\d+)/i', $tmpquota, $matches))
|
||||||
|
{
|
||||||
|
# It matches - put it into an array with userid as key (for easy lookup later)
|
||||||
|
$usedquota[$matches[1]] = array(
|
||||||
|
'block' => array(
|
||||||
|
'used' => $matches[2],
|
||||||
|
'soft' => $matches[3],
|
||||||
|
'hard' => $matches[4],
|
||||||
|
'grace' => $matches[5]
|
||||||
|
),
|
||||||
|
'file' => array(
|
||||||
|
'used' => $matches[6],
|
||||||
|
'soft' => $matches[7],
|
||||||
|
'hard' => $matches[8],
|
||||||
|
'grace' => $matches[9]
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
$result = $db->query("SELECT * FROM `" . TABLE_PANEL_CUSTOMERS . "` ORDER BY `customerid` ASC");
|
$result = $db->query("SELECT * FROM `" . TABLE_PANEL_CUSTOMERS . "` ORDER BY `customerid` ASC");
|
||||||
|
|
||||||
while($row = $db->fetch_array($result))
|
while($row = $db->fetch_array($result))
|
||||||
@@ -179,7 +208,7 @@ while($row = $db->fetch_array($result))
|
|||||||
safeSQLLogfile($domainlist[$row['customerid']], $row['loginname']);
|
safeSQLLogfile($domainlist[$row['customerid']], $row['loginname']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// callAwstatsGetTraffic is called ONLY HERE and
|
// callAwstatsGetTraffic is called ONLY HERE and
|
||||||
// *not* also in the special-logfiles-loop, because the function
|
// *not* also in the special-logfiles-loop, because the function
|
||||||
// will iterate through all customer-domains and the awstats-configs
|
// will iterate through all customer-domains and the awstats-configs
|
||||||
// know the logfile-name, #246
|
// know the logfile-name, #246
|
||||||
@@ -191,7 +220,7 @@ while($row = $db->fetch_array($result))
|
|||||||
{
|
{
|
||||||
$httptraffic+= floatval(callWebalizerGetTraffic($row['loginname'], $row['documentroot'] . '/webalizer/', $caption, $domainlist[$row['customerid']]));
|
$httptraffic+= floatval(callWebalizerGetTraffic($row['loginname'], $row['documentroot'] . '/webalizer/', $caption, $domainlist[$row['customerid']]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// make the stuff readable for the customer, #258
|
// make the stuff readable for the customer, #258
|
||||||
makeChownWithNewStats($row);
|
makeChownWithNewStats($row);
|
||||||
|
|
||||||
@@ -207,7 +236,7 @@ while($row = $db->fetch_array($result))
|
|||||||
$db->close();
|
$db->close();
|
||||||
require_once ($pathtophpfiles . '/lib/userdata.inc.php');
|
require_once ($pathtophpfiles . '/lib/userdata.inc.php');
|
||||||
$db = new db($sql['host'], $sql['user'], $sql['password'], $sql['db']);
|
$db = new db($sql['host'], $sql['user'], $sql['password'], $sql['db']);
|
||||||
|
|
||||||
if ($db->link_id == 0) {
|
if ($db->link_id == 0) {
|
||||||
fclose($debugHandler);
|
fclose($debugHandler);
|
||||||
unlink($lockfile);
|
unlink($lockfile);
|
||||||
@@ -285,23 +314,33 @@ while($row = $db->fetch_array($result))
|
|||||||
|
|
||||||
fwrite($debugHandler, 'calculating webspace usage for ' . $row['loginname'] . "\n");
|
fwrite($debugHandler, 'calculating webspace usage for ' . $row['loginname'] . "\n");
|
||||||
$webspaceusage = 0;
|
$webspaceusage = 0;
|
||||||
|
|
||||||
if(file_exists($row['documentroot']) && is_dir($row['documentroot']))
|
# Using repquota, it's faster using this tool than using du traversing the complete directory
|
||||||
|
if ($settings['system']['diskquota_enabled'])
|
||||||
{
|
{
|
||||||
$back = safe_exec('du -sk ' . escapeshellarg($row['documentroot']) . '');
|
# We may use the array we created earlier, the used diskspace is stored in [<guid>][block][used]
|
||||||
foreach($back as $backrow)
|
$webspaceusage = floatval($usedquota[$row['guid']]['block']['used']);
|
||||||
{
|
|
||||||
$webspaceusage = explode(' ', $backrow);
|
|
||||||
}
|
|
||||||
|
|
||||||
$webspaceusage = floatval($webspaceusage['0']);
|
|
||||||
unset($back);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fwrite($debugHandler, 'documentroot ' . $row['documentroot'] . ' does not exist' . "\n");
|
# Use the old fashioned way with "du"
|
||||||
|
if(file_exists($row['documentroot']) && is_dir($row['documentroot']))
|
||||||
|
{
|
||||||
|
$back = safe_exec('du -sk ' . escapeshellarg($row['documentroot']) . '');
|
||||||
|
foreach($back as $backrow)
|
||||||
|
{
|
||||||
|
$webspaceusage = explode(' ', $backrow);
|
||||||
|
}
|
||||||
|
|
||||||
|
$webspaceusage = floatval($webspaceusage['0']);
|
||||||
|
unset($back);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fwrite($debugHandler, 'documentroot ' . $row['documentroot'] . ' does not exist' . "\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MailSpace-Usage
|
* MailSpace-Usage
|
||||||
*/
|
*/
|
||||||
@@ -317,7 +356,7 @@ while($row = $db->fetch_array($result))
|
|||||||
{
|
{
|
||||||
$emailusage = explode(' ', $backrow);
|
$emailusage = explode(' ', $backrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
$emailusage = floatval($emailusage['0']);
|
$emailusage = floatval($emailusage['0']);
|
||||||
unset($back);
|
unset($back);
|
||||||
}
|
}
|
||||||
@@ -380,11 +419,11 @@ while($row = $db->fetch_array($result))
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
$db->query("UPDATE `" . TABLE_FTP_QUOTATALLIES . "` SET `bytes_in_used`='" . (float)$current_diskspace['all'] . "'*1024 WHERE `name` = '" . $row['loginname'] . "' OR `name` LIKE '" . $row['loginname'] . $settings['customer']['ftpprefix'] . "%'");
|
$db->query("UPDATE `" . TABLE_FTP_QUOTATALLIES . "` SET `bytes_in_used`='" . (float)$current_diskspace['all'] . "'*1024 WHERE `name` = '" . $row['loginname'] . "' OR `name` LIKE '" . $row['loginname'] . $settings['customer']['ftpprefix'] . "%'");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pureftpd Quota
|
* Pureftpd Quota
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if($settings['system']['ftpserver'] == "pureftpd")
|
if($settings['system']['ftpserver'] == "pureftpd")
|
||||||
{
|
{
|
||||||
$result_quota = $db->query("SELECT homedir FROM `" . TABLE_FTP_USERS . "` WHERE customerid = '" . $row['customerid'] . "'");
|
$result_quota = $db->query("SELECT homedir FROM `" . TABLE_FTP_USERS . "` WHERE customerid = '" . $row['customerid'] . "'");
|
||||||
@@ -400,7 +439,7 @@ while($row = $db->fetch_array($result))
|
|||||||
$user = $row['guid'];
|
$user = $row['guid'];
|
||||||
$group = $row['guid'];
|
$group = $row['guid'];
|
||||||
}
|
}
|
||||||
|
|
||||||
while($row_quota = $db->fetch_array($result_quota))
|
while($row_quota = $db->fetch_array($result_quota))
|
||||||
{
|
{
|
||||||
$quotafile = "" . $row_quota['homedir'] . ".ftpquota";
|
$quotafile = "" . $row_quota['homedir'] . ".ftpquota";
|
||||||
|
|||||||
Reference in New Issue
Block a user