summaryrefslogtreecommitdiff
path: root/server/src/pracrod.cc
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/pracrod.cc')
-rw-r--r--server/src/pracrod.cc243
1 files changed, 243 insertions, 0 deletions
diff --git a/server/src/pracrod.cc b/server/src/pracrod.cc
new file mode 100644
index 0000000..c9fa58b
--- /dev/null
+++ b/server/src/pracrod.cc
@@ -0,0 +1,243 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * pracrod.cc
+ *
+ * Wed Aug 22 12:15:59 CEST 2007
+ * Copyright 2007 Bent Bisballe Nyeng, Lars Bisballe Jensen and Peter Skaarup
+ * deva@aasimon.org, elsenator@gmail.com and piparum@piparum.dk
+ ****************************************************************************/
+
+/*
+ * This file is part of Pracro.
+ *
+ * Pracro is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Pracro is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Pracro; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+// For ETC
+#include <config.h>
+
+// For setuid and setgid
+#include <sys/types.h>
+#include <unistd.h>
+
+// For signal
+#include <signal.h>
+
+// For errno and strerror
+#include <errno.h>
+
+#include <stdio.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+// For getpwent and getgrent
+#include <sys/types.h>
+#include <grp.h>
+#include <pwd.h>
+
+// For getopt_long and friends
+#include <getopt.h>
+
+#include "configuration.h"
+
+#include "server.h"
+
+#include "tcpsocket.h"
+
+static const char version_str[] =
+"Pracro server v" VERSION "\n"
+;
+
+static const char copyright_str[] =
+"Copyright (C) 2006-2007 Bent Bisballe Nyeng - Aasimon.org.\n"
+"This is free software. You may redistribute copies of it under the terms of\n"
+"the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.\n"
+"There is NO WARRANTY, to the extent permitted by law.\n"
+"\n"
+"Written by Bent Bisballe Nyeng (deva@aasimon.org)\n"
+;
+
+static const char usage_str[] =
+"Usage: %s [options]\n"
+"Options:\n"
+" -c, --config file Read configfile from 'file'\n"
+" -f, --foreground Run in foreground mode (non-background mode)\n"
+" -u, --user user Run as 'user' (overrides the configfile)\n"
+" -g, --group group Run as 'group' (overrides the configfile)\n"
+" -v, --version Print version information and exit.\n"
+" -h, --help Print this message and exit.\n"
+;
+
+void reload(int fisk)
+{
+ int port;
+ printf("Reload!\n");
+ port = Pentominos::config()->lookup("port");
+ Pentominos::config()->reload();
+
+ { // Force wake the server process for reinitialization.
+ Pentominos::TCPSocket socket;
+ socket.connect("localhost", port);
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ int c;
+ char *configfile = NULL;
+ char *user = NULL;
+ char *group = NULL;
+ bool foreground = false;
+
+ int option_index = 0;
+ while(1) {
+ int this_option_optind = optind ? optind : 1;
+ static struct option long_options[] = {
+ {"foreground", no_argument, 0, 'f'},
+ {"config", required_argument, 0, 'c'},
+ {"user", required_argument, 0, 'u'},
+ {"group", required_argument, 0, 'g'},
+ {"help", no_argument, 0, 'h'},
+ {"version", no_argument, 0, 'v'},
+ {0, 0, 0, 0}
+ };
+
+ c = getopt_long (argc, argv, "hvfc:u:g:", long_options, &option_index);
+
+ if (c == -1)
+ break;
+
+ switch(c) {
+ case 'c':
+ configfile = strdup(optarg);
+ break;
+
+ case 'f':
+ foreground = true;
+ break;
+
+ case 'u':
+ user = strdup(optarg);
+ break;
+
+ case 'g':
+ group = strdup(optarg);
+ break;
+
+ case '?':
+ case 'h':
+ printf(version_str);
+ printf(usage_str, argv[0]);
+ return 0;
+
+ case 'v':
+ printf(version_str);
+ printf(copyright_str);
+ return 0;
+
+ default:
+ break;
+ }
+ }
+
+ char *cfname = NULL;
+ if(!configfile) cfname = ETC"/pracrod.conf";
+ else cfname = configfile;
+ Pentominos::Configuration conf(cfname);
+ Pentominos::initConfig(&conf);
+
+ if(!user) {
+ std::string userstr;
+ try {
+ userstr = (std::string)Pentominos::config()->lookup("user");
+ user = strdup(userstr.c_str());
+ } catch( ... ) {
+ printf("User not found in config.\n");
+ }
+ }
+
+ if(user) {
+ // Fetch user id
+ int uid = -1;
+ struct passwd *p = getpwent();
+ while(p) {
+ if(strcmp(p->pw_name, user) == 0) uid = p->pw_uid;
+ p = getpwent();
+ }
+ if(uid == -1) {
+ fprintf(stderr, "Could not find user \"%s\" in /etc/passwd file.\n", user);
+ return 1;
+ }
+
+ if(setuid(uid) == -1) {
+ fprintf(stderr, "Could not switch to user %s: %s\n", user, strerror(errno));
+ return 1;
+ }
+ }
+
+ if(!group) {
+ std::string groupstr;
+ try {
+ groupstr = (std::string)Pentominos::config()->lookup("group");
+ group = strdup(groupstr.c_str());
+ } catch( ... ) {
+ printf("Group not found in config.\n");
+ }
+
+ }
+
+ if(group) {
+ // Fetch group id
+ int gid = -1;
+ struct group *g = getgrent();
+ while(g) {
+ if(strcmp(g->gr_name, group) == 0) gid = g->gr_gid;
+ g = getgrent();
+ }
+ if(gid == -1) {
+ fprintf(stderr, "Could not find group \"%s\" in /etc/group file.\n", group);
+ return 1;
+ }
+
+ if(setgid(gid) == -1) {
+ fprintf(stderr, "Could not switch to group %s: %s\n", group, strerror(errno));
+ return 1;
+ }
+ }
+
+ if(!foreground) {
+ daemon(0,0);
+ signal (SIGTERM, SIG_IGN);
+ signal (SIGINT, SIG_IGN);
+ } else {
+ printf("Running in foreground mode.\n");
+ }
+
+ // Create callback to reload conf files.
+ signal (SIGHUP, reload);
+
+ signal(SIGCLD, SIG_IGN); // Ved SIGCHILD til IGNORE maa wait/waitpid ikke kaldes
+ // (ellers kommer der kernel-brok)
+
+ // Activate the server main loop.
+ server();
+
+ // Clean up
+ if(configfile) free(configfile);
+ if(user) free(user);
+ if(group) free(group);
+
+ return 0;
+}