/********************************************************************** * * gtiaction.cpp -- * Copyright (C) 2005 The New Zealand Digital Library Project * * A component of the Greenstone digital library software * from the New Zealand Digital Library Project at the * University of Waikato, New Zealand. * * 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 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., 675 Mass Ave, Cambridge, MA 02139, USA. * *********************************************************************/ #include "gsdl_modules_cfg.h" #ifdef GSDL_USE_GTI_ACTION #include #include #include #include "gtiaction.h" #include "fileutil.h" #include "gsdlunicode.h" gtiaction::gtiaction() { cgiarginfo arg_ainfo; arg_ainfo.shortname = "tlc"; arg_ainfo.longname = "translation target language code"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (&cerr, arg_ainfo); arg_ainfo.shortname = "tfk"; arg_ainfo.longname = "translation file key"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (&cerr, arg_ainfo); arg_ainfo.shortname = "ncpp"; arg_ainfo.longname = "number of chunks per page"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = "1"; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (&cerr, arg_ainfo); } gtiaction::~gtiaction() { delete[] set_gsdlhome_cstr; delete[] set_gsdlos_cstr; } bool gtiaction::init (ostream& /*logout*/) { // Set GSDLHOME and GSDLOS environment variables text_t set_gsdlhome = "GSDLHOME=" + gsdlhome; text_t set_gsdlos = "GSDLOS="; #if defined (__WIN32__) set_gsdlos += "windows"; #else struct utsname *buf = new struct utsname(); if (uname(buf) == -1) { // uname failed, so this must be linux set_gsdlos += "linux"; } else { text_t gsdlos = buf->sysname; lc(gsdlos); set_gsdlos += gsdlos; } delete buf; #endif // These will be cleaned up in the destructor set_gsdlhome_cstr = set_gsdlhome.getcstr(); set_gsdlos_cstr = set_gsdlos.getcstr(); putenv(set_gsdlhome_cstr); putenv(set_gsdlos_cstr); return true; } bool gtiaction::check_cgiargs(cgiargsinfoclass& /*argsinfo*/, cgiargsclass& args, recptprotolistclass* /*protos*/, ostream& logout) { // Authenticate the user, except for the "home" and "lang" pages if (args["p"] != "home" && args["p"] != "lang") { args["uan"] = 1; args["ug"] = "langadmin_" + args["tlc"]; } return true; } bool gtiaction::do_action(cgiargsclass& args, recptprotolistclass* /*protos*/, browsermapclass* /*browsers*/, displayclass& disp, outconvertclass& outconvert, ostream& textout, ostream& logout) { textout << outconvert << disp << ("_gti:header_\n") << ("_gti:content_\n") << ("_gti:footer_\n"); return true; } void gtiaction::get_cgihead_info(cgiargsclass& /*args*/, recptprotolistclass* /*protos*/, response_t& response, text_t& response_data, ostream& logout) { response = content; response_data = "text/html"; } void gtiaction::define_internal_macros(displayclass& disp, cgiargsclass& args, recptprotolistclass* protos, ostream& logout) { // logout << endl << "Arguments: " << args << endl; logout << endl << "CGI arg p: " << args["p"] << endl; // For some reason this must be done as well as setting the macro in gti.dm // is that still true?? disp.setmacro("preflink", displayclass::defaultpackage, "_gti:preflink_"); // Define the page content for the GTI home page if (args["p"] == "home") { define_gti_home_page(disp, args, logout); return; } // Define the page content for the GTI language page if (args["p"] == "lang") { define_gti_lang_page(disp, args, logout); return; } // Define the page content for the GTI search page if (args["p"] == "find") { define_gti_find_page(disp, args, logout); return; } // Define the page content for the GTI excel page if (args["p"] == "excel") { define_gti_excel_page(disp, args, logout); return; } // Process user translations if (args["p"] == "submit") { process_gti_submissions(disp, args, logout, true); } // Define the page content for the GTI core pages (containing the translation input forms) define_gti_core_page(disp, args, logout); } void gtiaction::define_gti_home_page(displayclass& disp, cgiargsclass& args, ostream& logout) { disp.setmacro("gtiformcontent", "gti", "_gti:gtihome_"); languageinfo_tmap loaded_languages = recpt->get_configinfo().languages; // Get the languages specified in the main.cfg file, and put them into a map to sort by name text_tmap gti_languages_name_code_mapping; languageinfo_tmap::const_iterator loaded_language = loaded_languages.begin(); while (loaded_language != loaded_languages.end()) { // English is not a valid GTI target language, since it is the source language if (loaded_language->first != "en") { gti_languages_name_code_mapping[loaded_language->second.longname] = loaded_language->first; } ++loaded_language; } // Set the gtitlcselection macro text_t gti_tlc_selection = ""; disp.setmacro("gtitlcselection", "gti", gti_tlc_selection); } void gtiaction::define_gti_lang_page(displayclass& disp, cgiargsclass& args, ostream& logout) { // Get the target language code from the CGI arguments text_t target_language_code = args["tlc"]; disp.setmacro("gtiformcontent", "gti", "_gti:gtilang_"); // Send a request to gti.pl to get the valid translation files text_t gti_arguments = "get-language-status " + target_language_code; GTI_Response gti_response = parse_gti_response(do_gti_request(gti_arguments, logout), logout); if (gti_response.error_message != "") { // An error has occurred disp.setmacro("gtiformcontent", "gti", "_gti:gtierror_"); disp.setmacro("gtierrormessage", "gti", gti_response.error_message); return; } languageinfo_tmap loaded_languages = recpt->get_configinfo().languages; disp.setmacro("gtitargetlanguagename", "gti", loaded_languages[target_language_code].longname); // Set the gtitfkselection macro text_t gti_tfk_selection = ""; text_tmap::iterator translation_file = gti_response.translation_files_index_to_key_mapping.begin(); while (translation_file != gti_response.translation_files_index_to_key_mapping.end()) { text_t translation_file_key = translation_file->second; gti_tfk_selection += "\n"; gti_tfk_selection += "\n"; text_t num_chunks_translated = gti_response.translation_files_key_to_num_chunks_translated_mapping[translation_file_key]; text_t num_chunks_requiring_translation = gti_response.translation_files_key_to_num_chunks_requiring_translation_mapping[translation_file_key]; text_t num_chunks_requiring_updating = gti_response.translation_files_key_to_num_chunks_requiring_updating_mapping[translation_file_key]; gti_tfk_selection += "\n"; ++translation_file; } gti_tfk_selection += "
"; gti_tfk_selection += "_textgti" + translation_file_key + "_
_gtitranslationfilestatus_(" + num_chunks_translated + "," + num_chunks_requiring_translation + "," + num_chunks_requiring_updating + ")
"; disp.setmacro("gtitfkselection", "gti", gti_tfk_selection); } void gtiaction::define_gti_find_page(displayclass& disp, cgiargsclass& args, ostream& logout) { // Get the target language code and file to translate from the CGI arguments text_t target_language_code = args["tlc"]; text_t translation_file_key = args["tfk"]; text_t query_string = to_utf8(args["q"]); // Process user corrections if (args["sp"] != "") { process_gti_submissions(disp, args, logout, false); } disp.setmacro("gtiformcontent", "gti", "_gti:gtifind_"); languageinfo_tmap loaded_languages = recpt->get_configinfo().languages; disp.setmacro("gtitargetlanguagename", "gti", loaded_languages[target_language_code].longname); disp.setmacro("gtitranslationfiledesc", "gti", "_gti:textgti" + translation_file_key + "_"); if (query_string == "") { // No query, so no search results disp.setmacro("gtifindformcontent", "gti", ""); return; } // Display text right to left if target language is Arabic or Farsi or Urdu if (target_language_code == "ar" || target_language_code == "fa" || target_language_code == "ur") { disp.setmacro("gtitextdirection", "gti", "rtl"); } else { disp.setmacro("gtitextdirection", "gti", "ltr"); } // Send a request to gti.pl to get the valid translation files logout << "Query argument: " << query_string << endl; text_t gti_arguments = "search-chunks " + target_language_code + " " + translation_file_key + " " + query_string; GTI_Response gti_response = parse_gti_response(do_gti_request(gti_arguments, logout), logout); if (gti_response.error_message != "") { // An error has occurred disp.setmacro("gtiformcontent", "gti", "_gti:gtierror_"); disp.setmacro("gtierrormessage", "gti", gti_response.error_message); return; } disp.setmacro("gtinumchunksmatchingquery", "gti", gti_response.num_chunks_matching_query); // Loop through the chunks returned, displaying them on the page text_t gti_find_form_content = "_gtifindformheader_\n"; text_tmap::iterator chunk_key_iterator = gti_response.target_file_chunks_key_to_text_mapping.begin(); while (chunk_key_iterator != gti_response.target_file_chunks_key_to_text_mapping.end()) { text_t chunk_key = chunk_key_iterator->first; // Need to escape any underscores in the chunk key to show it correctly on the page text_t chunk_key_escaped = escape_all(chunk_key, '_'); // Need to escape any backslashes, underscores, commas, parentheses, and single quotes in the chunk text text_t target_file_chunk_text = gti_response.target_file_chunks_key_to_text_mapping[chunk_key]; text_t target_file_chunk_text_escaped = escape_all(target_file_chunk_text, '\\'); target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '_'); target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, ','); target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '('); target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, ')'); target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '"'); target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '\''); // This chunk matches the query gti_find_form_content += "_gtichunkmatchingquery_(" + chunk_key_escaped + "," + target_file_chunk_text_escaped + ")\n"; chunk_key_iterator++; } gti_find_form_content += "_gtifindformfooter_\n"; disp.setmacro("gtifindformcontent", "gti", gti_find_form_content); } void gtiaction::define_gti_excel_page(displayclass& disp, cgiargsclass& args, ostream& logout) { // Get the target language code and file to translate from the CGI arguments text_t target_language_code = args["tlc"]; text_t translation_file_key = args["tfk"]; disp.setmacro("gtiformcontent", "gti", "_gti:gtiexcel_"); languageinfo_tmap loaded_languages = recpt->get_configinfo().languages; disp.setmacro("gtitargetlanguagename", "gti", loaded_languages[target_language_code].longname); disp.setmacro("gtitranslationfiledesc", "gti", "_gti:textgti" + translation_file_key + "_"); // Send a request to gti.pl to get the valid translation files text_t gti_arguments = "get-first-n-chunks-requiring-work " + target_language_code + " " + translation_file_key + " " + "10000" + " | java -classpath $GSDLHOME/bin/java ApplyXSLT $GSDLHOME/etc/gti-generate-excel-xml.xsl -"; text_t gti_response_xml_text = do_gti_request(gti_arguments, logout); // !! UNFINISHED !! } void gtiaction::define_gti_core_page(displayclass& disp, cgiargsclass& args, ostream& logout) { // Get the target language code and file to translate from the CGI arguments text_t target_language_code = args["tlc"]; text_t translation_file_key = args["tfk"]; text_t num_chunks_per_page = args["ncpp"]; logout << "Num chunks per page: " << num_chunks_per_page << endl; disp.setmacro("gtiformcontent", "gti", "_gti:gticore_"); // Display text right to left if target language is Arabic or Farsi or Urdu if (target_language_code == "ar" || target_language_code == "fa" || target_language_code == "ur") { disp.setmacro("gtitextdirection", "gti", "rtl"); } else { disp.setmacro("gtitextdirection", "gti", "ltr"); } // Send a request to gti.pl to get the first string to translate text_t gti_arguments = "get-first-n-chunks-requiring-work " + target_language_code + " " + translation_file_key + " " + num_chunks_per_page; GTI_Response gti_response = parse_gti_response(do_gti_request(gti_arguments, logout), logout); if (gti_response.error_message != "") { // An error has occurred disp.setmacro("gtiformcontent", "gti", "_gti:gtierror_"); disp.setmacro("gtierrormessage", "gti", gti_response.error_message); return; } languageinfo_tmap loaded_languages = recpt->get_configinfo().languages; disp.setmacro("gtitargetlanguagename", "gti", loaded_languages[target_language_code].longname); disp.setmacro("gtitargetfilepath", "gti", gti_response.translation_files_key_to_target_file_path_mapping[translation_file_key]); disp.setmacro("gtitranslationfiledesc", "gti", "_gti:textgti" + translation_file_key + "_"); disp.setmacro("gtiviewtranslationfileinaction", "gti", "_gti:gtiview" + translation_file_key + "inaction_"); disp.setmacro("gtinumchunkstranslated", "gti", gti_response.translation_files_key_to_num_chunks_translated_mapping[translation_file_key]); disp.setmacro("gtinumchunksrequiringtranslation", "gti", gti_response.translation_files_key_to_num_chunks_requiring_translation_mapping[translation_file_key]); disp.setmacro("gtinumchunksrequiringupdating", "gti", gti_response.translation_files_key_to_num_chunks_requiring_updating_mapping[translation_file_key]); // Check if the translation file is finished if (gti_response.translation_files_key_to_num_chunks_requiring_translation_mapping[translation_file_key] == "0" && gti_response.translation_files_key_to_num_chunks_requiring_updating_mapping[translation_file_key] == "0") { disp.setmacro("gtiformcontent", "gti", "_gti:gtidone_"); return; } // Loop through the chunks returned, displaying them on the page text_t gti_core_form_content = ""; text_tmap::iterator chunk_key_iterator = gti_response.source_file_chunks_key_to_text_mapping.begin(); while (chunk_key_iterator != gti_response.source_file_chunks_key_to_text_mapping.end()) { text_t chunk_key = chunk_key_iterator->first; // Need to escape any underscores in the chunk key to show it correctly on the page text_t chunk_key_escaped = escape_all(chunk_key, '_'); // Need to escape any backslashes, underscores, commas, parentheses, and single quotes in the chunk text text_t source_file_chunk_text = gti_response.source_file_chunks_key_to_text_mapping[chunk_key]; text_t source_file_chunk_text_escaped = escape_all(source_file_chunk_text, '\\'); source_file_chunk_text_escaped = escape_all(source_file_chunk_text_escaped, '_'); source_file_chunk_text_escaped = escape_all(source_file_chunk_text_escaped, ','); source_file_chunk_text_escaped = escape_all(source_file_chunk_text_escaped, '('); source_file_chunk_text_escaped = escape_all(source_file_chunk_text_escaped, ')'); source_file_chunk_text_escaped = escape_all(source_file_chunk_text_escaped, '\''); text_t target_file_chunk_text = gti_response.target_file_chunks_key_to_text_mapping[chunk_key]; text_t target_file_chunk_text_escaped = escape_all(target_file_chunk_text, '\\'); target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '_'); target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, ','); target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '('); target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, ')'); target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '\''); text_t source_file_chunk_date = gti_response.source_file_chunks_key_to_date_mapping[chunk_key]; text_t target_file_chunk_date = gti_response.target_file_chunks_key_to_date_mapping[chunk_key]; // This chunk requires translation if (target_file_chunk_text == "") { gti_core_form_content += "_gtichunkrequiringtranslation_(" + chunk_key_escaped + "," + source_file_chunk_text_escaped + "," + source_file_chunk_date + ")\n"; } // This chunk requires updating else { gti_core_form_content += "_gtichunkrequiringupdating_(" + chunk_key_escaped + "," + source_file_chunk_text_escaped + "," + source_file_chunk_date + "," + target_file_chunk_text_escaped + "," + target_file_chunk_date + ")\n"; } chunk_key_iterator++; } disp.setmacro("gticoreformcontent", "gti", gti_core_form_content); } void gtiaction::process_gti_submissions(displayclass& disp, cgiargsclass& args, ostream& logout, bool force_submission) { // Get the target language code and file to translate from the CGI arguments text_t target_language_code = args["tlc"]; text_t translation_file_key = args["tfk"]; text_t submitter_username = args["un"]; // Submitted chunk arguments contain the language code followed by "::" char* source_chunk_key_start_cstr = ((text_t) "en" + "%3A%3A").getcstr(); char* target_chunk_key_start_cstr = (target_language_code + "%3A%3A").getcstr(); // Find the cgi arguments with submitted chunk information text_t submission_text; cgiargsclass::const_iterator cgi_argument = args.begin(); while (cgi_argument != args.end()) { char* cgi_argument_name_cstr = cgi_argument->first.getcstr(); // Source file text if (strncmp(cgi_argument_name_cstr, source_chunk_key_start_cstr, strlen(source_chunk_key_start_cstr)) == 0) { submission_text += "\n"; submission_text += to_utf8(xml_safe(unescape_commas(args[cgi_argument->first]))) + "\n"; submission_text += "\n"; } // Target file text if (strncmp(cgi_argument_name_cstr, target_chunk_key_start_cstr, strlen(target_chunk_key_start_cstr)) == 0) { submission_text += "\n"; submission_text += to_utf8(xml_safe(unescape_commas(args[cgi_argument->first]))) + "\n"; submission_text += "\n"; } delete[] cgi_argument_name_cstr; ++cgi_argument; } logout << "Submission text: " << submission_text << endl; // Send the submission to gti.pl text_t gti_arguments = "submit-translations " + target_language_code + " " + translation_file_key + " " + submitter_username; if (force_submission) { gti_arguments += " -force_submission"; } do_gti_submission(gti_arguments, submission_text, logout); logout << "Done." << endl; delete[] source_chunk_key_start_cstr; delete[] target_chunk_key_start_cstr; } text_t gtiaction::escape_all(text_t text_string, char character_to_escape) { text_t text_string_escaped = ""; text_t::iterator text_string_character = text_string.begin(); while (text_string_character != text_string.end()) { if (*text_string_character == character_to_escape) { text_string_escaped += "\\"; } text_string_escaped.push_back(*text_string_character); text_string_character++; } return text_string_escaped; } text_t gtiaction::unescape_commas(text_t text_string) { text_t text_string_commas_unescaped = ""; text_t::iterator text_string_character = text_string.begin(); while (text_string_character != text_string.end()) { if (*text_string_character == '%' && (text_string_character+1) != text_string.end() && *(text_string_character+1) == '2' && (text_string_character+2) != text_string.end() && *(text_string_character+2) == 'C') { text_string_commas_unescaped += ","; text_string_character += 2; } else { text_string_commas_unescaped.push_back(*text_string_character); } text_string_character++; } return text_string_commas_unescaped; } text_t gtiaction::xml_safe(const text_t &text_string) { text_t text_string_safe; text_t::const_iterator here = text_string.begin(); text_t::const_iterator end = text_string.end(); while (here != end) { if (*here == '&') text_string_safe += "&"; else if (*here == '<') text_string_safe += "<"; else if (*here == '>') text_string_safe += ">"; else text_string_safe.push_back(*here); ++here; } return text_string_safe; } char* xml_get_attribute(const char** attributes, char* attribute_name) { for (int i = 0; (attributes[i] != NULL); i += 2) { if (strcmp(attribute_name, attributes[i]) == 0) { return strdup(attributes[i+1]); } } return NULL; } static void XMLCALL gti_response_xml_start_element(void* user_data, const char* element_name_cstr, const char** attributes) { GTI_Response* gti_response = (GTI_Response*) user_data; text_t element_name = element_name_cstr; cerr << "In startElement() for " << element_name << endl; if (element_name == "GTIError") { gti_response->recorded_text = ""; gti_response->is_recording_text = true; } if (element_name == "TranslationFile") { int translation_file_index = gti_response->translation_files_index_to_key_mapping.size(); gti_response->translation_file_key = xml_get_attribute(attributes, "key"); gti_response->translation_files_index_to_key_mapping[translation_file_index] = gti_response->translation_file_key; gti_response->translation_files_key_to_target_file_path_mapping[gti_response->translation_file_key] = xml_get_attribute(attributes, "target_file_path"); gti_response->translation_files_key_to_num_chunks_translated_mapping[gti_response->translation_file_key] = xml_get_attribute(attributes, "num_chunks_translated"); gti_response->translation_files_key_to_num_chunks_requiring_translation_mapping[gti_response->translation_file_key] = xml_get_attribute(attributes, "num_chunks_requiring_translation"); gti_response->translation_files_key_to_num_chunks_requiring_updating_mapping[gti_response->translation_file_key] = xml_get_attribute(attributes, "num_chunks_requiring_updating"); } if (element_name == "ChunksMatchingQuery") { gti_response->num_chunks_matching_query = xml_get_attribute(attributes, "size"); } if (element_name == "Chunk") { gti_response->chunk_key = xml_get_attribute(attributes, "key"); } if (element_name == "SourceFileText") { gti_response->source_file_chunks_key_to_date_mapping[gti_response->chunk_key] = xml_get_attribute(attributes, "date"); gti_response->recorded_text = ""; gti_response->is_recording_text = true; } if (element_name == "TargetFileText") { if (xml_get_attribute(attributes, "date") != NULL) { gti_response->target_file_chunks_key_to_date_mapping[gti_response->chunk_key] = xml_get_attribute(attributes, "date"); } gti_response->recorded_text = ""; gti_response->is_recording_text = true; } } static void XMLCALL gti_response_xml_end_element(void* user_data, const char* element_name_cstr) { GTI_Response* gti_response = (GTI_Response*) user_data; text_t element_name = element_name_cstr; if (element_name == "GTIError") { gti_response->error_message = to_uni(gti_response->recorded_text); gti_response->is_recording_text = false; } if (element_name == "SourceFileText") { gti_response->source_file_chunks_key_to_text_mapping[gti_response->chunk_key] = to_uni(gti_response->recorded_text); gti_response->is_recording_text = false; } if (element_name == "TargetFileText") { gti_response->target_file_chunks_key_to_text_mapping[gti_response->chunk_key] = to_uni(gti_response->recorded_text); gti_response->is_recording_text = false; } } static void XMLCALL gti_response_xml_character_data(void *user_data, const char* text_cstr, int text_length) { GTI_Response* gti_response = (GTI_Response*) user_data; if (gti_response->is_recording_text) { gti_response->recorded_text.appendcarr(text_cstr, text_length); } } text_t gtiaction::do_gti_request(text_t gti_arguments, ostream& logout) { // Send the request to gti.pl and read the XML output text_t gti_command = "perl -S " + filename_cat(gsdlhome, "bin", "script", "gti.pl") + " " + gti_arguments; char* gti_command_cstr = gti_command.getcstr(); FILE *gti_pipe = popen(gti_command_cstr, "r"); delete[] gti_command_cstr; if (gti_pipe == NULL) { logout << "Error: Could not open pipe for GTI command " << gti_command << endl; return ""; } // Read the gti.pl response text_t gti_response_xml_text; while (!feof(gti_pipe)) { char buffer[1024]; gti_response_xml_text.appendcarr(buffer, fread(buffer, 1, 1024, gti_pipe)); } pclose(gti_pipe); return gti_response_xml_text; } GTI_Response gtiaction::parse_gti_response(text_t gti_response_xml_text, ostream& logout) { GTI_Response gti_response; gti_response.is_recording_text = false; // Parse the gti.pl response (XML) logout << "Parsing GTI command response: " << gti_response_xml_text << endl; XML_Parser xml_parser = XML_ParserCreate(NULL); XML_SetUserData(xml_parser, >i_response); XML_SetElementHandler(xml_parser, gti_response_xml_start_element, gti_response_xml_end_element); XML_SetCharacterDataHandler(xml_parser, gti_response_xml_character_data); char* gti_response_xml_text_cstr = gti_response_xml_text.getcstr(); int parse_status = XML_Parse(xml_parser, gti_response_xml_text_cstr, strlen(gti_response_xml_text_cstr), XML_TRUE); delete[] gti_response_xml_text_cstr; if (parse_status == XML_STATUS_ERROR) { logout << "Parse error " << XML_ErrorString(XML_GetErrorCode(xml_parser)) << " at line " << XML_GetCurrentLineNumber(xml_parser) << endl; return gti_response; } XML_ParserFree(xml_parser); logout << "Finished parse." << endl; return gti_response; } void gtiaction::do_gti_submission(text_t gti_arguments, text_t gti_submission, ostream& logout) { // Send the submission to gti.pl text_t gti_command = "perl -S " + filename_cat(gsdlhome, "bin", "script", "gti.pl") + " " + gti_arguments; char* gti_command_cstr = gti_command.getcstr(); FILE *gti_pipe = popen(gti_command_cstr, "w"); delete[] gti_command_cstr; if (gti_pipe == NULL) { logout << "Error: Could not open pipe for GTI command " << gti_command << endl; return; } // Write the gti.pl submission char* gti_submission_cstr = gti_submission.getcstr(); fwrite(gti_submission_cstr, 1, strlen(gti_submission_cstr), gti_pipe); delete[] gti_submission_cstr; pclose(gti_pipe); } #endif // GSDL_USE_GTI_ACTION