diff options
-rw-r--r-- | opentracker.c | 33 | ||||
-rw-r--r-- | trackerlogic.c | 44 |
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 | ||
314 | typedef struct { int val; ot_torrent * torrent; } ot_record; | ||
315 | |||
314 | /* Fetches stats from tracker */ | 316 | /* Fetches stats from tracker */ |
315 | size_t return_stats_for_tracker( char *reply ) { | 317 | size_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 | } |