00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00039 #include <unistd.h>
00040
00041 #ifdef __WIN32__
00042 #include <conio.h>
00043 #include <winsock.h>
00044 #else
00045 #include <netdb.h>
00046 #include <sys/socket.h>
00047 #include <netinet/in.h>
00048 #endif
00049
00050 #include <string.h>
00051
00052 #include "splt.h"
00053 #include "socket_manager.h"
00054
00055 #define SPLT_BUFFER_SIZE 1024
00056 #define SPLT_MAXIMUM_NUMBER_OF_LINES_READ 1000
00057
00058
00059 void splt_sm_connect(splt_socket_handler *sh, const char *hostname, int port,
00060 splt_state *state)
00061 {
00062 struct hostent *host_entity = NULL;
00063
00064 int err = splt_su_copy(hostname, &sh->hostname);
00065 if (err < 0) { sh->error = err; return; }
00066
00067 #ifdef __WIN32__
00068 WSADATA winsock;
00069 long winsockinit = WSAStartup(0x0101,&winsock);
00070 if (winsockinit != 0)
00071 {
00072 splt_e_set_strerror_msg(state);
00073 sh->error = SPLT_FREEDB_ERROR_INITIALISE_SOCKET;
00074 return;
00075 }
00076 #endif
00077
00078 host_entity = gethostbyname(hostname);
00079
00080 if (host_entity == NULL)
00081 {
00082 splt_e_set_strherror_msg(state);
00083 splt_e_set_error_data(state, hostname);
00084 sh->error = SPLT_FREEDB_ERROR_CANNOT_GET_HOST;
00085 return;
00086 }
00087
00088 struct sockaddr_in my_socket;
00089 memset(&my_socket, 0x0, sizeof(my_socket));
00090 my_socket.sin_family = AF_INET;
00091 my_socket.sin_addr.s_addr = ((struct in_addr *) (host_entity->h_addr)) ->s_addr;
00092 my_socket.sin_port = htons(port);
00093
00094 sh->fd = socket(AF_INET, SOCK_STREAM, 0);
00095 if (sh->fd == -1)
00096 {
00097 splt_e_set_strerror_msg(state);
00098 sh->error = SPLT_FREEDB_ERROR_CANNOT_OPEN_SOCKET;
00099 return;
00100 }
00101
00102 if (connect(sh->fd, (void *)&my_socket, sizeof(my_socket)) < 0)
00103 {
00104 splt_e_set_strerror_msg(state);
00105 splt_e_set_error_data(state, hostname);
00106 sh->error = SPLT_FREEDB_ERROR_CANNOT_CONNECT;
00107 return;
00108 }
00109 }
00110
00111 void splt_sm_send(splt_socket_handler *sh, const char *message,
00112 splt_state *state)
00113 {
00114 if (send(sh->fd, message, strlen(message), 0) == -1)
00115 {
00116 splt_e_set_strerror_msg(state);
00117 splt_e_set_error_data(state, sh->hostname);
00118 sh->error = SPLT_FREEDB_ERROR_CANNOT_SEND_MESSAGE;
00119 }
00120 }
00121
00122 void splt_sm_send_http_message(splt_socket_handler *sh, const char *message,
00123 splt_state *state)
00124 {
00125 char *message_with_http = NULL;
00126 int err = splt_su_append_str(&message_with_http,
00127 message, " HTTP/1.0\r\nHost: ", sh->hostname, "\r\n\r\n", NULL);
00128 if (err < 0) { sh->error = err; return; }
00129
00130 splt_sm_send(sh, message_with_http, state);
00131
00132 if (message_with_http)
00133 {
00134 free(message_with_http);
00135 message_with_http = NULL;
00136 }
00137 }
00138
00139 int splt_sm_process_without_headers_functor(const char *received_line,
00140 int line_number, void *user_data)
00141 {
00142 splt_sm_functor_decorator *sm_fd = (splt_sm_functor_decorator *) user_data;
00143
00144 if (!sm_fd->processing_headers)
00145 {
00146 int real_line_number =
00147 sm_fd->line_number_after_headers - sm_fd->num_lines_to_skip;
00148
00149 if (real_line_number > 0)
00150 {
00151 int we_continue = sm_fd->functor(received_line, real_line_number, sm_fd->user_data);
00152 if (!we_continue)
00153 {
00154 return SPLT_FALSE;
00155 }
00156 }
00157 sm_fd->line_number_after_headers++;
00158 }
00159
00160 if (strlen(received_line) == 0)
00161 {
00162 sm_fd->processing_headers = SPLT_FALSE;
00163 }
00164
00165 return SPLT_TRUE;
00166 }
00167
00168 void splt_sm_receive_and_process_without_headers_with_recv(splt_socket_handler *sh,
00169 splt_state *state,
00170 ssize_t (*recv_func)(int fd, void *buf, size_t len, int flags),
00171 int (*process_functor)(const char *received_line, int line_number, void *user_data),
00172 void *user_data, int number_of_lines_to_skip_after_headers)
00173 {
00174 splt_sm_functor_decorator *sm_fd = malloc(sizeof(splt_sm_functor_decorator));
00175 if (!sm_fd)
00176 {
00177 sh->error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
00178 return;
00179 }
00180
00181 sm_fd->functor = process_functor;
00182 sm_fd->user_data = user_data;
00183 sm_fd->processing_headers = SPLT_TRUE;
00184 sm_fd->num_lines_to_skip = number_of_lines_to_skip_after_headers;
00185 sm_fd->line_number_after_headers = 1;
00186 sm_fd->line_number = 1;
00187
00188 splt_sm_receive_and_process_with_recv(sh, state,
00189 recv_func, splt_sm_process_without_headers_functor, sm_fd);
00190
00191 free(sm_fd);
00192 sm_fd = NULL;
00193 }
00194
00195 void splt_sm_receive_and_process_without_headers(splt_socket_handler *sh,
00196 splt_state *state,
00197 int (*process_functor)(const char *received_line, int line_number, void *user_data),
00198 void *user_data, int number_of_lines_to_skip_after_headers)
00199 {
00200 splt_sm_receive_and_process_without_headers_with_recv(sh, state, recv,
00201 process_functor, user_data, number_of_lines_to_skip_after_headers);
00202 }
00203
00204 void splt_sm_receive_and_process(splt_socket_handler *sh, splt_state *state,
00205 int (*process_functor)(const char *received_line, int line_number, void *user_data),
00206 void *user_data)
00207 {
00208 splt_sm_receive_and_process_with_recv(sh, state, recv, process_functor, user_data);
00209 }
00210
00211 void splt_sm_receive_and_process_with_recv(splt_socket_handler *sh, splt_state *state,
00212 ssize_t (*recv_func)(int fd, void *buf, size_t len, int flags),
00213 int (*process_functor)(const char *received_line, int line_number, void *user_data),
00214 void *user_data)
00215 {
00216 int err = SPLT_OK;
00217
00218 char *lines = NULL;
00219
00220 char *remaining_line = NULL;
00221 int remaining_line_size = 0;
00222
00223 char buffer[SPLT_BUFFER_SIZE] = { '\0' };
00224
00225 int number_of_lines_read = 0;
00226
00227 char *line_begin = NULL;
00228 char *line_end = NULL;
00229
00230 int line_number = 1;
00231
00232 while (number_of_lines_read < SPLT_MAXIMUM_NUMBER_OF_LINES_READ) {
00233 memset(buffer, '\0', SPLT_BUFFER_SIZE);
00234 #ifdef __WIN32__
00235 int received_bytes = recv(sh->fd, buffer, SPLT_BUFFER_SIZE, 0);
00236 #else
00237 int received_bytes = recv_func(sh->fd, buffer, SPLT_BUFFER_SIZE, 0);
00238 #endif
00239 if (received_bytes == -1)
00240 {
00241 splt_e_set_strerror_msg(state);
00242 splt_e_set_error_data(state, sh->hostname);
00243 sh->error = SPLT_FREEDB_ERROR_CANNOT_RECV_MESSAGE;
00244 goto end;
00245 }
00246
00247 if (received_bytes == 0)
00248 {
00249 break;
00250 }
00251
00252 err = splt_su_set(&lines, remaining_line, remaining_line_size, NULL);
00253 if (err < 0) { sh->error = err; goto end; }
00254
00255 err = splt_su_append(&lines, buffer, received_bytes, NULL);
00256 if (err < 0) { sh->error = err; goto end; }
00257
00258 remaining_line_size += received_bytes;
00259
00260 if (!lines)
00261 {
00262 continue;
00263 }
00264
00265 line_begin = lines;
00266 line_end = NULL;
00267
00268 while ((line_end = strchr(line_begin, '\n')) != NULL)
00269 {
00270 int line_size = (line_end - line_begin) + 1;
00271
00272 char *line = NULL;
00273 err = splt_su_set(&line, line_begin, line_size, "\0", 1, NULL);
00274 if (err < 0) { sh->error = err; goto end; }
00275
00276 splt_su_line_to_unix(line);
00277 splt_su_str_cut_last_char(line);
00278
00279 int we_continue = process_functor(line, line_number, user_data);
00280
00281 line_number++;
00282
00283 if (line)
00284 {
00285 free(line);
00286 line = NULL;
00287 }
00288
00289 if (!we_continue)
00290 {
00291 goto end;
00292 }
00293
00294 remaining_line_size -= line_size;
00295 line_begin = line_end + 1;
00296 }
00297
00298 err = splt_su_set(&remaining_line, line_begin, remaining_line_size, NULL);
00299 if (err < 0) { sh->error = err; goto end; }
00300 }
00301
00302 end:
00303 if (lines)
00304 {
00305 free(lines);
00306 lines = NULL;
00307 }
00308 if (remaining_line)
00309 {
00310 free(remaining_line);
00311 remaining_line = NULL;
00312 }
00313 }
00314
00315 void splt_sm_close(splt_socket_handler *sh, splt_state *state)
00316 {
00317 if (closesocket(sh->fd) == -1)
00318 {
00319 splt_e_set_strerror_msg(state);
00320 sh->error = SPLT_FREEDB_ERROR_CANNOT_DISCONNECT;
00321 }
00322
00323 #ifdef __WIN32__
00324 WSACleanup();
00325 #endif
00326 }
00327
00328 splt_socket_handler *splt_sm_socket_handler_new(int *error)
00329 {
00330 splt_socket_handler *sh = malloc(sizeof(splt_socket_handler));
00331 if (sh == NULL)
00332 {
00333 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
00334 return NULL;
00335 }
00336 memset(sh, 0x0, sizeof(splt_socket_handler));
00337
00338 sh->error = SPLT_OK;
00339 sh->hostname = NULL;
00340
00341 return sh;
00342 }
00343
00344 void splt_sm_socket_handler_free(splt_socket_handler **sh)
00345 {
00346 if (!sh || !*sh)
00347 {
00348 return;
00349 }
00350
00351 if ((*sh)->hostname)
00352 {
00353 free((*sh)->hostname);
00354 (*sh)->hostname = NULL;
00355 }
00356
00357 free(*sh);
00358 *sh = NULL;
00359 }
00360