ath9k: fix various calibration related bugs and clean up the code
[openwrt.git] / package / uhttpd / src / uhttpd.c
index da37794..8272962 100644 (file)
@@ -47,7 +47,7 @@ static void uh_sigchld(int sig)
        while( waitpid(-1, NULL, WNOHANG) > 0 ) { }
 }
 
        while( waitpid(-1, NULL, WNOHANG) > 0 ) { }
 }
 
-static void uh_config_parse(const char *path)
+static void uh_config_parse(struct config *conf)
 {
        FILE *c;
        char line[512];
 {
        FILE *c;
        char line[512];
@@ -55,7 +55,10 @@ static void uh_config_parse(const char *path)
        char *pass = NULL;
        char *eol  = NULL;
 
        char *pass = NULL;
        char *eol  = NULL;
 
-       if( (c = fopen(path ? path : "/etc/httpd.conf", "r")) != NULL )
+       const char *path = conf->file ? conf->file : "/etc/httpd.conf";
+
+
+       if( (c = fopen(path, "r")) != NULL )
        {
                memset(line, 0, sizeof(line));
 
        {
                memset(line, 0, sizeof(line));
 
@@ -71,12 +74,26 @@ static void uh_config_parse(const char *path)
                                if( !uh_auth_add(line, user, pass) )
                                {
                                        fprintf(stderr,
                                if( !uh_auth_add(line, user, pass) )
                                {
                                        fprintf(stderr,
-                                               "Can not manage more than %i basic auth realms, "
-                                               "will skip the rest\n", UH_LIMIT_AUTHREALMS
+                                               "Notice: No password set for user %s, ignoring "
+                                               "authentication on %s\n", user, line
                                        );
                                        );
+                               }
+                       }
+                       else if( !strncmp(line, "I:", 2) )
+                       {
+                               if( !(user = strchr(line, ':')) || (*user++ = 0) ||
+                                   !(eol = strchr(user, '\n')) || (*eol++  = 0) )
+                                       continue;
 
 
-                                       break;
-                               } 
+                               conf->index_file = strdup(user);
+                       }
+                       else if( !strncmp(line, "E404:", 5) )
+                       {
+                               if( !(user = strchr(line, ':')) || (*user++ = 0) ||
+                                   !(eol = strchr(user, '\n')) || (*eol++  = 0) )
+                                               continue;
+
+                               conf->error_handler = strdup(user);
                        }
                }
 
                        }
                }
 
@@ -302,6 +319,7 @@ static struct http_request * uh_http_header_parse(struct client *cl, char *buffe
                }
 
                /* valid enough */
                }
 
                /* valid enough */
+               req.redirect_status = 200;
                return &req;
        }
 
                return &req;
        }
 
@@ -416,8 +434,11 @@ int main (int argc, char **argv)
        /* maximum file descriptor number */
        int new_fd, cur_fd, max_fd = 0;
 
        /* maximum file descriptor number */
        int new_fd, cur_fd, max_fd = 0;
 
+#ifdef HAVE_TLS
        int tls = 0;
        int keys = 0;
        int tls = 0;
        int keys = 0;
+#endif
+
        int bound = 0;
        int nofork = 0;
 
        int bound = 0;
        int nofork = 0;
 
@@ -426,9 +447,10 @@ int main (int argc, char **argv)
        char bind[128];
        char *port = NULL;
 
        char bind[128];
        char *port = NULL;
 
-       /* library handles */
-       void *tls_lib;
-       void *lua_lib;
+#if defined(HAVE_TLS) || defined(HAVE_LUA)
+       /* library handle */
+       void *lib;
+#endif
 
        /* clear the master and temp sets */
        FD_ZERO(&used_fds);
 
        /* clear the master and temp sets */
        FD_ZERO(&used_fds);
@@ -466,7 +488,7 @@ int main (int argc, char **argv)
 
 #ifdef HAVE_TLS
        /* load TLS plugin */
 
 #ifdef HAVE_TLS
        /* load TLS plugin */
-       if( ! (tls_lib = dlopen("uhttpd_tls.so", RTLD_LAZY | RTLD_GLOBAL)) )
+       if( ! (lib = dlopen("uhttpd_tls.so", RTLD_LAZY | RTLD_GLOBAL)) )
        {
                fprintf(stderr,
                        "Notice: Unable to load TLS plugin - disabling SSL support! "
        {
                fprintf(stderr,
                        "Notice: Unable to load TLS plugin - disabling SSL support! "
@@ -476,14 +498,14 @@ int main (int argc, char **argv)
        else
        {
                /* resolve functions */
        else
        {
                /* resolve functions */
-               if( !(conf.tls_init   = dlsym(tls_lib, "uh_tls_ctx_init"))      ||
-                   !(conf.tls_cert   = dlsym(tls_lib, "uh_tls_ctx_cert"))      ||
-                   !(conf.tls_key    = dlsym(tls_lib, "uh_tls_ctx_key"))       ||
-                   !(conf.tls_free   = dlsym(tls_lib, "uh_tls_ctx_free"))      ||
-                       !(conf.tls_accept = dlsym(tls_lib, "uh_tls_client_accept")) ||
-                       !(conf.tls_close  = dlsym(tls_lib, "uh_tls_client_close"))  ||
-                       !(conf.tls_recv   = dlsym(tls_lib, "uh_tls_client_recv"))   ||
-                       !(conf.tls_send   = dlsym(tls_lib, "uh_tls_client_send"))
+               if( !(conf.tls_init   = dlsym(lib, "uh_tls_ctx_init"))      ||
+                   !(conf.tls_cert   = dlsym(lib, "uh_tls_ctx_cert"))      ||
+                   !(conf.tls_key    = dlsym(lib, "uh_tls_ctx_key"))       ||
+                   !(conf.tls_free   = dlsym(lib, "uh_tls_ctx_free"))      ||
+                       !(conf.tls_accept = dlsym(lib, "uh_tls_client_accept")) ||
+                       !(conf.tls_close  = dlsym(lib, "uh_tls_client_close"))  ||
+                       !(conf.tls_recv   = dlsym(lib, "uh_tls_client_recv"))   ||
+                       !(conf.tls_send   = dlsym(lib, "uh_tls_client_send"))
                ) {
                        fprintf(stderr,
                                "Error: Failed to lookup required symbols "
                ) {
                        fprintf(stderr,
                                "Error: Failed to lookup required symbols "
@@ -501,8 +523,9 @@ int main (int argc, char **argv)
        }
 #endif
 
        }
 #endif
 
-       while( (opt = getopt(argc, argv, "fC:K:p:s:h:c:l:L:d:r:m:x:t:")) > 0 )
-       {
+       while( (opt = getopt(argc, argv,
+               "fSDC:K:E:I:p:s:h:c:l:L:d:r:m:x:t:T:")) > 0
+       ) {
                switch(opt)
                {
                        /* [addr:]port */
                switch(opt)
                {
                        /* [addr:]port */
@@ -546,6 +569,7 @@ int main (int argc, char **argv)
                                        &hints, (opt == 's'), &conf
                                );
 
                                        &hints, (opt == 's'), &conf
                                );
 
+                               memset(bind, 0, sizeof(bind));
                                break;
 
 #ifdef HAVE_TLS
                                break;
 
 #ifdef HAVE_TLS
@@ -592,6 +616,38 @@ int main (int argc, char **argv)
                                }
                                break;
 
                                }
                                break;
 
+                       /* error handler */
+                       case 'E':
+                               if( (strlen(optarg) == 0) || (optarg[0] != '/') )
+                               {
+                                       fprintf(stderr, "Error: Invalid error handler: %s\n",
+                                               optarg);
+                                       exit(1);
+                               }
+                               conf.error_handler = optarg;
+                               break;
+
+                       /* index file */
+                       case 'I':
+                               if( (strlen(optarg) == 0) || (optarg[0] == '/') )
+                               {
+                                       fprintf(stderr, "Error: Invalid index page: %s\n",
+                                               optarg);
+                                       exit(1);
+                               }
+                               conf.index_file = optarg;
+                               break;
+
+                       /* don't follow symlinks */
+                       case 'S':
+                               conf.no_symlinks = 1;
+                               break;
+
+                       /* don't list directories */
+                       case 'D':
+                               conf.no_dirlists = 1;
+                               break;
+
 #ifdef HAVE_CGI
                        /* cgi prefix */
                        case 'x':
 #ifdef HAVE_CGI
                        /* cgi prefix */
                        case 'x':
@@ -618,6 +674,11 @@ int main (int argc, char **argv)
                                break;
 #endif
 
                                break;
 #endif
 
+                       /* network timeout */
+                       case 'T':
+                               conf.network_timeout = atoi(optarg);
+                               break;
+
                        /* no fork */
                        case 'f':
                                nofork = 1;
                        /* no fork */
                        case 'f':
                                nofork = 1;
@@ -663,6 +724,10 @@ int main (int argc, char **argv)
                                        "       -K file         ASN.1 server private key file\n"
 #endif
                                        "       -h directory    Specify the document root, default is '.'\n"
                                        "       -K file         ASN.1 server private key file\n"
 #endif
                                        "       -h directory    Specify the document root, default is '.'\n"
+                                       "       -E string       Use given virtual URL as 404 error handler\n"
+                                       "       -I string       Use given filename as index page for directories\n"
+                                       "       -S              Do not follow symbolic links outside of the docroot\n"
+                                       "       -D              Do not allow directory listings, send 403 instead\n"
 #ifdef HAVE_LUA
                                        "       -l string       URL prefix for Lua handler, default is '/lua'\n"
                                        "       -L file         Lua handler script, omit to disable Lua\n"
 #ifdef HAVE_LUA
                                        "       -l string       URL prefix for Lua handler, default is '/lua'\n"
                                        "       -L file         Lua handler script, omit to disable Lua\n"
@@ -673,6 +738,7 @@ int main (int argc, char **argv)
 #if defined(HAVE_CGI) || defined(HAVE_LUA)
                                        "       -t seconds      CGI and Lua script timeout in seconds, default is 60\n"
 #endif
 #if defined(HAVE_CGI) || defined(HAVE_LUA)
                                        "       -t seconds      CGI and Lua script timeout in seconds, default is 60\n"
 #endif
+                                       "       -T seconds      Network timeout in seconds, default is 30\n"
                                        "       -d string       URL decode given string\n"
                                        "       -r string       Specify basic auth realm\n"
                                        "       -m string       MD5 crypt given string\n"
                                        "       -d string       URL decode given string\n"
                                        "       -r string       Specify basic auth realm\n"
                                        "       -m string       MD5 crypt given string\n"
@@ -710,7 +776,11 @@ int main (int argc, char **argv)
                conf.realm = "Protected Area";
 
        /* config file */
                conf.realm = "Protected Area";
 
        /* config file */
-       uh_config_parse(conf.file);
+       uh_config_parse(&conf);
+
+       /* default network timeout */
+       if( conf.network_timeout <= 0 )
+               conf.network_timeout = 30;
 
 #if defined(HAVE_CGI) || defined(HAVE_LUA)
        /* default script timeout */
 
 #if defined(HAVE_CGI) || defined(HAVE_LUA)
        /* default script timeout */
@@ -726,7 +796,7 @@ int main (int argc, char **argv)
 
 #ifdef HAVE_LUA
        /* load Lua plugin */
 
 #ifdef HAVE_LUA
        /* load Lua plugin */
-       if( ! (lua_lib = dlopen("uhttpd_lua.so", RTLD_LAZY | RTLD_GLOBAL)) )
+       if( ! (lib = dlopen("uhttpd_lua.so", RTLD_LAZY | RTLD_GLOBAL)) )
        {
                fprintf(stderr,
                        "Notice: Unable to load Lua plugin - disabling Lua support! "
        {
                fprintf(stderr,
                        "Notice: Unable to load Lua plugin - disabling Lua support! "
@@ -736,9 +806,9 @@ int main (int argc, char **argv)
        else
        {
                /* resolve functions */
        else
        {
                /* resolve functions */
-               if( !(conf.lua_init    = dlsym(lua_lib, "uh_lua_init"))    ||
-                   !(conf.lua_close   = dlsym(lua_lib, "uh_lua_close"))   ||
-                   !(conf.lua_request = dlsym(lua_lib, "uh_lua_request"))
+               if( !(conf.lua_init    = dlsym(lib, "uh_lua_init"))    ||
+                   !(conf.lua_close   = dlsym(lib, "uh_lua_close"))   ||
+                   !(conf.lua_request = dlsym(lib, "uh_lua_request"))
                ) {
                        fprintf(stderr,
                                "Error: Failed to lookup required symbols "
                ) {
                        fprintf(stderr,
                                "Error: Failed to lookup required symbols "
@@ -892,8 +962,29 @@ int main (int argc, char **argv)
                                                /* 404 */
                                                else
                                                {
                                                /* 404 */
                                                else
                                                {
-                                                       uh_http_sendhf(cl, 404, "Not Found",
-                                                               "No such file or directory");
+                                                       /* Try to invoke an error handler */
+                                                       pin = uh_path_lookup(cl, conf.error_handler);
+
+                                                       if( pin && uh_auth_check(cl, req, pin) )
+                                                       {
+                                                               req->redirect_status = 404;
+
+#ifdef HAVE_CGI
+                                                               if( uh_path_match(conf.cgi_prefix, pin->name) )
+                                                               {
+                                                                       uh_cgi_request(cl, req, pin);
+                                                               }
+                                                               else
+#endif
+                                                               {
+                                                                       uh_file_request(cl, req, pin);
+                                                               }
+                                                       }
+                                                       else
+                                                       {
+                                                               uh_http_sendhf(cl, 404, "Not Found",
+                                                                       "No such file or directory");
+                                                       }
                                                }
                                        }
 
                                                }
                                        }
 
This page took 0.038775 seconds and 4 git commands to generate.