Updated init script.
[dtbartle/bnbt.git] / tracker_scrape.cpp
1 /***\r
2 *\r
3 * BNBT Beta 8.0 - A C++ BitTorrent Tracker\r
4 * Copyright (C) 2003-2004 Trevor Hogan\r
5 *\r
6 * CBTT variations (C) 2003-2005 Harold Feit\r
7 *\r
8 * This library is free software; you can redistribute it and/or\r
9 * modify it under the terms of the GNU Lesser General Public\r
10 * License as published by the Free Software Foundation; either\r
11 * version 2.1 of the License, or (at your option) any later version.\r
12 *\r
13 * This library is distributed in the hope that it will be useful,\r
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
16 * Lesser General Public License for more details.\r
17 *\r
18 * You should have received a copy of the GNU Lesser General Public\r
19 * License along with this library; if not, write to the Free Software\r
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
21 *\r
22 ***/\r
23 \r
24 #include "bnbt.h"\r
25 #include "bnbt_mysql.h"\r
26 #include "atom.h"\r
27 #include "bencode.h"\r
28 #include "tracker.h"\r
29 #include "util.h"\r
30 \r
31 void CTracker :: serverResponseScrape( struct request_t *pRequest, struct response_t *pResponse, user_t user )\r
32 {\r
33         if( !m_bAllowScrape )\r
34         {\r
35                 pResponse->strCode = "403 Forbidden";\r
36 \r
37                 return;\r
38         }\r
39 \r
40         typedef multimap<string,string> stringmap;\r
41         pResponse->strCode = "200 OK";\r
42 \r
43         pResponse->mapHeaders.insert( pair<string, string>( "Content-Type", "text/plain" ) );\r
44 \r
45         // retrieve info hash (note that the client sends an actual hash so don't convert it)\r
46 \r
47         //      Commented - MultiMapping InfoHash paramaters instead\r
48         //      string strInfoHash = pRequest->multiParams["info_hash"];\r
49         //  Major rehaul in the scrape function to allow for multi-scrape\r
50 \r
51         CAtomDicti *pScrape = new CAtomDicti( );\r
52         CAtomDicti *pFiles = new CAtomDicti( );\r
53         CAtomDicti *pFlags = new CAtomDicti( );\r
54 \r
55         pScrape->setItem( "files", pFiles );\r
56         pScrape->setItem( "flags", pFlags );\r
57 \r
58         pFlags->setItem( "min_request_interval", new CAtomLong( m_iMinRequestInterval ) );\r
59 \r
60         if ( !pRequest->hasQuery )\r
61         {\r
62                 // disable global scraping\r
63                 if( !m_bAllowGlobalScrape )\r
64                 {\r
65                         pResponse->strCode = "403 Forbidden";\r
66                         return;\r
67                 }\r
68 #ifdef BNBT_MYSQL\r
69    if( m_bMySQLOverrideDState && m_iMySQLRefreshStatsInterval > 0 )\r
70    {\r
71       // Modified by =Xotic=\r
72       string strQuery;\r
73       strQuery = "SELECT bseeders,bleechers,bcompleted,bhash FROM torrents";\r
74 \r
75       CMySQLQuery *pQuery = new CMySQLQuery( strQuery );\r
76 \r
77       vector<string> vecQuery;\r
78          // full\r
79       while( ( vecQuery = pQuery->nextRow( ) ).size( ) == 4 )\r
80       {\r
81             CAtomDicti *pHuh = new CAtomDicti( );\r
82 \r
83             pHuh->setItem( "complete", new CAtomInt( atoi( vecQuery[0].c_str( ) ) ) );\r
84             pHuh->setItem( "incomplete", new CAtomInt( atoi( vecQuery[1].c_str( ) ) ) );\r
85             pHuh->setItem( "downloaded", new CAtomInt( atoi( vecQuery[2].c_str( ) ) ) );\r
86 \r
87             if( m_pAllowed )\r
88             {\r
89                CAtom *pList = m_pAllowed->getItem( vecQuery[3] );\r
90 \r
91                if( pList && dynamic_cast<CAtomList *>( pList ) )\r
92                {\r
93                   vector<CAtom *> vecTorrent = dynamic_cast<CAtomList *>( pList )->getValue( );\r
94 \r
95                   if( vecTorrent.size( ) == 6 )\r
96                   {\r
97                      CAtom *pName = vecTorrent[1];\r
98 \r
99                      if( pName )\r
100                         pHuh->setItem( "name", new CAtomString( pName->toString( ) ) );\r
101                   }\r
102                }\r
103             }\r
104 \r
105             pFiles->setItem( vecQuery[3], pHuh );\r
106          }\r
107                 delete pQuery;\r
108                 pResponse->strContent = Encode ( pScrape );\r
109                 delete pScrape;\r
110                 return;\r
111    }\r
112 #endif\r
113         if( m_pDFile )\r
114         {\r
115                 map<string, CAtom *> *pmapDicti = m_pDFile->getValuePtr( );\r
116 \r
117                 for( map<string, CAtom *> :: iterator i = pmapDicti->begin( ); i != pmapDicti->end( ); i++ )\r
118                 {\r
119                         if( (*i).second->isDicti( ) )\r
120                         {\r
121                                 CAtomDicti *pHuh = new CAtomDicti( );\r
122 \r
123                                 map<string, CAtom *> *pmapPeersDicti = ( (CAtomDicti *)(*i).second )->getValuePtr( );\r
124 \r
125                                 unsigned long iSeeders = 0;\r
126                                 unsigned long iLeechers = 0;\r
127 \r
128                                 for( map<string, CAtom *> :: iterator j = pmapPeersDicti->begin( ); j != pmapPeersDicti->end( ); j++ )\r
129                                 {\r
130                                         if( (*j).second->isDicti( ) )\r
131                                         {\r
132                                                 CAtom *pLeft = ( (CAtomDicti *)(*j).second )->getItem( "left" );\r
133 \r
134                                                 if( pLeft && pLeft->isLong( ) )\r
135                                                 {\r
136                                                         if( ( (CAtomLong *)pLeft )->getValue( ) == 0 )\r
137                                                                 iSeeders++;\r
138                                                         else\r
139                                                                 iLeechers++;\r
140                                                 }\r
141                                         }\r
142                                 }\r
143 \r
144                                 pHuh->setItem( "complete", new CAtomInt( iSeeders ) );\r
145                                 pHuh->setItem( "incomplete", new CAtomInt( iLeechers ) );\r
146 \r
147                                 if( m_pAllowed )\r
148                                 {\r
149                                         CAtom *pList = m_pAllowed->getItem( (*i).first );\r
150 \r
151                                         if( pList && pList->isList( ) )\r
152                                         {\r
153                                                 vector<CAtom *> vecTorrent = ( (CAtomList *)pList )->getValue( );\r
154 \r
155                                                 if( vecTorrent.size( ) == 6 )\r
156                                                 {\r
157                                                         CAtom *pName = vecTorrent[1];\r
158 \r
159                                                         if( pName )\r
160                                                                 pHuh->setItem( "name", new CAtomString( pName->toString( ) ) );\r
161                                                 }\r
162                                         }\r
163                                 }\r
164 \r
165                                 if( m_pCompleted )\r
166                                 {\r
167                                         CAtom *pCompleted = m_pCompleted->getItem( (*i).first );\r
168 \r
169                                         if( pCompleted && pCompleted->isLong( ) )\r
170                                                 pHuh->setItem( "downloaded", new CAtomLong( ( (CAtomLong *)pCompleted )->getValue( ) ) );\r
171                                 }\r
172 \r
173                                 pFiles->setItem( (*i).first, pHuh );\r
174                                 }\r
175                         }\r
176                 }\r
177                 pResponse->strContent = Encode ( pScrape );\r
178                 delete pScrape;\r
179                 return;\r
180         }\r
181         else\r
182         {\r
183                 for(stringmap::iterator pos = pRequest->multiParams.lower_bound("info_hash"); pos != pRequest->multiParams.upper_bound("info_hash"); pos++)\r
184                 {\r
185 #ifdef BNBT_MYSQL\r
186                if( m_bMySQLOverrideDState && m_iMySQLRefreshStatsInterval > 0 )\r
187                         {\r
188                                 string strQuery;\r
189                                 strQuery = "SELECT bseeders,bleechers,bcompleted FROM torrents WHERE bhash=\'" + UTIL_StringToMySQL( (*pos).second ) + "\'";\r
190 \r
191                                 CMySQLQuery *pQuery = new CMySQLQuery( strQuery );\r
192                                 vector<string> vecQuery;\r
193          // single\r
194          while( ( vecQuery = pQuery->nextRow( ) ).size( ) == 3 )\r
195          {\r
196             CAtomDicti *pHuh = new CAtomDicti( );\r
197 \r
198             pHuh->setItem( "complete", new CAtomInt( atoi( vecQuery[0].c_str( ) ) ) );\r
199             pHuh->setItem( "incomplete", new CAtomInt( atoi( vecQuery[1].c_str( ) ) ) );\r
200             pHuh->setItem( "downloaded", new CAtomInt( atoi( vecQuery[2].c_str( ) ) ) );\r
201 \r
202             if( m_pAllowed )\r
203             {\r
204                CAtom *pList = m_pAllowed->getItem( (*pos).second );\r
205 \r
206                if( pList && dynamic_cast<CAtomList *>( pList ) )\r
207                {\r
208                   vector<CAtom *> vecTorrent = dynamic_cast<CAtomList *>( pList )->getValue( );\r
209 \r
210                   if( vecTorrent.size( ) == 6 )\r
211                   {\r
212                      CAtom *pName = vecTorrent[1];\r
213 \r
214                      if( pName )\r
215                         pHuh->setItem( "name", new CAtomString( pName->toString( ) ) );\r
216                   }\r
217                }\r
218             }\r
219 \r
220             pFiles->setItem( (*pos).second , pHuh );\r
221          }\r
222                       delete pQuery;\r
223                  }\r
224                    else\r
225                    {\r
226 #endif\r
227                         CAtom *pPeers = m_pDFile->getItem( (*pos).second );\r
228 \r
229                         if( pPeers && pPeers->isDicti( ) )\r
230                         {\r
231                                 CAtomDicti *pHuh = new CAtomDicti( );\r
232 \r
233                                 map<string, CAtom *> *pmapPeersDicti = ( (CAtomDicti *)pPeers )->getValuePtr( );\r
234 \r
235                                 unsigned long iSeeders = 0;\r
236                                 unsigned long iLeechers = 0;\r
237 \r
238                                 for( map<string, CAtom *> :: iterator j = pmapPeersDicti->begin( ); j != pmapPeersDicti->end( ); j++ )\r
239                                 {\r
240                                         if( (*j).second->isDicti( ) )\r
241                                         {\r
242                                                 CAtom *pLeft = ( (CAtomDicti *)(*j).second )->getItem( "left" );\r
243 \r
244                                                 if( pLeft && pLeft->isLong( ) )\r
245                                                 {\r
246                                                         if( ( (CAtomLong *)pLeft )->getValue( ) == 0 )\r
247                                                                 iSeeders++;\r
248                                                         else\r
249                                                                 iLeechers++;\r
250                                                 }\r
251                                         }\r
252                                 }\r
253 \r
254                                 pHuh->setItem( "complete", new CAtomInt( iSeeders ) );\r
255                                 pHuh->setItem( "incomplete", new CAtomInt( iLeechers ) );\r
256 \r
257                                 if( m_pAllowed )\r
258                                 {\r
259                                         CAtom *pList = m_pAllowed->getItem( (*pos).second );\r
260 \r
261                                         if( pList && pList->isList( ) )\r
262                                         {\r
263                                                 vector<CAtom *> vecTorrent = ( (CAtomList *)pList )->getValue( );\r
264 \r
265                                                 if( vecTorrent.size( ) == 6 )\r
266                                                 {\r
267                                                         CAtom *pName = vecTorrent[1];\r
268 \r
269                                                         if( pName )\r
270                                                                 pHuh->setItem( "name", new CAtomString( pName->toString( ) ) );\r
271                                                 }\r
272                                         }\r
273                                 }\r
274 \r
275                                 if( m_pCompleted )\r
276                                 {\r
277                                         CAtom *pCompleted = m_pCompleted->getItem( (*pos).second );\r
278 \r
279                                         if( pCompleted && pCompleted->isLong( ) )\r
280                                                 pHuh->setItem( "downloaded", new CAtomLong( ( (CAtomLong *)pCompleted )->getValue( ) ) );\r
281                                 }\r
282 \r
283                                 pFiles->setItem( (*pos).second, pHuh );\r
284                         }\r
285 \r
286                 }\r
287 \r
288 #ifdef BNBT_MYSQL\r
289 }\r
290 #endif\r
291 \r
292         pResponse->strContent = Encode( pScrape );\r
293         delete pScrape;\r
294 \r
295         }\r
296 \r
297 }\r