diff --git a/README.md b/README.md index 21287b7..78089d8 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Sync files across directories: | Class | Description | |---------------|-------------| -| Execute | Issues shell commands.| +| Execute | Issues com.olexyn.ensync.shell commands.| | Main | Main class. Run from here.| | Routines | Contains higher level routines.| | Tools | Simple tools used by other classes.| @@ -30,4 +30,6 @@ Sync files across directories: ### Issues - What about parallel Threads? -- What about error handling? (i.e. if a web-directory is not available) \ No newline at end of file +- What about error handling? (i.e. if a web-directory is not available) +- Make commands more expressive e.g. collection dir dir dir -> keep all 3 dirs on sync. +- Figure out a way to handle deletions. \ No newline at end of file diff --git a/src/com/olexyn/ensync/Core.java b/src/com/olexyn/ensync/Core.java new file mode 100644 index 0000000..3ec0003 --- /dev/null +++ b/src/com/olexyn/ensync/Core.java @@ -0,0 +1,13 @@ +package com.olexyn.ensync; + +import java.util.List; + +public class Core { + + + public Core(){ + + } + + +} diff --git a/src/com/olexyn/ensync/Main.java b/src/com/olexyn/ensync/Main.java index 56cfa50..32fff86 100644 --- a/src/com/olexyn/ensync/Main.java +++ b/src/com/olexyn/ensync/Main.java @@ -1,24 +1,109 @@ package com.olexyn.ensync; -import java.io.BufferedReader; -import java.util.ArrayList; -import java.util.List; +import com.olexyn.ensync.artifacts.SyncDirectory; +import com.olexyn.ensync.artifacts.SyncEntity; -public class Main { +import java.io.File; +import java.util.*; +public class Main { public static void main(String[] args) { - String conf = new Tools().getConf(); - List cmdBuffer = new Routines().parseConfToCmdBuffer(conf); + Tools tools = new Tools(); + Execute x = new Execute(); + + + SyncEntity syncEntity = new SyncEntity("test"); + syncEntity.addDirectory("/home/user/test/a"); + syncEntity.addDirectory("/home/user/test/b"); + syncEntity.addDirectory("/home/user/test/c"); + + int br1 = 0; + + while (true) { + + for (Map.Entry entry : syncEntity.syncDirectories.entrySet()) { + + SyncDirectory syncDirectory = entry.getValue(); + + + syncDirectory.updateStateFileNew(); + syncDirectory.updatePoolNew(); + + // + for (File createdFile : syncDirectory.getListCreated()) { + for (Map.Entry otherEntry : syncEntity.syncDirectories.entrySet()) { + SyncDirectory otherSyncDirectory = otherEntry.getValue(); + + if (!syncDirectory.equals(otherSyncDirectory)){ + // Example: + // syncDirectory /foo + // otherSyncDirectory /bar + // createdFile /foo/hello/created-file.gif + // relativePath /hello/created-file.gif + String relativePath = createdFile.getPath().replace(syncDirectory.realPath, ""); + String targetPath = otherSyncDirectory.realPath + relativePath; + String targetParentPath = new File(targetPath).getParent(); + if (!new File(targetParentPath).exists()){ + String[] cmd = new String[]{"mkdir", + "-p", + targetParentPath}; + x.execute(cmd); + } + + String[] cmd = new String[]{"cp", + createdFile.getPath(), + otherSyncDirectory.realPath + relativePath}; + x.execute(cmd); + } + } + + } + + // + for (File deletedFile : syncDirectory.getListDeleted()) { + + for (Map.Entry otherEntry : syncEntity.syncDirectories.entrySet()) { + SyncDirectory otherSyncDirectory = otherEntry.getValue(); + + if (!syncDirectory.equals(otherSyncDirectory)){ + String relativePath = deletedFile.getPath().replace(syncDirectory.realPath, ""); + String[] cmd = new String[]{"rm", "-r", + otherSyncDirectory.realPath + relativePath}; + x.execute(cmd); + } + } + + } + + + syncEntity.addToMapCreated(syncDirectory.getListCreated()); + syncEntity.addToMapDeleted(syncDirectory.getListDeleted()); +// + // WARNING: + // Be very carefull when to update the StateFileOld + // i.e. you create a File and update StateFileOld without updating + // -> create newFile -> update StateFileNew-> getListCreated contains newFile -> addToMapCreated -> create copies as needed -> updateStateFileOld -> OK + // -> create newFile -> update StateFileOld -> getListDeletd contains newFile -> VERY BAD + // + syncDirectory.updateStateFileBoth(); + syncDirectory.updatePoolBoth(); + + - System.out.println("bar"); - new Execute().executeBatch(cmdBuffer); + } + //Map mapCreated = syncEntity.getMapCreated(); + //Map mapDeleted = syncEntity.getMapDeleted(); - String br = null; + int br = 0; + try {Thread.sleep(1000);} + catch (InterruptedException e){ + } + } } } diff --git a/src/com/olexyn/ensync/Tools.java b/src/com/olexyn/ensync/Tools.java index c77b774..e7ea453 100644 --- a/src/com/olexyn/ensync/Tools.java +++ b/src/com/olexyn/ensync/Tools.java @@ -1,7 +1,11 @@ package com.olexyn.ensync; import java.io.BufferedReader; +import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -15,14 +19,21 @@ public class Tools { /** + * */ - public void rsync(String param , String source , String destination) { + public void rsync(String param, + String source, + String destination) { // - BufferedReader foo = x.execute(new String[]{"rsync", param, source, destination}).output; + BufferedReader foo = x.execute(new String[]{"rsync", + param, + source, + destination}).output; } - public String getConf(){ - BufferedReader output = x.execute(new String[]{"cat", System.getProperty("user.dir")+"/src/com/olexyn/ensync/sync.conf"}).output; + public String getConf() { + BufferedReader output = x.execute(new String[]{"cat", + System.getProperty("user.dir") + "/src/com/olexyn/ensync/sync.conf"}).output; return brToString(output); } @@ -34,4 +45,79 @@ public class Tools { } return sb.toString(); } + + /** + * StateFile -> FilePool + */ + public Map fileToPool(File file, + String type) { + List lines = fileToLines(file); + return linesToFilePool(lines, type); + } + + + /** + * CREATE a StateFile from realPath.

+ * WRITE the StateFle to stateFilePath. + * @param realPath the path of the directory the StateFile is created for. + * @param stateFilePath the desired path for the created Statefile. + */ + public File generateStateFile(String realPath, String stateFilePath) { + String[] cmd = new String[]{System.getProperty("user.dir") + "/src/com/olexyn/ensync/shell/toFile.sh", + "find", + realPath, + stateFilePath}; + x.execute(cmd); + return new File(realPath); + } + + + public List fileToLines(File file) { + String filePath = file.getPath(); + List lines = null; + try { + lines = Files.readAllLines(Paths.get(filePath)); + } catch (IOException e) { + e.printStackTrace(); + } + return lines; + } + + + public Map linesToFilePool(List lines, + String type) { + + Map filepool = new HashMap<>(); + + for (String line : lines) { + File file = new File(line); + + if (type.equals("all") || type.equals("dir") && file.isDirectory() || type.equals("file") && file.isFile()) { + filepool.put(line, file); + } + } + return filepool; + } + + + public List mapMinus(Map fromA, + Map substractB) { + + List difference = new ArrayList<>(); + Iterator iterator = fromA.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = (Map.Entry) iterator.next(); + String key = (String) entry.getKey(); + + File file = fromA.get(key); + + + if (fromA.containsKey(key) && !substractB.containsKey(key)) { + difference.add(file); + } + + + } + return difference; + } } diff --git a/src/com/olexyn/ensync/artifacts/SyncDirectory.java b/src/com/olexyn/ensync/artifacts/SyncDirectory.java new file mode 100644 index 0000000..8967730 --- /dev/null +++ b/src/com/olexyn/ensync/artifacts/SyncDirectory.java @@ -0,0 +1,134 @@ +package com.olexyn.ensync.artifacts; + +import com.olexyn.ensync.Tools; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class SyncDirectory { + + public String realPath; + public String stateFileBasePath; + public String stateFileOldPath; + public String stateFileNewPath; + public File stateFileOld; + public File stateFileNew; + private Map poolOld = new HashMap<>(); + private Map poolNew = new HashMap<>(); + private List listCreated = new ArrayList<>(); + private List listDeleted = new ArrayList<>(); + + + Tools tools = new Tools(); + + /** + * Create a SyncDirectory from realPath. + * + * @param realPath + * @see SyncEntity + */ + public SyncDirectory(String realPath) { + this.realPath = realPath; + stateFileBasePath = "/tmp/find" + this.realPath.replace("/", "-"); + stateFileOldPath = stateFileBasePath + "-old"; + stateFileNewPath = stateFileBasePath + "-new"; + stateFileOld = getStateFileOld(); + stateFileNew = getStateFileNew(); + poolOld = getPoolOld(); + poolNew = getPoolNew(); + + } + + /** + * IF NOT EXISTS the StateFileOld for this SyncDirectory,

+ * - THEN create the File on Disk. + * + * @return the StateFileOld. + */ + public File getStateFileOld() { + stateFileOld = new File(stateFileOldPath); + if (!stateFileOld.exists()) { + stateFileOld = tools.generateStateFile(realPath, stateFileOldPath); + } + return stateFileOld; + } + + /** + * READ directory contents.

+ * WRITE a new StateFileNew to Disk. This is IMPORTANT in order to make sure that StateFileOld is NEVER newer than StateFileNew.

+ * WRITE a new StateFileOld to Disk. + */ + public void updateStateFileBoth() { + // + tools.generateStateFile(realPath, stateFileNewPath); + tools.generateStateFile(realPath, stateFileOldPath); + } + + public File getStateFileNew() { + stateFileNew = new File(stateFileNewPath); + if (!stateFileNew.exists()) { + stateFileNew = tools.generateStateFile(realPath, stateFileNewPath); + } + return stateFileNew; + } + + /** + * READ directory contents.

+ * WRITE a new StateFileNew Disk. + */ + public void updateStateFileNew() { + // + tools.generateStateFile(realPath, stateFileNewPath); + } + + + public Map getPoolOld() { + if (poolOld.isEmpty()) { + updatePoolBoth(); + } + return poolOld; + } + + /** + * UPDATE PoolOld FROM contents of StateFileOld. + */ + public void updatePoolBoth() { + poolNew = tools.fileToPool(getStateFileNew(), "all"); + poolOld = tools.fileToPool(getStateFileOld(), "all"); + + } + + + public Map getPoolNew() { + if (poolNew.isEmpty()) { + updatePoolNew(); + } + return poolNew; + } + + /** + * UPDATE PoolNew FROM contents of StateFileNew. + */ + public void updatePoolNew() { + poolNew = tools.fileToPool(getStateFileNew(), "all"); + + } + + public List getListCreated() { + + listCreated = tools.mapMinus(getPoolNew(), getPoolOld()); + + return listCreated; + } + + public List getListDeleted() { + + listDeleted = tools.mapMinus(getPoolOld(), getPoolNew()); + + return listDeleted; + } + +} diff --git a/src/com/olexyn/ensync/artifacts/SyncEntity.java b/src/com/olexyn/ensync/artifacts/SyncEntity.java new file mode 100644 index 0000000..16f2c6b --- /dev/null +++ b/src/com/olexyn/ensync/artifacts/SyncEntity.java @@ -0,0 +1,86 @@ +package com.olexyn.ensync.artifacts; + + +import com.olexyn.ensync.Tools; + +import java.io.File; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * A SyncEntity is a collection of SyncDirectories, + * that are supposed to be kept in sync. + */ +public class SyncEntity { + + public String name; + public int syncInterval = 3600; + public Map syncDirectories = new HashMap<>(); + private Map mapCreated = new HashMap<>(); + private Map mapDeleted = new HashMap<>(); + Tools tools = new Tools(); + + /** + * @see SyncEntity + */ + public SyncEntity(String name) { + this.name = name; + + } + + /** + * Creates a new Syncdirectory. + *

+ * Adds the created SyncDirectory to this SyncEntity. + * + * @param realPath the path from which the Syncdirectory is created. + * @see SyncDirectory + */ + public void addDirectory(String realPath) { + if (new File(realPath).isDirectory()) { + syncDirectories.put(realPath, new SyncDirectory(realPath)); + } + } + + public Map getMapCreated() { + for (Map.Entry entry : syncDirectories.entrySet()) { + SyncDirectory syncDirectory = entry.getValue(); + for (File file : syncDirectory.getListCreated()) { + mapCreated.put(file.getPath(), file); + } + + } + + + return mapCreated; + } + + public Map getMapDeleted() { + + for (Map.Entry entry : syncDirectories.entrySet()) { + SyncDirectory syncDirectory = entry.getValue(); + for (File file : syncDirectory.getListDeleted()) { + mapDeleted.put(file.getPath(), file); + } + + } + + + return mapDeleted; + } + + public void addToMapCreated(List listCreated) { + for (File file : listCreated) { + mapCreated.put(file.getPath(), file); + } + } + + + public void addToMapDeleted(List listDeleted) { + for (File file : listDeleted) { + mapDeleted.put(file.getPath(), file); + } + } + +} diff --git a/src/com/olexyn/ensync/file-ops-covered-vs-missing.png b/src/com/olexyn/ensync/file-ops-covered-vs-missing.png new file mode 100644 index 0000000..c6ed079 Binary files /dev/null and b/src/com/olexyn/ensync/file-ops-covered-vs-missing.png differ diff --git a/src/com/olexyn/ensync/file-ops-covered-vs-missing.uxf b/src/com/olexyn/ensync/file-ops-covered-vs-missing.uxf new file mode 100644 index 0000000..29b776f --- /dev/null +++ b/src/com/olexyn/ensync/file-ops-covered-vs-missing.uxf @@ -0,0 +1,458 @@ + + + 10 + + UMLObject + + 290 + 420 + 110 + 40 + + Directory B + + + + UMLObject + + 290 + 380 + 110 + 40 + + Directory A + + + + UMLObject + + 290 + 230 + 110 + 40 + + Delete +bg=red +group=1 + + + + UMLObject + + 290 + 270 + 110 + 40 + + Create +bg=green +group=1 + + + + UMLObject + + 290 + 310 + 110 + 40 + + Modify +bg=yellow +group=1 + + + + UMLState + + 440 + 530 + 70 + 40 + + YES +bg=green + + + + UMLState + + 440 + 420 + 70 + 40 + + File + + + + UMLState + + 530 + 420 + 70 + 40 + + File +bg=red + + + + UMLState + + 890 + 530 + 70 + 40 + + NO +bg=red + + + + UMLObject + + 290 + 190 + 110 + 40 + + Unchanged +bg=white +group=1 + + + + UMLState + + 440 + 380 + 70 + 40 + + File + + + + UMLState + + 530 + 380 + 70 + 40 + + File + + + + UMLState + + 620 + 420 + 70 + 40 + + File +bg=red + + + + UMLState + + 620 + 380 + 70 + 40 + + File +bg=red + + + + UMLState + + 710 + 420 + 70 + 40 + + File +bg=green + + + + UMLState + + 710 + 380 + 70 + 40 + + File + + + + UMLState + + 800 + 420 + 70 + 40 + + File +bg=green + + + + UMLState + + 800 + 380 + 70 + 40 + + File +bg=green + + + + UMLState + + 890 + 420 + 70 + 40 + + File +bg=yellow + + + + UMLState + + 890 + 380 + 70 + 40 + + File + + + + UMLState + + 980 + 420 + 70 + 40 + + File +bg=yellow + + + + UMLState + + 980 + 380 + 70 + 40 + + File +bg=yellow + + + + UMLState + + 1070 + 380 + 70 + 40 + + File +bg=red + + + + UMLState + + 1070 + 420 + 70 + 40 + + File +bg=green + + + + UMLState + + 1160 + 380 + 70 + 40 + + File +bg=red + + + + UMLState + + 1160 + 420 + 70 + 40 + + File +bg=yellow + + + + UMLState + + 1250 + 380 + 70 + 40 + + File +bg=green + + + + UMLState + + 1250 + 420 + 70 + 40 + + File +bg=yellow + + + + UMLNote + + 420 + 190 + 150 + 80 + + 2^4 = 16 +however only 10 +because 6 are symmetrical. +bg=white + + + + UMLObject + + 290 + 530 + 110 + 40 + + Covered? + + + + UMLState + + 620 + 530 + 70 + 40 + + MAYBE +bg=yellow + + + + UMLState + + 530 + 530 + 70 + 40 + + YES +bg=green + + + + UMLState + + 710 + 530 + 70 + 40 + + YES +bg=green + + + + UMLState + + 980 + 530 + 70 + 40 + + NO +bg=red + + + + UMLState + + 1160 + 530 + 70 + 40 + + NO +bg=red + + + + UMLState + + 1250 + 530 + 70 + 40 + + NO +bg=red + + + + UMLState + + 800 + 530 + 70 + 40 + + NO +bg=red + + + + UMLState + + 1070 + 530 + 70 + 40 + + NO +bg=red + + + diff --git a/src/com/olexyn/ensync/handle-deletes.png b/src/com/olexyn/ensync/handle-deletes.png new file mode 100644 index 0000000..4bc2151 Binary files /dev/null and b/src/com/olexyn/ensync/handle-deletes.png differ diff --git a/src/com/olexyn/ensync/handle-deletes.uxf b/src/com/olexyn/ensync/handle-deletes.uxf new file mode 100644 index 0000000..1382bbd --- /dev/null +++ b/src/com/olexyn/ensync/handle-deletes.uxf @@ -0,0 +1,588 @@ + + + 10 + + UMLClass + + 250 + 120 + 140 + 40 + + File System +halign=left + + + + Relation + + 310 + 150 + 160 + 280 + + lt=<- + 140.0;260.0;10.0;10.0 + + + UMLClass + + 100 + 580 + 120 + 60 + + Collection of +Accepted +State Files +halign=left + + + + UMLState + + 370 + 410 + 170 + 40 + + User initiates a +File System update. +halign=left + + + + Relation + + 210 + 590 + 180 + 30 + + lt=. + 10.0;10.0;160.0;10.0 + + + UMLState + + 370 + 570 + 150 + 60 + + Check if a newer +State File +is available +halign=left + + + + UMLState + + 80 + 240 + 170 + 40 + + Update State File +from File System +halign=left + + + + UMLClass + + 100 + 500 + 130 + 40 + + Last Accepted +State File +bg=green +halign=left + + + + UMLClass + + 100 + 320 + 130 + 40 + + Current +State File +bg=yellow +halign=left + + + + UMLState + + 80 + 410 + 160 + 40 + + Accept State File + + + + Relation + + 430 + 440 + 40 + 150 + + lt=<- + 10.0;130.0;20.0;10.0 + + + Relation + + 150 + 350 + 30 + 80 + + lt=<- + 10.0;60.0;10.0;10.0 + + + Relation + + 310 + 620 + 150 + 120 + + lt=<- +[YES] + 10.0;100.0;130.0;10.0 + + + UMLState + + 240 + 720 + 170 + 60 + + Update File System +according to newest +State File + + + + Relation + + 150 + 440 + 30 + 80 + + lt=<- + 10.0;60.0;10.0;10.0 + + + Relation + + 150 + 150 + 190 + 110 + + lt=<- + 10.0;90.0;170.0;10.0 + + + Relation + + 150 + 270 + 30 + 70 + + lt=<- + 10.0;50.0;10.0;10.0 + + + Relation + + 150 + 530 + 30 + 70 + + lt=. + 10.0;10.0;10.0;50.0 + + + UMLClass + + 860 + 0 + 340 + 50 + + SyncEntity +-- +Map<SyncDirectory> directories +halign=left + + + + UMLClass + + 1300 + 90 + 230 + 200 + + SyncDirectory + +-- +String realPath +String stateFileBasePath +File stateFileOld +File stateFileNew +Map<String,File> poolOld +Map<String,File> poolNew +List<String> listCreated +List<String> listDeleted +halign=left + + + + Relation + + 1190 + 30 + 130 + 90 + + lt=<- + 110.0;70.0;10.0;10.0 + + + UMLClass + + 1620 + 740 + 130 + 60 + + StateFileOld +bg=yellow +halign=left + + + + UMLClass + + 1750 + 740 + 130 + 30 + + StateFileNew +bg=green +halign=left + + + + UMLClass + + 1750 + 770 + 130 + 30 + + ListDeleted +halign=left + + + + UMLClass + + 1620 + 820 + 130 + 30 + + StateFileOld +bg=yellow +halign=left + + + + UMLClass + + 1750 + 820 + 130 + 60 + + StateFileNew +bg=green +halign=left + + + + UMLClass + + 1620 + 850 + 130 + 30 + + ListCreated +halign=left + + + + UMLState + + 1220 + 650 + 170 + 60 + + update +StateFileNew + + + + UMLState + + 1190 + 770 + 120 + 40 + + get +ListCreated + + + + UMLState + + 1310 + 770 + 120 + 40 + + get +ListDeleted + + + + Relation + + 1230 + 700 + 90 + 90 + + lt=<- + 10.0;70.0;70.0;10.0 + + + Relation + + 1310 + 700 + 80 + 90 + + lt=<- + 60.0;70.0;10.0;10.0 + + + UMLState + + 1190 + 850 + 120 + 40 + + add to +MapCreated + + + + UMLState + + 1310 + 850 + 120 + 40 + + add to +MapDeleted + + + + Relation + + 1360 + 800 + 30 + 70 + + lt=<- + 10.0;50.0;10.0;10.0 + + + Relation + + 1240 + 800 + 30 + 70 + + lt=<- + 10.0;50.0;10.0;10.0 + + + UMLState + + 1230 + 970 + 170 + 60 + + Perform +File Operations +for Sycronization + + + + Relation + + 1310 + 880 + 80 + 110 + + lt=<- + 10.0;90.0;60.0;10.0 + + + Relation + + 1240 + 880 + 100 + 110 + + lt=<- + 80.0;90.0;10.0;10.0 + + + UMLClass + + 1020 + 610 + 440 + 320 + + For Each SyncDirectory +halign=left +layer=-1 + + + + UMLClass + + 1600 + 720 + 300 + 180 + + +halign=left +layer=-1 + + + + Relation + + 1420 + 780 + 200 + 50 + + lt=. + 180.0;30.0;10.0;10.0 + + + Relation + + 1280 + 580 + 40 + 90 + + lt=<- + 10.0;70.0;20.0;10.0 + + + UMLSpecialState + + 1290 + 570 + 20 + 20 + + type=initial + + + + UMLSpecialState + + 1300 + 1200 + 20 + 20 + + type=final + + + + Relation + + 1300 + 1020 + 30 + 80 + + lt=<- + 10.0;60.0;10.0;10.0 + + + Relation + + 1290 + 1130 + 40 + 90 + + lt=<- + 20.0;70.0;10.0;10.0 + + + UMLState + + 1220 + 1080 + 170 + 60 + + update +StateFileBoth + + + diff --git a/src/com/olexyn/ensync/shell/pipe.sh b/src/com/olexyn/ensync/shell/pipe.sh new file mode 100755 index 0000000..dc6f96c --- /dev/null +++ b/src/com/olexyn/ensync/shell/pipe.sh @@ -0,0 +1,6 @@ +#!/bin/bash +a=$1 +b=$2 +$a | $b + +# this is a pipe \ No newline at end of file diff --git a/src/com/olexyn/ensync/shell/pipe2.sh b/src/com/olexyn/ensync/shell/pipe2.sh new file mode 100755 index 0000000..826e21f --- /dev/null +++ b/src/com/olexyn/ensync/shell/pipe2.sh @@ -0,0 +1,7 @@ +#!/bin/bash +a=$1 +b=$2 +c=$3 +$a | $b | $c + +# this is a double pipe \ No newline at end of file diff --git a/src/com/olexyn/ensync/shell/toFile.sh b/src/com/olexyn/ensync/shell/toFile.sh new file mode 100755 index 0000000..8585b3d --- /dev/null +++ b/src/com/olexyn/ensync/shell/toFile.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +a=$1 +b=$2 +c=$3 + +$a $b > $c \ No newline at end of file diff --git a/src/com/olexyn/ensync/sync.conf b/src/com/olexyn/ensync/sync.conf deleted file mode 100644 index b2aca4c..0000000 --- a/src/com/olexyn/ensync/sync.conf +++ /dev/null @@ -1,13 +0,0 @@ -# -u update -# -r recursive -# -v verbose -# -t keep modification times -# -W whole file (faster if network bandwith is faster then disk bandwith) -# -# examples: -# ./dirA -- urvtW -> ./dirB -# ./dirA <- urvtW ---- urvtW -> ./dirB -/home/user/ws/idea/env-sync/src/com/olexyn/ensync/tmp/in/ <- urvtW ---- urvtW -> /home/user/ws/idea/env-sync/src/com/olexyn/ensync/tmp/out/ -# backup -# /home/user/ws/ -- urvtW -> /media/time/backup/auto/ws -/home/user/wiki/ -- urvtW -> /media/time/backup/auto/wiki \ No newline at end of file