Remove do-nothing command and add warning about it
[amule.git] / src / TextClient.cpp
blob978daae8db8be7e786e9a7acf740b7bd0fa9b69c
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.
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.
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.
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
27 #include "config.h" // Needed for VERSION
28 #include "TextClient.h"
30 #ifndef __WINDOWS__
31 #include <unistd.h> // Do_not_auto_remove
32 #endif
35 //-------------------------------------------------------------------
38 //-------------------------------------------------------------------
40 #include <ec/cpp/ECSpecialTags.h>
42 #include <wx/tokenzr.h>
44 #include <common/Format.h> // Needed for CFormat
45 #include "OtherFunctions.h"
46 #include "Constants.h" // Needed for Priority Levels
47 #include "DataToText.h" // Needed for PriorityToStr
48 #include "MuleVersion.h" // Needed for GetMuleVersion()
50 //-------------------------------------------------------------------
52 enum {
53 CMD_ID_STATUS,
54 CMD_ID_RESUME,
55 CMD_ID_PAUSE,
56 CMD_ID_PRIORITY_LOW,
57 CMD_ID_PRIORITY_NORMAL,
58 CMD_ID_PRIORITY_HIGH,
59 CMD_ID_PRIORITY_AUTO,
60 CMD_ID_CANCEL,
61 CMD_ID_CONNECT,
62 CMD_ID_CONNECT_ED2K,
63 CMD_ID_CONNECT_KAD,
64 CMD_ID_DISCONNECT,
65 CMD_ID_DISCONNECT_ED2K,
66 CMD_ID_DISCONNECT_KAD,
67 CMD_ID_RELOAD_SHARED,
68 CMD_ID_RELOAD_IPFILTER_LOCAL,
69 CMD_ID_RELOAD_IPFILTER_NET,
70 CMD_ID_SET_IPFILTER_ON,
71 CMD_ID_SET_IPFILTER_OFF,
72 CMD_ID_SET_IPFILTER_CLIENTS_ON,
73 CMD_ID_SET_IPFILTER_CLIENTS_OFF,
74 CMD_ID_SET_IPFILTER_SERVERS_ON,
75 CMD_ID_SET_IPFILTER_SERVERS_OFF,
76 CMD_ID_SET_IPFILTER_LEVEL,
77 CMD_ID_GET_IPFILTER,
78 CMD_ID_GET_IPFILTER_STATE,
79 CMD_ID_GET_IPFILTER_STATE_CLIENTS,
80 CMD_ID_GET_IPFILTER_STATE_SERVERS,
81 CMD_ID_GET_IPFILTER_LEVEL,
82 CMD_ID_SHOW_UL,
83 CMD_ID_SHOW_DL,
84 CMD_ID_SHOW_LOG,
85 CMD_ID_SHOW_SERVERS,
86 CMD_ID_SHOW_SHARED,
87 CMD_ID_RESET_LOG,
88 CMD_ID_SHUTDOWN,
89 CMD_ID_ADDLINK,
90 CMD_ID_SET_BWLIMIT_UP,
91 CMD_ID_SET_BWLIMIT_DOWN,
92 CMD_ID_GET_BWLIMITS,
93 CMD_ID_STATTREE,
94 CMD_ID_SEARCH,
95 CMD_ID_SEARCH_GLOBAL,
96 CMD_ID_SEARCH_LOCAL,
97 CMD_ID_SEARCH_KAD,
98 CMD_ID_SEARCH_RESULTS,
99 CMD_ID_SEARCH_PROGRESS,
100 CMD_ID_DOWNLOAD,
101 // IDs for deprecated commands
102 CMD_ID_SET_IPFILTER
106 // method to create a SearchFile
107 SearchFile::SearchFile(const CEC_SearchFile_Tag *tag)
109 nHash = tag->FileHash();
110 sHash = nHash.Encode();
111 sFileName = tag->FileName();
112 lFileSize = tag->SizeFull();
113 lSourceCount = tag->SourceCount();
114 bPresent = tag->AlreadyHave();
117 //-------------------------------------------------------------------
118 IMPLEMENT_APP (CamulecmdApp)
119 //-------------------------------------------------------------------
121 void CamulecmdApp::OnInitCmdLine(wxCmdLineParser& parser)
123 CaMuleExternalConnector::OnInitCmdLine(parser, "amulecmd");
124 parser.AddOption(wxT("c"), wxT("command"),
125 _("Execute <str> and exit."),
126 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL);
129 bool CamulecmdApp::OnCmdLineParsed(wxCmdLineParser& parser)
131 m_HasCmdOnCmdLine = parser.Found(wxT("command"), &m_CmdString);
132 if (m_CmdString.Lower().StartsWith(wxT("help")))
134 OnInitCommandSet();
135 printf("%s %s\n", m_appname, (const char *)unicode2char(GetMuleVersion()));
136 Parse_Command(m_CmdString);
137 exit(0);
139 m_interactive = !m_HasCmdOnCmdLine;
140 return CaMuleExternalConnector::OnCmdLineParsed(parser);
143 void CamulecmdApp::TextShell(const wxString& prompt)
145 if (m_HasCmdOnCmdLine)
146 Parse_Command(m_CmdString);
147 else
148 CaMuleExternalConnector::TextShell(prompt);
151 int CamulecmdApp::ProcessCommand(int CmdId)
153 wxString args = GetCmdArgs();
154 CECPacket *request = 0;
155 std::list<CECPacket *> request_list;
156 int tmp_int = 0;
157 EC_SEARCH_TYPE search_type = EC_SEARCH_KAD;
159 // Implementation of the deprecated command 'SetIPFilter'.
160 if (CmdId == CMD_ID_SET_IPFILTER) {
161 if ( ! args.IsEmpty() ) {
162 if (args.IsSameAs(wxT("ON"), false)) {
163 CmdId = CMD_ID_SET_IPFILTER_ON;
164 } else if (args.IsSameAs(wxT("OFF"), false)) {
165 CmdId = CMD_ID_SET_IPFILTER_OFF;
166 } else {
167 return CMD_ERR_INVALID_ARG;
169 } else {
170 CmdId = CMD_ID_GET_IPFILTER_STATE;
174 switch (CmdId) {
175 case CMD_ID_STATUS:
176 request_list.push_back(new CECPacket(EC_OP_STAT_REQ, EC_DETAIL_CMD));
177 break;
179 case CMD_ID_SHUTDOWN:
180 request_list.push_back(new CECPacket(EC_OP_SHUTDOWN));
181 break;
183 case CMD_ID_CONNECT:
184 if ( !args.IsEmpty() ) {
185 unsigned int ip[4];
186 unsigned int port;
187 // Not much we can do against this unicode2char.
188 int result = sscanf(unicode2char(args), "%3d.%3d.%3d.%3d:%5d", &ip[0], &ip[1], &ip[2], &ip[3], &port);
189 if (result != 5) {
190 // Try to resolve DNS -- good for dynamic IP servers
191 wxString serverName(args.BeforeFirst(wxT(':')));
192 long lPort;
193 bool ok = args.AfterFirst(wxT(':')).ToLong(&lPort);
194 port = (unsigned int)lPort;
195 amuleIPV4Address a;
196 a.Hostname(serverName);
197 a.Service(port);
198 result = sscanf(unicode2char(a.IPAddress()), "%3d.%3d.%3d.%3d", &ip[0], &ip[1], &ip[2], &ip[3]);
199 if (serverName.IsEmpty() || !ok || (result != 4)) {
200 Show(_("Invalid IP format. Use xxx.xxx.xxx.xxx:xxxx\n"));
201 return 0;
204 EC_IPv4_t addr;
205 addr.m_ip[0] = ip[0];
206 addr.m_ip[1] = ip[1];
207 addr.m_ip[2] = ip[2];
208 addr.m_ip[3] = ip[3];
209 addr.m_port = port;
210 request = new CECPacket(EC_OP_SERVER_CONNECT);
211 request->AddTag(CECTag(EC_TAG_SERVER, addr));
212 request_list.push_back(request);
213 } else {
214 request_list.push_back(new CECPacket(EC_OP_CONNECT));
216 break;
218 case CMD_ID_CONNECT_ED2K:
219 request_list.push_back(new CECPacket(EC_OP_SERVER_CONNECT));
220 break;
222 case CMD_ID_CONNECT_KAD:
223 request_list.push_back(new CECPacket(EC_OP_KAD_START));
224 break;
226 case CMD_ID_DISCONNECT:
227 request_list.push_back(new CECPacket(EC_OP_DISCONNECT));
228 break;
230 case CMD_ID_DISCONNECT_ED2K:
231 request_list.push_back(new CECPacket(EC_OP_SERVER_DISCONNECT));
232 break;
234 case CMD_ID_DISCONNECT_KAD:
235 request_list.push_back(new CECPacket(EC_OP_KAD_STOP));
236 break;
238 case CMD_ID_RELOAD_SHARED:
239 request_list.push_back(new CECPacket(EC_OP_SHAREDFILES_RELOAD));
240 break;
242 case CMD_ID_RELOAD_IPFILTER_LOCAL:
243 request_list.push_back(new CECPacket(EC_OP_IPFILTER_RELOAD));
244 break;
246 case CMD_ID_RELOAD_IPFILTER_NET:
247 request = new CECPacket(EC_OP_IPFILTER_UPDATE);
248 request->AddTag(EC_TAG_STRING, args);
249 request_list.push_back(request);
250 break;
252 case CMD_ID_SET_IPFILTER_ON:
253 case CMD_ID_SET_IPFILTER_CLIENTS_ON:
254 case CMD_ID_SET_IPFILTER_SERVERS_ON:
255 tmp_int = 1;
256 /* fall through */
257 case CMD_ID_SET_IPFILTER_OFF:
258 case CMD_ID_SET_IPFILTER_CLIENTS_OFF:
259 case CMD_ID_SET_IPFILTER_SERVERS_OFF:
261 if (CmdId == CMD_ID_SET_IPFILTER_CLIENTS_ON || CmdId == CMD_ID_SET_IPFILTER_CLIENTS_OFF) {
262 CmdId = CMD_ID_GET_IPFILTER_STATE_CLIENTS;
263 } else if (CmdId == CMD_ID_SET_IPFILTER_SERVERS_ON || CmdId == CMD_ID_SET_IPFILTER_SERVERS_OFF) {
264 CmdId = CMD_ID_GET_IPFILTER_STATE_SERVERS;
265 } else {
266 CmdId = CMD_ID_GET_IPFILTER_STATE;
269 request = new CECPacket(EC_OP_SET_PREFERENCES);
270 CECEmptyTag prefs(EC_TAG_PREFS_SECURITY);
271 if (CmdId != CMD_ID_GET_IPFILTER_STATE_SERVERS) {
272 prefs.AddTag(CECTag(EC_TAG_IPFILTER_CLIENTS, (uint8)tmp_int));
274 if (CmdId != CMD_ID_GET_IPFILTER_STATE_CLIENTS) {
275 prefs.AddTag(CECTag(EC_TAG_IPFILTER_SERVERS, (uint8)tmp_int));
277 request->AddTag(prefs);
278 request_list.push_back(request);
280 /* fall through */
281 case CMD_ID_GET_IPFILTER:
282 case CMD_ID_GET_IPFILTER_STATE:
283 case CMD_ID_GET_IPFILTER_STATE_CLIENTS:
284 case CMD_ID_GET_IPFILTER_STATE_SERVERS:
285 request = new CECPacket(EC_OP_GET_PREFERENCES);
286 request->AddTag(CECTag(EC_TAG_SELECT_PREFS, (uint32)EC_PREFS_SECURITY));
287 request_list.push_back(request);
288 break;
290 case CMD_ID_SET_IPFILTER_LEVEL:
291 if (!args.IsEmpty()) // This 'if' must stay as long as we support the deprecated 'IPLevel' command.
293 unsigned long int level = 0;
294 if (args.ToULong(&level) == true && level < 256) {
295 request = new CECPacket(EC_OP_SET_PREFERENCES);
296 CECEmptyTag prefs(EC_TAG_PREFS_SECURITY);
297 prefs.AddTag(CECTag(EC_TAG_IPFILTER_LEVEL, (uint8)level));
298 request->AddTag(prefs);
299 request_list.push_back(request);
300 } else {
301 return CMD_ERR_INVALID_ARG;
304 CmdId = CMD_ID_GET_IPFILTER_LEVEL;
305 /* fall through */
306 case CMD_ID_GET_IPFILTER_LEVEL:
307 request = new CECPacket(EC_OP_GET_PREFERENCES);
308 request->AddTag(CECTag(EC_TAG_SELECT_PREFS, (uint32)EC_PREFS_SECURITY));
309 request_list.push_back(request);
310 break;
312 case CMD_ID_PAUSE:
313 case CMD_ID_CANCEL:
314 case CMD_ID_RESUME:
316 if ( args.IsEmpty() ) {
317 Show(_("This command requires an argument. Valid arguments: 'all', filename, or a number.\n"));
318 return 0;
319 } else {
320 wxStringTokenizer argsTokenizer(args);
321 wxString token;
322 CMD4Hash hash;
324 // Grab the entire dl queue right away
325 CECPacket request_all(EC_OP_GET_DLOAD_QUEUE, EC_DETAIL_CMD);
326 const CECPacket *reply_all = SendRecvMsg_v2(&request_all);
328 if (reply_all) {
329 switch(CmdId) {
330 case CMD_ID_PAUSE:
331 request = new CECPacket(EC_OP_PARTFILE_PAUSE); break;
332 case CMD_ID_CANCEL:
333 request = new CECPacket(EC_OP_PARTFILE_DELETE); break;
334 case CMD_ID_RESUME:
335 request = new CECPacket(EC_OP_PARTFILE_RESUME); break;
336 default: wxFAIL;
339 // We loop through all the arguments
340 while(argsTokenizer.HasMoreTokens()) {
341 token=argsTokenizer.GetNextToken();
343 // If the user requested all, then we select all files and exit the loop
344 // since there is little point to add anything more to "everything"
345 if( token == wxT("all") ) {
346 for (CECPacket::const_iterator it = reply_all->begin(); it != reply_all->end(); ++it) {
347 const CEC_PartFile_Tag *tag = static_cast<const CEC_PartFile_Tag *>(&*it);
348 request->AddTag(CECTag(EC_TAG_PARTFILE, tag->FileHash()));
350 break;
351 } else if ( hash.Decode(token.Trim(false).Trim(true)) ) {
352 if ( !hash.IsEmpty() ) {
353 Show(_("Processing by hash: "+token+wxT("\n")));
354 request->AddTag(CECTag(EC_TAG_PARTFILE, hash));
356 } else {
357 // Go through the dl queue and look at each filename
358 for (CECPacket::const_iterator it = reply_all->begin(); it != reply_all->end(); ++it) {
359 const CEC_PartFile_Tag *tag = static_cast<const CEC_PartFile_Tag *>(&*it);
360 wxString partmetname = tag->PartMetName();
362 // We check for filename, XXX.pat.met, XXX.part, XXX
363 if( tag->FileName() == token ||
364 partmetname == token ||
365 partmetname.Truncate(partmetname.Len()-4) == token ||
366 partmetname.Truncate(partmetname.Len()-5) == token) {
367 Show(_("Processing by filename: "+token+wxT("\n")));
368 request->AddTag(CECTag(EC_TAG_PARTFILE, tag->FileHash()));
371 } // End of filename check else
372 } // End of argument token loop
374 request_list.push_back(request);
376 delete reply_all;
378 } // End of dl queue processing
380 } // end of command processing
381 break;
384 case CMD_ID_PRIORITY_LOW:
385 case CMD_ID_PRIORITY_NORMAL:
386 case CMD_ID_PRIORITY_HIGH:
387 case CMD_ID_PRIORITY_AUTO:
388 if ( args.IsEmpty() ) {
389 Show(_("This command requires an argument. Valid arguments: a file hash.\n"));
390 return 0;
391 } else {
392 CMD4Hash hash;
393 if (hash.Decode(args.Trim(false).Trim(true))) {
394 if (!hash.IsEmpty()) {
395 request = new CECPacket(EC_OP_PARTFILE_PRIO_SET);
396 CECTag hashtag(EC_TAG_PARTFILE, hash);
397 switch(CmdId) {
398 case CMD_ID_PRIORITY_LOW:
399 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_PRIO, (uint8)PR_LOW));
400 break;
401 case CMD_ID_PRIORITY_NORMAL:
402 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_PRIO, (uint8)PR_NORMAL));
403 break;
404 case CMD_ID_PRIORITY_HIGH:
405 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_PRIO, (uint8)PR_HIGH));
406 break;
407 case CMD_ID_PRIORITY_AUTO:
408 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_PRIO, (uint8)PR_AUTO));
409 break;
410 default: wxFAIL;
412 request->AddTag(hashtag);
413 request_list.push_back(request);
414 } else {
415 Show(_("Not a valid number\n"));
416 return 0;
418 } else {
419 Show(_("Not a valid hash (length should be exactly 32 chars)\n"));
420 return 0;
423 break;
425 case CMD_ID_SHOW_UL:
426 request_list.push_back(new CECPacket(EC_OP_GET_ULOAD_QUEUE));
427 break;
429 case CMD_ID_SHOW_DL:
430 request_list.push_back(new CECPacket(EC_OP_GET_DLOAD_QUEUE));
431 break;
433 case CMD_ID_SHOW_LOG:
434 request_list.push_back(new CECPacket(EC_OP_GET_LOG));
435 break;
437 case CMD_ID_SHOW_SERVERS:
438 request_list.push_back(new CECPacket(EC_OP_GET_SERVER_LIST, EC_DETAIL_CMD));
439 break;
441 case CMD_ID_SHOW_SHARED:
442 request_list.push_back(new CECPacket(EC_OP_GET_SHARED_FILES));
443 break;
445 case CMD_ID_RESET_LOG:
446 request_list.push_back(new CECPacket(EC_OP_RESET_LOG));
447 break;
449 case CMD_ID_ADDLINK:
450 if (args.StartsWith(wxT("ed2k://"))) {
451 //aMule doesn't like AICH links without |/| in front of h=
452 if (args.Find(wxT("|h=")) > -1 && args.Find(wxT("|/|h=")) == -1) {
453 args.Replace(wxT("|h="),wxT("|/|h="));
455 // repair links where | is replaced with %7C (Firefox)
456 if (args.StartsWith(wxT("ed2k://%7C"))) {
457 args.Replace(wxT("%7C"),wxT("|"));
460 request = new CECPacket(EC_OP_ADD_LINK);
461 request->AddTag(CECTag(EC_TAG_STRING, args));
462 request_list.push_back(request);
463 break;
465 case CMD_ID_SET_BWLIMIT_UP:
466 tmp_int = EC_TAG_CONN_MAX_UL - EC_TAG_CONN_MAX_DL;
467 /* fall through */
468 case CMD_ID_SET_BWLIMIT_DOWN:
469 tmp_int += EC_TAG_CONN_MAX_DL;
471 unsigned long int limit;
472 if (args.ToULong(&limit)) {
473 request = new CECPacket(EC_OP_SET_PREFERENCES);
474 CECEmptyTag prefs(EC_TAG_PREFS_CONNECTIONS);
475 prefs.AddTag(CECTag(tmp_int, (uint16)limit));
476 request->AddTag(prefs);
477 request_list.push_back(request);
478 } else {
479 return CMD_ERR_INVALID_ARG;
482 /* fall through */
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;
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;
500 } else {
501 delete request;
502 return CMD_ERR_INVALID_ARG;
505 request_list.push_back(request);
506 break;
507 case CMD_ID_SEARCH_GLOBAL:
508 search_type = EC_SEARCH_GLOBAL;
509 /* fall through */
510 case CMD_ID_SEARCH_LOCAL:
511 if (search_type != EC_SEARCH_GLOBAL){
512 search_type = EC_SEARCH_LOCAL;
514 /* fall through */
515 case CMD_ID_SEARCH_KAD:
516 if (search_type != EC_SEARCH_GLOBAL && search_type != EC_SEARCH_LOCAL){
517 search_type = EC_SEARCH_KAD;
519 if (!args.IsEmpty())
521 wxString search = args;
522 wxString type;
523 wxString extention;
524 uint32 avail = 0;
525 uint32 min_size = 0;
526 uint32 max_size = 0;
528 request = new CECPacket(EC_OP_SEARCH_START);
529 request->AddTag(CEC_Search_Tag (search, search_type, type, extention, avail, min_size, max_size));
530 request_list.push_back(request);
532 break;
533 case CMD_ID_SEARCH:
534 /* TRANSLATORS:
535 'help search' is a command to the program, do not translate it. */
536 Show(_("No search type defined.\nType 'help search' to get more help.\n"));
537 break;
540 case CMD_ID_SEARCH_RESULTS:
541 request_list.push_back(new CECPacket(EC_OP_SEARCH_RESULTS, EC_DETAIL_FULL));
542 break;
544 case CMD_ID_SEARCH_PROGRESS:
545 request_list.push_back(new CECPacket(EC_OP_SEARCH_PROGRESS));
546 break;
548 case CMD_ID_DOWNLOAD:
549 if (!args.IsEmpty())
551 unsigned long int id = 0;
552 if (args.ToULong(&id) == true && id < m_Results_map.size()) {
554 SearchFile* file = m_Results_map[id];
555 Show(CFormat(_("Download File: %lu %s\n")) % id % file->sFileName);
556 request = new CECPacket(EC_OP_DOWNLOAD_SEARCH_RESULT);
557 // get with id the hash and category=0
558 uint32 category = 0;
559 CECTag hashtag(EC_TAG_PARTFILE, file->nHash);
560 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_CAT, category));
561 request->AddTag(hashtag);
562 request_list.push_back(request);
563 } else {
564 return CMD_ERR_INVALID_ARG;
567 break;
569 default:
570 return CMD_ERR_PROCESS_CMD;
573 m_last_cmd_id = CmdId;
575 if ( ! request_list.empty() ) {
576 std::list<CECPacket *>::iterator it = request_list.begin();
577 while ( it != request_list.end() ) {
578 CECPacket *curr = *it++;
579 if (curr->GetOpCode() == EC_OP_SHUTDOWN) {
580 SendPacket(curr);
581 delete curr;
582 return CMD_ID_QUIT;
584 const CECPacket *reply = SendRecvMsg_v2(curr);
585 delete curr;
586 if ( reply ) {
587 Process_Answer_v2(reply);
588 delete reply;
591 request_list.resize(0);
594 return CMD_OK;
598 * Method to show the results in the console
600 void CamulecmdApp::ShowResults(CResultMap results_map)
602 unsigned int name_max = 80;
603 unsigned int mb_max = 5;
604 unsigned int nr_max = 5;
605 wxString output, name, sources, mb , kb;
607 printf("Nr. Filename: Size(MB): Sources: \n");
608 printf("-----------------------------------------------------------------------------------------------------------\n");
610 for( std::map<unsigned long int,SearchFile*>::iterator iter = results_map.begin(); iter != results_map.end(); ++iter ) {
611 unsigned long int id = 0;
612 id = (*iter).first;
613 SearchFile* file = (*iter).second;
615 output.Printf(wxT("%lu. "), id);
616 output = output.SubString(0, nr_max).Append(file->sFileName).Append(' ', name_max);
617 mb.Printf(wxT(" %ld"), file->lFileSize/1024/1024);
618 kb.Printf(wxT(".%03ld"), file->lFileSize/1024%1024);
619 output = output.SubString(0, nr_max + name_max + mb_max - mb.Length() ).Append(mb).Append(kb);
620 printf("%s %ld\n",(const char*)unicode2char(output), file->lSourceCount );
625 // Formats a statistics (sub)tree to text
626 static wxString StatTree2Text(const CEC_StatTree_Node_Tag *tree, int depth)
628 if (!tree) {
629 return wxEmptyString;
631 wxString result = wxString(wxChar(' '), depth) + tree->GetDisplayString() + wxT("\n");
632 for (CECTag::const_iterator it = tree->begin(); it != tree->end(); ++it) {
633 const CEC_StatTree_Node_Tag *tmp = static_cast<const CEC_StatTree_Node_Tag*>(&*it);
634 if (tmp->GetTagName() == EC_TAG_STATTREE_NODE) {
635 result += StatTree2Text(tmp, depth + 1);
638 return result;
642 * Format EC packet into text form for output to console
644 void CamulecmdApp::Process_Answer_v2(const CECPacket *response)
646 wxString s;
647 wxString msgFailedUnknown(_("Request failed with an unknown error."));
648 wxASSERT(response);
649 switch (response->GetOpCode()) {
650 case EC_OP_NOOP:
651 s << _("Operation was successful.");
652 break;
653 case EC_OP_FAILED:
655 const CECTag *tag = response->GetFirstTagSafe();
656 if (tag->IsString()) {
657 s << CFormat(_("Request failed with the following error: %s")) % wxGetTranslation(tag->GetStringData());
658 } else {
659 s << msgFailedUnknown;
662 break;
663 case EC_OP_SET_PREFERENCES:
665 const CECTag *tab = response->GetTagByNameSafe(EC_TAG_PREFS_SECURITY);
666 const CECTag *ipfilterLevel = tab->GetTagByName(EC_TAG_IPFILTER_LEVEL);
667 if (ipfilterLevel) {
668 if (m_last_cmd_id == CMD_ID_GET_IPFILTER ||
669 m_last_cmd_id == CMD_ID_GET_IPFILTER_STATE ||
670 m_last_cmd_id == CMD_ID_GET_IPFILTER_STATE_CLIENTS) {
671 s += CFormat(_("IP filtering for clients is %s.\n"))
672 % ((tab->GetTagByName(EC_TAG_IPFILTER_CLIENTS) == NULL) ? _("OFF") : _("ON"));
674 if (m_last_cmd_id == CMD_ID_GET_IPFILTER ||
675 m_last_cmd_id == CMD_ID_GET_IPFILTER_STATE ||
676 m_last_cmd_id == CMD_ID_GET_IPFILTER_STATE_SERVERS) {
677 s += CFormat(_("IP filtering for servers is %s.\n"))
678 % ((tab->GetTagByName(EC_TAG_IPFILTER_SERVERS) == NULL) ? _("OFF") : _("ON"));
680 if (m_last_cmd_id == CMD_ID_GET_IPFILTER ||
681 m_last_cmd_id == CMD_ID_GET_IPFILTER_LEVEL) {
682 s << CFormat(_("Current IPFilter Level is %d.\n")) % ipfilterLevel->GetInt();
685 tab = response->GetTagByNameSafe(EC_TAG_PREFS_CONNECTIONS);
686 const CECTag *connMaxUL = tab->GetTagByName(EC_TAG_CONN_MAX_UL);
687 const CECTag *connMaxDL = tab->GetTagByName(EC_TAG_CONN_MAX_DL);
688 if (connMaxUL && connMaxDL) {
689 s << CFormat(_("Bandwidth limits: Up: %u kB/s, Down: %u kB/s.\n"))
690 % connMaxUL->GetInt() % connMaxDL->GetInt();
693 break;
694 case EC_OP_STRINGS:
695 for (CECPacket::const_iterator it = response->begin(); it != response->end(); ++it) {
696 const CECTag &tag = *it;
697 s << tag.GetStringData() << wxT("\n");
699 break;
700 case EC_OP_STATS: {
701 const CEC_ConnState_Tag *connState = static_cast<const CEC_ConnState_Tag*>(response->GetTagByName(EC_TAG_CONNSTATE));
702 if (connState) {
703 s << _("eD2k") << wxT(": ");
704 if (connState->IsConnectedED2K()) {
705 const CECTag *server = connState->GetTagByName(EC_TAG_SERVER);
706 const CECTag *serverName = server ? server->GetTagByName(EC_TAG_SERVER_NAME) : NULL;
707 if (server && serverName) {
708 s << CFormat(_("Connected to %s %s %s")) %
709 serverName->GetStringData() %
710 server->GetIPv4Data().StringIP() %
711 (connState->HasLowID() ? _("with LowID") : _("with HighID"));
713 } else if (connState->IsConnectingED2K()) {
714 s << _("Now connecting");
715 } else {
716 s << _("Not connected");
718 s << wxT('\n') << _("Kad") << wxT(": ");
719 if (connState->IsKadRunning()) {
720 if (connState->IsConnectedKademlia()) {
721 s << _("Connected") << wxT(" (");
722 if (connState->IsKadFirewalled()) {
723 s << _("firewalled");
724 } else {
725 s << _("ok");
727 s << wxT(')');
728 } else {
729 s << _("Not connected");
731 } else {
732 s << _("Not running");
734 s << wxT('\n');
736 const CECTag *tmpTag;
737 if ((tmpTag = response->GetTagByName(EC_TAG_STATS_DL_SPEED)) != 0) {
738 s << CFormat(_("\nDownload:\t%s")) % CastItoSpeed(tmpTag->GetInt());
740 if ((tmpTag = response->GetTagByName(EC_TAG_STATS_UL_SPEED)) != 0) {
741 s << CFormat(_("\nUpload:\t%s")) % CastItoSpeed(tmpTag->GetInt());
743 if ((tmpTag = response->GetTagByName(EC_TAG_STATS_UL_QUEUE_LEN)) != 0) {
744 s << CFormat(_("\nClients in queue:\t%d\n")) % tmpTag->GetInt();
746 if ((tmpTag = response->GetTagByName(EC_TAG_STATS_TOTAL_SRC_COUNT)) != 0) {
747 s << CFormat(_("\nTotal sources:\t%d\n")) % tmpTag->GetInt();
749 break;
751 case EC_OP_DLOAD_QUEUE:
752 for (CECPacket::const_iterator it = response->begin(); it != response->end(); ++it) {
753 const CEC_PartFile_Tag *tag = static_cast<const CEC_PartFile_Tag *>(&*it);
754 uint64 filesize, donesize;
755 filesize = tag->SizeFull();
756 donesize = tag->SizeDone();
757 s << tag->FileHashString() << wxT(" ") <<
758 tag->FileName() <<
759 (CFormat(wxT("\n\t [%.1f%%] %4i/%4i "))
760 % ((float)donesize / ((float)filesize)*100.0)
761 % ((int)tag->SourceCount() - (int)tag->SourceNotCurrCount())
762 % (int)tag->SourceCount()) <<
763 ((int)tag->SourceCountA4AF() ? wxString(CFormat(wxT("+%2.2i ")) % (int)tag->SourceCountA4AF()) : wxString(wxT(" "))) <<
764 ((int)tag->SourceXferCount() ? wxString(CFormat(wxT("(%2.2i) - ")) % (int)tag->SourceXferCount()) : wxString(wxT(" - "))) <<
765 tag->GetFileStatusString();
766 s << wxT(" - ") << tag->PartMetName();
767 if (tag->DownPrio() < 10) {
768 s << wxT(" - ") << PriorityToStr((int)tag->DownPrio(), 0);
769 } else {
770 s << wxT(" - ") << PriorityToStr((tag->DownPrio() - 10), 1);
772 if ( tag->SourceXferCount() > 0) {
773 s << wxT(" - ") + CastItoSpeed(tag->Speed());
775 s << wxT("\n");
777 break;
778 case EC_OP_ULOAD_QUEUE:
779 for (CECPacket::const_iterator it = response->begin(); it != response->end(); ++it) {
780 const CECTag *tag = & *it;
781 const CECTag *clientName = tag->GetTagByName(EC_TAG_CLIENT_NAME);
782 const CECTag *partfileName = tag->GetTagByName(EC_TAG_PARTFILE_NAME);
783 const CECTag *partfileSizeXfer = tag->GetTagByName(EC_TAG_PARTFILE_SIZE_XFER);
784 const CECTag *partfileSpeed = tag->GetTagByName(EC_TAG_CLIENT_UP_SPEED);
785 if (clientName && partfileName && partfileSizeXfer && partfileSpeed) {
786 s << wxT("\n") <<
787 CFormat(wxT("%10u ")) % tag->GetInt() <<
788 clientName->GetStringData() << wxT(" ") <<
789 partfileName->GetStringData() << wxT(" ") <<
790 CastItoXBytes(partfileSizeXfer->GetInt()) << wxT(" ") <<
791 CastItoSpeed(partfileSpeed->GetInt());
794 break;
795 case EC_OP_LOG:
796 for (CECPacket::const_iterator it = response->begin(); it != response->end(); ++it) {
797 const CECTag &tag = *it;
798 s << tag.GetStringData() << wxT("\n");
800 break;
801 case EC_OP_SERVER_LIST:
802 for (CECPacket::const_iterator it = response->begin(); it != response->end(); ++it) {
803 const CECTag &tag = *it;
804 const CECTag *serverName = tag.GetTagByName(EC_TAG_SERVER_NAME);
805 if (serverName) {
806 wxString ip = tag.GetIPv4Data().StringIP();
807 ip.Append(' ', 24 - ip.Length());
808 s << ip << serverName->GetStringData() << wxT("\n");
811 break;
813 case EC_OP_SHARED_FILES:
814 for (CECPacket::const_iterator it = response->begin(); it != response->end(); ++it) {
815 const CEC_SharedFile_Tag *tag = static_cast<const CEC_SharedFile_Tag *>(&*it);
816 s << tag->FileHashString() << wxT(" ");
817 wxString filePath = tag->FilePath();
818 bool ispartfile = true;
819 if (filePath.EndsWith(wxT(".part"))) {
820 for (unsigned i = 0; i < filePath.Length() - 5; i++) {
821 if (filePath[i] < wxT('0') || filePath[i] > wxT('9')) {
822 ispartfile = false;
823 break;
826 } else {
827 ispartfile = false;
829 if (ispartfile) {
830 s << _("[PartFile]") << wxT(" ");
831 } else {
832 s << filePath
833 #ifdef __WINDOWS__
834 << wxT('\\');
835 #else
836 << wxT('/');
837 #endif
839 s << tag->FileName()
840 << wxT("\n\t") << PriorityToStr(tag->UpPrio() % 10, tag->UpPrio() >= 10) << wxT(" - ") << CFormat(wxT("%i(%i) / %i(%i) - %s (%s) - %.2f\n"))
841 % tag->GetRequests() % tag->GetAllRequests()
842 % tag->GetAccepts() % tag->GetAllAccepts()
843 % CastItoXBytes(tag->GetXferred()) % CastItoXBytes(tag->GetAllXferred())
844 % (static_cast<float>(tag->GetAllXferred()) / static_cast<float>(tag->SizeFull()));
846 break;
848 case EC_OP_STATSTREE:
849 s << StatTree2Text(static_cast<const CEC_StatTree_Node_Tag*>(response->GetTagByName(EC_TAG_STATTREE_NODE)), 0);
850 break;
852 case EC_OP_SEARCH_RESULTS:
854 int i = 0;
855 m_Results_map.clear();
856 s += CFormat(_("Number of search results: %i\n")) % response->GetTagCount();
857 for (CECPacket::const_iterator it = response->begin(); it != response->end(); ++it) {
858 const CEC_SearchFile_Tag *tag = static_cast<const CEC_SearchFile_Tag *>(&*it);
859 //printf("Tag FileName: %s \n",(const char*)unicode2char(tag->FileName()));
860 m_Results_map[i++] = new SearchFile(tag);
862 ShowResults(m_Results_map);
863 break;
865 case EC_OP_SEARCH_PROGRESS:
867 const CECTag *tab = response->GetTagByNameSafe(EC_TAG_SEARCH_STATUS);
868 uint32 progress = tab->GetInt();
869 if (progress <= 100) {
870 s += CFormat(_("Search progress: %u %% \n")) % progress;
871 } else {
872 s += _("Search progress not available");
874 break;
876 default:
877 s += CFormat(_("Received an unknown reply from the server, OpCode = %#x.")) % response->GetOpCode();
879 Process_Answer(s);
882 void CamulecmdApp::OnInitCommandSet()
884 CCommandTree *tmp;
885 CCommandTree *tmp2;
886 CCommandTree *tmp3;
888 CaMuleExternalConnector::OnInitCommandSet();
890 m_commands.AddCommand(wxT("Status"), CMD_ID_STATUS, wxTRANSLATE("Show short status information."),
891 wxTRANSLATE("Show connection status, current up/download speeds, etc.\n"), CMD_PARAM_NEVER);
893 m_commands.AddCommand(wxT("Statistics"), CMD_ID_STATTREE, wxTRANSLATE("Show full statistics tree."),
894 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"));
896 m_commands.AddCommand(wxT("Shutdown"), CMD_ID_SHUTDOWN, wxTRANSLATE("Shut down aMule."),
897 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);
899 tmp = m_commands.AddCommand(wxT("Reload"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Reload the given object."), wxEmptyString, CMD_PARAM_NEVER);
900 tmp->AddCommand(wxT("Shared"), CMD_ID_RELOAD_SHARED, wxTRANSLATE("Reload shared files list."), wxEmptyString, CMD_PARAM_NEVER);
902 tmp2 = tmp->AddCommand(wxT("IPFilter"), CMD_ID_RELOAD_IPFILTER_LOCAL, wxTRANSLATE("Reload IP filtering table."), wxEmptyString, CMD_PARAM_OPTIONAL);
903 tmp2->AddCommand(wxT("File"), CMD_ID_RELOAD_IPFILTER_LOCAL, wxTRANSLATE("Reload current IP filtering table."), wxEmptyString, CMD_PARAM_NEVER);
904 tmp2->AddCommand(wxT("Net"), CMD_ID_RELOAD_IPFILTER_NET, wxTRANSLATE("Update IP filtering table from URL."),
905 wxTRANSLATE("If URL is omitted the URL from the preferences is used."), CMD_PARAM_OPTIONAL);
907 tmp = m_commands.AddCommand(wxT("Connect"), CMD_ID_CONNECT, wxTRANSLATE("Connect to the network."),
908 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);
909 tmp->AddCommand(wxT("ED2K"), CMD_ID_CONNECT_ED2K, wxTRANSLATE("Connect to eD2k only."), wxEmptyString, CMD_PARAM_NEVER);
910 tmp->AddCommand(wxT("Kad"), CMD_ID_CONNECT_KAD, wxTRANSLATE("Connect to Kad only."), wxEmptyString, CMD_PARAM_NEVER);
912 tmp = m_commands.AddCommand(wxT("Disconnect"), CMD_ID_DISCONNECT, wxTRANSLATE("Disconnect from the network."),
913 wxTRANSLATE("This will disconnect from all networks that are currently connected.\n"), CMD_PARAM_NEVER);
914 tmp->AddCommand(wxT("ED2K"), CMD_ID_DISCONNECT_ED2K, wxTRANSLATE("Disconnect from eD2k only."), wxEmptyString, CMD_PARAM_NEVER);
915 tmp->AddCommand(wxT("Kad"), CMD_ID_DISCONNECT_KAD, wxTRANSLATE("Disconnect from Kad only."), wxEmptyString, CMD_PARAM_NEVER);
917 m_commands.AddCommand(wxT("Add"), CMD_ID_ADDLINK, wxTRANSLATE("Add an eD2k or magnet link to core."),
918 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);
920 tmp = m_commands.AddCommand(wxT("Set"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Set a preference value."),
921 wxEmptyString, CMD_PARAM_NEVER);
923 tmp2 = tmp->AddCommand(wxT("IPFilter"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Set IP filtering preferences."), wxEmptyString, CMD_PARAM_NEVER);
924 tmp2->AddCommand(wxT("On"), CMD_ID_SET_IPFILTER_ON, wxTRANSLATE("Turn IP filtering on for both clients and servers."), wxEmptyString, CMD_PARAM_NEVER);
925 tmp2->AddCommand(wxT("Off"), CMD_ID_SET_IPFILTER_OFF, wxTRANSLATE("Turn IP filtering off for both clients and servers."), wxEmptyString, CMD_PARAM_NEVER);
926 tmp3 = tmp2->AddCommand(wxT("Clients"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Enable/Disable IP filtering for clients."), wxEmptyString, CMD_PARAM_NEVER);
927 tmp3->AddCommand(wxT("On"), CMD_ID_SET_IPFILTER_CLIENTS_ON, wxTRANSLATE("Turn IP filtering on for clients."), wxEmptyString, CMD_PARAM_NEVER);
928 tmp3->AddCommand(wxT("Off"), CMD_ID_SET_IPFILTER_CLIENTS_OFF, wxTRANSLATE("Turn IP filtering off for clients."), wxEmptyString, CMD_PARAM_NEVER);
929 tmp3 = tmp2->AddCommand(wxT("Servers"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Enable/Disable IP filtering for servers."), wxEmptyString, CMD_PARAM_NEVER);
930 tmp3->AddCommand(wxT("On"), CMD_ID_SET_IPFILTER_SERVERS_ON, wxTRANSLATE("Turn IP filtering on for servers."), wxEmptyString, CMD_PARAM_NEVER);
931 tmp3->AddCommand(wxT("Off"), CMD_ID_SET_IPFILTER_SERVERS_OFF, wxTRANSLATE("Turn IP filtering off for servers."), wxEmptyString, CMD_PARAM_NEVER);
932 tmp2->AddCommand(wxT("Level"), CMD_ID_SET_IPFILTER_LEVEL, wxTRANSLATE("Select IP filtering level."),
933 wxTRANSLATE("Valid filtering levels are in the range 0-255, and it's default (initial)\nvalue is 127.\n"), CMD_PARAM_ALWAYS);
935 tmp2 = tmp->AddCommand(wxT("BwLimit"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Set bandwidth limits."),
936 wxTRANSLATE("The value given to these commands has to be in kilobytes/sec.\n"), CMD_PARAM_NEVER);
937 tmp2->AddCommand(wxT("Up"), CMD_ID_SET_BWLIMIT_UP, wxTRANSLATE("Set upload bandwidth limit."),
938 wxTRANSLATE("The given value must be in kilobytes/sec.\n"), CMD_PARAM_ALWAYS);
939 tmp2->AddCommand(wxT("Down"), CMD_ID_SET_BWLIMIT_DOWN, wxTRANSLATE("Set download bandwidth limit."),
940 wxTRANSLATE("The given value must be in kilobytes/sec.\n"), CMD_PARAM_ALWAYS);
942 tmp = m_commands.AddCommand(wxT("Get"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Get and display a preference value."),
943 wxEmptyString, CMD_PARAM_NEVER);
945 tmp2 = tmp->AddCommand(wxT("IPFilter"), CMD_ID_GET_IPFILTER, wxTRANSLATE("Get IP filtering preferences."), wxEmptyString, CMD_PARAM_NEVER);
946 tmp3 = tmp2->AddCommand(wxT("State"), CMD_ID_GET_IPFILTER_STATE, wxTRANSLATE("Get IP filtering state for both clients and servers."), wxEmptyString, CMD_PARAM_NEVER);
947 tmp3->AddCommand(wxT("Clients"), CMD_ID_GET_IPFILTER_STATE_CLIENTS, wxTRANSLATE("Get IP filtering state for clients only."), wxEmptyString, CMD_PARAM_NEVER);
948 tmp3->AddCommand(wxT("Servers"), CMD_ID_GET_IPFILTER_STATE_SERVERS, wxTRANSLATE("Get IP filtering state for servers only."), wxEmptyString, CMD_PARAM_NEVER);
949 tmp2->AddCommand(wxT("Level"), CMD_ID_GET_IPFILTER_LEVEL, wxTRANSLATE("Get IP filtering level."), wxEmptyString, CMD_PARAM_NEVER);
951 tmp->AddCommand(wxT("BwLimits"), CMD_ID_GET_BWLIMITS, wxTRANSLATE("Get bandwidth limits."), wxEmptyString, CMD_PARAM_NEVER);
953 tmp = m_commands.AddCommand(wxT("Search"), CMD_ID_SEARCH, wxTRANSLATE("Execute a search."),
954 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);
955 tmp->AddCommand(wxT("global"), CMD_ID_SEARCH_GLOBAL, wxTRANSLATE("Execute a global search."), wxEmptyString, CMD_PARAM_ALWAYS);
956 tmp->AddCommand(wxT("local"), CMD_ID_SEARCH_LOCAL, wxTRANSLATE("Execute a local search"), wxEmptyString, CMD_PARAM_ALWAYS);
957 tmp->AddCommand(wxT("kad"), CMD_ID_SEARCH_KAD, wxTRANSLATE("Execute a kad search"), wxEmptyString, CMD_PARAM_ALWAYS);
959 m_commands.AddCommand(wxT("Results"), CMD_ID_SEARCH_RESULTS, wxTRANSLATE("Show the results of the last search."),
960 wxTRANSLATE("Return the results of the previous search.\n"), CMD_PARAM_NEVER);
962 m_commands.AddCommand(wxT("Progress"), CMD_ID_SEARCH_PROGRESS, wxTRANSLATE("Show the progress of a search."),
963 wxTRANSLATE("Show the progress of a search.\n"), CMD_PARAM_NEVER);
965 m_commands.AddCommand(wxT("Download"), CMD_ID_DOWNLOAD, wxTRANSLATE("Start downloading a file"),
966 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);
970 // TODO: These commands below need implementation and/or rewrite!
973 m_commands.AddCommand(wxT("Pause"), CMD_ID_PAUSE, wxTRANSLATE("Pause download."),
974 wxEmptyString, CMD_PARAM_ALWAYS);
976 m_commands.AddCommand(wxT("Resume"), CMD_ID_RESUME, wxTRANSLATE("Resume download."),
977 wxEmptyString, CMD_PARAM_ALWAYS);
979 m_commands.AddCommand(wxT("Cancel"), CMD_ID_CANCEL, wxTRANSLATE("Cancel download."),
980 wxEmptyString, CMD_PARAM_ALWAYS);
982 tmp = m_commands.AddCommand(wxT("Priority"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Set download priority."),
983 wxTRANSLATE("Set priority of a download to Low, Normal, High or Auto.\n"), CMD_PARAM_ALWAYS);
984 tmp->AddCommand(wxT("Low"), CMD_ID_PRIORITY_LOW, wxTRANSLATE("Set priority to low."), wxEmptyString, CMD_PARAM_ALWAYS);
985 tmp->AddCommand(wxT("Normal"), CMD_ID_PRIORITY_NORMAL, wxTRANSLATE("Set priority to normal."), wxEmptyString, CMD_PARAM_ALWAYS);
986 tmp->AddCommand(wxT("High"), CMD_ID_PRIORITY_HIGH, wxTRANSLATE("Set priority to high."), wxEmptyString, CMD_PARAM_ALWAYS);
987 tmp->AddCommand(wxT("Auto"), CMD_ID_PRIORITY_AUTO, wxTRANSLATE("Set priority to auto."), wxEmptyString, CMD_PARAM_ALWAYS);
989 tmp = m_commands.AddCommand(wxT("Show"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Show queues/lists."),
990 wxTRANSLATE("Show upload/download queue, server list or shared files list.\n"), CMD_PARAM_ALWAYS);
991 tmp->AddCommand(wxT("UL"), CMD_ID_SHOW_UL, wxTRANSLATE("Show upload queue."), wxEmptyString, CMD_PARAM_NEVER);
992 tmp->AddCommand(wxT("DL"), CMD_ID_SHOW_DL, wxTRANSLATE("Show download queue."), wxEmptyString, CMD_PARAM_NEVER);
993 tmp->AddCommand(wxT("Log"), CMD_ID_SHOW_LOG, wxTRANSLATE("Show log."), wxEmptyString, CMD_PARAM_NEVER);
994 tmp->AddCommand(wxT("Servers"), CMD_ID_SHOW_SERVERS, wxTRANSLATE("Show servers list."), wxEmptyString, CMD_PARAM_NEVER);
995 tmp->AddCommand(wxT("Shared"), CMD_ID_SHOW_SHARED, wxTRANSLATE("Show shared files list."), wxEmptyString, CMD_PARAM_NEVER);
997 m_commands.AddCommand(wxT("Reset"), CMD_ID_RESET_LOG, wxTRANSLATE("Reset log."), wxEmptyString, CMD_PARAM_NEVER);
1000 // Deprecated commands, kept for backwards compatibility only.
1003 #define DEPRECATED(OLDCMD, ID, NEWCMD, PARAM) \
1004 m_commands.AddCommand(wxT(OLDCMD), CMD_ID_##ID | CMD_DEPRECATED, CFormat(wxTRANSLATE("Deprecated command, use '%s' instead.")) % wxT(NEWCMD), \
1005 CFormat(wxTRANSLATE("This is a deprecated command, and may be removed in the future.\nUse '%s' instead.\n")) % wxT(NEWCMD), CMD_PARAM_##PARAM)
1007 DEPRECATED("Stats", STATUS, "Status", NEVER);
1008 DEPRECATED("SetIPFilter", SET_IPFILTER, "Set IPFilter", OPTIONAL);
1009 DEPRECATED("GetIPLevel", GET_IPFILTER_LEVEL, "Get IPFilter Level", NEVER);
1010 DEPRECATED("SetIPLevel", SET_IPFILTER_LEVEL, "Set IPFilter Level", ALWAYS);
1011 DEPRECATED("IPLevel", SET_IPFILTER_LEVEL, "Get/Set IPFilter Level", OPTIONAL);
1012 DEPRECATED("Servers", SHOW_SERVERS, "Show Servers", NEVER);
1013 DEPRECATED("GetBWLimits", GET_BWLIMITS, "Get BwLimits", NEVER);
1014 DEPRECATED("SetUpBWLimit", SET_BWLIMIT_UP, "Set BwLimit Up", ALWAYS);
1015 DEPRECATED("SetDownBWLimit", SET_BWLIMIT_DOWN, "Set BwLimit Down", ALWAYS);
1018 int CamulecmdApp::OnRun()
1020 ConnectAndRun(wxT("aMulecmd"), wxT(VERSION));
1021 return 0;
1024 // Stub functions needed by the linker in ASIO builds
1025 #include "GuiEvents.h"
1026 namespace MuleNotify
1028 void HandleNotification(const class CMuleNotiferBase&) {}
1029 void HandleNotificationAlways(const class CMuleNotiferBase&) {}
1032 // File_checked_for_headers