summaryrefslogtreecommitdiff
path: root/server/miav_server.cc
diff options
context:
space:
mode:
Diffstat (limited to 'server/miav_server.cc')
-rw-r--r--server/miav_server.cc159
1 files changed, 155 insertions, 4 deletions
diff --git a/server/miav_server.cc b/server/miav_server.cc
index 2005afd..b1dfcac 100644
--- a/server/miav_server.cc
+++ b/server/miav_server.cc
@@ -27,24 +27,175 @@
#include <config.h>
#include "miav_server.h"
-#include "miav_daemon.h"
#include "miav_config.h"
#include "info_console.h"
#include <stdio.h>
+#include <string.h>
+
+#include "server.h"
+#include "socket.h"
+
+#include <signal.h>
+#include <errno.h>
+
+// For getpwent and getgrent
+#include <sys/types.h>
+#include <grp.h>
+#include <pwd.h>
+
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#elif defined(HAVE_STDLIB_H) // Solaris has getopt() here
+#include <stdlib.h>
+#else
+#error "Don't know where getopt() is prototyped"
+#endif
+
+static const char usage_str[] =
+"Usage: %s [options]\n"
+"Options:\n"
+" -c file Read configfile from 'file'\n"
+" -i Run in interactive mode (non-background mode)\n"
+" -h This message\n"
+;
+
+static char *config_file = ETC"/miav.conf";
/**
* This function starts the MIaV server.
*/
int main(int argc, char *argv[])
{
- MiavDaemon daemon;
+ int optc;
+ int lose = 0;
+ bool interactive = false;
+
+ // Parse the commandline
+ while((optc = getopt(argc, argv, "c:ih")) != EOF) {
+ switch(optc) {
+ case 'c':
+ config_file = strdup(optarg);
+ if(!config_file) {
+ fprintf(stderr, "Fatal: out of memory\n");
+ return 1;
+ }
+ break;
+ case 'i':
+ interactive = true;
+ break;
+ case 'h':
+ fprintf(stdout, usage_str, argv[0]);
+ return 0;
+ default:
+ lose++;
+ break;
+ }
+ }
+
+ if(lose) {
+ // Error message was printed by getopt
+ return 1;
+ }
+
+ fprintf(stderr, "Using config file [%s]\n", config_file);
+
+ MiavConfig cfg(config_file);
+ MIaV::initConfig(&cfg);
- MiavConfig cfg(ETC"/miav.conf");
+ InfoConsole info;
+ MIaV::initInfo(&info);
string *user = cfg.readString("server_user");
string *group = cfg.readString("server_group");
+
+ // Fetch user id
+ int uid = -1;
+ struct passwd *p = getpwent();
+ while(p) {
+ if(strcmp(p->pw_name, user->c_str()) == 0) uid = p->pw_uid;
+ p = getpwent();
+ }
+ if(uid == -1) {
+ fprintf(stderr, "Could not find user \"%s\" in /etc/passwd file.\n", user->c_str());
+ }
+
+ // Fetch group id
+ int gid = -1;
+ struct group *g = getgrent();
+ while(g) {
+ if(strcmp(g->gr_name, group->c_str()) == 0) gid = g->gr_gid;
+ g = getgrent();
+ }
+ if(gid == -1) {
+ fprintf(stderr, "Could not find group \"%s\" in /etc/group file.\n", group->c_str());
+ }
+
+ if(!interactive) {
+ fprintf(stderr, "Entering daemon mode\n");
+ daemon(0,0);
+ signal (SIGTERM, SIG_IGN);
+ signal (SIGINT, SIG_IGN);
+ signal (SIGHUP, SIG_IGN);
+ } else {
+ fprintf(stderr, "Running interactive\n");
+ }
+
+ int port = MIaV::config->readInt("server_port");
+ pid_t childpid; // variable to store the child's pid
+
+ signal(SIGCLD, SIG_IGN); // Ved SIGCHILD til IGNORE maa wait/waitpid ikke kaldes
+ // (ellers kommer der kernel-brok)
+
+ MIaV::info->info("Starting MIaV server v. %s", VERSION);
+ MIaV::info->info("Listening on port %d", port);
+ Socket *socket = new Socket(port);
+
+ if(socket->hasError()) {
+ MIaV::info->error("Listening socket has errors, quitting.");
+ delete socket;
+ return 1;
+ }
+
+ while(1) {
+ Socket *csocket = new Socket(socket->slisten());
+
+ if(socket->hasError()) {
+ MIaV::info->error("Server socket has errors, quitting.");
+ delete csocket;
+ break;
+ }
+
+ if(csocket->hasError()) {
+ MIaV::info->error("Child socket has errors, quitting.");
+ delete csocket;
+ break;
+ }
+
+ if(!csocket->isConnected()) {
+ MIaV::info->error("Child socket is not connected, quitting.");
+ delete csocket;
+ break;
+ }
+
+ childpid = fork();
+
+ switch(childpid) {
+ case -1: // fork() returns -1 on failure
+ MIaV::info->log("Fork error: %s", strerror(errno));
+ exit(1);
+ case 0: // fork() returns 0 to the child process
+ delete socket; // Close listen socket.
+ newConnection(csocket);
+ delete csocket; // Close communication socket.
+ exit(0);
+
+ default: // fork() returns new pid to the parent process
+ break;
+ }
+ }
- return daemon.run(user->c_str(), group->c_str());
+ delete socket;
+ return 0;
}