/* * This file part of gsopcast - A gtk front-end of p2p tv sopcast. * http://lianwei3.googlepages.com/home2 * Copyright (C) 2006 Wei Lian * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "socket.h" #include "header.h" #include "channel.h" pid_t pid_sop; pid_t pid_player; pid_t pid_channel; int stdout_pipe[2]; int stdin_pipe[2]; char channels_url[64]; char outport[8]; extern GtkWidget *label_player; extern GtkWidget *entry_player; //xihels@gmail.com extern GtkWidget *entry_inport; extern GtkWidget *entry_outport; //xihels@gmail.com//////// //----------------------------------------------------- /*size_t my_write_func(void *ptr, size_t size, size_t nmemb, FILE * stream) { return write(stdout_pipe[1], ptr, size * nmemb); }*/ //----------------------------------------------------- struct MemoryStruct chunk; //----------------------------------------------------- gboolean handle_stdout_pipe(GIOChannel * source, GIOCondition cond, gpointer d) { GError *error = NULL; // for error handling GIOStatus status; // save the reading status gsize bytes_read; // save the number of chars read if ((status = g_io_channel_read_chars(source, chunk.memory + chunk.size, PER_SIZE, &bytes_read, &error)) == G_IO_STATUS_NORMAL && bytes_read > 0) { chunk.size += bytes_read; chunk.memory[chunk.size] = 0; if (strstr(chunk.memory, "")) { void channel_list_update(char *); channel_list_update(chunk.memory); free(chunk.memory); chunk.memory = NULL; } else chunk.memory = (char *) realloc(chunk.memory, chunk.size + PER_SIZE + 1); } return TRUE; } //----------------------------------------------------- ////////////////////fork new process void fork_channel() { if (chunk.memory) free(chunk.memory); chunk.memory = (char *) malloc(PER_SIZE + 1); chunk.size = 0; pid_t pid; pid = fork(); if (pid == -1) { perror("fork"); pid_channel = -2; exit(-1); } else if (pid == 0) { int fd = open("/dev/null", O_WRONLY); dup2(fd, 2); dup2(stdout_pipe[1], 1); execlp("wget", "wget", channels_url, "-O", "-", NULL); /* CURL *curl = curl_easy_init(); curl_easy_setopt(curl, CURLOPT_URL, channels_url); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_write_func); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); curl_easy_perform(curl); curl_easy_cleanup(curl);*/ _exit(0); } else { // parent pid_channel = pid; } } //----------------------------------------------------- void fork_sop(char *play_url) { //////////setting inport and outport int i, j; char inport[8]; int sock; ///choose inport and outport number //xihels@gmail.com char *line = strdup(gtk_entry_get_text(GTK_ENTRY(entry_inport))); i = atoi(line); free(line); if (i == 0) { //xihels@gmail.com while (1) { i = rand() % (65536 - 3000) + 3000; ////3000 to 65535 sock = connect_to_server("127.0.0.1", i); if (sock == -1) break; else if (sock >= 0) close(sock); } } sprintf(inport, "%d", i); //xihels@gmail.com line = strdup(gtk_entry_get_text(GTK_ENTRY(entry_outport))); j = atoi(line); if (j == 0) { while (1) { j = rand() % (65536 - 3000) + 3000; sock = connect_to_server("127.0.0.1", j); if (sock == -1 && j != i) break; else if (sock >= 0) close(sock); } } sprintf(outport, "%d", j); /////////////////////// pid_t pid; pid = fork(); if (pid == -1) { perror("fork"); // pid_sop = -2; exit(-1); } else if (pid == 0) { int fd = open("/dev/null", O_WRONLY); dup2(fd, 1); execlp("sp-sc", "sp-sc", play_url, inport, outport, NULL); perror("sp-sc"); _exit(-1); } else { // parent pid_sop = pid; } } //----------------------------------------------------- void fork_player() { if (pid_player != -2) return; ///change color GdkColor color; gdk_color_parse("blue", &color); gtk_widget_modify_fg(label_player, GTK_STATE_NORMAL, &color); /////////////////////get player info char *line = strdup(gtk_entry_get_text(GTK_ENTRY(entry_player))); int iter = 0; char *savept; char *playopt[32]; playopt[0] = strtok_r(line, " ,", &savept); while ((playopt[++iter] = strtok_r(NULL, " ,", &savept)) != NULL); char url[32] = "http://127.0.0.1:"; strcat(url, outport); playopt[iter] = url; playopt[++iter] = NULL; ///fork pid_t pid = fork(); if (pid == -1) { perror("fork"); exit(-1); } else if (pid == 0) { /////////////mask the error output int fd = open("/dev/null", O_WRONLY); ///clear remaining data int nread; ioctl(stdin_pipe[0], FIONREAD, &nread); char tmp[8]; while (nread) { int n = read(stdin_pipe[0], tmp, sizeof(tmp)); nread -= n; } //// dup2(stdin_pipe[0], 0); dup2(fd, 1); dup2(fd, 2); /////////////execute command execvp(playopt[0], playopt); perror("player"); _exit(-1); } else { // parent pid_player = pid; free(line); } } ///////kill process //----------------------------------------------------- void kill_sop() { if (pid_sop > 0) { // if (kill ((pid_t) pid_sop, SIGTERM) == -1) ////seems sp-sc can be SIGKILLed without causing any problem kill((pid_t) pid_sop, SIGKILL); } } //----------------------------------------------------- void kill_player() { if (pid_player > 0) { /* int kill_player = kill((pid_t) pid_player, SIGTERM); if (kill_player == -1) kill_player = kill((pid_t) pid_player, SIGKILL);*/ DIR *dir = opendir("/proc"); if (!dir) { fprintf(stderr, "Cannot open /proc\n"); exit(1); } ///loop char playerUrl[64] = "http://127.0.0.1:"; strcat(playerUrl, outport); struct dirent *next; while ((next = readdir(dir)) != NULL) { if (strcmp(next->d_name, "..") == 0) continue; if (!isdigit(*next->d_name)) continue; char filename[64]; snprintf(filename, sizeof(filename), "/proc/%s/cmdline", next->d_name); FILE *status; if (!(status = fopen(filename, "r"))) { continue; } int n; char buffer[256]; if ((n = fread(buffer, 1, sizeof(buffer), status)) == 0) { fclose(status); continue; } fclose(status); ///replace 0 with ' ' while (char *ptr = (char *)memchr(buffer, 0, n - 1)) *ptr = ' '; ///find process pid and kill if (strstr(buffer, playerUrl)) { kill(strtol(next->d_name, NULL, 0), SIGKILL); } } closedir(dir); } }