version 0.1.6
[fms.git] / libs / shttpd / standalone.c
diff --git a/libs/shttpd/standalone.c b/libs/shttpd/standalone.c
new file mode 100644 (file)
index 0000000..41b361e
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
+ * All rights reserved
+ *
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * Sergey Lyubka wrote this file.  As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return.
+ */
+
+#include "defs.h"
+
+static const char      *config_file = CONFIG;
+static int             exit_flag;
+
+static void
+signal_handler(int sig_num)
+{
+       switch (sig_num) {
+#ifndef _WIN32
+       case SIGCHLD:
+               while (waitpid(-1, &sig_num, WNOHANG) > 0) ;
+               break;
+#endif /* !_WIN32 */
+       default:
+               exit_flag = sig_num;
+               break;
+       }
+}
+
+int
+main(int argc, char *argv[])
+{
+       struct shttpd_ctx       *ctx;
+
+       current_time = time(NULL);
+       if (argc > 1 && argv[argc - 2][0] != '-' && argv[argc - 1][0] != '-')
+               config_file = argv[argc - 1];
+
+#if !defined(NO_AUTH)
+       if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'A') {
+               if (argc != 6)
+                       usage(argv[0]);
+               exit(edit_passwords(argv[2],argv[3],argv[4],argv[5]));
+       }
+#endif /* NO_AUTH */
+
+       ctx = init_from_argc_argv(config_file, argc, argv);
+
+#ifndef _WIN32
+       /* Switch to alternate UID, it is safe now, after shttpd_listen() */
+       if (ctx->uid != NULL) {
+               struct passwd   *pw;
+
+               if ((pw = getpwnam(ctx->uid)) == NULL)
+                       elog(E_FATAL, 0, "main: unknown user [%s]", ctx->uid);
+               else if (setgid(pw->pw_gid) == -1)
+                       elog(E_FATAL, NULL, "main: setgid(%s): %s",
+                           ctx->uid, strerror(errno));
+               else if (setuid(pw->pw_uid) == -1)
+                       elog(E_FATAL, NULL, "main: setuid(%s): %s",
+                           ctx->uid, strerror(errno));
+       }
+       (void) signal(SIGCHLD, signal_handler);
+       (void) signal(SIGPIPE, SIG_IGN);
+#endif /* _WIN32 */
+
+       (void) signal(SIGTERM, signal_handler);
+       (void) signal(SIGINT, signal_handler);
+
+       if (ctx->inetd_mode) {
+               (void) freopen("/dev/null", "a", stderr);
+               shttpd_add_socket(ctx, fileno(stdin));
+       } else {
+               open_listening_ports(ctx);
+       }
+
+       elog(E_LOG, NULL, "shttpd %s started on port(s) %s, serving %s",
+           VERSION, ctx->ports, ctx->document_root);
+
+       while (exit_flag == 0)
+               shttpd_poll(ctx, 5000);
+
+       elog(E_LOG, NULL, "%d requests %.2lf Mb in %.2lf Mb out. "
+           "Exit on signal %d", ctx->nrequests, (double) (ctx->in / 1048576),
+           (double) ctx->out / 1048576, exit_flag);
+
+       shttpd_fini(ctx);
+
+       return (EXIT_SUCCESS);
+}