Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <errno.h>
- #include <string.h>
- #include <ctype.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <signal.h>
- #include "mmboxtypes.h"
- #include "mmboxfunction.h"
- #include "mmboxd.h"
- #include "load.h"
- int main(int argc, char *argv[]);
- void sighandler(int signal);
- int readInt();
- pid_t readPid();
- size_t readSize();
- char* readString();
- void writeInt(int num);
- void writePid(pid_t num);
- void writeChar(char c);
- void writeString(int num,char *str);
- void writeSize(size_t num);
- int to,from;
- struct flock *f;
- /*contiene la lista degli utenti*/
- user_t *userlist;
- /*contiene n, viene settato a y se la lista degli utenti è modificata*/
- char mod='n';
- int main(int argc, char *argv[]){
- /* installazione del segnale SIGTERM*/
- signal(SIGTERM, sighandler);
- /* creazione delle fifo*/
- umask(S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
- if ((mkfifo(FIFOTOMMBOX, FILE_MODE) < 0) && (errno != EEXIST)) {
- fprintf(stderr, "Errore creazione fifo.\n");
- exit(EXIT_FAILURE);
- }
- umask(S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
- if ((mkfifo(FIFOFROMMMBOX, FILE_MODE) < 0) && (errno != EEXIST)) {
- fprintf(stderr, "Errore creazione fifo.\n");
- exit(EXIT_FAILURE);
- }
- /* inizializzo la lista utenti*/
- userlist=openUsers();
- userlist->id=getppid();//assegno ad admin il pid di mmboxMan
- userlist->logged=1;
- userlist=openMsgs(userlist);
- /* vedere cosa devo farci*/
- f = malloc(sizeof(struct flock));
- if (f == NULL) {
- fprintf(stderr, "Errore allocazione di memoria\n");
- exit(EXIT_FAILURE);
- }
- memset(f, 0, sizeof(struct flock));
- /* variabili usate nel while*/
- user_t *list;//lista di appoggio
- int cmd; //comando
- pid_t id;//identificatore
- char *username;
- char *password;
- char *obj;
- void *buf;
- pid_t res; //risultato del comando, è il primo valore che viene spedito
- int number;
- mail_t *msgs;
- user_t *user;
- int m=0;//usato in rcv
- /* ciclo infinito fino al segnale sigterm*/
- while(1){
- list=userlist;
- /*apertura delle fifo*/
- to=open(FIFOTOMMBOX,O_RDWR);
- from=open(FIFOFROMMMBOX,O_WRONLY);
- if(to<0 || from<0) {
- unlink(FIFOFROMMMBOX);
- unlink(FIFOTOMMBOX);
- exit(EXIT_FAILURE);
- }
- cmd=readInt();
- id=readPid();
- switch(cmd){
- case CONNECT:
- /*sulla fifo devono essere spedit:
- -comando
- -pid
- -dim username
- -username
- */
- username=readString();
- res=connect(list,username,id);
- /*scrivo il risultato sulla fifo, il risultato è 0 se non è stato possibile connettersi, altrimenti è un identivicativo*/
- writePid(res);
- if(username!=NULL)free(username);
- break;
- case LOGIN:
- /*sulla fifo devono essere spediti:d
- -comando
- -pid
- -dim password
- -password*/
- password=readString();
- list=login(list,password,id);
- if(list==NULL) writePid(0);//non è stato possibile effettuare la login
- else writePid(list->id);//scrive l'id se è stato possibile effettuare il login
- if(password!=NULL)free(password);
- break;
- case QUIT:
- /*sulla fifo devono essere spediti:
- -comando
- -pid*/
- list=searchId(list,id);
- list=closedMsgs(list);
- list->logged--;//assumo che solo chi ha fatto login può chiamare quit
- if(list->logged==0) list->id=0;
- break;
- //non scrivo niente sulla fifo
- case STAT_CLIENT:
- /*sulla fifo devono essere spediti:
- -comando
- -pid*/
- list=searchId(list,id);
- if(list==NULL){
- /*questa configuarazione indica che non è stato trovato il pid come loggato,
- non dovrebbe mai avvenire per controlli di mmbox*/
- writeInt(0); //free_space
- writeInt(0); //used_space
- writeInt(0); //message number
- writeInt(0); //dim username
- }
- else{
- writeInt((list->quota)-(list->used_space));//free_space
- writeInt(list->used_space);//used_space
- writeInt(list->msg_n); //number of messages
- writeString(strlen(list->username),list->username);//dimensione e username
- }
- break;
- case LIST:
- /*ritorna tutti i messaggi della mailbox srive uso lo 0 come valore sentinella*/
- /*leggo dalla fifo:
- -comando
- -identificativo
- */
- msgs=searchMailsetI(list,id);
- list=userlist;
- if(msgs==NULL) {
- list=openMsgs(list);
- msgs=list->mailset;
- }
- /*scrivo sulla fifo le seguenti cose:*/
- while(msgs!=NULL){
- writeString(strlen(msgs->sender),msgs->sender);//sender
- //recipient è sempre lo stesso
- writeString(strlen(msgs->obj),msgs->obj);//object
- writeString(strlen(msgs->date),msgs->date);//date
- writeChar(msgs->r); //flag letto
- writeChar(msgs->m); //flag marcato
- writeSize(msgs->dim);//size
- msgs=msgs->next;
- }
- writeInt(0); //valore sentinella, indica che sono terminati i messaggi
- break;
- case SEND:
- /*sulla fifo devono essere spediti:
- -comando
- -pid
- -dest(dim)
- -obj(dim)
- -dim msg
- -msg*/
- username=readString(); //dest
- obj=readString(); //object
- size_t size;
- size=readSize();
- int r,again;
- buf=NULL;/////
- buf=malloc(size);////////////
- if(buf==NULL) exit(EXIT_FAILURE);
- do {
- r = read(to,buf,size);
- again = (r < 0 && errno == EINTR);
- } while (again); //msg
- msgs=send(list,username,obj,buf,size,id);
- /*viene scritto 0 in caso di successo 1 altrimenti*/
- if(msgs==NULL) writeInt(1);
- else{
- /*in questo caso la send è andata a buon fine*/
- writeInt(0);
- list=userlist;
- list=searchUsername(list,username);
- list->mailset=msgs;
- list->mailset_changed='y';//TODO ridondante (lo stesso c'è anche nella send di mmboxfunction)
- }
- if(obj!=NULL) free(obj);
- break;
- case RCV:
- /*sulla fifo devono essere spediti:
- -pid
- -comando
- -id msg
- -size*/
- number=readInt();
- size_t s;
- s=readSize();//dal manager mando 0
- if(s==0)m=1;
- list=searchId(list,id);
- list->mailset_changed='y';
- if(list->logged==0 && list->mailset==NULL)list=openMsgs(list);
- buf=receive(list,id,number,buf,s);
- /*sulla fifo viene spedito 0 + buf se l'operazione è andata a buon fine altrimenti viene spedito 1*/
- if(buf!=NULL){
- writeInt(0);
- int w,again=0;
- if(m==1) {
- msgs=searchMsgId(list->mailset,number);
- writeSize(msgs->dim);
- s=msgs->dim;
- }
- do {
- w = write(from,buf,s);
- again = (w < 0 && errno == EINTR);
- } while (again);
- break;
- }
- else{
- writeInt(1);
- }
- break;
- case DELETE:
- /*sulla fifo devono essere spediti:
- -pid
- -comando
- -id msg*/
- number=readInt();
- number=delete(list,id,number);
- writeInt(number);
- if (number==0) {
- list=searchId(list,id);
- list->mailset_changed='y';
- }
- break;
- case RESUME:
- /*sulla fifo devono essere spediti:
- -pid
- -comando
- -id msg*/
- number=readInt();
- number=resume(list,id,number);
- if(number>0)writeInt(0);
- else writeInt(1);
- break;
- case STAT_MANAGER:
- /*se è specificato l'username lo leggo*/
- /*sulla fifo devono essere spediti
- -pid
- -comando
- -username(*)*/
- username=readString();
- while(list!=NULL){
- /*sulla fifo scrivo utente e relativa quota se l'username è uguale a quello in considerazione spedisco anche used space*/
- writeString(strlen(list->username),list->username);
- writeInt(list->quota);
- if(username!=NULL && strcmp(username,list->username)==0){
- if(list->mailset==NULL) {
- user=openMsgs(list);
- list=user;
- }
- writeInt(list->used_space);
- writeInt(list->quota-list->used_space);
- }
- list=list->next;
- }
- writeInt(0);
- if(username!=NULL)free(username);
- break;
- case ADDUSER:
- /*sulla fifo devono essere spediti
- -pid
- -comando
- -username*/
- username=readString();
- list=addUser(list,username);
- /*vuol dire che l'add è andata a buon fine*/
- if(list!=NULL) {
- userlist=list;
- writeInt(0); //scriviamo che l'operazione è andata a buon fine
- }
- else{
- writeInt(1); //scriviamo che l'operazione non è andata a buon fine
- }
- if(username!=NULL)free(username);
- mod='y';
- break;
- case PASSWD:
- /*sulla fifo devono essere spediti
- -pid
- -comando
- -username
- -password*/
- username=readString();//username
- buf=readString();//password
- list=addPassword(list,username,buf);
- if(list!=NULL) {
- userlist=list;
- writeInt(0); //scriviamo che l'operazione è andata a buon fine
- }
- else{
- writeInt(1); //scriviamo che l'operazione non è andata a buon fine
- }
- if(username != NULL) free(username);
- mod='y';
- break;
- case DELUSER:
- /*sulla fifo devono essere spediti
- -pid
- -comando
- -username*/
- username=readString();
- list=deleteUser(list,username);
- if(list!=NULL) {
- userlist=list;
- writeInt(0); //scriviamo che l'operazione è andata a buon fine
- }
- else{
- writeInt(1); //scriviamo che l'operazione non è andata a buon fine
- }
- if(username != NULL) free(username);
- mod='y';
- break;
- case QMOD:
- /*sulla fifo devono essere spediti
- -pid
- -comando
- -username
- -newsize*/
- username=readString();
- number=readInt();//newsize
- writeInt(qmod(list,username,number));
- mod='y';
- break;
- }//fine switch
- /* chiusura delle fifo*/
- if(close(to)<0 || close(from)){
- unlink(FIFOFROMMMBOX);
- unlink(FIFOTOMMBOX);
- exit(EXIT_FAILURE);
- }
- } //FINE CICLO WHILE
- } //END
- /*legge un intero dalla fifo*/
- int readInt(){
- int num,again=0,r;
- do {
- r = read(to, &num, sizeof(int));
- again = (r < 0 && errno == EINTR);
- } while (again);
- if (r < 0) {
- close(to);
- close(from);
- unlink(FIFOTOMMBOX);
- unlink(FIFOFROMMMBOX);
- exit(EXIT_FAILURE);
- }
- return num;
- }
- /*legge un numero di tipo pid dalla fifo*/
- pid_t readPid(){
- pid_t pid;
- int again=0,r;
- do {
- r = read(to, &pid, sizeof(pid_t));
- again = (r < 0 && errno == EINTR);
- }
- while (again);
- if (r < 0) {
- close(to);
- close(from);
- unlink(FIFOTOMMBOX);
- unlink(FIFOFROMMMBOX);
- exit(EXIT_FAILURE);
- }
- return pid;
- }
- /*legge un intero di tipo size_t*/
- size_t readSize(){
- size_t size;
- int again=0,r;
- do {
- r = read(to, &size, sizeof(size_t));
- again = (r < 0 && errno == EINTR);
- } while (again);
- if (r < 0) {
- close(to);
- close(from);
- unlink(FIFOTOMMBOX);
- unlink(FIFOFROMMMBOX);
- exit(EXIT_FAILURE);
- }
- return size;
- }
- /*legge una stringa dalla fifo (prima legge la dimensione poi la stringa)*/
- char* readString(){
- int again=0,r,size;
- size=readInt();
- if(size==0) return NULL;
- char *str;
- str=(char*)malloc(size*sizeof(char)+1);
- if(str==NULL) {
- exit(EXIT_FAILURE);
- }
- do {
- r = read(to, str, size*sizeof(char));
- again = (r < 0 && errno == EINTR);
- } while (again);
- if (r < 0) {
- close(to);
- close(from);
- unlink(FIFOTOMMBOX);
- unlink(FIFOFROMMMBOX);
- exit(EXIT_FAILURE);
- }
- str[size]='\0';
- return str;
- }
- /*scrive un intero sulla fifo*/
- void writeInt(int num){
- int again=0,w;
- do {
- w = write(from,&num, sizeof(int));
- again = (w < 0 && errno == EINTR);
- } while (again);
- if (w < 0) {
- close(to);
- close(from);
- unlink(FIFOTOMMBOX);
- unlink(FIFOFROMMMBOX);
- exit(EXIT_FAILURE);
- }
- }
- /*scrive un pid sulla fifo*/
- void writePid(pid_t num){
- int again=0,w;
- do {
- w = write(from,&num, sizeof(pid_t));
- again = (w < 0 && errno == EINTR);
- } while (again);
- if (w < 0) {
- close(to);
- close(from);
- unlink(FIFOTOMMBOX);
- unlink(FIFOFROMMMBOX);
- exit(EXIT_FAILURE);
- }
- }
- /*scrive un elemento di tipo size_t*/
- void writeSize(size_t num){
- int again=0,w;
- do {
- w = write(from,&num, sizeof(size_t));
- again = (w < 0 && errno == EINTR);
- } while (again);
- if (w < 0) {
- close(to);
- close(from);
- unlink(FIFOTOMMBOX);
- unlink(FIFOFROMMMBOX);
- exit(EXIT_FAILURE);
- }
- }
- /*scrive un char*/
- void writeChar(char c){
- int again=0,w;
- do {
- w = write(from,&c, sizeof(char));
- again = (w < 0 && errno == EINTR);
- } while (again);
- if (w < 0) {
- close(to);
- close(from);
- unlink(FIFOTOMMBOX);
- unlink(FIFOFROMMMBOX);
- exit(EXIT_FAILURE);
- }
- }
- /* scrive una stringa*/
- void writeString(int num,char *str){
- int again=0,w;
- writeInt(num);
- do {
- w = write(from,str, num*sizeof(char));
- again = (w < 0 && errno == EINTR);
- } while (again);
- if (w < 0) {
- close(to);
- close(from);
- unlink(FIFOTOMMBOX);
- unlink(FIFOFROMMMBOX);
- exit(EXIT_FAILURE);
- }
- }
- void sighandler(int signal) {
- if (signal == SIGTERM){
- /* if (f != NULL) {*/
- /* free(f);*/
- /* f = NULL;*/
- /* }*/
- user_t *user;
- user=userlist;
- while(user!=NULL){
- user=closedMsgs(user);
- user=user->next;
- }
- if(mod=='y')
- closedUsers(userlist);
- close(to);
- close(from);
- unlink(FIFOTOMMBOX);
- unlink(FIFOFROMMMBOX);
- exit(EXIT_SUCCESS);
- }
- }
Add Comment
Please, Sign In to add comment