Le applicazioni client e server condividono un certo numero di subroutine che ho raccolto in questo file:
Da notare che per le subroutine di trasmissione dei dati sono state aggiunte alcune linee di codice per verificare, in fase di testing, l'effettivo numero di byte trasmessi e/o ricevuti.Questa funzione è invocata autonomamente dalla funzione
scandir()
ed è utilizzata per scegliere quali file
includere nella lista che scandir()
sta costruendo.
Come richiesto dal testo modificato dell'applicazione, con questa funzione è possibile ignorare tutti i file che non rientrino nella categoria dei "file regolari" o in quella delle "directory", oltre alle directory speciali "." e "..".
Poiché la struttura passata come argomento è di tipo
"direct" ("dirent" nelle librerie non-BSD), si sarebbe
potuto utilizzare il campo "d_type" di tale struttura. Purtroppo,
però, sulla mia Linux-box il campo risulta sempre vuoto. È
stato necessario, allora, ricorrere ancora una volta alla funzione
stat()
.
#include <stdio.h> #include <unistd.h> #include <sys/stat.h> #include <sys/dir.h> /* * This file collects the common functions * shared by server's and client's programs. */ #include "defs.h" #define DEBUG extern const char *PRGNAME; int select_dir(struct direct *dir) { struct stat file; /* * Selecting function for scandir(). * Only regular files and dir are allowed. */ if (stat(dir->d_name, &file) == -1) { perror("stating in select_dir"); return FALSE; } if (S_ISDIR(file.st_mode)) { if (strcmp(dir->d_name, ".") != 0 && strcmp(dir->d_name, "..") != 0) return TRUE; } if (S_ISREG(file.st_mode)) return TRUE; return FALSE; }
Questa subroutine è stata messa qui allo scopo di alleggerire il
codice principale. Il suo scopo, infatti, è semplicemente quello di
leggere count
byte dal socket sock
e riporli nel
buffer msg
, considerando tutti gli eventuali messaggi d'errore
e prestando particolare attenzione all'eventualità che la
quantità di dati da ricevere sia inferiore alla dimensione del
buffer.
int readmsg(const int sock, char *msg, const size_t count) { int rval; /* * Reads a message msg of count byte from socket sock * and prints it on stdout if DEBUG is enabled. */ #ifdef DEBUG printf("%s: Rcvd:", PRGNAME); #endif while ((rval = read(sock, msg, count)) <= 0) if ((rval = read(sock, msg, count)) == -1) perror("reading message from socket"); #ifdef DEBUG printf(" %-15s (%3u bytes)\n", msg, rval); #endif return rval; }
Questa subroutine è stata messa qui allo scopo di alleggerire il
codice principale. Il suo scopo, infatti, è semplicemente quello di
scrivere count
byte sul socket sock
e prendendoli
dal buffer msg
, considerando tutti gli eventuali messaggi
d'errore e prestando particolare attenzione all'eventualità che la
quantità di dati da trasmettere sia inferiore alla dimensione del
buffer.
int writemsg(const int sock, const char *msg, const size_t count) { int rval; /* * Writes message msg of count byte from socket sock * and prints it on stdout if DEBUG is enabled. */ #ifdef DEBUG printf("%s: Send:", PRGNAME); #endif if ((rval = write(sock, msg, count)) == -1) perror("writing message to socket"); #ifdef DEBUG printf(" %-15s (%3u bytes)\n", msg, rval); #endif return rval; }
Anche questa subroutine è stata messa qui allo scopo di
alleggerire il codice principale. Il suo scopo consiste nel leggere una
struttura di tipo "stat
" contenente, fra le altre cose, le
informazioni sul tempo dell'ultimo accesso e dell'ultima modifica.
int readstat(const int sock, struct stat *filestat) { int rval; /* * Reads stat informations from socket sock * and prints a log message on stdout if DEBUG is enabled. */ #ifdef DEBUG printf("%s: Rcvd:", PRGNAME); #endif if ((rval = read(sock, filestat, sizeof(*filestat))) == -1) { perror("receiving file stat"); exit(3); } #ifdef DEBUG printf(" %-15s (%3u bytes)\n", "File stat", rval); #endif return rval; }
È la controparte in scrittura della subroutine precedente.
int writestat(const int sock, const struct stat *filestat) { int rval; /* * Writes stat informations to socket sock * and prints a log message on stdout if DEBUG is enabled. */ #ifdef DEBUG printf("%s: Send:", PRGNAME); #endif if ((rval = write(sock, filestat, sizeof(*filestat))) == -1) { perror("Sending file stat"); exit(3); } #ifdef DEBUG printf(" %-15s (%3u bytes)\n", "File stat", rval); sleep(2); #endif return rval; }