/*
- * Copyright (c) 2007-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2007-2010 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* @APPLE_LICENSE_HEADER_END@
*/
-#include <asl_core.h>
-#include <asl_memory.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
+#include <asl_core.h>
+#include <asl_msg.h>
+#include <asl_msg_list.h>
#include <asl_private.h>
+#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];
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);
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;
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);
}
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;
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;
}
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
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--;
}
}
else
{
- ms = (mem_string_t *)s->string_cache[mid];
+ ms = s->string_cache[mid];
if (hash < ms->hash) top = mid;
else bot = mid;
}
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;
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;
/* 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];
}
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];
}
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;
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)
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;
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);
}
/*
- * 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));
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 (msg->val[i] != NULL) r->time = asl_parse_time(msg->val[i]);
+ if (val != NULL) r->time = asl_core_parse_time(val, NULL);
}
- else if (!strcmp(msg->key[i], ASL_KEY_TIME_NSEC))
+ else if (!strcmp(key, ASL_KEY_TIME_NSEC))
{
- if (msg->val[i] != NULL) r->nano = atoi(msg->val[i]);
+ if (val != NULL) r->nano = atoi(val);
}
- else if (!strcmp(msg->key[i], ASL_KEY_HOST))
+ else if (!strcmp(key, ASL_KEY_HOST))
{
- if (msg->val[i] != NULL) r->host = asl_memory_string_retain(s, msg->val[i], 1);
+ if (val != NULL) r->host = asl_memory_string_retain(s, val, 1);
}
- else if (!strcmp(msg->key[i], ASL_KEY_SENDER))
+ else if (!strcmp(key, ASL_KEY_SENDER))
{
- if (msg->val[i] != NULL) r->sender = 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_PID))
+ else if (!strcmp(key, ASL_KEY_PID))
{
- if (msg->val[i] != NULL) r->pid = atoi(msg->val[i]);
+ if (val != NULL) r->pid = atoi(val);
}
- else if (!strcmp(msg->key[i], ASL_KEY_REF_PID))
+ else if (!strcmp(key, ASL_KEY_REF_PID))
{
- if (msg->val[i] != NULL) r->refpid = atoi(msg->val[i]);
+ if (val != NULL) r->refpid = atoi(val);
}
- else if (!strcmp(msg->key[i], ASL_KEY_UID))
+ else if (!strcmp(key, ASL_KEY_UID))
{
- if (msg->val[i] != NULL) r->uid = atoi(msg->val[i]);
+ if (val != NULL) r->uid = atoi(val);
}
- else if (!strcmp(msg->key[i], ASL_KEY_GID))
+ else if (!strcmp(key, ASL_KEY_GID))
{
- if (msg->val[i] != NULL) r->gid = atoi(msg->val[i]);
+ if (val != NULL) r->gid = atoi(val);
}
- else if (!strcmp(msg->key[i], ASL_KEY_LEVEL))
+ else if (!strcmp(key, ASL_KEY_LEVEL))
{
- if (msg->val[i] != NULL) r->level = atoi(msg->val[i]);
+ if (val != NULL) r->level = atoi(val);
}
- else if (!strcmp(msg->key[i], ASL_KEY_MSG))
+ else if (!strcmp(key, ASL_KEY_MSG))
{
- if (msg->val[i] != NULL) r->message = asl_memory_string_retain(s, msg->val[i], 1);
+ if (val != NULL) r->message = asl_memory_string_retain(s, val, 1);
}
- else if (!strcmp(msg->key[i], ASL_KEY_FACILITY))
+ else if (!strcmp(key, ASL_KEY_SENDER_MACH_UUID))
{
- if (msg->val[i] != NULL) r->facility = 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_REF_PROC))
+ else if (!strcmp(key, ASL_KEY_FACILITY))
{
- if (msg->val[i] != NULL) r->refproc = 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_SESSION))
+ else if (!strcmp(key, ASL_KEY_REF_PROC))
{
- if (msg->val[i] != NULL) r->session = 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_READ_UID))
+ else if (!strcmp(key, ASL_KEY_SESSION))
{
- if (((r->flags & ASL_MSG_FLAG_READ_UID_SET) == 0) && (msg->val[i] != NULL))
+ if (val != NULL) r->session = asl_memory_string_retain(s, val, 1);
+ }
+ else if (!strcmp(key, ASL_KEY_READ_UID))
+ {
+ 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);
}
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);
-
- /* 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;
+ dispatch_sync(s->queue, ^{
+ mem_record_t *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;
}
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;
*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;
}
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;
/* 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));
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)
{
}
*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)
{
}
*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)
{
}
*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)
{
}
*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)
{
}
*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)
{
}
*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)
{
}
*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)
{
}
*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)
{
}
*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)
{
}
*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)
{
}
*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);
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)
{
}
*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);
return NULL;
}
}
- else if (!strcmp(q->key[i], ASL_KEY_FACILITY))
+ else if (!strcmp(key, ASL_KEY_SENDER_MACH_UUID))
+ {
+ 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 (q->val[i] == NULL) continue;
+ if (val == NULL) continue;
if (*type & ASL_QUERY_MATCH_FACILITY)
{
}
*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);
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)
{
}
*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);
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)
{
}
*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);
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)
{
}
*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);
}
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;
}
}
- val = asl_memory_string_retain(s, q->val[i], 0);
+ mval = asl_memory_string_retain(s, val, 0);
if (out->kvcount == 0)
{
}
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)
return NULL;
}
- out->kvlist[out->kvcount++] = key;
- out->kvlist[out->kvcount++] = val;
+ out->kvlist[out->kvcount++] = mkey;
+ out->kvlist[out->kvcount++] = mval;
}
}
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;
}
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;
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);
}
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]);
{
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);
}
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;
/*
{
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)
{
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
{
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++;
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);
}
*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;
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)
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;
+}