|
|
@ -34,14 +34,13 @@ namespace client |
|
|
|
// TODO: this is actually proxy class
|
|
|
|
// TODO: this is actually proxy class
|
|
|
|
class AddressBookFilesystemStorage: public AddressBookStorage |
|
|
|
class AddressBookFilesystemStorage: public AddressBookStorage |
|
|
|
{ |
|
|
|
{ |
|
|
|
private: |
|
|
|
|
|
|
|
i2p::fs::HashedStorage storage; |
|
|
|
|
|
|
|
std::string etagsPath, indexPath, localPath; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public: |
|
|
|
public: |
|
|
|
|
|
|
|
|
|
|
|
AddressBookFilesystemStorage (): storage("addressbook", "b", "", "b32") |
|
|
|
AddressBookFilesystemStorage (): storage("addressbook", "b", "", "b32") |
|
|
|
{ |
|
|
|
{ |
|
|
|
i2p::config::GetOption("persist.addressbook", m_IsPersist); |
|
|
|
i2p::config::GetOption("persist.addressbook", m_IsPersist); |
|
|
|
|
|
|
|
if (m_IsPersist) |
|
|
|
|
|
|
|
i2p::config::GetOption("addressbook.hostsfile", m_HostsFile); |
|
|
|
} |
|
|
|
} |
|
|
|
std::shared_ptr<const i2p::data::IdentityEx> GetAddress (const i2p::data::IdentHash& ident) const; |
|
|
|
std::shared_ptr<const i2p::data::IdentityEx> GetAddress (const i2p::data::IdentHash& ident) const; |
|
|
|
void AddAddress (std::shared_ptr<const i2p::data::IdentityEx> address); |
|
|
|
void AddAddress (std::shared_ptr<const i2p::data::IdentityEx> address); |
|
|
@ -62,7 +61,10 @@ namespace client |
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
private: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
i2p::fs::HashedStorage storage; |
|
|
|
|
|
|
|
std::string etagsPath, indexPath, localPath; |
|
|
|
bool m_IsPersist; |
|
|
|
bool m_IsPersist; |
|
|
|
|
|
|
|
std::string m_HostsFile; // file to dump hosts.txt, empty if not used
|
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
bool AddressBookFilesystemStorage::Init() |
|
|
|
bool AddressBookFilesystemStorage::Init() |
|
|
@ -183,35 +185,59 @@ namespace client |
|
|
|
|
|
|
|
|
|
|
|
int AddressBookFilesystemStorage::Save (const std::map<std::string, std::shared_ptr<Address> >& addresses) |
|
|
|
int AddressBookFilesystemStorage::Save (const std::map<std::string, std::shared_ptr<Address> >& addresses) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (addresses.empty()) { |
|
|
|
if (addresses.empty()) |
|
|
|
|
|
|
|
{ |
|
|
|
LogPrint(eLogWarning, "Addressbook: not saving empty addressbook"); |
|
|
|
LogPrint(eLogWarning, "Addressbook: not saving empty addressbook"); |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int num = 0; |
|
|
|
int num = 0; |
|
|
|
std::ofstream f (indexPath, std::ofstream::out); // in text mode
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!f.is_open ()) { |
|
|
|
|
|
|
|
LogPrint (eLogWarning, "Addressbook: Can't open ", indexPath); |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (const auto& it: addresses) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
if (it.second->IsValid ()) |
|
|
|
// save index file
|
|
|
|
{ |
|
|
|
std::ofstream f (indexPath, std::ofstream::out); // in text mode
|
|
|
|
f << it.first << ","; |
|
|
|
if (f.is_open ()) |
|
|
|
if (it.second->IsIdentHash ()) |
|
|
|
{ |
|
|
|
f << it.second->identHash.ToBase32 (); |
|
|
|
for (const auto& it: addresses) |
|
|
|
else |
|
|
|
{ |
|
|
|
f << it.second->blindedPublicKey->ToB33 (); |
|
|
|
if (it.second->IsValid ()) |
|
|
|
f << std::endl; |
|
|
|
{ |
|
|
|
num++; |
|
|
|
f << it.first << ","; |
|
|
|
|
|
|
|
if (it.second->IsIdentHash ()) |
|
|
|
|
|
|
|
f << it.second->identHash.ToBase32 (); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
f << it.second->blindedPublicKey->ToB33 (); |
|
|
|
|
|
|
|
f << std::endl; |
|
|
|
|
|
|
|
num++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
LogPrint (eLogWarning, "Addressbook: invalid address ", it.first); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
LogPrint (eLogInfo, "Addressbook: ", num, " addresses saved"); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
LogPrint (eLogWarning, "Addressbook: invalid address ", it.first); |
|
|
|
LogPrint (eLogWarning, "Addressbook: Can't open ", indexPath); |
|
|
|
} |
|
|
|
} |
|
|
|
LogPrint (eLogInfo, "Addressbook: ", num, " addresses saved"); |
|
|
|
if (!m_HostsFile.empty ()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// dump full hosts.txt
|
|
|
|
|
|
|
|
std::ofstream f (m_HostsFile, std::ofstream::out); // in text mode
|
|
|
|
|
|
|
|
if (f.is_open ()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
for (const auto& it: addresses) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
std::shared_ptr<const i2p::data::IdentityEx> addr; |
|
|
|
|
|
|
|
if (it.second->IsIdentHash ()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
addr = GetAddress (it.second->identHash); |
|
|
|
|
|
|
|
if (addr) |
|
|
|
|
|
|
|
f << it.first << "=" << addr->ToBase64 () << std::endl; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
LogPrint (eLogWarning, "Addressbook: Can't open ", m_HostsFile); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return num; |
|
|
|
return num; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -494,7 +520,7 @@ namespace client |
|
|
|
while (!f.eof ()) |
|
|
|
while (!f.eof ()) |
|
|
|
{ |
|
|
|
{ |
|
|
|
getline(f, s); |
|
|
|
getline(f, s); |
|
|
|
if (!s.length()) continue; // skip empty line
|
|
|
|
if (s.empty () || s[0] == '#') continue; // skip empty line or comment
|
|
|
|
m_Subscriptions.push_back (std::make_shared<AddressBookSubscription> (*this, s)); |
|
|
|
m_Subscriptions.push_back (std::make_shared<AddressBookSubscription> (*this, s)); |
|
|
|
} |
|
|
|
} |
|
|
|
LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded"); |
|
|
|
LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded"); |
|
|
@ -507,9 +533,10 @@ namespace client |
|
|
|
std::vector<std::string> subsList; |
|
|
|
std::vector<std::string> subsList; |
|
|
|
boost::split(subsList, subscriptionURLs, boost::is_any_of(","), boost::token_compress_on); |
|
|
|
boost::split(subsList, subscriptionURLs, boost::is_any_of(","), boost::token_compress_on); |
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < subsList.size (); i++) |
|
|
|
for (const auto& s: subsList) |
|
|
|
{ |
|
|
|
{ |
|
|
|
m_Subscriptions.push_back (std::make_shared<AddressBookSubscription> (*this, subsList[i])); |
|
|
|
if (s.empty () || s[0] == '#') continue; // skip empty line or comment
|
|
|
|
|
|
|
|
m_Subscriptions.push_back (std::make_shared<AddressBookSubscription> (*this, s)); |
|
|
|
} |
|
|
|
} |
|
|
|
LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded"); |
|
|
|
LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded"); |
|
|
|
} |
|
|
|
} |
|
|
|