}
for (;;) {
- _cleanup_free_ char *u = NULL, *full = NULL;
+ _cleanup_free_ char *full = NULL;
_cleanup_close_ int fd = -EBADF;
- const char *a, *b;
struct dirent *de;
ManagedJournalFile *f;
uid_t uid;
log_ratelimit_warning_errno(errno, JOURNAL_LOG_RATELIMIT,
"Failed to enumerate %s, ignoring: %m",
s->system_storage.path);
-
break;
}
- a = startswith(de->d_name, "user-");
- if (!a)
- continue;
- b = endswith(de->d_name, ".journal");
- if (!b)
- continue;
-
- u = strndup(a, b-a);
- if (!u)
- return log_oom();
-
- r = parse_uid(u, &uid);
+ r = journal_file_parse_uid_from_filename(de->d_name, &uid);
if (r < 0) {
- log_debug_errno(r, "Failed to parse UID from file name '%s', ignoring: %m", de->d_name);
+ /* Don't warn if the file is not an online or offline user journal. */
+ if (r != -EREMOTE)
+ log_warning_errno(r, "Failed to parse UID from file name '%s', ignoring: %m", de->d_name);
continue;
}
############################################################
tests += [
+ [files('sd-journal/test-journal-file.c')],
+
[files('sd-journal/test-journal-send.c')],
[files('sd-journal/test-journal-match.c')],
#include "string-util.h"
#include "strv.h"
#include "sync-util.h"
+#include "user-util.h"
#include "xattr-util.h"
#define DEFAULT_DATA_HASH_TABLE_SIZE (2047ULL*sizeof(HashItem))
return r;
}
+int journal_file_parse_uid_from_filename(const char *path, uid_t *ret_uid) {
+ _cleanup_free_ char *buf = NULL, *p = NULL;
+ const char *a, *b, *at;
+ int r;
+
+ /* This helper returns -EREMOTE when the filename doesn't match user online/offline journal
+ * pattern. Hence it currently doesn't parse archived or disposed user journals. */
+
+ assert(path);
+ assert(ret_uid);
+
+ r = path_extract_filename(path, &p);
+ if (r < 0)
+ return r;
+ if (r == O_DIRECTORY)
+ return -EISDIR;
+
+ a = startswith(p, "user-");
+ if (!a)
+ return -EREMOTE;
+ b = endswith(p, ".journal");
+ if (!b)
+ return -EREMOTE;
+
+ at = strchr(a, '@');
+ if (at)
+ return -EREMOTE;
+
+ buf = strndup(a, b-a);
+ if (!buf)
+ return -ENOMEM;
+
+ return parse_uid(buf, ret_uid);
+}
+
int journal_file_archive(JournalFile *f, char **ret_previous_path) {
_cleanup_free_ char *p = NULL;
void journal_file_print_header(JournalFile *f);
int journal_file_archive(JournalFile *f, char **ret_previous_path);
+int journal_file_parse_uid_from_filename(const char *path, uid_t *uid);
JournalFile* journal_initiate_close(JournalFile *f, Set *deferred_closes);
int journal_file_dispose(int dir_fd, const char *fname);
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "journal-file.h"
+#include "tests.h"
+#include "user-util.h"
+
+static void test_journal_file_parse_uid_from_filename_simple(
+ const char *path,
+ uid_t expected_uid,
+ int expected_error) {
+
+ uid_t uid = UID_INVALID;
+ int r;
+
+ log_info("testing %s", path);
+
+ r = journal_file_parse_uid_from_filename(path, &uid);
+ assert_se(r == expected_error);
+ if (r < 0)
+ assert_se(uid == UID_INVALID);
+ else
+ assert_se(uid == expected_uid);
+}
+
+TEST(journal_file_parse_uid_from_filename) {
+
+ test_journal_file_parse_uid_from_filename_simple("/var/log/journal/", 0, -EISDIR);
+
+ /* The helper should return -EREMOTE for any filenames that don't look like an online or offline user
+ * journals. This includes archived and disposed journal files. */
+ test_journal_file_parse_uid_from_filename_simple("/etc/password", 0, -EREMOTE);
+ test_journal_file_parse_uid_from_filename_simple("system.journal", 0, -EREMOTE);
+ test_journal_file_parse_uid_from_filename_simple("user-1000@0005d26980bdce6e-2f2a4939583822ef.journal~", 0, -EREMOTE);
+ test_journal_file_parse_uid_from_filename_simple("user-1000@xxx-yyy-zzz.journal", 0, -EREMOTE);
+
+ test_journal_file_parse_uid_from_filename_simple("user-1000.journal", 1000, 0);
+ test_journal_file_parse_uid_from_filename_simple("user-foo.journal", 0, -EINVAL);
+ test_journal_file_parse_uid_from_filename_simple("user-65535.journal", 0, -ENXIO);
+}
+
+DEFINE_TEST_MAIN(LOG_INFO);