* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#define HAVE_AV_CONFIG_H
+
+#include "config.h"
+#if HAVE_CLOSESOCKET != 1
+#define closesocket close
+#endif
+#include <string.h>
+#include <stdlib.h>
#include "avformat.h"
#include <stdarg.h>
#include <sys/time.h>
#undef time //needed because HAVE_AV_CONFIG_H is defined on top
#include <time.h>
-#include <sys/types.h>
-#include <sys/socket.h>
#include <sys/wait.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
#include <signal.h>
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif
+#include "network.h"
#include "version.h"
#include "ffserver.h"
#include "random.h"
+#include "avstring.h"
#undef exit
float avg_frame_size; /* frame size averraged over last frames with exponential mean */
} FeedData;
-struct sockaddr_in my_http_addr;
-struct sockaddr_in my_rtsp_addr;
+static struct sockaddr_in my_http_addr;
+static struct sockaddr_in my_rtsp_addr;
static char logfilename[1024];
static HTTPContext *first_http_ctx;
close(i);
}
- pstrcpy(pathname, sizeof(pathname), my_program_name);
+ av_strlcpy(pathname, my_program_name, sizeof(pathname));
slash = strrchr(pathname, '/');
if (!slash) {
closesocket(server_fd);
return -1;
}
- fcntl(server_fd, F_SETFL, O_NONBLOCK);
+ ff_socket_nonblock(server_fd, 1);
return server_fd;
}
second to handle timeouts */
do {
ret = poll(poll_table, poll_entry - poll_table, delay);
- if (ret < 0 && errno != EAGAIN && errno != EINTR)
+ if (ret < 0 && ff_neterrno() != FF_NETERROR(EAGAIN) &&
+ ff_neterrno() != FF_NETERROR(EINTR))
return -1;
} while (ret < 0);
&len);
if (fd < 0)
return;
- fcntl(fd, F_SETFL, O_NONBLOCK);
+ ff_socket_nonblock(fd, 1);
/* XXX: should output a warning page when coming
close to the connection limit */
read_loop:
len = recv(c->fd, c->buffer_ptr, 1, 0);
if (len < 0) {
- if (errno != EAGAIN && errno != EINTR)
+ if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
+ ff_neterrno() != FF_NETERROR(EINTR))
return -1;
} else if (len == 0) {
return -1;
return 0;
len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
if (len < 0) {
- if (errno != EAGAIN && errno != EINTR) {
+ if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
+ ff_neterrno() != FF_NETERROR(EINTR)) {
/* error : close connection */
av_freep(&c->pb_buffer);
return -1;
return 0;
len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
if (len < 0) {
- if (errno != EAGAIN && errno != EINTR) {
+ if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
+ ff_neterrno() != FF_NETERROR(EINTR)) {
/* error : close connection */
av_freep(&c->pb_buffer);
return -1;
len = send(c->fd, c->packet_buffer_ptr,
c->packet_buffer_end - c->packet_buffer_ptr, 0);
if (len < 0) {
- if (errno != EAGAIN && errno != EINTR) {
+ if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
+ ff_neterrno() != FF_NETERROR(EINTR)) {
/* error : close connection */
av_freep(&c->packet_buffer);
return -1;
enum IPAddressAction last_action = IP_DENY;
IPAddressACL *acl;
struct in_addr *src = &c->from_addr.sin_addr;
- unsigned long src_addr = ntohl(src->s_addr);
+ unsigned long src_addr = src->s_addr;
for (acl = stream->acl; acl; acl = acl->next) {
if (src_addr >= acl->first.s_addr && src_addr <= acl->last.s_addr) {
FFStream *stream;
/* compute filename by matching without the file extensions */
- pstrcpy(file1, sizeof(file1), filename);
+ av_strlcpy(file1, filename, sizeof(file1));
p = strrchr(file1, '.');
if (p)
*p = '\0';
for(stream = first_stream; stream != NULL; stream = stream->next) {
- pstrcpy(file2, sizeof(file2), stream->filename);
+ av_strlcpy(file2, stream->filename, sizeof(file2));
p = strrchr(file2, '.');
if (p)
*p = '\0';
if (!strcmp(file1, file2)) {
- pstrcpy(filename, max_size, stream->filename);
+ av_strlcpy(filename, stream->filename, max_size);
break;
}
}
p = c->buffer;
get_word(cmd, sizeof(cmd), (const char **)&p);
- pstrcpy(c->method, sizeof(c->method), cmd);
+ av_strlcpy(c->method, cmd, sizeof(c->method));
if (!strcmp(cmd, "GET"))
c->post = 0;
return -1;
get_word(url, sizeof(url), (const char **)&p);
- pstrcpy(c->url, sizeof(c->url), url);
+ av_strlcpy(c->url, url, sizeof(c->url));
get_word(protocol, sizeof(protocol), (const char **)&p);
if (strcmp(protocol, "HTTP/1.0") && strcmp(protocol, "HTTP/1.1"))
return -1;
- pstrcpy(c->protocol, sizeof(c->protocol), protocol);
+ av_strlcpy(c->protocol, protocol, sizeof(c->protocol));
if (ffserver_debug)
http_log("New connection: %s %s\n", cmd, url);
/* find the filename and the optional info string in the request */
p = strchr(url, '?');
if (p) {
- pstrcpy(info, sizeof(info), p);
+ av_strlcpy(info, p, sizeof(info));
*p = '\0';
} else {
info[0] = '\0';
}
- pstrcpy(filename, sizeof(filename)-1, url + ((*url == '/') ? 1 : 0));
+ av_strlcpy(filename, url + ((*url == '/') ? 1 : 0), sizeof(filename)-1);
for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
if (strncasecmp(p, "User-Agent:", 11) == 0) {
// "redirect" / request to index.html
if (!strlen(filename))
- pstrcpy(filename, sizeof(filename) - 1, "index.html");
+ av_strlcpy(filename, "index.html", sizeof(filename) - 1);
stream = first_stream;
while (stream != NULL) {
}
}
- /* If already streaming this feed, dont let start an another feeder */
+ /* If already streaming this feed, do not let start another feeder. */
if (stream->feed_opened) {
snprintf(msg, sizeof(msg), "This feed is already being received.");
goto send_error;
{
char hostname[256], *p;
/* extract only hostname */
- pstrcpy(hostname, sizeof(hostname), hostbuf);
+ av_strlcpy(hostname, hostbuf, sizeof(hostname));
p = strrchr(hostname, ':');
if (p)
*p = '\0';
}
break;
default:
- av_abort();
+ abort();
break;
}
char *eosf;
if (stream->feed != stream) {
- pstrcpy(sfilename, sizeof(sfilename) - 10, stream->filename);
+ av_strlcpy(sfilename, stream->filename, sizeof(sfilename) - 10);
eosf = sfilename + strlen(sfilename);
if (eosf - sfilename >= 4) {
if (strcmp(eosf - 4, ".asf") == 0) {
video_bit_rate += st->codec->bit_rate;
break;
default:
- av_abort();
+ abort();
}
}
url_fprintf(pb, "<TD align=center> %s <TD align=right> %d <TD align=right> %d <TD> %s %s <TD align=right> %d <TD> %s %s",
st->codec->qmin, st->codec->qmax, st->codec->time_base.den / st->codec->time_base.num);
break;
default:
- av_abort();
+ abort();
}
url_fprintf(pb, "<tr><td align=right>%d<td>%s<td align=right>%d<td>%s<td>%s\n",
i, type, st->codec->bit_rate/1000, codec ? codec->name : "", parameters);
switch(c->state) {
case HTTPSTATE_SEND_DATA_HEADER:
memset(&c->fmt_ctx, 0, sizeof(c->fmt_ctx));
- pstrcpy(c->fmt_ctx.author, sizeof(c->fmt_ctx.author),
- c->stream->author);
- pstrcpy(c->fmt_ctx.comment, sizeof(c->fmt_ctx.comment),
- c->stream->comment);
- pstrcpy(c->fmt_ctx.copyright, sizeof(c->fmt_ctx.copyright),
- c->stream->copyright);
- pstrcpy(c->fmt_ctx.title, sizeof(c->fmt_ctx.title),
- c->stream->title);
+ av_strlcpy(c->fmt_ctx.author, c->stream->author,
+ sizeof(c->fmt_ctx.author));
+ av_strlcpy(c->fmt_ctx.comment, c->stream->comment,
+ sizeof(c->fmt_ctx.comment));
+ av_strlcpy(c->fmt_ctx.copyright, c->stream->copyright,
+ sizeof(c->fmt_ctx.copyright));
+ av_strlcpy(c->fmt_ctx.title, c->stream->title,
+ sizeof(c->fmt_ctx.title));
/* open output stream by using specified codecs */
c->fmt_ctx.oformat = c->stream->fmt;
/* TCP data output */
len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
if (len < 0) {
- if (errno != EAGAIN && errno != EINTR) {
+ if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
+ ff_neterrno() != FF_NETERROR(EINTR)) {
/* error : close connection */
return -1;
} else {
len = recv(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
if (len < 0) {
- if (errno != EAGAIN && errno != EINTR) {
+ if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
+ ff_neterrno() != FF_NETERROR(EINTR)) {
/* error : close connection */
goto fail;
}
get_word(url, sizeof(url), &p);
get_word(protocol, sizeof(protocol), &p);
- pstrcpy(c->method, sizeof(c->method), cmd);
- pstrcpy(c->url, sizeof(c->url), url);
- pstrcpy(c->protocol, sizeof(c->protocol), protocol);
+ av_strlcpy(c->method, cmd, sizeof(c->method));
+ av_strlcpy(c->url, url, sizeof(c->url));
+ av_strlcpy(c->protocol, protocol, sizeof(c->protocol));
c->pb = &pb1;
if (url_open_dyn_buf(c->pb) < 0) {
return;
}
- pstrcpy(session_id, sizeof(session_id), rtp_c->session_id);
+ av_strlcpy(session_id, rtp_c->session_id, sizeof(session_id));
/* abort the session */
close_connection(rtp_c);
goto fail;
nb_connections++;
c->stream = stream;
- pstrcpy(c->session_id, sizeof(c->session_id), session_id);
+ av_strlcpy(c->session_id, session_id, sizeof(c->session_id));
c->state = HTTPSTATE_READY;
c->is_packetized = 1;
c->rtp_protocol = rtp_protocol;
proto_str = "???";
break;
}
- pstrcpy(c->protocol, sizeof(c->protocol), "RTP/");
- pstrcat(c->protocol, sizeof(c->protocol), proto_str);
+ av_strlcpy(c->protocol, "RTP/", sizeof(c->protocol));
+ av_strlcat(c->protocol, proto_str, sizeof(c->protocol));
current_bandwidth += stream->bandwidth;
c->stream->feed->streams[c->stream->feed_streams[stream_index]],
sizeof(AVStream));
}
+ st->priv_data = NULL;
/* build destination RTP address */
ipaddr = inet_ntoa(dest_addr->sin_addr);
goto found;
break;
default:
- av_abort();
+ abort();
}
}
}
break;
default:
- av_abort();
+ abort();
}
st = av_mallocz(sizeof(AVStream));
if (!strcasecmp(cmd, "Port")) {
get_arg(arg, sizeof(arg), &p);
- my_http_addr.sin_port = htons (atoi(arg));
+ val = atoi(arg);
+ if (val < 1 || val > 65536) {
+ fprintf(stderr, "%s:%d: Invalid port: %s\n",
+ filename, line_num, arg);
+ errors++;
+ }
+ my_http_addr.sin_port = htons(val);
} else if (!strcasecmp(cmd, "BindAddress")) {
get_arg(arg, sizeof(arg), &p);
- if (!inet_aton(arg, &my_http_addr.sin_addr)) {
- fprintf(stderr, "%s:%d: Invalid IP address: %s\n",
+ if (resolve_host(&my_http_addr.sin_addr, arg) != 0) {
+ fprintf(stderr, "%s:%d: Invalid host/IP address: %s\n",
filename, line_num, arg);
errors++;
}
ffserver_daemon = 0;
} else if (!strcasecmp(cmd, "RTSPPort")) {
get_arg(arg, sizeof(arg), &p);
- my_rtsp_addr.sin_port = htons (atoi(arg));
+ val = atoi(arg);
+ if (val < 1 || val > 65536) {
+ fprintf(stderr, "%s:%d: Invalid port: %s\n",
+ filename, line_num, arg);
+ errors++;
+ }
+ my_rtsp_addr.sin_port = htons(atoi(arg));
} else if (!strcasecmp(cmd, "RTSPBindAddress")) {
get_arg(arg, sizeof(arg), &p);
- if (!inet_aton(arg, &my_rtsp_addr.sin_addr)) {
- fprintf(stderr, "%s:%d: Invalid IP address: %s\n",
+ if (resolve_host(&my_rtsp_addr.sin_addr, arg) != 0) {
+ fprintf(stderr, "%s:%d: Invalid host/IP address: %s\n",
filename, line_num, arg);
errors++;
}
feed->child_argv = (char **) av_mallocz(64 * sizeof(char *));
for (i = 0; i < 62; i++) {
- char argbuf[256];
-
- get_arg(argbuf, sizeof(argbuf), &p);
- if (!argbuf[0])
+ get_arg(arg, sizeof(arg), &p);
+ if (!arg[0])
break;
- feed->child_argv[i] = av_malloc(strlen(argbuf) + 1);
- strcpy(feed->child_argv[i], argbuf);
+ feed->child_argv[i] = av_strdup(arg);
}
feed->child_argv[i] = av_malloc(30 + strlen(feed->filename));
} else if (!strcasecmp(cmd, "VideoSize")) {
get_arg(arg, sizeof(arg), &p);
if (stream) {
- parse_image_size(&video_enc.width, &video_enc.height, arg);
+ av_parse_video_frame_size(&video_enc.width, &video_enc.height, arg);
if ((video_enc.width % 16) != 0 ||
(video_enc.height % 16) != 0) {
fprintf(stderr, "%s:%d: Image size must be a multiple of 16\n",
audio_id = CODEC_ID_NONE;
} else if (!strcasecmp(cmd, "ACL")) {
IPAddressACL acl;
- struct hostent *he;
get_arg(arg, sizeof(arg), &p);
if (strcasecmp(arg, "allow") == 0) {
get_arg(arg, sizeof(arg), &p);
- he = gethostbyname(arg);
- if (!he) {
+ if (resolve_host(&acl.first, arg) != 0) {
fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n",
filename, line_num, arg);
errors++;
} else {
- /* Only take the first */
- acl.first.s_addr = ntohl(((struct in_addr *) he->h_addr_list[0])->s_addr);
acl.last = acl.first;
}
get_arg(arg, sizeof(arg), &p);
if (arg[0]) {
- he = gethostbyname(arg);
- if (!he) {
+ if (resolve_host(&acl.last, arg) != 0) {
fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n",
filename, line_num, arg);
errors++;
- } else {
- /* Only take the first */
- acl.last.s_addr = ntohl(((struct in_addr *) he->h_addr_list[0])->s_addr);
}
}
} else if (!strcasecmp(cmd, "MulticastAddress")) {
get_arg(arg, sizeof(arg), &p);
if (stream) {
- if (!inet_aton(arg, &stream->multicast_ip)) {
- fprintf(stderr, "%s:%d: Invalid IP address: %s\n",
+ if (resolve_host(&stream->multicast_ip, arg) != 0) {
+ fprintf(stderr, "%s:%d: Invalid host/IP address: %s\n",
filename, line_num, arg);
errors++;
}
"\n"
"You should have received a copy of the GNU Lesser General Public\n"
"License along with FFmpeg; if not, write to the Free Software\n"
- "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n"
);
}