mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
cleaned a bit the code in rsinit.cc
This commit is contained in:
parent
7ee0b4575e
commit
370d50b41a
@ -270,304 +270,234 @@ bool doPortRestrictions = false;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS_SYS
|
||||
#ifdef PTW32_STATIC_LIB
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
#ifndef WINDOWS_SYS
|
||||
int RsInit::InitRetroShare(int argc, char **argv, bool /* strictCheck */)
|
||||
{
|
||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
#else
|
||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
#ifdef WINDOWS_SYS
|
||||
/* THIS IS A HACK TO ALLOW WINDOWS TO ACCEPT COMMANDLINE ARGUMENTS */
|
||||
|
||||
/* for static PThreads under windows... we need to init the library...
|
||||
*/
|
||||
#ifdef PTW32_STATIC_LIB
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
int argc;
|
||||
int i;
|
||||
const int MAX_ARGS = 32;
|
||||
int j;
|
||||
char *argv[MAX_ARGS];
|
||||
char *wholeline = (char*)GetCommandLine();
|
||||
int cmdlen = strlen(wholeline);
|
||||
// duplicate line, so we can put in spaces..
|
||||
char dupline[cmdlen+1];
|
||||
strcpy(dupline, wholeline);
|
||||
|
||||
int RsInit::InitRetroShare(int argcIgnored, char **argvIgnored, bool strictCheck)
|
||||
{
|
||||
|
||||
/* THIS IS A HACK TO ALLOW WINDOWS TO ACCEPT COMMANDLINE ARGUMENTS */
|
||||
int argc;
|
||||
int i;
|
||||
#ifdef USE_CMD_ARGS
|
||||
char** argv = argvIgnored;
|
||||
argc = argcIgnored;
|
||||
#else
|
||||
const int MAX_ARGS = 32;
|
||||
int j;
|
||||
char *argv[MAX_ARGS];
|
||||
char *wholeline = (char*)GetCommandLine();
|
||||
int cmdlen = strlen(wholeline);
|
||||
// duplicate line, so we can put in spaces..
|
||||
char dupline[cmdlen+1];
|
||||
strcpy(dupline, wholeline);
|
||||
|
||||
/* break wholeline down ....
|
||||
* NB. This is very simplistic, and will not
|
||||
* handle multiple spaces, or quotations etc, only for debugging purposes
|
||||
*/
|
||||
argv[0] = dupline;
|
||||
for(i = 1, j = 0; (j + 1 < cmdlen) && (i < MAX_ARGS);)
|
||||
{
|
||||
/* find next space. */
|
||||
for(;(j + 1 < cmdlen) && (dupline[j] != ' ');j++);
|
||||
if (j + 1 < cmdlen)
|
||||
{
|
||||
dupline[j] = '\0';
|
||||
argv[i++] = &(dupline[j+1]);
|
||||
}
|
||||
}
|
||||
argc = i;
|
||||
/* break wholeline down ....
|
||||
* NB. This is very simplistic, and will not
|
||||
* handle multiple spaces, or quotations etc, only for debugging purposes
|
||||
*/
|
||||
argv[0] = dupline;
|
||||
for(i = 1, j = 0; (j + 1 < cmdlen) && (i < MAX_ARGS);)
|
||||
{
|
||||
/* find next space. */
|
||||
for(;(j + 1 < cmdlen) && (dupline[j] != ' ');j++);
|
||||
if (j + 1 < cmdlen)
|
||||
{
|
||||
dupline[j] = '\0';
|
||||
argv[i++] = &(dupline[j+1]);
|
||||
}
|
||||
}
|
||||
argc = i;
|
||||
#endif
|
||||
|
||||
for( i=0; i<argc; i++)
|
||||
printf("%d: %s\n", i, argv[i]);
|
||||
for(int i=0; i<argc; i++)
|
||||
printf("%d: %s\n", i, argv[i]);
|
||||
|
||||
/* for static PThreads under windows... we need to init the library...
|
||||
*/
|
||||
#ifdef PTW32_STATIC_LIB
|
||||
pthread_win32_process_attach_np();
|
||||
#endif
|
||||
/* for static PThreads under windows... we need to init the library... */
|
||||
#ifdef PTW32_STATIC_LIB
|
||||
pthread_win32_process_attach_np();
|
||||
#endif
|
||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
|
||||
std::string prefUserString = "";
|
||||
std::string opt_base_dir;
|
||||
std::string prefUserString = "";
|
||||
std::string opt_base_dir;
|
||||
|
||||
/* getopt info: every availiable option is listed here. if it is followed by a ':' it
|
||||
needs an argument. If it is followed by a '::' the argument is optional.
|
||||
*/
|
||||
//rsInitConfig->logfname = "" ;
|
||||
//rsInitConfig->inet = "" ;
|
||||
/* getopt info: every availiable option is listed here. if it is followed by a ':' it
|
||||
needs an argument. If it is followed by a '::' the argument is optional.
|
||||
*/
|
||||
//rsInitConfig->logfname = "" ;
|
||||
//rsInitConfig->inet = "" ;
|
||||
|
||||
#ifdef __APPLE__
|
||||
/* HACK to avoid stupid OSX Finder behaviour
|
||||
* remove the commandline arguments - if we detect we are launched from Finder,
|
||||
/* HACK to avoid stupid OSX Finder behaviour
|
||||
* remove the commandline arguments - if we detect we are launched from Finder,
|
||||
* and we have the unparsable "-psn_0_12332" option.
|
||||
* this is okay, as you cannot pass commandline arguments via Finder anyway
|
||||
*/
|
||||
if ((argc >= 2) && (0 == strncmp(argv[1], "-psn", 4)))
|
||||
{
|
||||
argc = 1;
|
||||
}
|
||||
if ((argc >= 2) && (0 == strncmp(argv[1], "-psn", 4)))
|
||||
{
|
||||
argc = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
argstream as(argc,argv) ;
|
||||
argstream as(argc,argv) ;
|
||||
|
||||
|
||||
as >> option('a',"auto-login" ,rsInitConfig->autoLogin ,"AutoLogin (Windows Only) + StartMinimised")
|
||||
>> option('m',"minimized" ,rsInitConfig->startMinimised ,"Start minimized." )
|
||||
>> option('s',"stderr" ,rsInitConfig->outStderr ,"output to stderr instead of log file." )
|
||||
>> option('u',"udp" ,rsInitConfig->udpListenerOnly,"Only listen to UDP." )
|
||||
>> option('e',"external-port" ,rsInitConfig->forceExtPort ,"Use a forwarded external port." )
|
||||
as >> option('a',"auto-login" ,rsInitConfig->autoLogin ,"AutoLogin (Windows Only) + StartMinimised")
|
||||
>> option('m',"minimized" ,rsInitConfig->startMinimised ,"Start minimized." )
|
||||
>> option('s',"stderr" ,rsInitConfig->outStderr ,"output to stderr instead of log file." )
|
||||
>> option('u',"udp" ,rsInitConfig->udpListenerOnly,"Only listen to UDP." )
|
||||
>> option('e',"external-port" ,rsInitConfig->forceExtPort ,"Use a forwarded external port." )
|
||||
|
||||
>> parameter('l',"log-file" ,rsInitConfig->logfname ,"logfile" ,"Set Log filename." ,false)
|
||||
>> parameter('d',"debug-level" ,rsInitConfig->debugLevel ,"level" ,"Set debug level." ,false)
|
||||
>> parameter('w',"password" ,rsInitConfig->passwd ,"password" ,"Set Login Password." ,false)
|
||||
>> parameter('i',"ip-address" ,rsInitConfig->inet ,"nnn.nnn.nnn.nnn", "Set IP address to use." ,false)
|
||||
>> parameter('p',"port" ,rsInitConfig->port ,"port", "Set listenning port to use." ,false)
|
||||
>> parameter('c',"base-dir" ,opt_base_dir ,"directory", "Set base directory." ,false)
|
||||
>> parameter('U',"user-id" ,prefUserString ,"ID", "[User Name/GPG id/SSL id] Sets Account to Use, Useful when Autologin is enabled",false)
|
||||
// by rshare 'r' "link" "Link" "Open RsLink with protocol retroshare://"
|
||||
// by rshare 'f' "rsfile" "RsFile" "Open RsFile like RsCollection"
|
||||
>> parameter('l',"log-file" ,rsInitConfig->logfname ,"logfile" ,"Set Log filename." ,false)
|
||||
>> parameter('d',"debug-level" ,rsInitConfig->debugLevel ,"level" ,"Set debug level." ,false)
|
||||
>> parameter('w',"password" ,rsInitConfig->passwd ,"password" ,"Set Login Password." ,false)
|
||||
>> parameter('i',"ip-address" ,rsInitConfig->inet ,"nnn.nnn.nnn.nnn", "Set IP address to use." ,false)
|
||||
>> parameter('p',"port" ,rsInitConfig->port ,"port", "Set listenning port to use." ,false)
|
||||
>> parameter('c',"base-dir" ,opt_base_dir ,"directory", "Set base directory." ,false)
|
||||
>> parameter('U',"user-id" ,prefUserString ,"ID", "[User Name/GPG id/SSL id] Sets Account to Use, Useful when Autologin is enabled",false)
|
||||
// by rshare 'r' "link" "Link" "Open RsLink with protocol retroshare://"
|
||||
// by rshare 'f' "rsfile" "RsFile" "Open RsFile like RsCollection"
|
||||
#ifdef LOCALNET_TESTING
|
||||
>> parameter('R',"restrict-port" ,portRestrictions ,"port1-port2","Apply port restriction" ,false)
|
||||
#endif
|
||||
>> help('h',"help","Display this Help") ;
|
||||
|
||||
as.defaultErrorHandling(true) ;
|
||||
|
||||
if(rsInitConfig->autoLogin) rsInitConfig->startMinimised = true ;
|
||||
if(rsInitConfig->outStderr) rsInitConfig->haveLogFile = false ;
|
||||
if(!rsInitConfig->logfname.empty()) rsInitConfig->haveLogFile = true;
|
||||
if(rsInitConfig->inet != "127.0.0.1") rsInitConfig->forceLocalAddr = true;
|
||||
#ifdef LOCALNET_TESTING
|
||||
>> parameter('R',"restrict-port" ,portRestrictions ,"port1-port2","Apply port restriction" ,false)
|
||||
#endif
|
||||
>> help('h',"help","Display this Help") ;
|
||||
|
||||
as.defaultErrorHandling(true) ;
|
||||
|
||||
if(rsInitConfig->autoLogin) rsInitConfig->startMinimised = true ;
|
||||
if(rsInitConfig->outStderr) rsInitConfig->haveLogFile = false ;
|
||||
if(!rsInitConfig->logfname.empty()) rsInitConfig->haveLogFile = true;
|
||||
if(rsInitConfig->inet != "127.0.0.1") rsInitConfig->forceLocalAddr = true;
|
||||
#ifdef LOCALNET_TESTING
|
||||
if(!portRestrictions.empty()) doPortRestrictions = true;
|
||||
if(!portRestrictions.empty()) doPortRestrictions = true;
|
||||
#endif
|
||||
|
||||
#ifdef SUSPENDED_CODE
|
||||
#ifdef LOCALNET_TESTING
|
||||
while((c = getopt(argc, argv,"hesamui:p:c:w:l:d:U:r:R:")) != -1)
|
||||
#else
|
||||
while((c = getopt(argc, argv,"hesamui:p:c:w:l:d:U:r:")) != -1)
|
||||
#endif
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'h':
|
||||
std::cerr << "Help: " << std::endl;
|
||||
std::cerr << "The commandline options are for retroshare-nogui, a headless server in a shell, or systems without QT." << std::endl << std::endl;
|
||||
std::cerr << "-l [logfile] Set the logfilename" << std::endl;
|
||||
std::cerr << "-w [password] Set the password" << std::endl;
|
||||
std::cerr << "-i [ip_adress] Set IP Adress to use" << std::endl;
|
||||
std::cerr << "-p [port] Set the Port to listen on" << std::endl;
|
||||
std::cerr << "-c [basedir] Set the config basdir" << std::endl;
|
||||
std::cerr << "-s Output to Stderr" << std::endl;
|
||||
std::cerr << "-d [debuglevel] Set the debuglevel" << std::endl;
|
||||
std::cerr << "-a AutoLogin (Windows Only) + StartMinimised" << std::endl;
|
||||
std::cerr << "-m StartMinimised" << std::endl;
|
||||
std::cerr << "-u Only listen to UDP" << std::endl;
|
||||
std::cerr << "-e Use a forwarded external Port" << std::endl ;
|
||||
std::cerr << "-U [User Name/GPG id/SSL id] Sets Account to Use, Useful when Autologin is enabled." << std::endl;
|
||||
std::cerr << "-r link Use RetroShare link." << std::endl;
|
||||
#ifdef LOCALNET_TESTING
|
||||
std::cerr << "-R <lport-uport> Port Restrictions." << std::endl;
|
||||
#endif
|
||||
exit(1);
|
||||
break;
|
||||
default:
|
||||
if (strictCheck) {
|
||||
std::cerr << "Unknown Option!" << std::endl;
|
||||
std::cerr << "Use '-h' for help." << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
setOutputLevel((RsLog::logLvl)rsInitConfig->debugLevel);
|
||||
|
||||
setOutputLevel((RsLog::logLvl)rsInitConfig->debugLevel);
|
||||
// set the debug file.
|
||||
if (rsInitConfig->haveLogFile)
|
||||
setDebugFile(rsInitConfig->logfname.c_str());
|
||||
|
||||
// // set the default Debug Level...
|
||||
// if (rsInitConfig->haveDebugLevel)
|
||||
// {
|
||||
// if ((rsInitConfig->debugLevel > 0) &&
|
||||
// (rsInitConfig->debugLevel <= PQL_DEBUG_ALL))
|
||||
// {
|
||||
// std::cerr << "Setting Debug Level to: ";
|
||||
// std::cerr << rsInitConfig->debugLevel;
|
||||
// std::cerr << std::endl;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// std::cerr << "Ignoring Invalid Debug Level: ";
|
||||
// std::cerr << rsInitConfig->debugLevel;
|
||||
// std::cerr << std::endl;
|
||||
// }
|
||||
// }
|
||||
|
||||
// set the debug file.
|
||||
if (rsInitConfig->haveLogFile)
|
||||
setDebugFile(rsInitConfig->logfname.c_str());
|
||||
|
||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
#ifndef WINDOWS_SYS
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
#else
|
||||
// Windows Networking Init.
|
||||
WORD wVerReq = MAKEWORD(2,2);
|
||||
WSADATA wsaData;
|
||||
// Windows Networking Init.
|
||||
WORD wVerReq = MAKEWORD(2,2);
|
||||
WSADATA wsaData;
|
||||
|
||||
if (0 != WSAStartup(wVerReq, &wsaData))
|
||||
{
|
||||
std::cerr << "Failed to Startup Windows Networking";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Started Windows Networking";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
if (0 != WSAStartup(wVerReq, &wsaData))
|
||||
{
|
||||
std::cerr << "Failed to Startup Windows Networking";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Started Windows Networking";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
#endif
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
// SWITCH off the SIGPIPE - kills process on Linux.
|
||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
// SWITCH off the SIGPIPE - kills process on Linux.
|
||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
#ifndef WINDOWS_SYS
|
||||
struct sigaction sigact;
|
||||
sigact.sa_handler = SIG_IGN;
|
||||
sigact.sa_flags = 0;
|
||||
struct sigaction sigact;
|
||||
sigact.sa_handler = SIG_IGN;
|
||||
sigact.sa_flags = 0;
|
||||
|
||||
sigset_t set;
|
||||
sigemptyset(&set);
|
||||
//sigaddset(&set, SIGINT); // or whatever other signal
|
||||
sigact.sa_mask = set;
|
||||
sigset_t set;
|
||||
sigemptyset(&set);
|
||||
//sigaddset(&set, SIGINT); // or whatever other signal
|
||||
sigact.sa_mask = set;
|
||||
|
||||
if (0 == sigaction(SIGPIPE, &sigact, NULL))
|
||||
{
|
||||
std::cerr << "RetroShare:: Successfully installed the SIGPIPE Block" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "RetroShare:: Failed to install the SIGPIPE Block" << std::endl;
|
||||
}
|
||||
if (0 == sigaction(SIGPIPE, &sigact, NULL))
|
||||
{
|
||||
std::cerr << "RetroShare:: Successfully installed the SIGPIPE Block" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "RetroShare:: Failed to install the SIGPIPE Block" << std::endl;
|
||||
}
|
||||
#endif
|
||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
|
||||
// Hash the main executable.
|
||||
|
||||
uint64_t tmp_size ;
|
||||
// Hash the main executable.
|
||||
|
||||
if(!RsDirUtil::getFileHash(argv[0],rsInitConfig->main_executable_hash,tmp_size,NULL))
|
||||
std::cerr << "Cannot hash executable! Plugins will not be loaded correctly." << std::endl;
|
||||
else
|
||||
std::cerr << "Hashed main executable: " << rsInitConfig->main_executable_hash << std::endl;
|
||||
uint64_t tmp_size ;
|
||||
|
||||
/* At this point we want to.
|
||||
if(!RsDirUtil::getFileHash(argv[0],rsInitConfig->main_executable_hash,tmp_size,NULL))
|
||||
std::cerr << "Cannot hash executable! Plugins will not be loaded correctly." << std::endl;
|
||||
else
|
||||
std::cerr << "Hashed main executable: " << rsInitConfig->main_executable_hash << std::endl;
|
||||
|
||||
/* At this point we want to.
|
||||
* 1) Load up Dase Directory.
|
||||
* 3) Get Prefered Id.
|
||||
* 2) Get List of Available Accounts.
|
||||
* 4) Get List of GPG Accounts.
|
||||
*/
|
||||
/* create singletons */
|
||||
AuthSSL::AuthSSLInit();
|
||||
AuthSSL::getAuthSSL() -> InitAuth(NULL, NULL, NULL, "");
|
||||
/* create singletons */
|
||||
AuthSSL::AuthSSLInit();
|
||||
AuthSSL::getAuthSSL() -> InitAuth(NULL, NULL, NULL, "");
|
||||
|
||||
rsAccounts = new RsAccountsDetail();
|
||||
rsAccounts = new RsAccountsDetail();
|
||||
|
||||
// first check config directories, and set bootstrap values.
|
||||
if(!rsAccounts->setupBaseDirectory(opt_base_dir))
|
||||
return RS_INIT_BASE_DIR_ERROR ;
|
||||
// first check config directories, and set bootstrap values.
|
||||
if(!rsAccounts->setupBaseDirectory(opt_base_dir))
|
||||
return RS_INIT_BASE_DIR_ERROR ;
|
||||
|
||||
// Setup PGP stuff.
|
||||
std::string pgp_dir = rsAccounts->PathPGPDirectory();
|
||||
// Setup PGP stuff.
|
||||
std::string pgp_dir = rsAccounts->PathPGPDirectory();
|
||||
|
||||
if(!RsDirUtil::checkCreateDirectory(pgp_dir))
|
||||
throw std::runtime_error("Cannot create pgp directory " + pgp_dir) ;
|
||||
if(!RsDirUtil::checkCreateDirectory(pgp_dir))
|
||||
throw std::runtime_error("Cannot create pgp directory " + pgp_dir) ;
|
||||
|
||||
AuthGPG::init( pgp_dir + "/retroshare_public_keyring.gpg",
|
||||
pgp_dir + "/retroshare_secret_keyring.gpg",
|
||||
pgp_dir + "/retroshare_trustdb.gpg",
|
||||
pgp_dir + "/lock");
|
||||
AuthGPG::init( pgp_dir + "/retroshare_public_keyring.gpg",
|
||||
pgp_dir + "/retroshare_secret_keyring.gpg",
|
||||
pgp_dir + "/retroshare_trustdb.gpg",
|
||||
pgp_dir + "/lock");
|
||||
|
||||
// load Accounts.
|
||||
if (!rsAccounts->loadAccounts())
|
||||
{
|
||||
return RS_INIT_NO_KEYRING ;
|
||||
}
|
||||
|
||||
// choose alternative account.
|
||||
if(prefUserString != "")
|
||||
{
|
||||
if (!rsAccounts->selectAccountByString(prefUserString))
|
||||
// load Accounts.
|
||||
if (!rsAccounts->loadAccounts())
|
||||
{
|
||||
std::cerr << "Invalid User name/GPG id/SSL id: not found in list";
|
||||
std::cerr << std::endl;
|
||||
return RS_INIT_AUTH_FAILED ;
|
||||
}
|
||||
}
|
||||
|
||||
/* check that we have selected someone */
|
||||
RsPeerId preferredId;
|
||||
bool existingUser = rsAccounts->getPreferredAccountId(preferredId);
|
||||
|
||||
if (existingUser)
|
||||
{
|
||||
if (rsInitConfig->passwd != "")
|
||||
{
|
||||
return RS_INIT_HAVE_ACCOUNT;
|
||||
return RS_INIT_NO_KEYRING ;
|
||||
}
|
||||
|
||||
if(RsLoginHandler::getSSLPassword(preferredId,false,rsInitConfig->passwd))
|
||||
// choose alternative account.
|
||||
if(prefUserString != "")
|
||||
{
|
||||
RsInit::setAutoLogin(true);
|
||||
std::cerr << "Autologin has succeeded" << std::endl;
|
||||
return RS_INIT_HAVE_ACCOUNT;
|
||||
if (!rsAccounts->selectAccountByString(prefUserString))
|
||||
{
|
||||
std::cerr << "Invalid User name/GPG id/SSL id: not found in list";
|
||||
std::cerr << std::endl;
|
||||
return RS_INIT_AUTH_FAILED ;
|
||||
}
|
||||
}
|
||||
|
||||
/* check that we have selected someone */
|
||||
RsPeerId preferredId;
|
||||
bool existingUser = rsAccounts->getPreferredAccountId(preferredId);
|
||||
|
||||
if (existingUser)
|
||||
{
|
||||
if (rsInitConfig->passwd != "")
|
||||
{
|
||||
return RS_INIT_HAVE_ACCOUNT;
|
||||
}
|
||||
|
||||
if(RsLoginHandler::getSSLPassword(preferredId,false,rsInitConfig->passwd))
|
||||
{
|
||||
RsInit::setAutoLogin(true);
|
||||
std::cerr << "Autologin has succeeded" << std::endl;
|
||||
return RS_INIT_HAVE_ACCOUNT;
|
||||
}
|
||||
}
|
||||
return RS_INIT_OK;
|
||||
}
|
||||
return RS_INIT_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user