finished api for file Server side

This commit is contained in:
elvis
2022-04-10 20:51:43 +02:00
parent 98f3f0847c
commit da270caea1
2 changed files with 278 additions and 13 deletions

View File

@ -71,6 +71,46 @@ _sendM_cleanup:
return;
}
// invia un file
int sendFile(fileT *f, long fd_c, taglia_t *taglia) {
if(!f || !taglia) {
errno = EINVAL;
return -1;
}
// send filepath dimension, then filepath
int64_t filepathLength = (int64_t) strnlen(f->filepath, MAXLENMESS)+1;
if (writen(fd_c, &filepathLength, sizeof(filepathLength)) < 0) {
perror("writen");
return -1;
}
if (writen(fd_c, f->filepath, (size_t) filepathLength) < 0) {
perror("writen");
return -1;
}
// send file dimension, then file
int64_t validLength = (int64_t) f->valid;
if (writen(fd_c, &validLength, sizeof(validLength)) < 0) {
perror("writen");
return -1;
}
if (writen(fd_c, f->data, f->valid) < 0) {
perror("writen");
return -1;
}
char tmp_log[LOGBUFSIZE];
int n = 0;
size_t m = sizeof(tmp_log);
n += snprintf(tmp_log+n, m-n, "File \"%s\", di dimensione %llu Bytes al client %ld .\n", f->filepath, validLength, fd_c);
if(taglia_write(taglia, tmp_log) < 0) {
perror("taglia_write");
return 1;
}
return 0;
}
// invio il messaggio al client e poi il file
void sendMessageFile(char *m, fileT *f, long fd_c, taglia_t *taglia, char *mlog) {
if(!f) {
@ -94,8 +134,10 @@ void sendMessageFile(char *m, fileT *f, long fd_c, taglia_t *taglia, char *mlog)
goto _sendMF_cleanup;
}
if(taglia_write(taglia, mlog) < 0)
if(taglia_write(taglia, mlog) < 0) {
perror("log write");
goto _sendMF_cleanup;
}
return;
@ -137,8 +179,8 @@ _sendMFN_cleanup:
return;
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void openFile(char *filepath, int flags, queueT *q, long fd_c, taglia_t *taglia) {
// messaggio da scrivere sul logfile
char tmp_buf[LOGBUFSIZE];
@ -526,36 +568,259 @@ void lockFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mu
void unlockFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waiting_t **waiting) {
// messaggio da scrivere sul logfile
char tmp_buf[LOGBUFSIZE];
int n = 0;
size_t m = sizeof(tmp_buf);
if(!filepath || !q || !taglia || !lock || !waiting) {
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una unlockFile sul file \"%s\" e' terminata con errore.\n", fd_c, filepath);
errno = EINVAL;
serror(MESY, fd_c, taglia, tmp_buf);
return;
}
// cerco il file su cui rilasciare la lock
if(!searchFile(q, filepath)) { // file e' assente
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una unlockFile sul file \"%s\" ma risulta assente.\n", fd_c, filepath);
errno = ENOENT;
serror(MENT, fd_c, taglia, tmp_buf);
return;
}
if (unlockFileInQueue(q, filepath, fd_c) != 0) {
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una unlockFile sul file \"%s\" ma non è stata rilasciata la lock.\n", fd_c, filepath);
serror(MENT, fd_c, taglia, tmp_buf);
return;
}
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una unlockFile sul file \"%s\" e' terminata con successo\n", fd_c, filepath);
sendMessage(MEOK, fd_c, taglia, tmp_buf);
// segnalo a un client in lista d'attesa che una lock e' stata rilasciata
if (pthread_mutex_lock(lock) == -1) { // begin ME
perror("lock");
return;
}
int waked = -1;
waked = removeFirstWaiting(waiting, filepath);
if (waked != -1) {
// we lock the file for the other client
lockFile(filepath, q, waked, taglia, lock, waiting);
}
if (pthread_mutex_unlock(lock) == -1) { // end ME
perror("unlock");
return;
}
return;
}
void closeFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waiting_t **waiting) {
// messaggio da scrivere sul logfile
char tmp_buf[LOGBUFSIZE];
int n = 0;
size_t m = sizeof(tmp_buf);
if(!filepath || !q || !taglia || !lock || !waiting) {
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una closeFile sul file \"%s\" e' terminata con errore.\n", fd_c, filepath);
errno = EINVAL;
serror(MESY, fd_c, taglia, tmp_buf);
return;
}
// cerco il file da chiudere
if(!searchFile(q, filepath)) { // file e' assente
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una closeFile sul file \"%s\" ma risulta assente.\n", fd_c, filepath);
errno = ENOENT;
serror(MENT, fd_c, taglia, tmp_buf);
return;
}
if (closeFileInQueue(q, filepath, fd_c) == -1) {
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una closeFile sul file \"%s\" e' terminata con errore.\n", fd_c, filepath);
serror(MENT, fd_c, taglia, tmp_buf);
return;
}
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una closeFile sul file \"%s\" e' terminata con successo\n", fd_c, filepath);
sendMessage(MEOK, fd_c, taglia, tmp_buf);
// segnalo a un client in lista d'attesa che una lock e' stata rilasciata
if (pthread_mutex_lock(lock) == -1) { // begin ME
perror("lock");
return;
}
int waked = -1;
waked = removeFirstWaiting(waiting, filepath);
if (waked != -1) {
// we lock the file for the other client
lockFile(filepath, q, waked, taglia, lock, waiting);
}
if (pthread_mutex_unlock(lock) == -1) { // end ME
perror("unlock");
return;
}
return;
}
void removeFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waiting_t **waiting) {
// messaggio da scrivere sul logfile
char tmp_buf[LOGBUFSIZE];
int n = 0;
size_t m = sizeof(tmp_buf);
if(!filepath || !q || !taglia || !lock || !waiting) {
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una removeFile sul file \"%s\" e' terminata con errore.\n", fd_c, filepath);
errno = EINVAL;
serror(MESY, fd_c, taglia, tmp_buf);
return;
}
// cerco il file da eliminare
if(!searchFile(q, filepath)) { // file e' assente
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una removeFile sul file \"%s\" ma risulta assente.\n", fd_c, filepath);
errno = ENOENT;
serror(MENT, fd_c, taglia, tmp_buf);
return;
}
if (removeFileFromQueue(q, filepath, fd_c) == -1) {
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una removeFile sul file \"%s\" e' terminata con errore.\n", fd_c, filepath);
serror(MENT, fd_c, taglia, tmp_buf);
return;
}
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una removeFile sul file \"%s\" e' terminata con successo\n", fd_c, filepath);
sendMessage(MEOK, fd_c, taglia, tmp_buf);
// segnalo a un client in lista d'attesa che un file e' stato rimosso
if (pthread_mutex_lock(lock) == -1) { // begin ME
perror("lock");
return;
}
int waked = -1;
waked = removeFirstWaiting(waiting, filepath);
if (waked != -1) {
// we lock the file for the other client
lockFile(filepath, q, waked, taglia, lock, waiting);
}
if (pthread_mutex_unlock(lock) == -1) { // end ME
perror("unlock");
return;
}
return;
}
// -----------------------------------------------------------------------------
/* funzioni ausiliarie relative ai client in attesa di lock */
int addWaiting(waiting_t **waiting, char *filepath, int fd_c) {
if(!waiting || !filepath) {
errno = EINVAL;
return -1;
}
waiting_t *new = calloc(1, sizeof(waiting_t));
if (!new) {
perror("calloc");
return -1;
}
new->file = calloc(MAXLENMESS, sizeof(char));
if (!new->file) {
perror("calloc");
free(new);
return -1;
}
strncpy(new->file, filepath, strnlen(filepath, MAXLENMESS-1)+1);
new->fd = fd_c;
new->next = NULL;
// se la lista è vuota
if(*waiting == NULL) {
*waiting = new;
return 0;
}
// se la lista ha almeno un elemento
waiting_t *tail = *waiting;
while(tail->next) {
tail = tail->next;
}
tail->next = new;
int sendFile(fileT *f, long fd_c, taglia_t *taglia) {
return 0;
}
// remove first who is waiting on the lock for the file
int removeFirstWaiting(waiting_t **waiting, char *filepath) {
if(!waiting || !filepath) {
errno = EINVAL;
return -1;
}
int addWaiting(waiting_t **waiting, char *file, int fd) {
return 0;
// none waiting
if(*waiting == NULL) {
return -1;
}
waiting_t *curr = *waiting;
waiting_t *prec = NULL;
long fd_c = -1;
// first one waiting
if (strcmp(curr->file, filepath) == 0) {
fd_c = curr->fd;
*waiting = curr->next;
free(curr->file);
free(curr);
return fd_c;
}
// more than one waiting
while (curr->next) {
prec = curr;
curr = curr->next;
if (strcmp(curr->file, filepath) == 0) {
fd_c = curr->fd;
prec->next = curr->next;
free(curr->file);
free(curr);
return fd_c;
}
}
return -1;
}
int removeFirstWaiting(waiting_t **waiting, char *file) {
return 0;
}
// destroy waiting structure
void clearWaiting(waiting_t **waiting) {
if(!waiting) {
return;
}
waiting_t *curr = *waiting;
waiting_t *next = NULL;
while (curr) {
next = curr->next;
free(curr->file);
free(curr);
curr = next;
}
*waiting = NULL;
return;
}