2
0
mirror of https://github.com/meganz/MEGAcmd synced 2025-08-22 18:07:09 +00:00
MEGAcmd/src/megacmd_server_main.cpp

211 lines
5.6 KiB
C++
Raw Normal View History

/**
* (c) 2013 by Mega Limited, Auckland, New Zealand
*
* This file is part of MEGAcmd.
*
* MEGAcmd is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* @copyright Simplified (2-clause) BSD License.
*
* You should have received a copy of the license along with this
* program.
*/
#include "megacmd.h"
#include "megaapi.h"
#include "megacmdlogger.h"
#include "megacmd_rotating_logger.h"
#include "configurationmanager.h"
#include <vector>
using std::vector;
bool extractarg(vector<const char*>& args, const char *what)
{
for (int i = int(args.size()); i--; )
{
if (!strcmp(args[i], what))
{
args.erase(args.begin() + i);
return true;
}
}
return false;
}
bool extractargparam(vector<const char*>& args, const char *what, std::string& param)
{
for (int i = int(args.size()) - 1; --i >= 0; )
{
if (!strcmp(args[i], what) && args.size() > i)
{
param = args[i + 1];
args.erase(args.begin() + i, args.begin() + i + 2);
return true;
}
}
return false;
}
std::pair<int/*sdk*/, int/*cmd*/> getLogLevels(std::vector<const char*>& args)
{
using mega::MegaApi;
using megacmd::ConfigurationManager;
#ifndef DEBUG
constexpr int defaultSdkLogLevel = (int) MegaApi::LOG_LEVEL_ERROR;
#else
constexpr int defaultSdkLogLevel = (int) MegaApi::LOG_LEVEL_DEBUG;
#endif
constexpr int defaultCmdLogLevel = (int) MegaApi::LOG_LEVEL_DEBUG;
int sdkLogLevel = ConfigurationManager::getConfigurationValue("sdkLogLevel", defaultSdkLogLevel);
int cmdLogLevel = ConfigurationManager::getConfigurationValue("cmdLogLevel", defaultCmdLogLevel);
bool debug = extractarg(args, "--debug");
bool debugfull = extractarg(args, "--debug-full");
bool verbose = extractarg(args, "--verbose");
bool verbosefull = extractarg(args, "--verbose-full");
const char *envCmdLogLevel = getenv("MEGACMD_LOGLEVEL");
if (envCmdLogLevel)
{
std::string loglevelenv(envCmdLogLevel);
debug |= !loglevelenv.compare("DEBUG");
debugfull |= !loglevelenv.compare("FULLDEBUG");
verbose |= !loglevelenv.compare("VERBOSE");
verbosefull |= !loglevelenv.compare("FULLVERBOSE");
}
if (debug)
{
cmdLogLevel = MegaApi::LOG_LEVEL_DEBUG;
}
if (debugfull)
{
sdkLogLevel = MegaApi::LOG_LEVEL_DEBUG;
cmdLogLevel = MegaApi::LOG_LEVEL_DEBUG;
}
if (verbose)
{
cmdLogLevel = MegaApi::LOG_LEVEL_MAX;
}
if (verbosefull)
{
sdkLogLevel = MegaApi::LOG_LEVEL_MAX;
cmdLogLevel = MegaApi::LOG_LEVEL_MAX;
}
return {sdkLogLevel, cmdLogLevel};
}
#ifdef _WIN32
// returns true if attempted to uninstall
bool mayUninstall(std::vector<const char*> &args)
{
bool buninstall = extractarg(args, "--uninstall") || extractarg(args, "/uninstall");
if (buninstall)
{
megacmd::uninstall();
return true;
}
return false;
}
#endif
#ifndef _WIN32
#include <sys/wait.h>
static bool is_pid_running(pid_t pid) {
while(waitpid(-1, 0, WNOHANG) > 0) {
// Wait for defunct....
}
if (0 == kill(pid, 0))
{
return true; // Process exists
}
return 0;
}
#endif
// mechanism used for updates/restarts in order to wait for other process
void waitIfRequired(std::vector<const char*> &args)
{
std::string shandletowait;
bool dowaitforhandle = extractargparam(args, "--wait-for", shandletowait);
if (dowaitforhandle)
{
#ifdef _WIN32
DWORD processId = atoi(shandletowait.c_str());
HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);
cout << "Waiting for former server to end" << endl;
WaitForSingleObject( processHandle, INFINITE );
CloseHandle(processHandle);
#else
pid_t processId = atoi(shandletowait.c_str());
while (is_pid_running(processId))
{
cerr << "Waiting for former MEGAcmd server to end: " << processId << endl;
sleep(1);
}
#endif
}
}
//TODO: things that will require testing (make them reach Jira release somehow)
// - ALL PARAMETERS (including api url)
// - windows uninstall and updating
// - linux updates (signals and waiting)
// - windows execution with non utf-8 paths
// - linux forking (clients into server)
int main(int argc, char* argv[])
{
#ifdef WIN32
megacmd::Instance<megacmd::WindowsConsoleController> windowsConsoleController;
#endif
std::vector<const char*> args;
if (argc > 1)
{
args = std::vector<const char*>(argv + 1, argv + argc);
}
#ifdef _WIN32
if (mayUninstall(args))
{
return 0;
}
#endif
waitIfRequired(args);
bool logToCout = !extractarg(args, "--do-not-log-to-stdout");
auto logLevels = getLogLevels(args);
int sdkLogLevel = logLevels.first;
int cmdLogLevel = logLevels.second;
bool skiplockcheck = extractarg(args, "--skip-lock-check");
std::string debug_api_url;
extractargparam(args, "--apiurl", debug_api_url); // only for debugging
bool disablepkp = extractarg(args, "--disablepkp"); // only for debugging
auto createLoggedStream = []
{
return new megacmd::FileRotatingLoggedStream(megacmd::MegaCmdLogger::getDefaultFilePath());
};
return megacmd::executeServer(argc, argv, createLoggedStream,
logToCout, sdkLogLevel, cmdLogLevel,
skiplockcheck, debug_api_url, disablepkp);
}