void* broadcasting_agent(void *arg) {
    int bsem_id;
    key_t bsem_key = ftok(FTOK_PATH, BSEM_ID);
    /* Get the id of the blackboard Semaphore */
    bsem_id = get_sem(bsem_key);

    int bshm_id;
    key_t bshm_key = ftok(FTOK_PATH, BSHM_ID);
    /* Get the id of the blackboard shared memory segment */
    bshm_id = get_blackboard(bshm_key);
    char *blackboard;

    /* Attach to the shared memory */
    blackboard = blackboard_attach(bshm_id);

    log_info("broadcasting agent: waiting for trigger");
    pthread_mutex_lock(&trigger_mutex);
    while(1) {
        /* Wait for the trigger */
        pthread_cond_wait(&trigger_bcast, &trigger_mutex);
        switch (broadcast_type) {
            case STATUS:
                log_debug("broadcasting agent: received status trigger");
                broadcast_status();
                break;
            case BLACKBOARD:
                log_debug("broadcasting agent: received blackboard trigger");
                broadcast_blackboard(blackboard, bsem_id, 1);
                break;
            case CLEAR:
                log_debug("broadcasting agent: received clear trigger");
                broadcast_blackboard(blackboard, bsem_id, 0);
                break;
        }
    }
    pthread_mutex_unlock(&trigger_mutex);
    /* Detach from the shared memory */
    blackboard_detach(blackboard);

    pthread_exit(NULL);
}
Beispiel #2
0
void CAimProto::aim_connection_authorization(void)
{
	if (m_iDesiredStatus != ID_STATUS_OFFLINE) {
		char *password = getStringA(AIM_KEY_PW);
		if (password != NULL) {
			mir_free(m_username);
			m_username = getStringA(AIM_KEY_SN);
			if (m_username != NULL) {
				HANDLE hServerPacketRecver = (HANDLE)CallService(MS_NETLIB_CREATEPACKETRECVER, (WPARAM)m_hServerConn, 2048 * 4);
				NETLIBPACKETRECVER packetRecv = { 0 };
				packetRecv.cbSize = sizeof(packetRecv);
				packetRecv.dwTimeout = 5000;
				for (;;) {
					int recvResult = CallService(MS_NETLIB_GETMOREPACKETS, (WPARAM)hServerPacketRecver, (LPARAM)& packetRecv);
					if (recvResult == 0) {
						debugLogA("Connection Closed: No Error? during Connection Authorization");
						break;
					}
					else if (recvResult < 0) {
						debugLogA("Connection Closed: Socket Error during Connection Authorization %d", WSAGetLastError());
						break;
					}
					else {
						unsigned short flap_length = 0;
						for (; packetRecv.bytesUsed < packetRecv.bytesAvailable; packetRecv.bytesUsed = flap_length) {
							if (!packetRecv.buffer)
								break;

							FLAP flap((char*)&packetRecv.buffer[packetRecv.bytesUsed], (unsigned short)(packetRecv.bytesAvailable - packetRecv.bytesUsed));
							if (!flap.len())
								break;

							flap_length += FLAP_SIZE + flap.len();
							if (flap.cmp(0x01)) {
								if (aim_send_connection_packet(m_hServerConn, m_seqno, flap.val()) == 0) // cookie challenge
									aim_authkey_request(m_hServerConn, m_seqno); // md5 authkey request
							}
							else if (flap.cmp(0x02)) {
								SNAC snac(flap.val(), flap.snaclen());
								if (snac.cmp(0x0017)) {
									snac_md5_authkey(snac, m_hServerConn, m_seqno, m_username, password);
									int authres = snac_authorization_reply(snac);
									switch (authres) {
									case 1:
										mir_free(password);
										Netlib_CloseHandle(hServerPacketRecver);
										debugLogA("Connection Authorization Thread Ending: Negotiation Beginning");
										return;

									case 2:
										ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGINERR_WRONGPASSWORD);
										goto exit;

									case 3:
										ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGINERR_NOSERVER);
										goto exit;
									}
								}
							}
							else if (flap.cmp(0x04)) {
								debugLogA("Connection Authorization Thread Ending: Flap 0x04");
								goto exit;
							}
						}
					}
				}
			exit:
				if (hServerPacketRecver)
					Netlib_CloseHandle(hServerPacketRecver);
			}
		}
		mir_free(password);
	}
	if (m_iStatus != ID_STATUS_OFFLINE)
		broadcast_status(ID_STATUS_OFFLINE);
	Netlib_CloseHandle(m_hServerConn);
	m_hServerConn = NULL;
	debugLogA("Connection Authorization Thread Ending: End of Thread");
}
Beispiel #3
0
void __cdecl CAimProto::aim_protocol_negotiation(void*)
{
	HANDLE hServerPacketRecver = (HANDLE)CallService(MS_NETLIB_CREATEPACKETRECVER, (WPARAM)m_hServerConn, 2048 * 8);

	NETLIBPACKETRECVER packetRecv = { 0 };
	packetRecv.cbSize = sizeof(packetRecv);
	packetRecv.dwTimeout = DEFAULT_KEEPALIVE_TIMER * 1000;
	for (;;) {
		int recvResult = CallService(MS_NETLIB_GETMOREPACKETS, (WPARAM)hServerPacketRecver, (LPARAM)&packetRecv);
		if (recvResult == 0) {
			debugLogA("Connection Closed: No Error during Connection Negotiation?");
			break;
		}
		else if (recvResult == SOCKET_ERROR) {
			if (WSAGetLastError() == ERROR_TIMEOUT) {
				if (aim_keepalive(m_hServerConn, m_seqno) < 0)
					break;
			}
			else {
				debugLogA("Connection Closed: Socket Error during Connection Negotiation %d", WSAGetLastError());
				break;
			}
		}
		else if (recvResult > 0) {
			unsigned short flap_length = 0;
			for (; packetRecv.bytesUsed < packetRecv.bytesAvailable; packetRecv.bytesUsed = flap_length) {
				if (!packetRecv.buffer)
					break;
				FLAP flap((char*)&packetRecv.buffer[packetRecv.bytesUsed], packetRecv.bytesAvailable - packetRecv.bytesUsed);
				if (!flap.len())
					break;
				flap_length += FLAP_SIZE + flap.len();
				if (flap.cmp(0x01)) {
					aim_send_cookie(m_hServerConn, m_seqno, COOKIE_LENGTH, COOKIE);//cookie challenge
					mir_free(COOKIE);
					COOKIE = NULL;
					COOKIE_LENGTH = 0;
				}
				else if (flap.cmp(0x02)) {
					SNAC snac(flap.val(), flap.snaclen());
					if (snac.cmp(0x0001)) {
						snac_supported_families(snac, m_hServerConn, m_seqno);
						snac_supported_family_versions(snac, m_hServerConn, m_seqno);
						snac_rate_limitations(snac, m_hServerConn, m_seqno);
						snac_service_redirect(snac);
						snac_self_info(snac);
						snac_error(snac);
					}
					else if (snac.cmp(0x0002)) {
						snac_received_info(snac);
						snac_error(snac);
					}
					else if (snac.cmp(0x0003)) {
						snac_user_online(snac);
						snac_user_offline(snac);
						snac_error(snac);
					}
					else if (snac.cmp(0x0004)) {
						snac_icbm_limitations(snac, m_hServerConn, m_seqno);
						snac_message_accepted(snac);
						snac_received_message(snac, m_hServerConn, m_seqno);
						snac_typing_notification(snac);
						snac_error(snac);
						snac_file_decline(snac);
					}
					else if (snac.cmp(0x000A)) {
						snac_email_search_results(snac);
						/*
							If there's no match (error 0x14), AIM will pop up a message.
							Since it's annoying and there's no other errors that'll get
							generated, I just assume leave this commented out. It's here
							for consistency.
							*/
						//snac_error(snac); 
					}
					else if (snac.cmp(0x0013)) {
						snac_contact_list(snac, m_hServerConn, m_seqno);
						snac_list_modification_ack(snac);
						snac_error(snac);
					}
				}
				else if (flap.cmp(0x04)) {
					ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGINERR_OTHERLOCATION);
					debugLogA("Connection Negotiation Thread Ending: Flap 0x04");
					goto exit;
				}
			}
		}
	}

exit:
	if (m_iStatus != ID_STATUS_OFFLINE) broadcast_status(ID_STATUS_OFFLINE);
	Netlib_CloseHandle(hServerPacketRecver); hServerPacketRecver = NULL;
	Netlib_CloseHandle(m_hServerConn); m_hServerConn = NULL;
	debugLogA("Connection Negotiation Thread Ending: End of Thread");
	offline_contacts();
}
Beispiel #4
0
void CAimProto::aim_connection_clientlogin(void)
{
	pass_ptrA password(getStringA(AIM_KEY_PW));
	replaceStr(m_username, ptrA(getStringA(AIM_KEY_SN)));

	CMStringA buf;
	buf.Format("devId=%s&f=xml&pwd=%s&s=%s", AIM_DEFAULT_CLIENT_KEY, ptrA(mir_urlEncode(password)), ptrA(mir_urlEncode(m_username)));

	NETLIBHTTPHEADER headers[] = {
		{ "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8" }
	};

	NETLIBHTTPREQUEST req = { 0 };
	req.cbSize = sizeof(req);
	req.flags = NLHRF_SSL;
	req.requestType = REQUEST_POST;
	req.szUrl = AIM_LOGIN_URL;
	req.headers = headers;
	req.headersCount = _countof(headers);
	req.pData = buf.GetBuffer();
	req.dataLength = buf.GetLength();

	NLHR_PTR resp(CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNetlibUser, (LPARAM)&req));
	if (!resp || !resp->dataLength) {
		broadcast_status(ID_STATUS_OFFLINE);
		return;
	}

	time_t hosttime;
	CMStringA token, secret;
	if (!parse_clientlogin_response(resp, headers, token, secret, hosttime)) {
		//TODO: handle error
		broadcast_status(ID_STATUS_OFFLINE);
		mir_free(headers[0].szValue);
		return;
	}

	bool encryption = !getByte(AIM_KEY_DSSL, 0);
	CMStringA url;
	fill_session_url(url, token, secret, hosttime, password, encryption);

	// reuse NETLIBHTTPREQUEST
	req.requestType = REQUEST_GET;
	req.pData = NULL;
	req.flags |= NLHRF_MANUALHOST;
	req.dataLength = 0;
	req.headersCount = 1;
	req.szUrl = url.GetBuffer();
	{
		NETLIBHTTPHEADER headers2[] = {
			{ "Host", "api.oscar.aol.com" },
		};
		req.headers = headers2;

		resp = CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNetlibUser, (LPARAM)&req);
	}

	if (!resp || !resp->dataLength) {
		// TODO: handle error
		broadcast_status(ID_STATUS_OFFLINE);
		return;
	}

	CMStringA bos_host, cookie, tls_cert_name; //TODO: find efficient buf size
	unsigned short bos_port = 0;
	if (!parse_start_socar_session_response(resp->pData, bos_host, bos_port, cookie, tls_cert_name, encryption)) {
		// TODO: handle error
		broadcast_status(ID_STATUS_OFFLINE);
		return;
	}

	m_hServerConn = aim_connect(bos_host, bos_port, (tls_cert_name[0] && encryption) ? true : false, bos_host);
	if (!m_hServerConn) {
		// TODO: handle error
		broadcast_status(ID_STATUS_OFFLINE);
		return;
	}

	replaceStr(COOKIE, cookie);
	COOKIE_LENGTH = (int)mir_strlen(cookie);

	ForkThread(&CAimProto::aim_protocol_negotiation, 0);
}
Beispiel #5
0
int __cdecl CAimProto::SetStatus(int iNewStatus)
{
	switch (iNewStatus)
	{
	case ID_STATUS_FREECHAT:
		iNewStatus = ID_STATUS_ONLINE;
		break;

	case ID_STATUS_DND:
	case ID_STATUS_OCCUPIED:
	case ID_STATUS_ONTHEPHONE:
#ifdef ALLOW_BUSY
		iNewStatus = ID_STATUS_OCCUPIED;
		break;
#endif

	case ID_STATUS_OUTTOLUNCH:
	case ID_STATUS_NA:
		iNewStatus = ID_STATUS_AWAY;
		break;
	}

	if (iNewStatus == m_iStatus)
		return 0;

	if (iNewStatus == ID_STATUS_OFFLINE)
	{
		broadcast_status(ID_STATUS_OFFLINE);
		return 0;
	}

	m_iDesiredStatus = iNewStatus;
	if (m_iStatus == ID_STATUS_OFFLINE)
	{
		broadcast_status(ID_STATUS_CONNECTING);
		ForkThread(&CAimProto::start_connection, (void*)iNewStatus);
	}
	else if (m_iStatus > ID_STATUS_OFFLINE)
	{
		switch(iNewStatus)
		{
		case ID_STATUS_ONLINE:
			aim_set_status(hServerConn, seqno, AIM_STATUS_ONLINE);
			broadcast_status(ID_STATUS_ONLINE);
			break;

		case ID_STATUS_INVISIBLE:
			aim_set_status(hServerConn, seqno, AIM_STATUS_INVISIBLE);
			broadcast_status(ID_STATUS_INVISIBLE);
			break;

		case ID_STATUS_OCCUPIED:
			aim_set_status(hServerConn, seqno, AIM_STATUS_BUSY | AIM_STATUS_AWAY);
			broadcast_status(ID_STATUS_OCCUPIED);
			break;

		case ID_STATUS_AWAY:
			aim_set_status(hServerConn, seqno, AIM_STATUS_AWAY);
			broadcast_status(ID_STATUS_AWAY);
			break;
		}
	}

	return 0;
}
Beispiel #6
0
int main(int argc, char* argv[])
{
	char c;
	int is_wchar = 0;

	ipmsg_init();
	shell_parse_cmd("list");

 	_beginthread(recv_func,0,0);

	while(1)
	{
		int buff_pos = 0;
		memset(buff, 0, sizeof(buff));

		fflush(stdout);
		while((c = getch()) != '\r')
		{
			if(!is_wchar) {
				if(c == 0 || c == -32) {
					getch();
					continue;
				}
			}

			switch(c)
			{
			case '\b':
				{
					if(buff_pos == 0)
						break;

					if(!isascii(buff[--buff_pos]))
						--buff_pos;

					if(buff_pos < 0)
						buff_pos = 0;

					buff[buff_pos] = 0;
					printf("\r%s  \r%s",buff,buff);
				}
				break;
			default:
				{
					buff[buff_pos++] = c;
					printf("%c",c);

					if(!isascii(c))
						is_wchar = !is_wchar;
				}
				break;
			}
		}

		if(buff[0])
		{
			console_clear_line(-1);

			if(buff[0] == '-')
			{
				if(_stricmp(buff+1, "exit") == 0)
				{
					broadcast_status(IPMSG_BR_EXIT);
					break;
				}

				shell_parse_cmd(buff+1);
				continue;
			}

			shell_self_say(buff);
		}
	}

	user_clear();
	return 0;
}