* Add "less" target to view make output through less.
[matthijs/ABM2.git] / ABM2 / Amaltheia / Network.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005 by Dimitris Saougos & Filippos Papadopoulos   *
3  *   <psybases@gmail.com>                                                             *
4  *                                                                                                       *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU Library General Public License as       *
7  *   published by the Free Software Foundation; either version 2 of the    *
8  *   License, or (at your option) any later version.                                    *
9  *                                                                                                           *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU Library General Public     *
16  *   License along with this program; if not, write to the                 *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20
21 #include "Network.h"            
22
23 #include <sys/select.h>
24 #include <sys/time.h>
25 #include <unistd.h>
26
27 #include <ctype.h>
28 #include <cstring>
29 #include <cstdlib>
30 #include <cstdio>
31 #include <errno.h>
32 #include <sys/types.h>
33
34
35 Socket::Socket(int sd)
36 {       
37         int x = 1;
38         s=sd;
39         if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)) == -1)
40                 perror("sockopt");
41         this->type=AM_TCP;
42
43         return ;
44 }
45
46 Socket::Socket(int type, int protocol)
47 {
48         int x = 1;
49         int t = SOCK_STREAM;
50
51         if(type == AM_UDP)
52                 t  = SOCK_DGRAM;
53
54         s=socket(AF_INET, t, protocol);
55         if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)) == -1)
56                 perror("sockopt");
57
58         this->type=type;
59
60         return ;
61 }
62
63 Socket::~Socket()
64 {
65         shutdown(s, SHUT_RDWR);
66         
67         return ;
68 }
69
70 int Socket::Bind(int port)
71 {
72         struct sockaddr_in myaddr;
73
74         myaddr.sin_family=AF_INET;
75         myaddr.sin_port=htons(port);
76         myaddr.sin_addr.s_addr=htonl(INADDR_ANY);
77
78         int res=bind(s, (struct sockaddr *)&myaddr, sizeof(myaddr));
79         if (res ==-1)
80                 perror("bind returned -1"), exit(1);
81         
82         return res;
83 }
84
85 int Socket::Listen(int log)
86 {
87         int res=listen(s, log);
88         if (res ==-1)
89                 perror("listen returned -1"), exit(1);
90         
91         return res;
92 }
93
94 Socket* Socket::Accept(void)
95 {
96         socklen_t l = sizeof(struct sockaddr);
97
98         int res = accept(s, (struct sockaddr *)&peer, &l);
99         if(res == -1)
100                 perror("accept returned -1"), exit(1);
101         
102         Socket *tmp = new Socket((int)res);
103
104         return tmp;
105 }
106
107
108 int Socket::Connect()
109 {
110         struct in_addr tmp;
111         tmp.s_addr = peer.sin_addr.s_addr;
112         
113         printf(" con to %s %d\n", inet_ntoa(tmp), ntohs(peer.sin_port));
114         int res; 
115         res = connect(s, (struct sockaddr *)&peer, sizeof(peer));
116         
117         if (res ==-1)
118                 perror("connect returned -1");
119         
120         return res;
121 }
122  
123
124
125
126 int Socket::Send(void *buffer, unsigned long size)
127 {
128 //      printf("send buf=%s\n", (const char *)buffer);
129         int res=send(s, (const char *)buffer, size, 0);
130         
131         if (res ==-1)
132         {
133                 perror("send returned -1");
134                 if(errno == ENOTSOCK)           
135                         printf("ENOTSOCK\n");
136                 else
137                         printf("ERROR\n");
138         }
139         
140         return res;
141 }
142
143 int Socket::Receive(void *buffer, unsigned long size)
144 {
145         int res=recv(s, (char *)buffer, size, 0);
146         if (res ==-1)
147                 perror("recv returned -1"), exit(1);
148
149         return res;
150 }
151
152 int Socket::SendTo(void *buffer, unsigned long size)
153 {
154         int res=sendto(s, (const char *)buffer, size, 0, (const struct sockaddr *)&peer, sizeof(peer));
155         if (res ==-1)
156                 perror("sendto returned -1"), exit(1);
157
158         return res;
159 }
160
161 int Socket::RecvFrom(void *buffer, unsigned long size)
162 {
163         unsigned int l;
164         int res=recvfrom(s, (char *)buffer, size, 0, (struct sockaddr *)&peer, &l);
165         if (res ==-1)
166                 perror("recvfrom returned -1"), exit(1);
167
168         return res;
169 }
170
171 void Socket::SetPeer(struct sockaddr_in data)
172 {
173         memcpy(&peer, &data, sizeof(data));
174
175         return ;
176 }
177
178
179 struct sockaddr_in Socket::GetPeer(void)
180 {
181         return peer;
182 }
183
184 struct sockaddr_in Socket::CreatePeer(const char *address, int port)
185 {
186         struct sockaddr_in youraddr;
187
188         printf("Hostname address specified: %s\n", address);
189         
190         youraddr.sin_port=htons(port);
191         youraddr.sin_family=AF_INET;
192         youraddr.sin_addr.s_addr=0;
193
194         if (isdigit(address[0]))
195         {
196                 unsigned long addr;
197                 
198                 addr=inet_addr(address);
199                 
200                 memcpy((void *)&(youraddr.sin_addr), (const void *)&addr, sizeof(addr));
201         }
202         else
203         {
204                 struct hostent *otherhost;
205         
206                 otherhost = gethostbyname(address);
207
208                 if(otherhost == NULL)
209                         herror("otherhost");
210                 
211                 if (otherhost != NULL)
212                         memcpy((void *)&(youraddr.sin_addr), (const void *)otherhost->h_addr_list[0], otherhost->h_length);
213         }
214
215         return youraddr;
216 }
217
218
219 int Socket::Select(unsigned long seconds, unsigned long microsecs)
220 {
221         struct timeval tv;
222         
223         tv.tv_sec = seconds;
224         tv.tv_usec = microsecs;
225         
226         fd_set rfds;
227         FD_ZERO(&rfds);
228         FD_SET(s, &rfds);
229         
230         int ret = select(s+1, &rfds, NULL, NULL, &tv);
231         return ret;
232 }
233
234
235 int Socket::Select(unsigned long microsecs)
236 {
237         struct timeval tv;
238         
239         tv.tv_sec = 0;
240         tv.tv_usec = microsecs;
241         
242         fd_set rfds;
243         FD_ZERO(&rfds);
244         FD_SET(s, &rfds);
245         
246         int ret = select(s+1, &rfds, NULL, NULL, &tv);
247         return ret;
248 }
249
250
251 Network::Network()
252 {
253         ;
254 }
255
256 Network::~Network()
257 {
258         ;
259 }
260
261 Socket * Network::getSocket(int type, int protocol)
262 {
263         Socket *tmp=new Socket(type, protocol);
264
265         return tmp;
266 }