1 /***************************************************************************
2 *                                                                         *
3 *   Copyright 2010 Eugene Petrov <dhamp@ya.ru>                            *
4 *                                                                         *
5 *   This program is free software; you can redistribute it and/or modify  *
6 *   it under the terms of the GNU General Public License as published by  *
7 *   the Free Software Foundation; either version 2 of the License, or     *
8 *   (at your option) any later version.                                   *
9 *                                                                         *
10 ***************************************************************************/
11 
12 #pragma once
13 
14 #include <cassert>
15 #include <stdexcept>
16 #include <iostream>
17 
18 #include <xmlrpc-c/base.hpp>
19 #include <xmlrpc-c/registry.hpp>
20 
21 #include <xmlrpc-c/server_abyss.hpp>
22 
23 #include "utility.h"
24 #include "ServerManager.h"
25 
26 using namespace std;
27 
28 xmlrpc_c::registry xmlrpcRegistry;
29 xmlrpc_c::serverAbyss * server;
30 
31 class magnetAddMethod : public xmlrpc_c::method {
32 public:
magnetAddMethod()33     magnetAddMethod() {
34         this->_signature = "i:ss";
35         this->_help = "Adds a magnet link to the queue. Params: magnet link, download directory; returns: 0 on success, non-zero otherwise";
36     }
37 
38     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)39     execute(xmlrpc_c::paramList const& paramList,
40             xmlrpc_c::value *   const  retvalP) {
41 
42         string const smagnet(paramList.getString(0));
43         string const sddir(paramList.getString(1));
44         paramList.verifyEnd(2);
45 
46         string name, tth;
47         int64_t size;
48         bool ok = splitMagnet(smagnet, name, size, tth);
49         if (isVerbose) std::cout << "splitMagnet: \n tth: " << tth << "\n size: " << size << "\n name: " << name << std::endl;
50         if (ok && ServerThread::getInstance()->addInQueue(sddir, name, size, tth))
51             *retvalP = xmlrpc_c::value_int(0);
52         else
53             *retvalP = xmlrpc_c::value_int(1);
54     }
55 };
56 
57 class stopDaemonMethod : public xmlrpc_c::method {
58 public:
stopDaemonMethod()59     stopDaemonMethod() {
60         this->_signature = "s:";
61         this->_help = "(DEPRECATED) Stops the daemon. Params: none; returns: deprecation warning";
62     }
63 
64     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)65     execute(xmlrpc_c::paramList const& paramList,
66             xmlrpc_c::value *   const  retvalP) {
67 
68         *retvalP = xmlrpc_c::value_string("This method is deprecated. Please use system.shutdown instead.");
69         bServerTerminated = true;
70     }
71 };
72 
73 class hubAddMethod : public xmlrpc_c::method {
74 public:
hubAddMethod()75     hubAddMethod() {
76         this->_signature = "i:ss";
77         this->_help = "Adds a new hub and connects to it. Params: hub URL, encoding; returns: 0";
78     }
79 
80     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)81     execute(xmlrpc_c::paramList const& paramList,
82             xmlrpc_c::value *   const  retvalP) {
83 
84         string const shub(paramList.getString(0));
85         string const senc(paramList.getString(1));
86         paramList.verifyEnd(2);
87         ServerThread::getInstance()->connectClient(shub, senc);
88         *retvalP = xmlrpc_c::value_int(0);
89     }
90 };
91 
92 class hubDelMethod : public xmlrpc_c::method {
93 public:
hubDelMethod()94     hubDelMethod() {
95         this->_signature = "i:s";
96         this->_help = "Disconnects from a hub. Params: hub URL; returns: 0";
97     }
98 
99     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)100     execute(xmlrpc_c::paramList const& paramList,
101             xmlrpc_c::value *   const  retvalP) {
102 
103         string const shub(paramList.getString(0));
104         paramList.verifyEnd(1);
105         ServerThread::getInstance()->disconnectClient(shub);
106         *retvalP = xmlrpc_c::value_int(0);
107     }
108 };
109 
110 class hubSayMethod : public xmlrpc_c::method {
111 public:
hubSayMethod()112     hubSayMethod() {
113         this->_signature = "i:ss";
114         this->_help = "Sends a message on a hub. Params: hub URL, message; returns: 0 on success, non-zero otherwise";
115     }
116 
117     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)118     execute(xmlrpc_c::paramList const& paramList,
119             xmlrpc_c::value *   const  retvalP) {
120 
121         string const shub(paramList.getString(0));
122         string const smess(paramList.getString(1));
123         paramList.verifyEnd(2);
124         if (ServerThread::getInstance()->findHubInConnectedClients(shub)) {
125             ServerThread::getInstance()->sendMessage(shub, smess);
126             *retvalP = xmlrpc_c::value_int(0);
127         } else
128             *retvalP = xmlrpc_c::value_int(1);
129     }
130 };
131 
132 class hubSayPrivateMethod : public xmlrpc_c::method {
133 public:
hubSayPrivateMethod()134     hubSayPrivateMethod() {
135         this->_signature = "s:sss";
136         this->_help = "Sends a private message on a hub. Params: hub URL, nick, message; returns: error string";
137     }
138 
139     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)140     execute(xmlrpc_c::paramList const& paramList,
141             xmlrpc_c::value *   const  retvalP) {
142 
143         string const shub(paramList.getString(0));
144         string const snick(paramList.getString(1));
145         string const smess(paramList.getString(2));
146         paramList.verifyEnd(3);
147         if (ServerThread::getInstance()->sendPrivateMessage(shub, snick, smess))
148             *retvalP = xmlrpc_c::value_int(0);
149         else
150             *retvalP = xmlrpc_c::value_int(1);
151     }
152 };
153 
154 class listHubsMethod : public xmlrpc_c::method {
155 public:
listHubsMethod()156     listHubsMethod() {
157         this->_signature = "s:s";
158         this->_help = "Returns a list of connected hubs. Params: separator";
159     }
160 
161     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)162     execute(xmlrpc_c::paramList const& paramList,
163             xmlrpc_c::value *   const  retvalP) {
164 
165         string const sseparator(paramList.getString(0));
166         paramList.verifyEnd(1); string listhubs;
167         ServerThread::getInstance()->listConnectedClients(listhubs, sseparator);
168         *retvalP = xmlrpc_c::value_string(listhubs);
169     }
170 };
171 
172 class showVersionMethod : public xmlrpc_c::method {
173 public:
showVersionMethod()174     showVersionMethod() {
175         this->_signature = "s:";
176         this->_help = "Returns full client version. Params: none";
177     }
178 
179     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)180     execute(xmlrpc_c::paramList const& paramList,
181             xmlrpc_c::value *   const  retvalP) {
182 
183         string version(EISKALTDCPP_VERSION);
184         version.append(" (");
185         version.append(EISKALTDCPP_VERSION_SFX);
186         version.append(")");
187         *retvalP = xmlrpc_c::value_string(version);
188     }
189 };
190 
191 class showRatioMethod : public xmlrpc_c::method {
192 public:
showRatioMethod()193     showRatioMethod() {
194         this->_signature = "s:";
195         this->_help = "Returns upload/download ratio and absolute upload and download. "
196                       "Params: none; returns: \"ratio: X (uploads: Y, downloads: Z)\"";
197     }
198 
199     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)200     execute(xmlrpc_c::paramList const& paramList,
201             xmlrpc_c::value *   const  retvalP) {
202 
203         auto up    = SETTING(TOTAL_UPLOAD);
204         auto down  = SETTING(TOTAL_DOWNLOAD);
205         auto ratio = (down > 0) ? up / down : 0;
206 
207         string upload = Util::formatBytes(up);
208         string download = Util::formatBytes(down);
209 
210         map<string, xmlrpc_c::value> tmp_struct_in;
211         tmp_struct_in["ratio"] = xmlrpc_c::value_string(Util::toString(ratio));
212         tmp_struct_in["up"] = xmlrpc_c::value_string(upload);
213         tmp_struct_in["down"] = xmlrpc_c::value_string(download);
214         tmp_struct_in["up_bytes"] = xmlrpc_c::value_string(Util::toString(up));
215         tmp_struct_in["down_bytes"] = xmlrpc_c::value_string(Util::toString(down));
216         xmlrpc_c::value_struct const tmp_struct_out(tmp_struct_in);
217         *retvalP = tmp_struct_out;
218     }
219 };
220 
221 class addDirInShareMethod : public xmlrpc_c::method {
222 public:
addDirInShareMethod()223     addDirInShareMethod() {
224         this->_signature = "s:ss";
225         this->_help = "Adds a directory to the share. Params: directory, virtual name; returns: error string";
226     }
227 
228     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)229     execute(xmlrpc_c::paramList const& paramList,
230             xmlrpc_c::value *   const  retvalP) {
231 
232         string const sdirectory(paramList.getString(0));
233         string const svirtname(paramList.getString(1));
234         paramList.verifyEnd(2);
235         try {
236             if (ServerThread::getInstance()->addDirInShare(sdirectory, svirtname))
237                 *retvalP = xmlrpc_c::value_string("Directory added to share");
238             else
239                 *retvalP = xmlrpc_c::value_string("Directory doesn't exist");
240         } catch (const ShareException& e) {
241             *retvalP = xmlrpc_c::value_string(e.getError());
242         }
243     }
244 };
245 
246 class renameDirInShareMethod : public xmlrpc_c::method {
247 public:
renameDirInShareMethod()248     renameDirInShareMethod() {
249         this->_signature = "s:ss";
250         this->_help = "Renames a directory in the share. Params: directory, new virtual name; returns: error string";
251     }
252 
253     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)254     execute(xmlrpc_c::paramList const& paramList,
255             xmlrpc_c::value *   const  retvalP) {
256 
257         string const sdirectory(paramList.getString(0));
258         string const svirtname(paramList.getString(1));
259         paramList.verifyEnd(2);
260         try {
261             if (ServerThread::getInstance()->renameDirInShare(sdirectory, svirtname))
262                 *retvalP = xmlrpc_c::value_string("Directory has been renamed");
263             else
264                 *retvalP = xmlrpc_c::value_string("Directory not found");
265         } catch (const ShareException& e) {
266             *retvalP = xmlrpc_c::value_string(e.getError());
267         }
268     }
269 };
270 
271 class delDirFromShareMethod : public xmlrpc_c::method {
272 public:
delDirFromShareMethod()273     delDirFromShareMethod() {
274         this->_signature = "i:s";
275         this->_help = "Deletes a directory from the share. Params: virtual name of directory; returns: 0 on success, non-zero otherwise";
276     }
277 
278     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)279     execute(xmlrpc_c::paramList const& paramList,
280             xmlrpc_c::value *   const  retvalP) {
281 
282         string const sdirectory(paramList.getString(0));
283         paramList.verifyEnd(1);
284         if (ServerThread::getInstance()->delDirFromShare(sdirectory))
285             *retvalP = xmlrpc_c::value_int(0);
286         else
287             *retvalP = xmlrpc_c::value_int(1);
288     }
289 };
290 
291 class listShareMethod : public xmlrpc_c::method {
292 public:
listShareMethod()293     listShareMethod() {
294         this->_signature = "s:s";
295         this->_help = "Returns a list of shared directories. Params: separator";
296     }
297 
298     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)299     execute(xmlrpc_c::paramList const& paramList,
300             xmlrpc_c::value *   const  retvalP) {
301 
302         string const sseparator(paramList.getString(0));
303         paramList.verifyEnd(1);
304         string listshare;
305         ServerThread::getInstance()->listShare(listshare, sseparator);
306         *retvalP = xmlrpc_c::value_string(listshare);
307     }
308 };
309 
310 class refreshShareMethod : public xmlrpc_c::method {
311 public:
refreshShareMethod()312     refreshShareMethod() {
313         this->_signature = "i:";
314         this->_help = "Refreshes the share. Params: none; returns: 0";
315     }
316 
317     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)318     execute(xmlrpc_c::paramList const& paramList,
319             xmlrpc_c::value *   const  retvalP) {
320 
321         ShareManager::getInstance()->setDirty();
322         ShareManager::getInstance()->refresh(true);
323         *retvalP = xmlrpc_c::value_int(0);
324     }
325 };
326 
327 class getFileListMethod : public xmlrpc_c::method {
328 public:
getFileListMethod()329     getFileListMethod() {
330         this->_signature = "s:ss";
331         this->_help = "Adds the file list of a user to the download queue. Params: hub URL, nick; returns: error string";
332     }
333 
334     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)335     execute(xmlrpc_c::paramList const& paramList,
336             xmlrpc_c::value *   const  retvalP) {
337 
338         string const shub(paramList.getString(0));
339         string const snick(paramList.getString(1));
340         paramList.verifyEnd(2);
341         if (ServerThread::getInstance()->getFileList(shub, snick, false))
342             *retvalP = xmlrpc_c::value_int(0);
343         else
344             *retvalP = xmlrpc_c::value_int(1);
345     }
346 };
347 
348 class getChatPubMethod : public xmlrpc_c::method {
349 public:
getChatPubMethod()350     getChatPubMethod() {
351         this->_signature = "s:ss";
352         this->_help = "Returns a list of unread public chat messages on a hub. Params: hub URL, separator";
353     }
354 
355     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)356     execute(xmlrpc_c::paramList const& paramList,
357             xmlrpc_c::value *   const  retvalP) {
358 
359         string const shub(paramList.getString(0));
360         string const sseparator(paramList.getString(1));
361         paramList.verifyEnd(2);
362         string retchat;
363         ServerThread::getInstance()->getChatPubFromClient(retchat, shub, sseparator);
364         *retvalP = xmlrpc_c::value_string(retchat);
365     }
366 };
367 
368 class sendSearchMethod : public xmlrpc_c::method {
369 public:
sendSearchMethod()370     sendSearchMethod() {
371         this->_signature = "i:s";
372         this->_help = "Starts a search on all hubs. Params: search string; returns: 0 on success, non-zero otherwise";
373     }
374 
375     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)376     execute(xmlrpc_c::paramList const& paramList,
377             xmlrpc_c::value *   const  retvalP) {
378 
379         string const ssearch(paramList.getString(0));
380         paramList.verifyEnd(1);
381         if (ServerThread::getInstance()->sendSearchonHubs(ssearch, 0, 0, 0, 0, ""))
382             *retvalP = xmlrpc_c::value_int(0);
383         else
384             *retvalP = xmlrpc_c::value_int(1);
385     }
386 };
387 
388 class clearSearchResultsMethod : public xmlrpc_c::method {
389 public:
clearSearchResultsMethod()390     clearSearchResultsMethod() {
391         this->_signature = "i:s";
392         this->_help = "Clear search result on target hub/all hubs. Params: hub url; returns: array of search results";
393     }
394 
395     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)396     execute(xmlrpc_c::paramList const& paramList,
397             xmlrpc_c::value *   const  retvalP) {
398 
399         string const shuburl(paramList.getString(0));
400         if (ServerThread::getInstance()->clearSearchResults(shuburl))
401             *retvalP = xmlrpc_c::value_int(0);
402         else
403             *retvalP = xmlrpc_c::value_int(1);
404     }
405 };
406 
407 class returnSearchResultsMethod : public xmlrpc_c::method {
408 public:
returnSearchResultsMethod()409     returnSearchResultsMethod() {
410         this->_signature = "A:s";
411         this->_help = "Returns a list of search results on a certain hub. Params: hub URL; returns: array of search results";
412     }
413 
414     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)415     execute(xmlrpc_c::paramList const& paramList,
416             xmlrpc_c::value *   const  retvalP) {
417 
418         string const shuburl(paramList.getString(0));
419         vector<StringMap> hublist;
420         ServerThread::getInstance()->returnSearchResults(hublist, shuburl);
421         vector<xmlrpc_c::value> tmp_array_in;
422         for (const auto& hub : hublist) {
423             map<string, xmlrpc_c::value> tmp_struct_in;
424             for (const auto& rearchresult : hub) {
425                 pair<string, xmlrpc_c::value> member(rearchresult.first, xmlrpc_c::value_string(rearchresult.second));
426                 tmp_struct_in.insert(member);
427             }
428             xmlrpc_c::value_struct const tmp_struct_out(tmp_struct_in);
429             tmp_array_in.push_back(xmlrpc_c::value_struct(tmp_struct_out));
430         }
431         xmlrpc_c::value_array tmp_array_out(tmp_array_in);
432         *retvalP = tmp_array_out;
433     }
434 };
435 
436 class setPriorityQueueItemMethod : public xmlrpc_c::method {
437 public:
setPriorityQueueItemMethod()438     setPriorityQueueItemMethod() {
439         this->_signature = "i:si";
440         this->_help = "Sets the priority of a target. Params: target, priority in range from 0 (paused) to 5 (highest); returns: 0 on success; non-zero otherwise";
441     }
442 
443     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)444     execute(xmlrpc_c::paramList const& paramList,
445             xmlrpc_c::value *   const  retvalP) {
446 
447         string const starget(paramList.getString(0));
448         int const ipriority(paramList.getInt(1));
449         paramList.verifyEnd(2);
450         if (ServerThread::getInstance()->setPriorityQueueItem(starget, ipriority))
451             *retvalP = xmlrpc_c::value_int(0);
452         else
453             *retvalP = xmlrpc_c::value_int(1);
454     }
455 };
456 
457 class moveQueueItemMethod : public xmlrpc_c::method {
458 public:
moveQueueItemMethod()459     moveQueueItemMethod() {
460         this->_signature = "i:ss";
461         this->_help = "Move target param of queue item to new location. Params: target, new target; returns: 0 on success; non-zero otherwise";
462     }
463 
464     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)465     execute(xmlrpc_c::paramList const& paramList,
466             xmlrpc_c::value *   const  retvalP) {
467 
468         string const starget(paramList.getString(0));
469         string const snewtarget(paramList.getString(1));
470         paramList.verifyEnd(2);
471         if (ServerThread::getInstance()->moveQueueItem(starget, snewtarget))
472             *retvalP = xmlrpc_c::value_int(0);
473         else
474             *retvalP = xmlrpc_c::value_int(1);
475     }
476 };
477 
478 class removeQueueItemMethod : public xmlrpc_c::method {
479 public:
removeQueueItemMethod()480     removeQueueItemMethod() {
481         this->_signature = "i:ss";
482         this->_help = "Remove queue item by target. Params: target; returns: 0 on success; non-zero otherwise";
483     }
484 
485     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)486     execute(xmlrpc_c::paramList const& paramList,
487             xmlrpc_c::value *   const  retvalP) {
488 
489         string const starget(paramList.getString(0));;
490         paramList.verifyEnd(1);
491         if (ServerThread::getInstance()->removeQueueItem(starget))
492             *retvalP = xmlrpc_c::value_int(0);
493         else
494             *retvalP = xmlrpc_c::value_int(1);
495     }
496 };
497 
498 class listQueueTargetsMethod : public xmlrpc_c::method {
499 public:
listQueueTargetsMethod()500     listQueueTargetsMethod() {
501         this->_signature = "i:s";
502         this->_help = "List queue item targets. Params: separator";
503     }
504 
505     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)506     execute(xmlrpc_c::paramList const& paramList,
507             xmlrpc_c::value *   const  retvalP) {
508 
509         string const sseparator(paramList.getString(0));;
510         paramList.verifyEnd(1);
511         string tmp;
512         ServerThread::getInstance()->listQueueTargets(tmp, sseparator);
513         *retvalP = xmlrpc_c::value_string(tmp);
514     }
515 };
516 
517 class listQueueMethod : public xmlrpc_c::method {
518 public:
listQueueMethod()519     listQueueMethod() {
520         this->_signature = "i:s";
521         this->_help = "List queue items. Params: separator";
522     }
523 
524     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)525     execute(xmlrpc_c::paramList const& paramList,
526             xmlrpc_c::value *   const  retvalP) {
527 
528         unordered_map<string,StringMap> listqueue;
529         ServerThread::getInstance()->listQueue(listqueue);
530         map<string, xmlrpc_c::value> tmp_struct1_in;
531         for (const auto& item : listqueue) {
532             map<string, xmlrpc_c::value> tmp_struct2_in;
533             for (const auto& parameter : item.second) {
534                 pair<string, xmlrpc_c::value> member2(parameter.first, xmlrpc_c::value_string(parameter.second));
535                 tmp_struct2_in.insert(member2);
536             }
537             xmlrpc_c::value_struct const tmp_struct2_out(tmp_struct2_in);
538             pair<string, xmlrpc_c::value> member1(i->first, xmlrpc_c::value_struct(tmp_struct2_out));
539             tmp_struct1_in.insert(member1);
540         }
541         xmlrpc_c::value_struct tmp_struct1_out(tmp_struct1_in);
542         *retvalP = tmp_struct1_out;
543     }
544 };
545 
546 class getSourcesItemMethod : public xmlrpc_c::method {
547 public:
getSourcesItemMethod()548     getSourcesItemMethod() {
549         this->_signature = "i:s";
550         this->_help = "Return sources on target. Params: target, separator";
551     }
552 
553     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)554     execute(xmlrpc_c::paramList const& paramList,
555             xmlrpc_c::value *   const  retvalP) {
556 
557         string const starget(paramList.getString(0));;
558         string const sseparator(paramList.getString(1));;
559         paramList.verifyEnd(2);
560         string sources;
561         unsigned int online = 0;
562         ServerThread::getInstance()->getItemSourcesbyTarget(starget, sseparator, sources, online);
563         map<string, xmlrpc_c::value> tmp_struct_in;
564         tmp_struct_in["sources"] = xmlrpc_c::value_string(sources);
565         tmp_struct_in["online"] = xmlrpc_c::value_int(online);
566         xmlrpc_c::value_struct const tmp_struct_out(tmp_struct_in);
567         *retvalP = tmp_struct_out;
568     }
569 };
570 
571 class getHashStatusMethod : public xmlrpc_c::method {
572 public:
getHashStatusMethod()573     getHashStatusMethod() {
574         this->_signature = "i:s";
575         this->_help = "Return hashing status. Params: none";
576     }
577 
578     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)579     execute(xmlrpc_c::paramList const& paramList,
580             xmlrpc_c::value *   const  retvalP) {
581 
582         string tmp = " ",status = " "; int64_t bytes = 0; size_t files = 0;
583         ServerThread::getInstance()->getHashStatus(tmp, bytes, files, status);
584         map<string, xmlrpc_c::value> tmp_struct_in;
585         tmp_struct_in["currentfile"] = xmlrpc_c::value_string(tmp);
586         tmp_struct_in["status"] = xmlrpc_c::value_string(status);
587         tmp_struct_in["bytesleft"] = xmlrpc_c::value_i8(bytes);
588         tmp_struct_in["filesleft"] = xmlrpc_c::value_i8(files);
589         xmlrpc_c::value_struct const tmp_struct_out(tmp_struct_in);
590         *retvalP = tmp_struct_out;
591     }
592 };
593 
594 class pauseHashMethod : public xmlrpc_c::method {
595 public:
pauseHashMethod()596     pauseHashMethod() {
597         this->_signature = "i:s";
598         this->_help = "Switch pause hashing. Params: none";
599     }
600 
601     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)602     execute(xmlrpc_c::paramList const& paramList,
603             xmlrpc_c::value *   const  retvalP) {
604 
605         if (ServerThread::getInstance()->pauseHash())
606             *retvalP = xmlrpc_c::value_int(0);
607         else
608             *retvalP = xmlrpc_c::value_int(1);
609     }
610 };
611 
612 class getMethodListMethod : public xmlrpc_c::method {
613 public:
getMethodListMethod()614     getMethodListMethod() {
615         this->_signature = "i:s";
616         this->_help = "Return method list separated by \"|\". Params: none";
617     }
618 
619     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)620     execute(xmlrpc_c::paramList const& paramList,
621             xmlrpc_c::value *   const  retvalP) {
622 
623         string tmp;
624         ServerThread::getInstance()->getMethodList(tmp);
625         *retvalP = xmlrpc_c::value_string(tmp);
626     }
627 };
628 
629 class getHubUserListMethod: public xmlrpc_c::method {
630 public:
getHubUserListMethod()631     getHubUserListMethod() {
632         this->_signature = "i:ss";
633         this->_help = "Return user list on huburl. Params: huburl, separator";
634     }
635 
636     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)637     execute(xmlrpc_c::paramList const& paramList,
638             xmlrpc_c::value *   const  retvalP) {
639 
640         string const shuburl(paramList.getString(0));;
641         string const sseparator(paramList.getString(1));;
642         paramList.verifyEnd(2);
643         string tmp;
644         ServerThread::getInstance()->getHubUserList(tmp, shuburl, sseparator);
645         *retvalP = xmlrpc_c::value_string(tmp);
646     }
647 };
648 
649 class getUserInfoMethod : public xmlrpc_c::method {
650 public:
getUserInfoMethod()651     getUserInfoMethod() {
652         this->_signature = "i:ss";
653         this->_help = "Return info about user on huburl. Params: nick, huburl";
654     }
655 
656     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)657     execute(xmlrpc_c::paramList const& paramList,
658             xmlrpc_c::value *   const  retvalP) {
659 
660         string const snick(paramList.getString(0));;
661         string const shuburl(paramList.getString(1));;
662         paramList.verifyEnd(2);
663         StringMap params;
664         if (ServerThread::getInstance()->getUserInfo(params, snick, shuburl)) {
665             map<string, xmlrpc_c::value> tmp_struct_in;
666             for (const auto& parameter : params) {
667                 pair<string, xmlrpc_c::value> member(parameter.first, xmlrpc_c::value_string(parameter.second));
668                 tmp_struct_in.insert(member);
669             }
670             xmlrpc_c::value_struct const tmp_struct_out(tmp_struct_in);
671             *retvalP = tmp_struct_out;
672         } else
673             *retvalP = xmlrpc_c::value_nil();
674     }
675 };
676 
677 class matchAllListMethod : public xmlrpc_c::method {
678 public:
matchAllListMethod()679     matchAllListMethod() {
680         this->_signature = "s:";
681         this->_help = "Match all local file lists. Params: none; returns: 0";
682     }
683 
684     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)685     execute(xmlrpc_c::paramList const& paramList,
686             xmlrpc_c::value *   const  retvalP) {
687 
688         ServerThread::getInstance()->matchAllList();
689         *retvalP = xmlrpc_c::value_int(0);
690     }
691 };
692 
693 class listHubsFullDescMethod : public xmlrpc_c::method {
694 public:
listHubsFullDescMethod()695     listHubsFullDescMethod() {
696         this->_signature = "s:";
697         this->_help = "Return list all hubs with params. Params: none; returns: array of hub with params";
698     }
699 
700     void
execute(xmlrpc_c::paramList const & paramList,xmlrpc_c::value * const retvalP)701     execute(xmlrpc_c::paramList const& paramList,
702             xmlrpc_c::value *   const  retvalP) {
703 
704         unordered_map<string,StringMap> listhubs;
705         ServerThread::getInstance()->listHubsFullDesc(listhubs);
706         map<string, xmlrpc_c::value> tmp_struct1_in;
707         for (const auto& hub : listhubs) {
708             map<string, xmlrpc_c::value> tmp_struct2_in;
709             for (const auto& parameter : hub.second) {
710                 pair<string, xmlrpc_c::value> member2(parameter.first, xmlrpc_c::value_string(parameter.second));
711                 tmp_struct2_in.insert(member2);
712             }
713             xmlrpc_c::value_struct const tmp_struct2_out(tmp_struct2_in);
714             pair<string, xmlrpc_c::value> member1(hub.first, xmlrpc_c::value_struct(tmp_struct2_out));
715             tmp_struct1_in.insert(member1);
716         }
717         xmlrpc_c::value_struct tmp_struct1_out(tmp_struct1_in);
718         *retvalP = tmp_struct1_out;
719     }
720 };
721 
722 class systemShutdownMethod : public xmlrpc_c::registry::shutdown {
723 public:
~systemShutdownMethod()724     ~systemShutdownMethod() {}
725 
726     void
doit(std::string const & comment,void * const callInfo)727     doit(std::string const& comment, void * const callInfo) const {
728         if (isVerbose) std::cout << "Shutting down, comment: " << comment << std::endl;
729         bServerTerminated = true;
730     }
731 };
732