1010 */
1111class SendmailThrottle extends StdinMailParser
1212{
13+ const STATUS_OK = 0 ;
14+ const STATUS_QUOTA_REACHED = 1 ;
15+ const STATUS_OVERQUOTA = 2 ;
16+ const STATUS_BLOCKED = 3 ;
17+ const STATUS_EXCEPTION = 4 ;
18+
1319 /**
1420 * @var StdClass
1521 */
@@ -60,7 +66,7 @@ protected function _connect()
6066 *
6167 * status code 0: limit not reached, ok
6268 * status code 1: limit reached, sending notification to admin
63- * status code 2: limit succeeded , do not warn admin multiple times
69+ * status code 2: over limit , do not warn admin multiple times
6470 *
6571 * @param string $username
6672 * @param int $rcptCount number of recipients
@@ -74,41 +80,35 @@ public function run($username, $rcptCount)
7480 $ this ->_connect ();
7581
7682 // default status code: success
77- $ status = 0 ;
83+ $ status = self :: STATUS_OK ;
7884
7985 $ sql = 'SELECT * FROM throttle WHERE username = :username ' ;
8086 $ stmt = $ this ->_pdo ->prepare ($ sql );
8187 $ stmt ->bindParam (':username ' , $ username );
8288 $ stmt ->execute ();
83- $ obj = $ stmt ->fetchObject ();
84- if ($ obj ) {
89+ $ throttle = $ stmt ->fetchObject ();
90+ if ($ throttle ) {
8591 // reset counters on new day (after midnight)
86- $ dateUpdated = new DateTime ($ obj ->updated_ts );
92+ $ dateUpdated = new DateTime ($ throttle ->updated_ts );
8793 $ dateCurrent = new DateTime ();
8894 $ sameDay = ($ dateUpdated ->format ('Y-m-d ' ) == $ dateCurrent ->format ('Y-m-d ' ));
8995 if (!$ sameDay ) {
9096 $ countCur = 1 ;
9197 $ rcptCur = 1 ;
9298 } else {
93- $ countCur = ++$ obj ->count_cur ; // raise by 1
94- $ rcptCur = $ obj ->rcpt_cur + $ rcptCount ; // raise by number of recipients
99+ $ countCur = ++$ throttle ->count_cur ; // raise by 1
100+ $ rcptCur = $ throttle ->rcpt_cur + $ rcptCount ; // raise by number of recipients
95101 }
96102
97- $ countMax = $ obj ->count_max ;
98- $ countTot = ++$ obj ->count_tot ; // raise by 1
99- $ rcptMax = $ obj ->rcpt_max ;
100- $ rcptTot = $ obj ->rcpt_tot + $ rcptCount ; // raise by number of recipients
101-
102- // check email count
103- if ($ countCur > $ countMax ) {
104- // return 1 if previous status was 0 (ok), otherwise 2
105- $ status = ($ obj ->status == 0 ) ? 1 : 2 ;
106- }
103+ $ countMax = $ throttle ->count_max ;
104+ $ countTot = ++$ throttle ->count_tot ; // raise by 1
105+ $ rcptMax = $ throttle ->rcpt_max ;
106+ $ rcptTot = $ throttle ->rcpt_tot + $ rcptCount ; // raise by number of recipients
107107
108- // check recipient count
109- if ($ rcptCur > $ obj -> rcpt_max ) {
108+ // check email or recipient count
109+ if ($ countCur > $ countMax || $ rcptCur > $ rcptMax ) {
110110 // return 1 if previous status was 0 (ok), otherwise 2
111- $ status = ($ obj ->status == 0 ) ? 1 : 2 ;
111+ $ status = ($ throttle ->status == self :: STATUS_OK ) ? self :: STATUS_QUOTA_REACHED : self :: STATUS_OVERQUOTA ;
112112 }
113113
114114 $ sql = 'UPDATE throttle SET updated_ts = NOW(), count_cur = :countCur, count_tot = :countTot,
@@ -122,7 +122,12 @@ public function run($username, $rcptCount)
122122 $ stmt ->bindParam (':status ' , $ status , PDO ::PARAM_INT );
123123 $ stmt ->bindParam (':username ' , $ username );
124124 $ stmt ->execute ();
125- $ id = $ obj ->id ;
125+ $ id = $ throttle ->id ;
126+
127+ // if user is blocked, override previous status by return code 3
128+ if ($ throttle ->blocked ) {
129+ $ status = self ::STATUS_BLOCKED ;
130+ }
126131 } else {
127132 $ countMax = $ this ->_conf ->throttle ->countMax ;
128133 $ countCur = 1 ;
@@ -161,12 +166,16 @@ public function run($username, $rcptCount)
161166 $ rcptCur ,
162167 $ rcptTot
163168 );
164- syslog (LOG_INFO , $ syslogMsg );
169+ // Don't write to syslog for blocked useraccounts - we still have all meta information in messages
170+ // table but don't want to fill up syslog.
171+ if ($ status != self ::STATUS_BLOCKED ) {
172+ syslog (LOG_INFO , $ syslogMsg );
173+ }
165174
166- // Report message limit succeeded to administrator
167- if ($ status == 1 ) {
168- // Do not report on status code 2, as the admin only wants to get
169- // notified once!
175+ // Report message limit reached to administrator
176+ if ($ status == self :: STATUS_QUOTA_REACHED ) {
177+ // Do not report on status code 2, as the admin only wants to get notified once!
178+ // Also, he is never interested in blocked accounts (status code 3).
170179 mail (
171180 $ this ->_conf ->global ->adminTo ,
172181 $ this ->_conf ->throttle ->adminSubject ,
@@ -175,15 +184,13 @@ public function run($username, $rcptCount)
175184 );
176185 }
177186
178- // write to db log
187+ // write all meta information to db messages log
179188 $ this ->_logMessage ($ id , $ username , $ rcptCount , $ status );
180189
181- // return status code
182190 return $ status ;
183-
184191 } catch (PDOException $ e ) {
185192 syslog (LOG_WARNING , sprintf ('%s: PDOException: %s ' , $ this ->_conf ->throttle ->syslogPrefix , $ e ->getMessage ()));
186- return 3 ;
193+ return self :: STATUS_EXCEPTION ;
187194 }
188195 }
189196
0 commit comments