/* -*- 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 // For setuid and setgid #include #include // For signal #include // For errno and strerror #include #include #include #include // For getpwent and getgrent #include #include #include // For getopt_long and friends #include #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 .\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 = config()->lookup("port"); config()->reload(); { // Force wake the server process for reinitialization. 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; } } //std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char, _Traits = std::char_traits, _Alloc = std::allocator] //std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char, _Traits = std::char_traits, _Alloc = std::allocator] char *cfname = NULL; if(!configfile) cfname = ETC"/pracrod.conf"; else cfname = configfile; Configuration conf(cfname); initConfig(&conf); if(!user) { std::string userstr; try { user = (char*)(const char*)config()->lookup("user"); } 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 { group = (char*)(const char*)config()->lookup("group"); } 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; }