diff --git a/Makefile b/Makefile
index b76d9812bd4615d9d6eea2e56b60bb0da1ae0947..e273cf959e6aedc89cdfac11394362233cd3d83e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-CFLAGS= -g -Wall -O2
+CFLAGS= -w -g -Wall -O2
 CC=g++
 
 OBJ=Protocol.o
@@ -7,7 +7,7 @@ OBJ=Protocol.o
 	$(CC) $(CFLAGS) $^ -c -o $@
 cacoclient: client.cpp $(OBJ)
 	$(CC) $(CFLAGS) $^ -o $@
-# cacoserver: $(OBJ) client.cpp
-# 	$(CC) $(CFLAGS) $^ -o $@
+cacoserver: $(OBJ) server.cpp
+	$(CC) $(CFLAGS) $^ -o $@
 clean:
 	rm -f *.o caco*
diff --git a/Protocol.cpp b/Protocol.cpp
index 73dcaa6b16f01902bafc1c584df6131ecc506b13..bc6593ad29d8b04dea1d99a520aa07e84c48026f 100644
--- a/Protocol.cpp
+++ b/Protocol.cpp
@@ -1,3 +1,4 @@
+#include <sys/socket.h>
 #include "Protocol.h"
 #include "definitions.h"
 
@@ -10,24 +11,25 @@ void Protocol::setMessage(Message message){
 }
 
 int Protocol::readMessage(int sockt){
-    unsigned char* dataRec = recv(sockt, data, MAXSIZE, 0);
+    unsigned char dataRec[MAXSIZE+4];
+    int ret = recv(sockt, dataRec, MAXSIZE, 0);
     Message msg;
-    msg.c_ctrl.begin = data[0];
+    msg.c_ctrl.begin = dataRec[0];
     if(msg.i_ctrl.begin != BEGIN){
         return 0;
     }
-    msg.c_ctrl.size = data[1];
-    msg.c_ctrl.seqType = data[2];
-    msg.c_ctrl.parity = data[3+msg.i_ctrl.size];
+    msg.c_ctrl.size = dataRec[1];
+    msg.c_ctrl.seqType = dataRec[2];
+    msg.c_ctrl.parity = dataRec[3+msg.i_ctrl.size];
     // TODO: Check parity
     if(msg.i_ctrl.type == FIM){
         this->message = msg;
         return 1;
     }
 
-    unsigned char data[msg.i_ctrl.size];
-    strncat(data,dataRec+3,msg.i_ctrl.size);
-    this->data.insert(this->data.end(), data, data+msg.i_ctrl.size);
+    unsigned char msgData[msg.i_ctrl.size];
+    memcpy(msgData,dataRec+3,msg.i_ctrl.size);
+    this->data.insert(this->data.end(), msgData, msgData+msg.i_ctrl.size);
     this->message = msg;
     return -1;
 }
diff --git a/client.cpp b/client.cpp
index 947a3cdbe3e456e85f4568ccf06e114aa65833b4..dd8489900b3ba8aa3a3c4ba08bda38d935003979 100644
--- a/client.cpp
+++ b/client.cpp
@@ -1,34 +1,69 @@
+#include <sstream>
 #include "definitions.h"
 #include "dirFunctions.h"
 #include "ConexaoRawSocket.c"
 
-int main(){
+void printCommandsList();
+vector<string> getArgs();
 
-    int socket = ConexaoRawSocket(DEVICE);
-    
+int main(){
+    int sockt = ConexaoRawSocket(DEVICE);
+    vector<string> args;
+    printCommandsList();
     while(true){
-        string command, path;
         cout << endl << "Entre com o comando:" << endl;
-        cin >> command;
-        if(command == "quit"){
+        args = getArgs();
+        if(args[0] == "quit"){
             break;
         }
-        cin >> path;
-        if(command == "cd"){
-            cd(path);
-        }else if(command == "ls"){
-            ls(path);
-        }else if(command == "cdr"){
-            //TODO
-        }else if(command == "lsr"){
+        if(args[0] == "cd"){
+            cd(args[1]);
+        }else if(args[0] == "ls"){
+            try{
+                cout << ls(args);
+            }catch(char const* strException){
+                cerr<<"Error: "<< strException << endl;
+            }
+        }else if(args[0] == "cdr"){
             //TODO
-        }else if(command == "put"){
+        }else if(args[0] == "lsr"){
             //TODO
-        }else if(command == "get"){
+        }else if(args[0] == "put"){
             //TODO
+        }else if(args[0] == "get"){
+
+        }else if(args[0] == "help"){
+            printCommandsList();
         }else{
             cout << "Comando inexistente." << endl;
+            printCommandsList();
+
         }
     }
     return 0;
+}
+
+void printCommandsList(){
+    cout << "Os comandos suportados são:"<< endl;
+    cout << "cd - Mudar de diretório local"<< endl;
+    cout << "ls - Visualizar arquivos no diretório local"<< endl;
+    cout << "cdr - Mudar de diretório remoto"<< endl;
+    cout << "lsr - Visualizar arquivos no diretório remoto"<< endl;
+    cout << "put - Enviar arquivo para diretório remoto"<< endl;
+    cout << "get - Pegar arquivo do diretório remoto"<< endl;
+    cout << "help - Lista de comandos"<< endl;
+    cout << "quit - Sair"<< endl;
+}
+
+vector<string> getArgs(){
+    string line, arg;
+    getline(cin,line);
+    stringstream ss(line);
+    vector<string> args;
+    while(getline(ss, arg, ' ')){
+        if(!arg.empty()){
+            args.push_back(arg);
+        }
+    }
+    return args;
 }
\ No newline at end of file
diff --git a/dirFunctions.cpp b/dirFunctions.cpp
index 078e39c86c8e4134e08d493d9a79043593ddaba9..f3ae475a034b883ba635e2d3fb7d36268d2fc4c0 100644
--- a/dirFunctions.cpp
+++ b/dirFunctions.cpp
@@ -1,11 +1,20 @@
 #include <iostream>
 #include <errno.h>
 #include <unistd.h>
-#include <dirent.h>
 #include <string.h>
+#include <vector>
+#include <numeric> //accumulate
+#include <stdio.h> //popen
+#include <iterator>
 
 using namespace std;
 
+string concatStringVector(vector<string> vs){
+    ostringstream oss;
+    copy(vs.begin(), vs.end(), ostream_iterator<string>(oss, " "));
+    return oss.str();
+}
+
 void cd(string path){
     if(chdir(path.c_str()) != 0){
         cout << "Error: could not change directory." << endl;
@@ -13,16 +22,27 @@ void cd(string path){
     }
 }
 
-void ls(string path){
-    //TODO: #1
-    struct dirent *entry;
-    DIR *dir = opendir(path.c_str());
-    if(dir != NULL){
-        while((entry=readdir(dir)) != NULL){
-           cout << entry->d_name << endl;
-        }
-        closedir(dir);
-    }else{
-        cout<<"Error: could not open directory."<<endl;
+string ls(vector<string> args){
+    string output, command = concatStringVector(args);
+    FILE *lsOut = popen(command.c_str(), "r");
+    if(!lsOut){
+        throw "Couldn't execute ls";
     }
+    char buffer[1024];
+    while(fgets(buffer, sizeof(buffer), lsOut)!=NULL){
+        output += buffer;
+    }
+    pclose(lsOut);
+    return output;
+    //TODO: #1
+    // struct dirent *entry;
+    // DIR *dir = opendir(path.c_str());
+    // if(dir != NULL){
+    //     while((entry=readdir(dir)) != NULL){
+    //        cout << entry->d_name << endl;
+    //     }
+    //     closedir(dir);
+    // }else{
+    //     cout<<"Error: could not open directory."<<endl;
+    // }
 }
\ No newline at end of file
diff --git a/dirFunctions.h b/dirFunctions.h
index 1cb22424a70c1b679ffde53db571a39f89c614b8..fe120405bd8f732f027633b8b0ad3107c3d8b0a0 100644
--- a/dirFunctions.h
+++ b/dirFunctions.h
@@ -7,6 +7,6 @@ using namespace std;
 
 void cd(string path);
 
-void ls(string path);
+string ls(string path);
 
 #endif
\ No newline at end of file