#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
-#include <sys/poll.h>
#include <time.h>
#include <getopt.h>
#include <signal.h>
static const char *arg_field = NULL;
static bool arg_catalog = false;
static bool arg_reverse = false;
+static const char *arg_root = NULL;
static enum {
ACTION_SHOW,
" --no-pager Do not pipe output into a pager\n"
" -m --merge Show entries from all available journals\n"
" -D --directory=PATH Show journal files from directory\n"
+ " --root=ROOT Operate on catalog files underneath the root ROOT\n"
#ifdef HAVE_GCRYPT
" --interval=TIME Time interval for changing the FSS sealing key\n"
" --verify-key=KEY Specify FSS verification key\n"
ARG_NO_PAGER,
ARG_NO_TAIL,
ARG_NEW_ID128,
+ ARG_ROOT,
ARG_HEADER,
ARG_FULL,
ARG_SETUP_KEYS,
{ "merge", no_argument, NULL, 'm' },
{ "this-boot", no_argument, NULL, 'b' },
{ "directory", required_argument, NULL, 'D' },
+ { "root", required_argument, NULL, ARG_ROOT },
{ "header", no_argument, NULL, ARG_HEADER },
{ "priority", required_argument, NULL, 'p' },
{ "setup-keys", no_argument, NULL, ARG_SETUP_KEYS },
arg_directory = optarg;
break;
+ case ARG_ROOT:
+ arg_root = optarg;
+ break;
+
case 'c':
arg_cursor = optarg;
break;
break;
case ARG_INTERVAL:
- r = parse_usec(optarg, &arg_interval);
+ r = parse_sec(optarg, &arg_interval);
if (r < 0 || arg_interval <= 0) {
log_error("Failed to parse sealing key change interval: %s", optarg);
return -EINVAL;
else if (S_ISBLK(st.st_mode))
asprintf(&t, "_KERNEL_DEVICE=b%u:%u", major(st.st_rdev), minor(st.st_rdev));
else {
- log_error("File is not a device node, regular file or is not executable: %s", *i);
+ log_error("File is neither a device node, nor regular file, nor executable: %s", *i);
return -EINVAL;
}
fprintf(stderr,
ANSI_HIGHLIGHT_OFF "\n"
"The sealing key is automatically changed every %s.\n",
- format_timespan(tsb, sizeof(tsb), arg_interval));
+ format_timespan(tsb, sizeof(tsb), arg_interval, 0));
hn = gethostname_malloc();
log_info("=> Validated from %s to %s, final %s entries not sealed.",
format_timestamp(a, sizeof(a), first),
format_timestamp(b, sizeof(b), validated),
- format_timespan(c, sizeof(c), last > validated ? last - validated : 0));
+ format_timespan(c, sizeof(c), last > validated ? last - validated : 0, 0));
} else if (last > 0)
log_info("=> No sealing yet, %s of entries not sealed.",
- format_timespan(c, sizeof(c), last - first));
+ format_timespan(c, sizeof(c), last - first, 0));
else
log_info("=> No sealing yet, no entries in file.");
}
if (!have_access) {
if (strv_isempty(g))
- log_notice("Hint: You are currently not seeing messages from other users and\n"
- "the system. Users in the group 'systemd-journal' can see all messages.\n"
- "Pass -q to turn this notice off.");
+ log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
+ " Users in the 'systemd-journal' group can see all messages. Pass -q to\n"
+ " turn off this notice.");
else {
_cleanup_free_ char *s = NULL;
return log_oom();
log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
- "Users in the groups '%s' can see all messages.\n"
- "Pass -q to turn this notice off.", s);
+ " Users in the groups '%s' can see all messages.\n"
+ " Pass -q to turn off this notice.", s);
}
}
#endif
static int access_check(sd_journal *j) {
- uint64_t eacces = EACCES, *code;
Iterator it;
+ void *code;
int r = 0;
assert(j);
- assert(j->errors);
- assert(j->files);
if (set_isempty(j->errors)) {
if (hashmap_isempty(j->files))
- log_info("No journal files were found.");
+ log_notice("No journal files were found.");
return 0;
}
- if (!set_contains(j->errors, &eacces)) {
+ if (set_contains(j->errors, INT_TO_PTR(-EACCES))) {
#ifdef HAVE_ACL
/* If /var/log/journal doesn't even exist,
- unprivileged users have no access at all */
+ * unprivileged users have no access at all */
if (access("/var/log/journal", F_OK) < 0 &&
geteuid() != 0 &&
in_group("systemd-journal") <= 0) {
- log_error("Unprivileged users can't see messages unless persistent log storage\n"
- "is enabled. Users in the group 'systemd-journal' can always see messages.");
+ log_error("Unprivileged users cannot access messages, unless persistent log storage is\n"
+ "enabled. Users in the 'systemd-journal' group may always access messages.");
return -EACCES;
}
return r;
}
#else
- if (geteuid() != 0 && in_group("systemd-journal") <= 0)
- log_error("No access to messages.\n"
- "Users in the group 'systemd-journal' can see messages.");
+ if (geteuid() != 0 && in_group("systemd-journal") <= 0) {
+ log_error("Unprivileged users cannot access messages. Users in the 'systemd-journal' group\n"
+ "group may access messages.");
+ return -EACCES;
+ }
#endif
+
if (hashmap_isempty(j->files)) {
- log_error("No journal files were opened, due to insufficient permissions.");
+ log_error("No journal files were opened due to insufficient permissions.");
r = -EACCES;
}
}
SET_FOREACH(code, j->errors, it) {
- int err = -PTR_TO_INT(code);
+ int err;
+
+ err = -PTR_TO_INT(code);
assert(err > 0);
+
if (err != EACCES)
log_warning("Error was encountered while opening journal files: %s",
strerror(err));
}
- log_notice("Hint: run journalctl in debug mode: SYSTEMD_LOG_LEVEL=debug journalct ...");
-
return r;
}
goto finish;
}
- if (arg_action == ACTION_LIST_CATALOG ||
- arg_action == ACTION_DUMP_CATALOG) {
- bool oneline = arg_action == ACTION_LIST_CATALOG;
- if (optind < argc)
- r = catalog_list_items(stdout, oneline, argv + optind);
- else
- r = catalog_list(stdout, oneline);
- if (r < 0)
- log_error("Failed to list catalog: %s", strerror(-r));
- goto finish;
- }
+ if (arg_action == ACTION_UPDATE_CATALOG ||
+ arg_action == ACTION_LIST_CATALOG ||
+ arg_action == ACTION_DUMP_CATALOG) {
+
+ const char* database = CATALOG_DATABASE;
+ char _cleanup_free_ *copy = NULL;
+ if (arg_root) {
+ copy = strjoin(arg_root, "/", CATALOG_DATABASE, NULL);
+ if (!database) {
+ r = log_oom();
+ goto finish;
+ }
+ path_kill_slashes(copy);
+ database = copy;
+ }
+
+ if (arg_action == ACTION_UPDATE_CATALOG) {
+ r = catalog_update(database, arg_root, catalog_file_dirs);
+ if (r < 0)
+ log_error("Failed to list catalog: %s", strerror(-r));
+ } else {
+ bool oneline = arg_action == ACTION_LIST_CATALOG;
+
+ if (optind < argc)
+ r = catalog_list_items(stdout, database,
+ oneline, argv + optind);
+ else
+ r = catalog_list(stdout, database, oneline);
+ if (r < 0)
+ log_error("Failed to list catalog: %s", strerror(-r));
+ }
- if (arg_action == ACTION_UPDATE_CATALOG) {
- r = catalog_update();
goto finish;
}