Annotation of embedaddon/lighttpd/src/server.c, revision 1.1

1.1     ! misho       1: #include "server.h"
        !             2: #include "buffer.h"
        !             3: #include "network.h"
        !             4: #include "log.h"
        !             5: #include "keyvalue.h"
        !             6: #include "response.h"
        !             7: #include "request.h"
        !             8: #include "chunk.h"
        !             9: #include "http_chunk.h"
        !            10: #include "fdevent.h"
        !            11: #include "connections.h"
        !            12: #include "stat_cache.h"
        !            13: #include "plugin.h"
        !            14: #include "joblist.h"
        !            15: #include "network_backends.h"
        !            16: #include "version.h"
        !            17: 
        !            18: #include <sys/types.h>
        !            19: #include <sys/time.h>
        !            20: #include <sys/stat.h>
        !            21: 
        !            22: #include <string.h>
        !            23: #include <errno.h>
        !            24: #include <fcntl.h>
        !            25: #include <unistd.h>
        !            26: #include <stdlib.h>
        !            27: #include <time.h>
        !            28: #include <signal.h>
        !            29: #include <assert.h>
        !            30: #include <locale.h>
        !            31: 
        !            32: #include <stdio.h>
        !            33: 
        !            34: #ifdef HAVE_GETOPT_H
        !            35: # include <getopt.h>
        !            36: #endif
        !            37: 
        !            38: #ifdef HAVE_VALGRIND_VALGRIND_H
        !            39: # include <valgrind/valgrind.h>
        !            40: #endif
        !            41: 
        !            42: #ifdef HAVE_SYS_WAIT_H
        !            43: # include <sys/wait.h>
        !            44: #endif
        !            45: 
        !            46: #ifdef HAVE_PWD_H
        !            47: # include <grp.h>
        !            48: # include <pwd.h>
        !            49: #endif
        !            50: 
        !            51: #ifdef HAVE_SYS_RESOURCE_H
        !            52: # include <sys/resource.h>
        !            53: #endif
        !            54: 
        !            55: #ifdef HAVE_SYS_PRCTL_H
        !            56: # include <sys/prctl.h>
        !            57: #endif
        !            58: 
        !            59: #ifdef USE_OPENSSL
        !            60: # include <openssl/err.h> 
        !            61: #endif
        !            62: 
        !            63: #ifndef __sgi
        !            64: /* IRIX doesn't like the alarm based time() optimization */
        !            65: /* #define USE_ALARM */
        !            66: #endif
        !            67: 
        !            68: #ifdef HAVE_GETUID
        !            69: # ifndef HAVE_ISSETUGID
        !            70: 
        !            71: static int l_issetugid(void) {
        !            72:        return (geteuid() != getuid() || getegid() != getgid());
        !            73: }
        !            74: 
        !            75: #  define issetugid l_issetugid
        !            76: # endif
        !            77: #endif
        !            78: 
        !            79: static volatile sig_atomic_t srv_shutdown = 0;
        !            80: static volatile sig_atomic_t graceful_shutdown = 0;
        !            81: static volatile sig_atomic_t handle_sig_alarm = 1;
        !            82: static volatile sig_atomic_t handle_sig_hup = 0;
        !            83: static volatile sig_atomic_t forwarded_sig_hup = 0;
        !            84: 
        !            85: #if defined(HAVE_SIGACTION) && defined(SA_SIGINFO)
        !            86: static volatile siginfo_t last_sigterm_info;
        !            87: static volatile siginfo_t last_sighup_info;
        !            88: 
        !            89: static void sigaction_handler(int sig, siginfo_t *si, void *context) {
        !            90:        static siginfo_t empty_siginfo;
        !            91:        UNUSED(context);
        !            92: 
        !            93:        if (!si) si = &empty_siginfo;
        !            94: 
        !            95:        switch (sig) {
        !            96:        case SIGTERM:
        !            97:                srv_shutdown = 1;
        !            98:                last_sigterm_info = *si;
        !            99:                break;
        !           100:        case SIGINT:
        !           101:                if (graceful_shutdown) {
        !           102:                        srv_shutdown = 1;
        !           103:                } else {
        !           104:                        graceful_shutdown = 1;
        !           105:                }
        !           106:                last_sigterm_info = *si;
        !           107: 
        !           108:                break;
        !           109:        case SIGALRM: 
        !           110:                handle_sig_alarm = 1; 
        !           111:                break;
        !           112:        case SIGHUP:
        !           113:                /** 
        !           114:                 * we send the SIGHUP to all procs in the process-group
        !           115:                 * this includes ourself
        !           116:                 * 
        !           117:                 * make sure we only send it once and don't create a 
        !           118:                 * infinite loop
        !           119:                 */
        !           120:                if (!forwarded_sig_hup) {
        !           121:                        handle_sig_hup = 1;
        !           122:                        last_sighup_info = *si;
        !           123:                } else {
        !           124:                        forwarded_sig_hup = 0;
        !           125:                }
        !           126:                break;
        !           127:        case SIGCHLD:
        !           128:                break;
        !           129:        }
        !           130: }
        !           131: #elif defined(HAVE_SIGNAL) || defined(HAVE_SIGACTION)
        !           132: static void signal_handler(int sig) {
        !           133:        switch (sig) {
        !           134:        case SIGTERM: srv_shutdown = 1; break;
        !           135:        case SIGINT:
        !           136:             if (graceful_shutdown) srv_shutdown = 1;
        !           137:             else graceful_shutdown = 1;
        !           138: 
        !           139:             break;
        !           140:        case SIGALRM: handle_sig_alarm = 1; break;
        !           141:        case SIGHUP:  handle_sig_hup = 1; break;
        !           142:        case SIGCHLD:  break;
        !           143:        }
        !           144: }
        !           145: #endif
        !           146: 
        !           147: #ifdef HAVE_FORK
        !           148: static void daemonize(void) {
        !           149: #ifdef SIGTTOU
        !           150:        signal(SIGTTOU, SIG_IGN);
        !           151: #endif
        !           152: #ifdef SIGTTIN
        !           153:        signal(SIGTTIN, SIG_IGN);
        !           154: #endif
        !           155: #ifdef SIGTSTP
        !           156:        signal(SIGTSTP, SIG_IGN);
        !           157: #endif
        !           158:        if (0 != fork()) exit(0);
        !           159: 
        !           160:        if (-1 == setsid()) exit(0);
        !           161: 
        !           162:        signal(SIGHUP, SIG_IGN);
        !           163: 
        !           164:        if (0 != fork()) exit(0);
        !           165: 
        !           166:        if (0 != chdir("/")) exit(0);
        !           167: }
        !           168: #endif
        !           169: 
        !           170: static server *server_init(void) {
        !           171:        int i;
        !           172:        FILE *frandom = NULL;
        !           173: 
        !           174:        server *srv = calloc(1, sizeof(*srv));
        !           175:        assert(srv);
        !           176: #define CLEAN(x) \
        !           177:        srv->x = buffer_init();
        !           178: 
        !           179:        CLEAN(response_header);
        !           180:        CLEAN(parse_full_path);
        !           181:        CLEAN(ts_debug_str);
        !           182:        CLEAN(ts_date_str);
        !           183:        CLEAN(errorlog_buf);
        !           184:        CLEAN(response_range);
        !           185:        CLEAN(tmp_buf);
        !           186:        srv->empty_string = buffer_init_string("");
        !           187:        CLEAN(cond_check_buf);
        !           188: 
        !           189:        CLEAN(srvconf.errorlog_file);
        !           190:        CLEAN(srvconf.breakagelog_file);
        !           191:        CLEAN(srvconf.groupname);
        !           192:        CLEAN(srvconf.username);
        !           193:        CLEAN(srvconf.changeroot);
        !           194:        CLEAN(srvconf.bindhost);
        !           195:        CLEAN(srvconf.event_handler);
        !           196:        CLEAN(srvconf.pid_file);
        !           197: 
        !           198:        CLEAN(tmp_chunk_len);
        !           199: #undef CLEAN
        !           200: 
        !           201: #define CLEAN(x) \
        !           202:        srv->x = array_init();
        !           203: 
        !           204:        CLEAN(config_context);
        !           205:        CLEAN(config_touched);
        !           206:        CLEAN(status);
        !           207: #undef CLEAN
        !           208: 
        !           209:        for (i = 0; i < FILE_CACHE_MAX; i++) {
        !           210:                srv->mtime_cache[i].mtime = (time_t)-1;
        !           211:                srv->mtime_cache[i].str = buffer_init();
        !           212:        }
        !           213: 
        !           214:        if ((NULL != (frandom = fopen("/dev/urandom", "rb")) || NULL != (frandom = fopen("/dev/random", "rb")))
        !           215:                    && 1 == fread(srv->entropy, sizeof(srv->entropy), 1, frandom)) {
        !           216:                unsigned int e;
        !           217:                memcpy(&e, srv->entropy, sizeof(e) < sizeof(srv->entropy) ? sizeof(e) : sizeof(srv->entropy));
        !           218:                srand(e);
        !           219:                srv->is_real_entropy = 1;
        !           220:        } else {
        !           221:                unsigned int j;
        !           222:                srand(time(NULL) ^ getpid());
        !           223:                srv->is_real_entropy = 0;
        !           224:                for (j = 0; j < sizeof(srv->entropy); j++)
        !           225:                        srv->entropy[j] = rand();
        !           226:        }
        !           227:        if (frandom) fclose(frandom);
        !           228: 
        !           229:        srv->cur_ts = time(NULL);
        !           230:        srv->startup_ts = srv->cur_ts;
        !           231: 
        !           232:        srv->conns = calloc(1, sizeof(*srv->conns));
        !           233:        assert(srv->conns);
        !           234: 
        !           235:        srv->joblist = calloc(1, sizeof(*srv->joblist));
        !           236:        assert(srv->joblist);
        !           237: 
        !           238:        srv->fdwaitqueue = calloc(1, sizeof(*srv->fdwaitqueue));
        !           239:        assert(srv->fdwaitqueue);
        !           240: 
        !           241:        srv->srvconf.modules = array_init();
        !           242:        srv->srvconf.modules_dir = buffer_init_string(LIBRARY_DIR);
        !           243:        srv->srvconf.network_backend = buffer_init();
        !           244:        srv->srvconf.upload_tempdirs = array_init();
        !           245:        srv->srvconf.reject_expect_100_with_417 = 1;
        !           246: 
        !           247:        /* use syslog */
        !           248:        srv->errorlog_fd = STDERR_FILENO;
        !           249:        srv->errorlog_mode = ERRORLOG_FD;
        !           250: 
        !           251:        srv->split_vals = array_init();
        !           252: 
        !           253:        return srv;
        !           254: }
        !           255: 
        !           256: static void server_free(server *srv) {
        !           257:        size_t i;
        !           258: 
        !           259:        for (i = 0; i < FILE_CACHE_MAX; i++) {
        !           260:                buffer_free(srv->mtime_cache[i].str);
        !           261:        }
        !           262: 
        !           263: #define CLEAN(x) \
        !           264:        buffer_free(srv->x);
        !           265: 
        !           266:        CLEAN(response_header);
        !           267:        CLEAN(parse_full_path);
        !           268:        CLEAN(ts_debug_str);
        !           269:        CLEAN(ts_date_str);
        !           270:        CLEAN(errorlog_buf);
        !           271:        CLEAN(response_range);
        !           272:        CLEAN(tmp_buf);
        !           273:        CLEAN(empty_string);
        !           274:        CLEAN(cond_check_buf);
        !           275: 
        !           276:        CLEAN(srvconf.errorlog_file);
        !           277:        CLEAN(srvconf.breakagelog_file);
        !           278:        CLEAN(srvconf.groupname);
        !           279:        CLEAN(srvconf.username);
        !           280:        CLEAN(srvconf.changeroot);
        !           281:        CLEAN(srvconf.bindhost);
        !           282:        CLEAN(srvconf.event_handler);
        !           283:        CLEAN(srvconf.pid_file);
        !           284:        CLEAN(srvconf.modules_dir);
        !           285:        CLEAN(srvconf.network_backend);
        !           286: 
        !           287:        CLEAN(tmp_chunk_len);
        !           288: #undef CLEAN
        !           289: 
        !           290: #if 0
        !           291:        fdevent_unregister(srv->ev, srv->fd);
        !           292: #endif
        !           293:        fdevent_free(srv->ev);
        !           294: 
        !           295:        free(srv->conns);
        !           296: 
        !           297:        if (srv->config_storage) {
        !           298:                for (i = 0; i < srv->config_context->used; i++) {
        !           299:                        specific_config *s = srv->config_storage[i];
        !           300: 
        !           301:                        if (!s) continue;
        !           302: 
        !           303:                        buffer_free(s->document_root);
        !           304:                        buffer_free(s->server_name);
        !           305:                        buffer_free(s->server_tag);
        !           306:                        buffer_free(s->ssl_pemfile);
        !           307:                        buffer_free(s->ssl_ca_file);
        !           308:                        buffer_free(s->ssl_cipher_list);
        !           309:                        buffer_free(s->ssl_dh_file);
        !           310:                        buffer_free(s->ssl_ec_curve);
        !           311:                        buffer_free(s->error_handler);
        !           312:                        buffer_free(s->errorfile_prefix);
        !           313:                        array_free(s->mimetypes);
        !           314:                        buffer_free(s->ssl_verifyclient_username);
        !           315: #ifdef USE_OPENSSL
        !           316:                        SSL_CTX_free(s->ssl_ctx);
        !           317: #endif
        !           318:                        free(s);
        !           319:                }
        !           320:                free(srv->config_storage);
        !           321:                srv->config_storage = NULL;
        !           322:        }
        !           323: 
        !           324: #define CLEAN(x) \
        !           325:        array_free(srv->x);
        !           326: 
        !           327:        CLEAN(config_context);
        !           328:        CLEAN(config_touched);
        !           329:        CLEAN(status);
        !           330:        CLEAN(srvconf.upload_tempdirs);
        !           331: #undef CLEAN
        !           332: 
        !           333:        joblist_free(srv, srv->joblist);
        !           334:        fdwaitqueue_free(srv, srv->fdwaitqueue);
        !           335: 
        !           336:        if (srv->stat_cache) {
        !           337:                stat_cache_free(srv->stat_cache);
        !           338:        }
        !           339: 
        !           340:        array_free(srv->srvconf.modules);
        !           341:        array_free(srv->split_vals);
        !           342: 
        !           343: #ifdef USE_OPENSSL
        !           344:        if (srv->ssl_is_init) {
        !           345:                CRYPTO_cleanup_all_ex_data();
        !           346:                ERR_free_strings();
        !           347:                ERR_remove_state(0);
        !           348:                EVP_cleanup();
        !           349:        }
        !           350: #endif
        !           351: 
        !           352:        free(srv);
        !           353: }
        !           354: 
        !           355: static void show_version (void) {
        !           356: #ifdef USE_OPENSSL
        !           357: # define TEXT_SSL " (ssl)"
        !           358: #else
        !           359: # define TEXT_SSL
        !           360: #endif
        !           361:        char *b = PACKAGE_DESC TEXT_SSL \
        !           362: " - a light and fast webserver\n" \
        !           363: "Build-Date: " __DATE__ " " __TIME__ "\n";
        !           364: ;
        !           365: #undef TEXT_SSL
        !           366:        write(STDOUT_FILENO, b, strlen(b));
        !           367: }
        !           368: 
        !           369: static void show_features (void) {
        !           370:   const char features[] = ""
        !           371: #ifdef USE_SELECT
        !           372:       "\t+ select (generic)\n"
        !           373: #else
        !           374:       "\t- select (generic)\n"
        !           375: #endif
        !           376: #ifdef USE_POLL
        !           377:       "\t+ poll (Unix)\n"
        !           378: #else
        !           379:       "\t- poll (Unix)\n"
        !           380: #endif
        !           381: #ifdef USE_LINUX_SIGIO
        !           382:       "\t+ rt-signals (Linux 2.4+)\n"
        !           383: #else
        !           384:       "\t- rt-signals (Linux 2.4+)\n"
        !           385: #endif
        !           386: #ifdef USE_LINUX_EPOLL
        !           387:       "\t+ epoll (Linux 2.6)\n"
        !           388: #else
        !           389:       "\t- epoll (Linux 2.6)\n"
        !           390: #endif
        !           391: #ifdef USE_SOLARIS_DEVPOLL
        !           392:       "\t+ /dev/poll (Solaris)\n"
        !           393: #else
        !           394:       "\t- /dev/poll (Solaris)\n"
        !           395: #endif
        !           396: #ifdef USE_SOLARIS_PORT
        !           397:       "\t+ eventports (Solaris)\n"
        !           398: #else
        !           399:       "\t- eventports (Solaris)\n"
        !           400: #endif
        !           401: #ifdef USE_FREEBSD_KQUEUE
        !           402:       "\t+ kqueue (FreeBSD)\n"
        !           403: #else
        !           404:       "\t- kqueue (FreeBSD)\n"
        !           405: #endif
        !           406: #ifdef USE_LIBEV
        !           407:       "\t+ libev (generic)\n"
        !           408: #else
        !           409:       "\t- libev (generic)\n"
        !           410: #endif
        !           411:       "\nNetwork handler:\n\n"
        !           412: #if defined USE_LINUX_SENDFILE
        !           413:       "\t+ linux-sendfile\n"
        !           414: #else
        !           415:       "\t- linux-sendfile\n"
        !           416: #endif
        !           417: #if defined USE_FREEBSD_SENDFILE
        !           418:       "\t+ freebsd-sendfile\n"
        !           419: #else
        !           420:       "\t- freebsd-sendfile\n"
        !           421: #endif
        !           422: #if defined USE_SOLARIS_SENDFILEV
        !           423:       "\t+ solaris-sendfilev\n"
        !           424: #else
        !           425:       "\t- solaris-sendfilev\n"
        !           426: #endif
        !           427: #if defined USE_WRITEV
        !           428:       "\t+ writev\n"
        !           429: #else
        !           430:       "\t- writev\n"
        !           431: #endif
        !           432:       "\t+ write\n"
        !           433: #ifdef USE_MMAP
        !           434:       "\t+ mmap support\n"
        !           435: #else
        !           436:       "\t- mmap support\n"
        !           437: #endif
        !           438:       "\nFeatures:\n\n"
        !           439: #ifdef HAVE_IPV6
        !           440:       "\t+ IPv6 support\n"
        !           441: #else
        !           442:       "\t- IPv6 support\n"
        !           443: #endif
        !           444: #if defined HAVE_ZLIB_H && defined HAVE_LIBZ
        !           445:       "\t+ zlib support\n"
        !           446: #else
        !           447:       "\t- zlib support\n"
        !           448: #endif
        !           449: #if defined HAVE_BZLIB_H && defined HAVE_LIBBZ2
        !           450:       "\t+ bzip2 support\n"
        !           451: #else
        !           452:       "\t- bzip2 support\n"
        !           453: #endif
        !           454: #ifdef HAVE_LIBCRYPT
        !           455:       "\t+ crypt support\n"
        !           456: #else
        !           457:       "\t- crypt support\n"
        !           458: #endif
        !           459: #ifdef USE_OPENSSL
        !           460:       "\t+ SSL Support\n"
        !           461: #else
        !           462:       "\t- SSL Support\n"
        !           463: #endif
        !           464: #ifdef HAVE_LIBPCRE
        !           465:       "\t+ PCRE support\n"
        !           466: #else
        !           467:       "\t- PCRE support\n"
        !           468: #endif
        !           469: #ifdef HAVE_MYSQL
        !           470:       "\t+ mySQL support\n"
        !           471: #else
        !           472:       "\t- mySQL support\n"
        !           473: #endif
        !           474: #if defined(HAVE_LDAP_H) && defined(HAVE_LBER_H) && defined(HAVE_LIBLDAP) && defined(HAVE_LIBLBER)
        !           475:       "\t+ LDAP support\n"
        !           476: #else
        !           477:       "\t- LDAP support\n"
        !           478: #endif
        !           479: #ifdef HAVE_MEMCACHE_H
        !           480:       "\t+ memcached support\n"
        !           481: #else
        !           482:       "\t- memcached support\n"
        !           483: #endif
        !           484: #ifdef HAVE_FAM_H
        !           485:       "\t+ FAM support\n"
        !           486: #else
        !           487:       "\t- FAM support\n"
        !           488: #endif
        !           489: #ifdef HAVE_LUA_H
        !           490:       "\t+ LUA support\n"
        !           491: #else
        !           492:       "\t- LUA support\n"
        !           493: #endif
        !           494: #ifdef HAVE_LIBXML_H
        !           495:       "\t+ xml support\n"
        !           496: #else
        !           497:       "\t- xml support\n"
        !           498: #endif
        !           499: #ifdef HAVE_SQLITE3_H
        !           500:       "\t+ SQLite support\n"
        !           501: #else
        !           502:       "\t- SQLite support\n"
        !           503: #endif
        !           504: #ifdef HAVE_GDBM_H
        !           505:       "\t+ GDBM support\n"
        !           506: #else
        !           507:       "\t- GDBM support\n"
        !           508: #endif
        !           509:       "\n";
        !           510:   show_version();
        !           511:   printf("\nEvent Handlers:\n\n%s", features);
        !           512: }
        !           513: 
        !           514: static void show_help (void) {
        !           515: #ifdef USE_OPENSSL
        !           516: # define TEXT_SSL " (ssl)"
        !           517: #else
        !           518: # define TEXT_SSL
        !           519: #endif
        !           520:        char *b = PACKAGE_DESC TEXT_SSL " ("__DATE__ " " __TIME__ ")" \
        !           521: " - a light and fast webserver\n" \
        !           522: "usage:\n" \
        !           523: " -f <name>  filename of the config-file\n" \
        !           524: " -m <name>  module directory (default: "LIBRARY_DIR")\n" \
        !           525: " -p         print the parsed config-file in internal form, and exit\n" \
        !           526: " -t         test the config-file, and exit\n" \
        !           527: " -D         don't go to background (default: go to background)\n" \
        !           528: " -v         show version\n" \
        !           529: " -V         show compile-time features\n" \
        !           530: " -h         show this help\n" \
        !           531: "\n"
        !           532: ;
        !           533: #undef TEXT_SSL
        !           534: #undef TEXT_IPV6
        !           535:        write(STDOUT_FILENO, b, strlen(b));
        !           536: }
        !           537: 
        !           538: int main (int argc, char **argv) {
        !           539:        server *srv = NULL;
        !           540:        int print_config = 0;
        !           541:        int test_config = 0;
        !           542:        int i_am_root;
        !           543:        int o;
        !           544:        int num_childs = 0;
        !           545:        int pid_fd = -1, fd;
        !           546:        size_t i;
        !           547: #ifdef HAVE_SIGACTION
        !           548:        struct sigaction act;
        !           549: #endif
        !           550: #ifdef HAVE_GETRLIMIT
        !           551:        struct rlimit rlim;
        !           552: #endif
        !           553: 
        !           554: #ifdef USE_ALARM
        !           555:        struct itimerval interval;
        !           556: 
        !           557:        interval.it_interval.tv_sec = 1;
        !           558:        interval.it_interval.tv_usec = 0;
        !           559:        interval.it_value.tv_sec = 1;
        !           560:        interval.it_value.tv_usec = 0;
        !           561: #endif
        !           562: 
        !           563: 
        !           564:        /* for nice %b handling in strfime() */
        !           565:        setlocale(LC_TIME, "C");
        !           566: 
        !           567:        if (NULL == (srv = server_init())) {
        !           568:                fprintf(stderr, "did this really happen?\n");
        !           569:                return -1;
        !           570:        }
        !           571: 
        !           572:        /* init structs done */
        !           573: 
        !           574:        srv->srvconf.port = 0;
        !           575: #ifdef HAVE_GETUID
        !           576:        i_am_root = (getuid() == 0);
        !           577: #else
        !           578:        i_am_root = 0;
        !           579: #endif
        !           580:        srv->srvconf.dont_daemonize = 0;
        !           581: 
        !           582:        while(-1 != (o = getopt(argc, argv, "f:m:hvVDpt"))) {
        !           583:                switch(o) {
        !           584:                case 'f':
        !           585:                        if (srv->config_storage) {
        !           586:                                log_error_write(srv, __FILE__, __LINE__, "s",
        !           587:                                                "Can only read one config file. Use the include command to use multiple config files.");
        !           588: 
        !           589:                                server_free(srv);
        !           590:                                return -1;
        !           591:                        }
        !           592:                        if (config_read(srv, optarg)) {
        !           593:                                server_free(srv);
        !           594:                                return -1;
        !           595:                        }
        !           596:                        break;
        !           597:                case 'm':
        !           598:                        buffer_copy_string(srv->srvconf.modules_dir, optarg);
        !           599:                        break;
        !           600:                case 'p': print_config = 1; break;
        !           601:                case 't': test_config = 1; break;
        !           602:                case 'D': srv->srvconf.dont_daemonize = 1; break;
        !           603:                case 'v': show_version(); return 0;
        !           604:                case 'V': show_features(); return 0;
        !           605:                case 'h': show_help(); return 0;
        !           606:                default:
        !           607:                        show_help();
        !           608:                        server_free(srv);
        !           609:                        return -1;
        !           610:                }
        !           611:        }
        !           612: 
        !           613:        if (!srv->config_storage) {
        !           614:                log_error_write(srv, __FILE__, __LINE__, "s",
        !           615:                                "No configuration available. Try using -f option.");
        !           616: 
        !           617:                server_free(srv);
        !           618:                return -1;
        !           619:        }
        !           620: 
        !           621:        if (print_config) {
        !           622:                data_unset *dc = srv->config_context->data[0];
        !           623:                if (dc) {
        !           624:                        dc->print(dc, 0);
        !           625:                        fprintf(stdout, "\n");
        !           626:                } else {
        !           627:                        /* shouldn't happend */
        !           628:                        fprintf(stderr, "global config not found\n");
        !           629:                }
        !           630:        }
        !           631: 
        !           632:        if (test_config) {
        !           633:                printf("Syntax OK\n");
        !           634:        }
        !           635: 
        !           636:        if (test_config || print_config) {
        !           637:                server_free(srv);
        !           638:                return 0;
        !           639:        }
        !           640: 
        !           641:        /* close stdin and stdout, as they are not needed */
        !           642:        openDevNull(STDIN_FILENO);
        !           643:        openDevNull(STDOUT_FILENO);
        !           644: 
        !           645:        if (0 != config_set_defaults(srv)) {
        !           646:                log_error_write(srv, __FILE__, __LINE__, "s",
        !           647:                                "setting default values failed");
        !           648:                server_free(srv);
        !           649:                return -1;
        !           650:        }
        !           651: 
        !           652:        /* UID handling */
        !           653: #ifdef HAVE_GETUID
        !           654:        if (!i_am_root && issetugid()) {
        !           655:                /* we are setuid-root */
        !           656: 
        !           657:                log_error_write(srv, __FILE__, __LINE__, "s",
        !           658:                                "Are you nuts ? Don't apply a SUID bit to this binary");
        !           659: 
        !           660:                server_free(srv);
        !           661:                return -1;
        !           662:        }
        !           663: #endif
        !           664: 
        !           665:        /* check document-root */
        !           666:        if (srv->config_storage[0]->document_root->used <= 1) {
        !           667:                log_error_write(srv, __FILE__, __LINE__, "s",
        !           668:                                "document-root is not set\n");
        !           669: 
        !           670:                server_free(srv);
        !           671: 
        !           672:                return -1;
        !           673:        }
        !           674: 
        !           675:        if (plugins_load(srv)) {
        !           676:                log_error_write(srv, __FILE__, __LINE__, "s",
        !           677:                                "loading plugins finally failed");
        !           678: 
        !           679:                plugins_free(srv);
        !           680:                server_free(srv);
        !           681: 
        !           682:                return -1;
        !           683:        }
        !           684: 
        !           685:        /* open pid file BEFORE chroot */
        !           686:        if (srv->srvconf.pid_file->used) {
        !           687:                if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
        !           688:                        struct stat st;
        !           689:                        if (errno != EEXIST) {
        !           690:                                log_error_write(srv, __FILE__, __LINE__, "sbs",
        !           691:                                        "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
        !           692:                                return -1;
        !           693:                        }
        !           694: 
        !           695:                        if (0 != stat(srv->srvconf.pid_file->ptr, &st)) {
        !           696:                                log_error_write(srv, __FILE__, __LINE__, "sbs",
        !           697:                                                "stating existing pid-file failed:", srv->srvconf.pid_file, strerror(errno));
        !           698:                        }
        !           699: 
        !           700:                        if (!S_ISREG(st.st_mode)) {
        !           701:                                log_error_write(srv, __FILE__, __LINE__, "sb",
        !           702:                                                "pid-file exists and isn't regular file:", srv->srvconf.pid_file);
        !           703:                                return -1;
        !           704:                        }
        !           705: 
        !           706:                        if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
        !           707:                                log_error_write(srv, __FILE__, __LINE__, "sbs",
        !           708:                                                "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
        !           709:                                return -1;
        !           710:                        }
        !           711:                }
        !           712:        }
        !           713: 
        !           714:        if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
        !           715:                /* select limits itself
        !           716:                 *
        !           717:                 * as it is a hard limit and will lead to a segfault we add some safety
        !           718:                 * */
        !           719:                srv->max_fds = FD_SETSIZE - 200;
        !           720:        } else {
        !           721:                srv->max_fds = 4096;
        !           722:        }
        !           723: 
        !           724:        if (i_am_root) {
        !           725:                struct group *grp = NULL;
        !           726:                struct passwd *pwd = NULL;
        !           727:                int use_rlimit = 1;
        !           728: 
        !           729: #ifdef HAVE_VALGRIND_VALGRIND_H
        !           730:                if (RUNNING_ON_VALGRIND) use_rlimit = 0;
        !           731: #endif
        !           732: 
        !           733: #ifdef HAVE_GETRLIMIT
        !           734:                if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) {
        !           735:                        log_error_write(srv, __FILE__, __LINE__,
        !           736:                                        "ss", "couldn't get 'max filedescriptors'",
        !           737:                                        strerror(errno));
        !           738:                        return -1;
        !           739:                }
        !           740: 
        !           741:                if (use_rlimit && srv->srvconf.max_fds) {
        !           742:                        /* set rlimits */
        !           743: 
        !           744:                        rlim.rlim_cur = srv->srvconf.max_fds;
        !           745:                        rlim.rlim_max = srv->srvconf.max_fds;
        !           746: 
        !           747:                        if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
        !           748:                                log_error_write(srv, __FILE__, __LINE__,
        !           749:                                                "ss", "couldn't set 'max filedescriptors'",
        !           750:                                                strerror(errno));
        !           751:                                return -1;
        !           752:                        }
        !           753:                }
        !           754: 
        !           755:                if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
        !           756:                        srv->max_fds = rlim.rlim_cur < ((int)FD_SETSIZE) - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
        !           757:                } else {
        !           758:                        srv->max_fds = rlim.rlim_cur;
        !           759:                }
        !           760: 
        !           761:                /* set core file rlimit, if enable_cores is set */
        !           762:                if (use_rlimit && srv->srvconf.enable_cores && getrlimit(RLIMIT_CORE, &rlim) == 0) {
        !           763:                        rlim.rlim_cur = rlim.rlim_max;
        !           764:                        setrlimit(RLIMIT_CORE, &rlim);
        !           765:                }
        !           766: #endif
        !           767:                if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
        !           768:                        /* don't raise the limit above FD_SET_SIZE */
        !           769:                        if (srv->max_fds > ((int)FD_SETSIZE) - 200) {
        !           770:                                log_error_write(srv, __FILE__, __LINE__, "sd",
        !           771:                                                "can't raise max filedescriptors above",  FD_SETSIZE - 200,
        !           772:                                                "if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
        !           773:                                return -1;
        !           774:                        }
        !           775:                }
        !           776: 
        !           777: 
        !           778: #ifdef HAVE_PWD_H
        !           779:                /* set user and group */
        !           780:                if (srv->srvconf.username->used) {
        !           781:                        if (NULL == (pwd = getpwnam(srv->srvconf.username->ptr))) {
        !           782:                                log_error_write(srv, __FILE__, __LINE__, "sb",
        !           783:                                                "can't find username", srv->srvconf.username);
        !           784:                                return -1;
        !           785:                        }
        !           786: 
        !           787:                        if (pwd->pw_uid == 0) {
        !           788:                                log_error_write(srv, __FILE__, __LINE__, "s",
        !           789:                                                "I will not set uid to 0\n");
        !           790:                                return -1;
        !           791:                        }
        !           792:                }
        !           793: 
        !           794:                if (srv->srvconf.groupname->used) {
        !           795:                        if (NULL == (grp = getgrnam(srv->srvconf.groupname->ptr))) {
        !           796:                                log_error_write(srv, __FILE__, __LINE__, "sb",
        !           797:                                        "can't find groupname", srv->srvconf.groupname);
        !           798:                                return -1;
        !           799:                        }
        !           800:                        if (grp->gr_gid == 0) {
        !           801:                                log_error_write(srv, __FILE__, __LINE__, "s",
        !           802:                                                "I will not set gid to 0\n");
        !           803:                                return -1;
        !           804:                        }
        !           805:                }
        !           806: #endif
        !           807:                /* we need root-perms for port < 1024 */
        !           808:                if (0 != network_init(srv)) {
        !           809:                        plugins_free(srv);
        !           810:                        server_free(srv);
        !           811: 
        !           812:                        return -1;
        !           813:                }
        !           814: #ifdef HAVE_PWD_H
        !           815:                /* 
        !           816:                 * Change group before chroot, when we have access
        !           817:                 * to /etc/group
        !           818:                 * */
        !           819:                if (NULL != grp) {
        !           820:                        setgid(grp->gr_gid);
        !           821:                        setgroups(0, NULL);
        !           822:                        if (srv->srvconf.username->used) {
        !           823:                                initgroups(srv->srvconf.username->ptr, grp->gr_gid);
        !           824:                        }
        !           825:                }
        !           826: #endif
        !           827: #ifdef HAVE_CHROOT
        !           828:                if (srv->srvconf.changeroot->used) {
        !           829:                        tzset();
        !           830: 
        !           831:                        if (-1 == chroot(srv->srvconf.changeroot->ptr)) {
        !           832:                                log_error_write(srv, __FILE__, __LINE__, "ss", "chroot failed: ", strerror(errno));
        !           833:                                return -1;
        !           834:                        }
        !           835:                        if (-1 == chdir("/")) {
        !           836:                                log_error_write(srv, __FILE__, __LINE__, "ss", "chdir failed: ", strerror(errno));
        !           837:                                return -1;
        !           838:                        }
        !           839:                }
        !           840: #endif
        !           841: #ifdef HAVE_PWD_H
        !           842:                /* drop root privs */
        !           843:                if (NULL != pwd) {
        !           844:                        setuid(pwd->pw_uid);
        !           845:                }
        !           846: #endif
        !           847: #if defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_DUMPABLE)
        !           848:                /**
        !           849:                 * on IRIX 6.5.30 they have prctl() but no DUMPABLE
        !           850:                 */
        !           851:                if (srv->srvconf.enable_cores) {
        !           852:                        prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
        !           853:                }
        !           854: #endif
        !           855:        } else {
        !           856: 
        !           857: #ifdef HAVE_GETRLIMIT
        !           858:                if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) {
        !           859:                        log_error_write(srv, __FILE__, __LINE__,
        !           860:                                        "ss", "couldn't get 'max filedescriptors'",
        !           861:                                        strerror(errno));
        !           862:                        return -1;
        !           863:                }
        !           864: 
        !           865:                /**
        !           866:                 * we are not root can can't increase the fd-limit, but we can reduce it
        !           867:                 */
        !           868:                if (srv->srvconf.max_fds && srv->srvconf.max_fds < rlim.rlim_cur) {
        !           869:                        /* set rlimits */
        !           870: 
        !           871:                        rlim.rlim_cur = srv->srvconf.max_fds;
        !           872: 
        !           873:                        if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
        !           874:                                log_error_write(srv, __FILE__, __LINE__,
        !           875:                                                "ss", "couldn't set 'max filedescriptors'",
        !           876:                                                strerror(errno));
        !           877:                                return -1;
        !           878:                        }
        !           879:                }
        !           880: 
        !           881:                if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
        !           882:                        srv->max_fds = rlim.rlim_cur < ((int)FD_SETSIZE) - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
        !           883:                } else {
        !           884:                        srv->max_fds = rlim.rlim_cur;
        !           885:                }
        !           886: 
        !           887:                /* set core file rlimit, if enable_cores is set */
        !           888:                if (srv->srvconf.enable_cores && getrlimit(RLIMIT_CORE, &rlim) == 0) {
        !           889:                        rlim.rlim_cur = rlim.rlim_max;
        !           890:                        setrlimit(RLIMIT_CORE, &rlim);
        !           891:                }
        !           892: 
        !           893: #endif
        !           894:                if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
        !           895:                        /* don't raise the limit above FD_SET_SIZE */
        !           896:                        if (srv->max_fds > ((int)FD_SETSIZE) - 200) {
        !           897:                                log_error_write(srv, __FILE__, __LINE__, "sd",
        !           898:                                                "can't raise max filedescriptors above",  FD_SETSIZE - 200,
        !           899:                                                "if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
        !           900:                                return -1;
        !           901:                        }
        !           902:                }
        !           903: 
        !           904:                if (0 != network_init(srv)) {
        !           905:                        plugins_free(srv);
        !           906:                        server_free(srv);
        !           907: 
        !           908:                        return -1;
        !           909:                }
        !           910:        }
        !           911: 
        !           912:        /* set max-conns */
        !           913:        if (srv->srvconf.max_conns > srv->max_fds/2) {
        !           914:                /* we can't have more connections than max-fds/2 */
        !           915:                log_error_write(srv, __FILE__, __LINE__, "sdd", "can't have more connections than fds/2: ", srv->srvconf.max_conns, srv->max_fds);
        !           916:                srv->max_conns = srv->max_fds/2;
        !           917:        } else if (srv->srvconf.max_conns) {
        !           918:                /* otherwise respect the wishes of the user */
        !           919:                srv->max_conns = srv->srvconf.max_conns;
        !           920:        } else {
        !           921:                /* or use the default: we really don't want to hit max-fds */
        !           922:                srv->max_conns = srv->max_fds/3;
        !           923:        }
        !           924: 
        !           925:        if (HANDLER_GO_ON != plugins_call_init(srv)) {
        !           926:                log_error_write(srv, __FILE__, __LINE__, "s", "Initialization of plugins failed. Going down.");
        !           927: 
        !           928:                plugins_free(srv);
        !           929:                network_close(srv);
        !           930:                server_free(srv);
        !           931: 
        !           932:                return -1;
        !           933:        }
        !           934: 
        !           935: #ifdef HAVE_FORK
        !           936:        /* network is up, let's deamonize ourself */
        !           937:        if (srv->srvconf.dont_daemonize == 0) daemonize();
        !           938: #endif
        !           939: 
        !           940: 
        !           941: #ifdef HAVE_SIGACTION
        !           942:        memset(&act, 0, sizeof(act));
        !           943:        act.sa_handler = SIG_IGN;
        !           944:        sigaction(SIGPIPE, &act, NULL);
        !           945:        sigaction(SIGUSR1, &act, NULL);
        !           946: # if defined(SA_SIGINFO)
        !           947:        act.sa_sigaction = sigaction_handler;
        !           948:        sigemptyset(&act.sa_mask);
        !           949:        act.sa_flags = SA_SIGINFO;
        !           950: # else
        !           951:        act.sa_handler = signal_handler;
        !           952:        sigemptyset(&act.sa_mask);
        !           953:        act.sa_flags = 0;
        !           954: # endif
        !           955:        sigaction(SIGINT,  &act, NULL);
        !           956:        sigaction(SIGTERM, &act, NULL);
        !           957:        sigaction(SIGHUP,  &act, NULL);
        !           958:        sigaction(SIGALRM, &act, NULL);
        !           959:        sigaction(SIGCHLD, &act, NULL);
        !           960: 
        !           961: #elif defined(HAVE_SIGNAL)
        !           962:        /* ignore the SIGPIPE from sendfile() */
        !           963:        signal(SIGPIPE, SIG_IGN);
        !           964:        signal(SIGUSR1, SIG_IGN);
        !           965:        signal(SIGALRM, signal_handler);
        !           966:        signal(SIGTERM, signal_handler);
        !           967:        signal(SIGHUP,  signal_handler);
        !           968:        signal(SIGCHLD,  signal_handler);
        !           969:        signal(SIGINT,  signal_handler);
        !           970: #endif
        !           971: 
        !           972: #ifdef USE_ALARM
        !           973:        signal(SIGALRM, signal_handler);
        !           974: 
        !           975:        /* setup periodic timer (1 second) */
        !           976:        if (setitimer(ITIMER_REAL, &interval, NULL)) {
        !           977:                log_error_write(srv, __FILE__, __LINE__, "s", "setting timer failed");
        !           978:                return -1;
        !           979:        }
        !           980: 
        !           981:        getitimer(ITIMER_REAL, &interval);
        !           982: #endif
        !           983: 
        !           984: 
        !           985:        srv->gid = getgid();
        !           986:        srv->uid = getuid();
        !           987: 
        !           988:        /* write pid file */
        !           989:        if (pid_fd != -1) {
        !           990:                buffer_copy_long(srv->tmp_buf, getpid());
        !           991:                buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("\n"));
        !           992:                write(pid_fd, srv->tmp_buf->ptr, srv->tmp_buf->used - 1);
        !           993:                close(pid_fd);
        !           994:                pid_fd = -1;
        !           995:        }
        !           996: 
        !           997:        /* Close stderr ASAP in the child process to make sure that nothing
        !           998:         * is being written to that fd which may not be valid anymore. */
        !           999:        if (-1 == log_error_open(srv)) {
        !          1000:                log_error_write(srv, __FILE__, __LINE__, "s", "Opening errorlog failed. Going down.");
        !          1001: 
        !          1002:                plugins_free(srv);
        !          1003:                network_close(srv);
        !          1004:                server_free(srv);
        !          1005:                return -1;
        !          1006:        }
        !          1007: 
        !          1008:        if (HANDLER_GO_ON != plugins_call_set_defaults(srv)) {
        !          1009:                log_error_write(srv, __FILE__, __LINE__, "s", "Configuration of plugins failed. Going down.");
        !          1010: 
        !          1011:                plugins_free(srv);
        !          1012:                network_close(srv);
        !          1013:                server_free(srv);
        !          1014: 
        !          1015:                return -1;
        !          1016:        }
        !          1017: 
        !          1018:        /* dump unused config-keys */
        !          1019:        for (i = 0; i < srv->config_context->used; i++) {
        !          1020:                array *config = ((data_config *)srv->config_context->data[i])->value;
        !          1021:                size_t j;
        !          1022: 
        !          1023:                for (j = 0; config && j < config->used; j++) {
        !          1024:                        data_unset *du = config->data[j];
        !          1025: 
        !          1026:                        /* all var.* is known as user defined variable */
        !          1027:                        if (strncmp(du->key->ptr, "var.", sizeof("var.") - 1) == 0) {
        !          1028:                                continue;
        !          1029:                        }
        !          1030: 
        !          1031:                        if (NULL == array_get_element(srv->config_touched, du->key->ptr)) {
        !          1032:                                log_error_write(srv, __FILE__, __LINE__, "sbs",
        !          1033:                                                "WARNING: unknown config-key:",
        !          1034:                                                du->key,
        !          1035:                                                "(ignored)");
        !          1036:                        }
        !          1037:                }
        !          1038:        }
        !          1039: 
        !          1040:        if (srv->config_unsupported) {
        !          1041:                log_error_write(srv, __FILE__, __LINE__, "s",
        !          1042:                                "Configuration contains unsupported keys. Going down.");
        !          1043:        }
        !          1044: 
        !          1045:        if (srv->config_deprecated) {
        !          1046:                log_error_write(srv, __FILE__, __LINE__, "s",
        !          1047:                                "Configuration contains deprecated keys. Going down.");
        !          1048:        }
        !          1049: 
        !          1050:        if (srv->config_unsupported || srv->config_deprecated) {
        !          1051:                plugins_free(srv);
        !          1052:                network_close(srv);
        !          1053:                server_free(srv);
        !          1054: 
        !          1055:                return -1;
        !          1056:        }
        !          1057: 
        !          1058: 
        !          1059: #ifdef HAVE_FORK
        !          1060:        /* start watcher and workers */
        !          1061:        num_childs = srv->srvconf.max_worker;
        !          1062:        if (num_childs > 0) {
        !          1063:                int child = 0;
        !          1064:                while (!child && !srv_shutdown && !graceful_shutdown) {
        !          1065:                        if (num_childs > 0) {
        !          1066:                                switch (fork()) {
        !          1067:                                case -1:
        !          1068:                                        return -1;
        !          1069:                                case 0:
        !          1070:                                        child = 1;
        !          1071:                                        break;
        !          1072:                                default:
        !          1073:                                        num_childs--;
        !          1074:                                        break;
        !          1075:                                }
        !          1076:                        } else {
        !          1077:                                int status;
        !          1078: 
        !          1079:                                if (-1 != wait(&status)) {
        !          1080:                                        /** 
        !          1081:                                         * one of our workers went away 
        !          1082:                                         */
        !          1083:                                        num_childs++;
        !          1084:                                } else {
        !          1085:                                        switch (errno) {
        !          1086:                                        case EINTR:
        !          1087:                                                /**
        !          1088:                                                 * if we receive a SIGHUP we have to close our logs ourself as we don't 
        !          1089:                                                 * have the mainloop who can help us here
        !          1090:                                                 */
        !          1091:                                                if (handle_sig_hup) {
        !          1092:                                                        handle_sig_hup = 0;
        !          1093: 
        !          1094:                                                        log_error_cycle(srv);
        !          1095: 
        !          1096:                                                        /**
        !          1097:                                                         * forward to all procs in the process-group
        !          1098:                                                         * 
        !          1099:                                                         * we also send it ourself
        !          1100:                                                         */
        !          1101:                                                        if (!forwarded_sig_hup) {
        !          1102:                                                                forwarded_sig_hup = 1;
        !          1103:                                                                kill(0, SIGHUP);
        !          1104:                                                        }
        !          1105:                                                }
        !          1106:                                                break;
        !          1107:                                        default:
        !          1108:                                                break;
        !          1109:                                        }
        !          1110:                                }
        !          1111:                        }
        !          1112:                }
        !          1113: 
        !          1114:                /**
        !          1115:                 * for the parent this is the exit-point 
        !          1116:                 */
        !          1117:                if (!child) {
        !          1118:                        /** 
        !          1119:                         * kill all children too 
        !          1120:                         */
        !          1121:                        if (graceful_shutdown) {
        !          1122:                                kill(0, SIGINT);
        !          1123:                        } else if (srv_shutdown) {
        !          1124:                                kill(0, SIGTERM);
        !          1125:                        }
        !          1126: 
        !          1127:                        log_error_close(srv);
        !          1128:                        network_close(srv);
        !          1129:                        connections_free(srv);
        !          1130:                        plugins_free(srv);
        !          1131:                        server_free(srv);
        !          1132:                        return 0;
        !          1133:                }
        !          1134:        }
        !          1135: #endif
        !          1136: 
        !          1137:        if (NULL == (srv->ev = fdevent_init(srv, srv->max_fds + 1, srv->event_handler))) {
        !          1138:                log_error_write(srv, __FILE__, __LINE__,
        !          1139:                                "s", "fdevent_init failed");
        !          1140:                return -1;
        !          1141:        }
        !          1142: 
        !          1143:        /* libev backend overwrites our SIGCHLD handler and calls waitpid on SIGCHLD; we want our own SIGCHLD handling. */
        !          1144: #ifdef HAVE_SIGACTION
        !          1145:        sigaction(SIGCHLD, &act, NULL);
        !          1146: #elif defined(HAVE_SIGNAL)
        !          1147:        signal(SIGCHLD,  signal_handler);
        !          1148: #endif
        !          1149: 
        !          1150:        /*
        !          1151:         * kqueue() is called here, select resets its internals,
        !          1152:         * all server sockets get their handlers
        !          1153:         *
        !          1154:         * */
        !          1155:        if (0 != network_register_fdevents(srv)) {
        !          1156:                plugins_free(srv);
        !          1157:                network_close(srv);
        !          1158:                server_free(srv);
        !          1159: 
        !          1160:                return -1;
        !          1161:        }
        !          1162: 
        !          1163:        /* might fail if user is using fam (not gamin) and famd isn't running */
        !          1164:        if (NULL == (srv->stat_cache = stat_cache_init())) {
        !          1165:                log_error_write(srv, __FILE__, __LINE__, "s",
        !          1166:                        "stat-cache could not be setup, dieing.");
        !          1167:                return -1;
        !          1168:        }
        !          1169: 
        !          1170: #ifdef HAVE_FAM_H
        !          1171:        /* setup FAM */
        !          1172:        if (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM) {
        !          1173:                if (0 != FAMOpen2(srv->stat_cache->fam, "lighttpd")) {
        !          1174:                        log_error_write(srv, __FILE__, __LINE__, "s",
        !          1175:                                         "could not open a fam connection, dieing.");
        !          1176:                        return -1;
        !          1177:                }
        !          1178: #ifdef HAVE_FAMNOEXISTS
        !          1179:                FAMNoExists(srv->stat_cache->fam);
        !          1180: #endif
        !          1181: 
        !          1182:                srv->stat_cache->fam_fcce_ndx = -1;
        !          1183:                fdevent_register(srv->ev, FAMCONNECTION_GETFD(srv->stat_cache->fam), stat_cache_handle_fdevent, NULL);
        !          1184:                fdevent_event_set(srv->ev, &(srv->stat_cache->fam_fcce_ndx), FAMCONNECTION_GETFD(srv->stat_cache->fam), FDEVENT_IN);
        !          1185:        }
        !          1186: #endif
        !          1187: 
        !          1188: 
        !          1189:        /* get the current number of FDs */
        !          1190:        srv->cur_fds = open("/dev/null", O_RDONLY);
        !          1191:        close(srv->cur_fds);
        !          1192: 
        !          1193:        for (i = 0; i < srv->srv_sockets.used; i++) {
        !          1194:                server_socket *srv_socket = srv->srv_sockets.ptr[i];
        !          1195:                if (-1 == fdevent_fcntl_set(srv->ev, srv_socket->fd)) {
        !          1196:                        log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed:", strerror(errno));
        !          1197:                        return -1;
        !          1198:                }
        !          1199:        }
        !          1200: 
        !          1201:        /* main-loop */
        !          1202:        while (!srv_shutdown) {
        !          1203:                int n;
        !          1204:                size_t ndx;
        !          1205:                time_t min_ts;
        !          1206: 
        !          1207:                if (handle_sig_hup) {
        !          1208:                        handler_t r;
        !          1209: 
        !          1210:                        /* reset notification */
        !          1211:                        handle_sig_hup = 0;
        !          1212: 
        !          1213: 
        !          1214:                        /* cycle logfiles */
        !          1215: 
        !          1216:                        switch(r = plugins_call_handle_sighup(srv)) {
        !          1217:                        case HANDLER_GO_ON:
        !          1218:                                break;
        !          1219:                        default:
        !          1220:                                log_error_write(srv, __FILE__, __LINE__, "sd", "sighup-handler return with an error", r);
        !          1221:                                break;
        !          1222:                        }
        !          1223: 
        !          1224:                        if (-1 == log_error_cycle(srv)) {
        !          1225:                                log_error_write(srv, __FILE__, __LINE__, "s", "cycling errorlog failed, dying");
        !          1226: 
        !          1227:                                return -1;
        !          1228:                        } else {
        !          1229: #ifdef HAVE_SIGACTION
        !          1230:                                log_error_write(srv, __FILE__, __LINE__, "sdsd", 
        !          1231:                                        "logfiles cycled UID =",
        !          1232:                                        last_sighup_info.si_uid,
        !          1233:                                        "PID =",
        !          1234:                                        last_sighup_info.si_pid);
        !          1235: #else
        !          1236:                                log_error_write(srv, __FILE__, __LINE__, "s", 
        !          1237:                                        "logfiles cycled");
        !          1238: #endif
        !          1239:                        }
        !          1240:                }
        !          1241: 
        !          1242:                if (handle_sig_alarm) {
        !          1243:                        /* a new second */
        !          1244: 
        !          1245: #ifdef USE_ALARM
        !          1246:                        /* reset notification */
        !          1247:                        handle_sig_alarm = 0;
        !          1248: #endif
        !          1249: 
        !          1250:                        /* get current time */
        !          1251:                        min_ts = time(NULL);
        !          1252: 
        !          1253:                        if (min_ts != srv->cur_ts) {
        !          1254:                                int cs = 0;
        !          1255:                                connections *conns = srv->conns;
        !          1256:                                handler_t r;
        !          1257: 
        !          1258:                                switch(r = plugins_call_handle_trigger(srv)) {
        !          1259:                                case HANDLER_GO_ON:
        !          1260:                                        break;
        !          1261:                                case HANDLER_ERROR:
        !          1262:                                        log_error_write(srv, __FILE__, __LINE__, "s", "one of the triggers failed");
        !          1263:                                        break;
        !          1264:                                default:
        !          1265:                                        log_error_write(srv, __FILE__, __LINE__, "d", r);
        !          1266:                                        break;
        !          1267:                                }
        !          1268: 
        !          1269:                                /* trigger waitpid */
        !          1270:                                srv->cur_ts = min_ts;
        !          1271: 
        !          1272:                                /* cleanup stat-cache */
        !          1273:                                stat_cache_trigger_cleanup(srv);
        !          1274:                                /**
        !          1275:                                 * check all connections for timeouts
        !          1276:                                 *
        !          1277:                                 */
        !          1278:                                for (ndx = 0; ndx < conns->used; ndx++) {
        !          1279:                                        int changed = 0;
        !          1280:                                        connection *con;
        !          1281:                                        int t_diff;
        !          1282: 
        !          1283:                                        con = conns->ptr[ndx];
        !          1284: 
        !          1285:                                        if (con->state == CON_STATE_READ ||
        !          1286:                                            con->state == CON_STATE_READ_POST) {
        !          1287:                                                if (con->request_count == 1) {
        !          1288:                                                        if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) {
        !          1289:                                                                /* time - out */
        !          1290: #if 0
        !          1291:                                                                log_error_write(srv, __FILE__, __LINE__, "sd",
        !          1292:                                                                                "connection closed - read-timeout:", con->fd);
        !          1293: #endif
        !          1294:                                                                connection_set_state(srv, con, CON_STATE_ERROR);
        !          1295:                                                                changed = 1;
        !          1296:                                                        }
        !          1297:                                                } else {
        !          1298:                                                        if (srv->cur_ts - con->read_idle_ts > con->keep_alive_idle) {
        !          1299:                                                                /* time - out */
        !          1300: #if 0
        !          1301:                                                                log_error_write(srv, __FILE__, __LINE__, "sd",
        !          1302:                                                                                "connection closed - read-timeout:", con->fd);
        !          1303: #endif
        !          1304:                                                                connection_set_state(srv, con, CON_STATE_ERROR);
        !          1305:                                                                changed = 1;
        !          1306:                                                        }
        !          1307:                                                }
        !          1308:                                        }
        !          1309: 
        !          1310:                                        if ((con->state == CON_STATE_WRITE) &&
        !          1311:                                            (con->write_request_ts != 0)) {
        !          1312: #if 0
        !          1313:                                                if (srv->cur_ts - con->write_request_ts > 60) {
        !          1314:                                                        log_error_write(srv, __FILE__, __LINE__, "sdd",
        !          1315:                                                                        "connection closed - pre-write-request-timeout:", con->fd, srv->cur_ts - con->write_request_ts);
        !          1316:                                                }
        !          1317: #endif
        !          1318: 
        !          1319:                                                if (srv->cur_ts - con->write_request_ts > con->conf.max_write_idle) {
        !          1320:                                                        /* time - out */
        !          1321:                                                        if (con->conf.log_timeouts) {
        !          1322:                                                                log_error_write(srv, __FILE__, __LINE__, "sbsosds",
        !          1323:                                                                        "NOTE: a request for",
        !          1324:                                                                        con->request.uri,
        !          1325:                                                                        "timed out after writing",
        !          1326:                                                                        con->bytes_written,
        !          1327:                                                                        "bytes. We waited",
        !          1328:                                                                        (int)con->conf.max_write_idle,
        !          1329:                                                                        "seconds. If this a problem increase server.max-write-idle");
        !          1330:                                                        }
        !          1331:                                                        connection_set_state(srv, con, CON_STATE_ERROR);
        !          1332:                                                        changed = 1;
        !          1333:                                                }
        !          1334:                                        }
        !          1335: 
        !          1336:                                        if (con->state == CON_STATE_CLOSE && (srv->cur_ts - con->close_timeout_ts > HTTP_LINGER_TIMEOUT)) {
        !          1337:                                                changed = 1;
        !          1338:                                        }
        !          1339: 
        !          1340:                                        /* we don't like div by zero */
        !          1341:                                        if (0 == (t_diff = srv->cur_ts - con->connection_start)) t_diff = 1;
        !          1342: 
        !          1343:                                        if (con->traffic_limit_reached &&
        !          1344:                                            (con->conf.kbytes_per_second == 0 ||
        !          1345:                                             ((con->bytes_written / t_diff) < con->conf.kbytes_per_second * 1024))) {
        !          1346:                                                /* enable connection again */
        !          1347:                                                con->traffic_limit_reached = 0;
        !          1348: 
        !          1349:                                                changed = 1;
        !          1350:                                        }
        !          1351: 
        !          1352:                                        if (changed) {
        !          1353:                                                connection_state_machine(srv, con);
        !          1354:                                        }
        !          1355:                                        con->bytes_written_cur_second = 0;
        !          1356:                                        *(con->conf.global_bytes_per_second_cnt_ptr) = 0;
        !          1357: 
        !          1358: #if 0
        !          1359:                                        if (cs == 0) {
        !          1360:                                                fprintf(stderr, "connection-state: ");
        !          1361:                                                cs = 1;
        !          1362:                                        }
        !          1363: 
        !          1364:                                        fprintf(stderr, "c[%d,%d]: %s ",
        !          1365:                                                con->fd,
        !          1366:                                                con->fcgi.fd,
        !          1367:                                                connection_get_state(con->state));
        !          1368: #endif
        !          1369:                                }
        !          1370: 
        !          1371:                                if (cs == 1) fprintf(stderr, "\n");
        !          1372:                        }
        !          1373:                }
        !          1374: 
        !          1375:                if (srv->sockets_disabled) {
        !          1376:                        /* our server sockets are disabled, why ? */
        !          1377: 
        !          1378:                        if ((srv->cur_fds + srv->want_fds < srv->max_fds * 8 / 10) && /* we have enough unused fds */
        !          1379:                            (srv->conns->used <= srv->max_conns * 9 / 10) &&
        !          1380:                            (0 == graceful_shutdown)) {
        !          1381:                                for (i = 0; i < srv->srv_sockets.used; i++) {
        !          1382:                                        server_socket *srv_socket = srv->srv_sockets.ptr[i];
        !          1383:                                        fdevent_event_set(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
        !          1384:                                }
        !          1385: 
        !          1386:                                log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets enabled again");
        !          1387: 
        !          1388:                                srv->sockets_disabled = 0;
        !          1389:                        }
        !          1390:                } else {
        !          1391:                        if ((srv->cur_fds + srv->want_fds > srv->max_fds * 9 / 10) || /* out of fds */
        !          1392:                            (srv->conns->used >= srv->max_conns) || /* out of connections */
        !          1393:                            (graceful_shutdown)) { /* graceful_shutdown */
        !          1394: 
        !          1395:                                /* disable server-fds */
        !          1396: 
        !          1397:                                for (i = 0; i < srv->srv_sockets.used; i++) {
        !          1398:                                        server_socket *srv_socket = srv->srv_sockets.ptr[i];
        !          1399:                                        fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
        !          1400: 
        !          1401:                                        if (graceful_shutdown) {
        !          1402:                                                /* we don't want this socket anymore,
        !          1403:                                                 *
        !          1404:                                                 * closing it right away will make it possible for
        !          1405:                                                 * the next lighttpd to take over (graceful restart)
        !          1406:                                                 *  */
        !          1407: 
        !          1408:                                                fdevent_unregister(srv->ev, srv_socket->fd);
        !          1409:                                                close(srv_socket->fd);
        !          1410:                                                srv_socket->fd = -1;
        !          1411: 
        !          1412:                                                /* network_close() will cleanup after us */
        !          1413: 
        !          1414:                                                if (srv->srvconf.pid_file->used &&
        !          1415:                                                    srv->srvconf.changeroot->used == 0) {
        !          1416:                                                        if (0 != unlink(srv->srvconf.pid_file->ptr)) {
        !          1417:                                                                if (errno != EACCES && errno != EPERM) {
        !          1418:                                                                        log_error_write(srv, __FILE__, __LINE__, "sbds",
        !          1419:                                                                                        "unlink failed for:",
        !          1420:                                                                                        srv->srvconf.pid_file,
        !          1421:                                                                                        errno,
        !          1422:                                                                                        strerror(errno));
        !          1423:                                                                }
        !          1424:                                                        }
        !          1425:                                                }
        !          1426:                                        }
        !          1427:                                }
        !          1428: 
        !          1429:                                if (graceful_shutdown) {
        !          1430:                                        log_error_write(srv, __FILE__, __LINE__, "s", "[note] graceful shutdown started");
        !          1431:                                } else if (srv->conns->used >= srv->max_conns) {
        !          1432:                                        log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, connection limit reached");
        !          1433:                                } else {
        !          1434:                                        log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, out-of-fds");
        !          1435:                                }
        !          1436: 
        !          1437:                                srv->sockets_disabled = 1;
        !          1438:                        }
        !          1439:                }
        !          1440: 
        !          1441:                if (graceful_shutdown && srv->conns->used == 0) {
        !          1442:                        /* we are in graceful shutdown phase and all connections are closed
        !          1443:                         * we are ready to terminate without harming anyone */
        !          1444:                        srv_shutdown = 1;
        !          1445:                }
        !          1446: 
        !          1447:                /* we still have some fds to share */
        !          1448:                if (srv->want_fds) {
        !          1449:                        /* check the fdwaitqueue for waiting fds */
        !          1450:                        int free_fds = srv->max_fds - srv->cur_fds - 16;
        !          1451:                        connection *con;
        !          1452: 
        !          1453:                        for (; free_fds > 0 && NULL != (con = fdwaitqueue_unshift(srv, srv->fdwaitqueue)); free_fds--) {
        !          1454:                                connection_state_machine(srv, con);
        !          1455: 
        !          1456:                                srv->want_fds--;
        !          1457:                        }
        !          1458:                }
        !          1459: 
        !          1460:                if ((n = fdevent_poll(srv->ev, 1000)) > 0) {
        !          1461:                        /* n is the number of events */
        !          1462:                        int revents;
        !          1463:                        int fd_ndx;
        !          1464: #if 0
        !          1465:                        if (n > 0) {
        !          1466:                                log_error_write(srv, __FILE__, __LINE__, "sd",
        !          1467:                                                "polls:", n);
        !          1468:                        }
        !          1469: #endif
        !          1470:                        fd_ndx = -1;
        !          1471:                        do {
        !          1472:                                fdevent_handler handler;
        !          1473:                                void *context;
        !          1474:                                handler_t r;
        !          1475: 
        !          1476:                                fd_ndx  = fdevent_event_next_fdndx (srv->ev, fd_ndx);
        !          1477:                                if (-1 == fd_ndx) break; /* not all fdevent handlers know how many fds got an event */
        !          1478: 
        !          1479:                                revents = fdevent_event_get_revent (srv->ev, fd_ndx);
        !          1480:                                fd      = fdevent_event_get_fd     (srv->ev, fd_ndx);
        !          1481:                                handler = fdevent_get_handler(srv->ev, fd);
        !          1482:                                context = fdevent_get_context(srv->ev, fd);
        !          1483: 
        !          1484:                                /* connection_handle_fdevent needs a joblist_append */
        !          1485: #if 0
        !          1486:                                log_error_write(srv, __FILE__, __LINE__, "sdd",
        !          1487:                                                "event for", fd, revents);
        !          1488: #endif
        !          1489:                                switch (r = (*handler)(srv, context, revents)) {
        !          1490:                                case HANDLER_FINISHED:
        !          1491:                                case HANDLER_GO_ON:
        !          1492:                                case HANDLER_WAIT_FOR_EVENT:
        !          1493:                                case HANDLER_WAIT_FOR_FD:
        !          1494:                                        break;
        !          1495:                                case HANDLER_ERROR:
        !          1496:                                        /* should never happen */
        !          1497:                                        SEGFAULT();
        !          1498:                                        break;
        !          1499:                                default:
        !          1500:                                        log_error_write(srv, __FILE__, __LINE__, "d", r);
        !          1501:                                        break;
        !          1502:                                }
        !          1503:                        } while (--n > 0);
        !          1504:                } else if (n < 0 && errno != EINTR) {
        !          1505:                        log_error_write(srv, __FILE__, __LINE__, "ss",
        !          1506:                                        "fdevent_poll failed:",
        !          1507:                                        strerror(errno));
        !          1508:                }
        !          1509: 
        !          1510:                for (ndx = 0; ndx < srv->joblist->used; ndx++) {
        !          1511:                        connection *con = srv->joblist->ptr[ndx];
        !          1512:                        handler_t r;
        !          1513: 
        !          1514:                        connection_state_machine(srv, con);
        !          1515: 
        !          1516:                        switch(r = plugins_call_handle_joblist(srv, con)) {
        !          1517:                        case HANDLER_FINISHED:
        !          1518:                        case HANDLER_GO_ON:
        !          1519:                                break;
        !          1520:                        default:
        !          1521:                                log_error_write(srv, __FILE__, __LINE__, "d", r);
        !          1522:                                break;
        !          1523:                        }
        !          1524: 
        !          1525:                        con->in_joblist = 0;
        !          1526:                }
        !          1527: 
        !          1528:                srv->joblist->used = 0;
        !          1529:        }
        !          1530: 
        !          1531:        if (srv->srvconf.pid_file->used &&
        !          1532:            srv->srvconf.changeroot->used == 0 &&
        !          1533:            0 == graceful_shutdown) {
        !          1534:                if (0 != unlink(srv->srvconf.pid_file->ptr)) {
        !          1535:                        if (errno != EACCES && errno != EPERM) {
        !          1536:                                log_error_write(srv, __FILE__, __LINE__, "sbds",
        !          1537:                                                "unlink failed for:",
        !          1538:                                                srv->srvconf.pid_file,
        !          1539:                                                errno,
        !          1540:                                                strerror(errno));
        !          1541:                        }
        !          1542:                }
        !          1543:        }
        !          1544: 
        !          1545: #ifdef HAVE_SIGACTION
        !          1546:        log_error_write(srv, __FILE__, __LINE__, "sdsd", 
        !          1547:                        "server stopped by UID =",
        !          1548:                        last_sigterm_info.si_uid,
        !          1549:                        "PID =",
        !          1550:                        last_sigterm_info.si_pid);
        !          1551: #else
        !          1552:        log_error_write(srv, __FILE__, __LINE__, "s", 
        !          1553:                        "server stopped");
        !          1554: #endif
        !          1555: 
        !          1556:        /* clean-up */
        !          1557:        log_error_close(srv);
        !          1558:        network_close(srv);
        !          1559:        connections_free(srv);
        !          1560:        plugins_free(srv);
        !          1561:        server_free(srv);
        !          1562: 
        !          1563:        return 0;
        !          1564: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>