[[toc]]
+++ Notes
This describes modifications to IMP quota that can be configured to use one or two different devices (file systems). If using two devices, one is for INBOX and the other is for IMAP folders.
You can use one or two different devices (file systems) with quota enabled. This allows different quota values for INBOX and IMAP folders. Users use to keep messages on the INBOX. The bigger the quota, the bigger the INBOX file, with performance hit. In the other hand, messages are documents that must be filed, so you may want to give more space for IMAP folders than for the INBOX.
Uses system quota command.
+++ Modifications
||~ File ||~ Function(s) ||
|| imp/lib/Quota/command.php || IMP_Quota_command, getQuota ||
|| imp/lib/IMP.php || quota, quotaData ||
|| imp/lib/Quota.php || getQuota, getMessages ||
|| imp/config/servers.php || ||
You must modify the four files. Don't forget to change permission to each of them:
chown www-data command.php
Where www-data is the web user (Apache or equivalent).
You may need to give permission to your web user to execute quota:
chmod +s /usr/bin/quota
++++ command.php
'dev_inbx' => User´s INBOX file system device - REQUIRED
If you have INBOX and IMAP folders in the same device, use //ONLY// this parameter.
If you have INBOX and IMAP folders in different devices and quota enabled on them you //MUST// use 'dev_fldrs' parameter also.
Usually maps to /var/mail, /var/spool/mail.
Examples: '/dev/hda6', '/dev/sdb2', '/dev/md2', '/dev/mapper/VOL1-VarM'.
'dev_fldrs' => User´s home file system device - OPTIONAL
Use only if you have INBOX and IMAP folders in different devices and quota enabled on them.
Used for IMAP folders. Usually maps to /home.
Examples: '/dev/hda7', '/dev/sda3', '/dev/md1', '/dev/mapper/VOL2-Home'.
Obsolete parameters: grep_path, partition
Function now takes care of exceeded quotas, quota not defined for that user and if it is using one or two devices (dev_inbx, dev_fldrs).
Backup your original imp/lib/Quota/command.php and create a new command.php with the following code:
$servers['imap'] = array(
...
'quota' => array(
'driver' => 'command',
'params' => array(
'quota_path' => '/usr/bin/quota',
'dev_inbx' => '/dev/hda6')
)
);
* Two devices:
$servers['imap'] = array(
...
'quota' => array(
'driver' => 'command',
'params' => array(
'quota_path' => '/usr/bin/quota',
'dev_fldrs' => '/dev/hda7',
'dev_inbx' => '/dev/hda6')
)
);
----
++++ Quota.php
* New messages:
> Alerts quota exceeded, grace time or expired;
> Alerts almost full;
> Normal quota information.
Backup your original imp/lib/Quota.php. Edit Quota.php and replace functions "getQuota" and "getMessages" with the following code:
/**
* Get quota information (used/allocated), in bytes.
*
* @return mixed An associative array.
* 'limit...' = Maximum quota allowed
* 'usage...' = Currently used portion of quota (in bytes)
* 'limithome' and 'usagehome' for dev_fldrs (/home) (mail folders)
* 'limitvar' and 'usagevar' for dev_inbx (/var/mail) (INBOX)
* Returns PEAR_Error on failure.
*/
function getQuota()
{
return array('usagehome' => 0, 'limithome' => 0, 'usagevar' => 0, 'limitvar' => 0);
}
/**
* Returns the quota messages variants, including sprintf placeholders.
*
* @return array A hash with quota message templates.
*/
function getMessages()
{
return array(
'longh' => (isset($this->_params['format']['longh']))
? $this->_params['format']['longh']
: _("Folders: %.2fMB / %.2fMB (%.2f%%)"),
'longhaf' => (isset($this->_params['format']['longhaf']))
? $this->_params['format']['longhaf']
: _("ATTENTION! Folders area almost full: %.2fMB / %.2fMB (%.2f%%)"),
'longhle' => (isset($this->_params['format']['longhle']))
? $this->_params['format']['longhle']
: _("ATTENTION! Folders: Limit exceeded: %.2fMB / %.2fMB (%.2f%%). Please, solve before %s day(s)."),
'longhlee' => (isset($this->_params['format']['longhlee']))
? $this->_params['format']['longhlee']
: _("ATTENTION! Folders: Limit exceeded: %.2fMB / %.2fMB (%.2f%%). Expired."),
'shorth' => isset($this->_params['format']['shorth'])
? $this->_params['format']['shorth']
: _("Folders: %.0f%% of %.0fMB"),
'shorthaf' => isset($this->_params['format']['shorthaf'])
? $this->_params['format']['shorthaf']
: _("ATTENTION! Folders area almost full: %.0f%% of %.0fMB"),
'shorthle' => isset($this->_params['format']['shorthle'])
? $this->_params['format']['shorthle']
: _("ATTENTION! Folders: Limit exceeded: %.0f%% of %.0fMB. Please, solve before %s day(s)."),
'shorthlee' => isset($this->_params['format']['shorthlee'])
? $this->_params['format']['shorthlee']
: _("ATTENTION! Folders: Limit exceeded: %.0f%% of %.0fMB. Expired."),
'nolimit_longh' => isset($this->_params['format']['nolimit_longh'])
? $this->_params['format']['nolimit_longh']
: _("Folders: %.2fMB / NO limit."),
'nolimit_shorth' => isset($this->_params['format']['nolimit_shorth'])
? $this->_params['format']['nolimit_shorth']
: _("Folders: %.0f MB"),
'longi' => (isset($this->_params['format']['longi']))
? $this->_params['format']['longi']
: _("Inbox: %.2fMB / %.2fMB (%.2f%%)"),
'longiaf' => (isset($this->_params['format']['longiaf']))
? $this->_params['format']['longiaf']
: _("ATTENTION! Inbox almost full: %.2fMB / %.2fMB (%.2f%%)"),
'longile' => (isset($this->_params['format']['longile']))
? $this->_params['format']['longile']
: _("ATTENTION! Inbox: limit exceeded: %.2fMB / %.2fMB (%.2f%%). Please, solve in %s day(s)."),
'longilee' => (isset($this->_params['format']['longilee']))
? $this->_params['format']['longilee']
: _("ATTENTION! Inbox: limit exceeded: %.2fMB / %.2fMB (%.2f%%). Date expired."),
'shorti' => isset($this->_params['format']['shorti'])
? $this->_params['format']['shorti']
: _("Inbox: %.0f%% of %.0fMB"),
'shortiaf' => isset($this->_params['format']['shortiaf'])
? $this->_params['format']['shortiaf']
: _("ATTENTION! Inbox almost full: %.0f%% of %.0fMB"),
'shortile' => isset($this->_params['format']['shortile'])
? $this->_params['format']['shortile']
: _("ATTENTION! Inbox: Limit exceeded: %.0f%% of %.0fMB. Please, solve before %s day(s)."),
'shortilee' => isset($this->_params['format']['shortilee'])
? $this->_params['format']['shortilee']
: _("ATTENTION! Inbox: Limit exceeded: %.0f%% of %.0fMB. Expired."),
'nolimit_longi' => isset($this->_params['format']['nolimit_longi'])
? $this->_params['format']['nolimit_longi']
: _("Inbox: %.2f MB / NO LIMIT"),
'nolimit_shorti' => isset($this->_params['format']['nolimit_shorti'])
? $this->_params['format']['nolimit_shorti']
: _("Inbox: %.0f MB"));
}
----
++++ IMP.php
* Function quotaData takes care of using one or two devices (dev_inbx, dev_fldrs). New information scale:
> quota >= 100%, quotaalert. Alerts quota exceeded, grace time or expired;
> 90% <= quota < 100%, quotaalert. Alerts almost full;
> 75% <= quota < 90%, quotawarn;
> quota < 75%, control.
> To change the control and warn percentages just edit quotaData function to the desired values.
Backup your original imp/lib/IMP.php. Edit IMP.php and replace functions "quota" and "quotaData" with the following code:
/**
* Outputs IMP's quota information.
* Modified by Mauricio Jose T. Tecles
* Updated 2010 February 28
*/
function quota()
{
$quotadata = IMP::quotaData(true);
if (!empty($quotadata)) {
require_once IMP_BASE . '/lib/Template.php';
if (!empty($quotadata['messagehome'])) {
$t = new IMP_Template();
$t->set('class', $quotadata['classhome']);
$t->set('message', $quotadata['messagehome']);
echo $t->fetch(IMP_TEMPLATES . '/quota/quota.html');
}
$t = new IMP_Template();
$t->set('class', $quotadata['classvar']);
$t->set('message', $quotadata['messagevar']);
echo $t->fetch(IMP_TEMPLATES . '/quota/quota.html');
}
}
/**
* Returns data needed to output quota.
*
* @since IMP 4.2
*
* @param boolean $long Output long messages?
*
* @return array Array with these keys: class, message, percent.
*
* Modified by Mauricio Jose T. Tecles
* Updated 2010 February 28
*/
function quotaData($long = true)
{
if (!isset($_SESSION['imp']['quota']) ||
!is_array($_SESSION['imp']['quota'])) {
return false;
}
require_once IMP_BASE . '/lib/Quota.php';
$quotaDriver = &IMP_Quota::singleton($_SESSION['imp']['quota']['driver'], $_SESSION['imp']['quota']['params']);
if ($quotaDriver === false) {
return false;
}
$quota = $quotaDriver->getQuota();
if (is_a($quota, 'PEAR_Error')) {
Horde::logMessage($quota, __FILE__, __LINE__, PEAR_LOG_ERR);
return false;
}
$strings = $quotaDriver->getMessages();
$ret = array('percent' => 0);
/* Quota for dev_fldrs */
unset($ret['messagehome']);
if ($quota['soflimithome'] > 0) {
$quota['usagehome'] = $quota['usagehome'] / (1024 * 1024.0);
$quota['soflimithome'] = $quota['soflimithome'] / (1024 * 1024.0);
$ret['percent'] = ($quota['usagehome'] * 100) / $quota['soflimithome'];
if ($ret['percent'] >= 100) {
$ret['classhome'] = 'quotaalert';
if (ereg("none", $quota['gracehome'])) {
if ($long) {
$ret['messagehome'] = sprintf($strings['longhlee'], $quota['usagehome'], $quota['soflimithome'], $ret['percent']);
} else {
$ret['messagehome'] = sprintf($strings['shorthlee'], $ret['percent'], $quota['soflimithome']);
}
} else {
if ($long) {
$ret['messagehome'] = sprintf($strings['longhle'], $quota['usagehome'], $quota['soflimithome'], $ret['percent'], $quota['gracehome']);
} else {
$ret['messagehome'] = sprintf($strings['shorthle'], $ret['percent'], $quota['soflimithome'], $quota['gracehome']);
}
}
} elseif ($ret['percent'] >= 90) {
$ret['classhome'] = 'quotaalert';
if ($long) {
$ret['messagehome'] = sprintf($strings['longhaf'], $quota['usagehome'], $quota['soflimithome'], $ret['percent']);
} else {
$ret['messagehome'] = sprintf($strings['shorthaf'], $ret['percent'], $quota['soflimithome']);
}
} elseif ($ret['percent'] >= 75) {
$ret['classhome'] = 'quotawarn';
if ($long) {
$ret['messagehome'] = sprintf($strings['longh'], $quota['usagehome'], $quota['soflimithome'], $ret['percent']);
} else {
$ret['messagehome'] = sprintf($strings['shorth'], $ret['percent'], $quota['soflimithome']);
}
} else {
$ret['classhome'] = 'control';
if ($long) {
$ret['messagehome'] = sprintf($strings['longh'], $quota['usagehome'], $quota['soflimithome'], $ret['percent']);
} else {
$ret['messagehome'] = sprintf($strings['shorth'], $ret['percent'], $quota['soflimithome']);
}
}
} else {
// Hide unlimited quota message?
if (!empty($_SESSION['imp']['quota']['params']['hide_quota_when_unlimited'])) {
return false;
}
$ret['classhome'] = 'control';
if ($quota['usagehome'] > 0) {
$quota['usagehome'] = $quota['usagehome'] / (1024 * 1024.0);
if ($long) {
$ret['messagehome'] = sprintf($strings['nolimit_longh'], $quota['usagehome']);
} else {
$ret['messagehome'] = sprintf($strings['nolimit_shorth'], $quota['usagehome']);
}
} elseif ($quota['usagehome'] == 0) {
$ret['messagehome'] = sprintf(_("Folders: NO LIMIT"));
}
}
/* Quota for dev_inbx */
if ($quota['soflimitvar'] != 0) {
$quota['usagevar'] = $quota['usagevar'] / (1024 * 1024.0);
$quota['soflimitvar'] = $quota['soflimitvar'] / (1024 * 1024.0);
$ret['percent'] = ($quota['usagevar'] * 100) / $quota['soflimitvar'];
if ($ret['percent'] >= 100) {
$ret['classvar'] = 'quotaalert';
if (ereg("none", $quota['gracevar'])) {
if ($long) {
$ret['messagevar'] = sprintf($strings['longilee'], $quota['usagevar'], $quota['soflimitvar'], $ret['percent']);
} else {
$ret['messagevar'] = sprintf($strings['shortilee'], $ret['percent'], $quota['soflimitvar']);
}
} else {
if ($long) {
$ret['messagevar'] = sprintf($strings['longile'], $quota['usagevar'], $quota['soflimitvar'], $ret['percent'], $quota['gracevar']);
} else {
$ret['messagevar'] = sprintf($strings['shortile'], $ret['percent'], $quota['soflimitvar'], $quota['gracevar']);
}
}
} elseif ($ret['percent'] >= 90) {
$ret['classvar'] = 'quotaalert';
if ($long) {
$ret['messagevar'] = sprintf($strings['longiaf'], $quota['usagevar'], $quota['soflimitvar'], $ret['percent']);
} else {
$ret['messagevar'] = sprintf($strings['shortiaf'], $ret['percent'], $quota['soflimitvar']);
}
} elseif ($ret['percent'] >= 75) {
$ret['classvar'] = 'quotawarn';
if ($long) {
$ret['messagevar'] = sprintf($strings['longi'], $quota['usagevar'], $quota['soflimitvar'], $ret['percent']);
} else {
$ret['messagevar'] = sprintf($strings['shorti'], $ret['percent'], $quota['soflimitvar']);
}
} else {
$ret['classvar'] = 'control';
if ($long) {
$ret['messagevar'] = sprintf($strings['longi'], $quota['usagevar'], $quota['soflimitvar'], $ret['percent']);
} else {
$ret['messagevar'] = sprintf($strings['shorti'], $ret['percent'], $quota['soflimitvar']);
}
}
} else {
// Hide unlimited quota message?
if (!empty($_SESSION['imp']['quota']['params']['hide_quota_when_unlimited'])) {
return false;
}
$ret['classvar'] = 'control';
if ($quota['usagevar'] != 0) {
$quota['usagevar'] = $quota['usagevar'] / (1024 * 1024.0);
if ($long) {
$ret['messagevar'] = sprintf($strings['nolimit_longi'],
$quota['usagevar']);
} else {
$ret['messagevar'] = sprintf($strings['nolimit_shorti'],
$quota['usagevar']);
}
} else {
$ret['messagevar'] = sprintf(_("Inbox: NO LIMIT"));
}
}
return $ret;
}
----