+/* close connection socket */
+
+void close_connection (void)
+{
+ _closesocket (conn);
+ conn = INVALID_SOCKET;
+}
+
+/* receive data from socket */
+
+int receive_data (char **pdata)
+{
+ char buffer[BUFFER_SIZE] = {0};
+ char *data = NULL;
+ int len = 0;
+
+ if (conn == INVALID_SOCKET) {
+ VERBOSE (ERROR, PERROR ("Can't read data from closed socket\n"));
+ return 0;
+ }
+
+ while (1) {
+
+ /* timeout management */
+ fd_set rfds;
+ struct timeval tv = { 0, TIMEOUT };
+ FD_ZERO (&rfds);
+ FD_SET (conn, &rfds);
+
+ int retval = select (conn + 1, &rfds, NULL, NULL, &tv);
+ if (retval != 1) { /* 0 or SOCKET_ERROR */
+ break;
+ }
+
+ /* read from socket */
+ int rc = recv (conn, buffer, BUFFER_SIZE, 0);
+ VERBOSE (DEBUG, PRINT ("rc: %d\nerrno: %d\n", rc, ERRNO));
+
+ if (rc == 0) { /* sock closed or error */
+ if (data) {
+ free (data);
+ data = NULL;
+ }
+ len = (rc < 0) ? -1 : 0;
+ break;
+
+ } else if (rc > 0) {
+ data = realloc (data, len + rc);
+ memcpy (data + len, buffer, rc);
+ len += rc;
+ }
+ }
+
+ if (pdata != NULL) {
+ *pdata = data;
+ }
+ return len;
+}
+
+/* send data onto socket */
+
+int send_data (char *data, int len)
+{
+ int index = 0;
+
+ if (conn == INVALID_SOCKET) {
+ VERBOSE (ERROR, PERROR ("Can't read data from closed socket\n"));
+ return 0;
+ }
+
+ while (index < len) {
+ int rc = send (conn, data + index, len - index, 0);
+
+ if (rc <= 0) { /* sock closed or error */
+ index = (rc < 0) ? -1 : 0;
+ break;
+ } else if (rc > 0) {
+ index += rc;
+ }
+ }
+
+ return index;
+}