diff options
55 files changed, 3569 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 00000000..c6f0b941 --- /dev/null +++ b/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = lib src
\ No newline at end of file diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 00000000..9a3daccf --- /dev/null +++ b/autogen.sh @@ -0,0 +1 @@ +autoreconf --install --force diff --git a/configure.ac b/configure.ac new file mode 100644 index 00000000..7c686047 --- /dev/null +++ b/configure.ac @@ -0,0 +1,55 @@ +AC_INIT([CrashCatcher], [0.0.1], [jmoskovc@redhat.com, zprikryl@redhat.com]) + +AM_INIT_AUTOMAKE([-Wall -Werror foreign]) + +AC_DISABLE_STATIC +AC_PROG_LIBTOOL + +AC_PROG_CXX + +PKG_CHECK_MODULES([DBUS_GLIB], [dbus-glib-1]) +PKG_CHECK_MODULES([SQLITE3], [sqlite3]) +PKG_CHECK_MODULES([GTKMM], [gtkmm-2.4]) + +AC_CHECK_HEADER([sys/inotify.h], [], + [AC_MSG_ERROR([sys/inotify.h is needed to build CrashCatcher])]) + +PLUGINS_CONF_DIR='${libdir}/${PACKAGE_NAME}' +AC_ARG_WITH(pluginsconfdir, + [AS_HELP_STRING([--with-pluginsconfdir=[DIR]], + [Directory where plugin's configuration files are])], + [PLUGINS_CONF_DIR=$withval]) +AC_SUBST(PLUGINS_CONF_DIR) + +PLUGINS_LIB_DIR='${libdir}/${PACKAGE_NAME}' +AC_ARG_WITH(pluginslibdir, + [AS_HELP_STRING([--with-pluginslibdir=DIR], + [Directory where plugin's libraries are])], + [PLUGINS_LIB_DIR=$withval]) +AC_SUBST(PLUGINS_LIB_DIR) + +DEBUG_DUMPS_DIR='${prefix}/var/cache/${PACKAGE_NAME}' +AC_ARG_WITH(debugdumpsdir, + [AS_HELP_STRING([--with-debugdumpdir=DIR], + [Directory where debugdumps are created])], + [DEBUG_DUMPS_DIR="$withval"]) +AC_SUBST(DEBUG_DUMPS_DIR) + +AC_SUBST(DL_LIBS, -ldl) + +AC_CONFIG_HEADERS([config.h]) + +AC_CONFIG_FILES([ + Makefile + lib/Makefile + lib/DBus/Makefile + lib/DebugDump/Makefile + lib/MiddleWare/Makefile + lib/Plugins/Makefile + src/Makefile + src/Daemon/Makefile + src/Hooks/Makefile + src/Applet/Makefile +]) + +AC_OUTPUT
\ No newline at end of file diff --git a/doc/COPYING b/doc/COPYING new file mode 100644 index 00000000..d511905c --- /dev/null +++ b/doc/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/doc/ChangeLog b/doc/ChangeLog new file mode 100644 index 00000000..1a50eab6 --- /dev/null +++ b/doc/ChangeLog @@ -0,0 +1,39 @@ +* Mon Feb 2 2009 Jiri Moskovcak <jmoskovc@redhat.com> +- switch from dbus SESSION bus to SYSTEM bus +- send message thru dbus low-level api instead of glib +- code cleanup - modified DBusManager API + +* Fri Jan 30 2009 Jiri Moskovcak <jmoskovc@redhat.com> +- Added simple systray applet +- Added dbus support to daemon +- Some improvements to DBusManager library +- Code cleanup +- Daemon uses glib for event handling + +* Thu Jan 22 2009 Jiri Moskovcak <jmoskovc@redhat.com> +- Initial version of DBus library +- added autotools things + +* Thu Jan 22 2009 Zdenek Prikryl <zprikryl@redhat.com> +- added autotools things + +* Wed Jan 21 2009 Zdenek Prikryl <zprikryl@redhat.com> +- new directory structure +- new plugin architecture + +* Tue Jan 14 2009 Zdenek Prikryl <zprikryl@redhat.com> +- minor redesign of MiddleWare and PluginManager structure + +* Tue Jan 13 2009 Zdenek Prikryl <zprikryl@redhat.com> +- New DB interface +- Minor fixes in CCpp hook and CCpp init script + +* Thu Jan 8 2009 Jiri Moskovcak <jmoskovc@redhat.com> +- an early version of crash watcher daemon + +* Thu Jan 08 2009 Zdenek Prikryl <zprikryl@redhat.com> +- New Language and reporter plugin API, added function for loading settings +- New plugin interface, added unregister function +- Added interface for language and reporter plugins to MiddleWare library +- DebugDump library can create/delete dumps +- Initial version of CCpp add-on
\ No newline at end of file diff --git a/doc/CodingStyle b/doc/CodingStyle new file mode 100644 index 00000000..1e054013 --- /dev/null +++ b/doc/CodingStyle @@ -0,0 +1,64 @@ +Coding style used in CrashCatcher +================================= + +1. Class +-------- +1.1 Class has to start with 'C' + +1.2 Method +----------- +1.2.1 method starts witch a capital letter +1.2.2 method name can contain only letters +1.2.3 parameter of a method has to start with the letter 'p' + +1.3 Attribute +------------- +1.3.1 non-float attribute has to start with "m_n" +1.3.2 float attribute has to start with "m_f" +1.3.3 double attribute has to start with "m_d" +1.3.4 bool attribute has to start with "m_b" +1.3.5 string/char attribute has to start with "m_s" +1.3.6 pointer attribute has to start with "m_p" +1.3.7 template attribute has to start with a template name "m_map" +1.3.8 otherwise "m_" + +2. Type +------- +2.1 every type has to end with "_t" +2.2 types created from templates has to start with a template name +2.3 words in a type has to be separated with "_" + +3. Statement +------------ +3.1 "if", "while" and "for" has to have {} every time. +3.2 { is on the new line every time + +4. Example +---------- + +typedef std::map<int, int> map_new_type_t; + +class CAwesomeClass +{ + private: + map_new_type_t m_NewType; + std::string m_sName; + COtherClass* m_pOtherClass; + void PrivateFunction(int pParameter); + public: + CAwesomeClass(std::string pName) : + m_sName(pName), m_pOtherClass(NULL) + {} +}; + +void CAwesomeClass::PrivateFunction(int pParameter) +{ + if (pParameter != "") + { + // do something + } + else + { + // do something else + } +} diff --git a/doc/INSTALL b/doc/INSTALL new file mode 100644 index 00000000..5d4b510f --- /dev/null +++ b/doc/INSTALL @@ -0,0 +1,5 @@ +How to install +============== +1. ./autogen +2. ./configure +3. make
\ No newline at end of file diff --git a/doc/README b/doc/README new file mode 100644 index 00000000..552c248d --- /dev/null +++ b/doc/README @@ -0,0 +1,2 @@ +These sources are in early stages. They are changing every day :-)... +Anyway, patches are welcome.
\ No newline at end of file diff --git a/lib/DBus/DBusManager.cpp b/lib/DBus/DBusManager.cpp new file mode 100644 index 00000000..0b2cb97f --- /dev/null +++ b/lib/DBus/DBusManager.cpp @@ -0,0 +1,203 @@ +/* + 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 "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; +} + + +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; +} + +CDBusManager::~CDBusManager() +{ +} + +/* 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)) + { + throw std::string("Failed to acquire com.redhat.CrashCatcher:") + error->message ; + } +#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 */ + 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 new file mode 100644 index 00000000..e3537f89 --- /dev/null +++ b/lib/DBus/DBusManager.h @@ -0,0 +1,55 @@ +/* + 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. + */ + +#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> + +#define CC_DBUS_NAME "com.redhat.CrashCatcher" +#define CC_DBUS_PATH "/com/redhat/CrashCatcher" +#define CC_DBUS_IFACE "com.redhat.CrashCatcher" +#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; + + 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); +}; + +#endif /*DBUS_H_*/ diff --git a/lib/DBus/Makefile.am b/lib/DBus/Makefile.am new file mode 100644 index 00000000..0d4d9f6e --- /dev/null +++ b/lib/DBus/Makefile.am @@ -0,0 +1,11 @@ +lib_LTLIBRARIES = libDBus.la +libDBus_la_SOURCES = DBusManager.cpp DBusManager.h marshal.c marshal.h +libDBus_la_LDFLAGS = -version-info 0:1:0 +libDBus_la_LIBADD = $(DBUS_GLIB_LIBS) +libDBus_la_CPPFLAGS = $(DBUS_GLIB_CFLAGS) + + +check_PROGRAMS = test +test_SOURCES = test.cpp +test_LDADD = libDBus.la $(DL_LIBS) +test_CPPFLAGS = $(DBUS_GLIB_CFLAGS) diff --git a/lib/DBus/marshal.c b/lib/DBus/marshal.c new file mode 100644 index 00000000..247bf1bb --- /dev/null +++ b/lib/DBus/marshal.c @@ -0,0 +1,51 @@ + +#include <glib-object.h> + + +#ifdef G_ENABLE_DEBUG +#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) +#define g_marshal_value_peek_char(v) g_value_get_char (v) +#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) +#define g_marshal_value_peek_int(v) g_value_get_int (v) +#define g_marshal_value_peek_uint(v) g_value_get_uint (v) +#define g_marshal_value_peek_long(v) g_value_get_long (v) +#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) +#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) +#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) +#define g_marshal_value_peek_enum(v) g_value_get_enum (v) +#define g_marshal_value_peek_flags(v) g_value_get_flags (v) +#define g_marshal_value_peek_float(v) g_value_get_float (v) +#define g_marshal_value_peek_double(v) g_value_get_double (v) +#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) +#define g_marshal_value_peek_param(v) g_value_get_param (v) +#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) +#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) +#define g_marshal_value_peek_object(v) g_value_get_object (v) +#else /* !G_ENABLE_DEBUG */ +/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. + * Do not access GValues directly in your code. Instead, use the + * g_value_get_*() functions + */ +#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int +#define g_marshal_value_peek_char(v) (v)->data[0].v_int +#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint +#define g_marshal_value_peek_int(v) (v)->data[0].v_int +#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint +#define g_marshal_value_peek_long(v) (v)->data[0].v_long +#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 +#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 +#define g_marshal_value_peek_enum(v) (v)->data[0].v_long +#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_float(v) (v)->data[0].v_float +#define g_marshal_value_peek_double(v) (v)->data[0].v_double +#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer +#endif /* !G_ENABLE_DEBUG */ + + +/* VOID:STRING (marshal.list:1) */ + diff --git a/lib/DBus/marshal.h b/lib/DBus/marshal.h new file mode 100644 index 00000000..60608245 --- /dev/null +++ b/lib/DBus/marshal.h @@ -0,0 +1,15 @@ + +#ifndef __marshal_MARSHAL_H__ +#define __marshal_MARSHAL_H__ + +#include <glib-object.h> + +G_BEGIN_DECLS + +/* VOID:STRING (marshal.list:1) */ +#define marshal_VOID__STRING g_cclosure_marshal_VOID__STRING + +G_END_DECLS + +#endif /* __marshal_MARSHAL_H__ */ + diff --git a/lib/DBus/marshal.list b/lib/DBus/marshal.list new file mode 100644 index 00000000..30ba5d8d --- /dev/null +++ b/lib/DBus/marshal.list @@ -0,0 +1 @@ +VOID:STRING diff --git a/lib/DBus/test.cpp b/lib/DBus/test.cpp new file mode 100644 index 00000000..8f1d66cf --- /dev/null +++ b/lib/DBus/test.cpp @@ -0,0 +1,76 @@ +/* + 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 "DBusManager.h" +#include <cstring> +#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; +} + +int main(int argc, char** argv){ + GMainLoop *mainloop; + mainloop = g_main_loop_new(NULL, FALSE); + + //no sanity check, it's just a testing program! + if (argc < 2){ + std::cout << "Usage: " << argv[0] << " {s|c}" << std::endl; + return 0; + } + //service + if (strcmp(argv[1], "s") == 0){ + std::cout << "Service: " << std::endl; + CDBusManager dm; + try + { + dm.RegisterService(); + } + catch(std::string err) + { + std::cerr << err << std::endl; + return -1; + } + dm.LoopSend(); + + g_main_loop_run(mainloop); + } + //client + else if (strcmp(argv[1], "c") == 0){ + CDBusManager dm; + try + { + dm.ConnectToService(); + } + catch(std::string error) + { + std::cerr << error << std::endl; + return -1; + } + dm.RegisterToMessage("Crash",G_CALLBACK(print_cb),NULL,NULL); + g_main_loop_run(mainloop); + } + return 0; +} diff --git a/lib/DebugDump/DebugDump.cpp b/lib/DebugDump/DebugDump.cpp new file mode 100644 index 00000000..7dcfcc10 --- /dev/null +++ b/lib/DebugDump/DebugDump.cpp @@ -0,0 +1,243 @@ +/* + DebugDump.cpp + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@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 "DebugDump.h" +#include <fstream> +#include <iostream> +#include <sstream> +#include <sys/types.h> +#include <sys/stat.h> +#include <dirent.h> +#include <sys/utsname.h> +#include <limits.h> +#include <fcntl.h> +#include <sys/procfs.h> +#include <ctype.h> + +CDebugDump::CDebugDump() : + m_sDebugDumpDir("") +{} + +void CDebugDump::Open(const std::string& pDebugDumpDir, const mode_t pMode) +{ + m_sDebugDumpDir = pDebugDumpDir; + if (pMode == CREATE) + { + Delete(pDebugDumpDir); + Create(pDebugDumpDir); + SaveEnvironment(); + } + if (!Exist(pDebugDumpDir)) + { + throw "CDebugDump::CDebugDump(): "+pDebugDumpDir+" does not exist."; + } +} + +bool CDebugDump::Exist(const std::string& pDir) +{ + struct stat buf; + if (stat(pDir.c_str(), &buf) == 0) + { + if (S_ISDIR(buf.st_mode)) + { + return true; + } + } + return false; +} + +void CDebugDump::Create(const std::string& pDir) +{ + if (mkdir(pDir.c_str(), 0755) == -1) + { + throw "CDebugDump::Create(): Cannot create dir: " + pDir; + } +} + +void CDebugDump::Delete(const std::string& pDir) +{ + if (!Exist(pDir)) + { + return; + } + + DIR *dir = opendir(pDir.c_str()); + std::string fullPath; + struct dirent *dent = NULL; + if (dir != NULL) + { + while ((dent = readdir(dir)) != NULL) + { + if (std::string(dent->d_name) != "." && std::string(dent->d_name) != "..") + { + fullPath = pDir + "/" + dent->d_name; + if (dent->d_type == DT_DIR) + { + Delete(fullPath); + } + if (remove(fullPath.c_str()) == -1) + { + throw "CDebugDump::DeleteDir(): Cannot remove file: " + fullPath; + } + } + } + closedir(dir); + if (remove(pDir.c_str()) == -1) + { + throw "CDebugDump::DeleteDir(): Cannot remove dir: " + fullPath; + } + } +} + +void CDebugDump::SaveEnvironment() +{ + struct utsname buf; + if (uname(&buf) == 0) + { + SaveText(FILENAME_KERNEL, buf.release); + SaveText(FILENAME_ARCHITECTURE, buf.machine); + } +} + +void CDebugDump::LoadTextFile(const std::string& pPath, std::string& pData) +{ + std::ifstream fIn; + pData = ""; + fIn.open(pPath.c_str()); + if (fIn.is_open()) + { + std::string line; + while (!fIn.eof()) + { + getline (fIn,line); + pData += line; + } + fIn.close(); + } + else + { + throw "CDebugDump: LoadTextFile(): Cannot open file " + pPath; + } +} + +void CDebugDump::LoadBinaryFile(const std::string& pPath, char** pData, unsigned int* pSize) +{ + std::ifstream fIn; + fIn.open(pPath.c_str(), std::ios::binary | std::ios::ate); + unsigned int size; + if (fIn.is_open()) + { + size = fIn.tellg(); + char *data = new char [size]; + fIn.read(data, size); + + *pData = data; + *pSize = size; + + fIn.close(); + } + else + { + throw "CDebugDump: LoadBinaryFile(): Cannot open file " + pPath; + } +} + + +void CDebugDump::SaveTextFile(const std::string& pPath, const std::string& pData) +{ + std::ofstream fOut; + fOut.open(pPath.c_str()); + if (fOut.is_open()) + { + fOut << pData; + fOut.close(); + } + else + { + throw "CDebugDump: SaveTextFile(): Cannot open file " + pPath; + } +} + +void CDebugDump::SaveBinaryFile(const std::string& pPath, const char* pData, const unsigned pSize) +{ + std::ofstream fOut; + fOut.open(pPath.c_str(), std::ios::binary); + if (fOut.is_open()) + { + fOut.write(pData, pSize); + fOut.close(); + } + else + { + throw "CDebugDump: SaveBinaryFile(): Cannot open file " + pPath; + } +} + +void CDebugDump::LoadText(const std::string& pName, std::string& pData) +{ + std::string fullPath = m_sDebugDumpDir + "/" + pName; + LoadTextFile(fullPath, pData); +} +void CDebugDump::LoadBinary(const std::string& pName, char** pData, unsigned int* pSize) +{ + std::string fullPath = m_sDebugDumpDir + "/" + pName; + LoadBinaryFile(fullPath, pData, pSize); +} + +void CDebugDump::SaveText(const std::string& pName, const std::string& pData) +{ + std::string fullPath = m_sDebugDumpDir + "/" + pName; + SaveTextFile(fullPath, pData); +} +void CDebugDump::SaveBinary(const std::string& pName, const char* pData, const unsigned int pSize) +{ + std::string fullPath = m_sDebugDumpDir + "/" + pName; + SaveBinaryFile(fullPath, pData, pSize); +} + + +void CDebugDump::SaveProc(const std::string& pPID) +{ + std::string path = "/proc/"+pPID+"/exe"; + std::string data; + char executable[PATH_MAX]; + + if (readlink(path.c_str(), executable, PATH_MAX) == 0) + { + SaveText(FILENAME_EXECUTABLE, executable); + } + + path = "/proc/"+pPID+"/status"; + std::string uid = "0"; + int ii = 0; + + LoadTextFile(path, data); + data = data.substr(data.find("Uid:")+5); + + while (!isspace(data[ii])) + { + uid += data[ii]; + ii++; + } + SaveText(FILENAME_USER, uid); + + // TODO: Use packagekit +} diff --git a/lib/DebugDump/DebugDump.h b/lib/DebugDump/DebugDump.h new file mode 100644 index 00000000..8b8e79f5 --- /dev/null +++ b/lib/DebugDump/DebugDump.h @@ -0,0 +1,74 @@ +/* + DebugDump.h - header file for the library caring of writing new reports + to the specific directory + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@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. + */ + +#ifndef DEBUGDUMP_H_ +#define DEBUGDUMP_H_ + +#include <string> + +#define FILENAME_ARCHITECTURE "architecture" +#define FILENAME_KERNEL "kernel" +#define FILENAME_EXECUTABLE "executable" +#define FILENAME_TIME "time" +#define FILENAME_USER "uid" +#define FILENAME_PACKAGE "package" +#define FILENAME_HASH "hash" +#define FILENAME_LANGUAGE "language" +#define FILENAME_APPLICATION "application" +#define FILENAME_TEXT_FILE1 "text_file1" +#define FILENAME_BINARY_FILE1 "binary_file1" + +class CDebugDump +{ + private: + std::string m_sDebugDumpDir; + + void SaveEnvironment(); + + bool Exist(const std::string& pDir); + void Create(const std::string& pDir); + void Delete(const std::string& pDir); + + void LoadTextFile(const std::string& pName, std::string& pData); + void LoadBinaryFile(const std::string& pName, char** pData, unsigned int* pSize); + + void SaveTextFile(const std::string& pName, const std::string& pData); + void SaveBinaryFile(const std::string& pName, const char* pData, const unsigned int pSize); + + + public: + + typedef enum {CREATE, OPEN} mode_t; + + CDebugDump(); + void Open(const std::string& pDebugDumpDir, const mode_t pMode); + + void LoadText(const std::string& pName, std::string& pData); + void LoadBinary(const std::string& pName, char** pData, unsigned int* pSize); + + void SaveText(const std::string& pName, const std::string& pData); + void SaveBinary(const std::string& pName, const char* pData, const unsigned int pSize); + + void SaveProc(const std::string& pPID); +}; + +#endif /*DEBUGDUMP_H_*/ diff --git a/lib/DebugDump/Makefile.am b/lib/DebugDump/Makefile.am new file mode 100644 index 00000000..1a1ed3ee --- /dev/null +++ b/lib/DebugDump/Makefile.am @@ -0,0 +1,6 @@ +lib_LTLIBRARIES = libDebugDump.la +libDebugDump_la_SOURCES = DebugDump.cpp DebugDump.h +libDebugDump_la_LDFLAGS = -version-info 0:1:0 + +install-data-local: + $(mkdir_p) '$(DEBUG_DUMPS_DIR)'
\ No newline at end of file diff --git a/lib/Makefile.am b/lib/Makefile.am new file mode 100644 index 00000000..c5b18c43 --- /dev/null +++ b/lib/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = DebugDump MiddleWare Plugins DBus
\ No newline at end of file diff --git a/lib/MiddleWare/Application.h b/lib/MiddleWare/Application.h new file mode 100644 index 00000000..b68f9d50 --- /dev/null +++ b/lib/MiddleWare/Application.h @@ -0,0 +1,35 @@ +/* + Application.h - header file for application plugin + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@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. + */ + +#ifndef APPLICATION_H_ +#define APPLICATION_H_ + +#include <string> +#include "Plugin.h" + +class CApplication : public CPlugin +{ + public: + virtual ~CApplication() {} + virtual std::string GetReport(void* pData) = 0; +}; + +#endif /*APPLICATION_H_*/ diff --git a/lib/MiddleWare/CrashCatcherPlugin.cpp b/lib/MiddleWare/CrashCatcherPlugin.cpp new file mode 100644 index 00000000..e50ba535 --- /dev/null +++ b/lib/MiddleWare/CrashCatcherPlugin.cpp @@ -0,0 +1,154 @@ +/* + CrashCatcherPlugin.cpp + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@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 "CrashCatcherPlugin.h" + +CCrashCatcherPlugin::CCrashCatcherPlugin(const std::string& pLibPath) : + m_pDynamicLibrary(NULL), + m_pPluginInfo(NULL), + m_pFnPluginNew(NULL), + m_bEnabled(false) +{ + try + { + m_pDynamicLibrary = new CDynamicLibrary(pLibPath); + if (m_pDynamicLibrary == NULL) + { + throw std::string("Not enought memory."); + } + m_pPluginInfo = (p_plugin_info_t) m_pDynamicLibrary->FindSymbol("plugin_info"); + m_pFnPluginNew = (p_fn_plugin_new_t) m_pDynamicLibrary->FindSymbol("plugin_new"); + } + catch (...) + { + throw; + } +} + +CCrashCatcherPlugin::~CCrashCatcherPlugin() +{ + if (m_pDynamicLibrary != NULL) + { + delete m_pDynamicLibrary; + } +} + +void CCrashCatcherPlugin::LoadSettings(const std::string& pPath) +{ + std::ifstream fIn; + fIn.open(pPath.c_str()); + if (fIn.is_open()) + { + std::string line; + while (!fIn.eof()) + { + getline(fIn, line); + + int ii; + bool is_value = false; + std::string key = ""; + std::string value = ""; + for (ii = 0; ii < line.length(); ii++) + { + if (!isspace(line[ii])) + { + if (line[ii] == '#') + { + break; + } + else if (line[ii] == '=') + { + is_value = true; + } + else if (line[ii] == '=' && is_value) + { + key = ""; + value = ""; + break; + } + else if (!is_value) + { + key += line[ii]; + } + else + { + value += line[ii]; + } + } + } + if (key != "") + { + m_mapSettings[key] = value; + } + } + fIn.close(); + } +} + +const bool CCrashCatcherPlugin::IsEnabled() +{ + return m_mapSettings["Enabled"] == "yes"; +} + +const std::string& CCrashCatcherPlugin::GetVersion() +{ + return m_pPluginInfo->m_sVersion; +} + +const int CCrashCatcherPlugin::GetMagicNumber() +{ + return m_pPluginInfo->m_nMagicNumber; +} + +const std::string& CCrashCatcherPlugin::GetName() +{ + return m_pPluginInfo->m_sName; +} + +const std::string& CCrashCatcherPlugin::GetDescription() +{ + return m_pPluginInfo->m_sDescription; +} + +const std::string& CCrashCatcherPlugin::GetEmail() +{ + return m_pPluginInfo->m_sEmail; +} + +const std::string& CCrashCatcherPlugin::GetWWW() +{ + return m_pPluginInfo->m_sWWW; +} + +const plugin_type_t CCrashCatcherPlugin::GetType() +{ + return m_pPluginInfo->m_Type; +} + +CPlugin* CCrashCatcherPlugin::PluginNew() +{ + return m_pFnPluginNew(); +} + +const map_settings_t& CCrashCatcherPlugin::GetSettings() +{ + return m_mapSettings; +} diff --git a/lib/MiddleWare/CrashCatcherPlugin.h b/lib/MiddleWare/CrashCatcherPlugin.h new file mode 100644 index 00000000..0dcf4af3 --- /dev/null +++ b/lib/MiddleWare/CrashCatcherPlugin.h @@ -0,0 +1,63 @@ +/* + CrashCatcherPlugin.h - header file for CrashCatcher plugin. It takes care + of reporting thinks which has loaded plugin. + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@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. + */ + + +#ifndef CRASHCATCHERPLUGIN_H_ +#define CRASHCATCHERPLUGIN_H_ + +#include <string> +#include "DynamicLibrary.h" +#include "Plugin.h" + +class CCrashCatcherPlugin +{ + private: + + typedef const plugin_info_t* p_plugin_info_t; + typedef CPlugin* (*p_fn_plugin_new_t)(); + + CDynamicLibrary* m_pDynamicLibrary; + p_plugin_info_t m_pPluginInfo; + p_fn_plugin_new_t m_pFnPluginNew; + + bool m_bEnabled; + + map_settings_t m_mapSettings; + public: + CCrashCatcherPlugin(const std::string& pLibPath); + ~CCrashCatcherPlugin(); + + void LoadSettings(const std::string& pPath); + const bool IsEnabled(); + const std::string& GetVersion(); + const int GetMagicNumber(); + const std::string& GetName(); + const std::string& GetDescription(); + const std::string& GetEmail(); + const std::string& GetWWW(); + const plugin_type_t GetType(); + + CPlugin* PluginNew(); + const map_settings_t& GetSettings(); +}; + +#endif /*CRASHCATCHERPLUGIN_H_*/ diff --git a/lib/MiddleWare/Database.h b/lib/MiddleWare/Database.h new file mode 100644 index 00000000..da8567ab --- /dev/null +++ b/lib/MiddleWare/Database.h @@ -0,0 +1,98 @@ +/* + Database.h - header file for database plugin + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@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. + */ + + +#ifndef DATABASE_H_ +#define DATABASE_H_ + +#include <string> +#include <vector> +#include "Plugin.h" + +/* + * Table + * ===== + * UUID | DebugDumpPath | Architecture | Kernel | ProgramPath | Package | + * UID | Time | Count | Reported | BackTrace | TextData1 + * + * in the future we can add another TextData if we need it + */ + +#define DATABASE_COLUMN_UUID "UUID" +#define DATABASE_COLUMN_DEBUG_DUMP_PATH "DebugDumpPath" +#define DATABASE_COLUMN_ARCHITECTURE "Architecture" +#define DATABASE_COLUMN_KERNEL "Kernel" +#define DATABASE_COLUMN_EXECUTABLE "Executable" +#define DATABASE_COLUMN_PACKAGE "Package" +#define DATABASE_COLUMN_UID "UID" +#define DATABASE_COLUMN_TIME "Time" +#define DATABASE_COLUMN_COUNT "Count" +#define DATABASE_COLUMN_REPORTED "Reported" +#define DATABASE_COLUMN_BACKTRACE "BackTrace" +#define DATABASE_COLUMN_TEXTDATA1 "TextData1" + +typedef struct SDatabaseRow +{ + std::string m_sUUID; + std::string m_sDebugDumpPath; + std::string m_sArchitecture; + std::string m_sKernel; + std::string m_sExecutable; + std::string m_sPackage; + std::string m_sUID; + std::string m_sTime; + std::string m_sCount; + std::string m_sReported; + std::string m_sBackTrace; + std::string m_sTextData1; +} database_row_t; + +// <column_name, <array of values in all selected rows> > +typedef std::vector<database_row_t> vector_database_rows_t; + +class CDatabase : public CPlugin +{ + public: + virtual ~CDatabase() {} + + virtual void Connect() = 0; + virtual void DisConnect() = 0; + virtual void Insert(const std::string& pUUID, + const std::string& pDebugDumpPath, + const std::string& pArch, + const std::string& pKernel, + const std::string& pExecutable, + const std::string& pPackage, + const std::string& pUID, + const std::string& pTime) = 0; + + virtual void InsertBackTrace(const std::string& pUUID, + const std::string& pBackTrace) = 0; + + virtual void InsertTextData1(const std::string& pUUID, + const std::string& pData) = 0; + + virtual void Delete(const std::string& pUUID) = 0; + + const vector_database_rows_t GetUIDData(const std::string& pUID); +}; + +#endif /* DATABASE_H_ */ diff --git a/lib/MiddleWare/DynamicLibrary.cpp b/lib/MiddleWare/DynamicLibrary.cpp new file mode 100644 index 00000000..1c7c1cbd --- /dev/null +++ b/lib/MiddleWare/DynamicLibrary.cpp @@ -0,0 +1,57 @@ +/* + DynamicLybrary.cpp + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@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 "DynamicLibrary.h" +#include <iostream> + +CDynamicLibrary::CDynamicLibrary(const std::string& pPath) : + m_pHandle(NULL) +{ + Load(pPath); +} + +CDynamicLibrary::~CDynamicLibrary() +{ + if (m_pHandle != NULL) + { + dlclose(m_pHandle); + m_pHandle = NULL; + } +} + +void CDynamicLibrary::Load(const std::string& pPath) +{ + m_pHandle = dlopen(pPath.c_str(), RTLD_NOW); + if (m_pHandle == NULL) + { + throw "CDynamicLibrary::Load(): Cannot load " + pPath + " : " + std::string(dlerror()); + } +} + +void* CDynamicLibrary::FindSymbol(const std::string& pName) +{ + void* sym = dlsym(m_pHandle, pName.c_str()); + if (sym == NULL) + { + throw "CDynamicLibrary::Load(): Cannot find symbol '" + pName + "'"; + } + return sym; +} diff --git a/lib/MiddleWare/DynamicLibrary.h b/lib/MiddleWare/DynamicLibrary.h new file mode 100644 index 00000000..4962068c --- /dev/null +++ b/lib/MiddleWare/DynamicLibrary.h @@ -0,0 +1,42 @@ +/* + DynamicLybrary.h - header file for dynamic lybrarby wraper. It uses libdl. + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@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. + */ + + +#ifndef DYNAMICLIBRARYH_ +#define DYNAMICLIBRARYH_ + +#include <string> +#include <dlfcn.h> + +class CDynamicLibrary +{ + private: + void* m_pHandle; + + void Load(const std::string& pPath); + public: + CDynamicLibrary(const std::string& pPath); + ~CDynamicLibrary(); + + void* FindSymbol(const std::string& pName); +}; + +#endif /*DYNAMICLIBRARYH_*/ diff --git a/lib/MiddleWare/Language.h b/lib/MiddleWare/Language.h new file mode 100644 index 00000000..81024a53 --- /dev/null +++ b/lib/MiddleWare/Language.h @@ -0,0 +1,36 @@ +/* + Language.h - header file for language plugin + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@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. + */ + +#ifndef LANGUAGE_H_ +#define LANGUAGE_H_ + +#include <string> +#include "Plugin.h" + +class CLanguage : public CPlugin +{ + public: + virtual ~CLanguage() {} + virtual std::string GetUUID(void* pData) = 0; + virtual std::string GetReport(void* pData) = 0; +}; + +#endif /*LANGUAGE_H_*/ diff --git a/lib/MiddleWare/Makefile.am b/lib/MiddleWare/Makefile.am new file mode 100644 index 00000000..a6aa22e2 --- /dev/null +++ b/lib/MiddleWare/Makefile.am @@ -0,0 +1,16 @@ +lib_LTLIBRARIES = libMiddleWare.la +libMiddleWare_la_SOURCES = MiddleWare.cpp MiddleWare.h PluginManager.cpp \ + PluginManager.h CrashCatcherPlugin.cpp \ + CrashCatcherPlugin.h DynamicLibrary.cpp \ + DynamicLibrary.h +libMiddleWare_la_LIBADD = $(DL_LIBS) +libMiddleWare_la_LDFLAGS = -version-info 0:1:0 + + +check_PROGRAMS = test +test_SOURCES = test.cpp +test_LDADD = ../DebugDump/libDebugDump.la libMiddleWare.la $(DL_LIBS) +test_CPPFLAGS = -I$(srcdir)/../DebugDump \ + -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ + -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ + -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\"
\ No newline at end of file diff --git a/lib/MiddleWare/MiddleWare.cpp b/lib/MiddleWare/MiddleWare.cpp new file mode 100644 index 00000000..85b88c9c --- /dev/null +++ b/lib/MiddleWare/MiddleWare.cpp @@ -0,0 +1,87 @@ +/* + MiddleWare.cpp + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@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 "MiddleWare.h" + +CMiddleWare::CMiddleWare(const std::string& pPlugisConfDir, + const std::string& pPlugisLibDir) : + m_PluginManager(NULL) +{ + m_PluginManager = new CPluginManager(pPlugisConfDir, pPlugisLibDir); + if (m_PluginManager == NULL) + { + throw std::string("Not enought memory."); + } +} + +CMiddleWare::~CMiddleWare() +{ + if (m_PluginManager != NULL) + { + delete m_PluginManager; + } +} + +void CMiddleWare::LoadPlugins() +{ + m_PluginManager->LoadPlugins(); +} + +void CMiddleWare::LoadPlugin(const std::string& pName) +{ + m_PluginManager->LoadPlugin(pName); +} + +void CMiddleWare::UnLoadPlugin(const std::string& pName) +{ + m_PluginManager->UnLoadPlugin(pName); +} + +std::string CMiddleWare::GetUUID(const std::string& pLanguage, void* pData) +{ + CLanguage* language = m_PluginManager->GetLanguage(pLanguage); + if (language == NULL) + { + return ""; + } + return language->GetUUID(pData); +} + +std::string CMiddleWare::GetReport(const std::string& pLanguage, void* pData) +{ + CLanguage* language = m_PluginManager->GetLanguage(pLanguage); + if (language == NULL) + { + return ""; + } + return language->GetReport(pData); +} + +int CMiddleWare::Report(const std::string& pReporter, const std::string& pDebugDumpPath) +{ + CReporter* reporter = m_PluginManager->GetReporter(pReporter); + if (reporter == NULL) + { + return -1; + } + reporter->Report(pDebugDumpPath); +} + diff --git a/lib/MiddleWare/MiddleWare.h b/lib/MiddleWare/MiddleWare.h new file mode 100644 index 00000000..105266e2 --- /dev/null +++ b/lib/MiddleWare/MiddleWare.h @@ -0,0 +1,51 @@ +/* + MiddleWare.h - header file for MiddleWare library. It wraps plugins and + take case of them. + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@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. + */ + + +#ifndef MIDDLEWARE_H_ +#define MIDDLEWARE_H_ + +#include "PluginManager.h" + +class CMiddleWare +{ + private: + + CPluginManager* m_PluginManager; + + public: + CMiddleWare(const std::string& pPlugisConfDir, + const std::string& pPlugisLibDir); + + ~CMiddleWare(); + + void LoadPlugins(); + void LoadPlugin(const std::string& pName); + void UnLoadPlugin(const std::string& pName); + + std::string GetUUID(const std::string& pLanguage, void* pData); + std::string GetReport(const std::string& pLanguage, void* pData); + int Report(const std::string& pReporter, const std::string& pDebugDumpPath); + //void SaveDebugDumpToDataBase(const std::string& pPath); +}; + +#endif /*MIDDLEWARE_H_*/ diff --git a/lib/MiddleWare/Plugin.h b/lib/MiddleWare/Plugin.h new file mode 100644 index 00000000..7b4168c4 --- /dev/null +++ b/lib/MiddleWare/Plugin.h @@ -0,0 +1,86 @@ +/* + Plugin.h - header file for plugin. It contains mandatory macros + and common function for plugins + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@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. + */ + +#ifndef PLUGIN_H_ +#define PLUGIN_H_ + +#include <string> +#include <map> +#include <fstream> + +#define PLUGINS_MAGIC_NUMBER 1 + +#define PLUGINS_CONF_EXTENSION "conf" +#define PLUGINS_LIB_EXTENSIONS "so" + +typedef std::map<std::string, std::string> map_settings_t; + +class CPlugin +{ + public: + virtual ~CPlugin() {} + + virtual void Init(const map_settings_t& pSettings) = 0; + virtual void DeInit() = 0; +}; + +typedef enum { LANGUAGE, REPORTER, APPLICATION, DATABASE } plugin_type_t; + +typedef struct SPluginInfo +{ + const plugin_type_t m_Type; + const std::string m_sName; + const std::string m_sVersion; + const std::string m_sDescription; + const std::string m_sEmail; + const std::string m_sWWW; + const int m_nMagicNumber; +} plugin_info_t; + +#define PLUGIN_IFACE extern "C" + +#define PLUGIN_INIT(plugin_class)\ + PLUGIN_IFACE CPlugin* plugin_new()\ + {\ + plugin_class* plugin = new plugin_class();\ + if (plugin == NULL)\ + {\ + throw std::string("Not enought memory");\ + }\ + return plugin;\ + }\ + + +#define PLUGIN_INFO(type, name, version,\ + description, email, www)\ + PLUGIN_IFACE const plugin_info_t plugin_info =\ + {\ + type,\ + name,\ + version,\ + description,\ + email,\ + www,\ + PLUGINS_MAGIC_NUMBER,\ + }; + +#endif /* PLUGIN_H_ */ diff --git a/lib/MiddleWare/PluginManager.cpp b/lib/MiddleWare/PluginManager.cpp new file mode 100644 index 00000000..4e4c56da --- /dev/null +++ b/lib/MiddleWare/PluginManager.cpp @@ -0,0 +1,254 @@ +/* + PluginManager.cpp + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@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 <iostream> +#include "PluginManager.h" +#include <dirent.h> +#include <stdio.h> +#include <sys/types.h> + +CPluginManager::CPluginManager(const std::string& pPlugisConfDir, + const std::string& pPlugisLibDir) : + m_sPlugisConfDir(pPlugisConfDir), + m_sPlugisLibDir(pPlugisLibDir) +{} + +CPluginManager::~CPluginManager() +{ + map_crash_catcher_plugins_t::iterator it_p; + while ((it_p = m_mapCrashCatcherPlugins.begin()) != m_mapCrashCatcherPlugins.end()) + { + std::string pluginName = it_p->first; + UnLoadPlugin(pluginName); + } +} + +void CPluginManager::LoadPlugins() +{ + DIR *dir = opendir(m_sPlugisConfDir.c_str()); + struct dirent *dent = NULL; + if (dir != NULL) + { + while ((dent = readdir(dir)) != NULL) + { + if (dent->d_type == DT_REG) + { + std::string name = dent->d_name; + std::string extension = name.substr(name.length()-sizeof(PLUGINS_CONF_EXTENSION)+1); + if (extension == PLUGINS_CONF_EXTENSION) + { + name.erase(name.length()-sizeof(PLUGINS_CONF_EXTENSION)); + LoadPlugin(name); + } + } + } + closedir(dir); + } +} + +void CPluginManager::LoadPlugin(const std::string& pName) +{ + if (m_mapCrashCatcherPlugins.find(pName) == m_mapCrashCatcherPlugins.end()) + { + CCrashCatcherPlugin* crashCatcherPlugin = NULL; + CPlugin* plugin = NULL; + try + { + std::string libPath = m_sPlugisLibDir + "/lib" + pName + "." + PLUGINS_LIB_EXTENSIONS; + crashCatcherPlugin = new CCrashCatcherPlugin(libPath); + if (crashCatcherPlugin->GetMagicNumber() != PLUGINS_MAGIC_NUMBER) + { + throw std::string("non-compatible plugin"); + } + crashCatcherPlugin->LoadSettings(m_sPlugisConfDir + "/" + pName + "." + PLUGINS_CONF_EXTENSION); + std::cerr << "Loaded Plugin " << pName << " (" << crashCatcherPlugin->GetVersion() << ") " << "succesfully loaded." << std::endl; + std::cerr << " Description: " << crashCatcherPlugin->GetDescription() << std::endl; + std::cerr << " Email: " << crashCatcherPlugin->GetEmail() << std::endl; + std::cerr << " WWW: " << crashCatcherPlugin->GetWWW() << std::endl; + m_mapCrashCatcherPlugins[pName] = crashCatcherPlugin; + + if (crashCatcherPlugin->IsEnabled()) + { + plugin = crashCatcherPlugin->PluginNew(); + plugin->Init(crashCatcherPlugin->GetSettings()); + RegisterPlugin(plugin, pName, crashCatcherPlugin->GetType()); + } + + } + catch (std::string sError) + { + if (plugin != NULL) + { + delete plugin; + } + if (crashCatcherPlugin != NULL) + { + delete plugin; + } + std::cerr << "Failed to load plugin " << pName << " (" << sError << ")." << std::endl; + } + } +} + +void CPluginManager::UnLoadPlugin(const std::string& pName) +{ + if (m_mapCrashCatcherPlugins.find(pName) != m_mapCrashCatcherPlugins.end()) + { + UnRegisterPlugin(pName, m_mapCrashCatcherPlugins[pName]->GetType()); + delete m_mapCrashCatcherPlugins[pName]; + m_mapCrashCatcherPlugins.erase(pName); + std::cerr << "Plugin " << pName << " sucessfully unloaded." << std::endl; + } +} + + +void CPluginManager::RegisterPlugin(CPlugin* pPlugin, + const std::string pName, + const plugin_type_t& pPluginType) +{ + switch (pPluginType) + { + case LANGUAGE: + { + m_mapLanguages[pName] = (CLanguage*)pPlugin; + std::cerr << "Registred Language plugin " << pName << std::endl; + } + break; + case REPORTER: + { + m_mapReporters[pName] = (CReporter*)pPlugin; + std::cerr << "Registred Reporter plugin " << pName << std::endl; + } + break; + case APPLICATION: + { + m_mapApplications[pName] = (CApplication*)pPlugin; + std::cerr << "Registred Application plugin " << pName << std::endl; + } + break; + case DATABASE: + { + m_mapDatabases[pName] = (CDatabase*)pPlugin; + std::cerr << "Registred Database plugin " << pName << std::endl; + } + break; + default: + { + std::cerr << "Trying to register unknown type of plugin." << std::endl; + } + break; + } +} + +void CPluginManager::UnRegisterPlugin(const std::string pName, const plugin_type_t& pPluginType) +{ + switch (pPluginType) + { + case LANGUAGE: + { + if (m_mapLanguages.find(pName) != m_mapLanguages.end()) + { + m_mapLanguages[pName]->DeInit(); + delete m_mapLanguages[pName]; + m_mapLanguages.erase(pName); + std::cerr << "UnRegistred Language plugin " << pName << std::endl; + } + } + break; + case REPORTER: + { + if (m_mapReporters.find(pName) != m_mapReporters.end()) + { + m_mapReporters[pName]->DeInit(); + delete m_mapReporters[pName]; + m_mapReporters.erase(pName); + std::cerr << "UnRegistred Reporter plugin " << pName << std::endl; + } + } + break; + case APPLICATION: + { + if (m_mapApplications.find(pName) != m_mapApplications.end()) + { + m_mapApplications[pName]->DeInit(); + delete m_mapApplications[pName]; + m_mapApplications.erase(pName); + std::cerr << "UnRegistred Application plugin " << pName << std::endl; + } + } + break; + case DATABASE: + { + if (m_mapDatabases.find(pName) != m_mapDatabases.end()) + { + m_mapDatabases[pName]->DeInit(); + delete m_mapDatabases[pName]; + m_mapDatabases.erase(pName); + std::cerr << "UnRegistred Database plugin " << pName << std::endl; + } + } + break; + default: + std::cerr << "Trying to unregister unknown type of plugin." << std::endl; + break; + } +} + +CLanguage* CPluginManager::GetLanguage(const std::string& pName) +{ + if (m_mapLanguages.find(pName) != m_mapLanguages.end()) + { + return m_mapLanguages[pName]; + } + + return NULL; +} + +CReporter* CPluginManager::GetReporter(const std::string& pName) +{ + if (m_mapReporters.find(pName) != m_mapReporters.end()) + { + return m_mapReporters[pName]; + } + + return NULL; +} + +CApplication* CPluginManager::GetApplication(const std::string& pName) +{ + if (m_mapApplications.find(pName) != m_mapApplications.end()) + { + return m_mapApplications[pName]; + } + + return NULL; +} + +CDatabase* CPluginManager::GetDatabase(const std::string& pName) +{ + if (m_mapDatabases.find(pName) != m_mapDatabases.end()) + { + return m_mapDatabases[pName]; + } + + return NULL; +} + diff --git a/lib/MiddleWare/PluginManager.h b/lib/MiddleWare/PluginManager.h new file mode 100644 index 00000000..56799833 --- /dev/null +++ b/lib/MiddleWare/PluginManager.h @@ -0,0 +1,78 @@ +/* + PluginManager.h - header file for plugin manager. it takes care about + (un)loading plugins + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@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. + */ + +#ifndef PLUGINMANAGER_H_ +#define PLUGINMANAGER_H_ + +#include <map> +#include <string> +#include "CrashCatcherPlugin.h" +#include "Plugin.h" +#include "Language.h" +#include "Reporter.h" +#include "Database.h" +#include "Application.h" + +class CPluginManager +{ + private: + typedef std::map<std::string, CCrashCatcherPlugin*> map_crash_catcher_plugins_t; + typedef std::map<std::string, CLanguage*> map_languages_t; + typedef std::map<std::string, CReporter*> map_reporters_t; + typedef std::map<std::string, CApplication*> map_applications_t; + typedef std::map<std::string, CDatabase*> map_databases_t; + + + map_crash_catcher_plugins_t m_mapCrashCatcherPlugins; + map_languages_t m_mapLanguages; + map_reporters_t m_mapReporters; + map_applications_t m_mapApplications; + map_databases_t m_mapDatabases; + + std::string m_sPlugisConfDir; + std::string m_sPlugisLibDir; + + void RegisterPlugin(CPlugin* pPlugin, + const std::string pName, + const plugin_type_t& pPluginType); + + void UnRegisterPlugin(const std::string pName, + const plugin_type_t& pPluginType); + + public: + CPluginManager(const std::string& pPlugisConfDir, + const std::string& pPlugisLibDir); + + ~CPluginManager(); + + void LoadPlugins(); + void LoadPlugin(const std::string& pName); + void UnLoadPlugin(const std::string& pName); + + CLanguage* GetLanguage(const std::string& pName); + CReporter* GetReporter(const std::string& pName); + CApplication* GetApplication(const std::string& pName); + CDatabase* GetDatabase(const std::string& pName); + +}; + +#endif /*PLUGINMANAGER_H_*/ diff --git a/lib/MiddleWare/Reporter.h b/lib/MiddleWare/Reporter.h new file mode 100644 index 00000000..cff912bc --- /dev/null +++ b/lib/MiddleWare/Reporter.h @@ -0,0 +1,35 @@ +/* + Reporter.h - header file for reporter plugin + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@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. + */ + +#ifndef REPORTER_H_ +#define REPORTER_H_ + +#include <string> +#include "Plugin.h" + +class CReporter : public CPlugin +{ + public: + virtual ~CReporter() {} + virtual void Report(const std::string& pDebugDumpPath) = 0; +}; + +#endif /* REPORTER_H_ */ diff --git a/lib/MiddleWare/test.cpp b/lib/MiddleWare/test.cpp new file mode 100644 index 00000000..380af469 --- /dev/null +++ b/lib/MiddleWare/test.cpp @@ -0,0 +1,58 @@ +/* + test.cpp - simple library test + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@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 "MiddleWare.h" +#include "DebugDump.h" +#include <iostream> +#include <sys/types.h> +#include <unistd.h> + + +int main(int argc, char** argv) +{ + + + try + { + CMiddleWare middleWare(PLUGINS_CONF_DIR, PLUGINS_LIB_DIR); + CDebugDump* dd; + + middleWare.LoadPlugins(); + middleWare.UnLoadPlugin("Mailx"); + + dd = new CDebugDump(DEBUG_DUMPS_DIR); + + dd->Delete(); + dd->Create(); + dd->SaveTextFile("UUID", middleWare.GetUUID("CCpp", (void*)"data")); + char pid[100]; + sprintf(pid, "%d", getpid()); + dd->SaveProc(pid); + + delete dd; + } + catch (std::string sError) + { + std::cerr << sError << std::endl; + } + + return 0; +} diff --git a/lib/Plugins/CCpp.conf b/lib/Plugins/CCpp.conf new file mode 100644 index 00000000..1d15667b --- /dev/null +++ b/lib/Plugins/CCpp.conf @@ -0,0 +1,3 @@ +# Configuration file for CCpp add-on +Enabled = yes +MemoryMap = no
\ No newline at end of file diff --git a/lib/Plugins/CCpp.cpp b/lib/Plugins/CCpp.cpp new file mode 100644 index 00000000..54ec0907 --- /dev/null +++ b/lib/Plugins/CCpp.cpp @@ -0,0 +1,80 @@ +/* + DebugDump.cpp + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@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 "CCpp.h" +#include <fstream> +#include <ctype.h> + +#define CORE_PATTERN_IFACE "/proc/sys/kernel/core_pattern" +#define CORE_PATTERN CCPP_HOOK_PATH" %p %t %s" + +CLanguageCCpp::CLanguageCCpp() : + m_bMemoryMap(false) +{} + +std::string CLanguageCCpp::GetUUID(void* pData) +{ + if (m_bMemoryMap) + return "UUID a memory map"; + else + return "UUID bez memory map"; +} + +std::string CLanguageCCpp::GetReport(void* pData) +{ + return "reportuju jak blazen"; +} + +void CLanguageCCpp::Init(const map_settings_t& pSettings) +{ + std::ifstream fInCorePattern; + fInCorePattern.open(CORE_PATTERN_IFACE); + if (fInCorePattern.is_open()) + { + getline(fInCorePattern, m_sOldCorePattern); + fInCorePattern.close(); + } + std::ofstream fOutCorePattern; + fOutCorePattern.open(CORE_PATTERN_IFACE); + if (fOutCorePattern.is_open()) + { + fOutCorePattern << CORE_PATTERN << std::endl; + fOutCorePattern.close(); + } + + if (pSettings.find("MemoryMap")!= pSettings.end()) + { + m_bMemoryMap = pSettings.find("MemoryMap")->second == "yes"; + } + +} + + +void CLanguageCCpp::DeInit() +{ + std::ofstream fOutCorePattern; + fOutCorePattern.open(CORE_PATTERN_IFACE); + if (fOutCorePattern.is_open()) + { + fOutCorePattern << m_sOldCorePattern << std::endl; + fOutCorePattern.close(); + } +} diff --git a/lib/Plugins/CCpp.h b/lib/Plugins/CCpp.h new file mode 100644 index 00000000..904ac7c5 --- /dev/null +++ b/lib/Plugins/CCpp.h @@ -0,0 +1,54 @@ +/* + CCpp.h - header file for C/C++ language plugin + - it can ger UUID and memory maps from core files + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@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. + */ + +#ifndef CCPP_H_ +#define CCPP_H_ + +#include <string> +#include "Plugin.h" +#include "Language.h" + +class CLanguageCCpp : public CLanguage +{ + private: + bool m_bMemoryMap; + std::string m_sOldCorePattern; + public: + CLanguageCCpp(); + virtual ~CLanguageCCpp() {} + std::string GetUUID(void* pData); + std::string GetReport(void* pData); + void Init(const map_settings_t& pSettings); + void DeInit(); +}; + + +PLUGIN_INFO(LANGUAGE, + "CCpp", + "0.0.1", + "Simple C/C++ language plugin.", + "zprikryl@redhat.com", + "https://fedorahosted.org/crash-catcher/wiki"); + +PLUGIN_INIT(CLanguageCCpp); + +#endif /* CCPP */ diff --git a/lib/Plugins/Mailx.conf b/lib/Plugins/Mailx.conf new file mode 100644 index 00000000..2b0be9c9 --- /dev/null +++ b/lib/Plugins/Mailx.conf @@ -0,0 +1,12 @@ +# Configuration to Email reporter plugin + +Enabled = no + +# Parameters +Parameters = + +# Your Email +Email_From = zprikryl@redhat.com + +# Email To +Email_To = jmoskovc@redhat.com diff --git a/lib/Plugins/Mailx.cpp b/lib/Plugins/Mailx.cpp new file mode 100644 index 00000000..7f4b7a76 --- /dev/null +++ b/lib/Plugins/Mailx.cpp @@ -0,0 +1,74 @@ +/* + Mailx.cpp + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@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 "Mailx.h" +#include <stdio.h> + +#define MAILX_COMMAND "mailx" +#define MAILX_SUBJECT "CrashCatcher automated bug report" + +CMailx::CMailx() : + m_sEmailFrom(""), + m_sEmailTo(""), + m_sParameters() +{} + + +void CMailx::SendEmail(const std::string& pText) +{ + FILE* command; + std::string mailx_command = MAILX_COMMAND + m_sParameters + + " -s " + MAILX_SUBJECT + + " -r " + m_sEmailTo + " " + m_sEmailFrom; + + command = popen(mailx_command.c_str(), "w"); + if (!command) + { + throw std::string("CMailx::SendEmail: Can not execute mailx."); + } + if (fputs(pText.c_str(), command) == -1) + { + throw std::string("CMailx::SendEmail: Can not send data."); + } + pclose(command); +} + + +void CMailx::Report(const std::string& pDebugDumpPath) +{ + SendEmail("Nejakej zbesilej report."); +} + +void CMailx::Init(const map_settings_t& pSettings) +{ + if (pSettings.find("Email_From")!= pSettings.end()) + { + m_sEmailFrom = pSettings.find("Email_From")->second; + } + if (pSettings.find("Email_To")!= pSettings.end()) + { + m_sEmailFrom = pSettings.find("Email_To")->second; + } + if (pSettings.find("Parameters")!= pSettings.end()) + { + m_sParameters = pSettings.find("Parameters")->second; + } +} diff --git a/lib/Plugins/Mailx.h b/lib/Plugins/Mailx.h new file mode 100644 index 00000000..e1463ea0 --- /dev/null +++ b/lib/Plugins/Mailx.h @@ -0,0 +1,58 @@ +/* + Mailx.h - header file for Mailx reporter plugin + - it simple sends an email to specific address via mailx command + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@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. + */ + +#ifndef MAILX_H_ +#define MAILX_H_ + +#include <string> +#include "Plugin.h" +#include "Reporter.h" + +class CMailx : public CReporter +{ + private: + std::string m_sEmailFrom; + std::string m_sEmailTo; + std::string m_sParameters; + + void SendEmail(const std::string& pText); + + public: + CMailx(); + virtual ~CMailx() {} + void Init(const map_settings_t& pSettings); + void DeInit() {} + void Report(const std::string& pDebugDumpPath); +}; + + +PLUGIN_INFO(REPORTER, + "Mailx", + "0.0.1", + "Sends an email with a report via mailx command", + "zprikryl@redhat.com", + "https://fedorahosted.org/crash-catcher/wiki"); + +PLUGIN_INIT(CMailx); + + +#endif /* MAILX_H_ */ diff --git a/lib/Plugins/Makefile.am b/lib/Plugins/Makefile.am new file mode 100644 index 00000000..02ccafbe --- /dev/null +++ b/lib/Plugins/Makefile.am @@ -0,0 +1,22 @@ +AM_CPPFLAGS = -I$(srcdir)/../MiddleWare +pluginslibdir=$(PLUGINS_LIB_DIR) +pluginslib_LTLIBRARIES = libCCpp.la libMailx.la libSQLite3.la + +pluginsconfdir=$(PLUGINS_CONF_DIR) +pluginsconf_DATA = CCpp.conf Mailx.conf SQLite3.conf + +# CCpp +libCCpp_la_SOURCES = CCpp.cpp CCpp.h +libCCpp_la_LDFLAGS = -version-info 0:1:0 +libCCpp_la_CPPFLAGS = -I$(srcdir)/../MiddleWare -DCCPP_HOOK_PATH=\"${libexecdir}/hookCCpp\" + +# Mailx +libMailx_la_SOURCES = Mailx.cpp Mailx.h +libMailx_la_LDFLAGS = -version-info 0:1:0 + +# SQLite3 +libSQLite3_la_SOURCES = SQLite3.cpp SQLite3.h +libSQLite3_la_LDFLAGS = -version-info 0:1:0 +libSQLite3_la_LIBADD = $(SQLITE3_LIBS) +libSQLite3_la_CPPFLAGS = -I$(srcdir)/../MiddleWare $(SQLITE3_CFLAGS) + diff --git a/lib/Plugins/SQLite3.conf b/lib/Plugins/SQLite3.conf new file mode 100644 index 00000000..663bbf81 --- /dev/null +++ b/lib/Plugins/SQLite3.conf @@ -0,0 +1,5 @@ +# Configuration file for database plugin SQLite3 + +Enabled = yes +# DB path +DBPath = /tmp/CCDB diff --git a/lib/Plugins/SQLite3.cpp b/lib/Plugins/SQLite3.cpp new file mode 100644 index 00000000..05beb1b0 --- /dev/null +++ b/lib/Plugins/SQLite3.cpp @@ -0,0 +1,255 @@ +/* + DebugDump.h - header file for the library caring of writing new reports + to the specific directory + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@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 <sqlite3.h> +#include "SQLite3.h" +#include <string> + + +#define TABLE_NAME "CrashCatcher" + +CSQLite3::CSQLite3() : + m_sDBPath(""), + m_pDB(NULL) +{} + +bool CSQLite3::IsReported(const std::string& pUUID) +{ + vector_database_rows_t table; + GetTable("SELECT "DATABASE_COLUMN_REPORTED" FROM "TABLE_NAME" WHERE "DATABASE_COLUMN_UUID" = '"+pUUID+"';", table); + if(table.empty()) + { + return false; + } + return true; +} + +void CSQLite3::Exec(const std::string& pCommand) +{ + char *err; + int ret = sqlite3_exec(m_pDB, pCommand.c_str(), 0, 0, &err); + if (ret != SQLITE_OK) + { + throw std::string("SQLite3::Exec(): Error on: " + pCommand + " " + err); + } +} + +void CSQLite3::GetTable(const std::string& pCommand, vector_database_rows_t& pTable) +{ + + char **table; + int ncol, nrow; + char *err; + int ret = sqlite3_get_table(m_pDB, pCommand.c_str(), &table, &nrow, &ncol, &err); + if (ret != SQLITE_OK) + { + throw std::string("SQLite3::GetTable(): Error on: " + pCommand + " " + err); + } + pTable.clear(); + int ii; + for (ii = 0; ii < nrow; ii++) + { + int jj; + database_row_t row; + for (jj = 0; jj < ncol; jj++) + { + switch(jj) + { + case 0: row.m_sUUID = table[jj + ncol]; + break; + case 1: row.m_sDebugDumpPath = table[jj + ncol]; + break; + case 2: row.m_sArchitecture = table[jj + ncol]; + break; + case 3: row.m_sKernel = table[jj + ncol]; + break; + case 4: row.m_sExecutable = table[jj + ncol]; + break; + case 5: row.m_sPackage = table[jj + ncol]; + break; + case 6: row.m_sUID = table[jj + ncol]; + break; + case 7: row.m_sTime = table[jj + ncol]; + break; + case 8: row.m_sCount = table[jj + ncol]; + break; + case 9: row.m_sReported = table[jj + ncol]; + break; + case 10: row.m_sBackTrace = table[jj + ncol]; + break; + case 11: row.m_sTextData1 = table[jj + ncol]; + break; + default: + break; + } + } + pTable.push_back(row); + } + sqlite3_free_table(table); +} + + +void CSQLite3::Connect() +{ + int ret = sqlite3_open_v2(m_sDBPath.c_str(), + &m_pDB, + SQLITE_OPEN_READWRITE, + NULL); + + if(ret == SQLITE_CANTOPEN) + { + Create(); + } + else if (ret != SQLITE_OK) + { + throw std::string("SQLite3::Connect(): Could not open database.") + sqlite3_errmsg(m_pDB); + } +} + +void CSQLite3::Create() +{ + int ret = sqlite3_open_v2(m_sDBPath.c_str(), + &m_pDB, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, + NULL); + if(ret != SQLITE_OK) + { + throw std::string("SQLite3::Create(): Could not create database.") + sqlite3_errmsg(m_pDB); + } + + Exec("CREATE TABLE "TABLE_NAME"(" + DATABASE_COLUMN_UUID" VARCHAR NOT NULL PRIMARY KEY," + DATABASE_COLUMN_DEBUG_DUMP_PATH" VARCHAR NOT NULL," + DATABASE_COLUMN_ARCHITECTURE" VARCHAR(16) NOT NULL," + DATABASE_COLUMN_KERNEL" VARCHAR(32) NOT NULL," + DATABASE_COLUMN_EXECUTABLE" VARCHAR NOT NULL," + DATABASE_COLUMN_PACKAGE" VARCHAR(64) NOT NULL," + DATABASE_COLUMN_UID" VARCHAR(64) NOT NULL," + DATABASE_COLUMN_TIME" VARCHAR(32) NOT NULL," + DATABASE_COLUMN_COUNT" INT(10) NOT NULL DEFAULT 1," + DATABASE_COLUMN_REPORTED" INT(10) NOT NULL DEFAULT 0," + DATABASE_COLUMN_BACKTRACE" VARCHAR DEFAULT \"\"," + DATABASE_COLUMN_TEXTDATA1" VARCHAR DEFAULT \"\"" + ");"); +} + +void CSQLite3::DisConnect() +{ + sqlite3_close(m_pDB); +} + +void CSQLite3::Insert(const std::string& pUUID, + const std::string& pDebugDumpPath, + const std::string& pArch, + const std::string& pKernel, + const std::string& pExecutable, + const std::string& pPackage, + const std::string& pUID, + const std::string& pTime) +{ + if (!IsReported(pUUID)) + { + Exec("INSERT INTO "TABLE_NAME"(" + DATABASE_COLUMN_UUID"," + DATABASE_COLUMN_DEBUG_DUMP_PATH"," + DATABASE_COLUMN_ARCHITECTURE"," + DATABASE_COLUMN_KERNEL"," + DATABASE_COLUMN_EXECUTABLE"," + DATABASE_COLUMN_PACKAGE"," + DATABASE_COLUMN_UID"," + DATABASE_COLUMN_TIME")" + " VALUES ('"+pUUID+"'" + "'"+pDebugDumpPath+"'" + "'"+pArch+"'" + "'"+pKernel+"'" + "'"+pExecutable+"'" + "'"+pPackage+"'" + "'"+pUID+"'" + "'"+pTime+"'" + ");"); + } + else + { + Exec("UPDATE "TABLE_NAME" " + "SET "DATABASE_COLUMN_COUNT" = "DATABASE_COLUMN_COUNT" + 1 " + "WHERE "DATABASE_COLUMN_UUID" = '"+pUUID+"';"); + } +} + +void CSQLite3::Delete(const std::string& pUUID) +{ + if (IsReported(pUUID)) + { + Exec("DELETE FROM "TABLE_NAME + " WHERE "DATABASE_COLUMN_UUID" = '"+pUUID+"';"); + } +} + +void CSQLite3::InsertBackTrace(const std::string& pUUID, + const std::string& pBackTrace) +{ + if (IsReported(pUUID)) + { + Exec("UPDATE "TABLE_NAME + "SET "DATABASE_COLUMN_BACKTRACE" = "+pBackTrace+ + "WHERE "DATABASE_COLUMN_UUID" = '"+pUUID+"';"); + } +} + +void CSQLite3::InsertTextData1(const std::string& pUUID, + const std::string& pData) +{ + if (IsReported(pUUID)) + { + Exec("UPDATE "TABLE_NAME + "SET "DATABASE_COLUMN_TEXTDATA1" = "+pData+ + "WHERE "DATABASE_COLUMN_UUID" = '"+pUUID+"';"); + } +} + +const vector_database_rows_t CSQLite3::GetUIDData(const std::string& pUID) +{ + vector_database_rows_t table; + if (pUID == "0") + { + GetTable("SELECT * FROM "TABLE_NAME";", table); + Exec("UPDATE "TABLE_NAME" SET "DATABASE_COLUMN_REPORTED" = 1;"); + } + else + { + GetTable("SELECT * FROM "TABLE_NAME + " WHERE "DATABASE_COLUMN_UID" = '"+pUID+"';", + table); + Exec("UPDATE "TABLE_NAME + " SET "DATABASE_COLUMN_REPORTED" = 1 " + " WHERE "DATABASE_COLUMN_UID" = '"+pUID+"';"); + } + return table; +} + +void CSQLite3::Init(const map_settings_t& pSettings) +{ + if (pSettings.find("DBPath")!= pSettings.end()) + { + m_sDBPath = pSettings.find("DBPath")->second; + } +} diff --git a/lib/Plugins/SQLite3.h b/lib/Plugins/SQLite3.h new file mode 100644 index 00000000..5270988e --- /dev/null +++ b/lib/Plugins/SQLite3.h @@ -0,0 +1,80 @@ +/* + DebugDump.h - header file for the library caring of writing new reports + to the specific directory + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@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. + */ + +#ifndef SQLITE3_H_ +#define SQLITE3_H_ + +#include "Plugin.h" +#include "Database.h" + +class CSQLite3 : public CDatabase +{ + private: + + std::string m_sDBPath; + sqlite3* m_pDB; + + void Create(); + void Exec(const std::string& pCommand); + void GetTable(const std::string& pCommand, vector_database_rows_t& pTable); + bool IsReported(const std::string& pUUID); + + public: + CSQLite3(); + virtual ~CSQLite3() {} + + void Connect(); + void DisConnect(); + + void Insert(const std::string& pUUID, + const std::string& pDebugDumpPath, + const std::string& pArch, + const std::string& pKernel, + const std::string& pExecutable, + const std::string& pPackage, + const std::string& pUID, + const std::string& pTime); + + void InsertBackTrace(const std::string& pUUID, + const std::string& pBackTrace); + + void InsertTextData1(const std::string& pUUID, + const std::string& pData); + + void Delete(const std::string& pUUID); + + const vector_database_rows_t GetUIDData(const std::string& pUID); + + void Init(const map_settings_t& pSettings); + void DeInit() {} +}; + +PLUGIN_INFO(DATABASE, + "SQLite3", + "0.0.1", + "SQLite3 database plugin.", + "zprikryl@redhat.com", + "https://fedorahosted.org/crash-catcher/wiki"); + +PLUGIN_INIT(CSQLite3); + +#endif /* SQLITE3_H_ */ diff --git a/src/Applet/Applet.cpp b/src/Applet/Applet.cpp new file mode 100644 index 00000000..39b0cc41 --- /dev/null +++ b/src/Applet/Applet.cpp @@ -0,0 +1,40 @@ +#include "CCApplet.h" +#include "DBusManager.h" +#include <iostream> + +//@@global applet object +CApplet *applet; +static void +crash_notify_cb(DBusGProxy *proxy, char* progname, gpointer user_data) +{ + 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(); +} + +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 */ + Gtk::Main::run(); + return 0; +} diff --git a/src/Applet/CCApplet.cpp b/src/Applet/CCApplet.cpp new file mode 100644 index 00000000..a48260cd --- /dev/null +++ b/src/Applet/CCApplet.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 "CCApplet.h" + +CApplet::CApplet() +{ + m_nStatusIcon = Gtk::StatusIcon::create(Gtk::Stock::DIALOG_WARNING); + m_nStatusIcon->set_visible(false); +} + +CApplet::~CApplet() +{ +} + +void CApplet::ShowIcon() +{ + m_nStatusIcon->set_visible(true); +} + +void CApplet::HideIcon() +{ + m_nStatusIcon->set_visible(false); +} + +void CApplet::BlinkIcon(bool pBlink) +{ + m_nStatusIcon->set_blinking(pBlink); +} diff --git a/src/Applet/CCApplet.h b/src/Applet/CCApplet.h new file mode 100644 index 00000000..83c3e750 --- /dev/null +++ b/src/Applet/CCApplet.h @@ -0,0 +1,37 @@ +/* + 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. + */ + +#ifndef CC_APPLET_H_ +#define CC_APPLET_H_ + +#include <gtkmm.h> + +class CApplet +{ + private: + Glib::RefPtr<Gtk::StatusIcon> m_nStatusIcon; + public: + CApplet(); + ~CApplet(); + void ShowIcon(); + void HideIcon(); + void BlinkIcon(bool pBlink); +}; + +#endif /*CC_APPLET_H_*/ diff --git a/src/Applet/Makefile.am b/src/Applet/Makefile.am new file mode 100644 index 00000000..f98b5bc0 --- /dev/null +++ b/src/Applet/Makefile.am @@ -0,0 +1,6 @@ +bin_PROGRAMS = applet +applet_SOURCES = Applet.cpp CCApplet.cpp CCApplet.h +applet_CPPFLAGS = -I../../lib/MiddleWare \ + -I../../lib/DBus \ + -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" $(DBUS_GLIB_CFLAGS) $(GTKMM_CFLAGS) +applet_LDADD = ../../lib/MiddleWare/libMiddleWare.la ../../lib/DBus/libDBus.la $(DL_LIBS) $(GTKMM_LIBS) diff --git a/src/Daemon/CrashWatcher.cpp b/src/Daemon/CrashWatcher.cpp new file mode 100644 index 00000000..2155b2b7 --- /dev/null +++ b/src/Daemon/CrashWatcher.cpp @@ -0,0 +1,176 @@ +/* + 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 "CrashWatcher.h" +#include <unistd.h> +#include <iostream> +#include <climits> +#include <cstdlib> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <cstring> +#include <csignal> + +void terminate(int signal) +{ + exit(0); +} + +gboolean CCrashWatcher::handle_event_cb(GIOChannel *gio, GIOCondition condition, gpointer daemon){ + GIOError err; + char buf[INOTIFY_BUFF_SIZE]; + guint len; + int i = 0; + err = g_io_channel_read (gio, buf, INOTIFY_BUFF_SIZE, &len); + if (err != G_IO_ERROR_NONE) { + g_warning ("Error reading inotify fd: %d\n", err); + return FALSE; + } + /* reconstruct each event and send to the user's callback */ + while (i < len) { + const char *name; + struct inotify_event *event; + + event = (struct inotify_event *) &buf[i]; + if (event->len) + name = &buf[i] + sizeof (struct inotify_event); + i += sizeof (struct inotify_event) + event->len; +#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); + } + return TRUE; +} + +CCrashWatcher::CCrashWatcher(const std::string& pPath) +{ + int watch = 0; + m_sTarget = pPath; + m_nMainloop = g_main_loop_new(NULL,FALSE); + /* register on dbus */ + m_nDbus_manager.RegisterService(); + if((m_nFd = inotify_init()) == -1){ + throw std::string("Init Failed"); + //std::cerr << "Init Failed" << std::endl; + exit(-1); + } + 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() +{ +} + +void CCrashWatcher::Lock() +{ + int lfp = open("crashcatcher.lock",O_RDWR|O_CREAT,0640); + if (lfp < 0) + throw "CCrashWatcher.cpp:can not open lock file"; + if (lockf(lfp,F_TLOCK,0) < 0) + throw "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 */ +} + +void CCrashWatcher::StartWatch() +{ + char *buff = new char[INOTIFY_BUFF_SIZE]; + int len = 0; + int i = 0; + char action[FILENAME_MAX]; + struct inotify_event *pevent; + //run forever + while(1){ + i = 0; + len = read(m_nFd,buff,INOTIFY_BUFF_SIZE); + while(i < len){ + pevent = (struct inotify_event *)&buff[i]; + if (pevent->len) + std::strcpy(action, pevent->name); + else + std::strcpy(action, m_sTarget.c_str()); + i += sizeof(struct inotify_event) + pevent->len; +#ifdef DEBUG + std::cout << "Created file: " << action << std::endl; +#endif /*DEBUG*/ + } + } + delete[] buff; +} + +/* daemon loop with glib */ +void CCrashWatcher::GStartWatch() +{ + char *buff = new char[INOTIFY_BUFF_SIZE]; + int len = 0; + int i = 0; + char action[FILENAME_MAX]; + struct inotify_event *pevent; + g_io_add_watch (m_nGio, G_IO_IN, handle_event_cb, this); + //enter the event loop + g_main_run (m_nMainloop); + delete[] buff; +} + +void CCrashWatcher::RegisterSignals() +{ + signal(SIGTERM, terminate); +} + +void CCrashWatcher::Daemonize() +{ +#ifdef DEBUG + std::cout << "Daemonize" << std::endl; +#endif + // forking to background + pid_t pid = fork(); + if (pid < 0) + { + throw "CCrashWatcher.cpp:Daemonize:Fork error"; + } + /* parent exits */ + if (pid > 0) _exit(0); + /* child (daemon) continues */ + pid_t sid = setsid(); + if(sid == -1){ + throw "CCrashWatcher.cpp:Daemonize:setsid failed"; + } + Lock(); + GStartWatch(); +} + +void CCrashWatcher::Run() +{ +#ifdef DEBUG + std::cout << "Run" << std::endl; +#endif + Lock(); + GStartWatch(); +} + diff --git a/src/Daemon/CrashWatcher.h b/src/Daemon/CrashWatcher.h new file mode 100644 index 00000000..77cc1562 --- /dev/null +++ b/src/Daemon/CrashWatcher.h @@ -0,0 +1,58 @@ +/* + 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. + */ + +#ifndef CRASHWATCHER_H_ +#define CRASHWATCHER_H_ + +#include <string> +#include <sys/inotify.h> +#include <sys/inotify.h> +#include <glib.h> +#include "DBusManager.h" +#include "MiddleWare.h" + +// 1024 simultaneous actions +#define INOTIFY_BUFF_SIZE ((sizeof(struct inotify_event)+FILENAME_MAX)*1024) + + +class CCrashWatcher +{ + private: + static gboolean handle_event_cb(GIOChannel *gio, GIOCondition condition, gpointer data); + void RegisterSignals(); + void StartWatch(); + void GStartWatch(); + void Lock(); + + CDBusManager m_nDbus_manager; + int m_nFd; + GIOChannel* m_nGio; + GMainLoop *m_nMainloop; + std::string m_sTarget; + public: + CCrashWatcher(const std::string& pPath); + //CCrashWatcher(); + ~CCrashWatcher(); + //run as daemon + void Daemonize(); + //don't go background - for debug + void Run(); +}; + +#endif /*CRASHWATCHER_H_*/ diff --git a/src/Daemon/Daemon.cpp b/src/Daemon/Daemon.cpp new file mode 100644 index 00000000..2f0e575b --- /dev/null +++ b/src/Daemon/Daemon.cpp @@ -0,0 +1,66 @@ +/* + 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 "CrashWatcher.h" +#include <iostream> + +#define daemonize 0 + +int main(int argc, char** argv){ + try{ + CCrashWatcher daemon(DEBUG_DUMPS_DIR); + //if (argc > 1){ + // if (strcmp(argv[1], "-d") == 0){ + // daemonize = 0; + // } + // } + if(daemonize){ + try{ + daemon.Daemonize(); + } + catch(std::string err) + { + std::cerr << err << std::endl; + } + catch(...){ + std::cerr << "daemon.cpp:Daemonize" << std::endl; + } + } + else{ + try{ + #ifdef DEBUG + std::cerr << "trying to run" << std::endl; + #endif /*DEBUG*/ + daemon.Run(); + } + catch(std::string err) + { + std::cerr << err << std::endl; + } + catch(...){ + std::cerr << "daemon.cpp:Run" << std::endl; + } + } + } + catch(std::string err) + { + std::cerr << "Cannot create daemon: " << err << std::endl; + } +} + diff --git a/src/Daemon/Makefile.am b/src/Daemon/Makefile.am new file mode 100644 index 00000000..395eb120 --- /dev/null +++ b/src/Daemon/Makefile.am @@ -0,0 +1,6 @@ +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) +CrashCatcher_LDADD = ../../lib/MiddleWare/libMiddleWare.la ../../lib/DBus/libDBus.la $(DL_LIBS) diff --git a/src/Hooks/CCpp.cpp b/src/Hooks/CCpp.cpp new file mode 100644 index 00000000..79156d27 --- /dev/null +++ b/src/Hooks/CCpp.cpp @@ -0,0 +1,94 @@ +/* + CCpp.cpp - the hook for C/C++ crashing program + + Copyright (C) 2009 Zdenek Prikryl (zprikryl@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 "DebugDump.h" +#include <stdlib.h> +#include <string.h> +#include <limits.h> +#include <stdio.h> +#include <unistd.h> + +#define CORESTEP (1024) + +int main(int argc, char** argv) +{ + const char* program_name = argv[0]; + if (argc < 4) + { + fprintf(stderr, "Usage: %s: <pid> <time> <signal>\n", + program_name); + return -1; + } + const char* pid = argv[1]; + const char* time = argv[2]; + const char* signal = argv[3]; + + if (strcmp(signal, "11") != 0) + { + return 0; + } + + char path[PATH_MAX]; + CDebugDump dd; + snprintf(path, sizeof(path), "%s/%s%s", DEBUG_DUMPS_DIR, time, pid); + try + { + dd.Open(path, CDebugDump::CREATE); + dd.SaveText(FILENAME_TIME, time); + dd.SaveText(FILENAME_LANGUAGE, "CCpp"); + dd.SaveProc(pid); + + int size = CORESTEP*sizeof(char); + int ii = 0; + int data = 0; + char* core = NULL; + if ((core = (char*)malloc(size)) == NULL) + { + fprintf(stderr, "%s: not enaught memory.\n", program_name); + perror(""); + return -3; + } + while ((data = getc(stdin)) != EOF) + { + if (ii >= size) + { + size *= CORESTEP*sizeof(char); + if ((core = (char*)realloc(core, size)) == NULL) + { + fprintf(stderr, "%s: not enaught memory.\n", program_name); + perror(""); + return -3; + } + } + core[ii] = data; + ii++; + } + dd.SaveBinary(FILENAME_BINARY_FILE1, core, ii); + free(core); + } + catch (std::string sError) + { + fprintf(stderr, "%s: %s\n", program_name, sError.c_str()); + return -2; + } + + return 0; +} diff --git a/src/Hooks/Makefile.am b/src/Hooks/Makefile.am new file mode 100644 index 00000000..92efb6eb --- /dev/null +++ b/src/Hooks/Makefile.am @@ -0,0 +1,5 @@ +libexec_PROGRAMS = hookCCpp +hookCCpp_SOURCES = CCpp.cpp +hookCCpp_LDADD = ../../lib/DebugDump/libDebugDump.la +hookCCpp_CPPFLAGS = -I$(srcdir)/../../lib/DebugDump \ + -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\"
\ No newline at end of file diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 00000000..e653c2a8 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = Hooks Daemon Applet
\ No newline at end of file |