diff options
Diffstat (limited to 'server/src/pracrod.cc')
-rw-r--r-- | server/src/pracrod.cc | 243 |
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; +} |