sd-journal.c | sd-journal.c | |||
---|---|---|---|---|
skipping to change at line 1000 | skipping to change at line 1000 | |||
sid, le64toh(o->entry.seqnum), | sid, le64toh(o->entry.seqnum), | |||
bid, le64toh(o->entry.monotonic), | bid, le64toh(o->entry.monotonic), | |||
le64toh(o->entry.realtime), | le64toh(o->entry.realtime), | |||
le64toh(o->entry.xor_hash)) < 0) | le64toh(o->entry.xor_hash)) < 0) | |||
return -ENOMEM; | return -ENOMEM; | |||
return 0; | return 0; | |||
} | } | |||
_public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) { | _public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) { | |||
char *w, *state; | const char *word, *state; | |||
size_t l; | size_t l; | |||
unsigned long long seqnum, monotonic, realtime, xor_hash; | unsigned long long seqnum, monotonic, realtime, xor_hash; | |||
bool | bool | |||
seqnum_id_set = false, | seqnum_id_set = false, | |||
seqnum_set = false, | seqnum_set = false, | |||
boot_id_set = false, | boot_id_set = false, | |||
monotonic_set = false, | monotonic_set = false, | |||
realtime_set = false, | realtime_set = false, | |||
xor_hash_set = false; | xor_hash_set = false; | |||
sd_id128_t seqnum_id, boot_id; | sd_id128_t seqnum_id, boot_id; | |||
assert_return(j, -EINVAL); | assert_return(j, -EINVAL); | |||
assert_return(!journal_pid_changed(j), -ECHILD); | assert_return(!journal_pid_changed(j), -ECHILD); | |||
assert_return(!isempty(cursor), -EINVAL); | assert_return(!isempty(cursor), -EINVAL); | |||
FOREACH_WORD_SEPARATOR(w, l, cursor, ";", state) { | FOREACH_WORD_SEPARATOR(word, l, cursor, ";", state) { | |||
char *item; | char *item; | |||
int k = 0; | int k = 0; | |||
if (l < 2 || w[1] != '=') | if (l < 2 || word[1] != '=') | |||
return -EINVAL; | return -EINVAL; | |||
item = strndup(w, l); | item = strndup(word, l); | |||
if (!item) | if (!item) | |||
return -ENOMEM; | return -ENOMEM; | |||
switch (w[0]) { | switch (word[0]) { | |||
case 's': | case 's': | |||
seqnum_id_set = true; | seqnum_id_set = true; | |||
k = sd_id128_from_string(item+2, &seqnum_id); | k = sd_id128_from_string(item+2, &seqnum_id); | |||
break; | break; | |||
case 'i': | case 'i': | |||
seqnum_set = true; | seqnum_set = true; | |||
if (sscanf(item+2, "%llx", &seqnum) != 1) | if (sscanf(item+2, "%llx", &seqnum) != 1) | |||
k = -EINVAL; | k = -EINVAL; | |||
skipping to change at line 1106 | skipping to change at line 1106 | |||
if (xor_hash_set) { | if (xor_hash_set) { | |||
j->current_location.xor_hash = (uint64_t) xor_hash; | j->current_location.xor_hash = (uint64_t) xor_hash; | |||
j->current_location.xor_hash_set = true; | j->current_location.xor_hash_set = true; | |||
} | } | |||
return 0; | return 0; | |||
} | } | |||
_public_ int sd_journal_test_cursor(sd_journal *j, const char *cursor) { | _public_ int sd_journal_test_cursor(sd_journal *j, const char *cursor) { | |||
int r; | int r; | |||
char *w, *state; | const char *word, *state; | |||
size_t l; | size_t l; | |||
Object *o; | Object *o; | |||
assert_return(j, -EINVAL); | assert_return(j, -EINVAL); | |||
assert_return(!journal_pid_changed(j), -ECHILD); | assert_return(!journal_pid_changed(j), -ECHILD); | |||
assert_return(!isempty(cursor), -EINVAL); | assert_return(!isempty(cursor), -EINVAL); | |||
if (!j->current_file || j->current_file->current_offset <= 0) | if (!j->current_file || j->current_file->current_offset <= 0) | |||
return -EADDRNOTAVAIL; | return -EADDRNOTAVAIL; | |||
r = journal_file_move_to_object(j->current_file, OBJECT_ENTRY, j->c urrent_file->current_offset, &o); | r = journal_file_move_to_object(j->current_file, OBJECT_ENTRY, j->c urrent_file->current_offset, &o); | |||
if (r < 0) | if (r < 0) | |||
return r; | return r; | |||
FOREACH_WORD_SEPARATOR(w, l, cursor, ";", state) { | FOREACH_WORD_SEPARATOR(word, l, cursor, ";", state) { | |||
_cleanup_free_ char *item = NULL; | _cleanup_free_ char *item = NULL; | |||
sd_id128_t id; | sd_id128_t id; | |||
unsigned long long ll; | unsigned long long ll; | |||
int k = 0; | int k = 0; | |||
if (l < 2 || w[1] != '=') | if (l < 2 || word[1] != '=') | |||
return -EINVAL; | return -EINVAL; | |||
item = strndup(w, l); | item = strndup(word, l); | |||
if (!item) | if (!item) | |||
return -ENOMEM; | return -ENOMEM; | |||
switch (w[0]) { | switch (word[0]) { | |||
case 's': | case 's': | |||
k = sd_id128_from_string(item+2, &id); | k = sd_id128_from_string(item+2, &id); | |||
if (k < 0) | if (k < 0) | |||
return k; | return k; | |||
if (!sd_id128_equal(id, j->current_file->header->se qnum_id)) | if (!sd_id128_equal(id, j->current_file->header->se qnum_id)) | |||
return 0; | return 0; | |||
break; | break; | |||
case 'i': | case 'i': | |||
skipping to change at line 1984 | skipping to change at line 1984 | |||
if (r < 0) | if (r < 0) | |||
return r; | return r; | |||
field_length = strlen(field); | field_length = strlen(field); | |||
n = journal_file_entry_n_items(o); | n = journal_file_entry_n_items(o); | |||
for (i = 0; i < n; i++) { | for (i = 0; i < n; i++) { | |||
uint64_t p, l; | uint64_t p, l; | |||
le64_t le_hash; | le64_t le_hash; | |||
size_t t; | size_t t; | |||
int compression; | ||||
p = le64toh(o->entry.items[i].object_offset); | p = le64toh(o->entry.items[i].object_offset); | |||
le_hash = o->entry.items[i].hash; | le_hash = o->entry.items[i].hash; | |||
r = journal_file_move_to_object(f, OBJECT_DATA, p, &o); | r = journal_file_move_to_object(f, OBJECT_DATA, p, &o); | |||
if (r < 0) | if (r < 0) | |||
return r; | return r; | |||
if (le_hash != o->data.hash) | if (le_hash != o->data.hash) | |||
return -EBADMSG; | return -EBADMSG; | |||
l = le64toh(o->object.size) - offsetof(Object, data.payload ); | l = le64toh(o->object.size) - offsetof(Object, data.payload ); | |||
if (o->object.flags & OBJECT_COMPRESSED) { | compression = o->object.flags & OBJECT_COMPRESSION_MASK; | |||
if (compression) { | ||||
#ifdef HAVE_XZ | #if defined(HAVE_XZ) || defined(HAVE_LZ4) | |||
if (uncompress_startswith(o->data.payload, l, | if (decompress_startswith(compression, | |||
o->data.payload, l, | ||||
&f->compress_buffer, &f-> compress_buffer_size, | &f->compress_buffer, &f-> compress_buffer_size, | |||
field, field_length, '=') ) { | field, field_length, '=') ) { | |||
uint64_t rsize; | size_t rsize; | |||
if (!uncompress_blob(o->data.payload, l, | r = decompress_blob(compression, | |||
&f->compress_buffer, & | o->data.payload, l, | |||
f->compress_buffer_size, &rsize, | &f->compress_buffer, &f | |||
j->data_threshold)) | ->compress_buffer_size, &rsize, | |||
return -EBADMSG; | j->data_threshold); | |||
if (r < 0) | ||||
return r; | ||||
*data = f->compress_buffer; | *data = f->compress_buffer; | |||
*size = (size_t) rsize; | *size = (size_t) rsize; | |||
return 0; | return 0; | |||
} | } | |||
#else | #else | |||
return -EPROTONOSUPPORT; | return -EPROTONOSUPPORT; | |||
#endif | #endif | |||
} else if (l >= field_length+1 && | } else if (l >= field_length+1 && | |||
memcmp(o->data.payload, field, field_length) == 0 && | memcmp(o->data.payload, field, field_length) == 0 && | |||
o->data.payload[field_length] == '=') { | o->data.payload[field_length] == '=') { | |||
t = (size_t) l; | t = (size_t) l; | |||
if ((uint64_t) t != l) | if ((uint64_t) t != l) | |||
return -E2BIG; | return -E2BIG; | |||
*data = o->data.payload; | *data = o->data.payload; | |||
skipping to change at line 2045 | skipping to change at line 2048 | |||
if (r < 0) | if (r < 0) | |||
return r; | return r; | |||
} | } | |||
return -ENOENT; | return -ENOENT; | |||
} | } | |||
static int return_data(sd_journal *j, JournalFile *f, Object *o, const void **data, size_t *size) { | static int return_data(sd_journal *j, JournalFile *f, Object *o, const void **data, size_t *size) { | |||
size_t t; | size_t t; | |||
uint64_t l; | uint64_t l; | |||
int compression; | ||||
l = le64toh(o->object.size) - offsetof(Object, data.payload); | l = le64toh(o->object.size) - offsetof(Object, data.payload); | |||
t = (size_t) l; | t = (size_t) l; | |||
/* We can't read objects larger than 4G on a 32bit machine */ | /* We can't read objects larger than 4G on a 32bit machine */ | |||
if ((uint64_t) t != l) | if ((uint64_t) t != l) | |||
return -E2BIG; | return -E2BIG; | |||
if (o->object.flags & OBJECT_COMPRESSED) { | compression = o->object.flags & OBJECT_COMPRESSION_MASK; | |||
#ifdef HAVE_XZ | if (compression) { | |||
uint64_t rsize; | #if defined(HAVE_XZ) || defined(HAVE_LZ4) | |||
size_t rsize; | ||||
int r; | ||||
if (!uncompress_blob(o->data.payload, l, &f->compress_buffe | r = decompress_blob(compression, | |||
r, &f->compress_buffer_size, &rsize, j->data_threshold)) | o->data.payload, l, &f->compress_buffer | |||
return -EBADMSG; | , | |||
&f->compress_buffer_size, &rsize, j->da | ||||
ta_threshold); | ||||
if (r < 0) | ||||
return r; | ||||
*data = f->compress_buffer; | *data = f->compress_buffer; | |||
*size = (size_t) rsize; | *size = (size_t) rsize; | |||
#else | #else | |||
return -EPROTONOSUPPORT; | return -EPROTONOSUPPORT; | |||
#endif | #endif | |||
} else { | } else { | |||
*data = o->data.payload; | *data = o->data.payload; | |||
*size = t; | *size = t; | |||
} | } | |||
skipping to change at line 2390 | skipping to change at line 2399 | |||
*from = fmin; | *from = fmin; | |||
if (to) | if (to) | |||
*to = tmax; | *to = tmax; | |||
return first ? 0 : 1; | return first ? 0 : 1; | |||
} | } | |||
_public_ int sd_journal_get_cutoff_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t *from, uint64_t *to) { | _public_ int sd_journal_get_cutoff_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t *from, uint64_t *to) { | |||
Iterator i; | Iterator i; | |||
JournalFile *f; | JournalFile *f; | |||
bool first = true; | bool found = false; | |||
int r; | int r; | |||
assert_return(j, -EINVAL); | assert_return(j, -EINVAL); | |||
assert_return(!journal_pid_changed(j), -ECHILD); | assert_return(!journal_pid_changed(j), -ECHILD); | |||
assert_return(from || to, -EINVAL); | assert_return(from || to, -EINVAL); | |||
assert_return(from != to, -EINVAL); | assert_return(from != to, -EINVAL); | |||
HASHMAP_FOREACH(f, j->files, i) { | HASHMAP_FOREACH(f, j->files, i) { | |||
usec_t fr, t; | usec_t fr, t; | |||
r = journal_file_get_cutoff_monotonic_usec(f, boot_id, &fr, &t); | r = journal_file_get_cutoff_monotonic_usec(f, boot_id, &fr, &t); | |||
if (r == -ENOENT) | if (r == -ENOENT) | |||
continue; | continue; | |||
if (r < 0) | if (r < 0) | |||
return r; | return r; | |||
if (r == 0) | if (r == 0) | |||
continue; | continue; | |||
if (first) { | if (found) { | |||
if (from) | if (from) | |||
*from = fr; | *from = MIN(fr, *from); | |||
if (to) | if (to) | |||
*to = t; | *to = MAX(t, *to); | |||
first = false; | ||||
} else { | } else { | |||
if (from) | if (from) | |||
*from = MIN(fr, *from); | *from = fr; | |||
if (to) | if (to) | |||
*to = MAX(t, *to); | *to = t; | |||
found = true; | ||||
} | } | |||
} | } | |||
return first ? 0 : 1; | return found; | |||
} | } | |||
void journal_print_header(sd_journal *j) { | void journal_print_header(sd_journal *j) { | |||
Iterator i; | Iterator i; | |||
JournalFile *f; | JournalFile *f; | |||
bool newline = false; | bool newline = false; | |||
assert(j); | assert(j); | |||
HASHMAP_FOREACH(f, j->files, i) { | HASHMAP_FOREACH(f, j->files, i) { | |||
End of changes. 25 change blocks. | ||||
35 lines changed or deleted | 45 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |