lcscom.c

Vai alla documentazione di questo file.
00001 
00012 #include <sys/types.h>
00013 #include <sys/socket.h>
00014 #include <sys/un.h>      /* indirizzo AF_UNIX */
00015 
00016 #include "Include/common.h"
00017 #include "Include/lcscom.h"
00018 
00019 /* Crea un channel di ascolto AF_UNIX */
00020 serverChannel_t createServerChannel(const char* path){
00021         serverChannel_t server_sk;
00022         struct sockaddr_un servaddr;     /* address of server */
00023     
00024         /* Creo il socket */
00025         if ((server_sk = socket(AF_UNIX,SOCK_STREAM,0)) < 0){
00026                 errore(__FILE__,__LINE__,"Server: socket create",errno);
00027                 return -1;
00028         }
00029         if (strlen(path) > UNIX_PATH_MAX){
00030                 errore(__FILE__,__LINE__,"Server: socket path too long (exceeding UNIX_PATH_MAX)",errno);    
00031                 return SFATENAMETOOLONG;
00032         }    
00033         memset(&servaddr, 0, sizeof(struct sockaddr_un));       /* Puliamo la struttura */  
00034         servaddr.sun_family = AF_UNIX;
00035         strncpy(servaddr.sun_path, path, UNIX_PATH_MAX);
00036     
00037         /* Rendiamo il socket visibile nel dominio */
00038         if (bind(server_sk, (struct sockaddr *)&servaddr, sizeof(struct sockaddr_un)) < 0){
00039                 close(server_sk);
00040                 errore(__FILE__,__LINE__,"Server: socket bind",errno);
00041                 return -1;     
00042         }
00043 
00044         /* Mettiamo il socket in attesa di connessioni */
00045         if (listen(server_sk,MAXCONN) < 0){
00046                 close(server_sk);
00047                 errore(__FILE__,__LINE__,"Server: socket listen",errno);                
00048                 return -1;
00049         }
00050         return server_sk;
00051 }
00052 
00053 /* Chiude e distrugge una socket creata dal server */
00054 int closeSocket(serverChannel_t s){
00055         /* Chiudo la socket in lettura e scrittura (invio SEOF al client) */
00056         if (shutdown(s, SHUT_RDWR) == -1){
00057                 errore(__FILE__,__LINE__,"client: socket shutdown",errno);              
00058                 return -1;      
00059         }       
00060         if (close(s)){
00061                 errore(__FILE__,__LINE__,"Server: socket close",errno);         
00062                 return -1;      
00063         }
00064         return 0;
00065 }
00066 
00067 /* Accetta una connessione da parte di un client e ritorna il
00068  * descrittore del channel di trasmissione con il client */
00069 channel_t acceptConnection(serverChannel_t s){
00070         channel_t  sk_comunication;
00071         
00072         /* In caso di errore la funzione accept ritorna -1 */
00073         if ((sk_comunication = accept(s, NULL, 0)) == -1)
00074                 errore(__FILE__,__LINE__,"Server: socket accept",errno);
00075         return sk_comunication;
00076 }
00077 
00078 /* Scrive un messaggio sul channel di trasmissione rispettando
00079  * la struttura che contiene il messaggio da scrivere  */ 
00080 int sendMessage(channel_t sc, message_t *msg){
00081         int char_sent, sent;
00082         int nsec;
00083         
00084         /* write ritorna -1 in caso di errore, altrimenti il numero di caratteri scritti */
00085         /* Temporizzazione in caso di errore. (^l^) */
00086         for (nsec = 1; nsec<=MAXSLEEP; nsec<<=1){
00087                 if ((sent = write(sc, &(msg->type), sizeof(char))) != -1) break;
00088                 if (nsec<=MAXSLEEP/2) sleep(nsec);
00089         }
00090         if (sent==-1){ errore(__FILE__,__LINE__,"Error send message 'type'",errno); return -1; }
00091         char_sent = sent;
00092         
00093         for (nsec = 1; nsec<=MAXSLEEP; nsec<<=1){
00094                 if ((sent = write(sc, &(msg->length), sizeof(unsigned int))) != -1) break;
00095                 if (nsec<=MAXSLEEP/2) sleep(nsec);
00096         }
00097         if (sent==-1){ errore(__FILE__,__LINE__,"Error send message 'length'",errno); return -1; }
00098         char_sent += sent;
00099 
00100         if (msg->length!=0){
00101                 for (nsec = 1; nsec<=MAXSLEEP; nsec<<=1){
00102                         if ((sent = write(sc, msg->buffer, msg->length)) != -1) break;
00103                         if (nsec<=MAXSLEEP/2) sleep(nsec);
00104                 }
00105                 if (sent==-1){ errore(__FILE__,__LINE__,"Error send message 'buffer'",errno); return -1; }              
00106                 char_sent += sent;
00107         }
00108         if (msg->buffer) free(msg->buffer);
00109         msg->buffer = NULL;
00110         return char_sent;
00111 }
00112 
00113 /* Legge un messaggio dal channel di trasmissione */
00114 int receiveMessage(channel_t sc, message_t *msg){
00115         int letti, read_cnt;
00116         if ((letti = read(sc, &(msg->type), sizeof(char))) < 0 ){
00117                 errore(__FILE__,__LINE__,"Error read message 'type'",errno);
00118                 return -1;              
00119         }else if (letti==0) return SEOF; /* EOF sul socket */
00120         read_cnt = letti;
00121         if ((letti = read(sc, &(msg->length), sizeof(unsigned int))) < 0){
00122                 errore(__FILE__,__LINE__,"Error read message 'length'",errno);
00123                 return -1;              
00124         }else if (letti==0) return SEOF; /* EOF sul socket */
00125         read_cnt += letti;
00126         
00127         if (msg->length!=0){
00128                 /* alloco il buffer di di lenght + 1 al fine di terminare la stringa */
00129                 if (!(msg->buffer = calloc(msg->length +1, sizeof(char)))){
00130                         errore(__FILE__,__LINE__,"Error calloc 'buffer'",errno);
00131                         return -1;                      
00132                 }
00133                 if ((letti = read(sc, msg->buffer, msg->length)) <= 0){
00134                         errore(__FILE__,__LINE__,"Error read message 'buffer'",errno);
00135                         free(msg->buffer);
00136                         msg->buffer = NULL;
00137                         if (letti==0) return SEOF; /* EOF sul socket */
00138                         return -1;
00139                 }
00140                 read_cnt += letti;
00141         }else
00142                 msg->buffer = NULL;
00143 
00144         return read_cnt;
00145 }
00146 
00147 /* Chiude e distrugge una socket (client) */
00148 int closeConnection(channel_t sc){
00149         /* Chiudo la socket lato client (invio SEOF al server) */
00150         if (shutdown(sc, SHUT_WR) == -1){
00151                 errore(__FILE__,__LINE__,"client: socket shutdown",errno);              
00152                 return -1;      
00153         }
00154         if (close(sc)){
00155                 errore(__FILE__,__LINE__,"client: socket close",errno);         
00156                 return -1;      
00157         }
00158         return 0;
00159 }
00160 
00161 /* Crea un channel di trasmissione verso il server */
00162 channel_t openConnection(const char* path){
00163         channel_t client_sk;
00164         struct sockaddr_un clientaddr;     /* address of server */
00165     int nsec;
00166     
00167         /* Creo il socket */
00168         if ((client_sk = socket(AF_UNIX,SOCK_STREAM,0)) < 0){
00169                 errore(__FILE__,__LINE__,"Client: socket create",errno);
00170                 return -1;
00171         }
00172         if (strlen(path) > UNIX_PATH_MAX ){
00173                 errore(__FILE__,__LINE__,"Client: socket path too long (exceeding UNIX_PATH_MAX)",errno);    
00174                 return SFATENAMETOOLONG;
00175         }
00176         memset(&clientaddr, 0, sizeof(struct sockaddr_un));     /* Puliamo la struttura */  
00177         clientaddr.sun_family = AF_UNIX;
00178         strncpy(clientaddr.sun_path, path, UNIX_PATH_MAX);
00179     
00180         /* Connessione con riprova */
00181         for (nsec = 1; nsec<=MAXSLEEP; nsec<<=1){
00182                 /* Richiedo la connessione alla socket del server */
00183                 if (connect(client_sk, (struct sockaddr *)&clientaddr, sizeof(struct sockaddr_un)) == 0)
00184                         return client_sk;
00185                 if (nsec<=MAXSLEEP/2) sleep(nsec);
00186         }
00187         errore(__FILE__,__LINE__-3,"Client: socket connect",errno);
00188         return -1;
00189 }
00190 
00191 
Generato il Fri Jan 28 22:16:29 2011 per SFAT: Simplified File Allocation Table Project da  doxygen 1.6.3