summaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/Makefile.am2
-rw-r--r--src/lib/abrt_curl.c50
-rw-r--r--src/lib/abrt_xmlrpc.c137
-rw-r--r--src/lib/abrt_xmlrpc.cpp102
-rw-r--r--src/lib/abrt_xmlrpc.h39
-rw-r--r--src/lib/event_config.c1
-rw-r--r--src/lib/event_xml_parser.c24
-rw-r--r--src/lib/hooklib.c2
-rw-r--r--src/lib/hooklib.h2
-rw-r--r--src/lib/parse_options.c51
-rw-r--r--src/lib/parse_options.h17
-rw-r--r--src/lib/read_write.c2
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, &param, &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;