diff -ruN licq.bak/include/licq_icqd.h licq.new/include/licq_icqd.h
--- licq.bak/include/licq_icqd.h        Mon Jan 20 21:00:24 2003
+++ licq.new/include/licq_icqd.h        Thu Feb 20 16:56:28 2003
@@ -462,6 +468,7 @@
   friend void *ProcessRunningEvent_Client_tep(void *p);
   friend void *ProcessRunningEvent_Server_tep(void *p);
   friend void *Shutdown_tep(void *p);
+  friend void *connect_to_server_tep(void *s);
   friend class ICQUser;
   friend class CSocketManager;
   friend class CChatManager;
diff -ruN licq.bak/plugins/qt-gui/src/mmsenddlg.cpp licq.new/plugins/qt-gui/src/mmsenddlg.cpp
--- licq.bak/plugins/qt-gui/src/mmsenddlg.cpp	Sun Feb 16 18:16:57 2003
+++ licq.new/plugins/qt-gui/src/mmsenddlg.cpp	Thu Feb 20 16:56:28 2003
@@ -26,6 +26,7 @@
 #include <qprogressbar.h>
 #include <qvgroupbox.h>
 #include <qtextcodec.h>
+#include <qregexp.h>
 
 #include <unistd.h>
 #include <stdio.h>
@@ -34,6 +35,7 @@
 #include "mmlistview.h"
 #include "sigman.h"
 #include "licq_user.h"
+#include "licq_translate.h"
 #include "licq_icqd.h"
 #include "licq_events.h"
 #include "usercodec.h"
@@ -160,7 +162,68 @@
       grpSending->setTitle(tr("Sending mass message to %1...").arg(codec->toUnicode(u->GetAlias())));
       gUserManager.DropUser(u);
 
-      icqEventTag = server->icqSendMessage(m_nUin, codec->fromUnicode(s1), false, ICQ_TCPxMSG_NORMAL, true);
+      // create initial strings (implicit copying, no allocation impact :)
+      char *tmp = gTranslator.NToRN(codec->fromUnicode(s1));
+      QCString wholeMessageRaw(tmp);
+      delete [] tmp;
+      unsigned int wholeMessagePos = 0;
+
+      bool needsSplitting = false;
+      // If we send through server (= have message limit), and we've crossed the limit
+      if ((wholeMessageRaw.length() - wholeMessagePos) > MAX_MESSAGE_SIZE)
+      {
+        needsSplitting = true;
+      }
+
+      QString message;
+      QCString messageRaw;
+
+      while (wholeMessageRaw.length() > wholeMessagePos)
+      {
+        if (needsSplitting)
+        {
+          // This is a bit ugly but adds safety. We don't simply search
+          // for a whitespace to cut at in the encoded text (since we don't
+          // really know how spaces are represented in its encoding), so
+          // we take the maximum length, then convert back to a Unicode string
+          // and then search for Unicode whitespaces.
+          messageRaw = wholeMessageRaw.mid(wholeMessagePos, MAX_MESSAGE_SIZE);
+          tmp = gTranslator.RNToN(messageRaw);
+          messageRaw = tmp;
+          delete [] tmp;
+          message = codec->toUnicode(messageRaw);
+
+          if ((wholeMessageRaw.length() - wholeMessagePos) > MAX_MESSAGE_SIZE)
+          {
+            // We try to find the optimal place to cut
+            // (according to our narrow-minded Latin1 idea of optimal :)
+            // prefer keeping sentences intact 1st
+            int foundIndex = message.findRev(QRegExp("[\\.\\n]"));
+            // slicing at 0 position would be useless
+            if (foundIndex <= 0)
+              foundIndex = message.findRev(QRegExp("\\s"));
+
+            if (foundIndex > 0)
+            {
+              message.truncate(foundIndex);
+              messageRaw = codec->fromUnicode(message);
+            }
+          }
+        }
+        else
+        {
+          message = s1;
+          messageRaw = codec->fromUnicode(message);
+        }
+
+        icqEventTag = server->icqSendMessage(m_nUin, messageRaw.data(),
+           false, ICQ_TCPxMSG_NORMAL, true);
+
+        tmp = gTranslator.NToRN(messageRaw);
+        wholeMessagePos += strlen(tmp);
+        delete [] tmp;
+      }
+
       break;
     }
     case ICQ_CMDxSUB_URL:
diff -ruN licq.bak/plugins/qt-gui/src/usereventdlg.cpp licq.new/plugins/qt-gui/src/usereventdlg.cpp
--- licq.bak/plugins/qt-gui/src/usereventdlg.cpp	Sat Feb 15 07:31:19 2003
+++ licq.new/plugins/qt-gui/src/usereventdlg.cpp	Thu Feb 20 16:56:28 2003
@@ -47,6 +47,7 @@
 #endif
 
 #include "licq_message.h"
+#include "licq_translate.h"
 #include "licq_icqd.h"
 #include "licq_log.h"
 #include "usercodec.h"
@@ -1230,6 +1231,12 @@
 //-----UserSendCommon::sendDone_common---------------------------------------
 void UserSendCommon::sendDone_common(ICQEvent *e)
 {
+  if (e == NULL)
+  {
+    setCaption(m_sBaseTitle + " [" + m_sProgressMsg + tr("error") + "]");
+    return;
+  }
+
   unsigned long icqEventTag = 0;
   std::list<unsigned long>::iterator iter;
   for (iter = m_lnEventTag.begin(); iter != m_lnEventTag.end(); iter++)
@@ -1237,6 +1244,7 @@
     if (e->Equals(*iter))
     {
       icqEventTag = *iter;
+      m_lnEventTag.erase(iter);
       break;
     }
   }
@@ -1245,34 +1253,27 @@
     return;
 
   QString title, result;
-  if (e == NULL)
+  switch (e->Result())
   {
+  case EVENT_ACKED:
+  case EVENT_SUCCESS:
+    result = tr("done");
+    QTimer::singleShot(5000, this, SLOT(slot_resettitle()));
+    break;
+  case EVENT_CANCELLED:
+    result = tr("cancelled");
+    break;
+  case EVENT_FAILED:
+    result = tr("failed");
+    break;
+  case EVENT_TIMEDOUT:
+    result = tr("timed out");
+    break;
+  case EVENT_ERROR:
     result = tr("error");
-  }
-  else
-  {
-    switch (e->Result())
-    {
-    case EVENT_ACKED:
-    case EVENT_SUCCESS:
-      result = tr("done");
-      QTimer::singleShot(5000, this, SLOT(slot_resettitle()));
-      break;
-    case EVENT_CANCELLED:
-      result = tr("cancelled");
-      break;
-    case EVENT_FAILED:
-      result = tr("failed");
-      break;
-    case EVENT_TIMEDOUT:
-      result = tr("timed out");
-      break;
-    case EVENT_ERROR:
-      result = tr("error");
-      break;
-    default:
-      break;
-    }
+    break;
+  default:
+    break;
   }
   title = m_sBaseTitle + " [" + m_sProgressMsg + result + "]";
   setCaption(title);
@@ -1284,12 +1285,10 @@
   if (mainwin->m_bAutoSendThroughServer && e->Result() == EVENT_CANCELLED)
     chkSendServer->setChecked(true);
 
-  m_lnEventTag.pop_front();
-
   if (m_lnEventTag.size() == 0)
     disconnect (sigman, SIGNAL(signal_doneUserFcn(ICQEvent *)), this, SLOT(sendDone_common(ICQEvent *)));
 
-  if (e == NULL || e->Result() != EVENT_ACKED)
+  if (e->Result() != EVENT_ACKED)
   {
     if (e->Command() == ICQ_CMDxTCP_START && e->Result() != EVENT_CANCELLED &&
 	(mainwin->m_bAutoSendThroughServer ||
@@ -1357,14 +1356,76 @@
   chkSendServer->setChecked(!bOnline);
   chkUrgent->setChecked(nLevel == ICQ_TCPxMSG_URGENT);
 
-  switch(e->SubCommand())
+  switch(e->SubCommand() & ~ICQ_CMDxSUB_FxMULTIREC)
   {
     case ICQ_CMDxSUB_MSG:
     {
       CEventMsg *ue = (CEventMsg *)e->UserEvent();
+      // create initial strings (implicit copying, no allocation impact :)
+      char *tmp = gTranslator.NToRN(codec->fromUnicode(ue->Message()));
+      QCString wholeMessageRaw(tmp);
+      delete [] tmp;
+      unsigned int wholeMessagePos = 0;
+
+      bool needsSplitting = false;
+      // If we send through server (= have message limit), and we've crossed the limit
+      if (!bOnline && ((wholeMessageRaw.length() - wholeMessagePos) > MAX_MESSAGE_SIZE))
+      {
+        needsSplitting = true;
+      }
+
+      QString message;
+      QCString messageRaw;
+
+      while (wholeMessageRaw.length() > wholeMessagePos)
+      {
+        if (needsSplitting)
+        {
+          // This is a bit ugly but adds safety. We don't simply search
+          // for a whitespace to cut at in the encoded text (since we don't
+          // really know how spaces are represented in its encoding), so
+          // we take the maximum length, then convert back to a Unicode string
+          // and then search for Unicode whitespaces.
+          messageRaw = wholeMessageRaw.mid(wholeMessagePos, MAX_MESSAGE_SIZE);
+          tmp = gTranslator.RNToN(messageRaw);
+          messageRaw = tmp;
+          delete [] tmp;
+          message = codec->toUnicode(messageRaw);
+
+          if ((wholeMessageRaw.length() - wholeMessagePos) > MAX_MESSAGE_SIZE)
+          {
+            // We try to find the optimal place to cut
+            // (according to our narrow-minded Latin1 idea of optimal :)
+            // prefer keeping sentences intact 1st
+            int foundIndex = message.findRev(QRegExp("[\\.\\n]"));
+            // slicing at 0 position would be useless
+            if (foundIndex <= 0)
+              foundIndex = message.findRev(QRegExp("\\s"));
+
+            if (foundIndex > 0)
+            {
+              message.truncate(foundIndex);
+              messageRaw = codec->fromUnicode(message);
+            }
+          }
+        }
+        else
+        {
+          message = ue->Message();
+          messageRaw = codec->fromUnicode(message);
+        }
+
+        icqEventTag = server->icqSendMessage(m_nUin, messageRaw.data(),
+           bOnline, nLevel, false, &icqColor);
+        m_lnEventTag.push_back(icqEventTag);
+
+        tmp = gTranslator.NToRN(messageRaw);
+        wholeMessagePos += strlen(tmp);
+        delete [] tmp;
+      }
+
+      icqEventTag = 0;
 
-      icqEventTag = server->icqSendMessage(m_nUin, ue->Message(), bOnline,
-         nLevel, false, &icqColor);
       break;
     }
     case ICQ_CMDxSUB_URL:
@@ -1528,8 +1589,6 @@
 //-----UserSendMsgEvent::sendButton------------------------------------------
 void UserSendMsgEvent::sendButton()
 {
-  #define PARTLEN (MAX_MESSAGE_SIZE - 14)
-
   // do nothing if a command is already being processed
   unsigned long icqEventTag = 0;
   if (m_lnEventTag.size())
@@ -1548,13 +1607,14 @@
   if (!UserSendCommon::checkSecure()) return;
 
   // create initial strings (implicit copying, no allocation impact :)
-  QString wholeMessage = mleSend->text();
-  QCString wholeMessageRaw = codec->fromUnicode(wholeMessage);
+  char *tmp = gTranslator.NToRN(codec->fromUnicode(mleSend->text()));
+  QCString wholeMessageRaw(tmp);
+  delete [] tmp;
   unsigned int wholeMessagePos = 0;
 
   bool needsSplitting = false;
   // If we send through server (= have message limit), and we've crossed the limit
-  if (chkSendServer->isChecked() && ((wholeMessageRaw.length() - wholeMessagePos) > PARTLEN))
+  if (chkSendServer->isChecked() && ((wholeMessageRaw.length() - wholeMessagePos) > MAX_MESSAGE_SIZE))
   {
      needsSplitting = true;
   }
@@ -1571,15 +1631,22 @@
         // really know how spaces are represented in its encoding), so
         // we take the maximum length, then convert back to a Unicode string
         // and then search for Unicode whitespaces.
-        messageRaw = wholeMessageRaw.mid(wholeMessagePos, PARTLEN);
+        messageRaw = wholeMessageRaw.mid(wholeMessagePos, MAX_MESSAGE_SIZE);
+        tmp = gTranslator.RNToN(messageRaw);
+        messageRaw = tmp;
+        delete [] tmp;
         message = codec->toUnicode(messageRaw);
         
-        if ((wholeMessageRaw.length() - wholeMessagePos) > PARTLEN)
+        if ((wholeMessageRaw.length() - wholeMessagePos) > MAX_MESSAGE_SIZE)
         {
            // We try to find the optimal place to cut
            // (according to our narrow-minded Latin1 idea of optimal :)
-           int foundIndex = message.findRev(QRegExp("[\\s\\.]"));
+           // prefer keeping sentences intact 1st
+           int foundIndex = message.findRev(QRegExp("[\\.\\n]"));
            // slicing at 0 position would be useless
+           if (foundIndex <= 0)
+             foundIndex = message.findRev(QRegExp("\\s"));
+
            if (foundIndex > 0)
            {
               message.truncate(foundIndex);
@@ -1590,7 +1657,7 @@
      else
      {
         message = mleSend->text();
-        messageRaw = wholeMessageRaw;
+        messageRaw = codec->fromUnicode(message);
      }
 
      if (chkMass->isChecked())
@@ -1604,8 +1671,10 @@
         chkUrgent->isChecked() ? ICQ_TCPxMSG_URGENT : ICQ_TCPxMSG_NORMAL,
         chkMass->isChecked(), &icqColor);
      m_lnEventTag.push_back(icqEventTag);
-   
-     wholeMessagePos += messageRaw.length();
+
+     tmp = gTranslator.NToRN(messageRaw);
+     wholeMessagePos += strlen(tmp);
+     delete [] tmp;
   }
   
   UserSendCommon::sendButton();
diff -ruN licq.bak/src/icqd-srv.cpp licq.new/src/icqd-srv.cpp
--- licq.bak/src/icqd-srv.cpp	Sat Feb 15 10:00:39 2003
+++ licq.new/src/icqd-srv.cpp	Thu Feb 20 16:56:28 2003
@@ -1045,10 +1055,16 @@
 
   if (ue != NULL) ue->m_eDir = D_SENDER;
   ICQEvent *e = new ICQEvent(this, m_nTCPSrvSocketDesc, p, CONNECT_SERVER, nUin, ue);
-  e->m_NoAck = true;
+  if (e == NULL)
+    return 0;
 
-  result = SendExpectEvent(e, &ProcessRunningEvent_Server_tep);
+  ICQUser *u = gUserManager.FetchUser(e->m_nDestinationUin, LOCK_R);
+  if (u == NULL || !u->StatusOffline())
+    e->m_NoAck = true;
+  if (u != NULL)
+    gUserManager.DropUser(u);
 
+  result = SendExpectEvent(e, &ProcessRunningEvent_Server_tep);
   return result;
 }
 
@@ -1190,7 +1206,12 @@
   m_bLoggingOn = true;
   m_tLogonTime = time(NULL);
 //  ICQEvent *e = SendEvent_Server(p);
-  SendEvent_Server(p);
+//  SendEvent_Server(p);
+  ICQEvent *e = new ICQEvent(this, m_nTCPSrvSocketDesc, p, CONNECT_SERVER, 0, NULL);
+  if (e == NULL)
+    return 0;
+  SendExpectEvent(e, &ProcessRunningEvent_Server_tep);
+
   return 0;
 }
 
@@ -1202,22 +1223,27 @@
   m_nTCPSrvSocketDesc = -1;
 
   m_eStatus = STATUS_OFFLINE_MANUAL;
-  m_bLoggingOn = false;
 
-
-  if (nSD == -1)
+  if (nSD == -1 && !m_bLoggingOn)
   {
     gLog.Warn("%sAttempt to logoff while not logged on.\n", L_WARNxSTR);
     return;
   }
 
+  m_bLoggingOn = false;
+
   gLog.Info("%sLogging off.\n", L_SRVxSTR);
-  CPU_Logoff p;
-  ICQEvent *cancelledEvent = new ICQEvent(this, nSD, &p, CONNECT_SERVER, 0, NULL);
-  cancelledEvent->m_pPacket = NULL;
-  cancelledEvent->m_bCancelled = true;
-  SendEvent(nSD, p, true);
-  gSocketManager.CloseSocket(nSD);
+  ICQEvent *cancelledEvent = NULL;
+
+  if (nSD != -1)
+  {
+    CPU_Logoff p;
+    cancelledEvent = new ICQEvent(this, nSD, &p, CONNECT_SERVER, 0, NULL);
+    cancelledEvent->m_pPacket = NULL;
+    cancelledEvent->m_bCancelled = true;
+    SendEvent(nSD, p, true);
+    gSocketManager.CloseSocket(nSD);
+  }
 
   postLogoff(nSD, cancelledEvent);
 }
@@ -1228,9 +1254,10 @@
   pthread_mutex_lock(&mutex_sendqueue_server);
   pthread_mutex_lock(&mutex_extendedevents);
   std::list<ICQEvent *>::iterator iter = m_lxRunningEvents.begin();
+
   while (iter != m_lxRunningEvents.end())
   {
-    if ((*iter)->m_nSocketDesc == nSD)
+    if ((*iter)->m_nSocketDesc == nSD || (*iter)->Channel() == ICQ_CHNxNEW)
     {
       ICQEvent *e = *iter;
       iter = m_lxRunningEvents.erase(iter);
@@ -1375,17 +1402,31 @@
     return -1;
   }
 
-  // Now get the internal ip from this socket
-  CPacket::SetLocalIp(  NetworkIpToPacketIp(s->LocalIp() ));
-  ICQOwner *o = gUserManager.FetchOwner(LOCK_W);
-  o->SetIntIp(s->LocalIp());
-  gUserManager.DropOwner();
+  static pthread_mutex_t connect_mutex = PTHREAD_MUTEX_INITIALIZER;
+  pthread_mutex_lock(&connect_mutex);
+  int socket;
+  if (m_nTCPSrvSocketDesc != -1)
+  {
+    gLog.Warn("%sConnection to server already exists, aborting.\n", L_WARNxSTR);
+    delete s;
+    socket = -1;
+  }
+  else
+  {
+    // Now get the internal ip from this socket
+    CPacket::SetLocalIp(  NetworkIpToPacketIp(s->LocalIp() ));
+    ICQOwner *o = gUserManager.FetchOwner(LOCK_W);
+    o->SetIntIp(s->LocalIp());
+    gUserManager.DropOwner();
+
+    gSocketManager.AddSocket(s);
+    socket = m_nTCPSrvSocketDesc = s->Descriptor();
+    gSocketManager.DropSocket(s);
+  }
 
-  gSocketManager.AddSocket(s);
-  m_nTCPSrvSocketDesc = s->Descriptor();
-  gSocketManager.DropSocket(s);
+  pthread_mutex_unlock(&connect_mutex);
 
-  return m_nTCPSrvSocketDesc;
+  return socket;
 }
 
 //-----FindUserForInfoUpdate-------------------------------------------------
@@ -2601,6 +2982,19 @@
 		gLog.Info("%sReceived rights for Instant Messaging..\n", L_SRVxSTR);
 		break;
 	}
+  case ICQ_SNACxMSG_SERVERxACK:
+  {
+    ICQEvent *e = DoneServerEvent(nSubSequence, EVENT_ACKED);
+    if (e)
+    {
+			e->m_nSubResult = ICQ_TCPxACK_ACCEPT;
+      ProcessDoneEvent(e);
+    }
+    else
+      gLog.Warn("%sAck for unknown event.\n", L_WARNxSTR);
+
+    break;
+  }
 	default:
 	{
 		gLog.Warn("%sUnknown Message Family Subtype: %04hx\n", L_SRVxSTR, nSubtype);
diff -ruN licq.bak/src/icqd-tcp.cpp licq.new/src/icqd-tcp.cpp
--- licq.bak/src/icqd-tcp.cpp	Mon Jan 20 21:00:31 2003
+++ licq.new/src/icqd-tcp.cpp	Thu Feb 20 16:56:28 2003
@@ -43,7 +43,7 @@
   if (nLevel == ICQ_TCPxMSG_URGENT) f |= E_URGENT;
   if (bMultipleRecipients) f |= E_MULTIxREC;
 
-	ICQUser *u = gUserManager.FetchUser(_nUin, LOCK_W);
+	ICQUser *u;
   if (!online) // send offline
   {
      e = new CEventMsg(m, ICQ_CMDxSND_THRUxSERVER, TIME_NOW, f);
@@ -55,9 +55,11 @@
      }
      result = icqSendThroughServer(_nUin, ICQ_CMDxSUB_MSG | (bMultipleRecipients ? ICQ_CMDxSUB_FxMULTIREC : 0),
                                    mDos, e);
+     u = gUserManager.FetchUser(_nUin, LOCK_W);
   }
   else        // send direct
   {
+    u = gUserManager.FetchUser(_nUin, LOCK_W);
     if (u == NULL) return 0;
     if (u->Secure()) f |= E_ENCRYPTED;
     e = new CEventMsg(m, ICQ_CMDxTCP_START, TIME_NOW, f);
@@ -73,8 +75,9 @@
   {
     u->SetSendServer(!online);
     u->SetSendLevel(nLevel);
+    gUserManager.DropUser(u);
   }
-  gUserManager.DropUser(u);
+
   if (pColor != NULL) CICQColor::SetDefaultColors(pColor);
 
   if (mDos)
@@ -142,14 +145,16 @@
   if (nLevel == ICQ_TCPxMSG_URGENT) f |= E_URGENT;
   if (bMultipleRecipients) f |= E_MULTIxREC;
 
-  ICQUser *u = gUserManager.FetchUser(_nUin, LOCK_W);
+  ICQUser *u;
   if (!online) // send offline
   {
     e = new CEventUrl(url, description, ICQ_CMDxSND_THRUxSERVER, TIME_NOW, f);
     result = icqSendThroughServer(_nUin, ICQ_CMDxSUB_URL | (bMultipleRecipients ? ICQ_CMDxSUB_FxMULTIREC : 0), m, e);
+    u = gUserManager.FetchUser(_nUin, LOCK_W);
   }
   else
   {
+    u = gUserManager.FetchUser(_nUin, LOCK_W);
     if (u == NULL) return 0;
     if (u->Secure()) f |= E_ENCRYPTED;
     e = new CEventUrl(url, description, ICQ_CMDxTCP_START, TIME_NOW, f);
@@ -164,8 +169,9 @@
   {
     u->SetSendServer(!online);
     u->SetSendLevel(nLevel);
+    gUserManager.DropUser(u);
   }
-  gUserManager.DropUser(u);
+
   if (pColor != NULL) CICQColor::SetDefaultColors(pColor);
 
   if (szDescDos)
@@ -292,14 +298,15 @@
   if (nLevel == ICQ_TCPxMSG_URGENT) f |= E_URGENT;
   if (bMultipleRecipients) f |= E_MULTIxREC;
 
-  u = gUserManager.FetchUser(nUin, LOCK_W);
   if (!online) // send offline
   {
     e = new CEventContactList(vc, false, ICQ_CMDxSND_THRUxSERVER, TIME_NOW, f);
     result = icqSendThroughServer(nUin, ICQ_CMDxSUB_CONTACTxLIST | (bMultipleRecipients ? ICQ_CMDxSUB_FxMULTIREC : 0), m, e);
+    u = gUserManager.FetchUser(nUin, LOCK_W);
   }
   else
   {
+    u = gUserManager.FetchUser(nUin, LOCK_W);
     if (u == NULL) return 0;
     if (u->Secure()) f |= E_ENCRYPTED;
     e = new CEventContactList(vc, false, ICQ_CMDxTCP_START, TIME_NOW, f);
@@ -314,8 +321,9 @@
   {
     u->SetSendServer(!online);
     u->SetSendLevel(nLevel);
+    gUserManager.DropUser(u);
   }
-  gUserManager.DropUser(u);
+
   if (pColor != NULL) CICQColor::SetDefaultColors(pColor);
 
   delete []m;
diff -ruN licq.bak/src/icqd-threads.cpp licq.new/src/icqd-threads.cpp
--- licq.bak/src/icqd-threads.cpp	Sun Feb  2 11:34:23 2003
+++ licq.new/src/icqd-threads.cpp	Thu Feb 20 16:56:28 2003
@@ -28,6 +28,29 @@
   gSocketManager.DropSocket((INetSocket *)s);
 }
 
+void *cleanup_thread_tep(void *t)
+{
+  pthread_detach(pthread_self());
+  int *s;
+  pthread_join(*((pthread_t *)t), (void **)&s);
+  delete (pthread_t *)t;
+  delete s;
+  pthread_exit(NULL);
+}
+
+void cleanup_thread(void *t)
+{
+  pthread_t cleanup;
+  pthread_create(&cleanup, NULL, &cleanup_thread_tep, t);
+}
+
+void *connect_to_server_tep(void *s)
+{
+  *((int *)s) = gLicqDaemon->ConnectToLoginServer();
+  pthread_exit(s);
+}
+
+
 /*------------------------------------------------------------------------------
  * ProcessRunningEvent_tep
  *
@@ -87,17 +110,28 @@
 
     if (e == NULL)
     {
-      pthread_mutex_unlock(&send_mutex);
+      bool bEmpty = d->m_lxSendQueue_Server.empty();
+
       pthread_mutex_unlock(&d->mutex_sendqueue_server);
-      pthread_exit(NULL);
-    }
+      pthread_mutex_unlock(&send_mutex);
 
-    d->m_lxSendQueue_Server.erase(iter);
+      if (bEmpty)
+        pthread_exit(NULL);
 
-    if (e->m_bCancelled)
+      struct timeval tv = { 1, 0 };
+      select(0, NULL, NULL, NULL, &tv);
+      pthread_mutex_lock(&send_mutex);
+      pthread_mutex_lock(&d->mutex_sendqueue_server);
+    }
+    else
     {
-      delete e;
-      e = NULL;
+      d->m_lxSendQueue_Server.erase(iter);
+
+      if (e->m_bCancelled)
+      {
+        delete e;
+        e = NULL;
+      }
     }
   }
 
@@ -128,8 +162,20 @@
         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
         gLog.Info("%sConnecting to login server.\n", L_SRVxSTR);
 
-        int socket = d->ConnectToLoginServer();
-        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+        pthread_t *t = new pthread_t;
+        int *s = new int;
+        pthread_create(t, NULL, connect_to_server_tep, s);
+        pthread_cleanup_push(cleanup_thread, t);
+          pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
+          pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+          pthread_testcancel();
+          pthread_join(*t, NULL);
+        pthread_cleanup_pop(0);
+        int socket = *s;
+        delete t;
+        delete s;
+
+        pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
         pthread_testcancel();
 
         e->m_nSocketDesc = socket;
