#include "cygwin.h" #include "misc.h" #include "protocol.h" #include "donkey.h" #include "sGui.h" #include "sFile.h" #include "sPacket.h" #include "sServer.h" #include "sCommand.h" #include "sTag.h" #include "cServer_udp.h" #include "opcodes.h" #include "sSource.h" /* Spezial Hashes: fffffffffffffffffffffff00000001 -> Information how many dl File Transfers requested fffffffffffffffffffffff00000002 -> Socket / Sources fffffffffffffffffffffff00000003 -> Traffic / Downlaod Information how many sSource are Slot waiting (max 257 Parts 0 => Have Slot 1-256 => dl_slot+1 */ static size_t sourceCount4Part (tHash &hash, int block, unsigned limit) {{{ class sFile *file = forHash(hash); if (file == NULL) return 0; size_t ret = file->part_sources[block]; if (ret > limit) return limit; return ret; }}} static size_t sourceCount4Part (tHash &hash, uint32_t von, uint32_t bis, unsigned limit) {{{ int block_0 = von / PARTSIZE; int block_n = bis / PARTSIZE; class sFile *file = forHash(hash); if (file == NULL) return 0; size_t check = 0; for (int j = block_0 ; j <= block_n; j++) check+=file->part_sources[j]; if (check > limit) check = limit; return check; }}} unsigned sGui::count = 0; sGui *sGui::first_gui = NULL; sGui :: sGui (class cSocket *Fd, struct in_addr ) : sSocket(Fd) {{{ prio = 0; next_gui = first_gui; first_gui = this; Type = tGui; status = CONNECTING; name = NULL; result_tree = NULL; result_len = 0; search_tree = NULL; search_len = 0; last_code = 0; auth = false; dl_status = false; ul_status = false; announced_server_connect = true ; // true to send initial disconncet() dl_timeout = currentTime; ul_timeout = currentTime; count++; }}} sGui ::~sGui (void) {{{ if (result_tree != NULL) Free2 (result_tree); if (search_tree != NULL) Free2 (search_tree); if (name != NULL) Free2 (name); count--; // remove me from the file_list if (first_gui == this) { first_gui = next_gui; return; } sGui *prev_file = first_gui; while (prev_file->next_gui != this && prev_file->next_gui != NULL) prev_file = prev_file->next_gui; if (prev_file == NULL) return; ASSERT (prev_file->next_gui == this); prev_file->next_gui = prev_file->next_gui->next_gui; }}} void sGui::Name (const char *NAME) {{{ Free2 (name); name = STRDUP (NAME); }}} void sGui::resultTree (char *tree,uint32_t len) {{{ if (result_tree != NULL) Free2 (result_tree); result_tree = tree; result_len = len; }}} void sGui::searchTree (char *tree,uint32_t len) {{{ if (result_tree != NULL) Free2 (search_tree); search_tree = tree; search_len = len; }}} int sGui::GUI_txt_g ( void ) {{{ if (!auth) return 0; char logbuf[256]; GUI_statusMessage("(open)"); if (use_kademlia) { snprintf(logbuf, 255, "ID: %32s", hash_bin2hex(client_hash)); GUI_statusMessage(logbuf); } snprintf(logbuf, 255, "%s:%u (0.0.0.0:0)\n", inet_ntoa(cSocket::getLocalExternalIP()), pref.ports.client); GUI_statusMessage(logbuf); snprintf(logbuf, 255, "Users: 172032 Files: 62914"); GUI_statusMessage(logbuf); if (use_kademlia) GUI_statusMessage("Shibboleth: This is cdonkey-0.8.5-cvs hybrid"); return 1; }}} // Client-Gui TCP handling (0x64) ... (0xE3) int sGui::GUI_serverlist (void ) {{{ // (0xAA) // send server list to gui if (!auth) return 0; tHash hash; bzero (hash, HASH_LEN); const struct eServers *s; // If all server are send AN if all server use max name.length and max desc.lenth unsigned max_cnt = cntServer() ; unsigned limit = max_cnt * (78 + sizeof(s->name) + sizeof(s->desc)); unsigned char *buffer, *BUFFER = buffer = reinterpret_cast(alloca (limit)); s = nextServers (true); size_t unused = limit; unsigned cnt = 0 ; while (s != NULL) { // we have reserved the maximum possible size cnt++; ADD_HASH (&buffer, &unused, hash); ADD_U4 (&buffer, &unused, s->ip.s_addr); ADD_U2 (&buffer, &unused, s->port ); ADD_U4 (&buffer, &unused, 6); add_intTag (&buffer, &unused, FT_PRIORITY , s->prio ); add_intTag (&buffer, &unused, ST_PING , currentTime - s->last_action); add_intTag (&buffer, &unused, ST_LONG_USERS , s->user); add_intTag (&buffer, &unused, ST_LONG_FILES , s->file); add_strTag (&buffer, &unused, ST_SERVERNAME , s->name); add_strTag (&buffer, &unused, ST_DESCRIPTION , s->desc); s = nextServers (false); } log (1, "Server list %i/%i\n", max_cnt, cnt); if (logSend ('>', this, CO_SERVER_LIST, true)) printf("count: %i\n", cnt); size_t len, LEN = len = 6 + 4 + limit - unused; unsigned char *buf, *BUF = buf = reinterpret_cast(alloca (LEN)); ADD_U1 (&buf, &len, OP_EDONKEYHEADER); ADD_U4 (&buf, &len, LEN - 5); ADD_U1 (&buf, &len, CO_SERVER_LIST); ADD_U4 (&buf, &len, cnt); if (cnt > 0) memcpy (buf, BUFFER, len); Write (BUF, LEN); return 1; }}} int sGui::GUI_shareFiles (void ) {{{ // (0xAD) logSend ('>', this, CO_SHARED_FILES, false); if (!auth) return 0; unsigned limit = 3000; // hardcoded ! BAD unsigned char *buffer, *BUFFER = buffer = reinterpret_cast(alloca (limit)); size_t unused = limit; unsigned cnt = 0 ; FILE_LIST {{{ if ( ! akt->get_Completed() ) continue; cnt++; ADD_HASH (&buffer, &unused, akt->hash); // hash ADD_U4 (&buffer, &unused, 0); // unused ADD_U2 (&buffer, &unused, 0 ); // unused ADD_U4 (&buffer, &unused, 4); // cnt of tag elements add_strTag (&buffer, &unused, FT_FILENAME , akt->Name()); // filename add_strTag (&buffer, &unused, FT_FILEFORMAT, "unknown"); // fileformat add_intTag (&buffer, &unused, FT_FILESIZE , akt->Size()); // filesize add_strTag (&buffer, &unused, FT_FILETYPE , "unknown" ); // filetype }}} if (cnt > 0) { size_t len, LEN = len = 6 + 4 + limit - unused; unsigned char *buf, *BUF = buf = reinterpret_cast(alloca (LEN)); ADD_U1 (&buf, &len, OP_EDONKEYHEADER); ADD_U4 (&buf, &len, LEN - 5); ADD_U1 (&buf, &len, CO_SHARED_FILES); ADD_U4 (&buf, &len, cnt); memcpy (buf, BUFFER, limit - unused); Write (BUF, LEN); } Code(0xE0); // ? return 1; }}} bool sGui::GUI_res_part_status (tHash &hash ) {{{ // (0xAE) SPLIT if (!auth) return 0; logSend ('>', this, CO_GAP_DETAILS, false); sFile *file = forHash (hash); if (file == NULL) {{{ printf("%s %i Unkown file\n", __FILE__, __LINE__); return false; }}} log (1,"stat for %s\n", file->Name()); unsigned maxCount = (file->size + PARTSIZE - 1) / PARTSIZE; uint32_t realCount = 0; size_t len, LEN = len = 24 + 10 * maxCount; unsigned char *buf, *BUF = buf = reinterpret_cast(alloca (LEN)); ADD_U1 (&buf, &len, OP_EDONKEYHEADER); ADD_U4 (&buf, &len, 0); ADD_U1 (&buf, &len, CO_GAP_DETAILS); ADD_HASH (&buf, &len, hash); ADD_U2 (&buf, &len, 0); uint32_t p_old_von = 0; uint16_t p_old_stat = 9997; for (unsigned b = 0; b < maxCount; b++) {{{ uint32_t p_von = b * PARTSIZE; uint32_t p_bis = p_von + PARTSIZE - 1; uint16_t p_stat = 2000; if (p_bis > file->size) p_bis = file->size - 1; if (!file->partStatus(b)) { if (file->downloads == 0) p_stat = 0; else p_stat = sourceCount4Part (hash, p_von, p_bis, 255); } if (p_old_stat == p_stat && b != 0) { buf -= 10; len += 10; p_von = p_old_von; realCount--; } ADD_U4 (&buf, &len, p_old_von = p_von); ADD_U4 (&buf, &len, p_bis); ADD_U2 (&buf, &len, p_old_stat = p_stat); realCount++; }}} buf = BUF; len = LEN; ADD_U1 (&buf, &len, OP_EDONKEYHEADER); ADD_U4 (&buf, &len, HASH_LEN + 2 + 10 * realCount + 1); ADD_U1 (&buf, &len, CO_GAP_DETAILS); ADD_HASH (&buf, &len, hash); ADD_U2 (&buf, &len, realCount); Write (BUF, 24 + realCount * 10); return true; }}} int sGui::GUI_core_status (void ) {{{ // (0xAF) if (!auth) return 0; logSend('>', this, CO_CLIENT_STATS, false); unsigned long need = 0; FILE_LIST need += akt->size; size_t len, LEN = len = 6 + 20; unsigned char *buf, *BUF = buf = reinterpret_cast(alloca (LEN)); ADD_U1 (&buf, &len, OP_EDONKEYHEADER); ADD_U4 (&buf, &len, LEN - 5); ADD_U1 (&buf, &len, CO_CLIENT_STATS); ADD_F4 (&buf, &len, 10000.0); // avail Space on Temp ADD_F4 (&buf, &len, 10000.0); // avail Space on Incomming ADD_F4 (&buf, &len, ((need / (1024.0*1024.0)))); // Space needed by the Downloads ADD_U4 (&buf, &len, cSocket::getLocalExternalIP().s_addr); // my ID ADD_U2 (&buf, &len, sSource::count + sServer::count); ADD_U2 (&buf, &len, 10); // People in the qeue ASSERT (len == 0); Write (BUF, LEN); return 1; }}} int sGui::GUI_statusMessage (const char *txt ) {{{ // (0xB4) if (!auth) return 0; size_t cnt = strlen(txt); if (cnt == 0) return 0; // ed2k_gui does not need a trailing LF char *temp = STRDUP(txt); if ( temp[cnt-1] == '\n' ) { temp[cnt-1] = 0; --cnt; } if (logSend('>', this, CO_STATUS_MSG, true)) printf("%s\n", txt); cnt = strlen(temp); if (cnt == 0 ) { free (temp); return 1; } size_t len, LEN = len = 6 + 2 + cnt; unsigned char *buf, *BUF = buf = reinterpret_cast(alloca (LEN)); ADD_U1 (&buf, &len, OP_EDONKEYHEADER); ADD_U4 (&buf, &len, LEN - 5); ADD_U1 (&buf, &len, CO_STATUS_MSG); ADD_S2 (&buf, &len, temp); ASSERT (len == 0); Write (BUF, LEN); free (temp); return 1; }}} int sGui::GUI_errorMessage (const char *txt ) {{{ // (0xB5) Currently not used if (!auth) return 0; logSend('>', this, CO_ERROR_MSG, false); size_t len, LEN = len = 6 + 2 + strlen(txt); unsigned char *buf, *BUF = buf = reinterpret_cast(alloca (LEN)); ADD_U1 (&buf, &len, OP_EDONKEYHEADER); ADD_U4 (&buf, &len, LEN - 5); ADD_U1 (&buf, &len, CO_ERROR_MSG); ADD_S2 (&buf, &len, txt); ASSERT (len == 0); Write (BUF, LEN); return 1; }}} int sGui::GUI_connected_to (const char* to_name ) {{{ // (0xB6) if (!auth) return 0; logSend('>', this, CO_CONNECTED_TO, false); size_t len, LEN = len = 6 + 2 + strlen(to_name); unsigned char *buf, *BUF = buf = reinterpret_cast(alloca (LEN)); ADD_U1 (&buf, &len, OP_EDONKEYHEADER); ADD_U4 (&buf, &len, LEN - 5); ADD_U1 (&buf, &len, CO_CONNECTED_TO); ADD_S2 (&buf, &len, to_name); ASSERT (len == 0); Write (BUF, LEN); announced_server_connect = true; return 1; }}} int sGui::GUI_disconnected (void ) {{{ // (0xB7) if (!auth) return 0; if ( announced_server_connect == false ) return 1; // Dont send disconnect twice logSend('>', this, CO_DISCONNECTED, false); size_t len, LEN = len = 6 ; unsigned char *buf, *BUF = buf = reinterpret_cast(alloca (LEN)); ADD_U1 (&buf, &len, OP_EDONKEYHEADER); ADD_U4 (&buf, &len, LEN - 5); ADD_U1 (&buf, &len, CO_DISCONNECTED); ASSERT (len == 0); Write (BUF, LEN); announced_server_connect = false; return 1; }}} int sGui::GUI_result_tcp (void ) {{{ // (0xBB) if (!auth) return 0; if (resultLen() <= 0) return 0; logSend('>', this, CO_ED_NEW_SEARCH_RESULT, false); size_t len, LEN = len = 6 + resultLen(); unsigned char *buf, *BUF = buf = reinterpret_cast(alloca (LEN)); ADD_U1 (&buf, &len, OP_EDONKEYHEADER); ADD_U4 (&buf, &len, LEN - 5); ADD_U1 (&buf, &len, CO_ED_NEW_SEARCH_RESULT); memcpy (buf, resultTree(), resultLen()); Write (BUF, LEN); return 1; }}} int sGui::GUI_new_download (const class sFile *file ) {{{ // (0xBC 188) if (!auth) return 0; logSend('>', this, CO_NEW_DOWNLOAD, false); const char *tmp_name = file->Name(); const char *tmp_hash = reinterpret_cast(hash_bin2hex (file->hash)); size_t cnt = 43 + strlen(tmp_name) + strlen(tmp_hash); size_t len, LEN = len = 6 + cnt; unsigned char *buf, *BUF = buf = reinterpret_cast(alloca (LEN)); ADD_U1 (&buf, &len, OP_EDONKEYHEADER); ADD_U4 (&buf, &len, LEN - 5); ADD_U1 (&buf, &len, CO_NEW_DOWNLOAD); ADD_HASH (&buf, &len, file->hash); ADD_U4 (&buf, &len, 0); // IP ADD_U2 (&buf, &len, 0); // PORT ADD_U4 (&buf, &len, 2); // number of tags add_strTag (&buf, &len, FT_FILENAME, tmp_name); add_intTag (&buf, &len, FT_FILESIZE, file->Size()); ADD_U1 (&buf, &len, 1); // Prio ADD_S2 (&buf, &len, tmp_hash ); // uniqID ASSERT (len == 0); Write (BUF, LEN); return 1; }}} int sGui::GUI_new_upload (const class sFile *file ) {{{ // (0xBE 190) if (!auth) return 0; logSend('>', this, CO_NEW_UPLOAD, false); const char *tmp_name = "Group"; size_t cnt = 2 + strlen(file->Name()) + 40 + strlen(tmp_name); size_t len, LEN = len = 6 + cnt; unsigned char *buf, *BUF = buf = reinterpret_cast(alloca (LEN)); ADD_U1 (&buf, &len, OP_EDONKEYHEADER); ADD_U4 (&buf, &len, LEN - 5); ADD_U1 (&buf, &len, CO_NEW_UPLOAD); ADD_S2 (&buf, &len, file->Name()); ADD_HASH (&buf, &len, file->hash); ADD_U4 (&buf, &len, 0 ); // IP ADD_U2 (&buf, &len, 0 ); // Port ADD_U4 (&buf, &len, 2 ); // number of tags add_strTag (&buf, &len, FT_FILENAME, tmp_name); add_intTag (&buf, &len, FT_FILESIZE, file->Size()); ASSERT (len == 0); Write (BUF, LEN); return 1; }}} int sGui::GUI_removeDownload (tHash &hash ) {{{ // (0xBD) if (!auth) return 0; if (!validSocket()) return 0; if (logSend('>', this, CO_REMOVE_DOWNLOAD, true)) printf("%32s\n", hash_bin2hex(hash)); size_t len, LEN = len = 6 + HASH_LEN; unsigned char *buf, *BUF = buf = reinterpret_cast(alloca (LEN)); ADD_U1 (&buf, &len, OP_EDONKEYHEADER); ADD_U4 (&buf, &len, LEN - 5); ADD_U1 (&buf, &len, CO_REMOVE_DOWNLOAD); ADD_HASH(&buf, &len, hash); ASSERT (len == 0); Write (BUF, LEN); return 1; }}} int sGui::GUI_dl_status (void ) {{{ // (0xC5 197) if (!auth) return 0; logSend('>', this, CO_DOWNLOAD_STATUS, false); int cnt = sFile::count - sFile::count_complete; cnt = 0; { FILE_LIST if (! akt->get_Completed() ) cnt++; } int cnt1 = 2 + 13 * cnt; size_t len, LEN = len = 6 + cnt1; unsigned char *buf, *BUF = buf = reinterpret_cast(alloca (LEN)); ADD_U1 (&buf, &len, OP_EDONKEYHEADER); ADD_U4 (&buf, &len, LEN - 5); ADD_U1 (&buf, &len, CO_DOWNLOAD_STATUS); ADD_U2 (&buf, &len, cnt) ; // NUM of DL uint16_t dl_id = 0; FILE_LIST {{{ // Information about all files if ( akt->get_Completed() ) continue; // dont show finished files in main view ADD_U2 (&buf, &len, dl_id++); // DL_ID uint8_t akt_status = STATUS_LOOKING; uint8_t akt_sources = 255; if (akt->downloads < akt_sources) akt_sources = akt->downloads; if (akt->downloads > 0 ) akt_status = STATUS_DOWNLOADING; if (akt->Pause () ) akt_status = STATUS_PAUSED; if (akt->status == ALL_DONE ) akt_status = STATUS_DONE; ADD_U1 (&buf, &len, akt_status); // DL_STATUS ADD_F4 (&buf, &len, akt->dlRate() /1024.0); // current speed // printf("akt->transfered %u\n", akt->transfered); // printf("akt->name %s\n", akt->Name()); // ASSERT(akt->transfered < 1000); ADD_U4 (&buf, &len, akt->transfered) ; // kb transferred unsigned not_full = 0; unsigned trying = 0; unsigned maxCount = (akt->size + PARTSIZE - 1) / PARTSIZE; tHash hash; memcpy (hash, akt->hash , HASH_LEN); for (unsigned i = 0; i < maxCount; i++) { if (akt->partStatus(i)) continue; not_full ++; if (sourceCount4Part (hash, i, 1)) trying++; } uint8_t percent = 100; if (not_full > 0) percent = (trying * 100) / not_full; ADD_U1 (&buf, &len, percent); // % avalable ADD_U1 (&buf, &len, akt_sources); // sources (max 255 shown) count OK but Gui show other value WHY ? }}} ASSERT (len == 0); Write (BUF, LEN); dl_timeout = currentTime; return 1; }}} int sGui::GUI_ul_status (void ) {{{ // (0xC6 218) Mehr Infos would be nice if (!auth) return 0; logSend('>', this, CO_UPLOAD_STATUS, false); int cnt = sFile::count; if (cnt > 65535) cnt = 65535; int cnt1 = 2 + 6 * cnt; size_t len, LEN = len = 6 + cnt1; unsigned char *buf, *BUF = buf = reinterpret_cast(alloca (LEN)); ADD_U1 (&buf, &len, OP_EDONKEYHEADER); ADD_U4 (&buf, &len, LEN - 5); ADD_U1 (&buf, &len, CO_UPLOAD_STATUS); ADD_U2 (&buf, &len, (cnt)); // NUM of DL uint16_t ul_id = 0; FILE_LIST { // LOOP through all files ADD_U2 (&buf, &len, ul_id++); // UL_ID-1 since here is no extra info ADD_F4 (&buf, &len, akt->ulRate() / 1024.0); // current speed } ASSERT (len == 0); Write (BUF, LEN); ul_timeout = currentTime; return 1; }}} int sGui::GUI_send_option (void ) {{{ // (0xC7) if (!auth) return 0; logSend ('>', this, CO_OPTIONS, false); size_t len, LEN = len = 6 + 39 + strlen(client_name) + strlen(incoming) + strlen(completed); unsigned char *buf, *BUF = buf = reinterpret_cast(alloca (LEN)); ADD_U1 (&buf, &len, OP_EDONKEYHEADER); ADD_U4 (&buf, &len, LEN - 5); ADD_U1 (&buf, &len, CO_OPTIONS); ADD_U2 (&buf, &len, (my_version)); // client version ADD_F4 (&buf, &len, dlSecond / 1024.0); // max down ADD_F4 (&buf, &len, ulSecond / 1024.0); // max up ADD_U2 (&buf, &len, pref.ports.client); // doorport ADD_U2 (&buf, &len, 0); // CRAP (deprecated) ADD_S2 (&buf, &len, client_name); // client name ADD_S2 (&buf, &len, incoming); // temp dir ADD_S2 (&buf, &len, completed); // incoming dir (completed dir) ADD_U1 (&buf, &len, 0); // DUMMY if overnet ADD_U1 (&buf, &len, 0); // DUMMY if overnet ADD_U1 (&buf, &len, 1); // allow private message ADD_U1 (&buf, &len, 1); // save corrupt ADD_U1 (&buf, &len, 1); // DUMMY ADD_U2 (&buf, &len, pref.ports.gui); // admin port ADD_U4 (&buf, &len, TCP_CLIENT_COUNT); // max connections ADD_U4 (&buf, &len, 0x020c0800); // core build date ADD_F4 (&buf, &len, (dlSecond + ulSecond) / 1024.0); // line download speed if (len != 0) printf("len = %i\n", len); ASSERT (len == 0); Write (BUF, LEN); Code(0x01); return 1; }}} int sGui::GUI_share_dirs (void ) {{{ // (0xD7) // sende meine shared dirs an die GUI logSend('>', this, CO_SHARED_DIRS, false); if (!auth) return 0; if (completed == NULL ) return 0; size_t cnt = 2 + 2 + strlen(completed); size_t len, LEN = len = 6 + cnt; unsigned char *buf, *BUF = buf = reinterpret_cast(alloca (LEN)); ADD_U1 (&buf, &len, OP_EDONKEYHEADER); ADD_U4 (&buf, &len, LEN - 5); ADD_U1 (&buf, &len, CO_SHARED_DIRS); ADD_U2 (&buf, &len, 1); ADD_S2 (&buf, &len, completed); ASSERT (len == 0); Write (BUF, LEN); return 1; }}} int sGui::GUI_login (sPacket *packet) {{{ // (0x64) logSend ('<', this, CO_LOGIN, false); if (packet == NULL) return 0; if (ctrl_pass == NULL || ctrl_user == NULL) return 0; char *log_name = packet->GET_S2 (); char *pass = packet->GET_S2 (); if ( 0 != strcmp (log_name, ctrl_user) || 0 != strcmp (pass, ctrl_pass)) {{{ printf("Gui DENY:%s pass:%s\n", log_name, pass ); Free2 (log_name); Free2 (pass); Close(); return 0; }}} auth = true; Code(0x64); Free2 (log_name); Free2 (pass); FILE_LIST { if ( ! akt->get_Completed() ) GUI_new_download (akt); GUI_new_upload(akt); } if ( tcp_server != NULL ) { // Stati which will be ignored for successful connection if ( tcp_server->Status() >= 4 && tcp_server->Status() <= 15 && tcp_server->Status() != SERVER_CLOSED && tcp_server->Status() != WAIT_SERVER_LIST ) { struct eServers *s = Server_ip (tcp_server->peer_ip); if ( s != NULL ) { char tmpname[33]; printf("XXX connected to %15s,%s Status: %i \n", inet_ntoa( s->ip ), s->name, tcp_server->Status() ); if ( strlen( s->name ) == 0 ) { // s->name ist leider nicht immer gesetzt (BUG?). Wir verwenden dann die IP // This is legal if the server have not yet respond with its name snprintf(tmpname,33, "%15s", inet_ntoa( s->ip ) ); GUI_connected_to(tmpname); } else GUI_connected_to(s->name); } } } return 1; }}} int sGui::GUI_shutdown (sPacket * ) {{{ // (0x65) logSend ('<', this, CO_SHUTDOWN, false); if (!auth) return 0; running = false; return 1; }}} int sGui::GUI_txt_command (sPacket *packet) {{{ // (0x66) logSend ('<', this, CO_TXTCOMMAND, false); if (packet == NULL) return 0; if (!auth) return 0; char *text = packet->GET_S2 (); const char *msg = sCommand::Execute(text); GUI_statusMessage (msg); Free2 (text); return 1; }}} int sGui::GUI_connect (sPacket *packet) {{{ // (0xC8) if (packet == NULL) return 0; struct in_addr ip; uint16_t new_port; char logbuf[256]; ip.s_addr = packet->GET_U4(); new_port = packet->GET_U2(); if (ip.s_addr == 0) { if (logSend('<', this, CO_CONNECT, true)) printf("RANDOM\n"); struct in_addr new_ip; if (tcp_server != NULL) delete tcp_server; GUI_disconnected(); if (nextServer (&new_ip, &new_port)) { tcp_server = new sServer (new_ip, new_port); snprintf(logbuf,255, "Trying Edonkey Server: %15s\n", inet_ntoa(new_ip) ); log (1,logbuf); GUI_LIST akt->GUI_statusMessage(logbuf); } return 1; } if (logSend('<', this, CO_CONNECT, true)) printf("SELECTED %15s:%5u\n", inet_ntoa(ip), new_port); if (tcp_server != NULL) delete tcp_server; GUI_disconnected(); tcp_server = new sServer (ip, new_port); snprintf(logbuf,255, "Trying Edonkey Server: %15s\n", inet_ntoa(ip) ); log (1,logbuf); GUI_LIST akt->GUI_statusMessage(logbuf); return 1; }}} int sGui::GUI_disconnect (sPacket * ) {{{ // (0xC9) logSend ('<', this, CO_DISCONNECT, false); if (tcp_server != NULL) delete tcp_server ; //tcp_server->Close(); tcp_server = NULL ; GUI_disconnected(); return 1; }}} int sGui::GUI_search (sPacket *packet) {{{ // (0xCA) if (packet == NULL) return 0; logSend ('<', this, CO_SEARCH, false); uint32_t len = packet->Length() - 1; char *tree = reinterpret_cast(MALLOC (len)); memcpy (tree, packet->DATA(), len); packet->GET_U1 (); char *searchstr = packet->GET_S2 (); log (1,"Searching: %s\n", searchstr) ; free(searchstr); searchTree (tree, len); tcp_search = true; return 1; }}} int sGui::GUI_search_ext (sPacket * ) {{{ // (0xCB) logSend ('<', this, CO_EXSEARCH, false); userver_listen->UDP_search4gui(this); return 1; }}} int sGui::req_download (sPacket *packet) {{{ // (0xCF) logSend ('<', this, CO_DOWNLOAD, false); tHash hash; packet->GET_HASH(hash); if (NULL != forHash(hash)) return 1; //dl already exists printf("HASH %32s\n", hash_bin2hex(hash)); const struct eFiles *f = nextFile(hash, true); printf("Found %i\n", cursor_count); while (f != NULL) { if (f->info_len != 0) { size_t len = f->info_len; unsigned char *dat = reinterpret_cast(alloca(len)); memcpy(dat, f->info, len); class sTag *tag = parse_tag (dat, &len); if (tag == NULL) { Free2 (dat); printf("bad\n"); break; } if (tag->size > 0 && tag->name != NULL) { sFile *file = new sFile (hash, tag->name, tag->size, incoming); GUI_new_download (file); GUI_new_upload (file); delete tag; return 1; } delete tag; } f = nextFile(hash, false); } return 1; }}} int sGui::GUI_dlPause (sPacket *packet) {{{ // (0xD0) if (packet == NULL) return 0; logSend ('<', this, CO_PAUSE_DOWNLOAD, false); tHash hash; packet->GET_HASH (hash); sFile *file = forHash (hash); if (file == NULL) return 1; file->Pause (1); return 1; }}} int sGui::GUI_dlResume (sPacket *packet) {{{ // (0xD1) if (packet == NULL) return 0; logSend ('<', this, CO_RESUME_DOWNLOAD, false); tHash hash; packet->GET_HASH (hash); sFile *file = forHash (hash); if (file == NULL) return 1; file->Pause (0); return 1; }}} int sGui::GUI_cancelDownload (sPacket *packet) {{{ // (0xD2) if (packet == NULL) return 0; logSend ('<', this, CO_CANCEL_DOWNLOAD, false); tHash hash; packet->GET_HASH (hash); sFile *file = forHash (hash); delete file; char *alt = reinterpret_cast(alloca (strlen(control) + 43)); char *neu = reinterpret_cast(alloca (strlen(control) + 43)); sprintf (alt, "%s%c%s.part.met" , control, dir_delim, hash_bin2hex (hash)); sprintf (neu, "%s%c%s.part.old" , control, dir_delim, hash_bin2hex (hash)); rename(alt, neu); return 1; }}} int sGui::GUI_download_prio (sPacket *packet) {{{ // (0xD3) if (packet == NULL) return 0; logSend ('<', this, CO_SETPRI_DOWNLOAD, false); tHash hash; packet->GET_HASH (hash); uint8_t sprio = packet->GET_U1 (); printf("Prio %u\n",sprio); if (sprio>2) return 1; sFile *file = forHash (hash); if (file == NULL) return 1; file->dlPrio (sprio); return 1; }}} int sGui::GUI_get_serverlist (sPacket * ) {{{ // (0xD5) // Gui request for server List if (!auth) return 0; logSend ('<', this, CO_GET_SERVERLIST, false); GUI_serverlist (); return 1; }}} int sGui::GUI_req_shared_dir (sPacket * ) {{{ // (0xD7) if(!auth) return 0; logSend ('<', this, CO_GET_SHARE_DIRS, false); GUI_share_dirs (); return 1; }}} int sGui::GUI_dlStatus_start (sPacket * ) {{{ // (0xD9) logSend ('<', this, CO_START_DL_STATUS, false); dl_status = true; if(!auth) return 0; GUI_dl_status(); return 1; }}} int sGui::GUI_dlStatus_stop (sPacket * ) {{{ // (0xDA) logSend ('<', this, CO_STOP_DL_STATUS, false); if(!auth) return 0; dl_status = false; return 1; }}} int sGui::GUI_ulStatus_start (sPacket * ) {{{ // (0xDB) if(!auth) return 0; logSend ('<', this, CO_START_UL_STATUS, false); ul_status = true; GUI_ul_status(); return 1; }}} int sGui::GUI_ulStatus_stop (sPacket * ) {{{ // (0xDC) if(!auth) return 0; logSend ('<', this, CO_STOP_UL_STATUS, false); ul_status = false; return 1; }}} int sGui::GUI_serverDelete (sPacket *packet) {{{ // (0xDD) if (packet == NULL || !auth) return 0; logSend ('<', this, CO_DELETE_SERVER, false); struct in_addr ip; uint16_t new_port; ip.s_addr = packet->GET_U4 (); new_port = packet->GET_U2 (); delServer (ip, new_port, -7); return 1; }}} int sGui::GUI_serverAdd (sPacket *packet) {{{ // (0xDE) if (packet == NULL || !auth) return 0; logSend ('<', this, CO_ADD_SERVER, false); struct in_addr ip; uint16_t new_port; ip.s_addr = packet->GET_U4 (); new_port = packet->GET_U2 (); saveServer (ip, new_port, 0, 0, true); return 1; }}} int sGui::GUI_serverPrio (sPacket *packet) {{{ // (0xDF) if (packet == NULL) return 0; logSend ('<', this, CO_SETPRI_SERVER, false); if(!auth) return 0; struct in_addr ip; ip.s_addr = packet->GET_U4 (); uint16_t new_port = packet->GET_U2 (); uint8_t new_prio = packet->GET_U1 (); setServer_prio (ip, new_port, new_prio); return 1; }}} int sGui::GUI_get_shareFiles (sPacket * ) {{{ // (0xE0) if (!auth) return 0; logSend ('<', this, CO_GET_SHARE_FILES, false); GUI_shareFiles(); Code(0xE0); // ? return 1; }}} int sGui::GUI_get_option (sPacket * ) {{{ // (0xE1) if (!auth) return 0; logSend ('<', this, CO_GET_OPTIONS, false); GUI_send_option (); return 1; }}} int sGui::GUI_add_download (sPacket *packet) {{{ // (0xE2) if (packet == NULL) return 0; logSend ('<', this, CO_REQ_NEW_DOWNLOAD, false); tHash hash; packet->GET_HASH(hash); if (NULL != forHash(hash)) return 1; // dl already exists packet->GET_U4 ( ); packet->GET_U2 ( ); class sTag *tag = parseTag (packet); if (tag == NULL) return 0; if (tag->name != NULL && tag->size > 0) new sFile (hash, tag->name, tag->size, incoming); delete tag; return 1; }}} int sGui::GUI_req_part_status (sPacket *packet) {{{ // (0xE3) if (packet == NULL) return 0; logSend ('<', this, CO_GET_GAP_DETAILS, false); tHash hash; packet->GET_HASH(hash); return GUI_res_part_status (hash); }}} int sGui::GUI_core_status_get (sPacket * ) {{{ // (0xe4) if (!auth) return 0; return GUI_core_status (); }}} int sGui::Donkey_gui (class sPacket *packet) {{{ if (packet == NULL) return 0; if (packet->Proto() != OP_EDONKEYHEADER) return 0; switch (packet->Command ()) { // case 0xCC : More Search // case 0xCD : Search User // case 0xD8 : Set Share Dirs // case 0xCE : ext Search user case 0xD6 : return 1; // Get Friend List (if anyone wan't it) // case 0xD4 : View Friend Files // case 0xE4 : return 1; // Request Client Stats case 0x64 : return GUI_login (packet); case 0x65 : return GUI_shutdown (packet); case 0x66 : return GUI_txt_command (packet); case 0xC8 : return GUI_connect (packet); case 0xC9 : return GUI_disconnect (packet); case 0xCA : return GUI_search (packet); case 0xCB : return GUI_search_ext (packet); case 0xCF : return req_download (packet); case 0xD0 : return GUI_dlPause (packet); // Pause Download case 0xD1 : return GUI_dlResume (packet); // Resume Download case 0xD2 : return GUI_cancelDownload (packet); case 0xD3 : return GUI_download_prio (packet); // Prio Download <8 bit> case 0xD5 : return GUI_get_serverlist (packet); case 0xD7 : return GUI_req_shared_dir (packet); case 0xD9 : return GUI_dlStatus_start (packet); case 0xDA : return GUI_dlStatus_stop (packet); case 0xDB : return GUI_ulStatus_start (packet); case 0xDC : return GUI_ulStatus_stop (packet); case 0xDD : return GUI_serverDelete (packet); case 0xDE : return GUI_serverAdd (packet); case 0xDF : return GUI_serverPrio (packet); case 0xE0 : return GUI_get_shareFiles (packet); case 0xE1 : return GUI_get_option (packet); case 0xE2 : return GUI_add_download (packet); case 0xE3 : return GUI_req_part_status (packet); case 0xE4 : return GUI_core_status_get (packet); default : logSend ('<', this, packet->Command (), false); break; } packet->Dump (); return 0; }}} void sGui::readWork(void) {{{ if (READ->Proto() == OP_EDONKEYHEADER) Donkey_gui (READ); else READ->Dump(); READ->readReset(); }}} void sGui::Work (void) {{{ if (!validSocket()) return; if(!auth) return; if (dl_timeout + 3 < currentTime || dl_timeout > currentTime) dl_timeout = currentTime; if (ul_timeout + 3 < currentTime || ul_timeout > currentTime) ul_timeout = currentTime; if(dl_timeout + 1 < currentTime && dl_status) GUI_dl_status(); if(ul_timeout + 1 < currentTime && ul_status) GUI_ul_status(); return; }}} /* * vim600: fdm=marker */