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); }
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"); }
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(); }
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); }
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; }
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; }