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