ShowAwayMsgDlg::ShowAwayMsgDlg(CICQDaemon *_server, CSignalManager* _sigman, const char *szId, unsigned long nPPID, QWidget *parent) : LicqDialog(parent, "ShowAwayMessageDialog") { m_szId = szId ? strdup(szId) : 0; m_nPPID = nPPID; sigman = _sigman; server = _server; QBoxLayout* top_lay = new QVBoxLayout(this, 10); mleAwayMsg = new MLEditWrap(true, this); // ICQ99b allows 37 chars per line, so we do the same //mleAwayMsg->setWordWrap(QMultiLineEditNew::FixedColumnWidth); //mleAwayMsg->setWrapColumnOrWidth(37); mleAwayMsg->setReadOnly(true); mleAwayMsg->setMinimumSize(230, 110); connect(mleAwayMsg, SIGNAL(signal_CtrlEnterPressed()), SLOT(accept())); top_lay->addWidget(mleAwayMsg); QBoxLayout* lay = new QHBoxLayout(top_lay, 10); chkShowAgain = new QCheckBox(tr("&Show Again"), this); lay->addWidget(chkShowAgain); lay->addStretch(1); lay->addSpacing(30); ICQUser *u = gUserManager.FetchUser(m_szId, m_nPPID, LOCK_R); QTextCodec * codec = UserCodec::codecForICQUser(u); // chkShowAgain->setChecked(u->ShowAwayMsg()); setCaption(QString(tr("%1 Response for %2")).arg(u->StatusStr()).arg(QString::fromUtf8(u->GetAlias()))); btnOk = new QPushButton(tr("&Ok"), this); btnOk->setMinimumWidth(75); btnOk->setDefault(true); btnOk->setFocus(); connect(btnOk, SIGNAL(clicked()), SLOT(accept())); lay->addWidget(btnOk); // Check if this is an active request or not if (sigman == NULL || server == NULL) { mleAwayMsg->setText(codec->toUnicode(u->AutoResponse())); gUserManager.DropUser(u); icqEventTag = 0; } else { bool bSendServer = (u->SocketDesc(ICQ_CHNxNONE) <= 0 && u->Version() > 6); gUserManager.DropUser(u); mleAwayMsg->setEnabled(false); mleAwayMsg->setBackgroundMode(PaletteBackground); connect (sigman, SIGNAL(signal_doneUserFcn(ICQEvent *)), this, SLOT(doneEvent(ICQEvent *))); icqEventTag = server->icqFetchAutoResponse(szId, nPPID, bSendServer); } show(); }
void *ProcessRunningEvent_Client_tep(void *p) { pthread_detach(pthread_self()); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); /* want to be cancelled immediately so we don't try to derefence the event after it has been deleted */ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); DEBUG_THREADS("[ProcessRunningEvent_Client_tep] Caught event.\n"); ICQEvent *e = (ICQEvent *)p; pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_testcancel(); CICQDaemon *d = e->m_pDaemon; // Check if the socket is connected if (e->m_nSocketDesc == -1) { unsigned long nDestinationUin = e->m_nDestinationUin; unsigned char nChannel = e->Channel(); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); ICQUser *u = gUserManager.FetchUser(nDestinationUin, LOCK_R); if (u == NULL) { if (d->DoneEvent(e, EVENT_ERROR) != NULL) d->ProcessDoneEvent(e); else { pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_testcancel(); delete e; } pthread_exit(NULL); } unsigned long nVersion = u->Version(); unsigned char nMode = u->Mode(); unsigned short nRemotePort = u->Port(); bool bSendIntIp = u->SendIntIp(); gUserManager.DropUser(u); ICQOwner *o = gUserManager.FetchOwner(LOCK_R); unsigned long nIP = bSendIntIp ? o->IntIp() : o->Ip(); unsigned short nLocalPort = o->Port(); gUserManager.DropOwner(); int socket = -1; if (!bSendIntIp && nVersion > 6 && nMode != MODE_DIRECT) { int nId = d->RequestReverseConnection(nDestinationUin, nChannel, nIP, nLocalPort, nRemotePort); if (nId != -1) { d->WaitForReverseConnection(nId, nDestinationUin); u = gUserManager.FetchUser(nDestinationUin, LOCK_R); if (u == NULL) { if (d->DoneEvent(e, EVENT_ERROR) != NULL) d->ProcessDoneEvent(e); else { pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_testcancel(); delete e; } pthread_exit(NULL); } socket = u->SocketDesc(nChannel); gUserManager.DropUser(u); } // if we failed, try direct anyway if (socket == -1) { pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_testcancel(); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); socket = d->ConnectToUser(nDestinationUin, nChannel); } } else { socket = d->ConnectToUser(nDestinationUin, nChannel); // if we failed, try through server if (socket == -1) { pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_testcancel(); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); int nId = d->RequestReverseConnection(nDestinationUin, nChannel, nIP, nLocalPort, nRemotePort); if (nId != -1) { d->WaitForReverseConnection(nId, nDestinationUin); u = gUserManager.FetchUser(nDestinationUin, LOCK_R); if (u == NULL) { if (d->DoneEvent(e, EVENT_ERROR) != NULL) d->ProcessDoneEvent(e); else { pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_testcancel(); delete e; } pthread_exit(NULL); } socket = u->SocketDesc(nChannel); gUserManager.DropUser(u); } } } pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_testcancel(); e->m_nSocketDesc = socket; // Check again, if still -1, fail the event if (e->m_nSocketDesc == -1) { pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); if (d->DoneEvent(e, EVENT_ERROR) != NULL) d->ProcessDoneEvent(e); else { pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_testcancel(); delete e; } pthread_exit(NULL); } } int socket = e->m_nSocketDesc; pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); INetSocket *s = gSocketManager.FetchSocket(socket); if (s == NULL) { pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_testcancel(); unsigned short nSequence = e->m_nSequence; pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); gLog.Warn(tr("%sSocket %d does not exist (#%hu).\n"), L_WARNxSTR, socket, nSequence); if (d->DoneEvent(e, EVENT_ERROR) != NULL) d->ProcessDoneEvent(e); else { pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_testcancel(); delete e; } pthread_exit(NULL); } CBuffer *buf; bool sent; char szErrorBuf[128]; pthread_cleanup_push(cleanup_socket, s); pthread_mutex_lock(&d->mutex_cancelthread); // check to make sure we were not cancelled already pthread_cleanup_push(cleanup_mutex, &d->mutex_cancelthread); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_testcancel(); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); //if we get here then we haven't been cancelled and we won't be //as long as we hold mutex_cancelthread buf = e->m_pPacket->Finalize(s); pthread_mutex_unlock(&d->mutex_cancelthread); pthread_cleanup_pop(0); sent = s->Send(buf); if (!sent) s->ErrorStr(szErrorBuf, 128); gSocketManager.DropSocket(s); pthread_cleanup_pop(0); if (!sent) { // Close the socket, alert the socket thread gSocketManager.CloseSocket(socket); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_testcancel(); unsigned short nSequence = e->m_nSequence; pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); gLog.Warn(tr("%sError sending event (#%hu):\n%s%s.\n"), L_WARNxSTR, -nSequence, L_BLANKxSTR, szErrorBuf); write(d->pipe_newsocket[PIPE_WRITE], "S", 1); // Kill the event, do after the above as ProcessDoneEvent erase the event if (d->DoneEvent(e, EVENT_ERROR) != NULL) d->ProcessDoneEvent(e); else { pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_testcancel(); delete e; } pthread_exit(NULL); } pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_testcancel(); e->thread_running = false; // pthread_exit is not async cancel safe??? pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); pthread_exit(NULL); // Avoid compiler warnings return NULL; }