ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/host/c++/socket++-1.10/sockinet.C
Revision: 1.1
Committed: Mon Feb 26 15:01:39 2001 UTC (23 years, 9 months ago) by ab11
Content type: text/plain
Branch: MAIN
CVS Tags: PROJECT_COMPLETION
Log Message:
Networking class. Assumed to be bug free.

File Contents

# Content
1 // sockinet.C -*- C++ -*- socket library
2 // Copyright (C) 1992,1993,1994 Gnanasekaran Swaminathan <gs4t@virginia.edu>
3 //
4 // Permission is granted to use at your own risk and distribute this software
5 // in source and binary forms provided the above copyright
6 // notice and this paragraph are preserved on all copies.
7 // This software is provided "as is" with no express or implied warranty.
8 //
9 // Version: 17Oct95 1.10
10
11 #include <config.h>
12 #include <sockinet.h>
13
14 EXTERN_C_BEGIN
15 #include <netdb.h>
16 #include <sys/time.h>
17 #include <sys/socket.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <errno.h>
21 EXTERN_C_END
22
23 void herror(const char*);
24
25 sockinetaddr::sockinetaddr ()
26 {
27 sin_family = sockinetbuf::af_inet;
28 sin_addr.s_addr = htonl(INADDR_ANY);
29 sin_port = 0;
30 }
31
32 sockinetaddr::sockinetaddr(unsigned long addr, int port_no)
33 // addr and port_no are in host byte order
34 {
35 sin_family = sockinetbuf::af_inet;
36 sin_addr.s_addr = htonl(addr);
37 sin_port = htons(port_no);
38 }
39
40 sockinetaddr::sockinetaddr(unsigned long addr, const char* sn, const char* pn)
41 // addr is in host byte order
42 {
43 sin_family = sockinetbuf::af_inet;
44 sin_addr.s_addr = htonl (addr); // Added by cgay@cs.uoregon.edu May 29, 1993
45 setport(sn, pn);
46 }
47
48 sockinetaddr::sockinetaddr (const char* host_name, int port_no)
49 // port_no is in host byte order
50 {
51 setaddr(host_name);
52 sin_port = htons(port_no);
53 }
54
55 sockinetaddr::sockinetaddr(const char* hn, const char* sn, const char* pn)
56 {
57 setaddr(hn);
58 setport(sn, pn);
59 }
60
61 sockinetaddr::sockinetaddr (const sockinetaddr& sina)
62 {
63 sin_family = sockinetbuf::af_inet;
64 sin_addr.s_addr = sina.sin_addr.s_addr;
65 sin_port = sina.sin_port;
66 }
67
68 void sockinetaddr::setport(const char* sn, const char* pn)
69 {
70 servent* sp = getservbyname(sn, pn);
71 if (sp == 0) {
72 perror(sn);
73 error ("sockinetaddr: invalid service name");
74 exit(1);
75 }
76 sin_port = sp->s_port;
77 }
78
79 int sockinetaddr::getport () const
80 {
81 return ntohs (sin_port);
82 }
83
84 void sockinetaddr::setaddr(const char* host_name)
85 {
86 if ( (sin_addr.s_addr = inet_addr(host_name)) == -1) {
87 hostent* hp = gethostbyname(host_name);
88 if (hp == 0) {
89 herror("sockinetaddr::sockinetaddr");
90 exit(1);
91 }
92 memcpy(&sin_addr, hp->h_addr, hp->h_length);
93 sin_family = hp->h_addrtype;
94 }else
95 sin_family = sockinetbuf::af_inet;
96 }
97
98 const char* sockinetaddr::gethostname () const
99 {
100 if (sin_addr.s_addr == htonl(INADDR_ANY)) {
101 static char hostname[64];
102 if (::gethostname(hostname, 63) == -1) {
103 perror("in sockinetaddr::gethostname");
104 return "";
105 }
106 return hostname;
107 }
108
109 hostent* hp = gethostbyaddr((const char*) &sin_addr,
110 sizeof(sin_addr),
111 family());
112 if (hp == 0) {
113 herror("sockinetaddr::gethostname");
114 return "";
115 }
116 if (hp->h_name) return hp->h_name;
117 return "";
118 }
119
120 sockinetbuf::sockinetbuf(sockbuf::type ty, int proto)
121 : sockbuf(af_inet, ty, proto)
122 {}
123
124 sockinetbuf& sockinetbuf::operator = (const sockbuf& si)
125 {
126 this->sockbuf::operator = (si);
127 return *this;
128
129 }
130
131 sockinetbuf& sockinetbuf::operator = (const sockinetbuf& si)
132 {
133 this->sockbuf::operator = (si);
134 return *this;
135 }
136
137 sockbuf* sockinetbuf::open(sockbuf::type st, int proto)
138 {
139 *this = sockinetbuf(st, proto);
140 return this;
141 }
142
143 sockinetaddr sockinetbuf::localaddr() const
144 {
145 sockinetaddr sin;
146 int len = sin.size();
147 if (::getsockname(rep->sock, sin.addr (), &len) == -1)
148 perror("sockinetbuf::localaddr()");
149 return sin;
150 }
151
152 int sockinetbuf::localport() const
153 {
154 sockinetaddr sin = localaddr();
155 if (sin.family() != af_inet) return -1;
156 return sin.getport();
157 }
158
159 const char* sockinetbuf::localhost() const
160 {
161 sockinetaddr sin = localaddr();
162 if (sin.family() != af_inet) return "";
163 return sin.gethostname();
164 }
165
166
167 sockinetaddr sockinetbuf::peeraddr() const
168 {
169 sockinetaddr sin;
170 int len = sin.size();
171 if (::getpeername(rep->sock, sin.addr (), &len) == -1)
172 perror("sockinetbuf::peeraddr()");
173 return sin;
174 }
175
176 int sockinetbuf::peerport() const
177 {
178 sockinetaddr sin = peeraddr();
179 if (sin.family() != af_inet) return -1;
180 return sin.getport();
181 }
182
183 const char* sockinetbuf::peerhost() const
184 {
185 sockinetaddr sin = peeraddr();
186 if (sin.family() != af_inet) return "";
187 return sin.gethostname();
188 }
189
190 int sockinetbuf::bind_until_success (int portno)
191 // a. bind to (INADDR_ANY, portno)
192 // b. if success return 0
193 // c. if failure and errno is EADDRINUSE, portno++ and go to step a.
194 // d. return errno.
195 {
196 for (;;) {
197 sockinetaddr sa ((unsigned long) INADDR_ANY, portno++);
198 int eno = bind (sa);
199 if (eno == 0)
200 return 0;
201 if (eno != EADDRINUSE)
202 return eno;
203 }
204 }
205
206 int sockinetbuf::bind (sockAddr& sa)
207 {
208 return sockbuf::bind (sa);
209 }
210
211 int sockinetbuf::bind ()
212 {
213 sockinetaddr sa;
214 return bind (sa);
215 }
216
217 int sockinetbuf::bind (unsigned long addr, int port_no)
218 // address and portno are in host byte order
219 {
220 sockinetaddr sa (addr, port_no);
221 return bind (sa);
222 }
223
224 int sockinetbuf::bind (const char* host_name, int port_no)
225 {
226 sockinetaddr sa (host_name, port_no);
227 return bind (sa);
228 }
229
230 int sockinetbuf::bind (unsigned long addr,
231 const char* service_name,
232 const char* protocol_name)
233 {
234 sockinetaddr sa (addr, service_name, protocol_name);
235 return bind (sa);
236 }
237
238 int sockinetbuf::bind (const char* host_name,
239 const char* service_name,
240 const char* protocol_name)
241 {
242 sockinetaddr sa (host_name, service_name, protocol_name);
243 return bind (sa);
244 }
245
246 int sockinetbuf::connect (sockAddr& sa)
247 {
248 return sockbuf::connect (sa);
249 }
250
251 int sockinetbuf::connect (unsigned long addr, int port_no)
252 // address and portno are in host byte order
253 {
254 sockinetaddr sa (addr, port_no);
255 return connect (sa);
256 }
257
258 int sockinetbuf::connect (const char* host_name, int port_no)
259 {
260 sockinetaddr sa (host_name, port_no);
261 return connect (sa);
262 }
263
264 int sockinetbuf::connect (unsigned long addr,
265 const char* service_name,
266 const char* protocol_name)
267 {
268 sockinetaddr sa (addr, service_name, protocol_name);
269 return connect (sa);
270 }
271
272 int sockinetbuf::connect (const char* host_name,
273 const char* service_name,
274 const char* protocol_name)
275 {
276 sockinetaddr sa (host_name, service_name, protocol_name);
277 return connect (sa);
278 }
279
280 isockinet::isockinet (sockbuf::type ty, int proto)
281 : ios (new sockinetbuf (ty, proto))
282 {}
283
284 isockinet::isockinet (const sockbuf& sb)
285 : ios (new sockinetbuf (sb))
286 {}
287
288 isockinet::~isockinet ()
289 {
290 delete ios::rdbuf ();
291 init (0);
292 }
293
294 osockinet::osockinet (sockbuf::type ty, int proto)
295 : ios (new sockinetbuf (ty, proto))
296 {}
297
298 osockinet::osockinet (const sockbuf& sb)
299 : ios (new sockinetbuf (sb))
300 {}
301
302 osockinet::~osockinet ()
303 {
304 delete ios::rdbuf ();
305 init (0);
306 }
307
308 iosockinet::iosockinet (sockbuf::type ty, int proto)
309 : ios (new sockinetbuf (ty, proto))
310 {}
311
312 iosockinet::iosockinet (const sockbuf& sb)
313 : ios (new sockinetbuf (sb))
314 {}
315
316 iosockinet::~iosockinet ()
317 {
318 delete ios::rdbuf ();
319 init (0);
320 }
321
322 #if !defined (__linux__)
323
324 extern "C" int h_errno;
325 static char* errmsg[] = {
326 ": No error\n",
327 ": Host not found\n",
328 ": Try again\n",
329 ": No recovery\n",
330 ": No address\n"
331 ": Unknown error\n"
332 };
333 void herror(const char* em)
334 {
335 if (h_errno > 5) h_errno = 5;
336 cerr << em << errmsg[h_errno];
337 }
338
339 #endif // !__linux__