diff --git a/src/Makefile.am b/src/Makefile.am index 7b0a385e..5b3d22e7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,7 @@ bin_PROGRAMS=MistBuffer MistController MistConnRAW MistConnRTMP MistConnHTTP Mis MistBuffer_SOURCES=buffer.cpp buffer_user.h buffer_user.cpp buffer_stream.h buffer_stream.cpp tinythread.cpp tinythread.h ../VERSION MistController_SOURCES=controller.cpp ../VERSION MistConnRAW_SOURCES=conn_raw.cpp ../VERSION -MistConnRTMP_SOURCES=conn_rtmp.cpp server_setup.h ../VERSION -MistConnHTTP_SOURCES=conn_http.cpp server_setup.h ../VERSION -MistConnHTTPProgressive_SOURCES=conn_http_progressive.cpp server_setup_http.h ../VERSION -MistConnHTTPDynamic_SOURCES=conn_http_dynamic.cpp server_setup_http.h ../VERSION +MistConnRTMP_SOURCES=conn_rtmp.cpp ../VERSION +MistConnHTTP_SOURCES=conn_http.cpp ../VERSION +MistConnHTTPProgressive_SOURCES=conn_http_progressive.cpp ../VERSION +MistConnHTTPDynamic_SOURCES=conn_http_dynamic.cpp ../VERSION diff --git a/src/analysers/amf_analyser.cpp b/src/analysers/amf_analyser.cpp index 8e7075e7..e98ed595 100644 --- a/src/analysers/amf_analyser.cpp +++ b/src/analysers/amf_analyser.cpp @@ -7,10 +7,13 @@ #include #include #include +#include /// Debugging tool for AMF data. /// Expects AMF data through stdin, outputs human-readable information to stderr. -int main() { +int main(int argc, char ** argv) { + Util::Config conf = Util::Config(argv[0], PACKAGE_VERSION); + conf.parseArgs(argc, argv); std::string temp; while (std::cin.good()){temp += std::cin.get();}//read all of std::cin to temp temp.erase(temp.size()-1, 1);//strip the invalid last character diff --git a/src/analysers/dtsc_analyser.cpp b/src/analysers/dtsc_analyser.cpp index 5c8d911f..d2d94cda 100644 --- a/src/analysers/dtsc_analyser.cpp +++ b/src/analysers/dtsc_analyser.cpp @@ -11,9 +11,13 @@ #include #include #include //DTSC support +#include /// Reads DTSC from stdin and outputs human-readable information to stderr. -int main() { +int main(int argc, char ** argv) { + Util::Config conf = Util::Config(argv[0], PACKAGE_VERSION); + conf.parseArgs(argc, argv); + DTSC::Stream Strm; std::string inBuffer; diff --git a/src/analysers/flv_analyser.cpp b/src/analysers/flv_analyser.cpp index 9892349f..7ac56842 100644 --- a/src/analysers/flv_analyser.cpp +++ b/src/analysers/flv_analyser.cpp @@ -11,9 +11,12 @@ #include #include #include //FLV support +#include /// Reads FLV from stdin and outputs human-readable information to stderr. -int main() { +int main(int argc, char ** argv) { + Util::Config conf = Util::Config(argv[0], PACKAGE_VERSION); + conf.parseArgs(argc, argv); FLV::Tag FLV_in; // Temporary storage for incoming FLV data. while (!feof(stdin)){ if (FLV_in.FileLoader(stdin)){ diff --git a/src/analysers/rtmp_analyser.cpp b/src/analysers/rtmp_analyser.cpp index 81b8474d..6dd8364a 100644 --- a/src/analysers/rtmp_analyser.cpp +++ b/src/analysers/rtmp_analyser.cpp @@ -17,6 +17,7 @@ #include #include #include +#include int Detail = 0; #define DETAIL_RECONSTRUCT 1 @@ -28,9 +29,12 @@ int Detail = 0; /// Will output FLV file to stdout, if available /// Automatically skips 3073 bytes of handshake data. int main(int argc, char ** argv){ - - if (argc > 1){ - Detail = atoi(argv[1]); + Util::Config conf = Util::Config(argv[0], PACKAGE_VERSION); + conf.addOption("detail", JSON::fromString("{\"arg_num\":1, \"arg\":\"integer\", \"default\":0, \"help\":\"Bitmask, 1 = Reconstruct, 2 = Explicit media info, 4 = Verbose chunks\"}")); + conf.parseArgs(argc, argv); + + Detail = conf.getInteger("detail"); + if (Detail > 0){ fprintf(stderr, "Detail level set:\n"); if ((Detail & DETAIL_RECONSTRUCT) == DETAIL_RECONSTRUCT){ fprintf(stderr, " - Will reconstuct FLV file to stdout\n"); diff --git a/src/conn_http_dynamic.cpp b/src/conn_http_dynamic.cpp index 58aa8a19..b5ce016b 100644 --- a/src/conn_http_dynamic.cpp +++ b/src/conn_http_dynamic.cpp @@ -229,7 +229,27 @@ namespace Connector_HTTP_Dynamic{ };//Connector_HTTP_Dynamic namespace -// Load http setup file with the correct settings for this HTTP connector -#define MAINHANDLER Connector_HTTP_Dynamic::Connector_HTTP_Dynamic -#define CONNECTOR "dynamic" -#include "server_setup_http.h" +int main(int argc, char ** argv){ + Util::Config conf(argv[0], PACKAGE_VERSION); + conf.addConnectorOptions(1935); + conf.parseArgs(argc, argv); + Socket::Server server_socket = Socket::Server("/tmp/mist/http_dynamic"); + if (!server_socket.connected()){return 1;} + conf.activate(); + + while (server_socket.connected() && conf.is_active){ + Socket::Connection S = server_socket.accept(); + if (S.connected()){//check if the new connection is valid + pid_t myid = fork(); + if (myid == 0){//if new child, start MAINHANDLER + return Connector_RTMP::Connector_RTMP(S); + }else{//otherwise, do nothing or output debugging text + #if DEBUG >= 3 + fprintf(stderr, "Spawned new process %i for socket %i\n", (int)myid, S.getSocket()); + #endif + } + } + }//while connected + server_socket.close(); + return 0; +}//main diff --git a/src/conn_http_progressive.cpp b/src/conn_http_progressive.cpp index c335d54d..403e768f 100644 --- a/src/conn_http_progressive.cpp +++ b/src/conn_http_progressive.cpp @@ -139,7 +139,27 @@ namespace Connector_HTTP_Progressive{ };//Connector_HTTP namespace -// Load http setup file with the correct settings for this HTTP connector -#define MAINHANDLER Connector_HTTP_Progressive::Connector_HTTP_Progressive -#define CONNECTOR "progressive" -#include "server_setup_http.h" +int main(int argc, char ** argv){ + Util::Config conf(argv[0], PACKAGE_VERSION); + conf.addConnectorOptions(1935); + conf.parseArgs(argc, argv); + Socket::Server server_socket = Socket::Server("/tmp/mist/http_progressive"); + if (!server_socket.connected()){return 1;} + conf.activate(); + + while (server_socket.connected() && conf.is_active){ + Socket::Connection S = server_socket.accept(); + if (S.connected()){//check if the new connection is valid + pid_t myid = fork(); + if (myid == 0){//if new child, start MAINHANDLER + return Connector_RTMP::Connector_RTMP(S); + }else{//otherwise, do nothing or output debugging text + #if DEBUG >= 3 + fprintf(stderr, "Spawned new process %i for socket %i\n", (int)myid, S.getSocket()); + #endif + } + } + }//while connected + server_socket.close(); + return 0; +}//main diff --git a/src/conn_raw.cpp b/src/conn_raw.cpp index 0044606f..1eec8857 100644 --- a/src/conn_raw.cpp +++ b/src/conn_raw.cpp @@ -2,22 +2,22 @@ /// Contains the main code for the RAW connector. #include +#include #include /// Contains the main code for the RAW connector. /// Expects a single commandline argument telling it which stream to connect to, /// then outputs the raw stream to stdout. int main(int argc, char ** argv) { - if (argc < 2){ - std::cout << "Usage: " << argv[0] << " stream_name" << std::endl; - return 1; - } - std::string input = "/tmp/shared_socket_"; - input += argv[1]; + Util::Config conf(argv[0], PACKAGE_VERSION); + conf.addOption("stream_name", JSON::fromString("{\"arg_num\":1, \"help\":\"Name of the stream to write to stdout.\"}")); + conf.parseArgs(argc, argv); + + std::string input = "/tmp/shared_socket_" + conf.getString("stream_name"); //connect to the proper stream Socket::Connection S(input); if (!S.connected()){ - std::cout << "Could not open stream " << argv[1] << std::endl; + std::cout << "Could not open stream " << conf.getString("stream_name") << std::endl; return 1; } //transport ~50kb at a time diff --git a/src/conn_rtmp.cpp b/src/conn_rtmp.cpp index 5f574015..f03b69cb 100644 --- a/src/conn_rtmp.cpp +++ b/src/conn_rtmp.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -499,9 +500,27 @@ void Connector_RTMP::parseAMFCommand(AMF::Object & amfdata, int messagetype, int #endif }//parseAMFCommand - -// Load main server setup file, default port 1935, handler is Connector_RTMP::Connector_RTMP -#define DEFAULT_PORT 1935 -#define MAINHANDLER Connector_RTMP::Connector_RTMP -#define CONFIGSECT RTMP -#include "server_setup.h" +int main(int argc, char ** argv){ + Util::Config conf(argv[0], PACKAGE_VERSION); + conf.addConnectorOptions(1935); + conf.parseArgs(argc, argv); + Socket::Server server_socket = Socket::Server(conf.getInteger("listen_port"), conf.getString("listen_interface")); + if (!server_socket.connected()){return 1;} + conf.activate(); + + while (server_socket.connected() && conf.is_active){ + Socket::Connection S = server_socket.accept(); + if (S.connected()){//check if the new connection is valid + pid_t myid = fork(); + if (myid == 0){//if new child, start MAINHANDLER + return Connector_RTMP::Connector_RTMP(S); + }else{//otherwise, do nothing or output debugging text + #if DEBUG >= 3 + fprintf(stderr, "Spawned new process %i for socket %i\n", (int)myid, S.getSocket()); + #endif + } + } + }//while connected + server_socket.close(); + return 0; +}//main diff --git a/src/controller.cpp b/src/controller.cpp index 26e3b4b5..81651b23 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -25,14 +25,15 @@ #include #include #include +#include #include #include -#include #include -#include #include #define UPLINK_INTERVAL 30 +#define COMPILED_USERNAME "" +#define COMPILED_PASSWORD "" Socket::Server API_Socket; ///< Main connection socket. std::map lastBuffer; ///< Last moment of contact with all buffers. @@ -308,6 +309,24 @@ void CheckStreams(JSON::Value & in, JSON::Value & out){ } int main(int argc, char ** argv){ + Storage = JSON::fromFile("config.json"); + JSON::Value stored_port = JSON::fromString("{\"long\":\"port\", \"short\":\"p\", \"arg\":\"integer\", \"help\":\"TCP port to listen on.\"}"); + stored_port["default"] = Storage["config"]["controller"]["port"]; + if (!stored_port["default"]){stored_port["default"] = 4242;} + JSON::Value stored_interface = JSON::fromString("{\"long\":\"interface\", \"short\":\"i\", \"arg\":\"string\", \"help\":\"Interface address to listen on, or 0.0.0.0 for all available interfaces.\"}"); + stored_interface["default"] = Storage["config"]["controller"]["interface"]; + if (!stored_interface["default"]){stored_interface["default"] = "0.0.0.0";} + JSON::Value stored_user = JSON::fromString("{\"long\":\"username\", \"short\":\"u\", \"arg\":\"string\", \"help\":\"Username to drop privileges to, or root to not drop provileges.\"}"); + stored_user["default"] = Storage["config"]["controller"]["username"]; + if (!stored_user["default"]){stored_user["default"] = "root";} + Util::Config conf = Util::Config(argv[0], PACKAGE_VERSION); + conf.addOption("listen_port", stored_port); + conf.addOption("listen_interface", stored_interface); + conf.addOption("username", stored_user); + conf.addOption("daemonize", JSON::fromString("{\"long\":\"daemon\", \"short\":\"d\", \"default\":1, \"long_off\":\"nodaemon\", \"short_off\":\"n\", \"help\":\"Whether or not to daemonize the process after starting.\"}")); + conf.addOption("account", JSON::fromString("{\"long\":\"account\", \"short\":\"a\", \"default\":\"\", \"help\":\"A username:password string to create a new account with.\"}")); + conf.parseArgs(argc, argv); + //setup signal handler struct sigaction new_action; new_action.sa_handler = signal_handler; @@ -318,76 +337,22 @@ int main(int argc, char ** argv){ sigaction(SIGTERM, &new_action, NULL); sigaction(SIGPIPE, &new_action, NULL); - Storage = JSON::fromFile("config.json"); - Util::Config C; - C.listen_port = (long long int)Storage["config"]["controller"]["port"]; - if (C.listen_port < 1){C.listen_port = 4242;} - C.interface = (std::string)Storage["config"]["controller"]["interface"]; - if (C.interface == ""){C.interface = "0.0.0.0";} - C.username = (std::string)Storage["config"]["controller"]["username"]; - if (C.username == ""){C.username = "root";} - - - int opt = 0; - static const char *optString = "ndvp:i:u:a:h?"; - static const struct option longOpts[] = { - {"help",0,0,'h'}, - {"port",1,0,'p'}, - {"interface",1,0,'i'}, - {"account",1,0,'a'}, - {"username",1,0,'u'}, - {"nodaemon",0,0,'n'}, - {"daemon",0,0,'d'}, - {"version",0,0,'v'}, - 0 - }; - while ((opt = getopt_long(argc, argv, optString, longOpts, 0)) != -1){ - switch (opt){ - case 'p': C.listen_port = atoi(optarg); break; - case 'i': C.interface = optarg; break; - case 'n': C.daemon_mode = false; break; - case 'd': C.daemon_mode = true; break; - case 'u': C.username = optarg; break; - case 'a':{ - std::string account = optarg; - size_t colon = account.find(':'); - if (colon == std::string::npos || colon == 0 || colon == account.size()){ - opt = '?';//invalid name/pass - show help - }else{ - std::string uname = account.substr(0, colon); - std::string pword = account.substr(colon + 1, std::string::npos); - Log("CONF", "Created account "+uname+" through commandline option"); - Storage["account"][uname]["password"] = md5(pword); - } - break; - } - case 'v': - printf("%s\n", PACKAGE_VERSION); - exit(1); - break; - case 'h': - case '?': - std::string doingdaemon = "true"; - if (!C.daemon_mode){doingdaemon = "false";} - printf("Options: -h[elp], -?, -v[ersion], -n[odaemon], -d[aemon], -p[ort] VAL, -i[nterface] VAL, -u[sername] VAL, -a[ccount] USERNAME:PASSWORD\n"); - printf("Defaults:\n interface: %s\n port: %i\n daemon mode: %s\n username: %s\n", C.interface.c_str(), C.listen_port, doingdaemon.c_str(), C.username.c_str()); - printf("Username root means no change to UID, no matter what the UID is.\n"); - printf("The -a option will create a new account with the given username and (raw) password. To delete accounts, manually edit the config.json file.\n"); - printf("This is %s version %s\n", argv[0], PACKAGE_VERSION); - exit(1); - break; + std::string account = conf.getString("account"); + if (account.size() > 0){ + size_t colon = account.find(':'); + if (colon != std::string::npos && colon != 0 && colon != account.size()){ + std::string uname = account.substr(0, colon); + std::string pword = account.substr(colon + 1, std::string::npos); + Log("CONF", "Created account "+uname+" through commandline option"); + Storage["account"][uname]["password"] = md5(pword); } - }//commandline options parser - + } time_t lastuplink = 0; time_t processchecker = 0; - API_Socket = Socket::Server(C.listen_port, C.interface, true); + API_Socket = Socket::Server(conf.getInteger("listen_port"), conf.getString("listen_interface"), true); mkdir("/tmp/mist", S_IRWXU | S_IRWXG | S_IRWXO);//attempt to create /tmp/mist/ - ignore failures Socket::Server Stats_Socket = Socket::Server("/tmp/mist/statistics", true); - Util::setUser(C.username); - if (C.daemon_mode){ - Util::Daemonize(); - } + conf.activate(); Socket::Connection Incoming; std::vector< ConnectedUser > users; std::vector buffers; @@ -506,9 +471,9 @@ int main(int argc, char ** argv){ Response["streams"] = Storage["streams"]; Response["log"] = Storage["log"]; Response["statistics"] = Storage["statistics"]; - Response["authorize"]["username"] = TOSTRING(COMPILED_USERNAME); + Response["authorize"]["username"] = COMPILED_USERNAME; Log("UPLK", "Responding to login challenge: " + (std::string)Request["authorize"]["challenge"]); - Response["authorize"]["password"] = md5(TOSTRING(COMPILED_PASSWORD) + (std::string)Request["authorize"]["challenge"]); + Response["authorize"]["password"] = md5(COMPILED_PASSWORD + (std::string)Request["authorize"]["challenge"]); it->H.Clean(); it->H.SetBody("command="+HTTP::Parser::urlencode(Response.toString())); it->H.BuildRequest(); diff --git a/src/converters/dtsc2flv.cpp b/src/converters/dtsc2flv.cpp index b7cadd7a..636c2a56 100644 --- a/src/converters/dtsc2flv.cpp +++ b/src/converters/dtsc2flv.cpp @@ -13,10 +13,11 @@ #include //FLV support #include //DTSC support #include //AMF support +#include /// Holds all code that converts filetypes to/from DTSC. namespace Converters{ - + /// Reads DTSC from STDIN, outputs FLV to STDOUT. int DTSC2FLV() { FLV::Tag FLV_out; // Temporary storage for outgoing FLV data. @@ -60,6 +61,8 @@ namespace Converters{ };//Converter namespace /// Entry point for DTSC2FLV, simply calls Converters::DTSC2FLV(). -int main(){ +int main(int argc, char ** argv){ + Util::Config conf = Util::Config(argv[0], PACKAGE_VERSION); + conf.parseArgs(argc, argv); return Converters::DTSC2FLV(); }//main diff --git a/src/converters/flv2dtsc.cpp b/src/converters/flv2dtsc.cpp index 1045b320..b5fc1931 100644 --- a/src/converters/flv2dtsc.cpp +++ b/src/converters/flv2dtsc.cpp @@ -13,6 +13,7 @@ #include //FLV support #include //DTSC support #include //AMF support +#include /// Holds all code that converts filetypes to/from to DTSC. namespace Converters{ @@ -65,6 +66,8 @@ namespace Converters{ };//Buffer namespace /// Entry point for FLV2DTSC, simply calls Converters::FLV2DTSC(). -int main(){ +int main(int argc, char ** argv){ + Util::Config conf = Util::Config(argv[0], PACKAGE_VERSION); + conf.parseArgs(argc, argv); return Converters::FLV2DTSC(); }//main diff --git a/src/server_setup.h b/src/server_setup.h deleted file mode 100644 index 8eb16daa..00000000 --- a/src/server_setup.h +++ /dev/null @@ -1,115 +0,0 @@ -/// \file server_setup.h -/// Contains generic functions for setting up a Connector. - -#ifndef MAINHANDLER - /// Handler that is called for accepted incoming connections. - #define MAINHANDLER NoHandler - #error "No handler was set!" -#endif - - -#ifndef DEFAULT_PORT - /// Default port for this server. - #define DEFAULT_PORT 0 - #error "No default port was set!" -#endif - - -#include //Socket library -#include //utilities for config management -#include -#include -#include -#include -Socket::Server server_socket; ///< Placeholder for the server socket - -/// Basic signal handler. Disconnects the server_socket if it receives -/// a SIGINT, SIGHUP or SIGTERM signal, but does nothing for SIGPIPE. -/// Disconnecting the server_socket will terminate the main listening loop -/// and cleanly shut down the process. -void signal_handler (int signum){ - switch (signum){ - case SIGINT: - #if DEBUG >= 1 - fprintf(stderr, "Received SIGINT - closing server socket.\n"); - #endif - break; - case SIGHUP: - #if DEBUG >= 1 - fprintf(stderr, "Received SIGHUP - closing server socket.\n"); - #endif - break; - case SIGTERM: - #if DEBUG >= 1 - fprintf(stderr, "Received SIGTERM - closing server socket.\n"); - #endif - break; - case SIGCHLD: - wait(0); - return; - break; - default: return; break; - } - if (!server_socket.connected()) return; - server_socket.close(); -}//signal_handler - -/// Generic main entry point and loop for DDV Connectors. -/// This sets up the proper termination handler, checks commandline options, -/// parses config files and opens a listening socket on the requested port. -/// Any incoming connections will be accepted and start up the function #MAINHANDLER, -/// which should be defined before including server_setup.cpp. -/// The default port is set by define #DEFAULT_PORT. -int main(int argc, char ** argv){ - Socket::Connection S;//placeholder for incoming connections - - //setup signal handler - struct sigaction new_action; - new_action.sa_handler = signal_handler; - sigemptyset (&new_action.sa_mask); - new_action.sa_flags = 0; - sigaction(SIGINT, &new_action, NULL); - sigaction(SIGHUP, &new_action, NULL); - sigaction(SIGTERM, &new_action, NULL); - sigaction(SIGPIPE, &new_action, NULL); - sigaction(SIGCHLD, &new_action, NULL); - - //set and parse configuration - Util::Config C; - C.listen_port = DEFAULT_PORT; - C.parseArgs(argc, argv); - - //setup a new server socket, for the correct interface and port - server_socket = Socket::Server(C.listen_port, C.interface); - if (!server_socket.connected()){ - #if DEBUG >= 1 - fprintf(stderr, "Error: could not make listening socket\n"); - #endif - return 1; - }else{ - #if DEBUG >= 3 - fprintf(stderr, "Made a listening socket on %s:%i...\n", C.interface.c_str(), C.listen_port); - #endif - } - - Util::setUser(C.username); - if (C.daemon_mode){Util::Daemonize();} - - while (server_socket.connected()){ - S = server_socket.accept(); - if (S.connected()){//check if the new connection is valid - pid_t myid = fork(); - if (myid == 0){//if new child, start MAINHANDLER - return MAINHANDLER(S); - }else{//otherwise, do nothing or output debugging text - #if DEBUG >= 3 - fprintf(stderr, "Spawned new process %i for socket %i\n", (int)myid, S.getSocket()); - #endif - } - } - }//while connected - #if DEBUG >= 1 - fprintf(stderr, "Server socket closed, exiting.\n"); - #endif - return 0; -}//main diff --git a/src/server_setup_http.h b/src/server_setup_http.h deleted file mode 100644 index 6cc6590f..00000000 --- a/src/server_setup_http.h +++ /dev/null @@ -1,112 +0,0 @@ -/// \file server_setup_http.h -/// Contains generic functions for setting up a HTTP Connector. - -#ifndef MAINHANDLER - /// Handler that is called for accepted incoming connections. - #define MAINHANDLER NoHandler - #error "No handler was set!" -#endif - -#ifndef CONNECTOR - /// Connector name for the socket. - #define CONNECTOR "NoConnector" - #error "No connector was set!" -#endif - -#include //Socket library -#include //utilities for config management -#include -#include -#include -#include -Socket::Server server_socket; ///< Placeholder for the server socket - -/// Basic signal handler. Disconnects the server_socket if it receives -/// a SIGINT, SIGHUP or SIGTERM signal, but does nothing for SIGPIPE. -/// Disconnecting the server_socket will terminate the main listening loop -/// and cleanly shut down the process. -void signal_handler (int signum){ - switch (signum){ - case SIGINT: - #if DEBUG >= 1 - fprintf(stderr, "Received SIGINT - closing server socket.\n"); - #endif - break; - case SIGHUP: - #if DEBUG >= 1 - fprintf(stderr, "Received SIGHUP - closing server socket.\n"); - #endif - break; - case SIGTERM: - #if DEBUG >= 1 - fprintf(stderr, "Received SIGTERM - closing server socket.\n"); - #endif - break; - case SIGCHLD: - wait(0); - return; - break; - default: return; break; - } - if (!server_socket.connected()) return; - server_socket.close(); -}//signal_handler - -/// Generic main entry point and loop for DDV HTTP-based Connectors. -/// This sets up the proper termination handler, checks commandline options, -/// parses config files and opens a listening socket. -/// Any incoming connections will be accepted and start up the function #MAINHANDLER, -/// which should be defined before including server_setup_http.cpp. -/// The connector name is set by define #CONNECTOR. -int main(int argc, char ** argv){ - Socket::Connection S;//placeholder for incoming connections - - //setup signal handler - struct sigaction new_action; - new_action.sa_handler = signal_handler; - sigemptyset (&new_action.sa_mask); - new_action.sa_flags = 0; - sigaction(SIGINT, &new_action, NULL); - sigaction(SIGHUP, &new_action, NULL); - sigaction(SIGTERM, &new_action, NULL); - sigaction(SIGPIPE, &new_action, NULL); - sigaction(SIGCHLD, &new_action, NULL); - - //set and parse configuration - Util::Config C; - C.parseArgs(argc, argv); - - //setup a new server socket, for the correct interface and port - server_socket = Socket::Server("/tmp/mist/http_" CONNECTOR); - if (!server_socket.connected()){ - #if DEBUG >= 1 - fprintf(stderr, "Error: could not make listening socket\n"); - #endif - return 1; - }else{ - #if DEBUG >= 3 - fprintf(stderr, "Made a listening socket on %s:%i...\n", C.interface.c_str(), C.listen_port); - #endif - } - - Util::setUser(C.username); - if (C.daemon_mode){Util::Daemonize();} - - while (server_socket.connected()){ - S = server_socket.accept(); - if (S.connected()){//check if the new connection is valid - pid_t myid = fork(); - if (myid == 0){//if new child, start MAINHANDLER - return MAINHANDLER(S); - }else{//otherwise, do nothing or output debugging text - #if DEBUG >= 3 - fprintf(stderr, "Spawned new process %i for socket %i\n", (int)myid, S.getSocket()); - #endif - } - } - }//while connected - #if DEBUG >= 1 - fprintf(stderr, "Server socket closed, exiting.\n"); - #endif - return 0; -}//main