FIND_LOCAL_COMMAND(LIBBATCH_RCP_COMMAND rcp rcp)
FIND_LOCAL_COMMAND(LIBBATCH_SSH_COMMAND ssh plink)
FIND_LOCAL_COMMAND(LIBBATCH_SCP_COMMAND scp pscp)
+ FIND_LOCAL_COMMAND(LIBBATCH_RSYNC_COMMAND rsync pscp)
EVAL (HAS_SH LIBBATCH_SH_COMMAND AND LIBBATCH_CP_COMMAND AND LIBBATCH_RM_COMMAND AND LIBBATCH_MKDIR_COMMAND)
EVAL (HAS_RSH LIBBATCH_RSH_COMMAND AND LIBBATCH_RCP_COMMAND)
EVAL (HAS_SSH LIBBATCH_SSH_COMMAND AND LIBBATCH_SCP_COMMAND)
+ EVAL (HAS_RSYNC LIBBATCH_SSH_COMMAND AND LIBBATCH_RSYNC_COMMAND)
# Mark shell commands as advanced options
# and assign the names without the LIBBATCH_ in front:
- SET (_cmds "RM;SH;CP;MKDIR;RSH;RCP;SSH;SCP")
+ SET (_cmds "RM;SH;CP;MKDIR;RSH;RCP;SSH;SCP;RSYNC")
FOREACH(_cmd ${_cmds})
MARK_AS_ADVANCED(LIBBATCH_${_cmd}_COMMAND)
SET(${_cmd}_COMMAND ${LIBBATCH_${_cmd}_COMMAND})
/* SSH tools (ssh, scp) found on the system */
#cmakedefine HAS_SSH
+/* SSH tools and rsync found */
+#cmakedefine HAS_RSYNC
+
/* A path to a ssh-like command */
#cmakedefine SSH_COMMAND "@SSH_COMMAND@"
/* A path to a scp-like command */
#cmakedefine SCP_COMMAND "@SCP_COMMAND@"
+/* A path to a scp-like command */
+#cmakedefine RSYNC_COMMAND "@RSYNC_COMMAND@"
+
#endif
CoupleType cpt = *static_cast< CoupleType * >(*Vit);
Couple outputFile = cpt;
string remotePath = outputFile.getRemote();
- if (!Utils::isAbsolutePath(remotePath)) {
- remotePath = params[WORKDIR].str() + "/" + remotePath;
+ if (!Utils::isAbsolutePath(remotePath) && !Utils::isOption(remotePath)) {
+ // rsync creates the whole tree after /./ in the destination folder
+ remotePath = params[WORKDIR].str() + "/./" + remotePath;
}
string localPath = outputFile.getLocal();
if (!Utils::isAbsolutePath(localPath)) {
localPath = directory + "/" + localPath;
}
- status = CommunicationProtocol::getInstance(SH).makeDirectory(
- Utils::dirname(localPath), "", "");
- if (status)
- LOG("Directory creation failed. Status is: " << status);
status = _protocol.copyFile(remotePath, _hostname, _username,
localPath, "", "");
if (status)
APPEND_CLASSES_TO_SRC_FILES(Core/CommunicationProtocolSSH)
ENDIF (HAS_SSH)
+IF (HAS_RSYNC)
+ APPEND_CLASSES_TO_SRC_FILES(Core/CommunicationProtocolRsync)
+ENDIF (HAS_RSYNC)
+
IF (LIBBATCH_BUILD_TESTS)
ADD_SUBDIRECTORY(Test)
#ifdef HAS_SSH
#include "CommunicationProtocolSSH.hxx"
#endif
+#ifdef HAS_RSYNC
+ #include "CommunicationProtocolRsync.hxx"
+#endif
#include "APIInternalFailureException.hxx"
#include "RunTimeException.hxx"
#include "Log.hxx"
+#include "Utils.hxx"
using namespace std;
#else
throw RunTimeException("Can't use SSH protocol (SSH tools were "
"not found on the system at compile time).");
+#endif
+ } else if (protocolType == RSYNC) {
+#ifdef HAS_RSYNC
+ static CommunicationProtocolRsync instanceRsync;
+ return instanceRsync;
+#else
+ throw RunTimeException("Can't use RSYNC protocol (RSYNC tools were "
+ "not found on the system at compile time).");
#endif
} else
throw APIInternalFailureException("Unknown communication protocol.");
// if the argument contains spaces, we surround it with simple quotes (Linux)
// or double quotes (Windows)
- if (commandArgs[i].find(' ') != string::npos) {
+ if (commandArgs[i].find(' ') != string::npos &&
+ !Utils::isOption(commandArgs[i])){
commandStr += string("\"") + commandArgs[i] + "\"";
} else {
commandStr += commandArgs[i];
namespace Batch {
- enum CommunicationProtocolType {SH, SSH, RSH};
+ enum CommunicationProtocolType {SH, SSH, RSH, RSYNC};
class BATCH_EXPORT CommunicationProtocol
{
--- /dev/null
+// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library 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. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * CommunicationProtocolRsync.cxx :
+ *
+ * Author : EDF R&D
+ */
+
+#include <libbatch_config.h>
+#include "Utils.hxx"
+
+#include "CommunicationProtocolRsync.hxx"
+
+using namespace std;
+
+namespace Batch {
+
+ CommunicationProtocolRsync::CommunicationProtocolRsync()
+ : CommunicationProtocolSSH()
+ {
+ _type = RSYNC;
+ }
+
+ vector<string> CommunicationProtocolRsync::getCopyCommandArgs(const string & sourcePath,
+ const string & sourceHost,
+ const string & sourceUser,
+ const string & destinationPath,
+ const string & destinationHost,
+ const string & destinationUser) const
+ {
+ vector<string> cmd;
+
+ string fullSource;
+
+ if(Utils::isOption(sourcePath))
+ fullSource += sourcePath;
+ else
+ {
+ if (sourceHost.size() != 0) {
+ if (sourceUser.size() != 0) {
+ fullSource += sourceUser + "@";
+ }
+ fullSource += sourceHost + ":";
+ }
+#ifndef WIN32
+ fullSource += "'";
+#endif
+ fullSource += sourcePath;
+#ifndef WIN32
+ fullSource += "'";
+#endif
+ }
+
+ string fullDestination;
+ if (destinationHost.size() != 0) {
+ if (destinationUser.size() != 0) {
+ fullDestination += destinationUser + "@";
+ }
+ fullDestination += destinationHost + ":";
+ }
+#ifndef WIN32
+ fullDestination += "'";
+#endif
+ fullDestination += destinationPath;
+#ifndef WIN32
+ fullDestination += "'";
+#endif
+
+ // Option -p is used to keep the same permissions for the destination file
+ // (particularly useful to keep scripts executable when copying them)
+ cmd.push_back(RSYNC_COMMAND);
+ if(!Utils::isOption(sourcePath))
+ {
+ cmd.push_back("-p");
+ cmd.push_back("-r");
+ if(Utils::usesRsyncRelativePath(sourcePath))
+ cmd.push_back("-R");
+ }
+ cmd.push_back(fullSource);
+ cmd.push_back(fullDestination);
+
+ return cmd;
+ }
+
+}
--- /dev/null
+// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library 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. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * CommunicationProtocolRsync.hxx :
+ *
+ * Author : EDF R&D
+ */
+
+#ifndef _BATCHCOMMUNICATIONPROTOCOLRSYNC_H_
+#define _BATCHCOMMUNICATIONPROTOCOLRSYNC_H_
+
+#include <string>
+#include <vector>
+
+#include "Defines.hxx"
+#include "CommunicationProtocolSSH.hxx"
+
+namespace Batch {
+
+ class BATCH_EXPORT CommunicationProtocolRsync : public CommunicationProtocolSSH
+ {
+ friend class CommunicationProtocol;
+
+ public:
+ std::vector<std::string> getCopyCommandArgs(const std::string & sourcePath,
+ const std::string & sourceHost,
+ const std::string & sourceUser,
+ const std::string & destinationPath,
+ const std::string & destinationHost,
+ const std::string & destinationUser) const;
+
+ protected:
+
+ CommunicationProtocolRsync();
+
+ };
+
+}
+
+#endif
return std::string(".");
}
+bool Utils::isOption(const std::string & val)
+{
+ return val.size() > 0 && val[0] == '-';
+}
+
+bool Utils::usesRsyncRelativePath(const std::string & path)
+{
+ return path.find("/./") != std::string::npos;
+}
+
string Utils::createAndOpenTemporaryFile(const string & prefix, ofstream & outputStream)
{
if (outputStream.is_open())
*/
static std::string dirname(const std::string & path);
+ /**
+ * Test if the string in parameter begins with '-' and it should be processed
+ * as an option, not as a path.
+ */
+ static bool isOption(const std::string & val);
+
+ /**
+ * Test if the path in parameter contains a "/./" sequence.
+ */
+ static bool usesRsyncRelativePath(const std::string & path);
+
/**
* Create a temporary file and open an output stream to write into this file.
* The file is created with the pattern "<tmpdir>/libbatch-<prefix>-XXXXXX" where <tmpdir> is the