00001 #include <fcntl.h>
00002 #include <string.h>
00003 #include <errno.h>
00004 #include <signal.h>
00005
00006 #include "defaults.h"
00007 #include "file.h"
00008 #include "guicast.h"
00009 #include "interlacemodes.h"
00010 #include "pipe.h"
00011
00012 extern "C" {
00013 int pipe_sigpipe_received;
00014
00015 void pipe_handle_sigpipe(int signum) {
00016 printf("Received sigpipe\n");
00017 pipe_sigpipe_received++;
00018 }
00019 }
00020
00021 Pipe::Pipe(char *command, char *sub_str, char sub_char) {
00022 this->command = command;
00023 this->sub_str = sub_str;
00024 this->sub_char = sub_char;
00025
00026 complete[0] = '\0';
00027 file = NULL;
00028 fd = -1;
00029
00030
00031 signal(SIGPIPE, pipe_handle_sigpipe);
00032 }
00033
00034 Pipe::~Pipe() {
00035 close();
00036 }
00037
00038 int Pipe::substitute() {
00039 if (command == NULL) {
00040 strcpy(complete, "");
00041 return 0;
00042 }
00043
00044 if (sub_str == NULL || sub_char == '\0') {
00045 strcpy(complete, command);
00046 return 0;
00047 }
00048
00049 int count = 0;
00050 char *c = command;
00051 char *f = complete;
00052 while (*c) {
00053
00054 if (*c != sub_char) {
00055 *f++ = *c++;
00056 continue;
00057 }
00058
00059
00060 c++;
00061
00062
00063 if (*c == sub_char) {
00064 *f++ = *c++;
00065 continue;
00066 }
00067
00068
00069 if (f + strlen(sub_str) - complete > sizeof(complete)) {
00070 printf("Pipe::substitute(): max length exceeded\n");
00071 return -1;
00072 }
00073 strcpy(f, sub_str);
00074 f += strlen(sub_str);
00075 count++;
00076 }
00077
00078 return count;
00079 }
00080
00081
00082
00083 int Pipe::open(char *mode) {
00084 if (file) close();
00085
00086 if (mode == NULL) {
00087 printf("Pipe::open(): no mode given\n");
00088 return 1;
00089 }
00090
00091 if (substitute() < 0) {
00092 return 1;
00093 }
00094
00095 if (complete == NULL || strlen(complete) == 0) {
00096 printf("Pipe::open(): no pipe to open\n");
00097 return 1;
00098 }
00099
00100 printf("trying popen(%s)\n", complete);
00101 file = popen(complete, mode);
00102 if (file != NULL) {
00103 fd = fileno(file);
00104 return 0;
00105 }
00106
00107
00108
00109
00110 printf("Pipe::open(%s,%s) failed: %s\n",
00111 complete, mode, strerror(errno));
00112 return 1;
00113 }
00114
00115 int Pipe::open_read() {
00116 return open("r");
00117 }
00118
00119 int Pipe::open_write() {
00120 return open("w");
00121 }
00122
00123 void Pipe::close() {
00124 pclose(file);
00125 file = 0;
00126 fd = -1;
00127 }
00128
00129
00130 PipeConfig::PipeConfig(BC_WindowBase *window, Defaults *defaults, Asset *asset)
00131 {
00132 this->window = window;
00133 this->defaults = defaults;
00134 this->asset = asset;
00135 }
00136
00137
00138
00139 int PipeConfig::create_objects(int x, int y, int textbox_width, int format) {
00140 int x1 = x;
00141 BC_Title *titlew;
00142
00143 textbox = new BC_TextBox(x + 120, y, textbox_width, 1, asset->pipe);
00144 window->add_subwindow(textbox);
00145 if (! asset->use_pipe) textbox->disable();
00146
00147 window->add_subwindow(new BC_Title(x, y, _("Use Pipe:")));
00148 checkbox = new PipeCheckBox(85, y - 5, asset->use_pipe, textbox);
00149 window->add_subwindow(checkbox);
00150
00151 x += 120;
00152 x += textbox_width;
00153
00154 recent = new BC_RecentList("PIPE", defaults, textbox,
00155 10, x, y, 350, 100);
00156 window->add_subwindow(recent);
00157 recent->load_items(FILE_FORMAT_PREFIX(format));
00158
00159 x = x1;
00160 y += 30;
00161 window->add_subwindow(titlew = new BC_Title(x, y, _("Stream Header:"), MEDIUMFONT, RED));
00162 x = x1 + 10;
00163 y += 30;
00164
00165 window->add_subwindow(new BC_Title(x, y, _("Interlacing:")));
00166 char string[BCTEXTLEN];
00167 ilacemode_to_text(string,asset->interlace_mode);
00168 window->add_subwindow(new BC_Title(x + titlew->get_w() + 5, y, string, MEDIUMFONT, YELLOW));
00169 }
00170
00171 PipeCheckBox::PipeCheckBox(int x, int y, int value, BC_TextBox *textbox)
00172 : BC_CheckBox(x, y, value)
00173 {
00174 this->textbox = textbox;
00175 }
00176 int PipeCheckBox::handle_event() {
00177 if (get_value()) textbox->enable();
00178 else textbox->disable();
00179 }
00180
00181 PipeStatus::PipeStatus(int x, int y, char *default_string)
00182 : BC_Title(x, y, default_string)
00183 {
00184 this->default_string = default_string;
00185 }
00186 int PipeStatus::set_status(Asset *asset) {
00187 if (! asset->use_pipe || ! asset->pipe || ! *(asset->pipe)) {
00188 set_color(BLACK);
00189 sprintf(status, default_string);
00190 }
00191 else {
00192 set_color(RED);
00193 sprintf(status, "| %s", asset->pipe);
00194 }
00195
00196 update(status);
00197 }
00198
00199
00200
00201 PipePreset::PipePreset(int x, int y, char *title, PipeConfig *config)
00202 : BC_PopupMenu(x, y, 150, title)
00203 {
00204 this->config = config;
00205 this->title = title;
00206 }
00207
00208 int PipePreset::handle_event() {
00209 char *text = get_text();
00210
00211 char *pipe = strchr(text, '|');
00212
00213 if (pipe) config->textbox->update(pipe + 1);
00214
00215 config->textbox->enable();
00216 config->checkbox->set_value(1, 1);
00217
00218
00219 set_text(title);
00220 }