Browse code

Provide fallback implementations of getaddrinfo() and freeaddrinfo(). Patch by Martin Storsjö <$firstname()$firstname,st>.

Originally committed as revision 21145 to svn://svn.ffmpeg.org/ffmpeg/trunk

Martin Storsjö authored on 2010/01/12 02:27:07
Showing 2 changed files
... ...
@@ -68,4 +68,42 @@ static inline void ff_network_close(void)
68 68
 int inet_aton (const char * str, struct in_addr * add);
69 69
 #endif
70 70
 
71
+#if !HAVE_STRUCT_ADDRINFO
72
+struct addrinfo {
73
+    int ai_flags;
74
+    int ai_family;
75
+    int ai_socktype;
76
+    int ai_protocol;
77
+    int ai_addrlen;
78
+    struct sockaddr *ai_addr;
79
+    char *ai_canonname;
80
+    struct addrinfo *ai_next;
81
+};
82
+#endif
83
+
84
+/* getaddrinfo constants */
85
+#ifndef EAI_FAIL
86
+#define EAI_FAIL 4
87
+#endif
88
+
89
+#ifndef AI_PASSIVE
90
+#define AI_PASSIVE 1
91
+#endif
92
+
93
+#ifndef AI_CANONNAME
94
+#define AI_CANONNAME 2
95
+#endif
96
+
97
+#ifndef AI_NUMERICHOST
98
+#define AI_NUMERICHOST 4
99
+#endif
100
+
101
+#if !HAVE_GETADDRINFO
102
+int ff_getaddrinfo(const char *node, const char *service,
103
+                   const struct addrinfo *hints, struct addrinfo **res);
104
+void ff_freeaddrinfo(struct addrinfo *res);
105
+#define getaddrinfo ff_getaddrinfo
106
+#define freeaddrinfo ff_freeaddrinfo
107
+#endif
108
+
71 109
 #endif /* AVFORMAT_NETWORK_H */
... ...
@@ -60,6 +60,76 @@ int inet_aton (const char * str, struct in_addr * add)
60 60
 }
61 61
 #endif /* !HAVE_INET_ATON */
62 62
 
63
+#if !HAVE_GETADDRINFO
64
+int ff_getaddrinfo(const char *node, const char *service,
65
+                const struct addrinfo *hints, struct addrinfo **res)
66
+{
67
+    struct hostent *h = NULL;
68
+    struct addrinfo *ai;
69
+    struct sockaddr_in *sin;
70
+
71
+    sin = av_mallocz(sizeof(struct sockaddr_in));
72
+    if (!sin)
73
+        return EAI_FAIL;
74
+    sin->sin_family = AF_INET;
75
+
76
+    if (node) {
77
+        if (!inet_aton(node, &sin->sin_addr)) {
78
+            if (hints && (hints->ai_flags & AI_NUMERICHOST)) {
79
+                av_free(sin);
80
+                return EAI_FAIL;
81
+            }
82
+            h = gethostbyname(node);
83
+            if (!h) {
84
+                av_free(sin);
85
+                return EAI_FAIL;
86
+            }
87
+            memcpy(&sin->sin_addr, h->h_addr_list[0], sizeof(struct in_addr));
88
+        }
89
+    } else {
90
+        if (hints && (hints->ai_flags & AI_PASSIVE)) {
91
+            sin->sin_addr.s_addr = INADDR_ANY;
92
+        } else
93
+            sin->sin_addr.s_addr = INADDR_LOOPBACK;
94
+    }
95
+
96
+    /* Note: getaddrinfo allows service to be a string, which
97
+     * should be looked up using getservbyname. */
98
+    if (service)
99
+        sin->sin_port = htons(atoi(service));
100
+
101
+    ai = av_mallocz(sizeof(struct addrinfo));
102
+    if (!ai) {
103
+        av_free(sin);
104
+        return EAI_FAIL;
105
+    }
106
+
107
+    *res = ai;
108
+    ai->ai_family = AF_INET;
109
+    ai->ai_socktype = hints ? hints->ai_socktype : 0;
110
+    switch (ai->ai_socktype) {
111
+    case SOCK_STREAM: ai->ai_protocol = IPPROTO_TCP; break;
112
+    case SOCK_DGRAM:  ai->ai_protocol = IPPROTO_UDP; break;
113
+    default:          ai->ai_protocol = 0;           break;
114
+    }
115
+
116
+    ai->ai_addr = (struct sockaddr *)sin;
117
+    ai->ai_addrlen = sizeof(struct sockaddr_in);
118
+    if (hints && (hints->ai_flags & AI_CANONNAME))
119
+        ai->ai_canonname = h ? av_strdup(h->h_name) : NULL;
120
+
121
+    ai->ai_next = NULL;
122
+    return 0;
123
+}
124
+
125
+void ff_freeaddrinfo(struct addrinfo *res)
126
+{
127
+    av_free(res->ai_canonname);
128
+    av_free(res->ai_addr);
129
+    av_free(res);
130
+}
131
+#endif
132
+
63 133
 /* resolve host with also IP address parsing */
64 134
 int resolve_host(struct in_addr *sin_addr, const char *hostname)
65 135
 {