instrumentation: add hrktorrent
authorP2P-Next <p2p-next@cs.pub.ro>
Fri, 6 Aug 2010 14:12:36 +0000 (17:12 +0300)
committerP2P-Next <p2p-next@cs.pub.ro>
Fri, 6 Aug 2010 14:12:36 +0000 (17:12 +0300)
19 files changed:
instrumentation/hrktorrent/CHANGELOG [new file with mode: 0644]
instrumentation/hrktorrent/CONTRIBUTORS [new file with mode: 0644]
instrumentation/hrktorrent/LICENSE [new file with mode: 0644]
instrumentation/hrktorrent/Makefile [new file with mode: 0644]
instrumentation/hrktorrent/README [new file with mode: 0644]
instrumentation/hrktorrent/core.cpp [new file with mode: 0644]
instrumentation/hrktorrent/core.h [new file with mode: 0644]
instrumentation/hrktorrent/hrktorrent.1 [new file with mode: 0644]
instrumentation/hrktorrent/hrktorrent.h [new file with mode: 0644]
instrumentation/hrktorrent/hrktorrent.rc.example [new file with mode: 0644]
instrumentation/hrktorrent/ipfilter.cpp [new file with mode: 0644]
instrumentation/hrktorrent/ipfilter.h [new file with mode: 0644]
instrumentation/hrktorrent/main.cpp [new file with mode: 0644]
instrumentation/hrktorrent/settings.cpp [new file with mode: 0644]
instrumentation/hrktorrent/settings.h [new file with mode: 0644]
instrumentation/hrktorrent/utils.cpp [new file with mode: 0644]
instrumentation/hrktorrent/utils.h [new file with mode: 0644]
instrumentation/hrktorrent/vars.mk [new file with mode: 0644]
instrumentation/hrktorrent/version.h [new file with mode: 0644]

diff --git a/instrumentation/hrktorrent/CHANGELOG b/instrumentation/hrktorrent/CHANGELOG
new file mode 100644 (file)
index 0000000..0de8625
--- /dev/null
@@ -0,0 +1,101 @@
+hrktorrent changelog:
+
+-----------------------
+0.3.5 [2009-Aug-14]
+-----------------------
+- Updated author name and email address
+- Actually terminate hrktorrent on CTRL+C
+- Better rule parsing, bugfix and speedup
+- Improved exception handling
+- Use libtorrent-rasterbar pkg-config package
+- Get rid of deprecated function references, comply to latest libtorrent
+  standards
+
+
+-----------------------
+0.3.4 [2008-Oct-21]
+-----------------------
+- Adopt code to style guidelines (James Munro)
+- Print the count of imported ipfilter.dat entries
+- Continue processing after error (Razvan Deaconescu)
+- Use std::cout for debug messages in constructor (Razvan Deaconescu)
+- Use ctrl+c for termination and fix another bug (Razvan Deaconescu)
+- Make 'make' output prettier
+
+-----------------------
+0.3.3 [2008-Aug-26]
+-----------------------
+- The CSettings class now supports integers and strings as setting types
+- Added the option "downloaddir" to set the target directory
+- Added Razvan Deaconescu's patch to ignore colum checking when hrktorrent is not being
+  run in a tty. Thanks!
+- Improved cleaning up the program
+- Fixed the Makefile
+- More verbosity
+- Support libtorrent's UPnP implementation
+
+-----------------------
+0.3.2 [2008-Jun-28]
+-----------------------
+- Fixed the multiple instances with DHT bug
+- DHT now uses public routers to bootstrap (bittorrent.com, bitcomet.com, utorrent.com)
+- Fixed "'add_torrent' is deprecated" warning when compiling
+- Fixed the line-feed problem in consoles
+
+-----------------------
+0.3.1 [2008-Mar-14]
+-----------------------
+- Configuration is now loaded from ~/.hrktorrent/hrktorrent.rc, as well as the ipfilter
+- DHT nodes are now being loaded and saved to the hrktorrent dir
+- Fixed a bug where you could run hrktorrent only once with DHT enabled
+- IPFilter has been improved
+
+-----------------------
+0.3.0 [2007-Dec-24]
+-----------------------
+- Added an IPFilter (loading from ~/.ipfilter.dat) [lots of code by xen, thanks!]
+- Major code cleanups
+
+-----------------------
+0.2.3 [2007-Dec-02]
+-----------------------
+- Added forcereannounce option for speed increasement
+- hrktorrent now sends it's own id (HT)
+- Made the Makefile distribution friendlier (thanks to drac's patch)
+- The amount of uploaded data is now being displayed
+
+-----------------------
+0.2.2 [2007-Nov-25 ]
+-----------------------
+- Added ETA
+- Output will now be truncated with dots, if it is longer than the terminal width
+- tuqs was so kind to write a manpage
+- Changed the Makefile so it doesn't strip the binary anymore
+
+-----------------------
+0.2.1 [2007-Nov-22 ]
+-----------------------
+- Fixed a crash bug [thanks to nico]
+
+-----------------------
+0.2 [ 2007-Nov-22 ]
+-----------------------
+- README written
+- LICENSE added (please please please correct mistakes, I'm not good at this!)
+- Complete rewrite
+- Major code cleanup
+- Config file support (~/.hrktorrent.rc)
+- Rewritten console output
+- DHT enabled
+- 'seed' option
+- 'verbose' option
+- Minor bugfixes
+- Improved commandline switches
+
+-----------------------
+0.1 [ 2007-Nov-18 ]
+-----------------------
+- Initial release
+- Basic torrent downloading with status output
+- Option to define the port range
+- Option to define the maximum upload speed
diff --git a/instrumentation/hrktorrent/CONTRIBUTORS b/instrumentation/hrktorrent/CONTRIBUTORS
new file mode 100644 (file)
index 0000000..7164af5
--- /dev/null
@@ -0,0 +1,4 @@
+James Munro
+Nico R. Wohlgemuth
+Razvan Deaconescu
+Sebastian Mair
diff --git a/instrumentation/hrktorrent/LICENSE b/instrumentation/hrktorrent/LICENSE
new file mode 100644 (file)
index 0000000..9516e3b
--- /dev/null
@@ -0,0 +1,24 @@
+* Copyright (c) <2007>, <Henrik Friedrichsen>
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*     * Redistributions of source code must retain the above copyright
+*       notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above copyright
+*       notice, this list of conditions and the following disclaimer in the
+*       documentation and/or other materials provided with the distribution.
+*     * Neither the names of the company nor the
+*       names of its contributors may be used to endorse or promote products
+*       derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY <Henrik Friedrichsen> ``AS IS'' AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL <Henrik Friedrichsen> BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/instrumentation/hrktorrent/Makefile b/instrumentation/hrktorrent/Makefile
new file mode 100644 (file)
index 0000000..a5f04db
--- /dev/null
@@ -0,0 +1,30 @@
+include vars.mk
+
+all: $(OUT) $(OUT)-static
+
+.cpp.o:
+       @echo [CXX] $<
+       @$(CXX) $(CXXFLAGS) -c -o $@ $<
+
+$(OUT): $(OBJ)
+       @echo [LD] $@
+       $(CXX) $(LDFLAGS) $(OBJ) $(LIBS) -o $(OUT)
+
+$(OUT)-static: $(OBJ)
+       @echo [LD] $@
+       $(CXX) $(OBJ) ../libtorrent-rasterbar/lib/libtorrent-rasterbar.a $(EXTRA_LIBS) -o $@
+
+clean:
+       -rm -rf $(OBJ) $(OUT) $(OUT)-static *~
+
+install: all
+       @install hrktorrent ${PREFIX}/bin
+       @mkdir -p ${PREFIX}/share/examples/hrktorrent
+       @install -m 644 hrktorrent.rc.example ${PREFIX}/share/examples/hrktorrent/hrktorrent.rc
+       @mkdir -p ${MANPREFIX}/man1
+       @install -m 644 hrktorrent.1 ${MANPREFIX}/man1/hrktorrent.1
+
+uninstall:
+       -@rm -f ${PREFIX}/bin/hrktorrent
+       -@rm -f ${MANPREFIX}/man1/hrktorrent.1
+       -@rm -r ${PREFIX}/share/examples/hrktorrent/
diff --git a/instrumentation/hrktorrent/README b/instrumentation/hrktorrent/README
new file mode 100644 (file)
index 0000000..2a04adf
--- /dev/null
@@ -0,0 +1,20 @@
+<-
+       hrktorrent 0.3.5
+       http://50hz.ws/hrktorrent/
+       LICENSE: BSD
+       Report bugs to: irc://irc.rizon.net #/dev/null (hrkfdn)
+       
+       Thanks to rasterbar's libtorrent!
+->
+
+To compile hrktorrent you need:
+a) boost
+b) asio header files
+c) libtorrent (the one by rasterbar: http://www.rasterbar.com/products/libtorrent/index.html)
+
+To use a config file, put it in your $HOME/.hrktorrent dir and name it "hrktorrent.rc", there is an example included.
+NOTE: Commandline switches override configuration file settings.
+
+For IP-Filtering, make sure it is enabled and copy the ipfilter.dat file to ~/.hrktorrent/ipfilter.dat
+
+Help is available by just running hrktorrent.
diff --git a/instrumentation/hrktorrent/core.cpp b/instrumentation/hrktorrent/core.cpp
new file mode 100644 (file)
index 0000000..c21bb64
--- /dev/null
@@ -0,0 +1,321 @@
+#include "hrktorrent.h"\r
+\r
+CCore* Core = 0;\r
+pthread_t statusthread;\r
+\r
+/* constructor. init torrent session! */\r
+CCore::CCore(int argc, char** argv)\r
+{\r
+       _argc = argc;\r
+       _argv = argv;\r
+       _running = true;\r
+\r
+       Settings = new CSettings();\r
+       std::cout << "Initializing " << APPNAME << " " << VERSION << std::endl;\r
+\r
+       Settings->LoadConfig();\r
+}\r
+\r
+/* destructor. free/delete garbage! */\r
+CCore::~CCore()\r
+{\r
+       VerbosePrint("Core", "Destructing core class.");\r
+       delete _session;\r
+}\r
+\r
+unsigned int\r
+GetETA(libtorrent::size_type done, libtorrent::size_type wanted, libtorrent::size_type downspeed)\r
+{\r
+       libtorrent::size_type delta = wanted - done;\r
+       if(downspeed > 0)\r
+               return (delta / downspeed);\r
+       else\r
+               return 0;\r
+}\r
+       \r
+\r
+void*\r
+CCore::StatusLoop(void* data)\r
+{\r
+       int curx, cury;\r
+       std::string s_output;\r
+       std::stringstream output;\r
+       \r
+       struct winsize ws;\r
+\r
+       libtorrent::session* s = Core->GetSession();\r
+       libtorrent::torrent_handle* t = Core->GetTorrent();\r
+\r
+       libtorrent::session_status sstatus;\r
+       libtorrent::torrent_status tstatus;\r
+       bool finished = false;\r
+       int eta = 0, columns = 0, loopcount = 0;\r
+       bool stdout_is_tty = false;\r
+\r
+       stdout_is_tty = (isatty(STDOUT_FILENO) == 1);\r
+       if (stdout_is_tty) {\r
+               if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0) {\r
+                       char errbuf[128];\r
+\r
+                       strerror_r(errno, errbuf, 128);\r
+                       std::cerr << "ioctl error: " << errbuf << std::endl;\r
+\r
+                       exit(EXIT_FAILURE);\r
+               }\r
+               columns = ws.ws_col;\r
+       }\r
+\r
+\r
+       while(Core->isRunning()) {\r
+               if(Settings->GetI("forcereannounce") > 0 && loopcount >= Settings->GetI("forcereannounce")*60) {\r
+                       loopcount = 0;\r
+                       t->force_reannounce();\r
+                       Core->VerbosePrint("Core", "Reannouncing!\n");\r
+               }\r
+\r
+               sstatus = s->status();\r
+               tstatus = t->status();\r
+               eta = GetETA(tstatus.total_done, tstatus.total_wanted, (libtorrent::size_type)sstatus.download_rate);\r
+\r
+               if(!finished && tstatus.total_wanted != 0 && tstatus.total_done == tstatus.total_wanted) {\r
+                       std::cout << "\nTorrent finished!" << std::endl;\r
+                       if(Settings->GetI("seed") == 0) {\r
+                               statusthread = 0;\r
+                               exit(EXIT_SUCCESS);\r
+                       }\r
+                       finished = true;\r
+               }\r
+\r
+               output << "ps: " << sstatus.num_peers;\r
+               if(Settings->GetI("dht") > 0) \r
+                       output << ", dht: " << sstatus.dht_nodes;\r
+               output << " <> ";\r
+               output << "dl: " << Round(sstatus.download_rate/1024, 2) << "kb/s, ";\r
+               output << "ul: " << Round(sstatus.upload_rate/1024, 2) << "kb/s <> ";\r
+               output << "dld: " << tstatus.total_done/1048576 << "mb, ";\r
+               output << "uld: " << sstatus.total_payload_upload/1048576 << "mb, ";\r
+               output << "size: " << tstatus.total_wanted/1048576 << "mb <> ";\r
+               output << "eta: ";\r
+               if(eta > 216000) {\r
+                       output << eta/216000 << "d ";\r
+                       eta -= (eta/216000)*216000;\r
+               }\r
+               if(eta > 3600) {\r
+                       output << eta/3600 << "h ";\r
+                       eta -= (eta/3600)*3600;\r
+               }\r
+               if(eta > 60) {\r
+                       output << eta/60 << "m ";\r
+                       eta -= (eta/60)*60;\r
+               }\r
+               output << eta << "s";\r
+               s_output = output.str();\r
+\r
+               if (stdout_is_tty) {\r
+                       if(s_output.length() > columns) {\r
+                               s_output.resize(columns - 3);\r
+                               s_output.append("..");\r
+                       }\r
+                       else if(s_output.length() < columns) {\r
+                               for(int i = 0; i < s_output.length() - columns; i++)\r
+                                       s_output.append(" ");\r
+                       }\r
+               }\r
+               if (stdout_is_tty) {\r
+                       std::cout << s_output.c_str() << "\r";\r
+               }\r
+               else {\r
+                       std::cout << s_output.c_str() << std::endl;\r
+               }\r
+\r
+       \r
+               std::cout.flush();\r
+               output.str("");\r
+\r
+               sleep(1);\r
+               loopcount++;\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
+void\r
+CCore::LoadDHT()\r
+{\r
+       std::string path = *Settings->getDir();\r
+       path.append("dhtnodes");\r
+       \r
+       std::ifstream nodefile(path.c_str(), std::ios_base::binary);\r
+       if(!nodefile.is_open()) {\r
+               mkdir(Settings->getDir()->c_str(), 0755);\r
+               VerbosePrint("DHT", "Could not load the nodefile.");\r
+               _session->start_dht();\r
+               return;\r
+       }\r
+\r
+       nodefile.unsetf(std::ios_base::skipws);\r
+\r
+       try {\r
+               libtorrent::entry state = libtorrent::bdecode(std::istream_iterator<char>(nodefile),\r
+                                                                                                         std::istream_iterator<char>());\r
+               _session->start_dht(state);\r
+               VerbosePrint("DHT", "DHT started with a nodefile.");\r
+       }\r
+       catch(std::exception& e) {\r
+               std::cout << e.what() << std::endl;\r
+               _session->start_dht();\r
+       }\r
+       nodefile.close();\r
+}\r
+\r
+void\r
+CCore::SaveDHT()\r
+{\r
+       std::string path = *Settings->getDir();\r
+       path.append("dhtnodes");\r
+\r
+       std::ofstream nodefile(path.c_str(), std::ios_base::binary);\r
+       if(!nodefile.is_open()) {\r
+               VerbosePrint("DHT", "Could not save the nodefile.");\r
+               return;\r
+       }\r
+\r
+       nodefile.unsetf(std::ios_base::skipws);\r
+\r
+       libtorrent::entry state = _session->dht_state();\r
+       libtorrent::bencode(std::ostream_iterator<char>(nodefile), state);\r
+       VerbosePrint("DHT", "Saved nodes.");\r
+       nodefile.close();\r
+}\r
+\r
+static void\r
+SignalHandler(int signo)\r
+{\r
+       Core->VerbosePrint("Core", "Received signal.");\r
+       Core->Shutdown();\r
+}\r
+\r
+void\r
+CCore::ScheduleSignal(int signo)\r
+{\r
+       struct sigaction sa;\r
+\r
+       memset(&sa, 0, sizeof(sa));\r
+       sa.sa_handler = SignalHandler;\r
+       sa.sa_flags = SA_RESETHAND;\r
+\r
+       if (sigaction(signo, &sa, NULL) < 0) {\r
+               char errbuf[128];\r
+\r
+               strerror_r(errno, errbuf, 128);\r
+\r
+               std::cerr << "sigaction error: " << errbuf << std::endl;\r
+               exit(EXIT_FAILURE);\r
+       }\r
+}\r
+\r
+void\r
+CCore::Shutdown()\r
+{\r
+       _running = false;\r
+       if(Settings->GetI("dht") > 0) {\r
+               SaveDHT();\r
+               _session->stop_dht();\r
+       }\r
+\r
+       if(statusthread) pthread_cancel(statusthread);\r
+       std::cout << "\nShutting down hrktorrent. Please wait." << std::endl;\r
+\r
+       exit(EXIT_SUCCESS);\r
+}\r
+\r
+int\r
+CCore::Run()\r
+{\r
+       _verbose = (Settings->GetI("verbose") > 0);\r
+       VerbosePrint("Core", "Verbose enabled.");\r
+       VerbosePrint("Core", "Starting torrent session!");\r
+\r
+       IPFilter = new CIPFilter();\r
+\r
+       _session = new libtorrent::session(libtorrent::fingerprint("HT", MAJOR, MINOR, REVISION, TAG));\r
+\r
+       if(Settings->GetI("upnp") > 0)\r
+               _session->start_upnp();\r
+\r
+       _session->listen_on(std::make_pair(Settings->GetI("minport"), Settings->GetI("maxport")));\r
+       if(Settings->GetI("maxup") > 0) {\r
+               _session->set_upload_rate_limit(Settings->GetI("maxup")*1024);\r
+               _session->set_local_upload_rate_limit(Settings->GetI("maxup")*1024);\r
+       }\r
+       if(Settings->GetI("maxdown") > 0){\r
+               _session->set_download_rate_limit(Settings->GetI("maxdown")*1024);\r
+               _session->set_local_download_rate_limit(Settings->GetI("maxdown")*1024);\r
+       }\r
+       try {\r
+               libtorrent::add_torrent_params parms;\r
+\r
+               boost::intrusive_ptr<libtorrent::torrent_info> info = new libtorrent::torrent_info(_argv[_argc-1]);\r
+               boost::filesystem::path p(Settings->GetS("downloaddir"));\r
+               boost::filesystem::create_directory(p);\r
+               if(!boost::filesystem::exists(p)) {\r
+                       std::cerr << "Download directory does not exist/could not be created." << std::endl;\r
+                       return EXIT_FAILURE;\r
+               }\r
+\r
+               parms.save_path = p;\r
+               parms.ti = info;\r
+               parms.paused = false;\r
+\r
+               _torrent = _session->add_torrent(parms);\r
+       } catch(std::exception& e) {\r
+               std::cerr << "Could not add torrent (" << e.what() <<")" << std::endl;\r
+               return EXIT_FAILURE;\r
+       }\r
+       \r
+       if(Settings->GetI("dht") > 0) {\r
+               VerbosePrint("Core", "Starting DHT.");\r
+               libtorrent::dht_settings dset;\r
+               dset.service_port = _session->listen_port();\r
+               _session->set_dht_settings(dset);\r
+               LoadDHT();\r
+\r
+               // known dht routers for bootstrapping\r
+               _session->add_dht_router(std::make_pair(std::string("router.bittorrent.com"), 6881));\r
+               _session->add_dht_router(std::make_pair(std::string("router.utorrent.com"), 6881));\r
+               _session->add_dht_router(std::make_pair(std::string("router.bitcomet.com"), 6881));\r
+       }\r
+\r
+       if(Settings->GetI("ipfilter") > 0 && IPFilter->IsActive()) {\r
+               _session->set_ip_filter(IPFilter->getFilter());\r
+       }\r
+\r
+       ScheduleSignal(SIGINT);\r
+       std::cout << "\"CTRL-C\" shuts hrktorrent down.\n" <<  std::endl;\r
+\r
+       pthread_create(&statusthread, NULL, StatusLoop, NULL);\r
+\r
+       /*\r
+        * reading stdin does not work with output redirection or running the\r
+        * program in background\r
+        */\r
+       /*\r
+       char input;\r
+       std::cin.unsetf(std::ios_base::skipws);\r
+       std::cin >> input;\r
+       */\r
+\r
+       /* wait for signal */\r
+       pause();\r
+\r
+       Shutdown();\r
+}\r
+\r
+void\r
+CCore::VerbosePrint(std::string source, std::string message)\r
+{\r
+       if(!_verbose) return;\r
+       std::cout << "[" << source << "] ";\r
+       std::cout << message << std::endl;\r
+}\r
+\r
diff --git a/instrumentation/hrktorrent/core.h b/instrumentation/hrktorrent/core.h
new file mode 100644 (file)
index 0000000..04adbd3
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef _CORE_H
+#define _CORE_H
+
+class CCore
+{
+       public:
+               CCore(int argc, char** argv);
+               ~CCore();
+
+               int Run();
+               void Shutdown();
+               void VerbosePrint(std::string source, std::string message);
+               static void* StatusLoop(void* data);
+
+               inline libtorrent::session* GetSession() { return _session; }
+               inline libtorrent::torrent_handle* GetTorrent() { return &_torrent; }
+               inline bool isRunning() { return _running == true; }
+       private:
+               bool _running;
+               libtorrent::session* _session;
+               libtorrent::torrent_handle _torrent; // TODO: multiple torrents?
+
+               void LoadDHT();
+               void SaveDHT();
+               void ScheduleSignal(int signo);
+
+               int _argc;
+               char** _argv;
+
+               bool _verbose;
+};
+extern CCore* Core;
+
+#endif
diff --git a/instrumentation/hrktorrent/hrktorrent.1 b/instrumentation/hrktorrent/hrktorrent.1
new file mode 100644 (file)
index 0000000..26117c2
--- /dev/null
@@ -0,0 +1,68 @@
+.\" hrktorrent.1
+.TH hrktorrent 0.3.4
+.SH NAME
+hrktorrent - a slim console torrent application supporting DHT
+.SH SYNOPSIS
+hrktorrent [--options] \fIfile.torrent\fR
+.SH DESCRIPTION
+hrktorrent is a slim rb_torrent based console torrent application supporting DHT.
+.SH OPTIONS
+.fi
+\fB--minport\fR - start port range (default: 6881)
+
+\fB--maxport\fR - end port range (default: 6999)
+
+\fB--maxdown\fR - download speed limit (in kb/s) (default: unlimited)
+
+\fB--maxup\fR - upload speed limit (in kb/s) (default: unlimited)
+
+\fB--nodht\fR - disable dht (default: on)
+
+\fB--noupnp\fR - disable upnp (default: on)
+
+\fB--noseed\fR - disable seeding (default: on)
+
+\fB--forcereannounce\fR - reannounce every X minutes (default: 2)
+
+\fB--ipfilter\fR - enable ip filtering (default: off)
+
+\fB--downloaddir\fR - set the directory you want the downloads saved to (default: .)
+
+\fB--verbose\fR - print verbose messages (default: off)
+.nf
+.SH CONFIGURATION FILE
+Any configuration files or files that hrktorrent creates are stored in ~/.hrktorrent
+
+.fi
+\fB~/.hrktorrent/hrktorrent.rc\fR
+
+minport        \fIint\fR  # minimum port
+
+maxport        \fIint\fR  # maximum port
+
+verbose        \fIbool\fR # verbose mode
+
+maxup  \fIint\fR  # max. upload speed
+
+maxdown        \fIint\fR  # max. download speed
+
+dht            \fIbool\fR # dht
+
+upnp           \fIbool\fR # upnp port lookup
+
+seed           \fIbool\fR # seed after finishing downloading
+
+forcereannounce        \fIint\fR  # update peers every X minutes (be careful with this value!)
+
+ipfilter       \fIbool\fR # enable ip filtering
+
+downloaddir    \fIstring\fR # the directory you want the downloads saved to. default is pwd
+
+\fBbools have to be set to anything higher than 0 to indicate them as true!\fR
+.nf
+.SH IPFILTER
+To use the IPFilter of libtorrent, you need to provide an ipfilter.dat file and copy it to ~/.hrktorrent/
+.SH EXAMPLE
+hrktorrent --minport6500 --maxport6600 --nodht file.torrent
+.SH AUTHOR
+Henrik Friedrichsen <hrkfrd@gmail.com>
diff --git a/instrumentation/hrktorrent/hrktorrent.h b/instrumentation/hrktorrent/hrktorrent.h
new file mode 100644 (file)
index 0000000..7544da9
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef _HRKTORRENT_H
+#define _HRKTORRENT_H
+
+#include <iostream>
+#include <fstream>
+#include <iterator>
+#include <exception>
+
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <boost/format.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/tuple/tuple.hpp>
+
+#include <libtorrent/entry.hpp>
+#include <libtorrent/bencode.hpp>
+#include <libtorrent/session.hpp>
+#include <libtorrent/session_settings.hpp>
+#include <libtorrent/ip_filter.hpp>
+
+#include "version.h"
+#include "core.h"
+#include "settings.h"
+#include "utils.h"
+#include "ipfilter.h"
+
+#endif
diff --git a/instrumentation/hrktorrent/hrktorrent.rc.example b/instrumentation/hrktorrent/hrktorrent.rc.example
new file mode 100644 (file)
index 0000000..8d097c1
--- /dev/null
@@ -0,0 +1,15 @@
+# please use only the following scheme
+minport                60100           # minimum port
+maxport                60200           # maximum port
+
+verbose                0               # verbose mode
+
+maxup          10              # max. upload speed
+maxdown                0               # max. download speed
+
+dht            1               # dht
+upnp           1               # upnp port lookup
+seed           1               # seed after finishing downloading
+forcereannounce        2               # update peers every X minutes (be careful with this value!)
+ipfilter       1               # enable ip filtering
+downloaddir    ~/incoming      # set default download dir
diff --git a/instrumentation/hrktorrent/ipfilter.cpp b/instrumentation/hrktorrent/ipfilter.cpp
new file mode 100644 (file)
index 0000000..d320cf9
--- /dev/null
@@ -0,0 +1,86 @@
+#include "hrktorrent.h"\r
+\r
+CIPFilter* IPFilter = 0;\r
+\r
+CIPFilter::CIPFilter()\r
+{\r
+       if(!Settings->GetI("ipfilter")) {\r
+               _active = false;\r
+               return;\r
+       }\r
+       else\r
+               _active = true;\r
+\r
+       std::string path = *Settings->getDir();\r
+       path.append("ipfilter.dat");\r
+\r
+       std::ifstream config(path.c_str(), std::ifstream::in);\r
+       if(!config.is_open()) {\r
+               Core->VerbosePrint("Settings", "Unable to load ip filter from file. Aborting.");\r
+               return;\r
+       }\r
+\r
+       std::cout << "Loading IPFilter. This could probably take a while!" << std::endl;\r
+       \r
+       while(config.good()) {\r
+               std::string line;\r
+               getline(config, line);\r
+               ParseFilterLine(line);\r
+       }\r
+\r
+       libtorrent::ip_filter::filter_tuple_t filters = _ipfilter.export_filter();\r
+       unsigned int entrycount = filters.get<0>().size() + filters.get<1>().size();\r
+       std::cout << entrycount << " entries imported." << std::endl;\r
+\r
+       config.close();\r
+}\r
+\r
+CIPFilter::~CIPFilter()\r
+{\r
+       Core->VerbosePrint("IPFilter", "Destroying IPFilter class.");\r
+}\r
+\r
+\r
+bool\r
+CIPFilter::AddRule(std::string start, std::string end)\r
+{\r
+       if(start.empty() || end.empty() || !_active) return false;\r
+\r
+       libtorrent::address astart, aend;\r
+       try {\r
+               astart = libtorrent::address::from_string(start);\r
+               aend = libtorrent::address::from_string(end);\r
+       } catch(boost::system::system_error& e) {\r
+               return false; // invalid rule\r
+       }\r
+\r
+       try {\r
+               _ipfilter.add_rule(astart, aend, libtorrent::ip_filter::blocked);\r
+       } catch(std::exception& e) {\r
+               return false;\r
+       }\r
+\r
+       return true;\r
+}\r
+\r
+void\r
+CIPFilter::ParseFilterLine(std::string line)\r
+{\r
+       if(line.size() == 0 || line.size() < 5 ) return;\r
+\r
+       std::string start;\r
+       std::string end;\r
+\r
+       std::string::size_type loc = line.find_first_of("-");\r
+       std::string::size_type loc2 = line.find_first_of(",");\r
+\r
+       start.assign(line);\r
+       start.resize(loc-1);\r
+\r
+       end.assign(line);\r
+       end.erase(0,loc+2);\r
+       end.resize(loc-1);\r
+\r
+       if(!AddRule(start,end))\r
+               Core->VerbosePrint("Settings", "Error adding line to ip filter.");\r
+}\r
diff --git a/instrumentation/hrktorrent/ipfilter.h b/instrumentation/hrktorrent/ipfilter.h
new file mode 100644 (file)
index 0000000..6b18df5
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef _IPFILTER_H\r
+#define _IPFILTER_H\r
+\r
+class CIPFilter\r
+{\r
+       public:\r
+               CIPFilter();\r
+               ~CIPFilter();\r
+               bool AddRule(std::string start, std::string end);\r
+               libtorrent::ip_filter getFilter() { return _ipfilter; }\r
+               bool IsActive() { return (_active == true); }\r
+\r
+       private:\r
+               void ParseFilterLine(std::string line);\r
+               libtorrent::ip_filter _ipfilter;\r
+\r
+               bool _active;\r
+};\r
+\r
+extern CIPFilter* IPFilter;\r
+\r
+#endif\r
diff --git a/instrumentation/hrktorrent/main.cpp b/instrumentation/hrktorrent/main.cpp
new file mode 100644 (file)
index 0000000..a6ab88b
--- /dev/null
@@ -0,0 +1,191 @@
+#include "hrktorrent.h"
+#include <getopt.h>
+void
+printusage()
+{
+       std::cout << APPNAME << " " << VERSION << " by hrkfdn (hrkfdn A T gmail D O T com) and other contributors\n";
+       std::cout << "usage: " << APPNAME << " [options] torrent-file\n";
+       std::cout << "NOTE: options provided by the commandline override configuration file entries!\n\n";
+
+       std::cout << "\t--minport\t\t- start port range (default: 6881)\n";
+       std::cout << "\t--maxport\t\t- end port range (default: 6999)\n";
+
+       std::cout << "\t--maxdown\t\t- download speed limit (in kb/s) (default: unlimited)\n";
+       std::cout << "\t--maxup\t\t\t- upload speed limit (in kb/s) (default: unlimited)\n";
+
+       std::cout << "\t--nodht\t\t\t- disable dht (default: on)\n";
+       std::cout << "\t--noupnp\t\t\t- disable upnp (default: on)\n";
+       std::cout << "\t--noseed\t\t- disable seeding (default: on)\n";
+       std::cout << "\t--forcereannounce\t- reannounce every X minutes (default: 2)\n";
+       std::cout << "\t--downloaddir\t- set the target directory (default: .)\n";
+       std::cout << "\t--ipfilter\t\t- enable ip filtering (default: off)\n\n";
+       std::cout << "\t--verbose\t\t- print verbose messages (default: off)\n\n";
+
+       std::cout << "example: hrktorrent --minport6500 --maxport6600 --nodht file.torrent\n";
+
+       std::cout << std::endl;
+}
+
+void
+parseargs(int argc, char** argv)
+{
+       int longval;
+       int option_index = 0;
+       int opt;
+       static struct option long_options[] = {
+               {"help", 0, NULL, 'h'},
+               {"ipfilter", 0, NULL, 'i'},
+               {"limitlocal", 0, NULL, 'l'},
+               {"nodht", 0, NULL, 't'},
+               {"noupnp", 0, NULL, 'n'},
+               {"noseed", 0, NULL, 's'},
+               {"verbose", 0, NULL, 'v'},
+               {"version", 0, NULL, 'V'},
+               {"minport", 1, NULL,'p'},
+               {"maxport", 1, NULL, 'P'},
+               {"maxdown", 1, NULL, 'd'},
+               {"maxup", 1, NULL, 'u'},
+               {"forcereannounce", 1, NULL, 'f'},
+               {"outputdir", 1, NULL, 'o'},
+               {0,0,0,0}
+       };
+
+       while (1) {
+               opt = getopt_long(argc, argv, "hnsiv:p:P:M:u:f:d:",long_options, &option_index);
+               if (opt == -1)
+                       break;
+
+               switch(opt)
+               {
+                       case 1:
+                               /* If this option set a flag, do nothing else now. */
+                               if (long_options[option_index].flag != 0)
+                                       break;
+                               //long_opt = long_options[option_index].name;
+                               printf ("option %s", long_options[option_index].name);
+                               if (optarg)
+                                       printf (" with arg %s", optarg);
+                               printf ("\n");
+                               break;
+                       case 'p':
+                               std::cout << opt << " "<< optarg<<std::endl;
+                               break;
+                       case 'P':
+                               std::cout << opt << " "<< optarg<<std::endl;
+                               break;
+                       case 'M':
+                               std::cout << opt << " "<< optarg<<std::endl;
+                               break;
+                       case 'u':
+                               std::cout << opt << " "<< optarg<<std::endl;
+                               break;
+                       case 'h':
+                               std::cout << opt << " "<< optarg<<std::endl;
+                               Settings->Set("nodht", 1);
+                               break;
+                       case 'n':
+                               std::cout << opt << " "<< optarg<<std::endl;
+                               Settings->Set("noupnp", 1);
+                               break;
+                       case 's':
+                               std::cout << opt << " "<< optarg<<std::endl;
+                               Settings->Set("noseed", 1);
+                               break;
+                       case 'd':
+                               std::cout << opt << " "<< optarg<<std::endl;
+                               break;
+                       case 'i':
+                               std::cout << opt << " "<< optarg<<std::endl;
+                               Settings->Set("ipfilter", 1);
+                               break;
+                       case 'v':
+                               std::cout << opt << " "<< optarg<<std::endl;
+                               Settings->Set("verbose", 1);
+                               break;
+                       default:
+                               std::cout <<"wtf"<<" "<<opt<<std::endl;
+
+               }
+
+       }
+
+}      
+/*
+void
+parseargs(int argc, char** argv)
+{
+       for(unsigned int i = 1; i < argc; i++) {
+               char* parg = argv[i];
+               if(strstr(parg, "--noseed")) {
+                       Settings->Set("seed", 0);
+                       continue;
+               }
+               else if(strstr(parg, "--nodht")) {
+                       Settings->Set("dht", 0);
+                       continue;
+               }
+               else if(strstr(parg, "--noupnp")) {
+                       Settings->Set("upnp", 0);
+                       continue;
+               }
+               else if(strstr(parg, "--verbose")) {
+                       Settings->Set("verbose", 1);
+                       continue;
+               }
+               else if(strstr(parg, "--ipfilter")) {
+                       Settings->Set("ipfilter", 1);
+                       continue;
+               }
+       
+
+               parg += 2;
+
+               std::map<std::string, setting_t>::iterator it;
+               for(it = Settings->getSettingMap()->begin(); it != Settings->getSettingMap()->end(); it++) {
+                       if(strstr(parg, it->first.c_str())) {
+                               char* val = parg + strlen(it->first.c_str());
+                               switch(it->second.type) {
+                                       case TYPE_INT:
+                                               it->second.ival = atoi(val);
+                                               break;
+                                       case TYPE_STRING:
+                                               it->second.sval = val;
+                                               break;
+                               }
+                               std::cout << it->first.c_str()<< "=(" << it->second.ival << ", "<<it->second.sval <<")" << std::endl;
+                       }
+               }
+       }
+}
+*/
+#define CLEAN(x) if(x) delete x
+void
+close()
+{
+       CLEAN(Settings);
+       CLEAN(IPFilter);
+
+       /* make sure this is always the last class to cleanup */
+       CLEAN(Core);
+}
+
+int
+main(int argc, char* argv[])
+{
+       atexit(close);
+
+       using namespace std;
+       int runstate = EXIT_FAILURE;
+
+       if(argc < 2) {
+               printusage();
+               return EXIT_FAILURE;
+       }
+
+//     Core = new CCore(argc, argv);
+       parseargs(argc, argv);
+//     runstate = Core->Run();
+
+//     return runstate;
+       return 0;
+}
diff --git a/instrumentation/hrktorrent/settings.cpp b/instrumentation/hrktorrent/settings.cpp
new file mode 100644 (file)
index 0000000..f799f04
--- /dev/null
@@ -0,0 +1,84 @@
+#include "hrktorrent.h"\r
+\r
+CSettings* Settings = 0;\r
+\r
+CSettings::CSettings()\r
+{\r
+       /* apply default settings */\r
+       Set("verbose", 1);\r
+\r
+       Set("minport", 6881);\r
+       Set("maxport", 6999);\r
+\r
+       Set("maxup", 0);\r
+       Set("maxdown", 0);\r
+\r
+       Set("dht", 1);\r
+       Set("upnp", 1);\r
+       Set("seed", 1);\r
+       Set("forcereannounce", 2);\r
+       Set("ipfilter", 1);\r
+\r
+       Set("downloaddir", ".");\r
+}\r
+\r
+CSettings::~CSettings()\r
+{\r
+       Core->VerbosePrint("Settings", "Destroying Settings class.");\r
+}\r
+\r
+void\r
+CSettings::LoadConfig()\r
+{\r
+       _dir = getenv("HOME");\r
+       _dir.append("/.hrktorrent/");\r
+       \r
+       std::string path = _dir;\r
+       path.append("hrktorrent.rc");\r
+\r
+       std::ifstream config(path.c_str(), std::ifstream::in);\r
+       if(!config.is_open()) {\r
+               /* workaround: Core->VerbosePrint uses non-initialized Core */\r
+               std::cout << "[Settings] Could not load config file. Will use default values." << std::endl;\r
+\r
+               /* cannot do: Core may not be properly initialized */\r
+               /* Core->VerbosePrint("Settings", "Could not load config file. Will use default values.");*/\r
+               return;\r
+       }\r
+\r
+       while(config.good()) {\r
+               std::string line;\r
+               getline(config, line);\r
+               ParseLine(line);\r
+       }\r
+\r
+       config.close();\r
+}\r
+\r
+void\r
+CSettings::ParseLine(std::string line)\r
+{\r
+       std::string var;\r
+       std::string value;\r
+       std::stringstream linestream;\r
+\r
+       std::string::size_type loc = line.find_first_of("#");\r
+       if(loc < line.size())\r
+               line.resize(loc);\r
+\r
+       linestream.str(line);\r
+\r
+       linestream >> var;\r
+       linestream >> value;\r
+       if(var.empty()) return;\r
+\r
+       switch(settings[var].type) {\r
+               case TYPE_INT:\r
+                       Set(var, atoi(value.c_str()));\r
+                       break;\r
+               case TYPE_STRING:\r
+                       Set(var, value);\r
+                       break;\r
+       }\r
+}\r
+\r
diff --git a/instrumentation/hrktorrent/settings.h b/instrumentation/hrktorrent/settings.h
new file mode 100644 (file)
index 0000000..e9a9a08
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef _SETTINGS_H
+#define _SETTINGS_H
+
+enum { TYPE_INT = 0, TYPE_STRING };
+
+typedef struct
+{
+       int type;
+       int ival;
+       std::string sval;
+} setting_t;
+
+class CSettings
+{
+       public:
+               CSettings();
+               ~CSettings();
+               void LoadConfig();
+               void ParseLine(std::string line);
+
+               void Set(std::string name, int ival) { settings[name].type = TYPE_INT; settings[name].ival = ival; }
+               void Set(std::string name, std::string sval) { settings[name].type = TYPE_STRING; settings[name].sval = sval; }
+
+               int GetI(std::string name) { return settings[name].ival; }
+               std::string GetS(std::string name) { return settings[name].sval; }
+
+               inline std::string* getDir() { return &_dir; }
+
+               inline std::map<std::string, setting_t>* getSettingMap() { return &settings; }
+       private:
+               std::map<std::string, setting_t> settings;
+               std::string _dir;
+};
+extern CSettings* Settings;
+
+#endif
diff --git a/instrumentation/hrktorrent/utils.cpp b/instrumentation/hrktorrent/utils.cpp
new file mode 100644 (file)
index 0000000..d768327
--- /dev/null
@@ -0,0 +1,12 @@
+#include "hrktorrent.h"
+
+float 
+Round(float Value, int NumPlaces)
+{
+       float Factor;
+       int Temp;
+   
+       Factor = pow(10.0, NumPlaces);
+       Temp = (int)(Value * Factor + 0.5f);
+       return Temp / Factor;
+}
diff --git a/instrumentation/hrktorrent/utils.h b/instrumentation/hrktorrent/utils.h
new file mode 100644 (file)
index 0000000..1383350
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _UTILS_H
+#define _UTILS_H
+
+extern float Round(float Value, int NumPlaces);
+
+#endif
diff --git a/instrumentation/hrktorrent/vars.mk b/instrumentation/hrktorrent/vars.mk
new file mode 100644 (file)
index 0000000..fe39492
--- /dev/null
@@ -0,0 +1,14 @@
+PREFIX         = /usr/local
+MANPREFIX      = ${PREFIX}/man
+CXX?           = g++
+OBJ            = main.o core.o settings.o utils.o ipfilter.o
+EXTRA_OBJ      =  ../libtorrent-rasterbar/lib/libtorrent-rasterbar.a
+OUT            = hrktorrent
+CXXFLAGS       += `PKG_CONFIG_PATH=../libtorrent-rasterbar pkg-config --cflags libtorrent-rasterbar`
+LIBS           = `PKG_CONFIG_PATH=../libtorrent-rasterbar pkg-config --libs libtorrent-rasterbar` -lpthread
+EXTRA_LIBS     = -lpthread -lboost_thread -lssl -lcrypto -lz -lm -lboost_system -lboost_filesystem -lrt
+
+#LIBS          = -lpthread
+#CXXFLAGS      += `pkg-config --cflags libtorrent-rasterbar`
+#LIBS          = `pkg-config --libs libtorrent-rasterbar` -lpthread
+
diff --git a/instrumentation/hrktorrent/version.h b/instrumentation/hrktorrent/version.h
new file mode 100644 (file)
index 0000000..07ce386
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef _VERSION_H
+#define _VERSION_H
+
+#define APPNAME                "hrktorrent"
+#define MAJOR          0
+#define MINOR          3
+#define REVISION       5
+#define TAG                    0
+#define VERSION                "0.3.5"
+
+#endif