openFile, readFile
This commit is contained in:
669
lib/api/api.c
669
lib/api/api.c
@ -1,16 +1,35 @@
|
|||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <api.h>
|
#include <api.h>
|
||||||
|
#include <conn.h>
|
||||||
|
|
||||||
#define SOCKNAMEMAX 256 // should be at least 108
|
#define SOCKNAMEMAX 256 // should be at least 108
|
||||||
|
|
||||||
|
|
||||||
|
#define MEOK "20" //OK
|
||||||
|
// #define ME "21" // not used
|
||||||
|
// #define ME "22" // not used
|
||||||
|
#define MEFP "25" // file purged
|
||||||
|
|
||||||
|
// #define ME "40" // not used
|
||||||
|
// #define ME "41" // not used
|
||||||
|
#define MESD "42" // shutting down
|
||||||
|
#define MENT "45" // requested file action not taken
|
||||||
|
|
||||||
|
#define MESY "50" // syntax error
|
||||||
|
// #define ME "51" // not used
|
||||||
|
// #define ME "52" // not used
|
||||||
|
#define MESE "55" // server error
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
/* structs */
|
/* structs */
|
||||||
typedef struct files_s {
|
typedef struct files_s {
|
||||||
@ -20,13 +39,29 @@ typedef struct files_s {
|
|||||||
|
|
||||||
typedef struct openfiles_s {
|
typedef struct openfiles_s {
|
||||||
int numOfFiles;
|
int numOfFiles;
|
||||||
files_t *f;
|
files_t *f; // list of files
|
||||||
char *wDir; // for files sent from the server after openFile
|
char *wDir; // for files sent from the server after openFile
|
||||||
char *rDir; // for files read from the server
|
char *rDir; // for files read from the server
|
||||||
|
char *createdAndLocked; // path of the last file that was created and locked
|
||||||
int print; // whether to print
|
int print; // whether to print
|
||||||
FILE *out; // where to print
|
FILE *out; // where to print
|
||||||
} openfiles_t;
|
} openfiles_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct recivedFile_s {
|
||||||
|
int64_t pathlen;
|
||||||
|
char *path;
|
||||||
|
int64_t filelen;
|
||||||
|
char *file;
|
||||||
|
} recivedFile_t;
|
||||||
|
|
||||||
|
typedef struct response_s {
|
||||||
|
char ME[2]; // response
|
||||||
|
int meerrno; // errno if sent
|
||||||
|
int numfiles; // number of files if sent
|
||||||
|
recivedFile_t *rf; // array of files
|
||||||
|
} response_t;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
/* variabili globali */
|
/* variabili globali */
|
||||||
static int fd_skt; // descriptor of the socket
|
static int fd_skt; // descriptor of the socket
|
||||||
@ -39,10 +74,18 @@ static openfiles_t *openedFiles = NULL;
|
|||||||
// closes every file opened by the client
|
// closes every file opened by the client
|
||||||
int closeEveryFile();
|
int closeEveryFile();
|
||||||
// closes and frees memory
|
// closes and frees memory
|
||||||
int removeOpenFile(const char *pathname);
|
int removeOpenFile(char *pathname);
|
||||||
|
// adds element
|
||||||
|
int addOpenFile(const char *pathname);
|
||||||
|
// checks if the file is open already
|
||||||
|
int isOpen(const char *pathname);
|
||||||
|
// reads everything the server sent into the variable passed to the function
|
||||||
|
// 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);
|
||||||
|
// frees memory inside response_t element
|
||||||
|
void freeResponse(response_t *res);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -62,6 +105,7 @@ int openConnection(const char* sockname, int msec, const struct timespec abstime
|
|||||||
}
|
}
|
||||||
openedFiles->f = NULL;
|
openedFiles->f = NULL;
|
||||||
openedFiles->numOfFiles = 0;
|
openedFiles->numOfFiles = 0;
|
||||||
|
openedFiles->createdAndLocked = NULL;
|
||||||
openedFiles->rDir = NULL;
|
openedFiles->rDir = NULL;
|
||||||
openedFiles->wDir = NULL;
|
openedFiles->wDir = NULL;
|
||||||
openedFiles->print = 0;
|
openedFiles->print = 0;
|
||||||
@ -130,6 +174,8 @@ int closeConnection(const char* sockname) {
|
|||||||
memset(socketName, 0, SOCKNAMEMAX);
|
memset(socketName, 0, SOCKNAMEMAX);
|
||||||
|
|
||||||
if (openedFiles) {
|
if (openedFiles) {
|
||||||
|
if(openedFiles->createdAndLocked)
|
||||||
|
free(openedFiles->createdAndLocked);
|
||||||
if(openedFiles->wDir)
|
if(openedFiles->wDir)
|
||||||
free(openedFiles->wDir);
|
free(openedFiles->wDir);
|
||||||
if(openedFiles->rDir)
|
if(openedFiles->rDir)
|
||||||
@ -141,11 +187,232 @@ int closeConnection(const char* sockname) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int openFile(const char* pathname, int flags) {
|
int openFile(const char* pathname, int flags) {
|
||||||
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)) { // already open
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// invio al server la stringa "openFile|$(pathname)|$(flags)"
|
||||||
|
size_t len = strlen("openFile")+1+strlen(pathname)+1+sizeof(flags)+1;
|
||||||
|
char *cmd = malloc(len);
|
||||||
|
if(!cmd) {
|
||||||
|
perror("malloc");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memset(cmd, 0, len);
|
||||||
|
snprintf(cmd, len, "openFile|%s|%d", pathname, flags);
|
||||||
|
|
||||||
|
// send cmd
|
||||||
|
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(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);
|
||||||
|
for(int i=0;i<res->numfiles;++i) {
|
||||||
|
fprintf(openedFiles->out, "%d) %s", 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);
|
||||||
|
}
|
||||||
|
if(storeFilesInDirectory(openedFiles->wDir, res->numfiles, res->rf) == -1) {
|
||||||
|
perror("storeFilesindirectory");
|
||||||
|
freeResponse(res);
|
||||||
|
free(res);
|
||||||
|
free(cmd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(openedFiles->print) {
|
||||||
|
fprintf(openedFiles->out, "I file espulsi non sono stati memorizzati su disco");
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(addOpenFile(pathname) == -1) {
|
||||||
|
perror("addOpenFile");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(flags == (O_CREATE | O_LOCK)) {
|
||||||
|
if(openedFiles->createdAndLocked)
|
||||||
|
free(openedFiles->createdAndLocked);
|
||||||
|
openedFiles->createdAndLocked = calloc(strlen(pathname)+1, sizeof(char));
|
||||||
|
if(!openedFiles->createdAndLocked) {
|
||||||
|
perror("calloc");
|
||||||
|
freeResponse(res);
|
||||||
|
free(res);
|
||||||
|
free(cmd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
strcpy(openedFiles->createdAndLocked, pathname);
|
||||||
|
}
|
||||||
|
|
||||||
|
freeResponse(res);
|
||||||
|
free(res);
|
||||||
|
|
||||||
|
free(cmd);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int readFile(const char* pathname, void** buf, size_t* size) {
|
int readFile(const char* pathname, void** buf, size_t* size) {
|
||||||
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) { // 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;
|
||||||
|
char *cmd = malloc(len);
|
||||||
|
if(!cmd) {
|
||||||
|
perror("malloc");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memset(cmd, 0, len);
|
||||||
|
snprintf(cmd, len, "readFile|%s", pathname);
|
||||||
|
|
||||||
|
// send cmd
|
||||||
|
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 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// no errors from server
|
||||||
|
if(res->numfiles != 1) {
|
||||||
|
freeResponse(res);
|
||||||
|
free(res);
|
||||||
|
free(cmd);
|
||||||
|
errno = EMSGSIZE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*size = (size_t) res->rf[0].filelen;
|
||||||
|
*buf = malloc(*size);
|
||||||
|
if(!*buf) {
|
||||||
|
freeResponse(res);
|
||||||
|
free(res);
|
||||||
|
free(cmd);
|
||||||
|
perror("malloc");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memcpy(*buf, res->rf[0].file, *size);
|
||||||
|
if(openedFiles->print) {
|
||||||
|
printf("Letto il file: %s", res->rf[0].path);
|
||||||
|
printf("Di dimensione: %ld B\n", *size);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
if(openedFiles->rDir) {
|
||||||
|
if(openedFiles->print) {
|
||||||
|
fprintf(openedFiles->out, "Il file letto e' stato scritto nella cartella: %s", openedFiles->rDir);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
if(storeFilesInDirectory(openedFiles->rDir, 1, res->rf) == -1) {
|
||||||
|
perror("storeFilesindirectory");
|
||||||
|
freeResponse(res);
|
||||||
|
free(res);
|
||||||
|
free(cmd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(openedFiles->print) {
|
||||||
|
fprintf(openedFiles->out, "Il file letto non è stato memorizzato su disco");
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
freeResponse(res);
|
||||||
|
free(res);
|
||||||
|
|
||||||
|
free(cmd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int readNFiles(int N, const char* dirname) {
|
int readNFiles(int N, const char* dirname) {
|
||||||
@ -191,7 +458,387 @@ void printInfo(int p, FILE *stream) {
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
int removeOpenFile(const char *pathname) {
|
int reciveData(response_t *res, int expected) {
|
||||||
|
if(!res) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int readnres;
|
||||||
|
readnres = readn(fd_skt, res->ME, sizeof(res->ME));
|
||||||
|
if(readnres <= 0) {
|
||||||
|
// readn sets errno
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(expected == 0) // no file expected
|
||||||
|
goto _nofile;
|
||||||
|
|
||||||
|
|
||||||
|
// file is expected
|
||||||
|
if(strncmp(res->ME, MEOK, sizeof(res->ME))==0){
|
||||||
|
// ok response
|
||||||
|
res->meerrno = 0;
|
||||||
|
// get number of files sent
|
||||||
|
readnres = readn(fd_skt, &res->numfiles, sizeof(int));
|
||||||
|
if(readnres<=0) // readn sets errno
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if(res->rf)
|
||||||
|
free(res->rf);
|
||||||
|
res->rf = calloc(res->numfiles, sizeof(recivedFile_t));
|
||||||
|
if(!res->rf){
|
||||||
|
perror("calloc");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// get files
|
||||||
|
for(int i=0;i<res->numfiles;++i) {
|
||||||
|
// read path
|
||||||
|
readnres = readn(fd_skt, &res->rf[i].pathlen, sizeof(int64_t));
|
||||||
|
if(readnres<=0) // readn sets errno
|
||||||
|
return -1;
|
||||||
|
res->rf[i].path = calloc(res->rf[i].pathlen, sizeof(char));
|
||||||
|
if(!res->rf[i].path){
|
||||||
|
perror("calloc");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
readnres = readn(fd_skt, res->rf[i].path, res->rf[i].pathlen);
|
||||||
|
if(readnres<=0) // readn sets errno
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// we replace '/' char with '-'
|
||||||
|
for(int j=0;j<res->rf[i].pathlen; ++j){
|
||||||
|
if(res->rf[i].path[j] == '/')
|
||||||
|
res->rf[i].path[j] = '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
// read file
|
||||||
|
readnres = readn(fd_skt, &res->rf[i].filelen, sizeof(int64_t));
|
||||||
|
if(readnres<=0) // readn sets errno
|
||||||
|
return -1;
|
||||||
|
res->rf[i].file = calloc(res->rf[i].filelen, sizeof(char));
|
||||||
|
if(!res->rf[i].file){
|
||||||
|
perror("calloc");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
readnres = readn(fd_skt, res->rf[i].file, res->rf[i].filelen);
|
||||||
|
if(readnres<=0) // readn sets errno
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(strncmp(res->ME, MEFP, sizeof(res->ME))==0){
|
||||||
|
// file purged
|
||||||
|
res->meerrno = 0;
|
||||||
|
// get number of files sent
|
||||||
|
readnres = readn(fd_skt, &res->numfiles, sizeof(int));
|
||||||
|
if(readnres<=0) // readn sets errno
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if(res->rf)
|
||||||
|
free(res->rf);
|
||||||
|
res->rf = calloc(res->numfiles, sizeof(recivedFile_t));
|
||||||
|
if(!res->rf){
|
||||||
|
perror("calloc");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// get files
|
||||||
|
for(int i=0;i<res->numfiles;++i) {
|
||||||
|
// read path
|
||||||
|
readnres = readn(fd_skt, &res->rf[i].pathlen, sizeof(int64_t));
|
||||||
|
if(readnres<=0) // readn sets errno
|
||||||
|
return -1;
|
||||||
|
res->rf[i].path = calloc(res->rf[i].pathlen, sizeof(char));
|
||||||
|
if(!res->rf[i].path){
|
||||||
|
perror("calloc");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
readnres = readn(fd_skt, res->rf[i].path, res->rf[i].pathlen);
|
||||||
|
if(readnres<=0) // readn sets errno
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// we replace '/' char with '-'
|
||||||
|
for(int j=0;j<res->rf[i].pathlen; ++j){
|
||||||
|
if(res->rf[i].path[j] == '/')
|
||||||
|
res->rf[i].path[j] = '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
// read file
|
||||||
|
readnres = readn(fd_skt, &res->rf[i].filelen, sizeof(int64_t));
|
||||||
|
if(readnres<=0) // readn sets errno
|
||||||
|
return -1;
|
||||||
|
res->rf[i].file = calloc(res->rf[i].filelen, sizeof(char));
|
||||||
|
if(!res->rf[i].file){
|
||||||
|
perror("calloc");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
readnres = readn(fd_skt, res->rf[i].file, res->rf[i].filelen);
|
||||||
|
if(readnres<=0) // readn sets errno
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(strncmp(res->ME, MESD, sizeof(res->ME))==0){
|
||||||
|
// server shutting down
|
||||||
|
readnres = readn(fd_skt, &res->meerrno, sizeof(errno));
|
||||||
|
if(readnres <= 0)// readn sets errno
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(strncmp(res->ME, MENT, sizeof(res->ME))==0){
|
||||||
|
// requested file action not taken
|
||||||
|
readnres = readn(fd_skt, &res->meerrno, sizeof(errno));
|
||||||
|
if(readnres <= 0)// readn sets errno
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(strncmp(res->ME, MESY, sizeof(res->ME))==0){
|
||||||
|
// syntax error
|
||||||
|
readnres = readn(fd_skt, &res->meerrno, sizeof(errno));
|
||||||
|
if(readnres <= 0)// readn sets errno
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(strncmp(res->ME, MESE, sizeof(res->ME))==0){
|
||||||
|
// server error
|
||||||
|
readnres = readn(fd_skt, &res->meerrno, sizeof(errno));
|
||||||
|
if(readnres <= 0)// readn sets errno
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = ENOPROTOOPT;
|
||||||
|
return -2;
|
||||||
|
|
||||||
|
_nofile:
|
||||||
|
res->numfiles = 0;
|
||||||
|
if(res->rf)
|
||||||
|
free(res->rf);
|
||||||
|
res->rf = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
if(strncmp(res->ME, MEOK, sizeof(res->ME))==0){
|
||||||
|
// simple ok response
|
||||||
|
res->meerrno = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(strncmp(res->ME, MEFP, sizeof(res->ME))==0){
|
||||||
|
// file purged
|
||||||
|
res->meerrno = 0;
|
||||||
|
// get number of files sent
|
||||||
|
readnres = readn(fd_skt, &res->numfiles, sizeof(int));
|
||||||
|
if(readnres<=0) // readn sets errno
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if(res->rf)
|
||||||
|
free(res->rf);
|
||||||
|
res->rf = calloc(res->numfiles, sizeof(recivedFile_t));
|
||||||
|
if(!res->rf){
|
||||||
|
perror("calloc");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// get files
|
||||||
|
for(int i=0;i<res->numfiles;++i) {
|
||||||
|
// read path
|
||||||
|
readnres = readn(fd_skt, &res->rf[i].pathlen, sizeof(int64_t));
|
||||||
|
if(readnres<=0) // readn sets errno
|
||||||
|
return -1;
|
||||||
|
res->rf[i].path = calloc(res->rf[i].pathlen, sizeof(char));
|
||||||
|
if(!res->rf[i].path){
|
||||||
|
perror("calloc");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
readnres = readn(fd_skt, res->rf[i].path, res->rf[i].pathlen);
|
||||||
|
if(readnres<=0) // readn sets errno
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// we replace '/' char with '-'
|
||||||
|
for(int j=0;j<res->rf[i].pathlen; ++j){
|
||||||
|
if(res->rf[i].path[j] == '/')
|
||||||
|
res->rf[i].path[j] = '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
// read file
|
||||||
|
readnres = readn(fd_skt, &res->rf[i].filelen, sizeof(int64_t));
|
||||||
|
if(readnres<=0) // readn sets errno
|
||||||
|
return -1;
|
||||||
|
res->rf[i].file = calloc(res->rf[i].filelen, sizeof(char));
|
||||||
|
if(!res->rf[i].file){
|
||||||
|
perror("calloc");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
readnres = readn(fd_skt, res->rf[i].file, res->rf[i].filelen);
|
||||||
|
if(readnres<=0) // readn sets errno
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(strncmp(res->ME, MESD, sizeof(res->ME))==0){
|
||||||
|
// server shutting down
|
||||||
|
readnres = readn(fd_skt, &res->meerrno, sizeof(errno));
|
||||||
|
if(readnres <= 0)// readn sets errno
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(strncmp(res->ME, MENT, sizeof(res->ME))==0){
|
||||||
|
// requested file action not taken
|
||||||
|
readnres = readn(fd_skt, &res->meerrno, sizeof(errno));
|
||||||
|
if(readnres <= 0)// readn sets errno
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(strncmp(res->ME, MESY, sizeof(res->ME))==0){
|
||||||
|
// syntax error
|
||||||
|
readnres = readn(fd_skt, &res->meerrno, sizeof(errno));
|
||||||
|
if(readnres <= 0)// readn sets errno
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(strncmp(res->ME, MESE, sizeof(res->ME))==0){
|
||||||
|
// server error
|
||||||
|
readnres = readn(fd_skt, &res->meerrno, sizeof(errno));
|
||||||
|
if(readnres <= 0)// readn sets errno
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = ENOPROTOOPT;
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int storeFilesInDirectory(char *dirname, int n, recivedFile_t *rf) {
|
||||||
|
if(!dirname || strcmp(dirname, "") || !rf || n<0) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create directory
|
||||||
|
if(mkdir(dirname, 0777) == -1) {
|
||||||
|
if(errno != EEXIST) { // unknown error
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t basepathlen = strlen(dirname)+1+1; // +1 for '/' and +1 for '\0'
|
||||||
|
char *basepath = calloc(basepathlen, sizeof(char));
|
||||||
|
if(!basepath) {
|
||||||
|
perror("calloc");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
strcpy(basepath, dirname);
|
||||||
|
strlcat(basepath, "/", basepathlen);
|
||||||
|
|
||||||
|
// for each file, create and write
|
||||||
|
for(int i=0;i<n;++i) {
|
||||||
|
char *filename = calloc(basepathlen + rf[i].pathlen, sizeof(char));
|
||||||
|
if(!filename){
|
||||||
|
perror("calloc");
|
||||||
|
free(basepath);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
strcpy(filename, basepath);
|
||||||
|
strlcat(filename, rf[i].path, basepathlen + rf[i].pathlen);
|
||||||
|
|
||||||
|
int fdo;
|
||||||
|
if((fdo = open(filename, O_WRONLY | O_CREAT, 0666)) == -1) { // open
|
||||||
|
free(filename);
|
||||||
|
free(basepath);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(write(fdo, rf[i].file, rf[i].filelen) == -1) { // write
|
||||||
|
free(filename);
|
||||||
|
free(basepath);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(close(fdo) == -1) { // close
|
||||||
|
free(filename);
|
||||||
|
free(basepath);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(basepath);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeResponse(response_t *res) {
|
||||||
|
if(!res)
|
||||||
|
return;
|
||||||
|
if(res->numfiles>0 && res->rf){
|
||||||
|
for(int i=0;i<res->numfiles;++i){
|
||||||
|
free(res->rf[i].path);
|
||||||
|
free(res->rf[i].file);
|
||||||
|
}
|
||||||
|
free(res->rf);
|
||||||
|
}
|
||||||
|
if(res->rf)
|
||||||
|
free(res->rf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int isOpen(const char *pathname) {
|
||||||
|
if(!pathname) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (openedFiles == NULL || openedFiles->f == NULL || openedFiles->numOfFiles == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
files_t *tmp = openedFiles->f;
|
||||||
|
while(tmp) {
|
||||||
|
if(strcmp(tmp->filename, pathname) == 0)
|
||||||
|
return 1;
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int addOpenFile(const char *pathname) {
|
||||||
|
if(!pathname) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
files_t *new = malloc(sizeof(files_t));
|
||||||
|
if(!new) {
|
||||||
|
perror("malloc");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t len = strlen(pathname)+1;
|
||||||
|
new->filename = calloc(len, sizeof(char));
|
||||||
|
if(!new->filename) {
|
||||||
|
perror("calloc");
|
||||||
|
free(new);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
strlcpy(new->filename, pathname, len);
|
||||||
|
new->next = NULL;
|
||||||
|
|
||||||
|
if(openedFiles->f == NULL) {
|
||||||
|
openedFiles->f = new;
|
||||||
|
openedFiles->numOfFiles = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
files_t *tail = openedFiles->f;
|
||||||
|
while(tail->next) {
|
||||||
|
tail = tail->next;
|
||||||
|
}
|
||||||
|
tail->next = new;
|
||||||
|
openedFiles->numOfFiles++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int removeOpenFile(char *pathname) {
|
||||||
if(!pathname) {
|
if(!pathname) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
#define LOGBUFSIZE 2048
|
#define LOGBUFSIZE 2048
|
||||||
|
|
||||||
#define MEOK "20" //OK
|
#define MEOK "20" //OK
|
||||||
#define MEHE "21" // help message
|
// #define ME "21" // not used
|
||||||
// #define ME "22" // not used
|
// #define ME "22" // not used
|
||||||
#define MEFP "25" // file purged
|
#define MEFP "25" // file purged
|
||||||
|
|
||||||
@ -131,6 +131,12 @@ void sendMessageFile(char *m, fileT *f, long fd_c, taglia_t *taglia, char *mlog)
|
|||||||
goto _sendMF_cleanup;
|
goto _sendMF_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int n = 1;
|
||||||
|
if(writen(fd_c, &n, sizeof(n)) < 0) {
|
||||||
|
perror("writen");
|
||||||
|
goto _sendMF_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
if(sendFile(f, fd_c, taglia) < 0) {
|
if(sendFile(f, fd_c, taglia) < 0) {
|
||||||
perror("sendFile");
|
perror("sendFile");
|
||||||
goto _sendMF_cleanup;
|
goto _sendMF_cleanup;
|
||||||
@ -165,6 +171,11 @@ void sendMessageFileN(char *m, fileT **f, int n, long fd_c, taglia_t *taglia, ch
|
|||||||
goto _sendMFN_cleanup;
|
goto _sendMFN_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(write(fd_c, &n, sizeof(n)) < 0) {
|
||||||
|
perror("writen");
|
||||||
|
goto _sendMFN_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
for(int i=0; i<n && (f[i]!=NULL); ++i) {
|
for(int i=0; i<n && (f[i]!=NULL); ++i) {
|
||||||
if(sendFile(f[i], fd_c, taglia) < 0) {
|
if(sendFile(f[i], fd_c, taglia) < 0) {
|
||||||
perror("sendFile");
|
perror("sendFile");
|
||||||
|
|||||||
Reference in New Issue
Block a user