+ if (!subDirs.contains(parentDir) && !skipDir) {
+ subDirs.add(parentDir);
+ }
+
+ targetPaths.put(relPath, targetBase + "/" + relPath);
+ }
+
+ // checksum
+ List<String> targetPathsEqualsToLocal = new ArrayList<String>();
+ if (checksum != null) {
+ Map<String, String> remoteChecksums = new HashMap<String, String>();
+ List<String> csLines = new ArrayList<String>();
+ String csExecutable;
+ if ("MD5".equals(checksum))
+ csExecutable = "/usr/bin/md5sum";
+ else if ("SHA".equals(checksum))
+ csExecutable = "/usr/bin/sha1sum";
+ else if ("SHA-256".equals(checksum))
+ csExecutable = "/usr/bin/sha256sum";
+ else if ("SHA-512".equals(checksum))
+ csExecutable = "/usr/bin/sha512sum";
+ else
+ throw new SlcException(
+ "Don't know how to remotely execute checksum "
+ + checksum);
+
+ StringBuffer csCmd = new StringBuffer(csExecutable);
+ int numberOfPaths = targetPaths.size();
+ int count = 0;
+ for (String targetPath : targetPaths.values()) {
+ csCmd.append(" ").append(targetPath);
+ count++;
+
+ if ((count % remoteChecksumsPerCall == 0)
+ || count == numberOfPaths) {
+ RemoteExec remoteCs = new RemoteExec();
+ remoteCs.setSshTarget(getSshTarget());
+ remoteCs.setCommand(csCmd.toString());
+ remoteCs.setStdOutLines(csLines);
+ remoteCs.setFailOnBadExitStatus(false);
+ remoteCs.run(session);
+ csCmd = new StringBuffer(csExecutable);
+ }
+
+ }
+
+ remoteChecksums: for (String csLine : csLines) {
+ StringTokenizer st = new StringTokenizer(csLine, ": ");
+ String cs = st.nextToken();
+ if (cs.equals(csExecutable)) {
+ // remote does not exist
+ continue remoteChecksums;
+ } else {
+ String targetPath = st.nextToken();
+ if (log.isTraceEnabled())
+ log.trace("REMOTE: " + targetPath + "=" + cs);
+ remoteChecksums.put(targetPath, cs);
+ }
+ }
+
+ // Local checksums
+ for (String relPath : resources.keySet()) {
+ Resource resource = resources.get(relPath);
+ String targetPath = targetPaths.get(relPath);
+ if (remoteChecksums.containsKey(targetPath)) {
+ String cs = DigestCheck.digest(checksum, resource);
+ if (log.isTraceEnabled())
+ log.trace("LOCAL : " + targetPath + "=" + cs);
+ if (remoteChecksums.get(targetPath).equals(cs))
+ targetPathsEqualsToLocal.add(targetPath);
+ }
+ }
+ }
+
+ // Prepare multitask
+
+ // Create dirs
+ StringBuffer mkdirCmd = new StringBuffer("mkdir -p");
+ RemoteExec remoteExec = new RemoteExec();
+ for (String dir : subDirs) {
+ // remoteExec.getCommands().add("mkdir -p " + dir);
+ mkdirCmd.append(' ');
+ if (dir.indexOf(' ') >= 0)
+ mkdirCmd.append('\"').append(dir).append('\"');
+ else
+ mkdirCmd.append(dir);
+ }
+ remoteExec.setCommand(mkdirCmd.toString());
+ multiTasks.getTasks().add(remoteExec);
+
+ // Perform copies
+ int copied = 0;
+ int skipped = 0;
+ copy: for (String relPath : resources.keySet()) {
+ String targetPath = targetPaths.get(relPath);
+ if (targetPathsEqualsToLocal.contains(targetPath)) {
+ if (log.isTraceEnabled())
+ log.trace("Skip copy of " + relPath
+ + " since it is equal to remote " + targetPath);
+ skipped++;
+ continue copy;
+ }