This just made my day.
-----Original Message-----
From: "Ted Unangst" <[email protected]>
Sent: 11/20/2014 6:26 PM
To: "[email protected]" <[email protected]>
Subject: httpd errata
[on behalf of reyk]
Many people want to test the new httpd in OpenBSD 5.6; so we decided
to provide various improvements from -current for 5.6.
See the description below for more details.
untrusted comment: signature from openbsd 5.6 base private key
RWR0EANmo9nqhn3Gnfk2/2x+xII6do92zreKp/t5zOwfkVgsQAI4ZCPkWAazbbnWNV7Ptkle876f/kb6C2KuvnTqvwUItsyvogA=
OpenBSD 5.6 errata 9, Nov 18, 2014: httpd was developed very rapidly
in the weeks before 5.6 release, and it has a few flaws. It would be
nice to get these flaws fully remediated before the next release, and
that requires the community to want to use it. Therefore here is a
"jumbo" patch that brings in the most important fixes.
Apply patch using:
signify -Vep /etc/signify/openbsd-56-base.pub -x 009_httpd.patch.sig \
-m - | (cd /usr/src && patch -p0)
Then build and install httpd:
cd /usr/src/usr.sbin/httpd
make obj
make
make install
Index: usr.sbin/httpd/config.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/config.c,v
retrieving revision 1.21
diff -u -p -r1.21 config.c
--- usr.sbin/httpd/config.c 6 Aug 2014 18:21:14 -0000 1.21
+++ usr.sbin/httpd/config.c 18 Nov 2014 15:02:54 -0000
@@ -223,7 +223,7 @@ config_getserver_config(struct httpd *en
#ifdef DEBUG
struct privsep *ps = env->sc_ps;
#endif
- struct server_config *srv_conf;
+ struct server_config *srv_conf, *parent;
u_int8_t *p = imsg->data;
u_int f;
@@ -233,18 +233,28 @@ config_getserver_config(struct httpd *en
IMSG_SIZE_CHECK(imsg, srv_conf);
memcpy(srv_conf, p, sizeof(*srv_conf));
+ /* Reset these variables to avoid free'ing invalid pointers */
+ serverconfig_reset(srv_conf);
+
+ TAILQ_FOREACH(parent, &srv->srv_hosts, entry) {
+ if (strcmp(parent->name, srv_conf->name) == 0)
+ break;
+ }
+ if (parent == NULL)
+ parent = &srv->srv_conf;
+
if (srv_conf->flags & SRVFLAG_LOCATION) {
/* Inherit configuration from the parent */
f = SRVFLAG_INDEX|SRVFLAG_NO_INDEX;
if ((srv_conf->flags & f) == 0) {
- srv_conf->flags |= srv->srv_conf.flags & f;
- (void)strlcpy(srv_conf->index, srv->srv_conf.index,
+ srv_conf->flags |= parent->flags & f;
+ (void)strlcpy(srv_conf->index, parent->index,
sizeof(srv_conf->index));
}
f = SRVFLAG_AUTO_INDEX|SRVFLAG_NO_AUTO_INDEX;
if ((srv_conf->flags & f) == 0)
- srv_conf->flags |= srv->srv_conf.flags & f;
+ srv_conf->flags |= parent->flags & f;
f = SRVFLAG_SOCKET|SRVFLAG_FCGI;
if ((srv_conf->flags & f) == SRVFLAG_FCGI) {
@@ -255,48 +265,48 @@ config_getserver_config(struct httpd *en
f = SRVFLAG_ROOT;
if ((srv_conf->flags & f) == 0) {
- srv_conf->flags |= srv->srv_conf.flags & f;
- (void)strlcpy(srv_conf->root, srv->srv_conf.root,
+ srv_conf->flags |= parent->flags & f;
+ (void)strlcpy(srv_conf->root, parent->root,
sizeof(srv_conf->root));
}
f = SRVFLAG_FCGI|SRVFLAG_NO_FCGI;
if ((srv_conf->flags & f) == 0)
- srv_conf->flags |= srv->srv_conf.flags & f;
+ srv_conf->flags |= parent->flags & f;
f = SRVFLAG_LOG|SRVFLAG_NO_LOG;
if ((srv_conf->flags & f) == 0) {
- srv_conf->flags |= srv->srv_conf.flags & f;
- srv_conf->logformat = srv->srv_conf.logformat;
+ srv_conf->flags |= parent->flags & f;
+ srv_conf->logformat = parent->logformat;
}
f = SRVFLAG_SYSLOG|SRVFLAG_NO_SYSLOG;
if ((srv_conf->flags & f) == 0)
- srv_conf->flags |= srv->srv_conf.flags & f;
+ srv_conf->flags |= parent->flags & f;
f = SRVFLAG_SSL;
- srv_conf->flags |= srv->srv_conf.flags & f;
+ srv_conf->flags |= parent->flags & f;
f = SRVFLAG_ACCESS_LOG;
if ((srv_conf->flags & f) == 0) {
- srv_conf->flags |= srv->srv_conf.flags & f;
+ srv_conf->flags |= parent->flags & f;
(void)strlcpy(srv_conf->accesslog,
- srv->srv_conf.accesslog,
+ parent->accesslog,
sizeof(srv_conf->accesslog));
}
f = SRVFLAG_ERROR_LOG;
if ((srv_conf->flags & f) == 0) {
- srv_conf->flags |= srv->srv_conf.flags & f;
+ srv_conf->flags |= parent->flags & f;
(void)strlcpy(srv_conf->errorlog,
- srv->srv_conf.errorlog,
+ parent->errorlog,
sizeof(srv_conf->errorlog));
}
- memcpy(&srv_conf->timeout, &srv->srv_conf.timeout,
+ memcpy(&srv_conf->timeout, &parent->timeout,
sizeof(srv_conf->timeout));
- srv_conf->maxrequests = srv->srv_conf.maxrequests;
- srv_conf->maxrequestbody = srv->srv_conf.maxrequestbody;
+ srv_conf->maxrequests = parent->maxrequests;
+ srv_conf->maxrequestbody = parent->maxrequestbody;
DPRINTF("%s: %s %d location \"%s\", "
"parent \"%s\", flags: %s",
@@ -330,6 +340,9 @@ config_getserver(struct httpd *env, stru
IMSG_SIZE_CHECK(imsg, &srv_conf);
memcpy(&srv_conf, p, sizeof(srv_conf));
s = sizeof(srv_conf);
+
+ /* Reset these variables to avoid free'ing invalid pointers */
+ serverconfig_reset(&srv_conf);
if ((u_int)(IMSG_DATA_SIZE(imsg) - s) <
(srv_conf.ssl_cert_len + srv_conf.ssl_key_len)) {
Index: usr.sbin/httpd/http.h
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/http.h,v
retrieving revision 1.5
diff -u -p -r1.5 http.h
--- usr.sbin/httpd/http.h 3 Aug 2014 21:33:27 -0000 1.5
+++ usr.sbin/httpd/http.h 18 Nov 2014 15:02:54 -0000
@@ -44,6 +44,32 @@ enum httpmethod {
HTTP_METHOD_LOCK,
HTTP_METHOD_UNLOCK,
+ /* WebDAV Versioning Extension, RFC 3253 */
+ HTTP_METHOD_VERSION_CONTROL,
+ HTTP_METHOD_REPORT,
+ HTTP_METHOD_CHECKOUT,
+ HTTP_METHOD_CHECKIN,
+ HTTP_METHOD_UNCHECKOUT,
+ HTTP_METHOD_MKWORKSPACE,
+ HTTP_METHOD_UPDATE,
+ HTTP_METHOD_LABEL,
+ HTTP_METHOD_MERGE,
+ HTTP_METHOD_BASELINE_CONTROL,
+ HTTP_METHOD_MKACTIVITY,
+
+ /* WebDAV Ordered Collections, RFC 3648 */
+ HTTP_METHOD_ORDERPATCH,
+
+ /* WebDAV Access Control, RFC 3744 */
+ HTTP_METHOD_ACL,
+
+ /* WebDAV Redirect Reference Resources, RFC 4437 */
+ HTTP_METHOD_MKREDIRECTREF,
+ HTTP_METHOD_UPDATEREDIRECTREF,
+
+ /* WebDAV Search, RFC 5323 */
+ HTTP_METHOD_SEARCH,
+
/* PATCH, RFC 5789 */
HTTP_METHOD_PATCH,
@@ -71,6 +97,22 @@ struct http_method {
{ HTTP_METHOD_MOVE, "MOVE" }, \
{ HTTP_METHOD_LOCK, "LOCK" }, \
{ HTTP_METHOD_UNLOCK, "UNLOCK" }, \
+ { HTTP_METHOD_VERSION_CONTROL, "VERSION-CONTROL" }, \
+ { HTTP_METHOD_REPORT, "REPORT" }, \
+ { HTTP_METHOD_CHECKOUT, "CHECKOUT" }, \
+ { HTTP_METHOD_CHECKIN, "CHECKIN" }, \
+ { HTTP_METHOD_UNCHECKOUT, "UNCHECKOUT" }, \
+ { HTTP_METHOD_MKWORKSPACE, "MKWORKSPACE" }, \
+ { HTTP_METHOD_UPDATE, "UPDATE" }, \
+ { HTTP_METHOD_LABEL, "LABEL" }, \
+ { HTTP_METHOD_MERGE, "MERGE" }, \
+ { HTTP_METHOD_BASELINE_CONTROL, "BASELINE-CONTROL" }, \
+ { HTTP_METHOD_MKACTIVITY, "MKACTIVITY" }, \
+ { HTTP_METHOD_ORDERPATCH, "ORDERPATCH" }, \
+ { HTTP_METHOD_ACL, "ACL" }, \
+ { HTTP_METHOD_MKREDIRECTREF, "MKREDIRECTREF" }, \
+ { HTTP_METHOD_UPDATEREDIRECTREF, "UPDATEREDIRECTREF" }, \
+ { HTTP_METHOD_SEARCH, "SEARCH" }, \
{ HTTP_METHOD_PATCH, "PATCH" }, \
{ HTTP_METHOD_NONE, NULL } \
}
@@ -155,6 +197,9 @@ struct http_descriptor {
enum httpmethod http_method;
int http_chunked;
char *http_version;
+
+ /* Rewritten path remains NULL if not used */
+ char *http_path_alias;
/* A tree of headers and attached lists for repeated headers. */
struct kv *http_lastheader;
Index: usr.sbin/httpd/httpd.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/httpd.c,v
retrieving revision 1.17
diff -u -p -r1.17 httpd.c
--- usr.sbin/httpd/httpd.c 5 Aug 2014 15:36:59 -0000 1.17
+++ usr.sbin/httpd/httpd.c 18 Nov 2014 15:02:54 -0000
@@ -289,10 +289,20 @@ parent_configure(struct httpd *env)
fatal("send media");
}
+ /* First send the servers... */
TAILQ_FOREACH(srv, env->sc_servers, srv_entry) {
+ if (srv->srv_conf.flags & SRVFLAG_LOCATION)
+ continue;
if (config_setserver(env, srv) == -1)
fatal("send server");
}
+ /* ...and now send the locations */
+ TAILQ_FOREACH(srv, env->sc_servers, srv_entry) {
+ if ((srv->srv_conf.flags & SRVFLAG_LOCATION) == 0)
+ continue;
+ if (config_setserver(env, srv) == -1)
+ fatal("send location");
+ }
/* The servers need to reload their config. */
env->sc_reload = env->sc_prefork_server + 1;
@@ -526,6 +536,46 @@ canonicalize_host(const char *host, char
}
const char *
+url_decode(char *url)
+{
+ char *p, *q;
+ char hex[3];
+ u_long x;
+
+ hex[2] = '\0';
+ p = q = url;
+
+ while (*p != '\0') {
+ switch (*p) {
+ case '%':
+ /* Encoding character is followed by two hex chars */
+ if (!(isxdigit(p[1]) && isxdigit(p[2])))
+ return (NULL);
+
+ hex[0] = p[1];
+ hex[1] = p[2];
+
+ /*
+ * We don't have to validate "hex" because it is
+ * guaranteed to include two hex chars followed by nul.
+ */
+ x = strtoul(hex, NULL, 16);
+ *q = (char)x;
+ p += 2;
+ break;
+ default:
+ *q = *p;
+ break;
+ }
+ p++;
+ q++;
+ }
+ *q = '\0';
+
+ return(url);
+}
+
+const char *
canonicalize_path(const char *input, char *path, size_t len)
{
const char *i;
@@ -580,28 +630,33 @@ canonicalize_path(const char *input, cha
return (path);
}
-ssize_t
-path_info(char *name)
+size_t
+path_info(char *path)
{
- char *p, *start, *end;
- char path[MAXPATHLEN];
+ char *p, *start, *end, ch;
struct stat st;
-
- if (strlcpy(path, name, sizeof(path)) >= sizeof(path))
- return (-1);
+ int ret;
start = path;
end = start + strlen(path);
for (p = end; p > start; p--) {
- if (*p != '/')
+ /* Scan every path component from the end and at each '/' */
+ if (p < end && *p != '/')
continue;
- if (stat(path, &st) == 0)
- break;
+
+ /* Temporarily cut the path component out */
+ ch = *p;
*p = '\0';
+ ret = stat(path, &st);
+ *p = ch;
+
+ /* Break if the initial path component was found */
+ if (ret == 0)
+ break;
}
- return (strlen(path));
+ return (p - start);
}
void
@@ -623,6 +678,40 @@ socket_rlimit(int maxfd)
rl.rlim_cur = MAX(rl.rlim_max, (rlim_t)maxfd);
if (setrlimit(RLIMIT_NOFILE, &rl) == -1)
fatal("socket_rlimit: failed to set resource limit");
+}
+
+char *
+evbuffer_getline(struct evbuffer *evb)
+{
+ u_int8_t *ptr = EVBUFFER_DATA(evb);
+ size_t len = EVBUFFER_LENGTH(evb);
+ char *str;
+ u_int i;
+
+ /* Safe version of evbuffer_readline() */
+ if ((str = get_string(ptr, len)) == NULL)
+ return (NULL);
+
+ for (i = 0; str[i] != '\0'; i++) {
+ if (str[i] == '\r' || str[i] == '\n')
+ break;
+ }
+
+ if (i == len) {
+ free(str);
+ return (NULL);
+ }
+
+ str[i] = '\0';
+
+ if ((i + 1) < len) {
+ if (ptr[i] == '\r' && ptr[i + 1] == '\n')
+ i++;
+ }
+
+ evbuffer_drain(evb, ++i);
+
+ return (str);
}
char *
Index: usr.sbin/httpd/httpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/httpd.h,v
retrieving revision 1.51
diff -u -p -r1.51 httpd.h
--- usr.sbin/httpd/httpd.h 6 Aug 2014 18:21:14 -0000 1.51
+++ usr.sbin/httpd/httpd.h 18 Nov 2014 15:02:54 -0000
@@ -276,7 +276,8 @@ struct client {
size_t clt_buflen;
struct evbuffer *clt_output;
struct event clt_ev;
- void *clt_desc;
+ void *clt_descreq;
+ void *clt_descresp;
int clt_sndbufsiz;
int clt_fd;
@@ -294,6 +295,8 @@ struct client {
int clt_fcgi_toread;
int clt_fcgi_padding_len;
int clt_fcgi_type;
+ int clt_fcgi_chunked;
+ int clt_fcgi_end;
struct evbuffer *clt_srvevb;
struct evbuffer *clt_log;
@@ -463,6 +466,8 @@ pid_t server(struct privsep *, struct p
int server_ssl_load_keypair(struct server *);
int server_privinit(struct server *);
void server_purge(struct server *);
+void serverconfig_free(struct server_config *);
+void serverconfig_reset(struct server_config *);
int server_socket_af(struct sockaddr_storage *, in_port_t);
in_port_t
server_socket_getport(struct sockaddr_storage *);
@@ -477,6 +482,8 @@ void server_sendlog(struct server_confi
void server_close(struct client *, const char *);
void server_dump(struct client *, const void *, size_t);
int server_client_cmp(struct client *, struct client *);
+int server_bufferevent_printf(struct client *, const char *, ...)
+ __attribute__((__format__ (printf, 2, 3)));
int server_bufferevent_print(struct client *, const char *);
int server_bufferevent_write_buffer(struct client *,
struct evbuffer *);
@@ -508,17 +515,20 @@ const char
void server_read_httpcontent(struct bufferevent *, void *);
void server_read_httpchunks(struct bufferevent *, void *);
int server_writeheader_http(struct client *clt, struct kv *, void *);
-int server_headers(struct client *,
+int server_headers(struct client *, void *,
int (*)(struct client *, struct kv *, void *), void *);
int server_writeresponse_http(struct client *);
int server_response_http(struct client *, u_int, struct media_type *,
- size_t);
+ size_t, time_t);
void server_reset_http(struct client *);
void server_close_http(struct client *);
int server_response(struct httpd *, struct client *);
+struct server_config *
+ server_getlocation(struct client *, const char *);
const char *
server_http_host(struct sockaddr_storage *, char *, size_t);
-void server_http_date(char *, size_t);
+char *server_http_parsehost(char *, char *, size_t, int *);
+ssize_t server_http_time(time_t, char *, size_t);
int server_log_http(struct client *, u_int, size_t);
/* server_file.c */
@@ -533,13 +543,15 @@ int fcgi_add_stdin(struct client *, str
void event_again(struct event *, int, short,
void (*)(int, short, void *),
struct timeval *, struct timeval *, void *);
+const char *url_decode(char *);
const char *canonicalize_host(const char *, char *, size_t);
const char *canonicalize_path(const char *, char *, size_t);
-ssize_t path_info(char *);
+size_t path_info(char *);
void imsg_event_add(struct imsgev *);
int imsg_compose_event(struct imsgev *, u_int16_t, u_int32_t,
pid_t, int, void *, u_int16_t);
void socket_rlimit(int);
+char *evbuffer_getline(struct evbuffer *);
char *get_string(u_int8_t *, size_t);
void *get_data(u_int8_t *, size_t);
int sockaddr_cmp(struct sockaddr *, struct sockaddr *, int);
@@ -575,6 +587,7 @@ void log_warn(const char *, ...) __attri
void log_warnx(const char *, ...) __attribute__((__format__ (printf, 1, 2)));
void log_info(const char *, ...) __attribute__((__format__ (printf, 1, 2)));
void log_debug(const char *, ...) __attribute__((__format__ (printf, 1, 2)));
+void logit(int, const char *, ...) __attribute__((__format__ (printf, 2,
3)));
void vlog(int, const char *, va_list) __attribute__((__format__ (printf, 2,
0)));
__dead void fatal(const char *);
__dead void fatalx(const char *);
Index: usr.sbin/httpd/logger.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/logger.c,v
retrieving revision 1.5
diff -u -p -r1.5 logger.c
--- usr.sbin/httpd/logger.c 6 Aug 2014 12:56:58 -0000 1.5
+++ usr.sbin/httpd/logger.c 18 Nov 2014 15:02:55 -0000
@@ -194,6 +194,9 @@ logger_open(struct server *srv, struct s
{
struct log_file *log, *logfile = NULL, *errfile = NULL;
+ if (srv_conf->flags & SRVFLAG_SYSLOG)
+ return(0);
+
/* disassociate */
srv_conf->logaccess = srv_conf->logerror = NULL;
Index: usr.sbin/httpd/parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/parse.y,v
retrieving revision 1.34
diff -u -p -r1.34 parse.y
--- usr.sbin/httpd/parse.y 6 Aug 2014 20:29:54 -0000 1.34
+++ usr.sbin/httpd/parse.y 18 Nov 2014 15:02:55 -0000
@@ -180,7 +180,7 @@ main : PREFORK NUMBER {
break;
if ($2 <= 0 || $2 > SERVER_MAXPROC) {
yyerror("invalid number of preforked "
- "servers: %d", $2);
+ "servers: %lld", $2);
YYERROR;
}
conf->sc_prefork_server = $2;
@@ -198,15 +198,6 @@ server : SERVER STRING {
YYACCEPT;
}
- TAILQ_FOREACH(s, conf->sc_servers, srv_entry)
- if (!strcmp(s->srv_conf.name, $2))
- break;
- if (s != NULL) {
- yyerror("server %s defined twice", $2);
- free($2);
- YYERROR;
- }
-
if ((s = calloc(1, sizeof (*s))) == NULL)
fatal("out of memory");
@@ -252,18 +243,46 @@ server : SERVER STRING {
srv_conf = &srv->srv_conf;
SPLAY_INIT(&srv->srv_clients);
- TAILQ_INSERT_TAIL(conf->sc_servers, srv, srv_entry);
} '{' optnl serveropts_l '}' {
+ struct server *s = NULL;
+
+ TAILQ_FOREACH(s, conf->sc_servers, srv_entry) {
+ if ((s->srv_conf.flags &
+ SRVFLAG_LOCATION) == 0 &&
+ strcmp(s->srv_conf.name,
+ srv->srv_conf.name) == 0 &&
+ s->srv_conf.port == srv->srv_conf.port &&
+ sockaddr_cmp(
+ (struct sockaddr *)&s->srv_conf.ss,
+ (struct sockaddr *)&srv->srv_conf.ss,
+ s->srv_conf.prefixlen) == 0)
+ break;
+ }
+ if (s != NULL) {
+ yyerror("server \"%s\" defined twice",
+ srv->srv_conf.name);
+ serverconfig_free(srv_conf);
+ free(srv);
+ YYABORT;
+ }
+
if (srv->srv_conf.ss.ss_family == AF_UNSPEC) {
yyerror("listen address not specified");
- free($2);
+ serverconfig_free(srv_conf);
+ free(srv);
YYERROR;
}
+
if (server_ssl_load_keypair(srv) == -1) {
yyerror("failed to load public/private keys "
"for server %s", srv->srv_conf.name);
+ serverconfig_free(srv_conf);
+ free(srv);
YYERROR;
}
+
+ TAILQ_INSERT_TAIL(conf->sc_servers, srv, srv_entry);
+
srv = NULL;
srv_conf = NULL;
}
@@ -367,17 +386,6 @@ serveroptsl : LISTEN ON STRING optssl po
YYACCEPT;
}
- TAILQ_FOREACH(s, conf->sc_servers, srv_entry)
- if (strcmp(s->srv_conf.name,
- srv->srv_conf.name) == 0 &&
- strcmp(s->srv_conf.location, $2) == 0)
- break;
- if (s != NULL) {
- yyerror("location %s defined twice", $2);
- free($2);
- YYERROR;
- }
-
if ((s = calloc(1, sizeof (*s))) == NULL)
fatal("out of memory");
@@ -416,12 +424,31 @@ serveroptsl : LISTEN ON STRING optssl po
srv = s;
srv_conf = &srv->srv_conf;
SPLAY_INIT(&srv->srv_clients);
- TAILQ_INSERT_TAIL(conf->sc_servers, srv, srv_entry);
} '{' optnl serveropts_l '}' {
+ struct server *s = NULL;
+
+ TAILQ_FOREACH(s, conf->sc_servers, srv_entry) {
+ if ((s->srv_conf.flags & SRVFLAG_LOCATION) &&
+ s->srv_conf.id == srv_conf->id &&
+ strcmp(s->srv_conf.location,
+ srv_conf->location) == 0)
+ break;
+ }
+ if (s != NULL) {
+ yyerror("location \"%s\" defined twice",
+ srv->srv_conf.location);
+ serverconfig_free(srv_conf);
+ free(srv);
+ YYABORT;
+ }
+
+ TAILQ_INSERT_TAIL(conf->sc_servers, srv, srv_entry);
+
srv = parentsrv;
srv_conf = &parentsrv->srv_conf;
parentsrv = NULL;
}
+ | include
;
fastcgi : NO FCGI {
@@ -623,7 +650,7 @@ tcpflags : SACK { srv_conf->tcpflags |
}
| BACKLOG NUMBER {
if ($2 < 0 || $2 > SERVER_MAX_CLIENTS) {
- yyerror("invalid backlog: %d", $2);
+ yyerror("invalid backlog: %lld", $2);
YYERROR;
}
srv_conf->tcpbacklog = $2;
@@ -631,13 +658,13 @@ tcpflags : SACK { srv_conf->tcpflags |
| SOCKET BUFFER NUMBER {
srv_conf->tcpflags |= TCPFLAG_BUFSIZ;
if ((srv_conf->tcpbufsiz = $3) < 0) {
- yyerror("invalid socket buffer size: %d", $3);
+ yyerror("invalid socket buffer size: %lld", $3);
YYERROR;
}
}
| IP STRING NUMBER {
if ($3 < 0) {
- yyerror("invalid ttl: %d", $3);
+ yyerror("invalid ttl: %lld", $3);
free($2);
YYERROR;
}
@@ -694,6 +721,9 @@ medianamesl : STRING {
}
free($1);
+ if (!loadcfg)
+ break;
+
if (media_add(conf->sc_mediatypes, &media) == NULL) {
yyerror("failed to add media type");
YYERROR;
@@ -729,7 +759,7 @@ port : PORT STRING {
}
| PORT NUMBER
[The entire original message is not included.]