finished api for file Server side
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user