Logo Search packages:      
Sourcecode: viewglob version File versions  Download package

socket-connect.c

/*
 * Copyright (c) 1993 W. Richard Stevens.  All rights reserved.
 * Permission to use or modify this software and its documentation only for
 * educational purposes and without fee is hereby granted, provided that
 * the above copyright notice appear in all copies.  The author makes no
 * representations about the suitability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 */

/*
      Copyright (C) 2004, 2005 Stephen Bach
      This file is part of the Viewglob package.

      Viewglob is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published by
      the Free Software Foundation; either version 2 of the License, or
      (at your option) any later version.

      Viewglob is distributed in the hope that it will be useful,
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      GNU General Public License for more details.

      You should have received a copy of the GNU General Public License
      along with Viewglob; if not, write to the Free Software
      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "common.h"
#include "socket-connect.h"

#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <netdb.h>

#include <string.h>

gint unix_connect(const char* port) {
      gint sockfd;
      struct sockaddr_un servaddr;
      gchar* home;
      gchar* name;

      if ((home = getenv("HOME")) == NULL) {
            g_critical("User does not have a home!");
            return -1;
      }

      name = g_strconcat(home, "/.viewglob/.", port, NULL);

      if (strlen(name) + 1 > sizeof(servaddr.sun_path)) {
            g_critical("Socket name too long");
            return -1;
      }

      sockfd = socket(AF_LOCAL, SOCK_STREAM, 0);
      if (sockfd < 0) {
            g_critical("Could not create socket: %s", g_strerror(errno));
            return -1;
      }

      memset(&servaddr, 0, sizeof(servaddr));
      servaddr.sun_family = AF_LOCAL;
      strcpy(servaddr.sun_path, name);
      g_free(name);

      if (connect(sockfd, (struct sockaddr*) &servaddr,
                        sizeof(servaddr)) == -1) {
            g_critical("Connection error to %s: %s", servaddr.sun_path,
                        g_strerror(errno));
            return -1;
      }

      return sockfd;
}


gint tcp_connect(const char *host, const char *serv) {
      gint sockfd;

#ifdef HAVE_GETADDRINFO
      gint                    n;
      struct addrinfo   hints, *res, *ressave;

      (void) memset(&hints, 0, sizeof(struct addrinfo));
      hints.ai_family = AF_UNSPEC;
      hints.ai_socktype = SOCK_STREAM;

      if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0) {
            g_critical("tcp_connect error for %s, %s: %s",
                         host, serv, gai_strerror(n));
            return -1;
      }
      ressave = res;

      do {
            sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
            if (sockfd < 0)
                  continue;   /* ignore this one */

            if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0)
                  break;            /* success */

            (void) close(sockfd);   /* ignore this one */
      } while ( (res = res->ai_next) != NULL);

      if (res == NULL) {      /* errno set from final connect() */
            g_critical("tcp_connect error for %s, %s: %s", host, serv,
                        g_strerror(errno));
            return -1;
      }

      freeaddrinfo(ressave);

#else
      struct sockaddr_in servaddr;
      struct in_addr** pptr;
      struct in_addr* inetaddrp[2];
      struct in_addr inetaddr;
      struct hostent* hp;

      int port = atoi(serv);

      if ((hp = gethostbyname(host)) == NULL) {
            if (inet_aton(host, &inetaddr) == 0) {
                  g_critical("Could not convert hostname: %s",
                              g_strerror(errno));
                  return -1;
            }
            else {
                  inetaddrp[0] = &inetaddr;
                  inetaddrp[1] = NULL;
                  pptr = inetaddrp;
            }
      }
      else
            pptr = (struct in_addr**) hp->h_addr_list;

      for ( ; *pptr != NULL; pptr++) {
            sockfd = socket(AF_INET, SOCK_STREAM, 0);
            if (sockfd < 0) {
                  g_critical("Could not create socket: %s", g_strerror(errno));
                  return -1;
            }

            memset(&servaddr, 0, sizeof(servaddr));
            servaddr.sin_family = AF_INET;
            servaddr.sin_port = htons(port);
            memcpy(&servaddr.sin_addr, *pptr, sizeof(struct in_addr));

            if (connect(sockfd, (struct sockaddr*) &servaddr,
                              sizeof(servaddr)) == 0)
                  break;   /* success */

            g_warning("Connection error: %s", g_strerror(errno));
            (void) close(sockfd);
      }
      
      if (*pptr == NULL) {
            g_critical("Unable to connect.");
            return -1;
      }
#endif

      return sockfd;
}


Generated by  Doxygen 1.6.0   Back to index