1: <?php
2: /**
3: * Implementation of IMP_Quota API for IMAP servers with a *nix quota command.
4: * This requires a modified "quota" command that allows the httpd server
5: * account to get quotas for other users. It also requires that your
6: * web server and imap server be the same server or at least have shared
7: * authentication and file servers (e.g. via NIS/NFS). And last, it (as
8: * written) requires the POSIX PHP extensions.
9: *
10: * Copyright 2002-2012 Horde LLC (http://www.horde.org/)
11: *
12: * See the enclosed file COPYING for license information (GPL). If you
13: * did not receive this file, see http://www.horde.org/licenses/gpl.
14: *
15: * @author Eric Rostetter <eric.rostetter@physics.utexas.edu>
16: * @category Horde
17: * @license http://www.horde.org/licenses/gpl GPL
18: * @package IMP
19: */
20: class IMP_Quota_Command extends IMP_Quota_Base
21: {
22: /**
23: * Constructor.
24: *
25: * @param array $params Parameters:
26: * <pre>
27: * 'grep_path' - (string) [REQUIRED] Path to the grep binary.
28: * 'partition' - (string) If all user mailboxes are on a single partition,
29: * the partition label. By default, quota will determine
30: * quota information using the user's home directory value.
31: * 'quota_path' - (string) [REQUIRED] Path to the quota binary.
32: * </pre>
33: */
34: public function __construct(array $params = array())
35: {
36: $params = array_merge(array(
37: 'quota_path' => 'quota',
38: 'grep_path' => 'grep',
39: 'partition' => null
40: ), $params);
41:
42: parent::__construct($params);
43: }
44:
45: /**
46: * Get the disk block size, if possible.
47: *
48: * We try to find out the disk block size from stat(). If not
49: * available, stat() should return -1 for this value, in which
50: * case we default to 1024 (for historical reasons). There are a
51: * large number of reasons this may fail, such as OS support,
52: * SELinux interference, the file being > 2 GB in size, the file
53: * we're referring to not being readable, etc.
54: *
55: * @return integer The disk block size.
56: */
57: protected function _blockSize()
58: {
59: $results = stat(__FILE__);
60: return ($results['blksize'] > 1)
61: ? $results['blksize']
62: : 1024;
63: }
64:
65: /**
66: * Get quota information (used/allocated), in bytes.
67: *
68: * @return array An array with the following keys:
69: * 'limit' = Maximum quota allowed
70: * 'usage' = Currently used portion of quota (in bytes)
71: * @throws IMP_Exception
72: */
73: public function getQuota()
74: {
75: if (empty($this->_params['partition'])) {
76: $passwd_array = posix_getpwnam($this->_params['username']);
77: list($junk, $search_string, $junk) = explode('/', $passwd_array['dir']);
78: } else {
79: $search_string = $this->_params['partition'];
80: }
81: $cmdline = $this->_params['quota_path'] . ' -u ' . escapeshellarg($this->_params['username']) . ' | ' . escapeshellcmd($this->_params['grep_path']) . ' ' . escapeshellarg($search_string);
82: exec($cmdline, $quota_data, $return_code);
83: if (($return_code == 0) && (count($quota_data) == 1)) {
84: $quota = split("[[:blank:]]+", trim($quota_data[0]));
85: $blocksize = $this->_blockSize();
86: return array(
87: 'limit' => $quota[2] * $blocksize,
88: 'usage' => $quota[1] * $blocksize
89: );
90: }
91:
92: throw new IMP_Exception(_("Unable to retrieve quota"));
93: }
94:
95: }
96: