]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - plugins/Irc/extlib/phergie/Phergie/Driver/Streams.php
Revert "Merged in Phergie changes"
[quix0rs-gnu-social.git] / plugins / Irc / extlib / phergie / Phergie / Driver / Streams.php
index 8fe53aaa2f97b76c89b2204c989dcdba5683907e..3f2ce052b1fc780f60d2427881c73f001137d8d8 100755 (executable)
@@ -1,6 +1,6 @@
 <?php
 /**
- * Phergie 
+ * Phergie
  *
  * PHP version 5
  *
@@ -11,7 +11,7 @@
  * It is also available through the world-wide-web at this URL:
  * http://phergie.org/license
  *
- * @category  Phergie 
+ * @category  Phergie
  * @package   Phergie
  * @author    Phergie Development Team <team@phergie.org>
  * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
  */
 
 /**
- * Driver that uses the sockets wrapper of the streams extension for 
- * communicating with the server and handles formatting and parsing of 
+ * Driver that uses the sockets wrapper of the streams extension for
+ * communicating with the server and handles formatting and parsing of
  * events using PHP.
  *
- * @category Phergie 
+ * @category Phergie
  * @package  Phergie
  * @author   Phergie Development Team <team@phergie.org>
  * @license  http://phergie.org/license New BSD License
@@ -47,26 +47,29 @@ class Phergie_Driver_Streams extends Phergie_Driver_Abstract
     protected $socket;
 
     /**
-     * Amount of time in seconds to wait to receive an event each time the 
+     * Amount of time in seconds to wait to receive an event each time the
      * socket is polled
      *
-     * @var float 
+     * @var float
      */
     protected $timeout = 0.1;
 
     /**
-     * Handles construction of command strings and their transmission to the 
+     * Handles construction of command strings and their transmission to the
      * server.
      *
      * @param string       $command Command to send
-     * @param string|array $args    Optional string or array of sequential 
+     * @param string|array $args    Optional string or array of sequential
      *        arguments
      *
-     * @return string Command string that was sent 
+     * @return string Command string that was sent
      * @throws Phergie_Driver_Exception
      */
     protected function send($command, $args = '')
     {
+        $connection = $this->getConnection();
+        $encoding = $connection->getEncoding();
+
         // Require an open socket connection to continue
         if (empty($this->socket)) {
             throw new Phergie_Driver_Exception(
@@ -86,20 +89,40 @@ class Phergie_Driver_Streams extends Phergie_Driver_Abstract
                 $end = count($args) - 1;
                 $args[$end] = ':' . $args[$end];
                 $args = implode(' ', $args);
+            } else {
+                $args = ':' . $args;
             }
 
             $buffer .= ' ' . $args;
         }
 
         // Transmit the command over the socket connection
-        fwrite($this->socket, $buffer . "\r\n");
+        $attempts = $written = 0;
+        $temp = $buffer . "\r\n";
+        $is_multibyte = !substr($encoding, 0, 8) === 'ISO-8859' && $encoding !== 'ASCII' && $encoding !== 'CP1252';
+        $length = ($is_multibyte) ? mb_strlen($buffer, '8bit') : strlen($buffer);
+        while (true) {
+            $written += (int) fwrite($this->socket, $temp);
+            if ($written < $length) {
+                $temp = substr($temp, $written);
+                $attempts++;
+                if ($attempts == 3) {
+                    throw new Phergie_Driver_Exception(
+                        'Unable to write to socket',
+                        Phergie_Driver_Exception::ERR_CONNECTION_WRITE_FAILED
+                    );
+                }
+            } else {
+                break;
+            }
+        }
 
         // Return the command string that was transmitted
         return $buffer;
     }
 
     /**
-     * Overrides the parent class to set the currently active socket handler 
+     * Overrides the parent class to set the currently active socket handler
      * when the active connection is changed.
      *
      * @param Phergie_Connection $connection Active connection
@@ -120,11 +143,11 @@ class Phergie_Driver_Streams extends Phergie_Driver_Abstract
 
     /**
      * Returns a list of hostmasks corresponding to sockets with data to read.
-     * 
+     *
      * @param int $sec  Length of time to wait for new data (seconds)
      * @param int $usec Length of time to wait for new data (microseconds)
      *
-     * @return array List of hostmasks or an empty array if none were found 
+     * @return array List of hostmasks or an empty array if none were found
      *         to have data to read
      */
     public function getActiveReadSockets($sec = 0, $usec = 200000)
@@ -147,7 +170,7 @@ class Phergie_Driver_Streams extends Phergie_Driver_Abstract
     }
 
     /**
-     * Sets the amount of time to wait for a new event each time the socket 
+     * Sets the amount of time to wait for a new event each time the socket
      * is polled.
      *
      * @param float $timeout Amount of time in seconds
@@ -164,7 +187,7 @@ class Phergie_Driver_Streams extends Phergie_Driver_Abstract
     }
 
     /**
-     * Returns the amount of time to wait for a new event each time the 
+     * Returns the amount of time to wait for a new event each time the
      * socket is polled.
      *
      * @return float Amount of time in seconds
@@ -175,7 +198,7 @@ class Phergie_Driver_Streams extends Phergie_Driver_Abstract
     }
 
     /**
-     * Supporting method to parse event argument strings where the last 
+     * Supporting method to parse event argument strings where the last
      * argument may contain a colon.
      *
      * @param string $args  Argument string to parse
@@ -191,11 +214,19 @@ class Phergie_Driver_Streams extends Phergie_Driver_Abstract
     /**
      * Listens for an event on the current connection.
      *
-     * @return Phergie_Event_Interface|null Event instance if an event was 
+     * @return Phergie_Event_Interface|null Event instance if an event was
      *         received, NULL otherwise
      */
     public function getEvent()
     {
+        // Check the socket is still active
+        if (feof($this->socket)) {
+            throw new Phergie_Driver_Exception(
+                'EOF detected on socket',
+                Phergie_Driver_Exception::ERR_CONNECTION_READ_FAILED
+            );
+        }
+
         // Check for a new event on the current connection
         $buffer = fgets($this->socket, 512);
 
@@ -217,10 +248,12 @@ class Phergie_Driver_Streams extends Phergie_Driver_Abstract
             // If the event could be from the server or a user...
 
             // Parse the server hostname or user hostmask, command, and arguments
-            list($prefix, $cmd, $args) 
+            list($prefix, $cmd, $args)
                 = array_pad(explode(' ', ltrim($buffer, ':'), 3), 3, null);
             if (strpos($prefix, '@') !== false) {
                 $hostmask = Phergie_Hostmask::fromString($prefix);
+            } else {
+                $hostmask = new Phergie_Hostmask(null, null, $prefix);
             }
         }
 
@@ -238,8 +271,9 @@ class Phergie_Driver_Streams extends Phergie_Driver_Abstract
 
         case 'privmsg':
         case 'notice':
-            $ctcp = substr(strstr($args, ':'), 1);
-            if (substr($ctcp, 0, 1) === "\x01" && substr($ctcp, -1) === "\x01") {
+            $args = $this->parseArguments($args, 2);
+            list($source, $ctcp) = $args;
+            if (substr($ctcp, 0, 1) === "\001" && substr($ctcp, -1) === "\001") {
                 $ctcp = substr($ctcp, 1, -1);
                 $reply = ($cmd == 'notice');
                 list($cmd, $args) = array_pad(explode(' ', $ctcp, 2), 2, null);
@@ -260,7 +294,7 @@ class Phergie_Driver_Streams extends Phergie_Driver_Abstract
                     }
                     break;
                 case 'action':
-                    $args = array($this->getConnection()->getNick(), $args);
+                    $args = array($source, $args);
                     break;
 
                 default:
@@ -268,28 +302,26 @@ class Phergie_Driver_Streams extends Phergie_Driver_Abstract
                     if ($reply) {
                         $cmd .= 'Response';
                     }
-                    $args = array($this->getConnection()->getNick(), $ctcp);
+                    $args = array($source, $args);
                     break;
                 }
-            } else {
-                $args = $this->parseArguments($args, 2);
             }
             break;
 
         case 'oper':
         case 'topic':
         case 'mode':
-            $args = $this->parseArguments($args); 
+            $args = $this->parseArguments($args);
             break;
 
         case 'part':
         case 'kill':
         case 'invite':
-            $args = $this->parseArguments($args, 2); 
+            $args = $this->parseArguments($args, 2);
             break;
 
         case 'kick':
-            $args = $this->parseArguments($args, 3); 
+            $args = $this->parseArguments($args, 3);
             break;
 
         // Remove the target from responses
@@ -360,14 +392,14 @@ class Phergie_Driver_Streams extends Phergie_Driver_Abstract
         $this->send(
             'USER',
             array(
-                $username, 
-                $hostname, 
-                $hostname, 
+                $username,
+                $hostname,
+                $hostname,
                 $realname
             )
         );
 
-        $this->send('NICK', $nick); 
+        $this->send('NICK', $nick);
 
         // Add the socket handler to the internal array for socket handlers
         $this->sockets[(string) $connection->getHostmask()] = $this->socket;
@@ -395,7 +427,7 @@ class Phergie_Driver_Streams extends Phergie_Driver_Abstract
     /**
      * Joins a channel.
      *
-     * @param string $channels Comma-delimited list of channels to join 
+     * @param string $channels Comma-delimited list of channels to join
      * @param string $keys     Optional comma-delimited list of channel keys
      *
      * @return void
@@ -414,7 +446,7 @@ class Phergie_Driver_Streams extends Phergie_Driver_Abstract
     /**
      * Leaves a channel.
      *
-     * @param string $channels Comma-delimited list of channels to leave 
+     * @param string $channels Comma-delimited list of channels to leave
      *
      * @return void
      */
@@ -600,9 +632,9 @@ class Phergie_Driver_Streams extends Phergie_Driver_Abstract
     /**
      * Sends a CTCP response to a user.
      *
-     * @param string       $nick    User nick 
+     * @param string       $nick    User nick
      * @param string       $command Command to send
-     * @param string|array $args    String or array of sequential arguments 
+     * @param string|array $args    String or array of sequential arguments
      *        (optional)
      *
      * @return void
@@ -615,7 +647,7 @@ class Phergie_Driver_Streams extends Phergie_Driver_Abstract
 
         $buffer = rtrim(strtoupper($command) . ' ' . $args);
 
-        $this->doNotice($nick, chr(1) . $buffer . chr(1)); 
+        $this->doNotice($nick, chr(1) . $buffer . chr(1));
     }
 
     /**
@@ -652,7 +684,7 @@ class Phergie_Driver_Streams extends Phergie_Driver_Abstract
      * Sends a CTCP TIME request to a user.
      *
      * @param string $nick User nick
-     * @param string $time Time string to send for a response 
+     * @param string $time Time string to send for a response
      *
      * @return void
      */