Line
Link Here
|
0 |
-- a/configure.ac |
0 |
++ b/configure.ac |
Lines 3-8
Link Here
|
3 |
AM_INIT_AUTOMAKE |
3 |
AM_INIT_AUTOMAKE |
4 |
AM_CONFIG_HEADER(config.h) |
4 |
AM_CONFIG_HEADER(config.h) |
5 |
|
5 |
|
|
|
6 |
AC_CHECK_FUNCS(getline) |
6 |
AC_PROG_CXX |
7 |
AC_PROG_CXX |
7 |
AC_PROG_LIBTOOL |
8 |
AC_PROG_LIBTOOL |
8 |
|
9 |
|
9 |
-- a/src/command_network.cc |
10 |
++ b/src/command_network.cc |
Lines 36-41
Link Here
|
36 |
|
36 |
|
37 |
#include "config.h" |
37 |
#include "config.h" |
38 |
|
38 |
|
|
|
39 |
#include <string> |
40 |
#include <sstream> |
41 |
#include <list> |
42 |
#include <unistd.h> |
43 |
|
39 |
#include <functional> |
44 |
#include <functional> |
40 |
#include <cstdio> |
45 |
#include <cstdio> |
41 |
#include <rak/address_info.h> |
46 |
#include <rak/address_info.h> |
Lines 62-67
Link Here
|
62 |
#include "control.h" |
67 |
#include "control.h" |
63 |
#include "command_helpers.h" |
68 |
#include "command_helpers.h" |
64 |
|
69 |
|
|
|
70 |
#include "utils/pattern.h" |
71 |
#include "core/ip_filter.h" |
72 |
|
73 |
|
65 |
torrent::Object |
74 |
torrent::Object |
66 |
apply_throttle(bool up, const torrent::Object& rawArgs) { |
75 |
apply_throttle(bool up, const torrent::Object& rawArgs) { |
67 |
const torrent::Object::list_type& args = rawArgs.as_list(); |
76 |
const torrent::Object::list_type& args = rawArgs.as_list(); |
Lines 209-214
Link Here
|
209 |
} |
218 |
} |
210 |
|
219 |
|
211 |
torrent::Object |
220 |
torrent::Object |
|
|
221 |
apply_ip_filter(const torrent::Object& rawArgs) { |
222 |
const torrent::Object::list_type& args = rawArgs.as_list(); |
223 |
|
224 |
std::list<std::string> files; |
225 |
|
226 |
for (torrent::Object::list_const_iterator itr = args.begin(), last = args.end(); itr != last; itr++) { |
227 |
std::string file( itr->as_string() ); |
228 |
utils::trim( file ); |
229 |
if( access(file.c_str(),F_OK | R_OK) ) |
230 |
throw torrent::input_error("IpFilter file '" + file + "' does not exist or not readable. Filter could not be loaded"); |
231 |
files.push_back( file ); |
232 |
} |
233 |
|
234 |
std::stringstream logMsg; |
235 |
if( files.empty() ) { |
236 |
logMsg << "IpFilter is empty"; |
237 |
control->core()->push_log( logMsg.str().c_str() ); |
238 |
} |
239 |
else { |
240 |
core::IpFilter* f = new core::IpFilter(); |
241 |
logMsg << "IpFilter is initialized with files: "; |
242 |
int entries = 0; |
243 |
clock_t time_start = clock(); |
244 |
for( std::list<std::string>::iterator itr = files.begin(); itr != files.end(); itr++) { |
245 |
std::cout << "Loading IP filters from '" << *itr << "'..."; |
246 |
std::cout.flush(); |
247 |
if( itr != files.begin() ) |
248 |
logMsg << ", "; |
249 |
logMsg << *itr; |
250 |
int merges = f->add_from_file( *itr ); |
251 |
if( merges < 0 ) { |
252 |
std::cout << "error" << std::endl; |
253 |
std::cout.flush(); |
254 |
throw torrent::input_error("IpFilter could not load file '" + *itr + "'"); |
255 |
} |
256 |
std::cout << "done. Loaded " << (f->size()-entries) << " ranges. " << merges << " ranges were merged." << std::endl; |
257 |
std::cout.flush(); |
258 |
entries = f->size(); |
259 |
} |
260 |
control->core()->push_log( logMsg.str().c_str() ); |
261 |
std::stringstream logMsg2("IpFilter loaded with "); |
262 |
logMsg2 << f->size() << " ranges total. " << f->get_merges() << " ranges were merged."; |
263 |
control->core()->push_log( logMsg2.str().c_str() ); |
264 |
std::cout << logMsg2.str() << std::endl; |
265 |
std::cout << "IP_Filters loaded in " << (double)(clock()-time_start)/CLOCKS_PER_SEC << " seconds" << std::endl; |
266 |
std::cout.flush(); |
267 |
control->core()->set_ip_filter( f ); |
268 |
} |
269 |
|
270 |
return torrent::Object(); |
271 |
} |
272 |
|
273 |
torrent::Object |
212 |
apply_tos(const torrent::Object& rawArg) { |
274 |
apply_tos(const torrent::Object& rawArg) { |
213 |
rpc::Command::value_type value; |
275 |
rpc::Command::value_type value; |
214 |
torrent::ConnectionManager* cm = torrent::connection_manager(); |
276 |
torrent::ConnectionManager* cm = torrent::connection_manager(); |
Lines 492-497
Link Here
|
492 |
|
554 |
|
493 |
ADD_VARIABLE_BOOL("peer_exchange", true); |
555 |
ADD_VARIABLE_BOOL("peer_exchange", true); |
494 |
|
556 |
|
|
|
557 |
ADD_COMMAND_VOID("reload_ip_filter", rak::make_mem_fun(control->core(), &core::Manager::reload_ip_filter)); |
558 |
ADD_COMMAND_LIST("ip_filter", rak::ptr_fn(&apply_ip_filter)); |
559 |
|
495 |
// Not really network stuff: |
560 |
// Not really network stuff: |
496 |
ADD_VARIABLE_BOOL ("handshake_log", false); |
561 |
ADD_VARIABLE_BOOL ("handshake_log", false); |
497 |
ADD_VARIABLE_STRING("log.tracker", ""); |
562 |
ADD_VARIABLE_STRING("log.tracker", ""); |
498 |
-- a/src/core/Makefile.am |
563 |
++ b/src/core/Makefile.am |
Lines 36-41
Link Here
|
36 |
view.cc \ |
36 |
view.cc \ |
37 |
view.h \ |
37 |
view.h \ |
38 |
view_manager.cc \ |
38 |
view_manager.cc \ |
39 |
view_manager.h |
39 |
view_manager.h \ |
|
|
40 |
ip_address.cc \ |
41 |
ip_address.h \ |
42 |
ip_filter.cc \ |
43 |
ip_filter.h \ |
44 |
ip_range.cc \ |
45 |
ip_range.h \ |
46 |
printable.h \ |
47 |
regex_namespace.h \ |
48 |
ip_filter_statics.cc \ |
49 |
getline.h \ |
50 |
getline.cc |
40 |
|
51 |
|
41 |
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) |
52 |
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) |
42 |
-- a/src/core/Makefile.in |
53 |
++ b/src/core/Makefile.in |
Lines 63-69
Link Here
|
63 |
manager.$(OBJEXT) poll_manager.$(OBJEXT) \ |
63 |
manager.$(OBJEXT) poll_manager.$(OBJEXT) \ |
64 |
poll_manager_epoll.$(OBJEXT) poll_manager_kqueue.$(OBJEXT) \ |
64 |
poll_manager_epoll.$(OBJEXT) poll_manager_kqueue.$(OBJEXT) \ |
65 |
poll_manager_select.$(OBJEXT) view.$(OBJEXT) \ |
65 |
poll_manager_select.$(OBJEXT) view.$(OBJEXT) \ |
66 |
view_manager.$(OBJEXT) |
66 |
view_manager.$(OBJEXT) \ |
|
|
67 |
ip_address.$(OBJEXT) \ |
68 |
ip_filter.$(OBJEXT) \ |
69 |
ip_range.$(OBJEXT) \ |
70 |
ip_filter_statics.$(OBJEXT) \ |
71 |
getline.$(OBJEXT) |
67 |
libsub_core_a_OBJECTS = $(am_libsub_core_a_OBJECTS) |
72 |
libsub_core_a_OBJECTS = $(am_libsub_core_a_OBJECTS) |
68 |
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) |
73 |
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) |
69 |
depcomp = $(SHELL) $(top_srcdir)/depcomp |
74 |
depcomp = $(SHELL) $(top_srcdir)/depcomp |
Lines 252-258
Link Here
|
252 |
view.cc \ |
257 |
view.cc \ |
253 |
view.h \ |
258 |
view.h \ |
254 |
view_manager.cc \ |
259 |
view_manager.cc \ |
255 |
view_manager.h |
260 |
view_manager.h \ |
|
|
261 |
ip_address.cc \ |
262 |
ip_address.h \ |
263 |
ip_filter.cc \ |
264 |
ip_filter.h \ |
265 |
ip_range.cc \ |
266 |
ip_range.h \ |
267 |
printable.h \ |
268 |
regex_namespace.h \ |
269 |
ip_filter_statics.cc \ |
270 |
getline.cc \ |
271 |
getline.h |
256 |
|
272 |
|
257 |
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) |
273 |
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) |
258 |
all: all-am |
274 |
all: all-am |
Lines 320-325
Link Here
|
320 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/poll_manager_select.Po@am__quote@ |
336 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/poll_manager_select.Po@am__quote@ |
321 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/view.Po@am__quote@ |
337 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/view.Po@am__quote@ |
322 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/view_manager.Po@am__quote@ |
338 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/view_manager.Po@am__quote@ |
|
|
339 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ip_address.Po@am__quote@ |
340 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ip_range.Po@am__quote@ |
341 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ip_filter_statics.Po@am__quote@ |
342 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getline.Po@am__quote@ |
323 |
|
343 |
|
324 |
.cc.o: |
344 |
.cc.o: |
325 |
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< |
345 |
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< |
326 |
-- a/src/core/ip_address.cc |
346 |
++ b/src/core/ip_address.cc |
Line 0
Link Here
|
0 |
-- a/src/core/ip_address.h |
1 |
#include <cstdlib> |
|
|
2 |
#include <string> |
3 |
#include <arpa/inet.h> |
4 |
|
5 |
#include "ip_address.h" |
6 |
#include "utils/pattern.h" |
7 |
|
8 |
namespace core { |
9 |
|
10 |
std::pair<bool,uint32_t> IpAddress::to_int( const std::string& address ) { |
11 |
uint32_t a; |
12 |
int r = inet_pton( AF_INET, address.c_str(), &a); |
13 |
if( r ) |
14 |
a = ntohl( a ); |
15 |
return std::pair<bool,uint32_t>( (r!=0), a ); |
16 |
} |
17 |
|
18 |
std::string IpAddress::to_string() const { |
19 |
char buf[128] = ""; |
20 |
uint32_t a = htonl( m_address ); |
21 |
inet_ntop( AF_INET, &a, buf, sizeof(buf) ); |
22 |
return std::string( buf ); |
23 |
} |
24 |
|
25 |
} |
|
|
26 |
++ b/src/core/ip_address.h |
Line 0
Link Here
|
0 |
-- a/src/core/ip_filter.cc |
1 |
#ifndef IPADDRESS_H |
|
|
2 |
#define IPADDRESS_H |
3 |
|
4 |
#include <inttypes.h> |
5 |
#include <string> |
6 |
|
7 |
#include "printable.h" |
8 |
#include "utils/pattern.h" |
9 |
#include "regex_namespace.h" |
10 |
|
11 |
namespace core { |
12 |
|
13 |
class IpAddress : public Printable { |
14 |
friend class IpRange; |
15 |
|
16 |
private: // constants |
17 |
static const std::string PATTERN_IP_EXPRESSION; |
18 |
static const std::string PATTERN_IP_BYTES_EXPRESSION; |
19 |
static const regex::Pattern PATTERN_IP_BYTES; |
20 |
|
21 |
static const int GRP_IP_FIRST_BYTE; |
22 |
static const int GRP_IP_BYTES_COUNT; |
23 |
|
24 |
private: // fields |
25 |
uint32_t m_address; |
26 |
|
27 |
private: // static methods |
28 |
|
29 |
private: // dynamic methods |
30 |
IpAddress() : m_address(0) {} |
31 |
|
32 |
void copy( const IpAddress& addr ) { m_address = addr.m_address;} |
33 |
|
34 |
public: // static methods |
35 |
static std::pair<bool,uint32_t> to_int( const std::string& strAddress ); |
36 |
static IpAddress* parse( const std::string& strAddress ) { |
37 |
std::pair<bool,uint32_t> result = to_int( strAddress ); |
38 |
return ( !result.first ) ? NULL : new IpAddress( result.second ); |
39 |
} |
40 |
|
41 |
public: // dynamic methods |
42 |
IpAddress( uint32_t address ) : m_address(address) {} |
43 |
IpAddress( const IpAddress& addr ) { copy( addr ); } |
44 |
IpAddress& operator= ( const IpAddress& addr ) { copy( addr ); return *this; } |
45 |
|
46 |
operator uint32_t() const { return m_address; } |
47 |
|
48 |
bool operator>= ( const IpAddress& ip ) const { return (m_address >= ip.m_address); } |
49 |
bool operator<= ( const IpAddress& ip ) const { return (m_address <= ip.m_address); } |
50 |
bool operator< ( const IpAddress& ip ) const { return (m_address < ip.m_address); } |
51 |
bool operator> ( const IpAddress& ip ) const { return (m_address > ip.m_address); } |
52 |
bool operator== ( const IpAddress& ip ) const { return (m_address == ip.m_address); } |
53 |
bool operator!= ( const IpAddress& ip ) const { return (m_address != ip.m_address); } |
54 |
|
55 |
bool operator>= ( uint32_t ip ) const { return (m_address >= ip); } |
56 |
bool operator<= ( uint32_t ip ) const { return (m_address <= ip); } |
57 |
bool operator< ( uint32_t ip ) const { return (m_address < ip); } |
58 |
bool operator> ( uint32_t ip ) const { return (m_address > ip); } |
59 |
bool operator== ( uint32_t ip ) const { return (m_address == ip); } |
60 |
bool operator!= ( uint32_t ip ) const { return (m_address != ip); } |
61 |
|
62 |
std::string to_string() const; |
63 |
}; |
64 |
} |
65 |
#endif |
|
|
66 |
++ b/src/core/ip_filter.cc |
Line 0
Link Here
|
0 |
-- a/src/core/ip_filter.h |
1 |
#include <sstream> |
|
|
2 |
#include <string> |
3 |
#include <map> |
4 |
#include <list> |
5 |
#include <fstream> |
6 |
#include <stdio.h> |
7 |
#include <stdlib.h> |
8 |
|
9 |
#ifdef HAVE_CONFIG_H |
10 |
#include <config.h> |
11 |
#endif |
12 |
|
13 |
#ifndef __linux__ |
14 |
#ifndef HAVE_GETLINE |
15 |
#include "getline.h" |
16 |
#endif |
17 |
#endif |
18 |
|
19 |
#include "ip_filter.h" |
20 |
|
21 |
namespace core { |
22 |
|
23 |
int IpFilter::merge_and_insert( range_map* rs, IpRange* r ) { |
24 |
if( !r || !r->get_from() ) |
25 |
return 0; |
26 |
|
27 |
std::pair<const IpAddress,IpRange::ptr> p( *r->get_from(), IpRange::ptr(r) ); |
28 |
std::pair<range_itr,bool> duo = rs->insert( p ); |
29 |
|
30 |
range_itr idx = duo.first; |
31 |
bool wasInserted = duo.second; |
32 |
IpRange* curr = NULL; |
33 |
int mergeCount = 0; |
34 |
|
35 |
if( !wasInserted ) { // exactly the same start address already exists |
36 |
curr = idx->second; |
37 |
if( *curr->get_to() < *r->get_to() ) |
38 |
curr->set_to( r->get_to() ); |
39 |
delete r; |
40 |
r = curr; |
41 |
mergeCount++; |
42 |
} |
43 |
else { |
44 |
if( idx != rs->begin() ) { |
45 |
--idx; |
46 |
curr = idx->second; // previous |
47 |
if( *r->get_from() <= *curr->get_to() ) |
48 |
r = curr; |
49 |
else |
50 |
++idx; |
51 |
} |
52 |
} |
53 |
|
54 |
if( idx != rs->end() ) |
55 |
++idx; |
56 |
|
57 |
while( idx != rs->end() ) { |
58 |
curr = idx->second; |
59 |
if( *r->get_to() < *curr->get_from() ) |
60 |
break; |
61 |
|
62 |
std::string d = r->get_description(); |
63 |
d += " / " + curr->get_description(); |
64 |
r->set_description( d ); |
65 |
if( *r->get_to() < *curr->get_to() ) |
66 |
r->set_to( curr->get_to() ); |
67 |
rs->erase( idx++ ); |
68 |
delete curr; |
69 |
mergeCount++; |
70 |
} |
71 |
return mergeCount; |
72 |
} |
73 |
|
74 |
int IpFilter::add_from_file( const std::string& fileName, range_map* rs, str_list* files ) { |
75 |
FILE *f = fopen(fileName.c_str(),"r"); |
76 |
int mergeCount = 0; |
77 |
if (f==0) return -1; |
78 |
char *line = (char *)malloc(64); |
79 |
size_t sz=64; |
80 |
int charsread = 0; |
81 |
int linesread=0; |
82 |
while( (charsread=getline(&line,&sz,f)) >=0 ) { |
83 |
if( (line[0] == '#' ) || ( charsread <= 1 ) ) |
84 |
continue; |
85 |
|
86 |
IpRange* ir = IpRange::parse( line, charsread ); |
87 |
if( !ir || !ir->get_from() || !ir->get_to() ) |
88 |
continue; |
89 |
|
90 |
mergeCount += merge_and_insert( rs, ir ); |
91 |
} |
92 |
free(line); |
93 |
files->push_back( std::string(fileName) ); |
94 |
fclose(f); |
95 |
m_merges += mergeCount; |
96 |
return mergeCount; |
97 |
} |
98 |
|
99 |
int IpFilter::add_from_file( const std::string& fileName ) { |
100 |
if( !m_ranges ) |
101 |
m_ranges = new range_map(); |
102 |
if( !m_loadedFiles ) |
103 |
m_loadedFiles = new std::list<std::string>(); |
104 |
|
105 |
return add_from_file( fileName, m_ranges, m_loadedFiles ); |
106 |
} |
107 |
|
108 |
int IpFilter::reload() { |
109 |
if( !m_loadedFiles || m_loadedFiles->empty() ) |
110 |
return 0; |
111 |
|
112 |
range_map* rs = new range_map(); |
113 |
str_list* files = new str_list(); |
114 |
int mergeCount = 0; |
115 |
for( str_list::const_iterator it = m_loadedFiles->begin(), end = m_loadedFiles->end(); it != end; it++ ) |
116 |
mergeCount += add_from_file( *it, rs, files ); |
117 |
|
118 |
range_map* rsOld = m_ranges; |
119 |
m_ranges = rs; |
120 |
if( rsOld ) { |
121 |
clear( rsOld ); |
122 |
delete rsOld; |
123 |
} |
124 |
|
125 |
str_list* filesOld = m_loadedFiles; |
126 |
m_loadedFiles = files; |
127 |
if( filesOld ) { |
128 |
clear( filesOld ); |
129 |
delete filesOld; |
130 |
} |
131 |
|
132 |
m_merges = mergeCount; |
133 |
return mergeCount; |
134 |
} |
135 |
|
136 |
IpRange* IpFilter::find_range( uint32_t ip ) const { |
137 |
if( (ip >= 0) && m_ranges && !m_ranges->empty() ) { |
138 |
range_itr idx = m_ranges->upper_bound( ip ); |
139 |
if( idx != m_ranges->begin() ) |
140 |
--idx; |
141 |
IpRange* curr = idx->second; |
142 |
if( curr->includes( ip ) ) |
143 |
return curr; |
144 |
} |
145 |
return NULL; |
146 |
} |
147 |
|
148 |
std::string IpFilter::to_string() const { |
149 |
std::stringstream result; |
150 |
if( !m_ranges ) |
151 |
result << "NULL" << std::endl; |
152 |
else { |
153 |
for( range_map::const_iterator it = m_ranges->begin() ; it != m_ranges->end(); it++ ) { |
154 |
const IpAddress a = it->first; |
155 |
IpRange* ir = it->second; |
156 |
result << a << ": " << *ir << std::endl; |
157 |
} |
158 |
} |
159 |
return result.str(); |
160 |
} |
161 |
|
162 |
void IpFilter::clear( range_map* map ) { |
163 |
if( map ) { |
164 |
for( range_itr i = map->begin(), j = map->end(); i != j; i++ ) |
165 |
delete i->second; |
166 |
map->clear(); |
167 |
} |
168 |
} |
169 |
|
170 |
void IpFilter::clear( str_list* list ) { |
171 |
if( list ) |
172 |
list->clear(); |
173 |
} |
174 |
|
175 |
} |
|
|
176 |
++ b/src/core/ip_filter.h |
Line 0
Link Here
|
0 |
-- a/src/core/ip_filter_statics.cc |
1 |
#ifndef IPFILTER_H |
|
|
2 |
#define IPFILTER_H |
3 |
|
4 |
#include <string> |
5 |
#include <map> |
6 |
#include <list> |
7 |
|
8 |
#include "printable.h" |
9 |
#include "ip_address.h" |
10 |
#include "ip_range.h" |
11 |
|
12 |
namespace core { |
13 |
|
14 |
typedef std::map<const IpAddress,IpRange::ptr> range_map; |
15 |
typedef range_map::iterator range_itr; |
16 |
typedef std::list<std::string> str_list; |
17 |
|
18 |
class IpFilter : public Printable { |
19 |
private: // fields |
20 |
int m_merges; |
21 |
range_map* m_ranges; |
22 |
str_list* m_loadedFiles; |
23 |
|
24 |
private: // static methods |
25 |
static void clear( range_map* map ); |
26 |
static void clear( str_list* list ); |
27 |
|
28 |
private: // dynamic methods |
29 |
void init_members(void) { // to avoid long constructor lines for every ctor |
30 |
m_ranges = NULL; |
31 |
m_loadedFiles = NULL; |
32 |
m_merges = 0; |
33 |
} |
34 |
int merge_and_insert( range_map* rs, IpRange* r ); |
35 |
int add_from_file( const std::string& fileName, range_map* rs, str_list* files ); |
36 |
|
37 |
public: // static methods |
38 |
|
39 |
public: // dynamic methods |
40 |
IpFilter() { init_members(); } |
41 |
~IpFilter() { |
42 |
clear(); |
43 |
if( m_ranges ) delete m_ranges; |
44 |
if( m_loadedFiles ) delete m_loadedFiles; |
45 |
m_ranges = NULL; |
46 |
m_loadedFiles = NULL; |
47 |
} |
48 |
IpFilter( std::string* files, int size ) { |
49 |
init_members(); |
50 |
for( int i = 0; i < size; i++, files++ ) |
51 |
add_from_file( *files ); |
52 |
} |
53 |
IpFilter( str_list& files ) { |
54 |
init_members(); |
55 |
for( str_list::const_iterator i = files.begin(), last = files.end(); i != last; i++ ) |
56 |
add_from_file( *i ); |
57 |
} |
58 |
IpFilter( IpFilter& f ) { |
59 |
init_members(); |
60 |
m_ranges = new range_map( *f.m_ranges ); |
61 |
m_loadedFiles = new str_list( *f.m_loadedFiles ); |
62 |
} |
63 |
|
64 |
int reload(); |
65 |
int add_from_file( const std::string& fileName ); |
66 |
int add_from_file( char* fileName ) { std::string s( fileName ); return add_from_file(s); } |
67 |
void clear() { clear( m_ranges ); clear( m_loadedFiles ); } |
68 |
|
69 |
IpRange* find_range( uint32_t ip ) const; |
70 |
|
71 |
bool is_filtered( uint32_t ip ) const { return (find_range( ip ) != NULL); } |
72 |
bool is_filtered( std::string ip ) const { |
73 |
static std::pair<bool,uint32_t> ipInt = IpAddress::to_int( ip ); |
74 |
return (!ipInt.first ? false : is_filtered( ipInt.second )); |
75 |
} |
76 |
|
77 |
std::string to_string() const; |
78 |
|
79 |
int size(void) { return ( m_ranges ? m_ranges->size() : 0 ); } |
80 |
int get_merges(void) { return m_merges; } |
81 |
void set_files( str_list& files) { m_loadedFiles = new str_list( files ); } |
82 |
}; |
83 |
|
84 |
} |
85 |
#endif |
|
|
86 |
++ b/src/core/ip_filter_statics.cc |
Line 0
Link Here
|
0 |
-- a/src/core/getline.cc |
1 |
#include "ip_address.h" |
|
|
2 |
#include "ip_range.h" |
3 |
#include "utils/pattern.h" |
4 |
|
5 |
namespace core { |
6 |
|
7 |
const std::string IpAddress::PATTERN_IP_EXPRESSION = "(([0-9]{1,3}\\.){3}[0-9]{1,3})"; |
8 |
const std::string IpAddress::PATTERN_IP_BYTES_EXPRESSION = "([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})"; |
9 |
const regex::Pattern IpAddress::PATTERN_IP_BYTES = PATTERN_IP_BYTES_EXPRESSION; |
10 |
|
11 |
const int IpAddress::GRP_IP_FIRST_BYTE = 1; |
12 |
const int IpAddress::GRP_IP_BYTES_COUNT = 4; |
13 |
|
14 |
const std::string IpRange::PATTERN_RANGE_EXPRESSION = "[[:space:]]*(.*)[[:space:]]*:[[:space:]]*" + IpAddress::PATTERN_IP_EXPRESSION + "[[:space:]]*-[[:space:]]*" + IpAddress::PATTERN_IP_EXPRESSION + "[[:space:]]*"; |
15 |
const regex::Pattern IpRange::PATTERN_RANGE = PATTERN_RANGE_EXPRESSION; |
16 |
|
17 |
const int IpRange::GRP_DESCRIPTION = 1; |
18 |
const int IpRange::GRP_FIRST_IP = 2; |
19 |
const int IpRange::GRP_SECOND_IP = 4; |
20 |
|
21 |
} |
|
|
22 |
++ b/src/core/getline.cc |
Line 0
Link Here
|
0 |
-- a/src/core/getline.h |
1 |
#include <string> |
|
|
2 |
#include <stdio.h> |
3 |
#include <stdlib.h> |
4 |
#include <sys/types.h> |
5 |
#include <sys/stat.h> |
6 |
#include <limits.h> |
7 |
#include <errno.h> |
8 |
|
9 |
namespace core { |
10 |
|
11 |
/* getline.c --- Implementation of replacement getline function. |
12 |
Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005 Free |
13 |
Software Foundation, Inc. |
14 |
|
15 |
/* Ported from glibc by Simon Josefsson. */ |
16 |
|
17 |
#ifndef SIZE_MAX |
18 |
# define SIZE_MAX ((size_t) -1) |
19 |
#endif |
20 |
#ifndef SSIZE_MAX |
21 |
# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2)) |
22 |
#endif |
23 |
#if !HAVE_FLOCKFILE |
24 |
# undef flockfile |
25 |
# define flockfile(x) ((void) 0) |
26 |
#endif |
27 |
#if !HAVE_FUNLOCKFILE |
28 |
# undef funlockfile |
29 |
# define funlockfile(x) ((void) 0) |
30 |
#endif |
31 |
|
32 |
/* Read up to (and including) a DELIMITER from FP into *LINEPTR (and |
33 |
NUL-terminate it). *LINEPTR is a pointer returned from malloc (or |
34 |
NULL), pointing to *N characters of space. It is realloc'ed as |
35 |
necessary. Returns the number of characters read (not including |
36 |
the null terminator), or -1 on error or EOF. */ |
37 |
|
38 |
ssize_t getline (char **lineptr, size_t *n, FILE *fp) |
39 |
{ |
40 |
ssize_t result; |
41 |
size_t cur_len = 0; |
42 |
|
43 |
if (lineptr == NULL || n == NULL || fp == NULL) |
44 |
{ |
45 |
errno = EINVAL; |
46 |
return -1; |
47 |
} |
48 |
|
49 |
flockfile (fp); |
50 |
|
51 |
if (*lineptr == NULL || *n == 0) |
52 |
{ |
53 |
*n = 120; |
54 |
*lineptr = (char *) malloc (*n); |
55 |
if (*lineptr == NULL) |
56 |
{ |
57 |
result = -1; |
58 |
goto unlock_return; |
59 |
} |
60 |
} |
61 |
|
62 |
for (;;) |
63 |
{ |
64 |
int i; |
65 |
|
66 |
i = getc (fp); |
67 |
if (i == EOF) |
68 |
{ |
69 |
result = -1; |
70 |
break; |
71 |
} |
72 |
|
73 |
/* Make enough space for len+1 (for final NUL) bytes. */ |
74 |
if (cur_len + 1 >= *n) |
75 |
{ |
76 |
size_t needed_max = |
77 |
SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX; |
78 |
size_t needed = 2 * *n + 1; /* Be generous. */ |
79 |
char *new_lineptr; |
80 |
|
81 |
if (needed_max < needed) |
82 |
needed = needed_max; |
83 |
if (cur_len + 1 >= needed) |
84 |
{ |
85 |
result = -1; |
86 |
goto unlock_return; |
87 |
} |
88 |
|
89 |
new_lineptr = (char *) realloc (*lineptr, needed); |
90 |
if (new_lineptr == NULL) |
91 |
{ |
92 |
result = -1; |
93 |
|
94 |
|
95 |
|
96 |
goto unlock_return; |
97 |
} |
98 |
|
99 |
*lineptr = new_lineptr; |
100 |
*n = needed; |
101 |
} |
102 |
|
103 |
(*lineptr)[cur_len] = i; |
104 |
cur_len++; |
105 |
|
106 |
if (i == '\n') |
107 |
break; |
108 |
} |
109 |
(*lineptr)[cur_len] = '\0'; |
110 |
result = cur_len ? cur_len : result; |
111 |
|
112 |
unlock_return: |
113 |
funlockfile (fp); |
114 |
return result; |
115 |
} |
116 |
|
117 |
} |
|
|
118 |
++ b/src/core/getline.h |
Line 0
Link Here
|
0 |
-- a/src/core/ip_range.cc |
1 |
#include <string> |
|
|
2 |
#include <stdio.h> |
3 |
#include <stdlib.h> |
4 |
#include <sys/types.h> |
5 |
#include <sys/stat.h> |
6 |
#include <limits.h> |
7 |
#include <errno.h> |
8 |
|
9 |
namespace core { |
10 |
|
11 |
/* getline.c --- Implementation of replacement getline function. |
12 |
Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005 Free |
13 |
Software Foundation, Inc. |
14 |
|
15 |
/* Ported from glibc by Simon Josefsson. */ |
16 |
|
17 |
/* Read up to (and including) a DELIMITER from FP into *LINEPTR (and |
18 |
NUL-terminate it). *LINEPTR is a pointer returned from malloc (or |
19 |
NULL), pointing to *N characters of space. It is realloc'ed as |
20 |
necessary. Returns the number of characters read (not including |
21 |
the null terminator), or -1 on error or EOF. */ |
22 |
|
23 |
ssize_t getline (char **lineptr, size_t *n, FILE *fp); |
24 |
|
25 |
} |
|
|
26 |
++ b/src/core/ip_range.cc |
Line 0
Link Here
|
0 |
-- a/src/core/ip_range.h |
1 |
#include <sstream> |
|
|
2 |
#include <string> |
3 |
|
4 |
#include "ip_range.h" |
5 |
#include "utils/pattern.h" |
6 |
#include "regex_namespace.h" |
7 |
|
8 |
namespace core { |
9 |
|
10 |
IpRange* IpRange::parse( const std::string& s ) { |
11 |
regex::Match m = PATTERN_RANGE.match( s ); |
12 |
|
13 |
if( !m.matches() ) { |
14 |
std::cout << "!! range format is invalid: '" << s << "'" << std::endl; |
15 |
return NULL; |
16 |
} |
17 |
|
18 |
std::string description = m.group( GRP_DESCRIPTION ); |
19 |
std::string ip1 = m.group( GRP_FIRST_IP ); |
20 |
std::string ip2 = m.group( GRP_SECOND_IP ); |
21 |
IpAddress* from = IpAddress::parse( ip1 ); |
22 |
IpAddress* to = IpAddress::parse( ip2 ); |
23 |
|
24 |
if( !from ) { |
25 |
std::cout << "!! from is invalid: description='" << description << ", ip1=" << ip1 << ", ip2=" << ip2 << std::endl; |
26 |
return NULL; |
27 |
} |
28 |
if( !to ) { |
29 |
std::cout << "!! to is invalid: description='" << description << ", ip1=" << ip1 << ", ip2=" << ip2 << std::endl; |
30 |
return NULL; |
31 |
} |
32 |
|
33 |
// if( !from || !to || (*to < *from) ) |
34 |
// return NULL; |
35 |
|
36 |
IpRange* r = new IpRange(); |
37 |
|
38 |
r->m_description = description; |
39 |
r->m_from = from; |
40 |
r->m_to = to; |
41 |
|
42 |
if( to && from && (*to < *from) ) { |
43 |
std::cout << "!! to < from: " << r->to_string() << std::endl; |
44 |
delete r; |
45 |
return NULL; |
46 |
} |
47 |
|
48 |
return r; |
49 |
} |
50 |
|
51 |
//fast version |
52 |
IpRange* IpRange::parse( const char *s, const int size ){ |
53 |
static char description[256]; |
54 |
static char ip1[24], ip2[24]; |
55 |
int pos=0, post=0, enddesc=size-1; |
56 |
while (enddesc>0 && s[enddesc]!=':') enddesc--; //find last ':' in the line |
57 |
while((pos<enddesc) && (unsigned char)s[pos]<=' ') pos++; // strip from start |
58 |
while ((pos<enddesc)){ |
59 |
if (post<255) description[post++]=s[pos]; |
60 |
pos++; |
61 |
} |
62 |
description[post]=0; |
63 |
if (s[pos]==':') pos++; |
64 |
post=0; |
65 |
while ((pos<size) && s[pos]!='-'){ |
66 |
if (post<23) ip1[post++]=s[pos]; |
67 |
pos++; |
68 |
} |
69 |
ip1[post]=0; |
70 |
if (s[pos]=='-'){ |
71 |
pos++; |
72 |
post=0; |
73 |
while ((pos<size) && s[pos]>' '){ |
74 |
if (post<23) ip2[post++]=s[pos]; |
75 |
pos++; |
76 |
} |
77 |
ip2[post]=0; |
78 |
} else ip2[0]=0; |
79 |
|
80 |
IpAddress* from = IpAddress::parse(ip1); |
81 |
IpAddress* to = IpAddress::parse(ip2); |
82 |
|
83 |
if( !from ) { |
84 |
std::cout << "!! from is invalid: description='" << description << ", ip1=" << ip1 << ", ip2=" << ip2 << std::endl; |
85 |
return NULL; |
86 |
} |
87 |
if( !to ) { |
88 |
std::cout << "!! to is invalid: description='" << description << ", ip1=" << ip1 << ", ip2=" << ip2 << std::endl; |
89 |
return NULL; |
90 |
} |
91 |
|
92 |
IpRange* r = new IpRange(); |
93 |
r->m_description = description; |
94 |
r->m_from = from; |
95 |
r->m_to = to; |
96 |
|
97 |
if( (*to < *from) ) { |
98 |
std::cout << "!! to < from: " << r->to_string() << std::endl; |
99 |
delete r; |
100 |
return NULL; |
101 |
} |
102 |
|
103 |
return r; |
104 |
} |
105 |
|
106 |
std::string IpRange::to_string() const { |
107 |
std::stringstream result; |
108 |
result << m_description << ": [" << m_from->to_string() << " - " << m_to->to_string() << ']'; |
109 |
return result.str(); |
110 |
} |
111 |
|
112 |
} |
|
|
113 |
++ b/src/core/ip_range.h |
Line 0
Link Here
|
0 |
-- a/src/core/manager.cc |
1 |
#ifndef IPRANGE_H |
|
|
2 |
#define IPRANGE_H |
3 |
|
4 |
#include <string> |
5 |
|
6 |
#include "printable.h" |
7 |
#include "ip_address.h" |
8 |
#include "utils/pattern.h" |
9 |
#include "regex_namespace.h" |
10 |
|
11 |
namespace core { |
12 |
|
13 |
class IpRange : public Printable { |
14 |
public: // constants |
15 |
static const std::string PATTERN_RANGE_EXPRESSION; |
16 |
static const regex::Pattern PATTERN_RANGE; |
17 |
|
18 |
static const int GRP_DESCRIPTION; |
19 |
static const int GRP_FIRST_IP; |
20 |
static const int GRP_SECOND_IP; |
21 |
|
22 |
private: // fields |
23 |
std::string m_description; |
24 |
const IpAddress* m_from; |
25 |
const IpAddress* m_to; |
26 |
|
27 |
private: // dynamic methods |
28 |
IpRange() : m_description(), m_from(NULL), m_to(NULL) {} |
29 |
|
30 |
public: // static methods |
31 |
typedef IpRange* ptr; |
32 |
static IpRange* parse( const std::string& s ); |
33 |
static IpRange* parse( const char *s, const int size ); |
34 |
|
35 |
public: // dynamic methods |
36 |
IpRange( IpRange& rng ) { copy(rng); } |
37 |
IpRange& operator= ( IpRange& rng ) { copy(rng); return *this; } |
38 |
|
39 |
void copy( IpRange& rng ) { |
40 |
m_description = rng.m_description; |
41 |
m_from = (!rng.m_from) ? NULL : new IpAddress( *rng.m_from ); |
42 |
m_to = (!rng.m_to) ? NULL : new IpAddress( *rng.m_to ); |
43 |
} |
44 |
|
45 |
const std::string& get_description ( void ) const { return m_description; } |
46 |
const IpAddress* get_from ( void ) const { return m_from; } |
47 |
const IpAddress* get_to ( void ) const { return m_to; } |
48 |
|
49 |
void set_description ( const std::string& description ) { m_description = description; } |
50 |
void set_from ( const IpAddress* from ) { if( m_from ) delete m_from; m_from = new IpAddress( *from ); } |
51 |
void set_to ( const IpAddress* to ) { if( m_to ) delete m_to; m_to = new IpAddress( *to ); } |
52 |
|
53 |
bool includes( const IpAddress& ip ) const { return includes((uint32_t)ip); } |
54 |
bool includes( uint32_t ip ) const { return (*m_from <= ip) && (*m_to >= ip); } |
55 |
|
56 |
~IpRange() { |
57 |
delete m_from; |
58 |
m_from = NULL; |
59 |
delete m_to; |
60 |
m_to = NULL; |
61 |
} |
62 |
|
63 |
std::string to_string() const; |
64 |
}; |
65 |
|
66 |
} |
67 |
#endif |
|
|
68 |
++ b/src/core/manager.cc |
Lines 39-44
Link Here
|
39 |
#include <cstdio> |
39 |
#include <cstdio> |
40 |
#include <cstring> |
40 |
#include <cstring> |
41 |
#include <fstream> |
41 |
#include <fstream> |
|
|
42 |
#include <sstream> |
42 |
#include <unistd.h> |
43 |
#include <unistd.h> |
43 |
#include <sys/select.h> |
44 |
#include <sys/select.h> |
44 |
#include <rak/address_info.h> |
45 |
#include <rak/address_info.h> |
Lines 151-156
Link Here
|
151 |
} |
152 |
} |
152 |
} |
153 |
} |
153 |
|
154 |
|
|
|
155 |
uint32_t |
156 |
Manager::filter_ip(const sockaddr* sa) { |
157 |
IpRange* r = NULL; |
158 |
// if something's wrong with filter or address it's gonna be allowed |
159 |
if( m_ipFilter && sa ) { |
160 |
const rak::socket_address* socketAddress = rak::socket_address::cast_from(sa); |
161 |
if( socketAddress->is_valid() && (socketAddress->family() == rak::socket_address::af_inet) ) |
162 |
r = m_ipFilter->find_range( socketAddress->sa_inet()->address_h() ); |
163 |
if( r ) |
164 |
m_logComplete.push_front("Address '" + socketAddress->address_str() + "' is rejected by IP filter range '" + r->to_string()); |
165 |
else |
166 |
if( rpc::call_command_value("get_handshake_log") ) |
167 |
m_logComplete.push_front("IP Filter allowed connection with '" + socketAddress->address_str() + "'"); |
168 |
} |
169 |
return (r==NULL); |
170 |
} |
171 |
|
172 |
|
154 |
void |
173 |
void |
155 |
Manager::push_log(const char* msg) { |
174 |
Manager::push_log(const char* msg) { |
156 |
m_logImportant.push_front(msg); |
175 |
m_logImportant.push_front(msg); |
Lines 158-164
Link Here
|
158 |
} |
177 |
} |
159 |
|
178 |
|
160 |
Manager::Manager() : |
179 |
Manager::Manager() : |
161 |
m_hashingView(NULL) |
180 |
m_hashingView(NULL), |
|
|
181 |
m_ipFilter(NULL) |
162 |
// m_pollManager(NULL) { |
182 |
// m_pollManager(NULL) { |
163 |
{ |
183 |
{ |
164 |
m_downloadStore = new DownloadStore(); |
184 |
m_downloadStore = new DownloadStore(); |
Lines 179-184
Link Here
|
179 |
delete m_downloadStore; |
199 |
delete m_downloadStore; |
180 |
delete m_httpQueue; |
200 |
delete m_httpQueue; |
181 |
delete m_fileStatusCache; |
201 |
delete m_fileStatusCache; |
|
|
202 |
|
203 |
set_ip_filter( NULL ); |
182 |
} |
204 |
} |
183 |
|
205 |
|
184 |
void |
206 |
void |
Lines 224-229
Link Here
|
224 |
CurlStack::global_init(); |
246 |
CurlStack::global_init(); |
225 |
|
247 |
|
226 |
torrent::connection_manager()->set_signal_handshake_log(sigc::mem_fun(this, &Manager::handshake_log)); |
248 |
torrent::connection_manager()->set_signal_handshake_log(sigc::mem_fun(this, &Manager::handshake_log)); |
|
|
249 |
torrent::connection_manager()->set_filter(sigc::mem_fun(this, &Manager::filter_ip)); |
227 |
} |
250 |
} |
228 |
|
251 |
|
229 |
void |
252 |
void |
Lines 557-560
Link Here
|
557 |
} |
580 |
} |
558 |
} |
581 |
} |
559 |
|
582 |
|
|
|
583 |
void Manager::reload_ip_filter(void) { |
584 |
if( m_ipFilter ) { |
585 |
push_log("Reloading IP filter"); |
586 |
m_ipFilter->reload(); |
587 |
std::stringstream logMsg("IpFilter reloaded with "); |
588 |
logMsg << m_ipFilter->size() << " ranges total. " << m_ipFilter->get_merges() << " ranges were merged."; |
589 |
push_log( logMsg.str().c_str() ); |
590 |
} |
591 |
} |
560 |
} |
592 |
} |
561 |
-- a/src/core/manager.h |
593 |
++ b/src/core/manager.h |
Lines 47-52
Link Here
|
47 |
#include "range_map.h" |
47 |
#include "range_map.h" |
48 |
#include "log.h" |
48 |
#include "log.h" |
49 |
|
49 |
|
|
|
50 |
#include "ip_filter.h" |
51 |
|
50 |
namespace torrent { |
52 |
namespace torrent { |
51 |
class Bencode; |
53 |
class Bencode; |
52 |
} |
54 |
} |
Lines 118-123
Link Here
|
118 |
|
120 |
|
119 |
void handshake_log(const sockaddr* sa, int msg, int err, const torrent::HashString* hash); |
121 |
void handshake_log(const sockaddr* sa, int msg, int err, const torrent::HashString* hash); |
120 |
|
122 |
|
|
|
123 |
uint32_t filter_ip(const sockaddr* sa); |
124 |
|
125 |
void set_ip_filter( IpFilter* ipFilter ) { |
126 |
IpFilter* old = m_ipFilter; |
127 |
m_ipFilter = ipFilter; |
128 |
if( old ) delete old; |
129 |
} |
130 |
void reload_ip_filter(void); |
131 |
|
121 |
static const int create_start = 0x1; |
132 |
static const int create_start = 0x1; |
122 |
static const int create_tied = 0x2; |
133 |
static const int create_tied = 0x2; |
123 |
static const int create_quiet = 0x4; |
134 |
static const int create_quiet = 0x4; |
Lines 153-158
Link Here
|
153 |
|
164 |
|
154 |
Log m_logImportant; |
165 |
Log m_logImportant; |
155 |
Log m_logComplete; |
166 |
Log m_logComplete; |
|
|
167 |
|
168 |
IpFilter* m_ipFilter; |
156 |
}; |
169 |
}; |
157 |
|
170 |
|
158 |
// Meh, cleanup. |
171 |
// Meh, cleanup. |
159 |
-- a/src/core/printable.h |
172 |
++ b/src/core/printable.h |
Line 0
Link Here
|
0 |
-- a/src/core/regex_namespace.h |
1 |
#ifndef PRINTABLE_H |
|
|
2 |
#define PRINTABLE_H |
3 |
|
4 |
#include <iostream> |
5 |
|
6 |
class Printable { |
7 |
public: |
8 |
virtual std::string to_string() const = 0; |
9 |
}; |
10 |
|
11 |
template<typename _CharT,class _Traits> inline std::basic_ostream<_CharT,_Traits>& |
12 |
operator<<( std::basic_ostream<_CharT,_Traits>& out, const Printable& val) { |
13 |
return out << val.to_string(); |
14 |
} |
15 |
|
16 |
#endif |
|
|
17 |
++ b/src/core/regex_namespace.h |
Line 0
Link Here
|
0 |
-- a/src/utils/Makefile.am |
1 |
#ifndef REGEXNAMESPACE_H |
|
|
2 |
#define REGEXNAMESPACE_H |
3 |
|
4 |
namespace regex = utils; |
5 |
|
6 |
#endif |
|
|
7 |
++ b/src/utils/Makefile.am |
Lines 9-14
Link Here
|
9 |
lockfile.cc \ |
9 |
lockfile.cc \ |
10 |
lockfile.h \ |
10 |
lockfile.h \ |
11 |
socket_fd.cc \ |
11 |
socket_fd.cc \ |
12 |
socket_fd.h |
12 |
socket_fd.h \ |
|
|
13 |
pattern.cc \ |
14 |
pattern.h |
13 |
|
15 |
|
14 |
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) |
16 |
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) |
15 |
-- a/src/utils/Makefile.in |
17 |
++ b/src/utils/Makefile.in |
Lines 58-64
Link Here
|
58 |
libsub_utils_a_LIBADD = |
58 |
libsub_utils_a_LIBADD = |
59 |
am_libsub_utils_a_OBJECTS = directory.$(OBJEXT) \ |
59 |
am_libsub_utils_a_OBJECTS = directory.$(OBJEXT) \ |
60 |
file_status_cache.$(OBJEXT) lockfile.$(OBJEXT) \ |
60 |
file_status_cache.$(OBJEXT) lockfile.$(OBJEXT) \ |
61 |
socket_fd.$(OBJEXT) |
61 |
socket_fd.$(OBJEXT) pattern.$(OBJEXT) |
62 |
libsub_utils_a_OBJECTS = $(am_libsub_utils_a_OBJECTS) |
62 |
libsub_utils_a_OBJECTS = $(am_libsub_utils_a_OBJECTS) |
63 |
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) |
63 |
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) |
64 |
depcomp = $(SHELL) $(top_srcdir)/depcomp |
64 |
depcomp = $(SHELL) $(top_srcdir)/depcomp |
Lines 220-226
Link Here
|
220 |
lockfile.cc \ |
220 |
lockfile.cc \ |
221 |
lockfile.h \ |
221 |
lockfile.h \ |
222 |
socket_fd.cc \ |
222 |
socket_fd.cc \ |
223 |
socket_fd.h |
223 |
socket_fd.h \ |
|
|
224 |
pattern.cc \ |
225 |
pattern.h |
224 |
|
226 |
|
225 |
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) |
227 |
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) |
226 |
all: all-am |
228 |
all: all-am |
Lines 275-280
Link Here
|
275 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_status_cache.Po@am__quote@ |
277 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_status_cache.Po@am__quote@ |
276 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lockfile.Po@am__quote@ |
278 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lockfile.Po@am__quote@ |
277 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket_fd.Po@am__quote@ |
279 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket_fd.Po@am__quote@ |
|
|
280 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pattern.Po@am__quote@ |
278 |
|
281 |
|
279 |
.cc.o: |
282 |
.cc.o: |
280 |
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< |
283 |
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< |
281 |
-- a/src/utils/pattern.cc |
284 |
++ b/src/utils/pattern.cc |
Line 0
Link Here
|
0 |
-- a/src/utils/pattern.h |
1 |
#include <string> |
|
|
2 |
#include <sys/types.h> |
3 |
#include <ctype.h> |
4 |
#include <regex.h> |
5 |
|
6 |
#include "pattern.h" |
7 |
|
8 |
namespace utils { |
9 |
|
10 |
int Pattern::countGroups( const std::string& str ) { |
11 |
int count1 = 0; |
12 |
int count2 = 0; |
13 |
|
14 |
for( size_t index = -1; (index = str.find( '(', index+1 )) != std::string::npos; ) |
15 |
count1++; |
16 |
for( size_t index = -1; (index = str.find( ')', index+1 )) != std::string::npos; ) |
17 |
count2++; |
18 |
|
19 |
return (count1 < count2) ? count1 : count2; |
20 |
} |
21 |
|
22 |
Pattern::Pattern( const std::string& pattern, Flags flags ) : lastResult(-1), |
23 |
preg(NULL) { |
24 |
int regFlags = REG_EXTENDED | REG_ICASE | REG_NEWLINE; |
25 |
if( !(flags & CASE_SENSITIVE) ) |
26 |
regFlags ^= REG_ICASE; |
27 |
if( (flags & DOT_MATCH_NEWLINE) ) |
28 |
regFlags ^= REG_NEWLINE; |
29 |
|
30 |
preg = new regex_t; |
31 |
numGroups = countGroups( pattern ) + 1; |
32 |
|
33 |
lastResult = regcomp( preg, pattern.c_str(), regFlags ); |
34 |
} |
35 |
|
36 |
Pattern::~Pattern() { |
37 |
regfree( preg ); |
38 |
delete( preg ); |
39 |
} |
40 |
|
41 |
std::string Pattern::getLastError() const { |
42 |
char errBuf[1024]; |
43 |
regerror( lastResult, preg, errBuf, sizeof(errBuf) ); |
44 |
return std::string(errBuf); |
45 |
} |
46 |
|
47 |
Match Pattern::match( const std::string& expression ) const { |
48 |
|
49 |
regmatch_t* pmatch = new regmatch_t[numGroups]; |
50 |
int res = regexec( preg, expression.c_str(), numGroups, pmatch, 0 ); |
51 |
return Match( expression, numGroups, pmatch, res, getLastError() ); |
52 |
} |
53 |
|
54 |
Match::Match( const std::string& expr, int ngroups, regmatch_t* groups, int result, const std::string& message ) : |
55 |
expression( expr ), |
56 |
nmatch( ngroups ), |
57 |
pmatch( groups ), |
58 |
matchResult( result ), |
59 |
matchMessage( message ) { |
60 |
} |
61 |
|
62 |
std::string Match::group( int i ) { |
63 |
if( (i >= nmatch) || (pmatch[i].rm_so < 0) ) |
64 |
return ""; |
65 |
|
66 |
return expression.substr( pmatch[i].rm_so, pmatch[i].rm_eo - pmatch[i].rm_so ); |
67 |
} |
68 |
|
69 |
std::string& trim( std::string& str ) { |
70 |
std::string::iterator it; |
71 |
for( it = str.begin(); (it < str.end()) && ( isspace(*it) || (*it == 0) ) ; it++ ); |
72 |
str.erase( str.begin(), it ); |
73 |
for( it = str.end()-1; (it >= str.begin()) && ( isspace(*it) || (*it == 0) ) ; it-- ); |
74 |
str.erase( ++it, str.end() ); |
75 |
return str; |
76 |
} |
77 |
|
78 |
} |
79 |
|
|
|
80 |
++ b/src/utils/pattern.h |
Line 0
Link Here
|
|
|
1 |
#ifndef PATTERN_H |
2 |
#define PATTERN_H |
3 |
|
4 |
#include <string> |
5 |
#include <sys/types.h> |
6 |
#include <ctype.h> |
7 |
#include <regex.h> |
8 |
|
9 |
namespace utils { |
10 |
|
11 |
class Match { |
12 |
public: |
13 |
Match( const std::string& expr, int ngroups, regmatch_t* pmatch, int matchResult, const std::string& matchMessage ); |
14 |
~Match() { delete[] pmatch; } |
15 |
std::string group( int i ); |
16 |
bool found() { return (matchResult == 0); } |
17 |
bool matches() { return found(); } |
18 |
std::string& getMatchMessage() { return matchMessage; } |
19 |
|
20 |
private: |
21 |
std::string expression; |
22 |
int nmatch; |
23 |
regmatch_t* pmatch; |
24 |
int matchResult; |
25 |
std::string matchMessage; |
26 |
}; |
27 |
|
28 |
class Pattern { |
29 |
public: |
30 |
enum Flags { |
31 |
DEFAULT = 0, // REG_EXTENDED | REG_ICASE | REG_NEWLINE |
32 |
CASE_SENSITIVE, |
33 |
DOT_MATCH_NEWLINE |
34 |
}; |
35 |
|
36 |
public: |
37 |
Pattern( const std::string& pattern, Flags f = Pattern::DEFAULT ); |
38 |
~Pattern(); |
39 |
bool isSuccess() { return (lastResult == 0); } |
40 |
std::string getLastError() const; |
41 |
Match match( const std::string& expression ) const; |
42 |
|
43 |
private: |
44 |
int countGroups( const std::string& str ); |
45 |
|
46 |
private: |
47 |
regex_t* preg; |
48 |
int lastResult; |
49 |
int numGroups; |
50 |
}; |
51 |
|
52 |
|
53 |
std::string& trim( std::string& str ); |
54 |
|
55 |
} |
56 |
|
57 |
// end of ifdef PATTERN_H |
58 |
#endif |
59 |
|