author | erik <erik> | 2007-07-09 22:06:00 (UTC) |
---|---|---|
committer | erik <erik> | 2007-07-09 22:06:00 (UTC) |
commit | a91bbaee9eb419dc985d9f5c3689831c8aa75c1e (patch) (side-by-side diff) | |
tree | ba0da224a93f7af1a80a4bef3186edff8dc9483f | |
parent | 1ec355e1cc016edd2e322ff7d57469feaa46474b (diff) | |
download | opie-a91bbaee9eb419dc985d9f5c3689831c8aa75c1e.zip opie-a91bbaee9eb419dc985d9f5c3689831c8aa75c1e.tar.gz opie-a91bbaee9eb419dc985d9f5c3689831c8aa75c1e.tar.bz2 |
Fix for opie bug 1719. This should make opie-irc play nicer with utf-8.
Patches were culled from OE. Thanks to whoever the original patch author
was.
-rw-r--r-- | noncore/net/opieirc/ircconnection.cpp | 5 | ||||
-rw-r--r-- | noncore/net/opieirc/ircmessageparser.cpp | 4 |
2 files changed, 5 insertions, 4 deletions
diff --git a/noncore/net/opieirc/ircconnection.cpp b/noncore/net/opieirc/ircconnection.cpp index 88e63f7..fb7e168 100644 --- a/noncore/net/opieirc/ircconnection.cpp +++ b/noncore/net/opieirc/ircconnection.cpp @@ -1,122 +1,123 @@ #include <unistd.h> #include <string.h> #include <qstringlist.h> #include <qdatetime.h> #include "ircconnection.h" IRCConnection::IRCConnection(IRCServer *server) { m_server = server; m_socket = new QSocket(this); m_connected = FALSE; m_loggedIn = FALSE; connect(m_socket, SIGNAL(connected()), this, SLOT(login())); connect(m_socket, SIGNAL(readyRead()), this, SLOT(dataReady())); connect(m_socket, SIGNAL(error(int)), this, SLOT(error(int))); connect(m_socket, SIGNAL(connectionClosed()), this, SLOT(disconnect())); connect(m_socket, SIGNAL(delayedCloseFinished()), this, SLOT(disconnect())); } /* Connect to the IRC server */ void IRCConnection::doConnect() { ASSERT(!m_connected); m_socket->connectToHost(m_server->hostname(), m_server->port()); } /* Send commands to the IRC server */ void IRCConnection::sendLine(QString line) { while((line.right(1) == "\n") || (line.right(1) == "\r")) line = line.left(line.length() - 1); line.append("\r\n"); - m_socket->writeBlock(line, line.length()); + QCString uline = line.utf8(); + m_socket->writeBlock(uline, uline.length()); } void IRCConnection::sendCTCPReply(const QString &nickname, const QString &type, const QString &args) { sendLine("NOTICE " + nickname + " :\001" + type + " " + args + "\001"); } void IRCConnection::sendCTCPRequest(const QString &nickname, const QString &type, const QString &args) { sendLine("PRIVMSG " + nickname + " :\001" + type + " " + args + "\001"); } void IRCConnection::sendCTCPPing(const QString &nickname) { QDateTime tm; tm.setTime_t(0); QString strtime = QString::number(tm.secsTo(QDateTime::currentDateTime())); sendCTCPRequest(nickname, "PING", strtime); } void IRCConnection::whois(const QString &nickname) { sendLine("WHOIS " + nickname); } /* * login() is called right after the connection * to the IRC server has been established */ void IRCConnection::login() { char hostname[256]; QString loginString; emit outputReady(IRCOutput(OUTPUT_CLIENTMESSAGE, tr("Connected, logging in .."))); m_connected = TRUE; gethostname(hostname, sizeof(hostname)-1); hostname[sizeof (hostname) - 1] = 0; /* Create a logon string and send it */ if (m_server->password().length()>0) { loginString += "PASS " + m_server->password() + "\r\n"; } loginString += "NICK " + m_server->nick() + "\r\n" + "USER " + m_server->username() + " " + hostname + " " + m_server->hostname() + " :" + m_server->realname() + "\r\n"; sendLine(loginString); } /* Called when data arrives on the socket */ void IRCConnection::dataReady() { while(m_socket->canReadLine()) { - IRCMessage message(m_socket->readLine()); + IRCMessage message(QString::fromUtf8(m_socket->readLine())); if (!m_loggedIn && message.isNumerical() && message.commandNumber() == 1) { /* Now autojoin all channels specified inside the server profile */ QStringList channels = QStringList::split(QChar(','), m_server->channels()); for (QStringList::Iterator it = channels.begin(); it != channels.end(); ++it) { QString channelName = (*it).stripWhiteSpace(); if (channelName.startsWith("#") || channelName.startsWith("+")) { sendLine("JOIN "+ channelName); } } m_loggedIn = TRUE; emit outputReady(IRCOutput(OUTPUT_CLIENTMESSAGE, tr("Successfully logged in."))); } emit messageArrived(&message); } } /* Called if any type of socket error occurs */ void IRCConnection::error(int num) { emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Socket error : ") + strerror(num))); } void IRCConnection::disconnect() { m_connected = FALSE; m_loggedIn = FALSE; emit outputReady(IRCOutput(OUTPUT_CONNCLOSE, tr("Connection closed"))); } bool IRCConnection::isConnected() { return m_connected; } bool IRCConnection::isLoggedIn() { return m_loggedIn; } void IRCConnection::close() { m_socket->close(); if (m_socket->state()==QSocket::Idle) { disconnect(); } } diff --git a/noncore/net/opieirc/ircmessageparser.cpp b/noncore/net/opieirc/ircmessageparser.cpp index c449a65..ae47f69 100644 --- a/noncore/net/opieirc/ircmessageparser.cpp +++ b/noncore/net/opieirc/ircmessageparser.cpp @@ -286,398 +286,398 @@ void IRCMessageParser::parseLiteralPrivMsg(IRCMessage *message) { emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Channel message with unknown sender"))); } } else { emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Channel message with unknown channel %1").arg(message->param(0).lower()) )); } } else {emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Received PRIVMSG of unknown type"))); } } void IRCMessageParser::parseLiteralNick(IRCMessage *message) { IRCPerson mask(message->prefix()); m_session->updateNickname(mask.nick(), message->param(0)); /* this way of handling nick changes really sucks if (mask.nick() == m_session->m_server->nick()) { We are changing our nickname m_session->m_server->setNick(message->param(0)); IRCOutput output(OUTPUT_NICKCHANGE, tr("You are now known as %1").arg( message->param(0))); output.addParam(0); emit outputReady(output); } else { Someone else is RCPerson *person = m_session->getPerson(mask.nick()); if (person) { //IRCOutput output(OUTPUT_NICKCHANGE, tr("%1 is now known as %2").arg( mask.nick() ).arg( message->param(0))); new code starts here -- this removes the person from all channels QList<IRCChannel> channels; m_session->getChannelsByPerson(person, channels); QListIterator<IRCChannel> it(channels); for (;it.current(); ++it) { IRCChannelPerson *chanperson = it.current()->getPerson(mask.nick()); it.current()->removePerson(chanperson); chanperson->person->setNick(message->param(0)); it.current()->addPerson(chanperson); IRCOutput output(OUTPUT_NICKCHANGE, tr("%1 is now known as %2").arg( mask.nick() ).arg( message->param(0))); output.addParam(person); emit outputReady(output); } new code ends here } else { emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nickname change of an unknown person"))); } }*/ } void IRCMessageParser::parseLiteralQuit(IRCMessage *message) { IRCPerson mask(message->prefix()); IRCPerson *person = m_session->getPerson(mask.nick()); if (person) { QList<IRCChannel> channels; m_session->getChannelsByPerson(person, channels); QListIterator<IRCChannel> it(channels); for (;it.current(); ++it) { IRCChannelPerson *chanperson = it.current()->getPerson(mask.nick()); it.current()->removePerson(chanperson); delete chanperson; } m_session->removePerson(person); IRCOutput output(OUTPUT_QUIT, tr("%1 has quit (%2)" ).arg( mask.nick() ).arg( message->param(0) )); output.addParam(person); emit outputReady(output); delete person; } else { emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Unknown person quit - desynchronized?"))); } } void IRCMessageParser::parseLiteralTopic(IRCMessage *message) { IRCPerson mask(message->prefix()); IRCChannel *channel = m_session->getChannel(message->param(0).lower()); if (channel) { IRCOutput output(OUTPUT_TOPIC, mask.nick() + tr(" changed topic to ") + "\"" + message->param(1) + "\""); output.addParam(channel); emit outputReady(output); } else { emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Unknown channel topic - desynchronized?"))); } } void IRCMessageParser::parseLiteralError(IRCMessage *message) { emit outputReady(IRCOutput(OUTPUT_ERROR, message->allParameters())); } void IRCMessageParser::parseCTCPPing(IRCMessage *message) { IRCPerson mask(message->prefix()); if(message->isCTCPReply()) { unsigned int sentTime = message->param(0).toUInt(); QDateTime tm; tm.setTime_t(0); unsigned int receivedTime = tm.secsTo(QDateTime::currentDateTime()); emit outputReady(IRCOutput(OUTPUT_CTCP, tr("Received a CTCP PING reply from %1: %2 seconds").arg(mask.nick()).arg(receivedTime-sentTime))); return; } m_session->m_connection->sendCTCPReply(mask.nick(), "PING", message->allParameters()); emit outputReady(IRCOutput(OUTPUT_CTCP, tr("Received a CTCP PING request from %1").arg(mask.nick()))); //IRCPerson mask(message->prefix()); QString dest = message->ctcpDestination(); if (dest.startsWith("#")) { IRCChannel *channel = m_session->getChannel(dest.lower()); if (channel) { IRCChannelPerson *person = channel->getPerson(mask.nick()); if (person) { IRCOutput output(OUTPUT_CHANACTION, tr("Received a CTCP PING from ")+ mask.nick()) ; output.addParam(channel); output.addParam(person); emit outputReady(output); } else { emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP PING with unknown person - Desynchronized?"))); } } else { emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP PING with unknown channel - Desynchronized?"))); } } else { if (message->ctcpDestination() == m_session->m_server->nick()) { IRCPerson *person = m_session->getPerson(mask.nick()); if (!person) { /* Person not yet known, create and add to the current session */ person = new IRCPerson(message->prefix()); m_session->addPerson(person); } IRCOutput output(OUTPUT_QUERYACTION, tr("Received a CTCP PING from ")+ mask.nick() ); output.addParam(person); emit outputReady(output); } else { emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP PING with bad recipient"))); } } } void IRCMessageParser::parseCTCPVersion(IRCMessage *message) { IRCPerson mask(message->prefix()); IRCOutput output(OUTPUT_CTCP); if(message->isCTCPRequest()) { m_session->m_connection->sendCTCPReply(mask.nick(), "VERSION", APP_VERSION " " APP_COPYSTR); output.setMessage(tr("Received a CTCP VERSION request from ") + mask.nick()); } else { output.setMessage("Received CTCP VERSION reply from " + mask.nick() + ":" + message->param(0)); } emit outputReady(output); } void IRCMessageParser::parseCTCPAction(IRCMessage *message) { IRCPerson mask(message->prefix()); QString dest = message->ctcpDestination(); if (dest.startsWith("#")) { IRCChannel *channel = m_session->getChannel(dest.lower()); if (channel) { IRCChannelPerson *person = channel->getPerson(mask.nick()); if (person) { IRCOutput output(OUTPUT_CHANACTION, "*" + mask.nick() + message->param(0)); output.addParam(channel); output.addParam(person); emit outputReady(output); } else { emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP ACTION with unknown person - Desynchronized?"))); } } else { emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP ACTION with unknown channel - Desynchronized?"))); } } else { if (message->ctcpDestination() == m_session->m_server->nick()) { IRCPerson *person = m_session->getPerson(mask.nick()); if (!person) { /* Person not yet known, create and add to the current session */ person = new IRCPerson(message->prefix()); m_session->addPerson(person); } IRCOutput output(OUTPUT_QUERYACTION, "*" + mask.nick() + message->param(0)); output.addParam(person); emit outputReady(output); } else { emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP ACTION with bad recipient"))); } } } void IRCMessageParser::parseCTCPDCC(IRCMessage *message) { QStringList params = QStringList::split(' ', message->param(0).stripWhiteSpace()); if(params[0] == "SEND") { QString nickname = IRCPerson(message->prefix()).nick(); if( params.count() != 5) { emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Malformed DCC request from %1").arg(nickname))); return; } bool accepted = DCCTransferTab::confirm(static_cast<QWidget*>(m_session->parent()), nickname, params[1], params[4].toUInt()); if(!accepted) return; QString filename = Opie::Ui::OFileDialog::getSaveFileName(Opie::Ui::OFileSelector::EXTENDED_ALL, QString::null, params[1], MimeTypes(), 0, tr("Save As")); if(filename.isEmpty()) return; odebug << "Receiving file " << filename << " from " << nickname << oendl; static_cast<IRCServerTab*>(m_session->parent())->mainwindow()->addDCC(DCCTransfer::Recv, params[2].toUInt(), params[3].toUInt(), filename, nickname, params[4].toUInt()); } } void IRCMessageParser::parseLiteralMode(IRCMessage *message) { IRCPerson mask(message->prefix()); if (IRCChannel::isValid(message->param(0))) { IRCChannel *channel = m_session->getChannel(message->param(0).lower()); if (channel) { QString temp, parameters = message->allParameters().right(message->allParameters().length() - channel->channelname().length() - 1); QTextIStream stream(¶meters); bool set = FALSE; while (!stream.atEnd()) { stream >> temp; if (temp.startsWith("+")) { set = TRUE; temp = temp.right(1); } else if (temp.startsWith("-")) { set = FALSE; temp = temp.right(1); } else { emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change has unknown type"))); return; } if (temp == "o") { stream >> temp; IRCChannelPerson *person = channel->getPerson(temp); if (person) { IRCOutput output(OUTPUT_CHANPERSONMODE, person->setOp(mask.nick(), set)); output.addParam(channel); output.addParam(person); emit outputReady(output); } else { emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change with unknown person - Desynchronized?"))); } } else if (temp == "v") { stream >> temp; IRCChannelPerson *person = channel->getPerson(temp); if (person) { IRCOutput output(OUTPUT_CHANPERSONMODE, person->setVoice(mask.nick(), set)); output.addParam(channel); output.addParam(person); emit outputReady(output); } else { emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change with unknown person - Desynchronized?"))); } } else { emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change with unknown flag"))); } } } else { emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change with unknown kannel - Desynchronized?"))); } } else { emit outputReady(IRCOutput(OUTPUT_ERROR, tr("User modes not supported yet"))); } } void IRCMessageParser::parseLiteralKick(IRCMessage *message) { IRCPerson mask(message->prefix()); IRCChannel *channel = m_session->getChannel(message->param(0).lower()); if (channel) { IRCChannelPerson *person = channel->getPerson(message->param(1)); if (person) { if (person->nick() == m_session->m_server->nick()) { m_session->removeChannel(channel); IRCOutput output(OUTPUT_SELFKICK, tr("You were kicked from ") + channel->channelname() + tr(" by ") + mask.nick() + " (" + message->param(2) + ")"); output.addParam(channel); emit outputReady(output); } else { /* someone else got kicked */ channel->removePerson(person); IRCOutput output(OUTPUT_OTHERKICK, person->nick() + tr(" was kicked from ") + channel->channelname() + tr(" by ") + mask.nick()+ " (" + message->param(2) + ")"); output.addParam(channel); output.addParam(person); emit outputReady(output); } } else { emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Unknown person kick - desynchronized?"))); } } else { emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Unknown channel kick - desynchronized?"))); } } void IRCMessageParser::parseNumericalNames(IRCMessage *message) { /* Name list sent when joining a channel */ IRCChannel *channel = m_session->getChannel(message->param(2).lower()); if (channel != 0) { QString people = message->param(3); QTextIStream stream(&people); QString temp; while (!stream.atEnd()) { stream >> temp; char flagch = temp.at(0).latin1(); int flag = 0; QString nick; /* Parse person flags */ if (flagch == '~' || flagch == '&' || flagch == '@' || flagch == '+' || flagch=='%' || flagch == '*') { nick = temp.right(temp.length()-1); switch (flagch) { /** * @note '~' and `&' are extensions of the unrealircd irc * daemon. This app can't see users w/out checking for these * chars. */ case '~': case '&': case '@': flag = IRCChannelPerson::PERSON_FLAG_OP; break; case '+': flag = IRCChannelPerson::PERSON_FLAG_VOICE; break; case '%': flag = IRCChannelPerson::PERSON_FLAG_HALFOP; break; default : flag = 0; break; } } else nick = temp; IRCPerson *person = m_session->getPerson(nick); if (person == 0) { person = new IRCPerson(); person->setNick(nick); m_session->addPerson(person); } IRCChannelPerson *chan_person = new IRCChannelPerson(person); chan_person->setFlags(flag); channel->addPerson(chan_person); } } else emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Server message with unknown channel"))); } void IRCMessageParser::parseNumericalEndOfNames(IRCMessage *message) { /* Done syncing to channel */ IRCChannel *channel = m_session->getChannel(message->param(1).lower()); if (channel) { channel->setHasPeople(TRUE); /* Yes, we want the names before anything happens inside the GUI */ IRCOutput output(OUTPUT_SELFJOIN, tr("You joined channel ") + channel->channelname()); output.addParam(channel); emit outputReady(output); } else { emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Server message with unknown channel"))); } } void IRCMessageParser::parseNumericalNicknameInUse(IRCMessage *) { /* If we are connnected this error is not critical */ if(m_session->isLoggedIn()) return; emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nickname is in use, please reconnect with a different nickname"))); m_session->endSession(); } void IRCMessageParser::parseNumericalNoSuchNick(IRCMessage *) { emit outputReady(IRCOutput(OUTPUT_ERROR, tr("No such nickname"))); } void IRCMessageParser::parseNumericalTopic(IRCMessage *message) { IRCChannel *channel = m_session->getChannel(message->param(1).lower()); if (channel) { - IRCOutput output(OUTPUT_TOPIC, tr("Topic for channel " + channel->channelname() + " is \"" + message->param(2) + "\"")); + IRCOutput output(OUTPUT_TOPIC, tr("Topic for channel ") + channel->channelname() + tr(" is \"") + message->param(2) + "\""); output.addParam(channel); emit outputReady(output); } else { - IRCOutput output(OUTPUT_TOPIC, tr("Topic for channel " + message->param(1) + " is \"" + message->param(2) + "\"")); + IRCOutput output(OUTPUT_TOPIC, tr("Topic for channel ") + message->param(1) + tr(" is \"") + message->param(2) + "\""); output.addParam(0); emit outputReady(output); } } void IRCMessageParser::parseNumericalTopicWhoTime(IRCMessage *) { } |