source: trunk/src/halSession.cpp @ 741

Revision 741, 23.0 KB checked in by Eoin, 11 years ago (diff)

Torrent manager given it's own header with cleanup refactoring.

Line 
1
2//         Copyright Eóin O'Callaghan 2006 - 2009.
3// Distributed under the Boost Software License, Version 1.0.
4//    (See accompanying file LICENSE_1_0.txt or copy at
5//          http://www.boost.org/LICENSE_1_0.txt)
6
7#include "stdAfx.hpp"
8
9#define TORRENT_MAX_ALERT_TYPES 32
10
11#include <boost/utility/in_place_factory.hpp>
12#include <boost/none.hpp>
13
14#include "win32_exception.hpp"
15
16#include "global/wtl_app.hpp"
17#include "global/string_conv.hpp"
18#include "global/ini_adapter.hpp"
19
20#include "halIni.hpp"
21#include "halTypes.hpp"
22#include "halEvent.hpp"
23#include "halSignaler.hpp"
24#include "halSession.hpp"
25
26#pragma warning (push, 1)
27#       include <libtorrent/create_torrent.hpp>
28#pragma warning (pop)
29
30namespace hal
31{
32
33bit_impl::bit_impl() :
34        session_(libt::fingerprint(HALITE_FINGERPRINT)),
35        keepChecking_(false),
36        bittorrent_ini_(L"BitTorrent.xml"),
37        the_torrents_(bittorrent_ini_),
38        default_torrent_max_connections_(-1),
39        default_torrent_max_uploads_(-1),
40        default_torrent_download_(-1),
41        default_torrent_upload_(-1),
42        resolve_countries_(true),
43        ip_filter_on_(false),
44        ip_filter_loaded_(false),
45        ip_filter_changed_(false),
46        ip_filter_count_(0),
47        dht_on_(false)
48{
49        try
50        {
51
52        torrent_internal::the_session_ = &session_;
53
54        session_.session::set_alert_mask(libt::alert::all_categories);         
55        session_.add_extension(&libt::create_metadata_plugin);
56        session_.add_extension(&libt::create_ut_pex_plugin);
57        session_.set_max_half_open_connections(10);
58       
59        hal::event_log.post(shared_ptr<hal::EventDetail>(
60                new hal::EventMsg(L"Loading BitTorrent.xml.", hal::event_logger::info)));               
61        bittorrent_ini_.load_data();
62        hal::event_log.post(shared_ptr<hal::EventDetail>(
63                new hal::EventMsg(L"Loading torrent parameters.", hal::event_logger::info)));   
64        the_torrents_.load_from_ini();
65        hal::event_log.post(shared_ptr<hal::EventDetail>(
66                new hal::EventMsg(L"Loading done!", hal::event_logger::info)));
67       
68#       if 0
69        try
70        {                                               
71        if (fs::exists(hal::app().get_working_directory()/L"Torrents.xml"))
72        {
73                assert(false);
74                {
75                fs::wifstream ifs(hal::app().get_working_directory()/L"Torrents.xml");
76       
77                event_log.post(shared_ptr<EventDetail>(new EventMsg(L"Loading old Torrents.xml")));
78       
79                TorrentMap torrents;
80                boost::archive::xml_wiarchive ia(ifs); 
81                ia >> boost::serialization::make_nvp("torrents", torrents);
82               
83                the_torrents_ = torrents;
84                }
85               
86                event_log.post(shared_ptr<EventDetail>(new EventMsg(
87                        hal::wform(L"Total %1%.") % the_torrents_.size())));                           
88               
89                fs::rename(hal::app().get_working_directory()/L"Torrents.xml", hal::app().get_working_directory()/L"Torrents.xml.safe.to.delete");
90
91        }                       
92        }
93        catch(const std::exception& e)
94        {
95                event_log.post(shared_ptr<EventDetail>(
96                        new EventStdException(event_logger::fatal, e, L"Loading Old Torrents.xml")));
97        }               
98#       endif
99
100        if (exists(hal::app().get_working_directory()/L"DHTState.bin"))
101        {
102                try
103                {
104                        dht_state_ = haldecode(hal::app().get_working_directory()/L"DHTState.bin");
105                }               
106                catch(const std::exception& e)
107                {
108                        event_log.post(shared_ptr<EventDetail>(
109                                new EventStdException(event_logger::critical, e, L"Loading DHTState.bin")));
110                }
111        }
112       
113        {       libt::session_settings settings = session_.settings();
114                settings.user_agent = string("Halite ") + HALITE_VERSION_STRING;
115                session_.set_settings(settings);
116        }
117       
118        start_alert_handler();
119
120        } HAL_GENERIC_FN_EXCEPTION_CATCH(L"bit_impl::bit_impl()")
121}
122
123bit_impl::~bit_impl()
124{       
125        try
126        {
127        HAL_DEV_MSG(L"Commence ~BitTorrent_impl"); 
128
129        stop_alert_handler();   
130        //save_torrent_data();
131       
132        HAL_DEV_MSG(L"Handler stopped!"); 
133        if (ip_filter_changed_)
134        {       
135                HAL_DEV_MSG(L"IP Filter needs saving."); 
136
137                fs::ofstream ofs(hal::app().get_working_directory()/L"IPFilter.bin", std::ios::binary);
138//              boost::archive::binary_oarchive oba(ofs);
139               
140                libt::ip_filter::filter_tuple_t vectors = ip_filter_.export_filter();   
141               
142                std::vector<libt::ip_range<boost::asio::ip::address_v4> > v4(vectors.get<0>());
143                std::vector<libt::ip_range<boost::asio::ip::address_v6> > v6(vectors.get<1>());
144               
145                v4.erase(std::remove(v4.begin(), v4.end(), 0), v4.end());
146                v6.erase(std::remove(v6.begin(), v6.end(), 0), v6.end());
147
148                write_vec_range(ofs, v4);
149//              write_vec_range(ofs, v6);
150        }       
151
152        } HAL_GENERIC_FN_EXCEPTION_CATCH(L"~BitTorrent_impl")
153}
154
155void bit_impl::ip_filter_count()
156{
157        libt::ip_filter::filter_tuple_t vectors = ip_filter_.export_filter();
158       
159        vectors.get<0>().erase(std::remove(vectors.get<0>().begin(), vectors.get<0>().end(), 0),
160                vectors.get<0>().end());
161        vectors.get<1>().erase(std::remove(vectors.get<1>().begin(), vectors.get<1>().end(), 0),
162                vectors.get<1>().end());
163        ip_filter_count_ = vectors.get<0>().size() + vectors.get<1>().size();
164}
165
166void bit_impl::ip_filter_load(progress_callback fn)
167{
168        fs::ifstream ifs(hal::app().get_working_directory()/L"IPFilter.bin", std::ios::binary);
169        if (ifs)
170        {
171                size_t v4_size;
172                ifs >> v4_size;
173               
174                size_t total = v4_size/100;
175                size_t previous = 0;
176               
177                for(unsigned i=0; i<v4_size; ++i)
178                {
179                        if (i-previous > total)
180                        {
181                                previous = i;
182
183                                if (fn) if (fn(i, v4_size, hal::app().res_wstr(HAL_TORRENT_LOAD_FILTERS))) break;
184                        }
185                       
186                        read_range_to_filter<boost::asio::ip::address_v4>(ifs, ip_filter_);
187                }
188        }       
189}
190
191void bit_impl::ip_filter_import(std::vector<libt::ip_range<boost::asio::ip::address_v4> >& v4,
192        std::vector<libt::ip_range<boost::asio::ip::address_v6> >& v6)
193{
194        for(std::vector<libt::ip_range<boost::asio::ip::address_v4> >::iterator i=v4.begin();
195                i != v4.end(); ++i)
196        {
197                ip_filter_.add_rule(i->first, i->last, libt::ip_filter::blocked);
198        }
199/*      for(std::vector<libt::ip_range<boost::asio::ip::address_v6> >::iterator i=v6.begin();
200                i != v6.end(); ++i)
201        {
202                ip_filter_.add_rule(i->first, i->last, libt::ip_filter::blocked);
203        }
204*/     
205        /* Note here we do not set ip_filter_changed_ */
206}
207
208bool bit_impl::ip_filter_import_dat(boost::filesystem::path file, progress_callback fn, bool octalFix)
209{
210        try
211        {
212
213        fs::ifstream ifs(file); 
214        if (ifs)
215        {
216                boost::uintmax_t total = fs::file_size(file);
217                boost::uintmax_t progress = 0;
218                boost::uintmax_t previous = 0;
219               
220                boost::regex reg("\\s*(\\d+\\.\\d+\\.\\d+\\.\\d+)\\s*-\\s*(\\d+\\.\\d+\\.\\d+\\.\\d+)\\s*.*");
221                boost::regex ip_reg("0*(\\d*)\\.0*(\\d*)\\.0*(\\d*)\\.0*(\\d*)");
222                boost::smatch m;
223               
224                string ip_address_line;         
225                while (!std::getline(ifs, ip_address_line).eof())
226                {               
227                        progress += (ip_address_line.length() + 2);
228                        if (progress-previous > total)
229                        {
230                                previous = progress;
231                                if (fn)
232                                {
233                                        if (fn(boost::numeric_cast<size_t>(progress), boost::numeric_cast<size_t>(total), 
234                                                        hal::app().res_wstr(HAL_TORRENT_IMPORT_FILTERS))) 
235                                                break;
236                                }
237                        }
238                       
239                        if (boost::regex_match(ip_address_line, m, reg))
240                        {
241                                string first = m[1];
242                                string last = m[2];
243                               
244                                if (octalFix)
245                                {
246                                        if (boost::regex_match(first, m, ip_reg))
247                                        {
248                                                first = ((m.length(1) != 0) ? m[1] : string("0")) + "." +
249                                                                ((m.length(2) != 0) ? m[2] : string("0")) + "." +
250                                                                ((m.length(3) != 0) ? m[3] : string("0")) + "." +
251                                                                ((m.length(4) != 0) ? m[4] : string("0"));
252                                        }                                       
253                                        if (boost::regex_match(last, m, ip_reg))
254                                        {
255                                                last = ((m.length(1) != 0) ? m[1] : string("0")) + "." +
256                                                           ((m.length(2) != 0) ? m[2] : string("0")) + "." +
257                                                           ((m.length(3) != 0) ? m[3] : string("0")) + "." +
258                                                           ((m.length(4) != 0) ? m[4] : string("0"));
259                                        }
260                                }
261                               
262                                try
263                                {                       
264                                        ip_filter_.add_rule(boost::asio::ip::address_v4::from_string(first),
265                                                boost::asio::ip::address_v4::from_string(last), libt::ip_filter::blocked);     
266                                }
267                                catch(...)
268                                {
269                                        hal::event_log.post(shared_ptr<hal::EventDetail>(
270                                                new hal::EventDebug(hal::event_logger::info, 
271                                                from_utf8((boost::format("Invalid IP range: %1%-%2%.") % first % last).str()))));
272                                }
273                        }
274                }
275        }
276       
277        ip_filter_changed_ = true;
278        ip_filter_count();
279       
280        }
281        catch(const std::exception& e)
282        {
283                event_log.post(shared_ptr<EventDetail>(
284                        new EventStdException(event_logger::critical, e, L"ip_filter_import_dat")));
285        }
286
287        return false;
288}
289
290bool bit_impl::create_torrent(const create_torrent_params& params, fs::wpath out_file, progress_callback fn)
291{               
292        try
293        {
294        libt::file_storage fs;
295        libt::file_pool f_pool;
296
297        HAL_DEV_MSG(L"Files");
298        for (file_size_pairs_t::const_iterator i = params.file_size_pairs.begin(), e = params.file_size_pairs.end();
299                        i != e; ++i)
300        {
301                HAL_DEV_MSG(hal::wform(L"file path: %1%, size: %2%") % (*i).first % (*i).second);
302                fs.add_file(to_utf8((*i).first.string()), (*i).second);
303        }
304
305        int piece_size = params.piece_size;
306        HAL_DEV_MSG(hal::wform(L"piece size: %1%") % piece_size);
307       
308        libt::create_torrent t(fs, piece_size);
309       
310/*      boost::scoped_ptr<libt::storage_interface> store(
311                libt::default_storage_constructor(t_info, to_utf8(params.root_path.string()),
312                        f_pool));
313*/
314        HAL_DEV_MSG(L"Trackers");
315        for (tracker_details_t::const_iterator i = params.trackers.begin(), e = params.trackers.end();
316                        i != e; ++i)
317        {
318                HAL_DEV_MSG(hal::wform(L"URL: %1%, Tier: %2%") % (*i).url % (*i).tier);
319                t.add_tracker(to_utf8((*i).url), (*i).tier);
320        }
321
322        HAL_DEV_MSG(L"Web Seeds");
323        for (web_seed_details_t::const_iterator i = params.web_seeds.begin(), e = params.web_seeds.end();
324                        i != e; ++i)
325        {
326                HAL_DEV_MSG(hal::wform(L"URL: %1%") % (*i).url);
327                t.add_url_seed(to_utf8((*i).url));
328        }
329
330        HAL_DEV_MSG(L"DHT Nodes");
331        for (dht_node_details_t::const_iterator i = params.dht_nodes.begin(), e = params.dht_nodes.end();
332                        i != e; ++i)
333        {
334                HAL_DEV_MSG(hal::wform(L"URL: %1%, port: %2%") % (*i).url % (*i).port);
335                t.add_node(hal::make_pair(to_utf8((*i).url), (*i).port));
336        }
337
338        HAL_DEV_MSG(hal::wform(L"root_path: %1%") % params.root_path.string());
339
340        set_piece_hashes(t, to_utf8(params.root_path.string()),
341                boost::bind(fn, _1, t.num_pieces(), hal::app().res_wstr(HAL_NEWT_HASHING_PIECES)));
342
343        t.set_creator(to_utf8(params.creator).c_str());
344        t.set_comment(to_utf8(params.comment).c_str());
345       
346        t.set_priv(params.private_torrent);
347
348        // create the torrent and print it to out
349        libt::entry e = t.generate();
350       
351        HAL_DEV_MSG(hal::wform(L"Writing to: %1%") % out_file);
352        fs::ofstream out(out_file, std::ios_base::binary);
353        libt::bencode(std::ostream_iterator<char>(out), t.generate());
354
355        } HAL_GENERIC_FN_EXCEPTION_CATCH(L"bit_impl::create_torrent()")
356       
357        HAL_DEV_MSG(L"Torrent creation completed!");
358
359        return false;
360}
361
362void bit_impl::start_alert_handler()
363{
364        mutex_t::scoped_lock l(mutex_);
365
366        if (alert_checker_ == boost::none)
367        {       
368                HAL_DEV_MSG(hal::wform(L"start_alert_handler"));
369
370                boost::function<void (void)> f = bind(&bit_impl::alert_handler, this);
371
372                keepChecking_ = true;
373                alert_checker_ = boost::in_place<boost::function<void (void)> >(bind(&bit_impl::alert_handler, this));
374        }
375}
376       
377void bit_impl::stop_alert_handler()
378{
379        mutex_t::scoped_lock l(mutex_);
380
381        keepChecking_ = false;
382
383        if (alert_checker_)
384        {
385                HAL_DEV_MSG(hal::wform(L"Interrupting alert handler"));
386
387                alert_checker_->interrupt();
388                alert_checker_->join();
389                alert_checker_ = boost::none;
390        }
391        else
392        {
393                HAL_DEV_MSG(hal::wform(L"Alert handler already stopped"));
394        }
395}
396       
397void bit_impl::alert_handler()
398{
399        win32_exception::install_handler();
400
401        try
402        {
403
404        while (keepChecking_)
405        {
406       
407        std::auto_ptr<libt::alert> p_alert = session_.pop_alert();
408       
409        class AlertHandler
410        {
411        public:
412        AlertHandler(bit_impl& bit_impl) :
413                bit_impl_(bit_impl)
414        {}
415
416        void operator()(libt::external_ip_alert const& a) const
417        {
418                event_log.post(shared_ptr<EventDetail>(
419                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
420                                hal::wform(hal::app().res_wstr(HAL_EXTERNAL_IP_ALERT))
421                                        % hal::from_utf8_safe(a.message())
422                                        % hal::from_utf8_safe(a.external_address.to_string()))
423                )       );                             
424        }
425
426        void operator()(libt::portmap_error_alert const& a) const
427        {
428                event_log.post(shared_ptr<EventDetail>(
429                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
430                                hal::wform(hal::app().res_wstr(HAL_PORTMAP_ERROR_ALERT))
431                                % (a.type == 0 ? 
432                                        hal::app().res_wstr(HAL_PORTMAP_TYPE_PMP) : 
433                                        hal::app().res_wstr(HAL_PORTMAP_TYPE_UPNP)))
434                )       );                             
435        }
436
437        void operator()(libt::portmap_alert const& a) const
438        {
439                event_log.post(shared_ptr<EventDetail>(
440                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
441                                hal::wform(hal::app().res_wstr(HAL_PORTMAP_ALERT))
442                                % (a.type == 0 ? 
443                                        hal::app().res_wstr(HAL_PORTMAP_TYPE_PMP) : 
444                                        hal::app().res_wstr(HAL_PORTMAP_TYPE_UPNP))
445                                % a.external_port)
446                )       );                             
447        }
448       
449        void operator()(libt::file_error_alert const& a) const
450        {
451                event_log.post(shared_ptr<EventDetail>(
452                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
453                                hal::wform(hal::app().res_wstr(HAL_FILE_ERROR_ALERT))
454                                % hal::from_utf8_safe(a.file)
455                                % hal::from_utf8_safe(a.msg))
456                )       );                             
457        }
458       
459        void operator()(libt::dht_reply_alert const& a) const
460        {
461                event_log.post(shared_ptr<EventDetail>(
462                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
463                                hal::wform(hal::app().res_wstr(HAL_DHT_REPLY_ALERT))
464                                        % a.num_peers
465                                        % get(a.handle)->name())
466                )       );                             
467        }
468
469        void operator()(libt::torrent_finished_alert const& a) const
470        {
471                event_log.post(shared_ptr<EventDetail>(
472                        new EventMsg((hal::wform(hal::app().res_wstr(LBT_EVENT_TORRENT_FINISHED)) 
473                                        % get(a.handle)->name()), 
474                                event_logger::info, a.timestamp())));
475               
476                get(a.handle)->finished();     
477        }
478       
479        void operator()(libt::torrent_paused_alert const& a) const
480        {
481                get(a.handle)->signals().torrent_paused();
482
483                wstring err = get(a.handle)->check_error();
484
485                if (err == L"")
486                {
487                        event_log.post(shared_ptr<EventDetail>(
488                                new EventMsg((hal::wform(hal::app().res_wstr(LBT_EVENT_TORRENT_PAUSED)) 
489                                                % get(a.handle)->name()), 
490                                        event_logger::debug, a.timestamp())));
491                       
492                        HAL_DEV_MSG(hal::wform(L"Torrent Paused alert, %1%.") % get(a.handle)->name());
493
494                        get(a.handle)->locked_process_event(ev_paused_alert());
495                }
496                else
497                {
498                        HAL_DEV_MSG(hal::wform(L"Torrent Error alert %2%, %1%.") % get(a.handle)->name() % err);
499
500                        event_log.post(shared_ptr<EventDetail>(
501                                new EventMsg((hal::wform(hal::app().res_wstr(HAL_TORRENT_ERROR_PAUSE_ALERT)) 
502                                                % err
503                                                % get(a.handle)->name()), 
504                                        event_logger::warning, a.timestamp())));
505
506                        get(a.handle)->locked_process_event(ev_error_alert(err));
507                }
508        }
509       
510        void operator()(libt::torrent_resumed_alert const& a) const
511        {
512                event_log.post(shared_ptr<EventDetail>(
513                        new EventMsg((hal::wform(hal::app().res_wstr(HAL_TORRENT_RESUME_ALERT)) 
514                                        % get(a.handle)->name()), 
515                                event_logger::debug, a.timestamp())));
516
517                get(a.handle)->locked_process_event(ev_resumed_alert());
518        }
519       
520        void operator()(libt::save_resume_data_alert const& a) const
521        {
522                event_log.post(shared_ptr<EventDetail>(
523                        new EventMsg((hal::wform(hal::app().res_wstr(HAL_WRITE_RESUME_ALERT)) 
524                                        % get(a.handle)->name()), 
525                                event_logger::info, a.timestamp())));
526
527                if (a.resume_data)
528                        get(a.handle)->write_resume_data(*a.resume_data);
529
530                get(a.handle)->signals().resume_data();
531                get(a.handle)->locked_process_event(ev_resume_data_alert());
532        }
533       
534        void operator()(libt::save_resume_data_failed_alert const& a) const
535        {
536                event_log.post(shared_ptr<EventDetail>(
537                        new EventMsg((hal::wform(hal::app().res_wstr(HAL_WRITE_RESUME_FAIL_ALERT)) 
538                                        % get(a.handle)->name()), 
539                                event_logger::warning, a.timestamp())));
540
541                get(a.handle)->locked_process_event(ev_resume_data_failed_alert());
542        }
543       
544        void operator()(libt::peer_error_alert const& a) const
545        {
546                event_log.post(shared_ptr<EventDetail>(
547                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
548                                hal::wform(hal::app().res_wstr(HAL_PEER_ALERT))
549                                        % hal::from_utf8_safe(a.message())
550                                        % hal::from_utf8_safe(a.ip.address().to_string()))
551                )       );                             
552        }
553               
554        void operator()(libt::peer_ban_alert const& a) const
555        {
556                event_log.post(shared_ptr<EventDetail>(
557                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
558                                hal::wform(hal::app().res_wstr(HAL_PEER_BAN_ALERT))
559                                        % get(a.handle)->name()
560                                        % hal::from_utf8_safe(a.ip.address().to_string()))
561                )       );                             
562        }
563               
564        void operator()(libt::hash_failed_alert const& a) const
565        {
566                event_log.post(shared_ptr<EventDetail>(
567                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
568                                hal::wform(hal::app().res_wstr(HAL_HASH_FAIL_ALERT))
569                                        % get(a.handle)->name()
570                                        % a.piece_index)
571                )       );                             
572        }
573               
574        void operator()(libt::url_seed_alert const& a) const
575        {
576                event_log.post(shared_ptr<EventDetail>(
577                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
578                                hal::wform(hal::app().res_wstr(HAL_URL_SEED_ALERT))
579                                        % get(a.handle)->name()
580                                        % hal::from_utf8_safe(a.url)
581                                        % hal::from_utf8_safe(a.message()))
582                )       );                             
583        }
584       
585        void operator()(libt::tracker_warning_alert const& a) const
586        {
587                event_log.post(shared_ptr<EventDetail>(
588                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
589                                hal::wform(hal::app().res_wstr(HAL_TRACKER_WARNING_ALERT))
590                                        % get(a.handle)->name()
591                                        % hal::from_utf8_safe(a.message()))
592                )       );                             
593        }
594       
595        void operator()(libt::tracker_announce_alert const& a) const
596        {
597                event_log.post(shared_ptr<EventDetail>(
598                        new EventMsg((hal::wform(hal::app().res_wstr(HAL_TRACKER_ANNOUNCE_ALERT)) 
599                                        % get(a.handle)->name()), 
600                                event_logger::info, a.timestamp())));
601        }
602       
603        void operator()(libt::tracker_error_alert const& a) const
604        {
605                event_log.post(shared_ptr<EventDetail>(
606                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
607                                hal::wform(hal::app().res_wstr(HAL_TRACKER_ALERT))
608                                        % get(a.handle)->name()
609                                        % hal::from_utf8_safe(a.message())
610                                        % a.times_in_row
611                                        % a.status_code)
612                )       );                             
613        }
614       
615        void operator()(libt::tracker_reply_alert const& a) const
616        {
617                event_log.post(shared_ptr<EventDetail>(
618                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
619                                hal::wform(hal::app().res_wstr(HAL_TRACKER_REPLY_ALERT))
620                                        % get(a.handle)->name()
621                                        % hal::from_utf8_safe(a.message())
622                                        % a.num_peers)
623                )       );                             
624        }
625       
626        void operator()(libt::fastresume_rejected_alert const& a) const
627        {
628                event_log.post(shared_ptr<EventDetail>(
629                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
630                                hal::wform(hal::app().res_wstr(HAL_FAST_RESUME_ALERT))
631                                        % get(a.handle)->name()
632                                        % hal::from_utf8_safe(a.message()))
633                )       );                             
634        }
635       
636        void operator()(libt::piece_finished_alert const& a) const
637        {
638                event_log.post(shared_ptr<EventDetail>(
639                        new EventGeneral(event_logger::debug, a.timestamp(),
640                                hal::wform(hal::app().res_wstr(HAL_PIECE_FINISHED_ALERT))
641                                        % get(a.handle)->name()
642                                        % a.piece_index)
643                )       );                             
644        }
645       
646        void operator()(libt::block_finished_alert const& a) const
647        {
648                event_log.post(shared_ptr<EventDetail>(
649                        new EventGeneral(event_logger::debug, a.timestamp(),
650                                hal::wform(hal::app().res_wstr(HAL_BLOCK_FINISHED_ALERT))
651                                        % get(a.handle)->name()
652                                        % a.block_index
653                                        % a.piece_index)
654                )       );                             
655        }
656       
657        void operator()(libt::block_downloading_alert const& a) const
658        {
659                event_log.post(shared_ptr<EventDetail>(
660                        new EventGeneral(event_logger::debug, a.timestamp(),
661                                hal::wform(hal::app().res_wstr(HAL_BLOCK_DOWNLOADING_ALERT))
662                                        % get(a.handle)->name()
663                                        % a.block_index
664                                        % a.piece_index)
665                )       );                             
666        }
667       
668        void operator()(libt::listen_failed_alert const& a) const
669        {
670                if (a.endpoint.address().is_v6())
671                {       
672                        event_log.post(shared_ptr<EventDetail>(
673                                new EventGeneral(event_logger::info, a.timestamp(),
674                                        hal::app().res_wstr(HAL_LISTEN_V6_FAILED_ALERT))
675                        )       );             
676                }
677                else
678                {
679                        event_log.post(shared_ptr<EventDetail>(
680                                new EventGeneral(event_logger::info, a.timestamp(),
681                                        hal::wform(hal::app().res_wstr(HAL_LISTEN_FAILED_ALERT))
682                                                % hal::from_utf8_safe(a.message()))
683                        )       );
684                }
685        }
686       
687        void operator()(libt::listen_succeeded_alert const& a) const
688        {
689                event_log.post(shared_ptr<EventDetail>(
690                        new EventGeneral(event_logger::info, a.timestamp(),
691                                hal::wform(hal::app().res_wstr(HAL_LISTEN_SUCCEEDED_ALERT))
692                                        % hal::from_utf8_safe(a.message()))
693                )       );     
694
695                //bit_impl_.signals.successful_listen();
696        }
697       
698        void operator()(libt::peer_blocked_alert const& a) const
699        {
700                event_log.post(shared_ptr<EventDetail>(
701                        new EventGeneral(event_logger::debug, a.timestamp(),
702                                hal::wform(hal::app().res_wstr(HAL_IPFILTER_ALERT))
703                                        % hal::from_utf8_safe(a.ip.to_string())
704                                        % hal::from_utf8_safe(a.message()))
705                )       );                             
706        }
707       
708/*      void operator()(libt::alert const& a) const
709        {
710                event_log.post(shared_ptr<EventDetail>(
711                                new EventLibtorrent(lbtAlertToHalEvent(a.severity()),
712                                        a.timestamp(), event_logger::unclassified, hal::from_utf8_safe(a.message()))));         
713        }*/
714       
715        private:
716                bit_impl& bit_impl_;
717               
718                torrent_internal_ptr get(libt::torrent_handle h) const 
719                { 
720                        torrent_internal_ptr p = bit_impl_.the_torrents_.get(from_utf8_safe(h.get_torrent_info().name())); 
721
722                        if (p)
723                                return p;
724                        else
725                                throw bit::null_torrent();
726                }
727       
728        } handler(*this);
729       
730        while (p_alert.get())
731        {       
732                try
733                {
734                mutex_t::scoped_lock l(mutex_);
735               
736                libt::handle_alert<
737                        libt::save_resume_data_alert,
738                        libt::save_resume_data_failed_alert,
739                        libt::external_ip_alert,
740                        libt::portmap_error_alert,
741                        libt::portmap_alert,
742                        libt::file_error_alert,
743                        libt::torrent_finished_alert,
744                        libt::torrent_paused_alert,
745                        libt::torrent_resumed_alert,
746                        libt::peer_error_alert,
747                        libt::peer_ban_alert,
748                        libt::hash_failed_alert,
749                        libt::url_seed_alert,
750                        libt::dht_reply_alert,
751                        libt::tracker_error_alert,
752                        libt::tracker_warning_alert,
753                        libt::tracker_announce_alert,
754                        libt::tracker_reply_alert,
755                        libt::fastresume_rejected_alert,
756                        libt::piece_finished_alert,
757                        libt::block_finished_alert,
758                        libt::block_downloading_alert,
759                        libt::listen_failed_alert,
760                        libt::listen_succeeded_alert,
761                        libt::peer_blocked_alert
762                >::handle_alert(p_alert, handler);                     
763               
764                }
765                catch(const libt::unhandled_alert&)
766                {
767//                      handler(*p_alert);
768                }
769                catch(const bit::null_torrent&)
770                {
771                        // These are logged as debug because they are rarely important to act on!
772                        event_log.post(shared_ptr<EventDetail>(\
773                                new EventMsg(L"null_torrent exception", event_logger::info)));
774                }
775                catch(const std::exception& e)
776                {
777                        // These are logged as debug because they are rarely important to act on!
778                        event_log.post(shared_ptr<EventDetail>(\
779                                new EventStdException(event_logger::debug, e, L"bit_impl::alert_handler()")));
780                }
781               
782                p_alert = session_.pop_alert();
783
784                boost::this_thread::interruption_point();
785        }       
786               
787        boost::this_thread::sleep(pt::milliseconds(100));
788       
789        }
790       
791        boost::this_thread::interruption_point();
792
793        } 
794        catch(boost::thread_interrupted&)
795        {
796                // Not an error!
797
798                event_log.post(shared_ptr<EventDetail>(
799                        new EventMsg(L"thread_interrupted exception", event_logger::info)));
800
801                return;
802        }
803        HAL_GENERIC_FN_EXCEPTION_CATCH(L"bit_impl::alert_handler()")
804}
805
806}
Note: See TracBrowser for help on using the repository browser.