libfreerdp-core/transport: add connect and disconnect code.
authorVic Lee <llyzs@163.com>
Sun, 3 Jul 2011 07:53:55 +0000 (15:53 +0800)
committerVic Lee <llyzs@163.com>
Sun, 3 Jul 2011 07:53:55 +0000 (15:53 +0800)
libfreerdp-core/transport.c

index 1cd116e..ac1b446 100644 (file)
 #include <freerdp/utils/stream.h>
 #include <freerdp/utils/memory.h>
 
+#include <sys/socket.h>
+#include <netdb.h>
+#include <fcntl.h>
+
 #include "transport.h"
 
 rdpTransport *
@@ -33,6 +37,8 @@ transport_new(void)
        transport = (rdpTransport *) xmalloc(sizeof(rdpTransport));
        memset(transport, 0, sizeof(rdpTransport));
 
+       transport->sockfd = -1;
+
        return transport;
 }
 
@@ -42,15 +48,94 @@ transport_free(rdpTransport * transport)
        xfree(transport);
 }
 
+static int
+transport_connect_sockfd(rdpTransport * transport, const char * server, int port)
+{
+       struct addrinfo hints = { 0 };
+       struct addrinfo * res, * ai;
+       int r;
+       char servname[10];
+       int sockfd = -1;
+
+       hints.ai_family = AF_UNSPEC;
+       hints.ai_socktype = SOCK_STREAM;
+
+       snprintf(servname, sizeof(servname), "%d", port);
+       r = getaddrinfo(server, servname, &hints, &res);
+       if (r != 0)
+       {
+               printf("transport_connect: getaddrinfo (%s)\n", gai_strerror(r));
+               return -1;
+       }
+
+       for (ai = res; ai; ai = ai->ai_next)
+       {
+               sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+               if (sockfd < 0)
+                       continue;
+
+               r = connect(sockfd, ai->ai_addr, ai->ai_addrlen);
+               if (r == 0)
+               {
+                       printf("connected to %s:%s\n", server, servname);
+                       break;
+               }
+
+               sockfd = -1;
+       }
+       freeaddrinfo(res);
+
+       if (sockfd == -1)
+       {
+               printf("unable to connect to %s:%s\n", server, servname);
+               return -1;
+       }
+
+       transport->sockfd = sockfd;
+
+       return 0;
+}
+
+static int
+transport_configure_sockfd(rdpTransport * transport)
+{
+       int flags;
+
+       flags = fcntl(transport->sockfd, F_GETFL);
+       if (flags == -1)
+       {
+               printf("transport_configure_sockfd: fcntl failed.\n");
+               return -1;
+       }
+       fcntl(transport->sockfd, F_SETFL, flags | O_NONBLOCK);
+
+       return 0;
+}
+
 int
 transport_connect(rdpTransport * transport, const char * server, int port)
 {
+       int r;
+
+       r = transport_connect_sockfd(transport, server, port);
+       if (r != 0)
+               return r;
+
+       r = transport_configure_sockfd(transport);
+       if (r != 0)
+               return r;
+
        return 0;
 }
 
 int
 transport_disconnect(rdpTransport * transport)
 {
+       if (transport->sockfd != -1)
+       {
+               close(transport->sockfd);
+               transport->sockfd = -1;
+       }
        return 0;
 }