diff options
| author | Karel Klic <kklic@redhat.com> | 2009-11-11 22:30:27 +0100 |
|---|---|---|
| committer | Karel Klic <kklic@redhat.com> | 2009-11-11 22:30:27 +0100 |
| commit | 07a12979cbf321c03c615f921aec601492e8d196 (patch) | |
| tree | a0eba8c5b0cf06be829c378ca8704470e37a036b /lib/Utils | |
| parent | 4bb5f0163c1cf3c65745ea06f1b42545ecaa35d7 (diff) | |
| parent | 640af192338643b3c9e6fbe0304726e951239c2b (diff) | |
| download | abrt-07a12979cbf321c03c615f921aec601492e8d196.tar.gz abrt-07a12979cbf321c03c615f921aec601492e8d196.tar.xz abrt-07a12979cbf321c03c615f921aec601492e8d196.zip | |
Merge branch 'master' of ssh://git.fedorahosted.org/git/abrt
Diffstat (limited to 'lib/Utils')
| -rw-r--r-- | lib/Utils/Action.h | 6 | ||||
| -rw-r--r-- | lib/Utils/Analyzer.h | 6 | ||||
| -rw-r--r-- | lib/Utils/CommLayerInner.cpp | 57 | ||||
| -rw-r--r-- | lib/Utils/CommLayerInner.h | 16 | ||||
| -rw-r--r-- | lib/Utils/DebugDump.cpp | 208 | ||||
| -rw-r--r-- | lib/Utils/DebugDump.h | 10 | ||||
| -rw-r--r-- | lib/Utils/Makefile.am | 5 | ||||
| -rw-r--r-- | lib/Utils/Observer.h | 4 | ||||
| -rw-r--r-- | lib/Utils/Plugin.cpp | 13 | ||||
| -rw-r--r-- | lib/Utils/Plugin.h | 6 | ||||
| -rw-r--r-- | lib/Utils/abrt_xmlrpc.cpp | 76 | ||||
| -rw-r--r-- | lib/Utils/abrt_xmlrpc.h | 27 | ||||
| -rw-r--r-- | lib/Utils/copyfd.cpp | 22 | ||||
| -rw-r--r-- | lib/Utils/logging.cpp | 46 | ||||
| -rw-r--r-- | lib/Utils/parse_release.cpp | 38 | ||||
| -rw-r--r-- | lib/Utils/xfuncs.cpp | 13 |
16 files changed, 355 insertions, 198 deletions
diff --git a/lib/Utils/Action.h b/lib/Utils/Action.h index 1286feb..5992cbf 100644 --- a/lib/Utils/Action.h +++ b/lib/Utils/Action.h @@ -22,7 +22,6 @@ #ifndef ACTION_H_ #define ACTION_H_ -#include <string> #include "Plugin.h" /** @@ -40,8 +39,7 @@ class CAction : public CPlugin * @param pActionDir An actual directory. * @param pArgs Plugin's arguments. */ - virtual void Run(const std::string& pActionDir, - const std::string& pArgs) = 0; + virtual void Run(const char *pActionDir, const char *pArgs) = 0; }; -#endif /*ACTION_H_*/ +#endif diff --git a/lib/Utils/Analyzer.h b/lib/Utils/Analyzer.h index e5bda57..9108a91 100644 --- a/lib/Utils/Analyzer.h +++ b/lib/Utils/Analyzer.h @@ -37,20 +37,20 @@ class CAnalyzer : public CPlugin * @param pDebugDumpPath A debugdump dir containing all necessary data. * @return A local UUID. */ - virtual std::string GetLocalUUID(const std::string& pDebugDumpPath) = 0; + virtual std::string GetLocalUUID(const char *pDebugDumpDir) = 0; /** * A method, which gets a global UUID of particular crash. * @param pDebugDumpPath A debugdump dir containing all necessary data. * @return A global UUID. */ - virtual std::string GetGlobalUUID(const std::string& pDebugDumpPath) = 0; + virtual std::string GetGlobalUUID(const char *pDebugDumpDir) = 0; /** * A method, which takes care of getting all additional data needed * for computing UUIDs and creating a report. This report could be send * somewhere afterwards. * @param pDebugDumpPath A debugdump dir containing all necessary data. */ - virtual void CreateReport(const std::string& pDebugDumpPath, int force) = 0; + virtual void CreateReport(const char *pDebugDumpDir, int force) = 0; }; #endif /*ANALYZER_H_*/ diff --git a/lib/Utils/CommLayerInner.cpp b/lib/Utils/CommLayerInner.cpp index b5b8db7..307fe66 100644 --- a/lib/Utils/CommLayerInner.cpp +++ b/lib/Utils/CommLayerInner.cpp @@ -10,29 +10,48 @@ static map_uint_str_t s_mapClientID; static pthread_mutex_t s_map_mutex; static bool s_map_mutex_inited; +/* called via [p]error_msg() */ +static void warn_client(const char *msg) +{ + if (!s_pObs) + return; + + uint64_t key = uint64_t(pthread_self()); + + pthread_mutex_lock(&s_map_mutex); + map_uint_str_t::const_iterator ki = s_mapClientID.find(key); + const char* peer = (ki != s_mapClientID.end() ? ki->second.c_str() : NULL); + pthread_mutex_unlock(&s_map_mutex); + + if (peer) + s_pObs->Warning(msg, peer, key); +} + void init_daemon_logging(CObserver *pObs) { s_pObs = pObs; if (!s_map_mutex_inited) { - pthread_mutex_init(&s_map_mutex, NULL); s_map_mutex_inited = true; + pthread_mutex_init(&s_map_mutex, NULL); + g_custom_logger = &warn_client; } } -void set_client_name(const char* name) +void set_client_name(const char *name) { uint64_t key = uint64_t(pthread_self()); pthread_mutex_lock(&s_map_mutex); - if (!name) + if (!name) { s_mapClientID.erase(key); - else + } else { s_mapClientID[key] = name; + } pthread_mutex_unlock(&s_map_mutex); } -void warn_client(const std::string& pMessage) +void update_client(const char *fmt, ...) { if (!s_pObs) return; @@ -44,26 +63,16 @@ void warn_client(const std::string& pMessage) const char* peer = (ki != s_mapClientID.end() ? ki->second.c_str() : NULL); pthread_mutex_unlock(&s_map_mutex); - if (peer) - s_pObs->Warning(pMessage, peer, key); - else /* Bug: someone tries to warn_client() without set_client_name()!? */ - log("Hmm, stray %s: '%s'", __func__, pMessage.c_str()); -} - -void update_client(const std::string& pMessage) -{ - if (!s_pObs) + if (!peer) return; - uint64_t key = uint64_t(pthread_self()); + va_list p; + va_start(p, fmt); + char *msg; + int used = vasprintf(&msg, fmt, p); + va_end(p); + if (used < 0) + return; - pthread_mutex_lock(&s_map_mutex); - map_uint_str_t::const_iterator ki = s_mapClientID.find(key); - const char* peer = (ki != s_mapClientID.end() ? ki->second.c_str() : NULL); - pthread_mutex_unlock(&s_map_mutex); - - if (peer) - s_pObs->Status(pMessage, peer, key); - else - log("Hmm, stray %s: '%s'", __func__, pMessage.c_str()); + s_pObs->Status(msg, peer, key); } diff --git a/lib/Utils/CommLayerInner.h b/lib/Utils/CommLayerInner.h index d161cfc..9c22968 100644 --- a/lib/Utils/CommLayerInner.h +++ b/lib/Utils/CommLayerInner.h @@ -9,15 +9,19 @@ void init_daemon_logging(CObserver *pObs); * Set client's name (dbus ID). NULL unsets it. */ void set_client_name(const char* name); -/* Ask a client to warn the user about a non-fatal, but unexpected condition. + +/* + * Ask a client to warn the user about a non-fatal, but unexpected condition. * In GUI, it will usually be presented as a popup message. + * Usually there is no need to call it directly, just use [p]error_msg(). */ -void warn_client(const std::string& pMessage); -/* Logs a message to a client. +//now static: void warn_client(const char *msg); + +/* + * Logs a message to a client. * In UI, it will usually appear as a new status line message in GUI, * or as a new message line in CLI. */ -void update_client(const std::string& pMessage); - -#endif /* COMMLAYERINNER_H_ */ +void update_client(const char *fmt, ...); +#endif diff --git a/lib/Utils/DebugDump.cpp b/lib/Utils/DebugDump.cpp index ec9e470..ba11d96 100644 --- a/lib/Utils/DebugDump.cpp +++ b/lib/Utils/DebugDump.cpp @@ -39,9 +39,16 @@ static bool isdigit_str(const char *str) return true; } -static std::string RemoveBackSlashes(const std::string& pDir); +static std::string RemoveBackSlashes(const char *pDir) +{ + unsigned len = strlen(pDir); + while (len != 0 && pDir[len-1] == '/') + len--; + return std::string(pDir, len); +} + static bool ExistFileDir(const char* pPath); -static void LoadTextFile(const std::string& pPath, std::string& pData); +static void LoadTextFile(const char *pPath, std::string& pData); CDebugDump::CDebugDump() : m_sDebugDumpDir(""), @@ -50,7 +57,7 @@ CDebugDump::CDebugDump() : m_bLocked(false) {} -void CDebugDump::Open(const std::string& pDir) +void CDebugDump::Open(const char *pDir) { if (m_bOpened) { @@ -59,7 +66,7 @@ void CDebugDump::Open(const std::string& pDir) m_sDebugDumpDir = RemoveBackSlashes(pDir); if (!ExistFileDir(m_sDebugDumpDir.c_str())) { - throw CABRTException(EXCEP_DD_OPEN, "CDebugDump::CDebugDump(): "+m_sDebugDumpDir+" does not exist."); + throw CABRTException(EXCEP_DD_OPEN, "CDebugDump::CDebugDump(): " + m_sDebugDumpDir + " does not exist."); } Lock(); m_bOpened = true; @@ -208,17 +215,17 @@ void CDebugDump::UnLock() } } -void CDebugDump::Create(const std::string& pDir, int64_t uid) +void CDebugDump::Create(const char *pDir, int64_t uid) { if (m_bOpened) { - throw CABRTException(EXCEP_ERROR, "CDebugDump::CDebugDump(): DebugDump is already opened."); + throw CABRTException(EXCEP_ERROR, "DebugDump is already opened"); } m_sDebugDumpDir = RemoveBackSlashes(pDir); if (ExistFileDir(m_sDebugDumpDir.c_str())) { - throw CABRTException(EXCEP_DD_OPEN, "CDebugDump::CDebugDump(): "+m_sDebugDumpDir+" already exists."); + throw CABRTException(EXCEP_DD_OPEN, ssprintf("'%s' already exists", m_sDebugDumpDir.c_str())); } Lock(); @@ -228,13 +235,13 @@ void CDebugDump::Create(const std::string& pDir, int64_t uid) { UnLock(); m_bOpened = false; - throw CABRTException(EXCEP_DD_OPEN, "CDebugDump::Create(): Cannot create dir: " + pDir); + throw CABRTException(EXCEP_DD_OPEN, ssprintf("Can't create dir '%s'", pDir)); } if (chmod(m_sDebugDumpDir.c_str(), 0700) == -1) { UnLock(); m_bOpened = false; - throw CABRTException(EXCEP_DD_OPEN, "CDebugDump::Create(): Cannot change permissions, dir: " + pDir); + throw CABRTException(EXCEP_DD_OPEN, ssprintf("Can't change mode of '%s'", pDir)); } struct passwd* pw = getpwuid(uid); gid_t gid = pw ? pw->pw_gid : uid; @@ -245,14 +252,15 @@ void CDebugDump::Create(const std::string& pDir, int64_t uid) perror_msg("can't change '%s' ownership to %u:%u", m_sDebugDumpDir.c_str(), (int)uid, (int)gid); } - SaveText(FILENAME_UID, ssprintf("%li", uid)); + SaveText(FILENAME_UID, to_string(uid).c_str()); SaveKernelArchitectureRelease(); - SaveTime(); + time_t t = time(NULL); + SaveText(FILENAME_TIME, to_string(t).c_str()); } -static void DeleteFileDir(const std::string& pDir) +static void DeleteFileDir(const char *pDir) { - DIR *dir = opendir(pDir.c_str()); + DIR *dir = opendir(pDir); if (!dir) return; @@ -261,26 +269,33 @@ static void DeleteFileDir(const std::string& pDir) { if (dot_or_dotdot(dent->d_name)) continue; - std::string fullPath = pDir + "/" + dent->d_name; + std::string fullPath = concat_path_file(pDir, dent->d_name); if (unlink(fullPath.c_str()) == -1) { if (errno != EISDIR) { closedir(dir); - throw CABRTException(EXCEP_DD_DELETE, std::string(__func__) + ": Cannot remove file: " + fullPath); + throw CABRTException(EXCEP_DD_DELETE, ssprintf("Can't remove dir %s", fullPath.c_str())); } - DeleteFileDir(fullPath); + DeleteFileDir(fullPath.c_str()); } } closedir(dir); - if (remove(pDir.c_str()) == -1) + if (remove(pDir) == -1) { - throw CABRTException(EXCEP_DD_DELETE, std::string(__func__) + ": Cannot remove dir: " + pDir); + throw CABRTException(EXCEP_DD_DELETE, ssprintf("Can't remove dir %s", pDir)); } } static bool IsTextFile(const char *name) { + /* Some files in our dump directories are known to always be textual */ + if (strcmp(name, "backtrace") == 0 + || strcmp(name, "cmdline") == 0 + ) { + return true; + } + /* This idiotic library thinks that file containing just "0" is not text (!!) magic_t m = magic_open(MAGIC_MIME_TYPE); @@ -320,25 +335,22 @@ static bool IsTextFile(const char *name) int r = full_read(fd, buf, sizeof(buf)); close(fd); + /* Every once in a while, even a text file contains a few garbled + * or unexpected non-ASCII chars. We should not declare it "binary". + */ + const unsigned RATIO = 50; + unsigned total_chars = r + RATIO; + unsigned bad_chars = 1; /* 1 prevents division by 0 later */ while (--r >= 0) { - if (buf[r] >= 0x7f) - return false; - /* Among control chars, only '\t','\n' etc are allowed */ - if (buf[r] < ' ' && !isspace(buf[r])) - return false; - } - return true; -} - -static std::string RemoveBackSlashes(const std::string& pDir) -{ - std::string ret = pDir; - while (ret[ret.length() - 1] == '/') - { - ret = ret.substr(0, ret.length() - 2); + if (buf[r] >= 0x7f + /* among control chars, only '\t','\n' etc are allowed */ + || (buf[r] < ' ' && !isspace(buf[r])) + ) { + bad_chars++; + } } - return ret; + return (total_chars / bad_chars) >= RATIO; } void CDebugDump::Delete() @@ -347,7 +359,7 @@ void CDebugDump::Delete() { return; } - DeleteFileDir(m_sDebugDumpDir); + DeleteFileDir(m_sDebugDumpDir.c_str()); } void CDebugDump::Close() @@ -374,100 +386,44 @@ void CDebugDump::SaveKernelArchitectureRelease() const char *release_ptr = release.c_str(); unsigned len_1st_str = strchrnul(release_ptr, '\n') - release_ptr; release.erase(len_1st_str); /* usually simply removes trailing '\n' */ - SaveText(FILENAME_RELEASE, release); + SaveText(FILENAME_RELEASE, release.c_str()); } -void CDebugDump::SaveTime() +static void LoadTextFile(const char *pPath, std::string& pData) { - time_t t = time(NULL); - SaveText(FILENAME_TIME, to_string(t)); -} - -static void LoadTextFile(const std::string& pPath, std::string& pData) -{ - std::ifstream fIn; + FILE *fp = fopen(pPath, "r"); + if (!fp) + { + throw CABRTException(EXCEP_DD_LOAD, ssprintf("Can't open file '%s'", pPath)); + } pData = ""; - fIn.open(pPath.c_str()); - if (fIn.is_open()) + int ch; + while ((ch = fgetc(fp)) != EOF) { - // TODO: rewrite this - int ch; - while ((ch = fIn.get())!= EOF) + if (ch == '\0') { - if (ch == 0) - { - pData += " "; - } - else if (isspace(ch) || (isascii(ch) && !iscntrl(ch))) - { - pData += ch; - } + pData += ' '; } - fIn.close(); - } - else - { - throw CABRTException(EXCEP_DD_LOAD, std::string(__func__) + ": Cannot open file " + pPath); - } -} - -static void 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 CABRTException(EXCEP_DD_LOAD, std::string(__func__) + ": Cannot open file " + pPath); - } -} - -static void SaveTextFile(const std::string& pPath, const std::string& pData) -{ - std::ofstream fOut; - fOut.open(pPath.c_str()); - if (fOut.is_open()) - { - fOut << pData; - if (!fOut.good()) + else if (isspace(ch) || (isascii(ch) && !iscntrl(ch))) { - throw CABRTException(EXCEP_DD_SAVE, std::string(__func__) + ": Cannot save file " + pPath); + pData += ch; } - fOut.close(); - } - else - { - throw CABRTException(EXCEP_DD_SAVE, std::string(__func__) + ": Cannot open file " + pPath); } + fclose(fp); } -static void SaveBinaryFile(const std::string& pPath, const char* pData, const unsigned pSize) +static void SaveBinaryFile(const char *pPath, const char* pData, unsigned pSize) { - std::ofstream fOut; - fOut.open(pPath.c_str(), std::ios::binary); - if (fOut.is_open()) + int fd = open(pPath, O_WRONLY | O_TRUNC | O_CREAT, 0666); + if (fd < 0) { - fOut.write(pData, pSize); - if (!fOut.good()) - { - throw CABRTException(EXCEP_DD_SAVE, std::string(__func__) + ": Cannot save file " + pPath); - } - fOut.close(); + throw CABRTException(EXCEP_DD_SAVE, ssprintf("Can't open file '%s'", pPath)); } - else + unsigned r = full_write(fd, pData, pSize); + close(fd); + if (r != pSize) { - throw CABRTException(EXCEP_DD_SAVE, std::string(__func__) + ": Cannot open file " + pPath); + throw CABRTException(EXCEP_DD_SAVE, ssprintf("Can't save file '%s'", pPath)); } } @@ -477,36 +433,27 @@ void CDebugDump::LoadText(const char* pName, std::string& pData) { throw CABRTException(EXCEP_DD_OPEN, "CDebugDump::LoadText(): DebugDump is not opened."); } - std::string fullPath = m_sDebugDumpDir + "/" + pName; - LoadTextFile(fullPath, pData); -} -void CDebugDump::LoadBinary(const char* pName, char** pData, unsigned int* pSize) -{ - if (!m_bOpened) - { - throw CABRTException(EXCEP_DD_OPEN, "CDebugDump::LoadBinary(): DebugDump is not opened."); - } - std::string fullPath = m_sDebugDumpDir + "/" + pName; - LoadBinaryFile(fullPath, pData, pSize); + std::string fullPath = m_sDebugDumpDir + '/' + pName; + LoadTextFile(fullPath.c_str(), pData); } -void CDebugDump::SaveText(const char* pName, const std::string& pData) +void CDebugDump::SaveText(const char* pName, const char* pData) { if (!m_bOpened) { throw CABRTException(EXCEP_DD_OPEN, "CDebugDump::SaveText(): DebugDump is not opened."); } std::string fullPath = m_sDebugDumpDir + "/" + pName; - SaveTextFile(fullPath, pData); + SaveBinaryFile(fullPath.c_str(), pData, strlen(pData)); } -void CDebugDump::SaveBinary(const char* pName, const char* pData, const unsigned int pSize) +void CDebugDump::SaveBinary(const char* pName, const char* pData, unsigned pSize) { if (!m_bOpened) { throw CABRTException(EXCEP_DD_OPEN, "CDebugDump::SaveBinary(): DebugDump is not opened."); } std::string fullPath = m_sDebugDumpDir + "/" + pName; - SaveBinaryFile(fullPath, pData, pSize); + SaveBinaryFile(fullPath.c_str(), pData, pSize); } void CDebugDump::InitGetNextFile() @@ -538,7 +485,7 @@ bool CDebugDump::GetNextFile(std::string& pFileName, std::string& pContent, bool { if (is_regular_file(dent, m_sDebugDumpDir.c_str())) { - std::string fullname = m_sDebugDumpDir + "/" + dent->d_name; + std::string fullname = concat_path_file(m_sDebugDumpDir.c_str(), dent->d_name); pFileName = dent->d_name; if (IsTextFile(fullname.c_str())) @@ -548,7 +495,7 @@ bool CDebugDump::GetNextFile(std::string& pFileName, std::string& pContent, bool } else { - pContent = ""; + pContent.clear(); pIsTextFile = false; } return true; @@ -558,4 +505,3 @@ bool CDebugDump::GetNextFile(std::string& pFileName, std::string& pContent, bool m_pGetNextFileDir = NULL; return false; } - diff --git a/lib/Utils/DebugDump.h b/lib/Utils/DebugDump.h index 189b42d..b48a386 100644 --- a/lib/Utils/DebugDump.h +++ b/lib/Utils/DebugDump.h @@ -51,7 +51,6 @@ class CDebugDump bool m_bLocked; void SaveKernelArchitectureRelease(); - void SaveTime(); void Lock(); void UnLock(); @@ -60,18 +59,17 @@ class CDebugDump CDebugDump(); ~CDebugDump() { Close(); } - void Open(const std::string& pDir); - void Create(const std::string& pDir, int64_t uid); + void Open(const char *pDir); + void Create(const char *pDir, int64_t uid); void Delete(); void Close(); bool Exist(const char* pFileName); void LoadText(const char* pName, std::string& pData); - void LoadBinary(const char* pName, char** pData, unsigned int* pSize); - void SaveText(const char* pName, const std::string& pData); - void SaveBinary(const char* pName, const char* pData, const unsigned int pSize); + void SaveText(const char* pName, const char *pData); + void SaveBinary(const char* pName, const char* pData, unsigned pSize); void InitGetNextFile(); bool GetNextFile(std::string& pFileName, std::string& pContent, bool& pIsTextFile); diff --git a/lib/Utils/Makefile.am b/lib/Utils/Makefile.am index 68c925f..1b141bd 100644 --- a/lib/Utils/Makefile.am +++ b/lib/Utils/Makefile.am @@ -11,10 +11,12 @@ libABRTUtils_la_SOURCES = \ logging.cpp \ copyfd.cpp \ skip_whitespace.cpp \ + parse_release.cpp \ CrashTypesSocket.cpp \ DebugDump.h DebugDump.cpp \ CommLayerInner.h CommLayerInner.cpp \ abrt_dbus.h abrt_dbus.cpp \ + abrt_xmlrpc.h abrt_xmlrpc.cpp \ Plugin.h Plugin.cpp make_descr.cpp \ Polkit.h Polkit.cpp \ Action.h Database.h Reporter.h Analyzer.h \ @@ -30,6 +32,7 @@ libABRTUtils_la_CPPFLAGS = \ -DVAR_RUN=\"$(VAR_RUN)\" \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ + $(XMLRPC_CFLAGS) $(XMLRPC_CLIENT_CFLAGS) \ $(POLKIT_CFLAGS) \ -D_GNU_SOURCE libABRTUtils_la_LDFLAGS = \ @@ -37,8 +40,10 @@ libABRTUtils_la_LDFLAGS = \ $(DL_LIBS) \ $(DBUS_LIBS) libABRTUtils_la_LIBADD = \ + $(XMLRPC_LIBS) $(XMLRPC_CLIENT_LIBS) \ $(POLKIT_LIBS) + install-data-local: $(mkdir_p) '$(DESTDIR)/$(DEBUG_DUMPS_DIR)' chmod 1777 '$(DESTDIR)/$(DEBUG_DUMPS_DIR)' diff --git a/lib/Utils/Observer.h b/lib/Utils/Observer.h index d6ec6f3..db74865 100644 --- a/lib/Utils/Observer.h +++ b/lib/Utils/Observer.h @@ -8,8 +8,8 @@ class CObserver { public: virtual ~CObserver() {} - virtual void Status(const std::string& pMessage, const char* peer, uint64_t pDest) = 0; - virtual void Warning(const std::string& pMessage, const char* peer, uint64_t pDest) = 0; + virtual void Status(const char *pMessage, const char* peer, uint64_t pDest) = 0; + virtual void Warning(const char *pMessage, const char* peer, uint64_t pDest) = 0; }; #endif diff --git a/lib/Utils/Plugin.cpp b/lib/Utils/Plugin.cpp index 161ead8..4d561b4 100644 --- a/lib/Utils/Plugin.cpp +++ b/lib/Utils/Plugin.cpp @@ -19,9 +19,18 @@ #include "Plugin.h" +CPlugin::CPlugin() {} + /* class CPlugin's virtuals */ CPlugin::~CPlugin() {} void CPlugin::Init() {} void CPlugin::DeInit() {} -void CPlugin::SetSettings(const map_plugin_settings_t& pSettings) {} -map_plugin_settings_t CPlugin::GetSettings() {return map_plugin_settings_t();} +void CPlugin::SetSettings(const map_plugin_settings_t& pSettings) +{ + m_pSettings = pSettings; +} + +const map_plugin_settings_t& CPlugin::GetSettings() +{ + return m_pSettings; +} diff --git a/lib/Utils/Plugin.h b/lib/Utils/Plugin.h index 00c7e5b..f93f7e7 100644 --- a/lib/Utils/Plugin.h +++ b/lib/Utils/Plugin.h @@ -47,7 +47,11 @@ */ class CPlugin { + protected: + map_plugin_settings_t m_pSettings; + public: + CPlugin(); /** * A destructor. */ @@ -69,7 +73,7 @@ class CPlugin * A method, which return current settings. It is not mandatory method. * @return Plugin's settings */ - virtual map_plugin_settings_t GetSettings(); + virtual const map_plugin_settings_t& GetSettings(); }; /** diff --git a/lib/Utils/abrt_xmlrpc.cpp b/lib/Utils/abrt_xmlrpc.cpp new file mode 100644 index 0000000..11c431b --- /dev/null +++ b/lib/Utils/abrt_xmlrpc.cpp @@ -0,0 +1,76 @@ +#if HAVE_CONFIG_H +# include "config.h" +#endif +#include "abrtlib.h" +#include "abrt_xmlrpc.h" +#include "ABRTException.h" + +void throw_if_xml_fault_occurred(xmlrpc_env *env) +{ + if (env->fault_occurred) + { + std::string errmsg = ssprintf("XML-RPC Fault: %s(%d)", env->fault_string, env->fault_code); + xmlrpc_env_clean(env); // this is needed ONLY if fault_occurred + xmlrpc_env_init(env); // just in case user catches ex and _continues_ to use env + error_msg("%s", errmsg.c_str()); // show error in daemon log + throw CABRTException(EXCEP_PLUGIN, errmsg); + } +} + +void abrt_xmlrpc_conn::new_xmlrpc_client(const char* url, bool no_ssl_verify) +{ + m_pClient = NULL; + m_pServer_info = NULL; + + xmlrpc_env env; + xmlrpc_env_init(&env); + + /* This should be done at program startup, once. + * We do it in abrtd's main */ + /* xmlrpc_client_setup_global_const(&env); */ + + struct xmlrpc_curl_xportparms curlParms; + memset(&curlParms, 0, sizeof(curlParms)); + /* curlParms.network_interface = NULL; - done by memset */ + curlParms.no_ssl_verifypeer = no_ssl_verify; + curlParms.no_ssl_verifyhost = no_ssl_verify; +#ifdef VERSION + curlParms.user_agent = PACKAGE_NAME"/"VERSION; +#else + curlParms.user_agent = "abrt"; +#endif + + struct xmlrpc_clientparms clientParms; + memset(&clientParms, 0, sizeof(clientParms)); + clientParms.transport = "curl"; + clientParms.transportparmsP = &curlParms; + clientParms.transportparm_size = XMLRPC_CXPSIZE(user_agent); + + xmlrpc_client_create(&env, XMLRPC_CLIENT_NO_FLAGS, + PACKAGE_NAME, VERSION, + &clientParms, XMLRPC_CPSIZE(transportparm_size), + &m_pClient); + throw_if_xml_fault_occurred(&env); + + m_pServer_info = xmlrpc_server_info_new(&env, url); + if (env.fault_occurred) + { + xmlrpc_client_destroy(m_pClient); + m_pClient = NULL; + } + throw_if_xml_fault_occurred(&env); +} + +void abrt_xmlrpc_conn::destroy_xmlrpc_client() +{ + if (m_pServer_info) + { + xmlrpc_server_info_free(m_pServer_info); + m_pServer_info = NULL; + } + if (m_pClient) + { + xmlrpc_client_destroy(m_pClient); + m_pClient = NULL; + } +} diff --git a/lib/Utils/abrt_xmlrpc.h b/lib/Utils/abrt_xmlrpc.h new file mode 100644 index 0000000..e67ab19 --- /dev/null +++ b/lib/Utils/abrt_xmlrpc.h @@ -0,0 +1,27 @@ +#ifndef ABRT_XMLRPC_H_ +#define ABRT_XMLRPC_H_ 1 + +#include <xmlrpc-c/base.h> +#include <xmlrpc-c/client.h> + +/* + * Simple class holding XMLRPC connection data. + * Used mainly to ensure we always destroy xmlrpc client and server_info + * on return or throw. + */ + +struct abrt_xmlrpc_conn { + xmlrpc_client* m_pClient; + xmlrpc_server_info* m_pServer_info; + + abrt_xmlrpc_conn(const char* url, bool no_ssl_verify) { new_xmlrpc_client(url, no_ssl_verify); } + ~abrt_xmlrpc_conn() { destroy_xmlrpc_client(); } + + void new_xmlrpc_client(const char* url, bool no_ssl_verify); + void destroy_xmlrpc_client(); +}; + +/* Utility function */ +void throw_if_xml_fault_occurred(xmlrpc_env *env); + +#endif diff --git a/lib/Utils/copyfd.cpp b/lib/Utils/copyfd.cpp index cda52b0..9abe752 100644 --- a/lib/Utils/copyfd.cpp +++ b/lib/Utils/copyfd.cpp @@ -105,3 +105,25 @@ off_t copyfd_eof(int fd1, int fd2) { return full_fd_action(fd1, fd2, 0); } + +off_t copy_file(const char *src_name, const char *dst_name) +{ + off_t r; + int src = open(src_name, O_RDONLY); + if (src < 0) + { + perror_msg("Can't open '%s'", src_name); + return -1; + } + int dst = open(dst_name, O_WRONLY | O_TRUNC | O_CREAT, 0666); + if (dst < 0) + { + close(src); + perror_msg("Can't open '%s'", dst_name); + return -1; + } + r = copyfd_eof(src, dst); + close(src); + close(dst); + return r; +} diff --git a/lib/Utils/logging.cpp b/lib/Utils/logging.cpp index f70d23f..cae609b 100644 --- a/lib/Utils/logging.cpp +++ b/lib/Utils/logging.cpp @@ -7,19 +7,18 @@ #include <syslog.h> int xfunc_error_retval = EXIT_FAILURE; - int g_verbose; +int logmode = LOGMODE_STDIO; +const char *msg_prefix = ""; +const char *msg_eol = "\n"; +void (*g_custom_logger)(const char*); void xfunc_die(void) { exit(xfunc_error_retval); } -const char *msg_prefix = ""; -const char *msg_eol = "\n"; -int logmode = LOGMODE_STDIO; - -void verror_msg(const char *s, va_list p, const char* strerr) +static void verror_msg_helper(const char *s, va_list p, const char* strerr, int flags) { char *msg; int prefix_len, strerr_len, msgeol_len, used; @@ -27,9 +26,6 @@ void verror_msg(const char *s, va_list p, const char* strerr) if (!logmode) return; - if (!s) /* nomsg[_and_die] uses NULL fmt */ - s = ""; /* some libc don't like printf(NULL) */ - used = vasprintf(&msg, s, p); if (used < 0) return; @@ -51,7 +47,7 @@ void verror_msg(const char *s, va_list p, const char* strerr) memcpy(msg, msg_prefix, prefix_len); } if (strerr) { - if (s[0]) { /* not perror_nomsg? */ + if (s[0]) { msg[used++] = ':'; msg[used++] = ' '; } @@ -60,24 +56,26 @@ void verror_msg(const char *s, va_list p, const char* strerr) } strcpy(&msg[used], msg_eol); - if (logmode & LOGMODE_STDIO) { + if (flags & LOGMODE_STDIO) { fflush(stdout); full_write(STDERR_FILENO, msg, used + msgeol_len); } - if (logmode & LOGMODE_SYSLOG) { + if (flags & LOGMODE_SYSLOG) { syslog(LOG_ERR, "%s", msg + prefix_len); } + if ((flags & LOGMODE_CUSTOM) && g_custom_logger) { + g_custom_logger(msg + prefix_len); + } free(msg); } -void error_msg_and_die(const char *s, ...) +void log_msg(const char *s, ...) { va_list p; va_start(p, s); - verror_msg(s, p, NULL); + verror_msg_helper(s, p, NULL, logmode); va_end(p); - xfunc_die(); } void error_msg(const char *s, ...) @@ -85,8 +83,18 @@ void error_msg(const char *s, ...) va_list p; va_start(p, s); - verror_msg(s, p, NULL); + verror_msg_helper(s, p, NULL, (logmode | LOGMODE_CUSTOM)); + va_end(p); +} + +void error_msg_and_die(const char *s, ...) +{ + va_list p; + + va_start(p, s); + verror_msg_helper(s, p, NULL, (logmode | LOGMODE_CUSTOM)); va_end(p); + xfunc_die(); } void perror_msg_and_die(const char *s, ...) @@ -95,7 +103,7 @@ void perror_msg_and_die(const char *s, ...) va_start(p, s); /* Guard against "<error message>: Success" */ - verror_msg(s, p, errno ? strerror(errno) : NULL); + verror_msg_helper(s, p, errno ? strerror(errno) : NULL, (logmode | LOGMODE_CUSTOM)); va_end(p); xfunc_die(); } @@ -106,7 +114,7 @@ void perror_msg(const char *s, ...) va_start(p, s); /* Guard against "<error message>: Success" */ - verror_msg(s, p, errno ? strerror(errno) : NULL); + verror_msg_helper(s, p, errno ? strerror(errno) : NULL, (logmode | LOGMODE_CUSTOM)); va_end(p); } @@ -122,5 +130,5 @@ void simple_perror_msg(const char *s) void die_out_of_memory(void) { - error_msg_and_die("Out of memory, exiting"); + error_msg_and_die("Out of memory, exiting"); } diff --git a/lib/Utils/parse_release.cpp b/lib/Utils/parse_release.cpp new file mode 100644 index 0000000..33d3edb --- /dev/null +++ b/lib/Utils/parse_release.cpp @@ -0,0 +1,38 @@ +#include "abrtlib.h" +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +using namespace std; + +void parse_release(const char *pRelease, string& pProduct, string& pVersion) +{ + if (strstr(pRelease, "Rawhide")) + { + pProduct = "Fedora"; + pVersion = "rawhide"; + return; + } + if (strstr(pRelease, "Fedora")) + { + pProduct = "Fedora"; + } + else if (strstr(pRelease, "Red Hat Enterprise Linux")) + { + pProduct = "Red Hat Enterprise Linux "; + } + + const char *release = strstr(pRelease, "release"); + const char *space = release ? strchr(release, ' ') : NULL; + + if (space++) while (*space != '\0' && *space != ' ') + { + /* Eat string like "5.2" */ + pVersion += *space; + if (pProduct == "Red Hat Enterprise Linux ") + { + pProduct += *space; + } + space++; + } +} diff --git a/lib/Utils/xfuncs.cpp b/lib/Utils/xfuncs.cpp index 533fbfa..97c2f76 100644 --- a/lib/Utils/xfuncs.cpp +++ b/lib/Utils/xfuncs.cpp @@ -355,3 +355,16 @@ std::string concat_path_file(const char *path, const char *filename) lc = last_char_is(path, '/'); return ssprintf("%s%s%s", path, (lc==NULL ? "/" : ""), filename); } + +bool string_to_bool(const char *s) +{ + if (s[0] == '1' && s[1] == '\0') + return true; + if (strcasecmp(s, "on") == 0) + return true; + if (strcasecmp(s, "yes") == 0) + return true; + if (strcasecmp(s, "true") == 0) + return true; + return false; +} |
