+int add_matches_for_user_unit(sd_journal *j, const char *unit, uid_t uid) {
+ int r;
+ _cleanup_free_ char *m1 = NULL, *m2 = NULL, *m3 = NULL, *m4 = NULL;
+
+ assert(j);
+ assert(unit);
+
+ if (asprintf(&m1, "_SYSTEMD_USER_UNIT=%s", unit) < 0 ||
+ asprintf(&m2, "USER_UNIT=%s", unit) < 0 ||
+ asprintf(&m3, "COREDUMP_USER_UNIT=%s", unit) < 0 ||
+ asprintf(&m4, "_UID=%d", uid) < 0)
+ return -ENOMEM;
+
+ (void) (
+ /* Look for messages from the user service itself */
+ (r = sd_journal_add_match(j, m1, 0)) ||
+ (r = sd_journal_add_match(j, m4, 0)) ||
+
+ /* Look for messages from systemd about this service */
+ (r = sd_journal_add_disjunction(j)) ||
+ (r = sd_journal_add_match(j, m2, 0)) ||
+ (r = sd_journal_add_match(j, m4, 0)) ||
+
+ /* Look for coredumps of the service */
+ (r = sd_journal_add_disjunction(j)) ||
+ (r = sd_journal_add_match(j, m3, 0)) ||
+ (r = sd_journal_add_match(j, m4, 0)) ||
+ (r = sd_journal_add_match(j, "_UID=0", 0))
+ );
+ return r;
+}
+
+int add_match_this_boot(sd_journal *j) {
+ char match[9+32+1] = "_BOOT_ID=";
+ sd_id128_t boot_id;
+ int r;
+
+ assert(j);
+
+ r = sd_id128_get_boot(&boot_id);
+ if (r < 0) {
+ log_error("Failed to get boot id: %s", strerror(-r));
+ return r;
+ }
+
+ sd_id128_to_string(boot_id, match + 9);
+ r = sd_journal_add_match(j, match, strlen(match));
+ if (r < 0) {
+ log_error("Failed to add match: %s", strerror(-r));
+ return r;
+ }
+
+ r = sd_journal_add_conjunction(j);
+ if (r < 0)
+ return r;
+
+ return 0;
+}
+
+int show_journal_by_unit(
+ FILE *f,
+ const char *unit,
+ OutputMode mode,
+ unsigned n_columns,
+ usec_t not_before,
+ unsigned how_many,
+ uid_t uid,
+ OutputFlags flags,
+ bool system) {
+
+ _cleanup_journal_close_ sd_journal*j = NULL;
+ int r;
+ int jflags = SD_JOURNAL_LOCAL_ONLY | system * SD_JOURNAL_SYSTEM;
+
+ assert(mode >= 0);
+ assert(mode < _OUTPUT_MODE_MAX);
+ assert(unit);
+
+ if (how_many <= 0)
+ return 0;
+
+ r = sd_journal_open(&j, jflags);
+ if (r < 0)
+ return r;
+
+ r = add_match_this_boot(j);
+ if (r < 0)
+ return r;
+
+ if (system)
+ r = add_matches_for_unit(j, unit);
+ else
+ r = add_matches_for_user_unit(j, unit, uid);
+ if (r < 0)
+ return r;
+
+ log_debug("Journal filter: %s", journal_make_match_string(j));
+
+ r = show_journal(f, j, mode, n_columns, not_before, how_many, flags);
+ if (r < 0)
+ return r;
+
+ return 0;
+}
+