Index: DistributedBackupService/delete.sh
===================================================================
--- DistributedBackupService/delete.sh	(nonexistent)
+++ DistributedBackupService/delete.sh	(revision 1)
@@ -0,0 +1,2 @@
+#!/bin/sh
+java -classpath bin client.TestApp 1 "DELETE" "files/dog.png"
\ No newline at end of file

Property changes on: DistributedBackupService/delete.sh
___________________________________________________________________
Added: svn:executable
Index: DistributedBackupService/rmi.sh
===================================================================
--- DistributedBackupService/rmi.sh	(nonexistent)
+++ DistributedBackupService/rmi.sh	(revision 1)
@@ -0,0 +1,2 @@
+cd bin/
+rmiregistry

Property changes on: DistributedBackupService/rmi.sh
___________________________________________________________________
Added: svn:executable
Index: DistributedBackupService/files/dog (22nd copy).png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: DistributedBackupService/files/dog (22nd copy).png
===================================================================
--- DistributedBackupService/files/dog (22nd copy).png	(nonexistent)
+++ DistributedBackupService/files/dog (22nd copy).png	(revision 1)

Property changes on: DistributedBackupService/files/dog (22nd copy).png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: DistributedBackupService/files/dog (23rd copy).png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: DistributedBackupService/files/dog (23rd copy).png
===================================================================
--- DistributedBackupService/files/dog (23rd copy).png	(nonexistent)
+++ DistributedBackupService/files/dog (23rd copy).png	(revision 1)

Property changes on: DistributedBackupService/files/dog (23rd copy).png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: DistributedBackupService/files/dog (24th copy).png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: DistributedBackupService/files/dog (24th copy).png
===================================================================
--- DistributedBackupService/files/dog (24th copy).png	(nonexistent)
+++ DistributedBackupService/files/dog (24th copy).png	(revision 1)

Property changes on: DistributedBackupService/files/dog (24th copy).png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: DistributedBackupService/files/dog.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: DistributedBackupService/files/dog.png
===================================================================
--- DistributedBackupService/files/dog.png	(nonexistent)
+++ DistributedBackupService/files/dog.png	(revision 1)

Property changes on: DistributedBackupService/files/dog.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: DistributedBackupService/src/chunk/Chunk.java
===================================================================
--- DistributedBackupService/src/chunk/Chunk.java	(nonexistent)
+++ DistributedBackupService/src/chunk/Chunk.java	(revision 1)
@@ -0,0 +1,109 @@
+package chunk;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicIntegerArray;
+
+public class Chunk {
+
+	private ConcurrentMap<String, AtomicIntegerArray> chunkReplication;
+
+	private String fileID;
+	private int chunkNo;
+	private int replication;
+	private byte[] data;
+	private int size;
+	private Set< Integer > chunks;
+
+	public Chunk(String fileID, int chunkNo, byte[] data) {
+		this.fileID = fileID;
+		this.chunkNo = chunkNo;
+		this.data = data;
+	}
+
+	public Chunk(String fileID, int chunkNo, int replication, byte[] data) {
+		this(fileID, chunkNo, data);
+		this.replication = replication;
+	}
+
+	public Chunk(Chunk chunkData, byte[] data) {
+		this(chunkData.getFileID(), chunkData.getChunkNo(), chunkData.getReplication(), data);
+	}
+
+	public Chunk(int chunkNo, int replication) {
+		this.chunkNo = chunkNo;
+		this.replication = replication;
+		this.chunks = new HashSet<>();
+	}
+
+	public Chunk(String fileID, int chunkNo, int replication, int size) {
+		this(chunkNo, replication);
+		this.fileID = fileID;
+		this.size = size;
+	}
+
+	// Peer information
+	public Chunk() {
+		chunkReplication = new ConcurrentHashMap<>();
+	}
+
+	public void resetChunkReplication(String fileID) {
+		chunkReplication.remove(fileID);
+	}
+
+	public void startChunkReplication(String fileID, int numChunks) {
+		chunkReplication.putIfAbsent(fileID, new AtomicIntegerArray(numChunks));
+	}
+
+	public Integer addChunkReplication(String fileID, int chunkNo) {
+		if (!chunkReplication.containsKey(fileID))
+			return null;
+
+		int replication = chunkReplication.get(fileID).addAndGet(chunkNo, 1);
+		System.out.println("Incrementing replication of " + fileID + "/" + chunkNo + " to " + replication);
+		return replication;
+	}
+
+	public int getChunkReplication(String fileID, int chunkNo) {
+		return chunkReplication.get(fileID).get(chunkNo);
+	}
+
+	public AtomicIntegerArray getChunkReplication(String fileID) {
+		return chunkReplication.get(fileID);
+	}
+
+	// Getters and setters 
+
+	public String getFileID() { return fileID; }
+
+	public int getChunkNo() { return chunkNo; }
+
+	public int getReplication() { return replication; }
+
+	public byte[] getData() { return data; }
+
+	public boolean removeChunk(Integer peerID) { return chunks.remove(peerID); }
+
+	public boolean addChunk(Integer peerID) { return chunks.add(peerID); }
+
+	public int getNumChunks() { return chunks.size(); }
+
+	public int getSize() { return size; }
+
+	public Set<Integer> getChunks() { return chunks; }
+
+	public void setFileID(String fileID) { this.fileID = fileID; }
+
+	public void setChunkNo(int chunkNo) { this.chunkNo = chunkNo; }
+
+	public void setReplication(int replication) { this.replication = replication; }
+
+	public void setData(byte[] data) { this.data = data; }
+
+	public void setSize(int size) { this.size = size; }
+
+	public void setChunks(Set<Integer> mirrors) { this.chunks = mirrors; }
+
+}
\ No newline at end of file

Property changes on: DistributedBackupService/src/chunk/Chunk.java
___________________________________________________________________
Added: svn:executable
Index: DistributedBackupService/src/chunk/FileManager.java
===================================================================
--- DistributedBackupService/src/chunk/FileManager.java	(nonexistent)
+++ DistributedBackupService/src/chunk/FileManager.java	(revision 1)
@@ -0,0 +1,152 @@
+package chunk;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+@SuppressWarnings("serial")
+public class FileManager implements Serializable {
+
+	private ConcurrentMap<String, FileManager> fileRepository;
+	private ConcurrentMap<String, ConcurrentMap<Integer, Chunk>> chunkRepository;
+
+	public FileManager() {
+		fileRepository = new ConcurrentHashMap<>();
+		chunkRepository = new ConcurrentHashMap<>();
+	}
+
+	private String fileID; 
+	private String pathName;
+	private String fileName;
+	private int numChunks;
+	private int wantedReplication;
+	private HashMap<String, Chunk> chunkMap;
+
+	public FileManager( File file, String fileID, int replicationDegree, HashMap<String, Chunk> chunksInfo ) {
+		this.fileID = fileID;
+		this.fileName = file.getName();
+		this.pathName = file.getPath();
+		this.numChunks = chunksInfo.size();
+		this.wantedReplication = replicationDegree;
+		this.chunkMap = chunksInfo;
+	}
+
+	public String getFileID() {
+		return fileID;
+	}
+
+	public int getNumChunks() {
+		return numChunks;
+	}
+
+	public String getPathname() {
+		return pathName;
+	}
+
+	public String getFileName() {
+		return fileName;
+	}
+
+	public int getWantedReplication() {
+		return wantedReplication;
+	}
+
+	public HashMap<String, Chunk> getChunks() {
+		return chunkMap;
+	}
+
+	synchronized public static FileManager loadDatabase(File file) throws ClassNotFoundException {
+		FileManager db = null;
+
+		try {
+			final ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(file));
+			db = (FileManager) inputStream.readObject();
+			inputStream.close();
+		} catch (final IOException pE) {
+			pE.printStackTrace();
+		}
+		return db;
+	}
+
+	public void addFile( String pathName, FileManager fileInfo ) {
+		fileRepository.put(pathName, fileInfo);
+	}
+
+	public void removeFile( String pathName ) {
+		fileRepository.remove(pathName);
+	}
+
+	public FileManager getFileInformation( String pathName) 
+	{
+		return fileRepository.get( pathName);
+	}
+
+	public void addChunk( Chunk chunk ) 
+	{
+		
+		String fileID = chunk.getFileID();
+		int chunkNo = chunk.getChunkNo();
+
+		ConcurrentMap<Integer, Chunk> fileChunks;
+		fileChunks = chunkRepository.getOrDefault(fileID, new ConcurrentHashMap<>());
+		fileChunks.putIfAbsent(chunkNo, chunk);
+
+		chunkRepository.putIfAbsent(fileID, fileChunks);
+
+	}
+ 
+	public Chunk getChunkInformation( String fileID, int chunkNo ) 
+	{
+		Map<Integer, Chunk> fileChunks = chunkRepository.get(fileID);
+
+		return fileChunks != null ? fileChunks.get(chunkNo) : null;
+	}
+
+	public void deleteChunk( String fileID, int chunkNo) 
+	{
+		if (!chunkRepository.containsKey(fileID))
+			return;
+
+		chunkRepository.get(fileID).remove(chunkNo);
+	}
+
+	public void deleteFileBackedUp( String fileID) 
+	{
+		if (!chunkRepository.containsKey( fileID))
+			return;
+
+		chunkRepository.remove(fileID);
+	}
+
+	public int getNumChunks(String pathname) {
+		return fileRepository.get(pathname).getNumChunks();
+	}
+
+	public Integer getRecognizedReplication(String fileID, int chunkNo) 
+	{
+		int ret;
+		try 
+		{	
+			ret = chunkRepository.get(fileID).get(chunkNo).getNumChunks();
+		} catch (NullPointerException e) {
+			return null;
+		}
+		return ret;
+	}
+
+	public boolean chunkExists(String fileID) {
+		return chunkRepository.containsKey(fileID);
+	}
+
+	public Set<Integer> getFileChunksKey(String fileID) {
+		return chunkRepository.get(fileID).keySet();
+	}
+
+}
\ No newline at end of file

Property changes on: DistributedBackupService/src/chunk/FileManager.java
___________________________________________________________________
Added: svn:executable
Index: DistributedBackupService/src/chunk/FolderManager.java
===================================================================
--- DistributedBackupService/src/chunk/FolderManager.java	(nonexistent)
+++ DistributedBackupService/src/chunk/FolderManager.java	(revision 1)
@@ -0,0 +1,190 @@
+package chunk;
+
+import java.io.*;
+import java.util.ArrayList;
+import chunk.FileManager;
+import server.Peer;
+import utils.Utils;
+
+import static java.util.Arrays.copyOfRange;
+
+public class FolderManager {
+	private static long maxMemory;
+	private static long usedMemory;
+	private Peer peer;
+	private String path;
+	private FileManager fileManager;
+	private static int chunkSizeLimit;
+
+	public FolderManager(Peer peer, long maxMemory) throws ClassNotFoundException {
+		this.peer = peer;
+		FolderManager.maxMemory = maxMemory;
+
+		chunkSizeLimit = 64000;
+		usedMemory = 0;
+		path = "results/peer_" + peer.getID() + "/";
+
+		File db = new File(path + "db");
+
+		if (db.exists()) {
+			fileManager = FileManager.loadDatabase(db);
+		} else {
+			fileManager = new FileManager();
+		}
+		makeDir(path + Utils.CHUNKS);
+	}
+
+	public static void makeDir(String name) {
+		File file = new File(name);
+		file.mkdirs();
+	}
+
+	synchronized public static boolean backupFile(String name, String path, byte[] information) throws IOException {
+		if (getFreeMemory() < information.length) {
+			System.out.println("Without space to backup file");
+			return false;
+		}
+		FileOutputStream out;
+		out = new FileOutputStream(path + "/" + name);
+		out.write(information);
+		out.close();
+
+		return FolderManager.incrUsedMemory(information.length);
+	}
+
+	synchronized public static byte[] loadFile(File file) throws IOException {
+		FileInputStream inStream;
+		byte[] information;
+
+		inStream = new FileInputStream(file);
+		information = new byte[(int) file.length()];
+
+		inStream.read(information);
+		inStream.close();
+
+		return information;
+	}
+
+	public static ArrayList<Chunk> loadChunks(String path, int chunksNumber) throws IOException {
+		ArrayList<Chunk> chunks = new ArrayList<>();
+
+		for (int i = 0; i <= chunksNumber; i++) {
+			byte[] information = loadFile(new File(path + "/" + i));
+			Chunk chunk = new Chunk("", i, 1, information);
+			chunks.add(chunk);
+		}
+
+		return chunks;
+	}
+
+	public static ArrayList<Chunk> fileSplit(byte[] fileInformation, String fileID, int replication) {
+		ArrayList<Chunk> chunks;
+		int numChunks;
+
+		numChunks = fileInformation.length / chunkSizeLimit + 1;
+		chunks = new ArrayList<>();
+
+		for (int i = 0; i < numChunks; i++) 
+		{
+			byte[] chunkinformation;
+
+			if (i == numChunks - 1) 
+			{
+				int leftOverBytes = fileInformation.length - (i * chunkSizeLimit);
+				chunkinformation = copyOfRange(fileInformation, i * chunkSizeLimit, i * chunkSizeLimit + leftOverBytes);
+			} 
+			else if (i == numChunks - 1 && fileInformation.length % chunkSizeLimit == 0) 
+			{
+				chunkinformation = new byte[0];
+			} 
+			else 
+			{
+				chunkinformation = copyOfRange(fileInformation, i * chunkSizeLimit, i * chunkSizeLimit + chunkSizeLimit);
+			}
+
+			Chunk chunk = new Chunk(fileID, i, replication, chunkinformation);
+			chunks.add(chunk);
+		}
+
+		return chunks;
+	}
+
+
+	public String getChunkPath(String fileID, int chunkNo) {
+		return getChunksPath() + fileID + "/" + chunkNo;
+	}
+
+	public byte[] loadChunk(String fileID, int chunkNo) {
+		byte[] chunkinformation = null;
+		String chunkPath = getChunksPath() + fileID + "/" + chunkNo;
+
+		try {
+			chunkinformation = loadFile(new File(chunkPath));
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+		return chunkinformation;
+	}
+
+
+	public String getRootPath() {
+		return path;
+	}
+
+	public String getChunksPath() {
+		return path + Utils.CHUNKS;
+	}
+
+	public String getRestoresPath() {
+		return path + Utils.RESTORES;
+	}
+
+	public FileManager getDatabase() {
+		return fileManager;
+	}
+
+	public void deleteChunk(String fileID, int chunkNo) {
+		String chunkPath = getChunkPath(fileID, chunkNo);
+		File file = new File(chunkPath);
+
+		long chunkSize = file.length();
+		file.delete();
+		decUsedMemory(chunkSize);
+		fileManager.deleteChunk(fileID, chunkNo);
+	}
+
+	public static long getMaxMemory() {
+		return maxMemory;
+	}
+
+	public static void setMaxMemory(int maxMemory) {
+		FolderManager.maxMemory = maxMemory;
+	}
+
+	public static long getUsedMemory() {
+		return FolderManager.usedMemory;
+	}
+
+	public static long getFreeMemory() {
+		return maxMemory - usedMemory;
+	}
+
+	private static void decUsedMemory(long n) {
+		usedMemory -= n;
+		if (usedMemory < 0) {
+			usedMemory = 0;
+			System.out.println("Used memory went below 0");
+		}
+	}
+
+	private static boolean incrUsedMemory(long n) {
+		if (usedMemory + n > maxMemory) {
+			System.out.println("Tried to surpass memory restrictions");
+			return false;
+		}
+		usedMemory += n;
+		System.out.println("Used memory: " + usedMemory + " / " + maxMemory);
+		return true;
+	}
+}
\ No newline at end of file

Property changes on: DistributedBackupService/src/chunk/FolderManager.java
___________________________________________________________________
Added: svn:executable
Index: DistributedBackupService/src/client/TestApp.java
===================================================================
--- DistributedBackupService/src/client/TestApp.java	(nonexistent)
+++ DistributedBackupService/src/client/TestApp.java	(revision 1)
@@ -0,0 +1,96 @@
+package client;
+
+import java.io.File;
+import java.rmi.RemoteException;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
+import java.util.HashMap;
+import java.util.Map;
+
+import server.InitiatorPeer;
+
+public class TestApp implements Runnable {
+
+	private InitiatorPeer initiatorPeer;
+	
+    private String peer_ap;
+    private String sub_protocol;
+    private String opnd_1;
+    private String opnd_2;
+
+    private Map<String, Runnable> protocols;
+    
+
+    public static void main(String[] args) {
+        if (args.length < 2 || args.length > 4) {
+        	System.out.println("Usage: <java TestApp <peer_ap> <sub_protocol> <opnd_1> <opnd_2> >");
+			System.out.println("<peer_ap> - peer access point");
+			System.out.println("<sub_protocol> - BACKUP, RESTORE, DELETE, RECLAIM");
+			System.out.println("<opnd_1> - path name of the file to backup/restore/delete");
+			System.out.println("<opnd_2> - replication degree");
+			System.exit(1);
+        }
+        
+        String peer_ap = args[0];
+        String sub_protocol = args[1];
+        String opnd_1;
+        String opnd_2;
+        
+        if(args.length > 2) 
+        	opnd_1 = args[2];
+        else
+        	opnd_1 = null;
+        
+        if(args.length > 3) 
+        	opnd_2 = args[3];
+        else
+        	opnd_2 = null;
+
+        TestApp app = new TestApp(peer_ap, sub_protocol, opnd_1, opnd_2);
+        new Thread(app).start();
+    }
+
+    public TestApp(String peer_ap, String sub_protocol, String opnd_1, String opnd_2) {
+    	protocols = new HashMap<>();
+    	
+        this.peer_ap = peer_ap;
+        this.sub_protocol = sub_protocol;
+        this.opnd_1 = opnd_1;
+        this.opnd_2 = opnd_2;
+
+        protocols.put("BACKUP", this::handleBackup);
+        protocols.put("DELETE", this::handleDelete);
+
+    }
+
+    @Override
+    public void run() {
+    	try {
+            Registry registry = LocateRegistry.getRegistry(null);
+            initiatorPeer = (InitiatorPeer) registry.lookup(peer_ap);
+        } catch (Exception e) {
+        	System.out.println("Error when opening RMI stub");
+            e.printStackTrace();
+        }
+        protocols.get(sub_protocol).run();
+    }
+    
+    private void handleBackup() {
+        File file = new File(this.opnd_1);
+        System.out.println("--> BACKUP :: Saving chunks at " + file.getAbsolutePath() + "\"");
+        try {
+            initiatorPeer.backup(file, Integer.parseInt(this.opnd_2));
+        } catch (RemoteException e) {
+        	e.printStackTrace();
+        }
+    }
+
+    private void handleDelete() {
+    	System.out.println("--> DELETE :: delete file: " + opnd_1 + "\"");
+        try {
+            initiatorPeer.delete(this.opnd_1);
+        } catch (RemoteException e) {
+        	e.printStackTrace();
+        }
+    }
+}

Property changes on: DistributedBackupService/src/client/TestApp.java
___________________________________________________________________
Added: svn:executable
Index: DistributedBackupService/src/handlers/BackupChunkHandler.java
===================================================================
--- DistributedBackupService/src/handlers/BackupChunkHandler.java	(nonexistent)
+++ DistributedBackupService/src/handlers/BackupChunkHandler.java	(revision 1)
@@ -0,0 +1,77 @@
+package handlers;
+
+import server.Peer;
+import sockets.Socket;
+import utils.Utils;
+
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicIntegerArray;
+
+import chunk.Chunk;
+import protocols.BackupChunk;
+
+public class BackupChunkHandler implements Runnable {
+
+    private final String protocolVersion;
+    private Peer parentPeer;
+    private Chunk chunk;
+    private AtomicIntegerArray chunkReplication;
+    private int retries = 5;
+
+    public BackupChunkHandler(BackupChunk backupInitiator, Chunk chunk) {
+        this.chunk = chunk;
+        this.parentPeer = backupInitiator.getPeer();
+        this.protocolVersion = backupInitiator.getVersion();
+        this.chunkReplication = parentPeer.getPeerInformation().getChunkReplication(chunk.getFileID());
+    }
+
+    BackupChunkHandler(Peer parentPeer, Chunk chunk) {
+        this.chunk = chunk;
+        this.parentPeer = parentPeer;
+        this.protocolVersion = Utils.VERSION;
+        this.chunkReplication = null;
+    }
+
+    @Override
+    public void run() {
+
+        int waitTime = 1000;
+        Message msg = generatePutChunkMsg(chunk, protocolVersion);
+
+        for (int i = 0; i < retries; ++i) {
+            if (isDesiredReplicationDegree()) {
+            	System.out.println("Achieved desired replication at i=" + i);
+                break;
+            }
+
+            try {
+                parentPeer.sendMsg(Socket.SocketType.MDB, msg);
+            } catch (IOException e) {
+            	System.out.println(e.getMessage());
+            }
+
+            sleep(waitTime);
+            waitTime *= 2;
+        }
+    }
+
+    protected boolean isDesiredReplicationDegree() {
+        return chunkReplication != null && chunkReplication.get(chunk.getChunkNo()) >= chunk.getReplication();
+    }
+
+    private void sleep(int waitTime) {
+        try {
+            Thread.sleep(waitTime);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private Message generatePutChunkMsg(Chunk chunk, String protocolVersion) {
+        String[] args = { protocolVersion, Integer.toString(parentPeer.getID()), chunk.getFileID(), Integer.toString(chunk.getChunkNo()), Integer.toString(chunk.getReplication())
+        };
+
+        return new Message(Utils.MessageType.PUTCHUNK, args, chunk.getData());
+    }
+
+}

Property changes on: DistributedBackupService/src/handlers/BackupChunkHandler.java
___________________________________________________________________
Added: svn:executable
Index: DistributedBackupService/src/handlers/Handler.java
===================================================================
--- DistributedBackupService/src/handlers/Handler.java	(nonexistent)
+++ DistributedBackupService/src/handlers/Handler.java	(revision 1)
@@ -0,0 +1,97 @@
+package handlers;
+
+import protocols.*;
+import server.Peer;
+
+import java.util.Random;
+import java.util.concurrent.*;
+
+import chunk.Chunk;
+import chunk.FileManager;
+
+public class Handler implements Runnable {
+	private Peer parentPeer;
+	private Chunk peerInformation;
+	private BlockingQueue<Message> msgQueue;
+	private ScheduledExecutorService executor;
+	private int delayLimit;
+
+	private Random random;
+
+	public Handler(Peer parentPeer) {
+		this.parentPeer = parentPeer;
+		this.peerInformation = parentPeer.getPeerInformation();
+		msgQueue = new LinkedBlockingQueue<>();
+		executor = Executors.newScheduledThreadPool(5);
+		delayLimit = 300;
+
+		this.random = new Random();
+	}
+
+	@Override
+	public void run() {
+		Message msg;
+
+		while (true) {
+			try {
+				msg = msgQueue.take();
+				if (msg == null) {
+					System.out.println("Null Message Received");
+					return;
+				}
+
+				System.out.println("R: " + msg.toString());
+
+				switch (msg.getType()) {
+				case PUTCHUNK:
+					Backup backup = new Backup(parentPeer, msg);
+					executor.execute(backup);
+					break;
+				case STORED:
+					peerInformation.addChunkReplication(msg.getFileID(), msg.getChunkNo());
+					break;
+				case GETCHUNK:
+
+					break;
+				case CHUNK:
+
+					break;
+				case REMOVED:
+					FileManager database = parentPeer.getDatabase();
+					String fileID = msg.getFileID();
+					int chunkNo = msg.getChunkNo();
+					
+					Chunk chunkInfo = database.getChunkInformation(fileID, chunkNo);
+
+					int perceivedReplication = database.getRecognizedReplication(fileID, chunkNo);
+					int targetReplication = chunkInfo.getReplication();
+
+					if (perceivedReplication < targetReplication) {
+						byte[] chunkData = parentPeer.loadChunk(fileID, chunkNo);
+
+						executor.schedule(
+								new RemovedChunkHandler(parentPeer, chunkInfo, chunkData),
+								this.random.nextInt(delayLimit + 1),
+								TimeUnit.MILLISECONDS
+								);
+					}
+					break;
+				case DELETE:
+					Delete delete = new Delete(parentPeer, msg);
+					executor.execute(delete);
+					break;
+				default:
+					return;
+				}
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+
+	public void pushMessage(byte[] data, int length) {
+		Message msgParsed = new Message(data, length);
+		msgQueue.add(msgParsed);
+	}
+}
\ No newline at end of file

Property changes on: DistributedBackupService/src/handlers/Handler.java
___________________________________________________________________
Added: svn:executable
Index: DistributedBackupService/src/handlers/Message.java
===================================================================
--- DistributedBackupService/src/handlers/Message.java	(nonexistent)
+++ DistributedBackupService/src/handlers/Message.java	(revision 1)
@@ -0,0 +1,211 @@
+package handlers;
+
+import utils.Utils;
+import utils.Utils.MessageType;
+
+import java.io.*;
+
+public class Message {
+
+	private int argsNo;
+
+	private int chunkNo;
+	private int senderID;
+	private String fileID;
+	private String version;
+	private int replication;
+	private MessageType msgType;
+
+	private byte [] body;
+
+	public Message(byte[] information, int length) { 
+		String header;
+		String headerWithoutStuff;
+		String [] splittedHeader;
+
+		header= readHeader(information);
+
+		headerWithoutStuff = header.trim().replaceAll("\\s+", " ");
+		splittedHeader = headerWithoutStuff.split("\\s+");
+		translateHeader(splittedHeader);
+
+		if (msgType == MessageType.CHUNK)
+			this.body = readBody(information, header.length(), length);
+
+		if(msgType == MessageType.PUTCHUNK) 
+			this.body = readBody(information, header.length(), length);
+	}
+
+	public Message(MessageType type, String[] args) {
+		this.msgType = type;
+		version = args[0];
+		senderID = Integer.parseInt(args[1]);
+		fileID = args[2];
+
+		if (type != MessageType.DELETE)
+			chunkNo = Integer.parseInt(args[3]);
+
+		if (type == MessageType.PUTCHUNK) {
+			replication = Integer.parseInt(args[4]);
+		}
+	}
+
+	public Message(MessageType type, String[] args, byte[] information) {
+		this(type, args);
+		body = information;
+	}
+
+	private String readHeader(byte[] information) {
+		ByteArrayInputStream stream;
+		BufferedReader reader;
+		String header = "";
+
+		stream = new ByteArrayInputStream(information);
+		reader = new BufferedReader(new InputStreamReader(stream));
+
+		try {
+			header = reader.readLine();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return header;
+	}
+
+	private byte[] readBody(byte[] information, int headerLength, int informationLength) {
+		int readBytes;
+		ByteArrayInputStream message;
+		byte[] bodyContent;
+
+		readBytes = informationLength - headerLength - 4;
+		message = new ByteArrayInputStream(information, headerLength + 4, readBytes);
+		bodyContent = new byte[readBytes];
+
+		message.read(bodyContent, 0, readBytes);
+
+		return bodyContent;
+	}
+
+	private void translateHeader(String[] headerSplit) {
+
+		switch (headerSplit[0]) {
+		case "PUTCHUNK": 
+		{
+			msgType = MessageType.PUTCHUNK;
+			argsNo = 6;
+		} break;
+		case "STORED":
+		{
+			msgType = MessageType.STORED;
+			argsNo = 5;
+		}
+		break;
+		case "GETCHUNK":
+		{	
+			msgType = MessageType.GETCHUNK;
+			argsNo = 5;
+		} break;
+		case "CHUNK":
+		{	msgType = MessageType.CHUNK;
+		argsNo = 5;
+		} break;
+		case "DELETE":
+		{	
+			msgType = MessageType.DELETE;
+			argsNo = 4;
+		} break;
+		case "REMOVED":
+		{	
+			msgType = MessageType.REMOVED;
+			argsNo = 5;
+		} break;
+		default:
+			return;
+		}
+
+		if (headerSplit.length != argsNo)
+			return;
+
+		version = headerSplit[1];
+		senderID = Integer.parseInt(headerSplit[2]);
+		fileID = headerSplit[3];
+
+		if (argsNo > 4)
+			chunkNo = Integer.parseInt(headerSplit[4]);
+
+		if (msgType == MessageType.PUTCHUNK)
+			replication = Integer.parseInt(headerSplit[5]);
+
+	}
+
+	public String headerString() {
+		String string;
+		if(msgType == MessageType.PUTCHUNK)
+			string = msgType + " " + version + " " + senderID + " " + fileID + " " + chunkNo + " " + replication + " " + Utils.CRLF + Utils.CRLF;
+		else if(msgType == MessageType.DELETE)
+			string = msgType + " " + version + " " + senderID + " " + fileID + " " + Utils.CRLF + Utils.CRLF;
+		else	
+			string = msgType + " " + version + " " + senderID + " " + fileID + " " + chunkNo + " " + Utils.CRLF + Utils.CRLF;
+		return string;
+	}
+
+	public byte[] getBytes() throws IOException {
+		byte header[]; 
+		header = headerString().getBytes();
+
+		if (body == null)
+			return header;
+		else {
+			ByteArrayOutputStream out = new ByteArrayOutputStream();
+			out.write(header);
+			out.write(body);
+			return out.toByteArray();
+		}
+	}
+
+	public String getVersion() {
+		return version;
+	}
+
+	public int getSenderID() {
+		return senderID;
+	}
+
+	public String getFileID() {
+		return fileID;
+	}
+
+	public int getChunkNo() {
+		return chunkNo;
+	}
+
+	public int getReplicationDegree() {
+		return replication;
+	}
+
+	public byte[] getBody() {
+		return body;
+	}
+
+	public MessageType getType() {
+		return msgType;
+	}
+
+	@Override
+	public String toString() {
+		String str;
+		if(msgType == MessageType.PUTCHUNK)
+		{
+			str = "<" + msgType +">" + " " + "<" + version+">" + " " + "<" + senderID+">" + " " +"<" + fileID+">" + " " + "<" +chunkNo+">";
+		} 
+		else if(msgType == MessageType.DELETE) 
+		{
+			str = "<" + msgType +">" + " " + "<" + version+">" + " " + "<" + senderID+">" + " " +"<" + fileID+">";
+		}
+		else 
+		{
+			str = "<" + msgType +">" + " " + "<" + version+">" + " " + "<" + senderID+">" + " " +"<" + fileID+">" + " " + "<" +chunkNo+">";
+		}
+		return str;
+	}
+
+}
\ No newline at end of file

Property changes on: DistributedBackupService/src/handlers/Message.java
___________________________________________________________________
Added: svn:executable
Index: DistributedBackupService/src/handlers/RemovedChunkHandler.java
===================================================================
--- DistributedBackupService/src/handlers/RemovedChunkHandler.java	(nonexistent)
+++ DistributedBackupService/src/handlers/RemovedChunkHandler.java	(revision 1)
@@ -0,0 +1,19 @@
+package handlers;
+
+import chunk.Chunk;
+import server.Peer;
+
+public class RemovedChunkHandler extends BackupChunkHandler {
+    private Chunk chunkInfo;
+
+    public RemovedChunkHandler(Peer parentPeer, Chunk chunkInfo, byte[] chunkData) {
+        super(parentPeer, new Chunk(chunkInfo, chunkData));
+
+        this.chunkInfo = chunkInfo;
+    }
+
+    @Override
+    protected boolean isDesiredReplicationDegree() {
+        return chunkInfo.getNumChunks() >= chunkInfo.getReplication();
+    }
+}

Property changes on: DistributedBackupService/src/handlers/RemovedChunkHandler.java
___________________________________________________________________
Added: svn:executable
Index: DistributedBackupService/src/protocols/Backup.java
===================================================================
--- DistributedBackupService/src/protocols/Backup.java	(nonexistent)
+++ DistributedBackupService/src/protocols/Backup.java	(revision 1)
@@ -0,0 +1,85 @@
+package protocols;
+
+import server.Peer;
+import sockets.Socket;
+import utils.Utils;
+
+import java.io.IOException;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+import chunk.Chunk;
+import handlers.Message;
+
+import static chunk.FolderManager.makeDir;
+import static chunk.FolderManager.backupFile;
+
+public class Backup implements Runnable {
+
+    private Peer peer;
+    private Message req;
+
+    private byte[] data;
+    private int replication;
+    private String fileID;
+    private int chunkNo;
+    private String version;
+    private int senderID;
+    private static int delayLimit;
+
+    public Backup(Peer peer, Message req) {
+        this.peer = peer;
+        this.req = req;
+
+        System.out.println("BACKUP begins!");
+    }
+
+
+    @Override
+    public void run() {
+
+        version = req.getVersion();
+        senderID = req.getSenderID();
+        fileID = req.getFileID();
+        chunkNo = req.getChunkNo();
+        replication = req.getReplicationDegree();
+        delayLimit = 300;
+
+        if (senderID == peer.getID()) { 
+        	System.out.println("Ignoring backup of own files");
+            return;
+        }
+
+        data = req.getBody();
+
+        String chunkPathname = peer.getPath("chunks") + "/" + fileID;
+
+        makeDir(peer.getPath("chunks") + "/" + fileID);
+
+        boolean success = false;
+        try {
+            success = backupFile(Integer.toString(chunkNo), chunkPathname, data);
+            //save to database
+            peer.addChunkToFileManager(new Chunk(fileID, chunkNo, replication, data.length));
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        if (! success) {
+        	System.out.println("Memory overflow");
+        } else {
+            sendMsgStored();
+        }
+
+        System.out.println("Finished backup!");
+    }
+
+    private void sendMsgStored() {
+        String[] args = {version, Integer.toString(peer.getID()),fileID, Integer.toString(chunkNo)};
+
+        Message msg = new Message(Utils.MessageType.STORED, args);
+
+        Random random = new Random();
+        peer.sendLateMsg(Socket.SocketType.MC, msg, random.nextInt(delayLimit + 1), TimeUnit.MILLISECONDS);
+    }
+}

Property changes on: DistributedBackupService/src/protocols/Backup.java
___________________________________________________________________
Added: svn:executable
Index: DistributedBackupService/src/protocols/BackupChunk.java
===================================================================
--- DistributedBackupService/src/protocols/BackupChunk.java	(nonexistent)
+++ DistributedBackupService/src/protocols/BackupChunk.java	(revision 1)
@@ -0,0 +1,94 @@
+package protocols;
+
+import server.Peer;
+import utils.Utils;
+
+import static chunk.FolderManager.fileSplit;
+
+import java.io.File;
+import java.util.HashMap;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.io.FileNotFoundException;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.security.NoSuchAlgorithmException;
+
+import chunk.Chunk;
+import chunk.FileManager;
+import chunk.FolderManager;
+import handlers.BackupChunkHandler;
+
+public class BackupChunk implements Runnable {
+
+	private String fileID;
+	private Peer peer;
+	private String version;
+
+	private byte[] data;
+	private int replication;
+	private File file;
+
+
+	public BackupChunk(String version, File file, int replication, Peer peer) {
+		this.version = version;
+		this.file = file;
+		this.replication = replication;
+		this.peer = peer;
+	}
+	
+
+	public Peer getPeer() {
+		return peer;
+	}
+
+	public String getVersion() {
+		return version;
+	}
+
+	@Override
+	public void run() {
+		try {
+			data = FolderManager.loadFile(file);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+		try {
+			fileID = hashFileID(file);
+		} catch (NoSuchAlgorithmException e) {
+			e.printStackTrace();
+		}
+		
+		ArrayList<Chunk> chunks;
+		chunks = fileSplit(data, fileID, replication);
+		
+		HashMap<String, Chunk> chunksInfo = new HashMap<>();
+
+		peer.getPeerInformation().startChunkReplication(fileID, chunks.size());
+
+		for (Chunk chunk : chunks) {
+			new Thread(new BackupChunkHandler(this, chunk)).start();
+			chunksInfo.put(Integer.toString(chunk.getChunkNo()), new Chunk(chunk.getChunkNo(), chunk.getReplication()));
+		}
+
+		peer.addFileToFileManager(file.getPath(), new FileManager(file, fileID, replication, chunksInfo));
+		peer.getPeerInformation().resetChunkReplication(fileID);
+
+		System.out.println("Finished backupInitiator!");
+	}
+
+	private String hashFileID(File file) throws NoSuchAlgorithmException {
+		BasicFileAttributes attributes;
+		try {
+			attributes = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
+		} catch (IOException e) {
+			System.out.println("Couldn't read file's metadata: " + e.getMessage());
+			return null;
+		}
+		
+		String fileId = file.getName() + attributes.lastModifiedTime() + attributes.size();
+		return Utils.hash(fileId);
+	}
+
+}

Property changes on: DistributedBackupService/src/protocols/BackupChunk.java
___________________________________________________________________
Added: svn:executable
Index: DistributedBackupService/src/protocols/Delete.java
===================================================================
--- DistributedBackupService/src/protocols/Delete.java	(nonexistent)
+++ DistributedBackupService/src/protocols/Delete.java	(revision 1)
@@ -0,0 +1,63 @@
+package protocols;
+
+import server.Peer;
+import java.util.Set;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+
+import chunk.FileManager;
+import handlers.Message;
+
+public class Delete implements Runnable {
+
+    private Peer peer;
+    private Message req;
+    private FileManager fileManager;
+
+    public Delete(Peer peer, Message req) {
+        this.peer = peer;
+        this.req = req;
+        this.fileManager = peer.getDatabase();
+
+        System.out.println("DELETE begins!");
+    }
+
+
+    @Override
+    public void run() {
+        String fileID;
+        String path;
+        Set<Integer> chunks;
+        
+        fileID = req.getFileID();
+
+        if (!fileManager.chunkExists(fileID)) {
+        	System.out.println("Can not find chunks!");
+            System.exit(-1);;
+        }
+
+        chunks = fileManager.getFileChunksKey(fileID);
+        path = peer.getPath("chunks");
+
+        for (Integer chunk : chunks) {
+            try {
+                Files.delete(Paths.get(path + "/" + fileID + "/" + chunk));
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+
+        try {
+            Files.delete(Paths.get(path + "/" + fileID));
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        fileManager.deleteFileBackedUp(fileID);
+        System.out.println("Delete successful.");
+    }
+
+}
\ No newline at end of file

Property changes on: DistributedBackupService/src/protocols/Delete.java
___________________________________________________________________
Added: svn:executable
Index: DistributedBackupService/src/protocols/DeleteChunk.java
===================================================================
--- DistributedBackupService/src/protocols/DeleteChunk.java	(nonexistent)
+++ DistributedBackupService/src/protocols/DeleteChunk.java	(revision 1)
@@ -0,0 +1,58 @@
+package protocols;
+
+import server.Peer;
+import sockets.Socket;
+import utils.Utils;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import chunk.FileManager;
+import handlers.Message;
+
+public class DeleteChunk implements Runnable {
+    private String version;
+    private String pathName;
+    private Peer peer;
+
+    public DeleteChunk(String version, String pathName, Peer parentPeer) {
+        this.version = version;
+        this.pathName = pathName;
+        this.peer = parentPeer;
+    }
+
+    @Override
+    public void run() {
+        FileManager fileInformation;
+        fileInformation = peer.getFile(pathName);
+        
+        if (fileInformation == null) {
+        	System.out.println("Can not find File!");
+            System.exit(-1);;
+        }
+        sendMsgToMC(fileInformation);
+        try {
+            Files.delete(Paths.get(pathName));
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        peer.deleteFileFromFileManager(pathName);
+    }
+
+    private boolean sendMsgToMC(FileManager fileInformation) {
+    	String idString = Integer.toString(peer.getID());
+        String[] args = { version, idString,fileInformation.getFileID() };
+
+        Message msg = new Message(Utils.MessageType.DELETE, args);
+
+        try {
+            peer.sendMsg(Socket.SocketType.MC, msg);
+        } catch (IOException e) {
+            e.printStackTrace();
+            return false;
+        }
+        return true;
+    }
+
+}

Property changes on: DistributedBackupService/src/protocols/DeleteChunk.java
___________________________________________________________________
Added: svn:executable
Index: DistributedBackupService/src/server/InitiatorPeer.java
===================================================================
--- DistributedBackupService/src/server/InitiatorPeer.java	(nonexistent)
+++ DistributedBackupService/src/server/InitiatorPeer.java	(revision 1)
@@ -0,0 +1,13 @@
+package server;
+
+import java.io.File;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+public interface InitiatorPeer extends Remote {
+    String backup(File file, int replicationDegree) throws RemoteException;
+    void restore(String pathname) throws RemoteException; 
+    void delete(String pathname) throws RemoteException;
+    void reclaim(int space) throws RemoteException;
+    void state() throws RemoteException;
+}

Property changes on: DistributedBackupService/src/server/InitiatorPeer.java
___________________________________________________________________
Added: svn:executable
Index: DistributedBackupService/src/server/Peer.java
===================================================================
--- DistributedBackupService/src/server/Peer.java	(nonexistent)
+++ DistributedBackupService/src/server/Peer.java	(revision 1)
@@ -0,0 +1,194 @@
+package server;
+
+import protocols.BackupChunk;
+import protocols.DeleteChunk;
+import sockets.Socket;
+import sockets.MultiCastSocket;
+import sockets.MDBSocket;
+import sockets.MDRSocket;
+import sockets.Socket.SocketType;
+import utils.Utils;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
+import java.rmi.server.UnicastRemoteObject;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.*;
+
+import chunk.*;
+import handlers.Handler;
+import handlers.Message;
+
+
+public class Peer implements InitiatorPeer {
+
+	private int id;
+	private Handler handler;
+	private ScheduledExecutorService agent;
+	private Map<SocketType, Socket> sockets;
+	private FolderManager folderManager;
+	private FileManager fileManager;
+
+	private Chunk peerInformation;
+
+	private MultiCastSocket mc;
+	private MDRSocket mdr;
+	private MDBSocket mdb;
+
+	public Peer(int id, String[] MC, String[] MDB, String[] MDR) throws IOException, ClassNotFoundException {
+		this.id = id; 
+		folderManager = new FolderManager(this, 8000000);     //8000000 = size of maximum memory (8MB)
+		fileManager = folderManager.getDatabase();
+
+		String mcAddr = MC[0];
+		String mcPort = MC[1];
+
+		String mdbAddr = MDB[0];
+		String mdbPort =  MDB[1];
+
+		String mdrAddr = MDR[0];
+		String mdrPort = MDR[1];
+
+		mc= new MultiCastSocket(this, mcAddr, mcPort);
+		mdb= new MDBSocket(this, mdbAddr, mdbPort);
+		mdr= new MDRSocket(this, mdrAddr, mdrPort);
+
+		new Thread(mc).start();
+		new Thread(mdb).start();
+		new Thread(mdr).start();
+
+		sockets = new HashMap<>();
+		sockets.put(SocketType.MC, mc);
+		sockets.put(SocketType.MDB, mdb);
+		sockets.put(SocketType.MDR, mdr);
+
+		peerInformation = new Chunk();
+		handler = new Handler(this);
+		new Thread(handler).start();
+
+		agent = new ScheduledThreadPoolExecutor(10);
+
+		System.out.println("Peer " + id + " is alive!");
+	}
+
+	public static void main(String args[]) {
+
+		String[] mc = args[1].split(":");
+		String[] mdb = args[2].split(":");
+		String[] mdr = args[3].split(":");
+
+		System.setProperty("java.net.preferIPv4Stack", "true"); // Flag needed for systems that use IPv6 by default
+
+		try {
+			Peer peer = new Peer(Integer.parseInt(args[0]), mc, mdb, mdr);
+			InitiatorPeer initiatorPeer = (InitiatorPeer) UnicastRemoteObject.exportObject(peer, 0);
+
+			Registry registry = LocateRegistry.getRegistry();
+			registry.rebind(args[0], initiatorPeer);
+
+			System.out.println("Peer ready!");
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	public int getID() {
+		return id;
+	}
+	
+	public Socket getSocket(SocketType socketType) {
+		return sockets.get(socketType);
+	}
+	
+	public String getPath(String path) {
+		String pathname;
+		if(path == "chunks")
+			pathname = folderManager.getChunksPath();
+		else
+			pathname = "";
+		return pathname;
+	}
+	
+	public void sendLateMsg(SocketType type, Message msg, long delay, TimeUnit unit) {
+		agent.schedule(() -> {
+			try {
+				sendMsg(type, msg);
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}, delay, unit);
+	}
+
+	public void sendMsg(SocketType socketType, Message msg) throws IOException {
+		System.out.println("S:  " + msg.toString());
+		sockets.get(socketType).sendMsg(msg.getBytes());
+	}
+
+	public void pushMsgHandler(byte[] data, int length) throws IOException {
+		handler.pushMessage(data, length);
+	}
+
+	public void addFileToFileManager(String pathName, FileManager fileInfo) {
+		fileManager.addFile(pathName, fileInfo);
+	}
+	
+	public void addChunkToFileManager(Chunk chunkInfo) {
+		fileManager.addChunk(chunkInfo);
+	}
+
+	public void deleteFileFromFileManager(String pathName) {
+		fileManager.removeFile(pathName);
+	}
+
+	public FileManager getFile(String pathName) {
+		return fileManager.getFileInformation(pathName);
+	}
+
+	public byte [] loadChunk(String fileID, int chunkNo) {
+		return folderManager.loadChunk(fileID, chunkNo);
+	}
+
+	public Chunk getPeerInformation() {
+		return peerInformation;
+	}
+
+	public FileManager getDatabase() {
+		return fileManager;
+	}
+
+	public FolderManager getSystemManager() {
+		return folderManager;
+	}
+
+
+	@Override
+	public String backup(File file, int replicationDegree) {
+		agent.execute(new BackupChunk(Utils.VERSION, file, replicationDegree, this));
+		return "backup command ok";
+	}
+
+	@Override
+	public void restore(String pathname) {
+		return;
+	}
+
+	@Override
+	public void delete(String pathname) {
+		agent.execute(new DeleteChunk("1.0", pathname, this));
+	}
+
+	@Override
+	public void reclaim(int space) {
+
+	}
+
+	@Override
+	public void state() {
+
+	}
+
+}

Property changes on: DistributedBackupService/src/server/Peer.java
___________________________________________________________________
Added: svn:executable
Index: DistributedBackupService/src/sockets/MDBSocket.java
===================================================================
--- DistributedBackupService/src/sockets/MDBSocket.java	(nonexistent)
+++ DistributedBackupService/src/sockets/MDBSocket.java	(revision 1)
@@ -0,0 +1,19 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package sockets;
+
+import java.io.IOException;
+
+import server.Peer;
+
+public class MDBSocket extends Socket {
+	public MDBSocket(Peer peer, String address, String port) throws IOException {
+		super(peer, address, port);
+		
+		System.out.println("MDB: socket is alive!");
+	}
+
+}
\ No newline at end of file

Property changes on: DistributedBackupService/src/sockets/MDBSocket.java
___________________________________________________________________
Added: svn:executable
Index: DistributedBackupService/src/sockets/MDRSocket.java
===================================================================
--- DistributedBackupService/src/sockets/MDRSocket.java	(nonexistent)
+++ DistributedBackupService/src/sockets/MDRSocket.java	(revision 1)
@@ -0,0 +1,13 @@
+package sockets;
+
+import java.io.IOException;
+
+import server.Peer;
+
+public class MDRSocket extends Socket {
+    public MDRSocket(Peer peer, String address, String port) throws IOException {
+        super(peer, address, port);
+        
+        System.out.println("MDR: socket is active!");
+    }
+}
\ No newline at end of file

Property changes on: DistributedBackupService/src/sockets/MDRSocket.java
___________________________________________________________________
Added: svn:executable
Index: DistributedBackupService/src/sockets/MultiCastSocket.java
===================================================================
--- DistributedBackupService/src/sockets/MultiCastSocket.java	(nonexistent)
+++ DistributedBackupService/src/sockets/MultiCastSocket.java	(revision 1)
@@ -0,0 +1,21 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package sockets;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.MulticastSocket;
+
+import server.Peer;
+
+
+public class MultiCastSocket extends Socket{
+    public MultiCastSocket(Peer peer, String address, String port) throws IOException {
+        super(peer, address, port);
+        
+        System.out.println("MC: socket is alive!");
+    }
+}
\ No newline at end of file

Property changes on: DistributedBackupService/src/sockets/MultiCastSocket.java
___________________________________________________________________
Added: svn:executable
Index: DistributedBackupService/src/sockets/Socket.java
===================================================================
--- DistributedBackupService/src/sockets/Socket.java	(nonexistent)
+++ DistributedBackupService/src/sockets/Socket.java	(revision 1)
@@ -0,0 +1,84 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package sockets;
+
+import utils.Utils;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.InetAddress;
+import java.net.MulticastSocket;
+
+import server.Peer;
+
+public class Socket implements Runnable {
+
+	protected int port;
+	protected MulticastSocket socket;
+	protected InetAddress address;
+	protected Peer peer;
+
+	public Socket(Peer peer, String address, String port) {
+		this.peer = peer;
+
+		try {
+			this.address = InetAddress.getByName(address);
+			this.port = Integer.parseInt(port);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	private void openSocket() {
+		try{
+			socket = new MulticastSocket(port);
+			socket.setTimeToLive(1);
+			socket.joinGroup(address);
+		} catch (IOException e){
+			e.printStackTrace();
+		}
+	}
+
+	public MulticastSocket getSocket() {
+		return socket;
+	}
+
+	@Override
+	public void run() {
+		openSocket();
+		byte[] buffer = new byte[Utils.PACKET_SIZE];
+
+		DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
+		
+		while(true) {
+			try {
+				this.socket.receive(packet);
+			}
+			catch(IOException e) {
+				e.printStackTrace();
+			}
+			try {
+				peer.pushMsgHandler(packet.getData(), packet.getLength());
+			} catch(IOException e) {
+				e.printStackTrace();
+			}
+
+		}
+	}
+
+	public void sendMsg(byte[] msg) {
+		DatagramPacket packet = new DatagramPacket(msg, msg.length, address, port);
+		try {
+			socket.send(packet);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+    public enum SocketType {
+        MC, MDB, MDR
+    }
+}

Property changes on: DistributedBackupService/src/sockets/Socket.java
___________________________________________________________________
Added: svn:executable
Index: DistributedBackupService/src/utils/Utils.java
===================================================================
--- DistributedBackupService/src/utils/Utils.java	(nonexistent)
+++ DistributedBackupService/src/utils/Utils.java	(revision 1)
@@ -0,0 +1,54 @@
+package utils;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class Utils {
+
+	public static final char CR = (char) 0x0D;
+	public static final char LF = (char) 0x0A;
+
+	public final static String CRLF = "" + CR + LF;
+
+	public static final int CHUNK_MAX_SIZE = 64000;
+	public static final int PACKET_SIZE = 65536;                    
+
+	public enum MessageType { PUTCHUNK, STORED, GETCHUNK, CHUNK, REMOVED, DELETE }
+
+    public enum SocketType { MC, MDB, MDR }
+
+	private static final String MULTICAST_ADDR = "224.0.0.1";
+	private static final int DEFAULT_PORT_MC = 8000;
+
+	private static final String MDB_ADDR = "224.0.0.2";
+	private static final int DEFAULT_PORT_MDB = 8001;
+
+	public static final String FILES = "../files/";
+	public static final String CHUNKS = "chunks/";
+
+	public static final String RESTORES = "restores/";
+	
+	public static final String VERSION = "1.0";
+	public static SocketType MDB;
+
+	private static String bytesToHex(byte[] hash) {
+		StringBuffer hexString = new StringBuffer();
+		for (int i = 0; i < hash.length; i++) {
+			String hex = Integer.toHexString(0xff & hash[i]);
+			if(hex.length() == 1) hexString.append('0');
+			hexString.append(hex);
+		}
+		return hexString.toString();
+	}
+
+	public static String hash(String originalString) throws NoSuchAlgorithmException {
+		MessageDigest digest = MessageDigest.getInstance("SHA-256");
+
+		byte[] encodedHash = digest.digest(originalString.getBytes(StandardCharsets.UTF_8));
+		String hashedID = bytesToHex(encodedHash);
+		System.out.println("" + encodedHash.length + " : " + hashedID);
+		return hashedID;
+	}
+
+}
\ No newline at end of file

Property changes on: DistributedBackupService/src/utils/Utils.java
___________________________________________________________________
Added: svn:executable
Index: DistributedBackupService/backup.sh
===================================================================
--- DistributedBackupService/backup.sh	(nonexistent)
+++ DistributedBackupService/backup.sh	(revision 1)
@@ -0,0 +1,2 @@
+#!/bin/sh
+java -classpath bin client.TestApp 1 "BACKUP" "files/dog.png" 1
\ No newline at end of file

Property changes on: DistributedBackupService/backup.sh
___________________________________________________________________
Added: svn:executable
Index: DistributedBackupService/build.sh
===================================================================
--- DistributedBackupService/build.sh	(nonexistent)
+++ DistributedBackupService/build.sh	(revision 1)
@@ -0,0 +1,5 @@
+#!/bin/sh
+rm -rf bin
+rm -f *.jar
+mkdir -p bin
+javac -Xlint:unchecked -d bin -sourcepath src src/client/TestApp.java src/server/Peer.java
\ No newline at end of file

Property changes on: DistributedBackupService/build.sh
___________________________________________________________________
Added: svn:executable
Index: DistributedBackupService/peer.sh
===================================================================
--- DistributedBackupService/peer.sh	(nonexistent)
+++ DistributedBackupService/peer.sh	(revision 1)
@@ -0,0 +1,7 @@
+#!/bin/sh
+if [ "$#" -ne 1 ]; then
+  echo "Usage: peer.sh <number>"
+  exit 1
+fi
+
+java -classpath bin server.Peer "$1" 224.0.0.0:8000 224.0.0.0:8001 224.0.0.0:8002
\ No newline at end of file

Property changes on: DistributedBackupService/peer.sh
___________________________________________________________________
Added: svn:executable
