Azzurra IRC Network Forum

[c] compilazione tesina urgente!

soundsgood · 10/12/2005 13:19 · #1
ciao chiedo un aiuto urgente a tutti voi. è importante!
la tesina va consegnata lunedi!

devo compilare in linux una tesina di sistemi operativi e mi da errori innanzitutto sulla creazione dei thread. la specifica della tesina è la seguente:

creazione di una bacheca elettronica che permette ad un utente di
1 leggere tutti i messaggi nella bacheca
2 deposito di un un nuovo messaggio
3 rimozione di un qualsiasi messaggio

la comunicazione tra client e server deve sfruttare le code di messaggi inoltre vengono adoperati i semafori del sistema unix/linux

potete controllare a voi che errori da e darmi eventuali suggerimenti?
che versioni di linux consigliate per compilare? che supporti i thread ecc

se mi date il vostro indirizzo email vi invio i file client e server

intanto li posto qui

grazie davvero a chi mi aiuta. un saluto a tutti



CLIENT

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
#define TAGLIA 512
#define KEY_SERVER 40








//----------------------------------------------------------------------------------------------


typedef struct { // STRUTTURA CONTENENTE LA RICHIESTA INIZIALE
long mtype; // TIPO DI RICHIESTA
int canale_risposta;
long pid_client; // PID DEL CLIENT CHE EFFETTUA LA RICHIESTA
} ric_servizio;


//----------------------------------------------------------------------------------------------

typedef struct { // STRUTTURA CONTENENTE INFORMAZIONI DI UN MESSAGGIO CHE SERVE PER STAMPARE L'INDICE GENERALE DEI MESSAGGI
int mess_id; /* ID MESS = NUMERO CRESCENTE*/
char file_txt[20]; /* NOME DEL FILE CHE CONTIENE EFFETTIVAMENTE IL MESSAGGIO*/

char user[20]; /* CHI HA SCRITTO IL MESSAGGIO MAX 20 CARATTERI*/
char oggetto[100]; /* OGGETTO MAX 100 CARATTERI */

} indice;

//--------------------------------------------------------------------------------------------------

typedef struct { /* STRUTTURA CONTENENTE IL MESSAGGIO INVIATO DAL SERVER (DA LEGGERE) */

int mess_id; /* ID MESS = NUMERO CRESCENTE*/
char user[20]; /* CHI HA SCRITTO IL MESSAGGIO MAX 20 CARATTERI*/
char oggetto[100]; /* OGGETTO MAX 100 CARATTERI */
char messaggio[514]; // MESSAGGIO VERO E PROPRIO

} mes_leggere; /* MESSAGGIO DAL SERVER DA STAMPARE*/



//----------------------------------------------------------------------------------------------



typedef struct { // MESSAGGIO DA INVIARE AL SERVER
long mtype;

char user[20]; /* CHI HA SCRITTO IL MESSAGGIO MAX 20 CARATTERI*/
char oggetto[100]; /* OGGETTO MAX 100 CARATTERI */
char messaggio[512]; // MESSAGGIO SCRITTO VERO E PROPRIO
} mes_inviato;


//-----------------------------------------------------------------------------------------------


typedef struct { // STRUTTURA DI INVIO DELL'INDICE DI SELEZIONE
long mtype;
int canale_risposta;
int n_mess; // numero del messaggio selezionato
} ind_inviato;


//----------------------------------------------------------------------------------------------

typedef struct { // STRUTTURA PER ACCOGLIERE il numero di messaggi sul server
long mtype;
int num_mes // numero di messaggi in bacheca
} n_messaggi;

//----------------------------------------------------------------------------------------------

typedef struct { // STRUTTURA PER RICEVERE LA CONFERMA DI POTER INVIARE UN MESSAGGIO
long mtype;
} conf;

//----------------------------------------------------------------------------------------------

int id_coda_client, id_coda_server, ret, status;

long key;

ind_inviato indice_inviato;

conf conferma;

ric_servizio richiesta_servizio;

indice indice_ricevuto;

mes_inviato messaggio_inviato;

mes_leggere messaggio_leggere;

n_messaggi numero_messaggi;




//-----------------------------------------------------------------------------------------------

main(int argc, char *argv[]) {

// CREAZIONE CODA SERVER
id_coda_server = msgget(KEY_SERVER, IPC_CREAT | 0666);
if(id_coda_server == -1) {
printf("Errore nell’apertura della server queue \n");
exit(-1);
}


key = getpid(); // CHIAVE CODA CLIENT

// CREAZIONE CODA CLIENT
id_coda_client = msgget(key, IPC_CREAT | IPC_EXCL | 0666);
if(id_coda_client == -1) {
id_coda_client = msgget(key, IPC_CREAT | 0666);
ret = msgctl(id_coda_client, IPC_RMID, 0);
id_coda_client = msgget(key, IPC_CREAT | IPC_EXCL | 0666);
if ( id_coda_client == -1 ) {
printf("Errore nell’installazione della client queue");
exit(-1);
}
}








printf("********* Benvenuto nella Bacheca Elettronica! *********\n\n");




//----------------------------------------------------------------------------

do {

printf("\n \n \n \n
Selezionare l’operazione che si desidera: \n \n

1.Lettura di un messaggio \n
2.Deposito di un nuovo messaggio \n
3.Rimozione di un messaggio \n
4.Esci \n\n ");


scanf("%ld", richiesta_servizio.mtype);
richiesta_servizio.canale_risposta = id_coda_client;





// DISTINGUIAMO LE RICHIESTE

//-------------------------------------------------------------------------------------------------------------



if(richiesta_servizio.mtype == 1) {



if ( msgsnd(id_coda_Server, &richiesta_servizio, sizeof(ric), 0) == -1 ) {
printf("Errore nell’invio della richiesta al server");
exit(-1);
}



// RICEZIONE DEL NUMERO MESSAGGI RESIDENTI SULLA BACHECA DAL SERVER
if( msgrcv(id_coda_client, &numero_messaggi, TAGLIA, 0, 0) == -1) {
printf("Errore nella ricezione dell’indice dal server");
exit(-1);
}


if(numero_messaggi.num_mes) { // SE LA BACHECA CONTIENE ALMENO UN MESSAGGIO

// RICEZIONE E STAMPA DELL'INDICE GENERALE DEI MESSAGGI RESIDENTI SULLA BACHECA
int count = 0;
do {
if( msgrcv(id_coda_client, &indice_ricevuto, TAGLIA, 0, 0) == -1) {
printf("Errore nella ricezione dell’indice dal server");
exit(-1);
}
printf("Messaggio numero: %s, User: %s, Oggetto: %s, .\n" , indice_ricevuto.mes_id, indice_ricevuto.user, indice_ricevuto.oggetto);
cont++;
} while(count != numero_messaggi.num_mes);



printf("Selezionare il numero del messaggio che si desidera leggere\n");
scanf("%d", indice_inviato.n_mess);

while((indice_inviato.n_mess > indice_ricevuto.num_mes) || (indice_inviato.n_mess < 1)) {
printf("Errore nell'indice selezionato. Selezionare il numero corretto del messaggio che si desidera leggere\n");
scanf("%d", indice_inviato.n_mess);
}

indice_inviato.canale_risposta = id_coda_client;
indice_inviato.mtype = 11; // TIPO STABILITO PER LA FUNZIONE LEGGI

// INVIO DELL'INDICE DEL MESSAGGIO CHE SI VUOLE LEGGERE
if( msgsnd(id_coda_server, &indice_inviato, sizeof(indice_inviato), 0) == -1) {
printf("Errore nell’invio al server del numero del messaggio da leggere\n");
exit(-1);
}

//RICEZIONE DEL MESSAGGIO DA LEGGERE E STAMPA
if( msgrcv(id_coda_client, &messaggio_leggere, TAGLIA, 0 , 0) == -1 ) {
print("Errore nella ricezione del messaggio da leggere\n");
exit(-1);
}

printf("Messaggio numero: %s, User: %s, Oggetto: %s, \n\n Messaggio: %s \n\n", messaggio_leggere.mes_id, messaggio_leggere.user, messaggio_leggere.oggetto, messaggio_leggere.messaggio);

}



// SE NON CI SONO MESSAGGI IN BACHECA
else {
printf("Non ci sono messaggi nella bacheca\n");
}

}


//--------------------------------------------------------------------------------------------------------


if(richiesta_servizio.mtype == 2) {


if ( msgsnd(id_coda_Server, &richiesta_servizio, sizeof(ric), 0) == -1 ) {
printf("Errore nell’invio della richiesta al server");
exit(-1);
}

messaggio_inviato.mtype = 12; // TIPO STABILITO PER LA FUNZIONE SCRIVI

// fgets() http://www.lilik.it/~mirko/gapil/gapilsu107.html#x249-1390007.2.5 (http://www.lilik.it/~mirko/gapil/gapilsu107.html#x249-1390007.2.5)
// il numero di caratteri passato alla fgets() deve essere n-2 di quelli dichiarati perche vi va aggiunto il newline (\n) e lo zero)

printf("Digitare il nome del mittente del messaggio (max 20 caratteri)\n");
scanf("%s", messaggio_inviato.user);

printf("Digitare l'oggetto del messaggio (max 100 caratteri)\n");
scanf("%s", messaggio_inviato.oggetto);

printf("Digitare il messaggio (max 500 caratteri)\n");
scanf("%s" , messaggio_inviato.messaggio);


if( msgrcv(id_coda_client, &conferma, TAGLIA, 0 , 0) == -1 ) {
print("Errore nella ricezione della conferma di invio del messaggio\n");
exit(-1);
}


if( msgsnd(id_coda_server, &messaggio_inviato, sizeof(messaggio_inviato), 0) == -1) {
printf("Errore nell’invio al server del messaggio da scrivere in bacheca\n");
exit(-1);
}

printf("Messaggio correttamente inviato al server");
}

---------------------------------------------------------------------------------------------------------

if(richiesta_servizio.mtype == 3) {


if ( msgsnd(id_coda_Server, &richiesta_servizio, sizeof(ric), 0) == -1 ) {
printf("Errore nell’invio della richiesta al server");
exit(-1);
}



// RICEZIONE DEL NUMERO DI MESSAGGI IN BACHECA
if( msgrcv(id_coda_client, &numero_messaggi, TAGLIA, 0, 0) == -1) {
printf("Errore nella ricezione dell’indice dal server");
exit(-1);
}

if(numero_messaggi.num_mes) { // SE LA BACHECA CONTIENE ALMENO UN MESSAGGIO

// RICEZIONE DELL'INDICE
int count = 0;
do {
if( msgrcv(id_coda_client, &indice_ricevuto, TAGLIA, 0, 0) == -1) {
printf(“Errore nella ricezione dell’indice dal server”);
exit(-1);
}
printf("Messaggio numero: %s, User: %s, Oggetto: %s.\n" , indice_ricevuto.mes_id, indice_ricevuto.user, indice_ricevuto.oggetto);
cont++;

} while(count != numero_messaggi.num_mes);




printf("Selezionare il numero del messaggio che si desidera eliminare\n");
scanf("%d", indice_inviato.n_mess);

while((indice_inviato.n_mess > indice_ricevuto.num_mes) || (indice_inviato.n_mess < 1)) {
printf("Errore nell'indice selezionato. Selezionare il numero corretto del messaggio che si desidera eliminare\n");
scanf("%d", indice_inviato.n_mess);
}

indice_inviato.canale_risposta = id_coda_client;
indice_inviato.mtype = 13; // TIPO STABILITO PER LA FUNZIONE ELIMINA


if( msgsnd(id_coda_server, &indice_inviato, sizeof(indice_inviato), 0) == -1) {
printf("Errore nell’invio al server del numero del messaggio da eliminare\n");
exit(-1);
}

}


else {
printf("Non ci sono messaggi nella bacheca\n");
}
}

} while ( richiesta_servizio.type != 4);



ret = msgctl(id_coda_client, IPC_RMID, NULL);
if(ret==-1) printf("Errore nella chiamata msgctl\n");

printf("Grazie e arrivederci\n");
exit(0);

}







SERVER

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
#define Errore_(x) { puts(x); exit(1); }
#define KEY_SERVER 40
#define mainfile "mainfile"
#define key_sem1 50
#define key_sem2 51
#define num_client 10

int ds_sem1;
int ds_sem2;

typedef struct { //STRUTTURA CONTENENTE LA RICHIESTA INIZIALE
long mtype; // tipo di richiesta
int canale_risposta;
long pid_client;
} ric_servizio;

typedef struct {
long mtype; // STRUTTURA CONTENENTE L'INDICE DI UN MESSAGGIO. SERVE PER STAMPARE INDICE CHE CREA IL CLIENT TRAMITE CICLO WHILE
int mess_id; /* ID MESS = NUMERO CRESCENTE*/
char file_txt[20]; /* NOME DEL FILE CHE CONTIENE EFFETTIVAMENTE IL MESSAGGIO*/

char user[20]; /* CHI HA SCRITTO IL MESSAGGIO MAX 20 CARATTERI*/
char oggetto[100]; /* OGGETTO MAX 100 CARATTERI */
} indice;

typedef struct { /* STRUTTURA CONTENENTE IL MESSAGGIO INVIATO DAL SERVER (DA LEGGERE) */
long mtype;
int mess_id; /* ID MESS = NUMERO CRESCENTE*/
char user[20]; /* CHI HA SCRITTO IL MESSAGGIO MAX 20 CARATTERI*/
char oggetto[100]; /* OGGETTO MAX 100 CARATTERI */
char messaggio[512]; // MESSAGGIO VERO E PROPRIO

} mes_leggere; /*messaggio DA SERVER DA STAMPARE*/


typedef struct { // MESSAGGIO DA INVIARE AL SERVER
long mtype;

char user[20]; /* CHI HA SCRITTO IL MESSAGGIO MAX 20 CARATTERI*/
char oggetto[100]; /* OGGETTO MAX 100 CARATTERI */
char messaggio[512]; // MESSAGGIO SCRITTO VERO E PROPRIO
} mes_inviato;

typedef struct {
long mtype;
int n_mess;
} n_messaggi;

typedef struct {
long mtype; //struttura di conferma
} conf;

typedef struct { // STRUTTURA DI INVIO DELL'INDICE DI SELEZIONE
long mtype;
int canale_risposta;
int n_mess; // numero del messaggio selezionato
} ind_inviato;


//------------------------------------------------------------------------------







int leggi(long pid_client, int j){

// blocco semaforo 1 lettura (il primo che trova a 1 lo decrementa)
struct sembuf oper;





/* VARIABILI LOCALI */
char* nome;
char* buffer;
char* dimensione;
int ds_main, des, size, inviato, num, codice, coda_client;
int* punt;
ind_inviato cod; // struct definita dal client
int offset = 4;
indice msg_info;
mes_leggere msg;

int id_coda_server = msgget(KEY_SERVER, IPC_CREAT | 0666); //apre coda del sever
if(id_coda_server == -1) {
Errore_("Errore nell'apertura della coda di msg del server\n");
}

// ricezione indice di selezione del messaggio che si vuole leggere
ris = msgrcv(id_coda_server, &cod, sizeof(ind_inviato), pid_client, 0);
if(ris == -1){
printf("impossibile aprire la coda del server");
exit(1);
}

codice = cod.n_mess;
coda_client = cod.canale_risposta;

/* APRO IL FILE INDICE*/
ds_main = open(mainfile, O_RDONLY, 0660);
if(ds_main == -1){
printf("impossibile aprire il file indice");
exit(1);
}

// calcolo posizionamento file pointer
size = sizeof(indice);
int pos = cod.n_mess - 1;
offset = offset + (pos * size) + 1; //ora sappiamo dove andare a leggere nel file

ris = lseek(ds_main, offset, 0);//posizioniamo il file pointer sulla struttura giusta
if (ris == -1)
Errore_("Errore nel posizionamento del file pointer\n");

/*LEGGO IL NOME DEL FILE CHE CONTIENE IL MESSAGGIO*/
ris = read(ds_main, &msg_info, sizeof(indice));
if(ris == -1){
printf("impossibile leggere il nome del file del messaggio");
exit(3);
}

strcpy(nome, msg_info.file_txt);

/*APRO IL FILE DI TESTO*/
des = open(nome, O_RDONLY, 0660);
if(des == -1){
printf("impossibile aprire il messaggio");
exit(4);
}

char testo_msg[512];

/*LEGGO TUTTO IL FILE DEL TESTO E LO COPIO NELL'AREA DI MEMORIA PUNTATA DA punt*/
ris = read(des, &testo_msg, 512);
if(ris == -1){
printf("impossibile leggere il messaggio");
exit(6);
}

strcpy(msg.messaggio, testo_msg);
strcpy(msg.user, msg_info.user);
strcpy(msg.oggetto, msg_info.oggetto);
msg.mess_id = msg_info.mess_id;
msg.mtype = 9;

/*INVIO IL MESSAGGIO ALLA CODA DEL CLIENT */
inviato= msgsnd(coda_client, &msg, sizeof(mes_leggere),0);
if(ris == -1){
printf("impossibile inviare il messaggio");
exit(-1);
}


close(ds_main);
close(des);

//sblocco semaforo 1 lettura (incrementa di uno quello che aveva decrementato prima)
oper.sem_op = 1;
oper.sem_flg = 0;
oper.sem_num = j;
ris = semop ((int) ds_sem1, &oper, 1);
if (ris == -1)
Errore_("Errore nella chiamata semop sul semaforo 1\n");
}







//------------------------------------------------------------------------------









void * scrivi(void * richiesta) {

int ris;
struct sembuf oper;

ric_servizio ric_aux;
memcpy (&ric_aux, &richiesta, sizeof(ric_servizio));

// sblocco semaforo2 proteggeva da scritture la struttura richiesta di servizio nel main
oper.sem_op = 1;
oper.sem_num = 0;
oper.sem_flg = 0;
ris = semop ((int) ds_sem2, &oper, 1);
if (ris == -1)
Errore_("Errore nella chiamata semop sul semaforo 2\n");



indice messaggio;
int ds_nuovo, ds_file, rich_invio;
mes_inviato msg2write;
conf ok;
char user[20];
char oggetto[100];
char testo[512];
int testo_dim;
int n_mess;
int coda_client = ric_aux.canale_risposta;

ok.mtype= 9;
rich_invio= msgsnd(coda_client,&ok,sizeof(conf));
if(rich_invio==-1){
printf("impossibile inviare conferma al client");
exit(1);
}

int id_coda_server = msgget(KEY_SERVER, IPC_CREAT | 0666); //apre coda del sever
if(id_coda_server == -1) {
Errore_("Errore nell'apertura della coda di msg del server\n");
}

ris = msgrcv(id_coda_server, &msg2write, sizeof(mes_inviato),12, 0);
if(ris == -1){
printf("Errore nella chiamata msgrcv sulla coda server\n");
exit(1);
}


strcpy(user, msg2write.user);
strcpy(oggetto, msg2write.oggetto);
strcpy(testo, msg2write.messaggio);


//ciclo che blocca tutti i semafori in lettura e in eliminazione
oper.sem_op = -1;
oper.sem_flg = 0;
int i;
for (i=0; i<num_client; i++) {
oper.sem_num = i;
ris = semop ((int) ds_sem1, &oper, 1);
if (ris == -1)
Errore_("Errore nella chiamata semop sul semaforo 1\n");
}




// apertura e lettura numero messaggi presenti
int ds_main = open(mainfile, O_RDWR, 0660);
if (ds_main == -1)
Errore_("Errore nell'apertura del file\n");

ris = read(ds_main, &n_mess, 4);
if (ris == -1)
Errore_("Errore nella lettura del file\n");



char nome_mess[12];
int num = n_mess + 1;

// creazione nome del nuovo file
sprintf(nome_mess,"messaggio%d",num);

// creazione file contenente testo del messaggio ricevuto
ds_nuovo = open(nome_mess, O_WRONLY|O_TRUNC|O_CREAT, 0666);
if(ds_nuovo == -1){
printf("impossibile creare il file di testo");
exit(1);
}

/*SCRIVE IN QUESTO FILE IL TESTO char* testo PASSATO DAL SERVER*/
ris = write(ds_nuovo,testo,512);
if(ris == -1){
printf("impossibile scrivere il file di testo");
exit(1);
}

/* riempio LA STRUTTURA INDICE*/
messaggio.mess_id = num;
strcpy(messaggio.file_txt, nome_mess);
strcpy(messaggio.user, user);
strcpy(messaggio.oggetto, oggetto);

//posizioniamo il file pointer sul punto giusto
ris = lseek(ds_main, 0, 2);
if (ris == -1)
Errore_("Errore nel posizionamento del file pointer\n");

/*SCRIVO LA STRUTTURA NEL FILE*/
ris = write(ds_main, &messaggio, sizeof(indice));
if(ris == -1){
printf("impossibile scrivere nel file");
exit(1);
}


// riposizionamento del file pointer del file indice
ris = lseek(ds_main, 0, 0);
if (ris == -1)
Errore_("Errore nel posizionamento del file pointer\n");

//scrittura nuovo numero di messaggi
n_mess++;
ris = write(ds_main, &n_mess, 4);
if (ris == -1)
Errore_("Errore nella scrittura del file\n");

/*CHIUDO I FILE APERTI */
close(ds_nuovo); // file contenente il testo
close(ds_file); // file indice

//sblocco dei semafori
oper.sem_op = 1;
for (i=0; i<num_client; i++) {
oper.sem_num = i;
ris = semop ((int) ds_sem1, &oper, 1);
if (ris == -1)
Errore_("Errore nella chiamata semop sul semaforo 1\n");
}
}





//------------------------------------------------------------------------------









void * visualizza(void* richiesta) {

int ris;
struct sembuf oper;

ric_servizio ric_aux;
memcpy (&ric_aux, &richiesta, sizeof(ric_servizio));

// sblocco semaforo2 proteggeva da scritture la struttura richiesta di servizio nel main
oper.sem_op = 1;
oper.sem_num = 0;
oper.sem_flg = 0;
ris = semop ((int) ds_sem2, &oper, 1);
if (ris == -1)
Errore_("Errore nella chiamata semop sul semaforo 2\n");

// blocco semaforo 1 lettura (il primo che trova a 1 lo decrementa)
oper.sem_op = -1;
oper.sem_flg = IPC_NOWAIT;
int sbloccato = 0;
int j = 0;

while(!sbloccato) {
if(j == num_client)
j=0;
oper.sem_num = j;
ris = semop ((int) ds_sem1, &oper, 1);
if (ris == -1) {
j++;
}
else
sbloccato = 1;
}

// apertura file indice
int ds_main = open(mainfile, O_RDWR, 0660);
if (ds_main == -1)
Errore_("Errore nell'apertura del file\n");


indice msg_info;
int n_mess;

// lettura del numero di messaggi residenti in bacheca
ris = read(ds_main, &n_mess, 4);
if (ris == -1)
Errore_("Errore nella lettura del file\n");
n_messaggi num;
num.n_mess = n_mess;
num.mtype = 9;
int ds_coda = ric_aux.canale_risposta;

// invio del numero di messaggi
ris = msgsnd(ds_coda, &num, sizeof(n_messaggi), 0);
if (ris == -1)
Errore_("Errore nella chiamata della msgsnd\n");

int i = 0;

// invio delle strutture per creare indice al client
while (i<n_mess) {
memset(&msg_info,0,sizeof(indice));
msg_info.mtype = 9;
ris = read(ds_main, &msg_info, sizeof(indice));
if (ris == -1)
Errore_("Errore nella lettura del file\n");
ris = msgsnd(ds_coda, &msg_info, sizeof(indice), 0);
if (ris == -1)
Errore_("Errore nella chiamata della msgsnd\n");
i++;
}
// chiusura file indice
close(ds_main);

//sblocco semaforo 1 lettura (incrementa di uno quello che aveva decrementato prima)
oper.sem_op = 1;
oper.sem_flg = 0;
oper.sem_num = j;
ris = semop((int) ds_sem1, &oper, 1);
if (ris == -1)
Errore_("Errore nella chiamata semop sul semaforo 1\n");

long pid = ric_aux.pid_client;
long type = ric_aux.mtype;

if (n_mess > 0) {
if(type == 1)
leggi(pid);
else if (type == 3)
elimina(pid);
}

}




//------------------------------------------------------------------------------




int defrag(int ds_main) {

int ris;
indice msg;
int n_mess;
/*creo un file ausilario dove andrò a mettere solo le strutture 'piene' cioè quelle non cancellate*/

int ds_aux = open("auxfile", O_WRONLY|O_TRUNC|O_CREAT, 0666);
if (ris == -1)
Errore_("Errore nella creazione del file\n");

/*con questo ciclo while vado a copiare una per una le strutture 'piene' del file da riordinare nel file ausiliario*/

ris = read(ds_main, &n_mess, 4);
if (ris == -1)
Errore_("Errore nella lettura del file\n");

int n = n_mess -1;

// scrittura nel nuovo file main del numero di messaggi presenti
ris = write(ds_aux, &n, 4);
if (ris == -1)
Errore_("Errore nella scrittura del file\n");

int i = 1;
int trovato = 0:

// copia di tutte le strutture dal main file al file ausiliario
while(i<=n_mess){
i++;
memset(&msg,0,sizeof(indice));
ris = read(ds_main, &msg, sizeof(indice));
if (ris == -1)
Errore_("Errore nella lettura del file\n");
if(msg.mess_id == -1){
trovato = 1;
continue;
}
if(trovato)
msg.mess_id -= 1; // aggiornamento id
ris = write(ds_aux, &msg, sizeof(indice));
if (ris == -1)
Errore_("Errore nella scrittura del file\n");
}

/*adesso cancello il vecchio file main non ordinato */

ris = open(filename, O_TRUNC, 0666);
if (ris == -1)
Errore_("Errore nella modifica del file pointer\n");



// rinomina del file ausiliario in main file
ris = rename("auxfile", mainfile);
if (ris == -1)
Errore_("Errore nella modifica del file pointer\n");



return ds_aux;
}





//------------------------------------------------------------------------------





int elimina (void * pid_client, int j) {
ind_inviato indice_sel; //struttura che contiene l'indice del msg da cancellare
indice msg_info; //struttura che deve contenere info sul messaggio da eliminare
long offset = 4; //serve x trovare la struttura nel file di indici
int ris; //verifica il "ritorno" di alcune funzioni
int ds_main; //descrittore del file di indici
int ds_text; //serve x mettere il nome del file da cancellare
indice auxmsg; //struttura ausiliaria

struct sembuf oper;

//sblocco semaforo j
oper.sem_op = 1;
oper.sem_flg = 0;
oper.sem_num = j;

ris = semop ((int) ds_sem1, &oper, 1);
if (ris == -1)
Errore_("Errore nella chiamata semop sul semaforo 1\n");




int id_coda_server = msgget(KEY_SERVER, IPC_CREAT | 0666); //apre coda del sever
if(id_coda_server == -1) {
Errore_("Errore nell'apertura della coda di msg del server\n");
}

ris = msgrcv(id_coda_server, indice_sel, sizeof(ind_inviato), pid_client, 0);
if (ris == -1)
Errore_("Errore nella chiamata della msgrcv\n");


//ciclo che blocca tutti i semafori in lettura e in scrittura
oper.sem_op = -1;
oper.sem_flg = 0;
int i;
for (i=0; i<num_client; i++) {
oper.sem_num = i;
ris = semop ((int) ds_sem1, &oper, 1);
if (ris == -1)
Errore_("Errore nella chiamata semop sul semaforo 1\n");
}



ds_main = open(mainfile, O_RDWR, 0660);
if (ds_main == -1)
Errore_("Errore nell'apertura del file\n");

/*trova il file da cancellare nel 'file di indici'*/

int size = sizeof(indice);
int pos = indice_sel.n_mess - 1;
offset = offset + (pos * size) + 1; //ora sappiamo dove andare a leggere nel file

ris = lseek(ds_main, offset, 0);//posizioniamo il file pointer sulla struttura giusta
if (ris == -1)
Errore_("Errore nel posizionamento del file pointer\n");

ris = read(ds_main, &msg_info, sizeof(indice));//mettiamo info del file da eliminare in
if (ris == -1) //una struttura
Errore_("Errore nella lettura del file\n");

/*una volta trovato il file giusto, ne identifica il nome e lo cancella*/

ds_text = open(msg_info.file_txt, O_TRUNC, 0660);
if (ris == -1)
Errore_("Errore nell'eliminazione del file\n");

/*ora bisogna rimuovere la struttura dal 'file di indici'...*/


ris = lseek(ds_main, offset, 0); /*questa riposiziona l'indice di lett/scritt*/
if (ris == -1)
Errore_("Errore nella modifica del file pointer\n");


/*...per farlo copio una struttura vuota dello stesso tipo con campo mess_id uguale a
-1 che indica una posizione vuota*/

auxmsg.mess_id = -1;
ris = write(ds_main, &auxmsg, sizeof(indice));
if (ris == -1)
Errore_("Errore nell'aggiornamento del file\n");

ds_main = defrag(ds_main);

close(ds_main);







// sblocco dei semafori
oper.sem_op = 1;
for (i=0; i<num_client; i++) {
oper.sem_num = i;
ris = semop ((int) ds_sem1, &oper, 1);
if (ris == -1)
Errore_("Errore nella chiamata semop sul semaforo 1\n");
}

}




//------------------------------------------------------------------------------






int main(int argc, char *argv[]) {
typedef struct{ /*serve per passare i parametri della funzione al thread*/ int n_mess;
} param;
param par_eli;
ric_servizio richiesta;
int ris;
pthread_t tid;
long type; //tipo di richiesta
long chiave_msgserv = 40; //chiave per creare coda di msg del server...un numero a caso
long ds_msgserv; //descrittore coda di messaggi del server
int n_mess;
int ds_file;



ris = creat(mainfile, 0666); //crea il file di indici
if (ris == -1)
Errore_("Errore nella creazione del file di indici\n");






// semaforo per sincronizzazione tra lettori, scrittori ed eliminatori
int ds_sem1 = semget (key_sem1, num_client, IPC_CREAT | 0666);//crea l'array di semafori
if (ds_sem1 == -1)
Errore_("Errore nella creazione del semaforo 1\n");

int array[num_client];
int i;
for(i=0; i<num_client; i++)
array[i] = 1;

ris = semctl(ds_sem1, 0, SETALL, array);
if (ris == -1)
Errore_("Errore nell'inizializzazione del semaforo 1\n");






//il semaforo 2 serve per bloccare sovrascritture della struttura da passare alle funzioni
int ds_sem2 = semget(key_sem2, 1, IPC_CREAT | 0666);
if (ds_sem2 == -1)
Errore_("Errore nella creazione del semaforo 2\n");

ris = semctl(ds_sem2, 0, SETVAL, 1);
if (ris == -1)
Errore_("Errore nell'inizializzazione del semaforo 2\n");

struct sembuf oper;
oper.sem_op = -1;
oper.sem_num = 0;
oper.sem_flg = 0;



// creazione coda server
ds_msgserv = msgget(chiave_msgserv, IPC_CREAT|IPC_EXCL|0666);
if (ds_msgserv == -1) {
ds_msgserv = msgget(chiave_msgserv, IPC_CREAT|0666);
msgctl(ds_msgserv, IPC_RMID, NULL);
ds_msgserv = msgget(chiave_msgserv, IPC_CREAT|IPC_EXCL|0666);
if(ds_msgserv == -1) Errore_("Errore nella chiamata msgget");
}

while(1){

//attivazione di semaforo2 che blocca sovrascrittura di richiesta
ris = semop (ds_sem2, &oper, 1);
if (ris == -1)
Errore_("Errore nella chiamata della semop sul semaforo 2\n");



ris = msgrcv(ds_msgserv, &richiesta, sizeof(ric_servizio), -3, 0);
if (ris == -1)
Errore_("Errore nella chiamata della msgrcv\n");
type = richiesta.mtype;

if (type == 1 || type == 3) {
ris = pthread_create(&tid, NULL, visualizza,(void*) &richiesta);
if (ris != 0)
Errore_("Errore nella crezione del thread\n");
}
else if (type == 2) {
ris = pthread_create(&tid, NULL, scrivi, (void*) &richiesta);
if (ris != 0)
Errore_("Errore nella crezione del thread\n");
}
}
}