]> git.pld-linux.org Git - packages/suck.git/blob - suck-ipv6.patch
7a7a8901bf39868d74db042c16e778691a982a10
[packages/suck.git] / suck-ipv6.patch
1 diff -ur suck-4.3.2-orig/active.c suck-4.3.2/active.c
2 --- suck-4.3.2-orig/active.c    2001-09-15 00:06:40.000000000 +0200
3 +++ suck-4.3.2/active.c 2007-03-22 18:56:20.000000000 +0100
4 @@ -181,7 +181,6 @@
5         
6         /* connect to localhost NNTP server */
7         int fd;
8 -       struct hostent *hi;
9         char *inbuf;
10         unsigned int port;
11  
12 @@ -190,7 +189,7 @@
13                 do_debug("Connecting to %s on port %d\n", master->localhost, port);
14         }
15         
16 -       if((fd = connect_to_nntphost(master->localhost, &hi, NULL, port, master->local_ssl, &master->local_ssl_struct)) >= 0) {
17 +       if((fd = connect_to_nntphost(master->v4only, master->localhost, NULL, port, master->local_ssl, &master->local_ssl_struct)) >= 0) {
18                 /* get the announcement line */
19                 if(sgetline(fd, &inbuf, master->local_ssl, master->local_ssl_struct) < 0) {
20                         close(fd);
21 diff -ur suck-4.3.2-orig/both.c suck-4.3.2/both.c
22 --- suck-4.3.2-orig/both.c      2003-03-25 23:38:45.000000000 +0100
23 +++ suck-4.3.2/both.c   2007-03-22 18:57:27.000000000 +0100
24 @@ -137,36 +137,51 @@
25         }
26         return retval;
27  }
28 -
29  /*---------------------------------------------*/
30 -struct hostent *get_hostent(const char *host) {
31 -       struct in_addr saddr;
32 -       int c;
33 -       struct hostent *hi = NULL;
34 +struct addrinfo *get_addrinfo(int family, const char *host, const char *port) {
35 +       struct addrinfo *hi = NULL;
36  
37 -       if(host==NULL) { 
38 +       if (host==NULL)
39 +       {
40                 error_log(ERRLOG_REPORT,both_phrases[0], NULL); 
41         }
42 -       else {
43 -               c=*host;
44 -               if(isdigit(c)) {
45 -                       saddr.s_addr = inet_addr(host); 
46 -                       hi = gethostbyaddr((char *)&saddr,sizeof(struct in_addr),AF_INET);
47 -               }
48 -               else {
49 -                       hi = gethostbyname(host);
50 -               }
51 +       else
52 +       {
53 +               struct addrinfo hints;
54 +               
55 +               memset(&hints, 0, sizeof(hints));
56 +               
57 +               hints.ai_family = family;
58 +               hints.ai_socktype = SOCK_STREAM;
59 +               hints.ai_flags = AI_CANONNAME;
60 +               
61 +#ifdef AI_ADDRCONFIG
62 +               hints.ai_flags |= AI_ADDRCONFIG;
63 +#endif
64 +               
65 +#ifdef AI_NUMERICSERV
66 +               hints.ai_flags |= AI_NUMERICSERV;
67 +#endif
68 +               
69 +               if (getaddrinfo(host, port, &hints, &hi))
70 +                       hi = NULL;
71         }
72         return hi;
73  }
74  /*--------------------------------------------*/
75 -int connect_to_nntphost(const char *host, struct hostent **hi, FILE *msgs, unsigned short int portnr, int do_ssl, void **ssl) {
76 +void free_addrinfo(struct addrinfo *hi)
77 +{
78 +       if (hi) freeaddrinfo(hi);
79 +}
80 +/*--------------------------------------------*/
81 +int connect_to_nntphost(int v4only, const char *host, FILE *msgs, unsigned short int portnr, int do_ssl, void **ssl) {
82         char *ptr, *realhost;
83 -       struct in_addr *aptr;
84 -       struct in_addr saddr;
85 -       struct sockaddr_in address;
86 +       char *bufhost;
87 +       char *ptr_last_colon;
88 +       struct addrinfo *hi;
89         char sport[10];
90         int sockfd = -1;
91 +       int colons;
92         
93  #ifdef HAVE_LIBSSL
94         SSL *ssl_struct = NULL;
95 @@ -184,65 +199,181 @@
96         }
97  #endif
98         /* handle host:port type syntax */
99 -       realhost = strdup(host);
100 -       if(realhost == NULL) {
101 +       bufhost = strdup(host);
102 +       if(bufhost == NULL) {
103                 MyPerror("out of memory copying host name");
104                 return sockfd;
105         }
106 -       ptr = strchr(realhost, ':');
107 -       if(ptr != NULL) {
108 +       
109 +       realhost = bufhost;
110 +       
111 +       // first count colons
112 +       colons = 0;
113 +       ptr = realhost;
114 +       ptr_last_colon = NULL;
115 +       
116 +       while (*ptr)
117 +       {
118 +               if (*ptr == ':')
119 +               {
120 +                       colons++;
121 +                       ptr_last_colon = ptr;
122 +               }
123 +               ptr++;
124 +       }
125 +       
126 +       if (colons > 1)
127 +       {
128 +               // this may be numeric IPv6 addr
129 +               // check for [addr]:port syntax
130 +               
131 +               if (*realhost != '[')
132 +               {
133 +                       // no such syntax -- don't interpret last colon as a port separator
134 +                       ptr_last_colon = NULL;
135 +               }
136 +               else
137 +               {
138 +                       // skip leading '['
139 +                       realhost++;     
140 +                       
141 +                       // find trailing ']'
142 +                       ptr = strchr(realhost, ']');
143 +                       if (ptr == NULL)
144 +                       {
145 +                               // no ']' ??
146 +                               // try to recover -- just forget about last colon (if any)
147 +                               ptr_last_colon = NULL;
148 +                       }
149 +                       else
150 +                       {
151 +                               // null terminate hostname
152 +                               *ptr = '\0';
153 +                               
154 +                               if (ptr_last_colon)
155 +                               {
156 +                                       // check if last colon is right after ']'
157 +                                       if (++ptr != ptr_last_colon)
158 +                                       {
159 +                                               // well this is not the case..
160 +                                               // try to recover again
161 +                                               ptr_last_colon = NULL;
162 +                                       }
163 +                               }
164 +                       }
165 +               }
166 +       }
167 +       
168 +       ptr = ptr_last_colon;
169 +       if (ptr != NULL)
170 +       {
171                 *ptr = '\0';  /* null terminate host name */
172                 portnr = atoi(++ptr); /* get port number */
173         }
174         
175 -       
176 -       
177         sprintf(sport, "%hu", portnr);  /* cause print_phrases wants all strings */
178         print_phrases(msgs, both_phrases[1], sport, NULL);
179  
180         /* Find the internet address of the NNTP server */
181 -       *hi = get_hostent(realhost);
182 -       if(*hi == NULL) {
183 +       hi = get_addrinfo(v4only ? PF_INET : PF_UNSPEC, realhost, sport);
184 +       if (hi == NULL)
185 +       {
186                 error_log(ERRLOG_REPORT,"%v1%: ",realhost, NULL);
187                 MyPerror(both_phrases[2]);
188 -               free(realhost);
189 +               free(bufhost);
190         }
191 -       else {
192 -               free(realhost);
193 -               print_phrases(msgs, both_phrases[3], (*hi)->h_name, NULL);
194 -               while((ptr = *((*hi)->h_aliases)) != NULL) {
195 -                       print_phrases(msgs, both_phrases[4], ptr, NULL );
196 -                       (*hi)->h_aliases++;
197 -               }
198 -               if((*hi)->h_addrtype != AF_INET) {
199 -                       error_log(ERRLOG_REPORT, both_phrases[5], NULL);
200 +       else
201 +       {
202 +               int supported_pf = 0;
203 +               char *canonname = hi->ai_canonname ? hi->ai_canonname : realhost;
204 +               
205 +               struct addrinfo *hi_ptr = hi;
206 +               
207 +               char *vhost = NULL;
208 +               struct addrinfo *hi_vhost = NULL;
209 +               
210 +               print_phrases(msgs, both_phrases[3], canonname, NULL);
211 +               
212 +               if (!v4only)
213 +               {
214 +                       // init IPv6 virtual host functionality.
215 +                       
216 +                       // if the VHOST environment variable is set, try to use its value
217 +                       // as the local address for the outgoing connection.
218 +                       
219 +                       vhost = getenv("VHOST");
220 +                       
221 +                       if (vhost)
222 +                       {
223 +                               hi_vhost = get_addrinfo(PF_INET6, vhost, NULL);
224 +                               
225 +                               if (!hi_vhost)
226 +                               {
227 +                                       print_phrases(msgs, "Invalid VHOST: %v1%\n", vhost, NULL);
228 +                               }
229 +                       }
230                 }
231 -               else {
232 -                       while((aptr = (struct in_addr *)*((*hi)->h_addr_list)++) != NULL) {
233 -                               saddr = *aptr;
234 -                               print_phrases(msgs, both_phrases[17], inet_ntoa(*aptr), NULL);
235 -                       }
236 -
237 -                       /* Create a socket */
238 -                       if((sockfd = socket( AF_INET, SOCK_STREAM, SOCKET_PROTOCOL)) == -1) {
239 -                               MyPerror(both_phrases[6]);
240 -                       }
241 -                       else { 
242 -                               address.sin_family = AF_INET;
243 -                               address.sin_port = htons(portnr);  /* NNTP port */
244 -                               address.sin_addr= saddr;
245 -
246 -                               /* Establish a connection */
247 -                               if(connect(sockfd, (struct sockaddr *)&address, sizeof address ) == -1) {
248 -                                       MyPerror(both_phrases[7]);
249 -                                       close(sockfd);
250 -                                       sockfd = -1;
251 +               
252 +               while (hi_ptr)
253 +               {
254 +                       if ((hi_ptr->ai_family == PF_INET) || (hi_ptr->ai_family == PF_INET6))
255 +                       {
256 +                               char num_host[NI_MAXHOST];
257 +                               
258 +                               supported_pf++;
259 +                               
260 +                               if (!getnameinfo(hi_ptr->ai_addr, hi_ptr->ai_addrlen, num_host, sizeof(num_host), NULL, 0, NI_NUMERICHOST))
261 +                                       print_phrases(msgs, both_phrases[17], num_host, NULL);
262 +                               
263 +                               /* Create a socket */
264 +                               if ((sockfd = socket(hi_ptr->ai_family, SOCK_STREAM, SOCKET_PROTOCOL)) < 0)
265 +                               {
266 +                                       MyPerror(both_phrases[6]);
267                                 }
268 -                               else {
269 -                                       print_phrases(msgs,both_phrases[8], (*hi)->h_name, NULL);
270 +                               else
271 +                               {
272 +                                       if ((hi_ptr->ai_family == PF_INET6) && (hi_vhost))
273 +                                       {
274 +                                               // IPv6 virtual host in action:
275 +                                               // explicitly bind() the socket to the specified local address
276 +                                               
277 +                                               if (bind(sockfd, hi_vhost->ai_addr, hi_vhost->ai_addrlen) < 0)
278 +                                               {
279 +                                                       print_phrases(msgs, "Invalid VHOST: %v1%\n", vhost, NULL);
280 +                                               }
281 +                                               else
282 +                                               {
283 +                                                       print_phrases(msgs, "VHOST: %v1%\n", vhost, NULL);
284 +                                               }
285 +                                       }
286 +                                       
287 +                                       /* Establish a connection */
288 +                                       if (connect(sockfd, hi_ptr->ai_addr, hi_ptr->ai_addrlen) < 0)
289 +                                       {
290 +                                               MyPerror(both_phrases[7]);
291 +                                               close(sockfd);
292 +                                               sockfd = -1;
293 +                                       }
294 +                                       else
295 +                                       {
296 +                                               print_phrases(msgs, both_phrases[8], canonname, NULL);
297 +                                               break;
298 +                                       }
299                                 }
300 -                       }
301 +                       }
302 +                       
303 +                       hi_ptr = hi_ptr->ai_next;
304 +               }
305 +               
306 +               if (!supported_pf)
307 +               {
308 +                       error_log(ERRLOG_REPORT, both_phrases[5], NULL);
309                 }
310 +               
311 +               free(bufhost);
312 +               free_addrinfo(hi);
313 +               free_addrinfo(hi_vhost);
314 +               
315  #ifdef HAVE_LIBSSL
316                 if(sockfd > -1 && do_ssl == TRUE) {
317                         if((ssl_struct = SSL_new(test1)) == NULL) {
318 diff -ur suck-4.3.2-orig/both.h suck-4.3.2/both.h
319 --- suck-4.3.2-orig/both.h      2002-08-28 00:54:34.000000000 +0200
320 +++ suck-4.3.2/both.h   2007-03-22 18:56:20.000000000 +0100
321 @@ -9,11 +9,12 @@
322  /* declarations */
323  int sgetline(int fd, char **sbuf, int, void *);
324  int sputline(int fd, const char *outbuf, int, void *);
325 -int connect_to_nntphost(const char *host, struct hostent **, FILE *, unsigned short int, int, void **);
326 +int connect_to_nntphost(int v4only, const char *host, FILE *, unsigned short int, int, void **);
327  void disconnect_from_nntphost(int, int, void **);
328  char *number(char *sp, int *intPtr);
329  char *get_long(char *, long *);
330 -struct hostent *get_hostent(const char *host);
331 +struct addrinfo *get_addrinfo(int family, const char *host, const char *port);
332 +void free_addrinfo(struct addrinfo *hi);
333  void signal_block(int);
334  void error_log(int mode, const char *fmt, ...);
335  void MyPerror(const char *);
336 diff -ur suck-4.3.2-orig/rpost.c suck-4.3.2/rpost.c
337 --- suck-4.3.2-orig/rpost.c     2003-03-25 23:50:00.000000000 +0100
338 +++ suck-4.3.2/rpost.c  2007-03-22 18:56:20.000000000 +0100
339 @@ -78,6 +78,7 @@
340  #ifdef PERL_EMBED
341         PerlInterpreter *perl_int;
342  #endif
343 +       int v4only;
344  } Args, *Pargs;
345  
346  /* function declarations */
347 @@ -114,7 +115,6 @@
348  int main(int argc, char *argv[], char *env[]) {
349         char *inbuf;
350         int response, retval, loop, fargc, i;
351 -       struct hostent *hi;
352         struct stat sbuf;
353         char **args, **fargs;
354         Args myargs;
355 @@ -149,6 +149,7 @@
356  #ifdef PERL_EMBED
357         myargs.perl_int = NULL;
358  #endif
359 +       myargs.v4only = FALSE;
360  
361         /* have to do this next so if set on cmd line, overrides this */
362  #ifdef N_PHRASES               /* in case someone nukes def */
363 @@ -230,6 +231,7 @@
364  #ifdef TIMEOUT
365                         do_debug("TimeOut = %d\n", TimeOut);
366  #endif
367 +                       do_debug("myargs.v4 = %d\n", myargs.v4only);
368                         do_debug("myargs.debug = TRUE\n");
369                 }
370  
371 @@ -241,7 +243,7 @@
372                         retval = RETVAL_ERROR;
373                 }
374                 else {
375 -                       myargs.sockfd = connect_to_nntphost( myargs.host, &hi, myargs.status_fptr, myargs.portnr, myargs.do_ssl, &myargs.ssl_struct);
376 +                       myargs.sockfd = connect_to_nntphost(myargs.v4only, myargs.host, myargs.status_fptr, myargs.portnr, myargs.do_ssl, &myargs.ssl_struct);
377                         if(myargs.sockfd < 0) {
378                                 retval = RETVAL_ERROR;
379                         }
380 @@ -296,7 +298,7 @@
381                                 retval = do_article(&myargs, stdin);
382                         }
383         
384 -                       print_phrases(myargs.status_fptr, rpost_phrases[4], hi->h_name, NULL);
385 +                       print_phrases(myargs.status_fptr, rpost_phrases[4], myargs.host, NULL);
386                         if(myargs.debug == TRUE) {
387                                 do_debug("Sending quit");
388                         }
389 @@ -738,6 +740,9 @@
390                                 myargs->portnr = DEFAULT_SSL_PORT;
391                                 break;
392  #endif
393 +                       case '4':
394 +                               myargs->v4only = TRUE;
395 +                               break;
396                           default:
397                                 error_log(ERRLOG_REPORT, rpost_phrases[30], argv[loop],NULL);
398                                 break;
399 diff -ur suck-4.3.2-orig/suck.c suck-4.3.2/suck.c
400 --- suck-4.3.2-orig/suck.c      2003-03-28 20:24:54.000000000 +0100
401 +++ suck-4.3.2/suck.c   2007-03-22 18:56:20.000000000 +0100
402 @@ -118,6 +118,7 @@
403         ARG_HIST_FILE, ARG_HEADER_ONLY, ARG_ACTIVE_LASTREAD, ARG_USEXOVER, ARG_RESETCOUNTER, \
404         ARG_LOW_READ, ARG_SHOW_GROUP, ARG_USE_SSL, ARG_LOCAL_SSL, ARG_BATCH_POST_NR, \
405         ARG_PASSWD_ENV,
406 +       ARG_V4_ONLY,
407  }; 
408  
409  typedef struct Arglist{
410 @@ -198,6 +199,7 @@
411         {"W",  "wait", 2, ARG_WAIT, 46},
412         {"X",  "no_xover", 0, ARG_XOVER, -1},
413         {"Z",  "use_xover", 0, ARG_USEXOVER, -1},
414 +       {"4",  "v4", 0, ARG_V4_ONLY, -1},
415         
416  };
417  
418 @@ -290,6 +292,7 @@
419         master.local_ssl_struct = NULL;
420         master.batch_post_nr = 0;
421         master.passwd_env = FALSE;
422 +       master.v4only = FALSE;
423         
424         /* have to do this next so if set on cmd line, overrides this */
425  
426 @@ -392,6 +395,7 @@
427                 do_debug("master.local_ssl = %s\n", true_str(master.local_ssl));
428                 do_debug("master.batch_post_nr =  %d\n",master.batch_post_nr);
429                 do_debug("master.passwd_env = %s\n", true_str(master.passwd_env));
430 +               do_debug("master.v4 = %d\n", master.v4only);
431  #ifdef TIMEOUT
432                 do_debug("TimeOut = %d\n", TimeOut);
433  #endif
434 @@ -665,7 +669,6 @@
435  
436         char *inbuf;
437         int nr, resp, retval = RETVAL_OK;
438 -       struct hostent *hi;
439         FILE *fp;
440         
441         
442 @@ -696,7 +699,7 @@
443         }
444         fp = (which_time == CONNECT_FIRST) ? master->msgs : NULL;
445  
446 -       master->sockfd = connect_to_nntphost( master->host, &hi, fp, master->portnr, master->do_ssl, &master->ssl_struct);
447 +       master->sockfd = connect_to_nntphost(master->v4only, master->host, fp, master->portnr, master->do_ssl, &master->ssl_struct);
448         
449         if(master->sockfd < 0 ) {
450                 retval = RETVAL_ERROR;
451 @@ -2132,6 +2135,9 @@
452                 master->local_ssl = TRUE;
453                 break;
454  #endif
455 +       case ARG_V4_ONLY:
456 +               master->v4only = TRUE;
457 +               break;
458                         
459         }
460         
461 diff -ur suck-4.3.2-orig/suck.h suck-4.3.2/suck.h
462 --- suck-4.3.2-orig/suck.h      2002-08-28 00:44:09.000000000 +0200
463 +++ suck-4.3.2/suck.h   2007-03-22 18:56:20.000000000 +0100
464 @@ -103,6 +103,7 @@
465         void *local_ssl_struct;
466         int batch_post_nr;
467         int passwd_env;
468 +       int v4only;
469  } Master, *PMaster;
470  
471  int get_a_chunk(PMaster, FILE *);
472 diff -ur suck-4.3.2-orig/testhost.c suck-4.3.2/testhost.c
473 --- suck-4.3.2-orig/testhost.c  2003-03-23 16:34:46.000000000 +0100
474 +++ suck-4.3.2/testhost.c       2007-03-22 18:56:20.000000000 +0100
475 @@ -59,7 +59,7 @@
476  int main(int argc, char *argv[]) {
477  
478         int sockfd, response, loop, cmd, quiet, mode_reader, do_ssl, retval = RETVAL_OK;
479 -       struct hostent *hi;
480 +       int v4only = FALSE;
481         struct stat sbuf;
482         unsigned short int portnr;
483         FILE *fptr = stdout;            /* used to print output to */
484 @@ -215,6 +215,9 @@
485                                 portnr = DEFAULT_SSL_PORT;
486                                 break;
487  #endif
488 +                       case '4':
489 +                               v4only = TRUE;
490 +                               break;
491                           default:
492                                 retval = RETVAL_ERROR;
493                                 error_log(ERRLOG_REPORT, test_phrases[7], argv[loop], NULL);
494 @@ -226,10 +229,16 @@
495                 }
496         }
497  
498 +       if (!host)
499 +       {
500 +               error_log(ERRLOG_REPORT, "No host specified\n", NULL);
501 +               retval = RETVAL_ERROR;
502 +       }
503 +
504         if(retval == RETVAL_OK) {
505                 load_phrases(phrases);  /* this is here so everything displays okay */
506  
507 -               sockfd = connect_to_nntphost( host, &hi, (quiet == FALSE)?  fptr : NULL, portnr, do_ssl, &ssl_struct);
508 +               sockfd = connect_to_nntphost(v4only, host, (quiet == FALSE)?  fptr : NULL, portnr, do_ssl, &ssl_struct);
509                 if(sockfd < 0 ) {
510                         retval = RETVAL_ERROR;
511                 }
This page took 0.091335 seconds and 2 git commands to generate.