/* * Fork and run an event script */ int RunEventScript(FPPevent *e) { pid_t pid = 0; char userScript[1024]; char eventScript[1024]; // Setup the script from our user strcpy(userScript, getScriptDirectory()); strcat(userScript, "/"); strncat(userScript, e->script, 1024 - strlen(userScript)); userScript[1023] = '\0'; // Setup the wrapper memcpy(eventScript, getFPPDirectory(), sizeof(eventScript)); strncat(eventScript, "/scripts/eventScript", sizeof(eventScript)-strlen(eventScript)-1); pid = fork(); if (pid == 0) // Event Script process { #ifndef NOROOT struct sched_param param; param.sched_priority = 0; if (sched_setscheduler(0, SCHED_OTHER, ¶m) != 0) { perror("sched_setscheduler"); exit(EXIT_FAILURE); } #endif ShutdownControlSocket(); char *args[128]; char *token = strtok(userScript, " "); int i = 1; args[0] = strdup(userScript); while (token && i < 126) { args[i] = strdup(token); i++; token = strtok(NULL, " "); } args[i] = NULL; if (chdir(getScriptDirectory())) { LogErr(VB_EVENT, "Unable to change directory to %s: %s\n", getScriptDirectory(), strerror(errno)); exit(EXIT_FAILURE); } execvp(eventScript, args); LogErr(VB_EVENT, "RunEventScript(), ERROR, we shouldn't be here, " "this means that execvp() failed trying to run '%s %s': %s\n", eventScript, args[0], strerror(errno)); exit(EXIT_FAILURE); } return 1; }
void PluginCallbackManager::init() { DIR *dp; struct dirent *ep; dp = opendir(getPluginDirectory()); if (dp != NULL) { while (ep = readdir(dp)) { int location = strstr(ep->d_name,".") - ep->d_name; // We're one of ".", "..", or hidden, so let's skip if ( location == 0 ) continue; LogDebug(VB_PLUGIN, "Found Plugin: (%s)\n", ep->d_name); std::string filename = std::string(getPluginDirectory()) + "/" + ep->d_name + "/callbacks"; bool found = false; if ( FileExists(filename.c_str()) ) { printf("Found callback with no extension"); found = true; } else { std::vector<std::string> extensions; extensions.push_back(std::string(".sh")); extensions.push_back(std::string(".pl")); extensions.push_back(std::string(".php")); extensions.push_back(std::string(".py")); for ( std::vector<std::string>::iterator i = extensions.begin(); i != extensions.end(); ++i) { std::string tmpFilename = filename + *i; if ( FileExists( tmpFilename.c_str() ) ) { filename += *i; found = true; } } } std::string eventScript = std::string(getFPPDirectory()) + "/scripts/eventScript"; if ( !found ) { LogExcess(VB_PLUGIN, "No callbacks supported by plugin: '%s'\n", ep->d_name); continue; } LogDebug(VB_PLUGIN, "Processing Callbacks (%s) for plugin: '%s'\n", filename.c_str(), ep->d_name); int output_pipe[2], pid, bytes_read; char readbuffer[128]; std::string callback_list = ""; if (pipe(output_pipe) == -1) { LogErr(VB_PLUGIN, "Failed to make pipe\n"); exit(EXIT_FAILURE); } if ((pid = fork()) == -1 ) { LogErr(VB_PLUGIN, "Failed to fork\n"); exit(EXIT_FAILURE); } if ( pid == 0 ) { dup2(output_pipe[1], STDOUT_FILENO); close(output_pipe[1]); execl(eventScript.c_str(), "eventScript", filename.c_str(), "--list", NULL); LogErr(VB_PLUGIN, "We failed to exec our callbacks query!\n"); exit(EXIT_FAILURE); } else { close(output_pipe[1]); while (true) { bytes_read = read(output_pipe[0], readbuffer, sizeof(readbuffer)-1); if (bytes_read <= 0) break; readbuffer[bytes_read] = '\0'; callback_list += readbuffer; } boost::trim(callback_list); LogExcess(VB_PLUGIN, "Callback output: (%s)\n", callback_list.c_str()); wait(NULL); } boost::char_separator<char> sep(","); boost::tokenizer< boost::char_separator<char> > tokens(callback_list, sep); BOOST_FOREACH (const std::string& type, tokens) { if (type == "media") { LogDebug(VB_PLUGIN, "Plugin %s supports media callback.\n", ep->d_name); MediaCallback *media = new MediaCallback(std::string(ep->d_name), filename); mCallbacks.push_back(media); } else if (type == "playlist") { LogDebug(VB_PLUGIN, "Plugin %s supports playlist callback.\n", ep->d_name); PlaylistCallback *playlist = new PlaylistCallback(std::string(ep->d_name), filename); mCallbacks.push_back(playlist); } else if (type == "nextplaylist") { LogDebug(VB_PLUGIN, "Plugin %s supports nextplaylist callback.\n", ep->d_name); NextPlaylistEntryCallback *nextplaylistentry = new NextPlaylistEntryCallback(std::string(ep->d_name), filename); mCallbacks.push_back(nextplaylistentry); } else if (type == "event") { LogDebug(VB_PLUGIN, "Plugin %s supports event callback.\n", ep->d_name); EventCallback *eventcallback = new EventCallback(std::string(ep->d_name), filename); mCallbacks.push_back(eventcallback); } } plugin_count += 1; } closedir(dp); } else {