Emacs/cc-ide: More robust function movement
[mediaserv.git] / main.cc
diff --git a/main.cc b/main.cc
index 9922bce..b5f01c6 100644 (file)
--- a/main.cc
+++ b/main.cc
@@ -2,19 +2,71 @@
 //
 // Copyright (C) 2006 
 
+// TODO: open log-file as non-root
+// TODO: open socket as root ?
+// TODO: so best should be: start mediaserv as root and then drop privileges
+// TODO: mime-db
+
 // Definition of non-inline non-template functions
 
 //#include "main.hh"
 //#include "main.ih"
 
 // Custom includes
+#include <unistd.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include <iostream>
+
+#include "Utils/Exception.hh"
+#include "Utils/DaemonTools.hh"
+#include "Server/HTTPLogger.hh"
+#include "Server/SimpleHTTPServer.hh"
+#include "Socket/Protocols/INet/TCPSocketHandle.hh"
 
 //#include "main.mpp"
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
+#define THROW_SYSERR(cmd,e) if (e) throw senf::SystemException(#cmd,errno)
+
 int main(int argc, char** argv)
 {
+    try {
+       struct ::passwd * pw = getpwnam("media"); THROW_SYSERR( getpwnam, !pw );
+       struct ::group * gr = getgrnam("media"); THROW_SYSERR( getgrnam, !gr );
+       THROW_SYSERR( setegid,::setegid(gr->gr_gid) < 0 );
+       THROW_SYSERR( seteuid, ::seteuid(pw->pw_uid) < 0 );
+       g0dil::mediaserv::HTTPLogger logger ("log/access.log");
+       THROW_SYSERR( seteuid, ::seteuid(0) < 0 );
+       THROW_SYSERR( setegid, ::setegid(0) );
+       try {
+           // We have to make sure not to access any sytem files after the chroot
+           // (initgroups accesses /etc/group, redirect_stdio accesses /dev/null)
+           senf::redirect_stdio();
+           THROW_SYSERR( initgroups, ::initgroups("media",gr->gr_gid) < 0 );
+           THROW_SYSERR( chdir, chdir("wwwroot") < 0 );
+           THROW_SYSERR( chroot, chroot(".") < 0 );
+           senf::TCPv4ServerSocketHandle socket (argv[1]);
+           THROW_SYSERR( setregid, ::setregid(gr->gr_gid,gr->gr_gid) < 0 );
+           THROW_SYSERR( setreuid, ::setreuid(pw->pw_uid,pw->pw_uid) < 0 );
+           senf::daemonize();
+           socket.blocking(false);
+           socket.protocol().reuseaddr(true);
+           g0dil::mediaserv::SimpleHTTPServer server (socket,logger);
+           
+           senf::Scheduler::instance().process();
+       }
+       catch (std::exception const & ex) {
+           logger.failedRequest(ex.what());
+       }
+    }
+    catch (std::exception const & ex) {
+       std::cerr << ex.what() << "\n";
+       exit(1);
+    }
     return 0;
 }