#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include <systemd/sd-journal.h>
sd_journal *j;
void
split_data_to_svs(
const
char
*msg, SV **k_sv, SV **v_sv) {
char
*data_copy = strdup(msg);
char
*k =
strtok
(data_copy,
"="
);
char
*v =
strtok
(NULL,
"="
);
(*k_sv) = newSVpv(k,
strlen
(k));
(*v_sv) = newSVpv(v,
strlen
(v));
}
MODULE = Linux::Systemd::Journal::Read PACKAGE = Linux::Systemd::Journal::Read
PROTOTYPES: ENABLE
NO_OUTPUT
void
__open()
CODE:
int
r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
if
(r < 0)
croak(
"Failed to open journal: %s\n"
,
strerror
(r));
uint64_t
get_usage(self)
CODE:
int
r = sd_journal_get_usage(j, &RETVAL);
if
(r < 0)
croak(
"Failed to open journal: %s\n"
,
strerror
(-r));
OUTPUT: RETVAL
int
next(self, uint64_t skip=0)
CODE:
if
(skip > 0)
RETVAL = sd_journal_next_skip(j, skip);
else
RETVAL = sd_journal_next(j);
POSTCALL:
if
(RETVAL < 0)
croak(
"Failed to move to next record: %s\n"
,
strerror
(-RETVAL));
OUTPUT: RETVAL
int
previous(self, uint64_t skip=0)
CODE:
if
(skip > 0)
RETVAL = sd_journal_previous_skip(j, skip);
else
RETVAL = sd_journal_previous(j);
POSTCALL:
if
(RETVAL < 0)
croak(
"Failed to move to previous record: %s\n"
,
strerror
(-RETVAL));
OUTPUT: RETVAL
NO_OUTPUT
void
seek_head(self)
CODE:
int
r = sd_journal_seek_head(j);
if
(r < 0)
croak(
"Failed to seek to journal head: %s\n"
,
strerror
(-r));
NO_OUTPUT
void
seek_tail(self)
CODE:
int
r = sd_journal_seek_tail(j);
if
(r < 0)
croak(
"Failed to seek to journal tail: %s\n"
,
strerror
(-r));
NO_OUTPUT
void
wait(self)
CODE:
int
r = sd_journal_wait(j, (uint64_t) -1);
if
(r < 0)
croak(
"Failed to wait for changes: %s\n"
,
strerror
(-r));
SV *
get_data(self,
const
char
*field)
CODE:
SV *key_sv;
char
*data;
size_t
l;
int
r = sd_journal_get_data(j, field, (
const
void
**) &data, &l);
if
(r < 0)
croak(
"Failed to read message field '%s': %s\n"
, field,
strerror
(-r));
split_data_to_svs(data, &key_sv, &RETVAL);
OUTPUT: RETVAL
HV *
get_entry(self)
PREINIT:
const
void
*data;
size_t
l;
SV *key_sv, *val_sv;
int
r;
CODE:
RETVAL = newHV();
sd_journal_restart_data(j);
while
((r = sd_journal_enumerate_data(j, &data, &l)) > 0) {
split_data_to_svs(data, &key_sv, &val_sv);
hv_store_ent(RETVAL, key_sv, val_sv, 0);
}
if
(r < 0)
croak(
"Failed to get entry data: %s\n"
,
strerror
(-r));
OUTPUT: RETVAL
# TODO should take binary data as well
NO_OUTPUT
void
__add_match(
const
char
*data)
CODE:
int
r = sd_journal_add_match(j, data, 0);
if
(r < 0)
croak(
"Failed to add a match: %s\n"
,
strerror
(-r));
NO_OUTPUT
void
__match_and()
CODE:
int
r = sd_journal_add_conjunction(j);
if
(r < 0)
croak(
"Failed to set conjunction: %s\n"
,
strerror
(-r));
NO_OUTPUT
void
__match_or()
CODE:
int
r = sd_journal_add_disjunction(j);
if
(r < 0)
croak(
"Failed to set disjunction: %s\n"
,
strerror
(-r));
NO_OUTPUT
void
flush_matches(self)
CODE:
sd_journal_flush_matches(j);
NO_OUTPUT
void
DESTROY(self)
CODE:
sd_journal_close(j);