finished api for file Server side
This commit is contained in:
@ -71,6 +71,46 @@ _sendM_cleanup:
|
|||||||
return;
|
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
|
// invio il messaggio al client e poi il file
|
||||||
void sendMessageFile(char *m, fileT *f, long fd_c, taglia_t *taglia, char *mlog) {
|
void sendMessageFile(char *m, fileT *f, long fd_c, taglia_t *taglia, char *mlog) {
|
||||||
if(!f) {
|
if(!f) {
|
||||||
@ -94,8 +134,10 @@ void sendMessageFile(char *m, fileT *f, long fd_c, taglia_t *taglia, char *mlog)
|
|||||||
goto _sendMF_cleanup;
|
goto _sendMF_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(taglia_write(taglia, mlog) < 0)
|
if(taglia_write(taglia, mlog) < 0) {
|
||||||
|
perror("log write");
|
||||||
goto _sendMF_cleanup;
|
goto _sendMF_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -137,8 +179,8 @@ _sendMFN_cleanup:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
void openFile(char *filepath, int flags, queueT *q, long fd_c, taglia_t *taglia) {
|
void openFile(char *filepath, int flags, queueT *q, long fd_c, taglia_t *taglia) {
|
||||||
// messaggio da scrivere sul logfile
|
// messaggio da scrivere sul logfile
|
||||||
char tmp_buf[LOGBUFSIZE];
|
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) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void closeFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waiting_t **waiting) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void removeFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waiting_t **waiting) {
|
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;
|
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;
|
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) {
|
// none waiting
|
||||||
return 0;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// destroy waiting structure
|
||||||
int removeFirstWaiting(waiting_t **waiting, char *file) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void clearWaiting(waiting_t **waiting) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,10 +51,10 @@ void removeFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_
|
|||||||
int sendFile(fileT *f, long fd_c, taglia_t *taglia);
|
int sendFile(fileT *f, long fd_c, taglia_t *taglia);
|
||||||
|
|
||||||
// Aggiunge una coppia client/file alla coda in attesa di ottenere una lock
|
// Aggiunge una coppia client/file alla coda in attesa di ottenere una lock
|
||||||
int addWaiting(waiting_t **waiting, char *file, int fd);
|
int addWaiting(waiting_t **waiting, char *filepath, int fd_c);
|
||||||
|
|
||||||
// Ottiene il primo client in attesa su una lock di un determinato file
|
// Ottiene il primo client in attesa su una lock di un determinato file
|
||||||
int removeFirstWaiting(waiting_t **waiting, char *file);
|
int removeFirstWaiting(waiting_t **waiting, char *filepath);
|
||||||
|
|
||||||
// Distrugge la lista d'attesa e ne libera la memoria
|
// Distrugge la lista d'attesa e ne libera la memoria
|
||||||
void clearWaiting(waiting_t **waiting);
|
void clearWaiting(waiting_t **waiting);
|
||||||
|
|||||||
Reference in New Issue
Block a user