+/* vi: set sw=4 ts=4: */
/*
* httpd implementation for busybox
*
*
* simplify patch stolen from libbb without using strdup
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*
*****************************************************************************
*
{
char buf[MAX_MEMORY_BUFF];
-#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
- const char *realm;
- char *remoteuser;
-#endif
+ USE_FEATURE_HTTPD_BASIC_AUTH(const char *realm;)
+ USE_FEATURE_HTTPD_BASIC_AUTH(char *remoteuser;)
const char *query;
-#ifdef CONFIG_FEATURE_HTTPD_CGI
- char *referer;
-#endif
+ USE_FEATURE_HTTPD_CGI(char *referer;)
const char *configFile;
memset(&lsocket, 0, sizeof(lsocket));
lsocket.sin_family = AF_INET;
lsocket.sin_addr.s_addr = INADDR_ANY;
- lsocket.sin_port = htons(config->port) ;
- fd = socket(AF_INET, SOCK_STREAM, 0);
- if (fd >= 0) {
- /* tell the OS it's OK to reuse a previous address even though */
- /* it may still be in a close down state. Allows bind to succeed. */
- int on = 1;
+ lsocket.sin_port = htons(config->port);
+ fd = bb_xsocket(AF_INET, SOCK_STREAM, 0);
+ /* tell the OS it's OK to reuse a previous address even though */
+ /* it may still be in a close down state. Allows bind to succeed. */
+ int on = 1;
#ifdef SO_REUSEPORT
- setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (void *)&on, sizeof(on)) ;
+ setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (void *)&on, sizeof(on)) ;
#else
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)) ;
+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)) ;
#endif
- if (bind(fd, (struct sockaddr *)&lsocket, sizeof(lsocket)) == 0) {
- listen(fd, 9);
- signal(SIGCHLD, SIG_IGN); /* prevent zombie (defunct) processes */
- } else {
- bb_perror_msg_and_die("bind");
- }
- } else {
- bb_perror_msg_and_die("create socket");
- }
+ bb_xbind(fd, (struct sockaddr *)&lsocket, sizeof(lsocket));
+ listen(fd, 9); /* bb_xlisten? */
+ signal(SIGCHLD, SIG_IGN); /* prevent zombie (defunct) processes */
return fd;
}
#endif /* CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY */
char *cookie = 0;
char *content_type = 0;
#endif
-#ifndef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
fd_set s_fd;
struct timeval tv;
int retval;
-#endif
struct sigaction sa;
#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
free(config->remoteuser);
#endif
# endif
+#endif /* CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY */
shutdown(a_c_w, SHUT_WR);
/* Properly wait for remote to closed */
FD_ZERO (&s_fd) ;
- FD_SET (a_c_w, &s_fd) ;
+ FD_SET (a_c_r, &s_fd) ;
do {
tv.tv_sec = 2 ;
tv.tv_usec = 0 ;
- retval = select (a_c_w + 1, &s_fd, NULL, NULL, &tv);
- } while (retval > 0 && (read (a_c_w, buf, sizeof (config->buf)) > 0));
+ retval = select (a_c_r + 1, &s_fd, NULL, NULL, &tv);
+ } while (retval > 0 && (read (a_c_r, buf, sizeof (config->buf)) > 0));
shutdown(a_c_r, SHUT_RD);
+#ifndef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
close(config->accepted_socket);
#endif /* CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY */
}
}
#endif
+enum httpd_opts_nums {
+ c_opt_config_file = 0,
+ d_opt_decode_url,
+ h_opt_home_httpd,
+ USE_FEATURE_HTTPD_ENCODE_URL_STR(e_opt_encode_url,)
+ USE_FEATURE_HTTPD_BASIC_AUTH(r_opt_realm,)
+ USE_FEATURE_HTTPD_AUTH_MD5(m_opt_md5,)
+ USE_FEATURE_HTTPD_SETUID(u_opt_setuid,)
+ SKIP_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY(p_opt_port,)
+};
static const char httpd_opts[]="c:d:h:"
-#ifdef CONFIG_FEATURE_HTTPD_ENCODE_URL_STR
- "e:"
-#endif
-#define OPT_INC_1 ENABLE_FEATURE_HTTPD_ENCODE_URL_STR
+ USE_FEATURE_HTTPD_ENCODE_URL_STR("e:")
+ USE_FEATURE_HTTPD_BASIC_AUTH("r:")
+ USE_FEATURE_HTTPD_AUTH_MD5("m:")
+ USE_FEATURE_HTTPD_SETUID("u:")
+ SKIP_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY("p:");
-#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
- "r:"
-#endif
-#define OPT_INC_2 ENABLE_FEATURE_HTTPD_BASIC_AUTH
+#define OPT_CONFIG_FILE (1<<c_opt_config_file)
+#define OPT_DECODE_URL (1<<d_opt_decode_url)
+#define OPT_HOME_HTTPD (1<<h_opt_home_httpd)
-#ifdef CONFIG_FEATURE_HTTPD_AUTH_MD5
- "m:"
-#endif
-#define OPT_INC_3 ENABLE_FEATURE_HTTPD_AUTH_MD5
+#define OPT_ENCODE_URL USE_FEATURE_HTTPD_ENCODE_URL_STR((1<<e_opt_encode_url)) \
+ SKIP_FEATURE_HTTPD_ENCODE_URL_STR(0)
-#ifndef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
- "p:"
-#endif
-#ifdef CONFIG_FEATURE_HTTPD_SETUID
- "u:"
-#endif
- ;
+#define OPT_REALM USE_FEATURE_HTTPD_BASIC_AUTH((1<<r_opt_realm)) \
+ SKIP_FEATURE_HTTPD_BASIC_AUTH(0)
+
+#define OPT_MD5 USE_FEATURE_HTTPD_AUTH_MD5((1<<m_opt_md5)) \
+ SKIP_FEATURE_HTTPD_AUTH_MD5(0)
-#define OPT_CONFIG_FILE (1<<0) /* c */
-#define OPT_DECODE_URL (1<<1) /* d */
-#define OPT_HOME_HTTPD (1<<2) /* h */
-#define OPT_ENCODE_URL (1<<(2+OPT_INC_1)) /* e */
-#define OPT_REALM (1<<(2+OPT_INC_1+OPT_INC_2)) /* r */
-#define OPT_MD5 (1<<(2+OPT_INC_1+OPT_INC_2+OPT_INC_3)) /* m */
-#define OPT_PORT (1<<(3+OPT_INC_1+OPT_INC_2+OPT_INC_3)) /* p */
-#define OPT_SETUID (1<<(4+OPT_INC_1+OPT_INC_2+OPT_INC_3)) /* u */
+#define OPT_SETUID USE_FEATURE_HTTPD_SETUID((1<<u_opt_setuid)) \
+ SKIP_FEATURE_HTTPD_SETUID(0)
+
+#define OPT_PORT SKIP_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY((1<<p_opt_port)) \
+ USE_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY(0)
#ifdef HTTPD_STANDALONE
unsigned long opt;
const char *home_httpd = home;
char *url_for_decode;
-#ifdef CONFIG_FEATURE_HTTPD_ENCODE_URL_STR
- const char *url_for_encode;
-#endif
-#ifndef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
- const char *s_port;
- int server;
-#endif
+ USE_FEATURE_HTTPD_ENCODE_URL_STR(const char *url_for_encode;)
+ SKIP_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY(const char *s_port;)
+ SKIP_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY(int server;)
-#ifdef CONFIG_FEATURE_HTTPD_SETUID
- const char *s_uid;
- long uid = -1;
-#endif
+ USE_FEATURE_HTTPD_SETUID(const char *s_uid;)
+ USE_FEATURE_HTTPD_SETUID(long uid = -1;)
-#ifdef CONFIG_FEATURE_HTTPD_AUTH_MD5
- const char *pass;
-#endif
+ USE_FEATURE_HTTPD_AUTH_MD5(const char *pass;)
config = xcalloc(1, sizeof(*config));
#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
opt = bb_getopt_ulflags(argc, argv, httpd_opts,
&(config->configFile), &url_for_decode, &home_httpd
-#ifdef CONFIG_FEATURE_HTTPD_ENCODE_URL_STR
- , &url_for_encode
-#endif
-#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
- , &(config->realm)
-# ifdef CONFIG_FEATURE_HTTPD_AUTH_MD5
- , &pass
-# endif
-#endif
-#ifndef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
- , &s_port
-#endif
-#ifdef CONFIG_FEATURE_HTTPD_SETUID
- , &s_uid
-#endif
- );
+ USE_FEATURE_HTTPD_ENCODE_URL_STR(, &url_for_encode)
+ USE_FEATURE_HTTPD_BASIC_AUTH(, &(config->realm))
+ USE_FEATURE_HTTPD_AUTH_MD5(, &pass)
+ USE_FEATURE_HTTPD_SETUID(, &s_uid)
+ SKIP_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY(, &s_port)
+ );
if(opt & OPT_DECODE_URL) {
printf("%s", decodeString(url_for_decode, 1));
#endif
#endif
- if(chdir(home_httpd)) {
- bb_perror_msg_and_die("can`t chdir to %s", home_httpd);
- }
+ bb_xchdir(home_httpd);
#ifndef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
server = openServer();
# ifdef CONFIG_FEATURE_HTTPD_SETUID
#if !ENABLE_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
# if !DEBUG
- if (daemon(1, 0) < 0) /* don`t change curent directory */
- bb_perror_msg_and_die("daemon");
+ bb_xdaemon(1, 0); /* don`t change curent directory */
# endif
return miniHttpd(server);
#else