Converted nearly everything to new config object from library.

This commit is contained in:
Thulinma 2012-07-21 04:32:37 +02:00
parent cecb015a4b
commit ffff1f9577
14 changed files with 147 additions and 330 deletions

View file

@ -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

View file

@ -7,10 +7,13 @@
#include <fstream>
#include <string>
#include <mist/amf.h>
#include <mist/config.h>
/// 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

View file

@ -11,9 +11,13 @@
#include <unistd.h>
#include <signal.h>
#include <mist/dtsc.h> //DTSC support
#include <mist/config.h>
/// 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;

View file

@ -11,9 +11,12 @@
#include <unistd.h>
#include <signal.h>
#include <mist/flv_tag.h> //FLV support
#include <mist/config.h>
/// 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)){

View file

@ -17,6 +17,7 @@
#include <mist/flv_tag.h>
#include <mist/amf.h>
#include <mist/rtmpchunks.h>
#include <mist/config.h>
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");

View file

@ -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

View file

@ -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

View file

@ -2,22 +2,22 @@
/// Contains the main code for the RAW connector.
#include <iostream>
#include <mist/config.h>
#include <mist/socket.h>
/// 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

View file

@ -12,6 +12,7 @@
#include <getopt.h>
#include <sstream>
#include <mist/socket.h>
#include <mist/config.h>
#include <mist/flv_tag.h>
#include <mist/amf.h>
#include <mist/rtmpchunks.h>
@ -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

View file

@ -25,14 +25,15 @@
#include <signal.h>
#include <sstream>
#include <openssl/md5.h>
#include <mist/config.h>
#include <mist/socket.h>
#include <mist/http_parser.h>
#include <mist/json.h>
#include <mist/procs.h>
#include <mist/config.h>
#include <mist/auth.h>
#define UPLINK_INTERVAL 30
#define COMPILED_USERNAME ""
#define COMPILED_PASSWORD ""
Socket::Server API_Socket; ///< Main connection socket.
std::map<std::string, int> 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<Socket::Connection> 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();

View file

@ -13,10 +13,11 @@
#include <mist/flv_tag.h> //FLV support
#include <mist/dtsc.h> //DTSC support
#include <mist/amf.h> //AMF support
#include <mist/config.h>
/// 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

View file

@ -13,6 +13,7 @@
#include <mist/flv_tag.h> //FLV support
#include <mist/dtsc.h> //DTSC support
#include <mist/amf.h> //AMF support
#include <mist/config.h>
/// 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

View file

@ -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 <mist/socket.h> //Socket library
#include <mist/config.h> //utilities for config management
#include <signal.h>
#include <sys/types.h>
#include <pwd.h>
#include <fstream>
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

View file

@ -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 <mist/socket.h> //Socket library
#include <mist/config.h> //utilities for config management
#include <signal.h>
#include <sys/types.h>
#include <pwd.h>
#include <fstream>
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