X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=scripts%2Fxmppdaemon.php;h=b2efc07c38c644092b4a1549761efb01af99c330;hb=769e5b7622445cf49cbaf5a416fb6b250b072866;hp=ead842928fd1b3039654a25126bc38e70f854407;hpb=eb2f9c98ac115ce67e9a740b200c832153ffa05c;p=quix0rs-gnu-social.git diff --git a/scripts/xmppdaemon.php b/scripts/xmppdaemon.php index ead842928f..b2efc07c38 100755 --- a/scripts/xmppdaemon.php +++ b/scripts/xmppdaemon.php @@ -1,8 +1,8 @@ #!/usr/bin/env php . */ -# Abort if called from a web server -if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) { - print "This script must be run from the command line\n"; - exit(); -} - define('INSTALLDIR', realpath(dirname(__FILE__) . '/..')); -define('LACONICA', true); -require_once(INSTALLDIR . '/lib/common.php'); -require_once(INSTALLDIR . '/lib/jabber.php'); -require_once(INSTALLDIR . '/lib/daemon.php'); +$shortoptions = 'fi::'; +$longoptions = array('id::', 'foreground'); + +$helptext = <<resource = $resource; + $this->resource = $resource . 'daemon'; } else { $this->resource = common_config('xmpp', 'resource') . 'daemon'; } - $this->log(LOG_INFO, "INITIALIZE XMPPDaemon {$this->user}@{$this->server}/{$this->resource}"); - } + $this->jid = $this->user.'@'.$this->server.'/'.$this->resource; - function connect() { + $this->log(LOG_INFO, "INITIALIZE XMPPDaemon {$this->jid}"); + } + function connect() + { $connect_to = ($this->host) ? $this->host : $this->server; $this->log(LOG_INFO, "Connecting to $connect_to on port $this->port"); @@ -68,60 +77,108 @@ class XMPPDaemon extends Daemon { return false; } + $this->log(LOG_INFO, "Connected"); + $this->conn->setReconnectTimeout(600); + $this->log(LOG_INFO, "Sending initial presence."); + jabber_send_presence("Send me a message to post a notice", 'available', null, 'available', 100); + + $this->log(LOG_INFO, "Done connecting."); + return !$this->conn->isDisconnected(); } - function name() { + function name() + { return strtolower('xmppdaemon.'.$this->resource); } - function run() { + function run() + { if ($this->connect()) { + $this->log(LOG_DEBUG, "Initializing stanza handlers."); + $this->conn->addEventHandler('message', 'handle_message', $this); $this->conn->addEventHandler('presence', 'handle_presence', $this); $this->conn->addEventHandler('reconnect', 'handle_reconnect', $this); - $this->conn->process(); + $this->log(LOG_DEBUG, "Beginning processing loop."); + + while ($this->conn->processTime(60)) { + $this->sendPing(); + } + } + } + + function sendPing() + { + if (!isset($this->pingid)) { + $this->pingid = 0; + } else { + $this->pingid++; } + + $this->log(LOG_DEBUG, "Sending ping #{$this->pingid}"); + + $this->conn->send(""); } - function handle_reconnect(&$pl) { + function handle_reconnect(&$pl) + { + $this->log(LOG_DEBUG, "Got reconnection callback."); $this->conn->processUntil('session_start'); + $this->log(LOG_DEBUG, "Sending reconnection presence."); $this->conn->presence('Send me a message to post a notice', 'available', null, 'available', 100); + unset($pl['xml']); + $pl['xml'] = null; + + $pl = null; + unset($pl); } - function get_user($from) { + function get_user($from) + { $user = User::staticGet('jabber', jabber_normalize_jid($from)); return $user; } - function handle_message(&$pl) { + function handle_message(&$pl) + { + $from = jabber_normalize_jid($pl['from']); + if ($pl['type'] != 'chat') { + $this->log(LOG_WARNING, "Ignoring message of type ".$pl['type']." from $from."); return; } + if (mb_strlen($pl['body']) == 0) { + $this->log(LOG_WARNING, "Ignoring message with empty body from $from."); return; } - $from = jabber_normalize_jid($pl['from']); - # Forwarded from another daemon (probably a broadcaster) for # us to handle if ($this->is_self($from)) { + $this->log(LOG_INFO, "Got forwarded notice from self ($from)."); $from = $this->get_ofrom($pl); + $this->log(LOG_INFO, "Originally sent by $from."); if (is_null($from) || $this->is_self($from)) { + $this->log(LOG_INFO, "Ignoring notice originally sent by $from."); return; } } $user = $this->get_user($from); + // For common_current_user to work + global $_cur; + $_cur = $user; + if (!$user) { $this->from_site($from, 'Unknown user; go to ' . common_local_url('imsettings') . @@ -130,6 +187,7 @@ class XMPPDaemon extends Daemon { return; } if ($this->handle_command($user, $pl['body'])) { + $this->log(LOG_INFO, "Command messag by $from handled."); return; } else if ($this->is_autoreply($pl['body'])) { $this->log(LOG_INFO, 'Ignoring auto reply from ' . $from); @@ -138,29 +196,41 @@ class XMPPDaemon extends Daemon { $this->log(LOG_INFO, 'Ignoring OTR from ' . $from); return; } else if ($this->is_direct($pl['body'])) { + $this->log(LOG_INFO, 'Got a direct message ' . $from); + preg_match_all('/d[\ ]*([a-z0-9]{1,64})/', $pl['body'], $to); $to = preg_replace('/^d([\ ])*/', '', $to[0][0]); $body = preg_replace('/d[\ ]*('. $to .')[\ ]*/', '', $pl['body']); + + $this->log(LOG_INFO, 'Direct message from '. $user->nickname . ' to ' . $to); + $this->add_direct($user, $body, $to, $from); } else { - $len = mb_strlen($pl['body']); - if($len > 140) { - $this->from_site($from, 'Message too long - maximum is 140 characters, you sent ' . $len); - return; - } + + $this->log(LOG_INFO, 'Posting a notice from ' . $user->nickname); + $this->add_notice($user, $pl); } $user->free(); unset($user); + unset($_cur); + + unset($pl['xml']); + $pl['xml'] = null; + + $pl = null; + unset($pl); } - function is_self($from) { + function is_self($from) + { return preg_match('/^'.strtolower(jabber_daemon_address()).'/', strtolower($from)); } - function get_ofrom($pl) { + function get_ofrom($pl) + { $xml = $pl['xml']; $addresses = $xml->sub('addresses'); if (!$addresses) { @@ -194,15 +264,19 @@ class XMPPDaemon extends Daemon { return $jid; } - function is_autoreply($txt) { + function is_autoreply($txt) + { if (preg_match('/[\[\(]?[Aa]uto[-\s]?[Rr]e(ply|sponse)[\]\)]/', $txt)) { return true; + } else if (preg_match('/^System: Message wasn\'t delivered. Offline storage size was exceeded.$/', $txt)) { + return true; } else { return false; } } - function is_otr($txt) { + function is_otr($txt) + { if (preg_match('/^\?OTR/', $txt)) { return true; } else { @@ -210,7 +284,8 @@ class XMPPDaemon extends Daemon { } } - function is_direct($txt) { + function is_direct($txt) + { if (strtolower(substr($txt, 0, 2))=='d ') { return true; } else { @@ -218,12 +293,14 @@ class XMPPDaemon extends Daemon { } } - function from_site($address, $msg) { + function from_site($address, $msg) + { $text = '['.common_config('site', 'name') . '] ' . $msg; jabber_send_message($address, $text); } - function handle_command($user, $body) { + function handle_command($user, $body) + { $inter = new CommandInterpreter(); $cmd = $inter->handle_command($user, $body); if ($cmd) { @@ -235,21 +312,26 @@ class XMPPDaemon extends Daemon { } } - function add_notice(&$user, &$pl) { + function add_notice(&$user, &$pl) + { $body = trim($pl['body']); - $content_shortened = common_shorten_link($body); - if (mb_strlen($content_shortened) > 140) { - $content = trim(mb_substr($body, 0, 140)); - $content_shortened = common_shorten_link($content); - } - else { - $content = $body; + $content_shortened = common_shorten_links($body); + if (Notice::contentTooLong($content_shortened)) { + $from = jabber_normalize_jid($pl['from']); + $this->from_site($from, sprintf(_("Message too long - maximum is %d characters, you sent %d"), + Notice::maxContent(), + mb_strlen($content_shortened))); + return; } - $notice = Notice::saveNew($user->id, $content, 'xmpp'); - if (is_string($notice)) { - $this->log(LOG_ERR, $notice); + + try { + $notice = Notice::saveNew($user->id, $content_shortened, 'xmpp'); + } catch (Exception $e) { + $this->log(LOG_ERR, $e->getMessage()); + $this->from_site($user->jabber, $e->getMessage()); return; } + common_broadcast_notice($notice); $this->log(LOG_INFO, 'Added notice ' . $notice->id . ' from user ' . $user->nickname); @@ -257,7 +339,8 @@ class XMPPDaemon extends Daemon { unset($notice); } - function handle_presence(&$pl) { + function handle_presence(&$pl) + { $from = jabber_normalize_jid($pl['from']); switch ($pl['type']) { case 'subscribe': @@ -289,24 +372,48 @@ class XMPPDaemon extends Daemon { } break; } + unset($pl['xml']); + $pl['xml'] = null; + + $pl = null; + unset($pl); } - function log($level, $msg) { - common_log($level, 'XMPPDaemon('.$this->resource.'): '.$msg); + function log($level, $msg) + { + $text = 'XMPPDaemon('.$this->resource.'): '.$msg; + common_log($level, $text); + if (!$this->daemonize) + { + $line = common_log_line($level, $text); + echo $line; + echo "\n"; + } } - function subscribed($to) { + function subscribed($to) + { jabber_special_presence('subscribed', $to); } } -ini_set("max_execution_time", "0"); -ini_set("max_input_time", "0"); -set_time_limit(0); -mb_internal_encoding('UTF-8'); +// Abort immediately if xmpp is not enabled, otherwise the daemon chews up +// lots of CPU trying to connect to unconfigured servers +if (common_config('xmpp','enabled')==false) { + print "Aborting daemon - xmpp is disabled\n"; + exit(); +} + +if (have_option('i', 'id')) { + $id = get_option_value('i', 'id'); +} else if (count($args) > 0) { + $id = $args[0]; +} else { + $id = null; +} -$resource = ($argc > 1) ? $argv[1] : (common_config('xmpp','resource') . '-listen'); +$foreground = have_option('f', 'foreground'); -$daemon = new XMPPDaemon($resource); +$daemon = new XMPPDaemon($id, !$foreground); $daemon->runOnce();