1 /*
2  * Copyright (C) 2001-2012 Jacek Sieka, arnetheduck on gmail point com
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #pragma once
20 
21 #include "SettingsManager.h"
22 #include "Socket.h"
23 #include "User.h"
24 #include "Thread.h"
25 #include "Client.h"
26 #include "Singleton.h"
27 #include "Semaphore.h"
28 #include "SearchManagerListener.h"
29 #include "TimerManager.h"
30 #include "AdcCommand.h"
31 #include "ClientManager.h"
32 
33 namespace dcpp {
34 
35 class SearchManager;
36 class SocketException;
37 
38 class SearchManager : public Speaker<SearchManagerListener>, public Singleton<SearchManager>, public Thread
39 {
40 public:
41     enum SizeModes {
42         SIZE_DONTCARE = 0x00,
43         SIZE_ATLEAST = 0x01,
44         SIZE_ATMOST = 0x02
45     };
46 
47     enum TypeModes {
48         TYPE_ANY = 0,
49         TYPE_AUDIO,
50         TYPE_COMPRESSED,
51         TYPE_DOCUMENT,
52         TYPE_EXECUTABLE,
53         TYPE_PICTURE,
54         TYPE_VIDEO,
55         TYPE_DIRECTORY,
56         TYPE_TTH,
57         TYPE_CD_IMAGE,
58         TYPE_LAST
59     };
60 private:
61     static const char* types[TYPE_LAST];
62 public:
63     static const char* getTypeStr(int type);
64 
65     void search(const string& aName, int64_t aSize, TypeModes aTypeMode, SizeModes aSizeMode, const string& aToken, void* aOwner = NULL);
66     void search(const string& aName, const string& aSize, TypeModes aTypeMode, SizeModes aSizeMode, const string& aToken, void* aOwner = NULL) {
67         search(aName, Util::toInt64(aSize), aTypeMode, aSizeMode, aToken, aOwner);
68     }
69 
70     uint64_t search(StringList& who, const string& aName, int64_t aSize, TypeModes aTypeMode, SizeModes aSizeMode, const string& aToken, const StringList& aExtList, void* aOwner = NULL);
71     uint64_t search(StringList& who, const string& aName, const string& aSize, TypeModes aTypeMode, SizeModes aSizeMode, const string& aToken, const StringList& aExtList, void* aOwner = NULL) {
72         return search(who, aName, Util::toInt64(aSize), aTypeMode, aSizeMode, aToken, aExtList, aOwner);
73     }
74 
75     void respond(const AdcCommand& cmd, const CID& cid,  bool isUdpActive, const string& hubIpPort);
76 
getPort()77     uint16_t getPort() const
78     {
79         return port;
80     }
81 
82     void listen();
83     void disconnect() noexcept;
onSearchResult(const string & aLine)84     void onSearchResult(const string& aLine) {
85         onData((const uint8_t*)aLine.data(), aLine.length(), Util::emptyString);
86     }
87 
88     void onRES(const AdcCommand& cmd, const UserPtr& from, const string& remoteIp = Util::emptyString);
89     void onPSR(const AdcCommand& cmd, UserPtr from, const string& remoteIp = Util::emptyString);
90     AdcCommand toPSR(bool wantResponse, const string& myNick, const string& hubIpPort, const string& tth, const vector<uint16_t>& partialInfo) const;
91 
92 private:
93     class UdpQueue: public Thread {
94     public:
UdpQueue()95         UdpQueue() : stop(false) {}
~UdpQueue()96         ~UdpQueue() noexcept { shutdown(); }
97 
98         int run();
shutdown()99         void shutdown() {
100             stop = true;
101             s.signal();
102         }
addResult(const string & buf,const string & ip)103         void addResult(const string& buf, const string& ip) {
104             {
105                 Lock l(csudp);
106                 resultList.push_back(make_pair(buf, ip));
107             }
108             s.signal();
109         }
110 
111     private:
112         CriticalSection csudp;
113         Semaphore s;
114 
115         deque<pair<string, string> > resultList;
116 
117         bool stop;
118     } queue;
119 
120     CriticalSection cs;
121     std::unique_ptr<Socket> socket;
122     uint16_t port;
123     bool stop;
124     friend class Singleton<SearchManager>;
125 
126     SearchManager();
127 
128     static std::string normalizeWhitespace(const std::string& aString);
129     int run();
130 
131     ~SearchManager();
132     void onData(const uint8_t* buf, size_t aLen, const string& address);
133 
134     string getPartsString(const PartsInfo& partsInfo) const;
135 };
136 
137 } // namespace dcpp
138