diff options
| author | Nikola Pajkovsky <npajkovs@redhat.com> | 2010-08-30 19:28:08 +0200 |
|---|---|---|
| committer | Denys Vlasenko <dvlasenk@redhat.com> | 2010-08-30 19:28:08 +0200 |
| commit | eb6a80fe031f648d11344ed912e9a5e1e722545e (patch) | |
| tree | 837100d82635c022447ff1821f3dcdab4278e45e /lib | |
| parent | dac728745922a717db05f2e8dcbe6c533dc0df6f (diff) | |
| download | abrt-eb6a80fe031f648d11344ed912e9a5e1e722545e.tar.gz abrt-eb6a80fe031f648d11344ed912e9a5e1e722545e.tar.xz abrt-eb6a80fe031f648d11344ed912e9a5e1e722545e.zip | |
get rid of CDebugDump class
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/plugins/CCpp.cpp | 174 | ||||
| -rw-r--r-- | lib/plugins/Kerneloops.cpp | 11 | ||||
| -rw-r--r-- | lib/plugins/KerneloopsScanner.cpp | 18 | ||||
| -rw-r--r-- | lib/plugins/Python.cpp | 16 | ||||
| -rw-r--r-- | lib/plugins/RunApp.cpp | 9 | ||||
| -rw-r--r-- | lib/plugins/SOSreport.cpp | 9 | ||||
| -rw-r--r-- | lib/utils/DebugDump.cpp | 320 |
7 files changed, 289 insertions, 268 deletions
diff --git a/lib/plugins/CCpp.cpp b/lib/plugins/CCpp.cpp index 2ecf9308..7665cad3 100644 --- a/lib/plugins/CCpp.cpp +++ b/lib/plugins/CCpp.cpp @@ -186,18 +186,17 @@ static char *get_backtrace(const char *pDebugDumpDir, const char *pDebugInfoDirs { update_client(_("Generating backtrace")); - string UID; - string executable; - CDebugDump dd; - if (!dd.Open(pDebugDumpDir)) + dump_dir_t *dd = dd_init(); + if (!dd_opendir(dd, pDebugDumpDir)) { + dd_close(dd); VERB1 log(_("Unable to open debug dump '%s'"), pDebugDumpDir); - return false; + return NULL; } - dd.LoadText(FILENAME_EXECUTABLE, executable); - dd.LoadText(CD_UID, UID); - dd.Close(); + char *uid = dd_loadtxt(dd, CD_UID); + char *executable = dd_loadtxt(dd, FILENAME_EXECUTABLE); + dd_close(dd); // Workaround for // http://sourceware.org/bugzilla/show_bug.cgi?id=9622 @@ -248,7 +247,8 @@ static char *get_backtrace(const char *pDebugDumpDir, const char *pDebugInfoDirs * BINARY_FILE if it is newer (to at least avoid gdb complaining). */ args[4] = (char*)"-ex"; - args[5] = xasprintf("file %s", executable.c_str()); + args[5] = xasprintf("file %s", executable); + free(executable); args[6] = (char*)"-ex"; args[7] = xasprintf("core-file %s/"FILENAME_COREDUMP, pDebugDumpDir); @@ -277,7 +277,7 @@ static char *get_backtrace(const char *pDebugDumpDir, const char *pDebugInfoDirs while (1) { args[9] = xasprintf("%s backtrace %u%s", thread_apply_all, bt_depth, full); - bt = exec_vp(args, xatoi_u(UID.c_str()), /*redirect_stderr:*/ 1, NULL); + bt = exec_vp(args, xatoi_u(uid), /*redirect_stderr:*/ 1, NULL); if (bt && (bt_depth <= 64 || strlen(bt) < 256*1024)) { free(args[9]); @@ -300,6 +300,7 @@ static char *get_backtrace(const char *pDebugDumpDir, const char *pDebugInfoDirs free(bt); free(args[9]); } + free(uid); free(args[5]); free(args[7]); return bt; @@ -334,16 +335,16 @@ static void GetIndependentBuildIdPC(const char *unstrip_n_output, static char* run_unstrip_n(const char *pDebugDumpDir) { - string UID; - CDebugDump dd; - if (!dd.Open(pDebugDumpDir)) + dump_dir_t *dd = dd_init(); + if (!dd_opendir(dd, pDebugDumpDir)) { + dd_close(dd); VERB1 log(_("Unable to open debug dump '%s'"), pDebugDumpDir); return NULL; } - dd.LoadText(CD_UID, UID); - dd.Close(); + char *uid = dd_loadtxt(dd, CD_UID); + dd_close(dd); char* args[4]; args[0] = (char*)"eu-unstrip"; @@ -351,7 +352,8 @@ static char* run_unstrip_n(const char *pDebugDumpDir) args[2] = (char*)"-n"; args[3] = NULL; - char *out = exec_vp(args, xatoi_u(UID.c_str()), /*redirect_stderr:*/ 0, NULL); + char *out = exec_vp(args, xatoi_u(uid), /*redirect_stderr:*/ 0, NULL); + free(uid); free(args[1]); @@ -527,18 +529,17 @@ static void trim_debuginfo_cache(unsigned max_mb) string CAnalyzerCCpp::GetLocalUUID(const char *pDebugDumpDir) { - string executable; - string package; - CDebugDump dd; - if (!dd.Open(pDebugDumpDir)) + dump_dir_t *dd = dd_init(); + if (!dd_opendir(dd, pDebugDumpDir)) { + dd_close(dd); VERB1 log(_("Unable to open debug dump '%s'"), pDebugDumpDir); return string(""); } - dd.LoadText(FILENAME_EXECUTABLE, executable); - dd.LoadText(FILENAME_PACKAGE, package); - dd.Close(); + char *executable = dd_loadtxt(dd, FILENAME_EXECUTABLE); + char *package = dd_loadtxt(dd, FILENAME_PACKAGE); + dd_close(dd); string independentBuildIdPC; char *unstrip_n_output = run_unstrip_n(pDebugDumpDir); @@ -551,8 +552,7 @@ string CAnalyzerCCpp::GetLocalUUID(const char *pDebugDumpDir) /* package variable has "firefox-3.5.6-1.fc11[.1]" format */ /* Remove distro suffix and maybe least significant version number */ - char *trimmed_package = xstrdup(package.c_str()); - char *p = trimmed_package; + char *p = package; while (*p) { if (*p == '.' && (p[1] < '0' || p[1] > '9')) @@ -563,7 +563,7 @@ string CAnalyzerCCpp::GetLocalUUID(const char *pDebugDumpDir) } p++; } - char *first_dot = strchr(trimmed_package, '.'); + char *first_dot = strchr(package, '.'); if (first_dot) { char *last_dot = strrchr(first_dot, '.'); @@ -576,26 +576,34 @@ string CAnalyzerCCpp::GetLocalUUID(const char *pDebugDumpDir) *last_dot = '\0'; } } - string hash_str = trimmed_package + executable + independentBuildIdPC; - free(trimmed_package); - return create_hash(hash_str.c_str()); + + char *hash_str = xasprintf("%s%s%s", package, executable, independentBuildIdPC.c_str()); + free(package); + free(executable); + + string hash = create_hash(hash_str); + free(hash_str); + + return hash; } string CAnalyzerCCpp::GetGlobalUUID(const char *pDebugDumpDir) { - CDebugDump dd; - if (!dd.Open(pDebugDumpDir)) + dump_dir_t *dd = dd_init(); + if (!dd_opendir(dd, pDebugDumpDir)) { + dd_close(dd); VERB1 log(_("Unable to open debug dump '%s'"), pDebugDumpDir); return string(""); } - if (dd.Exist(FILENAME_GLOBAL_UUID)) + if (dd_exist(dd, FILENAME_GLOBAL_UUID)) { - string uuid; - dd.LoadText(FILENAME_GLOBAL_UUID, uuid); - dd.Close(); - return uuid; + char *uuid = dd_loadtxt(dd, FILENAME_GLOBAL_UUID); + dd_close(dd); + string ret = uuid; + free(uuid); + return ret; } else { @@ -603,13 +611,10 @@ string CAnalyzerCCpp::GetGlobalUUID(const char *pDebugDumpDir) // This whole block should be deleted for Fedora 14. log(_("Getting global universal unique identification...")); - string executable; - string package; - string uid_str; - dd.LoadText(FILENAME_EXECUTABLE, executable); - dd.LoadText(FILENAME_PACKAGE, package); - if (m_bBacktrace) - dd.LoadText(CD_UID, uid_str); + string backtrace_path = concat_path_file(pDebugDumpDir, FILENAME_BACKTRACE); + char *executable = dd_loadtxt(dd, FILENAME_EXECUTABLE); + char *package = dd_loadtxt(dd, FILENAME_PACKAGE); + char *uid_str = m_bBacktrace ? dd_loadtxt(dd, CD_UID) : xstrdup(""); string independent_backtrace; if (m_bBacktrace) @@ -641,7 +646,7 @@ string CAnalyzerCCpp::GetGlobalUUID(const char *pDebugDumpDir) close(pipeout[0]); /* read side of the pipe */ /* abrt-backtrace is executed under the user's uid and gid. */ - uid_t uid = xatoi_u(uid_str.c_str()); + uid_t uid = xatoi_u(uid_str); struct passwd* pw = getpwuid(uid); gid_t gid = pw ? pw->pw_gid : uid; setgroups(1, &gid); @@ -707,12 +712,18 @@ string CAnalyzerCCpp::GetGlobalUUID(const char *pDebugDumpDir) */ else { - dd.SaveText(FILENAME_RATING, "0"); + dd_savetxt(dd, FILENAME_RATING, "0"); } - dd.Close(); + dd_close(dd); + + char *hash_str = xasprintf("%s%s%s", package, executable, independent_backtrace.c_str()); + free(package); + free(executable); - string hash_base = package + executable + independent_backtrace; - return create_hash(hash_base.c_str()); + string hash = create_hash(hash_str); + free(hash_str); + + return hash; } } @@ -748,42 +759,50 @@ static bool DebuginfoCheckPolkit(uid_t uid) void CAnalyzerCCpp::CreateReport(const char *pDebugDumpDir, int force) { - string package, executable, UID; - - CDebugDump dd; - if (!dd.Open(pDebugDumpDir)) + dump_dir_t *dd = dd_init(); + if (!dd_opendir(dd, pDebugDumpDir)) { + dd_close(dd); VERB1 log(_("Unable to open debug dump '%s'"), pDebugDumpDir); return; } /* Skip remote crashes. */ - if (dd.Exist(FILENAME_REMOTE)) + if (dd_exist(dd, FILENAME_REMOTE)) { - std::string remote_str; - dd.LoadText(FILENAME_REMOTE, remote_str); - bool remote = (remote_str.find('1') != std::string::npos); + char *remote_str = dd_loadtxt(dd, FILENAME_REMOTE); + bool remote = (remote_str[0] != '1'); + free(remote_str); if (remote && !m_bBacktraceRemotes) + { + dd_close(dd); return; + } } if (!m_bBacktrace) + { + dd_close(dd); return; + } if (!force) { - bool bt_exists = dd.Exist(FILENAME_BACKTRACE); + int bt_exists = dd_exist(dd, FILENAME_BACKTRACE); if (bt_exists) + { + dd_close(dd); return; /* backtrace already exists */ + } } - dd.LoadText(FILENAME_PACKAGE, package); - dd.LoadText(FILENAME_EXECUTABLE, executable); - dd.LoadText(CD_UID, UID); - dd.Close(); /* do not keep dir locked longer than needed */ + char *package = dd_loadtxt(dd, FILENAME_PACKAGE); + char *executable = dd_loadtxt(dd, FILENAME_EXECUTABLE); + char *uid = dd_loadtxt(dd, CD_UID); + dd_close(dd); /* do not keep dir locked longer than needed */ char *build_ids = NULL; - if (m_bInstallDebugInfo && DebuginfoCheckPolkit(xatoi_u(UID.c_str()))) + if (m_bInstallDebugInfo && DebuginfoCheckPolkit(xatoi_u(uid))) { if (m_nDebugInfoCacheMB > 0) trim_debuginfo_cache(m_nDebugInfoCacheMB); @@ -803,22 +822,25 @@ void CAnalyzerCCpp::CreateReport(const char *pDebugDumpDir, int force) char *bt_build_ids = xasprintf("%s%s", backtrace_str, (build_ids) ? build_ids : ""); free(build_ids); - if (!dd.Open(pDebugDumpDir)) + dd = dd_init(); + if (!dd_opendir(dd, pDebugDumpDir)) { + dd_close(dd); VERB1 log(_("Unable to open debug dump '%s'"), pDebugDumpDir); return; } - dd.SaveText(FILENAME_BACKTRACE, bt_build_ids); + dd_savetxt(dd, FILENAME_BACKTRACE, bt_build_ids); free(bt_build_ids); if (m_bMemoryMap) - dd.SaveText(FILENAME_MEMORYMAP, "memory map of the crashed C/C++ application, not implemented yet"); + dd_savetxt(dd, FILENAME_MEMORYMAP, "memory map of the crashed C/C++ application, not implemented yet"); /* Compute and store UUID from the backtrace. */ char *backtrace_cpy = xstrdup(backtrace_str); struct backtrace *backtrace = backtrace_parse(backtrace_cpy, false, false); free(backtrace_cpy); + if (backtrace) { /* Get the quality of the full backtrace. */ @@ -846,9 +868,9 @@ void CAnalyzerCCpp::CreateReport(const char *pDebugDumpDir, int force) /* Compute UUID. */ struct strbuf *bt = backtrace_tree_as_str(backtrace, false); - strbuf_prepend_str(bt, executable.c_str()); - strbuf_prepend_str(bt, package.c_str()); - dd.SaveText(FILENAME_GLOBAL_UUID, create_hash(bt->buf).c_str()); + strbuf_prepend_str(bt, executable); + strbuf_prepend_str(bt, package); + dd_savetxt(dd, FILENAME_GLOBAL_UUID, create_hash(bt->buf).c_str()); strbuf_free(bt); /* Compute and store backtrace rating. */ @@ -864,7 +886,7 @@ void CAnalyzerCCpp::CreateReport(const char *pDebugDumpDir, int force) else if (qtot < 0.8f) rating = "2"; else if (qtot < 0.9f) rating = "3"; else rating = "4"; - dd.SaveText(FILENAME_RATING, rating); + dd_savetxt(dd, FILENAME_RATING, rating); /* Get the function name from the crash frame. */ if (crash_thread) @@ -874,7 +896,7 @@ void CAnalyzerCCpp::CreateReport(const char *pDebugDumpDir, int force) if (abort_frame) crash_frame = abort_frame->next; if (crash_frame && crash_frame->function && 0 != strcmp(crash_frame->function, "??")) - dd.SaveText(FILENAME_CRASH_FUNCTION, crash_frame->function); + dd_savetxt(dd, FILENAME_CRASH_FUNCTION, crash_frame->function); } backtrace_free(backtrace); @@ -886,17 +908,19 @@ void CAnalyzerCCpp::CreateReport(const char *pDebugDumpDir, int force) the parser never fails, and it will be possible to get rid of the independent_backtrace and backtrace_rate_old. */ struct strbuf *ibt = independent_backtrace(backtrace_str); - strbuf_prepend_str(ibt, executable.c_str()); - strbuf_prepend_str(ibt, package.c_str()); - dd.SaveText(FILENAME_GLOBAL_UUID, create_hash(ibt->buf).c_str()); + strbuf_prepend_str(ibt, executable); + strbuf_prepend_str(ibt, package); + dd_savetxt(dd, FILENAME_GLOBAL_UUID, create_hash(ibt->buf).c_str()); strbuf_free(ibt); /* Compute and store backtrace rating. */ /* Crash frame is not known so store nothing. */ - dd.SaveText(FILENAME_RATING, to_string(backtrace_rate_old(backtrace_str)).c_str()); + dd_savetxt(dd, FILENAME_RATING, to_string(backtrace_rate_old(backtrace_str)).c_str()); } + free(executable); + free(package); free(backtrace_str); - dd.Close(); + dd_close(dd); } /* diff --git a/lib/plugins/Kerneloops.cpp b/lib/plugins/Kerneloops.cpp index 2ffc2e34..f6fa2606 100644 --- a/lib/plugins/Kerneloops.cpp +++ b/lib/plugins/Kerneloops.cpp @@ -126,17 +126,18 @@ std::string CAnalyzerKerneloops::GetLocalUUID(const char *pDebugDumpDir) { VERB3 log("Getting local universal unique identification"); - std::string oops; - CDebugDump dd; - if (!dd.Open(pDebugDumpDir)) + dump_dir_t *dd = dd_init(); + if (!dd_opendir(dd, pDebugDumpDir)) { + dd_close(dd); VERB1 log(_("Unable to open debug dump '%s'"), pDebugDumpDir); return std::string(""); } - dd.LoadText(FILENAME_BACKTRACE, oops); + char *oops = dd_loadtxt(dd, FILENAME_BACKTRACE); + unsigned hash = hash_oops_str(oops); + free(oops); - unsigned hash = hash_oops_str(oops.c_str()); hash &= 0x7FFFFFFF; return to_string(hash); diff --git a/lib/plugins/KerneloopsScanner.cpp b/lib/plugins/KerneloopsScanner.cpp index 8c25dff8..1621b04d 100644 --- a/lib/plugins/KerneloopsScanner.cpp +++ b/lib/plugins/KerneloopsScanner.cpp @@ -133,18 +133,18 @@ int save_oops_to_debug_dump(const vector_string_t& oopsList) char *second_line = (char*)strchr(first_line, '\n'); /* never NULL */ *second_line++ = '\0'; - CDebugDump dd; - if (dd.Create(path, /*uid:*/ 0)) + dump_dir_t *dd = dd_init(); + if (dd_create(dd, path, /*uid:*/ 0)) { - dd.SaveText(FILENAME_ANALYZER, "Kerneloops"); - dd.SaveText(FILENAME_EXECUTABLE, "kernel"); - dd.SaveText(FILENAME_KERNEL, first_line); - dd.SaveText(FILENAME_CMDLINE, "not_applicable"); - dd.SaveText(FILENAME_BACKTRACE, second_line); + dd_savetxt(dd, FILENAME_ANALYZER, "Kerneloops"); + dd_savetxt(dd, FILENAME_EXECUTABLE, "kernel"); + dd_savetxt(dd, FILENAME_KERNEL, first_line); + dd_savetxt(dd, FILENAME_CMDLINE, "not_applicable"); + dd_savetxt(dd, FILENAME_BACKTRACE, second_line); /* Optional, makes generated bz more informative */ strchrnul(second_line, '\n')[0] = '\0'; - dd.SaveText(FILENAME_REASON, second_line); - dd.Close(); + dd_savetxt(dd, FILENAME_REASON, second_line); + dd_close(dd); } else errors++; diff --git a/lib/plugins/Python.cpp b/lib/plugins/Python.cpp index 7b6e761a..d634e0c5 100644 --- a/lib/plugins/Python.cpp +++ b/lib/plugins/Python.cpp @@ -26,19 +26,18 @@ using namespace std; string CAnalyzerPython::GetLocalUUID(const char *pDebugDumpDir) { - CDebugDump dd; - if (!dd.Open(pDebugDumpDir)) + dump_dir_t *dd = dd_init(); + if (!dd_opendir(dd, pDebugDumpDir)) { + dd_close(dd); VERB1 log(_("Unable to open debug dump '%s'"), pDebugDumpDir); return string(""); } - string bt; - dd.LoadText(FILENAME_BACKTRACE, bt); - dd.Close(); + char *bt = dd_loadtxt(dd, FILENAME_BACKTRACE); + dd_close(dd); - const char *bt_str = bt.c_str(); - const char *bt_end = strchrnul(bt_str, '\n'); + const char *bt_end = strchrnul(bt, '\n'); char hash_str[MD5_RESULT_LEN*2 + 1]; unsigned char hash2[MD5_RESULT_LEN]; @@ -49,7 +48,8 @@ string CAnalyzerPython::GetLocalUUID(const char *pDebugDumpDir) //md5_hash(bt_str, bt_end - bt_str, &md5ctx); // For now using compat version: { - char *copy = xstrndup(bt_str, bt_end - bt_str); + char *copy = xstrndup(bt, bt_end - bt); + free(bt); char *s = copy; char *d = copy; unsigned colon_cnt = 0; diff --git a/lib/plugins/RunApp.cpp b/lib/plugins/RunApp.cpp index 632c26f1..f5833565 100644 --- a/lib/plugins/RunApp.cpp +++ b/lib/plugins/RunApp.cpp @@ -58,15 +58,16 @@ void CActionRunApp::Run(const char *pActionDir, const char *pArgs, int force) if (args.size() > FILENAME) { - CDebugDump dd; - if (!dd.Open(pActionDir)) + dump_dir_t *dd = dd_init(); + if (!dd_opendir(dd, pActionDir)) { + dd_close(dd); VERB1 log(_("Unable to open debug dump '%s'"), pActionDir); return; } - dd.SaveBinary(args[FILENAME].c_str(), cmd_out, cmd_out_size); - dd.Close(); + dd_savebin(dd, args[FILENAME].c_str(), cmd_out, cmd_out_size); + dd_close(dd); } free(cmd_out); diff --git a/lib/plugins/SOSreport.cpp b/lib/plugins/SOSreport.cpp index 4c9358da..5180266f 100644 --- a/lib/plugins/SOSreport.cpp +++ b/lib/plugins/SOSreport.cpp @@ -51,20 +51,21 @@ void CActionSOSreport::Run(const char *pActionDir, const char *pArgs, int force) { if (!force) { - CDebugDump dd; - if (!dd.Open(pActionDir)) + dump_dir_t *dd = dd_init(); + if (!dd_opendir(dd, pActionDir)) { + dd_close(dd); VERB1 log(_("Unable to open debug dump '%s'"), pActionDir); return; } - bool bt_exists = dd.Exist("sosreport.tar.bz2") || dd.Exist("sosreport.tar.xz"); + bool bt_exists = dd_exist(dd, "sosreport.tar.bz2") || dd_exist(dd, "sosreport.tar.xz"); if (bt_exists) { VERB3 log("%s already exists, not regenerating", "sosreport.tar.bz2"); return; } - dd.Close(); + dd_close(dd); } static const char command_default[] = diff --git a/lib/utils/DebugDump.cpp b/lib/utils/DebugDump.cpp index 6858fe36..8987b432 100644 --- a/lib/utils/DebugDump.cpp +++ b/lib/utils/DebugDump.cpp @@ -21,8 +21,8 @@ #include <sys/utsname.h> #include "abrtlib.h" #include "debug_dump.h" -#include "abrt_exception.h" #include "comm_layer_inner.h" +#include "strbuf.h" static bool isdigit_str(const char *str) { @@ -34,12 +34,12 @@ static bool isdigit_str(const char *str) return true; } -static std::string RemoveBackSlashes(const char *pDir) +static char* RemoveBackSlashes(const char *pDir) { unsigned len = strlen(pDir); while (len != 0 && pDir[len-1] == '/') len--; - return std::string(pDir, len); + return xstrndup(pDir, len); } static bool ExistFileDir(const char *pPath) @@ -55,64 +55,63 @@ static bool ExistFileDir(const char *pPath) return false; } -static bool LoadTextFile(const char *pPath, std::string& pData); +static char *LoadTextFile(const char *path); +static void dd_lock(dump_dir_t *dd); +static void dd_unlock(dump_dir_t *dd); -CDebugDump::CDebugDump() : - m_sDebugDumpDir(""), - m_pGetNextFileDir(NULL), - m_bOpened(false), - m_bLocked(false), - m_uid(0), - m_gid(0) -{} +dump_dir_t* dd_init(void) +{ + return (dump_dir_t*)xzalloc(sizeof(dump_dir_t)); +} -CDebugDump::~CDebugDump() +void dd_close(dump_dir_t *dd) { - /* Paranoia. In C++, destructor will abort() if it was called while unwinding - * the stack and it throws an exception. - */ - try - { - Close(); - m_sDebugDumpDir.clear(); - } - catch (...) + if (!dd) + return; + + dd_unlock(dd); + if (dd->next_dir) { - error_msg_and_die("Internal error"); + closedir(dd->next_dir); + free(dd->next_dir); } + + free(dd->dd_dir); + free(dd); } -bool CDebugDump::Open(const char *pDir) +int dd_opendir(dump_dir_t *dd, const char *dir) { - if (m_bOpened) + if (dd->opened) error_msg_and_die("CDebugDump is already opened"); - m_sDebugDumpDir = RemoveBackSlashes(pDir); - if (!ExistFileDir(m_sDebugDumpDir.c_str())) + dd->dd_dir = RemoveBackSlashes(dir); + if (!dd->dd_dir || !ExistFileDir(dd->dd_dir)) { - error_msg("'%s' does not exist", m_sDebugDumpDir.c_str()); - return false; + error_msg("'%s' does not exist", dd->dd_dir); + return 0; } - Lock(); - m_bOpened = true; + + dd_lock(dd); + dd->opened = 1; + /* In case caller would want to create more files, he'll need uid:gid */ - m_uid = 0; - m_gid = 0; struct stat stat_buf; - if (stat(m_sDebugDumpDir.c_str(), &stat_buf) == 0) + if (stat(dd->dd_dir, &stat_buf) == 0) { - m_uid = stat_buf.st_uid; - m_gid = stat_buf.st_gid; + dd->uid = stat_buf.st_uid; + dd->gid = stat_buf.st_gid; } - return true; + + return 1; } -bool CDebugDump::Exist(const char* pPath) +int dd_exist(dump_dir_t *dd, const char *path) { - char *full_path = concat_path_file(m_sDebugDumpDir.c_str(), pPath); - bool r = ExistFileDir(full_path); + char *full_path = concat_path_file(dd->dd_dir, path); + int ret = ExistFileDir(full_path); free(full_path); - return r; + return ret; } static bool GetAndSetLock(const char* pLockFile, const char* pPID) @@ -143,7 +142,9 @@ static bool GetAndSetLock(const char* pLockFile, const char* pPID) } if (isdigit_str(pid_buf)) { - if (access(ssprintf("/proc/%s", pid_buf).c_str(), F_OK) == 0) + char pid_str[sizeof("/proc/") + strlen(pid_buf)]; + sprintf(pid_str, "/proc/%s", pid_buf); + if (access(pid_str, F_OK) == 0) { log("Lock file '%s' is locked by process %s", pLockFile, pid_buf); return false; @@ -221,28 +222,30 @@ static bool GetAndSetLock(const char* pLockFile, const char* pPID) #endif } -void CDebugDump::Lock() +static void dd_lock(dump_dir_t *dd) { - if (m_bLocked) - error_msg_and_die("Locking bug on '%s'", m_sDebugDumpDir.c_str()); + if (dd->locked) + error_msg_and_die("Locking bug on '%s'", dd->dd_dir); + + char lock_buf[strlen(dd->dd_dir) + sizeof(".lock")]; + sprintf(lock_buf, "%s.lock", dd->dd_dir); - std::string lockFile = m_sDebugDumpDir + ".lock"; char pid_buf[sizeof(long)*3 + 2]; sprintf(pid_buf, "%lu", (long)getpid()); - while ((m_bLocked = GetAndSetLock(lockFile.c_str(), pid_buf)) != true) + while ((dd->locked = GetAndSetLock(lock_buf, pid_buf)) != true) { sleep(1); /* was 0.5 seconds */ } } -void CDebugDump::UnLock() +static void dd_unlock(dump_dir_t *dd) { - if (m_bLocked) + if (dd->locked) { - m_bLocked = false; - std::string lockFile = m_sDebugDumpDir + ".lock"; - xunlink(lockFile.c_str()); - VERB1 log("UnLocked '%s'", lockFile.c_str()); + char lock_buf[strlen(dd->dd_dir) + sizeof(".lock")]; + sprintf(lock_buf, "%s.lock", dd->dd_dir); + xunlink(lock_buf); + VERB1 log("Unlocked '%s'", lock_buf); } } @@ -265,65 +268,67 @@ void CDebugDump::UnLock() * Currently, we set dir's gid to passwd(uid)->pw_gid parameter, and we set uid to * abrt's user id. We do not allow write access to group. */ -bool CDebugDump::Create(const char *pDir, uid_t uid) +int dd_create(dump_dir_t *dd, const char *dir, uid_t uid) { - if (m_bOpened) + if (dd->opened) error_msg_and_die("DebugDump is already opened"); - m_sDebugDumpDir = RemoveBackSlashes(pDir); - if (ExistFileDir(m_sDebugDumpDir.c_str())) + dd->dd_dir = RemoveBackSlashes(dir); + if (ExistFileDir(dd->dd_dir)) { - error_msg("'%s' already exists", m_sDebugDumpDir.c_str()); - return false; + error_msg("'%s' already exists", dd->dd_dir); + return 0; } - Lock(); - m_bOpened = true; + dd_lock(dd); + dd->opened = 1; /* Was creating it with mode 0700 and user as the owner, but this allows * the user to replace any file in the directory, changing security-sensitive data * (e.g. "uid", "analyzer", "executable") */ - if (mkdir(m_sDebugDumpDir.c_str(), 0750) == -1) + if (mkdir(dd->dd_dir, 0750) == -1) { - UnLock(); - m_bOpened = false; - error_msg("Can't create dir '%s'", pDir); - return false; + dd_unlock(dd); + dd->opened = 0; + error_msg("Can't create dir '%s'", dir); + return 0; } /* mkdir's mode (above) can be affected by umask, fix it */ - if (chmod(m_sDebugDumpDir.c_str(), 0750) == -1) + if (chmod(dd->dd_dir, 0750) == -1) { - UnLock(); - m_bOpened = false; - error_msg("Can't change mode of '%s'", pDir); + dd_unlock(dd); + dd->opened = false; + error_msg("Can't change mode of '%s'", dir); return false; } /* Get ABRT's user id */ - m_uid = 0; + dd->uid = 0; struct passwd *pw = getpwnam("abrt"); if (pw) - m_uid = pw->pw_uid; + dd->uid = pw->pw_uid; else error_msg("User 'abrt' does not exist, using uid 0"); /* Get crashed application's group id */ - m_gid = 0; + dd->gid = 0; pw = getpwuid(uid); if (pw) - m_gid = pw->pw_gid; + dd->gid = pw->pw_gid; else - error_msg("User %lu does not exist, using gid 0", (long)uid); + error_msg("User %lu does not exist, using gid 0", (long)uid); - if (chown(m_sDebugDumpDir.c_str(), m_uid, m_gid) == -1) + if (chown(dd->dd_dir, dd->uid, dd->gid) == -1) { - perror_msg("can't change '%s' ownership to %lu:%lu", m_sDebugDumpDir.c_str(), - (long)m_uid, (long)m_gid); + perror_msg("can't change '%s' ownership to %lu:%lu", dd->dd_dir, + (long)dd->uid, (long)dd->gid); } - SaveText(CD_UID, to_string(uid).c_str()); + char uid_str[sizeof(long) * 3 + 2]; + sprintf(uid_str, "%lu", (long)uid); + dd_savetxt(dd, CD_UID, uid_str); { struct utsname buf; @@ -331,20 +336,20 @@ bool CDebugDump::Create(const char *pDir, uid_t uid) { perror_msg_and_die("uname"); } - SaveText(FILENAME_KERNEL, buf.release); - SaveText(FILENAME_ARCHITECTURE, buf.machine); - std::string release; - LoadTextFile("/etc/redhat-release", release); - 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.c_str()); + dd_savetxt(dd, FILENAME_KERNEL, buf.release); + dd_savetxt(dd, FILENAME_ARCHITECTURE, buf.machine); + char *release = LoadTextFile("/etc/redhat-release"); + strchrnul(release, '\n')[0] = '\0'; + dd_savetxt(dd, FILENAME_RELEASE, release); + free(release); } time_t t = time(NULL); - SaveText(FILENAME_TIME, to_string(t).c_str()); + char t_str[sizeof(time_t) * 3 + 2]; + sprintf(t_str, "%lu", (time_t)t); + dd_savetxt(dd, FILENAME_TIME, t_str); - return true; + return 1; } static bool DeleteFileDir(const char *pDir) @@ -352,15 +357,15 @@ static bool DeleteFileDir(const char *pDir) if (!ExistFileDir(pDir)) return true; - DIR *dir = opendir(pDir); - if (!dir) + DIR *d = opendir(pDir); + if (!d) { error_msg("Can't open dir '%s'", pDir); return false; } struct dirent *dent; - while ((dent = readdir(dir)) != NULL) + while ((dent = readdir(d)) != NULL) { if (dot_or_dotdot(dent->d_name)) continue; @@ -369,7 +374,7 @@ static bool DeleteFileDir(const char *pDir) { if (errno != EISDIR) { - closedir(dir); + closedir(d); error_msg("Can't remove dir '%s'", full_path); free(full_path); return false; @@ -378,7 +383,7 @@ static bool DeleteFileDir(const char *pDir) } free(full_path); } - closedir(dir); + closedir(d); if (rmdir(pDir) == -1) { error_msg("Can't remove dir %s", pDir); @@ -388,52 +393,40 @@ static bool DeleteFileDir(const char *pDir) return true; } -void CDebugDump::Delete() +void dd_delete(dump_dir_t *dd) { - if (!ExistFileDir(m_sDebugDumpDir.c_str())) + if (!ExistFileDir(dd->dd_dir)) { return; } - DeleteFileDir(m_sDebugDumpDir.c_str()); -} -void CDebugDump::Close() -{ - UnLock(); - if (m_pGetNextFileDir != NULL) - { - closedir(m_pGetNextFileDir); - m_pGetNextFileDir = NULL; - } - m_bOpened = false; + DeleteFileDir(dd->dd_dir); } -static bool LoadTextFile(const char *pPath, std::string& pData) +static char *LoadTextFile(const char *pPath) { FILE *fp = fopen(pPath, "r"); if (!fp) { - error_msg("Can't open file '%s'", pPath); - return false; + perror_msg("Can't open file '%s'", pPath); + return xstrdup(""); } - pData = ""; + + struct strbuf *buf_content = strbuf_new(); int ch; while ((ch = fgetc(fp)) != EOF) { if (ch == '\0') - { - pData += ' '; - } + strbuf_append_char(buf_content, ' '); else if (isspace(ch) || (isascii(ch) && !iscntrl(ch))) - { - pData += ch; - } + strbuf_append_char(buf_content, ch); } fclose(fp); - return true; + + return strbuf_free_nobuf(buf_content); } -static bool SaveBinaryFile(const char *pPath, const char* pData, unsigned pSize, uid_t uid, gid_t gid) +static bool SaveBinaryFile(const char *pPath, const char* pData, unsigned size, uid_t uid, gid_t gid) { /* "Why 0640?!" See ::Create() for security analysis */ unlink(pPath); @@ -447,9 +440,9 @@ static bool SaveBinaryFile(const char *pPath, const char* pData, unsigned pSize, { perror_msg("can't change '%s' ownership to %lu:%lu", pPath, (long)uid, (long)gid); } - unsigned r = full_write(fd, pData, pSize); + unsigned r = full_write(fd, pData, size); close(fd); - if (r != pSize) + if (r != size) { error_msg("Can't save file '%s'", pPath); return false; @@ -458,85 +451,86 @@ static bool SaveBinaryFile(const char *pPath, const char* pData, unsigned pSize, return true; } -void CDebugDump::LoadText(const char* pName, std::string& pData) +char* dd_loadtxt(const dump_dir_t *dd, const char *name) { - if (!m_bOpened) + if (!dd->opened) error_msg_and_die("DebugDump is not opened"); - char *full_path = concat_path_file(m_sDebugDumpDir.c_str(), pName); - LoadTextFile(full_path, pData); + char *full_path = concat_path_file(dd->dd_dir, name); + char *ret = LoadTextFile(full_path); free(full_path); + + return ret; } -void CDebugDump::SaveText(const char* pName, const char* pData) +void dd_savetxt(dump_dir_t *dd, const char *name, const char *data) { - if (!m_bOpened) + if (!dd->opened) error_msg_and_die("DebugDump is not opened"); - char *full_path = concat_path_file(m_sDebugDumpDir.c_str(), pName); - SaveBinaryFile(full_path, pData, strlen(pData), m_uid, m_gid); + char *full_path = concat_path_file(dd->dd_dir, name); + SaveBinaryFile(full_path, data, strlen(data), dd->uid, dd->gid); free(full_path); } -void CDebugDump::SaveBinary(const char* pName, const char* pData, unsigned pSize) +void dd_savebin(dump_dir_t* dd, const char* name, const char* data, unsigned size) { - if (!m_bOpened) + if (dd->opened) error_msg_and_die("DebugDump is not opened"); - char *full_path = concat_path_file(m_sDebugDumpDir.c_str(), pName); - SaveBinaryFile(full_path, pData, pSize, m_uid, m_gid); + + char *full_path = concat_path_file(dd->dd_dir, name); + SaveBinaryFile(full_path, data, size, dd->uid, dd->gid); free(full_path); } -bool CDebugDump::InitGetNextFile() +int dd_init_next_file(dump_dir_t *dd) { - if (!m_bOpened) + if (!dd->opened) error_msg_and_die("DebugDump is not opened"); - if (m_pGetNextFileDir != NULL) - { - closedir(m_pGetNextFileDir); - } - m_pGetNextFileDir = opendir(m_sDebugDumpDir.c_str()); - if (m_pGetNextFileDir == NULL) + if (dd->next_dir) + closedir(dd->next_dir); + + dd->next_dir = opendir(dd->dd_dir); + if (!dd->next_dir) { - error_msg("Can't open dir '%s'", m_sDebugDumpDir.c_str()); - return false; + error_msg("Can't open dir '%s'", dd->dd_dir); + return 0; } - return true; + return 1; } -bool CDebugDump::GetNextFile(std::string *short_name, std::string *full_name) +int dd_get_next_file(dump_dir_t *dd, char **short_name, char **full_name) { - if (m_pGetNextFileDir == NULL) - return false; + if (dd->next_dir == NULL) + return 0; struct dirent *dent; - while ((dent = readdir(m_pGetNextFileDir)) != NULL) + while ((dent = readdir(dd->next_dir)) != NULL) { - if (is_regular_file(dent, m_sDebugDumpDir.c_str())) + if (is_regular_file(dent, dd->dd_dir)) { if (short_name) - *short_name = dent->d_name; + *short_name = xstrdup(dent->d_name); if (full_name) - *full_name = concat_path_file(m_sDebugDumpDir.c_str(), dent->d_name); - return true; + *full_name = concat_path_file(dd->dd_dir, dent->d_name); + return 1; } } - closedir(m_pGetNextFileDir); - m_pGetNextFileDir = NULL; - return false; + + closedir(dd->next_dir); + dd->next_dir = NULL; + return 0; } /* Utility function */ -void delete_debug_dump_dir(const char *pDebugDumpDir) +void delete_debug_dump_dir(const char *dd_dir) { - CDebugDump dd; - if (dd.Open(pDebugDumpDir)) - { - dd.Delete(); - dd.Close(); - } + dump_dir_t *dd = dd_init(); + if (dd_opendir(dd, dd_dir)) + dd_delete(dd); else - VERB1 log("Unable to open debug dump '%s'", pDebugDumpDir); + VERB1 log("Unable to open debug dump '%s'", dd_dir); + dd_close(dd); } |
