diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/Makefile.am | 2 | ||||
-rw-r--r-- | src/lib/abrt_curl.c | 50 | ||||
-rw-r--r-- | src/lib/abrt_xmlrpc.c | 137 | ||||
-rw-r--r-- | src/lib/abrt_xmlrpc.cpp | 102 | ||||
-rw-r--r-- | src/lib/abrt_xmlrpc.h | 39 | ||||
-rw-r--r-- | src/lib/event_config.c | 1 | ||||
-rw-r--r-- | src/lib/event_xml_parser.c | 24 | ||||
-rw-r--r-- | src/lib/hooklib.c | 2 | ||||
-rw-r--r-- | src/lib/hooklib.h | 2 | ||||
-rw-r--r-- | src/lib/parse_options.c | 51 | ||||
-rw-r--r-- | src/lib/parse_options.h | 17 | ||||
-rw-r--r-- | src/lib/read_write.c | 2 |
12 files changed, 277 insertions, 152 deletions
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 88671f54..8fb147ac 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -87,7 +87,7 @@ libabrt_dbus_la_LIBADD = \ libabrt_web_la_SOURCES = \ abrt_curl.h abrt_curl.c \ - abrt_xmlrpc.h abrt_xmlrpc.cpp + abrt_xmlrpc.h abrt_xmlrpc.c libabrt_web_la_CPPFLAGS = \ -Wall -Wwrite-strings -Werror \ -I$(srcdir)/../include/report -I$(srcdir)/../include \ diff --git a/src/lib/abrt_curl.c b/src/lib/abrt_curl.c index 1cb9391d..0802a49b 100644 --- a/src/lib/abrt_curl.c +++ b/src/lib/abrt_curl.c @@ -175,6 +175,40 @@ static size_t fread_with_reporting(void *ptr, size_t size, size_t nmemb, void *u return fread(ptr, size, nmemb, fp); } +static int curl_debug(CURL *handle, curl_infotype it, char *buf, size_t bufsize, void *unused) +{ + if (logmode == 0) + return 0; + + switch (it) { + case CURLINFO_TEXT: /* The data is informational text. */ + log("curl: %.*s", (int) bufsize, buf); + break; + case CURLINFO_HEADER_IN: /* The data is header (or header-like) data received from the peer. */ + log("curl rcvd header: '%.*s'", (int) bufsize, buf); + break; + case CURLINFO_HEADER_OUT: /* The data is header (or header-like) data sent to the peer. */ + log("curl sent header: '%.*s'", (int) bufsize, buf); + break; + case CURLINFO_DATA_IN: /* The data is protocol data received from the peer. */ + if (g_verbose >= 3) + log("curl rcvd data: '%.*s'", (int) bufsize, buf); + else + log("curl rcvd data %u bytes", (int) bufsize); + break; + case CURLINFO_DATA_OUT: /* The data is protocol data sent to the peer. */ + if (g_verbose >= 3) + log("curl sent data: '%.*s'", (int) bufsize, buf); + else + log("curl sent data %u bytes", (int) bufsize); + break; + default: + break; + } + + return 0; +} + int abrt_post(abrt_post_state_t *state, const char *url, @@ -203,14 +237,18 @@ abrt_post(abrt_post_state_t *state, // curl will need it until curl_easy_cleanup. state->errmsg[0] = '\0'; xcurl_easy_setopt_ptr(handle, CURLOPT_ERRORBUFFER, state->errmsg); - // "Display a lot of verbose information about its operations. - // Very useful for libcurl and/or protocol debugging and understanding. - // The verbose information will be sent to stderr, or the stream set - // with CURLOPT_STDERR" - //xcurl_easy_setopt_long(handle, CURLOPT_VERBOSE, 1); // Shut off the built-in progress meter completely xcurl_easy_setopt_long(handle, CURLOPT_NOPROGRESS, 1); + if (g_verbose >= 2) { + // "Display a lot of verbose information about its operations. + // Very useful for libcurl and/or protocol debugging and understanding. + // The verbose information will be sent to stderr, or the stream set + // with CURLOPT_STDERR" + xcurl_easy_setopt_long(handle, CURLOPT_VERBOSE, 1); + xcurl_easy_setopt_ptr(handle, CURLOPT_DEBUGFUNCTION, curl_debug); + } + // TODO: do we need to check for CURLE_URL_MALFORMAT error *here*, // not in curl_easy_perform? xcurl_easy_setopt_ptr(handle, CURLOPT_URL, url); @@ -246,7 +284,7 @@ abrt_post(abrt_post_state_t *state, if (basename) basename++; else basename = data; #if 0 - // Simple way, without custom reader function + // Simple way, without custom reader function CURLFORMcode curlform_err = curl_formadd(&post, &last, CURLFORM_PTRNAME, "file", // element name CURLFORM_FILE, data, // filename to read from diff --git a/src/lib/abrt_xmlrpc.c b/src/lib/abrt_xmlrpc.c new file mode 100644 index 00000000..28d42325 --- /dev/null +++ b/src/lib/abrt_xmlrpc.c @@ -0,0 +1,137 @@ +/* + Copyright (C) 2010 ABRT team + Copyright (C) 2010 RedHat Inc + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#include "abrtlib.h" +#include "abrt_xmlrpc.h" + +void abrt_xmlrpc_die(xmlrpc_env *env) +{ + error_msg_and_die("fatal: XML-RPC(%d): %s", env->fault_code, env->fault_string); +} + +void abrt_xmlrpc_error(xmlrpc_env *env) +{ + error_msg("error: XML-RPC (%d): %s", env->fault_code, env->fault_string); +} + +struct abrt_xmlrpc *abrt_xmlrpc_new_client(const char *url, int ssl_verify) +{ + xmlrpc_env env; + xmlrpc_env_init(&env); + + struct abrt_xmlrpc *ax = xzalloc(sizeof(struct abrt_xmlrpc)); + + /* This should be done at program startup, once. We do it in main */ + /* xmlrpc_client_setup_global_const(&env); */ + + /* URL - bugzilla.redhat.com/show_bug.cgi?id=666893 Unable to make sense of + * XML-RPC response from server + * + * By default, XML data from the network may be no larger than 512K. + * XMLRPC_XML_SIZE_LIMIT_DEFAULT is #defined to (512*1024) in xmlrpc-c/base.h + * + * Users reported trouble with 733402 byte long responses, hope raising the + * limit to 2*512k is enough + */ + xmlrpc_limit_set(XMLRPC_XML_SIZE_LIMIT_ID, 2 * XMLRPC_XML_SIZE_LIMIT_DEFAULT); + + struct xmlrpc_curl_xportparms curl_parms; + memset(&curl_parms, 0, sizeof(curl_parms)); + /* curlParms.network_interface = NULL; - done by memset */ + curl_parms.no_ssl_verifypeer = !ssl_verify; + curl_parms.no_ssl_verifyhost = !ssl_verify; +#ifdef VERSION + curl_parms.user_agent = PACKAGE_NAME"/"VERSION; +#else + curl_parms.user_agent = "abrt"; +#endif + + struct xmlrpc_clientparms client_parms; + memset(&client_parms, 0, sizeof(client_parms)); + client_parms.transport = "curl"; + client_parms.transportparmsP = &curl_parms; + client_parms.transportparm_size = XMLRPC_CXPSIZE(user_agent); + + xmlrpc_client_create(&env, XMLRPC_CLIENT_NO_FLAGS, + PACKAGE_NAME, VERSION, + &client_parms, XMLRPC_CPSIZE(transportparm_size), + &ax->ax_client); + + if (env.fault_occurred) + abrt_xmlrpc_die(&env); + + ax->ax_server_info = xmlrpc_server_info_new(&env, url); + if (env.fault_occurred) + { + xmlrpc_client_destroy(ax->ax_client); + abrt_xmlrpc_die(&env); + } + + return ax; +} + +void abrt_xmlrpc_free_client(struct abrt_xmlrpc *ax) +{ + if (!ax) + return; + + if (ax->ax_server_info) + xmlrpc_server_info_free(ax->ax_server_info); + + if (ax->ax_client) + xmlrpc_client_destroy(ax->ax_client); + + free(ax); +} + +/* die or return expected results */ +xmlrpc_value *abrt_xmlrpc_call(struct abrt_xmlrpc *ax, + const char* method, const char* format, ...) +{ + xmlrpc_env env; + xmlrpc_env_init(&env); + + xmlrpc_value* param = NULL; + const char* suffix; + va_list args; + + va_start(args, format); + xmlrpc_build_value_va(&env, format, args, ¶m, &suffix); + va_end(args); + if (env.fault_occurred) + abrt_xmlrpc_die(&env); + + xmlrpc_value* result = NULL; + if (*suffix != '\0') + { + xmlrpc_env_set_fault_formatted( + &env, XMLRPC_INTERNAL_ERROR, "Junk after the argument " + "specifier: '%s'. There must be exactly one argument.", + suffix); + } + else + { + xmlrpc_client_call2(&env, ax->ax_client, ax->ax_server_info, method, + param, &result); + } + xmlrpc_DECREF(param); + if (env.fault_occurred) + abrt_xmlrpc_die(&env); + + return result; +} diff --git a/src/lib/abrt_xmlrpc.cpp b/src/lib/abrt_xmlrpc.cpp deleted file mode 100644 index ae75a47f..00000000 --- a/src/lib/abrt_xmlrpc.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - Copyright (C) 2010 ABRT team - Copyright (C) 2010 RedHat Inc - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -#include "abrtlib.h" -#include "abrt_xmlrpc.h" - -void throw_xml_fault(xmlrpc_env *env) -{ - error_msg_and_die("XML-RPC Fault(%d): %s", env->fault_code, env->fault_string); -} - -void throw_if_xml_fault_occurred(xmlrpc_env *env) -{ - if (env->fault_occurred) - { - throw_xml_fault(env); - } -} - -void abrt_xmlrpc_conn::new_xmlrpc_client(const char* url, bool ssl_verify) -{ - m_pClient = NULL; - m_pServer_info = NULL; - - xmlrpc_env env; - xmlrpc_env_init(&env); - - /* This should be done at program startup, once. We do it in main */ - /* xmlrpc_client_setup_global_const(&env); */ - - /* URL - bugzilla.redhat.com/show_bug.cgi?id=666893 Unable to make sense of - * XML-RPC response from server - * - * By default, XML data from the network may be no larger than 512K. - * XMLRPC_XML_SIZE_LIMIT_DEFAULT is #defined to (512*1024) in xmlrpc-c/base.h - * - * Users reported trouble with 733402 byte long responses, hope raising the - * limit to 2*512k is enough - */ - xmlrpc_limit_set(XMLRPC_XML_SIZE_LIMIT_ID, 2 * XMLRPC_XML_SIZE_LIMIT_DEFAULT); - - struct xmlrpc_curl_xportparms curlParms; - memset(&curlParms, 0, sizeof(curlParms)); - /* curlParms.network_interface = NULL; - done by memset */ - curlParms.no_ssl_verifypeer = !ssl_verify; - curlParms.no_ssl_verifyhost = !ssl_verify; -#ifdef VERSION - curlParms.user_agent = PACKAGE_NAME"/"VERSION; -#else - curlParms.user_agent = "abrt"; -#endif - - struct xmlrpc_clientparms clientParms; - memset(&clientParms, 0, sizeof(clientParms)); - clientParms.transport = "curl"; - clientParms.transportparmsP = &curlParms; - clientParms.transportparm_size = XMLRPC_CXPSIZE(user_agent); - - xmlrpc_client_create(&env, XMLRPC_CLIENT_NO_FLAGS, - PACKAGE_NAME, VERSION, - &clientParms, XMLRPC_CPSIZE(transportparm_size), - &m_pClient); - if (env.fault_occurred) - throw_xml_fault(&env); - - m_pServer_info = xmlrpc_server_info_new(&env, url); - if (env.fault_occurred) - { - xmlrpc_client_destroy(m_pClient); - m_pClient = NULL; - throw_xml_fault(&env); - } -} - -void abrt_xmlrpc_conn::destroy_xmlrpc_client() -{ - if (m_pServer_info) - { - xmlrpc_server_info_free(m_pServer_info); - m_pServer_info = NULL; - } - if (m_pClient) - { - xmlrpc_client_destroy(m_pClient); - m_pClient = NULL; - } -} diff --git a/src/lib/abrt_xmlrpc.h b/src/lib/abrt_xmlrpc.h index 93c5a9d6..5c94360f 100644 --- a/src/lib/abrt_xmlrpc.h +++ b/src/lib/abrt_xmlrpc.h @@ -19,37 +19,30 @@ #ifndef ABRT_XMLRPC_H_ #define ABRT_XMLRPC_H_ 1 -#include <curl/curl.h> +/* include/stdint.h: typedef int int32_t; + * include/xmlrpc-c/base.h: typedef int32_t xmlrpc_int32; + */ + #include <xmlrpc-c/base.h> #include <xmlrpc-c/client.h> #ifdef __cplusplus -/* - * Simple class holding XMLRPC connection data. - * Used mainly to ensure we always destroy xmlrpc client and server_info - * on return or throw. - */ -struct abrt_xmlrpc_conn { - xmlrpc_client* m_pClient; - xmlrpc_server_info* m_pServer_info; - - abrt_xmlrpc_conn(const char* url, bool ssl_verify) { new_xmlrpc_client(url, ssl_verify); } - /* this never throws exceptions - calls C functions only */ - ~abrt_xmlrpc_conn() { destroy_xmlrpc_client(); } - - void new_xmlrpc_client(const char* url, bool ssl_verify); - void destroy_xmlrpc_client(); -}; +extern "C" { #endif +struct abrt_xmlrpc { + xmlrpc_client *ax_client; + xmlrpc_server_info *ax_server_info; +}; -#ifdef __cplusplus -extern "C" { -#endif +struct abrt_xmlrpc *abrt_xmlrpc_new_client(const char *url, int ssl_verify); +void abrt_xmlrpc_free_client(struct abrt_xmlrpc *ax); +void abrt_xmlrpc_die(xmlrpc_env *env) __attribute__((noreturn)); +void abrt_xmlrpc_error(xmlrpc_env *env); -/* Utility functions */ -void throw_xml_fault(xmlrpc_env *env); -void throw_if_xml_fault_occurred(xmlrpc_env *env); +/* die or return expected results */ +xmlrpc_value *abrt_xmlrpc_call(struct abrt_xmlrpc *ax, + const char *method, const char *format, ...); #ifdef __cplusplus } diff --git a/src/lib/event_config.c b/src/lib/event_config.c index 66f9beba..9f48af54 100644 --- a/src/lib/event_config.c +++ b/src/lib/event_config.c @@ -55,6 +55,7 @@ void free_event_config(event_config_t *p) //free(p->action); free(p->description); free(p->long_descr); + free(p->creates_elements); for (opt = p->options; opt; opt = opt->next) free_event_option(opt->data); g_list_free(p->options); diff --git a/src/lib/event_xml_parser.c b/src/lib/event_xml_parser.c index 17e8a72e..5bf5f411 100644 --- a/src/lib/event_xml_parser.c +++ b/src/lib/event_xml_parser.c @@ -25,6 +25,7 @@ #define LONG_DESCR_ELEMENT "long-description" #define ALLOW_EMPTY_ELEMENT "allow-empty" #define NOTE_HTML_ELEMENT "note-html" +#define CREATES_ELEMENT "creates-elements" #define OPTION_ELEMENT "option" //#define ACTION_ELEMENT "action" #define NAME_ELEMENT "name" @@ -55,16 +56,16 @@ static const char *const option_types[] = static char *get_element_lang(struct my_parse_data *parse_data, const gchar **att_names, const gchar **att_values) { char *short_locale_end = strchr(parse_data->cur_locale, '_'); - VERB2 log("locale: %s", parse_data->cur_locale); + VERB3 log("locale: %s", parse_data->cur_locale); int i; for (i = 0; att_names[i] != NULL; ++i) { - VERB2 log("attr: %s:%s", att_names[i], att_values[i]); + VERB3 log("attr: %s:%s", att_names[i], att_values[i]); if (strcmp(att_names[i], "xml:lang") == 0) { if (strcmp(att_values[i], parse_data->cur_locale) == 0) { - VERB2 log("found translation for: %s", parse_data->cur_locale); + VERB3 log("found translation for: %s", parse_data->cur_locale); return xstrdup(att_values[i]); } @@ -74,7 +75,7 @@ static char *get_element_lang(struct my_parse_data *parse_data, const gchar **at if (short_locale_end && strncmp(att_values[i], parse_data->cur_locale, short_locale_end - parse_data->cur_locale) == 0 ) { - VERB2 log("found translation for shortlocale: %s", parse_data->cur_locale); + VERB3 log("found translation for shortlocale: %s", parse_data->cur_locale); return xstrndup(att_values[i], short_locale_end - parse_data->cur_locale); } } @@ -297,11 +298,18 @@ static void text(GMarkupParseContext *context, if (strcmp(inner_element, ACTION_ELEMENT) == 0) { VERB2 log("action description:'%s'", text_copy); - free(ui->eo_action); - ui->eo_action = text_copy; + free(ui->action); + ui->action = text_copy; return; } */ + if (strcmp(inner_element, CREATES_ELEMENT) == 0) + { + VERB2 log("creates_elements:'%s'", text_copy); + free(ui->creates_elements); + ui->creates_elements = text_copy; + return; + } if (strcmp(inner_element, NAME_ELEMENT) == 0) { if (parse_data->attribute_lang != NULL) /* if it isn't for other locale */ @@ -321,7 +329,7 @@ static void text(GMarkupParseContext *context, } if (strcmp(inner_element, DESCRIPTION_ELEMENT) == 0) { - VERB2 log("event description:'%s'", text_copy); + VERB3 log("event description:'%s'", text_copy); if (parse_data->attribute_lang != NULL) /* if it isn't for other locale */ { @@ -339,7 +347,7 @@ static void text(GMarkupParseContext *context, } if (strcmp(inner_element, LONG_DESCR_ELEMENT) == 0) { - VERB2 log("event long description:'%s'", text_copy); + VERB3 log("event long description:'%s'", text_copy); if (parse_data->attribute_lang != NULL) /* if it isn't for other locale */ { diff --git a/src/lib/hooklib.c b/src/lib/hooklib.c index 3bde4dfa..804a2394 100644 --- a/src/lib/hooklib.c +++ b/src/lib/hooklib.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2009 RedHat inc. + Copyright (C) 2009 RedHat inc. 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 diff --git a/src/lib/hooklib.h b/src/lib/hooklib.h index c140f951..1add7d09 100644 --- a/src/lib/hooklib.h +++ b/src/lib/hooklib.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2009 RedHat inc. + Copyright (C) 2009 RedHat inc. 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 diff --git a/src/lib/parse_options.c b/src/lib/parse_options.c index d9ce8a2f..4e4a3e08 100644 --- a/src/lib/parse_options.c +++ b/src/lib/parse_options.c @@ -24,12 +24,55 @@ #define USAGE_OPTS_WIDTH 24 #define USAGE_GAP 2 -void show_usage_and_die(const char *usage, const struct options *opt) +const char *g_progname; + +const char *abrt_init(char **argv) { - fprintf(stderr, _("Usage: %s\n"), usage); + char *env_verbose = getenv("ABRT_VERBOSE"); + if (env_verbose) + g_verbose = atoi(env_verbose); + + g_progname = strrchr(argv[0], '/'); + if (g_progname) + g_progname++; + else + g_progname = argv[0]; + + char *pfx = getenv("ABRT_PROG_PREFIX"); + if (pfx && string_to_bool(pfx)) + msg_prefix = g_progname; + + return g_progname; +} - if (opt->type != OPTION_GROUP) - fputc('\n', stderr); +void export_abrt_envvars(int pfx) +{ + putenv(xasprintf("ABRT_VERBOSE=%u", g_verbose)); + if (pfx) + { + putenv((char*)"ABRT_PROG_PREFIX=1"); + msg_prefix = g_progname; + } +} + +void show_usage_and_die(const char *usage, const struct options *opt) +{ + fputs(_("Usage: "), stderr); + while (*usage) + { + int len = strchrnul(usage, '\b') - usage; + if (len > 0) + { + fprintf(stderr, "%.*s", len, usage); + usage += len; + } + if (*usage == '\b') + { + fputs(g_progname, stderr); + usage++; + } + } + fputs("\n\n", stderr); for (; opt->type != OPTION_END; opt++) { diff --git a/src/lib/parse_options.h b/src/lib/parse_options.h index 8c784b96..d86662e2 100644 --- a/src/lib/parse_options.h +++ b/src/lib/parse_options.h @@ -23,6 +23,13 @@ extern "C" { #endif +const char *abrt_init(char **argv); +#define export_abrt_envvars abrt_export_abrt_envvars +void export_abrt_envvars(int pfx); +#define g_progname abrt_g_progname +extern const char *g_progname; + + enum parse_opt_type { OPTION_BOOL, OPTION_GROUP, @@ -50,12 +57,12 @@ struct options { * h - help */ #define OPT_END() { OPTION_END } -#define OPT_BOOL(s, l, v, h) { OPTION_BOOL, (s), (l), (v), NULL, (h) } #define OPT_GROUP(h) { OPTION_GROUP, 0, NULL, NULL, NULL, (h) } -#define OPT_INTEGER(s, l, v, h) { OPTION_INTEGER, (s), (l), (v), "NUM", (h) } -#define OPT_STRING(s, l, v, a, h) { OPTION_STRING, (s), (l), (v), (a), (h) } -#define OPT_OPTSTRING(s, l, v, a, h) { OPTION_OPTSTRING, (s), (l), (v), (a), (h) } -#define OPT_LIST(s, l, v, a, h) { OPTION_LIST, (s), (l), (v), (a), (h) } +#define OPT_BOOL( s, l, v, h) { OPTION_BOOL , (s), (l), (v), NULL , (h) } +#define OPT_INTEGER( s, l, v, h) { OPTION_INTEGER , (s), (l), (v), "NUM", (h) } +#define OPT_STRING( s, l, v, a, h) { OPTION_STRING , (s), (l), (v), (a) , (h) } +#define OPT_OPTSTRING(s, l, v, a, h) { OPTION_OPTSTRING, (s), (l), (v), (a) , (h) } +#define OPT_LIST( s, l, v, a, h) { OPTION_LIST , (s), (l), (v), (a) , (h) } #define OPT__VERBOSE(v) OPT_BOOL('v', "verbose", (v), _("Be verbose")) diff --git a/src/lib/read_write.c b/src/lib/read_write.c index da067f78..fe85fcfb 100644 --- a/src/lib/read_write.c +++ b/src/lib/read_write.c @@ -88,7 +88,7 @@ ssize_t full_write(int fd, const void *buf, size_t len) /* user can do another write to know the error code */ return total; } - return cc; /* write() returns -1 on failure. */ + return cc; /* write() returns -1 on failure. */ } total += cc; |