]> git.pld-linux.org Git - packages/gawk.git/blob - gawk-3.1.5-ipv6.patch
- patches from fedora
[packages/gawk.git] / gawk-3.1.5-ipv6.patch
1 diff -bru gawk-3.1.5.orig/io.c gawk-3.1.5/io.c
2 --- gawk-3.1.5.orig/io.c        2006-07-07 16:13:08.000000000 +0200
3 +++ gawk-3.1.5/io.c     2006-07-10 13:18:13.000000000 +0200
4 @@ -71,7 +71,6 @@
5  extern int MRL;
6  
7  #ifdef HAVE_SOCKETS
8 -enum inet_prot { INET_NONE, INET_TCP, INET_UDP, INET_RAW };
9  
10  #ifndef SHUT_RD
11  #define SHUT_RD                0
12 @@ -1133,24 +1132,60 @@
13  /* socketopen --- open a socket and set it into connected state */
14  
15  static int
16 -socketopen(enum inet_prot type, int localport, int remoteport, const char *remotehostname)
17 +socketopen(int type, const char *localpname, const char *remotepname,
18 +       const char *remotehostname)
19  {
20 -       struct hostent *hp = gethostbyname(remotehostname);
21 -       struct sockaddr_in local_addr, remote_addr;
22 +       struct addrinfo *lres, *lres0;
23 +       struct addrinfo lhints;
24 +       struct addrinfo *rres, *rres0;
25 +       struct addrinfo rhints;
26 +
27 +       int lerror;
28 +       int rerror;
29 +
30         int socket_fd;
31         int any_remote_host = strcmp(remotehostname, "0");
32  
33 +       memset (&lhints, '\0', sizeof (lhints));
34 +       lhints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
35 +       lhints.ai_socktype = type;
36 +
37 +       lerror = getaddrinfo (NULL, localpname, &lhints, &lres);
38 +       if (lerror) {
39 +               if (strcmp(localpname, "0"))
40 +                       fatal(_("local port invalid in `/inet'"));
41 +               lres0 = NULL;
42 +               lres = &lhints;
43 +       } else
44 +               lres0 = lres;
45 +
46 +       while (lres) {
47 +               memset (&rhints, '\0', sizeof (rhints));
48 +               rhints.ai_flags = lhints.ai_flags;
49 +               rhints.ai_socktype = lhints.ai_socktype;
50 +               rhints.ai_family = lhints.ai_family;
51 +               rhints.ai_protocol = lhints.ai_protocol;
52 +
53 +               rerror = getaddrinfo (remotehostname, remotepname, &rhints, &rres);
54 +               if (rerror) {
55 +                       if (lres0)
56 +                               freeaddrinfo(lres0);
57 +                       fatal(_("remote host and port information invalid"));
58 +               }
59 +               rres0 = rres;
60         socket_fd = INVALID_HANDLE;
61 -       switch (type) {
62 -       case INET_TCP:  
63 -               if (localport != 0 || remoteport != 0) {
64 +               while (rres) {
65 +                       socket_fd = socket (rres->ai_family,
66 +                               rres->ai_socktype, rres->ai_protocol);
67 +                       if (socket_fd < 0 || socket_fd == INVALID_HANDLE)
68 +                               goto nextrres;
69 +
70 +                       if (type == SOCK_STREAM) {
71                         int on = 1;
72  #ifdef SO_LINGER
73                         struct linger linger;
74 -
75                         memset(& linger, '\0', sizeof(linger));
76  #endif
77 -                       socket_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
78                         setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR,
79                                 (char *) & on, sizeof(on));
80  #ifdef SO_LINGER
81 @@ -1160,57 +1195,27 @@
82                                 (char *) & linger, sizeof(linger));
83  #endif
84                 }
85 -               break;
86 -       case INET_UDP:  
87 -               if (localport != 0 || remoteport != 0)
88 -                       socket_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 
89 -               break;
90 -       case INET_RAW:  
91 -#ifdef SOCK_RAW
92 -               if (localport == 0 && remoteport == 0)
93 -                       socket_fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); 
94 -#endif
95 -               break;
96 -       case INET_NONE:
97 -               /* fall through */
98 -       default:
99 -               cant_happen();
100 -               break;
101 -       }
102 +                       if (bind(socket_fd, lres->ai_addr, lres->ai_addrlen) != 0)
103 +                               goto nextrres;
104  
105 -       if (socket_fd < 0 || socket_fd == INVALID_HANDLE
106 -           || (hp == NULL && any_remote_host != 0))
107 -               return INVALID_HANDLE;
108 -
109 -       local_addr.sin_family = remote_addr.sin_family = AF_INET;
110 -       local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
111 -       remote_addr.sin_addr.s_addr = htonl(INADDR_ANY);
112 -       local_addr.sin_port  = htons(localport);
113 -       remote_addr.sin_port = htons(remoteport);
114 -       if (bind(socket_fd, (struct sockaddr *) &local_addr, sizeof(local_addr)) == 0) {
115                 if (any_remote_host != 0) { /* not ANY => create a client */
116 -                       if (type == INET_TCP || type == INET_UDP) {
117 -                               memcpy(&remote_addr.sin_addr, hp->h_addr,
118 -                                       sizeof(remote_addr.sin_addr));
119 -                               if (connect(socket_fd,
120 -                                               (struct sockaddr *) &remote_addr,
121 -                                               sizeof(remote_addr)) != 0) {
122 -                                       close(socket_fd);
123 -                                       if (localport == 0)
124 -                                               socket_fd = INVALID_HANDLE;
125 -                                       else
126 -                                               socket_fd = socketopen(type, localport, 0, "0");
127 -                               }
128 +                               if (type != SOCK_RAW) {
129 +                                       if (connect(socket_fd, rres->ai_addr,
130 +                                               rres->ai_addrlen) == 0)
131 +                                               break;
132                         } else {
133                                 /* /inet/raw client not ready yet */ 
134                                 fatal(_("/inet/raw client not ready yet, sorry"));
135                                 if (geteuid() != 0)
136 +                                               /* FIXME: is this second fatal ever reached? */
137                                         fatal(_("only root may use `/inet/raw'."));
138                         }
139                 } else { /* remote host is ANY => create a server */
140 -                       if (type == INET_TCP) {
141 +                               if (type == SOCK_STREAM) {
142                                 int clientsocket_fd = INVALID_HANDLE;
143 -                               socklen_t namelen = sizeof(remote_addr);
144 +
145 +                                       struct sockaddr_storage remote_addr;
146 +                                       socklen_t namelen = sizeof (remote_addr);
147  
148                                 if (listen(socket_fd, 1) >= 0
149                                     && (clientsocket_fd = accept(socket_fd,
150 @@ -1218,25 +1223,22 @@
151                                                 &namelen)) >= 0) {
152                                         close(socket_fd);
153                                         socket_fd = clientsocket_fd;
154 -                               } else {
155 -                                       close(socket_fd);
156 -                                       socket_fd = INVALID_HANDLE;
157 +                                               break;
158                                 }
159 -                       } else if (type == INET_UDP) {
160 +                               } else if (type == SOCK_DGRAM) {
161  #ifdef MSG_PEEK
162                                 char buf[10];
163 +                                       struct sockaddr_storage remote_addr;
164                                 socklen_t readle;
165  
166                                 if (recvfrom(socket_fd, buf, 1, MSG_PEEK,
167                                         (struct sockaddr *) & remote_addr,
168 -                                       & readle) < 1
169 -                                               || readle != sizeof(remote_addr)
170 -                                   || connect(socket_fd,
171 +                                               & readle) >= 0
172 +                                               && readle
173 +                                               && connect(socket_fd,
174                                         (struct sockaddr *)& remote_addr,
175 -                                               readle) != 0) {
176 -                                       close(socket_fd);
177 -                                       socket_fd = INVALID_HANDLE;
178 -                               }
179 +                                                       readle) == 0)
180 +                                               break;
181  #endif
182                         } else {
183                                 /* /inet/raw server not ready yet */ 
184 @@ -1245,10 +1247,20 @@
185                                         fatal(_("only root may use `/inet/raw'."));
186                         }
187                 }
188 -       } else {
189 +
190 +nextrres:
191 +                       if (socket_fd != INVALID_HANDLE)
192                 close(socket_fd);
193                 socket_fd = INVALID_HANDLE;
194 +                       rres = rres->ai_next;
195 +               }
196 +               freeaddrinfo(rres0);
197 +               if (socket_fd != INVALID_HANDLE)
198 +                       break;
199 +               lres = lres->ai_next;
200         }
201 +       if (lres0)
202 +               freeaddrinfo(lres0);
203  
204         return socket_fd;
205  }
206 @@ -1313,30 +1325,24 @@
207         } else if (STREQN(name, "/inet/", 6)) {
208  #ifdef HAVE_SOCKETS
209                 /* /inet/protocol/localport/hostname/remoteport */
210 -               enum inet_prot protocol = INET_NONE;
211 -               int localport, remoteport;
212 +               int protocol;
213                 char *hostname;
214                 char *hostnameslastcharp;
215                 char *localpname;
216 -               char proto[4];
217 -               struct servent *service;
218 +               char *localpnamelastcharp;
219  
220                 cp = (char *) name + 6;
221                 /* which protocol? */
222                 if (STREQN(cp, "tcp/", 4))
223 -                       protocol = INET_TCP;
224 +                       protocol = SOCK_STREAM;
225                 else if (STREQN(cp, "udp/", 4))
226 -                       protocol = INET_UDP;
227 +                       protocol = SOCK_DGRAM;
228                 else if (STREQN(cp, "raw/", 4))
229 -                       protocol = INET_RAW;
230 +                       protocol = SOCK_RAW;
231                 else
232                         fatal(_("no (known) protocol supplied in special filename `%s'"),
233                                 name);
234  
235 -               proto[0] = cp[0];
236 -               proto[1] = cp[1];   
237 -               proto[2] = cp[2];   
238 -               proto[3] =  '\0';
239                 cp += 4;
240  
241                 /* which localport? */
242 @@ -1354,25 +1360,17 @@
243                  * By using atoi() the use of decimal numbers is enforced.
244                  */
245                 *cp = '\0';
246 -
247 -               localport = atoi(localpname);
248 -               if (strcmp(localpname, "0") != 0
249 -                   && (localport <= 0 || localport > 65535)) {
250 -                       service = getservbyname(localpname, proto);
251 -                       if (service == NULL)
252 -                               fatal(_("local port invalid in `%s'"), name);
253 -                       else
254 -                               localport = ntohs(service->s_port);
255 -               }
256 -               *cp = '/';
257 +               localpnamelastcharp = cp;
258  
259                 /* which hostname? */
260                 cp++;
261                 hostname = cp;
262                 while (*cp != '/' && *cp != '\0')
263                         cp++; 
264 -               if (*cp != '/' || cp == hostname)
265 +               if (*cp != '/' || cp == hostname) {
266 +                       *localpnamelastcharp = '/';
267                         fatal(_("must supply a remote hostname to `/inet'"));
268 +               }
269                 *cp = '\0';
270                 hostnameslastcharp = cp;
271  
272 @@ -1386,22 +1384,15 @@
273                  * Here too, require a port, let them explicitly put 0 if
274                  * they don't care.
275                  */
276 -               if (*cp == '\0')
277 +               if (*cp == '\0') {
278 +                       *localpnamelastcharp = '/';
279 +                       *hostnameslastcharp = '/';
280                         fatal(_("must supply a remote port to `/inet'"));
281 -               remoteport = atoi(cp);
282 -               if (strcmp(cp, "0") != 0
283 -                   && (remoteport <= 0 || remoteport > 65535)) {
284 -                       service = getservbyname(cp, proto);
285 -                       if (service == NULL)
286 -                                fatal(_("remote port invalid in `%s'"), name);
287 -                       else
288 -                               remoteport = ntohs(service->s_port);
289                 }
290  
291 -               /* Open Sesame! */
292 -               openfd = socketopen(protocol, localport, remoteport, hostname);
293 +               openfd = socketopen(protocol, localpname, cp, hostname);
294 +               *localpnamelastcharp = '/';
295                 *hostnameslastcharp = '/';
296 -
297  #else /* ! HAVE_SOCKETS */
298                 fatal(_("TCP/IP communications are not supported"));
299  #endif /* HAVE_SOCKETS */
This page took 0.07871 seconds and 3 git commands to generate.