00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #define _SVID_SOURCE
00025 #define _DARWIN_C_SOURCE
00026
00027 #include "config.h"
00028 #include "avformat.h"
00029 #include <unistd.h>
00030 #include <fcntl.h>
00031 #include <sys/time.h>
00032 #include "os_support.h"
00033
00034 #if CONFIG_NETWORK
00035 #if !HAVE_POLL_H
00036 #if HAVE_WINSOCK2_H
00037 #include <winsock2.h>
00038 #elif HAVE_SYS_SELECT_H
00039 #include <sys/select.h>
00040 #endif
00041 #endif
00042
00043 #include "network.h"
00044
00045 #if !HAVE_INET_ATON
00046 #include <stdlib.h>
00047 #include <strings.h>
00048
00049 int ff_inet_aton (const char * str, struct in_addr * add)
00050 {
00051 unsigned int add1 = 0, add2 = 0, add3 = 0, add4 = 0;
00052
00053 if (sscanf(str, "%d.%d.%d.%d", &add1, &add2, &add3, &add4) != 4)
00054 return 0;
00055
00056 if (!add1 || (add1|add2|add3|add4) > 255) return 0;
00057
00058 add->s_addr = htonl((add1 << 24) + (add2 << 16) + (add3 << 8) + add4);
00059
00060 return 1;
00061 }
00062 #else
00063 int ff_inet_aton (const char * str, struct in_addr * add)
00064 {
00065 return inet_aton(str, add);
00066 }
00067 #endif
00068
00069 #if !HAVE_GETADDRINFO
00070 int ff_getaddrinfo(const char *node, const char *service,
00071 const struct addrinfo *hints, struct addrinfo **res)
00072 {
00073 struct hostent *h = NULL;
00074 struct addrinfo *ai;
00075 struct sockaddr_in *sin;
00076
00077 #if HAVE_WINSOCK2_H
00078 int (WSAAPI *win_getaddrinfo)(const char *node, const char *service,
00079 const struct addrinfo *hints,
00080 struct addrinfo **res);
00081 HMODULE ws2mod = GetModuleHandle("ws2_32.dll");
00082 win_getaddrinfo = GetProcAddress(ws2mod, "getaddrinfo");
00083 if (win_getaddrinfo)
00084 return win_getaddrinfo(node, service, hints, res);
00085 #endif
00086
00087 *res = NULL;
00088 sin = av_mallocz(sizeof(struct sockaddr_in));
00089 if (!sin)
00090 return EAI_FAIL;
00091 sin->sin_family = AF_INET;
00092
00093 if (node) {
00094 if (!ff_inet_aton(node, &sin->sin_addr)) {
00095 if (hints && (hints->ai_flags & AI_NUMERICHOST)) {
00096 av_free(sin);
00097 return EAI_FAIL;
00098 }
00099 h = gethostbyname(node);
00100 if (!h) {
00101 av_free(sin);
00102 return EAI_FAIL;
00103 }
00104 memcpy(&sin->sin_addr, h->h_addr_list[0], sizeof(struct in_addr));
00105 }
00106 } else {
00107 if (hints && (hints->ai_flags & AI_PASSIVE)) {
00108 sin->sin_addr.s_addr = INADDR_ANY;
00109 } else
00110 sin->sin_addr.s_addr = INADDR_LOOPBACK;
00111 }
00112
00113
00114
00115 if (service)
00116 sin->sin_port = htons(atoi(service));
00117
00118 ai = av_mallocz(sizeof(struct addrinfo));
00119 if (!ai) {
00120 av_free(sin);
00121 return EAI_FAIL;
00122 }
00123
00124 *res = ai;
00125 ai->ai_family = AF_INET;
00126 ai->ai_socktype = hints ? hints->ai_socktype : 0;
00127 switch (ai->ai_socktype) {
00128 case SOCK_STREAM: ai->ai_protocol = IPPROTO_TCP; break;
00129 case SOCK_DGRAM: ai->ai_protocol = IPPROTO_UDP; break;
00130 default: ai->ai_protocol = 0; break;
00131 }
00132
00133 ai->ai_addr = (struct sockaddr *)sin;
00134 ai->ai_addrlen = sizeof(struct sockaddr_in);
00135 if (hints && (hints->ai_flags & AI_CANONNAME))
00136 ai->ai_canonname = h ? av_strdup(h->h_name) : NULL;
00137
00138 ai->ai_next = NULL;
00139 return 0;
00140 }
00141
00142 void ff_freeaddrinfo(struct addrinfo *res)
00143 {
00144 #if HAVE_WINSOCK2_H
00145 void (WSAAPI *win_freeaddrinfo)(struct addrinfo *res);
00146 HMODULE ws2mod = GetModuleHandle("ws2_32.dll");
00147 win_freeaddrinfo = (void (WSAAPI *)(struct addrinfo *res))
00148 GetProcAddress(ws2mod, "freeaddrinfo");
00149 if (win_freeaddrinfo) {
00150 win_freeaddrinfo(res);
00151 return;
00152 }
00153 #endif
00154
00155 av_free(res->ai_canonname);
00156 av_free(res->ai_addr);
00157 av_free(res);
00158 }
00159
00160 int ff_getnameinfo(const struct sockaddr *sa, int salen,
00161 char *host, int hostlen,
00162 char *serv, int servlen, int flags)
00163 {
00164 const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
00165
00166 #if HAVE_WINSOCK2_H
00167 int (WSAAPI *win_getnameinfo)(const struct sockaddr *sa, socklen_t salen,
00168 char *host, DWORD hostlen,
00169 char *serv, DWORD servlen, int flags);
00170 HMODULE ws2mod = GetModuleHandle("ws2_32.dll");
00171 win_getnameinfo = GetProcAddress(ws2mod, "getnameinfo");
00172 if (win_getnameinfo)
00173 return win_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
00174 #endif
00175
00176 if (sa->sa_family != AF_INET)
00177 return EAI_FAMILY;
00178 if (!host && !serv)
00179 return EAI_NONAME;
00180
00181 if (host && hostlen > 0) {
00182 struct hostent *ent = NULL;
00183 uint32_t a;
00184 if (!(flags & NI_NUMERICHOST))
00185 ent = gethostbyaddr((const char *)&sin->sin_addr,
00186 sizeof(sin->sin_addr), AF_INET);
00187
00188 if (ent) {
00189 snprintf(host, hostlen, "%s", ent->h_name);
00190 } else if (flags & NI_NAMERQD) {
00191 return EAI_NONAME;
00192 } else {
00193 a = ntohl(sin->sin_addr.s_addr);
00194 snprintf(host, hostlen, "%d.%d.%d.%d",
00195 ((a >> 24) & 0xff), ((a >> 16) & 0xff),
00196 ((a >> 8) & 0xff), ( a & 0xff));
00197 }
00198 }
00199
00200 if (serv && servlen > 0) {
00201 struct servent *ent = NULL;
00202 if (!(flags & NI_NUMERICSERV))
00203 ent = getservbyport(sin->sin_port, flags & NI_DGRAM ? "udp" : "tcp");
00204
00205 if (ent) {
00206 snprintf(serv, servlen, "%s", ent->s_name);
00207 } else
00208 snprintf(serv, servlen, "%d", ntohs(sin->sin_port));
00209 }
00210
00211 return 0;
00212 }
00213
00214 const char *ff_gai_strerror(int ecode)
00215 {
00216 switch(ecode) {
00217 case EAI_FAIL : return "A non-recoverable error occurred";
00218 case EAI_FAMILY : return "The address family was not recognized or the address length was invalid for the specified family";
00219 case EAI_NONAME : return "The name does not resolve for the supplied parameters";
00220 }
00221
00222 return "Unknown error";
00223 }
00224 #endif
00225
00226 int ff_socket_nonblock(int socket, int enable)
00227 {
00228 #if HAVE_WINSOCK2_H
00229 return ioctlsocket(socket, FIONBIO, &enable);
00230 #else
00231 if (enable)
00232 return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) | O_NONBLOCK);
00233 else
00234 return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) & ~O_NONBLOCK);
00235 #endif
00236 }
00237 #endif
00238
00239 #if CONFIG_FFSERVER
00240 #if !HAVE_POLL_H
00241 int poll(struct pollfd *fds, nfds_t numfds, int timeout)
00242 {
00243 fd_set read_set;
00244 fd_set write_set;
00245 fd_set exception_set;
00246 nfds_t i;
00247 int n;
00248 int rc;
00249
00250 #if HAVE_WINSOCK2_H
00251 if (numfds >= FD_SETSIZE) {
00252 errno = EINVAL;
00253 return -1;
00254 }
00255 #endif
00256
00257 FD_ZERO(&read_set);
00258 FD_ZERO(&write_set);
00259 FD_ZERO(&exception_set);
00260
00261 n = -1;
00262 for(i = 0; i < numfds; i++) {
00263 if (fds[i].fd < 0)
00264 continue;
00265 #if !HAVE_WINSOCK2_H
00266 if (fds[i].fd >= FD_SETSIZE) {
00267 errno = EINVAL;
00268 return -1;
00269 }
00270 #endif
00271
00272 if (fds[i].events & POLLIN) FD_SET(fds[i].fd, &read_set);
00273 if (fds[i].events & POLLOUT) FD_SET(fds[i].fd, &write_set);
00274 if (fds[i].events & POLLERR) FD_SET(fds[i].fd, &exception_set);
00275
00276 if (fds[i].fd > n)
00277 n = fds[i].fd;
00278 };
00279
00280 if (n == -1)
00281
00282 return 0;
00283
00284 if (timeout < 0)
00285 rc = select(n+1, &read_set, &write_set, &exception_set, NULL);
00286 else {
00287 struct timeval tv;
00288
00289 tv.tv_sec = timeout / 1000;
00290 tv.tv_usec = 1000 * (timeout % 1000);
00291 rc = select(n+1, &read_set, &write_set, &exception_set, &tv);
00292 };
00293
00294 if (rc < 0)
00295 return rc;
00296
00297 for(i = 0; i < (nfds_t) n; i++) {
00298 fds[i].revents = 0;
00299
00300 if (FD_ISSET(fds[i].fd, &read_set)) fds[i].revents |= POLLIN;
00301 if (FD_ISSET(fds[i].fd, &write_set)) fds[i].revents |= POLLOUT;
00302 if (FD_ISSET(fds[i].fd, &exception_set)) fds[i].revents |= POLLERR;
00303 };
00304
00305 return rc;
00306 }
00307 #endif
00308 #endif
00309