From 7c0db4531d66467745b9601548b21f57c1a4075c Mon Sep 17 00:00:00 2001 From: Thulinma Date: Wed, 15 Apr 2015 14:24:43 +0200 Subject: [PATCH 1/3] Removed legacy libraries (converter, ftp, filesystem) from codebase. --- CMakeLists.txt | 6 - lib/converter.cpp | 328 -------------------------- lib/converter.h | 35 --- lib/filesystem.cpp | 318 -------------------------- lib/filesystem.h | 67 ------ lib/ftp.cpp | 557 --------------------------------------------- lib/ftp.h | 82 ------- 7 files changed, 1393 deletions(-) delete mode 100644 lib/converter.cpp delete mode 100644 lib/converter.h delete mode 100644 lib/filesystem.cpp delete mode 100644 lib/filesystem.h delete mode 100644 lib/ftp.cpp delete mode 100644 lib/ftp.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ec63094d..08a380e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,12 +92,9 @@ set(libHeaders ${SOURCE_DIR}/lib/bitstream.h ${SOURCE_DIR}/lib/checksum.h ${SOURCE_DIR}/lib/config.h - ${SOURCE_DIR}/lib/converter.h ${SOURCE_DIR}/lib/defines.h ${SOURCE_DIR}/lib/dtsc.h - ${SOURCE_DIR}/lib/filesystem.h ${SOURCE_DIR}/lib/flv_tag.h - ${SOURCE_DIR}/lib/ftp.h ${SOURCE_DIR}/lib/http_parser.h ${SOURCE_DIR}/lib/json.h ${SOURCE_DIR}/lib/mp4_adobe.h @@ -128,12 +125,9 @@ set(libSources ${SOURCE_DIR}/lib/bitfields.cpp ${SOURCE_DIR}/lib/bitstream.cpp ${SOURCE_DIR}/lib/config.cpp - ${SOURCE_DIR}/lib/converter.cpp ${SOURCE_DIR}/lib/dtsc.cpp ${SOURCE_DIR}/lib/dtscmeta.cpp - ${SOURCE_DIR}/lib/filesystem.cpp ${SOURCE_DIR}/lib/flv_tag.cpp - ${SOURCE_DIR}/lib/ftp.cpp ${SOURCE_DIR}/lib/http_parser.cpp ${SOURCE_DIR}/lib/json.cpp ${SOURCE_DIR}/lib/mp4_adobe.cpp diff --git a/lib/converter.cpp b/lib/converter.cpp deleted file mode 100644 index 752b0664..00000000 --- a/lib/converter.cpp +++ /dev/null @@ -1,328 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "timing.h" -#include "converter.h" -#include "procs.h" -#include "config.h" - -namespace Converter { - - ///\brief The base constructor - Converter::Converter() { - fillFFMpegEncoders(); - } - - ///\brief A function that fill the internal variables with values provided by examing ffmpeg output - /// - ///Checks for the following encoders: - /// - AAC - /// - H264 - /// - MP3 - void Converter::fillFFMpegEncoders() { - std::vector cmd; - cmd.reserve(3); - cmd.push_back((char *)"ffmpeg"); - cmd.push_back((char *)"-encoders"); - cmd.push_back(NULL); - int outFD = -1; - Util::Procs::StartPiped("FFMpegInfo", &cmd[0], 0, &outFD, 0); - while (Util::Procs::isActive("FFMpegInfo")) { - Util::sleep(100); - } - FILE * outFile = fdopen(outFD, "r"); - char * fileBuf = 0; - size_t fileBufLen = 0; - while (!(feof(outFile) || ferror(outFile)) && (getline(&fileBuf, &fileBufLen, outFile) != -1)) { - if (strstr(fileBuf, "aac") || strstr(fileBuf, "AAC")) { - strtok(fileBuf, " \t"); - allCodecs["ffmpeg"][strtok(NULL, " \t")] = "aac"; - } - if (strstr(fileBuf, "h264") || strstr(fileBuf, "H264")) { - strtok(fileBuf, " \t"); - allCodecs["ffmpeg"][strtok(NULL, " \t")] = "h264"; - } - if (strstr(fileBuf, "mp3") || strstr(fileBuf, "MP3")) { - strtok(fileBuf, " \t"); - allCodecs["ffmpeg"][strtok(NULL, " \t")] = "mp3"; - } - } - fclose(outFile); - } - - ///\brief A function to obtain all available codecs that have been obtained from the encoders. - ///\return A reference to the allCodecs member. - converterInfo & Converter::getCodecs() { - return allCodecs; - } - - ///\brief A function to obtain the available encoders in JSON format. - ///\return A JSON::Value containing all encoder:codec pairs. - JSON::Value Converter::getEncoders() { - JSON::Value result; - for (converterInfo::iterator convIt = allCodecs.begin(); convIt != allCodecs.end(); convIt++) { - for (codecInfo::iterator codIt = convIt->second.begin(); codIt != convIt->second.end(); codIt++) { - if (codIt->second == "h264") { - result[convIt->first]["video"][codIt->first] = codIt->second; - } else { - result[convIt->first]["audio"][codIt->first] = codIt->second; - - } - } - } - return result; - } - - ///\brief Looks in a given path for all files that could be converted - ///\param myPath The location to look at, this should be a folder. - ///\return A JSON::Value containing all media files in the location, with their corresponding metadata values. - JSON::Value Converter::queryPath(std::string myPath) { - char const * cmd[3] = {0, 0, 0}; - std::string mistPath = Util::getMyPath() + "MistInfo"; - cmd[0] = mistPath.c_str(); - JSON::Value result; - DIR * Dirp = opendir(myPath.c_str()); - struct stat StatBuf; - if (Dirp) { - dirent * entry; - while ((entry = readdir(Dirp))) { - if (stat(std::string(myPath + "/" + entry->d_name).c_str(), &StatBuf) == -1) { - continue; - } - if ((StatBuf.st_mode & S_IFREG) == 0) { - continue; - } - std::string fileName = entry->d_name; - std::string mijnPad = std::string(myPath + (myPath[myPath.size() - 1] == '/' ? "" : "/") + entry->d_name); - cmd[1] = mijnPad.c_str(); - result[fileName] = JSON::fromString(Util::Procs::getOutputOf((char * const *)cmd)); - } - } - return result; - } - - ///\brief Start a conversion with the given parameters - ///\param name The name to use for logging the conversion. - ///\param parameters The parameters, accepted are the following: - /// - input The input url - /// - output The output url - /// - encoder The encoder to use - /// - video An object containing video parameters, if not existant no video will be output. Values are: - /// - width The width of the resulting video - /// - height The height of the resulting video - /// - codec The codec to encode video in, or copy to use the current codec - /// - fpks The framerate in fps * 1000 - /// - audio An object containing audio parameters, if not existant no audio will be output. Values are: - /// - codec The codec to encode audio in, or copy to use the current codec - /// - samplerate The target samplerate for the audio, in hz - void Converter::startConversion(std::string name, JSON::Value parameters) { - if (!parameters.isMember("input")) { - statusHistory[name] = "No input file supplied"; - return; - } - if (!parameters.isMember("output")) { - statusHistory[name] = "No output file supplied"; - return; - } - struct stat statBuf; - std::string outPath = parameters["output"].asString(); - outPath = outPath.substr(0, outPath.rfind('/')); - int statRes = stat(outPath.c_str(), & statBuf); - if (statRes == -1 || !S_ISDIR(statBuf.st_mode)) { - statusHistory[name] = "Output path is either non-existent, or not a path."; - return; - } - if (!parameters.isMember("encoder")) { - statusHistory[name] = "No encoder specified"; - return; - } - if (allCodecs.find(parameters["encoder"]) == allCodecs.end()) { - statusHistory[name] = "Can not find encoder " + parameters["encoder"].asString(); - return; - } - if (parameters.isMember("video")) { - if (parameters["video"].isMember("width") && !parameters["video"].isMember("height")) { - statusHistory[name] = "No height parameter given"; - return; - } - if (parameters["video"].isMember("height") && !parameters["video"].isMember("width")) { - statusHistory[name] = "No width parameter given"; - return; - } - } - std::stringstream encoderCommand; - if (parameters["encoder"] == "ffmpeg") { - encoderCommand << "ffmpeg -i "; - encoderCommand << parameters["input"].asString() << " "; - if (parameters.isMember("video")) { - if (!parameters["video"].isMember("codec") || parameters["video"]["codec"] == "copy") { - encoderCommand << "-vcodec copy "; - } else { - codecInfo::iterator vidCodec = allCodecs["ffmpeg"].find(parameters["video"]["codec"]); - if (vidCodec == allCodecs["ffmpeg"].end()) { - statusHistory[name] = "Can not find video codec " + parameters["video"]["codec"].asString(); - return; - } - encoderCommand << "-vcodec " << vidCodec->first << " "; - if (parameters["video"]["codec"].asString() == "h264") { - //Enforce baseline - encoderCommand << "-preset slow -profile:v baseline -level 30 "; - } - if (parameters["video"].isMember("fpks")) { - encoderCommand << "-r " << parameters["video"]["fpks"].asInt() / 1000 << " "; - } - if (parameters["video"].isMember("width")) { - encoderCommand << "-s " << parameters["video"]["width"].asInt() << "x" << parameters["video"]["height"].asInt() << " "; - } - ///\todo Keyframe interval (different in older and newer versions of ffmpeg?) - } - } else { - encoderCommand << "-vn "; - } - if (parameters.isMember("audio")) { - if (!parameters["audio"].isMember("codec")) { - encoderCommand << "-acodec copy "; - } else { - codecInfo::iterator audCodec = allCodecs["ffmpeg"].find(parameters["audio"]["codec"]); - if (audCodec == allCodecs["ffmpeg"].end()) { - statusHistory[name] = "Can not find audio codec " + parameters["audio"]["codec"].asString(); - return; - } - if (audCodec->second == "aac") { - encoderCommand << "-strict -2 "; - } - encoderCommand << "-acodec " << audCodec->first << " "; - if (parameters["audio"].isMember("samplerate")) { - encoderCommand << "-ar " << parameters["audio"]["samplerate"].asInt() << " "; - } - } - } else { - encoderCommand << "-an "; - } - encoderCommand << "-f flv -"; - } - int statusFD = -1; - Util::Procs::StartPiped2(name, encoderCommand.str(), Util::getMyPath() + "MistFLV2DTSC -o " + parameters["output"].asString(), 0, 0, &statusFD, 0); - parameters["statusFD"] = statusFD; - allConversions[name] = parameters; - allConversions[name]["status"]["duration"] = "?"; - allConversions[name]["status"]["progress"] = 0; - allConversions[name]["status"]["frame"] = 0; - allConversions[name]["status"]["time"] = 0; - } - - ///\brief Updates the internal status of the converter class. - /// - ///Will check for each running conversion whether it is still running, and update its status accordingly - void Converter::updateStatus() { - if (allConversions.size()) { - std::map::iterator cIt; - bool hasChanged = true; - while (hasChanged && allConversions.size()) { - hasChanged = false; - for (cIt = allConversions.begin(); cIt != allConversions.end(); cIt++) { - if (Util::Procs::isActive(cIt->first)) { - int statusFD = dup(cIt->second["statusFD"].asInt()); - fsync(statusFD); - FILE * statusFile = fdopen(statusFD, "r"); - char * fileBuf = 0; - size_t fileBufLen = 0; - fseek(statusFile, 0, SEEK_END); - std::string line; - int totalTime = 0; - do { - getdelim(&fileBuf, &fileBufLen, '\r', statusFile); - line = fileBuf; - if (line.find("Duration") != std::string::npos) { - int curOffset = line.find("Duration: ") + 10; - totalTime += atoi(line.substr(curOffset, 2).c_str()) * 60 * 60 * 1000; - totalTime += atoi(line.substr(curOffset + 3, 2).c_str()) * 60 * 1000; - totalTime += atoi(line.substr(curOffset + 6, 2).c_str()) * 1000; - totalTime += atoi(line.substr(curOffset + 9, 2).c_str()) * 10; - cIt->second["duration"] = totalTime; - } - } while (!feof(statusFile) && line.find("frame") != 0); //"frame" is the fist word on an actual status line of ffmpeg - if (!feof(statusFile)) { - cIt->second["status"] = parseFFMpegStatus(line); - cIt->second["status"]["duration"] = cIt->second["duration"]; - cIt->second["status"]["progress"] = (cIt->second["status"]["time"].asInt() * 100) / cIt->second["duration"].asInt(); - } else { - line.erase(line.end() - 1); - line = line.substr(line.rfind("\n") + 1); - cIt->second["status"] = line; - } - free(fileBuf); - fclose(statusFile); - } else { - if (statusHistory.find(cIt->first) == statusHistory.end()) { - statusHistory[cIt->first] = "Conversion successful, running DTSCFix"; - Util::Procs::Start(cIt->first + "DTSCFix", Util::getMyPath() + "MistDTSCFix " + cIt->second["output"].asString()); - } - allConversions.erase(cIt); - hasChanged = true; - break; - } - } - } - } - if (statusHistory.size()) { - std::map::iterator sIt; - for (sIt = statusHistory.begin(); sIt != statusHistory.end(); sIt++) { - if (statusHistory[sIt->first].find("DTSCFix") != std::string::npos) { - if (Util::Procs::isActive(sIt->first + "DTSCFIX")) { - continue; - } - statusHistory[sIt->first] = "Conversion successful"; - } - } - } - } - - ///\brief Parses a single ffmpeg status line into a JSON format - ///\param statusLine The current status of ffmpeg - ///\return A JSON::Value with the following values set: - /// - frame The current last encoded frame - /// - time The current last encoded timestamp - JSON::Value Converter::parseFFMpegStatus(std::string statusLine) { - JSON::Value result; - int curOffset = statusLine.find("frame=") + 6; - result["frame"] = atoi(statusLine.substr(curOffset, statusLine.find("fps=") - curOffset).c_str()); - curOffset = statusLine.find("time=") + 5; - int myTime = 0; - myTime += atoi(statusLine.substr(curOffset, 2).c_str()) * 60 * 60 * 1000; - myTime += atoi(statusLine.substr(curOffset + 3, 2).c_str()) * 60 * 1000; - myTime += atoi(statusLine.substr(curOffset + 6, 2).c_str()) * 1000; - myTime += atoi(statusLine.substr(curOffset + 9, 2).c_str()) * 10; - result["time"] = myTime; - return result; - } - - ///\brief Obtain the current internal status of the conversion class - ///\return A JSON::Value with the status of each conversion - JSON::Value Converter::getStatus() { - updateStatus(); - JSON::Value result; - if (allConversions.size()) { - for (std::map::iterator cIt = allConversions.begin(); cIt != allConversions.end(); cIt++) { - result[cIt->first] = cIt->second["status"]; - result[cIt->first]["details"] = cIt->second; - } - } - if (statusHistory.size()) { - std::map::iterator sIt; - for (sIt = statusHistory.begin(); sIt != statusHistory.end(); sIt++) { - result[sIt->first] = sIt->second; - } - } - return result; - } - - ///\brief Clears the status history of all conversions - void Converter::clearStatus() { - statusHistory.clear(); - } -} diff --git a/lib/converter.h b/lib/converter.h deleted file mode 100644 index a082e994..00000000 --- a/lib/converter.h +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include - -#include "json.h" - -///\brief A typedef to simplify accessing all codecs -typedef std::map codecInfo; -///\brief A typedef to simplify accessing all encoders -typedef std::map converterInfo; - -///\brief A namespace containing all functions for handling the conversion API -namespace Converter { - - ///\brief A class containing the basic conversion API functionality - class Converter { - public: - Converter(); - converterInfo & getCodecs(); - JSON::Value getEncoders(); - JSON::Value queryPath(std::string myPath); - void startConversion(std::string name, JSON::Value parameters); - void updateStatus(); - JSON::Value getStatus(); - void clearStatus(); - JSON::Value parseFFMpegStatus(std::string statusLine); - private: - void fillFFMpegEncoders(); - ///\brief Holds a list of all current known codecs - converterInfo allCodecs; - ///\brief Holds a list of all the current conversions - std::map allConversions; - ///\brief Stores the status of all conversions, and the history - std::map statusHistory; - }; -} diff --git a/lib/filesystem.cpp b/lib/filesystem.cpp deleted file mode 100644 index c2e9b76d..00000000 --- a/lib/filesystem.cpp +++ /dev/null @@ -1,318 +0,0 @@ -#include "filesystem.h" -#include "defines.h" - -Filesystem::Directory::Directory(std::string PathName, std::string BasePath) { - MyBase = BasePath; - if (PathName[0] == '/') { - PathName.erase(0, 1); - } - if (BasePath[BasePath.size() - 1] != '/') { - BasePath += "/"; - } - MyPath = PathName; - FillEntries(); -} - -Filesystem::Directory::~Directory() { -} - -void Filesystem::Directory::FillEntries() { - ValidDir = true; - struct stat StatBuf; - Entries.clear(); - DIR * Dirp = opendir((MyBase + MyPath).c_str()); - if (!Dirp) { - ValidDir = false; - } else { - dirent * entry; - while ((entry = readdir(Dirp))) { - if (stat((MyBase + MyPath + "/" + entry->d_name).c_str(), &StatBuf) == -1) { - DEBUG_MSG(DLVL_DEVEL, "Skipping %s, reason %s", entry->d_name, strerror(errno)); - continue; - } - ///Convert stat to string - Entries[std::string(entry->d_name)] = StatBuf; - } - } -} - -void Filesystem::Directory::Print() { - /// \todo Remove? Libraries shouldn't print stuff. - if (!ValidDir) { - DEBUG_MSG(DLVL_ERROR, "%s is not a valid directory", (MyBase + MyPath).c_str()); - return; - } - printf("%s:\n", (MyBase + MyPath).c_str()); - for (std::map::iterator it = Entries.begin(); it != Entries.end(); it++) { - printf("\t%s\n", (*it).first.c_str()); - } - printf("\n"); -} - -bool Filesystem::Directory::IsDir() { - return ValidDir; -} - -std::string Filesystem::Directory::PWD() { - return "/" + MyPath; -} - -std::string Filesystem::Directory::LIST(std::vector ActiveStreams) { - FillEntries(); - int MyPermissions; - std::stringstream Converter; - passwd * pwd; //For Username - group * grp; //For Groupname - tm * tm; //For time localisation - char datestring[256]; //For time localisation - - std::string MyLoc = MyBase + MyPath; - if (MyLoc[MyLoc.size() - 1] != '/') { - MyLoc += "/"; - } - - for (std::map::iterator it = Entries.begin(); it != Entries.end(); it++) { - - bool Active = (std::find(ActiveStreams.begin(), ActiveStreams.end(), (*it).first) != ActiveStreams.end()); - if ((Active && (MyVisible[MyPath] & S_ACTIVE)) || ((!Active) && (MyVisible[MyPath] & S_INACTIVE)) || (((*it).second.st_mode / 010000) == 4)) { - if (((*it).second.st_mode / 010000) == 4) { - Converter << 'd'; - } else { - Converter << '-'; - } - MyPermissions = (((*it).second.st_mode % 010000) / 0100); - if (MyPermissions & 4) { - Converter << 'r'; - } else { - Converter << '-'; - } - if (MyPermissions & 2) { - Converter << 'w'; - } else { - Converter << '-'; - } - if (MyPermissions & 1) { - Converter << 'x'; - } else { - Converter << '-'; - } - MyPermissions = (((*it).second.st_mode % 0100) / 010); - if (MyPermissions & 4) { - Converter << 'r'; - } else { - Converter << '-'; - } - if (MyPermissions & 2) { - Converter << 'w'; - } else { - Converter << '-'; - } - if (MyPermissions & 1) { - Converter << 'x'; - } else { - Converter << '-'; - } - MyPermissions = ((*it).second.st_mode % 010); - if (MyPermissions & 4) { - Converter << 'r'; - } else { - Converter << '-'; - } - if (MyPermissions & 2) { - Converter << 'w'; - } else { - Converter << '-'; - } - if (MyPermissions & 1) { - Converter << 'x'; - } else { - Converter << '-'; - } - Converter << ' '; - Converter << (*it).second.st_nlink; - Converter << ' '; - if ((pwd = getpwuid((*it).second.st_uid))) { - Converter << pwd->pw_name; - } else { - Converter << (*it).second.st_uid; - } - Converter << ' '; - if ((grp = getgrgid((*it).second.st_gid))) { - Converter << grp->gr_name; - } else { - Converter << (*it).second.st_gid; - } - Converter << ' '; - Converter << (*it).second.st_size; - Converter << ' '; - tm = localtime(&((*it).second.st_mtime)); - strftime(datestring, sizeof(datestring), "%b %d %H:%M", tm); - Converter << datestring; - Converter << ' '; - Converter << (*it).first; - Converter << '\n'; - } - } - return Converter.str(); -} - -bool Filesystem::Directory::CWD(std::string Path) { - if (Path[0] == '/') { - Path.erase(0, 1); - MyPath = Path; - } else { - if (MyPath != "") { - MyPath += "/"; - } - MyPath += Path; - } - FillEntries(); - printf("New Path: %s\n", MyPath.c_str()); - if (MyPermissions.find(MyPath) != MyPermissions.end()) { - printf("\tPermissions: %d\n", MyPermissions[MyPath]); - } - return SimplifyPath(); -} - -bool Filesystem::Directory::CDUP() { - return CWD(".."); -} - -std::string Filesystem::Directory::RETR(std::string Path) { - std::string Result; - std::string FileName; - if (Path[0] == '/') { - Path.erase(0, 1); - FileName = MyBase + Path; - } else { - FileName = MyBase + MyPath + "/" + Path; - } - std::ifstream File; - File.open(FileName.c_str()); - while (File.good()) { - Result += File.get(); - } - File.close(); - return Result; -} - -void Filesystem::Directory::STOR(std::string Path, std::string Data) { - if (MyPermissions.find(MyPath) == MyPermissions.end() || (MyPermissions[MyPath] & P_STOR)) { - std::string FileName; - if (Path[0] == '/') { - Path.erase(0, 1); - FileName = MyBase + Path; - } else { - FileName = MyBase + MyPath + "/" + Path; - } - std::ofstream File; - File.open(FileName.c_str()); - File << Data; - File.close(); - } -} - -bool Filesystem::Directory::SimplifyPath() { - MyPath += "/"; - std::vector TempPath; - std::string TempString; - for (std::string::iterator it = MyPath.begin(); it != MyPath.end(); it++) { - if ((*it) == '/') { - if (TempString == "..") { - if (!TempPath.size()) { - return false; - } - TempPath.erase((TempPath.end() - 1)); - } else if (TempString != "." && TempString != "") { - TempPath.push_back(TempString); - } - TempString = ""; - } else { - TempString += (*it); - } - } - MyPath = ""; - for (std::vector::iterator it = TempPath.begin(); it != TempPath.end(); it++) { - MyPath += (*it); - if (it != (TempPath.end() - 1)) { - MyPath += "/"; - } - } - if (MyVisible.find(MyPath) == MyVisible.end()) { - MyVisible[MyPath] = S_ALL; - } - return true; -} - -bool Filesystem::Directory::DELE(std::string Path) { - if (MyPermissions.find(MyPath) == MyPermissions.end() || (MyPermissions[MyPath] & P_DELE)) { - std::string FileName; - if (Path[0] == '/') { - Path.erase(0, 1); - FileName = MyBase + Path; - } else { - FileName = MyBase + MyPath + "/" + Path; - } - if (std::remove(FileName.c_str())) { - DEBUG_MSG(DLVL_ERROR, "Removing file %s failed", FileName.c_str()); - return false; - } - return true; - } - return false; -} - -bool Filesystem::Directory::MKD(std::string Path) { - std::string FileName; - if (Path[0] == '/') { - Path.erase(0, 1); - FileName = MyBase + Path; - } else { - FileName = MyBase + MyPath + "/" + Path; - } - if (mkdir(FileName.c_str(), S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { - DEBUG_MSG(DLVL_ERROR, "Creating directory %s failed", FileName.c_str()); - return false; - } - MyVisible[FileName] = S_ALL; - return true; -} - -bool Filesystem::Directory::Rename(std::string From, std::string To) { - if (MyPermissions.find(MyPath) == MyPermissions.end() || (MyPermissions[MyPath] & P_RNFT)) { - std::string FileFrom; - if (From[0] == '/') { - From.erase(0, 1); - FileFrom = MyBase + From; - } else { - FileFrom = MyBase + MyPath + "/" + From; - } - std::string FileTo; - if (To[0] == '/') { - FileTo = MyBase + To; - } else { - FileTo = MyBase + MyPath + "/" + To; - } - if (std::rename(FileFrom.c_str(), FileTo.c_str())) { - DEBUG_MSG(DLVL_ERROR, "Renaming %s to %s failed", FileFrom.c_str(), FileTo.c_str()); - return false; - } - return true; - } - return false; -} - -void Filesystem::Directory::SetPermissions(std::string Path, char Permissions) { - MyPermissions[Path] = Permissions; -} - -bool Filesystem::Directory::HasPermission(char Permission) { - if (MyPermissions.find(MyPath) == MyPermissions.end() || (MyPermissions[MyPath] & Permission)) { - return true; - } - return false; -} - -void Filesystem::Directory::SetVisibility(std::string Pathname, char Visible) { - MyVisible[Pathname] = Visible; -} diff --git a/lib/filesystem.h b/lib/filesystem.h deleted file mode 100644 index c901fcc2..00000000 --- a/lib/filesystem.h +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Filesystem { - enum DIR_Permissions { - P_LIST = 0x01, //List - P_RETR = 0x02, //Retrieve - P_STOR = 0x04, //Store - P_RNFT = 0x08, //Rename From/To - P_DELE = 0x10, //Delete - P_MKD = 0x20, //Make directory - P_RMD = 0x40, //Remove directory - }; - - enum DIR_Show { - S_NONE = 0x00, S_ACTIVE = 0x01, S_INACTIVE = 0x02, S_ALL = 0x03, - }; - - class Directory { - public: - Directory(std::string PathName = "", std::string BasePath = "."); - ~Directory(); - void Print(); - bool IsDir(); - std::string PWD(); - std::string LIST(std::vector ActiveStreams = std::vector()); - bool CWD(std::string Path); - bool CDUP(); - bool DELE(std::string Path); - bool MKD(std::string Path); - std::string RETR(std::string Path); - void STOR(std::string Path, std::string Data); - bool Rename(std::string From, std::string To); - void SetPermissions(std::string PathName, char Permissions); - bool HasPermission(char Permission); - void SetVisibility(std::string Pathname, char Visible); - private: - bool ValidDir; - bool SimplifyPath(); - void FillEntries(); - std::string MyBase; - std::string MyPath; - std::map Entries; - std::map MyPermissions; - std::map MyVisible; - }; -//Directory Class -}//Filesystem namespace diff --git a/lib/ftp.cpp b/lib/ftp.cpp deleted file mode 100644 index 286a8472..00000000 --- a/lib/ftp.cpp +++ /dev/null @@ -1,557 +0,0 @@ -#include "ftp.h" - -FTP::User::User(Socket::Connection NewConnection, std::map Credentials) { - Conn = NewConnection; - MyPassivePort = 0; - USER = ""; - PASS = ""; - MODE = MODE_STREAM; - STRU = STRU_FILE; - TYPE = TYPE_ASCII_NONPRINT; - PORT = 20; - RNFR = ""; - AllCredentials = Credentials; - - MyDir = Filesystem::Directory("", FTPBasePath); - MyDir.SetPermissions("", Filesystem::P_LIST); - MyDir.SetPermissions("Unconverted", Filesystem::P_LIST | Filesystem::P_DELE | Filesystem::P_RNFT | Filesystem::P_STOR | Filesystem::P_RETR); - MyDir.SetPermissions("Converted", Filesystem::P_LIST | Filesystem::P_DELE | Filesystem::P_RNFT | Filesystem::P_RETR); - MyDir.SetPermissions("OnDemand", Filesystem::P_LIST | Filesystem::P_RETR); - MyDir.SetPermissions("Live", Filesystem::P_LIST); - - MyDir.SetVisibility("Converted", Filesystem::S_INACTIVE); - MyDir.SetVisibility("OnDemand", Filesystem::S_ACTIVE); - -} - -FTP::User::~User() { -} - -int FTP::User::ParseCommand(std::string Command) { - Commands ThisCmd = CMD_NOCMD; - if (Command.substr(0, 4) == "NOOP") { - ThisCmd = CMD_NOOP; - Command.erase(0, 5); - } - if (Command.substr(0, 4) == "USER") { - ThisCmd = CMD_USER; - Command.erase(0, 5); - } - if (Command.substr(0, 4) == "PASS") { - ThisCmd = CMD_PASS; - Command.erase(0, 5); - } - if (Command.substr(0, 4) == "QUIT") { - ThisCmd = CMD_QUIT; - Command.erase(0, 5); - } - if (Command.substr(0, 4) == "PORT") { - ThisCmd = CMD_PORT; - Command.erase(0, 5); - } - if (Command.substr(0, 4) == "RETR") { - ThisCmd = CMD_RETR; - Command.erase(0, 5); - } - if (Command.substr(0, 4) == "STOR") { - ThisCmd = CMD_STOR; - Command.erase(0, 5); - } - if (Command.substr(0, 4) == "TYPE") { - ThisCmd = CMD_TYPE; - Command.erase(0, 5); - } - if (Command.substr(0, 4) == "MODE") { - ThisCmd = CMD_MODE; - Command.erase(0, 5); - } - if (Command.substr(0, 4) == "STRU") { - ThisCmd = CMD_STRU; - Command.erase(0, 5); - } - if (Command.substr(0, 4) == "EPSV") { - ThisCmd = CMD_EPSV; - Command.erase(0, 5); - } - if (Command.substr(0, 4) == "PASV") { - ThisCmd = CMD_PASV; - Command.erase(0, 5); - } - if (Command.substr(0, 4) == "LIST") { - ThisCmd = CMD_LIST; - Command.erase(0, 5); - } - if (Command.substr(0, 4) == "CDUP") { - ThisCmd = CMD_CDUP; - Command.erase(0, 5); - } - if (Command.substr(0, 4) == "DELE") { - ThisCmd = CMD_DELE; - Command.erase(0, 5); - } - if (Command.substr(0, 4) == "RNFR") { - ThisCmd = CMD_RNFR; - Command.erase(0, 5); - } - if (Command.substr(0, 4) == "RNTO") { - ThisCmd = CMD_RNTO; - Command.erase(0, 5); - } - if (Command.substr(0, 3) == "PWD") { - ThisCmd = CMD_PWD; - Command.erase(0, 4); - } - if (Command.substr(0, 3) == "CWD") { - ThisCmd = CMD_CWD; - Command.erase(0, 4); - } - if (Command.substr(0, 3) == "RMD") { - ThisCmd = CMD_RMD; - Command.erase(0, 4); - } - if (Command.substr(0, 3) == "MKD") { - ThisCmd = CMD_MKD; - Command.erase(0, 4); - } - if (ThisCmd != CMD_RNTO) { - RNFR = ""; - } - switch (ThisCmd) { - case CMD_NOOP: { - return 200; //Command okay. - break; - } - case CMD_USER: { - USER = ""; - PASS = ""; - if (Command == "") { - return 501; - } //Syntax error in parameters or arguments. - USER = Command; - return 331; //User name okay, need password. - break; - } - case CMD_PASS: { - if (USER == "") { - return 503; - } //Bad sequence of commands - if (Command == "") { - return 501; - } //Syntax error in parameters or arguments. - PASS = Command; - if (!LoggedIn()) { - USER = ""; - PASS = ""; - return 530; //Not logged in. - } - return 230; - break; - } - case CMD_LIST: { - Socket::Connection Connected = Passive.accept(); - if (Connected.connected()) { - Conn.SendNow("125 Data connection already open; transfer starting.\n"); - } else { - Conn.SendNow("150 File status okay; about to open data connection.\n"); - } - while (!Connected.connected()) { - Connected = Passive.accept(); - } - std::string tmpstr = MyDir.LIST(ActiveStreams); - Connected.SendNow(tmpstr); - Connected.close(); - return 226; - break; - } - case CMD_QUIT: { - return 221; //Service closing control connection. Logged out if appropriate. - break; - } - case CMD_PORT: { - if (!LoggedIn()) { - return 530; - } //Not logged in. - if (Command == "") { - return 501; - } //Syntax error in parameters or arguments. - PORT = atoi(Command.c_str()); - return 200; //Command okay. - break; - } - case CMD_EPSV: { - if (!LoggedIn()) { - return 530; - } //Not logged in. - MyPassivePort = (rand() % 9999); - Passive = Socket::Server(MyPassivePort, "0.0.0.0", true); - return 229; - break; - } - case CMD_PASV: { - if (!LoggedIn()) { - return 530; - } //Not logged in. - MyPassivePort = (rand() % 9999) + 49152; - Passive = Socket::Server(MyPassivePort, "0.0.0.0", true); - return 227; - break; - } - case CMD_RETR: { - if (!LoggedIn()) { - return 530; - } //Not logged in. - if (Command == "") { - return 501; - } //Syntax error in parameters or arguments. - if (!MyDir.HasPermission(Filesystem::P_RETR)) { - return 550; - } //Access denied. - Socket::Connection Connected = Passive.accept(); - if (Connected.connected()) { - Conn.SendNow("125 Data connection already open; transfer starting.\n"); - } else { - Conn.SendNow("150 File status okay; about to open data connection.\n"); - } - while (!Connected.connected()) { - Connected = Passive.accept(); - } - std::string tmpstr = MyDir.RETR(Command); - Connected.SendNow(tmpstr); - Connected.close(); - return 226; - break; - } - case CMD_STOR: { - if (!LoggedIn()) { - return 530; - } //Not logged in. - if (Command == "") { - return 501; - } //Syntax error in parameters or arguments. - if (!MyDir.HasPermission(Filesystem::P_STOR)) { - return 550; - } //Access denied. - Socket::Connection Connected = Passive.accept(); - if (Connected.connected()) { - Conn.SendNow("125 Data connection already open; transfer starting.\n"); - } else { - Conn.SendNow("150 File status okay; about to open data connection.\n"); - } - while (!Connected.connected()) { - Connected = Passive.accept(); - } - std::string Buffer; - while (Connected.spool()) { - } - /// \todo Comment me back in. ^_^ - //Buffer = Connected.Received(); - MyDir.STOR(Command, Buffer); - return 250; - break; - } - case CMD_TYPE: { - if (!LoggedIn()) { - return 530; - } //Not logged in. - if (Command == "") { - return 501; - } //Syntax error in parameters or arguments. - if (Command.size() != 1 && Command.size() != 3) { - return 501; - } //Syntax error in parameters or arguments. - switch (Command[0]) { - case 'A': { - if (Command.size() > 1) { - if (Command[1] != ' ') { - return 501; - } //Syntax error in parameters or arguments. - if (Command[2] != 'N') { - return 504; - } //Command not implemented for that parameter. - } - TYPE = TYPE_ASCII_NONPRINT; - break; - } - case 'I': { - if (Command.size() > 1) { - if (Command[1] != ' ') { - return 501; - } //Syntax error in parameters or arguments. - if (Command[2] != 'N') { - return 504; - } //Command not implemented for that parameter. - } - TYPE = TYPE_IMAGE_NONPRINT; - break; - } - default: { - return 504; //Command not implemented for that parameter. - break; - } - } - return 200; //Command okay. - break; - } - case CMD_MODE: { - if (!LoggedIn()) { - return 530; - } //Not logged in. - if (Command == "") { - return 501; - } //Syntax error in parameters or arguments. - if (Command.size() != 1) { - return 501; - } //Syntax error in parameters or arguments. - if (Command[0] != 'S') { - return 504; - } //Command not implemented for that parameter. - MODE = MODE_STREAM; - return 200; //Command okay. - break; - } - case CMD_STRU: { - if (!LoggedIn()) { - return 530; - } //Not logged in. - if (Command == "") { - return 501; - } //Syntax error in parameters or arguments. - if (Command.size() != 1) { - return 501; - } //Syntax error in parameters or arguments. - switch (Command[0]) { - case 'F': { - STRU = STRU_FILE; - break; - } - case 'R': { - STRU = STRU_RECORD; - break; - } - default: { - return 504; //Command not implemented for that parameter. - break; - } - } - return 200; //Command okay. - break; - } - case CMD_PWD: { - if (!LoggedIn()) { - return 550; - } //Not logged in. - if (Command != "") { - return 501; - } //Syntax error in parameters or arguments. - return 2570; //257 -- 0 to indicate PWD over MKD - break; - } - case CMD_CWD: { - if (!LoggedIn()) { - return 530; - } //Not logged in. - Filesystem::Directory TmpDir = MyDir; - if (TmpDir.CWD(Command)) { - if (TmpDir.IsDir()) { - MyDir = TmpDir; - return 250; - } - } - return 550; - break; - } - case CMD_CDUP: { - if (!LoggedIn()) { - return 530; - } //Not logged in. - if (Command != "") { - return 501; - } //Syntax error in parameters or arguments. - Filesystem::Directory TmpDir = MyDir; - if (TmpDir.CDUP()) { - if (TmpDir.IsDir()) { - MyDir = TmpDir; - return 250; - } - } - return 550; - break; - } - case CMD_DELE: { - if (!LoggedIn()) { - return 530; - } //Not logged in. - if (Command == "") { - return 501; - } //Syntax error in parameters or arguments. - if (!MyDir.DELE(Command)) { - return 550; - } - return 250; - break; - } - case CMD_RMD: { - if (!LoggedIn()) { - return 530; - } //Not logged in. - if (Command == "") { - return 501; - } //Syntax error in parameters or arguments. - if (!MyDir.HasPermission(Filesystem::P_RMD)) { - return 550; - } - if (!MyDir.DELE(Command)) { - return 550; - } - return 250; - break; - } - case CMD_MKD: { - if (!LoggedIn()) { - return 530; - } //Not logged in. - if (Command == "") { - return 501; - } //Syntax error in parameters or arguments. - if (!MyDir.HasPermission(Filesystem::P_MKD)) { - return 550; - } - if (!MyDir.MKD(Command)) { - return 550; - } - return 2571; - break; - } - case CMD_RNFR: { - if (!LoggedIn()) { - return 530; - } //Not logged in. - if (Command == "") { - return 501; - } //Syntax error in parameters or arguments. - RNFR = Command; - return 350; //Awaiting further information - } - case CMD_RNTO: { - if (!LoggedIn()) { - return 530; - } //Not logged in. - if (Command == "") { - return 501; - } //Syntax error in parameters or arguments. - if (RNFR == "") { - return 503; - } //Bad sequence of commands - if (!MyDir.Rename(RNFR, Command)) { - return 550; - } - return 250; - } - default: { - return 502; //Command not implemented. - break; - } - } -} - -bool FTP::User::LoggedIn() { - if (USER == "" || PASS == "") { - return false; - } - if (!AllCredentials.size()) { - return true; - } - if ((AllCredentials.find(USER) != AllCredentials.end()) && AllCredentials[USER] == PASS) { - return true; - } - return false; -} - -std::string FTP::User::NumToMsg(int MsgNum) { - std::string Result; - switch (MsgNum) { - case 200: { - Result = "200 Message okay.\n"; - break; - } - case 221: { - Result = "221 Service closing control connection. Logged out if appropriate.\n"; - break; - } - case 226: { - Result = "226 Closing data connection.\n"; - break; - } - case 227: { - std::stringstream sstr; - sstr << "227 Entering passive mode (0,0,0,0,"; - sstr << (MyPassivePort >> 8) % 256; - sstr << ","; - sstr << MyPassivePort % 256; - sstr << ").\n"; - Result = sstr.str(); - break; - } - case 229: { - std::stringstream sstr; - sstr << "229 Entering extended passive mode (|||"; - sstr << MyPassivePort; - sstr << "|).\n"; - Result = sstr.str(); - break; - } - case 230: { - Result = "230 User logged in, proceed.\n"; - break; - } - case 250: { - Result = "250 Requested file action okay, completed.\n"; - break; - } - case 2570: { //PWD - Result = "257 \"" + MyDir.PWD() + "\" selected as PWD\n"; - break; - } - case 2571: { //MKD - Result = "257 \"" + MyDir.PWD() + "\" created\n"; - break; - } - case 331: { - Result = "331 User name okay, need password.\n"; - break; - } - case 350: { - Result = "350 Requested file action pending further information\n"; - break; - } - case 501: { - Result = "501 Syntax error in parameters or arguments.\n"; - break; - } - case 502: { - Result = "502 Command not implemented.\n"; - break; - } - case 503: { - Result = "503 Bad sequence of commands.\n"; - break; - } - case 504: { - Result = "504 Command not implemented for that parameter.\n"; - break; - } - case 530: { - Result = "530 Not logged in.\n"; - break; - } - case 550: { - Result = "550 Requested action not taken.\n"; - break; - } - default: { - Result = "Error msg not implemented?\n"; - break; - } - } - return Result; -} diff --git a/lib/ftp.h b/lib/ftp.h deleted file mode 100644 index 41350657..00000000 --- a/lib/ftp.h +++ /dev/null @@ -1,82 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "./socket.h" -#include "./filesystem.h" -#include - -#include "./json.h" - -namespace FTP { - static std::string FTPBasePath = "/tmp/mist/OnDemand/"; - - enum Mode { - MODE_STREAM, - }; - //FTP::Mode enumeration - - enum Structure { - STRU_FILE, STRU_RECORD, - }; - //FTP::Structure enumeration - - enum Type { - TYPE_ASCII_NONPRINT, TYPE_IMAGE_NONPRINT, - }; - //FTP::Type enumeration - - enum Commands { - CMD_NOCMD, - CMD_NOOP, - CMD_USER, - CMD_PASS, - CMD_QUIT, - CMD_PORT, - CMD_RETR, - CMD_STOR, - CMD_TYPE, - CMD_MODE, - CMD_STRU, - CMD_EPSV, - CMD_PASV, - CMD_LIST, - CMD_PWD, - CMD_CWD, - CMD_CDUP, - CMD_DELE, - CMD_RMD, - CMD_MKD, - CMD_RNFR, - CMD_RNTO, - }; - //FTP::Commands enumeration - - class User { - public: - User(Socket::Connection NewConnection, std::map Credentials); - ~User(); - int ParseCommand(std::string Command); - bool LoggedIn(); - std::string NumToMsg(int MsgNum); - Socket::Connection Conn; - private: - std::map AllCredentials; - std::string USER; - std::string PASS; - Mode MODE; - Structure STRU; - Type TYPE; - int PORT; - Socket::Server Passive; - int MyPassivePort; - Filesystem::Directory MyDir; - std::string RNFR; - std::vector ActiveStreams; - }; -//FTP::User class - -}//FTP Namespace From 184f7ad6c84b1ff40a4ddaac172e317e85e9a414 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Thu, 16 Apr 2015 12:21:33 +0200 Subject: [PATCH 2/3] Removed old MistInfo binary and dependencies on it. --- CMakeLists.txt | 10 --- src/analysers/info.cpp | 108 -------------------------- src/controller/controller_streams.cpp | 80 +++++++------------ 3 files changed, 28 insertions(+), 170 deletions(-) delete mode 100644 src/analysers/info.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 08a380e2..2aad4e9a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -203,16 +203,6 @@ makeAnalyser(DTSC dtsc) makeAnalyser(AMF amf) makeAnalyser(MP4 mp4) makeAnalyser(OGG ogg) -add_executable(MistInfo - src/analysers/info.cpp -) -target_link_libraries(MistInfo - mist -) -install( - TARGETS MistInfo - DESTINATION bin -) ######################################## # MistServer - Inputs # diff --git a/src/analysers/info.cpp b/src/analysers/info.cpp deleted file mode 100644 index 4b01a9c9..00000000 --- a/src/analysers/info.cpp +++ /dev/null @@ -1,108 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace Info { - int getInfo(int argc, char* argv[]) { - if (argc < 2){ - fprintf( stderr, "Usage: %s \n", argv[0] ); - return 1; - } - DTSC::File F(argv[1]); - JSON::Value fileSpecs = F.getMeta().toJSON(); - if( !fileSpecs ) { - char ** cmd = (char**)malloc(3*sizeof(char*)); - cmd[0] = (char*)"ffprobe"; - cmd[1] = argv[1]; - cmd[2] = NULL; - int outFD = -1; - Util::Procs::StartPiped("FFProbe", cmd, 0, 0, &outFD); - while( Util::Procs::isActive("FFProbe")){ Util::sleep(100); } - FILE * outFile = fdopen( outFD, "r" ); - char * fileBuf = 0; - size_t fileBufLen = 0; - while ( !(feof(outFile) || ferror(outFile)) && (getline(&fileBuf, &fileBufLen, outFile) != -1)){ - std::string line = fileBuf; - if (line.find("Input") != std::string::npos){ - std::string tmp = line.substr(line.find(", ") + 2); - fileSpecs["format"] = tmp.substr(0, tmp.find(",")); - } - if (line.find("Duration") != std::string::npos){ - std::string tmp = line.substr(line.find(": ", line.find("Duration")) + 2); - tmp = tmp.substr(0, tmp.find(",")); - int length = (((atoi(tmp.substr(0,2).c_str()) * 60) + atoi(tmp.substr(3,2).c_str())) * 60) + atoi(tmp.substr(6,2).c_str()); - fileSpecs["length"] = length; - length *= 100; - length += atoi(tmp.substr(9,2).c_str()); - fileSpecs["lastms"] = length * 10; - } - if (line.find("bitrate") != std::string::npos ){ - std::string tmp = line.substr(line.find(": ", line.find("bitrate")) + 2); - fileSpecs["bps"] = atoi(tmp.substr(0, tmp.find(" ")).c_str()) * 128; - } - if (line.find("Stream") != std::string::npos ){ - std::string tmp = line.substr(line.find(" ", line.find("Stream")) + 1); - int strmIdx = fileSpecs["streams"].size(); - int curPos = 0; - curPos = tmp.find(": ", curPos) + 2; - fileSpecs["streams"][strmIdx]["type"] = tmp.substr(curPos, tmp.find(":", curPos) - curPos); - curPos = tmp.find(":", curPos) + 2; - fileSpecs["streams"][strmIdx]["codec"] = tmp.substr(curPos, tmp.find_first_of(", ", curPos) - curPos); - curPos = tmp.find(",", curPos) + 2; - if (fileSpecs["streams"][strmIdx]["type"] == "Video"){ - fileSpecs["streams"][strmIdx]["encoding"] = tmp.substr(curPos, tmp.find(",", curPos) - curPos); - curPos = tmp.find(",", curPos) + 2; - fileSpecs["streams"][strmIdx]["width"] = atoi(tmp.substr(curPos, tmp.find("x", curPos) - curPos).c_str()); - curPos = tmp.find("x", curPos) + 1; - fileSpecs["streams"][strmIdx]["height"] = atoi(tmp.substr(curPos, tmp.find(",", curPos) - curPos).c_str()); - curPos = tmp.find(",", curPos) + 2; - fileSpecs["streams"][strmIdx]["bps"] = atoi(tmp.substr(curPos, tmp.find(" ", curPos) - curPos).c_str()) * 128; - curPos = tmp.find(",", curPos) + 2; - fileSpecs["streams"][strmIdx]["fpks"] = (int)(atof(tmp.substr(curPos, tmp.find(" ", curPos) - curPos).c_str()) * 1000); - fileSpecs["streams"][strmIdx].removeMember( "type" ); - fileSpecs["video"] = fileSpecs["streams"][strmIdx]; - }else if (fileSpecs["streams"][strmIdx]["type"] == "Audio"){ - fileSpecs["streams"][strmIdx]["samplerate"] = atoi(tmp.substr(curPos, tmp.find(" ", curPos) - curPos).c_str()); - curPos = tmp.find(",", curPos) + 2; - if (tmp.substr(curPos, tmp.find(",", curPos) - curPos) == "stereo"){ - fileSpecs["streams"][strmIdx]["channels"] = 2; - }else if (tmp.substr(curPos, tmp.find(",", curPos) - curPos) == "mono"){ - fileSpecs["streams"][strmIdx]["channels"] = 1; - }else{ - fileSpecs["streams"][strmIdx]["channels"] = tmp.substr(curPos, tmp.find(",", curPos) - curPos); - } - curPos = tmp.find(",", curPos) + 2; - fileSpecs["streams"][strmIdx]["samplewidth"] = tmp.substr(curPos, tmp.find(",", curPos) - curPos); - curPos = tmp.find(",", curPos) + 2; - fileSpecs["streams"][strmIdx]["bps"] = atoi(tmp.substr(curPos, tmp.find(" ", curPos) - curPos).c_str()) * 128; - fileSpecs["streams"][strmIdx].removeMember( "type" ); - fileSpecs["audio"] = fileSpecs["streams"][strmIdx]; - } - } - } - fclose( outFile ); - fileSpecs.removeMember( "streams" ); - } else { - fileSpecs["format"] = "dtsc"; - JSON::Value tracks = fileSpecs["tracks"]; - for(JSON::ObjIter trackIt = tracks.ObjBegin(); trackIt != tracks.ObjEnd(); trackIt++){ - fileSpecs["tracks"][trackIt->first].removeMember("fragments"); - fileSpecs["tracks"][trackIt->first].removeMember("keys"); - fileSpecs["tracks"][trackIt->first].removeMember("keysizes"); - fileSpecs["tracks"][trackIt->first].removeMember("parts"); - } - } - printf( "%s", fileSpecs.toString().c_str() ); - return 0; - } -} - -int main(int argc, char* argv[]) { - return Info::getInfo(argc, argv); -} diff --git a/src/controller/controller_streams.cpp b/src/controller/controller_streams.cpp index 3ea14fc2..f7d42e20 100644 --- a/src/controller/controller_streams.cpp +++ b/src/controller/controller_streams.cpp @@ -125,60 +125,35 @@ namespace Controller { // if the file isn't dtsc and there's no dtsh file, run getStream on it // this guarantees that if the stream is playable, it now has a valid header. DEBUG_MSG(DLVL_INSANE, "(re)loading metadata for stream %s", name.c_str()); - if ((URL.substr(URL.size() - 5) != ".dtsc") && (stat((URL+".dtsh").c_str(), &fileinfo) != 0)){ - DEBUG_MSG(DLVL_INSANE, "Stream %s is non-DTSC file without DTSH. Opening stream to generate DTSH...", name.c_str()); - Util::startInput(name); - DEBUG_MSG(DLVL_INSANE, "Waiting for stream %s to open...", name.c_str()); - //wait for the stream - { - char streamPageName[NAME_BUFFER_SIZE]; - snprintf(streamPageName, NAME_BUFFER_SIZE, SHM_STREAM_INDEX, name.c_str()); - IPC::sharedPage streamIndex(streamPageName, DEFAULT_META_PAGE_SIZE, false, false); - if (!streamIndex.mapped){ - DEBUG_MSG(DLVL_INSANE, "Stream %s opening failed! Cancelling and marking as corrupt.", name.c_str()); - data["meta"].null(); - data["meta"]["tracks"].null(); - data["error"] = "Stream offline: Corrupt file?"; - if (data["error"].asStringRef() != prevState){ - Log("WARN", "Source file " + URL + " seems to be corrupt."); - } - data["online"] = 0; - return; + Util::startInput(name); + DEBUG_MSG(DLVL_INSANE, "Waiting for stream %s to open...", name.c_str()); + //wait for the stream + { + char streamPageName[NAME_BUFFER_SIZE]; + snprintf(streamPageName, NAME_BUFFER_SIZE, SHM_STREAM_INDEX, name.c_str()); + IPC::sharedPage streamIndex(streamPageName, DEFAULT_META_PAGE_SIZE, false, false); + if (!streamIndex.mapped){ + DEBUG_MSG(DLVL_INSANE, "Stream %s opening failed! Cancelling and marking as corrupt.", name.c_str()); + data["meta"].null(); + data["meta"]["tracks"].null(); + data["error"] = "Stream offline: Corrupt file?"; + if (data["error"].asStringRef() != prevState){ + Log("WARN", "Source file " + URL + " seems to be corrupt."); } - unsigned int i = 0; - JSON::fromDTMI((const unsigned char*)streamIndex.mapped + 8, streamIndex.len - 8, i, data["meta"]); - if (data["meta"].isMember("tracks") && data["meta"]["tracks"].size()){ - for(JSON::ObjIter trackIt = data["meta"]["tracks"].ObjBegin(); trackIt != data["meta"]["tracks"].ObjEnd(); trackIt++){ - trackIt->second.removeMember("fragments"); - trackIt->second.removeMember("keys"); - trackIt->second.removeMember("keysizes"); - trackIt->second.removeMember("parts"); - trackIt->second.removeMember("ivecs");/*LTS*/ - } - } - if ( !data["meta"] || !data["meta"].isMember("tracks") || !data["meta"]["tracks"]){ - data["error"] = "Stream offline: Corrupt file?"; - if (data["error"].asStringRef() != prevState){ - Log("WARN", "Source file " + URL + " seems to be corrupt."); - } - data["online"] = 0; - return; - } - DEBUG_MSG(DLVL_INSANE, "Metadata for stream %s (re)loaded", name.c_str()); + data["online"] = 0; + return; } - DEBUG_MSG(DLVL_INSANE, "Stream %s opened", name.c_str()); - }else{ - //now, run mistinfo on the source - or on the accompanying dtsh file, if it exists - if (stat((URL+".dtsh").c_str(), &fileinfo) == 0){ - DEBUG_MSG(DLVL_INSANE, "Stream %s has a DTSH - opening DTSH instead of main stream file", name.c_str()); - URL += ".dtsh"; + unsigned int i = 0; + JSON::fromDTMI((const unsigned char*)streamIndex.mapped + 8, streamIndex.len - 8, i, data["meta"]); + if (data["meta"].isMember("tracks") && data["meta"]["tracks"].size()){ + for(JSON::ObjIter trackIt = data["meta"]["tracks"].ObjBegin(); trackIt != data["meta"]["tracks"].ObjEnd(); trackIt++){ + trackIt->second.removeMember("fragments"); + trackIt->second.removeMember("keys"); + trackIt->second.removeMember("keysizes"); + trackIt->second.removeMember("parts"); + trackIt->second.removeMember("ivecs"); + } } - char * tmp_cmd[3] = {0, 0, 0}; - std::string mistinfo = Util::getMyPath() + "MistInfo"; - tmp_cmd[0] = (char*)mistinfo.c_str(); - tmp_cmd[1] = (char*)URL.c_str(); - DEBUG_MSG(DLVL_INSANE, "Running MistInfo for stream %s on file %s", name.c_str(), tmp_cmd[1]); - data["meta"] = JSON::fromString(Util::Procs::getOutputOf(tmp_cmd)); if ( !data["meta"] || !data["meta"].isMember("tracks") || !data["meta"]["tracks"]){ data["error"] = "Stream offline: Corrupt file?"; if (data["error"].asStringRef() != prevState){ @@ -187,8 +162,9 @@ namespace Controller { data["online"] = 0; return; } - DEBUG_MSG(DLVL_INSANE, "Metadata for stream %s succesfully (re)loaded", name.c_str()); + DEBUG_MSG(DLVL_INSANE, "Metadata for stream %s (re)loaded", name.c_str()); } + DEBUG_MSG(DLVL_INSANE, "Stream %s opened", name.c_str()); } if (!hasViewers(name)){ if ( !data.isMember("error")){ From 243a05c8af9457ad5a71d2fc4742d8f8d2db238b Mon Sep 17 00:00:00 2001 From: Thulinma Date: Thu, 16 Apr 2015 12:23:03 +0200 Subject: [PATCH 3/3] Removed unused code from procs library, updated and simplified connector handler in controller. --- lib/procs.cpp | 400 +---------------------- lib/procs.h | 21 +- lib/shared_memory.cpp | 6 +- src/controller/controller_connectors.cpp | 68 ++-- 4 files changed, 56 insertions(+), 439 deletions(-) diff --git a/lib/procs.cpp b/lib/procs.cpp index 8bec4a33..9d51b3d4 100644 --- a/lib/procs.cpp +++ b/lib/procs.cpp @@ -21,8 +21,7 @@ #include #include "timing.h" -std::map Util::Procs::plist; -std::map Util::Procs::exitHandlers; +std::set Util::Procs::plist; bool Util::Procs::handler_set = false; @@ -39,7 +38,7 @@ static bool childRunning(pid_t p) { } /// sends sig 0 to process (pid). returns true if process is running -bool Util::Procs::isRunnning(pid_t pid){ +bool Util::Procs::isRunning(pid_t pid){ return !kill(pid, 0); } @@ -49,8 +48,8 @@ bool Util::Procs::isRunnning(pid_t pid){ /// all remaining children. Waits one more second for cleanup to finish, then exits. void Util::Procs::exit_handler() { int waiting = 0; - std::map listcopy = plist; - std::map::iterator it; + std::set listcopy = plist; + std::set::iterator it; if (listcopy.empty()) { return; } @@ -58,7 +57,7 @@ void Util::Procs::exit_handler() { //wait up to 0.5 second for applications to shut down while (!listcopy.empty() && waiting <= 25) { for (it = listcopy.begin(); it != listcopy.end(); it++) { - if (!childRunning((*it).first)) { + if (!childRunning(*it)) { listcopy.erase(it); break; } @@ -76,8 +75,8 @@ void Util::Procs::exit_handler() { //send sigint to all remaining if (!listcopy.empty()) { for (it = listcopy.begin(); it != listcopy.end(); it++) { - DEBUG_MSG(DLVL_DEVEL, "SIGINT %d: %s", (*it).first, (*it).second.c_str()); - kill((*it).first, SIGINT); + DEBUG_MSG(DLVL_DEVEL, "SIGINT %d", *it); + kill(*it, SIGINT); } } @@ -86,7 +85,7 @@ void Util::Procs::exit_handler() { //wait up to 5 seconds for applications to shut down while (!listcopy.empty() && waiting <= 250) { for (it = listcopy.begin(); it != listcopy.end(); it++) { - if (!childRunning((*it).first)) { + if (!childRunning(*it)) { listcopy.erase(it); break; } @@ -104,8 +103,8 @@ void Util::Procs::exit_handler() { //send sigkill to all remaining if (!listcopy.empty()) { for (it = listcopy.begin(); it != listcopy.end(); it++) { - DEBUG_MSG(DLVL_DEVEL, "SIGKILL %d: %s", (*it).first, (*it).second.c_str()); - kill((*it).first, SIGKILL); + DEBUG_MSG(DLVL_DEVEL, "SIGKILL %d", *it); + kill(*it, SIGKILL); } } @@ -114,7 +113,7 @@ void Util::Procs::exit_handler() { //wait up to 1 second for applications to shut down while (!listcopy.empty() && waiting <= 50) { for (it = listcopy.begin(); it != listcopy.end(); it++) { - if (!childRunning((*it).first)) { + if (!childRunning(*it)) { listcopy.erase(it); break; } @@ -170,23 +169,15 @@ void Util::Procs::childsig_handler(int signum) { return; } -#if DEBUG >= DLVL_HIGH - std::string pname = plist[ret]; -#endif plist.erase(ret); #if DEBUG >= DLVL_HIGH if (!isActive(pname)) { - DEBUG_MSG(DLVL_HIGH, "Process %s fully terminated", pname.c_str()); + DEBUG_MSG(DLVL_HIGH, "Process %d fully terminated", ret); } else { DEBUG_MSG(DLVL_HIGH, "Child process %d exited", ret); } #endif - if (exitHandlers.count(ret) > 0) { - TerminationNotifier tn = exitHandlers[ret]; - exitHandlers.erase(ret); - tn(ret, exitcode); - } } } @@ -195,8 +186,8 @@ void Util::Procs::childsig_handler(int signum) { std::string Util::Procs::getOutputOf(char * const * argv) { std::string ret; int fin = 0, fout = -1, ferr = 0; - StartPiped("output_getter", argv, &fin, &fout, &ferr); - while (isActive("output_getter")) { + pid_t myProc = StartPiped(argv, &fin, &fout, &ferr); + while (isActive(myProc)) { Util::sleep(100); } FILE * outFile = fdopen(fout, "r"); @@ -210,258 +201,12 @@ std::string Util::Procs::getOutputOf(char * const * argv) { return ret; } -/// Runs the given command and returns the stdout output as a string. -std::string Util::Procs::getOutputOf(std::string cmd) { - std::string ret; - int fin = 0, fout = -1, ferr = 0; - StartPiped("output_getter", cmd, &fin, &fout, &ferr); - while (isActive("output_getter")) { - Util::sleep(100); - } - FILE * outFile = fdopen(fout, "r"); - char * fileBuf = 0; - size_t fileBufLen = 0; - while (!(feof(outFile) || ferror(outFile)) && (getline(&fileBuf, &fileBufLen, outFile) != -1)) { - ret += fileBuf; - } - free(fileBuf); - fclose(outFile); - return ret; -} - - -/// Attempts to run the command cmd. -/// Replaces the current process - use after forking first! -/// This function will never return - it will either run the given -/// command or kill itself with return code 42. -void Util::Procs::runCmd(std::string & cmd) { - //split cmd into arguments - //supports a maximum of 20 arguments - char * tmp = (char *)cmd.c_str(); - char * tmp2 = 0; - char * args[21]; - int i = 0; - tmp2 = strtok(tmp, " "); - args[0] = tmp2; - while (tmp2 != 0 && (i < 20)) { - tmp2 = strtok(0, " "); - ++i; - args[i] = tmp2; - } - if (i == 20) { - args[20] = 0; - } - //execute the command - execvp(args[0], args); - DEBUG_MSG(DLVL_ERROR, "Error running %s: %s", cmd.c_str(), strerror(errno)); - _exit(42); -} - -/// Starts a new process if the name is not already active. -/// \return 0 if process was not started, process PID otherwise. -/// \arg name Name for this process - only used internally. -/// \arg cmd Commandline for this process. -pid_t Util::Procs::Start(std::string name, std::string cmd) { - if (isActive(name)) { - return getPid(name); - } - setHandler(); - pid_t ret = fork(); - if (ret == 0) { - runCmd(cmd); - } else { - if (ret > 0) { - DEBUG_MSG(DLVL_HIGH, "Process %s started, PID %d: %s", name.c_str(), ret, cmd.c_str()); - plist.insert(std::pair(ret, name)); - } else { - DEBUG_MSG(DLVL_ERROR, "Process %s could not be started: fork() failed", name.c_str()); - return 0; - } - } - return ret; -} - -/// Starts two piped processes if the name is not already active. -/// \return 0 if process was not started, sub (sending) process PID otherwise. -/// \arg name Name for this process - only used internally. -/// \arg cmd Commandline for sub (sending) process. -/// \arg cmd2 Commandline for main (receiving) process. -pid_t Util::Procs::Start(std::string name, std::string cmd, std::string cmd2) { - if (isActive(name)) { - return getPid(name); - } - setHandler(); - int pfildes[2]; - if (pipe(pfildes) == -1) { - DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. Pipe creation failed.", name.c_str()); - return 0; - } - - int devnull = open("/dev/null", O_RDWR); - pid_t ret = fork(); - if (ret == 0) { - close(pfildes[0]); - dup2(pfildes[1], STDOUT_FILENO); - close(pfildes[1]); - dup2(devnull, STDIN_FILENO); - dup2(devnull, STDERR_FILENO); - runCmd(cmd); - } else { - if (ret > 0) { - plist.insert(std::pair(ret, name)); - } else { - DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. fork() failed.", name.c_str()); - close(pfildes[1]); - close(pfildes[0]); - return 0; - } - } - - pid_t ret2 = fork(); - if (ret2 == 0) { - close(pfildes[1]); - dup2(pfildes[0], STDIN_FILENO); - close(pfildes[0]); - dup2(devnull, STDOUT_FILENO); - dup2(devnull, STDERR_FILENO); - runCmd(cmd2); - } else { - if (ret2 > 0) { - DEBUG_MSG(DLVL_HIGH, "Process %s started, PIDs (%d, %d): %s | %s", name.c_str(), ret, ret2, cmd.c_str(), cmd2.c_str()); - plist.insert(std::pair(ret2, name)); - } else { - DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. fork() failed.", name.c_str()); - Stop(name); - close(pfildes[1]); - close(pfildes[0]); - return 0; - } - } - close(pfildes[1]); - close(pfildes[0]); - return ret; -} - -/// Starts three piped processes if the name is not already active. -/// \return 0 if process was not started, sub (sending) process PID otherwise. -/// \arg name Name for this process - only used internally. -/// \arg cmd Commandline for sub (sending) process. -/// \arg cmd2 Commandline for sub (middle) process. -/// \arg cmd3 Commandline for main (receiving) process. -pid_t Util::Procs::Start(std::string name, std::string cmd, std::string cmd2, std::string cmd3) { - if (isActive(name)) { - return getPid(name); - } - setHandler(); - int pfildes[2]; - int pfildes2[2]; - if (pipe(pfildes) == -1) { - DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. Pipe creation failed.", name.c_str()); - return 0; - } - if (pipe(pfildes2) == -1) { - DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. Pipe creation failed.", name.c_str()); - return 0; - } - - int devnull = open("/dev/null", O_RDWR); - pid_t ret = fork(); - if (ret == 0) { - close(pfildes[0]); - dup2(pfildes[1], STDOUT_FILENO); - close(pfildes[1]); - dup2(devnull, STDIN_FILENO); - dup2(devnull, STDERR_FILENO); - close(pfildes2[1]); - close(pfildes2[0]); - runCmd(cmd); - } else { - if (ret > 0) { - plist.insert(std::pair(ret, name)); - } else { - DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. fork() failed.", name.c_str()); - close(pfildes[1]); - close(pfildes[0]); - close(pfildes2[1]); - close(pfildes2[0]); - return 0; - } - } - - pid_t ret2 = fork(); - if (ret2 == 0) { - close(pfildes[1]); - close(pfildes2[0]); - dup2(pfildes[0], STDIN_FILENO); - close(pfildes[0]); - dup2(pfildes2[1], STDOUT_FILENO); - close(pfildes2[1]); - dup2(devnull, STDERR_FILENO); - runCmd(cmd2); - } else { - if (ret2 > 0) { - DEBUG_MSG(DLVL_HIGH, "Process %s started, PIDs (%d, %d): %s | %s", name.c_str(), ret, ret2, cmd.c_str(), cmd2.c_str()); - plist.insert(std::pair(ret2, name)); - } else { - DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. fork() failed.", name.c_str()); - Stop(name); - close(pfildes[1]); - close(pfildes[0]); - close(pfildes2[1]); - close(pfildes2[0]); - return 0; - } - } - close(pfildes[1]); - close(pfildes[0]); - - pid_t ret3 = fork(); - if (ret3 == 0) { - close(pfildes[1]); - close(pfildes[0]); - close(pfildes2[1]); - dup2(pfildes2[0], STDIN_FILENO); - close(pfildes2[0]); - dup2(devnull, STDOUT_FILENO); - dup2(devnull, STDERR_FILENO); - runCmd(cmd3); - } else { - if (ret3 > 0) { - DEBUG_MSG(DLVL_HIGH, "Process %s started, PIDs (%d, %d, %d): %s | %s | %s", name.c_str(), ret, ret2, ret3, cmd.c_str(), cmd2.c_str(), cmd3.c_str()); - plist.insert(std::pair(ret3, name)); - } else { - DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. fork() failed.", name.c_str()); - Stop(name); - close(pfildes[1]); - close(pfildes[0]); - close(pfildes2[1]); - close(pfildes2[0]); - return 0; - } - } - - return ret3; -} - /// Starts a new process with given fds if the name is not already active. /// \return 0 if process was not started, process PID otherwise. -/// \arg name Name for this process - only used internally. /// \arg argv Command for this process. /// \arg fdin Standard input file descriptor. If null, /dev/null is assumed. Otherwise, if arg contains -1, a new fd is automatically allocated and written into this arg. Then the arg will be used as fd. /// \arg fdout Same as fdin, but for stdout. /// \arg fdout Same as fdin, but for stderr. -pid_t Util::Procs::StartPiped(std::string name, char * const * argv, int * fdin, int * fdout, int * fderr) { - if (isActive(name)) { - DEBUG_MSG(DLVL_WARN, "Process %s already active - skipping start", name.c_str()); - return getPid(name); - } - int pidtemp = StartPiped(argv, fdin, fdout, fderr); - if (pidtemp > 0) { - plist.insert(std::pair(pidtemp, name)); - } - return pidtemp; -} - pid_t Util::Procs::StartPiped(char * const * argv, int * fdin, int * fdout, int * fderr) { pid_t pid; int pipein[2], pipeout[2], pipeerr[2]; @@ -574,6 +319,7 @@ pid_t Util::Procs::StartPiped(char * const * argv, int * fdin, int * fdout, int } return 0; } else { //parent + plist.insert(pid); DEBUG_MSG(DLVL_HIGH, "Piped process %s started, PID %d", argv[0], pid); if (devnull != -1) { close(devnull); @@ -594,70 +340,6 @@ pid_t Util::Procs::StartPiped(char * const * argv, int * fdin, int * fdout, int return pid; } -/// Starts a new process with given fds if the name is not already active. -/// \return 0 if process was not started, process PID otherwise. -/// \arg name Name for this process - only used internally. -/// \arg cmd Command for this process. -/// \arg fdin Standard input file descriptor. If null, /dev/null is assumed. Otherwise, if arg contains -1, a new fd is automatically allocated and written into this arg. Then the arg will be used as fd. -/// \arg fdout Same as fdin, but for stdout. -/// \arg fdout Same as fdin, but for stderr. -pid_t Util::Procs::StartPiped(std::string name, std::string cmd, int * fdin, int * fdout, int * fderr) { - //Convert the given command to a char * [] - char * tmp = (char *)cmd.c_str(); - char * tmp2 = 0; - char * args[21]; - int i = 0; - tmp2 = strtok(tmp, " "); - args[0] = tmp2; - while (tmp2 != 0 && (i < 20)) { - tmp2 = strtok(0, " "); - ++i; - args[i] = tmp2; - } - if (i == 20) { - args[20] = 0; - } - return StartPiped(name, args, fdin, fdout, fderr); -} - - -pid_t Util::Procs::StartPiped2(std::string name, std::string cmd1, std::string cmd2, int * fdin, int * fdout, int * fderr1, int * fderr2) { - int pfildes[2]; - if (pipe(pfildes) == -1) { - DEBUG_MSG(DLVL_ERROR, "Pipe creation failed for process %s", name.c_str()); - return 0; - } - pid_t res1 = StartPiped(name, cmd1, fdin, &pfildes[1], fderr1); - if (!res1) { - close(pfildes[1]); - close(pfildes[0]); - return 0; - } - pid_t res2 = StartPiped(name + "receiving", cmd2, &pfildes[0], fdout, fderr2); - if (!res2) { - Stop(res1); - close(pfildes[1]); - close(pfildes[0]); - return 0; - } - //we can close these because the fork in StartPiped() copies them. - close(pfildes[1]); - close(pfildes[0]); - return res1; -} -/// Stops the named process, if running. -/// \arg name (Internal) name of process to stop -void Util::Procs::Stop(std::string name) { - int max = 5; - while (isActive(name)) { - Stop(getPid(name)); - max--; - if (max <= 0) { - return; - } - } -} - /// Stops the process with this pid, if running. /// \arg name The PID of the process to stop. void Util::Procs::Stop(pid_t name) { @@ -672,10 +354,10 @@ void Util::Procs::Murder(pid_t name) { /// (Attempts to) stop all running child processes. void Util::Procs::StopAll() { - std::map listcopy = plist; - std::map::iterator it; + std::set listcopy = plist; + std::set::iterator it; for (it = listcopy.begin(); it != listcopy.end(); it++) { - Stop((*it).first); + Stop(*it); } } @@ -684,54 +366,8 @@ int Util::Procs::Count() { return plist.size(); } -/// Returns true if a process by this name is currently active. -bool Util::Procs::isActive(std::string name) { - std::map listcopy = plist; - std::map::iterator it; - for (it = listcopy.begin(); it != listcopy.end(); it++) { - if ((*it).second == name) { - if (childRunning((*it).first)) { - return true; - } else { - plist.erase((*it).first); - } - } - } - return false; -} - /// Returns true if a process with this PID is currently active. bool Util::Procs::isActive(pid_t name) { return (plist.count(name) == 1) && (kill(name, 0) == 0); } -/// Gets PID for this named process, if active. -/// \return NULL if not active, process PID otherwise. -pid_t Util::Procs::getPid(std::string name) { - std::map::iterator it; - for (it = plist.begin(); it != plist.end(); it++) { - if ((*it).second == name) { - return (*it).first; - } - } - return 0; -} - -/// Gets name for this process PID, if active. -/// \return Empty string if not active, name otherwise. -std::string Util::Procs::getName(pid_t name) { - if (plist.count(name) == 1) { - return plist[name]; - } - return ""; -} - -/// Registers one notifier function for when a process indentified by PID terminates. -/// \return true if the notifier could be registered, false otherwise. -bool Util::Procs::SetTerminationNotifier(pid_t pid, TerminationNotifier notifier) { - if (plist.find(pid) != plist.end()) { - exitHandlers[pid] = notifier; - return true; - } - return false; -} diff --git a/lib/procs.h b/lib/procs.h index 4a90e233..4a06c5f0 100644 --- a/lib/procs.h +++ b/lib/procs.h @@ -4,19 +4,16 @@ #pragma once #include #include -#include +#include #include /// Contains utility code, not directly related to streaming media namespace Util { - typedef void (*TerminationNotifier)(pid_t pid, int exitCode); - /// Deals with spawning, monitoring and stopping child processes class Procs { private: - static std::map plist; ///< Holds active processes - static std::map exitHandlers; ///< termination function, if any + static std::set plist; ///< Holds active processes static bool handler_set; ///< If true, the sigchld handler has been setup. static void childsig_handler(int signum); static void exit_handler(); @@ -24,25 +21,13 @@ namespace Util { static void setHandler(); public: static std::string getOutputOf(char * const * argv); - static std::string getOutputOf(std::string cmd); - static pid_t Start(std::string name, std::string cmd); - static pid_t Start(std::string name, std::string cmd, std::string cmd2); - static pid_t Start(std::string name, std::string cmd, std::string cmd2, std::string cmd3); static pid_t StartPiped(char * const * argv, int * fdin, int * fdout, int * fderr); - static pid_t StartPiped(std::string name, char * const * argv, int * fdin, int * fdout, int * fderr); - static pid_t StartPiped(std::string name, std::string cmd, int * fdin, int * fdout, int * fderr); - static pid_t StartPiped2(std::string name, std::string cmd1, std::string cmd2, int * fdin, int * fdout, int * fderr1, int * fderr2); - static void Stop(std::string name); static void Stop(pid_t name); static void Murder(pid_t name); static void StopAll(); static int Count(); - static bool isActive(std::string name); static bool isActive(pid_t name); - static bool isRunnning(pid_t pid); - static pid_t getPid(std::string name); - static std::string getName(pid_t name); - static bool SetTerminationNotifier(pid_t pid, TerminationNotifier notifier); + static bool isRunning(pid_t pid); }; } diff --git a/lib/shared_memory.cpp b/lib/shared_memory.cpp index 42d48cf4..73c2d667 100644 --- a/lib/shared_memory.cpp +++ b/lib/shared_memory.cpp @@ -305,12 +305,12 @@ namespace IPC { } while (i < 10 && !handle && autoBackoff); } if (!handle) { - FAIL_MSG("%s for page %s failed: %s", (master ? "CreateFileMapping" : "OpenFileMapping"), name.c_str(), strerror(errno)); + FAIL_MSG("%s for page %s failed with error code %u", (master ? "CreateFileMapping" : "OpenFileMapping"), name.c_str(), GetLastError()); return; } mapped = (char *)MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (!mapped) { - FAIL_MSG("MapViewOfFile for page %s failed: %s", name.c_str(), strerror(errno)); + FAIL_MSG("MapViewOfFile for page %s failed with error code %u", name.c_str(), GetLastError()); return; } //Under cygwin, the extra 4 bytes contain the real size of the page. @@ -740,7 +740,7 @@ namespace IPC { DEBUG_MSG(DLVL_VERYHIGH, "Shared memory %s is now at count %u", baseName.c_str(), amount); } unsigned short tmpPID = *((unsigned short *)(it->mapped+1+offset+payLen-2)); - if(!Util::Procs::isRunnning(tmpPID) && !(*counter == 126 || *counter == 127 || *counter == 254 || *counter == 255)){ + if(!Util::Procs::isRunning(tmpPID) && !(*counter == 126 || *counter == 127 || *counter == 254 || *counter == 255)){ WARN_MSG("process disappeared, timing out. (pid %d)", tmpPID); *counter = 126; //if process is already dead, instant timeout. } diff --git a/src/controller/controller_connectors.cpp b/src/controller/controller_connectors.cpp index 191cbcd9..a1e8faa9 100644 --- a/src/controller/controller_connectors.cpp +++ b/src/controller/controller_connectors.cpp @@ -18,21 +18,16 @@ ///\brief Holds everything unique to the controller. namespace Controller { - static std::map currentConnectors; /// currentConnectors; ///::iterator iter; + std::map::iterator iter; for (iter = currentConnectors.begin(); iter != currentConnectors.end(); iter++){ - if (iter->second.substr(0, protocol.size()) == protocol){ - Log("CONF", "Killing connector for update: " + iter->second); - Util::Procs::Stop(toConn(iter->first)); + if (iter->first.substr(0, protocol.size()) == protocol){ + Log("CONF", "Killing connector for update: " + iter->first); + Util::Procs::Stop(iter->second); } } } @@ -65,7 +60,8 @@ namespace Controller { } } - static inline void buildPipedArguments(JSON::Value & p, char * argarr[], JSON::Value & capabilities){ + static inline void buildPipedArguments(const std::string & proto, char * argarr[], JSON::Value & capabilities){ + JSON::Value p = JSON::fromString(proto); int argnum = 0; static std::string tmparg; tmparg = Util::getMyPath() + std::string("MistOut") + p["connector"].asStringRef(); @@ -82,12 +78,11 @@ namespace Controller { if (pipedCapa.isMember("optional")){builPipedPart(p, argarr, argnum, pipedCapa["optional"]);} } - ///\brief Checks current protocol coguration, updates state of enabled connectors if neccesary. + ///\brief Checks current protocol configuration, updates state of enabled connectors if neccessary. ///\param p An object containing all protocols. ///\param capabilities An object containing the detected capabilities. void CheckProtocols(JSON::Value & p, JSON::Value & capabilities){ - std::map new_connectors; - std::map::iterator iter; + std::set runningConns; // used for building args int zero = 0; @@ -102,12 +97,13 @@ namespace Controller { for (JSON::ArrIter ait = p.ArrBegin(); ait != p.ArrEnd(); ait++){ counter = ait - p.ArrBegin(); std::string prevOnline = ( *ait)["online"].asString(); - #define connName (*ait)["connector"].asStringRef() + const std::string & connName = (*ait)["connector"].asStringRef(); + //do not further parse if there's no connector name if ( !(*ait).isMember("connector") || connName == ""){ ( *ait)["online"] = "Missing connector name"; continue; } - + //ignore connectors that are not installed if ( !capabilities["connectors"].isMember(connName)){ ( *ait)["online"] = "Not installed"; if (( *ait)["online"].asString() != prevOnline){ @@ -115,14 +111,13 @@ namespace Controller { } continue; } - - #define connCapa capabilities["connectors"][connName] - + //list connectors that go through HTTP as 'enabled' without actually running them. + JSON::Value & connCapa = capabilities["connectors"][connName]; if (connCapa.isMember("socket") || (connCapa.isMember("deps") && connCapa["deps"].asStringRef() == "HTTP")){ ( *ait)["online"] = "Enabled"; continue; } - + //check required parameters, skip if anything is missing if (connCapa.isMember("required")){ bool gotAll = true; for (JSON::ObjIter it = connCapa["required"].ObjBegin(); it != connCapa["required"].ObjEnd(); ++it){ @@ -137,12 +132,13 @@ namespace Controller { } if (!gotAll){continue;} } - + //remove current online status ( *ait).removeMember("online"); /// \todo Check dependencies? - - new_connectors[counter] = (*ait).toString(); - if (Util::Procs::isActive(toConn(counter))){ + //set current online status + std::string myCmd = (*ait).toString(); + runningConns.insert(myCmd); + if (currentConnectors.count(myCmd) && Util::Procs::isActive(currentConnectors[myCmd])){ ( *ait)["online"] = 1; }else{ ( *ait)["online"] = 0; @@ -150,28 +146,28 @@ namespace Controller { } //shut down deleted/changed connectors - for (iter = currentConnectors.begin(); iter != currentConnectors.end(); iter++){ - if (new_connectors.count(iter->first) != 1 || new_connectors[iter->first] != iter->second){ - Log("CONF", "Stopping connector " + iter->second); - Util::Procs::Stop(toConn(iter->first)); + std::map::iterator it; + for (it = currentConnectors.begin(); it != currentConnectors.end(); it++){ + if (!runningConns.count(it->first)){ + Log("CONF", "Stopping connector " + it->first); + Util::Procs::Stop(it->second); } } //start up new/changed connectors - for (iter = new_connectors.begin(); iter != new_connectors.end(); iter++){ - if (currentConnectors.count(iter->first) != 1 || currentConnectors[iter->first] != iter->second || !Util::Procs::isActive(toConn(iter->first))){ - Log("CONF", "Starting connector: " + iter->second); + while (runningConns.size() && conf.is_active){ + if (!currentConnectors.count(*runningConns.begin()) || !Util::Procs::isActive(currentConnectors[*runningConns.begin()])){ + Log("CONF", "Starting connector: " + *runningConns.begin()); // clear out old args for (i=0; i<15; i++){argarr[i] = 0;} // get args for this connector - buildPipedArguments(p[(long long unsigned)iter->first], (char **)&argarr, capabilities); + buildPipedArguments(*runningConns.begin(), (char **)&argarr, capabilities); // start piped w/ generated args - Util::Procs::StartPiped(toConn(iter->first), argarr, &zero, &out, &err);//redirects output to out. Must make a new pipe, redirect std err + currentConnectors[*runningConns.begin()] = Util::Procs::StartPiped(argarr, &zero, &out, &err); } + runningConns.erase(runningConns.begin()); } - - //store new state - currentConnectors = new_connectors; } } +