summaryrefslogtreecommitdiffstats
path: root/lib/utils/DebugDump.cpp
diff options
context:
space:
mode:
authorNikola Pajkovsky <npajkovs@redhat.com>2010-08-30 19:28:08 +0200
committerDenys Vlasenko <dvlasenk@redhat.com>2010-08-30 19:28:08 +0200
commiteb6a80fe031f648d11344ed912e9a5e1e722545e (patch)
tree837100d82635c022447ff1821f3dcdab4278e45e /lib/utils/DebugDump.cpp
parentdac728745922a717db05f2e8dcbe6c533dc0df6f (diff)
downloadabrt-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/utils/DebugDump.cpp')
-rw-r--r--lib/utils/DebugDump.cpp320
1 files changed, 157 insertions, 163 deletions
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);
}