mirror of
https://codeberg.org/crimeflare/cloudflare-tor
synced 2024-12-22 15:40:32 +00:00
Upload files to 'tool/PGListUtil/src/common'
This commit is contained in:
parent
225e7b2ef1
commit
b3a4f05d9f
171
tool/PGListUtil/src/common/CErrorList.cpp
Normal file
171
tool/PGListUtil/src/common/CErrorList.cpp
Normal file
@ -0,0 +1,171 @@
|
||||
#include <stdio.h>
|
||||
#include <boost/xpressive/xpressive.hpp>
|
||||
#include "CErrorList.h"
|
||||
|
||||
namespace pglu {
|
||||
namespace error {
|
||||
|
||||
CErrorList::CErrorList() :
|
||||
m_pool(sizeof(CError)),
|
||||
m_errFoot(&m_errHead),
|
||||
m_errNext(&m_errHead),
|
||||
m_count(0)
|
||||
{
|
||||
m_errHead.line = 0;
|
||||
m_errHead.kind = SYNTAX;
|
||||
m_errHead.next = NULL;
|
||||
}
|
||||
|
||||
CErrorList::~CErrorList() {
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CErrorList::Clear() {
|
||||
m_pool.purge_memory();
|
||||
m_errHead.next = NULL;
|
||||
m_errFoot = &m_errHead;
|
||||
m_errNext = &m_errHead;
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
bool CErrorList::LoadListFile(const char *path) {
|
||||
char buf[PGLU_LENGTH_FILELINE];
|
||||
uint ip_begin1, ip_begin2, ip_begin3, ip_begin4;
|
||||
uint ip_end1, ip_end2, ip_end3, ip_end4;
|
||||
FILE *fp;
|
||||
CError *err = m_errFoot;
|
||||
|
||||
using namespace boost::xpressive;
|
||||
|
||||
static cmatch match;
|
||||
static mark_tag tagIp1(1), tagIp2(2), tagIp3(3), tagIp4(4), tagIp5(5), tagIp6(6), tagIp7(7), tagIp8(8);
|
||||
static mark_tag tagSep(9), tagMask(10);
|
||||
|
||||
static cregex reSyntax =
|
||||
as_xpr(':') >> *_s >>
|
||||
(tagIp1 = repeat<1, 3>(_d)) >> as_xpr('.') >>
|
||||
(tagIp2 = repeat<1, 3>(_d)) >> as_xpr('.') >>
|
||||
(tagIp3 = repeat<1, 3>(_d)) >> as_xpr('.') >>
|
||||
(tagIp4 = repeat<1, 3>(_d)) >>
|
||||
*_s >> as_xpr('-') >> *_s >>
|
||||
(tagIp5 = repeat<1, 3>(_d)) >> as_xpr('.') >>
|
||||
(tagIp6 = repeat<1, 3>(_d)) >> as_xpr('.') >>
|
||||
(tagIp7 = repeat<1, 3>(_d)) >> as_xpr('.') >>
|
||||
(tagIp8 = repeat<1, 3>(_d)) >>
|
||||
*_s >> (_ln | eos);
|
||||
|
||||
static cregex reSyntaxRestorable =
|
||||
(tagIp1 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
|
||||
(tagIp2 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
|
||||
(tagIp3 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
|
||||
(tagIp4 = repeat<1, 3>(_d)) >> *_s >> (
|
||||
(tagSep = +as_xpr('-')) >> *_s >>
|
||||
(tagIp5 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
|
||||
(tagIp6 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
|
||||
(tagIp7 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
|
||||
(tagIp8 = repeat<1, 3>(_d))
|
||||
|
|
||||
(tagSep = +(set = '/', '\\')) >> *_s >>
|
||||
(tagMask = repeat<1, 2>(_d))
|
||||
) >> *_s >> (_ln | eos);
|
||||
|
||||
#define reIpError repeat<3>(+_d >> *_s >> (set = '.', ',') >> *_s) >> +_d
|
||||
|
||||
static cregex reSyntaxError =
|
||||
reIpError >> *_s >> (
|
||||
*as_xpr('-') >> *_s >> reIpError |
|
||||
+(set = '/', '\\') >> *_s >> +_d
|
||||
);
|
||||
|
||||
fp = fopen(path, "r");
|
||||
if(fp == NULL)
|
||||
return false;
|
||||
|
||||
for(int line = 1; fgets(buf, PGLU_LENGTH_FILELINE, fp); ++line) {
|
||||
|
||||
if(regex_search(buf, match, reSyntax)) {
|
||||
if(!(
|
||||
(ip_begin1 = ParseDigit3(match[1].first, match[1].second)) < 256 &&
|
||||
(ip_begin2 = ParseDigit3(match[2].first, match[2].second)) < 256 &&
|
||||
(ip_begin3 = ParseDigit3(match[3].first, match[3].second)) < 256 &&
|
||||
(ip_begin4 = ParseDigit3(match[4].first, match[4].second)) < 256 &&
|
||||
(ip_end1 = ParseDigit3(match[5].first, match[5].second)) < 256 &&
|
||||
(ip_end2 = ParseDigit3(match[6].first, match[6].second)) < 256 &&
|
||||
(ip_end3 = ParseDigit3(match[7].first, match[7].second)) < 256 &&
|
||||
(ip_end4 = ParseDigit3(match[8].first, match[8].second)) < 256 &&
|
||||
(uint)((ip_begin1 << 24) | (ip_begin2 << 16) | (ip_begin3 << 8) | ip_begin4) <=
|
||||
(uint)((ip_end1 << 24) | (ip_end2 << 16) | (ip_end3 << 8) | ip_end4)
|
||||
)) {
|
||||
++m_count;
|
||||
err->next = (CError*)m_pool.malloc();
|
||||
err = err->next;
|
||||
err->line = line;
|
||||
err->kind = IP;
|
||||
}
|
||||
|
||||
} else if(regex_search(buf, match, reSyntaxRestorable)) {
|
||||
++m_count;
|
||||
err->next = (CError*)m_pool.malloc();
|
||||
err = err->next;
|
||||
err->line = line;
|
||||
if(*(match[9].first) == '-') {
|
||||
if(
|
||||
(ip_begin1 = ParseDigit3(match[1].first, match[1].second)) < 256 &&
|
||||
(ip_begin2 = ParseDigit3(match[2].first, match[2].second)) < 256 &&
|
||||
(ip_begin3 = ParseDigit3(match[3].first, match[3].second)) < 256 &&
|
||||
(ip_begin4 = ParseDigit3(match[4].first, match[4].second)) < 256 &&
|
||||
(ip_end1 = ParseDigit3(match[5].first, match[5].second)) < 256 &&
|
||||
(ip_end2 = ParseDigit3(match[6].first, match[6].second)) < 256 &&
|
||||
(ip_end3 = ParseDigit3(match[7].first, match[7].second)) < 256 &&
|
||||
(ip_end4 = ParseDigit3(match[8].first, match[8].second)) < 256 &&
|
||||
(uint)((ip_begin1 << 24) | (ip_begin2 << 16) | (ip_begin3 << 8) | ip_begin4) <=
|
||||
(uint)((ip_end1 << 24) | (ip_end2 << 16) | (ip_end3 << 8) | ip_end4)
|
||||
) {
|
||||
err->kind = SYNTAX_RESTORABLE;
|
||||
} else {
|
||||
err->kind = SYNTAX;
|
||||
}
|
||||
} else {
|
||||
uint mask = ParseDigit3(match[10].first, match[10].second);
|
||||
if(
|
||||
ParseDigit3(match[1].first, match[1].second) < 256 &&
|
||||
ParseDigit3(match[2].first, match[2].second) < 256 &&
|
||||
ParseDigit3(match[3].first, match[3].second) < 256 &&
|
||||
ParseDigit3(match[4].first, match[4].second) < 256 &&
|
||||
mask < 33
|
||||
) {
|
||||
err->kind = SYNTAX_RESTORABLE;
|
||||
} else {
|
||||
err->kind = SYNTAX;
|
||||
}
|
||||
}
|
||||
} else if(regex_search(buf, reSyntaxError)) {
|
||||
++m_count;
|
||||
err->next = (CError*)m_pool.malloc();
|
||||
err = err->next;
|
||||
err->line = line;
|
||||
err->kind = SYNTAX;
|
||||
}
|
||||
#ifdef __MINGW32__
|
||||
ZeroString(buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
err->next = NULL;
|
||||
m_errFoot = err;
|
||||
return true;
|
||||
}
|
||||
|
||||
int CErrorList::Count() {
|
||||
return m_count;
|
||||
}
|
||||
|
||||
CError * CErrorList::GetNext() {
|
||||
if(m_errNext)
|
||||
m_errNext = m_errNext->next;
|
||||
return m_errNext;
|
||||
}
|
||||
|
||||
} // namespace error
|
||||
} // namespace pglu
|
43
tool/PGListUtil/src/common/CErrorList.h
Normal file
43
tool/PGListUtil/src/common/CErrorList.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef CERRLIST_H
|
||||
#define CERRLIST_H
|
||||
|
||||
#include <boost/pool/pool.hpp>
|
||||
#include "common.h"
|
||||
|
||||
namespace pglu {
|
||||
namespace error {
|
||||
|
||||
typedef enum _EErrKind {
|
||||
SYNTAX,
|
||||
IP,
|
||||
SYNTAX_RESTORABLE
|
||||
} EErrKind;
|
||||
|
||||
typedef struct _CError {
|
||||
int line;
|
||||
EErrKind kind;
|
||||
_CError * next;
|
||||
} CError;
|
||||
|
||||
class CErrorList {
|
||||
private:
|
||||
boost::pool<> m_pool;
|
||||
CError m_errHead;
|
||||
CError * m_errFoot;
|
||||
CError * m_errNext;
|
||||
int m_count;
|
||||
|
||||
public:
|
||||
CErrorList();
|
||||
~CErrorList();
|
||||
|
||||
void Clear();
|
||||
bool LoadListFile(const char *path);
|
||||
int Count();
|
||||
CError * GetNext();
|
||||
};
|
||||
|
||||
} // namespace error
|
||||
} // namespace pglu
|
||||
|
||||
#endif // CERRLIST_H
|
125
tool/PGListUtil/src/common/CFilter.cpp
Normal file
125
tool/PGListUtil/src/common/CFilter.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "CFilter.h"
|
||||
|
||||
namespace pglu {
|
||||
namespace filter {
|
||||
|
||||
namespace {
|
||||
|
||||
char *strichr(const char *str, int chr) {
|
||||
const char *p = str;
|
||||
chr = tolower((unsigned char)chr);
|
||||
for(; tolower((unsigned char)(*p)) != chr; ++p)
|
||||
if(*p == '\0')
|
||||
return NULL;
|
||||
return (char*)p;
|
||||
}
|
||||
|
||||
char *stristr(const char *str, const char *pattern) {
|
||||
if(*pattern == '\0')
|
||||
return (char*)str;
|
||||
|
||||
const char *p = str;
|
||||
size_t len = strlen(pattern);
|
||||
for(; (p = strichr(p, pattern[0])) != NULL; ++p)
|
||||
if(!strnicmp(p, pattern, len))
|
||||
return (char*)p;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool search_and(const char *str, const char *terms, const bool del) {
|
||||
do {
|
||||
if(!stristr(str, terms))
|
||||
return del; // not found
|
||||
while(*terms != '\0')
|
||||
++terms;
|
||||
++terms;
|
||||
} while(*terms != '\0');
|
||||
return !del; // found all
|
||||
}
|
||||
|
||||
bool search_or(const char *str, const char *terms, const bool del) {
|
||||
do {
|
||||
if(stristr(str, terms))
|
||||
return !del; // found
|
||||
while(*terms != '\0')
|
||||
++terms;
|
||||
++terms;
|
||||
} while(*terms != '\0');
|
||||
return del; // not found
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
//--------------------------------------
|
||||
// CFilter class
|
||||
//--------------------------------------
|
||||
|
||||
CFilter::CFilter() :
|
||||
m_terms(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
CFilter::CFilter(const char *strFilter, const EFilterMode mode, const bool del) :
|
||||
m_terms(NULL)
|
||||
{
|
||||
Assign(strFilter, mode, del);
|
||||
}
|
||||
|
||||
CFilter::~CFilter() {
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CFilter::Assign(const char *strFilter, const EFilterMode mode, const bool del) {
|
||||
Clear();
|
||||
|
||||
if(mode == AND)
|
||||
m_search = search_and;
|
||||
else if(mode == OR)
|
||||
m_search = search_or;
|
||||
else
|
||||
return;
|
||||
|
||||
m_mode = mode;
|
||||
m_del = del;
|
||||
|
||||
m_terms = new char[strlen(strFilter) + 2];
|
||||
|
||||
while(*strFilter == ' ' || *strFilter == '\t')
|
||||
++strFilter;
|
||||
|
||||
char *strTerms = m_terms;
|
||||
while(*strFilter != '\0') {
|
||||
*(strTerms++) = *(strFilter++);
|
||||
if(*strFilter == ' ' || *strFilter == '\t') {
|
||||
*(strTerms++) = '\0';
|
||||
do {
|
||||
++strFilter;
|
||||
} while(*strFilter == ' ' || *strFilter == '\t');
|
||||
}
|
||||
}
|
||||
*strTerms = '\0';
|
||||
*(strTerms + 1) = '\0';
|
||||
}
|
||||
|
||||
void CFilter::Clear() {
|
||||
if(m_terms) {
|
||||
delete[] m_terms;
|
||||
m_terms = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool CFilter::IsEmpty() {
|
||||
if(m_terms)
|
||||
return *m_terms == '\0';
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CFilter::IsMatch(const char *str) {
|
||||
return m_search(str, m_terms, m_del);
|
||||
}
|
||||
|
||||
} // namespace filter
|
||||
} // namespace pglu
|
34
tool/PGListUtil/src/common/CFilter.h
Normal file
34
tool/PGListUtil/src/common/CFilter.h
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef CFILTER_H
|
||||
#define CFILTER_H
|
||||
|
||||
namespace pglu {
|
||||
namespace filter {
|
||||
|
||||
typedef enum _EFilterMode {
|
||||
AND,
|
||||
OR
|
||||
} EFilterMode;
|
||||
|
||||
class CFilter {
|
||||
private:
|
||||
char * m_terms;
|
||||
EFilterMode m_mode;
|
||||
bool m_del;
|
||||
|
||||
bool (* m_search)(const char *, const char *, const bool);
|
||||
|
||||
public:
|
||||
CFilter();
|
||||
CFilter(const char *strFilter, const EFilterMode mode, const bool del);
|
||||
~CFilter();
|
||||
|
||||
void Assign(const char *strFilter, const EFilterMode mode, const bool del);
|
||||
void Clear();
|
||||
bool IsEmpty();
|
||||
bool IsMatch(const char *str);
|
||||
};
|
||||
|
||||
} // namespace filter
|
||||
} // namespace pglu
|
||||
|
||||
#endif // CFILTER_H
|
355
tool/PGListUtil/src/common/CIpList.cpp
Normal file
355
tool/PGListUtil/src/common/CIpList.cpp
Normal file
@ -0,0 +1,355 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "CIpList.h"
|
||||
|
||||
namespace pglu {
|
||||
namespace ip {
|
||||
|
||||
namespace {
|
||||
|
||||
inline void Ip_Swap(CIp **ipA, CIp **ipB) {
|
||||
CIp *ip = *ipA;
|
||||
*ipA = *ipB;
|
||||
*ipB = ip;
|
||||
}
|
||||
|
||||
void Ip_SortByIpQuick(CIp **ipBegin, CIp **ipEnd) {
|
||||
CIp **ipA;
|
||||
CIp **ipB;
|
||||
int nGap = ipEnd - ipBegin;
|
||||
|
||||
if(nGap < 64)
|
||||
return;
|
||||
|
||||
ipA = ipBegin + ((int)(nGap / 2));
|
||||
if((*ipBegin)->ip64 > (*ipA)->ip64)
|
||||
Ip_Swap(ipBegin, ipA);
|
||||
if((*ipBegin)->ip64 > (*ipEnd)->ip64)
|
||||
Ip_Swap(ipBegin, ipEnd);
|
||||
if((*ipA)->ip64 > (*ipEnd)->ip64)
|
||||
Ip_Swap(ipA, ipEnd);
|
||||
ulong ip64 = (*ipA)->ip64;
|
||||
|
||||
ipB = ipEnd - 1;
|
||||
Ip_Swap(ipA, ipB);
|
||||
ipA = ipBegin;
|
||||
|
||||
for(; ; ) {
|
||||
while((*(++ipA))->ip64 < ip64);
|
||||
while((*(--ipB))->ip64 > ip64);
|
||||
if(ipA > ipB)
|
||||
break;
|
||||
Ip_Swap(ipA, ipB);
|
||||
}
|
||||
Ip_Swap(ipA, ipEnd - 1);
|
||||
|
||||
Ip_SortByIpQuick(ipBegin, ipB);
|
||||
Ip_SortByIpQuick(ipA + 1, ipEnd);
|
||||
}
|
||||
|
||||
void Ip_SortByIpInsert(CIp **ipBegin, CIp **ipEnd) {
|
||||
CIp **ipA = ipBegin + 1;
|
||||
CIp **ipB;
|
||||
CIp **ipAEnd = ipEnd + 1;
|
||||
CIp **ipBEnd = ipBegin - 1;
|
||||
ulong ip64;
|
||||
for(; ipA != ipAEnd; ++ipA) {
|
||||
ip64 = (*ipA)->ip64;
|
||||
for(ipB = ipA - 1; ipB != ipBEnd && (*ipB)->ip64 > ip64; --ipB)
|
||||
Ip_Swap(ipB, ipB + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void Ip_SortByIp(CIp **ipBegin, CIp **ipEnd) {
|
||||
Ip_SortByIpQuick(ipBegin, ipEnd);
|
||||
Ip_SortByIpInsert(ipBegin, ipEnd);
|
||||
}
|
||||
|
||||
CIp * Ip_SortByCaption(CIp *ipHeadA) {
|
||||
if(!ipHeadA || !(ipHeadA->next))
|
||||
return ipHeadA;
|
||||
|
||||
// split ipBを2倍で進めることでipAを中間位置に持っていく
|
||||
CIp *ipA = ipHeadA;
|
||||
CIp *ipB = ipHeadA->next->next;
|
||||
while(ipB) {
|
||||
ipA = ipA->next;
|
||||
ipB = ipB->next;
|
||||
if(ipB)
|
||||
ipB = ipB->next;
|
||||
}
|
||||
CIp *ipHeadB = ipA->next;
|
||||
ipA->next = NULL;
|
||||
|
||||
ipHeadA = Ip_SortByCaption(ipHeadA);
|
||||
ipHeadB = Ip_SortByCaption(ipHeadB);
|
||||
|
||||
// merge
|
||||
CIp ipMerged;
|
||||
ipA = &ipMerged;
|
||||
while(ipHeadA || ipHeadB) {
|
||||
if(((ipHeadA && ipHeadB) && stricmp(ipHeadA->caption, ipHeadB->caption) <= 0) || !ipHeadB) {
|
||||
ipA->next = ipHeadA;
|
||||
ipHeadA = ipHeadA->next;
|
||||
} else {
|
||||
ipA->next = ipHeadB;
|
||||
ipHeadB = ipHeadB->next;
|
||||
}
|
||||
ipA = ipA->next;
|
||||
}
|
||||
ipA->next = NULL;
|
||||
|
||||
return ipMerged.next;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
//--------------------------------------
|
||||
// CIpList class
|
||||
//--------------------------------------
|
||||
|
||||
CIpList::CIpList() :
|
||||
m_poolIp(sizeof(CIp)),
|
||||
m_ipFoot(&m_ipHead),
|
||||
m_count(0),
|
||||
m_countDisabled(0)
|
||||
{
|
||||
m_ipHead.caption = NULL;
|
||||
m_ipHead.ip64 = 0L;
|
||||
m_ipHead.next = NULL;
|
||||
}
|
||||
|
||||
CIpList::~CIpList() {
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CIpList::Clear() {
|
||||
for(CIp *ip = m_ipHead.next; ip; ip = ip->next)
|
||||
delete[] ip->caption;
|
||||
m_poolIp.purge_memory();
|
||||
m_ipHead.next = NULL;
|
||||
m_ipFoot = &m_ipHead;
|
||||
m_count = 0;
|
||||
m_countDisabled = 0;
|
||||
UnSetFilter();
|
||||
}
|
||||
|
||||
void CIpList::SetFilter(const char *filter, const filter::EFilterMode mode, const bool del) {
|
||||
m_filter.Assign(filter, mode, del);
|
||||
}
|
||||
|
||||
void CIpList::UnSetFilter() {
|
||||
m_filter.Clear();
|
||||
}
|
||||
|
||||
CIp * CIpList::CreateIp(boost::xpressive::cmatch & match) {
|
||||
CIp *ip = (CIp*)m_poolIp.malloc();
|
||||
|
||||
const char *capBegin = match.prefix().first;
|
||||
const char *capEnd = match[9].first;
|
||||
size_t lenCap = capEnd - capBegin;
|
||||
char *chunk = new char[lenCap + 1];
|
||||
memcpy(chunk, capBegin, lenCap);
|
||||
*(chunk + lenCap) = '\0';
|
||||
ip->caption = chunk;
|
||||
|
||||
uchar *ip8 = ip->ip8;
|
||||
ip8[4] = ParseDigit3(match[4].first, match[4].second);
|
||||
ip8[5] = ParseDigit3(match[3].first, match[3].second);
|
||||
ip8[6] = ParseDigit3(match[2].first, match[2].second);
|
||||
ip8[7] = ParseDigit3(match[1].first, match[1].second);
|
||||
|
||||
if(*(match[10].first) == '-') {
|
||||
ip8[0] = ParseDigit3(match[8].first, match[8].second);
|
||||
ip8[1] = ParseDigit3(match[7].first, match[7].second);
|
||||
ip8[2] = ParseDigit3(match[6].first, match[6].second);
|
||||
ip8[3] = ParseDigit3(match[5].first, match[5].second);
|
||||
} else {
|
||||
ip->ip32[0] = ip->ip32[1] | (0xFFFFFFFF >> ParseDigit3(match[11].first, match[11].second));
|
||||
}
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
||||
bool CIpList::LoadListFile(const char *path) {
|
||||
char buf[PGLU_LENGTH_FILELINE];
|
||||
char colon;
|
||||
char *colon_p;
|
||||
|
||||
using namespace boost::xpressive;
|
||||
|
||||
static cmatch match;
|
||||
static mark_tag tagIp1(1), tagIp2(2), tagIp3(3), tagIp4(4), tagIp5(5), tagIp6(6), tagIp7(7), tagIp8(8);
|
||||
static mark_tag tagColon(9), tagSep(10), tagMask(11);
|
||||
|
||||
static cregex reSyntax = // bos >> (tag = *_) >> // slower
|
||||
(tagColon = as_xpr(':')) >> *_s >>
|
||||
(tagIp1 = repeat<1, 3>(_d)) >> as_xpr('.') >>
|
||||
(tagIp2 = repeat<1, 3>(_d)) >> as_xpr('.') >>
|
||||
(tagIp3 = repeat<1, 3>(_d)) >> as_xpr('.') >>
|
||||
(tagIp4 = repeat<1, 3>(_d)) >>
|
||||
*_s >> (tagSep = as_xpr('-')) >> *_s >>
|
||||
(tagIp5 = repeat<1, 3>(_d)) >> as_xpr('.') >>
|
||||
(tagIp6 = repeat<1, 3>(_d)) >> as_xpr('.') >>
|
||||
(tagIp7 = repeat<1, 3>(_d)) >> as_xpr('.') >>
|
||||
(tagIp8 = repeat<1, 3>(_d)) >>
|
||||
*_s >> (_ln | eos);
|
||||
|
||||
static cregex reSyntaxRestorable =
|
||||
(tagColon = !as_xpr(':')) >> *_s >>
|
||||
(tagIp1 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
|
||||
(tagIp2 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
|
||||
(tagIp3 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
|
||||
(tagIp4 = repeat<1, 3>(_d)) >> *_s >> (
|
||||
(tagSep = +as_xpr('-')) >> *_s >>
|
||||
(tagIp5 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
|
||||
(tagIp6 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
|
||||
(tagIp7 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
|
||||
(tagIp8 = repeat<1, 3>(_d))
|
||||
|
|
||||
(tagSep = +(set = '/', '\\')) >> *_s >>
|
||||
(tagMask = repeat<1, 2>(_d))
|
||||
) >> *_s >> (_ln | eos);
|
||||
|
||||
FILE *fp = fopen(path, "r");
|
||||
if(fp == NULL)
|
||||
return false;
|
||||
|
||||
CIp *ip = m_ipFoot;
|
||||
|
||||
if(m_filter.IsEmpty()) {
|
||||
while(fgets(buf, PGLU_LENGTH_FILELINE, fp)) {
|
||||
|
||||
if(regex_search(buf, match, reSyntax) || regex_search(buf, match, reSyntaxRestorable)) {
|
||||
++m_count;
|
||||
ip->next = CreateIp(match);
|
||||
ip = ip->next;
|
||||
}
|
||||
#ifdef __MINGW32__
|
||||
ZeroString(buf);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
while(fgets(buf, PGLU_LENGTH_FILELINE, fp)) {
|
||||
|
||||
if(regex_search(buf, match, reSyntax) || regex_search(buf, match, reSyntaxRestorable)) {
|
||||
colon_p = (char*)(match[9].first);
|
||||
colon = *colon_p;
|
||||
*colon_p = '\0';
|
||||
|
||||
if(m_filter.IsMatch(buf)) {
|
||||
++m_count;
|
||||
ip->next = CreateIp(match);
|
||||
ip = ip->next;
|
||||
}
|
||||
*colon_p = colon;
|
||||
}
|
||||
#ifdef __MINGW32__
|
||||
ZeroString(buf);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
ip->next = NULL;
|
||||
m_ipFoot = ip;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CIpList::SaveListFile(const char *path, const bool append) {
|
||||
uchar *ip8;
|
||||
|
||||
FILE *fp = fopen(path, (append ? "a" : "w"));
|
||||
if(fp == NULL)
|
||||
return false;
|
||||
|
||||
for(CIp *ip = m_ipHead.next; ip; ip = ip->next) {
|
||||
// IPが0Lなら書き出さない
|
||||
if(ip->ip64 != 0L) {
|
||||
ip8 = ip->ip8;
|
||||
fprintf(fp,
|
||||
"%s:%u.%u.%u.%u-%u.%u.%u.%u\n",
|
||||
ip->caption,
|
||||
ip8[7], ip8[6], ip8[5], ip8[4],
|
||||
ip8[3], ip8[2], ip8[1], ip8[0]
|
||||
);
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CIpList::CheckAndSort(const bool sortCap, const bool sortIp, const bool delDupIp) {
|
||||
CIp **ipBegin;
|
||||
CIp **ipEnd;
|
||||
CIp *ip;
|
||||
|
||||
if(m_count < 2)
|
||||
return;
|
||||
|
||||
if(sortIp || delDupIp) {
|
||||
// リストから配列を複製
|
||||
CIp **ipSort = new CIp*[m_count];
|
||||
ipBegin = ipSort;
|
||||
for(ip = m_ipHead.next; ip; ip = ip->next)
|
||||
*(ipBegin++) = ip;
|
||||
|
||||
// 配列をソート
|
||||
Ip_SortByIp(ipSort, ipSort + m_count - 1);
|
||||
|
||||
if(delDupIp) {
|
||||
// すでにIPが0Lなものを無効としてカウント
|
||||
ipBegin = ipSort;
|
||||
ipEnd = ipBegin + m_count;
|
||||
|
||||
for(; ipBegin != ipEnd && (*ipBegin)->ip64 == 0L; ++ipBegin)
|
||||
++m_countDisabled;
|
||||
if(ipBegin == ipEnd)
|
||||
goto END_SORT; // 全てのIPが0L
|
||||
|
||||
// 重複したIPは0Lにして無効としてカウント
|
||||
for(--ipEnd; ipBegin != ipEnd; ++ipBegin)
|
||||
if((*ipBegin)->ip64 == (*(ipBegin + 1))->ip64) {
|
||||
(*ipBegin)->ip64 = 0L;
|
||||
++m_countDisabled;
|
||||
}
|
||||
}
|
||||
if(sortIp) {
|
||||
// 配列の中身を連結
|
||||
ipBegin = ipSort;
|
||||
ipEnd = ipSort + m_count;
|
||||
ip = &m_ipHead;
|
||||
while(ipBegin != ipEnd) {
|
||||
ip->next = *(ipBegin++);
|
||||
ip = ip->next;
|
||||
}
|
||||
ip->next = NULL;
|
||||
}
|
||||
END_SORT:
|
||||
delete[] ipSort;
|
||||
}
|
||||
|
||||
if(sortCap)
|
||||
m_ipHead.next = Ip_SortByCaption(m_ipHead.next);
|
||||
|
||||
if(sortIp || sortCap) {
|
||||
// m_ipFootを再設定
|
||||
ip = m_ipHead.next;
|
||||
if(ip) {
|
||||
for(; ip->next; ip = ip->next);
|
||||
m_ipFoot = ip;
|
||||
} else {
|
||||
m_ipFoot = &m_ipHead;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int CIpList::Count() {
|
||||
return m_count;
|
||||
}
|
||||
|
||||
int CIpList::CountDisabled() {
|
||||
return m_countDisabled;
|
||||
}
|
||||
|
||||
} // namespace ip
|
||||
} // namespace pglu
|
Loading…
Reference in New Issue
Block a user