OpenFile
This commit is contained in:
@ -1,32 +1,223 @@
|
||||
#include <apiFile.h>
|
||||
#include <taglialegna.h>
|
||||
|
||||
#define MAXLENMESS 512
|
||||
|
||||
#define MEOK "20" //OK
|
||||
#define MEHE "21" // help message
|
||||
// #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
|
||||
|
||||
|
||||
void openFile(char *filepath, int flags, queueT *q, long fd_c, logT *logFileT);
|
||||
void openFile(char *filepath, int flags, queueT *q, long fd_c, taglia_t *taglia) {
|
||||
// messaggio da scrivere sul logfile
|
||||
char tmp_buf[2048];
|
||||
int n = 0;
|
||||
size_t m = sizeof(tmp_buf);
|
||||
|
||||
if(!filepath || !q || !taglia) {
|
||||
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminata con errore\n", fd_c, flags, filepath);
|
||||
errno = EINVAL;
|
||||
serror(MESY, fd_c, taglia, tmp_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
int found = searchFile(q, filepath); // cerco il file nella queue
|
||||
int create = flags & 0x1; // also %2
|
||||
int lock = flags >> 1 & 0x1; // also >>1%2
|
||||
fileT *removed = NULL; // file che è stato rimosso
|
||||
|
||||
if(found && create) { // si vuole creare il file ma esiste già
|
||||
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminata con errore\n", fd_c, flags, filepath);
|
||||
errno = EEXIST;
|
||||
serror(MENT, fd_c, taglia, tmp_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!found && !create) { // si vuole aprire e non creare un file inesistente
|
||||
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminato con errore\n", fd_c, flags, filepath);
|
||||
errno = ENOENT;
|
||||
serror(MENT, fd_c, taglia, tmp_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
if(found && !create) {
|
||||
if(openFileInQueue(q, file, lock, fd_c) == -1) {
|
||||
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminato con errore\n", fd_c, flags, filepath);
|
||||
perror("openFileInQueue");
|
||||
serror(MESE, fd_c, taglia, tmp_buf);
|
||||
return;
|
||||
}
|
||||
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminata con successo\n", fd_c, flags, filepath);
|
||||
sendMessage(MEOK, fd_c, taglia, tmp_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!found && create) { // not found and creating new file
|
||||
if(getLen(q) == queue->maxLen) { // capacity miss
|
||||
removed = dequeue(q);
|
||||
if(!removed) {
|
||||
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminato con errore\n", fd_c, flags, filepath);
|
||||
perror("dequeue");
|
||||
serror(MESE, fd_c, taglia, tmp_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
fileT *f = createFileT(filepath, lock, fd_c, 1); // create new file
|
||||
|
||||
if(!f) {
|
||||
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminato con errore del server\n", fd_c, flags, filepath);
|
||||
perror("createFileT");
|
||||
serror(MESE, fd_c, taglia);
|
||||
return;
|
||||
}
|
||||
|
||||
if(enqueue(q, f) != 0) {
|
||||
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminato con errore del server\n", fd_c, flags, filepath);
|
||||
perror("enqueue");
|
||||
serror(MESE, fd_c, taglia);
|
||||
return;
|
||||
}
|
||||
|
||||
taglia_update(taglia, q, 1); // removed only one file
|
||||
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" ha causato una capacity miss. File espulso \"%s\"\n", fd_c, flags, filepath, removed->filepath);
|
||||
sendMessageFile(MEFP, removed, fd_c, taglia, tmp_buf);
|
||||
free(removed);
|
||||
return;
|
||||
}
|
||||
|
||||
fileT *f = createFileT(filepath, lock, fd_c, 1);
|
||||
|
||||
if(!f) {
|
||||
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminato con errore del server\n", fd_c, flags, filepath);
|
||||
perror("createFileT");
|
||||
serror(MESE, fd_c, taglia);
|
||||
return;
|
||||
}
|
||||
|
||||
if(enqueue(q, f) != 0) {
|
||||
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminato con errore del server\n", fd_c, flags, filepath);
|
||||
perror("enqueue");
|
||||
serror(MESE, fd_c, taglia);
|
||||
return;
|
||||
}
|
||||
// abbiamo aggiunto un file quindi il numero di file è cambiato
|
||||
// quindi bisogna fare un update del log
|
||||
taglia_update(taglia, q, 0);
|
||||
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminato con successo\n", fd_c, flags, filepath);
|
||||
sendMessage(MEOK, fd_c, taglia, tmp_buf);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// invio il messaggio al client
|
||||
void sendMessage(char *m, long fd_c, taglia_t *taglia, char *mlog) {
|
||||
if(!m) {
|
||||
m = MEOK;
|
||||
}
|
||||
|
||||
if(writen(fd_c, m, strnlen(m, MAXLENMESS)+1) < 0) {
|
||||
perror("writen");
|
||||
goto _sendM_cleanup;
|
||||
}
|
||||
|
||||
if(taglia_write(taglia, mlog) < 0)
|
||||
goto _sendM_cleanup;
|
||||
|
||||
return;
|
||||
|
||||
_sendM_cleanup:
|
||||
return;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
errno = EINVAL;
|
||||
serror(MESY, fd_c);
|
||||
goto _sendMF_cleanup;
|
||||
}
|
||||
if(!m) {
|
||||
m = MEPF;
|
||||
}
|
||||
|
||||
if(writen(fd_c, m, strnlen(m, MAXLENMESS)+1) < 0) {
|
||||
perror("writen");
|
||||
goto _sendMF_cleanup;
|
||||
}
|
||||
|
||||
if(sendFile(f, fd_c, taglia) < 0) {
|
||||
perror("sendFile");
|
||||
goto _sendMF_cleanup;
|
||||
}
|
||||
|
||||
if(taglia_write(taglia, mlog) < 0)
|
||||
goto _sendMF_cleanup;
|
||||
|
||||
return;
|
||||
|
||||
_sendMF_cleanup:
|
||||
return;
|
||||
}
|
||||
|
||||
// invio il messaggio al client e poi l'errno
|
||||
void serror(char *m, long fd_c, taglia_t *taglia, char *mlog) {
|
||||
if(!m) {
|
||||
errno = EINVAL;
|
||||
m = MESY;
|
||||
}
|
||||
if(writen(fd_c, m, strnlen(m, MAXLENMESS)+1) < 0) {
|
||||
perror("writen");
|
||||
goto _serror_cleanup;
|
||||
}
|
||||
if(writen(fd_c, &errno, sizeof(errno)) < 0) {
|
||||
perror("writen");
|
||||
goto _serror_cleanup;
|
||||
}
|
||||
|
||||
if(taglia_write(taglia, mlog) < 0)
|
||||
goto _serror_cleanup;
|
||||
|
||||
return;
|
||||
|
||||
_serror_cleanup:
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void readFile(char *filepath, queueT *q, long fd_c, logT *logFileT);
|
||||
void readFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia);
|
||||
|
||||
|
||||
void readNFiles(char *numStr, queueT *q, long fd_c, logT *logFileT);
|
||||
void readNFiles(char *numStr, queueT *q, long fd_c, taglia_t *taglia);
|
||||
|
||||
|
||||
void writeFile(char *filepath, size_t size, queueT *q, long fd_c, logT *logFileT, int append);
|
||||
void writeFile(char *filepath, size_t size, queueT *q, long fd_c, taglia_t *taglia, int append);
|
||||
|
||||
|
||||
void lockFile(char *filepath, queueT *q, long fd_c, logT *logFileT, pthread_mutex_t *lock, waitingT **waiting);
|
||||
void lockFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waitingT **waiting);
|
||||
|
||||
|
||||
void unlockFile(char *filepath, queueT *q, long fd_c, logT *logFileT, pthread_mutex_t *lock, waitingT **waiting);
|
||||
void unlockFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waitingT **waiting);
|
||||
|
||||
|
||||
void closeFile(char *filepath, queueT *q, long fd_c, logT *logFileT, pthread_mutex_t *lock, waitingT **waiting);
|
||||
void closeFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waitingT **waiting);
|
||||
|
||||
|
||||
void removeFile(char *filepath, queueT *q, long fd_c, logT *logFileT, pthread_mutex_t *lock, waitingT **waiting);
|
||||
void removeFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waitingT **waiting);
|
||||
|
||||
|
||||
|
||||
int sendFile(fileT *f, long fd_c, logT *logFileT);
|
||||
int sendFile(fileT *f, long fd_c, taglia_t *taglia);
|
||||
|
||||
|
||||
int addWaiting(waitingT **waiting, char *file, int fd);
|
||||
|
||||
@ -16,37 +16,37 @@ typedef struct struct_waiting {
|
||||
/**
|
||||
* Apri o crea un nuovo file
|
||||
* \param filepath: nome del file
|
||||
* \param flags
|
||||
* \param flags:
|
||||
* \param q: queue in cui inserire il file
|
||||
* \param fd_c:
|
||||
* \param logFileT:
|
||||
* \param taglia_t:
|
||||
*/
|
||||
void openFile(char *filepath, int flags, queueT *q, long fd_c, logT *logFileT);
|
||||
void openFile(char *filepath, int flags, queueT *q, long fd_c, taglia_t *taglia);
|
||||
|
||||
// Leggi un file e invialo al client
|
||||
void readFile(char *filepath, queueT *q, long fd_c, logT *logFileT);
|
||||
void readFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia);
|
||||
|
||||
// Invia al client $n file qualsiasi dalla queue
|
||||
void readNFiles(char *numStr, queueT *q, long fd_c, logT *logFileT);
|
||||
void readNFiles(char *numStr, queueT *q, long fd_c, taglia_t *taglia);
|
||||
|
||||
// Scrivi dati su un file già creato (append o overwrite)
|
||||
void writeFile(char *filepath, size_t size, queueT *q, long fd_c, logT *logFileT, int append);
|
||||
void writeFile(char *filepath, size_t size, queueT *q, long fd_c, taglia_t *taglia, int append);
|
||||
|
||||
// Acquisisci lock di un file
|
||||
void lockFile(char *filepath, queueT *q, long fd_c, logT *logFileT, pthread_mutex_t *lock, waitingT **waiting);
|
||||
void lockFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waitingT **waiting);
|
||||
|
||||
// Rilascia una Lock di un file
|
||||
void unlockFile(char *filepath, queueT *q, long fd_c, logT *logFileT, 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);
|
||||
|
||||
// Chiudi un file
|
||||
void closeFile(char *filepath, queueT *q, long fd_c, logT *logFileT, 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);
|
||||
|
||||
// Rimuovi un file
|
||||
void removeFile(char *filepath, queueT *q, long fd_c, logT *logFileT, 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);
|
||||
|
||||
|
||||
// Funzione ausiliaria che invia un file al client
|
||||
int sendFile(fileT *f, long fd_c, logT *logFileT);
|
||||
int sendFile(fileT *f, long fd_c, taglia_t *taglia);
|
||||
|
||||
// Aggiunge una coppia client/file alla coda in attesa di ottenere una lock
|
||||
int addWaiting(waiting_t **waiting, char *file, int fd);
|
||||
|
||||
@ -673,6 +673,38 @@ _end_find_in_queue:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// cerco
|
||||
int searchFile(queueT *q, char *filepath) {
|
||||
if(!q || !filepath) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LOCK_RETURN(&q->m, NULL); // begin me
|
||||
|
||||
if (q->len == 0)
|
||||
goto _end_search_file_in_queue;
|
||||
|
||||
nodeT *tmp = q->head;
|
||||
|
||||
while (tmp) {
|
||||
if (strcmp(filepath, (tmp->data)->filepath) == 0) { // trovato
|
||||
break;
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
if(!tmp)
|
||||
goto _end_search_file_in_queue;
|
||||
|
||||
UNLOCK_RETURN(&q->m, NULL); // end me
|
||||
return 1;
|
||||
|
||||
_end_search_file_in_queue:
|
||||
UNLOCK_RETURN(&q->m, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// numero di elementi della queue
|
||||
size_t getLen(queueT *q) {
|
||||
if(!q) {
|
||||
|
||||
@ -191,7 +191,7 @@ int removeFileFromQueue(queueT *q, char *filepath, int owner);
|
||||
|
||||
|
||||
/**
|
||||
* Cerca un fileT nella coda.
|
||||
* Cerca un fileT nella coda e ritorna una copia.
|
||||
* \param q: puntatore alla coda sulla quale cercare il fileT
|
||||
* \param filepath: path assoluto del fileT da cercare
|
||||
*
|
||||
@ -199,6 +199,15 @@ int removeFileFromQueue(queueT *q, char *filepath, int owner);
|
||||
*/
|
||||
fileT* find(queueT *q, char *filepath);
|
||||
|
||||
/**
|
||||
* Cerca il fileT nella coda e ritorna il siultato dell'operazione
|
||||
* \param q: puntatore alla coda sulla quale cercare il fileT
|
||||
* \param filepath: path assoluto del fileT da cercare
|
||||
*
|
||||
* \retval 0 se non trovato, 1 se trovato
|
||||
*/
|
||||
int searchFile(queueT *q, char *filepath);
|
||||
|
||||
/**
|
||||
* Numero di elementi presenti nella coda.
|
||||
* \param q: puntatore alla coda
|
||||
|
||||
@ -50,7 +50,7 @@ static inline int writen(long fd, void *buf, size_t size) {
|
||||
int r;
|
||||
char *bufptr = (char*)buf;
|
||||
while(left>0) {
|
||||
if ((r=write((int)fd ,bufptr,left)) == -1) {
|
||||
if ((r=write((int) fd, bufptr, left)) == -1) {
|
||||
if (errno == EINTR) continue;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -163,7 +163,7 @@ int main(int argc, char *argv[]) {
|
||||
char buf[2048];
|
||||
int n;
|
||||
n = snprintf(buf, sizeof(buf), "Creato socket: %s\n", socketName);
|
||||
if( n<0 || m<n ) {
|
||||
if( n<0 ) {
|
||||
perror("snprintf");
|
||||
goto _cleanup;
|
||||
}
|
||||
@ -190,7 +190,7 @@ int main(int argc, char *argv[]) {
|
||||
char buf[2048];
|
||||
int n;
|
||||
n = snprintf(buf, sizeof(buf), "Creato threadpool di dimensione %d e lending size %d\n", threadsInPool, pendingSize);
|
||||
if( n<0 || m<n ) {
|
||||
if( n<0 ) {
|
||||
perror("snprintf");
|
||||
goto _cleanup;
|
||||
}
|
||||
@ -214,7 +214,7 @@ int main(int argc, char *argv[]) {
|
||||
char buf[2048];
|
||||
int n;
|
||||
n = snprintf(buf, sizeof(buf), "File Server ready.\n\tMaxFiles: %d\n\tMaxSize: %d\n", maxFiles, maxSize);
|
||||
if( n<0 || m<n ) {
|
||||
if( n<0 ) {
|
||||
perror("snprintf");
|
||||
goto _cleanup;
|
||||
}
|
||||
@ -267,7 +267,7 @@ int main(int argc, char *argv[]) {
|
||||
char buf[512];
|
||||
int n;
|
||||
n = snprintf(buf, sizeof(buf), "New client: %l\n", *connfd);
|
||||
if( n<0 || m<n ) {
|
||||
if( n<0 ) {
|
||||
perror("snprintf");
|
||||
goto _cleanup;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user