1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
13: class Horde_Imsp_Client_Socket extends Horde_Imsp_Client_Base
14: {
15: 16: 17: 18: 19:
20: protected $_stream;
21:
22: 23: 24: 25:
26: protected $_authObj;
27:
28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42:
43: public function __construct(array $params)
44: {
45: parent::__construct($params);
46: $this->_imspOpen();
47: $this->_logger->debug('Initializing Horde_Imsp object.');
48: }
49:
50: 51: 52: 53: 54: 55: 56:
57: public function authenticate($login = true)
58: {
59: if (!$this->_authObj->authenticate($this, $login)) {
60: return false;
61: }
62:
63: return true;
64: }
65:
66: 67: 68:
69: public function logout()
70: {
71: $this->_logger->debug('Closing IMSP Connection.');
72: $command_string = 'LOGOUT';
73: $this->send($command_string);
74: fclose($this->_stream);
75: }
76:
77: 78: 79: 80: 81: 82:
83: public function capability()
84: {
85: $command_string = 'CAPABILITY';
86: $this->send($command_string);
87: $server_response = $this->receive();
88: if (preg_match("/^\* CAPABILITY/", $server_response)) {
89: $capability = preg_replace("/^\* CAPABILITY/", '', $server_response);
90: $server_response = $this->receive();
91: if (!$server_response == 'OK') {
92: $this->_logger->err('Did not receive the expected response from the server.');
93: throw new Horde_Imsp_Exception('Did not receive the expected response from the server.');
94: } else {
95: $this->_logger->debug('CAPABILITY completed OK');
96: return $capability;
97: }
98: }
99: }
100:
101: 102: 103: 104: 105: 106: 107: 108: 109: 110:
111: public function send($commandText, $includeTag = true, $sendCRLF = true, $continuation = false)
112: {
113: $command_text = '';
114:
115: if (!$this->_stream) {
116: throw new Horde_Imsp_Exception('No IMSP connection in place');
117: }
118:
119: if ($includeTag) {
120: $this->_tag = $this->_getNextCommandTag();
121: $command_text = "$this->_tag ";
122: }
123: $command_text .= $commandText;
124:
125: if ($sendCRLF) {
126: $command_text .= "\r\n";
127: }
128:
129: $this->_logger->debug('C: ' . $command_text);
130: if (!fputs($this->_stream, $command_text)) {
131: $this->_logger->err('Connection to IMSP host failed.');
132: fclose($this->_stream);
133: throw new Horde_Imsp_Exception('Connection to IMSP host failed');
134: }
135:
136: if ($continuation && !preg_match("/^\+/", $this->receive())) {
137: $this->_logger->err('Did not receive expected command continuation response from IMSP server.');
138: throw new Horde_Imsp_Exception('Did not receive expected command continuation response from IMSP server.');
139: }
140: }
141:
142: 143: 144: 145: 146: 147:
148: public function receive()
149: {
150: if (!$this->_stream) {
151: throw new Horde_Imsp_Exception('No IMSP connection in place.');
152: }
153: $result = fgets($this->_stream, 512);
154: if (!$result) {
155: $this->_logger->err('Did not receive the expected response from the server.');
156: throw new Horde_Imsp_Exception('Did not receive the expected response from the server.');
157: }
158: $meta = stream_get_meta_data($this->_stream);
159: if ($meta['timed_out']) {
160: $this->_logger->err('Connection timed out.');
161: throw new Horde_Imsp_Exception(Horde_Imsp_Translation::t('Connection timed out!'));
162: }
163:
164: $server_response = trim($result);
165: $this->_logger->debug('S: ' . $server_response);
166:
167: 168: 169: 170:
171: while (preg_match("/^" . $this->_lastCommandTag . "/", $server_response)) {
172: $server_response = trim(fgets($this->_stream, 512));
173: throw new Horde_Imsp_Exception('Did not receive the expected response from the server: ' . $server_response);
174: }
175:
176: $currentTag = $this->_tag;
177: if (preg_match("/^" . $currentTag . " NO/", $server_response)) {
178: $this->lastRawError = $server_response;
179: return 'NO';
180: }
181:
182: if (preg_match("/^" . $currentTag . " BAD/", $server_response)) {
183: $this->_logger->err('The IMSP server did not understand your request.');
184: $this->lastRawError = $server_response;
185: return 'BAD';
186: }
187:
188: if (preg_match("/^" . $currentTag . " OK/", $server_response)) {
189: return 'OK';
190: }
191:
192: 193: 194:
195: return $server_response;
196: }
197:
198: 199: 200: 201: 202: 203:
204: public function getServerResponseChunks()
205: {
206: $server_response = trim(fgets($this->_stream, 512));
207: $chunks = explode(' ', $server_response);
208:
209: return $chunks;
210: }
211:
212: 213: 214: 215: 216: 217: 218: 219:
220: public function receiveStringLiteral($length)
221: {
222: $literal = '';
223: do {
224: $temp = fread($this->_stream, $length);
225: $length -= strlen($temp);
226: $literal .= $temp;
227: } while ($length > 0 && strlen($temp));
228: $this->_logger->debug('From{}: ' . $literal);
229:
230: return $literal;
231: }
232:
233: 234: 235: 236: 237:
238: protected function _imspOpen()
239: {
240: $fp = @fsockopen($this->host, $this->port);
241: if (!$fp) {
242: $this->_logger->err('Connection to IMSP host failed.');
243: throw new Horde_Imsp_Exception('Connection to IMSP host failed.');
244: }
245: $this->_stream = $fp;
246: $server_response = $this->receive();
247: if (!preg_match("/^\* OK/", $server_response)) {
248: fclose($fp);
249: $this->_logger->err('Did not receive the expected response from the server.');
250: }
251: }
252:
253: }