From e5d2c9c5b2a2de0b2dc5844d3b5525e0d646170f Mon Sep 17 00:00:00 2001 From: elvis Date: Sat, 23 Apr 2022 00:56:30 +0200 Subject: [PATCH] all api functions --- lib/api/api.c | 749 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 718 insertions(+), 31 deletions(-) diff --git a/lib/api/api.c b/lib/api/api.c index 61b306c..8827102 100644 --- a/lib/api/api.c +++ b/lib/api/api.c @@ -74,7 +74,7 @@ static openfiles_t *openedFiles = NULL; // closes every file opened by the client int closeEveryFile(); // closes and frees memory -int removeOpenFile(char *pathname); +int removeOpenFile(const char *pathname); // adds element int addOpenFile(const char *pathname); // checks if the file is open already @@ -83,7 +83,7 @@ int isOpen(const char *pathname); // expected is 1 if a file could be sent (if no server errors occurs) int reciveData(response_t *res, int expected); // saves the files in the specified directory -int storeFilesInDirectory(char *dirname, int n, recivedFile_t *rf); +int storeFilesInDirectory(const char *dirname, int n, recivedFile_t *rf); // frees memory inside response_t element void freeResponse(response_t *res); @@ -208,7 +208,7 @@ int openFile(const char* pathname, int flags) { } // invio al server la stringa "openFile|$(pathname)|$(flags)" - size_t len = strlen("openFile")+1+strlen(pathname)+1+sizeof(flags)+1; + long len = strlen("openFile")+1+strlen(pathname)+1+sizeof(flags)+1; char *cmd = malloc(len); if(!cmd) { perror("malloc"); @@ -218,6 +218,11 @@ int openFile(const char* pathname, int flags) { snprintf(cmd, len, "openFile|%s|%d", pathname, flags); // send cmd + if (writen(fd_skt, &len, sizeof(long)) == -1) { + // writen sets errno + free(cmd); + return -1; + } if (writen(fd_skt, cmd, len) == -1) { // writen sets errno free(cmd); @@ -249,16 +254,16 @@ int openFile(const char* pathname, int flags) { if(strncmp(res->ME, MEFP, sizeof(res->ME)) == 0) { // some files were purged if(openedFiles->print){ - fprintf(openedFiles->out, "Il server ha espulso i seguenti file:"); - fflush(stdout); + fprintf(openedFiles->out, "Il server ha espulso i seguenti file:\n"); + fflush(openedFiles->out); for(int i=0;inumfiles;++i) { - fprintf(openedFiles->out, "%d) %s", i, res->rf[i].path); + fprintf(openedFiles->out, "%d) %s\n", i, res->rf[i].path); } } if(openedFiles->wDir) { if(openedFiles->print) { - fprintf(openedFiles->out, "I file espulsi sono stati scritti nella cartella: %s", openedFiles->wDir); - fflush(stdout); + fprintf(openedFiles->out, "I file espulsi sono stati scritti nella cartella: %s\n", openedFiles->wDir); + fflush(openedFiles->out); } if(storeFilesInDirectory(openedFiles->wDir, res->numfiles, res->rf) == -1) { perror("storeFilesindirectory"); @@ -269,8 +274,8 @@ int openFile(const char* pathname, int flags) { } } else { if(openedFiles->print) { - fprintf(openedFiles->out, "I file espulsi non sono stati memorizzati su disco"); - fflush(stdout); + fprintf(openedFiles->out, "I file espulsi non sono stati memorizzati su disco\n"); + fflush(openedFiles->out); } } } @@ -319,13 +324,13 @@ int readFile(const char* pathname, void** buf, size_t* size) { return -1; } - if (isOpen(pathname) != 1) { // if it's not open => error + if(isOpen(pathname) != 1) { // if it's not open => error errno = EPERM; return -1; } // invio al server la stringa readFile|$(pathname)" - size_t len = strlen("readFile")+1+strlen(pathname)+1; + long len = strlen("readFile")+1+strlen(pathname)+1; char *cmd = malloc(len); if(!cmd) { perror("malloc"); @@ -335,6 +340,11 @@ int readFile(const char* pathname, void** buf, size_t* size) { snprintf(cmd, len, "readFile|%s", pathname); // send cmd + if (writen(fd_skt, &len, sizeof(long)) == -1) { + // writen sets errno + free(cmd); + return -1; + } if (writen(fd_skt, cmd, len) == -1) { // writen sets errno free(cmd); @@ -355,8 +365,7 @@ int readFile(const char* pathname, void** buf, size_t* size) { free(cmd); return -1; } - if(res->meerrno != 0) { - // errno from server + if(res->meerrno != 0) { // errno from server freeResponse(res); errno = res->meerrno; free(res); @@ -383,14 +392,14 @@ int readFile(const char* pathname, void** buf, size_t* size) { } memcpy(*buf, res->rf[0].file, *size); if(openedFiles->print) { - printf("Letto il file: %s", res->rf[0].path); + printf("Letto il file: %s\n", res->rf[0].path); printf("Di dimensione: %ld B\n", *size); - fflush(stdout); + fflush(openedFiles->out); } if(openedFiles->rDir) { if(openedFiles->print) { - fprintf(openedFiles->out, "Il file letto e' stato scritto nella cartella: %s", openedFiles->rDir); - fflush(stdout); + fprintf(openedFiles->out, "Il file letto e' stato scritto nella cartella: %s\n", openedFiles->rDir); + fflush(openedFiles->out); } if(storeFilesInDirectory(openedFiles->rDir, 1, res->rf) == -1) { perror("storeFilesindirectory"); @@ -401,12 +410,11 @@ int readFile(const char* pathname, void** buf, size_t* size) { } } else { if(openedFiles->print) { - fprintf(openedFiles->out, "Il file letto non è stato memorizzato su disco"); - fflush(stdout); + fprintf(openedFiles->out, "Il file letto non è stato memorizzato su disco\n"); + fflush(openedFiles->out); } } - freeResponse(res); free(res); @@ -416,36 +424,717 @@ int readFile(const char* pathname, void** buf, size_t* size) { } int readNFiles(int N, const char* dirname) { - return 1; + if(!dirname) { + errno = EINVAL; + return -1; + } + if(!openedFiles){ + errno = EPROTO; + return -1; + } + if(openedFiles->createdAndLocked) + free(openedFiles->createdAndLocked); + openedFiles->createdAndLocked = NULL; + + if(strcmp(socketName, "") == 0) { + errno = ENOTCONN; + return -1; + } + + // invio al server la stringa "readNFile|$(N)" + long len = strlen("readNFile")+1+sizeof(N)+1; + char *cmd = malloc(len); + if(!cmd) { + perror("malloc"); + return -1; + } + memset(cmd, 0, len); + snprintf(cmd, len, "readNFile|%d", N); + + // send cmd + if (writen(fd_skt, &len, sizeof(long)) == -1) { + // writen sets errno + free(cmd); + return -1; + } + if (writen(fd_skt, cmd, len) == -1) { + // writen sets errno + free(cmd); + return -1; + } + + // recive response + response_t *res = calloc(1, sizeof(response_t)); + if(!res){ + perror("calloc"); + free(cmd); + return -1; + } + if(reciveData(res, 1) < 0) { // 1 because if we get a MEOK we expect N files + // errno is set by reciveData + freeResponse(res); + free(res); + free(cmd); + return -1; + } + if(res->meerrno != 0) { // errno from server + freeResponse(res); + errno = res->meerrno; + free(res); + free(cmd); + return -1; + } + // save files to directory + if(storeFilesInDirectory(dirname, res->numfiles, res->rf) == -1) { + perror("storeFilesindirectory"); + freeResponse(res); + free(res); + free(cmd); + return -1; + } + + int n = res->numfiles; + + freeResponse(res); + free(res); + + free(cmd); + return n; } int writeFile(const char* pathname, const char* dirname) { - return 1; + if(!pathname) { + errno = EINVAL; + return -1; + } + if(!openedFiles){ + errno = EPROTO; + return -1; + } + if (strcmp(openedFiles->createdAndLocked, pathname) != 0) { + errno = EPERM; + return -1; + } + if(openedFiles->createdAndLocked) + free(openedFiles->createdAndLocked); + openedFiles->createdAndLocked = NULL; + + if(strcmp(socketName, "") == 0) { + errno = ENOTCONN; + return -1; + } + + // leggo il file da scrivere sul server + int fdi = -1; + size_t lung = 0; + size_t incr = 0; + size_t size = 0; + if ((fdi = open(pathname, O_RDONLY)) == -1) { + perror("open"); + return -1; + } + + // get file length + struct stat sb; + if (fstat(fdi, &sb) == -1) { + perror("stat"); + return -1; + } + lung = sb.st_size; + + void *content = malloc(lung); + if(!content) { + perror("malloc"); + return -1; + } + + // read file + while ((incr = read(fdi, content, lung)) > 0) { + size += incr; + lung -= incr; + } + + if (incr == -1) { + free(content); + return -1; + } + + if (openedFiles->print) { + fprintf(openedFiles->out, "Dimensione: %ld B\n", size); + fflush(openedFiles->out); + } + + if (close(fdi) == -1) { + free(content); + return -1; + } + + // invio al server la stringa "writeFile|$(pathname)|$(size)" + long len = strlen("writeFile")+1+strlen(pathname)+1+sizeof(size)+1; + char *cmd = malloc(len); + if(!cmd) { + perror("malloc"); + free(content); + return -1; + } + memset(cmd, 0, len); + snprintf(cmd, len, "writeFile|%s|%zu", pathname, size); + + // send cmd + if (writen(fd_skt, &len, sizeof(long)) == -1) { + // writen sets errno + free(content); + free(cmd); + return -1; + } + if (writen(fd_skt, cmd, len) == -1) { + // writen sets errno + free(content); + free(cmd); + return -1; + } + + // recive response + response_t *res = calloc(1, sizeof(response_t)); + if(!res){ + perror("calloc"); + free(cmd); + free(content); + return -1; + } + if(reciveData(res, 0) < 0) { // 0 because if we get a MEOK we don't expect files + // errno is set by reciveData + freeResponse(res); + free(res); + free(cmd); + free(content); + return -1; + } + + if(res->meerrno != 0) { // errno from server + freeResponse(res); + errno = res->meerrno; + free(res); + free(cmd); + free(content); + return -1; + } + if(strncmp(res->ME, MEFP, sizeof(res->ME)) == 0) { + // some files were purged + if(openedFiles->print){ + fprintf(openedFiles->out, "Il server ha espulso i seguenti file:\n"); + fflush(openedFiles->out); + for(int i=0;inumfiles;++i) { + fprintf(openedFiles->out, "%d) %s\n", i, res->rf[i].path); + } + } + if(dirname) { + if(storeFilesInDirectory(dirname, res->numfiles, res->rf) == -1) { + perror("storeFilesindirectory"); + freeResponse(res); + free(res); + free(content); + free(cmd); + return -1; + } + if(openedFiles->print) { + fprintf(openedFiles->out, "I file espulsi sono stati scritti nella cartella: %s\n", dirname); + fflush(openedFiles->out); + } + } else { + if(openedFiles->print) { + fprintf(openedFiles->out, "I file espulsi non sono stati memorizzati su disco\n"); + fflush(openedFiles->out); + } + } + } + + // send file to server + if (writen(fd_skt, content, size) == -1) { + // errno set by writen + freeResponse(res); + free(res); + free(cmd); + free(content); + return -1; + } + + freeResponse(res); + free(res); + + free(cmd); + + free(content); + + return 0; } int appendToFile(const char* pathname, void* buf, size_t size, const char* dirname) { - return 1; + if(!pathname || !buf) { + errno = EINVAL; + return -1; + } + if(!openedFiles){ + errno = EPROTO; + return -1; + } + if(openedFiles->createdAndLocked) + free(openedFiles->createdAndLocked); + openedFiles->createdAndLocked = NULL; + + if(strcmp(socketName, "") == 0) { + errno = ENOTCONN; + return -1; + } + + if (isOpen(pathname) != 1) { + errno = EPERM; + return -1; + } + + if (openedFiles->print) { + fprintf(openedFiles->out, "Dimensione: %ld B\n", size); + fflush(openedFiles->out); + } + + // invio al server la stringa "appendToFile|$(pathname)|$(size)" + long len = strlen("appendToFile")+1+strlen(pathname)+1+sizeof(size)+1; + char *cmd = malloc(len); + if(!cmd) { + perror("malloc"); + return -1; + } + memset(cmd, 0, len); + snprintf(cmd, len, "appendToFile|%s|%zu", pathname, size); + + // send cmd + if (writen(fd_skt, &len, sizeof(long)) == -1) { + // writen sets errno + free(cmd); + return -1; + } + if (writen(fd_skt, cmd, len) == -1) { + // writen sets errno + free(cmd); + return -1; + } + + // recive response + response_t *res = calloc(1, sizeof(response_t)); + if(!res){ + perror("calloc"); + free(cmd); + return -1; + } + if(reciveData(res, 0) < 0) { // 0 because if we get a MEOK we don't expect files + // errno is set by reciveData + freeResponse(res); + free(res); + free(cmd); + return -1; + } + + if(res->meerrno != 0) { // errno from server + freeResponse(res); + errno = res->meerrno; + free(res); + free(cmd); + return -1; + } + + if(strncmp(res->ME, MEFP, sizeof(res->ME)) == 0) { + // some files were purged + if(openedFiles->print){ + fprintf(openedFiles->out, "Il server ha espulso i seguenti file:\n"); + fflush(openedFiles->out); + for(int i=0;inumfiles;++i) { + fprintf(openedFiles->out, "%d) %s\n", i, res->rf[i].path); + } + } + if(dirname) { + if(storeFilesInDirectory(dirname, res->numfiles, res->rf) == -1) { + perror("storeFilesindirectory"); + freeResponse(res); + free(res); + free(cmd); + return -1; + } + if(openedFiles->print) { + fprintf(openedFiles->out, "I file espulsi sono stati scritti nella cartella: %s\n", dirname); + fflush(openedFiles->out); + } + } else { + if(openedFiles->print) { + fprintf(openedFiles->out, "I file espulsi non sono stati memorizzati su disco\n"); + fflush(openedFiles->out); + } + } + } + + // send file to server + if (writen(fd_skt, buf, size) == -1) { + // errno set by writen + freeResponse(res); + free(res); + free(cmd); + return -1; + } + + freeResponse(res); + free(res); + free(cmd); + + return 0; } int lockFile(const char* pathname) { - return 1; + if(!pathname){ + errno = EINVAL; + return -1; + } + if(!openedFiles){ + errno = EPROTO; + return -1; + } + if(openedFiles->createdAndLocked) + free(openedFiles->createdAndLocked); + openedFiles->createdAndLocked = NULL; + + if(strcmp(socketName, "") == 0) { + errno = ENOTCONN; + return -1; + } + + int existing = 0; + if(isOpen(pathname)){ // file is already open + existing = 1; + goto _unlockFile; + } + + if (openFile(pathname, O_LOCK) == 0) // open the file with the lock + return 0; + + if (errno == ENOENT) // file created but not locked + goto _unlockFile; + + return -1; // errno != ENOENT + +_unlockFile: { + // invio al server la stringa "lockFile|$(pathname)" + long len = strlen("lockFile")+1+strlen(pathname)+1; + char *cmd = malloc(len); + if(!cmd) { + perror("malloc"); + return -1; + } + memset(cmd, 0, len); + snprintf(cmd, len, "lockFile|%s", pathname); + + // send cmd + if (writen(fd_skt, &len, sizeof(long)) == -1) { + // writen sets errno + free(cmd); + return -1; + } + if (writen(fd_skt, cmd, len) == -1) { + // writen sets errno + free(cmd); + return -1; + } + + // recive response + response_t *res = calloc(1, sizeof(response_t)); + if(!res){ + perror("calloc"); + free(cmd); + return -1; + } + + // 0 because if we get a MEOK we dont expect a file + if(reciveData(res, 0) < 0) { + // errno is set by reciveData + freeResponse(res); + free(res); + free(cmd); + return -1; + } + if(res->meerrno != 0) { + // errno from server + freeResponse(res); + errno = res->meerrno; + free(res); + free(cmd); + return -1; + } + + if(!existing) { + if(addOpenFile(pathname) == -1) { + perror("addOpenFile"); + freeResponse(res); + free(res); + free(cmd); + return -1; + } + } + + freeResponse(res); + free(res); + free(cmd); + return 0; + } } int unlockFile(const char* pathname) { - return 1; + if(!pathname){ + errno = EINVAL; + return -1; + } + if(!openedFiles){ + errno = EPROTO; + return -1; + } + if(openedFiles->createdAndLocked) + free(openedFiles->createdAndLocked); + openedFiles->createdAndLocked = NULL; + + if(strcmp(socketName, "") == 0) { + errno = ENOTCONN; + return -1; + } + if(isOpen(pathname) != 1) { // not open + errno = EPERM; + return -1; + } + + // invio al server la stringa "unlockFile|$(pathname)" + long len = strlen("unlockFile")+1+strlen(pathname)+1; + char *cmd = malloc(len); + if(!cmd) { + perror("malloc"); + return -1; + } + memset(cmd, 0, len); + snprintf(cmd, len, "unlockFile|%s", pathname); + + // send cmd + if (writen(fd_skt, &len, sizeof(long)) == -1) { + // writen sets errno + free(cmd); + return -1; + } + if (writen(fd_skt, cmd, len) == -1) { + // writen sets errno + free(cmd); + return -1; + } + + // recive response + response_t *res = calloc(1, sizeof(response_t)); + if(!res){ + perror("calloc"); + free(cmd); + return -1; + } + if(reciveData(res, 0) < 0) { // 0 because if we get a MEOK we dont expect a file + // errno is set by reciveData + freeResponse(res); + free(res); + free(cmd); + return -1; + } + if(res->meerrno != 0) { + // errno from server + freeResponse(res); + errno = res->meerrno; + free(res); + free(cmd); + return -1; + } + + freeResponse(res); + free(res); + free(cmd); + return 0; } int closeFile(const char *pathname) { - return 1; + if(!pathname){ + errno = EINVAL; + return -1; + } + if(!openedFiles){ + errno = EPROTO; + return -1; + } + if(openedFiles->createdAndLocked) + free(openedFiles->createdAndLocked); + openedFiles->createdAndLocked = NULL; + + if(strcmp(socketName, "") == 0) { + errno = ENOTCONN; + return -1; + } + + if(isOpen(pathname) != 1) { // not open + errno = EPERM; + return -1; + } + + // invio al server la stringa "closeFile|$(pathname)" + long len = strlen("closeFile")+1+strlen(pathname)+1; + char *cmd = malloc(len); + if(!cmd) { + perror("malloc"); + return -1; + } + memset(cmd, 0, len); + snprintf(cmd, len, "closeFile|%s", pathname); + + // send cmd + if (writen(fd_skt, &len, sizeof(long)) == -1) { + // writen sets errno + free(cmd); + return -1; + } + if (writen(fd_skt, cmd, len) == -1) { + // writen sets errno + free(cmd); + return -1; + } + + // recive response + response_t *res = calloc(1, sizeof(response_t)); + if(!res){ + perror("calloc"); + free(cmd); + return -1; + } + if(reciveData(res, 0) < 0) { // 0 because if we get a MEOK we dont expect a file + // errno is set by reciveData + freeResponse(res); + free(res); + free(cmd); + return -1; + } + if(res->meerrno != 0) { + // errno from server + freeResponse(res); + errno = res->meerrno; + free(res); + free(cmd); + return -1; + } + + if (removeOpenFile(pathname) == -1) { + perror("removeOpenFile"); + } else { + openedFiles->numOfFiles--; + } + + freeResponse(res); + free(res); + free(cmd); + + return 0; } int removeFile(const char* pathname) { + if(!pathname){ + errno = EINVAL; + return -1; + } + if(!openedFiles){ + errno = EPROTO; + return -1; + } + if(openedFiles->createdAndLocked) + free(openedFiles->createdAndLocked); + openedFiles->createdAndLocked = NULL; + + if(strcmp(socketName, "") == 0) { + errno = ENOTCONN; + return -1; + } + + if (isOpen(pathname) != 1) { // not open + errno = EPERM; + return -1; + } + + // invio al server la stringa "removeFile|$(pathname)" + long len = strlen("removeFile")+1+strlen(pathname)+1; + char *cmd = malloc(len); + if(!cmd) { + perror("malloc"); + return -1; + } + memset(cmd, 0, len); + snprintf(cmd, len, "removeFile|%s", pathname); + + // send cmd + if (writen(fd_skt, &len, sizeof(long)) == -1) { + // writen sets errno + free(cmd); + return -1; + } + if (writen(fd_skt, cmd, len) == -1) { + // writen sets errno + free(cmd); + return -1; + } + + // recive response + response_t *res = calloc(1, sizeof(response_t)); + if(!res){ + perror("calloc"); + free(cmd); + return -1; + } + if(reciveData(res, 0) < 0) { // 0 because if we get a MEOK we dont expect a file + // errno is set by reciveData + freeResponse(res); + free(res); + free(cmd); + return -1; + } + if(res->meerrno != 0) { + // errno from server + freeResponse(res); + errno = res->meerrno; + free(res); + free(cmd); + return -1; + } + + if (removeOpenFile(pathname) == -1) { + perror("removeOpenFile"); + } else { + openedFiles->numOfFiles--; + } + + free(cmd); return 1; } // ----------------------------------------------------------------------------- int setDirectory(char* Dir, int rw) { + if (!Dir) { + errno = EINVAL; + return -1; + } + + if (rw == 1) { + if(openedFiles->wDir) + free(openedFiles->wDir); + openedFiles->wDir = malloc(strlen(Dir)+1); + strncpy(openedFiles->wDir, Dir, strlen(Dir)+1); + } else { + if(openedFiles->rDir) + free(openedFiles->rDir); + openedFiles->rDir = malloc(strlen(Dir)+1); + strncpy(openedFiles->rDir, Dir, strlen(Dir)+1); + } return 1; } @@ -706,7 +1395,7 @@ _nofile: return -2; } -int storeFilesInDirectory(char *dirname, int n, recivedFile_t *rf) { +int storeFilesInDirectory(const char *dirname, int n, recivedFile_t *rf) { if(!dirname || strcmp(dirname, "") || !rf || n<0) { errno = EINVAL; return -1; @@ -775,8 +1464,6 @@ void freeResponse(response_t *res) { } free(res->rf); } - if(res->rf) - free(res->rf); return; } @@ -838,7 +1525,7 @@ int addOpenFile(const char *pathname) { return 0; } -int removeOpenFile(char *pathname) { +int removeOpenFile(const char *pathname) { if(!pathname) { errno = EINVAL; return -1;