Mercurial > libavformat.hg
comparison tcp.c @ 0:05318cf2e886 libavformat
renamed libav to libavformat
author | bellard |
---|---|
date | Mon, 25 Nov 2002 19:07:40 +0000 |
parents | |
children | a58a8a53eb46 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:05318cf2e886 |
---|---|
1 /* | |
2 * TCP protocol | |
3 * Copyright (c) 2002 Fabrice Bellard. | |
4 * | |
5 * This library is free software; you can redistribute it and/or | |
6 * modify it under the terms of the GNU Lesser General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2 of the License, or (at your option) any later version. | |
9 * | |
10 * This library is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * Lesser General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU Lesser General Public | |
16 * License along with this library; if not, write to the Free Software | |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 */ | |
19 #include "avformat.h" | |
20 #include <unistd.h> | |
21 #include <ctype.h> | |
22 #include <sys/types.h> | |
23 #include <sys/socket.h> | |
24 #include <netinet/in.h> | |
25 #ifndef __BEOS__ | |
26 # include <arpa/inet.h> | |
27 #else | |
28 # include "barpainet.h" | |
29 #endif | |
30 #include <netdb.h> | |
31 | |
32 typedef struct TCPContext { | |
33 int fd; | |
34 } TCPContext; | |
35 | |
36 /* resolve host with also IP address parsing */ | |
37 int resolve_host(struct in_addr *sin_addr, const char *hostname) | |
38 { | |
39 struct hostent *hp; | |
40 | |
41 if ((inet_aton(hostname, sin_addr)) == 0) { | |
42 hp = gethostbyname(hostname); | |
43 if (!hp) | |
44 return -1; | |
45 memcpy (sin_addr, hp->h_addr, sizeof(struct in_addr)); | |
46 } | |
47 return 0; | |
48 } | |
49 | |
50 /* return non zero if error */ | |
51 static int tcp_open(URLContext *h, const char *uri, int flags) | |
52 { | |
53 struct sockaddr_in dest_addr; | |
54 char hostname[1024], *q; | |
55 int port, fd = -1; | |
56 TCPContext *s; | |
57 const char *p; | |
58 | |
59 s = av_malloc(sizeof(TCPContext)); | |
60 if (!s) | |
61 return -ENOMEM; | |
62 h->priv_data = s; | |
63 p = uri; | |
64 if (!strstart(p, "tcp://", &p)) | |
65 goto fail; | |
66 q = hostname; | |
67 while (*p != ':' && *p != '/' && *p != '\0') { | |
68 if ((q - hostname) < sizeof(hostname) - 1) | |
69 *q++ = *p; | |
70 p++; | |
71 } | |
72 *q = '\0'; | |
73 if (*p != ':') | |
74 goto fail; | |
75 p++; | |
76 port = strtoul(p, (char **)&p, 10); | |
77 if (port <= 0 || port >= 65536) | |
78 goto fail; | |
79 | |
80 dest_addr.sin_family = AF_INET; | |
81 dest_addr.sin_port = htons(port); | |
82 if (resolve_host(&dest_addr.sin_addr, hostname) < 0) | |
83 goto fail; | |
84 | |
85 fd = socket(PF_INET, SOCK_STREAM, 0); | |
86 if (fd < 0) | |
87 goto fail; | |
88 | |
89 if (connect(fd, (struct sockaddr *)&dest_addr, | |
90 sizeof(dest_addr)) < 0) | |
91 goto fail; | |
92 | |
93 s->fd = fd; | |
94 return 0; | |
95 | |
96 fail: | |
97 if (fd >= 0) | |
98 close(fd); | |
99 av_free(s); | |
100 return -EIO; | |
101 } | |
102 | |
103 static int tcp_read(URLContext *h, UINT8 *buf, int size) | |
104 { | |
105 TCPContext *s = h->priv_data; | |
106 int size1, len; | |
107 | |
108 size1 = size; | |
109 while (size > 0) { | |
110 #ifdef CONFIG_BEOS_NETSERVER | |
111 len = recv (s->fd, buf, size, 0); | |
112 #else | |
113 len = read (s->fd, buf, size); | |
114 #endif | |
115 if (len < 0) { | |
116 if (errno != EINTR && errno != EAGAIN) | |
117 #ifdef __BEOS__ | |
118 return errno; | |
119 #else | |
120 return -errno; | |
121 #endif | |
122 else | |
123 continue; | |
124 } else if (len == 0) { | |
125 break; | |
126 } | |
127 size -= len; | |
128 buf += len; | |
129 } | |
130 return size1 - size; | |
131 } | |
132 | |
133 static int tcp_write(URLContext *h, UINT8 *buf, int size) | |
134 { | |
135 TCPContext *s = h->priv_data; | |
136 int ret, size1; | |
137 | |
138 size1 = size; | |
139 while (size > 0) { | |
140 #ifdef CONFIG_BEOS_NETSERVER | |
141 ret = send (s->fd, buf, size, 0); | |
142 #else | |
143 ret = write (s->fd, buf, size); | |
144 #endif | |
145 if (ret < 0 && errno != EINTR && errno != EAGAIN) | |
146 #ifdef __BEOS__ | |
147 return errno; | |
148 #else | |
149 return -errno; | |
150 #endif | |
151 size -= ret; | |
152 buf += ret; | |
153 } | |
154 return size1 - size; | |
155 } | |
156 | |
157 static int tcp_close(URLContext *h) | |
158 { | |
159 TCPContext *s = h->priv_data; | |
160 #ifdef CONFIG_BEOS_NETSERVER | |
161 closesocket(s->fd); | |
162 #else | |
163 close(s->fd); | |
164 #endif | |
165 av_free(s); | |
166 return 0; | |
167 } | |
168 | |
169 URLProtocol tcp_protocol = { | |
170 "tcp", | |
171 tcp_open, | |
172 tcp_read, | |
173 tcp_write, | |
174 NULL, /* seek */ | |
175 tcp_close, | |
176 }; |