diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-09-17 00:54:45 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-09-17 00:54:45 +0200 |
commit | 965e2c893488164c6b36ec1942e762bb42e7fb61 (patch) | |
tree | 2875a673449bd10e5845f4aacda349767135ba20 | |
parent | 92e1cccad55ec52e4fb0cfff538cae836c1e1941 (diff) | |
download | abrt-965e2c893488164c6b36ec1942e762bb42e7fb61.tar.gz abrt-965e2c893488164c6b36ec1942e762bb42e7fb61.tar.xz abrt-965e2c893488164c6b36ec1942e762bb42e7fb61.zip |
remove C++ dbus glue in src/CLI; fix a bug in --report
Several kb of code removed. The nly remaining use of C++ glue
is desktop applet.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | lib/Utils/Makefile.am | 1 | ||||
-rw-r--r-- | lib/Utils/abrt_dbus.cpp | 112 | ||||
-rw-r--r-- | lib/Utils/abrt_dbus.h | 226 | ||||
-rw-r--r-- | src/CLI/CLI.cpp | 360 | ||||
-rw-r--r-- | src/CLI/CommLayerClientDBus.cpp | 14 | ||||
-rw-r--r-- | src/CLI/CommLayerClientDBus.h | 17 | ||||
-rw-r--r-- | src/CLI/Makefile.am | 3 | ||||
-rw-r--r-- | src/Daemon/CommLayerServerDBus.cpp | 379 |
8 files changed, 588 insertions, 524 deletions
diff --git a/lib/Utils/Makefile.am b/lib/Utils/Makefile.am index b662ae9a..cef82d9d 100644 --- a/lib/Utils/Makefile.am +++ b/lib/Utils/Makefile.am @@ -9,6 +9,7 @@ libABRTUtils_la_SOURCES = \ DebugDump.h DebugDump.cpp \ DBusClientProxy.h DBusClientProxy.cpp \ CommLayerInner.h CommLayerInner.cpp \ + abrt_dbus.h abrt_dbus.cpp \ Plugin.h Plugin.cpp \ Polkit.h Polkit.cpp \ Action.h Database.h Reporter.h Analyzer.h \ diff --git a/lib/Utils/abrt_dbus.cpp b/lib/Utils/abrt_dbus.cpp new file mode 100644 index 00000000..3d868b9d --- /dev/null +++ b/lib/Utils/abrt_dbus.cpp @@ -0,0 +1,112 @@ +#include <dbus/dbus.h> +#include "abrtlib.h" +#include "abrt_dbus.h" + +DBusConnection* g_dbus_conn; + +/* + * Helpers for building DBus messages + */ + +//void store_bool(DBusMessageIter* iter, bool val) +//{ +// dbus_bool_t db = val; +// if (!dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &db)) +// die_out_of_memory(); +//} +void store_int32(DBusMessageIter* iter, int32_t val) +{ + if (!dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &val)) + die_out_of_memory(); +} +void store_uint32(DBusMessageIter* iter, uint32_t val) +{ + if (!dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &val)) + die_out_of_memory(); +} +void store_int64(DBusMessageIter* iter, int64_t val) +{ + if (!dbus_message_iter_append_basic(iter, DBUS_TYPE_INT64, &val)) + die_out_of_memory(); +} +void store_uint64(DBusMessageIter* iter, uint64_t val) +{ + if (!dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT64, &val)) + die_out_of_memory(); +} +void store_string(DBusMessageIter* iter, const char* val) +{ + if (!dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &val)) + die_out_of_memory(); +} + +/* + * Helpers for parsing DBus messages + */ + +//int load_bool(DBusMessageIter* iter, bool& val) +//{ +// int type = dbus_message_iter_get_arg_type(iter); +// if (type != DBUS_TYPE_BOOLEAN) +// error_msg_and_die("%s expected in dbus message, but not found ('%c')", "bool", type); +// dbus_bool_t db; +// dbus_message_iter_get_basic(iter, &db); +// val = db; +// return dbus_message_iter_next(iter); +//} +int load_int32(DBusMessageIter* iter, int32_t& val) +{ + int type = dbus_message_iter_get_arg_type(iter); + if (type != DBUS_TYPE_INT32) + { + error_msg("%s expected in dbus message, but not found ('%c')", "int32", type); + return -1; + } + dbus_message_iter_get_basic(iter, &val); + return dbus_message_iter_next(iter); +} +int load_uint32(DBusMessageIter* iter, uint32_t& val) +{ + int type = dbus_message_iter_get_arg_type(iter); + if (type != DBUS_TYPE_UINT32) + { + error_msg("%s expected in dbus message, but not found ('%c')", "uint32", type); + return -1; + } + dbus_message_iter_get_basic(iter, &val); + return dbus_message_iter_next(iter); +} +int load_int64(DBusMessageIter* iter, int64_t& val) +{ + int type = dbus_message_iter_get_arg_type(iter); + if (type != DBUS_TYPE_INT64) + { + error_msg("%s expected in dbus message, but not found ('%c')", "int64", type); + return -1; + } + dbus_message_iter_get_basic(iter, &val); + return dbus_message_iter_next(iter); +} +int load_uint64(DBusMessageIter* iter, uint64_t& val) +{ + int type = dbus_message_iter_get_arg_type(iter); + if (type != DBUS_TYPE_UINT64) + { + error_msg("%s expected in dbus message, but not found ('%c')", "uint64", type); + return -1; + } + dbus_message_iter_get_basic(iter, &val); + return dbus_message_iter_next(iter); +} +int load_charp(DBusMessageIter* iter, const char*& val) +{ + int type = dbus_message_iter_get_arg_type(iter); + if (type != DBUS_TYPE_STRING) + { + error_msg("%s expected in dbus message, but not found ('%c')", "string", type); + return -1; + } + dbus_message_iter_get_basic(iter, &val); +//log("load_charp:'%s'", val); + return dbus_message_iter_next(iter); +} diff --git a/lib/Utils/abrt_dbus.h b/lib/Utils/abrt_dbus.h new file mode 100644 index 00000000..e2bf9fbf --- /dev/null +++ b/lib/Utils/abrt_dbus.h @@ -0,0 +1,226 @@ +#include <dbus/dbus.h> +#include <map> +#include <vector> +#include "abrtlib.h" + +extern DBusConnection* g_dbus_conn; + +/* + * Helpers for building DBus messages + */ + +//void store_bool(DBusMessageIter* iter, bool val); +void store_int32(DBusMessageIter* iter, int32_t val); +void store_uint32(DBusMessageIter* iter, uint32_t val); +void store_int64(DBusMessageIter* iter, int64_t val); +void store_uint64(DBusMessageIter* iter, uint64_t val); +void store_string(DBusMessageIter* iter, const char* val); + +//static inline void store_val(DBusMessageIter* iter, bool val) { store_bool(iter, val); } +static inline void store_val(DBusMessageIter* iter, int32_t val) { store_int32(iter, val); } +static inline void store_val(DBusMessageIter* iter, uint32_t val) { store_uint32(iter, val); } +static inline void store_val(DBusMessageIter* iter, int64_t val) { store_int64(iter, val); } +static inline void store_val(DBusMessageIter* iter, uint64_t val) { store_uint64(iter, val); } +static inline void store_val(DBusMessageIter* iter, const char* val) { store_string(iter, val); } +static inline void store_val(DBusMessageIter* iter, const std::string& val) { store_string(iter, val.c_str()); } + +/* Templates for vector and map */ +template <typename T> struct abrt_dbus_type {}; +//template <> struct abrt_dbus_type<bool> { static const char* csig() { return "b"; } }; +template <> struct abrt_dbus_type<int32_t> { static const char* csig() { return "i"; } static std::string sig(); }; +template <> struct abrt_dbus_type<uint32_t> { static const char* csig() { return "u"; } static std::string sig(); }; +template <> struct abrt_dbus_type<int64_t> { static const char* csig() { return "x"; } static std::string sig(); }; +template <> struct abrt_dbus_type<uint64_t> { static const char* csig() { return "t"; } static std::string sig(); }; +template <> struct abrt_dbus_type<std::string> { static const char* csig() { return "s"; } static std::string sig(); }; +#define ABRT_DBUS_SIG(T) (abrt_dbus_type<T>::csig() ? abrt_dbus_type<T>::csig() : abrt_dbus_type<T>::sig().c_str()) +template <typename E> +struct abrt_dbus_type< std::vector<E> > { + static const char* csig() { return NULL; } + static std::string sig() { return ssprintf("a%s", ABRT_DBUS_SIG(E)); } +}; +template <typename K, typename V> +struct abrt_dbus_type< std::map<K,V> > { + static const char* csig() { return NULL; } + static std::string sig() { return ssprintf("a{%s%s}", ABRT_DBUS_SIG(K), ABRT_DBUS_SIG(V)); } +}; + +template<typename E> +static void store_vector(DBusMessageIter* iter, const std::vector<E>& val) +{ + DBusMessageIter sub_iter; + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, ABRT_DBUS_SIG(E), &sub_iter)) + die_out_of_memory(); + + typename std::vector<E>::const_iterator vit = val.begin(); + for (; vit != val.end(); ++vit) + { + store_val(&sub_iter, *vit); + } + + if (!dbus_message_iter_close_container(iter, &sub_iter)) + die_out_of_memory(); +} +/* +template<> +static void store_vector(DBus::MessageIter &iter, const std::vector<uint8_t>& val) +{ + if we use such vector, MUST add specialized code here (see in dbus-c++ source) +} +*/ +template<typename K, typename V> +static void store_map(DBusMessageIter* iter, const std::map<K,V>& val) +{ + DBusMessageIter sub_iter; + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, + ssprintf("{%s%s}", ABRT_DBUS_SIG(K), ABRT_DBUS_SIG(V)).c_str(), + &sub_iter)) + die_out_of_memory(); + + typename std::map<K,V>::const_iterator mit = val.begin(); + for (; mit != val.end(); ++mit) + { + DBusMessageIter sub_sub_iter; + if (!dbus_message_iter_open_container(&sub_iter, DBUS_TYPE_DICT_ENTRY, NULL, &sub_sub_iter)) + die_out_of_memory(); + store_val(&sub_sub_iter, mit->first); + store_val(&sub_sub_iter, mit->second); + if (!dbus_message_iter_close_container(&sub_iter, &sub_sub_iter)) + die_out_of_memory(); + } + + if (!dbus_message_iter_close_container(iter, &sub_iter)) + die_out_of_memory(); +} + +template<typename E> +static inline void store_val(DBusMessageIter* iter, const std::vector<E>& val) { store_vector(iter, val); } +template<typename K, typename V> +static inline void store_val(DBusMessageIter* iter, const std::map<K,V>& val) { store_map(iter, val); } + + +/* + * Helpers for parsing DBus messages + */ + +enum { + ABRT_DBUS_ERROR = -1, + ABRT_DBUS_LAST_FIELD = 0, + ABRT_DBUS_MORE_FIELDS = 1, +}; +/* Checks type, loads data, advances to the next arg. + * Returns TRUE if next arg exists. + */ +//int load_bool(DBusMessageIter* iter, bool& val); +int load_int32(DBusMessageIter* iter, int32_t &val); +int load_uint32(DBusMessageIter* iter, uint32_t &val); +int load_int64(DBusMessageIter* iter, int64_t &val); +int load_uint64(DBusMessageIter* iter, uint64_t &val); +int load_charp(DBusMessageIter* iter, const char*& val); +//static inline int load_val(DBusMessageIter* iter, bool &val) { return load_bool(iter, val); } +static inline int load_val(DBusMessageIter* iter, int32_t &val) { return load_int32(iter, val); } +static inline int load_val(DBusMessageIter* iter, uint32_t &val) { return load_uint32(iter, val); } +static inline int load_val(DBusMessageIter* iter, int64_t &val) { return load_int64(iter, val); } +static inline int load_val(DBusMessageIter* iter, uint64_t &val) { return load_uint64(iter, val); } +static inline int load_val(DBusMessageIter* iter, const char*& val) { return load_charp(iter, val); } +static inline int load_val(DBusMessageIter* iter, std::string& val) +{ + const char* str; + int r = load_charp(iter, str); + val = str; + return r; +} + +/* Templates for vector and map */ +template<typename E> +static int load_vector(DBusMessageIter* iter, std::vector<E>& val) +{ + int type = dbus_message_iter_get_arg_type(iter); + if (type != DBUS_TYPE_ARRAY) + { + error_msg("array expected in dbus message, but not found ('%c')", type); + return -1; + } + + DBusMessageIter sub_iter; + dbus_message_iter_recurse(iter, &sub_iter); + + int r; +//int cnt = 0; + //type = dbus_message_iter_get_arg_type(&sub_iter); + /* here "type" is the element's type, and it will be checked by load_val */ + // if (type != DBUS_TYPE_INVALID) - not needed? + do { + E elem; +//cnt++; + r = load_val(&sub_iter, elem); + if (r < 0) + return r; + val.push_back(elem); + } while (r == ABRT_DBUS_MORE_FIELDS); +//log("%s: %d elems", __func__, cnt); + + return dbus_message_iter_next(iter); +} +/* +template<> +static int load_vector(DBusMessageIter* iter, std::vector<uint8_t>& val) +{ + if we use such vector, MUST add specialized code here (see in dbus-c++ source) +} +*/ +template<typename K, typename V> +static int load_map(DBusMessageIter* iter, std::map<K,V>& val) +{ + int type = dbus_message_iter_get_arg_type(iter); + if (type != DBUS_TYPE_ARRAY) + { + error_msg("array expected in dbus message, but not found ('%c')", type); + return -1; + } + + DBusMessageIter sub_iter; + dbus_message_iter_recurse(iter, &sub_iter); + + bool next_exists; + int r; +//int cnt = 0; + do { + type = dbus_message_iter_get_arg_type(&sub_iter); + if (type != DBUS_TYPE_DICT_ENTRY) + { + error_msg("sub_iter type is not DBUS_TYPE_DICT_ENTRY (%c)!", type); + return -1; + } + + DBusMessageIter sub_sub_iter; + dbus_message_iter_recurse(&sub_iter, &sub_sub_iter); + + K key; + r = load_val(&sub_sub_iter, key); + if (r != ABRT_DBUS_MORE_FIELDS) + { + if (r == ABRT_DBUS_LAST_FIELD) + error_msg("malformed map element in dbus message"); + return -1; + } + V value; + r = load_val(&sub_sub_iter, value); + if (r != ABRT_DBUS_LAST_FIELD) + { + if (r == ABRT_DBUS_MORE_FIELDS) + error_msg("malformed map element in dbus message"); + return -1; + } + val[key] = value; +//cnt++; + next_exists = dbus_message_iter_next(&sub_iter); + } while (next_exists); +//log("%s: %d elems", __func__, cnt); + + return dbus_message_iter_next(iter); +} + +template<typename E> +static inline int load_val(DBusMessageIter* iter, std::vector<E>& val) { return load_vector(iter, val); } +template<typename K, typename V> +static inline int load_val(DBusMessageIter* iter, std::map<K,V>& val) { return load_map(iter, val); } diff --git a/src/CLI/CLI.cpp b/src/CLI/CLI.cpp index aaaef5bc..319bd0e8 100644 --- a/src/CLI/CLI.cpp +++ b/src/CLI/CLI.cpp @@ -1,95 +1,31 @@ +#include <iostream> +#include <getopt.h> #include "ABRTException.h" #include "ABRTSocket.h" -#include "ABRTException.h" -#include <iostream> -#include <CommLayerClientDBus.h> -#include <string.h> - -#define SOCKET_FILE VAR_RUN"/abrt.socket" - -typedef enum {HELP, - GET_LIST, - GET_LIST_FULL, - REPORT, - REPORT_ALWAYS, - DELETE} param_mode_t; - -typedef struct param_s -{ - param_mode_t m_Mode; - char* m_sUUID; -} param_t; +#include "abrtlib.h" +#include "abrt_dbus.h" +#include "DBusCommon.h" -void print_usage(char* pProgramName) +enum { - std::cout << pProgramName << " [OPTION]" << std::endl << std::endl; - std::cout << "[OPTION]" << std::endl; - std::cout << "\t--help - prints this text" << std::endl; - std::cout << "\t--get-list - prints list of crashes which are not reported" << std::endl; - std::cout << "\t--get-list-full - prints list of all crashes" << std::endl; - std::cout << "\t--report <uuid> - create and send a report" << std::endl; - std::cout << "\t--report-always <uuid> - create and send a report without asking" << std::endl; - std::cout << "\t--delete <uuid> - delete crash" << std::endl; -} + HELP, + GET_LIST, + GET_LIST_FULL, + REPORT, + REPORT_ALWAYS, + DELETE +}; -void parse_args(int argc, char** argv, param_t& param) -{ - if (argc == 2) - { - if (!strcmp(argv[1], "--help") || !strcmp(argv[1], "--version")) - { - param.m_Mode = HELP; - } - else if (!strcmp(argv[1], "--get-list")) - { - param.m_Mode = GET_LIST; - } - else if (!strcmp(argv[1], "--get-list-full")) - { - param.m_Mode = GET_LIST_FULL; - } - else - { - param.m_Mode = HELP; - } - } - else if (argc == 3) - { - if (!strcmp(argv[1], "--report")) - { - param.m_Mode = REPORT; - param.m_sUUID = argv[2]; - } - else if (!strcmp(argv[1], "--report-always")) - { - param.m_Mode = REPORT_ALWAYS; - param.m_sUUID = argv[2]; - } - else if (!strcmp(argv[1], "--delete")) - { - param.m_Mode = DELETE; - param.m_sUUID = argv[2]; - } - else - { - param.m_Mode = HELP; - } - } - else - { - param.m_Mode = HELP; - } -} +static DBusConnection* s_dbus_conn; -void print_crash_infos(const vector_crash_infos_t& pCrashInfos, - const param_mode_t& pMode) +static void print_crash_infos(const vector_crash_infos_t& pCrashInfos, int pMode) { unsigned int ii; for (ii = 0; ii < pCrashInfos.size(); ii++) { if (pCrashInfos[ii].find(CD_REPORTED)->second[CD_CONTENT] != "1" || pMode == GET_LIST_FULL) { - std::cout << ii << ". " << std::endl; + std::cout << ii << ".\n"; std::cout << "\tUID : " << pCrashInfos[ii].find(CD_UID)->second[CD_CONTENT] << std::endl; std::cout << "\tUUID : " << pCrashInfos[ii].find(CD_UUID)->second[CD_CONTENT] << std::endl; std::cout << "\tPackage : " << pCrashInfos[ii].find(CD_PACKAGE)->second[CD_CONTENT] << std::endl; @@ -100,10 +36,10 @@ void print_crash_infos(const vector_crash_infos_t& pCrashInfos, } } -void print_crash_report(const map_crash_report_t& pCrashReport) +static void print_crash_report(const map_crash_report_t& pCrashReport) { - map_crash_report_t::const_iterator it; - for (it = pCrashReport.begin(); it != pCrashReport.end(); it++) + map_crash_report_t::const_iterator it = pCrashReport.begin(); + for (; it != pCrashReport.end(); it++) { if (it->second[CD_TYPE] != CD_SYS) { @@ -114,77 +50,221 @@ void print_crash_report(const map_crash_report_t& pCrashReport) } } -int main(int argc, char** argv) +/* + * DBus member calls + */ + +/* helpers */ +static DBusMessage* new_call_msg(const char* method) +{ + DBusMessage* msg = dbus_message_new_method_call(CC_DBUS_NAME, CC_DBUS_PATH, CC_DBUS_IFACE, method); + if (!msg) + die_out_of_memory(); + return msg; +} +static DBusMessage* send_get_reply_and_unref(DBusMessage* msg) +{ + DBusError err; + dbus_error_init(&err); + DBusMessage *reply = dbus_connection_send_with_reply_and_block(s_dbus_conn, msg, /*timeout*/ -1, &err); + if (reply == NULL) + { +//analyse error + error_msg_and_die("Error sending DBus message"); + } + dbus_message_unref(msg); + return reply; +} + +static vector_crash_infos_t call_GetCrashInfos() +{ + DBusMessage* msg = new_call_msg("GetCrashInfos"); + + DBusMessage *reply = send_get_reply_and_unref(msg); + + vector_crash_infos_t argout; + DBusMessageIter in_iter; + if (!dbus_message_iter_init(reply, &in_iter)) /* no values */ + error_msg_and_die("dbus call %s: return type mismatch", "GetCrashInfos"); + int r = load_val(&in_iter, argout); + if (r != ABRT_DBUS_LAST_FIELD) /* more values present, or bad type */ + error_msg_and_die("dbus call %s: return type mismatch", "GetCrashInfos"); + dbus_message_unref(reply); + return argout; +} + +static map_crash_report_t call_CreateReport(const char* uuid) { - vector_crash_infos_t ci; - map_crash_report_t cr; - param_t param; - std::string answer = "n"; + DBusMessage* msg = new_call_msg("GetJobResult"); + dbus_message_append_args(msg, + DBUS_TYPE_STRING, &uuid, + DBUS_TYPE_INVALID); - parse_args(argc, argv, param); + DBusMessage *reply = send_get_reply_and_unref(msg); - if (param.m_Mode == HELP) + map_crash_report_t argout; + DBusMessageIter in_iter; + if (!dbus_message_iter_init(reply, &in_iter)) /* no values */ + error_msg_and_die("dbus call %s: return type mismatch", "GetJobResult"); + int r = load_val(&in_iter, argout); + if (r != ABRT_DBUS_LAST_FIELD) /* more values present, or bad type */ + error_msg_and_die("dbus call %s: return type mismatch", "GetJobResult"); + dbus_message_unref(reply); + return argout; +} + +static void call_Report(const map_crash_report_t& report) +{ + DBusMessage* msg = new_call_msg("Report"); + DBusMessageIter out_iter; + dbus_message_iter_init_append(msg, &out_iter); + store_val(&out_iter, report); + + DBusMessage *reply = send_get_reply_and_unref(msg); + //it returns a single value of report_status_t type, + //but we don't use it (yet?) + + dbus_message_unref(reply); + return; +} + +static void call_DeleteDebugDump(const char* uuid) +{ + DBusMessage* msg = new_call_msg("DeleteDebugDump"); + dbus_message_append_args(msg, + DBUS_TYPE_STRING, &uuid, + DBUS_TYPE_INVALID); + + DBusMessage *reply = send_get_reply_and_unref(msg); + //it returns a single boolean value, + //but we don't use it (yet?) + + dbus_message_unref(reply); + return; +} + +static void handle_dbus_err(bool error_flag, DBusError *err) +{ + if (dbus_error_is_set(err)) { - print_usage(argv[0]); - return 1; + error_msg("dbus error: %s", err->message); + /* dbus_error_free(&err); */ + error_flag = true; } - try + if (!error_flag) + return; + error_msg_and_die( + "error requesting DBus name %s, possible reasons: " + "abrt run by non-root; dbus config is incorrect", + CC_DBUS_NAME); +} + +static const struct option longopts[] = +{ + /* name, has_arg, flag, val */ + { "help" , no_argument , NULL, HELP }, + { "version" , no_argument , NULL, HELP }, + { "get-list" , no_argument , NULL, GET_LIST }, + { "get-list-full", no_argument , NULL, GET_LIST_FULL }, + { "report" , required_argument, NULL, REPORT }, + { "report-always", required_argument, NULL, REPORT_ALWAYS }, + { "delete" , required_argument, NULL, DELETE }, +}; + +int main(int argc, char** argv) +{ + char* uuid = NULL; + int op = -1; + + while (1) { -#ifdef ENABLE_DBUS - DBus::Glib::BusDispatcher dispatcher; - /* this should bind the dispatcher with mainloop */ - dispatcher.attach(NULL); - DBus::default_dispatcher = &dispatcher; - DBus::Connection conn = DBus::Connection::SystemBus(); - CCommLayerClientDBus ABRTDaemon(conn, CC_DBUS_PATH, CC_DBUS_NAME); - if(!conn.has_name(CC_DBUS_NAME)){ - std::cout << "Daemon is not running!" << std::endl; - return -1; - } -#elif ENABLE_SOCKET - CABRTSocket ABRTDaemon; - ABRTDaemon.Connect(SOCKET_FILE); -#endif - switch (param.m_Mode) + int option_index; + int c = getopt_long_only(argc, argv, "", longopts, &option_index); + switch (c) { - case GET_LIST: - ci = ABRTDaemon.GetCrashInfos(); - print_crash_infos(ci, GET_LIST); - break; - case GET_LIST_FULL: - ci = ABRTDaemon.GetCrashInfos(); - print_crash_infos(ci, GET_LIST_FULL); - break; case REPORT: - cr = ABRTDaemon.CreateReport(param.m_sUUID); - print_crash_report(cr); - std::cout << std::endl << "Do you want to send the report? [y/n]: "; - std::flush(std::cout); - std::cin >> answer; - if (answer == "Y" || answer == "y") - { - ABRTDaemon.Report(cr); - } - break; case REPORT_ALWAYS: - cr = ABRTDaemon.CreateReport(param.m_sUUID); - ABRTDaemon.Report(cr); - break; case DELETE: - ABRTDaemon.DeleteDebugDump(param.m_sUUID); - break; + uuid = optarg; + /* fall through */ + case GET_LIST: + case GET_LIST_FULL: + if (op == -1) + break; + /* fall through */ + case -1: /* end of options */ + if (op != -1) + break; + error_msg("You must specify exactly one operation."); + /* fall through */ default: - print_usage(argv[0]); - break; + case HELP: + char* progname = strrchr(argv[0], '/'); + if (progname) + progname++; + else + progname = argv[0]; + /* note: message has embedded tabs */ + std::cout << "Usage: " << progname << " [OPTION]\n\n" + " --get-list print list of crashes which are not reported\n" + " --get-list-full print list of all crashes\n" + " --report UUID create and send a report\n" + " --report-always UUID create and send a report without asking\n" + " --delete UUID delete crash\n"; + return 1; } -#if ENABLE_SOCKET - ABRTDaemon.DisConnect(); -#endif - + if (c == -1) + break; + op = c; } - catch (CABRTException& e) + +#ifdef ENABLE_DBUS + DBusError err; + dbus_error_init(&err); + s_dbus_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); + handle_dbus_err(s_dbus_conn == NULL, &err); +#elif ENABLE_SOCKET + CABRTSocket ABRTDaemon; + ABRTDaemon.Connect(VAR_RUN"/abrt.socket"); +#endif + switch (op) { - std::cout << e.what() << std::endl; + case GET_LIST: + case GET_LIST_FULL: + { + vector_crash_infos_t ci = call_GetCrashInfos(); + print_crash_infos(ci, op); + break; + } + case REPORT: + { + map_crash_report_t cr = call_CreateReport(uuid); + print_crash_report(cr); + std::cout << "\nDo you want to send the report? [y/n]: "; + std::flush(std::cout); + std::string answer = "n"; + std::cin >> answer; + if (answer == "Y" || answer == "y") + { + call_Report(cr); + } + break; + } + case REPORT_ALWAYS: + { + map_crash_report_t cr = call_CreateReport(uuid); + call_Report(cr); + break; + } + case DELETE: + { + call_DeleteDebugDump(uuid); + break; + } } +#if ENABLE_SOCKET + ABRTDaemon.DisConnect(); +#endif + return 0; } diff --git a/src/CLI/CommLayerClientDBus.cpp b/src/CLI/CommLayerClientDBus.cpp deleted file mode 100644 index 77983463..00000000 --- a/src/CLI/CommLayerClientDBus.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "CommLayerClientDBus.h" -CCommLayerClientDBus::CCommLayerClientDBus(DBus::Connection &connection, const char *path, const char *name) -: CDBusClient_proxy(connection), - DBus::ObjectProxy(connection, path, name) -{ -} -CCommLayerClientDBus::~CCommLayerClientDBus() -{ -}; - -void Crash(std::string &value) -{ - std::cout << "Another Crash?" << std::endl; -} diff --git a/src/CLI/CommLayerClientDBus.h b/src/CLI/CommLayerClientDBus.h deleted file mode 100644 index 9e63f58c..00000000 --- a/src/CLI/CommLayerClientDBus.h +++ /dev/null @@ -1,17 +0,0 @@ -#include <DBusCommon.h> -#include <DBusClientProxy.h> -#include <iostream> - -class CCommLayerClientDBus -: public CDBusClient_proxy, - public DBus::IntrospectableProxy, - public DBus::ObjectProxy -{ - public: - CCommLayerClientDBus(DBus::Connection &connection, const char *path, const char *name); - ~CCommLayerClientDBus(); - void Crash(std::string &value) - { - std::cout << "Another Crash?" << std::endl; - } -}; diff --git a/src/CLI/Makefile.am b/src/CLI/Makefile.am index 9823965e..9d7667eb 100644 --- a/src/CLI/Makefile.am +++ b/src/CLI/Makefile.am @@ -6,8 +6,7 @@ bin_PROGRAMS = abrt-cli abrt_cli_SOURCES = \ CLI.cpp \ - ABRTSocket.h ABRTSocket.cpp \ - CommLayerClientDBus.h CommLayerClientDBus.cpp + ABRTSocket.h ABRTSocket.cpp abrt_cli_CPPFLAGS = \ -I$(srcdir)/../../inc \ -I$(srcdir)/../../lib/Utils \ diff --git a/src/Daemon/CommLayerServerDBus.cpp b/src/Daemon/CommLayerServerDBus.cpp index d84a3345..8f913ad5 100644 --- a/src/Daemon/CommLayerServerDBus.cpp +++ b/src/Daemon/CommLayerServerDBus.cpp @@ -1,336 +1,13 @@ -#include <iostream> +//#include <iostream> #include <dbus/dbus.h> #include "abrtlib.h" +#include "abrt_dbus.h" #include "ABRTException.h" #include "CrashWatcher.h" #include "Settings.h" #include "Daemon.h" #include "CommLayerServerDBus.h" - -static DBusConnection* s_pConn; - - -/* - * Helpers for building DBus messages - */ - -//static void store_bool(DBusMessageIter* iter, bool val); -static void store_int32(DBusMessageIter* iter, int32_t val); -static void store_uint32(DBusMessageIter* iter, uint32_t val); -static void store_int64(DBusMessageIter* iter, int64_t val); -static void store_uint64(DBusMessageIter* iter, uint64_t val); -static void store_string(DBusMessageIter* iter, const char* val); - -//static inline void store_val(DBusMessageIter* iter, bool val) { store_bool(iter, val); } -static inline void store_val(DBusMessageIter* iter, int32_t val) { store_int32(iter, val); } -static inline void store_val(DBusMessageIter* iter, uint32_t val) { store_uint32(iter, val); } -static inline void store_val(DBusMessageIter* iter, int64_t val) { store_int64(iter, val); } -static inline void store_val(DBusMessageIter* iter, uint64_t val) { store_uint64(iter, val); } -static inline void store_val(DBusMessageIter* iter, const char* val) { store_string(iter, val); } -static inline void store_val(DBusMessageIter* iter, const std::string& val) { store_string(iter, val.c_str()); } - -//static void store_bool(DBusMessageIter* iter, bool val) -//{ -// dbus_bool_t db = val; -// if (!dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &db)) -// die_out_of_memory(); -//} -static void store_int32(DBusMessageIter* iter, int32_t val) -{ - if (!dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &val)) - die_out_of_memory(); -} -static void store_uint32(DBusMessageIter* iter, uint32_t val) -{ - if (!dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &val)) - die_out_of_memory(); -} -static void store_int64(DBusMessageIter* iter, int64_t val) -{ - if (!dbus_message_iter_append_basic(iter, DBUS_TYPE_INT64, &val)) - die_out_of_memory(); -} -static void store_uint64(DBusMessageIter* iter, uint64_t val) -{ - if (!dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT64, &val)) - die_out_of_memory(); -} -static void store_string(DBusMessageIter* iter, const char* val) -{ - if (!dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &val)) - die_out_of_memory(); -} - -/* Templates for vector and map */ -template <typename T> struct type {}; -//template <> struct type<bool> { static const char* csig() { return "b"; } }; -template <> struct type<int32_t> { static const char* csig() { return "i"; } static std::string sig(); }; -template <> struct type<uint32_t> { static const char* csig() { return "u"; } static std::string sig(); }; -template <> struct type<int64_t> { static const char* csig() { return "x"; } static std::string sig(); }; -template <> struct type<uint64_t> { static const char* csig() { return "t"; } static std::string sig(); }; -template <> struct type<std::string> { static const char* csig() { return "s"; } static std::string sig(); }; -#define SIG(T) (type<T>::csig() ? type<T>::csig() : type<T>::sig().c_str()) -template <typename E> -struct type< std::vector<E> > { - static const char* csig() { return NULL; } - static std::string sig() { return ssprintf("a%s", SIG(E)); } -}; -template <typename K, typename V> -struct type< std::map<K,V> > { - static const char* csig() { return NULL; } - static std::string sig() { return ssprintf("a{%s%s}", SIG(K), SIG(V)); } -}; - -template<typename E> -static void store_vector(DBusMessageIter* iter, const std::vector<E>& val) -{ - DBusMessageIter sub_iter; - if (!dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, SIG(E), &sub_iter)) - die_out_of_memory(); - - typename std::vector<E>::const_iterator vit = val.begin(); - for (; vit != val.end(); ++vit) - { - store_val(&sub_iter, *vit); - } - - if (!dbus_message_iter_close_container(iter, &sub_iter)) - die_out_of_memory(); -} -/* -template<> -static void store_vector(DBus::MessageIter &iter, const std::vector<uint8_t>& val) -{ - if we use such vector, MUST add specialized code here (see in dbus-c++ source) -} -*/ -template<typename K, typename V> -static void store_map(DBusMessageIter* iter, const std::map<K,V>& val) -{ - DBusMessageIter sub_iter; - if (!dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, - ssprintf("{%s%s}", SIG(K), SIG(V)).c_str(), - &sub_iter)) - die_out_of_memory(); - - typename std::map<K,V>::const_iterator mit = val.begin(); - for (; mit != val.end(); ++mit) - { - DBusMessageIter sub_sub_iter; - if (!dbus_message_iter_open_container(&sub_iter, DBUS_TYPE_DICT_ENTRY, NULL, &sub_sub_iter)) - die_out_of_memory(); - store_val(&sub_sub_iter, mit->first); - store_val(&sub_sub_iter, mit->second); - if (!dbus_message_iter_close_container(&sub_iter, &sub_sub_iter)) - die_out_of_memory(); - } - - if (!dbus_message_iter_close_container(iter, &sub_iter)) - die_out_of_memory(); -} - -template<typename E> -static inline void store_val(DBusMessageIter* iter, const std::vector<E>& val) { store_vector(iter, val); } -template<typename K, typename V> -static inline void store_val(DBusMessageIter* iter, const std::map<K,V>& val) { store_map(iter, val); } - - -/* - * Helpers for parsing DBus messages - */ - -enum { - ERROR = -1, - LAST_FIELD = 0, - MORE_FIELDS = 1, -}; -/* Checks type, loads data, advances to the next arg. - * Returns TRUE if next arg exists. - */ -//static int load_bool(DBusMessageIter* iter, bool& val); -static int load_int32(DBusMessageIter* iter, int32_t &val); -static int load_uint32(DBusMessageIter* iter, uint32_t &val); -static int load_int64(DBusMessageIter* iter, int64_t &val); -static int load_uint64(DBusMessageIter* iter, uint64_t &val); -static int load_charp(DBusMessageIter* iter, const char*& val); -//static inline int load_val(DBusMessageIter* iter, bool &val) { return load_bool(iter, val); } -static inline int load_val(DBusMessageIter* iter, int32_t &val) { return load_int32(iter, val); } -static inline int load_val(DBusMessageIter* iter, uint32_t &val) { return load_uint32(iter, val); } -static inline int load_val(DBusMessageIter* iter, int64_t &val) { return load_int64(iter, val); } -static inline int load_val(DBusMessageIter* iter, uint64_t &val) { return load_uint64(iter, val); } -static inline int load_val(DBusMessageIter* iter, const char*& val) { return load_charp(iter, val); } -static inline int load_val(DBusMessageIter* iter, std::string& val) -{ - const char* str; - int r = load_charp(iter, str); - val = str; - return r; -} - -//static int load_bool(DBusMessageIter* iter, bool& val) -//{ -// int type = dbus_message_iter_get_arg_type(iter); -// if (type != DBUS_TYPE_BOOLEAN) -// error_msg_and_die("%s expected in dbus message, but not found ('%c')", "bool", type); -// dbus_bool_t db; -// dbus_message_iter_get_basic(iter, &db); -// val = db; -// return dbus_message_iter_next(iter); -//} -static int load_int32(DBusMessageIter* iter, int32_t& val) -{ - int type = dbus_message_iter_get_arg_type(iter); - if (type != DBUS_TYPE_INT32) - { - error_msg("%s expected in dbus message, but not found ('%c')", "int32", type); - return -1; - } - dbus_message_iter_get_basic(iter, &val); - return dbus_message_iter_next(iter); -} -static int load_uint32(DBusMessageIter* iter, uint32_t& val) -{ - int type = dbus_message_iter_get_arg_type(iter); - if (type != DBUS_TYPE_UINT32) - { - error_msg("%s expected in dbus message, but not found ('%c')", "uint32", type); - return -1; - } - dbus_message_iter_get_basic(iter, &val); - return dbus_message_iter_next(iter); -} -static int load_int64(DBusMessageIter* iter, int64_t& val) -{ - int type = dbus_message_iter_get_arg_type(iter); - if (type != DBUS_TYPE_INT64) - { - error_msg("%s expected in dbus message, but not found ('%c')", "int64", type); - return -1; - } - dbus_message_iter_get_basic(iter, &val); - return dbus_message_iter_next(iter); -} -static int load_uint64(DBusMessageIter* iter, uint64_t& val) -{ - int type = dbus_message_iter_get_arg_type(iter); - if (type != DBUS_TYPE_UINT64) - { - error_msg("%s expected in dbus message, but not found ('%c')", "uint64", type); - return -1; - } - dbus_message_iter_get_basic(iter, &val); - return dbus_message_iter_next(iter); -} -static int load_charp(DBusMessageIter* iter, const char*& val) -{ - int type = dbus_message_iter_get_arg_type(iter); - if (type != DBUS_TYPE_STRING) - { - error_msg("%s expected in dbus message, but not found ('%c')", "string", type); - return -1; - } - dbus_message_iter_get_basic(iter, &val); -//log("load_charp:'%s'", val); - return dbus_message_iter_next(iter); -} - -/* Templates for vector and map */ -template<typename E> -static int load_vector(DBusMessageIter* iter, std::vector<E>& val) -{ - int type = dbus_message_iter_get_arg_type(iter); - if (type != DBUS_TYPE_ARRAY) - { - error_msg("array expected in dbus message, but not found ('%c')", type); - return -1; - } - - DBusMessageIter sub_iter; - dbus_message_iter_recurse(iter, &sub_iter); - - int r; -//int cnt = 0; - //type = dbus_message_iter_get_arg_type(&sub_iter); - /* here "type" is the element's type, and it will be checked by load_val */ - // if (type != DBUS_TYPE_INVALID) - not needed? - do { - E elem; -//cnt++; - r = load_val(&sub_iter, elem); - if (r < 0) - return r; - val.push_back(elem); - } while (r == MORE_FIELDS); -//log("%s: %d elems", __func__, cnt); - - return dbus_message_iter_next(iter); -} -/* -template<> -static int load_vector(DBusMessageIter* iter, std::vector<uint8_t>& val) -{ - if we use such vector, MUST add specialized code here (see in dbus-c++ source) -} -*/ -template<typename K, typename V> -static int load_map(DBusMessageIter* iter, std::map<K,V>& val) -{ - int type = dbus_message_iter_get_arg_type(iter); - if (type != DBUS_TYPE_ARRAY) - { - error_msg("array expected in dbus message, but not found ('%c')", type); - return -1; - } - - DBusMessageIter sub_iter; - dbus_message_iter_recurse(iter, &sub_iter); - - bool next_exists; - int r; -//int cnt = 0; - do { - type = dbus_message_iter_get_arg_type(&sub_iter); - if (type != DBUS_TYPE_DICT_ENTRY) - { - error_msg("sub_iter type is not DBUS_TYPE_DICT_ENTRY (%c)!", type); - return -1; - } - - DBusMessageIter sub_sub_iter; - dbus_message_iter_recurse(&sub_iter, &sub_sub_iter); - - K key; - r = load_val(&sub_sub_iter, key); - if (r != MORE_FIELDS) - { - if (r == LAST_FIELD) - error_msg("malformed map element in dbus message"); - return -1; - } - V value; - r = load_val(&sub_sub_iter, value); - if (r != LAST_FIELD) - { - if (r == MORE_FIELDS) - error_msg("malformed map element in dbus message"); - return -1; - } - val[key] = value; -//cnt++; - next_exists = dbus_message_iter_next(&sub_iter); - } while (next_exists); -//log("%s: %d elems", __func__, cnt); - - return dbus_message_iter_next(iter); -} - -template<typename E> -static inline int load_val(DBusMessageIter* iter, std::vector<E>& val) { return load_vector(iter, val); } -template<typename K, typename V> -static inline int load_val(DBusMessageIter* iter, std::map<K,V>& val) { return load_map(iter, val); } - - /* * DBus signal emitters */ @@ -349,9 +26,9 @@ static DBusMessage* new_signal_msg(const char* member, const char* peer = NULL) } static void send_flush_and_unref(DBusMessage* msg) { - if (!dbus_connection_send(s_pConn, msg, NULL /* &serial */)) + if (!dbus_connection_send(g_dbus_conn, msg, NULL /* &serial */)) error_msg_and_die("Error sending DBus message"); - dbus_connection_flush(s_pConn); + dbus_connection_flush(g_dbus_conn); VERB3 log("DBus message sent"); dbus_message_unref(msg); } @@ -427,7 +104,7 @@ static long get_remote_uid(DBusMessage* call, const char** ppSender = NULL) const char* sender = dbus_message_get_sender(call); if (ppSender) *ppSender = sender; - long uid = dbus_bus_get_unix_user(s_pConn, sender, &err); + long uid = dbus_bus_get_unix_user(g_dbus_conn, sender, &err); if (dbus_error_is_set(&err)) { dbus_error_free(&err); @@ -461,9 +138,9 @@ static int handle_CreateReport(DBusMessage* call, DBusMessage* reply) return -1; } int r = load_val(&in_iter, pUUID); - if (r != LAST_FIELD) + if (r != ABRT_DBUS_LAST_FIELD) { - if (r == MORE_FIELDS) + if (r == ABRT_DBUS_MORE_FIELDS) error_msg("dbus call %s: extra parameters", "CreateReport"); return -1; } @@ -492,9 +169,9 @@ static int handle_GetJobResult(DBusMessage* call, DBusMessage* reply) return -1; } int r = load_val(&in_iter, pUUID); - if (r != LAST_FIELD) + if (r != ABRT_DBUS_LAST_FIELD) { - if (r == MORE_FIELDS) + if (r == ABRT_DBUS_MORE_FIELDS) error_msg("dbus call %s: extra parameters", "GetJobResult"); return -1; } @@ -521,9 +198,9 @@ static int handle_Report(DBusMessage* call, DBusMessage* reply) return -1; } int r = load_val(&in_iter, argin1); - if (r != LAST_FIELD) + if (r != ABRT_DBUS_LAST_FIELD) { - if (r == MORE_FIELDS) + if (r == ABRT_DBUS_MORE_FIELDS) error_msg("dbus call %s: extra parameters", "Report"); return -1; } @@ -563,9 +240,9 @@ static int handle_DeleteDebugDump(DBusMessage* call, DBusMessage* reply) return -1; } int r = load_val(&in_iter, argin1); - if (r != LAST_FIELD) + if (r != ABRT_DBUS_LAST_FIELD) { - if (r == MORE_FIELDS) + if (r == ABRT_DBUS_MORE_FIELDS) error_msg("dbus call %s: extra parameters", "DeleteDebugDump"); return -1; } @@ -604,9 +281,9 @@ static int handle_GetPluginSettings(DBusMessage* call, DBusMessage* reply) return -1; } int r = load_val(&in_iter, PluginName); - if (r != LAST_FIELD) + if (r != ABRT_DBUS_LAST_FIELD) { - if (r == MORE_FIELDS) + if (r == ABRT_DBUS_MORE_FIELDS) error_msg("dbus call %s: extra parameters", "GetPluginSettings"); return -1; } @@ -632,17 +309,17 @@ static int handle_SetPluginSettings(DBusMessage* call, DBusMessage* reply) } std::string PluginName; int r = load_val(&in_iter, PluginName); - if (r != MORE_FIELDS) + if (r != ABRT_DBUS_MORE_FIELDS) { - if (r == LAST_FIELD) + if (r == ABRT_DBUS_LAST_FIELD) error_msg("dbus call %s: too few parameters", "SetPluginSettings"); return -1; } map_plugin_settings_t plugin_settings; r = load_val(&in_iter, plugin_settings); - if (r != LAST_FIELD) + if (r != ABRT_DBUS_LAST_FIELD) { - if (r == MORE_FIELDS) + if (r == ABRT_DBUS_MORE_FIELDS) error_msg("dbus call %s: extra parameters", "SetPluginSettings"); return -1; } @@ -665,9 +342,9 @@ static int handle_RegisterPlugin(DBusMessage* call, DBusMessage* reply) } const char* PluginName; int r = load_val(&in_iter, PluginName); - if (r != LAST_FIELD) + if (r != ABRT_DBUS_LAST_FIELD) { - if (r == MORE_FIELDS) + if (r == ABRT_DBUS_MORE_FIELDS) error_msg("dbus call %s: extra parameters", "RegisterPlugin"); return -1; } @@ -689,9 +366,9 @@ static int handle_UnRegisterPlugin(DBusMessage* call, DBusMessage* reply) } const char* PluginName; int r = load_val(&in_iter, PluginName); - if (r != LAST_FIELD) + if (r != ABRT_DBUS_LAST_FIELD) { - if (r == MORE_FIELDS) + if (r == ABRT_DBUS_MORE_FIELDS) error_msg("dbus call %s: extra parameters", "UnRegisterPlugin"); return -1; } @@ -724,9 +401,9 @@ static int handle_SetSettings(DBusMessage* call, DBusMessage* reply) } map_abrt_settings_t param1; int r = load_val(&in_iter, param1); - if (r != LAST_FIELD) + if (r != ABRT_DBUS_LAST_FIELD) { - if (r == MORE_FIELDS) + if (r == ABRT_DBUS_MORE_FIELDS) error_msg("dbus call %s: extra parameters", "SetSettings"); return -1; } @@ -770,7 +447,7 @@ static gboolean handle_dbus(GIOChannel *gio, GIOCondition condition, gpointer da */ dbus_watch_handle(watch, dbus_flags); - while (dbus_connection_dispatch(s_pConn) == DBUS_DISPATCH_DATA_REMAINS) + while (dbus_connection_dispatch(g_dbus_conn) == DBUS_DISPATCH_DATA_REMAINS) VERB3 log("%s: more data to process, looping", __func__); return TRUE; /* "glib, do not remove this even source!" */ } @@ -967,7 +644,7 @@ CCommLayerServerDBus::CCommLayerServerDBus() dbus_error_init(&err); VERB3 log("dbus_bus_get"); - s_pConn = conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); + g_dbus_conn = conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); handle_dbus_err(conn == NULL, &err); //do we need this? why? @@ -1016,5 +693,5 @@ CCommLayerServerDBus::CCommLayerServerDBus() CCommLayerServerDBus::~CCommLayerServerDBus() { -// do we need to do something here? +// do we need to do anything here? } |