Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tfarmserver.h"
Toshihiro Shimizu 890ddd
#include "tfarmexecutor.h"
Toshihiro Shimizu 890ddd
#include "tfarmcontroller.h"
Toshihiro Shimizu 890ddd
#include "tthreadmessage.h"
Toshihiro Shimizu 890ddd
#include "tthread.h"
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
#include "tsmartpointer.h"
Toshihiro Shimizu 890ddd
#include "service.h"
Toshihiro Shimizu 890ddd
#include "tlog.h"
Toshihiro Shimizu 890ddd
#include "tfilepath_io.h"
Toshihiro Shimizu 890ddd
#include "tcli.h"
Dave 5a9475
#include "tversion.h"
Dave 5a9475
using namespace TVER;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <string></string>
Toshihiro Shimizu 890ddd
#include <map></map>
Shinya Kitaoka ee259f
#include <sstream></sstream>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <qstring></qstring>
Toshihiro Shimizu 890ddd
#include <qprocess></qprocess>
Toshihiro Shimizu 890ddd
#include <qcoreapplication></qcoreapplication>
Toshihiro Shimizu 890ddd
#include <qeventloop></qeventloop>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tthread.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
#include <iostream></iostream>
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#include <sys param.h=""></sys>
Toshihiro Shimizu 890ddd
#include <unistd.h></unistd.h>
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
shun-iwasawa 443318
// #define REDIRECT_OUTPUT
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
#define QUOTE_STR "\""
Toshihiro Shimizu 890ddd
#define CASMPMETER "casmpmeter.exe"
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#define QUOTE_STR "'"
Toshihiro Shimizu 890ddd
#define CASMPMETER "casmpmeter"
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifndef _WIN32
Toshihiro Shimizu 890ddd
#define NO_ERROR 0
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// forward declaration
Toshihiro Shimizu 890ddd
class FarmServer;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------
Shinya Kitaoka 120a6e
TFilePath getGlobalRoot() {
Dave 5a9475
  TVER::ToonzVersion tver;
Shinya Kitaoka 120a6e
  TFilePath rootDir;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Dave 5a9475
  std::string regpath = "SOFTWARE\\" + tver.getAppName() + "\\" +
Dave 5a9475
                        tver.getAppName() + "\\" + tver.getAppVersionString() +
Dave 5a9475
                        "\\FARMROOT";
Dave 5a9475
  TFilePath name(regpath);
Shinya Kitaoka 120a6e
  rootDir = TFilePath(TSystem::getSystemValue(name).toStdString());
Toshihiro Shimizu 890ddd
#else
Dave 5a9475
// Leggo la localRoot da File txt
Dave 5a9475
#ifdef MACOSX
Dave 5a9475
  // If MACOSX, change to MACOSX path
shun-iwasawa 443318
  std::string unixpath =
shun-iwasawa 443318
      "./" + tver.getAppName() + ".app/Contents/Resources/configfarmroot.txt";
Dave 5a9475
#else
Dave 5a9475
  // set path to something suitable for most linux (Unix?) systems
Dave 5a9475
  std::string unixpath = "/etc/" + tver.getAppName() + "/opentoonz.conf";
Dave 5a9475
#endif
Dave 5a9475
  TFilePath name(unixpath);
Dave 5a9475
  Tifstream is(name);
Shinya Kitaoka 120a6e
  if (is) {
Shinya Kitaoka 120a6e
    char line[1024];
Shinya Kitaoka 120a6e
    is.getline(line, 80);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    char *s = line;
Shinya Kitaoka 120a6e
    while (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\"') s++;
Shinya Kitaoka 120a6e
    if (*s != '\0') {
Shinya Kitaoka 120a6e
      char *t = s;
Shinya Kitaoka 120a6e
      while (*t) t++;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      std::string pathName(s, t - 1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      rootDir = TFilePath(pathName);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  return rootDir;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFilePath getLocalRoot() {
Dave 5a9475
  TVER::ToonzVersion tver;
Shinya Kitaoka 120a6e
  TFilePath lroot;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Dave 5a9475
  QString regpath = QString::fromStdString(
Dave 5a9475
      "SOFTWARE\\" + tver.getAppName() + "\\" + tver.getAppName() + "\\" +
Dave 5a9475
      tver.getAppVersionString() + "\\FARMROOT");
Dave 5a9475
  TFilePath name(regpath);
Shinya Kitaoka 120a6e
  lroot = TFilePath(TSystem::getSystemValue(name).toStdString()) +
Shinya Kitaoka 120a6e
          TFilePath("toonzfarm");
Toshihiro Shimizu 890ddd
#else
Dave 5a9475
#ifdef MACOSX
Dave 5a9475
  // If MACOSX, change to MACOSX path
shun-iwasawa 443318
  std::string unixpath =
shun-iwasawa 443318
      "./" + tver.getAppName() + ".app/Contents/Resources/configfarmroot.txt";
Dave 5a9475
#else
Dave 5a9475
  // set path to something suitable for most linux (Unix?) systems
Rozhuk Ivan ac51ab
#ifdef FREEBSD
shun-iwasawa 443318
  std::string unixpath =
shun-iwasawa 443318
      "/usr/local/etc/" + tver.getAppName() + "/opentoonz.conf";
Rozhuk Ivan ac51ab
#else
Dave 5a9475
  std::string unixpath = "/etc/" + tver.getAppName() + "/opentoonz.conf";
Dave 5a9475
#endif
Rozhuk Ivan ac51ab
#endif
Dave 5a9475
  TFilePath name(unixpath);
Dave 5a9475
  Tifstream is(name);
Shinya Kitaoka 120a6e
  if (is) {
Shinya Kitaoka 120a6e
    char line[1024];
Shinya Kitaoka 120a6e
    is.getline(line, 80);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    char *s = line;
Shinya Kitaoka 120a6e
    while (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\"') s++;
Shinya Kitaoka 120a6e
    if (*s != '\0') {
Shinya Kitaoka 120a6e
      char *t = s;
Shinya Kitaoka 120a6e
      while (*t) t++;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      std::string pathName(s, t - 1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      lroot = TFilePath(pathName);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  return lroot;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFilePath getBinRoot() {
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Shinya Kitaoka 120a6e
  return TSystem::getBinDir();
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
  return getLocalRoot() + "bin";
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool dirExists(const TFilePath &dirFp) {
Shinya Kitaoka 120a6e
  bool exists = false;
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Shinya Kitaoka 120a6e
  TFileStatus fs(dirFp);
Shinya Kitaoka 120a6e
  exists = fs.isDirectory();
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
  int acc = access(::to_string(dirFp).c_str(), 00);  // 00 == solo esistenza
Shinya Kitaoka 120a6e
  exists  = acc != -1;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  return exists;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool myDoesExists(const TFilePath &fp) {
Shinya Kitaoka 120a6e
  bool exists = false;
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Shinya Kitaoka 120a6e
  TFileStatus fs(fp);
Shinya Kitaoka 120a6e
  exists = fs.doesExist();
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
  int acc = access(::to_string(fp).c_str(), 00);  // 00 == solo esistenza
Shinya Kitaoka 120a6e
  exists  = acc != -1;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  return exists;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline bool isBlank(char c) { return c == ' ' || c == '\t' || c == '\n'; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // anonymous namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class FarmServerService final : public TService {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  FarmServerService(std::ostream &os)
Shinya Kitaoka 120a6e
      : TService("ToonzFarm Server", "ToonzFarm Server")
Shinya Kitaoka 120a6e
      , m_os(os)
Shinya Kitaoka 120a6e
      , m_userLog(0) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ~FarmServerService() { delete m_userLog; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  void onStart(int argc, char *argv[]) override;
Shinya Kitaoka 473e70
  void onStop() override;
Toshihiro Shimizu 890ddd
otakuto 158f9f
  void loadControllerData(QString &hostName, std::string &ipAddr, int &port);
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Shinya Kitaoka 120a6e
  void loadDiskMountingPoints(const TFilePath &fp);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void mountDisks();
Shinya Kitaoka 120a6e
  void unmountDisks();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<std::string, std::string=""> m_disks;</std::string,>
otakuto 158f9f
  std::vector<std::string> m_disksMounted;</std::string>
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int m_port;
Shinya Kitaoka 120a6e
  QString m_addr;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  FarmServer *m_farmServer;
Shinya Kitaoka 120a6e
  std::ostream &m_os;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TUserLog *m_userLog;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FarmServerService service(std::cout);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class FarmControllerProxy final : public TSmartObject {
Shinya Kitaoka 120a6e
  TFarmController *m_controller;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  FarmControllerProxy(TFarmController *controller) : m_controller(controller) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ~FarmControllerProxy() { delete m_controller; }
Shinya Kitaoka 120a6e
  TFarmController *getController() const { return m_controller; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  // not implemented
Shinya Kitaoka 120a6e
  FarmControllerProxy(const FarmControllerProxy &);
Shinya Kitaoka 120a6e
  FarmControllerProxy &operator=(const FarmControllerProxy &);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// non posso usare lo smartpointer di tnzcore perche' non linka su .NET
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class FarmControllerProxyP {
Shinya Kitaoka 120a6e
  FarmControllerProxy *m_proxy;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  FarmControllerProxyP() : m_proxy(0) {}
Shinya Kitaoka 120a6e
  ~FarmControllerProxyP() {
Shinya Kitaoka 120a6e
    if (m_proxy) m_proxy->release();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  FarmControllerProxyP(const FarmControllerProxyP &src) : m_proxy(src.m_proxy) {
Shinya Kitaoka 120a6e
    if (m_proxy) m_proxy->addRef();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  FarmControllerProxyP &operator=(const FarmControllerProxyP &src) {
Shinya Kitaoka 120a6e
    FarmControllerProxyP tmp(*this);
otakuto ed7dcd
    std::swap(tmp.m_proxy, m_proxy);
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  FarmControllerProxyP &operator=(TFarmController *controller) {
Shinya Kitaoka 120a6e
    if (m_proxy && m_proxy->getController() == controller) return *this;
Shinya Kitaoka 120a6e
    if (m_proxy) m_proxy->release();
Shinya Kitaoka 120a6e
    m_proxy = new FarmControllerProxy(controller);
Shinya Kitaoka 120a6e
    m_proxy->addRef();
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFarmController *operator->() { return getPointer(); }
Shinya Kitaoka 120a6e
  TFarmController *getPointer() const {
Shinya Kitaoka 120a6e
    return m_proxy ? m_proxy->getController() : 0;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class FarmServer final : public TFarmExecutor, public TFarmServer {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  FarmServer(int port, TUserLog *log);
Shinya Kitaoka 120a6e
  ~FarmServer();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void setController(const ControllerData &data) {
Shinya Kitaoka 120a6e
    m_controllerData            = data;
Shinya Kitaoka 120a6e
    TFarmController *controller = 0;
Shinya Kitaoka 120a6e
    TFarmControllerFactory factory;
Shinya Kitaoka 120a6e
    factory.create(data, &controller);
Shinya Kitaoka 120a6e
    m_controller = controller;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  TFarmController *getController() const { return m_controller.getPointer(); }
otakuto 158f9f
  void setAppPaths(const std::vector<tfilepath> &);</tfilepath>
Shinya Kitaoka 120a6e
otakuto 158f9f
  QString execute(const std::vector<qstring> &argv) override;</qstring>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // TFarmServer overrides
Shinya Kitaoka 473e70
  int addTask(const QString &taskid, const QString &cmdline) override;
Shinya Kitaoka 473e70
  int terminateTask(const QString &taskid) override;
otakuto 158f9f
  int getTasks(std::vector<qstring> &tasks) override;</qstring>
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void queryHwInfo(HwInfo &hwInfo) override;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void attachController(const ControllerData &data);
Shinya Kitaoka 38fd86
  void attachController(const QString &name, const QString &addr,
Shinya Kitaoka 38fd86
                        int port) override {
Shinya Kitaoka 120a6e
    attachController(ControllerData(name, addr, port));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void detachController(const ControllerData &data);
Shinya Kitaoka 38fd86
  void detachController(const QString &name, const QString &addr,
Shinya Kitaoka 38fd86
                        int port) override {
Shinya Kitaoka 120a6e
    detachController(ControllerData(name, addr, port));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // class specific methods
Shinya Kitaoka 120a6e
  void removeTask(const QString &id);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  TThread::Executor *m_executor;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ControllerData m_controllerData;
Shinya Kitaoka 120a6e
  FarmControllerProxyP m_controller;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TThread::Mutex m_mux;
otakuto 158f9f
  std::vector<qstring> m_tasks;</qstring>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TUserLog *m_userLog;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  // vector<tfilepath> m_appPaths;</tfilepath>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  // not implemented
Shinya Kitaoka 120a6e
  FarmServer(const FarmServer &);
Shinya Kitaoka 120a6e
  FarmServer &operator=(const FarmServer &);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// class Task
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class Task final : public TThread::Runnable {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  Task(const QString &id, const QString &cmdline, TUserLog *log,
Shinya Kitaoka 120a6e
       FarmServer *server, const FarmControllerProxyP &controller)
Shinya Kitaoka 120a6e
      : m_id(id)
Shinya Kitaoka 120a6e
      , m_cmdline(cmdline)
Shinya Kitaoka 120a6e
      , m_log(log)
Shinya Kitaoka 120a6e
      , m_server(server)
Shinya Kitaoka 120a6e
      , m_controller(controller) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  void run() override;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  QString m_id;
Shinya Kitaoka 120a6e
  QString m_cmdline;
Shinya Kitaoka 120a6e
  TUserLog *m_log;
Shinya Kitaoka 120a6e
  FarmServer *m_server;
Shinya Kitaoka 120a6e
  FarmControllerProxyP m_controller;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  // not implemented
Shinya Kitaoka 120a6e
  Task(const Task &);
Shinya Kitaoka 120a6e
  Task &operator=(const Task &);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Campbell Barton e4aac6
static QString getExeName(bool isComposer) {
Dave ba9da1
  QString name = isComposer ? "tcomposer" : "tcleanup";
Dave ba9da1
Dave ba9da1
#ifdef _WIN32
Dave ba9da1
  return name + ".exe ";
Campbell Barton e4aac6
#elif defined(MACOSX)
Dave ba9da1
  TVER::ToonzVersion tver;
artisteacher 2f3a62
  return "\"./" + QString::fromStdString(tver.getAppName()) +
Dave ba9da1
         ".app/Contents/MacOS/" + name + "\" ";
Dave ba9da1
#else
Dave ba9da1
  return name;
Dave ba9da1
#endif
Dave ba9da1
}
Dave ba9da1
Dave ba9da1
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Task::run() {
Dave ba9da1
  QString cmdline;
Dave ba9da1
Dave ba9da1
  // ===========
Dave ba9da1
  // remap commandLine to local executable
Dave ba9da1
Dave ba9da1
  QStringList l   = m_cmdline.split(" ");
Dave ba9da1
  QString appName = l.at(0);
Dave ba9da1
  // m_log->info(appName);
Dave ba9da1
  if (appName.contains("tcomposer") || appName.contains("tcleanup")) {
Dave ba9da1
    bool m_isComposerTask = appName.contains("tcomposer");
Dave ba9da1
    // m_log->info(QString::number(m_isComposerTask));
Dave ba9da1
    appName = getExeName(m_isComposerTask);
Dave ba9da1
    // m_log->info(appName);
Dave ba9da1
Dave ba9da1
    int i   = 0;
Dave ba9da1
    cmdline = appName;
Dave ba9da1
    // m_log->info(cmdline);
Dave ba9da1
    for (i = 1; i < l.size(); i++) {
Dave ba9da1
      cmdline += " ";
Dave ba9da1
      cmdline += l.at(i);
Dave ba9da1
      // m_log->info(cmdline);
Dave ba9da1
    }
Dave ba9da1
    // m_log->info("remap commandLine to local executable");
Dave ba9da1
    // m_log->info(appName);
Dave ba9da1
  } else {
Dave ba9da1
    cmdline = m_cmdline;
Dave ba9da1
  }
Dave ba9da1
Dave ba9da1
  // ===========
Shinya Kitaoka 120a6e
  QString logMsg("Starting task at ");
Shinya Kitaoka 120a6e
  logMsg += QDateTime::currentDateTime().toString();
Shinya Kitaoka 120a6e
  logMsg += "\n";
Dave ba9da1
  logMsg += "\"" + cmdline + "\"";
Shinya Kitaoka 120a6e
  logMsg += "\n\n";
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_log->info(logMsg);
Toshihiro Shimizu 890ddd
Campbell Barton e4aac6
  // ===========
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Shinya Kitaoka 120a6e
  if (m_cmdline.contains("runcasm")) service.mountDisks();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_cmdline.contains(".bat"))
Dave ba9da1
    cmdline = "cmd /C " + cmdline;
Shinya Kitaoka 120a6e
  else
Dave ba9da1
    cmdline = cmdline;
Toshihiro Shimizu 890ddd
#ifdef LEVO
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    // metto da parte il primo token della command line che e' il nome
Shinya Kitaoka 120a6e
    // dell'eseguibile
Shinya Kitaoka 120a6e
    // Attenzione: case sensitive!
Shinya Kitaoka 120a6e
    QStringList l = m_cmdline.split(" ");
Shinya Kitaoka 120a6e
    // assert(!"CONTROLLARE QUI");
Shinya Kitaoka 120a6e
    QString appName = l.at(1);
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = 2; i < l.size(); i++) cmdline += l.at(i);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // cerco se il nome dell'applicazione e' tra quelle del file di
Shinya Kitaoka 120a6e
    // configurazione
otakuto 158f9f
    for (auto const &appPath : m_server->m_appPaths) {
Shinya Kitaoka 120a6e
      if (appPath.getName() == appName.toStdString()) {
Shinya Kitaoka 120a6e
        exename = QString::fromStdWString(appPath.getWideString());
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
#endif  // LEVO
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // cout << exename << endl;
Shinya Kitaoka 120a6e
  // cout << cmdline << endl;
Shinya Kitaoka 120a6e
shun-iwasawa 443318
  // parse command line
shun-iwasawa 443318
  QString prgName;
shun-iwasawa 443318
  QString argsStr = "";
shun-iwasawa 443318
  int sepPos      = cmdline.indexOf(" ");
shun-iwasawa 443318
shun-iwasawa 443318
  if (sepPos == -1) {
shun-iwasawa 443318
    prgName = cmdline;
shun-iwasawa 443318
  } else {
shun-iwasawa 443318
    prgName = cmdline.left(sepPos);
shun-iwasawa 443318
    argsStr = cmdline.right(cmdline.size() - sepPos - 1);
shun-iwasawa 443318
  }
Shinya Kitaoka 120a6e
shun-iwasawa 443318
  QProcess process;
shun-iwasawa 443318
  process.setProgram(prgName);
shun-iwasawa 443318
#if defined(_WIN32)
shun-iwasawa 443318
  process.setNativeArguments(argsStr);
shun-iwasawa 443318
#else
shun-iwasawa 443318
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
shun-iwasawa 443318
  process.setArguments(argsStr.split(" ", Qt::SkipEmptyParts));
shun-iwasawa 443318
#else
shun-iwasawa 443318
  process.setArguments(argsStr.split(" ", QString::SkipEmptyParts));
shun-iwasawa 443318
#endif
shun-iwasawa 443318
#endif
shun-iwasawa 443318
  process.start();
Shinya Kitaoka 120a6e
  process.waitForFinished(-1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int exitCode  = process.exitCode();
Shinya Kitaoka 120a6e
  int errorCode = process.error();
Shinya Kitaoka 120a6e
  bool ret      = (errorCode != QProcess::UnknownError) || exitCode;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // int ret=QProcess::execute(/*"C:\\depot\\vincenzo\\toonz\\main\\x86_debug\\"
Shinya Kitaoka 120a6e
  // +*/cmdline);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (ret != 0) {
Shinya Kitaoka 120a6e
    QString logMsg("Task aborted ");
Shinya Kitaoka 120a6e
    logMsg += "\n\n";
Shinya Kitaoka 120a6e
    m_log->warning(logMsg);
Shinya Kitaoka 120a6e
    m_controller->taskSubmissionError(m_id, exitCode);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    logMsg = "Task completed at ";
Shinya Kitaoka 120a6e
    logMsg += QDateTime::currentDateTime().toString();
Shinya Kitaoka 120a6e
    logMsg += "\n\n";
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_log->info(logMsg);
Shinya Kitaoka 120a6e
    m_controller->taskCompleted(m_id, exitCode);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // CloseHandle(hJob);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_server->removeTask(m_id);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //************* COMMENTATO A CAUSA DI UN PROBLEMA SU XP
Shinya Kitaoka 120a6e
  // ora i dischi vengono montati al primo task di tipo "runcasm"
Shinya Kitaoka 120a6e
  // e smontati allo stop del servizio
Shinya Kitaoka 120a6e
  // service.unmountDisks();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FarmServer::FarmServer(int port, TUserLog *log)
Shinya Kitaoka 120a6e
    : TFarmExecutor(port), m_controller(), m_userLog(log) {
Shinya Kitaoka 120a6e
  TFarmServer::HwInfo hwInfo;
Shinya Kitaoka 120a6e
  queryHwInfo(hwInfo);
Shinya Kitaoka 120a6e
  m_executor = new TThread::Executor;
Shinya Kitaoka 120a6e
  m_executor->setMaxActiveTasks(1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FarmServer::~FarmServer() { delete m_executor; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
otakuto 158f9f
QString FarmServer::execute(const std::vector<qstring> &argv) {</qstring>
Shinya Kitaoka 120a6e
  if (argv.size() > 0) {
Shinya Kitaoka 120a6e
    if (argv[0] == "addTask" && argv.size() == 3) {
Shinya Kitaoka 120a6e
      // assert(!"Da fare");
Shinya Kitaoka 120a6e
      int ret = addTask(argv[1], argv[2]);
Shinya Kitaoka 120a6e
      return QString::number(ret);
Shinya Kitaoka 120a6e
    } else if (argv[0] == "terminateTask" && argv.size() > 1) {
Shinya Kitaoka 120a6e
      int ret = terminateTask(argv[1]);
Shinya Kitaoka 120a6e
      return QString::number(ret);
Shinya Kitaoka 120a6e
    } else if (argv[0] == "getTasks") {
otakuto 158f9f
      std::vector<qstring> tasks;</qstring>
Shinya Kitaoka 120a6e
      int ret = getTasks(tasks);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      QString reply(QString::number(ret));
Shinya Kitaoka 120a6e
      reply += ",";
Shinya Kitaoka 120a6e
otakuto 158f9f
      for (auto const &e : tasks) {
otakuto 158f9f
        reply += e;
Shinya Kitaoka 120a6e
        reply += ",";
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Rozhuk Ivan 823a31
      if (!reply.isEmpty()) reply = reply.left(reply.size() - 1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      return reply;
Shinya Kitaoka 120a6e
    } else if (argv[0] == "queryHwInfo") {
Shinya Kitaoka 120a6e
      TFarmServer::HwInfo hwInfo;
Shinya Kitaoka 120a6e
      queryHwInfo(hwInfo);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      QString ret;
Shinya Kitaoka 120a6e
      ret += QString::number((unsigned long)hwInfo.m_cpuCount);
Shinya Kitaoka 120a6e
      ret += ",";
Shinya Kitaoka 120a6e
      ret += QString::number((unsigned long)(hwInfo.m_totPhysMem / 1024));
Shinya Kitaoka 120a6e
      ret += ",";
Shinya Kitaoka 120a6e
      ret += QString::number((unsigned long)(hwInfo.m_availPhysMem / 1024));
Shinya Kitaoka 120a6e
      ret += ",";
Shinya Kitaoka 120a6e
      ret += QString::number((unsigned long)(hwInfo.m_totVirtMem / 1024));
Shinya Kitaoka 120a6e
      ret += ",";
Shinya Kitaoka 120a6e
      ret += QString::number((unsigned long)(hwInfo.m_availVirtMem / 1024));
Shinya Kitaoka 120a6e
      ret += ",";
Shinya Kitaoka 120a6e
      ret += QString::number(hwInfo.m_type);
Shinya Kitaoka 120a6e
      return ret;
Shinya Kitaoka 120a6e
    } else if (argv[0] == "attachController" && argv.size() > 3) {
Shinya Kitaoka 120a6e
      int port;
Shinya Kitaoka 120a6e
      fromStr(port, argv[3]);
Shinya Kitaoka 120a6e
      attachController(ControllerData(argv[1], argv[2], port));
Shinya Kitaoka 120a6e
      return "";
Shinya Kitaoka 120a6e
    } else if (argv[0] == "detachController" && argv.size() > 3) {
Shinya Kitaoka 120a6e
      int port;
Shinya Kitaoka 120a6e
      fromStr(port, argv[3]);
Shinya Kitaoka 120a6e
      detachController(ControllerData(argv[1], argv[2], port));
Shinya Kitaoka 120a6e
      return "";
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return QString::number(-1);
Shinya Kitaoka 120a6e
  ;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int FarmServer::addTask(const QString &id, const QString &cmdline) {
Shinya Kitaoka 120a6e
  // std::cout << "Server: addTask" << id << cmdline << std::endl;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  QString lcmdline = cmdline;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (lcmdline.contains("runcasm")) {
Shinya Kitaoka 120a6e
    // il task e' runcasm
Shinya Kitaoka 120a6e
    TFilePath rootDir = getGlobalRoot();
Shinya Kitaoka 120a6e
    TFilePath logfilePath =
Shinya Kitaoka 120a6e
        (rootDir + "logs" + id.toStdString()).withType(".log");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    lcmdline +=
Shinya Kitaoka 120a6e
        " -logfile " + QString::fromStdWString(logfilePath.getWideString());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TFilePath casmpmeterFp = getBinRoot() + CASMPMETER;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    lcmdline += " -ac " + QString::fromStdWString(casmpmeterFp.getWideString());
Shinya Kitaoka 120a6e
    lcmdline += " -ac_args " + QString(QUOTE_STR);
Shinya Kitaoka 120a6e
    lcmdline += "$count $total $frame $filename " + id + QUOTE_STR;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (lcmdline.contains("zrender")) lcmdline += " -taskid " + id;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (lcmdline.contains("tcomposer")) {
Shinya Kitaoka 120a6e
    lcmdline += " -farm " + QString::number(m_controllerData.m_port) + "@" +
Shinya Kitaoka 120a6e
                m_controllerData.m_hostName;
Shinya Kitaoka 120a6e
    lcmdline += " -id " + id;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_executor->addTask(new Task(id, lcmdline, m_userLog, this, m_controller));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  QMutexLocker sl(&m_mux);
Shinya Kitaoka 120a6e
  m_tasks.push_back(id);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int FarmServer::terminateTask(const QString &taskid) {
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
shun-iwasawa 443318
  HANDLE hJob = OpenJobObject(MAXIMUM_ALLOWED,   // access right
shun-iwasawa 443318
                              TRUE,              // inheritance state
Shinya Kitaoka 120a6e
                              taskid.toUtf8());  // job name
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (hJob != NULL) {
Shinya Kitaoka 120a6e
    BOOL res = TerminateJobObject(hJob,  // handle to job
Shinya Kitaoka 120a6e
                                  2);    // exit code
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
otakuto 158f9f
int FarmServer::getTasks(std::vector<qstring> &tasks) {</qstring>
Shinya Kitaoka 120a6e
  QMutexLocker sl(&m_mux);
Shinya Kitaoka 120a6e
  tasks = m_tasks;
Shinya Kitaoka 120a6e
  return m_tasks.size();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FarmServer::queryHwInfo(HwInfo &hwInfo) {
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Shinya Kitaoka 120a6e
  MEMORYSTATUS buff;
Shinya Kitaoka 120a6e
  GlobalMemoryStatus(&buff);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  hwInfo.m_totPhysMem   = buff.dwTotalPhys;
Shinya Kitaoka 120a6e
  hwInfo.m_availPhysMem = buff.dwAvailPhys;
Shinya Kitaoka 120a6e
  hwInfo.m_totVirtMem   = buff.dwTotalVirtual;
Shinya Kitaoka 120a6e
  hwInfo.m_availVirtMem = buff.dwAvailVirtual;
Shinya Kitaoka 120a6e
  hwInfo.m_cpuCount     = TSystem::getProcessorCount();
Shinya Kitaoka 120a6e
  hwInfo.m_type         = Windows;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
  // We can just retrieve the overall physical memory - the rest is defaulted to
Shinya Kitaoka 120a6e
  // 500 MB
Rozhuk Ivan 26d905
  hwInfo.m_totPhysMem   = TSystem::getMemorySize(true);
Rozhuk Ivan 26d905
  hwInfo.m_availPhysMem = TSystem::getFreeMemorySize(true);
Shinya Kitaoka 120a6e
  hwInfo.m_totVirtMem   = 500000000;
Shinya Kitaoka 120a6e
  hwInfo.m_availVirtMem = 500000000;
Rozhuk Ivan 26d905
  hwInfo.m_cpuCount     = TSystem::getProcessorCount();
Rozhuk Ivan 26d905
#ifdef __sgi
Rozhuk Ivan 26d905
  hwInfo.m_type         = Irix;
Rozhuk Ivan 26d905
#else
shun-iwasawa 443318
  hwInfo.m_type = Linux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FarmServer::attachController(const ControllerData &data) {
Shinya Kitaoka 120a6e
  setController(data);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FarmServer::detachController(const ControllerData &data) {
Shinya Kitaoka 120a6e
  if (m_controllerData == data) {
Shinya Kitaoka 120a6e
    // delete m_controller;
Shinya Kitaoka 120a6e
    m_controller = 0;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FarmServer::removeTask(const QString &id) {
Shinya Kitaoka 120a6e
  QMutexLocker sl(&m_mux);
otakuto 158f9f
  std::vector<qstring>::iterator it = find(m_tasks.begin(), m_tasks.end(), id);</qstring>
Shinya Kitaoka 120a6e
  if (it != m_tasks.end()) m_tasks.erase(it);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
std::string getLine(std::istream &is) {
Shinya Kitaoka 120a6e
  std::string out;
Shinya Kitaoka 120a6e
  char c;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (!is.eof()) {
Shinya Kitaoka 120a6e
    is.get(c);
Rozhuk Ivan 823a31
    if (c != '\r') {
Rozhuk Ivan 823a31
      if (c != '\n') {
Rozhuk Ivan 823a31
        if (!is.fail()) {
Shinya Kitaoka 120a6e
          out.append(1, c);
Rozhuk Ivan 823a31
        } else {
Shinya Kitaoka 120a6e
          break;
shun-iwasawa 443318
        }
Rozhuk Ivan 823a31
      } else {
Shinya Kitaoka 120a6e
        break;
Rozhuk Ivan 823a31
      }
Rozhuk Ivan 823a31
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return out;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // anonymous namespace
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int inline STRICMP(const QString &a, const QString &b) {
Shinya Kitaoka 120a6e
  return a.compare(b, Qt::CaseSensitive);
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
int inline STRICMP(const char *a, const char *b) {
Shinya Kitaoka 120a6e
  QString str(a);
Shinya Kitaoka 120a6e
  return str.compare(QString(b), Qt::CaseSensitive);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Campbell Barton ccd505
static bool loadServerData(const QString &hostname, QString &addr, int &port) {
Shinya Kitaoka 120a6e
  TFilePath rootDir = getGlobalRoot();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TFilePath fp = rootDir + "config" + "servers.txt";
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifndef _WIN32
Shinya Kitaoka 120a6e
  int acc = access(::to_string(fp).c_str(), 00);  // 00 == solo esistenza
Shinya Kitaoka 120a6e
  bool fileExists = acc != -1;
Shinya Kitaoka 120a6e
  if (!fileExists) return false;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  Tifstream is(fp);
Shinya Kitaoka 120a6e
  if (!is.good()) return false;
Shinya Kitaoka 120a6e
  while (!is.eof()) {
Shinya Kitaoka 120a6e
    std::string line = getLine(is);
Shinya Kitaoka 120a6e
    std::istringstream iss(line);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    std::string name;
Shinya Kitaoka 120a6e
    std::string ipAddress;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    iss >> name >> ipAddress >> port;
Shinya Kitaoka 120a6e
    if (name[0] == '#') continue;
shun-iwasawa 443318
    if (STRICMP(hostname.toUtf8(), name.c_str()) == 0) {
Shinya Kitaoka 120a6e
      addr = QString(ipAddress.c_str());
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FarmServerService::onStart(int argc, char *argv[]) {
Shinya Kitaoka 120a6e
  // Initialize thread components
Shinya Kitaoka 120a6e
  TThread::init();
Dave 5a9475
  TVER::ToonzVersion tver;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
//  DebugBreak();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TFilePath lRootDir = getLocalRoot();
Shinya Kitaoka 120a6e
  TFileStatus fs(lRootDir);
Shinya Kitaoka 120a6e
  bool lRootDirExists = fs.isDirectory();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!lRootDirExists) {
Shinya Kitaoka 120a6e
    std::string errMsg("Unable to start the Server");
Shinya Kitaoka 120a6e
    errMsg += "\n";
Dave 5a9475
    errMsg += "The directory " + ::to_string(lRootDir) +
Dave 5a9475
              " specified as Local Root does not exist";
Shinya Kitaoka 120a6e
    errMsg += "\n";
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    addToMessageLog(errMsg);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// DEBUG MAC SERVIZIO (DA TOGLIERE)
Toshihiro Shimizu 890ddd
#ifdef MACOSX
Shinya Kitaoka 120a6e
    system("echo 'local root does not exist' >> err.log");
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // exit the program
Shinya Kitaoka 120a6e
    setStatus(TService::Stopped, NO_ERROR, 0);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TFilePath gRootDir = getGlobalRoot();
Shinya Kitaoka 120a6e
  if (::to_string(gRootDir) == "") {
Dave 5a9475
    std::string errMsg("Unable to get TFARMGLOBALROOT environment variable (" +
Dave 5a9475
                       ::to_string(gRootDir) + ")");
Shinya Kitaoka 120a6e
    addToMessageLog(errMsg);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// DEBUG MAC SERVIZIO (DA TOGLIERE)
Toshihiro Shimizu 890ddd
#ifdef MACOSX
Shinya Kitaoka 120a6e
    system("echo 'Unable to set the global root' >> err.log");
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // exit the program
Shinya Kitaoka 120a6e
    setStatus(TService::Stopped, NO_ERROR, 0);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool gRootDirExists = dirExists(gRootDir);
Shinya Kitaoka 120a6e
  ;
Shinya Kitaoka 120a6e
  if (!gRootDirExists) {
Shinya Kitaoka 120a6e
    std::string errMsg("Unable to start the Server");
Shinya Kitaoka 120a6e
    errMsg += "\n";
Shinya Kitaoka 120a6e
    errMsg += "The directory " + ::to_string(gRootDir) +
Shinya Kitaoka 120a6e
              " specified as Global Root does not exist";
Shinya Kitaoka 120a6e
    ;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    addToMessageLog(errMsg);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// DEBUG MAC SERVIZIO (DA TOGLIERE)
Toshihiro Shimizu 890ddd
#ifdef MACOSX
Shinya Kitaoka 120a6e
    system("echo 'Global root does not exist' >> err.log");
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // exit the program
Shinya Kitaoka 120a6e
    setStatus(TService::Stopped, NO_ERROR, 0);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // legge dal file di configurazione le informazioni sul controller
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TFilePath fp = gRootDir + "config" + "controller.txt";
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ControllerData controllerData;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    ::loadControllerData(fp, controllerData);
Shinya Kitaoka 120a6e
  } catch (TException &e) {
Shinya Kitaoka 120a6e
    std::string errMsg("Unable to start the Server");
Shinya Kitaoka 120a6e
    errMsg += "\n";
Shinya Kitaoka 120a6e
    errMsg += ::to_string(e.getMessage());
Shinya Kitaoka 120a6e
    addToMessageLog(errMsg);
Shinya Kitaoka 120a6e
    setStatus(TService::Stopped, NO_ERROR, 0);  // exit the program
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (isRunningAsConsoleApp()) {
Shinya Kitaoka 120a6e
    // i messaggi verranno ridiretti sullo standard output
Shinya Kitaoka 120a6e
    m_userLog = new TUserLog();
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    TFilePath logFilePath = lRootDir + "server.log";
Shinya Kitaoka 120a6e
    m_userLog             = new TUserLog(logFilePath);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Tact Yoshida ceffab
  std::string appverinfo = tver.getAppVersionInfo("Farm Server") + "\n\n";
Dave 5a9475
  m_userLog->info(appverinfo.c_str());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // legge dal file di configurazione dei server il numero di porta da
Shinya Kitaoka 120a6e
  // utilizzare
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool ret = loadServerData(TSystem::getHostName(), m_addr, m_port);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!ret) {
Shinya Kitaoka 120a6e
    QString msg("Unable to get the port number of ");
Shinya Kitaoka 120a6e
    msg += TSystem::getHostName();
Shinya Kitaoka 120a6e
    msg += " from the servers config file";
Shinya Kitaoka 120a6e
    msg += "\n";
Dave 5a9475
    msg += "Using the default port number ";
Dave 5a9475
    msg += QString::number(m_port);
Shinya Kitaoka 120a6e
    msg += "\n";
Shinya Kitaoka 120a6e
    msg += "\n";
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    m_userLog->info(msg);
Shinya Kitaoka 120a6e
    m_port = 8002;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef __sgi
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    std::ofstream os("/tmp/.tfarmserverd.dat");
Shinya Kitaoka 120a6e
    os << m_port;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_farmServer = new FarmServer(m_port, m_userLog);
Shinya Kitaoka 120a6e
  m_farmServer->setController(controllerData);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    m_farmServer->getController()->attachServer(TSystem::getHostName(), m_addr,
Shinya Kitaoka 120a6e
                                                m_port);
Shinya Kitaoka 120a6e
  } catch (TException const &) {
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Shinya Kitaoka 120a6e
  TFilePath diskMountingsFilePath = lRootDir + "config" + "diskmap.cfg";
Shinya Kitaoka 120a6e
  if (myDoesExists(diskMountingsFilePath)) {
Shinya Kitaoka 120a6e
    loadDiskMountingPoints(diskMountingsFilePath);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // i dischi vengono montati al primo task di tipo "runcasm"
Shinya Kitaoka 120a6e
    // e smontati allo stop del servizio
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // mountDisks();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Carica da un file di configurazione i path dei programmi da lanciare.
Shinya Kitaoka 120a6e
  // Per tutti i programmi il cui path non e' contenuto nel file di
Shinya Kitaoka 120a6e
  // configurazione
Shinya Kitaoka 120a6e
  // si assume che il path del folder del programma sia specificato
Shinya Kitaoka 120a6e
  // nella variabile di sistema PATH
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  QEventLoop eventLoop;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Connect the server's listening finished signal to main loop quit.
Shinya Kitaoka 120a6e
  QObject::connect(m_farmServer, SIGNAL(finished()), &eventLoop, SLOT(quit()));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Run the TcpIp server's listening state
Shinya Kitaoka 120a6e
  m_farmServer->start();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Main loop starts here
Shinya Kitaoka 120a6e
  eventLoop.exec();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  //----------------------Farm server loops here------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int rc = m_farmServer->getExitCode();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef __sgi
Shinya Kitaoka 120a6e
  remove("/tmp/.tfarmserver.dat");
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (rc != 0) {
Shinya Kitaoka 120a6e
    std::string msg("An error occurred starting the ToonzFarm Server");
Shinya Kitaoka 120a6e
    msg += "\n";
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Shinya Kitaoka 120a6e
    LPVOID lpMsgBuf;
Shinya Kitaoka 120a6e
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
Shinya Kitaoka 120a6e
                      FORMAT_MESSAGE_IGNORE_INSERTS,
Shinya Kitaoka 120a6e
                  NULL, rc,
Shinya Kitaoka 120a6e
                  0,  // Default language
Shinya Kitaoka 120a6e
                  (LPTSTR)&lpMsgBuf, 0, NULL);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    msg += std::string((char *)lpMsgBuf);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Free the buffer.
Shinya Kitaoka 120a6e
    LocalFree(lpMsgBuf);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    addToMessageLog(msg);
Shinya Kitaoka 120a6e
    m_userLog->error(QString::fromStdString(msg));
Shinya Kitaoka 120a6e
    setStatus(TService::Stopped, NO_ERROR, 0);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::string msg("Exiting with code ");
Shinya Kitaoka 120a6e
  msg += std::to_string(ret);
Shinya Kitaoka 120a6e
  msg += "\n";
Shinya Kitaoka 120a6e
  m_userLog->info(QString::fromStdString(msg));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FarmServerService::onStop() {
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    m_farmServer->getController()->detachServer(TSystem::getHostName(), m_addr,
Shinya Kitaoka 120a6e
                                                m_port);
Shinya Kitaoka 120a6e
  } catch (TException & /*e*/) {
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Campbell Barton e4aac6
  // i dischi vengono montati al primo task di tipo "runcasm"
Campbell Barton e4aac6
  // e smontati allo stop del servizio
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Shinya Kitaoka 120a6e
  unmountDisks();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TTcpIpClient client;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int socketId;
Shinya Kitaoka 120a6e
  int ret = client.connect(TSystem::getHostName(), "", m_farmServer->getPort(),
Shinya Kitaoka 120a6e
                           socketId);
Shinya Kitaoka 120a6e
  if (ret == OK) {
Shinya Kitaoka 120a6e
    client.send(socketId, "shutdown");
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FarmServerService::loadDiskMountingPoints(const TFilePath &fp) {
Shinya Kitaoka 120a6e
  Tifstream is(fp);
Shinya Kitaoka 120a6e
  if (!is) throw std::string("File " + ::to_string(fp) + " not found");
Shinya Kitaoka 120a6e
  char buffer[1024];
Shinya Kitaoka 120a6e
  while (is.getline(buffer, sizeof(buffer))) {
Shinya Kitaoka 120a6e
    char *s = buffer;
Shinya Kitaoka 120a6e
    while (isBlank(*s)) s++;
Shinya Kitaoka 120a6e
    if (*s == '\0' || *s == '#' || *s == '!') continue;
Shinya Kitaoka 120a6e
    if (*s == '=') continue;  // errore: from vuoto
Shinya Kitaoka 120a6e
    char *t = s;
Shinya Kitaoka 120a6e
    while (*t && *t != '=') t++;
Shinya Kitaoka 120a6e
    if (*t != '=') continue;  // errore: manca '='
Shinya Kitaoka 120a6e
    char *q = t;
Shinya Kitaoka 120a6e
    while (q > s && isBlank(*(q - 1))) q--;
Shinya Kitaoka 120a6e
    if (q == s)
Shinya Kitaoka 120a6e
      continue;  // non dovrebbe succedere mai: prima di '=' tutti blanks
Shinya Kitaoka 120a6e
    std::string from(s, q - s);
Shinya Kitaoka 120a6e
    s = t + 1;
Shinya Kitaoka 120a6e
    while (isBlank(*s)) s++;
Shinya Kitaoka 120a6e
    if (*s == '\0') continue;  // errore: dst vuoto
Shinya Kitaoka 120a6e
    t = s;
Shinya Kitaoka 120a6e
    while (*t) t++;
Shinya Kitaoka 120a6e
    while (t > s && isBlank(*(t - 1))) t--;
Shinya Kitaoka 120a6e
    if (t == s) continue;  // non dovrebbe succedere mai: dst vuoto
otakuto 158f9f
    std::string dst(s, t - s);
Shinya Kitaoka 120a6e
    m_disks[from] = dst;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FarmServerService::mountDisks() {
Shinya Kitaoka 120a6e
  std::map<std::string, std::string="">::iterator it = m_disks.begin();</std::string,>
Shinya Kitaoka 120a6e
  for (; it != m_disks.end(); ++it) {
Shinya Kitaoka 120a6e
    std::string drive      = it->first;
Shinya Kitaoka 120a6e
    std::string remoteName = it->second;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    NETRESOURCE NetResource;
Shinya Kitaoka 120a6e
    NetResource.dwType      = RESOURCETYPE_DISK;
Shinya Kitaoka 120a6e
    NetResource.lpLocalName = (LPSTR)drive.c_str();  // "O:";
Shinya Kitaoka 120a6e
    NetResource.lpRemoteName =
Shinya Kitaoka 120a6e
        (LPSTR)remoteName.c_str();  // "\\\\vega\\PERSONALI";
Shinya Kitaoka 120a6e
    NetResource.lpProvider = NULL;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    DWORD res =
Shinya Kitaoka 120a6e
        WNetAddConnection2(&NetResource,  // connection details
Shinya Kitaoka 120a6e
                           0,             // password
Shinya Kitaoka 120a6e
                           TSystem::getUserName().toUtf8(),  // user name
Shinya Kitaoka 120a6e
                           0);  // connection options
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (res == NO_ERROR) m_disksMounted.push_back(drive);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (res != NO_ERROR && res != ERROR_ALREADY_ASSIGNED) {
Shinya Kitaoka 120a6e
      // ERROR_BAD_NET_NAME
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      DWORD dwLastError;
Shinya Kitaoka 120a6e
      char errorBuf[1024];
Shinya Kitaoka 120a6e
      char nameBuf[1024];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      DWORD rett =
Shinya Kitaoka 120a6e
          WNetGetLastError(&dwLastError,      // error code
Shinya Kitaoka 120a6e
                           errorBuf,          // error description buffer
Shinya Kitaoka 120a6e
                           sizeof(errorBuf),  // size of description buffer
Shinya Kitaoka 120a6e
                           nameBuf,           // buffer for provider name
Shinya Kitaoka 120a6e
                           sizeof(nameBuf));  // size of provider name buffer
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      std::string errorMessage("Unable to map ");
Shinya Kitaoka 120a6e
      errorMessage += NetResource.lpRemoteName;
Shinya Kitaoka 120a6e
      errorMessage += " to logic volume ";
Shinya Kitaoka 120a6e
      errorMessage += NetResource.lpLocalName;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      addToMessageLog(errorMessage);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FarmServerService::unmountDisks() {
otakuto 158f9f
  for (auto const &drive : m_disksMounted) {
Shinya Kitaoka 120a6e
    DWORD res =
Shinya Kitaoka 120a6e
        WNetCancelConnection2(drive.c_str(),           // resource name
Shinya Kitaoka 120a6e
                              CONNECT_UPDATE_PROFILE,  // connection type
Shinya Kitaoka 120a6e
                              TRUE);  // unconditional disconnect option
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (res != NO_ERROR && res != ERROR_NOT_CONNECTED) {
Shinya Kitaoka 120a6e
      std::string errorMessage("Unable to unmap ");
Shinya Kitaoka 120a6e
      errorMessage += drive.c_str();
Shinya Kitaoka 120a6e
      addToMessageLog(errorMessage);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_disksMounted.clear();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int main(int argc, char **argv) {
Shinya Kitaoka 120a6e
  QCoreApplication a(argc, argv);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool console = false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (argc > 1) {
Shinya Kitaoka 120a6e
    std::string serviceName(
Shinya Kitaoka 120a6e
        "ToonzFarmServer");  // Must be the same of the installer's
Shinya Kitaoka 120a6e
    std::string serviceDisplayName = serviceName;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TCli::SimpleQualifier consoleQualifier("-console", "Run as console app");
Shinya Kitaoka 120a6e
    TCli::StringQualifier installQualifier("-install name",
Shinya Kitaoka 120a6e
                                           "Install service as 'name'");
Shinya Kitaoka 120a6e
    TCli::SimpleQualifier removeQualifier("-remove", "Remove service");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TCli::Usage usage(argv[0]);
Shinya Kitaoka 120a6e
    usage.add(consoleQualifier + installQualifier + removeQualifier);
Shinya Kitaoka 120a6e
    if (!usage.parse(argc, argv)) exit(1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Shinya Kitaoka 120a6e
    if (installQualifier.isSelected()) {
Shinya Kitaoka 120a6e
      char szPath[512];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      if (installQualifier.getValue() != "")
Shinya Kitaoka 120a6e
        serviceDisplayName = installQualifier.getValue();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      if (GetModuleFileName(NULL, szPath, 512) == 0) {
Shinya Kitaoka 120a6e
        std::cout << "Unable to install";
Shinya Kitaoka 120a6e
        std::cout << serviceName << " - ";
Shinya Kitaoka 120a6e
        std::cout << getLastErrorText().c_str() << std::endl << std::endl;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
        return 0;
Shinya Kitaoka 120a6e
      }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      TService::install(serviceName, serviceDisplayName, TFilePath(szPath));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      return 0;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (removeQualifier.isSelected()) {
Shinya Kitaoka 120a6e
      TService::remove(serviceName);
Shinya Kitaoka 120a6e
      return 0;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (consoleQualifier.isSelected()) console = true;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TSystem::hasMainLoop(false);
Shinya Kitaoka 120a6e
  TService::instance()->run(argc, argv, console);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}