OpenCoverage

netopen.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/bash/src/lib/sh/netopen.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* -
2 * netopen.c -- functions to make tcp/udp connections-
3 *-
4 * Chet Ramey-
5 * chet@ins.CWRU.Edu-
6 */-
7-
8/* Copyright (C) 1987-2016 Free Software Foundation, Inc.-
9-
10 This file is part of GNU Bash, the Bourne Again SHell.-
11-
12 Bash is free software: you can redistribute it and/or modify-
13 it under the terms of the GNU General Public License as published by-
14 the Free Software Foundation, either version 3 of the License, or-
15 (at your option) any later version.-
16-
17 Bash is distributed in the hope that it will be useful,-
18 but WITHOUT ANY WARRANTY; without even the implied warranty of-
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the-
20 GNU General Public License for more details.-
21-
22 You should have received a copy of the GNU General Public License-
23 along with Bash. If not, see <http://www.gnu.org/licenses/>.-
24*/-
25-
26#include <config.h>-
27-
28#if defined (HAVE_NETWORK)-
29-
30#if defined (HAVE_UNISTD_H)-
31# include <unistd.h>-
32#endif-
33-
34#include <stdio.h> -
35#include <sys/types.h>-
36-
37#if defined (HAVE_SYS_SOCKET_H)-
38# include <sys/socket.h>-
39#endif-
40-
41#if defined (HAVE_NETINET_IN_H)-
42# include <netinet/in.h>-
43#endif-
44-
45#if defined (HAVE_NETDB_H)-
46# include <netdb.h>-
47#endif-
48-
49#if defined (HAVE_ARPA_INET_H)-
50# include <arpa/inet.h>-
51#endif-
52-
53#include <bashansi.h>-
54#include <bashintl.h>-
55-
56#include <errno.h>-
57-
58#include <shell.h>-
59#include <xmalloc.h>-
60-
61#ifndef errno-
62extern int errno;-
63#endif-
64-
65#if !defined (HAVE_INET_ATON)-
66extern int inet_aton __P((const char *, struct in_addr *));-
67#endif-
68-
69#ifndef HAVE_GETADDRINFO-
70static int _getaddr __P((char *, struct in_addr *));-
71static int _getserv __P((char *, int, unsigned short *));-
72static int _netopen4 __P((char *, char *, int));-
73#else /* HAVE_GETADDRINFO */-
74static int _netopen6 __P((char *, char *, int));-
75#endif-
76-
77static int _netopen __P((char *, char *, int));-
78-
79#ifndef HAVE_GETADDRINFO-
80/* Stuff the internet address corresponding to HOST into AP, in network-
81 byte order. Return 1 on success, 0 on failure. */-
82-
83static int-
84_getaddr (host, ap)-
85 char *host;-
86 struct in_addr *ap;-
87{-
88 struct hostent *h;-
89 int r;-
90-
91 r = 0;-
92 if (host[0] >= '0' && host[0] <= '9')-
93 {-
94 /* If the first character is a digit, guess that it's an-
95 Internet address and return immediately if inet_aton succeeds. */-
96 r = inet_aton (host, ap);-
97 if (r)-
98 return r;-
99 }-
100#if !defined (HAVE_GETHOSTBYNAME)-
101 return 0;-
102#else-
103 h = gethostbyname (host);-
104 if (h && h->h_addr)-
105 {-
106 bcopy(h->h_addr, (char *)ap, h->h_length);-
107 return 1;-
108 }-
109#endif-
110 return 0;-
111 -
112}-
113-
114/* Return 1 if SERV is a valid port number and stuff the converted value into-
115 PP in network byte order. */ -
116static int-
117_getserv (serv, proto, pp)-
118 char *serv;-
119 int proto;-
120 unsigned short *pp;-
121{-
122 intmax_t l;-
123 unsigned short s;-
124-
125 if (legal_number (serv, &l))-
126 {-
127 s = (unsigned short)(l & 0xFFFF);-
128 if (s != l)-
129 return (0);-
130 s = htons (s);-
131 if (pp)-
132 *pp = s;-
133 return 1;-
134 }-
135 else-
136#if defined (HAVE_GETSERVBYNAME)-
137 {-
138 struct servent *se;-
139-
140 se = getservbyname (serv, (proto == 't') ? "tcp" : "udp");-
141 if (se == 0)-
142 return 0;-
143 if (pp)-
144 *pp = se->s_port; /* ports returned in network byte order */-
145 return 1;-
146 }-
147#else /* !HAVE_GETSERVBYNAME */-
148 return 0;-
149#endif /* !HAVE_GETSERVBYNAME */-
150}-
151-
152/*-
153 * Open a TCP or UDP connection to HOST on port SERV. Uses the-
154 * traditional BSD mechanisms. Returns the connected socket or -1 on error.-
155 */-
156static int -
157_netopen4(host, serv, typ)-
158 char *host, *serv;-
159 int typ;-
160{-
161 struct in_addr ina;-
162 struct sockaddr_in sin;-
163 unsigned short p;-
164 int s, e;-
165-
166 if (_getaddr(host, &ina) == 0)-
167 {-
168 internal_error (_("%s: host unknown"), host);-
169 errno = EINVAL;-
170 return -1;-
171 }-
172-
173 if (_getserv(serv, typ, &p) == 0)-
174 {-
175 internal_error(_("%s: invalid service"), serv);-
176 errno = EINVAL;-
177 return -1;-
178 }-
179 -
180 memset ((char *)&sin, 0, sizeof(sin));-
181 sin.sin_family = AF_INET;-
182 sin.sin_port = p;-
183 sin.sin_addr = ina;-
184-
185 s = socket(AF_INET, (typ == 't') ? SOCK_STREAM : SOCK_DGRAM, 0);-
186 if (s < 0)-
187 {-
188 sys_error ("socket");-
189 return (-1);-
190 }-
191-
192 if (connect (s, (struct sockaddr *)&sin, sizeof (sin)) < 0)-
193 {-
194 e = errno;-
195 sys_error("connect");-
196 close(s);-
197 errno = e;-
198 return (-1);-
199 }-
200-
201 return(s);-
202}-
203#endif /* ! HAVE_GETADDRINFO */-
204-
205#ifdef HAVE_GETADDRINFO-
206/*-
207 * Open a TCP or UDP connection to HOST on port SERV. Uses getaddrinfo(3)-
208 * which provides support for IPv6. Returns the connected socket or -1-
209 * on error.-
210 */-
211static int-
212_netopen6 (host, serv, typ)-
213 char *host, *serv;-
214 int typ;-
215{-
216 int s, e;-
217 struct addrinfo hints, *res, *res0;-
218 int gerr;-
219-
220 memset ((char *)&hints, 0, sizeof (hints));-
221 /* XXX -- if problems with IPv6, set to PF_INET for IPv4 only */-
222#ifdef DEBUG /* PF_INET is the one that works for me */-
223 hints.ai_family = PF_INET;-
224#else-
225 hints.ai_family = PF_UNSPEC;-
226#endif-
227 hints.ai_socktype = (typ == 't') ? SOCK_STREAM : SOCK_DGRAM;
(typ == 't')Description
TRUEnever evaluated
FALSEnever evaluated
0
228-
229 gerr = getaddrinfo (host, serv, &hints, &res0);-
230 if (gerr)
gerrDescription
TRUEnever evaluated
FALSEnever evaluated
0
231 {-
232 if (gerr == EAI_SERVICE)
gerr == -8Description
TRUEnever evaluated
FALSEnever evaluated
0
233 internal_error ("%s: %s", serv, gai_strerror (gerr));
never executed: internal_error ("%s: %s", serv, gai_strerror (gerr));
0
234 else-
235 internal_error ("%s: %s", host, gai_strerror (gerr));
never executed: internal_error ("%s: %s", host, gai_strerror (gerr));
0
236 errno = EINVAL;-
237 return -1;
never executed: return -1;
0
238 }-
239-
240 for (res = res0; res; res = res->ai_next)
resDescription
TRUEnever evaluated
FALSEnever evaluated
0
241 {-
242 if ((s = socket (res->ai_family, res->ai_socktype, res->ai_protocol)) < 0)
(s = socket (r...protocol)) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
243 {-
244 if (res->ai_next)
res->ai_nextDescription
TRUEnever evaluated
FALSEnever evaluated
0
245 continue;
never executed: continue;
0
246 sys_error ("socket");-
247 freeaddrinfo (res0);-
248 return -1;
never executed: return -1;
0
249 }-
250 if (connect (s, res->ai_addr, res->ai_addrlen) < 0)
connect (s, re...i_addrlen) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
251 {-
252 if (res->ai_next)
res->ai_nextDescription
TRUEnever evaluated
FALSEnever evaluated
0
253 {-
254 close (s);-
255 continue;
never executed: continue;
0
256 }-
257 e = errno;-
258 sys_error ("connect");-
259 close (s);-
260 freeaddrinfo (res0);-
261 errno = e;-
262 return -1;
never executed: return -1;
0
263 }-
264 freeaddrinfo (res0);-
265 break;
never executed: break;
0
266 }-
267 return s;
never executed: return s;
0
268}-
269#endif /* HAVE_GETADDRINFO */-
270-
271/*-
272 * Open a TCP or UDP connection to HOST on port SERV. Uses getaddrinfo(3)-
273 * if available, falling back to the traditional BSD mechanisms otherwise.-
274 * Returns the connected socket or -1 on error.-
275 */-
276static int -
277_netopen(host, serv, typ)-
278 char *host, *serv;-
279 int typ;-
280{-
281#ifdef HAVE_GETADDRINFO-
282 return (_netopen6 (host, serv, typ));
never executed: return (_netopen6 (host, serv, typ));
0
283#else-
284 return (_netopen4 (host, serv, typ));-
285#endif-
286}-
287-
288/*-
289 * Open a TCP or UDP connection given a path like `/dev/tcp/host/port' to-
290 * host `host' on port `port' and return the connected socket.-
291 */-
292int-
293netopen (path)-
294 char *path;-
295{-
296 char *np, *s, *t;-
297 int fd;-
298-
299 np = (char *)xmalloc (strlen (path) + 1);-
300 strcpy (np, path);-
301-
302 s = np + 9;-
303 t = strchr (s, '/');
__builtin_constant_p ( '/' )Description
TRUEnever evaluated
FALSEnever evaluated
!__builtin_constant_p ( s )Description
TRUEnever evaluated
FALSEnever evaluated
( '/' ) == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
304 if (t == 0)
t == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
305 {-
306 internal_error (_("%s: bad network path specification"), path);-
307 free (np);-
308 return -1;
never executed: return -1;
0
309 }-
310 *t++ = '\0';-
311 fd = _netopen (s, t, path[5]);-
312 free (np);-
313-
314 return fd;
never executed: return fd;
0
315}-
316-
317#if 0-
318/*-
319 * Open a TCP connection to host `host' on the port defined for service-
320 * `serv' and return the connected socket.-
321 */-
322int-
323tcpopen (host, serv)-
324 char *host, *serv;-
325{-
326 return (_netopen (host, serv, 't'));-
327}-
328-
329/*-
330 * Open a UDP connection to host `host' on the port defined for service-
331 * `serv' and return the connected socket.-
332 */-
333int-
334udpopen (host, serv)-
335 char *host, *serv;-
336{-
337 return _netopen (host, serv, 'u');-
338}-
339#endif-
340-
341#else /* !HAVE_NETWORK */-
342-
343int-
344netopen (path)-
345 char *path;-
346{-
347 internal_error (_("network operations not supported"));-
348 return -1;-
349}-
350-
351#endif /* !HAVE_NETWORK */-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.1.2