940 lines
20 KiB
C
940 lines
20 KiB
C
#define _POSIX_C_SOURCE 200809L
|
|
|
|
#include <ctype.h>
|
|
#include <errno.h>
|
|
#include <fts.h>
|
|
#include <signal.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <time.h>
|
|
#include <unistd.h>
|
|
|
|
#include <api.h>
|
|
#include <strsep_gnu.h>
|
|
|
|
#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);
|
|
// esegue tutti i comandi nella lista
|
|
int execute(cmd_t *l, int print);
|
|
|
|
// per chiudere la connessione prima dell'uscita
|
|
void cleanup() {
|
|
if (strncmp(globalSocket, "", 2) != 0) {
|
|
closeConnection(globalSocket);
|
|
strncpy(globalSocket, "", 2);
|
|
}
|
|
}
|
|
// compare files
|
|
int compare(const FTSENT ** first, const FTSENT ** second) {
|
|
return (strcmp((*first)->fts_name, (*second)->fts_name));
|
|
}
|
|
|
|
// -h
|
|
static void usage(const char *argv0) {
|
|
// TODO change this
|
|
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");
|
|
}
|
|
// -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);
|
|
// -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);
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// 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;
|
|
|
|
int opt = 0;
|
|
char args[MAXARGLENGTH];
|
|
|
|
int print = 0;
|
|
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);
|
|
addCommand(&cmds, opt, args);
|
|
++f;
|
|
}
|
|
break;
|
|
case 'p': // print to stdout
|
|
printInfo(1, stdout);
|
|
++print;
|
|
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;
|
|
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;
|
|
}
|
|
}
|
|
|
|
if(execute(cmds, print) < 0) {
|
|
perror("execute");
|
|
goto _cleanup;
|
|
}
|
|
|
|
if(cmds) {
|
|
destroyCommandList(cmds);
|
|
}
|
|
|
|
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;
|
|
|
|
free(tmp->arg);
|
|
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;
|
|
}
|
|
|
|
cmd_t *tail = *l;
|
|
while (tail->next) {
|
|
tail = tail->next;
|
|
}
|
|
|
|
tail->next = new;
|
|
return 0;
|
|
}
|
|
|
|
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)
|
|
fprintf(stdout, "t - Tempo fra due richieste: %ld ms\tEsito: ok\n", num);
|
|
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
tmp = tmp->next;
|
|
}
|
|
|
|
fflush(stdout);
|
|
|
|
// 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) {
|
|
fprintf(stdout, "f - Connessione al socket: %s\tEsito: ", globalSocket);
|
|
if(ok)
|
|
printf("ok\n");
|
|
if(!ok)
|
|
printf("errore\n");
|
|
}
|
|
if(!ok) {
|
|
closeConnection(tmp->arg);
|
|
return 0; // no socket to connect, nothing to do
|
|
}
|
|
// we only read the first -f, no error reported if more than one is
|
|
// specified
|
|
tmp = NULL;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
if(tmp)
|
|
tmp = tmp->next;
|
|
}
|
|
fflush(stdout);
|
|
|
|
// 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) {
|
|
fprintf(stdout, "\nError: -D has no -w or -W matching after\n");
|
|
return 0;
|
|
}
|
|
unmachedD = 1;
|
|
break;
|
|
case 'w':
|
|
case 'W':
|
|
unmachedD = 0;
|
|
break;
|
|
case 'd':
|
|
if(unmachedd) {
|
|
fprintf(stdout, "\nError: -d has no -r or -R matching after\n");
|
|
return 0;
|
|
}
|
|
unmachedd = 1;
|
|
break;
|
|
case 'r':
|
|
case 'R':
|
|
unmachedd = 0;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
tmp = tmp->next;
|
|
}
|
|
if(unmachedD) {
|
|
fprintf(stdout, "\nError: -D has no -w or -W matching after\n");
|
|
return 0;
|
|
}
|
|
if(unmachedd) {
|
|
fprintf(stdout, "\nError: -d has no -r or -R matching after\n");
|
|
return 0;
|
|
}
|
|
fflush(stdout);
|
|
|
|
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);
|
|
Dir = calloc(strnlen(tmp->arg, MAXARGLENGTH)+1, sizeof(char));
|
|
strncpy(Dir, tmp->arg, strnlen(tmp->arg, MAXARGLENGTH));
|
|
|
|
if (setDirectory(Dir, 1) == -1) {
|
|
if(print)
|
|
perror("-D");
|
|
}
|
|
if (print)
|
|
printf("\nD - Cartella per le scritture: %s\tEsito: ok\n", Dir);
|
|
break;
|
|
case 'r':
|
|
cmd_r(tmp->arg, dir, print);
|
|
break;
|
|
case 'R':
|
|
cmd_R(tmp->arg, dir, print);
|
|
break;
|
|
case 'd':
|
|
if(dir)
|
|
free(dir);
|
|
dir = calloc(strnlen(tmp->arg, MAXARGLENGTH)+1, sizeof(char));
|
|
strncpy(dir, tmp->arg, strnlen(tmp->arg, MAXARGLENGTH));
|
|
|
|
if(setDirectory(dir, 0) == -1) {
|
|
if(print)
|
|
perror("-d");
|
|
}
|
|
if(print)
|
|
printf("\nd - Cartella per le letture: %s\tEsito: ok\n", dir);
|
|
break;
|
|
case 'l':
|
|
cmd_l(tmp->arg, print);
|
|
break;
|
|
case 'u':
|
|
cmd_u(tmp->arg, print);
|
|
break;
|
|
case 'c':
|
|
cmd_c(tmp->arg, print);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
// maybe better: while(nanosleep(&interval, &interval));
|
|
nanosleep(&interval, NULL);
|
|
tmp = tmp->next;
|
|
}
|
|
|
|
if(print)
|
|
printf("\n");
|
|
|
|
if(dir)
|
|
free(dir);
|
|
|
|
if(Dir)
|
|
free(Dir);
|
|
|
|
cleanup();
|
|
|
|
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) {
|
|
if(!dirname) {
|
|
errno = EINVAL;
|
|
return -1;
|
|
}
|
|
int num;
|
|
|
|
// we copy dirname because we are nice
|
|
char *tofree = calloc(strnlen(dirname, MAXARGLENGTH)+1, sizeof(char));
|
|
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) {
|
|
printf("\nw - Scrivo i seguenti file sul server: \n");
|
|
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);
|
|
|
|
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
|
|
char *tmp = malloc(child->fts_namelen + child->fts_pathlen + 2);
|
|
snprintf(tmp, child->fts_namelen + child->fts_pathlen + 2, "%s/%s", child->fts_path, child->fts_name);
|
|
|
|
if(print) {
|
|
printf("%s [", tmp);
|
|
}
|
|
|
|
// we send the file with the other function but set print to
|
|
// 0 since we do the printing before
|
|
int r = cmd_W(tmp, Dir, 0);
|
|
|
|
if(print && !r) {
|
|
printf("Esito: ok");
|
|
} else if (print && r) {
|
|
printf("Esito: errore");
|
|
}
|
|
|
|
if(print) {
|
|
printf("]\n");
|
|
}
|
|
|
|
free(tmp);
|
|
--num;
|
|
}
|
|
child = child->fts_link;
|
|
}
|
|
}
|
|
fts_close(fhandle);
|
|
}
|
|
free(tofree);
|
|
return 0;
|
|
}
|
|
|
|
int cmd_W(char *filelist, char *Dir, int print) {
|
|
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;
|
|
}
|
|
memset(tofree, 0, strnlen(filelist, MAXARGLENGTH)+1);
|
|
strncpy(tofree, filelist, strnlen(filelist, MAXARGLENGTH)+1);
|
|
|
|
char *token = NULL;
|
|
char *string = tofree;
|
|
|
|
if (print == 1) {
|
|
printf("W - Scrivo i seguenti file sul server: \n");
|
|
fflush(stdout);
|
|
}
|
|
|
|
int r = 0;
|
|
while ((token = strsep_gnu(&string, ",")) != NULL) {
|
|
int ok = 1;
|
|
int opened = 0;
|
|
if (print == 1) {
|
|
printf("%s [", token);
|
|
fflush(stdout);
|
|
}
|
|
|
|
// creo il file in modalita' locked
|
|
if (openFile(token, O_CREATE | O_LOCK) == -1) {
|
|
ok = 0;
|
|
} else { // creato con successo
|
|
opened = 1;
|
|
}
|
|
|
|
if (opened && (writeFile(token, Dir) == -1)) {
|
|
ok = 0;
|
|
}
|
|
|
|
if (opened && !ok) { // errore precedente -> elimino il file vuoto
|
|
removeFile(token);
|
|
} else if (opened && (closeFile(token) == -1)) { // chiudo il file
|
|
ok = 0;
|
|
}
|
|
|
|
if (print != 0) {
|
|
printf("Esito: ");
|
|
|
|
if (ok)
|
|
printf("ok");
|
|
else {
|
|
printf("errore");
|
|
perror("-w");
|
|
}
|
|
|
|
printf("]\n");
|
|
fflush(stdout);
|
|
}
|
|
if(!ok)
|
|
r = -1;
|
|
}
|
|
|
|
free(tofree);
|
|
return r;
|
|
}
|
|
|
|
int cmd_r(char *filelist, char *dir, int print) {
|
|
if (!filelist) {
|
|
errno = EINVAL;
|
|
return -1;
|
|
}
|
|
|
|
// we copy filelist because we are nice
|
|
char *tofree = malloc(strnlen(filelist, MAXARGLENGTH)+1);
|
|
memset(tofree, 0, strnlen(filelist, MAXARGLENGTH)+1);
|
|
if(!tofree) {
|
|
perror("malloc");
|
|
return -1;
|
|
}
|
|
strncpy(tofree, filelist, strnlen(filelist, MAXARGLENGTH));
|
|
|
|
char *token = NULL;
|
|
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;
|
|
|
|
printInfo(0, stdout);
|
|
// read the content of the file
|
|
if (ok && readFile(token, &buf, &size) == -1) {
|
|
fprintf(stdout, "\nreadFile\n");
|
|
fflush(stdout);
|
|
ok = 0;
|
|
}
|
|
if (print) {
|
|
printInfo(1, stdout);
|
|
}
|
|
if (ok && print) {
|
|
printf("Dimensione: %zu B\t", size);
|
|
fflush(stdout);
|
|
}
|
|
if (buf) {
|
|
free(buf);
|
|
}
|
|
|
|
// close the file
|
|
if (opened && closeFile(token) == -1) {
|
|
fprintf(stdout, "\ncloseFile\n");
|
|
fflush(stdout);
|
|
ok = 0;
|
|
}
|
|
if (print) {
|
|
printf("[Esito: ");
|
|
|
|
if (ok) {
|
|
printf("ok");
|
|
} else {
|
|
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);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int cmd_R(char *numStr, char *dir, int print) {
|
|
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;
|
|
|
|
// we copy numStr because we are nice
|
|
char *tofree = malloc(strnlen(numStr, MAXARGLENGTH)+1);
|
|
if(!tofree) {
|
|
perror("malloc");
|
|
return -1;
|
|
}
|
|
strncpy(tofree, numStr, strnlen(numStr, MAXARGLENGTH));
|
|
|
|
char *secondArg = tofree;
|
|
strsep_gnu(&secondArg, ",");
|
|
|
|
if (!secondArg) {
|
|
n = -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;
|
|
}
|
|
}
|
|
n = (int) strtol(number, NULL, 10);
|
|
n = (n==0)?-1:n;
|
|
} else {
|
|
free(tofree);
|
|
errno = EINVAL;
|
|
return -1;
|
|
}
|
|
|
|
free(tofree);
|
|
|
|
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");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int cmd_l(char *filelist, int print) {
|
|
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;
|
|
}
|
|
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);
|
|
return 0;
|
|
}
|
|
|
|
int cmd_u(char *filelist, int print) {
|
|
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;
|
|
}
|
|
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);
|
|
return 0;
|
|
}
|
|
|
|
int cmd_c(char *filelist, int print) {
|
|
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;
|
|
}
|
|
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);
|
|
return 0;
|
|
}
|