diff --git a/Makefile b/Makefile index 6a2a0c677ba975bded4e4466f26f078a9102dd18..1c228040e0c221c3a971f6096d9815b4ae848864 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ LIB=./lib INCLUDE=./include SRC=./src OBJ=./obj -FLAGS = -Wall +FLAGS = -w main: connectionRawSocket messages submessages $(CC) $(SRC)/main.cpp $(OBJ)/connectionRawSocket.o $(OBJ)/messages.o $(OBJ)/submessages.o $(FLAGS) -I$(INCLUDE) -L$(LIB) -o connection diff --git a/include/connectionRawSocket.h b/include/connectionRawSocket.h index 8ac29581d21c0223c4d85835947e750d23ed6c52..587d95723853ff1d9c44d26b4e3be5b6e81e7b07 100644 --- a/include/connectionRawSocket.h +++ b/include/connectionRawSocket.h @@ -26,6 +26,7 @@ #include <dirent.h> #include <unistd.h> #include <sys/stat.h> +#include <sys/statvfs.h> using namespace std; diff --git a/include/messages.h b/include/messages.h index 980e324fed2ae3ef1f8b5d74c2993b2e23c9b706..676d450e50800c73e0a9611d6a683eb7f9dd22e4 100644 --- a/include/messages.h +++ b/include/messages.h @@ -14,13 +14,15 @@ class Message{ static int sendCD(unsigned char*); static int sendLS(unsigned char*); static int sendPUT(unsigned char*); - static int sendGET(unsigned char*); + static int sendGET(unsigned char*, char*); static int sendData(unsigned char*); // Método que divide e envia uma mensagem. // Métodos que faz o recebimento e resposta aos comandos static int receiveCD(unsigned char*); // Lida com mensagens tipo CD - static int receiveLS(unsigned char*); // Lida com mensagens tipo LS - static int receivePUT(unsigned char*); // Lida com... ok você entendeu + static int receiveLS(unsigned char*, char*); // Lida com mensagens tipo LS + static int receivePUT(unsigned char*, char*); // Lida com... ok você entendeu static int receiveGET(unsigned char*); - static int receiveData(unsigned char*, int); // Método que recebe as mensagens e as agrupa + static int receiveData(unsigned char*, int, int); // Método que recebe as mensagens e as agrupa + + static int lsParameter(string); // Usado para decidir qual tipo de ls será feito. }; diff --git a/include/slidingWindow.h b/include/slidingWindow.h deleted file mode 100644 index c355594690a7516823cb93f8eef91ca82dd989a9..0000000000000000000000000000000000000000 --- a/include/slidingWindow.h +++ /dev/null @@ -1,11 +0,0 @@ -// Implementado por: Eduardo Machado e Victor Perszel -// 2015 - -#include <iostream> -#include <sstream> -#include "messages.h" -#include "connectionRawSocket.h" - -class slidingWindow{ - -} \ No newline at end of file diff --git a/miniShell/miniShell.c b/miniShell/miniShell.c deleted file mode 100644 index bfca2ec8e471c321eef8006b89513bc2dfc7ec58..0000000000000000000000000000000000000000 --- a/miniShell/miniShell.c +++ /dev/null @@ -1,56 +0,0 @@ -/* Implementado por: Eduardo Machado e Victor Perszel */ -/* 2015 */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <dirent.h> -#include <unistd.h> -#include <sys/stat.h> -#include <sys/types.h> - -int lsMini(char *parameter){ - char lsAux[10]; - - /* Para dar um ls apenas, é necessário escrever "ls ." */ - /* Precisamos pensar em um jeito de concertar isso. */ - switch(lsParameter(parameter)){ - case 1: - strcpy(lsAux, "ls"); - system(lsAux); - break; - case 2: - strcpy(lsAux, "ls -a"); - system(lsAux); - break; - case 3: - strcpy(lsAux, "ls -l"); - system(lsAux); - break; - case 4: - strcpy(lsAux, "ls -la"); - system(lsAux); - break; - case -1: - puts("Parâmetro de ls inválido."); - return -1; - break; - } - printf("\n"); - return 0; -} - -int cdMini(char *intendedDirectory){ - int errorTest; - errorTest = chdir(intendedDirectory); - return errorTest; -} - -int lsParameter(char *parameter){ - if(strcmp(parameter,".")==0) return 1; - else if(strcmp(parameter,"-a")==0) return 2; - else if(strcmp(parameter,"-l")==0) return 3; - else if(strcmp(parameter,"-la")==0) return 4; - else return -1; -} diff --git a/miniShell/miniShell.cpp b/miniShell/miniShell.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fdcbfec0b531662d1cf010e999c8d0ae96546ba6 --- /dev/null +++ b/miniShell/miniShell.cpp @@ -0,0 +1,81 @@ +/* Implementado por: Eduardo Machado e Victor Perszel */ +/* 2015 */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <dirent.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include <iostream> +#include <string> +#include <fstream> +#include <map> +#include <cstdlib> +#include <cmath> +#include <vector> + +using namespace std; + +int lsParameter(string parameter){ + if(parameter == ".") return 1; + else if(parameter == "-a") return 2; + else if(parameter == "-l") return 3; + else if(parameter == "-la") return 4; + else return -1; +} + +int lsMini(string parameter, char* currentPath){ + string mostra, temp, path, lsAux, fileName; + ifstream lsFile; + + path = currentPath; + /* Para dar um ls apenas, é necessário escrever "ls ." */ + /* Precisamos pensar em um jeito de concertar isso. */ + switch(lsParameter(parameter)){ + case 1: + lsAux = "ls > " + path + "/ls.txt"; + system(lsAux.c_str()); + break; + case 2: + lsAux = "ls -a > " + path + "/ls.txt"; + system(lsAux.c_str()); + break; + case 3: + lsAux = "ls -l > " + path + "/ls.txt"; + system(lsAux.c_str()); + break; + case 4: + lsAux = "ls -la > " + path + "/ls.txt"; + system(lsAux.c_str()); + break; + case -1: + puts("Parâmetro de ls inválido."); + return -1; + break; + } + printf("\n"); + + // Abertura do arquivo de entrada. + fileName = path + "/ls.txt"; + lsFile.open(fileName.c_str(), ios::in); + lsFile.seekg (0); + // Leitura do arquivo. + while(getline(lsFile, temp)) { + mostra += temp + "\n"; + } + // Remove arquivo ls.txt + remove(fileName.c_str()); + + cout << "mostra:" << mostra << endl; + return 0; +} + +int cdMini(string intendedDirectory){ + int errorTest; + errorTest = chdir(intendedDirectory.c_str()); + return errorTest; +} diff --git a/miniShell/runMiniShell.c b/miniShell/runMiniShell.cpp similarity index 51% rename from miniShell/runMiniShell.c rename to miniShell/runMiniShell.cpp index f08d387a16f5b4fb661c04cbc78ad92f9c512fb6..3bbb1dd1f30db58577d3ef9677ebef3a98c7970b 100644 --- a/miniShell/runMiniShell.c +++ b/miniShell/runMiniShell.cpp @@ -1,16 +1,12 @@ /* Programa criado apenas para fazer testes da biblioteca miniShell */ -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include "miniShell.c" +#include "miniShell.cpp" int main(int argc, char const *argv[]) { - char *command, *parameter, *buff, *currentPath; + char *buff, *currentPath; long size; + string command, parameter; - command=malloc(sizeof(char)*10); - parameter=malloc(sizeof(char)*10); while(1){ /* Escreve onde você está. */ size = pathconf(".", _PC_PATH_MAX); @@ -19,14 +15,14 @@ int main(int argc, char const *argv[]) { printf("%s $ ", currentPath); /* Executa o comando escolhido. */ - scanf("%s", command); - if(strcmp(command,"ls")==0){ - strcpy(parameter,""); - scanf("%s", parameter); - lsMini(parameter); + cin >> command; + if(command == "ls"){ + parameter = ""; + cin >> parameter; + lsMini(parameter, currentPath); } - else if(strcmp(command,"cd")==0){ - scanf("%s", parameter); + else if(command == "cd"){ + cin >> parameter; cdMini(parameter); } } diff --git a/src/messages.cpp b/src/messages.cpp index df99bf0241d24e96fb200644d152d3f82fb641d0..cc938869e79f0faa03cbe3bba48a7b0459a0b02a 100644 --- a/src/messages.cpp +++ b/src/messages.cpp @@ -118,13 +118,12 @@ int Message::sendLS(unsigned char* options){ send(soquete,nack.objToString(),nack.getSize()+4, 0); success = 0; } else { - strcat(listagem,(char*)answer.getData()); // Põe em "listagem" - ack.setData((unsigned char*)answer.getSeq(),1,0); - send(soquete, ack.objToString(), ack.getSize()+4, 0); // Manda um ACK + if(receiveData((unsigned char*)"ls", atoi((char*)answer.getData()), 0) == 0){ + success = 1; + }else{ + success = 0; + } } - } else if (answer.getType() == 15) { // Se for FIM - ack.setData((unsigned char*)answer.getSeq(),1,0); - success = 1; } } } else { @@ -247,13 +246,20 @@ int Message::sendPUT(unsigned char* fileName){ } } -int Message::sendGET(unsigned char* fileName){ - int error, success = 0, garbage, rv; +int Message::sendGET(unsigned char* fileName, char* currentPath){ + int error, success = 0, garbage, rv, size, availableSize; char *receiptMessage = (char*)malloc(sizeof(char*)*64); string temp, fileData; struct pollfd ufds[1]; // usado para timeout em recv SubMessage get, answer, ack, nack, err, ok; ofstream fileOut; + struct statvfs *buff; + + // Calcula espaço livre + if(statvfs(currentPath, buff) == -1){ + cout << "Erro ao calcular espaço livre (messages.cpp::receivePUT)" << endl; + } + availableSize = buff->f_bsize * buff->f_bfree; ufds[0].fd = soquete; ufds[0].events = POLLIN; @@ -296,7 +302,8 @@ int Message::sendGET(unsigned char* fileName){ success = 0; } } else if (answer.getType() == 9){ // Tamanho - if(testaSeTamanhoEhInvalido()){ + size = atoi((char*)answer.getData()); + if(availableSize < size){ err.setData((unsigned char*)answer.getSeq(),1,0); send(soquete, err.objToString(), err.getSize()+4, 0); // Erro return -1; @@ -307,10 +314,10 @@ int Message::sendGET(unsigned char* fileName){ } else { ok.setData((unsigned char*)answer.getSeq(),8,0); // Manda um ok send(soquete,ok.objToString(),ok.getSize()+4, 0); - if(receiveData(fileName,atoi((char*)answer.getData())) == -1){ + if(receiveData(fileName,atoi((char*)answer.getData()),1) == -1){ cout << "Erro no recebimento de dados (messages.cpp::sendGET)" << endl; return -1; - } else{ + } else { cout << "Arquivo transferido com sucesso" << endl; return 0; } @@ -522,11 +529,81 @@ int Message::receiveCD(unsigned char* intendedDirectory){ } } +int Message::lsParameter(string parameter){ + if(parameter == ".") return 1; + else if(parameter == "-a") return 2; + else if(parameter == "-l") return 3; + else if(parameter == "-la") return 4; + else return -1; +} + +int Message::receiveLS(unsigned char* options, char* currentPath){ + string show, temp, path, lsAux, fileName, parameter; + ifstream lsFile; + unsigned char* lsData; + int i; + + parameter = (char*)options; + path = currentPath; + /* Para dar um ls apenas, é necessário escrever "ls ." */ + /* Precisamos pensar em um jeito de concertar isso. */ + switch(lsParameter(parameter)){ + case 1: + lsAux = "ls > " + path + "/ls.txt"; + system(lsAux.c_str()); + break; + case 2: + lsAux = "ls -a > " + path + "/ls.txt"; + system(lsAux.c_str()); + break; + case 3: + lsAux = "ls -l > " + path + "/ls.txt"; + system(lsAux.c_str()); + break; + case 4: + lsAux = "ls -la > " + path + "/ls.txt"; + system(lsAux.c_str()); + break; + case -1: + puts("Parâmetro de ls inválido."); + return -1; + break; + } + printf("\n"); + + // Abertura do arquivo de entrada. + fileName = path + "/ls.txt"; + lsFile.open(fileName.c_str(), ios::in); + lsFile.seekg (0); + // Leitura do arquivo. + while(getline(lsFile, temp)) { + show += temp + "\n"; + } + // Remove arquivo ls.txt + remove(fileName.c_str()); + + lsData=(unsigned char*)malloc(sizeof(unsigned char)*show.size()); + for(i = 0; i < show.size(); i++){ + lsData[i] = show[i]; + } + + if(sendData(lsData) == 0){ + return 0; + }else{ + return -1; + } +} + int Message::receiveGET(unsigned char* fileName){ - SubMessage resposta; - FILE *file; char* tam; - int fileSize; + unsigned char* dados; + int fileSize, rv, i, success = 0; + ifstream file; + string temp, data; + SubMessage resposta, answer; + struct pollfd ufds[1]; + ufds[0].fd = soquete; + ufds[0].events = POLLIN; if(access((char*)fileName, F_OK) == -1){ // Verifica se o arquivo existe resposta.setData((unsigned char*)'0',14,0); // Manda um Erro @@ -536,18 +613,119 @@ int Message::receiveGET(unsigned char* fileName){ send(soquete,resposta.objToString(),resposta.getSize()+4, 0); } else { // Calcula o tamanho do arquivo - file = fopen((char*)fileName, "r"); - fseek(file, 0, SEEK_END); - fileSize = ftell(file); + file.seekg (0, ios::end); + fileSize = file.tellg(); + file.seekg (0, ios::beg); + + while(getline(file, temp)) { + data += temp + "\n"; + } + dados=(unsigned char*)malloc(sizeof(unsigned char)*data.size()); + for(i = 0; i < data.size(); ++i){ + dados[i] = data[i]; + } + // Manda o tamanho do arquivo sprintf(tam, "%d", fileSize); - resposta.setData((unsigned char*)tam,9,0); - send(soquete, resposta.objToString(), resposta.getSize()+4, 0); - } + while(!success){ // Esse while está aqui pois a mensagem pode não chegar e precisar ser reenviada + resposta.setData((unsigned char*)tam,9,0); + send(soquete, resposta.objToString(), resposta.getSize()+4, 0); + // Espera resposta + rv = poll(ufds, 1, 500); + if(rv){ + if(rv == -1){ + cout << "Erro no recebimento dos dados (messages.cpp::receiveGET)" << endl; + return -1; + } else { + // Lê começo da mensagem e vê se tem o delimitador de início + if(answer.getStartMessage() == 0x7E){ // 0x7E = 01111110 + if(answer.getType() == 14){ // Recebemos um erro + // Tamanho é muito pequeno + cout << "Tamanho de arquivo muito grande, pare (messages.cpp::receiveGET)" << endl; + return -1; + } else if(answer.getType() == 8){ // Recebemos um OK, enviar dados + success = 1; + if(sendData(dados)){ + cout << "Erro ao enviar dados, abortando (messages.cpp::receiveGET)" << endl; + return -1; + } else { + cout << "Dados enviados com sucesso" << endl; + return 0; + } + } else { // Provavelmente recebemos um NACK, de qualquer jeito, enviamos de novo + success = 0; + } + } + } + } else { + // TIMEOUT + cout << "Tempo limite de resposta excedido :c\n" << endl; + cout << "TIMEOUT ATINGIDO (messages.cpp::receiveGET)" << endl; + return -1; + } + } + } +} +int Message::receivePUT(unsigned char* fileName, char* currentPath){ + int success = 0, rv, size, availableSize; + char *receiptMessage = (char*)malloc(sizeof(char*)*64); + SubMessage resposta, answer; + struct statvfs *buff; + struct pollfd ufds[1]; + ufds[0].fd = soquete; + ufds[0].events = POLLIN; + + // Calcula espaço livre + if(statvfs(currentPath, buff) == -1){ + cout << "Erro ao calcular espaço livre (messages.cpp::receivePUT)" << endl; + } + availableSize = buff->f_bsize * buff->f_bfree; + while(!success){ + rv = poll(ufds, 1, 500); + if(rv){ + if(rv == -1){ + cout << "Erro no recebimento dos dados (messages.cpp::receivePUT)" << endl; + return -1; + } else { + // Esperamos receber o tamanho + recv(soquete, receiptMessage, 68*sizeof(char), 0); + answer.stringToObj((unsigned char*)receiptMessage); + // Lê começo da mensagem e vê se tem o delimitador de início + if(answer.getStartMessage() == 0x7E){ // 0x7E = 01111110 + if(answer.getType() == 9){ // Recebeu tamanho + success = 1; + size = atoi((char*)answer.getData()); // Converte o tamanho para int + if(answer.checkParity()){ // Se a paridade estiver errada + resposta.setData((unsigned char*)answer.getSeq(),0,0); // Manda um nack + send(soquete,resposta.objToString(),resposta.getSize()+4, 0); + } else if (availableSize < size){ // Se não houver espaço + resposta.setData((unsigned char*)'2',14,0); // Manda um Erro + send(soquete,resposta.objToString(),resposta.getSize()+4, 0); + } else { + resposta.setData((unsigned char*)'0',8,0); // Manda um OK + send(soquete,resposta.objToString(),resposta.getSize()+4, 0); + // Fica esperando dados + if(receiveData(fileName,size,1) == 0){ + cout << "Dados recebidos com sucesso!" << endl; + return 0; + } else { + cout << "Erro ao receber dados (messages.cpp::receivePUT)" << endl; + return -1; + } + } + } + } + } + } else { + // TIMEOUT + cout << "Tempo limite de resposta excedido :c\n" << endl; + cout << "TIMEOUT ATINGIDO (messages.cpp::receivePUT)" << endl; + } + } } -int Message::receiveData(unsigned char* fileName, int size){ +int Message::receiveData(unsigned char* fileName, int size, int save){ int numberOfMessages, messagesCounter = 0, seqCounter; int i, garbage, error, rv, success = 0, greaterSeq = 0; unsigned char *subData; @@ -627,8 +805,14 @@ while(!success){ for(i = 0; i < greaterSeq; ++i){ finalMessage += subMensagem[i]; } - // Escrita no arquivo de saída. - fileOut.open((char *)fileName, ios::out); - fileOut << finalMessage; + + if(save){ + // Escrita no arquivo de saída. + fileOut.open((char *)fileName, ios::out); + fileOut << finalMessage; + } else { + cout << finalMessage << endl; + } + return 0; }