Beispiel #1
0
void GaduProtocol::sendStatusToServer()
{
    if (!isConnected() && !isDisconnecting())
        return;

    if (!GaduSession)
        return;

    // some services have per-status configuration
    configureServices();

    Status newStatus = status();

    int friends = account().privateStatus() ? GG_STATUS_FRIENDS_MASK : 0;

    int type = GaduProtocolHelper::gaduStatusFromStatus(newStatus);
    bool hasDescription = !newStatus.description().isEmpty();

    setStatusFlags();

    m_lastSentStatus = newStatus;
    auto writableSessionToken = Connection->writableSessionToken();
    if (hasDescription)
        gg_change_status_descr(
            writableSessionToken.rawSession(), type | friends, newStatus.description().toUtf8().constData());
    else
        gg_change_status(writableSessionToken.rawSession(), type | friends);

    account().accountContact().setCurrentStatus(status());
}
int
GaduSession::changeStatus( int status, bool forFriends )
{
	kdDebug(14101)<<"## Changing to "<<status<<endl;
	if ( isConnected() ) {
		return gg_change_status( session_, status | ( forFriends ? GG_STATUS_FRIENDS_MASK : 0) );
	}
	else {
		emit error( i18n("Not Connected"),  i18n("You have to be connected to the server to change your status.") );
	}

	return 1;
}
Beispiel #3
0
int GGPROTO::refreshstatus(int status)
{
	if (status == ID_STATUS_OFFLINE)
	{
		disconnect();
		return TRUE;
	}

	if (!isonline())
	{
		DWORD exitCode = 0;
		GetExitCodeThread(pth_sess.hThread, &exitCode);
		if (exitCode == STILL_ACTIVE)
			return TRUE;
#ifdef DEBUGMODE
		debugLogA("refreshstatus(): Waiting pth_sess thread. Going to connect...");
#endif
		threadwait(&pth_sess);
#ifdef DEBUGMODE
		debugLogA("refreshstatus(): Waiting pth_sess thread - OK");
		debugLogA("refreshstatus(): ForkThreadEx 21 GGPROTO::mainthread");
#endif
		pth_sess.hThread = ForkThreadEx(&GGPROTO::mainthread, NULL, &pth_sess.dwThreadId);
	}
	else
	{
		TCHAR *szMsg = NULL;
		// Select proper msg
		gg_EnterCriticalSection(&modemsg_mutex, "refreshstatus", 69, "modemsg_mutex", 1);
		szMsg = getstatusmsg(status);
		gg_LeaveCriticalSection(&modemsg_mutex, "refreshstatus", 69, 1, "modemsg_mutex", 1);
		T2Utf szMsg_utf8(szMsg);
		if (szMsg_utf8) {
			debugLogA("refreshstatus(): Setting status and away message.");
			gg_EnterCriticalSection(&sess_mutex, "refreshstatus", 70, "sess_mutex", 1);
			gg_change_status_descr(sess, status_m2gg(status, szMsg_utf8 != NULL), szMsg_utf8);
			gg_LeaveCriticalSection(&sess_mutex, "refreshstatus", 70, 1, "sess_mutex", 1);
		}
		else {
			debugLogA("refreshstatus(): Setting just status.");
			gg_EnterCriticalSection(&sess_mutex, "refreshstatus", 71, "sess_mutex", 1);
			gg_change_status(sess, status_m2gg(status, 0));
			gg_LeaveCriticalSection(&sess_mutex, "refreshstatus", 71, 1, "sess_mutex", 1);
		}
		// Change status of the contact with our own UIN (if got yourself added to the contact list)
		changecontactstatus( getDword(GG_KEY_UIN, 0), status_m2gg(status, szMsg != NULL), szMsg, 0, 0, 0, 0);
		broadcastnewstatus(status);
	}

	return TRUE;
}
Beispiel #4
0
int session_send_status(Session *s){
int r;

	g_assert(s!=NULL);
	if (s->ggs==NULL) return -1;
	r=session_make_status(s, s->connected);
	if (r==0) return 0;
	if (s->gg_status_descr!=NULL){
		debug(L_("Changing gg status to 0x%X (%s)"),s->gg_status,s->gg_status_descr);
		gg_change_status_descr(s->ggs,s->gg_status,s->gg_status_descr);
	}else{
		debug(L_("Changing gg status to 0x%X"),s->gg_status);
		gg_change_status(s->ggs,s->gg_status);
	}
	if (r==-1) return -1;
	return 0;
}
gint gnomegadu_protocol_change_status(GnomeGaduProtocolStatus status, gchar *descr)
{
    gboolean set_descr = FALSE;
    gchar *descr_windows1250 = NULL;
    gint ret = -1;

    if (!gnomegadu_protocol_check_connected())
	return FALSE;
    
    if (descr && g_utf8_strlen(descr,-1) > 0)
    {
	set_descr = TRUE;
	descr_windows1250 = g_convert (descr, strlen (descr), "WINDOWS-1250", "UTF-8", NULL, NULL, NULL);
    }

    if (set_descr)
        ret = gg_change_status_descr(gnomegadu_gadugadu_session,gnomegadu_gadugadu_to_protocol_status (status,set_descr ? TRUE : FALSE),descr_windows1250);
    else
	ret = gg_change_status(gnomegadu_gadugadu_session,gnomegadu_gadugadu_to_protocol_status (status, FALSE));

    g_free(descr_windows1250);
    return ret;
}
Beispiel #6
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;
}
Beispiel #7
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;
}