Overview

Packages

  • Kolab
    • Filter
    • Test

Classes

  • Dovecot_LDA
  • DropWrapper
  • EchoWrapper
  • Horde_Kolab_Filter
  • Horde_Kolab_Filter_Base
  • Horde_Kolab_Filter_Cli
  • Horde_Kolab_Filter_Cli_Parser
  • Horde_Kolab_Filter_Configuration
  • Horde_Kolab_Filter_Content
  • Horde_Kolab_Filter_Exception
  • Horde_Kolab_Filter_Exception_IoError
  • Horde_Kolab_Filter_Exception_Temporary
  • Horde_Kolab_Filter_Exception_Usage
  • Horde_Kolab_Filter_Factory
  • Horde_Kolab_Filter_Incoming
  • Horde_Kolab_Filter_Response
  • Horde_Kolab_Filter_Temporary_File
  • Horde_Kolab_Filter_Transport
  • Horde_Kolab_Filter_Transport_drop
  • Horde_Kolab_Filter_Transport_echo
  • Horde_Kolab_Filter_Transport_lda
  • Horde_Kolab_Filter_Transport_lmtp
  • Horde_Kolab_Filter_Transport_smtp
  • Horde_Kolab_Filter_Transport_stdout
  • Kolab_Filter_Outlook
  • Net_LMTP_TLS
  • StdOutWrapper

Interfaces

  • Horde_Kolab_Filter_Temporary
  • Overview
  • Package
  • Class
  • Tree
  1: <?PHP
  2: /**
  3:  * @package Kolab_Filter
  4:  */
  5: 
  6: /**
  7:  * Defines a transport mechanism for delivering mails to the dovecot
  8:  * IMAP server.
  9:  *
 10:  * Copyright 2008 Intevation GmbH
 11:  *
 12:  * See the enclosed file COPYING for license information (LGPL). If you
 13:  * did not receive this file, see http://www.horde.org/licenses/lgpl21.
 14:  *
 15:  * @author  Sascha Wilde <wilde@intevation.de>
 16:  * @package Kolab_Filter
 17:  */
 18: class Dovecot_LDA
 19: {
 20:     /**
 21:      * The mail sender.
 22:      *
 23:      * @var string
 24:      */
 25:     var $_envelopeSender;
 26: 
 27:     /**
 28:      * The mail recipient.
 29:      *
 30:      * @var string
 31:      */
 32:     var $_envelopeTo = array();
 33: 
 34:     /**
 35:      * Transport status.
 36:      *
 37:      * @var int
 38:      */
 39:     var $_status;
 40: 
 41:     /**
 42:      * The data that should be sent.
 43:      *
 44:      * @var array
 45:      */
 46:     var $_data;
 47: 
 48:     /**
 49:      * File handle for delivery.
 50:      *
 51:      * @var int
 52:      */
 53:     var $_deliver_fh;
 54: 
 55:     function Dovecot_LDA()
 56:     {
 57:         $this->_envelopeTo = false;
 58:         $this->_status = 220;
 59:     }
 60: 
 61:     /**
 62:      * Pretends to connect to Dovecot which is not necessary.
 63:      *
 64:      * @return boolean|PEAR_Error Always true.
 65:      */
 66:     function connect()
 67:     {
 68:         global $conf;
 69: 
 70:         if (!isset($conf['kolab']['filter']['dovecot_deliver'])) {
 71:             return PEAR::raiseError('Path to the dovecot delivery tool missing!');
 72:         }
 73:         return true;
 74:     }
 75: 
 76:     /**
 77:      * Pretends to disconnect from Dovecot which is not necessary.
 78:      *
 79:      * @return boolean Always true.
 80:      */
 81:     function disconnect()
 82:     {
 83:         return true;
 84:     }
 85: 
 86: 
 87:     /**
 88:      * Set the mail sender.
 89:      *
 90:      * @return boolean Always true.
 91:      */
 92:     function mailFrom($sender)
 93:     {
 94:         $this->_envelopeSender = $sender;
 95:         $this->_status = 250;
 96:         return true;
 97:     }
 98: 
 99:     /**
100:      * Add a mail recipient.
101:      *
102:      * @return boolean Always true.
103:      */
104:     function rcptTo($rcpt)
105:     {
106:         $this->_envelopeTo[] = $rcpt;
107:         $this->_status = 250;
108:         return true;
109:     }
110: 
111:     /**
112:      * Receive commands.
113:      *
114:      * @param string $cmd The command.
115:      *
116:      * @return boolean|PEAR_Error True if the command succeeded.
117:      */
118:     function _put($cmd)
119:     {
120:         if ($cmd == "DATA") {
121:             $this->_status = 354;
122:         } else {
123:             $this->_status = 500;
124:             return PEAR::raiseError('Dovecot LDA Backend received an unknown command.');
125:         }
126:         return true;
127:     }
128: 
129:     /**
130:      * Check the current response code.
131:      *
132:      * @param string $code The response to parse.
133:      *
134:      * @return boolean|PEAR_Error True if the current status matches
135:      * the expectation.
136:      */
137:     function _parseResponse($code)
138:     {
139:         if ($code) {
140:             if ($this->_status == $code) {
141:                 return true;
142:             } else {
143:                 return PEAR::raiseError(sprintf("Dovecot LDA status is %s though %s was expected!.",
144:                                                 $this->_status, $code));
145:             }
146:         } else {
147:             return $this->status;
148:         }
149:     }
150: 
151:     /**
152:      * Send actual mail data.
153:      *
154:      * @param string $data The data to write.
155:      *
156:      * @return boolean|PEAR_Error True if successful.
157:      */
158:     function _send($data)
159:     {
160:         $errors = array();
161:         if ($data == ".\r\n" or $data == "\r\n.\r\n") {
162:             foreach ($this->_envelopeTo as $recipient) {
163:                 $result = $this->_start_deliver($recipient);
164:                 if (is_a($result, 'PEAR_Error')) {
165:                     $errors[] = $result;
166:                     continue;
167:                 }
168: 
169:                 $result = $this->_deliver();
170:                 if (is_a($result, 'PEAR_Error')) {
171:                     $errors[] = $result;
172:                     continue;
173:                 }
174: 
175:                 $result = $this->_stop_deliver();
176:                 if (is_a($result, 'PEAR_Error')) {
177:                     $errors[] = $result;
178:                     continue;
179:                 }
180:             }
181:             if (empty($errors)) {
182:                 $this->_status = 250;
183:             } else {
184:                 $this->_status = 500;
185:                 $msg = '';
186:                 foreach ($errors as $error) {
187:                     $msg[] = $error->getMessage();
188:                 }
189:                 return PEAR::raiseError(sprintf("Dovecot delivery failed: %s",
190:                                                 join(', ', $msg)));
191:             }
192:         } else {
193:             $this->_data[] = $data;
194:         }
195:         return true;
196:     }
197: 
198: 
199:     /**
200:      * Start the delivery process for a recipient.
201:      *
202:      * @param string $recipient The recipient of the message.
203:      *
204:      * @return boolean|PEAR_Error True if successful.
205:      */
206:     function _start_deliver($recipient)
207:     {
208:         global $conf;
209: 
210:         Horde::logMessage(sprintf("Starting Dovecot delivery process with UID %d, GID %d (sender=%s, recipient=%s) ...",
211:                                   getmyuid(), getmygid(),
212:                                   $this->_envelopeSender, $recipient), 'DEBUG');
213: 
214:         $deliver = $conf['kolab']['filter']['dovecot_deliver'];
215: 
216:         $this->_deliver_fh = popen($deliver . ' -f "' . $this->_envelopeSender .
217:                                    '" -d "' . $recipient . '"', "w");
218:         if ($this->_deliver_fh === false) {
219:             return PEAR::raiseError('Failed to connect to the dovecot delivery tool!');
220:         }
221:         return true;
222:     }
223: 
224:     /**
225:      * End the delivery process for a recipient.
226:      *
227:      * @return boolean|PEAR_Error True if successful.
228:      */
229:     function _stop_deliver()
230:     {
231:         Horde::logMessage("Stoping Dovecot delivery process ...", 'DEBUG');
232:         $retval = pclose($this->_deliver_fh);
233:         Horde::logMessage(sprintf("... return value was %d\n", $retval), 'DEBUG');
234:         if ($retval != 0) {
235:             return PEAR::raiseError('Dovecot LDA Backend delivery process signaled an error.');
236:         }
237:         return true;
238:     }
239: 
240:     /**
241:      * Write data to the deliver process.
242:      *
243:      * @return boolean|PEAR_Error True if successful.
244:      */
245:     function _deliver()
246:     {
247:         foreach ($this->_data as $line) {
248:             if (!fwrite($this->_deliver_fh, $line)) {
249:                 return PEAR::raiseError('Dovecot LDA Backend failed writing to the deliver process.');
250:             }
251:         }
252:         return true;
253:     }
254: }
255: 
API documentation generated by ApiGen