Example #1
0
void GGWrapper::enterLoop()
{
    while(!mWorkerThread.interruption_requested())
    {
        boost::any item = mpQueue->poll();
        if(item.empty())
        {
            //Logger::log("Looping\r\n");
            gg_event *event = pollGGEvent();
            if(event != 0)
            {
                processGGEvent(*event);
                gg_free_event(event);
            }
        }
        else
        {
            processEvent(boost::any_cast<ggEvent&>(item));
        }

        sendPing();

    }
    Logger::log("Finished Looping!");
    //probably here some cleaning or just do everything in destructor;
}
void
GaduDCCServer::watcher() {

	gg_event* dccEvent;
	bool handled = false;

	disableNotifiers();

	dccEvent = gg_dcc_watch_fd( dccSock );
	if ( ! dccEvent ) {
		// connection is f****d
		// we should try to reenable it
//		closeDCC();
		return;
	}
	switch ( dccEvent->type ) {
		case GG_EVENT_NONE:
			break;
		case GG_EVENT_DCC_ERROR:
			kdDebug( 14100 ) << " dcc error occured " << endl;
			break;
		case GG_EVENT_DCC_NEW:
			// I do expect reciver to set this boolean to true if he handled signal
			// if so, no other reciver should be bothered with it, and I shall not close it
			// otherwise connection is closed as not handled
			emit incoming( dccEvent->event.dcc_new, handled );
			if ( !handled ) {
				if ( dccEvent->event.dcc_new->file_fd > 0) {
					close( dccEvent->event.dcc_new->file_fd );
				}
				gg_dcc_free( dccEvent->event.dcc_new );
			}
			break;
		default:
			kdDebug(14100) << "unknown/unhandled DCC EVENT: " << dccEvent->type << endl;
			break;
	}

	if ( dccEvent ) {
		gg_free_event( dccEvent );
	}

	enableNotifiers( dccSock->check );
}
Example #3
0
void __cdecl GGPROTO::dccmainthread(void*)
{
	uin_t uin;
	gg_event *e;
	struct timeval tv;
	fd_set rd, wd;
	int ret;
	SOCKET maxfd;
	DWORD tick;
	list_t l;
	char szFilename[MAX_PATH];

	// Zero up lists
	watches = transfers = requests = l = NULL;

	debugLogA("dccmainthread(): started. DCC Server Thread Starting");

	// Readup number
	if (!(uin = getDword(GG_KEY_UIN, 0)))
	{
		debugLogA("dccmainthread(): No Gadu-Gadu number specified. Exiting.");
		if (hEvent) SetEvent(hEvent);
#ifdef DEBUGMODE
		debugLogA("dccmainthread(): end 1.");
#endif
		return;
	}

	// Create listen socket on config direct port
	if (!(dcc = gg_dcc_socket_create(uin, (uint16_t)getWord(GG_KEY_DIRECTPORT, GG_KEYDEF_DIRECTPORT))))
	{
		debugLogA("dccmainthread(): Cannot create DCC listen socket. Exiting.");
		// Signalize mainthread we haven't start
		if (hEvent) SetEvent(hEvent);
#ifdef DEBUGMODE
		debugLogA("dccmainthread(): end 2.");
#endif
		return;
	}

	gg_dcc_port = dcc->port;
	gg_dcc_ip = inet_addr("255.255.255.255");
	debugLogA("dccmainthread(): Listening on port %d.", gg_dcc_port);

	// Signalize mainthread we started
	if (hEvent) SetEvent(hEvent);

	// Add main dcc handler to watches
	list_add(&watches, dcc, 0);

	// Do while we are in the main server thread
	while(pth_dcc.dwThreadId && dcc)
	{
		// Timeouts
		tv.tv_sec = 1;
		tv.tv_usec = 0;

		// Prepare descriptiors for select
		FD_ZERO(&rd);
		FD_ZERO(&wd);

		for (maxfd = 0, l = watches; l; l = l->next)
		{
			gg_common *w = (gg_common*)l->data;

			if (!w || w->state == GG_STATE_ERROR || w->state == GG_STATE_IDLE || w->state == GG_STATE_DONE)
				continue;

			// Check if it's proper descriptor
			if (w->fd == -1) continue;

			if (w->fd > maxfd)
				maxfd = w->fd;
			if ((w->check & GG_CHECK_READ))
				FD_SET(w->fd, &rd);
			if ((w->check & GG_CHECK_WRITE))
				FD_SET(w->fd, &wd);
		}

		// Wait for data on selects
		ret = select(maxfd + 1, &rd, &wd, NULL, &tv);

		// Check for select error
		if (ret == -1)
		{
			if (errno == EBADF)
				debugLogA("dccmainthread(): Bad descriptor on select().");
			else if (errno != EINTR)
				debugLogA("dccmainthread(): Unknown error on select().");
			continue;
		}

		// Process watches (carefull with l)
		l = watches;
		gg_EnterCriticalSection(&ft_mutex, "dccmainthread", 37, "ft_mutex", 1);
		while (l)
		{
			struct gg_common *local_c = (gg_common*)l->data;
			struct gg_dcc *local_dcc = (gg_dcc*)l->data;
			struct gg_dcc7 *local_dcc7 = (gg_dcc7*)l->data;
			l = l->next;

			switch (local_c->type)
			{
				default:
					if (!local_dcc || (!FD_ISSET(local_dcc->fd, &rd) && !FD_ISSET(local_dcc->fd, &wd)))
						continue;

					/////////////////////////////////////////////////////////////////
					// Process DCC events

					// Connection broken/closed
					gg_LeaveCriticalSection(&ft_mutex, "dccmainthread", 37, 2, "ft_mutex", 1);
					if (!(e = gg_dcc_socket_watch_fd(local_dcc)))
					{
						debugLogA("dccmainthread(): Socket closed.");
						// Remove socket and _close
						gg_EnterCriticalSection(&ft_mutex, "dccmainthread", 37, "ft_mutex", 1);
						list_remove(&watches, local_dcc, 0);
						gg_dcc_socket_free(local_dcc);

						// Check if it's main socket
						if (local_dcc == dcc) dcc = NULL;
						continue;
					} else {
						gg_EnterCriticalSection(&ft_mutex, "dccmainthread", 37, "ft_mutex", 1);
						debugLogA("dccmainthread(): Event: %s", ggdebug_eventtype(e));
					}

					switch(e->type)
					{
						// Client connected
						case GG_EVENT_DCC_NEW:
							list_add(&watches, e->event.dcc_new, 0);
							e->event.dcc_new = NULL;
							break;

						//
						case GG_EVENT_NONE:
							// If transfer in progress do status
							if (local_dcc->file_fd != -1 && local_dcc->offset > 0 && (((tick = GetTickCount()) - local_dcc->tick) > GGSTATREFRESHEVERY))
							{
								PROTOFILETRANSFERSTATUS pfts;
								local_dcc->tick = tick;
								mir_snprintf(szFilename, "%s%s", local_dcc->folder, local_dcc->file_info.filename);
								memset(&pfts, 0, sizeof(PROTOFILETRANSFERSTATUS));
								pfts.cbSize = sizeof(PROTOFILETRANSFERSTATUS);
								pfts.hContact = (UINT_PTR)local_dcc->contact;
								pfts.flags = (local_dcc->type == GG_SESSION_DCC_SEND);
								pfts.pszFiles = NULL;
								pfts.totalFiles = 1;
								pfts.currentFileNumber = 0;
								pfts.totalBytes = local_dcc->file_info.size;
								pfts.totalProgress = local_dcc->offset;
								pfts.szWorkingDir = local_dcc->folder;
								pfts.szCurrentFile = szFilename;
								pfts.currentFileSize = local_dcc->file_info.size;
								pfts.currentFileProgress = local_dcc->offset;
								pfts.currentFileTime = 0;
								gg_LeaveCriticalSection(&ft_mutex, "dccmainthread", 37, 3, "ft_mutex", 1);
								ProtoBroadcastAck((UINT_PTR)local_dcc->contact, ACKTYPE_FILE, ACKRESULT_DATA, local_dcc, (LPARAM)&pfts);
								gg_EnterCriticalSection(&ft_mutex, "dccmainthread", 37, "ft_mutex", 1);
							}
							break;

						// Connection was successfuly ended
						case GG_EVENT_DCC_DONE:
							debugLogA("dccmainthread(): Client: %d, Transfer done ! Closing connection.", dcc->peer_uin);
							// Remove from watches
							list_remove(&watches, local_dcc, 0);
							// Close file & success
							if (local_dcc->file_fd != -1)
							{
								PROTOFILETRANSFERSTATUS pfts;
								mir_snprintf(szFilename, "%s%s", local_dcc->folder, local_dcc->file_info.filename);
								memset(&pfts, 0, sizeof(PROTOFILETRANSFERSTATUS));
								pfts.cbSize = sizeof(PROTOFILETRANSFERSTATUS);
								pfts.hContact = (UINT_PTR)local_dcc->contact;
								pfts.flags = (local_dcc->type == GG_SESSION_DCC_SEND);
								pfts.pszFiles = NULL;
								pfts.totalFiles = 1;
								pfts.currentFileNumber = 0;
								pfts.totalBytes = local_dcc->file_info.size;
								pfts.totalProgress = local_dcc->file_info.size;
								pfts.szWorkingDir = local_dcc->folder;
								pfts.szCurrentFile = szFilename;
								pfts.currentFileSize = local_dcc->file_info.size;
								pfts.currentFileProgress = local_dcc->file_info.size;
								pfts.currentFileTime = 0;
								gg_LeaveCriticalSection(&ft_mutex, "dccmainthread", 37, 4, "ft_mutex", 1);
								ProtoBroadcastAck((UINT_PTR)local_dcc->contact, ACKTYPE_FILE, ACKRESULT_DATA, local_dcc, (LPARAM)&pfts);
								gg_EnterCriticalSection(&ft_mutex, "dccmainthread", 37, "ft_mutex", 1);
								_close(local_dcc->file_fd); local_dcc->file_fd = -1;
								gg_LeaveCriticalSection(&ft_mutex, "dccmainthread", 37, 5, "ft_mutex", 1);
								ProtoBroadcastAck((UINT_PTR)local_dcc->contact, ACKTYPE_FILE, ACKRESULT_SUCCESS, local_dcc, 0);
								gg_EnterCriticalSection(&ft_mutex, "dccmainthread", 37, "ft_mutex", 1);
							}
							// Free dcc
							gg_free_dcc(local_dcc); if (local_dcc == dcc) dcc = NULL;
							break;

						// Client error
						case GG_EVENT_DCC_ERROR:
							switch (e->event.dcc_error)
							{
								case GG_ERROR_DCC_HANDSHAKE:
									debugLogA("dccmainthread(): Client: %d, Handshake error.", local_dcc->peer_uin);
									break;
								case GG_ERROR_DCC_NET:
									debugLogA("dccmainthread(): Client: %d, Network error.", local_dcc->peer_uin);
									break;
								case GG_ERROR_DCC_FILE:
									debugLogA("dccmainthread(): Client: %d, File read/write error.", local_dcc->peer_uin);
									break;
								case GG_ERROR_DCC_EOF:
									debugLogA("dccmainthread(): Client: %d, End of file/connection error.", local_dcc->peer_uin);
									break;
								case GG_ERROR_DCC_REFUSED:
									debugLogA("dccmainthread(): Client: %d, Connection refused error.", local_dcc->peer_uin);
									break;
								default:
									debugLogA("dccmainthread(): Client: %d, Unknown error.", local_dcc->peer_uin);
							}
							// Don't do anything if it's main socket
							if (local_dcc == dcc) break;

							// Remove from watches
							list_remove(&watches, local_dcc, 0);

							// Close file & fail
							if (local_dcc->contact)
							{
								_close(local_dcc->file_fd); local_dcc->file_fd = -1;
								gg_LeaveCriticalSection(&ft_mutex, "dccmainthread", 37, 6, "ft_mutex", 1);
								ProtoBroadcastAck((UINT_PTR)local_dcc->contact, ACKTYPE_FILE, ACKRESULT_FAILED, local_dcc, 0);
								gg_EnterCriticalSection(&ft_mutex, "dccmainthread", 37, "ft_mutex", 1);
							}
							// Free dcc
							gg_free_dcc(local_dcc); if (local_dcc == dcc) dcc = NULL;
							break;

						// Need file acknowledgement
						case GG_EVENT_DCC_NEED_FILE_ACK:
							debugLogA("dccmainthread(): Client: %d, File ack filename \"%s\" size %d.", local_dcc->peer_uin,
									local_dcc->file_info.filename, local_dcc->file_info.size);
							// Do not watch for transfer until user accept it
							list_remove(&watches, local_dcc, 0);
							// Add to waiting transfers
							list_add(&transfers, local_dcc, 0);

							//////////////////////////////////////////////////
							// Add file recv request
							{
								// Make new ggtransfer struct
								local_dcc->contact = (void*)getcontact(local_dcc->peer_uin, 0, 0, NULL);
								TCHAR* filenameT = mir_utf8decodeT((char*)dcc->file_info.filename);

								PROTORECVFILET pre = {0};
								pre.dwFlags = PRFF_TCHAR;
								pre.fileCount = 1;
								pre.timestamp = time(NULL);
								pre.descr.t = filenameT;
								pre.files.t = &filenameT;
								pre.lParam = (LPARAM)local_dcc;

								gg_LeaveCriticalSection(&ft_mutex, "dccmainthread", 37, 7, "ft_mutex", 1);
								ProtoChainRecvFile((UINT_PTR)local_dcc->contact, &pre);
								gg_EnterCriticalSection(&ft_mutex, "dccmainthread", 37, "ft_mutex", 1);

								mir_free(filenameT);
							}
							break;

						// Need client accept
						case GG_EVENT_DCC_CLIENT_ACCEPT:
							debugLogA("dccmainthread(): Client: %d, Client accept.", local_dcc->peer_uin);
							// Check if user is on the list and if it is my uin
							if (getcontact(local_dcc->peer_uin, 0, 0, NULL) &&
								getDword(GG_KEY_UIN, -1) == local_dcc->uin)
								break;

							// Kill unauthorized dcc
							list_remove(&watches, dcc, 0);
							gg_free_dcc(local_dcc); if (local_dcc == dcc) dcc = NULL;
							break;

						// Client connected as we wished to (callback)
						case GG_EVENT_DCC_CALLBACK:
						{
							int found = 0;
							debugLogA("dccmainthread(): Callback from client %d.", local_dcc->peer_uin);
							// Seek for stored callback request
							for (l = requests; l; l = l->next)
							{
								struct gg_dcc *req = (gg_dcc*)l->data;

								if (req && req->peer_uin == local_dcc->peer_uin)
								{
									gg_dcc_set_type(local_dcc, GG_SESSION_DCC_SEND);
									found = 1;

									// Copy data req ===> dcc
									local_dcc->folder = req->folder;
									local_dcc->contact = req->contact;
									local_dcc->file_fd = req->file_fd;
									memcpy(&local_dcc->file_info, &req->file_info, sizeof(struct gg_file_info));
									// Copy data back to dcc ===> req
									memcpy(req, local_dcc, sizeof(struct gg_dcc));

									// Remove request
									list_remove(&requests, req, 0);
									// Remove dcc from watches
									list_remove(&watches, local_dcc, 0);
									// Add request to watches
									list_add(&watches, req, 0);
									// Free old dat
									gg_free_dcc(local_dcc);
									debugLogA("dccmainthread(): Found stored request to client %d, filename \"%s\" size %d, folder \"%s\".",
										req->peer_uin, req->file_info.filename, req->file_info.size, req->folder);
									break;
								}
							}

							if (!found)
							{
								debugLogA("dccmainthread(): Unknown request to client %d.", local_dcc->peer_uin);
								// Kill unauthorized dcc
								list_remove(&watches, local_dcc, 0);
								gg_free_dcc(local_dcc); if (local_dcc == dcc) dcc = NULL;
							}
							break;
						}
					}

					// Free event
					gg_free_event(e);
					break;

				case GG_SESSION_DCC7_SOCKET:
				case GG_SESSION_DCC7_GET:
				case GG_SESSION_DCC7_SEND:
				case GG_SESSION_DCC7_VOICE:
					if (!local_dcc7 || (!FD_ISSET(local_dcc7->fd, &rd) && !FD_ISSET(local_dcc7->fd, &wd)))
						continue;

					/////////////////////////////////////////////////////////////////
					// Process DCC7 events

					// Connection broken/closed
					gg_LeaveCriticalSection(&ft_mutex, "dccmainthread", 37, 8, "ft_mutex", 1);
					if (!(e = gg_dcc7_watch_fd(local_dcc7)))
					{
						debugLogA("dccmainthread(): Socket closed.");
						// Remove socket and _close
						gg_EnterCriticalSection(&ft_mutex, "dccmainthread", 37, "ft_mutex", 1);
						list_remove(&watches, local_dcc7, 0);
						gg_dcc7_free(local_dcc7);
						continue;
					} else {
						gg_EnterCriticalSection(&ft_mutex, "dccmainthread", 37, "ft_mutex", 1);
						debugLogA("dccmainthread(): Event: %s", ggdebug_eventtype(e));
					}

					switch(e->type)
					{
						//
						case GG_EVENT_NONE:
							// If transfer in progress do status
							if (local_dcc7->file_fd != -1 && local_dcc7->offset > 0 && (((tick = GetTickCount()) - local_dcc7->tick) > GGSTATREFRESHEVERY))
							{
								PROTOFILETRANSFERSTATUS pfts;
								local_dcc7->tick = tick;
								mir_snprintf(szFilename, "%s%s", local_dcc->folder, local_dcc7->filename);
								memset(&pfts, 0, sizeof(PROTOFILETRANSFERSTATUS));
								pfts.cbSize = sizeof(PROTOFILETRANSFERSTATUS);
								pfts.hContact = (UINT_PTR)local_dcc7->contact;
								pfts.flags = (local_dcc7->type == GG_SESSION_DCC7_SEND);
								pfts.pszFiles = NULL;
								pfts.totalFiles = 1;
								pfts.currentFileNumber = 0;
								pfts.totalBytes = local_dcc7->size;
								pfts.totalProgress = local_dcc7->offset;
								pfts.szWorkingDir = local_dcc7->folder;
								pfts.szCurrentFile = szFilename;
								pfts.currentFileSize = local_dcc7->size;
								pfts.currentFileProgress = local_dcc7->offset;
								pfts.currentFileTime = 0;
								gg_LeaveCriticalSection(&ft_mutex, "dccmainthread", 37, 9, "ft_mutex", 1);
								ProtoBroadcastAck((UINT_PTR)local_dcc7->contact, ACKTYPE_FILE, ACKRESULT_DATA, local_dcc7, (LPARAM)&pfts);
								gg_EnterCriticalSection(&ft_mutex, "dccmainthread", 37, "ft_mutex", 1);
							}
							break;

						// Connection was successfuly ended
						case GG_EVENT_DCC7_DONE:
							debugLogA("dccmainthread(): Client: %d, Transfer done ! Closing connection.", dcc->peer_uin);
							// Remove from watches
							list_remove(&watches, local_dcc7, 0);
							// Close file & success
							if (local_dcc7->file_fd != -1)
							{
								PROTOFILETRANSFERSTATUS pfts;
								mir_snprintf(szFilename, "%s%s", local_dcc->folder, local_dcc7->filename);
								memset(&pfts, 0, sizeof(PROTOFILETRANSFERSTATUS));
								pfts.cbSize = sizeof(PROTOFILETRANSFERSTATUS);
								pfts.hContact = (UINT_PTR)local_dcc7->contact;
								pfts.flags = (local_dcc7->type == GG_SESSION_DCC7_SEND);
								pfts.pszFiles = NULL;
								pfts.totalFiles = 1;
								pfts.currentFileNumber = 0;
								pfts.totalBytes = local_dcc7->size;
								pfts.totalProgress = local_dcc7->size;
								pfts.szWorkingDir = local_dcc7->folder;
								pfts.szCurrentFile = szFilename;
								pfts.currentFileSize = local_dcc7->size;
								pfts.currentFileProgress = local_dcc7->size;
								pfts.currentFileTime = 0;
								gg_LeaveCriticalSection(&ft_mutex, "dccmainthread", 37, 10, "ft_mutex", 1);
								ProtoBroadcastAck((UINT_PTR)local_dcc7->contact, ACKTYPE_FILE, ACKRESULT_DATA, local_dcc7, (LPARAM)&pfts);
								gg_EnterCriticalSection(&ft_mutex, "dccmainthread", 37, "ft_mutex", 1);
								_close(local_dcc7->file_fd); local_dcc7->file_fd = -1;
								gg_LeaveCriticalSection(&ft_mutex, "dccmainthread", 37, 11, "ft_mutex", 1);
								ProtoBroadcastAck((UINT_PTR)local_dcc7->contact, ACKTYPE_FILE, ACKRESULT_SUCCESS, local_dcc7, 0);
								gg_EnterCriticalSection(&ft_mutex, "dccmainthread", 37, "ft_mutex", 1);
							}
							// Free dcc
							gg_dcc7_free(local_dcc7);
							break;

						// Client error
						case GG_EVENT_DCC7_ERROR:
							switch (e->event.dcc7_error)
							{
								case GG_ERROR_DCC7_HANDSHAKE:
									debugLogA("dccmainthread(): Client: %d, Handshake error.", local_dcc7->peer_uin);
									break;
								case GG_ERROR_DCC7_NET:
									debugLogA("dccmainthread(): Client: %d, Network error.", local_dcc7->peer_uin);
									break;
								case GG_ERROR_DCC7_FILE:
									debugLogA("dccmainthread(): Client: %d, File read/write error.", local_dcc7->peer_uin);
									break;
								case GG_ERROR_DCC7_EOF:
									debugLogA("dccmainthread(): Client: %d, End of file/connection error.", local_dcc7->peer_uin);
									break;
								case GG_ERROR_DCC7_REFUSED:
									debugLogA("dccmainthread(): Client: %d, Connection refused error.", local_dcc7->peer_uin);
									break;
								case GG_ERROR_DCC7_RELAY:
									debugLogA("dccmainthread(): Client: %d, Relay connection error.", local_dcc7->peer_uin);
									break;
								default:
									debugLogA("dccmainthread(): Client: %d, Unknown error.", local_dcc7->peer_uin);
							}
							// Remove from watches
							list_remove(&watches, local_dcc7, 0);

							// Close file & fail
							if (local_dcc7->file_fd != -1)
							{
								_close(local_dcc7->file_fd);
								local_dcc7->file_fd = -1;
							}

							if (local_dcc7->contact) {
								gg_LeaveCriticalSection(&ft_mutex, "dccmainthread", 37, 12, "ft_mutex", 1);
								ProtoBroadcastAck((UINT_PTR)local_dcc7->contact, ACKTYPE_FILE, ACKRESULT_FAILED, local_dcc7, 0);
								gg_EnterCriticalSection(&ft_mutex, "dccmainthread", 37, "ft_mutex", 1);
							}

							// Free dcc
							gg_dcc7_free(local_dcc7);
							break;
					}

					// Free event
					gg_free_event(e);
					break;
			}
		}
		gg_LeaveCriticalSection(&ft_mutex, "dccmainthread", 37, 1, "ft_mutex", 1);
	}

	// Close all dcc client sockets
	for (l = watches; l; l = l->next)
	{
		struct gg_common *c = (gg_common*)l->data;
		if (!c) continue;
		if (c->type == GG_SESSION_DCC7_SOCKET || c->type == GG_SESSION_DCC7_SEND || c->type == GG_SESSION_DCC7_GET)
		{
			struct gg_dcc7 *local_dcc7 = (gg_dcc7*)l->data;
			gg_dcc7_free(local_dcc7);
		}
		else
		{
			struct gg_dcc *local_dcc = (gg_dcc*)l->data;
			gg_dcc_socket_free(local_dcc);

			// Check if it's main socket
			if (local_dcc == dcc) dcc = NULL;
		}
	}
	// Close all waiting for aknowledgle transfers
	for (l = transfers; l; l = l->next)
	{
		struct gg_common *c = (gg_common*)l->data;
		if (!c) continue;
		if (c->type == GG_SESSION_DCC7_SOCKET || c->type == GG_SESSION_DCC7_SEND || c->type == GG_SESSION_DCC7_GET)
		{
			struct gg_dcc7 *local_dcc7 = (gg_dcc7*)l->data;
			gg_dcc7_free(local_dcc7);
		}
		else
		{
			struct gg_dcc *local_dcc = (gg_dcc*)l->data;
			gg_dcc_socket_free(local_dcc);
		}
	}
	// Close all waiting dcc requests
	for (l = requests; l; l = l->next)
	{
		struct gg_dcc *local_dcc = (gg_dcc*)l->data;
		if (local_dcc) gg_free_dcc(local_dcc);
	}
	list_destroy(watches, 0);
	list_destroy(transfers, 0);
	list_destroy(requests, 0);

	gg_dcc_port = 0;
	gg_dcc_ip = 0;
	debugLogA("dccmainthread(): end. DCC Server Thread Ending");
}
Example #4
0
void
GaduSession::checkDescriptor()
{
	disableNotifiers();

	struct gg_event* event;
//	struct gg_dcc*   dccSock;
	KGaduMessage	gaduMessage;
	KGaduNotify	gaduNotify;

	if ( !( event = gg_watch_fd( session_ ) ) ) {
		kdDebug(14100)<<"Connection was broken for some reason"<<endl;
		destroyNotifiers();
		logoff( Kopete::Account::ConnectionReset );
		return;
	}

	// FD changed, recreate socket notifiers
	if ( session_->state == GG_STATE_CONNECTING_HUB || session_->state == GG_STATE_CONNECTING_GG ) {
		kdDebug(14100)<<"recreating notifiers"<<endl;
		destroyNotifiers();
		createNotifiers( true );
	}

	switch( event->type ) {
		case GG_EVENT_MSG:
			kdDebug(14100) << "incoming message:class:" << event->event.msg.msgclass << endl;
			if ( event->event.msg.msgclass & GG_CLASS_CTCP ) {
				kdDebug( 14100 ) << "incomming ctcp " << endl;
				// TODO: DCC CONNECTION
				emit incomingCtcp( event->event.msg.sender );
			}

			if ( (event->event.msg.msgclass & GG_CLASS_MSG) || (event->event.msg.msgclass & GG_CLASS_CHAT) ) {
				gaduMessage.message =
					textcodec->toUnicode((const char*)event->event.msg.message);
				gaduMessage.sender_id = event->event.msg.sender;
				gaduMessage.sendTime.setTime_t( event->event.msg.time, Qt::LocalTime );
				gaduMessage.message = rtf->convertToHtml( gaduMessage.message, event->event.msg.formats_length, event->event.msg.formats );
				emit messageReceived( &gaduMessage );
			}
		break;
		case GG_EVENT_ACK:
			emit ackReceived( event->event.ack.recipient );
		break;
		case GG_EVENT_STATUS:
			gaduNotify.status = event->event.status.status;
			gaduNotify.contact_id = event->event.status.uin;
			if ( event->event.status.descr ) {
				gaduNotify.description = textcodec->toUnicode( event->event.status.descr );
			}
			else {
				gaduNotify.description = QString::null;
			}
			gaduNotify.remote_port	= 0;
			gaduNotify.version	= 0;
			gaduNotify.image_size	= 0;
			gaduNotify.time		= 0;
			gaduNotify.fileCap	= false;

			emit contactStatusChanged( &gaduNotify );
		break;
		case GG_EVENT_STATUS60:
			gaduNotify.status	= event->event.status60.status;
			gaduNotify.contact_id	= event->event.status60.uin;
			if ( event->event.status60.descr ) {
				gaduNotify.description = textcodec->toUnicode( event->event.status60.descr );
			}
			else {
				gaduNotify.description = QString::null;
			}
			gaduNotify.remote_ip.setAddress( ntohl( event->event.status60.remote_ip ) );
			gaduNotify.remote_port	= event->event.status60.remote_port;
			gaduNotify.version	= event->event.status60.version;
			gaduNotify.image_size	= event->event.status60.image_size;
			gaduNotify.time		= event->event.status60.time;
			if ( event->event.status60.remote_ip && gaduNotify.remote_port > 10 ) {
				gaduNotify.fileCap = true;
			}
			else {
				gaduNotify.fileCap = false;
			}

			emit contactStatusChanged( &gaduNotify );
		break;
		case GG_EVENT_NOTIFY60:
			notify60( event );
		break;
		case GG_EVENT_CONN_SUCCESS:
			kdDebug(14100) << "success server: " << session_->server_addr << endl;
			emit connectionSucceed();
		break;
		case GG_EVENT_CONN_FAILED:
			kdDebug(14100) << "failed server: " << session_->server_addr << endl;
			destroySession();
			kdDebug(14100) << "emit connection failed(" << event->event.failure << ") signal" << endl;
			emit connectionFailed( (gg_failure_t)event->event.failure );
			break;
		case GG_EVENT_DISCONNECT:
			kdDebug(14100)<<"event Disconnected"<<endl;
			// it should be called either when we requested disconnect, or when other client connects with our UID
			logoff( Kopete::Account::Manual );
		break;
		case GG_EVENT_PONG:
			emit pong();
		break;
		case GG_EVENT_NONE:
			break;
		case GG_EVENT_PUBDIR50_SEARCH_REPLY:
		case GG_EVENT_PUBDIR50_WRITE:
		case GG_EVENT_PUBDIR50_READ:
			sendResult( event->event.pubdir50 );
	        break;
		case GG_EVENT_USERLIST:
			handleUserlist( event );
		break;
		default:
			kdDebug(14100)<<"Unprocessed GaduGadu Event = "<<event->type<<endl;
		break;
	}

	if ( event ) {
		gg_free_event( event );
	}

	if ( session_ ) {
		enableNotifiers( session_->check );
	}
}
Example #5
0
int main(void)
{
	struct gg_login_params p;
	struct gg_session *sess;
	struct timeval tv;
	struct gg_event *e;
	fd_set rd, wd;
	time_t last = 0, now;
	int ret;

#ifdef _WIN32
	gg_win32_init_network();
#endif

	gg_debug_level = ~0;

	memset(&p, 0, sizeof(p));
	p.uin = 123456;
	p.password = "******";
	p.async = 1;

	sess = gg_login(&p);

	if (!sess) {
		printf("gg_login failed.\n");
		return 1;
	}

	for (;;) {
		FD_ZERO(&rd);
		FD_ZERO(&wd);

		if ((sess->check & GG_CHECK_READ))
			FD_SET(sess->fd, &rd);
		if ((sess->check & GG_CHECK_WRITE))
			FD_SET(sess->fd, &wd);

		tv.tv_sec = 1;
		tv.tv_usec = 0;

		ret = select(sess->fd + 1, &rd, &wd, NULL, &tv);

		if (ret == -1) {
			perror("select");
			return 1;
		}

		now = time(NULL);

		if (now != last) {
			if (sess->timeout != -1 && sess->timeout-- == 0 &&
				!sess->soft_timeout)
			{
				printf("Przekroczenie czasu operacji.\n");
				gg_free_session(sess);
				return 1;
			}
		}

		if (sess && (FD_ISSET(sess->fd, &rd) ||
			FD_ISSET(sess->fd, &wd) ||
			(sess->timeout == 0 && sess->soft_timeout)))
		{
			if (!(e = gg_watch_fd(sess))) {
				printf("Połączenie zerwane.\n");
				gg_free_session(sess);
				return 1;
			}

			if (e->type == GG_EVENT_CONN_SUCCESS) {
				printf("Połączono z serwerem.\n");
				gg_free_event(e);
				gg_logoff(sess);
				gg_free_session(sess);
				return 0;
			}

			if (e->type == GG_EVENT_CONN_FAILED) {
				printf("Błąd połączenia.\n");
				gg_free_event(e);
				gg_logoff(sess);
				gg_free_session(sess);
				return 1;
			}

			gg_free_event(e);
		}
	}

	return 1;
}
Example #6
0
int main()
{
	struct gg_login_params p;
	struct gg_session *sess;
	struct timeval tv;
	struct gg_event *e;
	fd_set rd, wd;
	int ret;

	gg_debug_level = ~0;
	
	memset(&p, 0, sizeof(p));
	p.uin = 123456;
	p.password = "******";
	p.async = 1;
	
	sess = gg_login(&p);

	for (;;) {
		FD_ZERO(&rd);
		FD_ZERO(&wd);

		if ((sess->check & GG_CHECK_READ))
			FD_SET(sess->fd, &rd);
		if ((sess->check & GG_CHECK_WRITE))
			FD_SET(sess->fd, &wd);

		tv.tv_sec = 10;
		tv.tv_usec = 0;
		
		ret = select(sess->fd + 1, &rd, &wd, NULL, &tv);
	
		if (!ret) {
			printf("timeout! wypad!\n");
			return 1;
		} else {
			if (sess && (FD_ISSET(sess->fd, &rd) || FD_ISSET(sess->fd, &wd))) {
				if (!(e = gg_watch_fd(sess))) {
					printf("zerfauo pouontshenie!\n");
					return 1;
				}
				if (e->type == GG_EVENT_CONN_SUCCESS) {
					printf("po³±czy³em siê\n");
					gg_free_event(e);
					gg_logoff(sess);
					gg_free_session(sess);
					return 1;
				}
				if (e->type == GG_EVENT_CONN_FAILED) {
					printf("errrror\n");
					gg_free_event(e);
					gg_logoff(sess);
					gg_free_session(sess);
					return 1;
				}
				gg_free_event(e);
			}
		}
	}
	
	return -1;
}
void GaduProtocolSocketNotifiers::socketEvent()
{
    auto e = gg_watch_fd(m_session);
    if (!e || GG_STATE_IDLE == m_session->state)
    {
        if (e && e->type == GG_EVENT_CONN_FAILED)
            handleEventConnFailed(e);
        else
            m_protocol->socketConnFailed(GaduProtocol::ConnectionUnknow);
        return;
    }

    watchFor(m_session);   // maybe fd has changed, we need to check always

    switch (e->type)
    {
    case GG_EVENT_MSG:
        emit msgEventReceived(e);
        break;

    case GG_EVENT_MULTILOGON_MSG:
        emit multilogonMsgEventReceived(e);
        break;

    case GG_EVENT_MULTILOGON_INFO:
        handleEventMultilogonInfo(e);
        break;

    case GG_EVENT_TYPING_NOTIFICATION:
        emit typingNotificationEventReceived(e);
        break;

    case GG_EVENT_NOTIFY:
    case GG_EVENT_NOTIFY_DESCR:
        handleEventNotify(e);
        break;

    case GG_EVENT_NOTIFY60:
        handleEventNotify60(e);
        break;

    case GG_EVENT_STATUS:
    case GG_EVENT_STATUS60:
        handleEventStatus(e);
        break;

    case GG_EVENT_ACK:
        emit ackEventReceived(e);
        break;

    case GG_EVENT_CONN_FAILED:
        handleEventConnFailed(e);
        break;

    case GG_EVENT_CONN_SUCCESS:
        handleEventConnSuccess(e);
        break;

    case GG_EVENT_DISCONNECT:
        handleEventDisconnect(e);
        break;

    case GG_EVENT_PUBDIR50_SEARCH_REPLY:
        m_protocol->CurrentSearchService->handleEventPubdir50SearchReply(e);
    //			break;

    case GG_EVENT_PUBDIR50_READ:
        m_protocol->CurrentPersonalInfoService->handleEventPubdir50Read(e);
        m_protocol->CurrentContactPersonalInfoService->handleEventPubdir50Read(e);
    //			break;

    case GG_EVENT_PUBDIR50_WRITE:
        m_protocol->CurrentPersonalInfoService->handleEventPubdir50Write(e);
        break;

    case GG_EVENT_IMAGE_REQUEST:
        m_protocol->CurrentChatImageService->handleEventImageRequest(e);
        break;

    case GG_EVENT_IMAGE_REPLY:
        m_protocol->CurrentChatImageService->handleEventImageReply(e);
        break;

    case GG_EVENT_USERLIST100_VERSION:
        static_cast<GaduRosterService *>(m_protocol->rosterService())->handleEventUserlist100Version(e);
        break;

    case GG_EVENT_USERLIST100_REPLY:
        static_cast<GaduRosterService *>(m_protocol->rosterService())->handleEventUserlist100Reply(e);
        break;

    case GG_EVENT_USER_DATA:
        m_userDataService->handleUserDataEvent(e->event.user_data);
        break;

    case GG_EVENT_IMTOKEN:
        m_imTokenService->setIMToken(e->event.imtoken.imtoken);
        break;
    }

    gg_free_event(e);
}
Example #8
0
int main(int argc, char **argv)
{

   // Do po³±czenia
   struct gg_session *sess;
   struct gg_event *e;
   struct gg_login_params p;
   list_t searches = NULL;

   char *last_search_first_name = NULL;
   char *last_search_last_name = NULL;
   char *last_search_nickname = NULL;
   uin_t last_search_uin = 0;

   gg_pubdir50_t res;
   // Do wyszukiwania
   char *user;
   gg_pubdir50_t req;
   int i, all = 0;

   if (argc < 4) {
      fprintf(stderr, "Usage: %s <my_uid> <my_password> <params>\n\n", argv[0]);
      fprintf(stderr, "Parameters:\n");
      fprintf(stderr, " -f <val> (--first)     - first name\n");
      fprintf(stderr, " -l <val> (--last)      - last name\n");
      fprintf(stderr, " -n <val> (--nickname)  - nickname\n");
      fprintf(stderr, " -c <val> (--city)      - city\n");
      fprintf(stderr, " -u <val> (--uin)       - user ID\n");
      fprintf(stderr, " -F       (--female)    - search females only\n");
      fprintf(stderr, " -M       (--male)      - search males only\n");
      fprintf(stderr, " -a       (--active)    - search on-line users only\n");
      fprintf(stderr, " -b <val> (--born)      - year of birth\n");
      fprintf(stderr, " -s <val> (--start)     - search offset\n");
      fprintf(stderr, " -A       (--all)       - show all\n");
      return 1;
   }

   // Poziom debugowania
   gg_debug_level = 5;

   memset(&p, 0, sizeof(p));
   p.uin = atoi(argv[1]);
   p.password = argv[2];


   // Po³±czenie

   if (!(sess = gg_login(&p))) {
      printf("Connection failed: %s\n", strerror(errno));
      gg_free_session(sess);
      return 1;
   }

   printf("Po³±czono.\n");

   // Wyszukiwanie

   if (!sess || sess->state != GG_STATE_CONNECTED) {
      printf("not_connected\n");
      return 1;
   }

   argv = argv + 3;

   // próba odpalenia trybu szukania konkretnego usera
   user = strdup(argv[0]);

   // Konwersja do CP
   for (i = 0; argv[i]; i++) {
      iso_to_cp(argv[i]);
   }

   // Zapytanie
   if (!(req = gg_pubdir50_new(GG_PUBDIR50_SEARCH))) {
      printf("\n");
      return 1;
   }

   // wyszukiwanie UIN
   if (argv[0] && argv[0][0] != '-') {
      uin_t uin = get_uin(user);

      if (!uin) {
	 printf("User not found (%s)\n", user);
	 return 1;
      }

      gg_pubdir50_add(req, GG_PUBDIR50_UIN, itoa(uin));
      i = 1;

   } else {
      i = 0;
   }

   free(user);

   // Parsowanie argumentów
   for (; argv[i]; i++) {
      char *arg = argv[i];

      if (match_arg(arg, 'f', "first", 2) && argv[i + 1]) {
	 gg_pubdir50_add(req, GG_PUBDIR50_FIRSTNAME, argv[++i]);
	 continue;
      }

      if (match_arg(arg, 'l', "last", 2) && argv[i + 1]) {
	 gg_pubdir50_add(req, GG_PUBDIR50_LASTNAME, argv[++i]);
	 continue;
      }

      if (match_arg(arg, 'n', "nickname", 2) && argv[i + 1]) {
	 gg_pubdir50_add(req, GG_PUBDIR50_NICKNAME, argv[++i]);
	 continue;
      }

      if (match_arg(arg, 'c', "city", 2) && argv[i + 1]) {
	 gg_pubdir50_add(req, GG_PUBDIR50_CITY, argv[++i]);
	 continue;
      }

      if (match_arg(arg, 'u', "uin", 2) && argv[i + 1]) {
	 gg_pubdir50_add(req, GG_PUBDIR50_UIN, itoa(get_uin(argv[++i])));
	 continue;
      }

      if (match_arg(arg, 's', "start", 3) && argv[i + 1]) {
	 gg_pubdir50_add(req, GG_PUBDIR50_START, argv[++i]);
	 continue;
      }

      if (match_arg(arg, 'F', "female", 2)) {
	 gg_pubdir50_add(req, GG_PUBDIR50_GENDER, GG_PUBDIR50_GENDER_FEMALE);
	 continue;
      }

      if (match_arg(arg, 'M', "male", 2)) {
	 gg_pubdir50_add(req, GG_PUBDIR50_GENDER, GG_PUBDIR50_GENDER_MALE);
	 continue;
      }

      if (match_arg(arg, 'a', "active", 2)) {
	 gg_pubdir50_add(req, GG_PUBDIR50_ACTIVE, GG_PUBDIR50_ACTIVE_TRUE);
	 continue;
      }

      if (match_arg(arg, 'b', "born", 2) && argv[i + 1]) {
	 char *foo = strchr(argv[++i], ':');

	 if (foo)
	    *foo = ' ';

	 gg_pubdir50_add(req, GG_PUBDIR50_BIRTHYEAR, argv[i]);
	 continue;
      }

      if (match_arg(arg, 'A', "all", 3)) {
	 if (!gg_pubdir50_get(req, 0, GG_PUBDIR50_START))
	    gg_pubdir50_add(req, GG_PUBDIR50_START, "0");
	 all = 1;
	 continue;
      }

      printf("invalid_params\n");

      gg_pubdir50_free(req);

      return 1;
   }

   // Wywo³anie wyszukiwania

   if (!gg_pubdir50(sess, req)) {
      printf("Search failed\n");
      return 1;
   }

   // Dodanie wyniku wyszykiwania do listy
   if (all) {
      list_add(&searches, req, 0);
   } else {
      gg_pubdir50_free(req);
   }

   // Pêtla czekaj±ca na wynik wyszukiwania
   while (1) {
      if (!(e = gg_watch_fd(sess))) {
	 printf("Connection interrupted: %s\n", strerror(errno));
	 gg_logoff(sess);
	 gg_free_session(sess);
	 return 1;
      }

      if (e->type == GG_EVENT_PUBDIR50_SEARCH_REPLY) {
         printf("Received results!\n");
         res = e->event.pubdir50;
         all = i = 0;
         int count, all = 0;
         list_t l;
         uin_t last_uin = 0;

         if ((count = gg_pubdir50_count(res)) < 1) {
            printf("search_not_found\n");
            return 1;
         }

         gg_debug(GG_DEBUG_MISC, "handle_search50, count = %d\n", gg_pubdir50_count(res));

         for (l = searches; l; l = l->next) {
            gg_pubdir50_t req = l->data;

            if (gg_pubdir50_seq(req) == gg_pubdir50_seq(res)) {
               all = 1;
               break;
            }
         }

         for (i = 0; i < count; i++) {
            const char *__fmnumber = gg_pubdir50_get(res, i, "fmnumber");
            const char *uin = (__fmnumber) ? __fmnumber : "?";

            const char *__firstname = gg_pubdir50_get(res, i, "firstname");
            char *firstname = strdup((__firstname) ? __firstname : "");

            const char *__lastname = gg_pubdir50_get(res, i, "lastname");
            char *lastname = strdup((__lastname) ? __lastname : "");

            const char *__nickname = gg_pubdir50_get(res, i, "nickname");
            char *nickname = strdup((__nickname) ? __nickname : "");

            const char *__fmstatus = gg_pubdir50_get(res, i, "fmstatus");
            int status = (__fmstatus) ? atoi(__fmstatus) : GG_STATUS_NOT_AVAIL;

            const char *__birthyear = gg_pubdir50_get(res, i, "birthyear");
            const char *birthyear = (__birthyear && strcmp(__birthyear, "0")) ? __birthyear : "-";

            const char *__city = gg_pubdir50_get(res, i, "city");
            char *city = strdup((__city) ? __city : "");

            char *name, *active;

            const char *target = NULL;

            cp_to_iso(firstname);
            cp_to_iso(lastname);
            cp_to_iso(nickname);
            cp_to_iso(city);

            if (count == 1 && !all) {
               free(last_search_first_name);
               free(last_search_last_name);
               free(last_search_nickname);
               last_search_first_name = strdup(firstname);
               last_search_last_name = strdup(lastname);
               last_search_nickname = strdup(nickname);
               last_search_uin = atoi(uin);
            }

            name = saprintf("%s %s", firstname, lastname);

            switch (status & 0x7f) {
               case GG_STATUS_AVAIL:
               case GG_STATUS_AVAIL_DESCR:
                  active = strdup("Avail");
                  break;
               case GG_STATUS_BUSY:
               case GG_STATUS_BUSY_DESCR:
                  active = strdup("Busy");
                  break;
               case GG_STATUS_INVISIBLE:
               case GG_STATUS_INVISIBLE_DESCR:
                  active = strdup("Invis");
                  break;
               default:
                  active = strdup("Inact");
            }

            printf("UIN\t: %s\n", uin);
            printf("Name\t: %s\n", name);
            printf("Nick\t: %s\n", nickname);
            printf("City\t: %s\n", city);
            printf("Birth\t: %s\n", birthyear);
            printf("Active\t: %s\n\n", active);

            free(name);
            free(active);

            free(firstname);
            free(lastname);
            free(nickname);
            free(city);

            last_uin = atoi(uin);
         }

         /* je¶li mieli¶my ,,/find --all'', szukamy dalej */
         for (l = searches; l; l = l->next) {
            gg_pubdir50_t req = l->data;
            uin_t next;

            if (gg_pubdir50_seq(req) != gg_pubdir50_seq(res))
               continue;

            /* nie ma dalszych? to dziêkujemy */
            if (!(next = gg_pubdir50_next(res)) || !sess || next < last_uin) {
               list_remove(&searches, req, 0);
               gg_pubdir50_free(req);
               break;
            }

            gg_pubdir50_add(req, GG_PUBDIR50_START, itoa(next));
            gg_pubdir50(sess, req);

            break;
         }
	 gg_free_event(e);
	 break;
      }

      gg_free_event(e);
   }

   gg_logoff(sess);
   gg_free_session(sess);

   return 0;
}
gboolean
gnomegadu_protocol_loop (GIOChannel * source, GIOCondition condition, gpointer data)
{
	static gint prev_check = GG_CHECK_READ;
	gboolean ret = TRUE;
	struct gg_event *e = NULL;

	/* w przypadku bledu/utraty polaczenia postap tak jak w przypadku disconnect */
	if (!gnomegadu_gadugadu_session || !(e = gg_watch_fd (gnomegadu_gadugadu_session)) || (condition & G_IO_ERR) ||
	    ((condition & G_IO_HUP)
	     && ((gnomegadu_gadugadu_session->state != GG_STATE_CONNECTING_GG) && (gnomegadu_gadugadu_session->check != GG_CHECK_WRITE))))
	{
		g_printerr ("gnomegadu_protocol_loop(): some kind of problem while processing\n");
		gnomegadu_gadugadu_disconnect ();
		prev_check = GG_CHECK_READ;
		return FALSE;
	}

	switch (e->type)
	{
	case GG_EVENT_NONE:
		g_print ("GG_EVENT_NONE\n");
		break;

	case GG_EVENT_PONG:
		g_print ("GG_EVENT_PONG\n");
		gg_ping (gnomegadu_gadugadu_session);
		break;

	case GG_EVENT_CONN_FAILED:
		g_print ("GG_EVENT_CONN_FAILED\n");
		gnomegadu_gadugadu_disconnect ();
		ret = FALSE;
		break;

	case GG_EVENT_DISCONNECT:
		g_print ("GG_EVENT_DISCONNECT\n");
		gnomegadu_gadugadu_disconnect ();
		ret = FALSE;
		break;

	case GG_EVENT_CONN_SUCCESS:
	{
		g_print ("GG_EVENT_CONN_SUCCESS\n");
		//wysyłam swoją listę
		gint i, j = 0;
		uint32_t *uins;
		GSList *contacts_list = gnomegadu_conf_get_contacts ();
		GSList *contacts_list_start = contacts_list;

		gnomegadu_protocol_is_connected = TRUE;

		if (!contacts_list)
			break;

		i = g_slist_length (contacts_list);
		uins = g_malloc0 (i * sizeof (uint32_t));
		while (contacts_list)
		{
			gchar *uin_str;
			gchar *path = (gchar *) contacts_list->data;
			gchar *uin_path = g_strconcat (path, "/uin", NULL);
			uin_str = gconf_client_get_string (gconf, uin_path, NULL);
			uins[j++] = g_strtod (uin_str, NULL);

			g_free (uin_path);
			contacts_list = g_slist_next(contacts_list);
		}

		if (j > 0)
			gg_notify (gnomegadu_gadugadu_session, uins, i);

		/* pingpong */
		g_timeout_add(100000, gnomegadu_protocol_ping, NULL);


		g_slist_foreach (contacts_list_start, gnomegadu_conf_free_list_of_string, NULL);
		g_slist_free (contacts_list_start);
		g_free (uins);
	}
		break;

//      case GG_EVENT_NOTIFY_DESCR:
	case GG_EVENT_NOTIFY:
	{
		gint i;
		g_print ("GG_EVENT_NOTIFY\n");

		for (i = 0; e->event.notify[i].uin; i++)
		{
			gchar *uin_str = g_strdup_printf ("%d", e->event.notify[i].uin);
			gint new_status = gnomegadu_gadugadu_from_protocol_status (e->event.notify[i].status);
			gnomegadu_userlist_set_model_status (uin_str, new_status, NULL);	//tutaj dodac obsluge opisów
			g_free (uin_str);
		}
	}
		break;
	case GG_EVENT_NOTIFY60:
	{
		gint i;
		g_print ("GG_EVENT_NOTIFY60\n");

		for (i = 0; e->event.notify60[i].uin; i++)
		{
			gchar *descr_utf = NULL;
			gchar *uin_str = g_strdup_printf ("%d", e->event.notify60[i].uin);
			gint new_status = gnomegadu_gadugadu_from_protocol_status (e->event.notify60[i].status);

			if (e->event.notify60[i].descr)
				descr_utf =
					g_convert (e->event.notify60[i].descr, strlen (e->event.notify60[i].descr), "UTF-8", "WINDOWS-1250", NULL, NULL, NULL);

			gnomegadu_userlist_set_model_status (uin_str, new_status, descr_utf);
			g_free (uin_str);
		}
	}
	break;
	case GG_EVENT_STATUS:
	case GG_EVENT_STATUS60:
	{
		GdkPixbuf *pix = NULL;
		gchar *descr_utf = NULL;
		gchar *uuid = NULL;
		gchar *display = NULL;
		gchar *notify_txt = NULL;
		gint new_status;
		gchar *uin_str  = NULL; 
		
		if (e->type == GG_EVENT_STATUS)
		{
		    new_status = gnomegadu_gadugadu_from_protocol_status (e->event.status.status);
		    uin_str    = g_strdup_printf ("%d", e->event.status.uin);

		    if (e->event.status.descr)
			descr_utf = g_convert (e->event.status.descr, strlen (e->event.status.descr), "UTF-8", "WINDOWS-1250", NULL, NULL, NULL);

		} else {
		    new_status = gnomegadu_gadugadu_from_protocol_status (e->event.status60.status);
		    uin_str    = g_strdup_printf ("%d", e->event.status60.uin);

		    if (e->event.status60.descr)
			descr_utf = g_convert (e->event.status60.descr, strlen (e->event.status60.descr), "UTF-8", "WINDOWS-1250", NULL, NULL, NULL);

		}
		
		gnomegadu_userlist_set_model_status (uin_str, new_status, descr_utf);

		uuid = gnomegadu_conf_contact_get_uuid_for_uin(uin_str);
		display = gnomegadu_conf_contact_get_display_for_uuid(uuid);

		pix = gnomegadu_stock_get_pixbuf (gnomegadu_ui_status_get_icon_name (new_status));
		notify_txt = g_strdup_printf("Status: %s\n<span size=\"smaller\" style=\"italic\">%s</span>",gnomegadu_protocol_status_txt(new_status),descr_utf ? descr_utf : "");
		gnomegadu_ui_notify_show (display, notify_txt, pix);
		g_object_unref (pix);
		
		gnomegadu_tray_blinking(2000);

		g_free (notify_txt);
		g_free (display);
		g_free (uuid);
		g_free (uin_str);
	}    
	break;
	case GG_EVENT_USERLIST:
	{
		g_print ("GG_EVENT_USERLIST\n");
		if (e->event.userlist.type == GG_USERLIST_GET_REPLY)
		{
			gint i;
			gfloat step;
			gchar **split_buf = NULL;
			GtkWidget *progress = glade_xml_get_widget (gladexml_import_userlist_progress, "ImportUserlistServerProgress");
			GtkWidget *progress_window = glade_xml_get_widget (gladexml_import_userlist_progress, "ImportUserlistServerProgressWindow");

			if (!progress_window || !progress)
				break;

			gchar *buf = e->event.userlist.reply;
			if (!buf)
			{
				gtk_widget_destroy(GTK_WIDGET(progress_window));
				
				GtkDialog *msgdialog = gtk_message_dialog_new_with_markup (NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
											   "<span weight=\"bold\"size=\"larger\">Lista jest pusta</span>\n\nLista kontaktów na serwerze jest pusta.");
				gtk_dialog_run (GTK_DIALOG (msgdialog));
				gtk_widget_destroy (GTK_WIDGET (msgdialog));
				break;
			}

			GConfChangeSet *changeset = gconf_change_set_new();

			split_buf = g_strsplit (buf, "\r\n", 2048);
			step = 1 / (gfloat)g_strv_length (split_buf);
			for (i = 0; i < g_strv_length (split_buf); i++)
			{
				gdouble percentage = gtk_progress_bar_get_fraction(GTK_PROGRESS_BAR (progress));
				
				if (percentage < 1)
					gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress), percentage + step);
				
				while (g_main_context_pending(NULL))
					g_main_context_iteration(NULL,TRUE);

				gnomegadu_ui_import_userlist_process_line (split_buf[i], changeset);
				
				if (!gconf_client_commit_change_set(gconf, changeset, TRUE, NULL))
					g_printerr("Some error while import");
			}

			gconf_change_set_unref(changeset);

			gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress), 1);
			
			while (g_main_context_pending(NULL))
				g_main_context_iteration(NULL,TRUE);
			
			gtk_widget_destroy(GTK_WIDGET(progress_window));
		}

	}
	break;
	case GG_EVENT_MSG:
	{
		gchar *uin_sender = NULL;
		
		if (e->event.msg.msgclass == GG_CLASS_CHAT)
		{
			gint i      = 0;
			uin_sender  = g_strdup_printf("%d", e->event.msg.sender);
			gchar *txt  = g_strdup((gchar *)e->event.msg.message);
			gchar *txt_utf = NULL;
			GList *list = NULL;

			g_print("message from sender: (%s):%s\n",uin_sender,txt);
			
			/* first add sender */
			list 	  = g_list_append(list,g_strdup(uin_sender));

			if (e->event.msg.recipients_count > 0)
			{
				gchar *uin_str_2 = NULL;
				/* then add recipients */
				for (i = 0; i < e->event.msg.recipients_count; i++)
				{
				    uin_str_2 = g_strdup_printf("%d",e->event.msg.recipients[i]);
				    list = g_list_append(list,g_strdup(uin_str_2));
				    g_free(uin_str_2);

				    g_print("conference(%d): %s\n",e->event.msg.recipients_count,uin_str_2);
				}
			}

			g_assert(list);
			
			//chat window
			GladeXML *chat_window_xml = gnomegadu_ui_chat_find(list,TRUE);
			g_assert(chat_window_xml);

			txt_utf = g_convert (txt, strlen (txt), "UTF-8", "WINDOWS-1250", NULL, NULL, NULL);
			gnomegadu_ui_chat_append_text(chat_window_xml,txt_utf,GNOMEGADU_CHAT_RCV, uin_sender);

			g_free(txt);
			g_free(uin_sender);			
		}
	}
	break;

	}

	gg_free_event (e);

	if (gnomegadu_gadugadu_session && prev_check != gnomegadu_gadugadu_session->check)
	{
		prev_check = gnomegadu_gadugadu_session->check;

		if (gnomegadu_gadugadu_session->check == GG_CHECK_READ)
		{
			g_source_remove (gnomegadu_watch_protocol);
			gnomegadu_watch_protocol = g_io_add_watch (gnomegadu_source_chan, G_IO_IN | G_IO_ERR | G_IO_HUP, gnomegadu_protocol_loop, NULL);
			ret = FALSE;
		}

		if (gnomegadu_gadugadu_session->check == GG_CHECK_WRITE)
		{
			g_source_remove (gnomegadu_watch_protocol);
			gnomegadu_watch_protocol = g_io_add_watch (gnomegadu_source_chan, G_IO_OUT | G_IO_ERR | G_IO_HUP, gnomegadu_protocol_loop, NULL);
			ret = FALSE;
		}
	}

	return ret;
}