summaryrefslogtreecommitdiffstats
path: root/src/lib/dump_dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/dump_dir.c')
-rw-r--r--src/lib/dump_dir.c468
1 files changed, 345 insertions, 123 deletions
diff --git a/src/lib/dump_dir.c b/src/lib/dump_dir.c
index 19f86072..a84e2814 100644
--- a/src/lib/dump_dir.c
+++ b/src/lib/dump_dir.c
@@ -1,6 +1,4 @@
/*
- DebugDump.cpp
-
Copyright (C) 2009 Zdenek Prikryl (zprikryl@redhat.com)
Copyright (C) 2009 RedHat inc.
@@ -22,11 +20,70 @@
#include "abrtlib.h"
#include "strbuf.h"
-// TODO:
+// Locking logic:
+//
+// The directory is locked by creating a symlink named .lock inside it,
+// whose value (where it "points to") is the pid of locking process.
+// We use symlink, not an ordinary file, because symlink creation
+// is an atomic operation.
+//
+// There are two cases where after .lock creation, we might discover
+// that directory is not really free:
+// * another process just created new directory, but didn't manage
+// to lock it before us.
+// * another process is deleting the directory, and we managed to sneak in
+// and create .lock after it deleted all files (including .lock)
+// but before it rmdir'ed the empty directory.
+//
+// Both these cases are detected by the fact that file named "time"
+// is not present (it must be present in any valid dump dir).
+// If after locking the dir we don't see time file, we remove the lock
+// at once and back off. What happens in concurrent processes
+// we interfered with?
+// * "create new dump dir" process just re-tries locking.
+// * "delete dump dir" process just retries rmdir.
//
-// Perhaps dd_opendir should do some sanity checking like
-// "if there is no "uid" file in the directory, it's not a crash dump",
-// and fail.
+// There is another case when we don't find time file:
+// when the directory is not really a *dump* dir - user gave us
+// an ordinary directory name by mistake.
+// We detect it by bailing out of "lock, check time file; sleep
+// and retry if it doesn't exist" loop using a counter.
+//
+// To make locking work reliably, it's important to set timeouts
+// correctly. For example, dd_create should retry locking
+// its newly-created directory much faster than dd_opendir
+// tries to lock the directory it tries to open.
+
+
+// How long to sleep between "symlink fails with EEXIST,
+// readlink fails with ENOENT" tries. Someone just unlocked the dir.
+// We never bail out in this case, we retry forever.
+// The value can be really small:
+#define SYMLINK_RETRY_USLEEP (10*1000)
+
+// How long to sleep when lock file with valid pid is seen by dd_opendir
+// (we are waiting for other process to unlock or die):
+#define WAIT_FOR_OTHER_PROCESS_USLEEP (500*1000)
+
+// How long to sleep when lock file with valid pid is seen by dd_create
+// (some idiot jumped the gun and locked the dir we just created).
+// Must not be the same as WAIT_FOR_OTHER_PROCESS_USLEEP (we depend on this)
+// and should be small (we have the priority in locking, this is OUR dir):
+#define CREATE_LOCK_USLEEP (10*1000)
+
+// How long to sleep after we locked a dir, found no time file
+// (either we are racing with someone, or it's not a dump dir)
+// and unlocked it;
+// and after how many tries to give up and declare it's not a dump dir:
+#define NO_TIME_FILE_USLEEP (50*1000)
+#define NO_TIME_FILE_COUNT 10
+
+// How long to sleep after we unlocked an empty dir, but then rmdir failed
+// (some idiot jumped the gun and locked the dir we are deleting);
+// and after how many tries to give up:
+#define RMDIR_FAIL_USLEEP (10*1000)
+#define RMDIR_FAIL_COUNT 50
+
static char *load_text_file(const char *path, unsigned flags);
@@ -53,12 +110,21 @@ static bool exist_file_dir(const char *path)
return false;
}
-static bool get_and_set_lock(const char* lock_file, const char* pid)
+/* Return values:
+ * -1: error
+ * 0: failed to lock (someone else has it locked)
+ * 1: success
+ */
+static int get_and_set_lock(const char* lock_file, const char* pid)
{
while (symlink(pid, lock_file) != 0)
{
if (errno != EEXIST)
- perror_msg_and_die("Can't create lock file '%s'", lock_file);
+ {
+ if (errno != ENOENT && errno != ENOTDIR)
+ perror_msg("Can't create lock file '%s'", lock_file);
+ return -1;
+ }
char pid_buf[sizeof(pid_t)*3 + 4];
ssize_t r = readlink(lock_file, pid_buf, sizeof(pid_buf) - 1);
@@ -67,54 +133,94 @@ static bool get_and_set_lock(const char* lock_file, const char* pid)
if (errno == ENOENT)
{
/* Looks like lock_file was deleted */
- usleep(10 * 1000); /* avoid CPU eating loop */
+ usleep(SYMLINK_RETRY_USLEEP); /* avoid CPU eating loop */
continue;
}
- perror_msg_and_die("Can't read lock file '%s'", lock_file);
+ perror_msg("Can't read lock file '%s'", lock_file);
+ return -1;
}
pid_buf[r] = '\0';
if (strcmp(pid_buf, pid) == 0)
{
log("Lock file '%s' is already locked by us", lock_file);
- return false;
+ return 0;
}
if (isdigit_str(pid_buf))
{
- char pid_str[sizeof("/proc/") + strlen(pid_buf)];
+ char pid_str[sizeof("/proc/") + sizeof(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", lock_file, pid_buf);
- return false;
+ return 0;
}
log("Lock file '%s' was locked by process %s, but it crashed?", lock_file, pid_buf);
}
/* The file may be deleted by now by other process. Ignore ENOENT */
if (unlink(lock_file) != 0 && errno != ENOENT)
{
- perror_msg_and_die("Can't remove stale lock file '%s'", lock_file);
+ perror_msg("Can't remove stale lock file '%s'", lock_file);
+ return -1;
}
}
VERB1 log("Locked '%s'", lock_file);
- return true;
+ return 1;
}
-static void dd_lock(struct dump_dir *dd)
+static int dd_lock(struct dump_dir *dd, unsigned sleep_usec)
{
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);
+ error_msg_and_die("Locking bug on '%s'", dd->dd_dirname);
char pid_buf[sizeof(long)*3 + 2];
sprintf(pid_buf, "%lu", (long)getpid());
- while ((dd->locked = get_and_set_lock(lock_buf, pid_buf)) != true)
+
+ unsigned dirname_len = strlen(dd->dd_dirname);
+ char lock_buf[dirname_len + sizeof("/.lock")];
+ strcpy(lock_buf, dd->dd_dirname);
+ strcpy(lock_buf + dirname_len, "/.lock");
+
+ unsigned count = NO_TIME_FILE_COUNT;
+ retry:
+ while (1)
{
- sleep(1); /* was 0.5 seconds */
+ int r = get_and_set_lock(lock_buf, pid_buf);
+ if (r < 0)
+ return r; /* error */
+ if (r > 0)
+ break; /* locked successfully */
+ /* Other process has the lock, wait for it to go away */
+ usleep(sleep_usec);
}
+
+ /* Are we called by dd_opendir (as opposed to dd_create)? */
+ if (sleep_usec == WAIT_FOR_OTHER_PROCESS_USLEEP) /* yes */
+ {
+ strcpy(lock_buf + dirname_len, "/time");
+ if (access(lock_buf, F_OK) != 0)
+ {
+ /* time file doesn't exist. We managed to lock the directory
+ * which was just created by somebody else, or is almost deleted
+ * by delete_file_dir.
+ * Unlock and back off.
+ */
+ strcpy(lock_buf + dirname_len, "/.lock");
+ xunlink(lock_buf);
+ VERB1 log("Unlocked '%s' (no time file)", lock_buf);
+ if (--count == 0)
+ {
+ errno = EISDIR; /* "this is an ordinary dir, not dump dir" */
+ return -1;
+ }
+ usleep(NO_TIME_FILE_USLEEP);
+ goto retry;
+ }
+ }
+
+ dd->locked = true;
+ return 0;
}
static void dd_unlock(struct dump_dir *dd)
@@ -122,9 +228,13 @@ static void dd_unlock(struct dump_dir *dd)
if (dd->locked)
{
dd->locked = 0;
- char lock_buf[strlen(dd->dd_dir) + sizeof(".lock")];
- sprintf(lock_buf, "%s.lock", dd->dd_dir);
+
+ unsigned dirname_len = strlen(dd->dd_dirname);
+ char lock_buf[dirname_len + sizeof("/.lock")];
+ strcpy(lock_buf, dd->dd_dirname);
+ strcpy(lock_buf + dirname_len, "/.lock");
xunlink(lock_buf);
+
VERB1 log("Unlocked '%s'", lock_buf);
}
}
@@ -136,7 +246,7 @@ static inline struct dump_dir *dd_init(void)
int dd_exist(struct dump_dir *dd, const char *path)
{
- char *full_path = concat_path_file(dd->dd_dir, path);
+ char *full_path = concat_path_file(dd->dd_dirname, path);
int ret = exist_file_dir(full_path);
free(full_path);
return ret;
@@ -154,7 +264,7 @@ void dd_close(struct dump_dir *dd)
/* free(dd->next_dir); - WRONG! */
}
- free(dd->dd_dir);
+ free(dd->dd_dirname);
free(dd);
}
@@ -170,52 +280,68 @@ struct dump_dir *dd_opendir(const char *dir, int flags)
{
struct dump_dir *dd = dd_init();
- /* Used to use rm_trailing_slashes(dir) here, but with dir = "."
- * or "..", or if the last component is a symlink,
- * then lock file is created in the wrong place.
- * IOW: this breaks locking.
- */
- dd->dd_dir = realpath(dir, NULL);
- if (!dd->dd_dir)
- {
- if (!(flags & DD_FAIL_QUIETLY))
- error_msg("'%s' does not exist", dir);
- dd_close(dd);
- return NULL;
- }
- dir = dd->dd_dir;
-
- dd_lock(dd);
+ dir = dd->dd_dirname = rm_trailing_slashes(dir);
- struct stat stat_buf;
- if (stat(dir, &stat_buf) != 0 || !S_ISDIR(stat_buf.st_mode))
+ errno = 0;
+ if (dd_lock(dd, WAIT_FOR_OTHER_PROCESS_USLEEP) < 0)
{
- if (!(flags & DD_FAIL_QUIETLY))
- error_msg("'%s' does not exist", dir);
+ if ((flags & DD_OPEN_READONLY) && errno == EACCES)
+ {
+ /* Directory is not writable. If it seems to be readable,
+ * return "read only" dd, not NULL */
+ struct stat stat_buf;
+ if (stat(dir, &stat_buf) == 0
+ && S_ISDIR(stat_buf.st_mode)
+ && access(dir, R_OK) == 0
+ ) {
+ return dd;
+ }
+ }
+ if (errno == EISDIR)
+ {
+ /* EISDIR: dd_lock can lock the dir, but it sees no time file there,
+ * even after it retried many times. It must be an ordinary directory!
+ *
+ * Without this check, e.g. abrt-action-print happily prints any current
+ * directory when run without arguments, because its option -d DIR
+ * defaults to "."!
+ */
+ /*if (!(flags & DD_FAIL_QUIETLY))... - no, DD_FAIL_QUIETLY only means
+ * "it's ok if it doesn exist", not "ok if contents is bogus"!
+ */
+ error_msg("'%s' is not a crash dump directory", dir);
+ dd_close(dd);
+ return NULL;
+ }
+
+ if (errno == ENOENT || errno == ENOTDIR)
+ {
+ if (!(flags & DD_FAIL_QUIETLY))
+ error_msg("'%s' does not exist", dir);
+ }
+ else
+ {
+ perror_msg("Can't access '%s'", dir);
+ }
dd_close(dd);
return NULL;
}
- /* In case caller would want to create more files, he'll need uid:gid */
- dd->dd_uid = stat_buf.st_uid;
- dd->dd_gid = stat_buf.st_gid;
-
- /* Without this check, e.g. abrt-action-print happily prints any current
- * directory when run without arguments, because its option -d DIR
- * defaults to "."! Let's require that at least some crash dump dir
- * specific files exist before we declare open successful:
- */
- char *name = concat_path_file(dir, FILENAME_ANALYZER);
- int bad = (lstat(name, &stat_buf) != 0 || !S_ISREG(stat_buf.st_mode));
- free(name);
- if (bad)
+ dd->dd_uid = (uid_t)-1L;
+ dd->dd_gid = (gid_t)-1L;
+ if (geteuid() == 0)
{
- /*if (!(flags & DD_FAIL_QUIETLY))... - no, DD_FAIL_QUIETLY only means
- * "it's ok if it doesn exist", not "ok if contents is bogus"!
- */
- error_msg("'%s' is not a crash dump directory", dir);
- dd_close(dd);
- return NULL;
+ /* In case caller would want to create more files, he'll need uid:gid */
+ struct stat stat_buf;
+ if (stat(dir, &stat_buf) != 0 || !S_ISDIR(stat_buf.st_mode))
+ {
+ if (!(flags & DD_FAIL_QUIETLY))
+ error_msg("'%s' does not exist", dir);
+ dd_close(dd);
+ return NULL;
+ }
+ dd->dd_uid = stat_buf.st_uid;
+ dd->dd_gid = stat_buf.st_gid;
}
return dd;
@@ -248,7 +374,7 @@ struct dump_dir *dd_create(const char *dir, uid_t uid)
* realpath will always return NULL. We don't really have to:
* dd_opendir(".") makes sense, dd_create(".") does not.
*/
- dir = dd->dd_dir = rm_trailing_slashes(dir);
+ dir = dd->dd_dirname = rm_trailing_slashes(dir);
const char *last_component = strrchr(dir, '/');
if (last_component)
@@ -265,15 +391,38 @@ struct dump_dir *dd_create(const char *dir, uid_t uid)
return NULL;
}
- dd_lock(dd);
-
+ bool created_parents = false;
+ try_again:
/* 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(dir, 0750) == -1)
{
- perror_msg("Can't create dir '%s'", dir);
+ int err = errno;
+ if (!created_parents && errno == ENOENT)
+ {
+ char *p = dd->dd_dirname + 1;
+ while ((p = strchr(p, '/')) != NULL)
+ {
+ *p = '\0';
+ int r = (mkdir(dd->dd_dirname, 0755) == 0 || errno == EEXIST);
+ *p++ = '/';
+ if (!r)
+ goto report_err;
+ }
+ created_parents = true;
+ goto try_again;
+ }
+ report_err:
+ errno = err;
+ perror_msg("Can't create directory '%s'", dir);
+ dd_close(dd);
+ return NULL;
+ }
+
+ if (dd_lock(dd, CREATE_LOCK_USLEEP) < 0)
+ {
dd_close(dd);
return NULL;
}
@@ -281,35 +430,51 @@ struct dump_dir *dd_create(const char *dir, uid_t uid)
/* mkdir's mode (above) can be affected by umask, fix it */
if (chmod(dir, 0750) == -1)
{
- perror_msg("Can't change mode of '%s'", dir);
+ perror_msg("can't change mode of '%s'", dir);
dd_close(dd);
return NULL;
}
- /* Get ABRT's user id */
- /*dd->dd_uid = 0; - dd_init did this already */
- struct passwd *pw = getpwnam("abrt");
- if (pw)
- dd->dd_uid = pw->pw_uid;
- else
- error_msg("User 'abrt' does not exist, using uid 0");
-
- /* Get crashed application's group id */
- /*dd->dd_gid = 0; - dd_init did this already */
- pw = getpwuid(uid);
- if (pw)
- dd->dd_gid = pw->pw_gid;
- else
- error_msg("User %lu does not exist, using gid 0", (long)uid);
-
- if (chown(dir, dd->dd_uid, dd->dd_gid) == -1)
+ dd->dd_uid = (uid_t)-1L;
+ dd->dd_gid = (gid_t)-1L;
+ if (uid != (uid_t)-1L)
{
- perror_msg("Can't change '%s' ownership to %lu:%lu", dir,
- (long)dd->dd_uid, (long)dd->dd_gid);
+ /* Get ABRT's user id */
+ dd->dd_uid = 0;
+ struct passwd *pw = getpwnam("abrt");
+ if (pw)
+ dd->dd_uid = pw->pw_uid;
+ else
+ error_msg("user 'abrt' does not exist, using uid 0");
+
+ /* Get crashed application's group id */
+ /*dd->dd_gid = 0; - dd_init did this already */
+ pw = getpwuid(uid);
+ if (pw)
+ dd->dd_gid = pw->pw_gid;
+ else
+ error_msg("User %lu does not exist, using gid 0", (long)uid);
+
+ if (chown(dir, dd->dd_uid, dd->dd_gid) == -1)
+ {
+ perror_msg("can't change '%s' ownership to %lu:%lu", dir,
+ (long)dd->dd_uid, (long)dd->dd_gid);
+ }
}
+ return dd;
+}
+
+void dd_create_basic_files(struct dump_dir *dd, uid_t uid)
+{
char long_str[sizeof(long) * 3 + 2];
+ time_t t = time(NULL);
+ sprintf(long_str, "%lu", (long)t);
+ dd_save_text(dd, FILENAME_TIME, long_str);
+
+ if (uid == (uid_t)-1)
+ uid = getuid();
sprintf(long_str, "%lu", (long)uid);
dd_save_text(dd, FILENAME_UID, long_str);
@@ -317,54 +482,102 @@ struct dump_dir *dd_create(const char *dir, uid_t uid)
uname(&buf); /* never fails */
dd_save_text(dd, FILENAME_KERNEL, buf.release);
dd_save_text(dd, FILENAME_ARCHITECTURE, buf.machine);
- char *release = load_text_file("/etc/redhat-release", /*flags:*/ 0);
- strchrnul(release, '\n')[0] = '\0';
- dd_save_text(dd, FILENAME_RELEASE, release);
- free(release);
+ dd_save_text(dd, FILENAME_HOSTNAME, buf.nodename);
- time_t t = time(NULL);
- sprintf(long_str, "%lu", (long)t);
- dd_save_text(dd, FILENAME_TIME, long_str);
-
- return dd;
+ char *release = load_text_file("/etc/system-release",
+ DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE);
+ if (!release)
+ release = load_text_file("/etc/redhat-release", /*flags:*/ 0);
+ dd_save_text(dd, FILENAME_OS_RELEASE, release);
+ free(release);
}
-static void delete_file_dir(const char *dir)
+static int delete_file_dir(const char *dir, bool skip_lock_file)
{
DIR *d = opendir(dir);
if (!d)
- return;
+ {
+ /* The caller expects us to error out only if the directory
+ * still exists (not deleted). If directory
+ * *doesn't exist*, return 0 and clear errno.
+ */
+ if (errno == ENOENT || errno == ENOTDIR)
+ {
+ errno = 0;
+ return 0;
+ }
+ return -1;
+ }
+ bool unlink_lock_file = false;
struct dirent *dent;
while ((dent = readdir(d)) != NULL)
{
if (dot_or_dotdot(dent->d_name))
continue;
+ if (skip_lock_file && strcmp(dent->d_name, ".lock") == 0)
+ {
+ unlink_lock_file = true;
+ continue;
+ }
char *full_path = concat_path_file(dir, dent->d_name);
if (unlink(full_path) == -1 && errno != ENOENT)
{
- if (errno != EISDIR)
+ int err = 0;
+ if (errno == EISDIR)
+ {
+ errno = 0;
+ err = delete_file_dir(full_path, /*skip_lock_file:*/ false);
+ }
+ if (errno || err)
{
- error_msg("Can't remove '%s'", full_path);
+ perror_msg("Can't remove '%s'", full_path);
free(full_path);
closedir(d);
- return;
+ return -1;
}
- delete_file_dir(full_path);
}
free(full_path);
}
closedir(d);
- if (rmdir(dir) == -1)
+
+ /* Here we know for sure that all files/subdirs we found via readdir
+ * were deleted successfully. If rmdir below fails, we assume someone
+ * is racing with us and created a new file.
+ */
+
+ if (unlink_lock_file)
{
- error_msg("Can't remove dir '%s'", dir);
+ char *full_path = concat_path_file(dir, ".lock");
+ xunlink(full_path);
+ free(full_path);
+
+ unsigned cnt = RMDIR_FAIL_COUNT;
+ do {
+ if (rmdir(dir) == 0)
+ return 0;
+ /* Someone locked the dir after unlink, but before rmdir.
+ * This "someone" must be dd_lock().
+ * It detects this (by seeing that there is no time file)
+ * and backs off at once. So we need to just retry rmdir,
+ * with minimal sleep.
+ */
+ usleep(RMDIR_FAIL_USLEEP);
+ } while (--cnt != 0);
}
+
+ int r = rmdir(dir);
+ if (r)
+ perror_msg("Can't remove directory '%s'", dir);
+ return r;
}
-void dd_delete(struct dump_dir *dd)
+int dd_delete(struct dump_dir *dd)
{
- delete_file_dir(dd->dd_dir);
+ int r = delete_file_dir(dd->dd_dirname, /*skip_lock_file:*/ true);
+ dd->locked = 0; /* delete_file_dir already removed .lock */
dd_close(dd);
+ return r;
}
static char *load_text_file(const char *path, unsigned flags)
@@ -411,10 +624,15 @@ static bool save_binary_file(const char *path, const char* data, unsigned size,
perror_msg("Can't open file '%s'", path);
return false;
}
- if (fchown(fd, uid, gid) == -1)
+
+ if (uid != (uid_t)-1L)
{
- perror_msg("can't change '%s' ownership to %lu:%lu", path, (long)uid, (long)gid);
+ if (fchown(fd, uid, gid) == -1)
+ {
+ perror_msg("can't change '%s' ownership to %lu:%lu", path, (long)uid, (long)gid);
+ }
}
+
unsigned r = full_write(fd, data, size);
close(fd);
if (r != size)
@@ -428,10 +646,14 @@ static bool save_binary_file(const char *path, const char* data, unsigned size,
char* dd_load_text_ext(const struct dump_dir *dd, const char *name, unsigned flags)
{
- if (!dd->locked)
- error_msg_and_die("dump_dir is not opened"); /* bug */
+// if (!dd->locked)
+// error_msg_and_die("dump_dir is not opened"); /* bug */
- char *full_path = concat_path_file(dd->dd_dir, name);
+ /* Compat with old abrt dumps. Remove in abrt-2.1 */
+ if (strcmp(name, "release") == 0)
+ name = FILENAME_OS_RELEASE;
+
+ char *full_path = concat_path_file(dd->dd_dirname, name);
char *ret = load_text_file(full_path, flags);
free(full_path);
@@ -448,7 +670,7 @@ void dd_save_text(struct dump_dir *dd, const char *name, const char *data)
if (!dd->locked)
error_msg_and_die("dump_dir is not opened"); /* bug */
- char *full_path = concat_path_file(dd->dd_dir, name);
+ char *full_path = concat_path_file(dd->dd_dirname, name);
save_binary_file(full_path, data, strlen(data), dd->dd_uid, dd->dd_gid);
free(full_path);
}
@@ -458,23 +680,23 @@ void dd_save_binary(struct dump_dir* dd, const char* name, const char* data, uns
if (!dd->locked)
error_msg_and_die("dump_dir is not opened"); /* bug */
- char *full_path = concat_path_file(dd->dd_dir, name);
+ char *full_path = concat_path_file(dd->dd_dirname, name);
save_binary_file(full_path, data, size, dd->dd_uid, dd->dd_gid);
free(full_path);
}
DIR *dd_init_next_file(struct dump_dir *dd)
{
- if (!dd->locked)
- error_msg_and_die("dump_dir is not opened"); /* bug */
+// if (!dd->locked)
+// error_msg_and_die("dump_dir is not opened"); /* bug */
if (dd->next_dir)
closedir(dd->next_dir);
- dd->next_dir = opendir(dd->dd_dir);
+ dd->next_dir = opendir(dd->dd_dirname);
if (!dd->next_dir)
{
- error_msg("Can't open dir '%s'", dd->dd_dir);
+ error_msg("Can't open directory '%s'", dd->dd_dirname);
}
return dd->next_dir;
@@ -488,12 +710,12 @@ int dd_get_next_file(struct dump_dir *dd, char **short_name, char **full_name)
struct dirent *dent;
while ((dent = readdir(dd->next_dir)) != NULL)
{
- if (is_regular_file(dent, dd->dd_dir))
+ if (is_regular_file(dent, dd->dd_dirname))
{
if (short_name)
*short_name = xstrdup(dent->d_name);
if (full_name)
- *full_name = concat_path_file(dd->dd_dir, dent->d_name);
+ *full_name = concat_path_file(dd->dd_dirname, dent->d_name);
return 1;
}
}
@@ -504,9 +726,9 @@ int dd_get_next_file(struct dump_dir *dd, char **short_name, char **full_name)
}
/* Utility function */
-void delete_crash_dump_dir(const char *dd_dir)
+void delete_dump_dir(const char *dirname)
{
- struct dump_dir *dd = dd_opendir(dd_dir, /*flags:*/ 0);
+ struct dump_dir *dd = dd_opendir(dirname, /*flags:*/ 0);
if (dd)
{
dd_delete(dd);