summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--opentracker.c33
-rw-r--r--trackerlogic.c44
2 files changed, 70 insertions, 7 deletions
diff --git a/opentracker.c b/opentracker.c
index a2f0db2..5fa6548 100644
--- a/opentracker.c
+++ b/opentracker.c
@@ -106,7 +106,7 @@ void httpresponse(int64 s,struct http_data* h)
106 ot_peer peer; 106 ot_peer peer;
107 ot_torrent *torrent; 107 ot_torrent *torrent;
108 ot_hash *hash = NULL; 108 ot_hash *hash = NULL;
109 int numwant, tmp, scanon; 109 int numwant, tmp, scanon, mode;
110 unsigned short port = htons(6881); 110 unsigned short port = htons(6881);
111 size_t reply_size = 0; 111 size_t reply_size = 0;
112 112
@@ -130,8 +130,37 @@ e400:
130 case 5: /* scrape ? */ 130 case 5: /* scrape ? */
131 if (byte_diff(data,5,"stats")) 131 if (byte_diff(data,5,"stats"))
132 goto e404; 132 goto e404;
133 scanon = 1;
134 mode = STATS_MRTG;
135
136 while( scanon ) {
137 switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) {
138 case -2: /* terminator */
139 scanon = 0;
140 break;
141 case -1: /* error */
142 goto e404;
143 case 4:
144 if(byte_diff(data,4,"mode")) {
145 scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
146 continue;
147 }
148 size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE );
149 if( len <= 0 ) goto e400_param;
150 if( !byte_diff(data,4,"mrtg"))
151 mode = STATS_MRTG;
152 else if( !byte_diff(data,4,"top5"))
153 mode = STATS_TOP5;
154 else
155 goto e400_param;
156 default:
157 scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
158 break;
159 }
160 }
161
133 /* Enough for http header + whole scrape string */ 162 /* Enough for http header + whole scrape string */
134 if( ( reply_size = return_stats_for_tracker( SUCCESS_HTTP_HEADER_LENGTH + static_reply ) ) <= 0 ) 163 if( ( reply_size = return_stats_for_tracker( SUCCESS_HTTP_HEADER_LENGTH + static_reply, mode ) ) <= 0 )
135 goto e500; 164 goto e500;
136 break; 165 break;
137 case 6: /* scrape ? */ 166 case 6: /* scrape ? */
diff --git a/trackerlogic.c b/trackerlogic.c
index 2a79df2..b044245 100644
--- a/trackerlogic.c
+++ b/trackerlogic.c
@@ -311,26 +311,60 @@ size_t return_scrape_for_torrent( ot_hash *hash, char *reply ) {
311 return r - reply; 311 return r - reply;
312} 312}
313 313
314typedef struct { int val; ot_torrent * torrent; } ot_record;
315
314/* Fetches stats from tracker */ 316/* Fetches stats from tracker */
315size_t return_stats_for_tracker( char *reply ) { 317size_t return_stats_for_tracker( char *reply, int mode ) {
316 time_t time_now = NOW; 318 time_t time_now = NOW;
317 int torrent_count = 0, peer_count = 0, seed_count = 0; 319 int torrent_count = 0, peer_count = 0, seed_count = 0;
320 ot_record top5s[5], top5c[5];
318 char *r = reply; 321 char *r = reply;
319 int i,j,k; 322 int i,j,k;
320 323
324 byte_zero( top5s, sizeof( top5s ) );
325 byte_zero( top5c, sizeof( top5c ) );
326
321 for( i=0; i<256; ++i ) { 327 for( i=0; i<256; ++i ) {
322 ot_vector *torrents_list = &all_torrents[i]; 328 ot_vector *torrents_list = &all_torrents[i];
323 torrent_count += torrents_list->size; 329 torrent_count += torrents_list->size;
324 for( j=0; j<torrents_list->size; ++j ) { 330 for( j=0; j<torrents_list->size; ++j ) {
325 ot_peerlist *peer_list = ( ((ot_torrent*)(torrents_list->data))[j] ).peer_list; 331 ot_peerlist *peer_list = ( ((ot_torrent*)(torrents_list->data))[j] ).peer_list;
332 int local_peers = 0, local_seeds = 0;
326 clean_peerlist( time_now, peer_list ); 333 clean_peerlist( time_now, peer_list );
327 for( k=0; k<OT_POOLS_COUNT; ++k ) { 334 for( k=0; k<OT_POOLS_COUNT; ++k ) {
328 peer_count += peer_list->peers[k].size; 335 local_peers += peer_list->peers[k].size;
329 seed_count += peer_list->seed_count[k]; 336 local_seeds += peer_list->seed_count[k];
337 }
338 if( mode == STATS_TOP5 ) {
339 int idx = 4; while( (idx >= 0) && ( local_peers > top5c[idx].val ) ) --idx;
340 if ( idx++ != 4 ) {
341 memmove( top5c + idx + 1, top5c + idx, ( 4 - idx ) * sizeof( ot_record ) );
342 top5c[idx].val = local_peers;
343 top5c[idx].torrent = (ot_torrent*)(torrents_list->data) + j;
344 }
345 idx = 4; while( (idx >= 0) && ( local_seeds > top5s[idx].val ) ) --idx;
346 if ( idx++ != 4 ) {
347 memmove( top5s + idx + 1, top5s + idx, ( 4 - idx ) * sizeof( ot_record ) );
348 top5s[idx].val = local_seeds;
349 top5s[idx].torrent = (ot_torrent*)(torrents_list->data) + j;
350 }
330 } 351 }
352 peer_count += local_peers; seed_count += local_seeds;
331 } 353 }
332 } 354 }
333 r += sprintf( r, "%i\n%i\nopentracker serving %i torrents\nSomething else.", peer_count, seed_count, torrent_count ); 355 if( mode == STATS_TOP5 ) {
356 int idx;
357 r += sprintf( r, "Top5 torrents by peers:\n" );
358 for( idx=0; idx<5; ++idx )
359 if( top5c[idx].torrent )
360 r += sprintf( r, "\t%i\t%s\n", top5c[idx].val, to_hex(top5c[idx].torrent->hash) );
361 r += sprintf( r, "Top5 torrents by seeds:\n" );
362 for( idx=0; idx<5; ++idx )
363 if( top5s[idx].torrent )
364 r += sprintf( r, "\t%i\t%s\n", top5s[idx].val, to_hex(top5s[idx].torrent->hash) );
365 } else {
366 r += sprintf( r, "%i\n%i\nopentracker serving %i torrents\nSomething else.", peer_count, seed_count, torrent_count );
367 }
334 368
335 return r - reply; 369 return r - reply;
336} 370}