mirror of https://github.com/BOINC/boinc.git
no proxy for ... support included
svn path=/workspaces/fweiler/boinc/; revision=16055
This commit is contained in:
parent
e2b48b6b34
commit
2a3e79a53d
|
@ -38,7 +38,7 @@
|
|||
#include "util.h"
|
||||
#include "error_numbers.h"
|
||||
#include "filesys.h"
|
||||
#include "proc_control.h"
|
||||
//#include "proc_control.h"
|
||||
|
||||
#include "file_names.h"
|
||||
#include "hostinfo.h"
|
||||
|
|
|
@ -250,6 +250,41 @@ int HTTP_OP::init_post2(
|
|||
return HTTP_OP::libcurl_exec(url, in, NULL, offset, true);
|
||||
}
|
||||
|
||||
//FW
|
||||
// returns 1, if url-host is defined in proxy exception list
|
||||
int HTTP_OP::noProxyForUrl(const char* url) {
|
||||
if (log_flags.proxy_debug) {
|
||||
msg_printf(0, MSG_INFO, "[proxy_debug] HTTP_OP::noProxyForUrl(): %s", url);
|
||||
}
|
||||
char hosturl[256];
|
||||
char hostnoproxy[256];
|
||||
char file[256];
|
||||
char noproxy[256];
|
||||
int port;
|
||||
//extracting the host from the url
|
||||
parse_url(url,hosturl,port,file);
|
||||
//tokenize the noproxy-entry and check for identical hosts
|
||||
strcpy(noproxy,pi.noproxy_hosts);
|
||||
char* token = strtok(noproxy,",");
|
||||
while(token!= NULL) {
|
||||
//extracting the host from the no_proxy url
|
||||
parse_url(token,hostnoproxy,port,file);
|
||||
if(strcmp(hostnoproxy,hosturl)==0) {
|
||||
if (log_flags.proxy_debug) {
|
||||
msg_printf(0, MSG_INFO, "[proxy_debug] disabling proxy for %s",url);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
//
|
||||
token = strtok(NULL,",");
|
||||
}
|
||||
if (log_flags.proxy_debug) {
|
||||
msg_printf(0, MSG_INFO, "[proxy_debug] returning with 0");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//FW
|
||||
|
||||
// the following will do an HTTP GET or POST using libcurl
|
||||
//
|
||||
int HTTP_OP::libcurl_exec(
|
||||
|
@ -411,10 +446,12 @@ int HTTP_OP::libcurl_exec(
|
|||
if (!out || !ends_with(std::string(out), std::string(".gz"))) {
|
||||
curlErr = curl_easy_setopt(curlEasy, CURLOPT_ENCODING, "");
|
||||
}
|
||||
|
||||
// setup any proxy they may need
|
||||
|
||||
// setup any proxy they may need
|
||||
//
|
||||
setupProxyCurl();
|
||||
//FW
|
||||
setupProxyCurl(noProxyForUrl(url));
|
||||
//FW
|
||||
|
||||
// set the content type in the header
|
||||
//
|
||||
|
@ -612,6 +649,9 @@ int HTTP_OP::set_proxy(PROXY_INFO *new_pi) {
|
|||
strcpy(pi.http_server_name, new_pi->http_server_name);
|
||||
pi.http_server_port = new_pi->http_server_port;
|
||||
pi.use_http_auth = new_pi->use_http_auth;
|
||||
//FW
|
||||
strcpy(pi.noproxy_hosts,new_pi->noproxy_hosts);
|
||||
//FW
|
||||
|
||||
pi.use_socks_proxy = new_pi->use_socks_proxy;
|
||||
strcpy(pi.socks5_user_name, new_pi->socks5_user_name);
|
||||
|
@ -761,7 +801,7 @@ int libcurl_debugfunction(
|
|||
}
|
||||
|
||||
|
||||
void HTTP_OP::setupProxyCurl() {
|
||||
void HTTP_OP::setupProxyCurl(int noProxyOnce) {
|
||||
// PROXY_INFO pi useful members:
|
||||
// pi.http_server_name
|
||||
// pi.http_server_port
|
||||
|
@ -793,7 +833,17 @@ void HTTP_OP::setupProxyCurl() {
|
|||
// the proxy connection), so it has been placed as a member data for HTTP_OP
|
||||
memset(szCurlProxyUserPwd,0x00,128);
|
||||
|
||||
if (pi.use_http_proxy) {
|
||||
//FW
|
||||
//disabling proxy usage once
|
||||
if(noProxyOnce) {
|
||||
curlErr = curl_easy_setopt(curlEasy,CURLOPT_PROXY,"");
|
||||
return;
|
||||
}
|
||||
//FW
|
||||
if (pi.use_http_proxy) {
|
||||
if (log_flags.proxy_debug) {
|
||||
msg_printf(0, MSG_INFO,"[proxy_debug]: setting up proxy %s:%d",pi.http_server_name,pi.http_server_port);
|
||||
}
|
||||
// setup a basic http proxy
|
||||
curlErr = curl_easy_setopt(curlEasy, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
|
||||
curlErr = curl_easy_setopt(curlEasy, CURLOPT_PROXYPORT, (long) pi.http_server_port);
|
||||
|
|
|
@ -136,7 +136,9 @@ public:
|
|||
);
|
||||
bool http_op_done();
|
||||
int set_proxy(PROXY_INFO *new_pi);
|
||||
void setupProxyCurl();
|
||||
void setupProxyCurl(int noProxyOnce);
|
||||
//
|
||||
int noProxyForUrl(const char* url);
|
||||
bool is_active() {
|
||||
return curlEasy!=NULL;
|
||||
}
|
||||
|
|
|
@ -1512,7 +1512,9 @@ void CAdvancedFrame::OnOptionsOptions(wxCommandEvent& WXUNUSED(event)) {
|
|||
dlg.m_HTTPAddressCtrl->SetValue(wxString(pDoc->proxy_info.http_server_name.c_str(), wxConvUTF8));
|
||||
dlg.m_HTTPUsernameCtrl->SetValue(wxString(pDoc->proxy_info.http_user_name.c_str(), wxConvUTF8));
|
||||
dlg.m_HTTPPasswordCtrl->SetValue(wxString(pDoc->proxy_info.http_user_passwd.c_str(), wxConvUTF8));
|
||||
|
||||
//FW
|
||||
dlg.m_HTTPNoProxiesCtrl->SetValue(wxString(pDoc->proxy_info.noproxy_hosts.c_str(), wxConvUTF8));
|
||||
//FW
|
||||
strBuffer.Printf(wxT("%d"), pDoc->proxy_info.http_server_port);
|
||||
dlg.m_HTTPPortCtrl->SetValue(strBuffer);
|
||||
|
||||
|
@ -1520,7 +1522,9 @@ void CAdvancedFrame::OnOptionsOptions(wxCommandEvent& WXUNUSED(event)) {
|
|||
dlg.m_SOCKSAddressCtrl->SetValue(wxString(pDoc->proxy_info.socks_server_name.c_str(), wxConvUTF8));
|
||||
dlg.m_SOCKSUsernameCtrl->SetValue(wxString(pDoc->proxy_info.socks5_user_name.c_str(), wxConvUTF8));
|
||||
dlg.m_SOCKSPasswordCtrl->SetValue(wxString(pDoc->proxy_info.socks5_user_passwd.c_str(), wxConvUTF8));
|
||||
|
||||
//FW
|
||||
dlg.m_SOCKSNoProxiesCtrl->SetValue(wxString(pDoc->proxy_info.noproxy_hosts.c_str(),wxConvUTF8));
|
||||
//FW
|
||||
strBuffer.Printf(wxT("%d"), pDoc->proxy_info.socks_server_port);
|
||||
dlg.m_SOCKSPortCtrl->SetValue(strBuffer);
|
||||
|
||||
|
@ -1566,7 +1570,11 @@ void CAdvancedFrame::OnOptionsOptions(wxCommandEvent& WXUNUSED(event)) {
|
|||
pDoc->proxy_info.http_server_name = (const char*)dlg.m_HTTPAddressCtrl->GetValue().mb_str();
|
||||
pDoc->proxy_info.http_user_name = (const char*)dlg.m_HTTPUsernameCtrl->GetValue().mb_str();
|
||||
pDoc->proxy_info.http_user_passwd = (const char*)dlg.m_HTTPPasswordCtrl->GetValue().mb_str();
|
||||
|
||||
//FW
|
||||
if(pDoc->proxy_info.use_http_proxy) {
|
||||
pDoc->proxy_info.noproxy_hosts = (const char*)dlg.m_HTTPNoProxiesCtrl->GetValue().mb_str();
|
||||
}
|
||||
//FW
|
||||
strBuffer = dlg.m_HTTPPortCtrl->GetValue();
|
||||
strBuffer.ToLong((long*)&iBuffer);
|
||||
pDoc->proxy_info.http_server_port = iBuffer;
|
||||
|
@ -1575,7 +1583,11 @@ void CAdvancedFrame::OnOptionsOptions(wxCommandEvent& WXUNUSED(event)) {
|
|||
pDoc->proxy_info.socks_server_name = (const char*)dlg.m_SOCKSAddressCtrl->GetValue().mb_str();
|
||||
pDoc->proxy_info.socks5_user_name = (const char*)dlg.m_SOCKSUsernameCtrl->GetValue().mb_str();
|
||||
pDoc->proxy_info.socks5_user_passwd = (const char*)dlg.m_SOCKSPasswordCtrl->GetValue().mb_str();
|
||||
|
||||
//FW
|
||||
if(pDoc->proxy_info.use_socks_proxy) {
|
||||
pDoc->proxy_info.noproxy_hosts = (const char*)dlg.m_SOCKSNoProxiesCtrl->GetValue().mb_str();
|
||||
}
|
||||
//FW
|
||||
strBuffer = dlg.m_SOCKSPortCtrl->GetValue();
|
||||
strBuffer.ToLong((long*)&iBuffer);
|
||||
pDoc->proxy_info.socks_server_port = iBuffer;
|
||||
|
|
|
@ -103,6 +103,10 @@ bool CDlgOptions::Create(wxWindow* parent, wxWindowID id, const wxString& captio
|
|||
m_SOCKSPortCtrl = NULL;
|
||||
m_SOCKSUsernameCtrl = NULL;
|
||||
m_SOCKSPasswordCtrl = NULL;
|
||||
//FW
|
||||
m_HTTPNoProxiesCtrl = NULL;
|
||||
m_SOCKSNoProxiesCtrl = NULL;
|
||||
//
|
||||
////@end CDlgOptions member initialisation
|
||||
|
||||
wxString strCaption = caption;
|
||||
|
@ -252,6 +256,16 @@ void CDlgOptions::CreateControls()
|
|||
m_HTTPPortCtrl->Create( itemPanel27, ID_HTTPPORTCTRL, _T(""), wxDefaultPosition, wxSize(50, -1), 0 );
|
||||
itemFlexGridSizer32->Add(m_HTTPPortCtrl, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
|
||||
|
||||
//FW
|
||||
wxStaticText* itemStaticText62 = new wxStaticText;
|
||||
itemStaticText62->Create( itemPanel27, wxID_STATIC, _("no proxy for:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
itemFlexGridSizer32->Add(itemStaticText62, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
|
||||
|
||||
m_HTTPNoProxiesCtrl = new wxTextCtrl;
|
||||
m_HTTPNoProxiesCtrl->Create(itemPanel27,ID_HTTPNOPROXYCTRL,_T(""),wxDefaultPosition,wxSize(150,-1),0);
|
||||
itemFlexGridSizer32->Add(m_HTTPNoProxiesCtrl,0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
|
||||
//FW
|
||||
|
||||
wxStaticBox* itemStaticBoxSizer37Static = new wxStaticBox(itemPanel27, wxID_ANY, _("Leave these blank if not needed"));
|
||||
wxStaticBoxSizer* itemStaticBoxSizer37 = new wxStaticBoxSizer(itemStaticBoxSizer37Static, wxVERTICAL);
|
||||
itemStaticBoxSizer30->Add(itemStaticBoxSizer37, 0, wxGROW|wxALL, 5);
|
||||
|
@ -308,6 +322,16 @@ void CDlgOptions::CreateControls()
|
|||
m_SOCKSPortCtrl->Create( itemPanel43, ID_SOCKSPORTCTRL, _T(""), wxDefaultPosition, wxSize(50, -1), 0 );
|
||||
itemFlexGridSizer48->Add(m_SOCKSPortCtrl, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
|
||||
|
||||
//FW
|
||||
wxStaticText* itemStaticText63 = new wxStaticText;
|
||||
itemStaticText63->Create( itemPanel43, wxID_STATIC, _("no proxy for:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
itemFlexGridSizer48->Add(itemStaticText63, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
|
||||
|
||||
m_SOCKSNoProxiesCtrl = new wxTextCtrl;
|
||||
m_SOCKSNoProxiesCtrl->Create(itemPanel43,ID_SOCKSNOPROXYCTRL,_T(""),wxDefaultPosition,wxSize(150,-1),0);
|
||||
itemFlexGridSizer48->Add(m_SOCKSNoProxiesCtrl,0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
|
||||
//FW
|
||||
|
||||
wxStaticBox* itemStaticBoxSizer53Static = new wxStaticBox(itemPanel43, wxID_ANY, _("Leave these blank if not needed"));
|
||||
wxStaticBoxSizer* itemStaticBoxSizer53 = new wxStaticBoxSizer(itemStaticBoxSizer53Static, wxVERTICAL);
|
||||
itemStaticBoxSizer46->Add(itemStaticBoxSizer53, 0, wxGROW|wxALL, 5);
|
||||
|
@ -400,11 +424,17 @@ void CDlgOptions::OnEnableHTTPProxyCtrlClick(wxCommandEvent& event) {
|
|||
m_HTTPPortCtrl->Enable(true);
|
||||
m_HTTPUsernameCtrl->Enable(true);
|
||||
m_HTTPPasswordCtrl->Enable(true);
|
||||
//FW
|
||||
m_HTTPNoProxiesCtrl->Enable(true);
|
||||
//FW
|
||||
} else {
|
||||
m_HTTPAddressCtrl->Enable(false);
|
||||
m_HTTPPortCtrl->Enable(false);
|
||||
m_HTTPUsernameCtrl->Enable(false);
|
||||
m_HTTPPasswordCtrl->Enable(false);
|
||||
//FW
|
||||
m_HTTPNoProxiesCtrl->Enable(false);
|
||||
//FW
|
||||
}
|
||||
|
||||
event.Skip();
|
||||
|
@ -421,11 +451,17 @@ void CDlgOptions::OnEnableHTTPProxyCtrlUpdate(wxUpdateUIEvent& event) {
|
|||
m_HTTPPortCtrl->Enable(true);
|
||||
m_HTTPUsernameCtrl->Enable(true);
|
||||
m_HTTPPasswordCtrl->Enable(true);
|
||||
//FW
|
||||
m_HTTPNoProxiesCtrl->Enable(true);
|
||||
//FW
|
||||
} else {
|
||||
m_HTTPAddressCtrl->Enable(false);
|
||||
m_HTTPPortCtrl->Enable(false);
|
||||
m_HTTPUsernameCtrl->Enable(false);
|
||||
m_HTTPPasswordCtrl->Enable(false);
|
||||
//FW
|
||||
m_HTTPNoProxiesCtrl->Enable(false);
|
||||
//FW
|
||||
}
|
||||
event.Skip();
|
||||
}
|
||||
|
@ -441,11 +477,17 @@ void CDlgOptions::OnEnableSOCKSProxyCtrlClick(wxCommandEvent& event) {
|
|||
m_SOCKSPortCtrl->Enable(true);
|
||||
m_SOCKSUsernameCtrl->Enable(true);
|
||||
m_SOCKSPasswordCtrl->Enable(true);
|
||||
//FW
|
||||
m_SOCKSNoProxiesCtrl->Enable(true);
|
||||
//FW
|
||||
} else {
|
||||
m_SOCKSAddressCtrl->Enable(false);
|
||||
m_SOCKSPortCtrl->Enable(false);
|
||||
m_SOCKSUsernameCtrl->Enable(false);
|
||||
m_SOCKSPasswordCtrl->Enable(false);
|
||||
//FW
|
||||
m_SOCKSNoProxiesCtrl->Enable(false);
|
||||
//FW
|
||||
}
|
||||
event.Skip();
|
||||
}
|
||||
|
@ -461,11 +503,17 @@ void CDlgOptions::OnEnableSOCKSProxyCtrlUpdate(wxUpdateUIEvent& event) {
|
|||
m_SOCKSPortCtrl->Enable(true);
|
||||
m_SOCKSUsernameCtrl->Enable(true);
|
||||
m_SOCKSPasswordCtrl->Enable(true);
|
||||
//FW
|
||||
m_SOCKSNoProxiesCtrl->Enable(true);
|
||||
//FW
|
||||
} else {
|
||||
m_SOCKSAddressCtrl->Enable(false);
|
||||
m_SOCKSPortCtrl->Enable(false);
|
||||
m_SOCKSUsernameCtrl->Enable(false);
|
||||
m_SOCKSPasswordCtrl->Enable(false);
|
||||
//FW
|
||||
m_SOCKSNoProxiesCtrl->Enable(false);
|
||||
//FW
|
||||
}
|
||||
event.Skip();
|
||||
}
|
||||
|
|
|
@ -74,6 +74,10 @@
|
|||
#define ID_SOCKSPORTCTRL 10014
|
||||
#define ID_SOCKSUSERNAMECTRL 10015
|
||||
#define ID_SOCKSPASSWORDCTRL 10016
|
||||
//FW
|
||||
#define ID_HTTPNOPROXYCTRL 10017
|
||||
#define ID_SOCKSNOPROXYCTRL 10018
|
||||
//FW
|
||||
////@end control identifiers
|
||||
|
||||
/*!
|
||||
|
@ -169,6 +173,10 @@ public:
|
|||
wxTextCtrl* m_SOCKSPortCtrl;
|
||||
wxTextCtrl* m_SOCKSUsernameCtrl;
|
||||
wxTextCtrl* m_SOCKSPasswordCtrl;
|
||||
//FW
|
||||
wxTextCtrl* m_HTTPNoProxiesCtrl;
|
||||
wxTextCtrl* m_SOCKSNoProxiesCtrl;
|
||||
//FW
|
||||
////@end CDlgOptions member variables
|
||||
};
|
||||
|
||||
|
|
|
@ -290,6 +290,9 @@ public:
|
|||
std::string http_user_passwd;
|
||||
std::string socks5_user_name;
|
||||
std::string socks5_user_passwd;
|
||||
//FW
|
||||
std::string noproxy_hosts;
|
||||
//FW
|
||||
|
||||
GR_PROXY_INFO();
|
||||
~GR_PROXY_INFO();
|
||||
|
|
|
@ -542,6 +542,7 @@ GR_PROXY_INFO::~GR_PROXY_INFO() {
|
|||
|
||||
int GR_PROXY_INFO::parse(MIOFILE& in) {
|
||||
char buf[4096];
|
||||
std::string noproxy;
|
||||
use_http_proxy = false;
|
||||
use_socks_proxy = false;
|
||||
use_http_authentication = false;
|
||||
|
@ -559,6 +560,9 @@ int GR_PROXY_INFO::parse(MIOFILE& in) {
|
|||
if (parse_bool(buf, "use_http_proxy", use_http_proxy)) continue;
|
||||
if (parse_bool(buf, "use_socks_proxy", use_socks_proxy)) continue;
|
||||
if (parse_bool(buf, "use_http_auth", use_http_authentication)) continue;
|
||||
//FW
|
||||
if (parse_str(buf, "<no_proxy>", noproxy_hosts)) continue;
|
||||
//FW
|
||||
}
|
||||
return ERR_XML_PARSE;
|
||||
}
|
||||
|
@ -576,6 +580,9 @@ void GR_PROXY_INFO::clear() {
|
|||
http_user_passwd.clear();
|
||||
socks5_user_name.clear();
|
||||
socks5_user_passwd.clear();
|
||||
//FW
|
||||
noproxy_hosts.clear();
|
||||
//
|
||||
}
|
||||
|
||||
CC_STATE::CC_STATE() {
|
||||
|
@ -1712,7 +1719,8 @@ int RPC_CLIENT::set_proxy_settings(GR_PROXY_INFO& pi) {
|
|||
" <socks_server_port>%d</socks_server_port>\n"
|
||||
" <socks_version>%d</socks_version>\n"
|
||||
" <socks5_user_name>%s</socks5_user_name>\n"
|
||||
" <socks5_user_passwd>%s</socks5_user_passwd>\n"
|
||||
" <socks5_user_passwd>%s</socks5_user_passwd>\n"
|
||||
" <no_proxy>%s%</no_proxy\n"
|
||||
" </proxy_info>\n"
|
||||
"</set_proxy_settings>\n",
|
||||
pi.use_http_proxy?" <use_http_proxy/>\n":"",
|
||||
|
@ -1726,7 +1734,8 @@ int RPC_CLIENT::set_proxy_settings(GR_PROXY_INFO& pi) {
|
|||
pi.socks_server_port,
|
||||
pi.socks_version,
|
||||
pi.socks5_user_name.c_str(),
|
||||
pi.socks5_user_passwd.c_str()
|
||||
pi.socks5_user_passwd.c_str(),
|
||||
pi.noproxy_hosts.c_str()
|
||||
);
|
||||
retval = rpc.do_rpc(buf);
|
||||
return retval;
|
||||
|
|
|
@ -50,6 +50,9 @@ int PROXY_INFO::parse(MIOFILE& in) {
|
|||
else if (parse_str(buf, "<socks5_user_passwd>", socks5_user_passwd,sizeof(socks5_user_passwd))) continue;
|
||||
else if (parse_str(buf, "<http_user_name>", http_user_name,sizeof(http_user_name))) continue;
|
||||
else if (parse_str(buf, "<http_user_passwd>", http_user_passwd,sizeof(http_user_passwd))) continue;
|
||||
//FW
|
||||
else if (parse_str(buf, "<no_proxy>",noproxy_hosts,sizeof(noproxy_hosts))) continue;
|
||||
//FW
|
||||
}
|
||||
return ERR_XML_PARSE;
|
||||
}
|
||||
|
@ -74,7 +77,8 @@ int PROXY_INFO::write(MIOFILE& out) {
|
|||
" <socks5_user_passwd>%s</socks5_user_passwd>\n"
|
||||
" <http_user_name>%s</http_user_name>\n"
|
||||
" <http_user_passwd>%s</http_user_passwd>\n"
|
||||
"</proxy_info>\n",
|
||||
" <no_proxy>%s</no_proxy>\n"
|
||||
"</proxy_info>\n",
|
||||
use_http_proxy?" <use_http_proxy/>\n":"",
|
||||
use_socks_proxy?" <use_socks_proxy/>\n":"",
|
||||
use_http_auth?" <use_http_auth/>\n":"",
|
||||
|
@ -86,7 +90,8 @@ int PROXY_INFO::write(MIOFILE& out) {
|
|||
s5un,
|
||||
s5up,
|
||||
hun,
|
||||
hup
|
||||
hup,
|
||||
noproxy_hosts
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
@ -104,6 +109,9 @@ void PROXY_INFO::clear() {
|
|||
strcpy(http_user_name, "");
|
||||
strcpy(http_user_passwd, "");
|
||||
socks_version = 0;
|
||||
//FW
|
||||
strcpy(noproxy_hosts, "");
|
||||
//FW
|
||||
}
|
||||
|
||||
const char *BOINC_RCSID_af13db88e5 = "$Id$";
|
||||
|
|
|
@ -32,8 +32,10 @@ struct PROXY_INFO {
|
|||
char http_user_name[256];
|
||||
char http_user_passwd[256];
|
||||
char socks5_user_name[256];
|
||||
char socks5_user_passwd[256];
|
||||
|
||||
char socks5_user_passwd[256];
|
||||
//FW
|
||||
char noproxy_hosts[256];
|
||||
//FW
|
||||
int parse(MIOFILE&);
|
||||
int write(MIOFILE&);
|
||||
void clear();
|
||||
|
|
Loading…
Reference in New Issue