1 | /* |
---|
2 | * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com> |
---|
3 | * All rights reserved |
---|
4 | * |
---|
5 | * "THE BEER-WARE LICENSE" (Revision 42): |
---|
6 | * Sergey Lyubka wrote this file. As long as you retain this notice you |
---|
7 | * can do whatever you want with this stuff. If we meet some day, and you think |
---|
8 | * this stuff is worth it, you can buy me a beer in return. |
---|
9 | */ |
---|
10 | |
---|
11 | #include "defs.h" |
---|
12 | |
---|
13 | static const char *config_file = CONFIG; |
---|
14 | static int exit_flag; |
---|
15 | |
---|
16 | static void |
---|
17 | signal_handler(int sig_num) |
---|
18 | { |
---|
19 | switch (sig_num) { |
---|
20 | #ifndef _WIN32 |
---|
21 | case SIGCHLD: |
---|
22 | while (waitpid(-1, &sig_num, WNOHANG) > 0) ; |
---|
23 | break; |
---|
24 | #endif /* !_WIN32 */ |
---|
25 | default: |
---|
26 | exit_flag = sig_num; |
---|
27 | break; |
---|
28 | } |
---|
29 | } |
---|
30 | |
---|
31 | int |
---|
32 | main(int argc, char *argv[]) |
---|
33 | { |
---|
34 | struct shttpd_ctx *ctx; |
---|
35 | |
---|
36 | current_time = time(NULL); |
---|
37 | if (argc > 1 && argv[argc - 2][0] != '-' && argv[argc - 1][0] != '-') |
---|
38 | config_file = argv[argc - 1]; |
---|
39 | |
---|
40 | #if !defined(NO_AUTH) |
---|
41 | if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'A') { |
---|
42 | if (argc != 6) |
---|
43 | usage(argv[0]); |
---|
44 | exit(edit_passwords(argv[2],argv[3],argv[4],argv[5])); |
---|
45 | } |
---|
46 | #endif /* NO_AUTH */ |
---|
47 | |
---|
48 | ctx = init_from_argc_argv(config_file, argc, argv); |
---|
49 | |
---|
50 | if (ctx->inetd_mode) |
---|
51 | (void) freopen("/dev/null", "a", stderr); |
---|
52 | |
---|
53 | if (ctx->inetd_mode) |
---|
54 | shttpd_add_socket(ctx, fileno(stdin)); |
---|
55 | else if (shttpd_listen(ctx, ctx->port) == -1) |
---|
56 | elog(E_FATAL, NULL, "Cannot open socket on port %d", ctx->port); |
---|
57 | |
---|
58 | #ifndef _WIN32 |
---|
59 | /* Switch to alternate UID, it is safe now, after shttpd_listen() */ |
---|
60 | if (ctx->uid != NULL) { |
---|
61 | struct passwd *pw; |
---|
62 | |
---|
63 | if ((pw = getpwnam(ctx->uid)) == NULL) |
---|
64 | elog(E_FATAL, 0, "main: unknown user [%s]", ctx->uid); |
---|
65 | else if (setgid(pw->pw_gid) == -1) |
---|
66 | elog(E_FATAL, NULL, "main: setgid(%s): %s", |
---|
67 | ctx->uid, strerror(errno)); |
---|
68 | else if (setuid(pw->pw_uid) == -1) |
---|
69 | elog(E_FATAL, NULL, "main: setuid(%s): %s", |
---|
70 | ctx->uid, strerror(errno)); |
---|
71 | } |
---|
72 | (void) signal(SIGCHLD, signal_handler); |
---|
73 | (void) signal(SIGPIPE, SIG_IGN); |
---|
74 | #endif /* _WIN32 */ |
---|
75 | |
---|
76 | (void) signal(SIGTERM, signal_handler); |
---|
77 | (void) signal(SIGINT, signal_handler); |
---|
78 | |
---|
79 | elog(E_LOG, NULL, "shttpd %s started on port %d, serving %s", |
---|
80 | VERSION, ctx->port, ctx->document_root); |
---|
81 | |
---|
82 | while (exit_flag == 0) |
---|
83 | shttpd_poll(ctx, 5000); |
---|
84 | |
---|
85 | elog(E_LOG, NULL, "%d requests %.2lf Mb in %.2lf Mb out. " |
---|
86 | "Exit on signal %d", ctx->nrequests, (double) (ctx->in / 1048576), |
---|
87 | (double) ctx->out / 1048576, exit_flag); |
---|
88 | |
---|
89 | shttpd_fini(ctx); |
---|
90 | |
---|
91 | return (EXIT_SUCCESS); |
---|
92 | } |
---|