2022-04-11 19:19:17 +02:00
# define _POSIX_C_SOURCE 200809L
# include <string.h>
2022-04-09 00:37:56 +02:00
# include <errno.h>
2022-04-11 19:19:17 +02:00
# include <inttypes.h>
2022-04-08 21:32:52 +02:00
2022-05-07 21:16:35 +02:00
# include "conn.h"
# include "apiFile.h"
# include "fileQueue.h"
# include "taglialegna.h"
2022-03-31 22:26:44 +02:00
# define MAXLENMESS 512
2022-04-09 22:43:26 +02:00
# define LOGBUFSIZE 2048
2022-03-31 22:26:44 +02:00
2022-05-07 21:16:35 +02:00
# define MEOK "20" /* OK */
// #define ME "21" /* not used */
// #define ME "22" /* not used */
# define MEFP "25" /* file purged */
2022-03-31 22:26:44 +02:00
2022-05-07 21:16:35 +02:00
// #define ME "40" /* not used */
// #define ME "41" /* not used */
# define MESD "42" /* shutting down */
# define MENT "45" /* requested file action not taken */
2022-03-31 22:26:44 +02:00
2022-05-07 21:16:35 +02:00
# define MESY "50" /* syntax error */
// #define ME "51" /* not used */
// #define ME "52" /* not used */
# define MESE "55" /* server error */
2022-03-31 22:26:44 +02:00
2022-04-04 18:58:40 +02:00
// -----------------------------------------------------------------------------
2022-05-07 21:16:35 +02:00
// helper functions
2022-04-04 18:58:40 +02:00
2022-05-07 21:16:35 +02:00
/* send to the client the message m and then errno */
2022-04-08 21:32:52 +02:00
void serror ( char * m , long fd_c , taglia_t * taglia , char * mlog ) {
if ( ! m ) {
errno = EINVAL ;
m = MESY ;
}
2022-04-27 21:18:25 +02:00
if ( writen ( fd_c , m , strnlen ( m , MAXLENMESS ) ) < 0 ) {
2022-05-07 21:16:35 +02:00
perror ( " serror: writen " ) ;
2022-04-08 21:32:52 +02:00
goto _serror_cleanup ;
}
if ( writen ( fd_c , & errno , sizeof ( errno ) ) < 0 ) {
2022-05-07 21:16:35 +02:00
perror ( " serror: writen " ) ;
2022-04-08 21:32:52 +02:00
goto _serror_cleanup ;
}
if ( taglia_write ( taglia , mlog ) < 0 )
goto _serror_cleanup ;
return ;
_serror_cleanup :
return ;
}
2022-05-07 21:16:35 +02:00
/* send to the client the message m */
2022-04-04 18:58:40 +02:00
void sendMessage ( char * m , long fd_c , taglia_t * taglia , char * mlog ) {
if ( ! m ) {
m = MEOK ;
}
2022-04-24 01:36:43 +02:00
if ( writen ( fd_c , m , strnlen ( m , MAXLENMESS ) ) < 0 ) {
2022-05-07 21:16:35 +02:00
perror ( " sendMessage: writen " ) ;
2022-04-04 18:58:40 +02:00
goto _sendM_cleanup ;
}
if ( taglia_write ( taglia , mlog ) < 0 )
goto _sendM_cleanup ;
return ;
_sendM_cleanup :
return ;
}
2022-05-07 21:16:35 +02:00
/* send to the client the file f */
2022-04-10 20:51:43 +02:00
int sendFile ( fileT * f , long fd_c , taglia_t * taglia ) {
if ( ! f | | ! taglia ) {
errno = EINVAL ;
return - 1 ;
}
2022-05-07 21:16:35 +02:00
/* send filepath dimension, then filepath */
2022-04-10 20:51:43 +02:00
int64_t filepathLength = ( int64_t ) strnlen ( f - > filepath , MAXLENMESS ) + 1 ;
if ( writen ( fd_c , & filepathLength , sizeof ( filepathLength ) ) < 0 ) {
2022-05-07 21:16:35 +02:00
perror ( " sendFile: writen " ) ;
2022-04-10 20:51:43 +02:00
return - 1 ;
}
if ( writen ( fd_c , f - > filepath , ( size_t ) filepathLength ) < 0 ) {
2022-05-07 21:16:35 +02:00
perror ( " sendFile: writen " ) ;
2022-04-10 20:51:43 +02:00
return - 1 ;
}
2022-05-07 21:16:35 +02:00
/* send file dimension, then file */
2022-04-10 20:51:43 +02:00
int64_t validLength = ( int64_t ) f - > valid ;
if ( writen ( fd_c , & validLength , sizeof ( validLength ) ) < 0 ) {
2022-05-07 21:16:35 +02:00
perror ( " sendFile: writen " ) ;
2022-04-10 20:51:43 +02:00
return - 1 ;
}
2022-05-07 21:16:35 +02:00
if ( validLength ! = 0 ) { /* if file has length 0 dont write */
2022-04-29 01:26:31 +02:00
if ( writen ( fd_c , f - > data , validLength ) < 0 ) {
2022-05-07 21:16:35 +02:00
perror ( " sendFile: writen " ) ;
2022-04-29 01:26:31 +02:00
return - 1 ;
}
2022-04-10 20:51:43 +02:00
}
char tmp_log [ LOGBUFSIZE ] ;
int n = 0 ;
size_t m = sizeof ( tmp_log ) ;
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_log + n , m - n , " Inviato file \" %s \" , di dimensione % " PRId64 " Bytes al client %ld . \n " ,
f - > filepath ,
validLength ,
fd_c ) ;
2022-04-10 20:51:43 +02:00
if ( taglia_write ( taglia , tmp_log ) < 0 ) {
2022-05-07 21:16:35 +02:00
perror ( " sendFile: taglia_write " ) ;
2022-04-10 20:51:43 +02:00
return 1 ;
}
return 0 ;
}
2022-05-07 21:16:35 +02:00
/* send to the client the message m then the file f */
2022-04-04 18:58:40 +02:00
void sendMessageFile ( char * m , fileT * f , long fd_c , taglia_t * taglia , char * mlog ) {
if ( ! f ) {
errno = EINVAL ;
2022-05-07 21:16:35 +02:00
char errmlog [ 2 * LOGBUFSIZE ] =
" Errore negli argomenti alla funzione sendMessagefile (fileT == NULL). "
" Messaggio originale: \n \t " ;
2022-04-08 21:32:52 +02:00
strncat ( errmlog , mlog , sizeof ( errmlog ) - strlen ( errmlog ) - 1 ) ;
2022-04-04 18:58:40 +02:00
goto _sendMF_cleanup ;
2022-05-07 21:16:35 +02:00
serror ( MESY , fd_c , taglia , errmlog ) ;
2022-04-04 18:58:40 +02:00
}
if ( ! m ) {
2022-04-08 21:32:52 +02:00
m = MEFP ;
2022-04-04 18:58:40 +02:00
}
2022-04-27 21:18:25 +02:00
if ( writen ( fd_c , m , strnlen ( m , MAXLENMESS ) ) < 0 ) {
2022-05-07 21:16:35 +02:00
perror ( " sendMessageFile: writen " ) ;
2022-04-04 18:58:40 +02:00
goto _sendMF_cleanup ;
}
2022-04-27 21:18:25 +02:00
int64_t * n = calloc ( 1 , sizeof ( * n ) ) ;
2022-04-29 01:26:31 +02:00
if ( ! n ) {
2022-05-07 21:16:35 +02:00
perror ( " sendMessageFile: calloc " ) ;
2022-04-27 21:18:25 +02:00
goto _sendMF_cleanup ;
}
* n = 1 ;
if ( writen ( fd_c , n , sizeof ( int64_t ) ) < 0 ) {
2022-05-07 21:16:35 +02:00
perror ( " sendMessageFile: writen " ) ;
2022-04-22 21:59:40 +02:00
goto _sendMF_cleanup ;
}
2022-04-27 21:18:25 +02:00
free ( n ) ;
2022-04-04 18:58:40 +02:00
if ( sendFile ( f , fd_c , taglia ) < 0 ) {
2022-05-07 21:16:35 +02:00
perror ( " sendMessageFile: sendFile " ) ;
2022-04-04 18:58:40 +02:00
goto _sendMF_cleanup ;
}
2022-04-10 20:51:43 +02:00
if ( taglia_write ( taglia , mlog ) < 0 ) {
2022-05-07 21:16:35 +02:00
perror ( " sendMessageFile: taglia_write " ) ;
2022-04-04 18:58:40 +02:00
goto _sendMF_cleanup ;
2022-04-10 20:51:43 +02:00
}
2022-04-04 18:58:40 +02:00
return ;
_sendMF_cleanup :
return ;
}
2022-05-07 21:16:35 +02:00
/* send to the client the message m then n files */
2022-04-29 21:04:45 +02:00
void sendMessageFileN ( char * m , fileT * * f , int64_t n , long fd_c , taglia_t * taglia , char * mlog ) {
2022-04-04 18:58:40 +02:00
if ( ! f ) {
errno = EINVAL ;
2022-05-07 21:16:35 +02:00
char errmlog [ 2 * LOGBUFSIZE ] =
" Errore negli argomenti alla funzione sendMessagefile (fileT == NULL). "
" Messaggio originale: \n \t " ;
2022-04-08 21:32:52 +02:00
strncat ( errmlog , mlog , sizeof ( errmlog ) - strlen ( errmlog ) - 1 ) ;
serror ( MESY , fd_c , taglia , errmlog ) ;
2022-04-04 18:58:40 +02:00
goto _sendMFN_cleanup ;
}
if ( ! m ) {
2022-04-08 21:32:52 +02:00
m = MEFP ;
2022-04-04 18:58:40 +02:00
}
2022-04-27 21:18:25 +02:00
if ( writen ( fd_c , m , strnlen ( m , MAXLENMESS ) ) < 0 ) {
2022-05-07 21:16:35 +02:00
perror ( " sendMessageFileN: writen " ) ;
2022-04-08 21:32:52 +02:00
goto _sendMFN_cleanup ;
2022-04-04 18:58:40 +02:00
}
2022-04-22 21:59:40 +02:00
if ( write ( fd_c , & n , sizeof ( n ) ) < 0 ) {
2022-05-07 21:16:35 +02:00
perror ( " sendMessageFileN: writen " ) ;
2022-04-22 21:59:40 +02:00
goto _sendMFN_cleanup ;
}
2022-04-04 18:58:40 +02:00
for ( int i = 0 ; i < n & & ( f [ i ] ! = NULL ) ; + + i ) {
if ( sendFile ( f [ i ] , fd_c , taglia ) < 0 ) {
2022-05-07 21:16:35 +02:00
perror ( " sendMessageFileN: sendFile " ) ;
2022-04-08 21:32:52 +02:00
goto _sendMFN_cleanup ;
2022-04-04 18:58:40 +02:00
}
}
if ( taglia_write ( taglia , mlog ) < 0 )
2022-04-08 21:32:52 +02:00
goto _sendMFN_cleanup ;
2022-04-04 18:58:40 +02:00
return ;
_sendMFN_cleanup :
return ;
}
2022-03-31 22:26:44 +02:00
2022-04-10 20:51:43 +02:00
// -----------------------------------------------------------------------------
2022-03-31 22:26:44 +02:00
void openFile ( char * filepath , int flags , queueT * q , long fd_c , taglia_t * taglia ) {
// messaggio da scrivere sul logfile
2022-04-09 22:43:26 +02:00
char tmp_buf [ LOGBUFSIZE ] ;
2022-03-31 22:26:44 +02:00
int n = 0 ;
size_t m = sizeof ( tmp_buf ) ;
if ( ! filepath | | ! q | | ! taglia ) {
2022-05-07 21:16:35 +02:00
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 ) ;
2022-03-31 22:26:44 +02:00
errno = EINVAL ;
serror ( MESY , fd_c , taglia , tmp_buf ) ;
return ;
}
2022-05-07 21:16:35 +02:00
int found = searchFile ( q , filepath ) ; /* search the file in the queue */
int create = ( flags & C_CREATE ) ? 1 : 0 ; /* also %2 */
int lock = ( flags & C_LOCK ) ? 1 : 0 ; /* also >>1%2 */
fileT * removed = NULL ; /* file that was removed */
2022-03-31 22:26:44 +02:00
2022-05-07 21:16:35 +02:00
if ( found & & create ) { /* file found but want to create new file */
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una openFile (flags = %x) sul file \" %s \" ma il file esiste già \n " ,
fd_c ,
flags ,
filepath ) ;
2022-03-31 22:26:44 +02:00
errno = EEXIST ;
serror ( MENT , fd_c , taglia , tmp_buf ) ;
return ;
}
2022-05-07 21:16:35 +02:00
if ( ! found & & ! create ) { /* file not found but expected */
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una openFile (flags = %x) sul file \" %s \" ma il file non esiste \n " ,
fd_c ,
flags ,
filepath ) ;
2022-03-31 22:26:44 +02:00
errno = ENOENT ;
serror ( MENT , fd_c , taglia , tmp_buf ) ;
return ;
}
2022-05-07 21:16:35 +02:00
if ( found & & ! create ) { /* file found */
2022-04-08 21:32:52 +02:00
if ( openFileInQueue ( q , filepath , lock , fd_c ) = = - 1 ) {
2022-05-07 21:16:35 +02:00
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 ( " openFile: openFileInQueue " ) ;
2022-03-31 22:26:44 +02:00
serror ( MESE , fd_c , taglia , tmp_buf ) ;
return ;
}
2022-05-07 21:16:35 +02:00
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 ) ;
2022-03-31 22:26:44 +02:00
sendMessage ( MEOK , fd_c , taglia , tmp_buf ) ;
return ;
}
2022-05-07 21:16:35 +02:00
if ( ! found & & create ) { /* not found and creating new file */
if ( getLen ( q ) = = q - > maxLen ) { /* capacity miss */
2022-03-31 22:26:44 +02:00
removed = dequeue ( q ) ;
if ( ! removed ) {
2022-05-07 21:16:35 +02:00
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 ( " openFile: dequeue " ) ;
2022-03-31 22:26:44 +02:00
serror ( MESE , fd_c , taglia , tmp_buf ) ;
return ;
}
2022-05-07 21:16:35 +02:00
/* create new file */
fileT * f = createFileT ( filepath , lock , fd_c , 1 ) ;
2022-03-31 22:26:44 +02:00
if ( ! f ) {
2022-05-07 21:16:35 +02:00
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 ( " openFile: createFileT " ) ;
2022-04-08 21:32:52 +02:00
serror ( MESE , fd_c , taglia , tmp_buf ) ;
2022-03-31 22:26:44 +02:00
return ;
}
if ( enqueue ( q , f ) ! = 0 ) {
2022-05-07 21:16:35 +02:00
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 ( " openFile: enqueue " ) ;
2022-04-08 21:32:52 +02:00
serror ( MESE , fd_c , taglia , tmp_buf ) ;
2022-03-31 22:26:44 +02:00
return ;
}
2022-05-07 21:16:35 +02:00
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 ) ;
2022-03-31 22:26:44 +02:00
sendMessageFile ( MEFP , removed , fd_c , taglia , tmp_buf ) ;
2022-04-29 01:26:31 +02:00
destroyFile ( removed ) ;
2022-03-31 22:26:44 +02:00
return ;
}
2022-05-07 21:16:35 +02:00
/* no capacity miss */
2022-03-31 22:26:44 +02:00
fileT * f = createFileT ( filepath , lock , fd_c , 1 ) ;
if ( ! f ) {
2022-05-07 21:16:35 +02:00
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 ( " openFile: createFileT " ) ;
2022-04-08 21:32:52 +02:00
serror ( MESE , fd_c , taglia , tmp_buf ) ;
2022-03-31 22:26:44 +02:00
return ;
}
if ( enqueue ( q , f ) ! = 0 ) {
2022-05-07 21:16:35 +02:00
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 ( " openFile: enqueue " ) ;
2022-04-08 21:32:52 +02:00
serror ( MESE , fd_c , taglia , tmp_buf ) ;
2022-03-31 22:26:44 +02:00
return ;
}
2022-05-07 21:16:35 +02:00
/* added a file, the number of files changed so update the log */
2022-03-31 22:26:44 +02:00
taglia_update ( taglia , q , 0 ) ;
2022-05-07 21:16:35 +02:00
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 ) ;
2022-03-31 22:26:44 +02:00
sendMessage ( MEOK , fd_c , taglia , tmp_buf ) ;
return ;
}
2022-04-09 01:11:46 +02:00
2022-05-07 21:16:35 +02:00
/* unreachable code */
2022-04-09 01:11:46 +02:00
return ;
2022-03-31 22:26:44 +02:00
}
2022-04-04 18:58:40 +02:00
void readFile ( char * filepath , queueT * q , long fd_c , taglia_t * taglia ) {
2022-05-07 21:16:35 +02:00
/* message to write to the logfile */
2022-04-09 22:43:26 +02:00
char tmp_buf [ LOGBUFSIZE ] ;
2022-04-04 18:58:40 +02:00
int n = 0 ;
size_t m = sizeof ( tmp_buf ) ;
if ( ! filepath | | ! q | | ! taglia ) {
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una readFile sul file \" %s \" e' terminata con errore del server \n " ,
fd_c ,
filepath ) ;
2022-04-04 18:58:40 +02:00
errno = EINVAL ;
serror ( MESY , fd_c , taglia , tmp_buf ) ;
return ;
2022-03-31 22:26:44 +02:00
}
2022-04-04 18:58:40 +02:00
fileT * f = NULL ;
f = find ( q , filepath ) ;
if ( ! f ) {
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una readFile sul file \" %s \" ma il file non esiste \n " ,
fd_c ,
filepath ) ;
2022-04-04 18:58:40 +02:00
errno = ENOENT ;
serror ( MESE , fd_c , taglia , tmp_buf ) ;
return ;
}
2022-03-31 22:26:44 +02:00
2022-05-07 21:16:35 +02:00
if ( f - > open = = 0 ) { /* file not already open */
2022-05-18 02:24:43 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una readFile sul file \" %s \" e' terminata con errore, file non precedentemente aperto \n " ,
2022-05-07 21:16:35 +02:00
fd_c ,
filepath ) ;
2022-04-04 18:58:40 +02:00
errno = EPERM ;
serror ( MENT , fd_c , taglia , tmp_buf ) ;
2022-05-07 21:16:35 +02:00
destroyFile ( f ) ; /* f is a copy so we need to cleen up */
2022-04-04 18:58:40 +02:00
return ;
}
2022-03-31 22:26:44 +02:00
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una readFile sul file \" %s \" di dimensione = %ld e' terminata con successo \n " ,
fd_c ,
filepath ,
f - > valid ) ;
2022-04-04 18:58:40 +02:00
sendMessageFile ( MEOK , f , fd_c , taglia , tmp_buf ) ;
2022-05-07 21:16:35 +02:00
destroyFile ( f ) ; /* f is a copy so we need to cleen up */
2022-03-31 22:26:44 +02:00
return ;
}
2022-04-04 18:58:40 +02:00
2022-05-07 21:16:35 +02:00
void readNFiles ( int num , queueT * q , long fd_c , taglia_t * taglia ) {
/* message to write to the logfile */
2022-04-09 22:43:26 +02:00
char tmp_buf [ LOGBUFSIZE ] ;
int n = 0 ;
size_t m = sizeof ( tmp_buf ) ;
if ( ! q | | ! taglia ) {
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una readNFile (n = %d) e' terminata con errore \n " ,
fd_c ,
num ) ;
2022-04-09 22:43:26 +02:00
errno = EINVAL ;
serror ( MESY , fd_c , taglia , tmp_buf ) ;
return ;
}
int oldNum = num ;
2022-04-29 21:04:45 +02:00
int64_t ntosend = ( num < = 0 | | num > getLen ( q ) ) ? getLen ( q ) : num ;
2022-05-17 18:41:50 +02:00
fileT * * toSend = NULL ;
2022-04-09 22:43:26 +02:00
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una readNFile (n = %d) e' terminata con successo. File inviati: \n " ,
fd_c ,
num ) ;
2022-05-17 18:41:50 +02:00
/* extract n files, but dont actually dequeue them */
toSend = request ( q , ( int ) ntosend ) ;
if ( toSend = = NULL ) {
n = 0 ;
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una readNFiles (n = %d) e' terminato con errore del server \n " ,
fd_c ,
oldNum ) ;
perror ( " readNFiles: request " ) ;
serror ( MESE , fd_c , taglia , tmp_buf ) ;
return ;
}
2022-05-03 23:14:39 +02:00
size_t tot = 0 ;
2022-04-29 21:04:45 +02:00
for ( int i = 0 ; i < ntosend ; + + i ) {
2022-05-17 18:41:50 +02:00
if ( toSend [ i ] = = NULL ) {
2022-04-09 22:43:26 +02:00
n = 0 ;
2022-05-17 18:41:50 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una readNFiles (n = %d) e' terminato con errore del server (file estratti [%d] inferiori a file richiesti [%ld]) \n " ,
2022-05-07 21:16:35 +02:00
fd_c ,
2022-05-17 18:41:50 +02:00
oldNum ,
i ,
ntosend ) ;
perror ( " readNFiles: request " ) ;
2022-04-09 22:43:26 +02:00
serror ( MESE , fd_c , taglia , tmp_buf ) ;
return ;
}
2022-05-03 23:14:39 +02:00
tot + = toSend [ i ] - > valid ;
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " \t %d) \" %s \" dim = %ld \n " ,
i ,
toSend [ i ] - > filepath ,
toSend [ i ] - > valid ) ;
2022-04-09 22:43:26 +02:00
}
2022-05-19 21:32:44 +02:00
n + = snprintf ( tmp_buf + n , m - n , " readNFile dimensione totale = %ld B \n " ,
2022-05-07 21:16:35 +02:00
tot ) ;
2022-04-09 22:43:26 +02:00
2022-04-29 21:04:45 +02:00
sendMessageFileN ( MEOK , toSend , ntosend , fd_c , taglia , tmp_buf ) ;
2022-04-09 22:43:26 +02:00
free ( toSend ) ;
2022-04-04 22:31:14 +02:00
return ;
}
2022-04-04 18:58:40 +02:00
void writeFile ( char * filepath , size_t size , queueT * q , long fd_c , taglia_t * taglia , int append ) {
2022-05-07 21:16:35 +02:00
/* message to write to the logfile */
2022-04-09 22:43:26 +02:00
char tmp_buf [ LOGBUFSIZE ] ;
2022-04-04 18:58:40 +02:00
int n = 0 ;
size_t m = sizeof ( tmp_buf ) ;
if ( ! filepath | | ! q | | ! taglia ) {
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una writeFile (append = %x) sul file \" %s \" e' terminata con errore \n " ,
fd_c ,
append ,
filepath ) ;
2022-03-31 22:26:44 +02:00
errno = EINVAL ;
2022-04-04 18:58:40 +02:00
serror ( MESY , fd_c , taglia , tmp_buf ) ;
return ;
2022-03-31 22:26:44 +02:00
}
2022-04-27 21:18:25 +02:00
2022-05-07 21:16:35 +02:00
/* search the file */
2022-04-04 18:58:40 +02:00
fileT * f = NULL ;
f = find ( q , filepath ) ;
2022-04-27 21:18:25 +02:00
2022-05-07 21:16:35 +02:00
if ( ! f ) { /* file is not present */
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una writeFile (append = %x) sul file \" %s \" , dimensione = %ld, e' terminata con errore, file non trovato \n " ,
fd_c ,
append ,
filepath ,
size ) ;
2022-04-04 18:58:40 +02:00
errno = ENOENT ;
serror ( MENT , fd_c , taglia , tmp_buf ) ;
destroyFile ( f ) ;
return ;
2022-03-31 22:26:44 +02:00
}
2022-03-18 20:49:28 +01:00
2022-05-07 21:16:35 +02:00
/* file not open || no append and no lock || not the owner of the lock */
2022-04-24 01:36:43 +02:00
if ( ! f - > open | | ( ! append & & ! f - > O_LOCK ) | | ( f - > O_LOCK & & f - > owner ! = fd_c ) ) {
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una writeFile (append = %x) sul file \" %s \" , dimensione = %ld, e' terminata con errore, non proprietario del file \n " ,
fd_c ,
append ,
filepath ,
size ) ;
2022-04-04 18:58:40 +02:00
errno = EPERM ;
serror ( MENT , fd_c , taglia , tmp_buf ) ;
destroyFile ( f ) ;
return ;
2022-03-31 22:26:44 +02:00
}
2022-05-07 21:16:35 +02:00
long trueSizeAdded = 0 ; /* we may have alredy some space allocated */
2022-04-04 18:58:40 +02:00
if ( append ) {
trueSizeAdded = size - f - > size + f - > valid ;
} else {
trueSizeAdded = ( size > f - > size ) ? size - f - > size : 0 ;
}
2022-05-07 21:16:35 +02:00
destroyFile ( f ) ; /* not needed anymore */
2022-03-18 20:49:28 +01:00
2022-05-07 21:16:35 +02:00
if ( trueSizeAdded > q - > maxSize ) { /* removing all files would not be enought */
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una writeFile (append = %x) sul file \" %s \" , dimensione = %ld ma il file e' piu' grande della dimensione massima \n " ,
fd_c ,
append ,
filepath ,
size ) ;
2022-05-03 23:14:39 +02:00
errno = EFBIG ;
serror ( MENT , fd_c , taglia , tmp_buf ) ;
return ;
}
2022-04-24 01:36:43 +02:00
if ( trueSizeAdded + getSize ( q ) > q - > maxSize ) {
2022-05-07 21:16:35 +02:00
/* writing would be more than capacity */
fileT * * removed = NULL ; /* array that may (worst case) hold all files to
* be sent to the client */
2022-04-04 18:58:40 +02:00
removed = dequeueN ( q , filepath , trueSizeAdded ) ;
2022-05-07 21:16:35 +02:00
if ( ! removed ) { /* internal error */
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una writeFile (append = %x) sul file \" %s \" , dimensione = %ld, e' terminata con errore del server \n " ,
fd_c ,
append ,
filepath ,
size ) ;
2022-04-04 18:58:40 +02:00
errno = ENOENT ;
serror ( MESY , fd_c , taglia , tmp_buf ) ;
return ;
}
int ln = 0 ;
fileT * tmp = removed [ ln ] ;
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una writeFile (append = %x) sul file \" %s \" , dimensione = %ld, e' terminata con successo, allocando %ld B in memoria. Ha causato una capacity miss e ha fatto espellere i seguenti file: " ,
fd_c ,
append ,
filepath ,
size ,
trueSizeAdded ) ;
2022-04-04 18:58:40 +02:00
while ( tmp ! = NULL ) {
n + = snprintf ( tmp_buf + n , m - n , " \" %s \" " , tmp - > filepath ) ;
+ + ln ;
tmp = removed [ ln ] ;
}
n + = snprintf ( tmp_buf + n , m - n , " \n " ) ;
taglia_update ( taglia , q , ln ) ;
2022-03-18 20:49:28 +01:00
2022-04-04 18:58:40 +02:00
sendMessageFileN ( MEFP , removed , ln , fd_c , taglia , tmp_buf ) ;
for ( int i = 0 ; i < ln & & ( removed [ i ] ! = NULL ) ; + + i ) {
destroyFile ( removed [ i ] ) ;
}
free ( removed ) ;
2022-03-18 20:49:28 +01:00
2022-05-07 21:16:35 +02:00
/* now we can get the actual file */
2022-04-04 18:58:40 +02:00
void * content = NULL ;
2022-04-24 01:36:43 +02:00
content = calloc ( size , sizeof ( char ) ) ;
2022-04-04 18:58:40 +02:00
if ( ! content ) {
2022-05-07 21:16:35 +02:00
perror ( " writeFile: calloc " ) ;
2022-04-04 18:58:40 +02:00
return ;
}
if ( ( readn ( fd_c , content , size ) ) = = - 1 ) {
2022-05-07 21:16:35 +02:00
perror ( " writeFile: readn " ) ;
2022-04-04 18:58:40 +02:00
return ;
}
2022-03-18 20:49:28 +01:00
2022-04-24 01:36:43 +02:00
n = 0 ;
2022-04-04 18:58:40 +02:00
if ( append ) {
if ( appendFileInQueue ( q , filepath , content , size , fd_c ) = = - 1 ) {
2022-05-07 21:16:35 +02:00
perror ( " writeFile: appendFileInQueue " ) ;
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una writeFile (append = %x) sul file \" %s \" , dimensione = %ld, errore del server \n " ,
fd_c ,
append ,
filepath ,
size ) ;
2022-04-24 01:36:43 +02:00
serror ( MESY , fd_c , taglia , tmp_buf ) ;
2022-04-08 21:32:52 +02:00
free ( content ) ;
2022-04-04 18:58:40 +02:00
return ;
}
} else {
if ( writeFileInQueue ( q , filepath , content , size , fd_c ) = = - 1 ) {
2022-05-07 21:16:35 +02:00
perror ( " writeFile: writeFileInQueue " ) ;
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una writeFile (append = %x) sul file \" %s \" , dimensione = %ld, errore del server \n " ,
fd_c ,
append ,
filepath ,
size ) ;
2022-04-24 01:36:43 +02:00
serror ( MESY , fd_c , taglia , tmp_buf ) ;
2022-04-08 21:32:52 +02:00
free ( content ) ;
2022-04-04 18:58:40 +02:00
return ;
}
}
2022-03-18 20:49:28 +01:00
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una writeFile (append = %x) sul file \" %s \" , dimensione = %ld, e' terminata con successo \n " ,
fd_c ,
append ,
filepath ,
size ) ;
2022-04-24 01:36:43 +02:00
sendMessage ( MEOK , fd_c , taglia , tmp_buf ) ;
2022-04-04 18:58:40 +02:00
taglia_update ( taglia , q , 0 ) ;
2022-04-08 21:32:52 +02:00
free ( content ) ;
2022-04-04 18:58:40 +02:00
return ;
}
2022-05-07 21:16:35 +02:00
/* no dequeue */
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una writeFile (append = %x) sul file \" %s \" , dimensione = %ld, accettata la richiesta. \n " ,
fd_c ,
append ,
filepath ,
size ) ;
2022-04-24 01:36:43 +02:00
sendMessage ( MEOK , fd_c , taglia , tmp_buf ) ;
2022-05-07 21:16:35 +02:00
/* no reason to remove the file yet */
2022-04-04 18:58:40 +02:00
void * content = NULL ;
2022-04-24 01:36:43 +02:00
content = calloc ( size , sizeof ( char ) ) ;
2022-04-04 18:58:40 +02:00
if ( ! content ) {
2022-05-07 21:16:35 +02:00
perror ( " writeFile: calloc " ) ;
2022-04-04 18:58:40 +02:00
return ;
}
if ( readn ( fd_c , content , size ) = = - 1 ) {
2022-05-07 21:16:35 +02:00
perror ( " writeFile: readn " ) ;
2022-04-04 18:58:40 +02:00
return ;
}
2022-03-18 20:49:28 +01:00
2022-04-24 01:36:43 +02:00
n = 0 ;
2022-03-18 20:49:28 +01:00
2022-04-04 18:58:40 +02:00
if ( append ) {
if ( appendFileInQueue ( q , filepath , content , size , fd_c ) = = - 1 ) {
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una writeFile (append = %x) sul file \" %s \" , dimensione = %ld, errore del server \n " ,
fd_c ,
append ,
filepath ,
size ) ;
2022-04-24 01:36:43 +02:00
serror ( MESY , fd_c , taglia , tmp_buf ) ;
2022-05-07 21:16:35 +02:00
perror ( " writeFile: appendFileInQueue " ) ;
2022-04-08 21:32:52 +02:00
free ( content ) ;
2022-04-04 18:58:40 +02:00
return ;
}
} else {
if ( writeFileInQueue ( q , filepath , content , size , fd_c ) = = - 1 ) {
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una writeFile (append = %x) sul file \" %s \" , dimensione = %ld, errore del server \n " ,
fd_c ,
append ,
filepath ,
size ) ;
2022-04-24 01:36:43 +02:00
serror ( MESY , fd_c , taglia , tmp_buf ) ;
2022-05-07 21:16:35 +02:00
perror ( " writeFile: writeFileInQueue " ) ;
2022-04-08 21:32:52 +02:00
free ( content ) ;
2022-04-04 18:58:40 +02:00
return ;
}
}
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una writeFile (append = %x) sul file \" %s \" , dimensione = %ld, e' terminata con successo \n " ,
fd_c ,
append ,
filepath ,
size ) ;
2022-04-24 01:36:43 +02:00
sendMessage ( MEOK , fd_c , taglia , tmp_buf ) ;
2022-03-18 20:49:28 +01:00
2022-04-04 18:58:40 +02:00
taglia_update ( taglia , q , 0 ) ;
2022-03-18 20:49:28 +01:00
2022-04-08 21:32:52 +02:00
free ( content ) ;
2022-04-04 18:58:40 +02:00
return ;
}
2022-03-18 20:49:28 +01:00
2022-04-08 21:32:52 +02:00
void lockFile ( char * filepath , queueT * q , long fd_c , taglia_t * taglia , pthread_mutex_t * lock , waiting_t * * waiting ) {
2022-05-07 21:16:35 +02:00
/* message to write to the logfile */
2022-04-09 22:43:26 +02:00
char tmp_buf [ LOGBUFSIZE ] ;
2022-04-09 01:11:46 +02:00
int n = 0 ;
size_t m = sizeof ( tmp_buf ) ;
if ( ! filepath | | ! q | | ! taglia | | ! lock | | ! waiting ) {
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una lockFile sul file \" %s \" e' terminata con errore. \n " ,
fd_c ,
filepath ) ;
2022-04-09 01:11:46 +02:00
errno = EINVAL ;
serror ( MESY , fd_c , taglia , tmp_buf ) ;
return ;
}
2022-05-07 21:16:35 +02:00
/* search the file to lock */
2022-04-09 01:11:46 +02:00
fileT * f = NULL ;
f = find ( q , filepath ) ;
2022-05-07 21:16:35 +02:00
if ( ! f ) { /* file is not present */
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una lockFile sul file \" %s \" ma risulta assente. \n " ,
fd_c ,
filepath ) ;
2022-04-09 01:11:46 +02:00
errno = ENOENT ;
serror ( MENT , fd_c , taglia , tmp_buf ) ;
destroyFile ( f ) ;
return ;
}
2022-05-07 21:16:35 +02:00
/* try to lock */
2022-04-09 01:11:46 +02:00
if ( openFileInQueue ( q , filepath , 1 , fd_c ) = = - 1 ) {
2022-05-07 21:16:35 +02:00
/* unable to aquire the lock, wait to be released by inserting into
* the waiting queue */
2022-04-09 01:11:46 +02:00
if ( errno = = EPERM ) {
2022-05-07 21:16:35 +02:00
if ( pthread_mutex_lock ( lock ) = = - 1 ) { /* begin ME */
perror ( " lockFile: pthread_mutex_lock " ) ;
2022-04-09 01:11:46 +02:00
destroyFile ( f ) ;
return ;
}
if ( addWaiting ( waiting , filepath , fd_c ) = = - 1 ) {
2022-05-07 21:16:35 +02:00
perror ( " lockFile: addWaiting " ) ;
2022-04-09 01:11:46 +02:00
pthread_mutex_unlock ( lock ) ;
destroyFile ( f ) ;
return ;
}
2022-05-07 21:16:35 +02:00
if ( pthread_mutex_unlock ( lock ) = = - 1 ) { /* end ME */
perror ( " lockFile: pthread_mutex_unlock " ) ;
2022-04-09 01:11:46 +02:00
}
destroyFile ( f ) ;
return ;
}
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una lockFile sul file \" %s \" e' terminata con errore. \n " ,
fd_c ,
filepath ) ;
2022-04-09 01:11:46 +02:00
errno = ENOLCK ;
serror ( MESE , fd_c , taglia , tmp_buf ) ;
destroyFile ( f ) ;
return ;
}
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una lockFile sul file \" %s \" e' terminata con successo \n " ,
fd_c ,
filepath ) ;
2022-04-09 01:11:46 +02:00
sendMessage ( MEOK , fd_c , taglia , tmp_buf ) ;
destroyFile ( f ) ;
2022-04-04 22:31:14 +02:00
return ;
}
2022-03-18 20:49:28 +01:00
2022-04-08 21:32:52 +02:00
void unlockFile ( char * filepath , queueT * q , long fd_c , taglia_t * taglia , pthread_mutex_t * lock , waiting_t * * waiting ) {
2022-05-07 21:16:35 +02:00
/* message to write to the logfile */
2022-04-10 20:51:43 +02:00
char tmp_buf [ LOGBUFSIZE ] ;
int n = 0 ;
size_t m = sizeof ( tmp_buf ) ;
if ( ! filepath | | ! q | | ! taglia | | ! lock | | ! waiting ) {
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una unlockFile sul file \" %s \" e' terminata con errore. \n " ,
fd_c ,
filepath ) ;
2022-04-10 20:51:43 +02:00
errno = EINVAL ;
serror ( MESY , fd_c , taglia , tmp_buf ) ;
return ;
}
2022-05-07 21:16:35 +02:00
/* search the file */
if ( ! searchFile ( q , filepath ) ) { /* file does not exist */
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una unlockFile sul file \" %s \" ma risulta assente. \n " ,
fd_c ,
filepath ) ;
2022-04-10 20:51:43 +02:00
errno = ENOENT ;
serror ( MENT , fd_c , taglia , tmp_buf ) ;
return ;
}
if ( unlockFileInQueue ( q , filepath , fd_c ) ! = 0 ) {
2022-05-07 21:16:35 +02:00
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 ) ;
2022-04-10 20:51:43 +02:00
serror ( MENT , fd_c , taglia , tmp_buf ) ;
return ;
}
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una unlockFile sul file \" %s \" e' terminata con successo \n " ,
fd_c ,
filepath ) ;
2022-04-10 20:51:43 +02:00
sendMessage ( MEOK , fd_c , taglia , tmp_buf ) ;
2022-05-07 21:16:35 +02:00
/* signal another waiting client that a lock has been released */
if ( pthread_mutex_lock ( lock ) = = - 1 ) { /* begin ME */
perror ( " unlockFile: pthread_mutex_lock " ) ;
2022-04-10 20:51:43 +02:00
return ;
}
int waked = - 1 ;
waked = removeFirstWaiting ( waiting , filepath ) ;
if ( waked ! = - 1 ) {
2022-05-07 21:16:35 +02:00
/* we lock the file for the other client */
2022-04-10 20:51:43 +02:00
lockFile ( filepath , q , waked , taglia , lock , waiting ) ;
}
2022-05-07 21:16:35 +02:00
if ( pthread_mutex_unlock ( lock ) = = - 1 ) { /* end ME */
perror ( " unlockFile: pthread_mutex_unlock " ) ;
2022-04-10 20:51:43 +02:00
return ;
}
2022-04-04 22:31:14 +02:00
return ;
}
2022-03-18 20:49:28 +01:00
2022-03-31 22:26:44 +02:00
2022-04-08 21:32:52 +02:00
void closeFile ( char * filepath , queueT * q , long fd_c , taglia_t * taglia , pthread_mutex_t * lock , waiting_t * * waiting ) {
2022-05-07 21:16:35 +02:00
/* message to write to the logfile */
2022-04-10 20:51:43 +02:00
char tmp_buf [ LOGBUFSIZE ] ;
int n = 0 ;
size_t m = sizeof ( tmp_buf ) ;
if ( ! filepath | | ! q | | ! taglia | | ! lock | | ! waiting ) {
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una closeFile sul file \" %s \" e' terminata con errore. \n " ,
fd_c ,
filepath ) ;
2022-04-10 20:51:43 +02:00
errno = EINVAL ;
serror ( MESY , fd_c , taglia , tmp_buf ) ;
return ;
}
2022-05-07 21:16:35 +02:00
if ( ! searchFile ( q , filepath ) ) { /* file does not exist */
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una closeFile sul file \" %s \" ma risulta assente. \n " ,
fd_c ,
filepath ) ;
2022-04-10 20:51:43 +02:00
errno = ENOENT ;
serror ( MENT , fd_c , taglia , tmp_buf ) ;
return ;
}
if ( closeFileInQueue ( q , filepath , fd_c ) = = - 1 ) {
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una closeFile sul file \" %s \" e' terminata con errore. \n " ,
fd_c ,
filepath ) ;
2022-04-10 20:51:43 +02:00
serror ( MENT , fd_c , taglia , tmp_buf ) ;
return ;
}
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una closeFile sul file \" %s \" e' terminata con successo \n " ,
fd_c ,
filepath ) ;
2022-04-10 20:51:43 +02:00
sendMessage ( MEOK , fd_c , taglia , tmp_buf ) ;
2022-05-07 21:16:35 +02:00
/* signal another waiting client that a lock has been released */
if ( pthread_mutex_lock ( lock ) = = - 1 ) { /* begin ME */
perror ( " closeFile: pthread_mutex_lock " ) ;
2022-04-10 20:51:43 +02:00
return ;
}
int waked = - 1 ;
waked = removeFirstWaiting ( waiting , filepath ) ;
if ( waked ! = - 1 ) {
2022-05-07 21:16:35 +02:00
/* we lock the file for the other client */
2022-04-10 20:51:43 +02:00
lockFile ( filepath , q , waked , taglia , lock , waiting ) ;
}
2022-05-07 21:16:35 +02:00
if ( pthread_mutex_unlock ( lock ) = = - 1 ) { /* end ME */
perror ( " closeFile: pthread_mutex_unlock " ) ;
2022-04-10 20:51:43 +02:00
return ;
}
2022-04-04 22:31:14 +02:00
return ;
}
2022-03-31 22:26:44 +02:00
2022-04-08 21:32:52 +02:00
void removeFile ( char * filepath , queueT * q , long fd_c , taglia_t * taglia , pthread_mutex_t * lock , waiting_t * * waiting ) {
2022-05-07 21:16:35 +02:00
/* message to write to the logfile */
2022-04-10 20:51:43 +02:00
char tmp_buf [ LOGBUFSIZE ] ;
int n = 0 ;
size_t m = sizeof ( tmp_buf ) ;
if ( ! filepath | | ! q | | ! taglia | | ! lock | | ! waiting ) {
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una removeFile sul file \" %s \" e' terminata con errore. \n " ,
fd_c ,
filepath ) ;
2022-04-10 20:51:43 +02:00
errno = EINVAL ;
serror ( MESY , fd_c , taglia , tmp_buf ) ;
return ;
}
2022-05-07 21:16:35 +02:00
/* search for the file to delete */
if ( ! searchFile ( q , filepath ) ) { /* file does not exist */
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una removeFile sul file \" %s \" ma risulta assente. \n " ,
fd_c ,
filepath ) ;
2022-04-10 20:51:43 +02:00
errno = ENOENT ;
serror ( MENT , fd_c , taglia , tmp_buf ) ;
return ;
}
if ( removeFileFromQueue ( q , filepath , fd_c ) = = - 1 ) {
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una removeFile sul file \" %s \" e' terminata con errore del server. \n " ,
fd_c ,
filepath ) ;
2022-04-10 20:51:43 +02:00
serror ( MENT , fd_c , taglia , tmp_buf ) ;
return ;
}
2022-05-07 21:16:35 +02:00
n + = snprintf ( tmp_buf + n , m - n , " Client %ld ha richiesto una removeFile sul file \" %s \" e' terminata con successo \n " ,
fd_c ,
filepath ) ;
2022-04-10 20:51:43 +02:00
sendMessage ( MEOK , fd_c , taglia , tmp_buf ) ;
2022-05-07 21:16:35 +02:00
/* signal another waiting client that a lock has been released */
if ( pthread_mutex_lock ( lock ) = = - 1 ) { /* begin ME */
perror ( " removeFile: pthread_mutex_lock " ) ;
2022-04-10 20:51:43 +02:00
return ;
}
int waked = - 1 ;
waked = removeFirstWaiting ( waiting , filepath ) ;
if ( waked ! = - 1 ) {
2022-05-07 21:16:35 +02:00
/* we lock the file for the other client */
2022-04-10 20:51:43 +02:00
lockFile ( filepath , q , waked , taglia , lock , waiting ) ;
}
2022-05-07 21:16:35 +02:00
if ( pthread_mutex_unlock ( lock ) = = - 1 ) { /* end ME */
perror ( " removeFile: pthread_mutex_unlock " ) ;
2022-04-10 20:51:43 +02:00
return ;
}
2022-04-04 22:31:14 +02:00
return ;
}
2022-03-31 22:26:44 +02:00
2022-04-10 20:51:43 +02:00
// -----------------------------------------------------------------------------
2022-05-07 21:16:35 +02:00
// helper functions for clients waiting locks
/* add a client to the waiting list */
2022-04-10 20:51:43 +02:00
int addWaiting ( waiting_t * * waiting , char * filepath , int fd_c ) {
if ( ! waiting | | ! filepath ) {
errno = EINVAL ;
return - 1 ;
}
2022-03-31 22:26:44 +02:00
2022-04-10 20:51:43 +02:00
waiting_t * new = calloc ( 1 , sizeof ( waiting_t ) ) ;
if ( ! new ) {
2022-05-07 21:16:35 +02:00
perror ( " addWaiting: calloc " ) ;
2022-04-10 20:51:43 +02:00
return - 1 ;
}
new - > file = calloc ( MAXLENMESS , sizeof ( char ) ) ;
if ( ! new - > file ) {
2022-05-07 21:16:35 +02:00
perror ( " addWaiting: calloc " ) ;
2022-04-10 20:51:43 +02:00
free ( new ) ;
return - 1 ;
}
2022-03-18 20:49:28 +01:00
2022-04-10 20:51:43 +02:00
strncpy ( new - > file , filepath , strnlen ( filepath , MAXLENMESS - 1 ) + 1 ) ;
new - > fd = fd_c ;
new - > next = NULL ;
2022-03-18 20:49:28 +01:00
2022-05-07 21:16:35 +02:00
/* if the list is empty */
2022-04-10 20:51:43 +02:00
if ( * waiting = = NULL ) {
* waiting = new ;
return 0 ;
}
2022-03-18 20:49:28 +01:00
2022-05-07 21:16:35 +02:00
/* if the list has at least 1 element */
2022-04-10 20:51:43 +02:00
waiting_t * tail = * waiting ;
while ( tail - > next ) {
tail = tail - > next ;
}
tail - > next = new ;
2022-03-18 20:49:28 +01:00
2022-04-08 21:32:52 +02:00
return 0 ;
2022-04-04 22:31:14 +02:00
}
2022-03-18 20:49:28 +01:00
2022-05-07 21:16:35 +02:00
/* remove first who is waiting on the lock for the file
* if no one is waiting for the lock it returns - 1 */
2022-04-10 20:51:43 +02:00
int removeFirstWaiting ( waiting_t * * waiting , char * filepath ) {
if ( ! waiting | | ! filepath ) {
errno = EINVAL ;
return - 1 ;
}
2022-05-07 21:16:35 +02:00
/* none waiting */
2022-04-10 20:51:43 +02:00
if ( * waiting = = NULL ) {
return - 1 ;
}
waiting_t * curr = * waiting ;
waiting_t * prec = NULL ;
long fd_c = - 1 ;
2022-05-07 21:16:35 +02:00
/* first one waiting */
2022-04-10 20:51:43 +02:00
if ( strcmp ( curr - > file , filepath ) = = 0 ) {
fd_c = curr - > fd ;
* waiting = curr - > next ;
free ( curr - > file ) ;
free ( curr ) ;
return fd_c ;
}
2022-05-07 21:16:35 +02:00
/* more than one waiting */
2022-04-10 20:51:43 +02:00
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 ) ;
2022-03-18 20:49:28 +01:00
2022-04-10 20:51:43 +02:00
return fd_c ;
}
}
return - 1 ;
}
2022-05-07 21:16:35 +02:00
/* free waiting structure */
2022-04-08 21:32:52 +02:00
void clearWaiting ( waiting_t * * waiting ) {
2022-04-10 20:51:43 +02:00
if ( ! waiting ) {
return ;
}
waiting_t * curr = * waiting ;
waiting_t * next = NULL ;
while ( curr ) {
next = curr - > next ;
2022-04-23 17:43:38 +02:00
if ( curr - > file )
free ( curr - > file ) ;
2022-04-10 20:51:43 +02:00
free ( curr ) ;
curr = next ;
}
* waiting = NULL ;
2022-04-04 22:31:14 +02:00
return ;
}