Main Page   Compound List   File List   Compound Members   File Members  

client.c

00001 /* DICElib (DIstributed CAVE Engine library) 
00002  * Copyright (c) 2001 Bruno Barberi Gnecco <brunobg@lsi.usp.br>
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a copy
00005  * of this software and associated documentation files (the "Software"), to
00006  * deal in the Software without restriction, including without limitation the
00007  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
00008  * sell copies of the Software, and to permit persons to whom the Software is
00009  * furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included in
00012  * all copies of the Software, its documentation and marketing & publicity
00013  * materials, and acknowledgment shall be given in the documentation, materials
00014  * and software packages that this Software was used.
00015  *
00016  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00018  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00019  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
00020  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00021  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00022  */
00023 
00024 #include "_dicelib.h"
00025 #include <string.h>
00026 #include <errno.h>
00027 #include <fcntl.h>
00028 #ifndef WINDOWS
00029 #include <netdb.h>
00030 #include <sys/socket.h>
00031 #include <sys/types.h>
00032 #include <unistd.h>
00033 #include <arpa/inet.h>
00034 #include <netinet/in.h>
00035 #include <netinet/tcp.h>
00036 #include <sys/time.h>
00037 #include <unistd.h>
00038 #include <signal.h>
00039 # ifdef USE_LTDL
00040 #  include <ltdl.h>
00041 # endif
00042 #else
00043 #include <winsock.h>
00044 #endif
00045 
00046 int DICE_is_original ( void ) {
00047         return (dice_data.id == 0);
00048 }
00049 
00050 int DICE_function ( void *data ) {
00051         if ( dice_data.function )
00052                 return dice_data.function(data);
00053         return -1;
00054 }
00055   
00056 #ifdef USE_ASYNC
00057 #define FUNCTION                "dice_client_sigio"
00058 
00060 void dice_client_sigio ( int signum ) {
00061         dice_packet                     packet;
00062         struct timeval                  tv;
00063         fd_set                          rfds;
00064         int                             ret;
00065 
00066         FD_ZERO(&rfds);
00067         FD_SET(dice_data.controlsock, &rfds);
00068         tv.tv_sec = 0;
00069         tv.tv_usec = 0;
00070 
00071         ret = select(dice_data.controlsock+1, &rfds, NULL, NULL, &tv);
00072         switch ( ret ) {
00073           case -1:
00074                 _dice_debug(1, dice_printf(FUNCTION, "%s\n", strerror(errno));)
00075           case 0:
00076                 return;
00077         }
00078 
00079         /* Ok, there's something there, go get it Rex! */
00080         packet = dice_packet_get(dice_data.controlsock);
00081         switch ( packet.packtype ) {
00082           case INVALID:
00083                 return;
00084           case SYNC:
00085                 _dice_debug(1, dice_printf(FUNCTION, "got a lonely SYNC!\n");)
00086                 return;
00087 #ifdef USE_ASYNC
00088           case VARIABLE_ASYNC:
00089                 DICE_async_update(packet.variable.name, packet.variable.value);
00090                 return;
00091 #endif
00092           case VARIABLE_SYNC:
00093                 _dice_debug(1, dice_printf(FUNCTION, "got a lonely VAR_SYNC!\n");)
00094                 return;
00095           case READY:
00096                 _dice_debug(1, dice_printf(FUNCTION, "got a lonely READY!\n");)
00097                 return;
00098           case CONTINUE:
00099                 _dice_debug(1, dice_printf(FUNCTION, "got a lonely CONTINUE!\n");)
00100                 return;
00101           case GOODBYE:
00102                 _dice_debug(1, dice_printf(FUNCTION, "got a goodbye!\n");)
00103                 exit(0);
00104                 return;
00105         }
00106 } 
00107 #endif
00108 
00109 #undef FUNCTION
00110 #define FUNCTION                "dice_init_client"
00111 
00119 int dice_init_client ( void ) {
00120         int                             flag;
00121         struct hostent                  *h;
00122         struct sockaddr_in              addr;
00123 #ifdef USE_ASYNC
00124         struct sigaction                newaction, oldaction;
00125 #endif
00126         dice_packet                     packet;
00127 
00128         _dice_debug(3, dice_printf(FUNCTION, "()\n");)
00129 
00130         /* Resolve the host */
00131         if ( (h = gethostbyname(dice_data.controlname)) == NULL ) {
00132                 _dice_debug(1, dice_printf(FUNCTION, "%s\n", strerror(errno));)
00133                 return -1;
00134         }
00135 
00136         /* Fill out the sockaddr_in structure */
00137         memset(&addr, 0, sizeof(addr));
00138         memcpy(&addr.sin_addr, h->h_addr, h->h_length); 
00139         addr.sin_family = AF_INET;
00140         addr.sin_port = htons(dice_data.port);
00141 
00142         /* Open the socket. */
00143         if ( (dice_data.controlsock = socket(AF_INET,SOCK_STREAM,0)) < 0 ) {
00144                 _dice_debug(1, dice_printf(FUNCTION, "%s\n", strerror(errno));)
00145                 return -1;
00146         }
00147 
00148         /* Attempt to connect */
00149         if ( connect(dice_data.controlsock, (struct sockaddr *)&addr, sizeof(addr)) < 0 ) {
00150                 _dice_debug(1, dice_printf(FUNCTION, "%s\n", strerror(errno));)
00151                 return -1;
00152         }
00153 
00154         flag = 1;
00155         setsockopt(dice_data.controlsock, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(int));
00156 
00157         /* handshaking: get our id. */
00158         packet = dice_packet_get(dice_data.controlsock);
00159         if (packet.packtype != HELLO) {
00160                 _dice_debug(1, dice_printf(FUNCTION, "Didn't get a HELLo packet\n");)
00161                 return -1;
00162         }
00163         dice_data.id = packet.hello.id;
00164         if (packet.hello.function) {
00165 #ifdef USE_LTDL
00166                 dice_data.function = lt_dlsym(dice_data.handle, 
00167                                 packet.hello.function);
00168                 if (!dice_data.function)
00169                         _dice_debug(1, dice_printf(FUNCTION, 
00170                                         "Error loading function \"%s\": %s\n",
00171                                         packet.hello.function, lt_dlerror());)
00172 #else
00173                 DICE_Function *f = DICE_MyFunctions;
00174 
00175                 while (f->name) {
00176                         if (!strcmp(f->name, packet.hello.function))
00177                                 break;
00178                         f++;
00179                 }
00180   
00181                 if (!f->name) { 
00182                         _dice_debug(2, dice_printf(FUNCTION,
00183                                         "Warning: couldn't load function \"%s\"\n",
00184                                         packet.hello.function);)
00185                 }
00186                 else
00187                         dice_data.function = f->func;
00188 /*              dice_functions_init(packet.hello.functions); */
00189 #endif
00190         }
00191         
00192 
00193 #ifdef USE_ASYNC
00194 /* todo: use fcntl(F_SETSIG) to use a signal other than SIGIO */        
00195         fcntl(dice_data.controlsock, F_SETFL, O_ASYNC);
00196         newaction.sa_handler = dice_client_sigio;
00197         sigemptyset(&newaction.sa_mask);
00198         newaction.sa_flags = SA_RESETHAND | SA_RESTART;
00199 
00200         sigaction(SIGIO, NULL, &oldaction);
00201         if ( oldaction.sa_handler == SIG_IGN ) {
00202                 _dice_debug(1, dice_printf(FUNCTION, "You cannot use SIGIO.\n");)
00203                 return -1;
00204         }
00205         sigaction(SIGIO, &newaction, NULL);
00206 #endif
00207 
00208         return 0;
00209 }

Generated at Sun Dec 9 16:13:18 2001 for dicelib by doxygen1.2.9.1 written by Dimitri van Heesch, © 1997-2001