libt2n: (gerd) small fixes, hello unit tests
[libt2n] / src / socket_client.cpp
1 /***************************************************************************
2  *   Copyright (C) 2006 by Gerd v. Egidy                                   *
3  *   gve@intra2net.com                                                     *
4  *                                                                         *
5  *   This library is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU Lesser General Public License version   *
7  *   2.1 as published by the Free Software Foundation.                     *
8  *                                                                         *
9  *   This library is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU Lesser General Public License for more details.                   *
13  *                                                                         *
14  *   You should have received a copy of the GNU Lesser General Public      *
15  *   License along with this program; if not, write to the                 *
16  *   Free Software Foundation, Inc.,                                       *
17  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
18  ***************************************************************************/
19
20 #include <stdio.h>
21 #include <errno.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <sys/types.h>
25 #include <sys/socket.h>
26 #include <sys/un.h>
27 #include <sys/time.h>
28 #include <arpa/inet.h>
29 #include <netinet/in.h>
30 #include <netdb.h>
31 #include <fcntl.h>
32 #include <time.h>
33 #include <pwd.h>
34 #include <grp.h>
35
36 #include <sstream>
37
38 #include "socket_client.hxx"
39 #include "t2n_exception.hxx"
40
41 using namespace std;
42
43 namespace libt2n
44 {
45
46 socket_client_connection::socket_client_connection(const std::string& _server, int _port, int _max_retries)
47     : client_connection(), socket_handler(0,tcp_s)
48 {
49     max_retries=_max_retries;
50
51     server=_server;
52     port=_port;
53
54     connect();
55 }
56
57 socket_client_connection::socket_client_connection(const std::string& _path, int _max_retries)
58     : client_connection(), socket_handler(0,unix_s)
59 {
60     max_retries=_max_retries;
61
62     path=_path;
63
64     connect();
65 }
66
67 void socket_client_connection::connect()
68 {
69     if (get_type() == unix_s)
70     {
71         struct sockaddr_un unix_addr;
72
73         unix_addr.sun_family = AF_UNIX;
74         strcpy (unix_addr.sun_path, path.c_str());
75
76         sock = socket(PF_UNIX, SOCK_STREAM, 0);
77         if (!sock)
78             throw t2n_connect_error(string("socket() error: ")+strerror(errno));
79
80         if (::connect(sock,(struct sockaddr *) &unix_addr, sizeof(unix_addr)))
81             throw t2n_connect_error(string("connect() error: ")+strerror(errno));
82     }
83     else if (get_type() == tcp_s)
84     {
85         struct sockaddr_in sock_addr;
86
87         sock_addr.sin_family = AF_INET;
88         sock_addr.sin_port = htons(port);
89
90         // find the target ip
91         if (inet_aton(server.c_str(),&sock_addr.sin_addr)==0)
92         {
93             struct hostent *server_hent;
94             server_hent=gethostbyname(server.c_str());
95             if (server_hent == NULL)
96                 throw t2n_connect_error(string("can't find server ")+server);
97
98             memcpy(&sock_addr.sin_addr,server_hent->h_addr_list[0],sizeof(sock_addr.sin_addr));
99         }
100
101         sock = socket(PF_INET, SOCK_STREAM, 0);
102         if (!sock)
103             throw t2n_connect_error(string("socket() error: ")+strerror(errno));
104
105         if (::connect(sock,(struct sockaddr *) &sock_addr, sizeof(sock_addr)))
106             throw t2n_connect_error(string("connect() error: ")+strerror(errno));
107     }
108     else
109         throw t2n_connect_error(string("invalid connection type"));
110
111     set_socket_options(sock);
112
113     do_callbacks(new_connection);
114 }
115
116 void socket_client_connection::close()
117 {
118     if (!client_connection::is_closed())
119     {
120         socket_handler::close();
121         client_connection::close();
122     }
123 }
124
125 }