diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | lib/DBus/DBusClient.cpp | 51 | ||||
-rw-r--r-- | lib/DBus/DBusClient.h | 38 | ||||
-rw-r--r-- | lib/DBus/DBusClientProxy.h | 85 | ||||
-rw-r--r-- | lib/DBus/DBusCommon.h | 28 | ||||
-rw-r--r-- | lib/DBus/DBusManager.cpp | 179 | ||||
-rw-r--r-- | lib/DBus/DBusManager.h | 26 | ||||
-rw-r--r-- | lib/DBus/DBusServer.cpp | 47 | ||||
-rw-r--r-- | lib/DBus/DBusServer.h | 34 | ||||
-rw-r--r-- | lib/DBus/DBusServerProxy.h | 114 | ||||
-rw-r--r-- | lib/DBus/DbusClient.h | 15 | ||||
-rw-r--r-- | lib/DBus/Makefile.am | 23 | ||||
-rw-r--r-- | lib/DBus/test.cpp | 28 | ||||
-rw-r--r-- | lib/DBus/test_client.cpp | 61 | ||||
-rw-r--r-- | lib/DBus/test_server.cpp | 45 | ||||
-rw-r--r-- | src/Applet/Applet.cpp | 50 | ||||
-rw-r--r-- | src/Applet/CCApplet.cpp | 53 | ||||
-rw-r--r-- | src/Applet/CCApplet.h | 13 | ||||
-rw-r--r-- | src/Applet/Makefile.am | 4 | ||||
-rw-r--r-- | src/Daemon/CrashWatcher.cpp | 27 | ||||
-rw-r--r-- | src/Daemon/CrashWatcher.h | 7 | ||||
-rw-r--r-- | src/Daemon/Makefile.am | 5 |
22 files changed, 709 insertions, 226 deletions
diff --git a/configure.ac b/configure.ac index baefc132..abc1c3cb 100644 --- a/configure.ac +++ b/configure.ac @@ -10,6 +10,8 @@ AC_PROG_CXX PKG_CHECK_MODULES([DBUS_GLIB], [dbus-glib-1]) PKG_CHECK_MODULES([SQLITE3], [sqlite3]) PKG_CHECK_MODULES([GTKMM], [gtkmm-2.4]) +PKG_CHECK_MODULES([GLIBMM], [glibmm-2.4]) +PKG_CHECK_MODULES([DBUSCPP], [dbus-c++-1]) PKG_CHECK_MODULES([PACKAGEKIT_GLIB], [packagekit-glib]) PKG_CHECK_MODULES([RPM], [rpm]) diff --git a/lib/DBus/DBusClient.cpp b/lib/DBus/DBusClient.cpp new file mode 100644 index 00000000..cb9c3a0e --- /dev/null +++ b/lib/DBus/DBusClient.cpp @@ -0,0 +1,51 @@ +/* + Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com) + 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 + 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 "DBusClient.h" +#include <iostream> + +CDBusClient::CDBusClient(DBus::Connection &connection, const char *path, const char *name) +: DBus::ObjectProxy(connection, path, name) +{ + m_pCrashHandler = NULL; + std::cerr << "Client created" << std::endl; +} + +CDBusClient::~CDBusClient() +{ + //clean +} + +void CDBusClient::Crash(std::string &value) +{ + if(m_pCrashHandler) + { + m_pCrashHandler(value.c_str()); + } + else + { + std::cout << "This is default handler, you should register your own with ConnectCrashHandler" << std::endl; + std::cout.flush(); + } +} + +void CDBusClient::ConnectCrashHandler(void (*pCrashHandler)(const char *progname)) +{ + m_pCrashHandler = pCrashHandler; +} diff --git a/lib/DBus/DBusClient.h b/lib/DBus/DBusClient.h new file mode 100644 index 00000000..5460141c --- /dev/null +++ b/lib/DBus/DBusClient.h @@ -0,0 +1,38 @@ +/* + Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com) + 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 + 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 <dbus-c++/dbus.h> +#include "DBusClientProxy.h" + +class CDBusClient +: public CDBusClient_proxy, + public DBus::IntrospectableProxy, + public DBus::ObjectProxy +{ +private: + /* the real signal handler called to handle the signal */ + void (*m_pCrashHandler)(const char *progname); +public: + + CDBusClient(DBus::Connection &connection, const char *path, const char *name); + ~CDBusClient(); + void ConnectCrashHandler(void (*pCrashHandler)(const char *progname)); + void Crash(std::string &value); +}; + diff --git a/lib/DBus/DBusClientProxy.h b/lib/DBus/DBusClientProxy.h new file mode 100644 index 00000000..f0b8a001 --- /dev/null +++ b/lib/DBus/DBusClientProxy.h @@ -0,0 +1,85 @@ +/* + Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com) + 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 + 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 <dbus-c++/dbus.h> +#include <dbus-c++/glib-integration.h> +#include "DBusCommon.h" + +class CDBusClient_proxy + : public DBus::InterfaceProxy +{ +public: + + CDBusClient_proxy() + : DBus::InterfaceProxy(CC_DBUS_IFACE) + { + //# define connect_signal(interface, signal, callback) + connect_signal(CDBusClient_proxy, Crash, _Crash_stub); + } + +public: + + /* properties exported by this interface */ +public: + + /* methods exported by this interface, + * this functions will invoke the corresponding methods on the remote objects + */ + /* + + < + <m_sUUID;m_sUID;m_sCount;m_sExecutable;m_sPackage> + <m_sUUID;m_sUID;m_sCount;m_sExecutable;m_sPackage> + <m_sUUID;m_sUID;m_sCount;m_sExecutable;m_sPackage> + ... + > + */ + dbus_vector_crash_infos_t GetCrashInfos(const std::string &pUID) + { + DBus::CallMessage call; + + DBus::MessageIter wi = call.writer(); + + wi << pUID; + call.member("GetCrashInfos"); + DBus::Message ret = invoke_method(call); + DBus::MessageIter ri = ret.reader(); + + dbus_vector_crash_infos_t argout; + ri >> argout; + return argout; + } +public: + + /* signal handlers for this interface + */ + virtual void Crash(std::string& value) = 0; + +private: + + /* unmarshalers (to unpack the DBus message before calling the actual signal handler) + */ + void _Crash_stub(const ::DBus::SignalMessage &sig) + { + DBus::MessageIter ri = sig.reader(); + + std::string value; ri >> value; + Crash(value); + } +}; diff --git a/lib/DBus/DBusCommon.h b/lib/DBus/DBusCommon.h new file mode 100644 index 00000000..8b36d82d --- /dev/null +++ b/lib/DBus/DBusCommon.h @@ -0,0 +1,28 @@ +/* + Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com) + 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 + 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. + */ + +/* we need this to know the data structures */ +#include "MiddleWare.h" + +#define CC_DBUS_NAME "com.redhat.CrashCatcher" +#define CC_DBUS_PATH "/com/redhat/CrashCatcher" +#define CC_DBUS_IFACE "com.redhat.CrashCatcher" + +//typedef std::vector<crash_info_t> vector_crash_infos_t; +typedef std::vector< std::vector<std::string> > dbus_vector_crash_infos_t; diff --git a/lib/DBus/DBusManager.cpp b/lib/DBus/DBusManager.cpp index 0b2cb97f..456c1786 100644 --- a/lib/DBus/DBusManager.cpp +++ b/lib/DBus/DBusManager.cpp @@ -19,185 +19,48 @@ #include "DBusManager.h" #include <iostream> -#include <marshal.h> - -// only for testing - used by LoopSend() -static gboolean send_message(DBusGConnection *con) -{ - DBusMessage *message; - /* Create a new signal "Crash" on the "com.redhat.CrashCatcher" interface, - * from the object "/com/redhat/CrashCatcher". */ - message = dbus_message_new_signal("/com/redhat/CrashCatcher/Crash", - "com.redhat.CrashCatcher", "Crash"); - if(!message){ - fprintf(stderr,"Message creating error"); - } - char *progname = "Foo"; - /* Append some info to the signal */ - dbus_message_append_args(message,DBUS_TYPE_STRING, &progname, DBUS_TYPE_INVALID); - /* get the DBusConnection */ - DBusConnection *dbus_con = dbus_g_connection_get_connection(con); - /* Send the signal via low level dbus function coz glib doesn't seem to work */ - if(!dbus_connection_send(dbus_con, message, NULL)){ - printf("Error while sending message\n"); - } - printf("flushing bus %p\n", dbus_con); - dbus_connection_flush(dbus_con); - /* Free the signal */ - dbus_message_unref(message); - /* Tell the user we send a signal */ - g_print("Message sent!\n"); - /* Return TRUE to tell the event loop we want to be called again */ - return TRUE; -} - +#include "marshal.h" CDBusManager::CDBusManager() { - GError *error = NULL; - g_type_init(); - /* first we need to connect to dbus */ - m_nBus = dbus_g_bus_get(DBUS_BUS, &error); - if(!m_nBus) - throw std::string("Couldn't connect to dbus") + error->message; + DBus::default_dispatcher = new DBus::Glib::BusDispatcher(); + m_pConn = new DBus::Connection(DBus::Connection::SessionBus()); + } CDBusManager::~CDBusManager() { + //delete DBus::default_dispatcher + // delete m_pConn } /* register name com.redhat.CrashCatcher on dbus */ void CDBusManager::RegisterService() { - GError *error = NULL; - guint request_name_result; - g_type_init(); - // then we need a proxy to talk to dbus - m_nBus_proxy = dbus_g_proxy_new_for_name(m_nBus, DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS); - if(!m_nBus_proxy){ - std::cerr << "Error while creating dbus proxy!" << error->message << std::endl; - } - /* and register our name */ - if (!dbus_g_proxy_call(m_nBus_proxy, "RequestName", &error, - G_TYPE_STRING, CC_DBUS_NAME, - G_TYPE_UINT, 0, - G_TYPE_INVALID, - G_TYPE_UINT, &request_name_result, - G_TYPE_INVALID)) + /* this can lead to race condition - rewrite with better check */ + if(m_pConn->has_name(CC_DBUS_NAME)) { - throw std::string("Failed to acquire com.redhat.CrashCatcher:") + error->message ; + /* shouldn't happen, but ... */ + throw std::string("Name already taken: ") + CC_DBUS_NAME; } + /* register our name */ + m_pConn->request_name(CC_DBUS_NAME,DBUS_NAME_FLAG_DO_NOT_QUEUE); #ifdef DEBUG std::cout << "Service running" << std::endl; #endif } -void CDBusManager::ConnectToDaemon() -{ - GError *error = NULL; - guint request_name_result; - g_type_init(); - /* create a proxy object to talk and listen to CC daemon */ - m_nCCBus_proxy = dbus_g_proxy_new_for_name_owner(m_nBus, CC_DBUS_NAME, - CC_DBUS_PATH_NOTIFIER, - CC_DBUS_IFACE, &error); - if(!m_nCCBus_proxy){ -#ifdef DEBUG - std::cerr << "Couldn't connect to daemon via dbus: " << error->message << std::endl; -#endif - throw std::string(error->message); - } -#ifdef DEBUG - std::cout << "Connected! Waiting for signals\n" << std::endl; -#endif -} - -void CDBusManager::RegisterToMessage(const std::string& pMessage, GCallback handler, void * data, GClosureNotify free_data_func) -{ -#ifdef DEBUG - std::cout << "Trying to register" << std::endl; -#endif /*DEBUG*/ - /* Register dbus signal marshaller */ - dbus_g_object_register_marshaller(marshal_VOID__STRING, - G_TYPE_NONE, G_TYPE_STRING, - G_TYPE_INVALID); - dbus_g_proxy_add_signal(m_nCCBus_proxy,"Crash",G_TYPE_STRING, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(m_nCCBus_proxy,"Crash",handler,NULL, NULL); -#ifdef DEBUG - std::cout << "Register done" << std::endl; -#endif /*DEBUG*/ -} - -bool CDBusManager::GSendMessage(const std::string& pMessage, const std::string& pMessParam) -{ - DBusMessage *message; - /* Create a new signal "Crash" on the "com.redhat.CrashCatcher" interface, - * from the object "/com/redhat/CrashCatcher/Crash". */ - message = dbus_message_new_signal ("/com/redhat/CrashCatcher/Crash", - "com.redhat.CrashCatcher", pMessage.c_str()); - if(!message){ - std::cerr << "Message creating error" << std::endl; - } -#ifdef DEBUG - std::cerr << message << std::endl; -#endif - const char *progname = pMessParam.c_str(); - /* Append some info to the signal */ - dbus_message_append_args(message,DBUS_TYPE_STRING, &progname, DBUS_TYPE_INVALID); - /* Send the signal */ - dbus_g_proxy_send(m_nCCBus_proxy, message, NULL); - /* Free the signal */ - dbus_message_unref(message); -#ifdef DEBUG - g_print("Message sent!\n"); -#endif - /* Return TRUE to tell the event loop we want to be called again */ - return TRUE; -} - bool CDBusManager::SendMessage(const std::string& pMessage, const std::string& pMessParam) { - DBusMessage *message; const char *progname = pMessParam.c_str(); - /* Create a new signal "Crash" on the "com.redhat.CrashCatcher" interface, - * from the object "/com/redhat/CrashCatcher/Crash". */ - message = dbus_message_new_signal ("/com/redhat/CrashCatcher/Crash", - "com.redhat.CrashCatcher", pMessage.c_str()); - if(!message){ - std::cerr << "Message creating error" << std::endl; - } -#ifdef DEBUG - std::cerr << message << std::endl; -#endif - /* Add program name as the message argument */ - dbus_message_append_args(message,DBUS_TYPE_STRING, &progname, DBUS_TYPE_INVALID); - /* Send the signal */ - DBusConnection *dbus_con = dbus_g_connection_get_connection(m_nBus); - /* Send the signal via low level dbus functio coz glib sucks */ - if(!dbus_connection_send(dbus_con, message, NULL)){ - throw "Error while sending message"; - } - /* flush the connection, otherwise, it won't show on dbus? */ - dbus_connection_flush(dbus_con); - /* Free the signal */ - dbus_message_unref(message); -#ifdef DEBUG - g_print("Message sent!\n"); -#endif - /* Return TRUE to tell the event loop we want to be called again */ + DBus::SignalMessage mess(CC_DBUS_PATH, CC_DBUS_NAME, pMessage.c_str()); + /* append some info to the signal */ + mess.append(DBUS_TYPE_STRING,&progname,DBUS_TYPE_INVALID); + /* send the message */ + m_pConn->send(mess); + /* flush - to make sure it's not stuck in queue */ + // probably not needed + //m_pConn->flush(); + std::cerr << "Message sent!" << std::endl; return TRUE; } - - -// just for testing purposes -void CDBusManager::LoopSend() -{ - g_timeout_add(1000, (GSourceFunc)send_message, m_nBus); -} - -void CDBusManager::Unregister() -{ - std::cerr << "Unregister" << std::endl; -} diff --git a/lib/DBus/DBusManager.h b/lib/DBus/DBusManager.h index f29d5d47..34181698 100644 --- a/lib/DBus/DBusManager.h +++ b/lib/DBus/DBusManager.h @@ -20,11 +20,11 @@ #ifndef DBUS_H_ #define DBUS_H_ -#include <dbus/dbus-glib.h> -#include <dbus/dbus-glib-lowlevel.h> -#include <dbus/dbus.h> -#include <glib.h> #include <string> +#include <dbus/dbus.h> +//#include <glibmm.h> +#include <dbus-c++/glib-integration.h> +#include <dbus-c++/dbus.h> #define CC_DBUS_NAME "com.redhat.CrashCatcher" #define CC_DBUS_PATH "/com/redhat/CrashCatcher" @@ -32,25 +32,19 @@ #define DBUS_BUS DBUS_BUS_SYSTEM #define CC_DBUS_PATH_NOTIFIER "/com/redhat/CrashCatcher/Crash" + + class CDBusManager { private: - DBusGConnection *m_nBus; - DBusGProxy *m_nBus_proxy; - DBusGProxy *m_nCCBus_proxy; - + DBus::Glib::BusDispatcher *m_pDispatcher; + DBus::Connection *m_pConn; public: CDBusManager(); ~CDBusManager(); - bool SendMessage(const std::string& pMessage, const std::string& pMessParam); - bool GSendMessage(const std::string& pMessage, const std::string& pMessParam); void RegisterService(); - void ConnectToService(); - void ConnectToDaemon(); - void LoopSend(); - void Unregister(); - void RegisterToMessage(const std::string& pMessage, GCallback handler, void * data, GClosureNotify free_data_func); - /** TODO + bool SendMessage(const std::string& pMessage, const std::string& pMessParam); + /** TODO //tries to reconnect after daemon failure void Reconnect(); */ diff --git a/lib/DBus/DBusServer.cpp b/lib/DBus/DBusServer.cpp new file mode 100644 index 00000000..2f92c966 --- /dev/null +++ b/lib/DBus/DBusServer.cpp @@ -0,0 +1,47 @@ +/* + Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com) + 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 + 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 "DBusServer.h" + +CDBusServer::CDBusServer(DBus::Connection &connection, const std::string& pServerPath) +: DBus::ObjectAdaptor(connection, pServerPath) +{ +} + +dbus_vector_crash_infos_t CDBusServer::GetCrashInfos(const std::string &pUID) +{ + dbus_vector_crash_infos_t info; + //CMiddleWare mw; + //mw.GetCrashInfos(); + std::vector<std::string> v; + v.push_back("vector1_prvek1"); + v.push_back("vector1_prvek_1"); + info.push_back(v); + v.clear(); + v.push_back("vector2_prvek1"); + v.push_back("vector2_prvek_1"); + v.push_back(pUID); + info.push_back(v); + return info; +} + +CDBusServer::~CDBusServer() +{ + //clean +} diff --git a/lib/DBus/DBusServer.h b/lib/DBus/DBusServer.h new file mode 100644 index 00000000..17f93939 --- /dev/null +++ b/lib/DBus/DBusServer.h @@ -0,0 +1,34 @@ +/* + Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com) + 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 + 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 <dbus-c++/dbus.h> +#include "DBusServerProxy.h" + +class CDBusServer +: public CDBusServer_adaptor, + public DBus::IntrospectableAdaptor, + public DBus::ObjectAdaptor +{ +public: + CDBusServer(DBus::Connection& connection, const std::string& pServerPath); + ~CDBusServer(); + int32_t Sum(const std::vector<int32_t> & ints); + dbus_vector_crash_infos_t GetCrashInfos(const std::string &pUID); +}; + diff --git a/lib/DBus/DBusServerProxy.h b/lib/DBus/DBusServerProxy.h new file mode 100644 index 00000000..a32bbc3d --- /dev/null +++ b/lib/DBus/DBusServerProxy.h @@ -0,0 +1,114 @@ +/* + Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com) + 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 + 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 <dbus-c++/dbus.h> +#include <dbus-c++/glib-integration.h> +#include "DBusCommon.h" + +class CDBusServer_adaptor +: public DBus::InterfaceAdaptor +{ +public: + + CDBusServer_adaptor() + : DBus::InterfaceAdaptor(CC_DBUS_IFACE) + { + register_method(CDBusServer_adaptor, GetCrashInfos, _GetCrashInfos_stub); + } + + DBus::IntrospectedInterface *const introspect() const + { + static DBus::IntrospectedArgument GetCrashInfos_args[] = + { + { "uid", "i", true}, + { "info", "aas", false }, + { 0, 0, 0 } + }; + static DBus::IntrospectedArgument Crash_args[] = + { + { "value", "v", false }, + { 0, 0, 0 } + }; + static DBus::IntrospectedMethod CDBusServer_adaptor_methods[] = + { + { "GetDumps", GetCrashInfos_args }, + { 0, 0 } + }; + static DBus::IntrospectedMethod CDBusServer_adaptor_signals[] = + { + { "Echoed", Crash_args }, + { 0, 0 } + }; + static DBus::IntrospectedProperty CDBusServer_adaptor_properties[] = + { + { 0, 0, 0, 0 } + }; + static DBus::IntrospectedInterface CDBusServer_adaptor_interface = + { + "com.redhat.CrashCatcher", + CDBusServer_adaptor_methods, + CDBusServer_adaptor_signals, + CDBusServer_adaptor_properties + }; + return &CDBusServer_adaptor_interface; + } + +public: + + /* properties exposed by this interface, use + * property() and property(value) to get and set a particular property + */ + +public: + + /* methods exported by this interface, + * you will have to implement them in your ObjectAdaptor + */ + virtual dbus_vector_crash_infos_t GetCrashInfos(const std::string &pUID) = 0; + +public: + + /* signal emitters for this interface + */ + void Crash(const std::string& arg1) + { + ::DBus::SignalMessage sig("Crash"); + ::DBus::MessageIter wi = sig.writer(); + wi << arg1; + emit_signal(sig); + } + + +private: + + /* unmarshalers (to unpack the DBus message before calling the actual interface method) + */ + DBus::Message _GetCrashInfos_stub(const DBus::CallMessage &call) + { + DBus::MessageIter ri = call.reader(); + + std::string argin1; ri >> argin1; + dbus_vector_crash_infos_t argout1 = GetCrashInfos(argin1); + DBus::ReturnMessage reply(call); + DBus::MessageIter wi = reply.writer(); + wi << argout1; + return reply; + } +}; + diff --git a/lib/DBus/DbusClient.h b/lib/DBus/DbusClient.h new file mode 100644 index 00000000..e278c50d --- /dev/null +++ b/lib/DBus/DbusClient.h @@ -0,0 +1,15 @@ +#include <dbus-c++/dbus.h> +#include "DBusClientProxy.h" + +class CDBusClient +: public org::freedesktop::DBus::CDBusClient_proxy, + public DBus::IntrospectableProxy, + public DBus::ObjectProxy +{ +public: + + CDBusClient(DBus::Connection &connection, const char *path, const char *name); + ~CDBusClient(); + void Crash(const DBus::Variant &value); +}; + diff --git a/lib/DBus/Makefile.am b/lib/DBus/Makefile.am index 0d4d9f6e..1f709e77 100644 --- a/lib/DBus/Makefile.am +++ b/lib/DBus/Makefile.am @@ -1,11 +1,20 @@ lib_LTLIBRARIES = libDBus.la -libDBus_la_SOURCES = DBusManager.cpp DBusManager.h marshal.c marshal.h +libDBus_la_SOURCES = DBusManager.cpp DBusManager.h DBusClient.h DBusClient.cpp \ + DBusClientProxy.h DBusServer.cpp DBusServer.h DBusServerProxy.h libDBus_la_LDFLAGS = -version-info 0:1:0 -libDBus_la_LIBADD = $(DBUS_GLIB_LIBS) -libDBus_la_CPPFLAGS = $(DBUS_GLIB_CFLAGS) +libDBus_la_LIBADD = $(DBUS_GLIB_LIBS) $(GLIBMM_LIBS) $(DBUSCPP_LIBS) +libDBus_la_CPPFLAGS = $(DBUS_GLIB_CFLAGS) $(GLIBMM_CFLAGS) $(DBUSCPP_CFLAGS) \ + -I../../lib/MiddleWare +#BUILT_SOURCES = crashcatcher-glue.h -check_PROGRAMS = test -test_SOURCES = test.cpp -test_LDADD = libDBus.la $(DL_LIBS) -test_CPPFLAGS = $(DBUS_GLIB_CFLAGS) +#crashcatcher-glue.h: crashcatcher.xml +# $(LIBTOOL) --mode=execute dbus-binding-tool --prefix=Crash --mode=glib-server --output=crashcatcher-glue.h $(srcdir)/crashcatcher.xml + +check_PROGRAMS = test_server test_client +test_server_SOURCES = test_server.cpp +test_server_LDADD = libDBus.la $(DL_LIBS) +test_server_CPPFLAGS = $(DBUS_GLIB_CFLAGS) $(DBUSCPP_CFLAGS) -g -I../../lib/MiddleWare +test_client_SOURCES = test_client.cpp +test_client_LDADD = libDBus.la $(DL_LIBS) +test_client_CPPFLAGS = $(DBUS_GLIB_CFLAGS) $(DBUSCPP_CFLAGS) -g -I../../lib/MiddleWare diff --git a/lib/DBus/test.cpp b/lib/DBus/test.cpp index 8f1d66cf..ad414b6a 100644 --- a/lib/DBus/test.cpp +++ b/lib/DBus/test.cpp @@ -22,19 +22,28 @@ #include <iostream> #include <climits> #include <stdlib.h> - -static void -print_cb(DBusGProxy *proxy, char* progname, gpointer user_data) -{ - DBusError error; - dbus_error_init (&error); - std::cerr << "Application " << progname << " has crashed!" << std::endl; -} +#include <unistd.h> int main(int argc, char** argv){ GMainLoop *mainloop; mainloop = g_main_loop_new(NULL, FALSE); - + CDBusManager dm; + try + { + dm.RegisterService(); + } + catch(std::string err) + { + std::cerr << err << std::endl; + return -1; + } + while(1) + { + dm.SendMessage("Crash","Svete"); + sleep(1); + } + g_main_loop_run(mainloop); + /* //no sanity check, it's just a testing program! if (argc < 2){ std::cout << "Usage: " << argv[0] << " {s|c}" << std::endl; @@ -72,5 +81,6 @@ int main(int argc, char** argv){ dm.RegisterToMessage("Crash",G_CALLBACK(print_cb),NULL,NULL); g_main_loop_run(mainloop); } + */ return 0; } diff --git a/lib/DBus/test_client.cpp b/lib/DBus/test_client.cpp new file mode 100644 index 00000000..ccdae45c --- /dev/null +++ b/lib/DBus/test_client.cpp @@ -0,0 +1,61 @@ +/* + Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com) + 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 + 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 "DBusClient.h" +#include <iostream> +#include <signal.h> + +DBus::BusDispatcher dispatcher; + +void niam(int sig) +{ + dispatcher.leave(); +} + +int main() +{ + signal(SIGTERM, niam); + signal(SIGINT, niam); + + DBus::default_dispatcher = &dispatcher; + + DBus::Connection conn = DBus::Connection::SessionBus(); + + CDBusClient client(conn, CC_DBUS_PATH, CC_DBUS_NAME); + /* + typedef std::vector< std::vector<std::string> > type_t; + type_t vec = client.GetCrashInfos("client"); + for (type_t::iterator it = vec.begin(); it!=vec.end(); ++it) { + for (std::vector<std::string>::iterator itt = it->begin(); itt!=it->end(); ++itt) { + std::cout << *itt << std::endl; + } + } + */ + dbus_vector_crash_infos_t v = client.GetCrashInfos("client"); + for (dbus_vector_crash_infos_t::iterator it = v.begin(); it!=v.end(); ++it) { + for (dbus_vector_crash_infos_t::value_type::iterator itt = it->begin(); itt!=it->end(); ++itt) { + std::cout << *itt << std::endl; + } + } + dispatcher.enter(); + + std::cout << "terminating" << std::endl; + + return 0; +} diff --git a/lib/DBus/test_server.cpp b/lib/DBus/test_server.cpp new file mode 100644 index 00000000..ba4d47a2 --- /dev/null +++ b/lib/DBus/test_server.cpp @@ -0,0 +1,45 @@ +/* + Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com) + 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 + 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 "DBusServer.h" +#include <iostream> +#include <signal.h> + +DBus::BusDispatcher dispatcher; + +void niam(int sig) +{ + dispatcher.leave(); +} + +int main() +{ + signal(SIGTERM, niam); + signal(SIGINT, niam); + + DBus::default_dispatcher = &dispatcher; + + DBus::Connection conn = DBus::Connection::SessionBus(); + + CDBusServer server(conn, CC_DBUS_PATH); + conn.request_name(CC_DBUS_NAME); + dispatcher.enter(); + + return 0; +} diff --git a/src/Applet/Applet.cpp b/src/Applet/Applet.cpp index 39b0cc41..cc40642e 100644 --- a/src/Applet/Applet.cpp +++ b/src/Applet/Applet.cpp @@ -1,40 +1,54 @@ +/* + Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com) + 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 + 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 "CCApplet.h" -#include "DBusManager.h" +#include "DBusClient.h" #include <iostream> //@@global applet object CApplet *applet; static void -crash_notify_cb(DBusGProxy *proxy, char* progname, gpointer user_data) +crash_notify_cb(const char* progname) { - DBusError error; - dbus_error_init (&error); #ifdef DEBUG std::cerr << "Application " << progname << " has crashed!" << std::endl; #endif /* smth happend, show the blinking icon */ applet->BlinkIcon(true); applet->ShowIcon(); + //applet->AddEvent(uid, std::string(progname)); + applet->SetIconTooltip("A crash in package %s has been detected!", progname); } int main(int argc, char **argv) { Gtk::Main kit(argc, argv); applet = new CApplet(); - CDBusManager dm; - /* connect to the daemon */ - try - { - dm.ConnectToDaemon(); - } - catch(std::string err) - { - std::cerr << "Applet: " << err << std::endl; - return -1; - } - /* catch the CC crash notify on the dbus */ - dm.RegisterToMessage("Crash",G_CALLBACK(crash_notify_cb),NULL,NULL); - /* run the main loop and wait for some events */ + /* move to the DBusClient::connect */ + DBus::Glib::BusDispatcher dispatcher; + /* this should bind the dispatcher with mainloop */ + dispatcher.attach(NULL); + DBus::default_dispatcher = &dispatcher; + + DBus::Connection conn = DBus::Connection::SystemBus(); + CDBusClient client(conn, CC_DBUS_PATH, CC_DBUS_NAME); + client.ConnectCrashHandler(crash_notify_cb); Gtk::Main::run(); return 0; } diff --git a/src/Applet/CCApplet.cpp b/src/Applet/CCApplet.cpp index fd9741ae..17ff6f92 100644 --- a/src/Applet/CCApplet.cpp +++ b/src/Applet/CCApplet.cpp @@ -19,33 +19,66 @@ #include "CCApplet.h" #include <iostream> +#include <cstdarg> +#include <sstream> CApplet::CApplet() { - m_nStatusIcon = Gtk::StatusIcon::create(Gtk::Stock::DIALOG_WARNING); m_nStatusIcon->set_visible(false); - // LTM click + // LMB click m_nStatusIcon->signal_activate().connect(sigc::mem_fun(*this, &CApplet::OnAppletActivate_CB)); - SetIconToolip("Pending events:"); + m_nStatusIcon->signal_popup_menu().connect(sigc::mem_fun(*this, &CApplet::OnMenuPopup_cb)); + SetIconTooltip("Pending events: %i",m_mapEvents.size()); + } CApplet::~CApplet() { } -void CApplet::SetIconToolip(const Glib::ustring& tip) +void CApplet::SetIconTooltip(const char *format, ...) { - m_nStatusIcon->set_tooltip(tip); + va_list args; + // change to smth sane like MAX_TOOLTIP length or rewrite this whole sh*t + size_t n,size = 10; + char *buf = new char[size]; + va_start (args, format); + while((n = vsnprintf (buf, size, format, args)) > size) + { + // string was larger than our buffer + // alloc larger buffer + size = n+1; + delete[] buf; + buf = new char[size]; + } + va_end (args); + if (n != -1) + { + m_nStatusIcon->set_tooltip(Glib::ustring((const char*)buf)); + } + else + { + m_nStatusIcon->set_tooltip("Error while setting tooltip!"); + } + delete[] buf; } void CApplet::OnAppletActivate_CB() { m_nStatusIcon->set_visible(false); //std::cout << "Activate" << std::endl; + //if(m_pMenuPopup) + //m_pMenuPopup->show(); } +void CApplet::OnMenuPopup_cb(guint button, guint32 activate_time) +{ + /* for now just hide the icon on RMB */ + m_nStatusIcon->set_blinking(false); +} + void CApplet::ShowIcon() { m_nStatusIcon->set_visible(true); @@ -56,6 +89,16 @@ void CApplet::HideIcon() m_nStatusIcon->set_visible(false); } +int CApplet::AddEvent(int pUUID, const std::string& pProgname) +{ + m_mapEvents[pUUID] = "pProgname"; + SetIconTooltip("Pending events: %i",m_mapEvents.size()); +} + +int CApplet::RemoveEvent(int pUUID) +{ + m_mapEvents.erase(pUUID); +} void CApplet::BlinkIcon(bool pBlink) { m_nStatusIcon->set_blinking(pBlink); diff --git a/src/Applet/CCApplet.h b/src/Applet/CCApplet.h index 428f4a9c..86c00efb 100644 --- a/src/Applet/CCApplet.h +++ b/src/Applet/CCApplet.h @@ -26,7 +26,7 @@ class CApplet { private: Glib::RefPtr<Gtk::StatusIcon> m_nStatusIcon; - int m_iPendingEvents; + std::map<int, std::string > m_mapEvents; public: CApplet(); ~CApplet(); @@ -34,9 +34,18 @@ class CApplet void HideIcon(); //void DisableIcon(); void BlinkIcon(bool pBlink); - void SetIconToolip(const Glib::ustring& tip); + void SetIconTooltip(const char *format, ...); + // create some event storage, to let user choose + // or ask the daemon every time? + // maybe just events which occured during current session + // map:: + int AddEvent(int pUUID, const std::string& pProgname); + int RemoveEvent(int pUUID); protected: + //@@TODO applet menus void OnAppletActivate_CB(); + void OnMenuPopup_cb(guint button, guint32 activate_time); + //menu Glib::RefPtr<Gtk::UIManager> m_refUIManager; Glib::RefPtr<Gtk::ActionGroup> m_refActionGroup; Gtk::Menu* m_pMenuPopup; diff --git a/src/Applet/Makefile.am b/src/Applet/Makefile.am index 8500b011..e329accb 100644 --- a/src/Applet/Makefile.am +++ b/src/Applet/Makefile.am @@ -2,5 +2,7 @@ bin_PROGRAMS = applet applet_SOURCES = Applet.cpp CCApplet.cpp CCApplet.h applet_CPPFLAGS = -I../../lib/DBus \ -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" \ - $(DBUS_GLIB_CFLAGS) $(GTKMM_CFLAGS) + $(DBUS_GLIB_CFLAGS) $(GTKMM_CFLAGS) $(DBUSCPP_CFLAGS) \ + -I../../lib/MiddleWare + applet_LDADD = ../../lib/DBus/libDBus.la $(DL_LIBS) $(GTKMM_LIBS) diff --git a/src/Daemon/CrashWatcher.cpp b/src/Daemon/CrashWatcher.cpp index e6802a3f..1474b2f6 100644 --- a/src/Daemon/CrashWatcher.cpp +++ b/src/Daemon/CrashWatcher.cpp @@ -55,9 +55,14 @@ gboolean CCrashWatcher::handle_event_cb(GIOChannel *gio, GIOCondition condition, #ifdef DEBUG std::cout << "Created file: " << name << std::endl; #endif /*DEBUG*/ - /* send message to dbus */ + CCrashWatcher *cc = (CCrashWatcher*)daemon; - cc->m_nDbus_manager.SendMessage("Crash", name); + CMiddleWare::crash_info_t crashinfo; + if(cc->m_pMW->SaveDebugDump(std::string(DEBUG_DUMPS_DIR) + "/" + name, crashinfo)) + { + /* send message to dbus */ + cc->m_pDbusServer->Crash(crashinfo.m_sPackage); + } } return TRUE; } @@ -66,9 +71,18 @@ CCrashWatcher::CCrashWatcher(const std::string& pPath) { int watch = 0; m_sTarget = pPath; + // middleware object + m_pMW = new CMiddleWare(PLUGINS_CONF_DIR,PLUGINS_LIB_DIR, std::string(CONF_DIR) + "/CrashCatcher.conf"); m_nMainloop = g_main_loop_new(NULL,FALSE); /* register on dbus */ - m_nDbus_manager.RegisterService(); + DBus::Glib::BusDispatcher *dispatcher; + dispatcher = new DBus::Glib::BusDispatcher(); + dispatcher->attach(NULL); + DBus::default_dispatcher = dispatcher; + DBus::Connection conn = DBus::Connection::SystemBus(); + + m_pDbusServer = new CDBusServer(conn,CC_DBUS_PATH); + conn.request_name(CC_DBUS_NAME); if((m_nFd = inotify_init()) == -1){ throw std::string("Init Failed"); //std::cerr << "Init Failed" << std::endl; @@ -76,23 +90,22 @@ CCrashWatcher::CCrashWatcher(const std::string& pPath) } if((watch = inotify_add_watch(m_nFd, pPath.c_str(), IN_CREATE)) == -1){ throw std::string("Add watch failed"); - //std::cerr << "Add watch failed: " << pPath << std::endl; - exit(-1); } m_nGio = g_io_channel_unix_new(m_nFd); } CCrashWatcher::~CCrashWatcher() { + //delete dispatcher, connection, etc.. } void CCrashWatcher::Lock() { int lfp = open("crashcatcher.lock",O_RDWR|O_CREAT,0640); if (lfp < 0) - throw "CCrashWatcher.cpp:can not open lock file"; + throw std::string("CCrashWatcher.cpp:can not open lock file"); if (lockf(lfp,F_TLOCK,0) < 0) - throw "CCrashWatcher.cpp:Lock:cannot create lock on lockfile"; + throw std::string("CCrashWatcher.cpp:Lock:cannot create lock on lockfile"); /* only first instance continues */ //sprintf(str,"%d\n",getpid()); //write(lfp,str,strlen(str)); /* record pid to lockfile */ diff --git a/src/Daemon/CrashWatcher.h b/src/Daemon/CrashWatcher.h index 1d092cb2..92ef27f9 100644 --- a/src/Daemon/CrashWatcher.h +++ b/src/Daemon/CrashWatcher.h @@ -24,7 +24,8 @@ #include <sys/inotify.h> #include <sys/inotify.h> #include <glib.h> -#include "DBusManager.h" +//#include "DBusManager.h" +#include "DBusServer.h" #include "MiddleWare.h" // 1024 simultaneous actions @@ -40,11 +41,13 @@ class CCrashWatcher void GStartWatch(); void Lock(); - CDBusManager m_nDbus_manager; + //CDBusManager m_nDbus_manager; + CDBusServer *m_pDbusServer; int m_nFd; GIOChannel* m_nGio; GMainLoop *m_nMainloop; std::string m_sTarget; + CMiddleWare *m_pMW; public: CCrashWatcher(const std::string& pPath); //CCrashWatcher(); diff --git a/src/Daemon/Makefile.am b/src/Daemon/Makefile.am index 32dbab0b..c562bb09 100644 --- a/src/Daemon/Makefile.am +++ b/src/Daemon/Makefile.am @@ -2,5 +2,8 @@ bin_PROGRAMS = CrashCatcher CrashCatcher_SOURCES = CrashWatcher.cpp CrashWatcher.h Daemon.cpp CrashCatcher_CPPFLAGS = -I../../lib/MiddleWare\ -I../../lib/DBus \ - -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" $(DBUS_GLIB_CFLAGS) + -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" $(DBUS_GLIB_CFLAGS) $(DBUSCPP_CFLAGS) \ + -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ + -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ + -DCONF_DIR=\"$(CONF_DIR)\" CrashCatcher_LDADD = ../../lib/MiddleWare/libMiddleWare.la ../../lib/DBus/libDBus.la $(DL_LIBS) |