~vcs-imports/gawk/master

« back to all changes in this revision

Viewing changes to missing_d/getaddrinfo.c

  • Committer: Arnold D. Robbins
  • Date: 2010-07-16 11:49:57 UTC
  • Revision ID: git-v1:6a2caf2157d87b4b582b2494bdd7d6a688dd0b1f
Tags: gawk-3.1.6
Move to gawk-3.1.6.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef HAVE_SOCKETS
 
2
#error getaddrinfo.c included by mistake! no socket support!
 
3
#else
 
4
#include <sys/types.h>
 
5
#include <sys/socket.h>
 
6
#ifdef HAVE_NETDB_H
 
7
#include <netdb.h>
 
8
#endif
 
9
#ifdef HAVE_NETINET_IN_H
 
10
#include <netinet/in.h>
 
11
#endif
 
12
#ifdef HAVE_ARPA_INET_H
 
13
#include <arpa/inet.h>
 
14
#endif
 
15
 
 
16
#include "getaddrinfo.h"
 
17
 
 
18
void
 
19
freeaddrinfo(struct addrinfo *res)
 
20
{
 
21
        if (res->ai_addr != NULL)
 
22
                free(res->ai_addr);
 
23
        free(res);
 
24
}
 
25
 
 
26
int
 
27
getaddrinfo(const char *hostname, const char *portname,
 
28
        struct addrinfo *hints, struct addrinfo **res)
 
29
{
 
30
        struct addrinfo *out;
 
31
        if (res == NULL)
 
32
                return -1;
 
33
 
 
34
        out = (struct addrinfo *) malloc(sizeof(*out));
 
35
        if (out == NULL) {
 
36
                *res = NULL;
 
37
                return -1;
 
38
        }
 
39
        memset(out, '\0', sizeof(*out));
 
40
 
 
41
        out->ai_addr = (struct sockaddr *) malloc(sizeof(struct sockaddr_in));
 
42
        if (out->ai_addr == NULL) {
 
43
                free(out);
 
44
                *res = NULL;
 
45
                return -1;
 
46
        }
 
47
 
 
48
        out->ai_socktype = SOCK_STREAM;
 
49
        if (hints != NULL) {
 
50
                if (hints->ai_socktype)
 
51
                        out->ai_socktype = hints->ai_socktype;
 
52
                if (hints->ai_protocol)
 
53
                        out->ai_protocol = hints->ai_protocol;
 
54
        }
 
55
 
 
56
        if (out->ai_protocol == 0) {
 
57
                switch (out->ai_socktype) {
 
58
                case SOCK_STREAM:
 
59
                        out->ai_protocol = IPPROTO_TCP;
 
60
                        break;
 
61
                case SOCK_DGRAM:
 
62
                        out->ai_protocol = IPPROTO_UDP;
 
63
                        break;
 
64
                case SOCK_RAW:
 
65
                        out->ai_protocol = IPPROTO_RAW;
 
66
                        break;
 
67
                }
 
68
        }
 
69
 
 
70
        out->ai_addrlen = sizeof(struct sockaddr_in);
 
71
        memset(out->ai_addr, '\0', sizeof(struct sockaddr_in));
 
72
 
 
73
        if (hostname != NULL) {
 
74
                struct hostent *he;
 
75
                he = gethostbyname(hostname);
 
76
                if (he != NULL && he->h_addr_list != NULL) {
 
77
                        ((struct sockaddr_in *)out->ai_addr)->sin_addr.s_addr
 
78
                                = ((struct in_addr *)he->h_addr_list[0])->s_addr;
 
79
                } else {
 
80
                        freeaddrinfo(out);
 
81
                        return -1;
 
82
                }
 
83
        } else {
 
84
                if (!(out->ai_flags & AI_PASSIVE))
 
85
                        ((struct sockaddr_in *)out->ai_addr)->sin_addr.s_addr
 
86
                                                        = htonl(INADDR_ANY);
 
87
        }
 
88
        ((struct sockaddr_in *)out->ai_addr)->sin_family = AF_INET;
 
89
        out->ai_family = AF_INET;
 
90
 
 
91
        if (portname != NULL && *portname) {
 
92
                long portnum;
 
93
                char *end;
 
94
                portnum = strtol(portname, &end, 10);
 
95
                if (*end == '\0' && portnum > 0 && portnum < 65536) {
 
96
                        ((struct sockaddr_in *)out->ai_addr)->sin_port
 
97
                                                        = htons(portnum);
 
98
                } else {
 
99
                        struct servent *se;
 
100
                        se = getservbyname(portname, NULL);
 
101
                        if (se != NULL) {
 
102
                                ((struct sockaddr_in *)out->ai_addr)->sin_port
 
103
                                                        = se->s_port;
 
104
                        }
 
105
                }
 
106
        }
 
107
 
 
108
        *res = out;
 
109
 
 
110
        return 0;
 
111
}
 
112
#endif