X-Git-Url: https://git.saurik.com/apple/syslog.git/blobdiff_plain/57b0aad2c678a02fcc3e8b5756d4a13d9061babf..refs/heads/master:/aslcommon/asl_memory.c diff --git a/aslcommon/asl_memory.c b/aslcommon/asl_memory.c index 5964cf0..1dcfab1 100644 --- a/aslcommon/asl_memory.c +++ b/aslcommon/asl_memory.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2008 Apple Inc. All rights reserved. + * Copyright (c) 2007-2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -21,8 +21,6 @@ * @APPLE_LICENSE_HEADER_END@ */ -#include -#include #include #include #include @@ -30,19 +28,21 @@ #include #include #include +#include +#include +#include #include +#include "asl_memory.h" #define DEFAULT_MAX_RECORDS 2000 -#define MEM_STRING_HEADER_SIZE 8 +#define DEFAULT_MAX_STRING_MEMORY 4096000 #define forever for(;;) -extern time_t asl_parse_time(const char *str); -extern int asl_msg_cmp(asl_msg_t *a, asl_msg_t *b); uint32_t -asl_memory_statistics(asl_memory_t *s, aslmsg *msg) +asl_memory_statistics(asl_memory_t *s, asl_msg_t **msg) { - aslmsg out; + asl_msg_t * out; uint32_t i, n; uint64_t size; char str[256]; @@ -50,7 +50,7 @@ asl_memory_statistics(asl_memory_t *s, aslmsg *msg) if (s == NULL) return ASL_STATUS_INVALID_STORE; if (msg == NULL) return ASL_STATUS_INVALID_ARG; - out = (aslmsg)calloc(1, sizeof(asl_msg_t)); + out = asl_msg_new(ASL_TYPE_MSG); if (out == NULL) return ASL_STATUS_NO_MEMORY; size = sizeof(asl_memory_t); @@ -58,21 +58,30 @@ asl_memory_statistics(asl_memory_t *s, aslmsg *msg) for (i = 0; i < s->string_count; i++) { - size += MEM_STRING_HEADER_SIZE; - if (((mem_string_t *)s->string_cache[i])->str != NULL) size += (strlen(((mem_string_t *)s->string_cache[i])->str) + 1); + size += sizeof(mem_string_t); + if (s->string_cache[i]->str != NULL) size += (strlen(s->string_cache[i]->str) + 1); } snprintf(str, sizeof(str), "%llu", size); - asl_set(out, "Size", str); + asl_msg_set_key_val(out, "Size", str); n = 0; for (i = 0; i < s->record_count; i++) if (s->record[i]->mid != 0) n++; + snprintf(str, sizeof(str), "%u", s->record_count); + asl_msg_set_key_val(out, "MaxRecords", str); + snprintf(str, sizeof(str), "%u", n); - asl_set(out, "RecordCount", str); + asl_msg_set_key_val(out, "RecordCount", str); snprintf(str, sizeof(str), "%u", s->string_count); - asl_set(out, "StringCount", str); + asl_msg_set_key_val(out, "StringCount", str); + + snprintf(str, sizeof(str), "%lu", s->curr_string_mem); + asl_msg_set_key_val(out, "StringMemory", str); + + snprintf(str, sizeof(str), "%lu", s->max_string_mem); + asl_msg_set_key_val(out, "MaxStringMemory", str); *msg = out; return ASL_STATUS_OK; @@ -81,35 +90,45 @@ asl_memory_statistics(asl_memory_t *s, aslmsg *msg) uint32_t asl_memory_close(asl_memory_t *s) { - uint32_t i; - if (s == NULL) return ASL_STATUS_OK; + + dispatch_sync(s->queue, ^{ + uint32_t i; - if (s->record != NULL) - { - for (i = 0; i < s->record_count; i++) + if (s->record != NULL) { - if (s->record[i] != NULL) free(s->record[i]); - s->record[i] = NULL; - } + for (i = 0; i < s->record_count; i++) + { + free(s->record[i]); + s->record[i] = NULL; + } - free(s->record); - s->record = NULL; - } + free(s->record); + s->record = NULL; + } - if (s->buffer_record != NULL) free(s->buffer_record); + free(s->buffer_record); + s->buffer_record = NULL; - if (s->string_cache != NULL) - { - for (i = 0; i < s->string_count; i++) + if (s->string_cache != NULL) { - if (s->string_cache[i] != NULL) free(s->string_cache[i]); - s->string_cache[i] = NULL; + for (i = 0; i < s->string_count; i++) + { + if (s->string_cache[i] != NULL) + { + free(s->string_cache[i]->str); + free(s->string_cache[i]); + } + + s->string_cache[i] = NULL; + } + + free(s->string_cache); + s->string_cache = NULL; } + }); - free(s->string_cache); - s->string_cache = NULL; - } + dispatch_release(s->queue); free(s); @@ -117,7 +136,7 @@ asl_memory_close(asl_memory_t *s) } uint32_t -asl_memory_open(uint32_t max_records, asl_memory_t **s) +asl_memory_open(uint32_t max_records, size_t max_str_mem, asl_memory_t **s) { asl_memory_t *out; uint32_t i; @@ -125,14 +144,25 @@ asl_memory_open(uint32_t max_records, asl_memory_t **s) if (s == NULL) return ASL_STATUS_INVALID_ARG; if (max_records == 0) max_records = DEFAULT_MAX_RECORDS; + if (max_str_mem == 0) max_str_mem = DEFAULT_MAX_STRING_MEMORY; out = calloc(1, sizeof(asl_memory_t)); if (out == NULL) return ASL_STATUS_NO_MEMORY; + out->queue = dispatch_queue_create("ASL Memory Queue", NULL); + if (out->queue == NULL) + { + free(out); + return ASL_STATUS_NO_MEMORY; + } + + out->max_string_mem = max_str_mem; + out->record_count = max_records; out->record = (mem_record_t **)calloc(max_records, sizeof(mem_record_t *)); if (out->record == NULL) { + dispatch_release(out->queue); free(out); return ASL_STATUS_NO_MEMORY; } @@ -158,28 +188,67 @@ asl_memory_open(uint32_t max_records, asl_memory_t **s) return ASL_STATUS_OK; } +static void +asl_memory_reset(asl_memory_t *s) +{ + uint32_t i; + if (s == NULL) return; + + /* clear all message records */ + for (i = 0; i < s->record_count; i++) + { + memset(s->record[i], 0, sizeof(mem_record_t)); + } + + /* reset the string cache */ + if (s->string_cache != NULL) + { + for (i = 0; i < s->string_count; i++) + { + if (s->string_cache[i] != NULL) + { + free(s->string_cache[i]->str); + free(s->string_cache[i]); + } + + s->string_cache[i] = NULL; + } + + free(s->string_cache); + s->string_cache = NULL; + } + + s->string_count = 0; +} + static mem_string_t * -mem_string_new(const char *str, uint32_t len, uint32_t hash) +asl_memory_string_new(const char *str, uint32_t len, uint32_t hash) { mem_string_t *out; - size_t ss; if (str == NULL) return NULL; - ss = MEM_STRING_HEADER_SIZE + len + 1; - out = (mem_string_t *)calloc(1, ss); + out = (mem_string_t *)calloc(1, sizeof(mem_string_t)); if (out == NULL) return NULL; out->hash = hash; out->refcount = 1; + out->str = malloc(len + 1); + if (out->str == NULL) + { + free(out); + return NULL; + } + memcpy(out->str, str, len); + out->str[len] = 0; return out; } /* * Find the first hash greater than or equal to a given hash in the string cache. - * Return s->string_count if hash is greater that or equal to last hash in the string cache. + * Return s->string_count if hash is greater than last hash in the string cache. * Caller must check if the hashes match or not. * * This routine is used both to find strings in the cache and to determine where to insert @@ -194,25 +263,24 @@ asl_memory_string_cache_search_hash(asl_memory_t *s, uint32_t hash) if (s->string_count == 0) return 0; if (s->string_count == 1) { - ms = (mem_string_t *)s->string_cache[0]; + ms = s->string_cache[0]; if (hash < ms->hash) return 0; return 1; } - top = s->string_count - 1; + range = top = s->string_count - 1; bot = 0; mid = top / 2; - range = top - bot; while (range > 1) { - ms = (mem_string_t *)s->string_cache[mid]; + ms = s->string_cache[mid]; if (hash == ms->hash) { while (mid > 0) { - ms = (mem_string_t *)s->string_cache[mid - 1]; + ms = s->string_cache[mid - 1]; if (hash != ms->hash) break; mid--; } @@ -221,7 +289,7 @@ asl_memory_string_cache_search_hash(asl_memory_t *s, uint32_t hash) } else { - ms = (mem_string_t *)s->string_cache[mid]; + ms = s->string_cache[mid]; if (hash < ms->hash) top = mid; else bot = mid; } @@ -230,10 +298,10 @@ asl_memory_string_cache_search_hash(asl_memory_t *s, uint32_t hash) mid = bot + (range / 2); } - ms = (mem_string_t *)s->string_cache[bot]; + ms = s->string_cache[bot]; if (hash <= ms->hash) return bot; - ms = (mem_string_t *)s->string_cache[top]; + ms = s->string_cache[top]; if (hash <= ms->hash) return top; return s->string_count; @@ -249,6 +317,7 @@ static mem_string_t * asl_memory_string_retain(asl_memory_t *s, const char *str, int create) { uint32_t i, where, hash, len; + mem_string_t *new; if (s == NULL) return NULL; if (str == NULL) return NULL; @@ -261,11 +330,11 @@ asl_memory_string_retain(asl_memory_t *s, const char *str, int create) /* asl_memory_string_cache_search_hash just tells us where to look */ if (where < s->string_count) { - while (((mem_string_t *)(s->string_cache[where]))->hash == hash) + while (s->string_cache[where]->hash == hash) { - if (!strcmp(str, ((mem_string_t *)(s->string_cache[where]))->str)) + if (!strcmp(str, s->string_cache[where]->str)) { - ((mem_string_t *)(s->string_cache[where]))->refcount++; + s->string_cache[where]->refcount++; return s->string_cache[where]; } @@ -277,24 +346,22 @@ asl_memory_string_retain(asl_memory_t *s, const char *str, int create) if (create == 0) return NULL; /* create a new mem_string_t and insert into the cache at index 'where' */ - if (s->string_count == 0) - { - s->string_cache = (void **)calloc(1, sizeof(void *)); - } - else - { - s->string_cache = (void **)reallocf(s->string_cache, (s->string_count + 1) * sizeof(void *)); - for (i = s->string_count; i > where; i--) s->string_cache[i] = s->string_cache[i - 1]; - } - + new = asl_memory_string_new(str, len, hash); + if (new == NULL) return NULL; + + s->string_cache = (mem_string_t **)reallocf(s->string_cache, (s->string_count + 1) * sizeof(void *)); if (s->string_cache == NULL) { s->string_count = 0; + free(new); return NULL; } + for (i = s->string_count; i > where; i--) s->string_cache[i] = s->string_cache[i - 1]; + + s->curr_string_mem += (sizeof(mem_string_t) + len + 1); + s->string_cache[where] = new; s->string_count++; - s->string_cache[where] = mem_string_new(str, len, hash); return s->string_cache[where]; } @@ -311,11 +378,11 @@ asl_memory_string_release(asl_memory_t *s, mem_string_t *m) if (m->refcount > 0) return ASL_STATUS_OK; where = asl_memory_string_cache_search_hash(s, m->hash); - if (((mem_string_t *)(s->string_cache[where]))->hash != m->hash) return ASL_STATUS_OK; + if (s->string_cache[where]->hash != m->hash) return ASL_STATUS_OK; while (s->string_cache[where] != m) { - if (((mem_string_t *)(s->string_cache[where]))->hash != m->hash) return ASL_STATUS_OK; + if (s->string_cache[where]->hash != m->hash) return ASL_STATUS_OK; where++; if (where >= s->string_count) return ASL_STATUS_OK; @@ -323,7 +390,12 @@ asl_memory_string_release(asl_memory_t *s, mem_string_t *m) for (i = where + 1; i < s->string_count; i++) s->string_cache[i - 1] = s->string_cache[i]; + if (m->str == NULL) s->curr_string_mem -= sizeof(mem_string_t); + else s->curr_string_mem -= (sizeof(mem_string_t) + strlen(m->str) + 1); + + free(m->str); free(m); + s->string_count--; if (s->string_count == 0) @@ -333,7 +405,7 @@ asl_memory_string_release(asl_memory_t *s, mem_string_t *m) return ASL_STATUS_OK; } - s->string_cache = (void **)reallocf(s->string_cache, s->string_count * sizeof(void *)); + s->string_cache = (mem_string_t **)reallocf(s->string_cache, s->string_count * sizeof(void *)); if (s->string_cache == NULL) { s->string_count = 0; @@ -356,6 +428,7 @@ asl_memory_record_clear(asl_memory_t *s, mem_record_t *r) asl_memory_string_release(s, r->host); asl_memory_string_release(s, r->sender); + asl_memory_string_release(s, r->sender_mach_uuid); asl_memory_string_release(s, r->facility); asl_memory_string_release(s, r->message); asl_memory_string_release(s, r->refproc); @@ -375,18 +448,22 @@ asl_memory_record_free(asl_memory_t *s, mem_record_t *r) } /* - * Encode an aslmsg as a record structure. + * Encode an asl_msg_t as a record structure. * Creates and caches strings. */ static uint32_t -asl_memory_message_encode(asl_memory_t *s, asl_msg_t *msg, mem_record_t *r) +asl_memory_message_encode(asl_memory_t *s, asl_msg_t *msg) { - uint32_t i; + uint32_t x; mem_string_t *k, *v; + mem_record_t *r; + const char *key, *val; if (s == NULL) return ASL_STATUS_INVALID_STORE; + if (s->buffer_record == NULL) return ASL_STATUS_INVALID_STORE; if (msg == NULL) return ASL_STATUS_INVALID_MESSAGE; - if (r == NULL) return ASL_STATUS_INVALID_ARG; + + r = s->buffer_record; memset(r, 0, sizeof(mem_record_t)); @@ -400,100 +477,103 @@ asl_memory_message_encode(asl_memory_t *s, asl_msg_t *msg, mem_record_t *r) r->time = (uint64_t)-1; r->nano = (uint32_t)-1; - for (i = 0; i < msg->count; i++) + key = NULL; + val = NULL; + + for (x = asl_msg_fetch((asl_msg_t *)msg, 0, &key, &val, NULL); x != IndexNull; x = asl_msg_fetch((asl_msg_t *)msg, x, &key, &val, NULL)) { - if (msg->key[i] == NULL) continue; + if (key == NULL) continue; - else if (!strcmp(msg->key[i], ASL_KEY_TIME)) + else if (!strcmp(key, ASL_KEY_TIME)) + { + if (val != NULL) r->time = asl_core_parse_time(val, NULL); + } + else if (!strcmp(key, ASL_KEY_TIME_NSEC)) { - if (msg->val[i] != NULL) r->time = asl_parse_time(msg->val[i]); + if (val != NULL) r->nano = atoi(val); } - else if (!strcmp(msg->key[i], ASL_KEY_TIME_NSEC)) + else if (!strcmp(key, ASL_KEY_HOST)) { - if (msg->val[i] != NULL) r->nano = atoi(msg->val[i]); + if (val != NULL) r->host = asl_memory_string_retain(s, val, 1); } - else if (!strcmp(msg->key[i], ASL_KEY_HOST)) + else if (!strcmp(key, ASL_KEY_SENDER)) { - if (msg->val[i] != NULL) r->host = asl_memory_string_retain(s, msg->val[i], 1); + if (val != NULL) r->sender = asl_memory_string_retain(s, val, 1); } - else if (!strcmp(msg->key[i], ASL_KEY_SENDER)) + else if (!strcmp(key, ASL_KEY_PID)) { - if (msg->val[i] != NULL) r->sender = asl_memory_string_retain(s, msg->val[i], 1); + if (val != NULL) r->pid = atoi(val); } - else if (!strcmp(msg->key[i], ASL_KEY_PID)) + else if (!strcmp(key, ASL_KEY_REF_PID)) { - if (msg->val[i] != NULL) r->pid = atoi(msg->val[i]); + if (val != NULL) r->refpid = atoi(val); } - else if (!strcmp(msg->key[i], ASL_KEY_REF_PID)) + else if (!strcmp(key, ASL_KEY_UID)) { - if (msg->val[i] != NULL) r->refpid = atoi(msg->val[i]); + if (val != NULL) r->uid = atoi(val); } - else if (!strcmp(msg->key[i], ASL_KEY_UID)) + else if (!strcmp(key, ASL_KEY_GID)) { - if (msg->val[i] != NULL) r->uid = atoi(msg->val[i]); + if (val != NULL) r->gid = atoi(val); } - else if (!strcmp(msg->key[i], ASL_KEY_GID)) + else if (!strcmp(key, ASL_KEY_LEVEL)) { - if (msg->val[i] != NULL) r->gid = atoi(msg->val[i]); + if (val != NULL) r->level = atoi(val); } - else if (!strcmp(msg->key[i], ASL_KEY_LEVEL)) + else if (!strcmp(key, ASL_KEY_MSG)) { - if (msg->val[i] != NULL) r->level = atoi(msg->val[i]); + if (val != NULL) r->message = asl_memory_string_retain(s, val, 1); } - else if (!strcmp(msg->key[i], ASL_KEY_MSG)) + else if (!strcmp(key, ASL_KEY_SENDER_MACH_UUID)) { - if (msg->val[i] != NULL) r->message = asl_memory_string_retain(s, msg->val[i], 1); + if (val != NULL) r->sender_mach_uuid = asl_memory_string_retain(s, val, 1); } - else if (!strcmp(msg->key[i], ASL_KEY_FACILITY)) + else if (!strcmp(key, ASL_KEY_FACILITY)) { - if (msg->val[i] != NULL) r->facility = asl_memory_string_retain(s, msg->val[i], 1); + if (val != NULL) r->facility = asl_memory_string_retain(s, val, 1); } - else if (!strcmp(msg->key[i], ASL_KEY_REF_PROC)) + else if (!strcmp(key, ASL_KEY_REF_PROC)) { - if (msg->val[i] != NULL) r->refproc = asl_memory_string_retain(s, msg->val[i], 1); + if (val != NULL) r->refproc = asl_memory_string_retain(s, val, 1); } - else if (!strcmp(msg->key[i], ASL_KEY_SESSION)) + else if (!strcmp(key, ASL_KEY_SESSION)) { - if (msg->val[i] != NULL) r->session = asl_memory_string_retain(s, msg->val[i], 1); + if (val != NULL) r->session = asl_memory_string_retain(s, val, 1); } - else if (!strcmp(msg->key[i], ASL_KEY_READ_UID)) + else if (!strcmp(key, ASL_KEY_READ_UID)) { - if (((r->flags & ASL_MSG_FLAG_READ_UID_SET) == 0) && (msg->val[i] != NULL)) + if (((r->flags & ASL_MSG_FLAG_READ_UID_SET) == 0) && (val != NULL)) { - r->ruid = atoi(msg->val[i]); + r->ruid = atoi(val); r->flags |= ASL_MSG_FLAG_READ_UID_SET; } } - else if (!strcmp(msg->key[i], ASL_KEY_READ_GID)) + else if (!strcmp(key, ASL_KEY_READ_GID)) { - if (((r->flags & ASL_MSG_FLAG_READ_GID_SET) == 0) && (msg->val[i] != NULL)) + if (((r->flags & ASL_MSG_FLAG_READ_GID_SET) == 0) && (val != NULL)) { - r->rgid = atoi(msg->val[i]); + r->rgid = atoi(val); r->flags |= ASL_MSG_FLAG_READ_GID_SET; } } - else if (!strcmp(msg->key[i], ASL_KEY_MSG_ID)) + else if (!strcmp(key, ASL_KEY_OS_ACTIVITY_ID)) + { + if (val != NULL) r->os_activity_id = atoll(val); + } + else if (!strcmp(key, ASL_KEY_MSG_ID)) { /* Ignore */ continue; } else { - k = asl_memory_string_retain(s, msg->key[i], 1); + k = asl_memory_string_retain(s, key, 1); if (k == NULL) continue; v = NULL; - if (msg->val[i] != NULL) v = asl_memory_string_retain(s, msg->val[i], 1); - - if (r->kvcount == 0) - { - r->kvlist = (mem_string_t **)calloc(2, sizeof(mem_string_t *)); - } - else - { - r->kvlist = (mem_string_t **)realloc(r->kvlist, (r->kvcount + 2) * sizeof(mem_string_t *)); - } + if (val != NULL) v = asl_memory_string_retain(s, val, 1); + r->kvlist = (mem_string_t **)reallocf(r->kvlist, (r->kvcount + 2) * sizeof(mem_string_t *)); if (r->kvlist == NULL) { asl_memory_record_clear(s, r); @@ -509,39 +589,60 @@ asl_memory_message_encode(asl_memory_t *s, asl_msg_t *msg, mem_record_t *r) } uint32_t -asl_memory_save(asl_memory_t *s, aslmsg msg, uint64_t *mid) +asl_memory_save(asl_memory_t *s, asl_msg_t *msg, uint64_t *mid) { - uint32_t status; - mem_record_t *t; + __block uint32_t status; if (s == NULL) return ASL_STATUS_INVALID_STORE; if (s->buffer_record == NULL) return ASL_STATUS_INVALID_STORE; - /* asl_memory_message_encode creates and caches strings */ - status = asl_memory_message_encode(s, msg, s->buffer_record); - if (status != ASL_STATUS_OK) return status; - - if (*mid != 0) - { - s->buffer_record->mid = *mid; - } - else - { - s->buffer_record->mid = asl_core_new_msg_id(0); - *mid = s->buffer_record->mid; - } - - /* clear the first record */ - t = s->record[s->record_first]; - asl_memory_record_clear(s, t); + dispatch_sync(s->queue, ^{ + mem_record_t *t; - /* add the new record to the record list (swap in the buffer record) */ - s->record[s->record_first] = s->buffer_record; - s->buffer_record = t; - - /* record list is a circular queue */ - s->record_first++; - if (s->record_first >= s->record_count) s->record_first = 0; + /* asl_memory_message_encode creates and caches strings */ + status = asl_memory_message_encode(s, msg); + if (status == ASL_STATUS_OK) + { + uint32_t loop_start_index = s->record_first; + + if (*mid != 0) + { + s->buffer_record->mid = *mid; + } + else + { + s->buffer_record->mid = asl_core_new_msg_id(0); + *mid = s->buffer_record->mid; + } + + /* clear the first record */ + t = s->record[s->record_first]; + asl_memory_record_clear(s, t); + + /* add the new record to the record list (swap in the buffer record) */ + s->record[s->record_first] = s->buffer_record; + s->buffer_record = t; + + /* record list is a circular queue */ + s->record_first++; + if (s->record_first >= s->record_count) s->record_first = 0; + + /* delete records if too much memory is in use */ + while (s->curr_string_mem > s->max_string_mem) + { + asl_memory_record_clear(s, s->record[s->record_first]); + s->record_first++; + if (s->record_first >= s->record_count) s->record_first = 0; + if (s->record_first == loop_start_index) + { + /* The entire ring has been cleared. This should never happen. */ + asl_memory_reset(s); + status = ASL_STATUS_FAILED; + break; + } + } + } + }); return status; } @@ -552,8 +653,10 @@ asl_memory_save(asl_memory_t *s, aslmsg msg, uint64_t *mid) static uint32_t asl_memory_message_decode(asl_memory_t *s, mem_record_t *r, asl_msg_t **out) { - uint32_t i, n; + uint32_t i; asl_msg_t *msg; + char tmp[64]; + const char *key, *val; if (s == NULL) return ASL_STATUS_INVALID_STORE; if (r == NULL) return ASL_STATUS_INVALID_ARG; @@ -561,321 +664,133 @@ asl_memory_message_decode(asl_memory_t *s, mem_record_t *r, asl_msg_t **out) *out = NULL; - msg = (asl_msg_t *)calloc(1, sizeof(asl_msg_t)); + msg = asl_msg_new(ASL_TYPE_MSG); if (msg == NULL) return ASL_STATUS_NO_MEMORY; - msg->type = ASL_TYPE_MSG; - /* Level and Message ID are always set */ - msg->count = 2; - if (r->time != (uint64_t)-1) msg->count++; - if (r->nano != (uint32_t)-1) msg->count++; - if (r->host != NULL) msg->count++; - if (r->sender != NULL) msg->count++; - if (r->facility != NULL) msg->count++; - if (r->refproc != NULL) msg->count++; - if (r->session != NULL) msg->count++; - if (r->pid != -1) msg->count++; - if (r->refpid != 0) msg->count++; - if (r->uid != -2) msg->count++; - if (r->gid != -2) msg->count++; - if (r->message != NULL) msg->count++; - if (r->flags & ASL_MSG_FLAG_READ_UID_SET) msg->count++; - if (r->flags & ASL_MSG_FLAG_READ_GID_SET) msg->count++; - - msg->count += (r->kvcount / 2); - - msg->key = (char **)calloc(msg->count, sizeof(char *)); - if (msg->key == NULL) - { - free(msg); - return ASL_STATUS_NO_MEMORY; - } - - msg->val = (char **)calloc(msg->count, sizeof(char *)); - if (msg->val == NULL) - { - free(msg->key); - free(msg); - return ASL_STATUS_NO_MEMORY; - } - - n = 0; - /* Message ID */ - msg->key[n] = strdup(ASL_KEY_MSG_ID); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - asprintf(&(msg->val[n]), "%llu", r->mid); - if (msg->val[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - n++; + snprintf(tmp, sizeof(tmp), "%llu", r->mid); + asl_msg_set_key_val(msg, ASL_KEY_MSG_ID, tmp); /* Level */ - msg->key[n] = strdup(ASL_KEY_LEVEL); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - asprintf(&(msg->val[n]), "%u", r->level); - if (msg->val[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - n++; + snprintf(tmp, sizeof(tmp), "%u", r->level); + asl_msg_set_key_val(msg, ASL_KEY_LEVEL, tmp); /* Time */ if (r->time != (uint64_t)-1) { - msg->key[n] = strdup(ASL_KEY_TIME); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - asprintf(&(msg->val[n]), "%llu", r->time); - if (msg->val[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - n++; + snprintf(tmp, sizeof(tmp), "%llu", r->time); + asl_msg_set_key_val(msg, ASL_KEY_TIME, tmp); } /* Nanoseconds */ if (r->nano != (uint32_t)-1) { - msg->key[n] = strdup(ASL_KEY_TIME_NSEC); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - asprintf(&(msg->val[n]), "%lu", r->nano); - if (msg->val[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - n++; + snprintf(tmp, sizeof(tmp), "%u", r->nano); + asl_msg_set_key_val(msg, ASL_KEY_TIME_NSEC, tmp); } /* Host */ if (r->host != NULL) { - msg->key[n] = strdup(ASL_KEY_HOST); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - msg->val[n] = strdup(r->host->str); - n++; + asl_msg_set_key_val(msg, ASL_KEY_HOST, r->host->str); } /* Sender */ if (r->sender != NULL) { - msg->key[n] = strdup(ASL_KEY_SENDER); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } + asl_msg_set_key_val(msg, ASL_KEY_SENDER, r->sender->str); + } - msg->val[n] = strdup(r->sender->str); - n++; + /* Sender mach UUID */ + if (r->sender_mach_uuid != NULL) + { + asl_msg_set_key_val(msg, ASL_KEY_SENDER_MACH_UUID, r->sender_mach_uuid->str); } /* Facility */ if (r->facility != NULL) { - msg->key[n] = strdup(ASL_KEY_FACILITY); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - msg->val[n] = strdup(r->facility->str); - n++; + asl_msg_set_key_val(msg, ASL_KEY_FACILITY, r->facility->str); } /* Ref Proc */ if (r->refproc != NULL) { - msg->key[n] = strdup(ASL_KEY_REF_PROC); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - msg->val[n] = strdup(r->refproc->str); - n++; + asl_msg_set_key_val(msg, ASL_KEY_REF_PROC, r->refproc->str); } /* Session */ if (r->session != NULL) { - msg->key[n] = strdup(ASL_KEY_SESSION); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - msg->val[n] = strdup(r->session->str); - n++; + asl_msg_set_key_val(msg, ASL_KEY_SESSION, r->session->str); } /* PID */ if (r->pid != -1) { - msg->key[n] = strdup(ASL_KEY_PID); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - asprintf(&(msg->val[n]), "%d", r->pid); - if (msg->val[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - n++; + snprintf(tmp, sizeof(tmp), "%d", r->pid); + asl_msg_set_key_val(msg, ASL_KEY_PID, tmp); } /* REF PID */ if (r->refpid != 0) { - msg->key[n] = strdup(ASL_KEY_REF_PID); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - asprintf(&(msg->val[n]), "%d", r->refpid); - if (msg->val[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - n++; + snprintf(tmp, sizeof(tmp), "%d", r->refpid); + asl_msg_set_key_val(msg, ASL_KEY_REF_PID, tmp); } /* UID */ if (r->uid != -2) { - msg->key[n] = strdup(ASL_KEY_UID); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - asprintf(&(msg->val[n]), "%d", r->uid); - if (msg->val[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - n++; + snprintf(tmp, sizeof(tmp), "%d", r->uid); + asl_msg_set_key_val(msg, ASL_KEY_UID, tmp); } /* GID */ if (r->gid != -2) { - msg->key[n] = strdup(ASL_KEY_GID); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - asprintf(&(msg->val[n]), "%d", r->gid); - if (msg->val[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - n++; + snprintf(tmp, sizeof(tmp), "%d", r->gid); + asl_msg_set_key_val(msg, ASL_KEY_GID, tmp); } /* Message */ if (r->message != NULL) { - msg->key[n] = strdup(ASL_KEY_MSG); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - msg->val[n] = strdup(r->message->str); - n++; + asl_msg_set_key_val(msg, ASL_KEY_MSG, r->message->str); } /* ReadUID */ if (r->flags & ASL_MSG_FLAG_READ_UID_SET) { - msg->key[n] = strdup(ASL_KEY_READ_UID); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - - asprintf(&(msg->val[n]), "%d", r->ruid); - if (msg->val[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - n++; + snprintf(tmp, sizeof(tmp), "%d", r->ruid); + asl_msg_set_key_val(msg, ASL_KEY_READ_UID, tmp); } /* ReadGID */ if (r->flags & ASL_MSG_FLAG_READ_GID_SET) { - msg->key[n] = strdup(ASL_KEY_READ_GID); - if (msg->key[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } + snprintf(tmp, sizeof(tmp), "%d", r->rgid); + asl_msg_set_key_val(msg, ASL_KEY_READ_GID, tmp); + } - asprintf(&(msg->val[n]), "%d", r->rgid); - if (msg->val[n] == NULL) - { - asl_free(msg); - return ASL_STATUS_NO_MEMORY; - } - n++; + /* OSActivityID */ + if (r->os_activity_id != 0) + { + snprintf(tmp, sizeof(tmp), "%llu", r->os_activity_id); + asl_msg_set_key_val(msg, ASL_KEY_OS_ACTIVITY_ID, tmp); } /* Key - Value List */ for (i = 0; i < r->kvcount; i++) { - if ((r->kvlist[i] != NULL) && (r->kvlist[i]->str != NULL)) msg->key[n] = strdup(r->kvlist[i]->str); + key = NULL; + val = NULL; + + if (r->kvlist[i] != NULL) key = r->kvlist[i]->str; i++; - if ((r->kvlist[i] != NULL) && (r->kvlist[i]->str != NULL)) msg->val[n] = strdup(r->kvlist[i]->str); - n++; + if (r->kvlist[i] != NULL) val = r->kvlist[i]->str; + + if (key != NULL) asl_msg_set_key_val(msg, key, val); } *out = msg; @@ -883,34 +798,44 @@ asl_memory_message_decode(asl_memory_t *s, mem_record_t *r, asl_msg_t **out) } uint32_t -asl_memory_fetch(asl_memory_t *s, uint64_t mid, aslmsg *msg, int32_t ruid, int32_t rgid) +asl_memory_fetch(asl_memory_t *s, uint64_t mid, asl_msg_t **msg, int32_t ruid, int32_t rgid) { - uint32_t i, status; + __block uint32_t status; if (s == NULL) return ASL_STATUS_INVALID_STORE; if (msg == NULL) return ASL_STATUS_INVALID_ARG; - for (i = 0; i < s->record_count; i++) - { - if (s->record[i]->mid == 0) break; + status = ASL_STATUS_INVALID_ID; + + dispatch_sync(s->queue, ^{ + uint32_t i; - if (s->record[i]->mid == mid) + for (i = 0; i < s->record_count; i++) { - status = asl_core_check_access(s->record[i]->ruid, s->record[i]->rgid, ruid, rgid, s->record[i]->flags); - if (status != ASL_STATUS_OK) return status; - return asl_memory_message_decode(s, s->record[i], msg); + if (s->record[i]->mid == 0) break; + + if (s->record[i]->mid == mid) + { + status = asl_core_check_access(s->record[i]->ruid, s->record[i]->rgid, ruid, rgid, s->record[i]->flags); + if (status != ASL_STATUS_OK) break; + + status = asl_memory_message_decode(s, s->record[i], msg); + break; + } } - } + }); - return ASL_STATUS_INVALID_ID; + return status; } static mem_record_t * asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) { mem_record_t *out; - uint32_t i, j; - mem_string_t *key, *val; + uint32_t i, x; + uint16_t op; + mem_string_t *mkey, *mval; + const char *key, *val; if (type == NULL) return NULL; @@ -923,14 +848,15 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) /* NULL query matches anything */ *type = ASL_QUERY_MATCH_TRUE; if (q == NULL) return NULL; - if (q->count == 0) return NULL; + if (asl_msg_count((asl_msg_t *)q) == 0) return NULL; /* we can only do fast match on equality tests */ *type = ASL_QUERY_MATCH_SLOW; - if (q->op != NULL) + + for (x = asl_msg_fetch((asl_msg_t *)q, 0, NULL, NULL, &op); x != IndexNull; x = asl_msg_fetch((asl_msg_t *)q, x, NULL, NULL, &op)) { - for (i = 0; i < q->count; i++) if (q->op[i] != ASL_QUERY_OP_EQUAL) return NULL; + if (op != ASL_QUERY_OP_EQUAL) return NULL; } out = (mem_record_t *)calloc(1, sizeof(mem_record_t)); @@ -940,13 +866,13 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) return NULL; } - for (i = 0; i < q->count; i++) + for (x = asl_msg_fetch((asl_msg_t *)q, 0, &key, &val, &op); x != IndexNull; x = asl_msg_fetch((asl_msg_t *)q, x, &key, &val, &op)) { - if (q->key[i] == NULL) continue; + if (key == NULL) continue; - else if (!strcmp(q->key[i], ASL_KEY_MSG_ID)) + else if (!strcmp(key, ASL_KEY_MSG_ID)) { - if (q->val[i] == NULL) continue; + if (val == NULL) continue; if (*type & ASL_QUERY_MATCH_MSG_ID) { @@ -956,11 +882,11 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) } *type |= ASL_QUERY_MATCH_MSG_ID; - out->mid = atoll(q->val[i]); + out->mid = atoll(val); } - else if (!strcmp(q->key[i], ASL_KEY_TIME)) + else if (!strcmp(key, ASL_KEY_TIME)) { - if (q->val[i] == NULL) continue; + if (val == NULL) continue; if (*type & ASL_QUERY_MATCH_TIME) { @@ -970,11 +896,11 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) } *type |= ASL_QUERY_MATCH_TIME; - out->time = asl_parse_time(q->val[i]); + out->time = asl_core_parse_time(val, NULL); } - else if (!strcmp(q->key[i], ASL_KEY_TIME_NSEC)) + else if (!strcmp(key, ASL_KEY_TIME_NSEC)) { - if (q->val[i] == NULL) continue; + if (val == NULL) continue; if (*type & ASL_QUERY_MATCH_NANO) { @@ -984,11 +910,11 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) } *type |= ASL_QUERY_MATCH_NANO; - out->nano = atoll(q->val[i]); + out->nano = atoll(val); } - else if (!strcmp(q->key[i], ASL_KEY_LEVEL)) + else if (!strcmp(key, ASL_KEY_LEVEL)) { - if (q->val[i] == NULL) continue; + if (val == NULL) continue; if (*type & ASL_QUERY_MATCH_LEVEL) { @@ -998,11 +924,11 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) } *type |= ASL_QUERY_MATCH_LEVEL; - out->level = atoi(q->val[i]); + out->level = atoi(val); } - else if (!strcmp(q->key[i], ASL_KEY_PID)) + else if (!strcmp(key, ASL_KEY_PID)) { - if (q->val[i] == NULL) continue; + if (val == NULL) continue; if (*type & ASL_QUERY_MATCH_PID) { @@ -1012,11 +938,11 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) } *type |= ASL_QUERY_MATCH_PID; - out->pid = atoi(q->val[i]); + out->pid = atoi(val); } - else if (!strcmp(q->key[i], ASL_KEY_UID)) + else if (!strcmp(key, ASL_KEY_UID)) { - if (q->val[i] == NULL) continue; + if (val == NULL) continue; if (*type & ASL_QUERY_MATCH_UID) { @@ -1026,11 +952,11 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) } *type |= ASL_QUERY_MATCH_UID; - out->uid = atoi(q->val[i]); + out->uid = atoi(val); } - else if (!strcmp(q->key[i], ASL_KEY_GID)) + else if (!strcmp(key, ASL_KEY_GID)) { - if (q->val[i] == NULL) continue; + if (val == NULL) continue; if (*type & ASL_QUERY_MATCH_GID) { @@ -1040,11 +966,11 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) } *type |= ASL_QUERY_MATCH_GID; - out->gid = atoi(q->val[i]); + out->gid = atoi(val); } - else if (!strcmp(q->key[i], ASL_KEY_READ_UID)) + else if (!strcmp(key, ASL_KEY_READ_UID)) { - if (q->val[i] == NULL) continue; + if (val == NULL) continue; if (*type & ASL_QUERY_MATCH_RUID) { @@ -1054,11 +980,11 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) } *type |= ASL_QUERY_MATCH_RUID; - out->ruid = atoi(q->val[i]); + out->ruid = atoi(val); } - else if (!strcmp(q->key[i], ASL_KEY_READ_GID)) + else if (!strcmp(key, ASL_KEY_READ_GID)) { - if (q->val[i] == NULL) continue; + if (val == NULL) continue; if (*type & ASL_QUERY_MATCH_RGID) { @@ -1068,11 +994,11 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) } *type |= ASL_QUERY_MATCH_RGID; - out->rgid = atoi(q->val[i]); + out->rgid = atoi(val); } - else if (!strcmp(q->key[i], ASL_KEY_REF_PID)) + else if (!strcmp(key, ASL_KEY_REF_PID)) { - if (q->val[i] == NULL) continue; + if (val == NULL) continue; if (*type & ASL_QUERY_MATCH_REF_PID) { @@ -1082,11 +1008,11 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) } *type |= ASL_QUERY_MATCH_REF_PID; - out->refpid = atoi(q->val[i]); + out->refpid = atoi(val); } - else if (!strcmp(q->key[i], ASL_KEY_HOST)) + else if (!strcmp(key, ASL_KEY_HOST)) { - if (q->val[i] == NULL) continue; + if (val == NULL) continue; if (*type & ASL_QUERY_MATCH_HOST) { @@ -1096,7 +1022,7 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) } *type |= ASL_QUERY_MATCH_HOST; - out->host = asl_memory_string_retain(s, q->val[i], 0); + out->host = asl_memory_string_retain(s, val, 0); if (out->host == NULL) { asl_memory_record_free(s, out); @@ -1104,9 +1030,9 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) return NULL; } } - else if (!strcmp(q->key[i], ASL_KEY_SENDER)) + else if (!strcmp(key, ASL_KEY_SENDER)) { - if (q->val[i] == NULL) continue; + if (val == NULL) continue; if (*type & ASL_QUERY_MATCH_SENDER) { @@ -1116,7 +1042,7 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) } *type |= ASL_QUERY_MATCH_SENDER; - out->sender = asl_memory_string_retain(s, q->val[i], 0); + out->sender = asl_memory_string_retain(s, val, 0); if (out->sender == NULL) { asl_memory_record_free(s, out); @@ -1124,9 +1050,29 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) return NULL; } } - else if (!strcmp(q->key[i], ASL_KEY_FACILITY)) + else if (!strcmp(key, ASL_KEY_SENDER_MACH_UUID)) { - if (q->val[i] == NULL) continue; + if (val == NULL) continue; + + if (*type & ASL_QUERY_MATCH_SMUUID) + { + asl_memory_record_free(s, out); + *type = ASL_QUERY_MATCH_SLOW; + return NULL; + } + + *type |= ASL_QUERY_MATCH_SMUUID; + out->sender = asl_memory_string_retain(s, val, 0); + if (out->sender_mach_uuid == NULL) + { + asl_memory_record_free(s, out); + *type = ASL_QUERY_MATCH_FALSE; + return NULL; + } + } + else if (!strcmp(key, ASL_KEY_FACILITY)) + { + if (val == NULL) continue; if (*type & ASL_QUERY_MATCH_FACILITY) { @@ -1136,7 +1082,7 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) } *type |= ASL_QUERY_MATCH_FACILITY; - out->facility = asl_memory_string_retain(s, q->val[i], 0); + out->facility = asl_memory_string_retain(s, val, 0); if (out->facility == NULL) { asl_memory_record_free(s, out); @@ -1144,9 +1090,9 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) return NULL; } } - else if (!strcmp(q->key[i], ASL_KEY_MSG)) + else if (!strcmp(key, ASL_KEY_MSG)) { - if (q->val[i] == NULL) continue; + if (val == NULL) continue; if (*type & ASL_QUERY_MATCH_MESSAGE) { @@ -1156,7 +1102,7 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) } *type |= ASL_QUERY_MATCH_MESSAGE; - out->message = asl_memory_string_retain(s, q->val[i], 0); + out->message = asl_memory_string_retain(s, val, 0); if (out->message == NULL) { asl_memory_record_free(s, out); @@ -1164,9 +1110,9 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) return NULL; } } - else if (!strcmp(q->key[i], ASL_KEY_REF_PROC)) + else if (!strcmp(key, ASL_KEY_REF_PROC)) { - if (q->val[i] == NULL) continue; + if (val == NULL) continue; if (*type & ASL_QUERY_MATCH_REF_PROC) { @@ -1176,7 +1122,7 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) } *type |= ASL_QUERY_MATCH_REF_PROC; - out->refproc = asl_memory_string_retain(s, q->val[i], 0); + out->refproc = asl_memory_string_retain(s, val, 0); if (out->refproc == NULL) { asl_memory_record_free(s, out); @@ -1184,9 +1130,9 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) return NULL; } } - else if (!strcmp(q->key[i], ASL_KEY_SESSION)) + else if (!strcmp(key, ASL_KEY_SESSION)) { - if (q->val[i] == NULL) continue; + if (val == NULL) continue; if (*type & ASL_QUERY_MATCH_SESSION) { @@ -1196,7 +1142,7 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) } *type |= ASL_QUERY_MATCH_SESSION; - out->session = asl_memory_string_retain(s, q->val[i], 0); + out->session = asl_memory_string_retain(s, val, 0); if (out->session == NULL) { asl_memory_record_free(s, out); @@ -1206,17 +1152,17 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) } else { - key = asl_memory_string_retain(s, q->key[i], 0); - if (key == NULL) + mkey = asl_memory_string_retain(s, key, 0); + if (mkey == NULL) { asl_memory_record_free(s, out); *type = ASL_QUERY_MATCH_FALSE; return NULL; } - for (j = 0; j < out->kvcount; j += 2) + for (i = 0; i < out->kvcount; i += 2) { - if (out->kvlist[j] == key) + if (out->kvlist[i] == mkey) { asl_memory_record_free(s, out); *type = ASL_QUERY_MATCH_SLOW; @@ -1224,7 +1170,7 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) } } - val = asl_memory_string_retain(s, q->val[i], 0); + mval = asl_memory_string_retain(s, val, 0); if (out->kvcount == 0) { @@ -1232,7 +1178,7 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) } else { - out->kvlist = (mem_string_t **)realloc(out->kvlist, (out->kvcount + 2) * sizeof(mem_string_t *)); + out->kvlist = (mem_string_t **)reallocf(out->kvlist, (out->kvcount + 2) * sizeof(mem_string_t *)); } if (out->kvlist == NULL) @@ -1242,8 +1188,8 @@ asl_memory_query_to_record(asl_memory_t *s, asl_msg_t *q, uint32_t *type) return NULL; } - out->kvlist[out->kvcount++] = key; - out->kvlist[out->kvcount++] = val; + out->kvlist[out->kvcount++] = mkey; + out->kvlist[out->kvcount++] = mval; } } @@ -1271,6 +1217,7 @@ asl_memory_fast_match(asl_memory_t *s, mem_record_t *r, uint32_t qtype, mem_reco if ((qtype & ASL_QUERY_MATCH_REF_PID) && (q->refpid != r->refpid)) return 0; if ((qtype & ASL_QUERY_MATCH_HOST) && (q->host != r->host)) return 0; if ((qtype & ASL_QUERY_MATCH_SENDER) && (q->sender != r->sender)) return 0; + if ((qtype & ASL_QUERY_MATCH_SMUUID) && (q->sender_mach_uuid != r->sender_mach_uuid)) return 0; if ((qtype & ASL_QUERY_MATCH_FACILITY) && (q->facility != r->facility)) return 0; if ((qtype & ASL_QUERY_MATCH_MESSAGE) && (q->message != r->message)) return 0; if ((qtype & ASL_QUERY_MATCH_REF_PROC) && (q->refproc != r->refproc)) return 0; @@ -1294,7 +1241,7 @@ asl_memory_fast_match(asl_memory_t *s, mem_record_t *r, uint32_t qtype, mem_reco } static uint32_t -asl_memory_slow_match(asl_memory_t *s, mem_record_t *r, mem_record_t *q, asl_msg_t *rawq) +asl_memory_slow_match(asl_memory_t *s, mem_record_t *r, asl_msg_t *rawq) { asl_msg_t *rawm; uint32_t status; @@ -1304,36 +1251,35 @@ asl_memory_slow_match(asl_memory_t *s, mem_record_t *r, mem_record_t *q, asl_msg if (status != ASL_STATUS_OK) return 0; status = 0; - if (asl_msg_cmp(rawq, rawm) != 0) status = 1; - asl_free(rawm); + if (asl_msg_cmp((asl_msg_t *)rawq, (asl_msg_t *)rawm) != 0) status = 1; + asl_msg_release(rawm); return status; } -uint32_t -asl_memory_match(asl_memory_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction, int32_t ruid, int32_t rgid) +static uint32_t +asl_memory_match_restricted_uuid_internal(asl_memory_t *s, asl_msg_list_t *query, asl_msg_list_t **res, uint64_t *last_id, uint64_t start_id, uint32_t count, uint32_t duration, int32_t direction, int32_t ruid, int32_t rgid, const char *uuid_str) { uint32_t status, i, where, start, j, do_match, did_match, rescount, *qtype; mem_record_t **qp; asl_msg_t *m; + size_t qcount; + struct timeval now, finish; - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (res == NULL) return ASL_STATUS_INVALID_ARG; - - do_match = 1; qp = NULL; qtype = NULL; rescount = 0; + qcount = asl_msg_list_count(query); - if ((query == NULL) || ((query != NULL) && (query->count == 0))) + if (qcount == 0) { do_match = 0; } else { - qp = (mem_record_t **)calloc(query->count, sizeof(mem_record_t *)); + qp = (mem_record_t **)calloc(qcount, sizeof(mem_record_t *)); if (qp == NULL) return ASL_STATUS_NO_MEMORY; - qtype = (uint32_t *)calloc(query->count, sizeof(uint32_t)); + qtype = (uint32_t *)calloc(qcount, sizeof(uint32_t)); if (qtype == NULL) { free(qp); @@ -1341,9 +1287,9 @@ asl_memory_match(asl_memory_t *s, aslresponse query, aslresponse *res, uint64_t } do_match = 0; - for (i = 0; i < query->count; i++) + for (i = 0; i < qcount; i++) { - qp[i] = asl_memory_query_to_record(s, query->msg[i], &(qtype[i])); + qp[i] = asl_memory_query_to_record(s, asl_msg_list_get_index(query, i), &(qtype[i])); if (qtype[i] == ASL_QUERY_MATCH_ERROR) { for (j = 0; j < i; j++) asl_memory_record_free(s, qp[j]); @@ -1372,7 +1318,38 @@ asl_memory_match(asl_memory_t *s, aslresponse query, aslresponse *res, uint64_t } } - if (i >= s->record_count) return ASL_STATUS_OK; + if (i >= s->record_count) + { + if (qp != NULL) + { + for (i = 0; i < qcount; i++) asl_memory_record_free(s, qp[i]); + free(qp); + free(qtype); + } + + return ASL_STATUS_OK; + } + + /* start the timer if a duration was specified */ + memset(&finish, 0, sizeof(struct timeval)); + if (duration != 0) + { + if (gettimeofday(&finish, NULL) == 0) + { + finish.tv_sec += (duration / USEC_PER_SEC); + finish.tv_usec += (duration % USEC_PER_SEC); + if (finish.tv_usec > USEC_PER_SEC) + { + finish.tv_usec -= USEC_PER_SEC; + finish.tv_sec += 1; + } + } + else + { + /* shouldn't happen, but if gettimeofday failed we just run without a timeout */ + memset(&finish, 0, sizeof(struct timeval)); + } + } start = where; @@ -1383,6 +1360,13 @@ asl_memory_match(asl_memory_t *s, aslresponse query, aslresponse *res, uint64_t { status = ASL_STATUS_INVALID_ID; if (s->record[where]->mid != 0) status = asl_core_check_access(s->record[where]->ruid, s->record[where]->rgid, ruid, rgid, s->record[where]->flags); + + if ((status == ASL_STATUS_OK) && (uuid_str != NULL)) + { + if (s->record[where]->sender_mach_uuid == NULL) status = ASL_STATUS_INVALID_ID; + else if (strcmp(s->record[where]->sender_mach_uuid->str, uuid_str) != 0) status = ASL_STATUS_INVALID_ID; + } + if (status != ASL_STATUS_OK) { if (direction >= 0) @@ -1408,15 +1392,19 @@ asl_memory_match(asl_memory_t *s, aslresponse query, aslresponse *res, uint64_t { did_match = 0; - for (j = 0; (j < query->count) && (did_match == 0); j++) + for (j = 0; (j < qcount) && (did_match == 0); j++) { if (qtype[j] == ASL_QUERY_MATCH_TRUE) { did_match = 1; } + else if (qtype[j] == ASL_QUERY_MATCH_FALSE) + { + did_match = 0; + } else if (qtype[j] == ASL_QUERY_MATCH_SLOW) { - did_match = asl_memory_slow_match(s, s->record[where], qp[j], query->msg[j]); + did_match = asl_memory_slow_match(s, s->record[where], asl_msg_list_get_index(query, j)); } else { @@ -1432,6 +1420,12 @@ asl_memory_match(asl_memory_t *s, aslresponse query, aslresponse *res, uint64_t if ((count != 0) && (rescount >= count)) break; } + /* check the timer */ + if ((finish.tv_sec != 0) && (gettimeofday(&now, NULL) == 0)) + { + if ((now.tv_sec > finish.tv_sec) || ((now.tv_sec == finish.tv_sec) && (now.tv_usec > finish.tv_usec))) break; + } + if (direction >= 0) { where++; @@ -1446,9 +1440,9 @@ asl_memory_match(asl_memory_t *s, aslresponse query, aslresponse *res, uint64_t if (where == s->record_first) break; } - if (query != NULL) + if (qp != NULL) { - for (i = 0; i < query->count; i++) asl_memory_record_free(s, qp[i]); + for (i = 0; i < qcount; i++) asl_memory_record_free(s, qp[i]); free(qp); free(qtype); } @@ -1456,22 +1450,14 @@ asl_memory_match(asl_memory_t *s, aslresponse query, aslresponse *res, uint64_t *res = NULL; if (rescount == 0) return ASL_STATUS_OK; - *res = (asl_msg_list_t *)calloc(1, sizeof(asl_msg_list_t)); + *res = asl_msg_list_new(); if (*res == NULL) return ASL_STATUS_NO_MEMORY; - (*res)->count = rescount; - - (*res)->msg = (asl_msg_t **)calloc(rescount, sizeof(asl_msg_t *)); - if ((*res)->msg == NULL) - { - free(*res); - *res = NULL; - return ASL_STATUS_NO_MEMORY; - } - where = start; forever { + int n = 0; + if (s->record[where]->flags & ASL_MSG_FLAG_SEARCH_MATCH) { s->record[where]->flags &= ASL_MSG_FLAG_SEARCH_CLEAR; @@ -1479,13 +1465,15 @@ asl_memory_match(asl_memory_t *s, aslresponse query, aslresponse *res, uint64_t status = asl_memory_message_decode(s, s->record[where], &m); if (status != ASL_STATUS_OK) { - aslresponse_free(*res); + asl_msg_list_release(*res); *res = NULL; return status; } - (*res)->msg[(*res)->curr++] = m; - if ((*res)->curr == rescount) break; + asl_msg_list_append(*res, m); + asl_msg_release(m); + n++; + if (n == rescount) break; } if (direction >= 0) @@ -1502,6 +1490,35 @@ asl_memory_match(asl_memory_t *s, aslresponse query, aslresponse *res, uint64_t if (where == s->record_first) break; } - (*res)->curr = 0; return ASL_STATUS_OK; } + +uint32_t +asl_memory_match_restricted_uuid(asl_memory_t *s, asl_msg_list_t *query, asl_msg_list_t **res, uint64_t *last_id, uint64_t start_id, uint32_t count, uint32_t duration, int32_t direction, int32_t ruid, int32_t rgid, const char *uuid_str) +{ + __block uint32_t status; + + if (s == NULL) return ASL_STATUS_INVALID_STORE; + if (res == NULL) return ASL_STATUS_INVALID_ARG; + + dispatch_sync(s->queue, ^{ + status = asl_memory_match_restricted_uuid_internal(s, query, res, last_id, start_id, count, duration, direction, ruid, rgid, uuid_str); + }); + + return status; +} + +uint32_t +asl_memory_match(asl_memory_t *s, asl_msg_list_t *query, asl_msg_list_t **res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction, int32_t ruid, int32_t rgid) +{ + __block uint32_t status; + + if (s == NULL) return ASL_STATUS_INVALID_STORE; + if (res == NULL) return ASL_STATUS_INVALID_ARG; + + dispatch_sync(s->queue, ^{ + status = asl_memory_match_restricted_uuid_internal(s, query, res, last_id, start_id, count, 0, direction, ruid, rgid, NULL); + }); + + return status; +}