int InstallAPIHook(const char *modname, const char *fnname, const char *targetmod, int newfn) { int len, i, *blah, lookingfor; unsigned long oldprotect; HANDLE hModule = GetModuleHandle(targetmod); if (!hModule) { DispMsg("Failed to get base of %s!", targetmod); return 0; } blah = (int *)ImageDirectoryEntryToData((void *)hModule, 1, IMAGE_DIRECTORY_ENTRY_IAT, (unsigned long *)&len); lookingfor = (int)GetProcAddress(GetModuleHandle(modname), fnname); for (i = 0; i != len; i++) { if (lookingfor == blah[i]) goto success; } DispMsg("Failed to find %s in IAT of %s!", fnname, modname); return 0; success: VirtualProtect(&blah[i], sizeof(int), PAGE_EXECUTE_READWRITE, &oldprotect); blah[i] = newfn; VirtualProtect(&blah[i], sizeof(int), oldprotect, &oldprotect); return 1; }
/* * Chat, if the parameters are not NULL, a connection with the named * channel is made with the give username which will be forced to the * used nick name. This mode is used for forced sysop chat. * If the parameters are NULL, then it's up to the user what happens. */ void Chat(char *username, char *channel) { int width, curpos = 0, stop = FALSE, data, rc; unsigned char ch; char sbuf[81], resp[128], *name, *mname; static char buf[200]; time_t c_start, c_end; WhosDoingWhat(SYSOPCHAT, NULL); clear(); rsize = rows - 5; rpointer = 0; if (SYSOP == TRUE) { /* * Forbid the sysop to chat, the sysop MUST use mbmon. */ Syslog('+', "The Sysop attempted to chat"); pout(LIGHTRED, BLACK, (char *) Language(29)); Enter(1); Pause(); return; } if (username && channel) { colour(LIGHTGREEN, BLACK); PUTCHAR('\007'); /* *** Sysop is starting chat *** */ pout(LIGHTGREEN, BLACK, (char *) Language(59)); Enter(1); sleep(1); PUTCHAR('\007'); sleep(1); PUTCHAR('\007'); Syslog('+', "Sysop chat started"); chat_with_sysop = TRUE; } else { Syslog('+', "User started chatting"); } /* * Setup the screen, this is only possible in ANSI mode. */ clear(); locate(1, 1); colour(WHITE, BLUE); snprintf(buf, 200, "%-*s", cols, " MBSE BBS Chat Server"); mvprintw(1, 1, buf); mname = xstrcpy(clencode(exitinfo.sUserName)); name = xstrcpy(clencode(exitinfo.Name)); width = cols - (strlen(name) + 3); snprintf(buf, 200, "CCON,4,%d,%s,%s,0;", mypid, mname, name); free(mname); free(name); if (socket_send(buf) == 0) { strncpy(buf, socket_receive(), sizeof(buf)-1); if (strncmp(buf, "200:1,", 6) == 0) { Syslog('!', "Chat server is not available"); colour(LIGHTRED, BLACK); mvprintw(4, 1, (char *) Language(30)); Enter(2); Pause(); chat_with_sysop = FALSE; return; } } locate(rows - 2, 1); colour(WHITE, BLUE); snprintf(buf, 200, "%-*s", cols, " Type \"/EXIT\" to exit or \"/HELP\" for help."); mvprintw(rows - 2, 1, buf); colour(WHITE, BLACK); mvprintw(rows - 1, 1, ">"); mvprintw(rows - 1, width + 2, "<"); memset(&sbuf, 0, sizeof(sbuf)); memset(&rbuf, 0, sizeof(rbuf)); colour(LIGHTGRAY, BLACK); /* * If username and channelname are given, send the /nick and /join * commands to the chatserver. */ if (username && channel) { snprintf(buf, 200, "CPUT:2,%d,/nick %s;", mypid, clencode(username)); if (socket_send(buf) == 0) strcpy(buf, socket_receive()); snprintf(buf, 200, "CPUT:2,%d,/join %s;", mypid, clencode(channel)); if (socket_send(buf) == 0) strcpy(buf, socket_receive()); } chatting = TRUE; c_start = time(NULL); while (stop == FALSE) { /* * Check for new message, loop fast until no more data available. */ data = TRUE; while (data) { snprintf(buf, 200, "CGET:1,%d;", mypid); if (socket_send(buf) == 0) { strncpy(buf, socket_receive(), sizeof(buf)-1); if (strncmp(buf, "100:2,", 6) == 0) { strncpy(resp, strtok(buf, ":"), 10); /* Should be 100 */ strncpy(resp, strtok(NULL, ","), 5); /* Should be 2 */ strncpy(resp, strtok(NULL, ","), 5); /* 1= fatal, chat ended */ rc = atoi(resp); memset(&resp, 0, sizeof(resp)); strncpy(resp, cldecode(strtok(NULL, ";")), 80); /* The message */ DispMsg(resp); if (rc == 1) { Syslog('+', "Chat server error: %s", resp); stop = TRUE; data = FALSE; } } else { data = FALSE; } } } if (stop) break; /* * Check for a pressed key, if so then process it. * Allow hi-ascii for multi-language. */ ch = testkey(rows -1, curpos + 2); if ((ch == KEY_BACKSPACE) || (ch == KEY_RUBOUT) || (ch == KEY_DEL)) { alarm_on(); if (curpos) { curpos--; sbuf[curpos] = '\0'; BackErase(); } else { PUTCHAR(7); } /* if KEY_DEL isprint, do no output again */ } else if (isprint(ch) || traduce((char *)&ch)) { alarm_on(); if (curpos < width) { PUTCHAR(ch); sbuf[curpos] = ch; curpos++; } else { PUTCHAR(7); } } else if ((ch == '\r') && curpos) { alarm_on(); snprintf(buf, 200, "CPUT:2,%d,%s;", mypid, clencode(sbuf)); if (socket_send(buf) == 0) { strcpy(buf, socket_receive()); if (strncmp(buf, "100:2,", 6) == 0) { strncpy(resp, strtok(buf, ":"), 10); /* Should be 100 */ strncpy(resp, strtok(NULL, ","), 5); /* Should be 2 */ strncpy(resp, strtok(NULL, ","), 5); /* 1= fatal, chat ended */ rc = atoi(resp); strncpy(resp, cldecode(strtok(NULL, ";")), 80); /* The message */ DispMsg(resp); if (rc == 1) { Syslog('+', "Chat server error: %s", resp); stop = TRUE; } } } curpos = 0; memset(&sbuf, 0, sizeof(sbuf)); locate(rows - 1, 2); clrtoeol(); colour(WHITE, BLACK); mvprintw(rows - 1, 1, ">"); mvprintw(rows - 1, width + 2, "<"); colour(LIGHTGRAY, BLACK); } } chatting = FALSE; c_end = time(NULL); mib_chats++; mib_chatminutes += (unsigned int) ((c_end - c_start) / 60); /* * Before sending the close command, purge all outstanding messages. */ data = TRUE; while (data) { snprintf(buf, 200, "CGET:1,%d;", mypid); if (socket_send(buf) == 0) { strncpy(buf, socket_receive(), sizeof(buf)-1); if (strncmp(buf, "100:2,", 6) == 0) { strncpy(resp, strtok(buf, ":"), 10); /* Should be 100 */ strncpy(resp, strtok(NULL, ","), 5); /* Should be 2 */ strncpy(resp, strtok(NULL, ","), 5); /* 1= fatal error */ rc = atoi(resp); memset(&resp, 0, sizeof(resp)); strncpy(resp, cldecode(strtok(NULL, ";")), 80); /* The message */ DispMsg(resp); if (rc == 1) { Syslog('+', "Chat server error: %s", resp); data = FALSE; /* Even if there is more, prevent a loop */ } } else { data = FALSE; } } } if (username && channel) { /* * Disjoin sysop channel */ /* *** Sysop has terminated chat *** */ snprintf(buf, 200, "%s", (char *) Language(60)); DispMsg(buf); Syslog('+', "Sysop chat ended"); chat_with_sysop = FALSE; } else { Syslog('+', "User chat ended"); } /* * Close server connection */ snprintf(buf, 200, "CCLO,1,%d;", mypid); if (socket_send(buf) == 0) { strcpy(buf, socket_receive()); } sleep(2); clear(); }
int CTcpServ::ReadSock(int sock) { int len = -1; int evlen = 14; // Length of API message head. char buf[TCP_MAXMSG]; int idx = m_opSockTable->Search(sock); if (idx>=TCP_MAX_CONNECT) { Print("No such socket=%d.", sock); return 0; } len = read(sock, buf, TCP_MAXMSG); // Read in 1024 bytes data. // Begin JOYIT tcp mode. if (len == 0) { // Connection be closed. int index; index = m_opSockTable->Search(sock); STcpLinkAttribute tla; tla.tcpLinkId = m_opSockTable->m_sSockTable[index].iLinkID; // m_opSockTable->Sock2Link(sock); strcpy(tla.ipAddr, m_opSockTable->m_sSockTable[index].IPAddr); WEvent ev; #ifdef __PSG_REDUANT ev.dmid = (m_iRealMID & 0xFFFF0000) | (LMI_SYSMGR<<4); #else // __PSG_REDUNANT ev.dmid = LMI_SYSMGR << 4; #endif // __PSG_REDUANT ev.smid = m_iRealMID; // ev.what=evOAM; ev.what = evBroadcast; // Modify 2004-12-27, by Wujianjin. ev.PtlId=PTL_SYSMGR; ev.PtlVer=VER_SYSMGR; ev.Priority=0; ev.evCode=SYSMGR_IPC_TCPDOWN; ev.Reserved=m_opSockTable->Sock2Link(sock); ev.bcEvent.src = m_iRealMID; ev.msgLen = sizeof(STcpLinkAttribute); ev.msgPtr = new char[ev.msgLen]; memcpy(ev.msgPtr,&tla,ev.msgLen); //ev.msgPtr = (char *)&tla; m_opClnt->SendMsg(ev); Print("TCP link=%d sock=%d tear down: sock read EOF.", tla.tcpLinkId, sock); // Print("Socket=%d shutdown.",sock); m_opSockTable->DelSock(sock); #ifdef __TCP_DEBUG // Print("Send to %d what=%d len=%d.", // (int)ev.dmid,(int)ev.what,(int)ev.msgLen); // Print("TCP connection shutdown. linkid=%d, sock=%d.", ev.Reserved, sock); #endif // __TCP_DEBUG ev.del(); return -1; } if (len<0) { if ((errno == EWOULDBLOCK) || (errno == EINTR) || (errno == EAGAIN)) // Resource temporarily unavailable // EAGIN: It is very common to get this error when your application // is doing non-blocking operations on files or network sockets. For // example, you can open a file/socket/fifo for reading with the // O_NONBLOCK flag. If you subsequently do a read(2) call and there // is no data waiting, instead of blocking and waiting until there is // data ready and returning that data, the read() call will return an // error (EAGAIN) to let your application know that there is no data // ready and to try again later. // Another example is if a system call failed due to insufficient // resources (such as virtual memory), but it might succeed if called // again. (eg fork(2) does this). { return 0; } else { // Socket read error. int index; index = m_opSockTable->Search(sock); STcpLinkAttribute tla; tla.tcpLinkId = m_opSockTable->m_sSockTable[index].iLinkID; // m_opSockTable->Sock2Link(sock); strcpy(tla.ipAddr, m_opSockTable->m_sSockTable[index].IPAddr); WEvent ev; #ifdef __PSG_REDUANT ev.dmid = (m_iRealMID & 0xFFFF0000) | (LMI_SYSMGR<<4); #else // __PSG_REDUNANT ev.dmid = LMI_SYSMGR << 4; #endif // __PSG_REDUANT ev.smid = m_iRealMID; // ev.what=evOAM; ev.what = evBroadcast; ev.PtlId=PTL_SYSMGR; ev.PtlVer=VER_SYSMGR; ev.Priority=0; ev.evCode=SYSMGR_IPC_TCPDOWN; ev.Reserved=m_opSockTable->Sock2Link(sock); ev.bcEvent.src = m_iRealMID; ev.msgLen = sizeof(STcpLinkAttribute); ev.msgPtr = new char[ev.msgLen]; memcpy(ev.msgPtr,&tla,ev.msgLen); //ev.msgPtr = (char *)&tla; m_opClnt->SendMsg(ev); Print("TCP link=%d sock=%d tear down: sock read error.", tla.tcpLinkId, sock); // Print("Socket=%d read error.",sock); m_opSockTable->DelSock(sock); #ifdef __TCP_DEBUG // Print("Send to %d what=%d len=%d.", // (int)ev.dmid,(int)ev.what,(int)ev.msgLen); // Print("TCP connection shutdown. linkid=%d, sock=%d.", ev.Reserved, sock); #endif // __TCP_DEBUG ev.del(); return -1; } } if (idx>=TCP_MAX_CONNECT) { Print("LinkID-Socket error (sock=%d).",sock); m_opSockTable->DelSock(sock); return 0; } int pos = m_opSockTable->m_sSockTable[idx].iReadBufPos; // bytes left memcpy(m_opSockTable->m_sSockTable[idx].caReadBuf+pos, buf, len); WEvent event; pos = 0; // The position of data has been deal. while (1) { //Not enogh bytes left if ((len+m_opSockTable->m_sSockTable[idx].iReadBufPos-pos) < evlen) { //Print("cnt=%d pos=%d rest len=%d.",tt,pos,len+m_opSockTable->m_sSockTable[idx].iReadBufPos-pos); //m_opSockTable->DelSock(sock); break; } //copy message header memcpy(&event, m_opSockTable->m_sSockTable[idx].caReadBuf+pos, evlen); // ????? if (event.PktLength >= (TCP_MAXMSG-evlen)) // ignor the rest { Print("The message which from link=%d sock=%d content invalid msgLen=%d.", m_opSockTable->m_sSockTable[idx].iLinkID, // Modify 2005-03-25, by Wujianjin. m_opSockTable->m_sSockTable[idx].iSockfd, event.PktLength); m_opSockTable->m_sSockTable[idx].iReadBufPos = 0; return 0; } pos += evlen; // Copy extra information if ((event.PktLength-evlen) > 0) { // Modify 2005-05-13, by Wujianjin. event.msgPtr = new char[event.PktLength-evlen]; if (NULL == event.msgPtr) { // Discard all data. Print("Memory allocate error."); m_opSockTable->m_sSockTable[idx].iReadBufPos = 0; return 0; } event.msgLen = event.PktLength-evlen; memcpy(event.msgPtr, m_opSockTable->m_sSockTable[idx].caReadBuf+pos, event.msgLen); } else if ((event.PktLength-evlen) < 0) { // Add 2005-05-13, by Wujianjin. // print all data in buffer for debug popose. DispMsg((char *)m_opSockTable->m_sSockTable[idx].caReadBuf, len + m_opSockTable->m_sSockTable[idx].iReadBufPos, 1); Print("link=%d sock=%d, PktLength=%d error.", m_opSockTable->m_sSockTable[idx].iLinkID, // Modify 2005-03-25, by Wujianjin. m_opSockTable->m_sSockTable[idx].iSockfd, event.PktLength); m_opSockTable->m_sSockTable[idx].iReadBufPos = 0; // Discard all data. return 0; } pos += (event.PktLength-evlen); // Move to next packet's head. if (pos > (len + m_opSockTable->m_sSockTable[idx].iReadBufPos)) { // Data not enough. //Print("Not enough bytes."); pos -= (event.PktLength); event.del( ); // Add 2005-12-23, by Wu jianjin. break; } // UINT8 Ptl=event.PtlId; UINT16 evCode=*(UINT16 *)event.msgPtr; //printf("evCode:%d\n", evCode); #ifdef __TCP_HEARTBEAT // if (Ptl == 0x01 && evCode == 0x59) if ((PTL_TCP == event.PtlId) && (SYSMGR_IPC_HEARTBEAT_ACK == evCode)) { // Heartbeat acknowledgement. // m_iHeartBeat[idx] = 1; // Delete 2005-01-27, by Wujianjin. m_iCheckLife[idx] = 0; // Clear the CHECK LIFE counter. // return 0; // HeartBeat handle, return here. event.del( ); // Add 2005-12-23, by Wu jianjin. } else if ((PTL_TCP == event.PtlId) && (SYSMGR_IPC_HEARTBEAT == evCode)) { // Heartbeat message, response ACK. // Add 2005-01-28, by Wujianjin. SJoyitApiHead hback; hback.PtlId = PTL_TCP; hback.PtlVer = VER_TCP; hback.PktLength = sizeof(SJoyitApiHead); hback.dmid = event.smid; hback.smid = m_iRealMID; hback.Reserved = m_opSockTable->m_sSockTable[idx].iLinkID; hback.Priority = 0; hback.msgType = SYSMGR_IPC_HEARTBEAT_ACK; hback.noie = 0; WEvent sev; memcpy(&sev, &hback, evlen); sev.PktLength =sizeof(WEvent)+hback.PktLength; sev.msgLen = hback.PktLength; sev.msgPtr = (char *)&hback; WriteToSock(sev); // return 0; // HeartBeat handle, return here. // Add 2005-03-25, by Wujianjin. event.del( ); // Add 2005-12-23, by Wu jianjin. } else #endif // __TCP_HEARTBEAT //#endif // ifdef __SRD_TCP { //printf("Recv from sock:\n"); // DispMsg(buf,len); /*如果能够收到正常数据包,则认为心跳正常*/ #ifdef __TCP_HEARTBEAT m_iCheckLife[idx] = 0; #endif WEvent ev; ev.msgLen = event.PktLength; ev.msgPtr = new char[ev.msgLen]; if (ev.msgPtr==NULL) { Print("Memory allocate error."); event.del( ); // Add 2005-12-23, by Wu jianjin. return 0; } memcpy(ev.msgPtr, &event, evlen); if ((event.msgPtr != NULL) && (event.msgLen > 0)) { memcpy(ev.msgPtr+evlen, event.msgPtr, event.msgLen); } ev.smid = m_iRealMID; // Add 2005-01-18, by Wujianjin. ev.dmid = event.dmid; ev.what=evNetwork; ev.PtlId=PTL_TCP; ev.PtlVer=VER_TCP; ev.Priority=0; ev.Reserved=m_opSockTable->Sock2Link(sock); m_opClnt->SendMsg(ev); #ifdef __TCP_DEBUG Print("TCP Rcv: TCP packet from linkid=%d sock=%d.", ev.Reserved, sock); // Print("Tx: Send to %d what=%d len=%d.",ev.dmid, ev.what, ev.msgLen); if (ev.msgPtr!=NULL) { DispMsg(ev.msgPtr,ev.msgLen, 1); } #endif // __TCP_DEBUG event.del(); ev.del(); } } char tmp[2*TCP_MAXMSG]; int tlen; // Move the left data to head. tlen = m_opSockTable->m_sSockTable[idx].iReadBufPos+len-pos; //Print("cnt=%d idx=%d bufpos=%d pos=%d len=%d tlen=%d.", //tt,idx,m_opSockTable->m_sSockTable[idx].iReadBufPos,pos,len,tlen); memcpy(tmp, m_opSockTable->m_sSockTable[idx].caReadBuf+pos, tlen); memcpy(m_opSockTable->m_sSockTable[idx].caReadBuf, tmp, tlen); m_opSockTable->m_sSockTable[idx].iReadBufPos = tlen; //Print("cnt=%d last pos=%d.",tt,tlen); return pos; #endif // __TCP_RAW_CONNECT }