function fromArray($arr) { $this->name = $arr['name']; $this->attribs = $arr['attribs']; $this->text = $arr['text']; $this->html = $arr['html']; $this->subtags = array(); foreach ($arr['tags'] as $subtag) { $newobj = new CXMLTag(); $newobj->fromArray($subtag); $this->subtags[] = $newobj; } }
function xmpp_presence($stanza, $sock, $ircsock) { global $xmppparams, $ircdata; $obj = new CXMLTag(); $obj->fromArray($stanza); $toparts = xmpp_parse_jid($obj->attribs['to']); $fromparts = xmpp_parse_jid($obj->attribs['from']); // Join only valid IRC channel if (!irc_valid_channel(from_utf($toparts['user']))) { debugmsg("Invalid channel name\n"); return false; } // Ignore invalid jid if (!$toparts['user'] || !$toparts['resource'] || !$fromparts['user'] || !$fromparts['resource']) { $answer = $obj->createError("modify", "jid-malformed", true); debugmsg("No nickname or room name\n"); xmpp_write($sock, $answer->toString()); return false; } $channel = from_utf($toparts['user']); // Normalize case if channel exists if ($norm_ch = $ircdata->channel_exists($channel)) { $channel = $norm_ch; } else { $ircdata->add_channel($channel); } $nick = $ircdata->jid_exists(from_utf($obj->attribs['from'])); $newnick = from_utf($toparts['resource']); $forcenick = ''; // dump_ircdata("ircdata.dump", FILE_APPEND, "Do"); if (!$nick) { debugmsg("New user, trying to join IRC\n"); if (isset($obj->attribs['type'])) { return false; } // First enter of JID $nick = from_utf($toparts['resource']); if (!irc_valid_nick($nick)) { $answer = $obj->createError("cancel", "not-acceptable", true); debugmsg("Invalid nick\n"); xmpp_write($sock, $answer->toString()); return false; } if ($ircdata->nick_exists($nick)) { $answer = $obj->createError("cancel", "conflict", true); debugmsg("Nick already exists\n"); xmpp_write($sock, $answer->toString()); return false; } $ircdata->add_nick($nick, '', '', '', from_utf($obj->attribs['from'])); // Send new nick to IRC server irc_nick($ircsock, $nick); } else { if (isset($obj->attribs['type'])) { if ($obj->attribs['type'] == 'unavailable') { debugmsg("Part room\n"); if ($ircdata->is_on($nick, $channel)) { if ($statustag = $obj->firstSubtag('status')) { $status = from_utf($statustag->text); } else { $status = ''; } xmpp_write($sock, xmpp_part(to_utf($nick), $toparts['user'])); irc_part($ircsock, $nick, $channel); $ircdata->part_channel($nick, $channel, $status); if (!$ircdata->get_on_channels($nick)) { irc_quit($ircsock, $nick, $status); $ircdata->remove_nick($nick); } } else { return false; } return true; } } // JID already exists // Fix for status changes if ($nick == $newnick) { //return false; debugmsg("JID already exists\n"); } if (strcasecmp(from_utf($toparts['resource']), $nick) != 0) { $forcenick = $nick; } } // Is channel pressent if ($nick != $newnick && $ircdata->is_on($nick, $channel)) { // debugmsg(" --- Test: user on channel", 1); if (!irc_valid_nick($newnick)) { $answer = $obj->createError('cancel', 'not-acceptable', true); debugmsg("Invalid nick\n"); xmpp_write($sock, $answer->toString()); return false; } // Change nick $can_change = $ircdata->can_change_nick($nick, $newnick); if ($can_change === true) { debugmsg("Changing nick\n"); irc_change_nick($ircsock, $nick, $newnick); xmpp_write($sock, xmpp_change_nick(to_utf($nick), to_utf($newnick))); $ircdata->change_nick($nick, $newnick); // dump_ircdata("ircdata2.dump", FILE_APPEND, "Posle"); return true; } else { $errtag = $obj->createError('cancel', $can_change['error'], true); debugmsg("Nick can't change\n"); xmpp_write($sock, $errtag->toString()); return false; } return false; } else { // debugmsg(" --- Test: can user join?", 1); if ($forcenick) { $nick = $forcenick; } $password = ''; if ($xtag = $obj->validSubtag('x', 'xmlns', FEAT_MUC)) { if ($passtag = $xtag->firstSubtag('password')) { $password = $passtag->text; } } $join = $ircdata->can_join($nick, $channel, from_utf($password)); // var_dump($join); if ($join === true) { $ircdata->join_channel($nick, $channel); // Give op to first user in channel if (count($ircdata->channels[$channel]['nicks']) == 1) { $ircdata->set_chumode($channel, $nick, 'o', true); irc_join($ircsock, $nick, $channel, '@'); } else { irc_join($ircsock, $nick, $channel); } // Send channel members to new user xmpp_write($sock, xmpp_presence_to_new(to_utf($nick), $toparts['user'])); // Send new user to channel members xmpp_write($sock, xmpp_presence_to_all(to_utf($nick), $toparts['user'], $forcenick ? to_utf($nick) : '')); // Send subject to new user xmpp_write($sock, xmpp_message_to_one(to_utf($ircdata->channels[$channel]['topic_by']), to_utf($nick), 'subject', to_utf(text_from_irc($ircdata->channels[$channel]['topic'])), $toparts['user'])); return true; } else { // Send error messages $errtag = false; switch ($join['error']) { case 'invite': $errtag = $obj->createError('auth', 'registration-required', true); break; case 'password': $errtag = $obj->createError('auth', 'not-authorized', true); break; case 'limit': $errtag = $obj->createError('wait', 'service-unavailable', true); break; case 'ban': $errtag = $obj->createError('auth', 'forbidden', true); break; } if ($errtag) { xmpp_write($sock, $errtag->toString()); } } } return false; }