~ubuntu-branches/debian/squeeze/freeciv/squeeze

« back to all changes in this revision

Viewing changes to utility/netintf.c

  • Committer: Bazaar Package Importer
  • Author(s): Clint Adams, Karl Goetz, Clint Adams
  • Date: 2010-02-23 22:09:02 UTC
  • mfrom: (1.2.13 upstream)
  • Revision ID: james.westby@ubuntu.com-20100223220902-kiyrmr9i4152cka5
Tags: 2.2.0-1
[ Karl Goetz ]
* Remove civserver files in /etc/ggzd/ (Closes: 523772, 517787)
* Adding ${misc:Depends} to all binary packages (lintian warnings)

[ Clint Adams ]
* New upstream version.
  - Drop data_dsc_use_bindir.diff (binary pathnames have changed).

Show diffs side-by-side

added added

removed removed

Lines of Context:
50
50
#include <windows.h>    /* GetTempPath */
51
51
#endif
52
52
 
 
53
#include "fcintl.h"
53
54
#include "log.h"
54
55
#include "shared.h"             /* TRUE, FALSE */
55
56
#include "support.h"
75
76
      errno = WSAGetLastError();
76
77
      return;
77
78
    default:
78
 
      freelog(LOG_ERROR, "Missing errno mapping for Winsock error #%d. "
79
 
                         "Please report this message at %s.",
80
 
                         WSAGetLastError(), BUG_URL);
 
79
      freelog(LOG_ERROR,
 
80
              "Missing errno mapping for Winsock error #%d.",
 
81
              WSAGetLastError());
 
82
      freelog(LOG_ERROR,
 
83
              /* TRANS: No full stop after the URL, could cause confusion. */
 
84
              _("Please report this message at %s"),
 
85
              BUG_URL);
81
86
  }
82
87
}
83
 
#endif
 
88
#endif /* HAVE_WINSOCK */
84
89
 
85
90
/***************************************************************
86
91
  Connect a socket to an address
87
92
***************************************************************/
88
 
int my_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen)
 
93
int fc_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen)
89
94
{
90
95
  int result;
91
96
  
103
108
/***************************************************************
104
109
  Wait for a number of sockets to change status
105
110
**************************************************************/
106
 
int my_select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
 
111
int fc_select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
107
112
              struct timeval *timeout)
108
113
{
109
114
  int result;
122
127
/***************************************************************
123
128
  Read from a socket.
124
129
***************************************************************/
125
 
int my_readsocket(int sock, void *buf, size_t size)
 
130
int fc_readsocket(int sock, void *buf, size_t size)
126
131
{
127
132
  int result;
128
133
  
141
146
/***************************************************************
142
147
  Write to a socket.
143
148
***************************************************************/
144
 
int my_writesocket(int sock, const void *buf, size_t size)
 
149
int fc_writesocket(int sock, const void *buf, size_t size)
145
150
{
146
151
  int result;
147
152
        
151
156
    set_socket_errno();
152
157
  }
153
158
#else
 
159
#  ifdef MSG_NOSIGNAL
 
160
  result = send(sock, buf, size, MSG_NOSIGNAL);
 
161
#  else
154
162
  result = write(sock, buf, size);
155
 
#endif
 
163
#  endif /* MSG_NOSIGNAL */
 
164
#endif /* HAVE_WINSOCK */
156
165
 
157
166
  return result;
158
167
}
160
169
/***************************************************************
161
170
  Close a socket.
162
171
***************************************************************/
163
 
void my_closesocket(int sock)
 
172
void fc_closesocket(int sock)
164
173
{
165
174
#ifdef HAVE_WINSOCK
166
175
  closesocket(sock);
172
181
/***************************************************************
173
182
  Initialize network stuff.
174
183
***************************************************************/
175
 
void my_init_network(void)
 
184
void fc_init_network(void)
176
185
{
177
186
#ifdef HAVE_WINSOCK
178
187
  WSADATA wsa;
179
188
 
180
189
  if (WSAStartup(MAKEWORD(1, 1), &wsa) != 0) {
181
 
    freelog(LOG_ERROR, "no usable WINSOCK.DLL: %s", mystrerror());
 
190
    freelog(LOG_ERROR, "no usable WINSOCK.DLL: %s", fc_strerror(fc_get_errno()));
182
191
  }
183
192
#endif
184
193
 
191
200
/***************************************************************
192
201
  Shutdown network stuff.
193
202
***************************************************************/
194
 
void my_shutdown_network(void)
 
203
void fc_shutdown_network(void)
195
204
{
196
205
#ifdef HAVE_WINSOCK
197
206
  WSACleanup();
201
210
/***************************************************************
202
211
  Set socket to non-blocking.
203
212
***************************************************************/
204
 
void my_nonblock(int sockfd)
 
213
void fc_nonblock(int sockfd)
205
214
{
206
215
#ifdef NONBLOCKING_SOCKETS
207
216
#ifdef HAVE_WINSOCK
212
221
  int f_set;
213
222
 
214
223
  if ((f_set=fcntl(sockfd, F_GETFL)) == -1) {
215
 
    freelog(LOG_ERROR, "fcntl F_GETFL failed: %s", mystrerror());
 
224
    freelog(LOG_ERROR, "fcntl F_GETFL failed: %s", fc_strerror(fc_get_errno()));
216
225
  }
217
226
 
218
227
  f_set |= O_NONBLOCK;
219
228
 
220
229
  if (fcntl(sockfd, F_SETFL, f_set) == -1) {
221
 
    freelog(LOG_ERROR, "fcntl F_SETFL failed: %s", mystrerror());
 
230
    freelog(LOG_ERROR, "fcntl F_SETFL failed: %s", fc_strerror(fc_get_errno()));
222
231
  }
223
232
#else
224
233
#ifdef HAVE_IOCTL
225
234
  long value=1;
226
235
 
227
236
  if (ioctl(sockfd, FIONBIO, (char*)&value) == -1) {
228
 
    freelog(LOG_ERROR, "ioctl failed: %s", mystrerror());
 
237
    freelog(LOG_ERROR, "ioctl failed: %s", fc_strerror(fc_get_errno()));
229
238
  }
230
239
#endif
231
240
#endif
236
245
}
237
246
 
238
247
/***************************************************************************
 
248
  Write information about socaddr to debug log.
 
249
***************************************************************************/
 
250
void sockaddr_debug(union fc_sockaddr *addr)
 
251
{
 
252
#ifdef IPV6_SUPPORT
 
253
  char buf[INET6_ADDRSTRLEN] = "Unknown";
 
254
 
 
255
  if (addr->saddr.sa_family == AF_INET6) { 
 
256
    inet_ntop(AF_INET6, &addr->saddr_in6.sin6_addr, buf, INET6_ADDRSTRLEN);
 
257
    freelog(LOG_DEBUG, "Host: %s, Port: %d (IPv6)",
 
258
            buf, ntohs(addr->saddr_in6.sin6_port));
 
259
  } else {
 
260
    inet_ntop(AF_INET, &addr->saddr_in4.sin_addr, buf, INET_ADDRSTRLEN);
 
261
    freelog(LOG_DEBUG, "Host: %s, Port: %d (IPv4)",
 
262
            buf, ntohs(addr->saddr_in4.sin_port));
 
263
  }
 
264
#else  /* IPv6 support */
 
265
  char *buf;
 
266
 
 
267
  buf = inet_ntoa(addr->saddr_in4.sin_addr);
 
268
 
 
269
  freelog(LOG_DEBUG, "Host: %s, Port: %d",
 
270
          buf, ntohs(addr->saddr_in4.sin_port));
 
271
#endif /* IPv6 support */
 
272
}
 
273
 
 
274
/***************************************************************************
 
275
  Gets size of address to fc_sockaddr. IPv6/IPv4 must be selected before
 
276
  calling this.
 
277
***************************************************************************/
 
278
int sockaddr_size(union fc_sockaddr *addr)
 
279
{
 
280
#ifdef IPV6_SUPPORT
 
281
  if (addr->saddr.sa_family == AF_INET6) {
 
282
    return sizeof(addr->saddr_in6);
 
283
  } else
 
284
#endif /* IPV6_SUPPORT */
 
285
  {
 
286
    return sizeof(addr->saddr_in4);
 
287
  }
 
288
}
 
289
 
 
290
/***************************************************************************
 
291
  Returns wether address is IPv6 address.
 
292
***************************************************************************/
 
293
bool sockaddr_ipv6(union fc_sockaddr *addr)
 
294
{
 
295
#ifdef IPV6_SUPPORT
 
296
  if (addr->saddr.sa_family == AF_INET6) {
 
297
    return TRUE;
 
298
  } else
 
299
#endif /* IPv6 support */
 
300
  {
 
301
    return FALSE;
 
302
  }
 
303
}
 
304
 
 
305
/***************************************************************************
239
306
  Look up the service at hostname:port and fill in *sa.
240
307
***************************************************************************/
241
 
bool net_lookup_service(const char *name, int port, union my_sockaddr *addr)
 
308
bool net_lookup_service(const char *name, int port, union fc_sockaddr *addr,
 
309
                        bool force_ipv4)
242
310
{
243
311
  struct hostent *hp;
244
 
  struct sockaddr_in *sock = &addr->sockaddr_in;
245
 
 
246
 
  sock->sin_family = AF_INET;
247
 
  sock->sin_port = htons(port);
248
 
 
249
 
  if (!name) {
250
 
    sock->sin_addr.s_addr = htonl(INADDR_ANY);
251
 
    return TRUE;
252
 
  }
253
 
 
254
 
#ifdef HAVE_INET_ATON
255
 
  if (inet_aton(name, &sock->sin_addr) != 0) {
256
 
    return TRUE;
257
 
  }
258
 
#else
259
 
  if ((sock->sin_addr.s_addr = inet_addr(name)) != INADDR_NONE) {
260
 
    return TRUE;
261
 
  }
262
 
#endif
 
312
  struct sockaddr_in *sock4;
 
313
#ifdef IPV6_SUPPORT
 
314
  struct sockaddr_in6 *sock6;
 
315
#endif /* IPv6 support */
 
316
 
 
317
  sock4 = &addr->saddr_in4;
 
318
 
 
319
#ifdef IPV6_SUPPORT
 
320
  sock6 = &addr->saddr_in6;
 
321
 
 
322
    if (!force_ipv4) {
 
323
    addr->saddr.sa_family = AF_INET6;
 
324
    sock6->sin6_port = htons(port);
 
325
 
 
326
    if (!name) {
 
327
      sock6->sin6_addr = in6addr_any;
 
328
      return TRUE;
 
329
    }
 
330
 
 
331
    if (inet_pton(AF_INET6, name, &sock6->sin6_addr)) {
 
332
      return TRUE;
 
333
    }
 
334
    /* TODO: Replace gethostbyname2() with getaddrinfo() */
 
335
    hp = gethostbyname2(name, AF_INET6);
 
336
  } else
 
337
#endif /* IPv6 support */
 
338
  {
 
339
    addr->saddr.sa_family = AF_INET;
 
340
    sock4->sin_port = htons(port);
 
341
 
 
342
    if (!name) {
 
343
      sock4->sin_addr.s_addr = htonl(INADDR_ANY);
 
344
      return TRUE;
 
345
    }
 
346
  }
 
347
 
 
348
#ifdef IPV6_SUPPORT
 
349
  if (force_ipv4 || !hp || hp->h_addrtype != AF_INET6) {
 
350
    /* Try to fallback to IPv4 resolution */
 
351
    if (!force_ipv4) {
 
352
      freelog(LOG_DEBUG, "Falling back to IPv4");
 
353
    }
 
354
    hp = gethostbyname2(name, AF_INET);
 
355
    if (!hp || hp->h_addrtype != AF_INET) {
 
356
      return FALSE;
 
357
    }
 
358
    addr->saddr.sa_family = AF_INET;
 
359
    sock4->sin_port = htons(port);
 
360
  }
 
361
#else  /* IPV6 support */
 
362
#if defined(HAVE_INET_ATON)
 
363
  if (inet_aton(name, &sock4->sin_addr) != 0) {
 
364
    return TRUE;
 
365
  }
 
366
#else  /* HAVE_INET_ATON */
 
367
  if ((sock4->sin_addr.s_addr = inet_addr(name)) != INADDR_NONE) {
 
368
    return TRUE;
 
369
  }
 
370
#endif /* HAVE_INET_ATON */
263
371
  hp = gethostbyname(name);
264
372
  if (!hp || hp->h_addrtype != AF_INET) {
265
373
    return FALSE;
266
374
  }
267
 
 
268
 
  memcpy(&sock->sin_addr, hp->h_addr, hp->h_length);
 
375
#endif /* IPv6 support */
 
376
 
 
377
#ifdef IPV6_SUPPORT
 
378
  if (addr->saddr.sa_family == AF_INET6) {
 
379
    memcpy(&sock6->sin6_addr, hp->h_addr, hp->h_length);
 
380
  } else
 
381
#endif /* IPv6 support */
 
382
  {
 
383
    memcpy(&sock4->sin_addr, hp->h_addr, hp->h_length);
 
384
  }
 
385
 
269
386
  return TRUE;
270
387
}
271
388
 
273
390
  Writes buf to socket and returns the response in an fz_FILE.
274
391
  Use only on blocking sockets.
275
392
*************************************************************************/
276
 
fz_FILE *my_querysocket(int sock, void *buf, size_t size)
 
393
fz_FILE *fc_querysocket(int sock, void *buf, size_t size)
277
394
{
278
395
  FILE *fp;
279
396
 
284
401
  }
285
402
  fflush(fp);
286
403
 
287
 
  /* we don't use my_closesocket on sock here since when fp is closed
 
404
  /* we don't use fc_closesocket on sock here since when fp is closed
288
405
   * sock will also be closed. fdopen doesn't dup the socket descriptor. */
289
406
#else
290
407
  {
312
429
      return NULL;
313
430
    }
314
431
 
315
 
    my_writesocket(sock, buf, size);
 
432
    fc_writesocket(sock, buf, size);
316
433
 
317
 
    while ((n = my_readsocket(sock, tmp, sizeof(tmp))) > 0) {
 
434
    while ((n = fc_readsocket(sock, tmp, sizeof(tmp))) > 0) {
318
435
      if (fwrite(tmp, 1, n, fp) != n) {
319
436
        die("socket %d: write error", sock);
320
437
      }
321
438
    }
322
439
    fflush(fp);
323
440
 
324
 
    my_closesocket(sock);
 
441
    fc_closesocket(sock);
325
442
 
326
443
    rewind(fp);
327
444
  }
334
451
  Returns a valid httpd server and port, plus the path to the resource
335
452
  at the url location.
336
453
*************************************************************************/
337
 
const char *my_lookup_httpd(char *server, int *port, const char *url)
 
454
const char *fc_lookup_httpd(char *server, int *port, const char *url)
338
455
{
339
456
  const char *purl, *str, *ppath, *pport;
 
457
  const char *str2;
 
458
  int chars_between = 0;
340
459
 
341
460
  if ((purl = getenv("http_proxy")) && purl[0] != '\0') {
342
461
    if (strncmp(purl, "http://", strlen("http://")) != 0) {
353
472
 
354
473
  str += strlen("http://");
355
474
 
356
 
  pport = strchr(str, ':');
357
 
  ppath = strchr(str, '/');
 
475
  if (*str == '[') {
 
476
    /* Literal IPv6 address (RFC 2732) */
 
477
    str++;
 
478
    str2 = strchr(str, ']') + 1;
 
479
    if (!str2) {
 
480
      str2 = str + strlen(str);
 
481
    }
 
482
    chars_between = 1;
 
483
  } else {
 
484
    str2 = str;
 
485
  }
 
486
 
 
487
  pport = strchr(str2, ':');
 
488
  ppath = strchr(str2, '/');
358
489
 
359
490
  /* snarf server. */
360
491
  server[0] = '\0';
361
492
 
362
493
  if (pport) {
363
 
    strncat(server, str, MIN(MAX_LEN_ADDR, pport-str));
 
494
    strncat(server, str, MIN(MAX_LEN_ADDR, pport-str-chars_between));
364
495
  } else {
365
496
    if (ppath) {
366
 
      strncat(server, str, MIN(MAX_LEN_ADDR, ppath-str));
 
497
      strncat(server, str, MIN(MAX_LEN_ADDR, ppath-str-chars_between));
367
498
    } else {
368
499
      strncat(server, str, MAX_LEN_ADDR);
369
500
    }
400
531
  URL-encode a string as per RFC 2396.
401
532
  Should work for all ASCII based charsets: including UTF-8.
402
533
***************************************************************/
403
 
const char *my_url_encode(const char *txt)
 
534
const char *fc_url_encode(const char *txt)
404
535
{
405
536
  static char buf[2048];
406
537
  unsigned ch;
436
567
  int port, s = socket(AF_INET, SOCK_STREAM, 0);
437
568
 
438
569
  for (port = starting_port;; port++) {
439
 
    union my_sockaddr tmp;
440
 
    struct sockaddr_in *sock = &tmp.sockaddr_in;
 
570
    union fc_sockaddr tmp;
 
571
    struct sockaddr_in *sock = &tmp.saddr_in4;
441
572
 
442
573
    memset(&tmp, 0, sizeof(tmp));
443
574
 
445
576
    sock->sin_port = htons(port);
446
577
    sock->sin_addr.s_addr = htonl(INADDR_ANY);
447
578
 
448
 
    if (bind(s, &tmp.sockaddr, sizeof(tmp.sockaddr)) == 0) {
 
579
    if (bind(s, &tmp.saddr, sockaddr_size(&tmp)) == 0) {
449
580
      break;
450
581
    }
451
582
  }
452
583
 
453
 
  my_closesocket(s);
 
584
  fc_closesocket(s);
454
585
  
455
586
  return port;
456
587
}