00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
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
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
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
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
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
00189 #endif
00190 }
00191
00192
00193 #ifdef USE_ASYNC
00194
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 }