source: trunk/src/halSession.cpp @ 764

Revision 764, 26.2 KB checked in by Eoin, 10 years ago (diff)

Fixed the starting (or not) of added torrents.

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