2022-04-24 13:01:13 +02:00
# define _POSIX_C_SOURCE 200809L
2022-04-20 18:25:55 +02:00
# include <ctype.h>
# include <errno.h>
2022-04-16 21:21:04 +02:00
# include <signal.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
2022-04-20 18:25:55 +02:00
# include <sys/types.h>
2022-05-02 23:26:05 +02:00
# include <sys/stat.h>
# include <fts.h>
2022-04-20 18:25:55 +02:00
# include <time.h>
# include <unistd.h>
2022-04-16 21:21:04 +02:00
# include <api.h>
2022-04-20 18:25:55 +02:00
# include <strsep_gnu.h>
2022-04-16 21:21:04 +02:00
# define UNIX_PATH_MAX 256
# define MAXARGLENGTH 256
static char globalSocket [ UNIX_PATH_MAX ] = " " ;
// struttura della lista dei comandi
typedef struct cmd_s {
char name ; // nome del comando
char * arg ; // (eventuale) argomento del comando
struct cmd_s * next ; // puntatore al prossimo comando nella lista
} cmd_t ;
// -----------------------------------------------------------------------------
// helper functions
// libera la memoria della lista dei comandi
void destroyCommandList ( cmd_t * l ) ;
// aggiunge un comando alla lista
int addCommand ( cmd_t * * l , char cmd , char * arg ) ;
2022-04-17 19:00:20 +02:00
// esegue tutti i comandi nella lista
int execute ( cmd_t * l , int print ) ;
2022-04-16 21:21:04 +02:00
// per chiudere la connessione prima dell'uscita
void cleanup ( ) {
2022-04-17 19:22:22 +02:00
if ( strncmp ( globalSocket , " " , 2 ) ! = 0 ) {
2022-04-16 21:21:04 +02:00
closeConnection ( globalSocket ) ;
2022-04-17 19:22:22 +02:00
strncpy ( globalSocket , " " , 2 ) ;
2022-04-16 21:21:04 +02:00
}
}
2022-04-21 00:09:15 +02:00
// compare files
int compare ( const FTSENT * * first , const FTSENT * * second ) {
return ( strcmp ( ( * first ) - > fts_name , ( * second ) - > fts_name ) ) ;
}
2022-04-16 21:21:04 +02:00
// -h
static void usage ( const char * argv0 ) {
// TODO change this
2022-04-17 23:50:38 +02:00
printf ( " Uso: %s \n " , argv0 ) ;
printf ( " -h: stampa il presente messaggio d'aiuto. \n " ) ;
printf ( " -f filename: connettiti al socket AF_UNIX 'filename'. \n " ) ;
printf ( " -w dirname[,n=0]: invia al server 'n' file nella cartella 'dirname'. Se n=0 o non e' specificato, tenta di inviare tutti i file al server. \n " ) ;
printf ( " -W file1[,file2]: scrivi sul server una lista di file, separati da virgole. \n " ) ;
printf ( " -D dirname: specifica la cartella dove scrivere i file espulsi dal server in seguito a capacity misses. \n " ) ;
printf ( " -r file1[,file2]: leggi dal server una lista di nomi di file, separati da virgole. \n " ) ;
printf ( " -R [n=0]: leggi dal server 'n' file qualsiasi. Se n=0 o non e' specificato, leggi tutti i file presenti nel server per i quali si hanno i permessi necessari. \n " ) ;
printf ( " -d dirname: cartella dove scrivere i file letti dal server con i comandi '-r' o '-R'. \n " ) ;
printf ( " -t time: se specificato, fra le richieste successive al server vi sara' un'attesa di 'time' millisecondi. \n " ) ;
printf ( " -l file1[,file2]: acquisisci la mutua esclusione su una lista di file, separati da virgole. \n " ) ;
printf ( " -u file1[,file2]: rilascia la mutua esclusione su una lista di file, separati da virgole. \n " ) ;
printf ( " -c file1[,file2]: rimuovi dal server una lista di file (se presenti), separati da virgole. \n " ) ;
printf ( " -p: stampa sullo standard output le informazioni riguardo ogni operazione effettuata. \n " ) ;
2022-04-16 21:21:04 +02:00
}
2022-04-17 19:00:20 +02:00
// -f
int cmd_f ( char * socket ) ;
// -w
int cmd_w ( char * dirname , char * Dir , int print ) ;
// -W
int cmd_W ( char * filelist , char * Dir , int print ) ;
2022-04-17 19:22:22 +02:00
// -r
int cmd_r ( char * filelist , char * dir , int print ) ;
// -R
int cmd_R ( char * numStr , char * dir , int print ) ;
// -l
int cmd_l ( char * filelist , int print ) ;
// -u
int cmd_u ( char * filelist , int print ) ;
// -c
int cmd_c ( char * filelist , int print ) ;
2022-04-17 19:00:20 +02:00
2022-04-20 18:25:55 +02:00
2022-04-16 21:21:04 +02:00
// -----------------------------------------------------------------------------
// MAIN
int main ( int argc , char * argv [ ] ) {
atexit ( cleanup ) ;
if ( argc < = 1 ) { // no arguments => -h
usage ( argv [ 0 ] ) ;
return 0 ;
}
struct sigaction siga ;
// ignoro il segnale SIGPIPE
memset ( & siga , 0 , sizeof ( siga ) ) ;
siga . sa_handler = SIG_IGN ;
if ( sigaction ( SIGPIPE , & siga , NULL ) = = - 1 ) {
perror ( " sigaction. \n " ) ;
return 1 ;
}
// lista dei comandi
cmd_t * cmds = NULL ;
2022-04-17 19:00:20 +02:00
int opt = 0 ;
2022-04-16 21:21:04 +02:00
char args [ MAXARGLENGTH ] ;
2022-04-17 19:00:20 +02:00
int print = 0 ;
2022-04-16 21:21:04 +02:00
char f = 0 ;
// add args to list
while ( ( opt = getopt ( argc , argv , " :hpf:t:w:W:D:r:R:d:l:u:c: " ) ) ! = - 1 ) {
switch ( opt ) {
case ' h ' : // help message
usage ( argv [ 0 ] ) ;
goto _cleanup ;
case ' f ' : // socket name
if ( ! f ) {
if ( optarg & & strnlen ( optarg , MAXARGLENGTH ) > 0 & & optarg [ 0 ] = = ' - ' ) {
fprintf ( stderr , " Il comando -f necessita di un argomento. \n " ) ;
goto _cleanup ;
}
memset ( args , 0 , MAXARGLENGTH ) ;
strncpy ( args , optarg , strnlen ( optarg , MAXARGLENGTH - 1 ) + 1 ) ;
2022-04-17 19:00:20 +02:00
addCommand ( & cmds , opt , args ) ;
2022-04-16 21:21:04 +02:00
+ + f ;
}
break ;
case ' p ' : // print to stdout
2022-04-21 20:08:22 +02:00
printInfo ( 1 , stdout ) ;
2022-04-17 19:00:20 +02:00
+ + print ;
2022-04-16 21:21:04 +02:00
break ;
case ' w ' : // send files from folder (n is specified after)
if ( optarg & & strnlen ( optarg , MAXARGLENGTH ) > 0 & & optarg [ 0 ] = = ' - ' ) {
fprintf ( stderr , " Il comando -w necessita di un argomento. \n " ) ;
goto _cleanup ;
}
memset ( args , 0 , MAXARGLENGTH ) ;
strncpy ( args , optarg , strnlen ( optarg , MAXARGLENGTH - 1 ) + 1 ) ;
addCommand ( & cmds , opt , args ) ;
break ;
2022-04-17 19:00:20 +02:00
case ' W ' : // files to send separated by ','
case ' D ' : // directory to store recived files
case ' r ' : // files to read from server separated by ','
case ' d ' : // directory to store read files
case ' t ' : // time in ms between requests
case ' l ' : // file to request lock of separated by ','
case ' u ' : // file to relese lock of separated by ','
case ' c ' : // files to remove separated by ','
if ( optarg & & strnlen ( optarg , MAXARGLENGTH ) > 0 & & optarg [ 0 ] = = ' - ' ) {
fprintf ( stderr , " Il comando -%c necessita di un argomento. \n " , optopt ) ;
goto _cleanup ;
}
memset ( args , 0 , MAXARGLENGTH ) ;
strncpy ( args , optarg , strnlen ( optarg , MAXARGLENGTH - 1 ) + 1 ) ;
addCommand ( & cmds , opt , args ) ;
break ;
case ' R ' : // read n random files
if ( optarg & & strnlen ( optarg , MAXARGLENGTH ) > 0 & & optarg [ 0 ] = = ' - ' ) {
optind - = 1 ;
addCommand ( & cmds , opt , NULL ) ;
break ;
}
memset ( args , 0 , MAXARGLENGTH ) ;
strncpy ( args , optarg , strnlen ( optarg , MAXARGLENGTH - 1 ) + 1 ) ;
addCommand ( & cmds , opt , args ) ;
break ;
case ' : ' : // command with no argument (:: is a GNU extension)
switch ( optopt ) {
case ' R ' :
addCommand ( & cmds , opt , NULL ) ;
break ;
default :
fprintf ( stderr , " Il comando -%c necessita di un argomento. \n " , optopt ) ;
goto _cleanup ;
}
break ;
case ' ? ' : // unknown
default : // unknown
fprintf ( stderr , " Comando non riconosciuto: -%c. \n " , optopt ) ;
usage ( argv [ 0 ] ) ;
goto _cleanup ;
2022-04-16 21:21:04 +02:00
}
}
2022-04-17 19:00:20 +02:00
if ( execute ( cmds , print ) < 0 ) {
perror ( " execute " ) ;
goto _cleanup ;
}
2022-04-16 21:21:04 +02:00
2022-04-25 20:24:55 +02:00
if ( cmds ) {
destroyCommandList ( cmds ) ;
}
2022-04-16 21:21:04 +02:00
return 0 ;
_cleanup :
if ( cmds ) {
destroyCommandList ( cmds ) ;
}
return 0 ;
}
// -----------------------------------------------------------------------------
void destroyCommandList ( cmd_t * l ) {
if ( ! l ) {
errno = EINVAL ;
return ;
}
cmd_t * tmp ;
// scorro tutta la lista e libero la memoria
while ( l ) {
tmp = l ;
l = l - > next ;
2022-04-25 20:24:55 +02:00
free ( tmp - > arg ) ;
2022-04-16 21:21:04 +02:00
free ( tmp ) ;
}
}
int addCommand ( cmd_t * * l , char cmd , char * arg ) {
if ( ! l ) {
errno = EINVAL ;
return - 1 ;
}
cmd_t * new = calloc ( 1 , sizeof ( cmd_t ) ) ;
if ( ! new ) {
perror ( " calloc " ) ;
return - 1 ;
}
new - > name = cmd ;
if ( arg ) {
new - > arg = malloc ( MAXARGLENGTH ) ;
if ( new - > arg = = NULL ) {
perror ( " malloc arg " ) ;
free ( new ) ;
return - 1 ;
}
strncpy ( new - > arg , arg , strnlen ( arg , MAXARGLENGTH - 1 ) + 1 ) ;
}
new - > next = NULL ;
// se lista vuota aggiungo in cima, altrimenti scorro la lista
if ( * l = = NULL ) {
* l = new ;
return 0 ;
}
2022-04-24 01:36:43 +02:00
cmd_t * tail = * l ;
2022-04-16 21:21:04 +02:00
while ( tail - > next ) {
tail = tail - > next ;
}
tail - > next = new ;
2022-04-16 15:07:25 +02:00
return 0 ;
}
2022-04-17 19:00:20 +02:00
int execute ( cmd_t * l , int print ) {
if ( ! l ) {
errno = EINVAL ;
return - 1 ;
}
cmd_t * tmp = l ;
struct timespec interval ;
interval . tv_nsec = 0 ;
interval . tv_sec = 0 ;
// loop that serches for -t
while ( tmp ) {
switch ( tmp - > name ) {
case ' t ' : { // time in ms between requests
long num ;
num = strtol ( tmp - > arg , NULL , 10 ) ;
if ( num = = 0 & & errno = = EINVAL ) {
errno = EINVAL ;
perror ( " Invalid time specified after -t " ) ;
return - 1 ;
}
// milliseconds converted to nanoseconds
interval . tv_nsec = ( num % 1000 ) * 1000000 ;
// seconds
interval . tv_sec = ( num / 1000 ) ;
if ( print )
2022-04-24 01:36:43 +02:00
fprintf ( stdout , " t - Tempo fra due richieste: %ld ms \t Esito: ok \n " , num ) ;
2022-04-17 19:00:20 +02:00
break ;
}
default :
break ;
}
tmp = tmp - > next ;
}
2022-04-24 01:36:43 +02:00
fflush ( stdout ) ;
2022-04-17 19:00:20 +02:00
// loop that serches for -f
tmp = l ;
while ( tmp ) {
switch ( tmp - > name ) {
case ' f ' : {
int ok = 1 ;
strncpy ( globalSocket , tmp - > arg , strnlen ( tmp - > arg , MAXARGLENGTH ) + 1 ) ;
if ( cmd_f ( tmp - > arg ) ! = 0 ) {
if ( print )
perror ( " -f " ) ;
ok = 0 ;
}
if ( print ) {
2022-04-24 01:36:43 +02:00
fprintf ( stdout , " f - Connessione al socket: %s \t Esito: " , globalSocket ) ;
2022-04-17 19:00:20 +02:00
if ( ok )
printf ( " ok \n " ) ;
if ( ! ok )
printf ( " errore \n " ) ;
}
2022-04-25 20:24:55 +02:00
if ( ! ok ) {
closeConnection ( tmp - > arg ) ;
2022-04-17 19:00:20 +02:00
return 0 ; // no socket to connect, nothing to do
2022-04-25 20:24:55 +02:00
}
2022-04-17 19:00:20 +02:00
// we only read the first -f, no error reported if more than one is
// specified
tmp = NULL ;
break ;
}
default :
break ;
}
2022-04-24 01:36:43 +02:00
if ( tmp )
tmp = tmp - > next ;
2022-04-17 19:00:20 +02:00
}
2022-04-24 01:36:43 +02:00
fflush ( stdout ) ;
2022-04-17 19:00:20 +02:00
// loop that checks for consistencies:
// 1) -D with no -w or -W after
// 2) -d with no -r or -R after
tmp = l ;
int unmachedD = 0 ;
int unmachedd = 0 ;
while ( tmp ) {
switch ( tmp - > name ) {
case ' D ' :
if ( unmachedD ) {
2022-04-24 01:36:43 +02:00
fprintf ( stdout , " \n Error: -D has no -w or -W matching after \n " ) ;
2022-04-17 19:00:20 +02:00
return 0 ;
}
unmachedD = 1 ;
break ;
case ' w ' :
case ' W ' :
unmachedD = 0 ;
break ;
case ' d ' :
if ( unmachedd ) {
2022-04-24 01:36:43 +02:00
fprintf ( stdout , " \n Error: -d has no -r or -R matching after \n " ) ;
2022-04-17 19:00:20 +02:00
return 0 ;
}
unmachedd = 1 ;
break ;
case ' r ' :
case ' R ' :
unmachedd = 0 ;
break ;
default :
break ;
}
tmp = tmp - > next ;
}
if ( unmachedD ) {
2022-04-24 01:36:43 +02:00
fprintf ( stdout , " \n Error: -D has no -w or -W matching after \n " ) ;
2022-04-17 19:00:20 +02:00
return 0 ;
}
if ( unmachedd ) {
2022-04-24 01:36:43 +02:00
fprintf ( stdout , " \n Error: -d has no -r or -R matching after \n " ) ;
2022-04-17 19:00:20 +02:00
return 0 ;
}
2022-04-24 01:36:43 +02:00
fflush ( stdout ) ;
2022-04-17 19:00:20 +02:00
char * Dir = NULL ; // -D folder
char * dir = NULL ; // -d folder
// loop that executes -w, -W, -D; -r, -R, -d; -l, -u, -c
tmp = l ;
while ( tmp ) {
switch ( tmp - > name ) {
case ' w ' :
cmd_w ( tmp - > arg , Dir , print ) ;
break ;
case ' W ' :
cmd_W ( tmp - > arg , Dir , print ) ;
break ;
case ' D ' :
if ( Dir )
free ( Dir ) ;
2022-04-25 20:24:55 +02:00
Dir = calloc ( strnlen ( tmp - > arg , MAXARGLENGTH ) + 1 , sizeof ( char ) ) ;
2022-04-17 19:00:20 +02:00
strncpy ( Dir , tmp - > arg , strnlen ( tmp - > arg , MAXARGLENGTH ) ) ;
if ( setDirectory ( Dir , 1 ) = = - 1 ) {
if ( print )
perror ( " -D " ) ;
}
if ( print )
printf ( " \n D - Cartella per le scritture: %s \t Esito: ok \n " , Dir ) ;
break ;
case ' r ' :
2022-04-17 19:22:22 +02:00
cmd_r ( tmp - > arg , dir , print ) ;
2022-04-17 19:00:20 +02:00
break ;
case ' R ' :
2022-04-17 19:22:22 +02:00
cmd_R ( tmp - > arg , dir , print ) ;
2022-04-17 19:00:20 +02:00
break ;
case ' d ' :
if ( dir )
free ( dir ) ;
2022-04-25 20:24:55 +02:00
dir = calloc ( strnlen ( tmp - > arg , MAXARGLENGTH ) + 1 , sizeof ( char ) ) ;
2022-04-17 19:00:20 +02:00
strncpy ( dir , tmp - > arg , strnlen ( tmp - > arg , MAXARGLENGTH ) ) ;
if ( setDirectory ( dir , 0 ) = = - 1 ) {
if ( print )
perror ( " -d " ) ;
}
if ( print )
printf ( " \n d - Cartella per le letture: %s \t Esito: ok \n " , dir ) ;
break ;
case ' l ' :
2022-04-17 19:22:22 +02:00
cmd_l ( tmp - > arg , print ) ;
2022-04-17 19:00:20 +02:00
break ;
case ' u ' :
2022-04-17 19:22:22 +02:00
cmd_u ( tmp - > arg , print ) ;
2022-04-17 19:00:20 +02:00
break ;
case ' c ' :
2022-04-17 19:22:22 +02:00
cmd_c ( tmp - > arg , print ) ;
2022-04-17 19:00:20 +02:00
break ;
default :
break ;
}
2022-04-17 19:22:22 +02:00
// maybe better: while(nanosleep(&interval, &interval));
nanosleep ( & interval , NULL ) ;
2022-04-17 19:00:20 +02:00
tmp = tmp - > next ;
}
2022-04-17 19:22:22 +02:00
if ( print )
printf ( " \n " ) ;
if ( dir )
free ( dir ) ;
if ( Dir )
free ( Dir ) ;
cleanup ( ) ;
2022-04-17 19:00:20 +02:00
return 0 ;
}
// -----------------------------------------------------------------------------
// funzioni relative ai comandi
int cmd_f ( char * socket ) {
if ( ! socket ) {
errno = EINVAL ;
return - 1 ;
}
struct timespec ts ;
ts . tv_sec = 2 ;
ts . tv_nsec = 0 ;
if ( openConnection ( socket , 100 , ts ) ! = 0 )
return - 1 ;
return 0 ;
}
int cmd_w ( char * dirname , char * Dir , int print ) {
2022-04-17 23:50:38 +02:00
if ( ! dirname ) {
errno = EINVAL ;
return - 1 ;
}
2022-04-20 18:25:55 +02:00
int num ;
// we copy dirname because we are nice
2022-04-29 01:26:31 +02:00
char * tofree = calloc ( strnlen ( dirname , MAXARGLENGTH ) + 1 , sizeof ( char ) ) ;
2022-04-20 18:25:55 +02:00
if ( ! tofree ) {
perror ( " malloc " ) ;
return - 1 ;
}
strncpy ( tofree , dirname , strnlen ( dirname , MAXARGLENGTH ) ) ;
char * firstArg ;
char * secondArg = tofree ;
firstArg = strsep_gnu ( & secondArg , " , " ) ; // secondArg has the number of files
if ( ! secondArg ) {
num = - 1 ;
} else if ( secondArg [ 0 ] = = ' n ' & & secondArg [ 1 ] = = ' = ' ) {
char * number = & secondArg [ 2 ] ;
for ( int i = 0 ; i < strlen ( number ) ; + + i ) {
if ( ! isdigit ( number [ i ] ) ) {
free ( tofree ) ;
errno = EINVAL ;
return - 1 ;
}
}
num = ( int ) strtol ( number , NULL , 10 ) ;
num = ( num = = 0 ) ? - 1 : num ;
} else {
free ( tofree ) ;
errno = EINVAL ;
return - 1 ;
}
if ( print ) {
2022-04-29 01:26:31 +02:00
printf ( " \n w - Scrivo i seguenti file sul server: \n " ) ;
2022-04-20 18:25:55 +02:00
fflush ( stdout ) ;
}
// we use fts to traverse all files in the directory recursively
FTS * fhandle = NULL ;
FTSENT * child = NULL ;
FTSENT * parent = NULL ;
fhandle = fts_open ( & firstArg , FTS_COMFOLLOW , & compare ) ;
2022-04-29 22:31:08 +02:00
char * * listFiles = calloc ( 0 , sizeof ( char * ) ) ;
int numFiles = 0 ;
2022-04-20 18:25:55 +02:00
if ( fhandle ! = NULL ) {
// we check for num == 0 so that -1 yields all files in folder
while ( num ! = 0 & & ( parent = fts_read ( fhandle ) ) ! = NULL ) {
child = fts_children ( fhandle , 0 ) ;
while ( num ! = 0 & & ( child ! = NULL ) ) { // for all children in folder
if ( child - > fts_info = = FTS_F ) { // if child is a file
2022-04-29 22:31:08 +02:00
+ + numFiles ;
listFiles = realloc ( listFiles , numFiles * sizeof ( char * ) ) ;
listFiles [ numFiles - 1 ] = calloc ( child - > fts_namelen + child - > fts_pathlen + 2 , sizeof ( char ) ) ;
snprintf ( listFiles [ numFiles - 1 ] , child - > fts_namelen + child - > fts_pathlen + 2 , " %s/%s " , child - > fts_path , child - > fts_name ) ;
2022-04-20 18:25:55 +02:00
- - num ;
}
child = child - > fts_link ;
}
}
fts_close ( fhandle ) ;
}
2022-04-29 22:31:08 +02:00
for ( int i = 0 ; i < numFiles ; + + i ) {
if ( print ) {
printf ( " %s [ " , listFiles [ i ] ) ;
}
// we send the file with the other function but set print to 0
int r = cmd_W ( listFiles [ i ] , Dir , 0 ) ;
if ( print & & ! r ) {
printf ( " Esito: ok " ) ;
} else if ( print & & r ) {
printf ( " Esito: errore " ) ;
}
if ( print ) {
printf ( " ] \n " ) ;
}
free ( listFiles [ i ] ) ;
}
free ( listFiles ) ;
2022-04-20 18:25:55 +02:00
free ( tofree ) ;
2022-04-17 19:00:20 +02:00
return 0 ;
}
int cmd_W ( char * filelist , char * Dir , int print ) {
2022-04-20 22:34:06 +02:00
if ( ! filelist ) {
errno = EINVAL ;
return - 1 ;
}
// we copy filelist because we are nice
char * tofree = malloc ( strnlen ( filelist , MAXARGLENGTH ) + 1 ) ;
if ( ! tofree ) {
perror ( " malloc " ) ;
return - 1 ;
}
2022-04-25 20:24:55 +02:00
memset ( tofree , 0 , strnlen ( filelist , MAXARGLENGTH ) + 1 ) ;
strncpy ( tofree , filelist , strnlen ( filelist , MAXARGLENGTH ) + 1 ) ;
2022-04-20 22:34:06 +02:00
2022-04-25 20:24:55 +02:00
char * token = NULL ;
2022-04-20 22:34:06 +02:00
char * string = tofree ;
if ( print = = 1 ) {
2022-04-24 01:36:43 +02:00
printf ( " W - Scrivo i seguenti file sul server: \n " ) ;
2022-04-20 22:34:06 +02:00
fflush ( stdout ) ;
}
2022-04-20 18:25:55 +02:00
2022-04-29 01:26:31 +02:00
int r = 0 ;
2022-04-20 23:33:40 +02:00
while ( ( token = strsep_gnu ( & string , " , " ) ) ! = NULL ) {
2022-04-20 22:34:06 +02:00
int ok = 1 ;
int opened = 0 ;
if ( print = = 1 ) {
2022-04-20 23:33:40 +02:00
printf ( " %s [ " , token ) ;
2022-04-20 22:34:06 +02:00
fflush ( stdout ) ;
}
// creo il file in modalita' locked
if ( openFile ( token , O_CREATE | O_LOCK ) = = - 1 ) {
ok = 0 ;
} else { // creato con successo
opened = 1 ;
}
2022-04-27 21:18:25 +02:00
if ( opened & & ( writeFile ( token , Dir ) = = - 1 ) ) {
2022-04-20 22:34:06 +02:00
ok = 0 ;
}
if ( opened & & ! ok ) { // errore precedente -> elimino il file vuoto
removeFile ( token ) ;
2022-04-27 21:18:25 +02:00
} else if ( opened & & ( closeFile ( token ) = = - 1 ) ) { // chiudo il file
2022-04-20 22:34:06 +02:00
ok = 0 ;
}
if ( print ! = 0 ) {
printf ( " Esito: " ) ;
2022-04-20 18:25:55 +02:00
2022-04-20 22:34:06 +02:00
if ( ok )
printf ( " ok " ) ;
else {
printf ( " errore " ) ;
perror ( " -w " ) ;
}
2022-04-20 18:25:55 +02:00
2022-04-20 23:33:40 +02:00
printf ( " ] \n " ) ;
2022-04-20 22:34:06 +02:00
fflush ( stdout ) ;
}
2022-04-29 01:26:31 +02:00
if ( ! ok )
r = - 1 ;
2022-04-20 22:34:06 +02:00
}
2022-04-20 18:25:55 +02:00
2022-04-20 22:34:06 +02:00
free ( tofree ) ;
2022-04-29 01:26:31 +02:00
return r ;
2022-04-17 19:00:20 +02:00
}
2022-04-17 19:22:22 +02:00
int cmd_r ( char * filelist , char * dir , int print ) {
2022-04-21 00:09:15 +02:00
if ( ! filelist ) {
errno = EINVAL ;
return - 1 ;
}
// we copy filelist because we are nice
char * tofree = malloc ( strnlen ( filelist , MAXARGLENGTH ) + 1 ) ;
2022-04-25 20:24:55 +02:00
memset ( tofree , 0 , strnlen ( filelist , MAXARGLENGTH ) + 1 ) ;
2022-04-21 00:09:15 +02:00
if ( ! tofree ) {
perror ( " malloc " ) ;
return - 1 ;
}
strncpy ( tofree , filelist , strnlen ( filelist , MAXARGLENGTH ) ) ;
2022-04-25 20:24:55 +02:00
char * token = NULL ;
2022-04-21 00:09:15 +02:00
char * string = tofree ;
if ( print ) {
printf ( " r - Leggo i seguenti file dal server: \n " ) ;
fflush ( stdout ) ;
}
while ( ( token = strsep_gnu ( & string , " , " ) ) ! = NULL ) {
int ok = 1 ;
int opened = 0 ;
if ( print ! = 0 ) {
printf ( " %s " , token ) ;
fflush ( stdout ) ;
}
if ( openFile ( token , 0 ) = = - 1 ) {
ok = 0 ;
} else {
opened = 1 ;
}
void * buf = NULL ;
size_t size = - 1 ;
2022-04-27 21:18:25 +02:00
printInfo ( 0 , stdout ) ;
2022-04-21 00:09:15 +02:00
// read the content of the file
if ( ok & & readFile ( token , & buf , & size ) = = - 1 ) {
2022-04-27 21:18:25 +02:00
fprintf ( stdout , " \n readFile \n " ) ;
fflush ( stdout ) ;
2022-04-21 00:09:15 +02:00
ok = 0 ;
}
if ( print ) {
2022-04-21 20:08:22 +02:00
printInfo ( 1 , stdout ) ;
2022-04-21 00:09:15 +02:00
}
if ( ok & & print ) {
printf ( " Dimensione: %zu B \t " , size ) ;
fflush ( stdout ) ;
}
if ( buf ) {
free ( buf ) ;
}
// close the file
if ( opened & & closeFile ( token ) = = - 1 ) {
2022-04-27 21:18:25 +02:00
fprintf ( stdout , " \n closeFile \n " ) ;
fflush ( stdout ) ;
2022-04-21 00:09:15 +02:00
ok = 0 ;
}
if ( print ) {
printf ( " [Esito: " ) ;
if ( ok ) {
printf ( " ok " ) ;
2022-04-27 21:18:25 +02:00
} else {
2022-04-21 00:09:15 +02:00
printf ( " errore " ) ;
perror ( " -r " ) ;
}
}
if ( print ) {
printf ( " ] \n " ) ;
fflush ( stdout ) ;
}
}
free ( tofree ) ;
if ( print & & dir ) {
printf ( " I file letti sono stati scritti nella cartella %s. \n . " , dir ) ;
fflush ( stdout ) ;
} else if ( print ) {
printf ( " I file letti non sono stati memorizzati su disco. \n " ) ;
fflush ( stdout ) ;
}
2022-04-17 19:22:22 +02:00
return 0 ;
}
int cmd_R ( char * numStr , char * dir , int print ) {
2022-04-21 00:09:15 +02:00
if ( print ) {
printf ( " R - Leggo i seguenti file dal server: \n " ) ;
fflush ( stdout ) ;
}
int n = - 1 ;
if ( ! numStr ) // skips the step of converting n from string to int
goto skipGetNumber ;
2022-04-29 21:04:45 +02:00
if ( strlen ( numStr ) < 2 )
goto skipGetNumber ;
2022-04-21 00:09:15 +02:00
2022-04-29 21:04:45 +02:00
if ( numStr [ 0 ] = = ' n ' & & numStr [ 1 ] = = ' = ' ) {
char * number = & numStr [ 2 ] ;
2022-04-21 00:09:15 +02:00
for ( int i = 0 ; i < strlen ( number ) ; + + i ) {
if ( ! isdigit ( number [ i ] ) ) {
errno = EINVAL ;
return - 1 ;
}
}
n = ( int ) strtol ( number , NULL , 10 ) ;
n = ( n = = 0 ) ? - 1 : n ;
} else {
errno = EINVAL ;
return - 1 ;
}
skipGetNumber :
if ( readNFiles ( n , dir ) = = - 1 ) {
return - 1 ;
}
if ( print & & dir ) {
printf ( " I file letti sono stati scritti nella cartella %s. \n " , dir ) ;
} else if ( print ) {
printf ( " I file letti non sono stati memorizzati su disco. \n " ) ;
}
2022-04-17 19:22:22 +02:00
return 0 ;
}
int cmd_l ( char * filelist , int print ) {
2022-04-20 23:33:40 +02:00
if ( ! filelist ) {
errno = EINVAL ;
return - 1 ;
}
// we copy filelist because we are nice
2022-04-29 22:31:08 +02:00
char * tofree = calloc ( strnlen ( filelist , MAXARGLENGTH ) + 1 , sizeof ( char ) ) ;
2022-04-20 23:33:40 +02:00
if ( ! tofree ) {
perror ( " malloc " ) ;
return - 1 ;
}
strncpy ( tofree , filelist , strnlen ( filelist , MAXARGLENGTH ) ) ;
char * token ;
char * string = tofree ;
if ( print ) {
printf ( " l - Acquisisco la mutua esclusione sui seguenti file: \n " ) ;
fflush ( stdout ) ;
}
while ( ( token = strsep_gnu ( & string , " , " ) ) ! = NULL ) {
if ( print ! = 0 ) {
printf ( " %s [Esito: " , token ) ;
fflush ( stdout ) ;
}
if ( lockFile ( token ) = = - 1 ) {
if ( print ! = 0 ) {
printf ( " errore " ) ;
perror ( " -l " ) ;
}
} else if ( print ! = 0 ) {
printf ( " ok " ) ;
}
if ( print ! = 0 ) {
printf ( " ] \n " ) ;
fflush ( stdout ) ;
}
}
free ( tofree ) ;
2022-04-17 19:22:22 +02:00
return 0 ;
}
int cmd_u ( char * filelist , int print ) {
2022-04-20 23:33:40 +02:00
if ( ! filelist ) {
errno = EINVAL ;
return - 1 ;
}
// we copy filelist because we are nice
2022-04-30 00:37:59 +02:00
char * tofree = calloc ( strnlen ( filelist , MAXARGLENGTH ) + 1 , sizeof ( char ) ) ;
2022-04-20 23:33:40 +02:00
if ( ! tofree ) {
2022-04-30 00:37:59 +02:00
perror ( " calloc " ) ;
2022-04-20 23:33:40 +02:00
return - 1 ;
}
strncpy ( tofree , filelist , strnlen ( filelist , MAXARGLENGTH ) ) ;
char * token ;
char * string = tofree ;
if ( print ) {
printf ( " u - Rilascio la mutua esclusione sui seguenti file: \n " ) ;
fflush ( stdout ) ;
}
while ( ( token = strsep_gnu ( & string , " , " ) ) ! = NULL ) {
if ( print ! = 0 ) {
printf ( " %s [Esito: " , token ) ;
fflush ( stdout ) ;
}
if ( unlockFile ( token ) = = - 1 ) {
if ( print ! = 0 ) {
printf ( " errore " ) ;
perror ( " -u " ) ;
}
} else if ( print ! = 0 ) {
printf ( " ok " ) ;
}
if ( print ! = 0 ) {
printf ( " ] \n " ) ;
fflush ( stdout ) ;
}
}
free ( tofree ) ;
2022-04-17 19:22:22 +02:00
return 0 ;
}
int cmd_c ( char * filelist , int print ) {
2022-04-20 23:33:40 +02:00
if ( ! filelist ) {
errno = EINVAL ;
return - 1 ;
}
// we copy filelist because we are nice
2022-04-30 00:37:59 +02:00
char * tofree = calloc ( strnlen ( filelist , MAXARGLENGTH ) + 1 , sizeof ( char ) ) ;
2022-04-20 23:33:40 +02:00
if ( ! tofree ) {
2022-04-30 00:37:59 +02:00
perror ( " calloc " ) ;
2022-04-20 23:33:40 +02:00
return - 1 ;
}
strncpy ( tofree , filelist , strnlen ( filelist , MAXARGLENGTH ) ) ;
char * token ;
char * string = tofree ;
if ( print ) {
printf ( " c - Cancello i seguenti file dal server: \n " ) ;
fflush ( stdout ) ;
}
while ( ( token = strsep_gnu ( & string , " , " ) ) ! = NULL ) {
if ( print ! = 0 ) {
printf ( " %s [Esito: " , token ) ;
fflush ( stdout ) ;
}
if ( lockFile ( token ) = = - 1 ) {
if ( print ) {
printf ( " errore " ) ;
perror ( " -c " ) ;
}
} else {
if ( removeFile ( token ) = = - 1 ) {
if ( print ) {
printf ( " errore " ) ;
perror ( " -c " ) ;
}
} else if ( print ) {
printf ( " ok " ) ;
}
}
if ( print ! = 0 ) {
printf ( " ] \n " ) ;
fflush ( stdout ) ;
}
}
free ( tofree ) ;
2022-04-17 19:22:22 +02:00
return 0 ;
}