Beispiel #1
0
gg_event* GGWrapper::pollGGEvent()
{
    if(!mpSession) return 0;
    fd_set rd, wd;
    FD_ZERO(&rd);
    FD_ZERO(&wd);
    timeval tv;
    tv.tv_sec = 0;
    tv.tv_usec = 0.05;
    if ((mpSession->check & GG_CHECK_READ))
            FD_SET(mpSession->fd, &rd);
    if ((mpSession->check & GG_CHECK_WRITE))
            FD_SET(mpSession->fd, &wd);

    select(mpSession->fd + 1,&rd,&wd,NULL,&tv);

    if(FD_ISSET(mpSession->fd, &rd) || FD_ISSET(mpSession->fd, &wd))
    {
        return gg_watch_fd(mpSession);
    }
    else
    {
        return 0;
    }
}
Beispiel #2
0
int main(int argc, char **argv)
{
	struct gg_session *gs;
	struct gg_login_params glp;
	struct gg_dcc7 *gd = NULL;
	time_t ping = 0, last = 0;
	int once = 0;

	if (argc != 2)
		usage(argv[0]);

/* strtol() ? */
	if (!(argv[1][0] >= '0' && argv[1][0] <= '9'))
		usage(argv[0]);

	if (atoi(argv[1]) >= TEST_MODE_LAST)
		usage(argv[0]);

	test_mode = atoi(argv[1]);

	signal(SIGPIPE, SIG_IGN);
	gg_debug_file = stdout;
	gg_debug_level = ~0;

	if (config_read() == -1 || config_peer == 0) {
		perror("config");
		exit(1);
	}

	memset(&glp, 0, sizeof(glp));
	glp.uin = config_uin;
	glp.password = config_password;
	glp.async = 1;
	glp.status = GG_STATUS_AVAIL;
#if 0
	glp.client_addr = config_ip;
	glp.client_port = config_port;
#endif
	glp.protocol_version = 0x2a;
	glp.has_audio = 1;
	glp.last_sysmsg = -1;

	gg_dcc_ip = config_ip;

	debug("Connecting...\n");

	if (!(gs = gg_login(&glp))) {
		perror("gg_login");
		exit(1);
	}

	for (;;) {
		fd_set rds, wds;
		struct timeval tv;
		time_t now;
		int res, maxfd = -1;

		FD_ZERO(&rds);
		FD_ZERO(&wds);

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

		maxfd = gs->fd;

		if ((gs->check & GG_CHECK_READ))
			FD_SET(gs->fd, &rds);

		if ((gs->check & GG_CHECK_WRITE))
			FD_SET(gs->fd, &wds);

		if (gd && gd->fd != -1) {
			if (gd->fd > maxfd)
				maxfd = gd->fd;

			if ((gd->check & GG_CHECK_READ))
				FD_SET(gd->fd, &rds);

			if ((gd->check & GG_CHECK_WRITE))
				FD_SET(gd->fd, &wds);
		}

		if (voice_fd != -1) {
			FD_SET(voice_fd, &rds);

			if (voice_fd > maxfd)
				maxfd = voice_fd;
		}

		if ((res = select(maxfd + 1, &rds, &wds, NULL, &tv)) == -1) {
			if (errno == EINTR)
				continue;

			perror("select");
			exit(1);
		}

		now = time(NULL);

		if (last != now) {
			if (gs->timeout != -1 && gs->timeout-- == 0 && !gs->soft_timeout) {
				debug("Timeout\n");
				exit(1);
			}
				/* vvvv XXX */
			if (gd && gd->timeout && gd->timeout != -1 && gd->timeout-- == 0 && !gd->soft_timeout) {
				debug("Timeout\n");
				exit(1);
			}

			last = now;
		}

		if (gs->state == GG_STATE_CONNECTED && ping && now - ping > 60) {
			ping = now;
			gg_ping(gs);
		}

		if (FD_ISSET(gs->fd, &rds) || FD_ISSET(gs->fd, &wds) || (gs->timeout == 0 && gs->soft_timeout)) {
			struct gg_event *ge;
			uin_t uin;
			int status;

			if (!(ge = gg_watch_fd(gs))) {
				debug("Connection broken\n");
				exit(1);
			}

			switch (ge->type) {
				case GG_EVENT_CONN_SUCCESS:
					debug("Connected\n");
					connected = 1;
					gg_notify(gs, &config_peer, 1);

					ping = time(NULL);

					break;

				case GG_EVENT_CONN_FAILED:
					debug("Connection failed\n");
					exit(1);

				case GG_EVENT_NONE:
					break;

				case GG_EVENT_MSG:
					debug("Message from %d: %s\n", ge->event.msg.sender, ge->event.msg.message);
					break;

				case GG_EVENT_DISCONNECT:
					debug("Forced to disconnect\n");
					exit(1);

				case GG_EVENT_NOTIFY60:
					uin = ge->event.notify60[0].uin;
					status = ge->event.notify60[0].status;
					/* fall-through */

				case GG_EVENT_STATUS60:
					if (ge->type == GG_EVENT_STATUS60) {
						uin = ge->event.status60.uin;
						status = ge->event.status60.status;
					}

					if (!once && uin == config_peer && (GG_S_A(status) ||
						GG_S_B(status)) && test_mode == TEST_MODE_SEND)
					{
						debug("Sending voice request...\n");

						if (voice_open_ext("/dev/dsp", 8000, 16, 2, EKG_CODEC_GSM) == -1) {
							printf("voice_open_ext('/dev/dsp', "
								"8000, 16, 2, CODEC_GSM) failed\n");
							exit(1);
						}
						printf("+OK\n");

						gd = gg_dcc7_voice_chat(gs, config_peer, 0x00);

						if (!gd) {
							perror("gg_dcc7_voice_chat");
							exit(1);
						}
						once = 1;
					}

					gg_change_status(gs, GG_STATUS_AVAIL);	/* XXX, libgadu sobie nie radzi */

					break;

				case GG_EVENT_DCC7_NEW:
					debug("Incoming direct connection\n");

					if (test_mode == TEST_MODE_RECEIVE) {
						gd = ge->event.dcc7_new;

						if (voice_open_ext("/dev/dsp", 8000, 16, 2, EKG_CODEC_GSM) == -1) {
							printf("voice_open_ext('/dev/dsp', "
								"8000, 16, 2, CODEC_GSM) failed\n");
							exit(1);
						}
						printf("+OK\n");

						gg_dcc7_accept_voice(gd, 0x00);
					}

					break;

				case GG_EVENT_DCC7_ERROR:
					debug("Direct connection error\n");
					exit(1);

				case GG_EVENT_DCC7_ACCEPT:
					debug("Accepted\n");
					break;

				case GG_EVENT_DCC7_REJECT:
					debug("Rejected\n");
					exit(1);

				default:
					debug("Unsupported event %d\n", ge->type);
					break;
			}

			gg_event_free(ge);
		}

		if (gd && gd->fd != -1 && (FD_ISSET(gd->fd, &rds) ||
			FD_ISSET(gd->fd, &wds) || (gd->timeout == 0 && gd->soft_timeout)))
		{
			struct gg_event *ge;

			if (!(ge = gg_dcc7_watch_fd(gd))) {
				debug("Direct connection broken\n");
				exit(1);
			}

			switch (ge->type) {
				case GG_EVENT_DCC7_ERROR:
					debug("Direct connection error\n");
					exit(1);

				case GG_EVENT_DCC7_CONNECTED:
					debug("Direct connection established\n");
					break;

				case GG_EVENT_DCC7_DONE:
					debug("Finished");
					gg_event_free(ge);
					gg_dcc7_free(gd);
					gg_free_session(gs);
					config_free();
					exit(1);

				case GG_EVENT_DCC7_VOICE_DATA:
					gg_debug(GG_DEBUG_MISC,
						"## GG_EVENT_DCC7_VOICE_DATA [%u]\n",
						ge->event.dcc7_voice_data.length);
					printf("## GG_EVENT_DCC7_VOICE_DATA [%u]\n",
						ge->event.dcc7_voice_data.length);

					if (voice_fd == -1) {
						printf("voice_fd == -1\n");
						exit(1);
					}

					if (ge->event.dcc7_voice_data.length == GG_DCC7_VOICE_FRAME_GSM_LENGTH)
						voice_play(ge->event.dcc7_voice_data.data,
							ge->event.dcc7_voice_data.length, EKG_CODEC_GSM);
					else if (ge->event.dcc7_voice_data.length == GG_DCC7_VOICE_FRAME_SPEEX_LENGTH)
						voice_play(ge->event.dcc7_voice_data.data,
							ge->event.dcc7_voice_data.length, EKG_CODEC_SPEEX);
					else if (ge->event.dcc7_voice_data.length == GG_DCC7_VOICE_FRAME_MELP_LENGTH)
						voice_play(ge->event.dcc7_voice_data.data,
							ge->event.dcc7_voice_data.length, EKG_CODEC_MELP);
					break;

				case GG_EVENT_NONE:
					break;

				default:
					debug("Unsupported event %d\n", ge->type);
					break;
			}

			gg_event_free(ge);
		}

		if (voice_fd != -1 && FD_ISSET(voice_fd, &rds)) {
			char buf[GG_DCC_VOICE_FRAME_LENGTH];	/* dłuższy z buforów */
			int length = GG_DCC_VOICE_FRAME_LENGTH;

			if (gd) {
				if (gd->state == GG_STATE_READING_VOICE_DATA) {
					/* XXX, implementowac speex */
					length = GG_DCC7_VOICE_FRAME_GSM_LENGTH;
					voice_record(buf, length, EKG_CODEC_GSM);

					if (1)
						gg_dcc7_voice_send(gd, buf, length);
					else {
						/* ten pakiet mamy wysylac co 1s */
						gg_dcc7_voice_mic_off(gd);
					}

				} else
					voice_record(buf, length, EKG_CODEC_NONE);
			} else
				voice_record(buf, length, EKG_CODEC_NONE);
		}
	}

	if (gg_debug_file != stdout)	/* w sumie stdout, tez moglibysmy zamknac.. czemu nie. */
		fclose(gg_debug_file);

	return 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 );
	}
}
Beispiel #4
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;
}
Beispiel #5
0
int main(int argc, char **argv)
{
	struct gg_login_params glp;
	struct gg_session *gs;
	time_t last = 0;
	int hide_sysmsg = 0;
	int ch;

	gg_debug_level = 255;
	
	memset(&glp, 0, sizeof(glp));
	glp.async = 1;

	config_read();

	while ((ch = getopt(argc, argv, "DShHLs:p:l:y")) != -1) {
		switch (ch) {
			case 'D':
				gg_debug_level = 0;
				break;

			case 'S':
				glp.async = 0;
				break;

			case 'L':
				glp.tls = 1;
				break;

			case 's':
				free(config_server);
				config_server = strdup(optarg);
				break;

			case 'p':
				free(config_proxy);
				config_proxy = strdup(optarg);
				break;

			case 'H':
				gg_proxy_http_only = 1;
				break;

			case 'l':
				glp.last_sysmsg = atoi(optarg);
				break;

			case 'h':
				usage(argv[0]);
				return 0;

			case 'y':
				hide_sysmsg = 1;
				break;

			default:
				usage(argv[0]);
				return 1;
		}
	}

	if (argc - optind >= 1) {
		config_uin = atoi(argv[optind]);
		optind++;

		if (argc - optind >= 1) {
			free(config_password);
			config_password = strdup(argv[optind]);
		}
	}

	if (config_uin == 0 || config_password == NULL) {
		usage(argv[0]);
		return 1;
	}

	if (config_server != NULL) {
		char *host;
		int port;

		parse_address(config_server, &host, &port);
		glp.server_addr = inet_addr(host);
		glp.server_port = port;
		free(host);
	}

	if (config_proxy != NULL) {
		char *host;
		int port;

		parse_address(optarg, &host, &port);
		gg_proxy_enabled = 1;
		gg_proxy_host = host;
		gg_proxy_port = port;
		free(config_proxy);
	}

	glp.uin = config_uin;
	glp.password = config_password;

	signal(SIGINT, sigint);

	gs = gg_login(&glp);

	if (gs == NULL) {
		perror("gg_login");
		free(gg_proxy_host);
		return 1;
	}

	for (;;) {
		struct timeval tv;
		fd_set rd, wd;
		int ret, fd, check;
		time_t now;

		if (disconnect_flag) {
			gg_change_status(gs, GG_STATUS_NOT_AVAIL);
			disconnect_flag = 0;
		}

		FD_ZERO(&rd);
		FD_ZERO(&wd);

		fd = gs->fd;
		check = gs->check;

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

		tv.tv_sec = 1;
		tv.tv_usec = 0;
		
		ret = select(fd + 1, &rd, &wd, NULL, &tv);

		if (ret == -1) {
			if (errno == EINTR)
				continue;
			perror("select");
			break;
		}

		now = time(NULL);

		if (now != last) {
			if (gs->timeout != -1 && gs->timeout-- == 0 && !gs->soft_timeout) {
				printf("Timeout!\n");
				break;
			}
		}
	
		if (gs != NULL && (FD_ISSET(fd, &rd) || FD_ISSET(fd, &wd) || (gs->timeout == 0 && gs->soft_timeout))) {
			struct gg_event *ge;

			ge = gg_watch_fd(gs);

			if (ge == NULL) {
				printf("Connection broken!\n");
				break;
			}

			if (ge->type == GG_EVENT_CONN_SUCCESS) {
				printf("Connected (press Ctrl-C to disconnect)\n");
				gg_notify(gs, NULL, 0);
			}

			if (ge->type == GG_EVENT_CONN_FAILED) {
				printf("Connection failed!\n");
				gg_event_free(ge);
				break;
			}

			if (ge->type == GG_EVENT_DISCONNECT_ACK) {
				printf("Connection closed\n");
				gg_event_free(ge);
				break;
			}

			if (ge->type == GG_EVENT_MSG) {
				if (ge->event.msg.sender != 0 || !hide_sysmsg)
					printf("Received message from %d:\n- plain text: %s\n- html: %s\n", ge->event.msg.sender, ge->event.msg.message, ge->event.msg.xhtml_message);
			}

			gg_event_free(ge);
		}
	}

	free(gg_proxy_host);
	
	gg_free_session(gs);

	config_free();

	return 0;
}
Beispiel #6
0
static int test(int resolver, int delay)
{
	struct gg_session *gs;
	struct gg_login_params glp;
	int loops = 0;

	delay_flag = delay;
	connect_flag = 0;

	memset(&glp, 0, sizeof(glp));
	glp.uin = 1;
	glp.password = "";
	glp.resolver = resolver;
	glp.async = 1;

	gs = gg_login(&glp);

	if (gs == NULL)
		return 0;

	if (!delay_flag) {
		for (loops = 0; loops < 5; loops++) {
			struct gg_event *ge;
			struct timeval tv;
			fd_set fds;

			FD_ZERO(&fds);
			FD_SET(gs->fd, &fds);

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

			if (select(gs->fd + 1, &fds, NULL, NULL, &tv) == -1) {
				if (errno == EAGAIN)
					continue;

				gg_free_session(gs);

				return 0;
			}

			ge = gg_watch_fd(gs);

			if (ge == NULL) {
				gg_free_session(gs);
				return 0;
			}

			if (ge->type == GG_EVENT_CONN_FAILED) {
				gg_event_free(ge);
				gg_free_session(gs);
				return 0;
			}

			if (gs->hub_addr != 0 && gs->hub_addr != inet_addr(LOCALHOST)) {
				struct in_addr hub_addr;
				hub_addr.s_addr = gs->hub_addr;
				printf("gethostbyname hook failed %s != %s\n",
					LOCALHOST, inet_ntoa(hub_addr));
				gg_event_free(ge);
				gg_free_session(gs);
				return 0;
			}

			gg_event_free(ge);

			if (connect_flag == 1)
				break;
		}
	} else {
		sleep(1);
	}

	gg_free_session(gs);

	if (loops == 5) {
		printf("timeout\n");
		return 0;
	}

	return 1;
}
Beispiel #7
0
int session_io_handler(Session *s){
struct gg_event *event;
char *jid,*str;
int chat;
GIOCondition condition=s->g_pollfd.revents;
time_t timestamp;
gboolean state;

	user_load_locale(s->user);
	debug(L_("Checking error conditions..."));
	if (condition&(G_IO_ERR|G_IO_NVAL)){
		if (condition&G_IO_ERR) g_warning(N_("Error on connection for %s, GGid: %i"),s->jid,s->ggs->uin);
		if (condition&G_IO_HUP){
			g_warning(N_("Hangup on connection for %s, GGid: %i"),s->jid,s->ggs->uin);
			return session_error(s);
		}
		if (condition&G_IO_NVAL) g_warning(N_("Invalid channel on connection for %s"),s->jid);

		session_broken(s);
		return FALSE;
	}

	debug(L_("watching fd (gg_debug_level=%i)..."),gg_debug_level);
	event=gg_watch_fd(s->ggs);
	if (!event){
		g_warning(N_("Connection broken. Session of %s, GGid: %i"),s->jid,s->ggs->uin);
		return session_error(s);
	}

	switch(event->type){
		case GG_EVENT_DISCONNECT:
			g_warning(N_("Server closed connection of %s, GGid: %i"),s->jid,s->ggs->uin);
			session_error(s);
			gg_event_free(event);
			return FALSE;
		case GG_EVENT_CONN_FAILED:
			g_message(N_("Login failed (%d:%s) for %s, GGid: %i"),
					event->event.failure,
					(event->event.failure>GG_FAILURE_NUM_REASONS||event->event.failure<1)?"-UNKNOWN-":gg_failure_reason[event->event.failure-1],
					s->jid,
					s->ggs->uin);
			if (s->req_id)
				jabber_iq_send_error(s->s,s->jid,NULL,s->req_id,401,_("Unauthorized"));
			else {
				str=g_strdup(from_utf8(gg_failure_reason_txt[event->event.failure-1]));
				presence_send(s->s,NULL,s->user->jid,0,NULL,str,0);
				g_free(str);
			}
			state = FALSE;
			if (!s->req_id)
				switch(event->event.failure){
					case GG_FAILURE_RESOLVING:
					case GG_FAILURE_CONNECTING:
					case GG_FAILURE_INVALID:
					case GG_FAILURE_READING:
					case GG_FAILURE_WRITING:
					case GG_FAILURE_TLS:
						state = session_try_next(s);
					default:
						break;
				}
			if (state) {
				s->connected=0;
				session_schedule_reconnect(s);
			} else
				session_remove(s);
			gg_event_free(event);
			return FALSE;
		case GG_EVENT_CONN_SUCCESS:
			g_message(L_("Login succeed for %s, GGid: %i"),s->jid,s->ggs->uin);
			if (s->req_id)
				jabber_iq_send_result(s->s,s->jid,NULL,s->req_id,NULL);
			if (s->req_id){
				g_free(s->req_id);
				s->req_id=NULL;
			}
			if (s->query){
				xmlnode_free(s->query);
				s->query=NULL;
			}
			if (!s->user->confirmed){
				s->user->confirmed=1;
				user_save(s->user);
			}
			s->connected=1;
			session_send_status(s);
			session_send_notify(s);
			presence_send(s->s,NULL,s->user->jid,s->user->invisible?-1:1,NULL,s->gg_status_descr,0);

			if (s->timeout_func) g_source_remove(s->timeout_func);
			s->timeout_func=NULL;
			if (s->ping_timeout_func) g_source_remove(s->ping_timeout_func);
			s->ping_timeout_func=g_timeout_add(ping_interval*1000,session_ping,s);
			if (s->pubdir_change){
				add_request(RT_CHANGE,s->jid,NULL,s->req_id,
							NULL,s->pubdir_change,s->s);
				gg_pubdir50_free(s->pubdir_change);
				s->pubdir_change=NULL;
			}
			if (s->get_roster){
				gg_userlist_request(s->ggs, GG_USERLIST_GET, NULL);
			}
			break;
		case GG_EVENT_NOTIFY:
			session_event_notify(s,event);
			break;
		case GG_EVENT_NOTIFY_DESCR:
			session_event_notify_descr(s,event);
			break;
		case GG_EVENT_NOTIFY60:
			session_event_notify60(s,event);
			break;
		case GG_EVENT_STATUS:
			session_event_status(s,
					event->event.status.status,
					event->event.status.uin,
					event->event.status.descr,
					0,0,0,0);
			break;
		case GG_EVENT_STATUS60:
			session_event_status(s,
					event->event.status60.status,
					event->event.status60.uin,
					event->event.status60.descr,
					1,
					event->event.status60.remote_ip,
					event->event.status60.remote_port,
					event->event.status60.version);
			break;
		case GG_EVENT_MSG:
			if (event->event.msg.recipients_count>1){
				debug(L_("Dropped conference message: sender: %i class: %i time: %lu"),
							event->event.msg.sender,
							event->event.msg.msgclass,
							(unsigned long)event->event.msg.time);
				break;
			}
			gg_messages_in++;
			debug(L_("Message: sender: %i class: %i time: %lu"),
							event->event.msg.sender,
							event->event.msg.msgclass,
							(unsigned long)event->event.msg.time);
			
			if (event->event.msg.sender==0){
				if (!user_sys_msg_received(s->user,event->event.msg.msgclass)) break;
				if (ignore_system_messages == ISM_IGNORE_ALL) break;
				if (ignore_system_messages == ISM_IGNORE_HTML
					&& strstr((const char *)event->event.msg.message, "<HTML>")) break;
				timestamp=event->event.msg.time;
				str=g_strdup_printf(_("GG System message #%i"),
							event->event.msg.msgclass);
				message_send_subject(s->s,jid, s->user->jid, str,
						string_from_gg((const char *)event->event.msg.message),
												timestamp);
				g_free(str);
				break;
			}
			else{
				Contact *c=user_get_contact(s->user,
						event->event.msg.sender,0);
				if ((!c && s->user->ignore_unknown) 
				    || (c && c->ignored)) {
					debug(L_("Ignoring the message."));
			       		break;
				}
				jid=jid_build_full(event->event.msg.sender);
				if ((event->event.msg.msgclass&GG_CLASS_CHAT)!=0) chat=1;
				else chat=0;
			}
			if ((event->event.msg.msgclass&GG_CLASS_QUEUED)!=0){
				timestamp=event->event.msg.time;
			}
			else timestamp=0;
			if(event->event.msg.formats_length>0)
				message_send_rich(s->s,jid,s->user->jid,chat,
						(char *)event->event.msg.message,timestamp,
						event->event.msg.formats_length,(void *)event->event.msg.formats);
			else
				message_send(s->s,jid,s->user->jid,chat,
						string_from_gg((const char *)event->event.msg.message),timestamp);
			g_free(jid);
			break;
		case GG_EVENT_PONG:
			s->waiting_for_pong=FALSE;
			if (s->ping_timer){
				g_timer_stop(s->ping_timer);
				debug(L_("Pong! ping time: %fs"),
						g_timer_elapsed(s->ping_timer,NULL));
			}
			if (s->timeout_func) g_source_remove(s->timeout_func);
			s->timeout_func=NULL;
			break;
		case GG_EVENT_PUBDIR50_SEARCH_REPLY:
			request_response_search(event);
			break;
		case GG_EVENT_PUBDIR50_WRITE:
			request_response_write(event);
			break;
		case GG_EVENT_ACK:
			debug("GG_EVENT_ACK");
			break;
		case GG_EVENT_NONE:
			debug("GG_EVENT_NONE");
			break;
		case GG_EVENT_USERLIST:
			if(event->event.userlist.type==GG_USERLIST_GET_REPLY)
				get_roster_done(s,event);
			else
				g_warning(N_("Wrong gg userlist type: %i"),event->event.userlist.type);
			break;
		default:
			g_warning(N_("Unknown GG event: %i"),event->type);
			break;
	}

	session_setup_g_source(s);

	gg_event_free(event);
	debug(L_("io handler done..."));

	return FALSE;
}
Beispiel #8
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;
}
Beispiel #9
0
int main(int argc, char **argv)
{
	struct gg_session *gs;
	struct gg_login_params glp;
	struct gg_dcc7 *gd = NULL;
	time_t ping = 0, last = 0;
	int fds[2] = { -1, -1 };

	if (argc != 2 || atoi(argv[1]) >= TEST_MODE_LAST) {
		fprintf(stderr, "usage: %s <mode>\n"
				"\n"
				"mode: 0 - send file\n"
				"      1 - send file, simulate NAT\n"
				"      2 - receive file\n"
				"      3 - receive file, simulate NAT\n"
				"      4 - receive file, resume at the end\n"
				"\n", argv[0]);
		exit(1);
	}

	test_mode = atoi(argv[1]);

	if (config_read() == -1 || config_peer == 0) {
		perror("config");
		exit(1);
	}

#ifdef _WIN32
	gg_win32_init_network();
	gg_win32_hook(connect, my_connect, &connect_hook);
#else
	signal(SIGPIPE, SIG_IGN);
#endif
	gg_debug_file = stdout;
	gg_debug_level = ~0;

	if (!config_file && socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) == -1) {
		perror("pipe");
		exit(1);
	}

	memset(&glp, 0, sizeof(glp));
	glp.uin = config_uin;
	glp.password = config_password;
	glp.async = 1;
	glp.client_addr = config_ip;
	glp.client_port = config_port;
	glp.protocol_version = GG_PROTOCOL_VERSION_100;

	if (config_dir && (test_mode == TEST_MODE_RECEIVE ||
		test_mode == TEST_MODE_RECEIVE_NAT ||
		test_mode == TEST_MODE_RECEIVE_RESUME))
	{
		if (chdir(config_dir) == -1) {
			perror("chdir");
			exit(1);
		}
	}

	debug("Connecting...\n");

	if (!(gs = gg_login(&glp))) {
		perror("gg_login");
		exit(1);
	}

	for (;;) {
		fd_set rds, wds;
		struct timeval tv;
		time_t now;
		int res, maxfd = -1;

		FD_ZERO(&rds);
		FD_ZERO(&wds);

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

		maxfd = gs->fd;

		if ((gs->check & GG_CHECK_READ))
			FD_SET(gs->fd, &rds);

		if ((gs->check & GG_CHECK_WRITE))
			FD_SET(gs->fd, &wds);

		if (gd && gd->fd != -1) {
			if (gd->fd > maxfd)
				maxfd = gd->fd;

			if ((gd->check & GG_CHECK_READ))
				FD_SET(gd->fd, &rds);

			if ((gd->check & GG_CHECK_WRITE))
				FD_SET(gd->fd, &wds);
		}

		if (fds[1] != -1) {
			if (fds[1] > maxfd)
				maxfd = fds[1];

			FD_SET(fds[1], &wds);
		}

		if ((res = select(maxfd + 1, &rds, &wds, NULL, &tv)) == -1) {
			if (errno == EINTR)
				continue;

			perror("select");
			exit(1);
		}

		now = time(NULL);

		if (last != now) {
			if (gs->timeout != -1 && gs->timeout-- == 0 && !gs->soft_timeout) {
				debug("Timeout\n");
				exit(1);
			}

			if (gd && gd->timeout != -1 && gd->timeout-- == 0 && !gd->soft_timeout) {
				debug("Timeout\n");
				exit(1);
			}

			last = now;
		}

		if (gs->state == GG_STATE_CONNECTED && ping && now - ping > 60) {
			ping = now;
			gg_ping(gs);
		}

		if (FD_ISSET(gs->fd, &rds) || FD_ISSET(gs->fd, &wds) || (gs->timeout == 0 && gs->soft_timeout)) {
			struct gg_event *ge;
			uin_t uin;
			int status;

			if (!(ge = gg_watch_fd(gs))) {
				debug("Connection broken\n");
				exit(1);
			}

			switch (ge->type) {
				case GG_EVENT_CONN_SUCCESS:
					debug("Connected\n");
					connected = 1;
					gg_notify(gs, &config_peer, 1);

					if (test_mode == TEST_MODE_RECEIVE_NAT)
						gs->client_addr = INADDR_NONE;

					ping = time(NULL);

					break;

				case GG_EVENT_CONN_FAILED:
					debug("Connection failed\n");
					exit(1);

				case GG_EVENT_MSG:
					debug("Message from %d: %s\n", ge->event.msg.sender, ge->event.msg.message);
					break;

				case GG_EVENT_DISCONNECT:
					debug("Forced to disconnect\n");
					exit(1);

				case GG_EVENT_USER_DATA:
					debug("User data\n");
					break;

				case GG_EVENT_NOTIFY60:
					uin = ge->event.notify60[0].uin;
					status = ge->event.notify60[0].status;
					/* fall-through */

				case GG_EVENT_STATUS60:
					if (ge->type == GG_EVENT_STATUS60) {
						uin = ge->event.status60.uin;
						status = ge->event.status60.status;
					}

					if (uin == config_peer &&
						(GG_S_A(status) || GG_S_B(status)) &&
						(test_mode == TEST_MODE_SEND || test_mode == TEST_MODE_SEND_NAT))
					{
						debug("Sending file...\n");

						if (config_file) {
							gd = gg_dcc7_send_file(gs, config_peer,
								config_file, NULL, NULL);
						} else {
							gd = gg_dcc7_send_file_fd(gs, config_peer, fds[0],
								config_size, "test.bin", "DummySHA1HashOfAAAAA");
						}

						if (!gd) {
							perror("gg_dcc7_send_file");
							exit(1);
						}
					}

					break;

				case GG_EVENT_DCC7_NEW:
					debug("Incoming direct connection\n");

					if (test_mode == TEST_MODE_RECEIVE ||
						test_mode == TEST_MODE_RECEIVE_NAT ||
						test_mode == TEST_MODE_RECEIVE_RESUME)
					{
						gd = ge->event.dcc7_new;
						if (config_dir) {
							gd->file_fd = open((char*) gd->filename,
								O_WRONLY | O_CREAT, 0600);
#if 0
							lseek(gd->file_fd, gd->size, SEEK_SET);
#endif
						} else
							gd->file_fd = open("/dev/null", O_WRONLY);
						if (gd->file_fd == -1) {
							perror("open");
							exit(1);
						}
						if (test_mode != TEST_MODE_RECEIVE_RESUME)
							gg_dcc7_accept(gd, 0);
						else
							gg_dcc7_accept(gd, gd->size);
					}

					break;

				case GG_EVENT_DCC7_ERROR:
					debug("Direct connection error\n");
					exit(1);

				case GG_EVENT_DCC7_ACCEPT:
					debug("Accepted\n");
					break;

				case GG_EVENT_DCC7_REJECT:
					debug("Rejected\n");
					exit(1);

				case GG_EVENT_DCC7_PENDING:
					debug("Pending\n");
					break;

				case GG_EVENT_NONE:
					break;

				default:
					debug("Unsupported event %d\n", ge->type);
					break;
			}

			gg_event_free(ge);
		}

		if (gd && gd->fd != -1 && (FD_ISSET(gd->fd, &rds) ||
			FD_ISSET(gd->fd, &wds) || (gd->timeout == 0 && gd->soft_timeout)))
		{
			struct gg_event *ge;

			if (!(ge = gg_dcc7_watch_fd(gd))) {
				debug("Direct connection broken\n");
				exit(1);
			}

			switch (ge->type) {
				case GG_EVENT_DCC7_ERROR:
					debug("Direct connection error\n");
					exit(1);

				case GG_EVENT_DCC7_CONNECTED:
					debug("Direct connection established\n");
					break;

				case GG_EVENT_DCC7_DONE:
					debug("Finished");
					gg_event_free(ge);
					gg_dcc7_free(gd);
					gg_free_session(gs);
					config_free();
					exit(1);

				case GG_EVENT_NONE:
					break;

				default:
					debug("Unsupported event %d\n", ge->type);
					break;
			}

			gg_event_free(ge);
		}

		if (fds[1] != -1 && FD_ISSET(fds[1], &wds)) {
			char buf[4096];

			memset(buf, 'A', sizeof(buf));

			if (write(fds[1], buf, sizeof(buf)) < 1) {
				perror("write");
				exit(1);
			}
		}
	}

	return 0;
}
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);
}
Beispiel #11
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;
}