/* * @(#)CDWserver.cpp * * This file is part of webCDwriter - Network CD/DVD Writing. * * Copyright (C) 1999-2005 Jörg P. M. Haeger * * webCDwriter 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. * * webCDwriter 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 webCDwriter; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Jörg Haeger, 17.03.1999 * eMail: mail@JoergHaeger.de * http://JoergHaeger.de */ #include #include #include #include #include #include #include "BufferedReader.h" #include "Config.h" #include "HTTPServer.h" #include "Log.h" #include "ServerPro.h" #include "ServerSocket.h" #include "Socket.h" #include "Thread.h" #include "Version.h" Config config; Log log; class CDWserver: public Thread { Socket *clientSocket; public: CDWserver(Socket *clientSocket) { this->clientSocket = clientSocket; } ~CDWserver() { delete clientSocket; } void run() { try { BufferedReader &reader = clientSocket->getInputStream(); if (true || reader.ready(10000)) { HTTPServer server(*clientSocket); server.run(); } else { ServerPro server(*clientSocket); server.run(); } } catch (Exception *e) { log.put(1, S.e + "Exception: " + e->getMessage()); delete e; } catch (const char *str) { log.put(1, S.e + "Catched: " + str); } log.debug("threads", "terminated"); } }; void sigAbrtHandler(int n) { log.put(1, "sigAbrtHandler: preparing for termination"); _exit(0); } void sigBusHandler(int n) { log.put(1, "sigBusHandler: preparing for termination"); _exit(0); } void sigHupHandler(int n) { log.put(1, "sigHupHandler: reopening the log file"); log.restart(); } void sigPipeHandler(int n) { log.put(5, "sigPipeHandler: broken pipe"); } void sigSegvHandler(int n) { log.put(1, "sigSegvHandler: preparing for termination"); _exit(0); } const Thread *mainThread = NULL; void sigTermHandler(int sig) { if (Thread::currentThread() == mainThread) { log.put(1, "sigTermHandler: preparing for termination"); Server::terminate(); // signal(sig, SIG_DFL); // raise(sig); exit(0); } else { log.put(1, "sigTermHandler: not main thread"); _exit(0); } } int main(int argc, char **args) { try { String appName = args[0]; if (appName.endsWith("CDWpasswd")) { if (argc < 2) { printf("Usage: %s \n", args[0]); return 1; } String id = args[1]; return ServerPro::passwd(id); } else if (appName.endsWith("CDWuseradd")) { if (argc < 2) { printf("Usage: %s \n", args[0]); return 1; } String id = args[1]; return ServerPro::useradd(id); } } catch (Exception *e) { printf("%s\n", e->toString().getBytes()); return 1; } String configFile = ""; int logToStdOut = 0, foreground = 0; for (int i = 1; i < argc; i++) { String arg = args[i]; if (arg.startsWith("--config=")) configFile = arg.substring(9); else if (arg.equals("--fg")) foreground = 1; else if (arg.equals("--stdout")) logToStdOut = 1; else { printf("%s%s %s\n", Version.product, Version.productPro, Version.version); printf("%s %s\n", Version.copyright, Version.author); printf("Usage: %s [options]\n", args[0]); printf("\t--config=FILE\tthe configuration file to use\n"); printf("\t--fg\t\tdo not go to the background\n"); printf("\t--stdout\twrite the log to stdout\n"); printf("\n"); return 0; } } config.load(configFile); StringBuffer::setLog(&log); if (!foreground) { // go to the background if (fork() > 0) exit(0); Thread::updateFirstThread(getpid()); } // try to create a pid file const char *pidFileName = getenv("pidFile"); if (pidFileName == NULL) pidFileName = "/var/run/CDWserver.pid"; FILE *pidFile = fopen(pidFileName, "w"); if (pidFile != NULL) { int pid = getpid(); fprintf(pidFile, "%d\n", pid); fclose(pidFile); } config.setPermissions(); ServerSocket serverSocket(config.getPortNo()); // try to change the group of this process setgid(config.getGid()); // try to change the user of this process setuid(config.getUid()); // the files created by CDWserver should be unreadable // to normal users umask(S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH); // fix problem with mkisofs unsetenv("HOME"); // fix problem with the dvd+rw-tools unsetenv("SUDO_COMMAND"); // start logging log.start(logToStdOut); log.put(1, S.e + "*** " + Version.product + Version.productPro + " " + Version.version + ", " + Server::timeToShortString()); log.put(1, S.e + "uid = " + (int)getuid() + ", euid = " + (int)geteuid() + ", gid = " + (int)getgid() + ", egid = " + (int)getegid()); Server::initStatic(); mainThread = Thread::currentThread(); signal(SIGABRT, sigAbrtHandler); signal(SIGBUS, sigBusHandler); signal(SIGHUP, sigHupHandler); signal(SIGPIPE, sigPipeHandler); signal(SIGSEGV, sigSegvHandler); signal(SIGTERM, sigTermHandler); for (int i = 1; ; i++) { log.put(5, "waiting for request..."); Socket *clientSocket = serverSocket.accept(); log.put(4, S.e + "Connection " + i + " accepted"); (new CDWserver(clientSocket))->start(); } return 0; }