1// 2// This file is part of the aMule Project. 3// 4// Copyright (c) 2003-2011 Angel Vidal ( kry@amule.org ) 5// Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org ) 6// 7// Any parts of this program derived from the xMule, lMule or eMule project, 8// or contributed by third-party developers are copyrighted by their 9// respective authors. 10// 11// This program is free software; you can redistribute it and/or modify 12// it under the terms of the GNU General Public License as published by 13// the Free Software Foundation; either version 2 of the License, or 14// (at your option) any later version. 15// 16// This program is distributed in the hope that it will be useful, 17// but WITHOUT ANY WARRANTY; without even the implied warranty of 18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19// GNU General Public License for more details. 20// 21// You should have received a copy of the GNU General Public License 22// along with this program; if not, write to the Free Software 23// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 24// 25 26 27#ifdef HAVE_CONFIG_H 28 #include "config.h" // Needed for VERSION 29#endif 30 31#include <common/ClientVersion.h> 32 33#include "TextClient.h" 34 35#ifndef __WXMSW__ 36 #include <unistd.h> // Do_not_auto_remove 37#endif 38 39 40//------------------------------------------------------------------- 41 42 43//------------------------------------------------------------------- 44 45#include <ec/cpp/ECSpecialTags.h> 46 47#include <wx/tokenzr.h> 48 49#include <common/Format.h> // Needed for CFormat 50#include "OtherFunctions.h" 51#include "KnownFile.h" // Needed for Priority Levels 52#include "DataToText.cpp" // Needed for PriorityToStr 53 54#define APP_INIT_SIZE_X 640 55#define APP_INIT_SIZE_Y 480 56 57#define theApp (*((CamulecmdApp*)wxTheApp)) 58 59//------------------------------------------------------------------- 60 61enum { 62 CMD_ID_STATUS, 63 CMD_ID_RESUME, 64 CMD_ID_PAUSE, 65 CMD_ID_PRIORITY_LOW, 66 CMD_ID_PRIORITY_NORMAL, 67 CMD_ID_PRIORITY_HIGH, 68 CMD_ID_PRIORITY_AUTO, 69 CMD_ID_CANCEL, 70 CMD_ID_CONNECT, 71 CMD_ID_CONNECT_ED2K, 72 CMD_ID_CONNECT_KAD, 73 CMD_ID_DISCONNECT, 74 CMD_ID_DISCONNECT_ED2K, 75 CMD_ID_DISCONNECT_KAD, 76 CMD_ID_RELOAD_SHARED, 77 CMD_ID_RELOAD_IPFILTER_LOCAL, 78 CMD_ID_RELOAD_IPFILTER_NET, 79 CMD_ID_SET_IPFILTER_ON, 80 CMD_ID_SET_IPFILTER_OFF, 81 CMD_ID_SET_IPFILTER_CLIENTS_ON, 82 CMD_ID_SET_IPFILTER_CLIENTS_OFF, 83 CMD_ID_SET_IPFILTER_SERVERS_ON, 84 CMD_ID_SET_IPFILTER_SERVERS_OFF, 85 CMD_ID_SET_IPFILTER_LEVEL, 86 CMD_ID_GET_IPFILTER, 87 CMD_ID_GET_IPFILTER_STATE, 88 CMD_ID_GET_IPFILTER_STATE_CLIENTS, 89 CMD_ID_GET_IPFILTER_STATE_SERVERS, 90 CMD_ID_GET_IPFILTER_LEVEL, 91 CMD_ID_SHOW_UL, 92 CMD_ID_SHOW_DL, 93 CMD_ID_SHOW_LOG, 94 CMD_ID_SHOW_SERVERS, 95 CMD_ID_SHOW_SHARED, 96 CMD_ID_RESET_LOG, 97 CMD_ID_SHUTDOWN, 98 CMD_ID_ADDLINK, 99 CMD_ID_SET_BWLIMIT_UP, 100 CMD_ID_SET_BWLIMIT_DOWN, 101 CMD_ID_GET_BWLIMITS, 102 CMD_ID_STATTREE, 103 CMD_ID_SEARCH, 104 CMD_ID_SEARCH_GLOBAL, 105 CMD_ID_SEARCH_LOCAL, 106 CMD_ID_SEARCH_KAD, 107 CMD_ID_SEARCH_RESULTS, 108 CMD_ID_SEARCH_PROGRESS, 109 CMD_ID_DOWNLOAD, 110 // IDs for deprecated commands 111 CMD_ID_SET_IPFILTER 112 113}; 114 115// method to create a SearchFile 116SearchFile::SearchFile(CEC_SearchFile_Tag *tag) 117{ 118 nHash = tag->FileHash(); 119 sHash = nHash.Encode(); 120 sFileName = tag->FileName(); 121 lFileSize = tag->SizeFull(); 122 lSourceCount = tag->SourceCount(); 123 bPresent = tag->AlreadyHave(); 124} 125 126//------------------------------------------------------------------- 127IMPLEMENT_APP (CamulecmdApp) 128//------------------------------------------------------------------- 129 130void CamulecmdApp::OnInitCmdLine(wxCmdLineParser& parser) 131{ 132 CaMuleExternalConnector::OnInitCmdLine(parser, "amulecmd"); 133 parser.AddOption(wxT("c"), wxT("command"), 134 _("Execute <str> and exit."), 135 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL); 136} 137 138bool CamulecmdApp::OnCmdLineParsed(wxCmdLineParser& parser) 139{ 140 m_HasCmdOnCmdLine = parser.Found(wxT("command"), &m_CmdString); 141 if (m_CmdString.Lower().StartsWith(wxT("help"))) 142 { 143 OnInitCommandSet(); 144 printf("%s %s\n", m_appname, (const char *)unicode2char(GetMuleVersion())); 145 Parse_Command(m_CmdString); 146 exit(0); 147 } 148 m_interactive = !m_HasCmdOnCmdLine; 149 return CaMuleExternalConnector::OnCmdLineParsed(parser); 150} 151 152void CamulecmdApp::TextShell(const wxString& prompt) 153{ 154 if (m_HasCmdOnCmdLine) 155 Parse_Command(m_CmdString); 156 else 157 CaMuleExternalConnector::TextShell(prompt); 158} 159 160int CamulecmdApp::ProcessCommand(int CmdId) 161{ 162 wxString args = GetCmdArgs(); 163 CECPacket *request = 0; 164 std::list<CECPacket *> request_list; 165 int tmp_int = 0; 166 EC_SEARCH_TYPE search_type = EC_SEARCH_KAD; 167 168 // Implementation of the deprecated command 'SetIPFilter'. 169 if (CmdId == CMD_ID_SET_IPFILTER) { 170 if ( ! args.IsEmpty() ) { 171 if (args.IsSameAs(wxT("ON"), false)) { 172 CmdId = CMD_ID_SET_IPFILTER_ON; 173 } else if (args.IsSameAs(wxT("OFF"), false)) { 174 CmdId = CMD_ID_SET_IPFILTER_OFF; 175 } else { 176 return CMD_ERR_INVALID_ARG; 177 } 178 } else { 179 CmdId = CMD_ID_GET_IPFILTER_STATE; 180 } 181 } 182 183 switch (CmdId) { 184 case CMD_ID_STATUS: 185 request_list.push_back(new CECPacket(EC_OP_STAT_REQ, EC_DETAIL_CMD)); 186 break; 187 188 case CMD_ID_SHUTDOWN: 189 request_list.push_back(new CECPacket(EC_OP_SHUTDOWN)); 190 break; 191 192 case CMD_ID_CONNECT: 193 if ( !args.IsEmpty() ) { 194 unsigned int ip[4]; 195 unsigned int port; 196 // Not much we can do against this unicode2char. 197 int result = sscanf(unicode2char(args), "%d.%d.%d.%d:%d", &ip[0], &ip[1], &ip[2], &ip[3], &port); 198 if (result != 5) { 199 // Try to resolve DNS -- good for dynamic IP servers 200 wxString serverName(args.BeforeFirst(wxT(':'))); 201 long lPort; 202 bool ok = args.AfterFirst(wxT(':')).ToLong(&lPort); 203 port = (unsigned int)lPort; 204 wxIPV4address a; 205 a.Hostname(serverName); 206 a.Service(port); 207 result = sscanf(unicode2char(a.IPAddress()), "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]); 208 if (serverName.IsEmpty() || !ok || (result != 4)) { 209 Show(_("Invalid IP format. Use xxx.xxx.xxx.xxx:xxxx\n")); 210 return 0; 211 } 212 } 213 EC_IPv4_t addr; 214 addr.m_ip[0] = ip[0]; 215 addr.m_ip[1] = ip[1]; 216 addr.m_ip[2] = ip[2]; 217 addr.m_ip[3] = ip[3]; 218 addr.m_port = port; 219 request = new CECPacket(EC_OP_SERVER_CONNECT); 220 request->AddTag(CECTag(EC_TAG_SERVER, addr)); 221 request_list.push_back(request); 222 } else { 223 request_list.push_back(new CECPacket(EC_OP_CONNECT)); 224 } 225 break; 226 227 case CMD_ID_CONNECT_ED2K: 228 request_list.push_back(new CECPacket(EC_OP_SERVER_CONNECT)); 229 break; 230 231 case CMD_ID_CONNECT_KAD: 232 request_list.push_back(new CECPacket(EC_OP_KAD_START)); 233 break; 234 235 case CMD_ID_DISCONNECT: 236 request_list.push_back(new CECPacket(EC_OP_DISCONNECT)); 237 break; 238 239 case CMD_ID_DISCONNECT_ED2K: 240 request_list.push_back(new CECPacket(EC_OP_SERVER_DISCONNECT)); 241 break; 242 243 case CMD_ID_DISCONNECT_KAD: 244 request_list.push_back(new CECPacket(EC_OP_KAD_STOP)); 245 break; 246 247 case CMD_ID_RELOAD_SHARED: 248 request_list.push_back(new CECPacket(EC_OP_SHAREDFILES_RELOAD)); 249 break; 250 251 case CMD_ID_RELOAD_IPFILTER_LOCAL: 252 request_list.push_back(new CECPacket(EC_OP_IPFILTER_RELOAD)); 253 break; 254 255 case CMD_ID_RELOAD_IPFILTER_NET: 256 request = new CECPacket(EC_OP_IPFILTER_UPDATE); 257 request->AddTag(EC_TAG_STRING, args); 258 request_list.push_back(request); 259 break; 260 261 case CMD_ID_SET_IPFILTER_ON: 262 case CMD_ID_SET_IPFILTER_CLIENTS_ON: 263 case CMD_ID_SET_IPFILTER_SERVERS_ON: 264 tmp_int = 1; 265 case CMD_ID_SET_IPFILTER_OFF: 266 case CMD_ID_SET_IPFILTER_CLIENTS_OFF: 267 case CMD_ID_SET_IPFILTER_SERVERS_OFF: 268 { 269 if (CmdId == CMD_ID_SET_IPFILTER_CLIENTS_ON || CmdId == CMD_ID_SET_IPFILTER_CLIENTS_OFF) { 270 CmdId = CMD_ID_GET_IPFILTER_STATE_CLIENTS; 271 } else if (CmdId == CMD_ID_SET_IPFILTER_SERVERS_ON || CmdId == CMD_ID_SET_IPFILTER_SERVERS_OFF) { 272 CmdId = CMD_ID_GET_IPFILTER_STATE_SERVERS; 273 } else { 274 CmdId = CMD_ID_GET_IPFILTER_STATE; 275 } 276 277 request = new CECPacket(EC_OP_SET_PREFERENCES); 278 CECEmptyTag prefs(EC_TAG_PREFS_SECURITY); 279 if (CmdId != CMD_ID_GET_IPFILTER_STATE_SERVERS) { 280 prefs.AddTag(CECTag(EC_TAG_IPFILTER_CLIENTS, (uint8)tmp_int)); 281 } 282 if (CmdId != CMD_ID_GET_IPFILTER_STATE_CLIENTS) { 283 prefs.AddTag(CECTag(EC_TAG_IPFILTER_SERVERS, (uint8)tmp_int)); 284 } 285 request->AddTag(prefs); 286 request_list.push_back(request); 287 } 288 case CMD_ID_GET_IPFILTER: 289 case CMD_ID_GET_IPFILTER_STATE: 290 case CMD_ID_GET_IPFILTER_STATE_CLIENTS: 291 case CMD_ID_GET_IPFILTER_STATE_SERVERS: 292 request = new CECPacket(EC_OP_GET_PREFERENCES); 293 request->AddTag(CECTag(EC_TAG_SELECT_PREFS, (uint32)EC_PREFS_SECURITY)); 294 request_list.push_back(request); 295 break; 296 297 case CMD_ID_SET_IPFILTER_LEVEL: 298 if (!args.IsEmpty()) // This 'if' must stay as long as we support the deprecated 'IPLevel' command. 299 { 300 unsigned long int level = 0; 301 if (args.ToULong(&level) == true && level < 256) { 302 request = new CECPacket(EC_OP_SET_PREFERENCES); 303 CECEmptyTag prefs(EC_TAG_PREFS_SECURITY); 304 prefs.AddTag(CECTag(EC_TAG_IPFILTER_LEVEL, (uint8)level)); 305 request->AddTag(prefs); 306 request_list.push_back(request); 307 } else { 308 return CMD_ERR_INVALID_ARG; 309 } 310 } 311 CmdId = CMD_ID_GET_IPFILTER_LEVEL; 312 case CMD_ID_GET_IPFILTER_LEVEL: 313 request = new CECPacket(EC_OP_GET_PREFERENCES); 314 request->AddTag(CECTag(EC_TAG_SELECT_PREFS, (uint32)EC_PREFS_SECURITY)); 315 request_list.push_back(request); 316 break; 317 318 case CMD_ID_PAUSE: 319 case CMD_ID_CANCEL: 320 case CMD_ID_RESUME: 321 { 322 if ( args.IsEmpty() ) { 323 Show(_("This command requires an argument. Valid arguments: 'all', filename, or a number.\n")); 324 return 0; 325 } else { 326 wxStringTokenizer argsTokenizer(args); 327 wxString token; 328 CMD4Hash hash; 329 330 // Grab the entire dl queue right away 331 CECPacket request_all(EC_OP_GET_DLOAD_QUEUE, EC_DETAIL_CMD); 332 const CECPacket *reply_all = SendRecvMsg_v2(&request_all); 333 334 if (reply_all) { 335 switch(CmdId) { 336 case CMD_ID_PAUSE: 337 request = new CECPacket(EC_OP_PARTFILE_PAUSE); break; 338 case CMD_ID_CANCEL: 339 request = new CECPacket(EC_OP_PARTFILE_DELETE); break; 340 case CMD_ID_RESUME: 341 request = new CECPacket(EC_OP_PARTFILE_RESUME); break; 342 default: wxFAIL; 343 } 344 345 // We loop through all the arguments 346 while(argsTokenizer.HasMoreTokens()) { 347 token=argsTokenizer.GetNextToken(); 348 349 // If the user requested all, then we select all files and exit the loop 350 // since there is little point to add anything more to "everything" 351 if( token == wxT("all") ) { 352 for (CECPacket::const_iterator it = reply_all->begin(); it != reply_all->end(); it++) { 353 CEC_PartFile_Tag *tag = (CEC_PartFile_Tag *) & *it; 354 request->AddTag(CECTag(EC_TAG_PARTFILE, tag->FileHash())); 355 } 356 break; 357 } else if ( hash.Decode(token.Trim(false).Trim(true)) ) { 358 if ( !hash.IsEmpty() ) { 359 Show(_("Processing by hash: "+token+wxT("\n"))); 360 request->AddTag(CECTag(EC_TAG_PARTFILE, hash)); 361 } 362 } else { 363 // Go through the dl queue and look at each filename 364 for (CECPacket::const_iterator it = reply_all->begin(); it != reply_all->end(); it++) { 365 CEC_PartFile_Tag *tag = (CEC_PartFile_Tag *) & *it; 366 wxString partmetname = tag->PartMetName(); 367 368 // We check for filename, XXX.pat.met, XXX.part, XXX 369 if( tag->FileName() == token || 370 partmetname == token || 371 partmetname.Truncate(partmetname.Len()-4) == token || 372 partmetname.Truncate(partmetname.Len()-5) == token) { 373 Show(_("Processing by filename: "+token+wxT("\n"))); 374 request->AddTag(CECTag(EC_TAG_PARTFILE, tag->FileHash())); 375 } 376 } 377 } // End of filename check else 378 } // End of argument token loop 379 380 request_list.push_back(request); 381 382 delete reply_all; 383 384 } // End of dl queue processing 385 386 } // end of command processing 387 break; 388 } 389 390 case CMD_ID_PRIORITY_LOW: 391 case CMD_ID_PRIORITY_NORMAL: 392 case CMD_ID_PRIORITY_HIGH: 393 case CMD_ID_PRIORITY_AUTO: 394 if ( args.IsEmpty() ) { 395 Show(_("This command requires an argument. Valid arguments: a file hash.\n")); 396 return 0; 397 } else { 398 CMD4Hash hash; 399 if (hash.Decode(args.Trim(false).Trim(true))) { 400 if (!hash.IsEmpty()) { 401 request = new CECPacket(EC_OP_PARTFILE_PRIO_SET); 402 CECTag hashtag(EC_TAG_PARTFILE, hash); 403 switch(CmdId) { 404 case CMD_ID_PRIORITY_LOW: 405 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_PRIO, (uint8)PR_LOW)); 406 break; 407 case CMD_ID_PRIORITY_NORMAL: 408 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_PRIO, (uint8)PR_NORMAL)); 409 break; 410 case CMD_ID_PRIORITY_HIGH: 411 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_PRIO, (uint8)PR_HIGH)); 412 break; 413 case CMD_ID_PRIORITY_AUTO: 414 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_PRIO, (uint8)PR_AUTO)); 415 break; 416 default: wxFAIL; 417 } 418 request->AddTag(hashtag); 419 request_list.push_back(request); 420 } else { 421 Show(_("Not a valid number\n")); 422 return 0; 423 } 424 } else { 425 Show(_("Not a valid hash (length should be exactly 32 chars)\n")); 426 return 0; 427 } 428 } 429 break; 430 431 case CMD_ID_SHOW_UL: 432 request_list.push_back(new CECPacket(EC_OP_GET_ULOAD_QUEUE)); 433 break; 434 435 case CMD_ID_SHOW_DL: 436 request_list.push_back(new CECPacket(EC_OP_GET_DLOAD_QUEUE)); 437 break; 438 439 case CMD_ID_SHOW_LOG: 440 request_list.push_back(new CECPacket(EC_OP_GET_LOG)); 441 break; 442 443 case CMD_ID_SHOW_SERVERS: 444 request_list.push_back(new CECPacket(EC_OP_GET_SERVER_LIST, EC_DETAIL_CMD)); 445 break; 446 447 case CMD_ID_RESET_LOG: 448 request_list.push_back(new CECPacket(EC_OP_RESET_LOG)); 449 break; 450 451 case CMD_ID_ADDLINK: 452 if (args.StartsWith(wxT("ed2k://"))) { 453 //aMule doesn't like AICH links without |/| in front of h= 454 if (args.Find(wxT("|h=")) > -1 && args.Find(wxT("|/|h=")) == -1) { 455 args.Replace(wxT("|h="),wxT("|/|h=")); 456 } 457 // repair links where | is replaced with %7C (Firefox) 458 if (args.StartsWith(wxT("ed2k://%7C"))) { 459 args.Replace(wxT("%7C"),wxT("|")); 460 } 461 } 462 request = new CECPacket(EC_OP_ADD_LINK); 463 request->AddTag(CECTag(EC_TAG_STRING, args)); 464 request_list.push_back(request); 465 break; 466 467 case CMD_ID_SET_BWLIMIT_UP: 468 tmp_int = EC_TAG_CONN_MAX_UL - EC_TAG_CONN_MAX_DL; 469 case CMD_ID_SET_BWLIMIT_DOWN: 470 tmp_int += EC_TAG_CONN_MAX_DL; 471 { 472 unsigned long int limit; 473 if (args.ToULong(&limit)) { 474 request = new CECPacket(EC_OP_SET_PREFERENCES); 475 CECEmptyTag prefs(EC_TAG_PREFS_CONNECTIONS); 476 prefs.AddTag(CECTag(tmp_int, (uint16)limit)); 477 request->AddTag(prefs); 478 request_list.push_back(request); 479 } else { 480 return CMD_ERR_INVALID_ARG; 481 } 482 } 483 case CMD_ID_GET_BWLIMITS: 484 request = new CECPacket(EC_OP_GET_PREFERENCES); 485 request->AddTag(CECTag(EC_TAG_SELECT_PREFS, (uint32)EC_PREFS_CONNECTIONS)); 486 request_list.push_back(request); 487 break; 488 489 case CMD_ID_STATTREE: 490 request = new CECPacket(EC_OP_GET_STATSTREE); 491 if (!args.IsEmpty()) { 492 unsigned long int max_versions; 493 if (args.ToULong(&max_versions)) { 494 if (max_versions < 256) { 495 request->AddTag(CECTag(EC_TAG_STATTREE_CAPPING, (uint8)max_versions)); 496 } else { 497 delete request; 498 return CMD_ERR_INVALID_ARG; 499 } 500 } else { 501 delete request; 502 return CMD_ERR_INVALID_ARG; 503 } 504 } 505 request_list.push_back(request); 506 break; 507 case CMD_ID_SEARCH_GLOBAL: 508 search_type = EC_SEARCH_GLOBAL; 509 case CMD_ID_SEARCH_LOCAL: 510 if (search_type != EC_SEARCH_GLOBAL){ 511 search_type = EC_SEARCH_LOCAL; 512 } 513 case CMD_ID_SEARCH_KAD: 514 if (search_type != EC_SEARCH_GLOBAL && search_type != EC_SEARCH_LOCAL){ 515 search_type = EC_SEARCH_KAD; 516 } 517 if (!args.IsEmpty()) 518 { 519 wxString search = args; 520 wxString type; 521 wxString extention; 522 uint32 avail = 0; 523 uint32 min_size = 0; 524 uint32 max_size = 0; 525 526 request = new CECPacket(EC_OP_SEARCH_START); 527 request->AddTag(CEC_Search_Tag (search, search_type, type, extention, avail, min_size, max_size)); 528 request_list.push_back(request); 529 } 530 break; 531 case CMD_ID_SEARCH: 532 printf("No search type defined.\nType 'help search' to get more help.\n"); 533 break; 534 535 536 case CMD_ID_SEARCH_RESULTS: 537 request_list.push_back(new CECPacket(EC_OP_SEARCH_RESULTS, EC_DETAIL_FULL)); 538 break; 539 540 case CMD_ID_SEARCH_PROGRESS: 541 request_list.push_back(new CECPacket(EC_OP_SEARCH_PROGRESS)); 542 break; 543 544 case CMD_ID_DOWNLOAD: 545 if (!args.IsEmpty()) 546 { 547 unsigned long int id = 0; 548 if (args.ToULong(&id) == true && id < m_Results_map.size()) { 549 550 SearchFile* file = m_Results_map[id]; 551 printf("Download File: %lu %s\n", id, (const char*)unicode2char(file->sFileName)); 552 request = new CECPacket(EC_OP_DOWNLOAD_SEARCH_RESULT); 553 // get with id the hash and category=0 554 uint32 category = 0; 555 CECTag hashtag(EC_TAG_PARTFILE, file->nHash); 556 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_CAT, category)); 557 request->AddTag(hashtag); 558 request_list.push_back(request); 559 } else { 560 return CMD_ERR_INVALID_ARG; 561 } 562 } 563 break; 564 565 default: 566 return CMD_ERR_PROCESS_CMD; 567 } 568 569 m_last_cmd_id = CmdId; 570 571 if ( ! request_list.empty() ) { 572 std::list<CECPacket *>::iterator it = request_list.begin(); 573 while ( it != request_list.end() ) { 574 CECPacket *curr = *it++; 575 if (curr->GetOpCode() == EC_OP_SHUTDOWN) { 576 SendPacket(curr); 577 delete curr; 578 return CMD_ID_QUIT; 579 } 580 const CECPacket *reply = SendRecvMsg_v2(curr); 581 delete curr; 582 if ( reply ) { 583 Process_Answer_v2(reply); 584 delete reply; 585 } 586 } 587 request_list.resize(0); 588 } 589 590 return CMD_OK; 591} 592 593 /* 594 * Method to show the results in the console 595 */ 596void CamulecmdApp::ShowResults(CResultMap results_map) 597{ 598 unsigned int name_max = 80; 599 unsigned int mb_max = 5; 600 unsigned int nr_max = 5; 601 unsigned long int id = 0; 602 wxString output, name, sources, mb , kb; 603 604 printf("Nr. Filename: Size(MB): Sources: \n"); 605 printf("-----------------------------------------------------------------------------------------------------------\n"); 606 607 for( std::map<unsigned long int,SearchFile*>::iterator iter = results_map.begin(); iter != results_map.end(); iter++ ) { 608 id = (*iter).first; 609 SearchFile* file = (*iter).second; 610 611 output.Printf(wxT("%i. "), id); 612 output = output.SubString(0, nr_max).Append(file->sFileName).Append(' ', name_max); 613 mb.Printf(wxT(" %d"), file->lFileSize/1024/1024); 614 kb.Printf(wxT(".%d"), file->lFileSize/1024%1024); 615 output = output.SubString(0, nr_max + name_max + mb_max - mb.Length() ).Append(mb).Append(kb); 616 printf("%s %ld\n",(const char*)unicode2char(output), file->lSourceCount ); 617 } 618} 619 620 621// Formats a statistics (sub)tree to text 622wxString StatTree2Text(CEC_StatTree_Node_Tag *tree, int depth) 623{ 624 if (!tree) { 625 return wxEmptyString; 626 } 627 wxString result = wxString(wxChar(' '), depth) + tree->GetDisplayString() + wxT("\n"); 628 for (CECTag::const_iterator it = tree->begin(); it != tree->end(); it++) { 629 CEC_StatTree_Node_Tag *tmp = (CEC_StatTree_Node_Tag*) & *it; 630 if (tmp->GetTagName() == EC_TAG_STATTREE_NODE) { 631 result += StatTree2Text(tmp, depth + 1); 632 } 633 } 634 return result; 635} 636 637/* 638 * Format EC packet into text form for output to console 639 */ 640void CamulecmdApp::Process_Answer_v2(const CECPacket *response) 641{ 642 wxString s; 643 wxString msgFailedUnknown(_("Request failed with an unknown error.")); 644 wxASSERT(response); 645 switch (response->GetOpCode()) { 646 case EC_OP_NOOP: 647 s << _("Operation was successful."); 648 break; 649 case EC_OP_FAILED: 650 { 651 const CECTag *tag = response->GetFirstTagSafe(); 652 if (tag->IsString()) { 653 s << CFormat(_("Request failed with the following error: %s")) % wxGetTranslation(tag->GetStringData()); 654 } else { 655 s << msgFailedUnknown; 656 } 657 } 658 break; 659 case EC_OP_SET_PREFERENCES: 660 { 661 const CECTag *tab = response->GetTagByNameSafe(EC_TAG_PREFS_SECURITY); 662 const CECTag *ipfilterLevel = tab->GetTagByName(EC_TAG_IPFILTER_LEVEL); 663 if (ipfilterLevel) { 664 if (m_last_cmd_id == CMD_ID_GET_IPFILTER || 665 m_last_cmd_id == CMD_ID_GET_IPFILTER_STATE || 666 m_last_cmd_id == CMD_ID_GET_IPFILTER_STATE_CLIENTS) { 667 s += CFormat(_("IP filtering for clients is %s.\n")) 668 % ((tab->GetTagByName(EC_TAG_IPFILTER_CLIENTS) == NULL) ? _("OFF") : _("ON")); 669 } 670 if (m_last_cmd_id == CMD_ID_GET_IPFILTER || 671 m_last_cmd_id == CMD_ID_GET_IPFILTER_STATE || 672 m_last_cmd_id == CMD_ID_GET_IPFILTER_STATE_SERVERS) { 673 s += CFormat(_("IP filtering for servers is %s.\n")) 674 % ((tab->GetTagByName(EC_TAG_IPFILTER_SERVERS) == NULL) ? _("OFF") : _("ON")); 675 } 676 if (m_last_cmd_id == CMD_ID_GET_IPFILTER || 677 m_last_cmd_id == CMD_ID_GET_IPFILTER_LEVEL) { 678 s << CFormat(_("Current IPFilter Level is %d.\n")) % ipfilterLevel->GetInt(); 679 } 680 } 681 tab = response->GetTagByNameSafe(EC_TAG_PREFS_CONNECTIONS); 682 const CECTag *connMaxUL = tab->GetTagByName(EC_TAG_CONN_MAX_UL); 683 const CECTag *connMaxDL = tab->GetTagByName(EC_TAG_CONN_MAX_DL); 684 if (connMaxUL && connMaxDL) { 685 s << CFormat(_("Bandwidth limits: Up: %u kB/s, Down: %u kB/s.\n")) 686 % connMaxUL->GetInt() % connMaxDL->GetInt(); 687 } 688 } 689 break; 690 case EC_OP_STRINGS: 691 for (CECPacket::const_iterator it = response->begin(); it != response->end(); it++) { 692 const CECTag &tag = *it; 693 s << tag.GetStringData() << wxT("\n"); 694 } 695 break; 696 case EC_OP_STATS: { 697 CEC_ConnState_Tag *connState = (CEC_ConnState_Tag*)response->GetTagByName(EC_TAG_CONNSTATE); 698 if (connState) { 699 s << _("eD2k") << wxT(": "); 700 if (connState->IsConnectedED2K()) { 701 CECTag *server = connState->GetTagByName(EC_TAG_SERVER); 702 CECTag *serverName = server ? server->GetTagByName(EC_TAG_SERVER_NAME) : NULL; 703 if (server && serverName) { 704 s << CFormat(_("Connected to %s %s %s")) % 705 serverName->GetStringData() % 706 server->GetIPv4Data().StringIP() % 707 (connState->HasLowID() ? _("with LowID") : _("with HighID")); 708 } 709 } else if (connState->IsConnectingED2K()) { 710 s << _("Now connecting"); 711 } else { 712 s << _("Not connected"); 713 } 714 s << wxT('\n') << _("Kad") << wxT(": "); 715 if (connState->IsKadRunning()) { 716 if (connState->IsConnectedKademlia()) { 717 s << _("Connected") << wxT(" ("); 718 if (connState->IsKadFirewalled()) { 719 s << _("firewalled"); 720 } else { 721 s << _("ok"); 722 } 723 s << wxT(')'); 724 } else { 725 s << _("Not connected"); 726 } 727 } else { 728 s << _("Not running"); 729 } 730 s << wxT('\n'); 731 } 732 const CECTag *tmpTag; 733 if ((tmpTag = response->GetTagByName(EC_TAG_STATS_DL_SPEED)) != 0) { 734 s << CFormat(_("\nDownload:\t%s")) % CastItoSpeed(tmpTag->GetInt()); 735 } 736 if ((tmpTag = response->GetTagByName(EC_TAG_STATS_UL_SPEED)) != 0) { 737 s << CFormat(_("\nUpload:\t%s")) % CastItoSpeed(tmpTag->GetInt()); 738 } 739 if ((tmpTag = response->GetTagByName(EC_TAG_STATS_UL_QUEUE_LEN)) != 0) { 740 s << CFormat(_("\nClients in queue:\t%d\n")) % tmpTag->GetInt(); 741 } 742 if ((tmpTag = response->GetTagByName(EC_TAG_STATS_TOTAL_SRC_COUNT)) != 0) { 743 s << CFormat(_("\nTotal sources:\t%d\n")) % tmpTag->GetInt(); 744 } 745 break; 746 } 747 case EC_OP_DLOAD_QUEUE: 748 for (CECPacket::const_iterator it = response->begin(); it != response->end(); it++) { 749 CEC_PartFile_Tag *tag = (CEC_PartFile_Tag *) & *it; 750 uint64 filesize, donesize; 751 filesize = tag->SizeFull(); 752 donesize = tag->SizeDone(); 753 s << tag->FileHashString() << wxT(" ") << 754 tag->FileName() << 755 (CFormat(wxT("\n\t [%.1f%%] %4i/%4i ")) 756 % ((float)donesize / ((float)filesize)*100.0) 757 % ((int)tag->SourceCount() - (int)tag->SourceNotCurrCount()) 758 % (int)tag->SourceCount()) << 759 ((int)tag->SourceCountA4AF() ? wxString(CFormat(wxT("+%2.2i ")) % (int)tag->SourceCountA4AF()) : wxString(wxT(" "))) << 760 ((int)tag->SourceXferCount() ? wxString(CFormat(wxT("(%2.2i) - ")) % (int)tag->SourceXferCount()) : wxString(wxT(" - "))) << 761 tag->GetFileStatusString(); 762 s << wxT(" - ") << tag->PartMetName(); 763 if (tag->DownPrio() < 10) { 764 s << wxT(" - ") << PriorityToStr((int)tag->DownPrio(), 0); 765 } else { 766 s << wxT(" - ") << PriorityToStr((tag->DownPrio() - 10), 1); 767 } 768 if ( tag->SourceXferCount() > 0) { 769 s << wxT(" - ") + CastItoSpeed(tag->Speed()); 770 } 771 s << wxT("\n"); 772 } 773 break; 774 case EC_OP_ULOAD_QUEUE: 775 for (CECPacket::const_iterator it = response->begin(); it != response->end(); it++) { 776 const CECTag *tag = & *it; 777 const CECTag *clientName = tag->GetTagByName(EC_TAG_CLIENT_NAME); 778 const CECTag *partfileName = tag->GetTagByName(EC_TAG_PARTFILE_NAME); 779 const CECTag *partfileSizeXfer = tag->GetTagByName(EC_TAG_PARTFILE_SIZE_XFER); 780 const CECTag *partfileSpeed = tag->GetTagByName(EC_TAG_CLIENT_UP_SPEED); 781 if (clientName && partfileName && partfileSizeXfer && partfileSpeed) { 782 s << wxT("\n") << 783 CFormat(wxT("%10u ")) % tag->GetInt() << 784 clientName->GetStringData() << wxT(" ") << 785 partfileName->GetStringData() << wxT(" ") << 786 CastItoXBytes(partfileSizeXfer->GetInt()) << wxT(" ") << 787 CastItoSpeed(partfileSpeed->GetInt()); 788 } 789 } 790 break; 791 case EC_OP_LOG: 792 for (CECPacket::const_iterator it = response->begin(); it != response->end(); it++) { 793 const CECTag &tag = *it; 794 s << tag.GetStringData() << wxT("\n"); 795 } 796 break; 797 case EC_OP_SERVER_LIST: 798 for (CECPacket::const_iterator it = response->begin(); it != response->end(); it++) { 799 const CECTag &tag = *it; 800 const CECTag *serverName = tag.GetTagByName(EC_TAG_SERVER_NAME); 801 if (serverName) { 802 wxString ip = tag.GetIPv4Data().StringIP(); 803 ip.Append(' ', 24 - ip.Length()); 804 s << ip << serverName->GetStringData() << wxT("\n"); 805 } 806 } 807 break; 808 case EC_OP_STATSTREE: 809 s << StatTree2Text((CEC_StatTree_Node_Tag*)response->GetTagByName(EC_TAG_STATTREE_NODE), 0); 810 break; 811 812 case EC_OP_SEARCH_RESULTS: 813 { 814 int i = 0; 815 m_Results_map.clear(); 816 s += CFormat(_("Number of search results: %i\n")) % response->GetTagCount(); 817 for (CECPacket::const_iterator it = response->begin(); it != response->end(); it++) { 818 CEC_SearchFile_Tag *tag = (CEC_SearchFile_Tag *) & *it; 819 //printf("Tag FileName: %s \n",(const char*)unicode2char(tag->FileName())); 820 m_Results_map[i++] = new SearchFile(tag); 821 } 822 ShowResults(m_Results_map); 823 break; 824 } 825 case EC_OP_SEARCH_PROGRESS: 826 { 827 const CECTag *tab = response->GetTagByNameSafe(EC_TAG_SEARCH_STATUS); 828 uint32 progress = tab->GetInt(); 829 if (progress <= 100) { 830 s += CFormat(_("Search progress: %u %% \n")) % progress; 831 } else { 832 s += _("Search progress not available"); 833 } 834 break; 835 } 836 default: 837 s += CFormat(_("Received an unknown reply from the server, OpCode = %#x.")) % response->GetOpCode(); 838 } 839 Process_Answer(s); 840} 841 842void CamulecmdApp::OnInitCommandSet() 843{ 844 CCommandTree *tmp; 845 CCommandTree *tmp2; 846 CCommandTree *tmp3; 847 848 CaMuleExternalConnector::OnInitCommandSet(); 849 850 m_commands.AddCommand(wxT("Status"), CMD_ID_STATUS, wxTRANSLATE("Show short status information."), 851 wxTRANSLATE("Show connection status, current up/download speeds, etc.\n"), CMD_PARAM_NEVER); 852 853 m_commands.AddCommand(wxT("Statistics"), CMD_ID_STATTREE, wxTRANSLATE("Show full statistics tree."), 854 wxTRANSLATE("Optionally, a number in the range 0-255 can be passed as an argument to this\ncommand, which tells how many entries of the client version subtrees should be\nshown. Passing 0 or omitting it means 'unlimited'.\n\nExample: 'statistics 5' will show only the top 5 versions for each client type.\n")); 855 856 m_commands.AddCommand(wxT("Shutdown"), CMD_ID_SHUTDOWN, wxTRANSLATE("Shut down aMule."), 857 wxTRANSLATE("Shut down the remote running core (amule/amuled).\nThis will also shut down the text client, since it is unusable without a\nrunning core.\n"), CMD_PARAM_NEVER); 858 859 tmp = m_commands.AddCommand(wxT("Reload"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Reload the given object."), wxEmptyString, CMD_PARAM_NEVER); 860 tmp->AddCommand(wxT("Shared"), CMD_ID_RELOAD_SHARED, wxTRANSLATE("Reload shared files list."), wxEmptyString, CMD_PARAM_NEVER); 861 862 tmp2 = tmp->AddCommand(wxT("IPFilter"), CMD_ID_RELOAD_IPFILTER_LOCAL, wxTRANSLATE("Reload IP filtering table."), wxEmptyString, CMD_PARAM_OPTIONAL); 863 tmp2->AddCommand(wxT("File"), CMD_ID_RELOAD_IPFILTER_LOCAL, wxTRANSLATE("Reload current IP filtering table."), wxEmptyString, CMD_PARAM_NEVER); 864 tmp2->AddCommand(wxT("Net"), CMD_ID_RELOAD_IPFILTER_NET, wxTRANSLATE("Update IP filtering table from URL."), 865 wxTRANSLATE("If URL is omitted the URL from the preferences is used."), CMD_PARAM_OPTIONAL); 866 867 tmp = m_commands.AddCommand(wxT("Connect"), CMD_ID_CONNECT, wxTRANSLATE("Connect to the network."), 868 wxTRANSLATE("This will connect to all networks that are enabled in Preferences.\nYou may also optionally specify a server address in IP:Port form, to connect to\nthat server only. The IP must be a dotted decimal IPv4 address,\nor a resolvable DNS name."), CMD_PARAM_OPTIONAL); 869 tmp->AddCommand(wxT("ED2K"), CMD_ID_CONNECT_ED2K, wxTRANSLATE("Connect to eD2k only."), wxEmptyString, CMD_PARAM_NEVER); 870 tmp->AddCommand(wxT("Kad"), CMD_ID_CONNECT_KAD, wxTRANSLATE("Connect to Kad only."), wxEmptyString, CMD_PARAM_NEVER); 871 872 tmp = m_commands.AddCommand(wxT("Disconnect"), CMD_ID_DISCONNECT, wxTRANSLATE("Disconnect from the network."), 873 wxTRANSLATE("This will disconnect from all networks that are currently connected.\n"), CMD_PARAM_NEVER); 874 tmp->AddCommand(wxT("ED2K"), CMD_ID_DISCONNECT_ED2K, wxTRANSLATE("Disconnect from eD2k only."), wxEmptyString, CMD_PARAM_NEVER); 875 tmp->AddCommand(wxT("Kad"), CMD_ID_DISCONNECT_KAD, wxTRANSLATE("Disconnect from Kad only."), wxEmptyString, CMD_PARAM_NEVER); 876 877 m_commands.AddCommand(wxT("Add"), CMD_ID_ADDLINK, wxTRANSLATE("Add an eD2k or magnet link to core."), 878 wxTRANSLATE("The eD2k link to be added can be:\n*) a file link (ed2k://|file|...), it will be added to the download queue,\n*) a server link (ed2k://|server|...), it will be added to the server list,\n*) or a serverlist link, in which case all servers in the list will be added to the\n server list.\n\nThe magnet link must contain the eD2k hash and file length.\n"), CMD_PARAM_ALWAYS); 879 880 tmp = m_commands.AddCommand(wxT("Set"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Set a preference value."), 881 wxEmptyString, CMD_PARAM_NEVER); 882 883 tmp2 = tmp->AddCommand(wxT("IPFilter"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Set IP filtering preferences."), wxEmptyString, CMD_PARAM_NEVER); 884 tmp2->AddCommand(wxT("On"), CMD_ID_SET_IPFILTER_ON, wxTRANSLATE("Turn IP filtering on for both clients and servers."), wxEmptyString, CMD_PARAM_NEVER); 885 tmp2->AddCommand(wxT("Off"), CMD_ID_SET_IPFILTER_OFF, wxTRANSLATE("Turn IP filtering off for both clients and servers."), wxEmptyString, CMD_PARAM_NEVER); 886 tmp3 = tmp2->AddCommand(wxT("Clients"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Enable/Disable IP filtering for clients."), wxEmptyString, CMD_PARAM_NEVER); 887 tmp3->AddCommand(wxT("On"), CMD_ID_SET_IPFILTER_CLIENTS_ON, wxTRANSLATE("Turn IP filtering on for clients."), wxEmptyString, CMD_PARAM_NEVER); 888 tmp3->AddCommand(wxT("Off"), CMD_ID_SET_IPFILTER_CLIENTS_OFF, wxTRANSLATE("Turn IP filtering off for clients."), wxEmptyString, CMD_PARAM_NEVER); 889 tmp3 = tmp2->AddCommand(wxT("Servers"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Enable/Disable IP filtering for servers."), wxEmptyString, CMD_PARAM_NEVER); 890 tmp3->AddCommand(wxT("On"), CMD_ID_SET_IPFILTER_SERVERS_ON, wxTRANSLATE("Turn IP filtering on for servers."), wxEmptyString, CMD_PARAM_NEVER); 891 tmp3->AddCommand(wxT("Off"), CMD_ID_SET_IPFILTER_SERVERS_OFF, wxTRANSLATE("Turn IP filtering off for servers."), wxEmptyString, CMD_PARAM_NEVER); 892 tmp2->AddCommand(wxT("Level"), CMD_ID_SET_IPFILTER_LEVEL, wxTRANSLATE("Select IP filtering level."), 893 wxTRANSLATE("Valid filtering levels are in the range 0-255, and it's default (initial)\nvalue is 127.\n"), CMD_PARAM_ALWAYS); 894 895 tmp2 = tmp->AddCommand(wxT("BwLimit"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Set bandwidth limits."), 896 wxTRANSLATE("The value given to these commands has to be in kilobytes/sec.\n"), CMD_PARAM_NEVER); 897 tmp2->AddCommand(wxT("Up"), CMD_ID_SET_BWLIMIT_UP, wxTRANSLATE("Set upload bandwidth limit."), 898 wxT("The given value must be in kilobytes/sec.\n"), CMD_PARAM_ALWAYS); 899 tmp2->AddCommand(wxT("Down"), CMD_ID_SET_BWLIMIT_DOWN, wxTRANSLATE("Set download bandwidth limit."), 900 wxT("The given value must be in kilobytes/sec.\n"), CMD_PARAM_ALWAYS); 901 902 tmp = m_commands.AddCommand(wxT("Get"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Get and display a preference value."), 903 wxEmptyString, CMD_PARAM_NEVER); 904 905 tmp2 = tmp->AddCommand(wxT("IPFilter"), CMD_ID_GET_IPFILTER, wxTRANSLATE("Get IP filtering preferences."), wxEmptyString, CMD_PARAM_NEVER); 906 tmp3 = tmp2->AddCommand(wxT("State"), CMD_ID_GET_IPFILTER_STATE, wxTRANSLATE("Get IP filtering state for both clients and servers."), wxEmptyString, CMD_PARAM_NEVER); 907 tmp3->AddCommand(wxT("Clients"), CMD_ID_GET_IPFILTER_STATE_CLIENTS, wxTRANSLATE("Get IP filtering state for clients only."), wxEmptyString, CMD_PARAM_NEVER); 908 tmp3->AddCommand(wxT("Servers"), CMD_ID_GET_IPFILTER_STATE_SERVERS, wxTRANSLATE("Get IP filtering state for servers only."), wxEmptyString, CMD_PARAM_NEVER); 909 tmp2->AddCommand(wxT("Level"), CMD_ID_GET_IPFILTER_LEVEL, wxTRANSLATE("Get IP filtering level."), wxEmptyString, CMD_PARAM_NEVER); 910 911 tmp->AddCommand(wxT("BwLimits"), CMD_ID_GET_BWLIMITS, wxTRANSLATE("Get bandwidth limits."), wxEmptyString, CMD_PARAM_NEVER); 912 913 tmp = m_commands.AddCommand(wxT("Search"), CMD_ID_SEARCH, wxTRANSLATE("Execute a search."), 914 wxTRANSLATE("A search type has to be specified by giving the type:\n GLOBAL\n LOCAL\n KAD\nExample: 'search kad file' will execute a kad search for \"file\".\n"), CMD_PARAM_ALWAYS); 915 tmp->AddCommand(wxT("global"), CMD_ID_SEARCH_GLOBAL, wxTRANSLATE("Execute a global search."), wxEmptyString, CMD_PARAM_ALWAYS); 916 tmp->AddCommand(wxT("local"), CMD_ID_SEARCH_LOCAL, wxTRANSLATE("Execute a local search"), wxEmptyString, CMD_PARAM_ALWAYS); 917 tmp->AddCommand(wxT("kad"), CMD_ID_SEARCH_KAD, wxTRANSLATE("Execute a kad search"), wxEmptyString, CMD_PARAM_ALWAYS); 918 919 m_commands.AddCommand(wxT("Results"), CMD_ID_SEARCH_RESULTS, wxTRANSLATE("Show the results of the last search."), 920 wxTRANSLATE("Return the results of the previous search.\n"), CMD_PARAM_NEVER); 921 922 m_commands.AddCommand(wxT("Progress"), CMD_ID_SEARCH_PROGRESS, wxTRANSLATE("Show the progress of a search."), 923 wxTRANSLATE("Show the progress of a search.\n"), CMD_PARAM_NEVER); 924 925 m_commands.AddCommand(wxT("Download"), CMD_ID_DOWNLOAD, wxTRANSLATE("Start downloading a file"), 926 wxTRANSLATE("The number of a file from the last search has to be given.\nExample: 'download 12' will start to download the file with the number 12 of the previous search.\n"), CMD_PARAM_ALWAYS); 927 928 929 // 930 // TODO: These commands below need implementation and/or rewrite! 931 // 932 933 m_commands.AddCommand(wxT("Pause"), CMD_ID_PAUSE, wxTRANSLATE("Pause download."), 934 wxEmptyString, CMD_PARAM_ALWAYS); 935 936 m_commands.AddCommand(wxT("Resume"), CMD_ID_RESUME, wxTRANSLATE("Resume download."), 937 wxEmptyString, CMD_PARAM_ALWAYS); 938 939 m_commands.AddCommand(wxT("Cancel"), CMD_ID_CANCEL, wxTRANSLATE("Cancel download."), 940 wxEmptyString, CMD_PARAM_ALWAYS); 941 942 tmp = m_commands.AddCommand(wxT("Priority"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Set download priority."), 943 wxTRANSLATE("Set priority of a download to Low, Normal, High or Auto.\n"), CMD_PARAM_ALWAYS); 944 tmp->AddCommand(wxT("Low"), CMD_ID_PRIORITY_LOW, wxTRANSLATE("Set priority to low."), wxEmptyString, CMD_PARAM_ALWAYS); 945 tmp->AddCommand(wxT("Normal"), CMD_ID_PRIORITY_NORMAL, wxTRANSLATE("Set priority to normal."), wxEmptyString, CMD_PARAM_ALWAYS); 946 tmp->AddCommand(wxT("High"), CMD_ID_PRIORITY_HIGH, wxTRANSLATE("Set priority to high."), wxEmptyString, CMD_PARAM_ALWAYS); 947 tmp->AddCommand(wxT("Auto"), CMD_ID_PRIORITY_AUTO, wxTRANSLATE("Set priority to auto."), wxEmptyString, CMD_PARAM_ALWAYS); 948 949 tmp = m_commands.AddCommand(wxT("Show"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Show queues/lists."), 950 wxTRANSLATE("Show upload/download queue, server list or shared files list.\n"), CMD_PARAM_ALWAYS); 951 tmp->AddCommand(wxT("UL"), CMD_ID_SHOW_UL, wxTRANSLATE("Show upload queue."), wxEmptyString, CMD_PARAM_NEVER); 952 tmp->AddCommand(wxT("DL"), CMD_ID_SHOW_DL, wxTRANSLATE("Show download queue."), wxEmptyString, CMD_PARAM_NEVER); 953 tmp->AddCommand(wxT("Log"), CMD_ID_SHOW_LOG, wxTRANSLATE("Show log."), wxEmptyString, CMD_PARAM_NEVER); 954 tmp->AddCommand(wxT("Servers"), CMD_ID_SHOW_SERVERS, wxTRANSLATE("Show servers list."), wxEmptyString, CMD_PARAM_NEVER); 955// tmp->AddCommand(wxT("Shared"), CMD_ID_SHOW_SHARED, wxTRANSLATE("Show shared files list."), wxEmptyString, CMD_PARAM_NEVER); 956 957 m_commands.AddCommand(wxT("Reset"), CMD_ID_RESET_LOG, wxTRANSLATE("Reset log."), wxEmptyString, CMD_PARAM_NEVER); 958 959 // 960 // Deprecated commands, kept for backwards compatibility only. 961 // 962 963#define DEPRECATED(OLDCMD, ID, NEWCMD, PARAM) \ 964 m_commands.AddCommand(wxT(OLDCMD), CMD_ID_##ID | CMD_DEPRECATED, CFormat(wxTRANSLATE("Deprecated command, use '%s' instead.")) % wxT(NEWCMD), \ 965 CFormat(wxTRANSLATE("This is a deprecated command, and may be removed in the future.\nUse '%s' instead.\n")) % wxT(NEWCMD), CMD_PARAM_##PARAM) 966 967 DEPRECATED("Stats", STATUS, "Status", NEVER); 968 DEPRECATED("SetIPFilter", SET_IPFILTER, "Set IPFilter", OPTIONAL); 969 DEPRECATED("GetIPLevel", GET_IPFILTER_LEVEL, "Get IPFilter Level", NEVER); 970 DEPRECATED("SetIPLevel", SET_IPFILTER_LEVEL, "Set IPFilter Level", ALWAYS); 971 DEPRECATED("IPLevel", SET_IPFILTER_LEVEL, "Get/Set IPFilter Level", OPTIONAL); 972 DEPRECATED("Servers", SHOW_SERVERS, "Show Servers", NEVER); 973 DEPRECATED("GetBWLimits", GET_BWLIMITS, "Get BwLimits", NEVER); 974 DEPRECATED("SetUpBWLimit", SET_BWLIMIT_UP, "Set BwLimit Up", ALWAYS); 975 DEPRECATED("SetDownBWLimit", SET_BWLIMIT_DOWN, "Set BwLimit Down", ALWAYS); 976} 977 978int CamulecmdApp::OnRun() 979{ 980 ConnectAndRun(wxT("aMulecmd"), wxT(VERSION)); 981 return 0; 982} 983 984// Dummy functions for EC logging 985bool ECLogIsEnabled() 986{ 987 return false; 988} 989 990void DoECLogLine(const wxString &) 991{ 992} 993// File_checked_for_headers 994