// This function adds a new record to an existing linked list
// or creates a new one if its a new event
int lol_add_record(lol *lo, char *buff)
{
	int i;
	lnode n;
	event e;
	char *ptr;
	llist *l;

	// Short circuit if event is not of interest
	if (extract_timestamp(buff, &e) == 0)
		return 0;

	ptr = strrchr(buff, 0x0a);
	if (ptr)
		*ptr = 0;
	n.message=strdup(buff);
	n.type = e.type;

	// Now see where this belongs
	for (i=0; i<=lo->maxi; i++) {
		if (lo->array[i].status == L_BUILDING) {
			l = lo->array[i].l;
			if (events_are_equal(&l->e, &e)) {
				free((char *)e.node);
				list_append(l, &n);
				return 1;
			}
		}
	}
	// Create new event and fill it in
	l = malloc(sizeof(llist));
	list_create(l);
	l->e.milli = e.milli;
	l->e.sec = e.sec;
	l->e.serial = e.serial;
	l->e.node = e.node;
	l->e.type = e.type;
	list_append(l, &n);
	lol_append(lo, l);
	check_events(lo,  e.sec);
	return 1;
}
/*
 * au_auparse_next_event - Get the next complete event
 * Args:
 * 	au - the parser state machine
 * Rtns:
 *	< 0	- error
 *	== 0	- no data
 *	> 0	- we have an event and it's set to the 'current event' au->le
 */
static int au_auparse_next_event(auparse_state_t *au)
{
	int rc, i, built;
	event_list_t *l;
	au_event_t e;

	/*
	 * Deal with Python memory management issues where it issues a
	 * auparse_destroy() call after an auparse_init() call but then wants
	 * to still work with auparse data. Basically, we assume if the user
	 * wants to parse for events (calling auparse_next_event()) we accept
	 * that they expect the memory structures to exist. This is a bit
	 * 'disconcerting' but the au_lol capability is a patch trying to
	 * redress a singleton approach to event processing.
	 */
	if (au->au_lo->array == NULL && au->au_lo->maxi == -1) {
#ifdef	LOL_EVENTS_DEBUG01
		if (debug) printf("Creating lol array\n");
#endif	/* LOL_EVENTS_DEBUG01 */
		au_lol_create(au->au_lo);
	}	

	/*
	 * First see if we have any empty events but with an allocated event
	 * list. These would have just been processed, so we can free them
	 */
	for (i = 0; i <= au->au_lo->maxi; i++) {
		au_lolnode *cur = &au->au_lo->array[i];
		if (cur->status == EBS_EMPTY && cur->l) {
#ifdef	LOL_EVENTS_DEBUG01
			if (debug) {printf("Freeing at start "); print_list_t(cur->l);}
#endif	/* LOL_EVENTS_DEBUG01 */
			aup_list_clear(cur->l);
			free(cur->l);
			au->le = NULL;	// this should crash any usage
					// of au->le until reset
			cur->l = NULL;
		}
	}
	/*
	 * Now see if we have completed events queued, and if so grab the
	 * first one and set it to be the 'current' event of interest
	 */
	if ((l = au_get_ready_event(au, 0)) != NULL) {
		rnode *r;

		aup_list_first(l);
		r = aup_list_get_cur(l);
		free_interpretation_list();
		load_interpretation_list(r->interp);
		aup_list_first_field(l);
		au->le = l;
#ifdef	LOL_EVENTS_DEBUG01
		if (debug) print_lol("upfront", au->au_lo);
#endif	/* LOL_EVENTS_DEBUG01 */
		return 1;
	}
	/*
	 * If no complete events are available, lets ingest
	 */
	while (1) {
		for (i = 0; i <= au->au_lo->maxi; i++) {
			au_lolnode *cur = &au->au_lo->array[i];
			if (cur->status == EBS_EMPTY && cur->l) {
#ifdef	LOL_EVENTS_DEBUG01
				if (debug) {printf("Freeing at loop"); print_list_t(cur->l);}
#endif	/* LOL_EVENTS_DEBUG01 */
				aup_list_clear(cur->l);
				free(cur->l);
				au->le = NULL;	/* this should crash any usage of au->le until reset */
				cur->l = NULL;
			}
		}
		rc = retrieve_next_line(au);
#ifdef	LOL_EVENTS_DEBUG01
		if (debug) printf("next_line(%d) '%s'\n", rc, au->cur_buf);
#endif	/* LOL_EVENTS_DEBUG01 */
		if (rc == 0) {
#ifdef	LOL_EVENTS_DEBUG01
			if (debug) printf("Empty line\n");
#endif	/* LOL_EVENTS_DEBUG01 */
			return 0;	/* NO data now */
		}
		if (rc == -2) {
			/*
			 * We are at EOF, so see if we have any accumulated
			 * events.
			 */
#ifdef	LOL_EVENTS_DEBUG01
			if (debug) printf("EOF\n");
#endif	/* LOL_EVENTS_DEBUG01 */
			au_terminate_all_events(au);
			if ((l = au_get_ready_event(au, 0)) != NULL) {
				rnode *r;

				aup_list_first(l);
				r = aup_list_get_cur(l);
				free_interpretation_list();
				load_interpretation_list(r->interp);
				aup_list_first_field(l);
				au->le = l;
#ifdef	LOL_EVENTS_DEBUG01
				if (debug) print_lol("eof termination",au->au_lo);
#endif	/* LOL_EVENTS_DEBUG01 */
				return 1;
			}
			return 0;
		} else if (rc < 0) {
#ifdef	LOL_EVENTS_DEBUG01
			/* Straight error */
			if (debug) printf("Error %d\n", rc);
#endif	/* LOL_EVENTS_DEBUG01 */
			return -1;
		}
		/* So we got a successful read ie rc > 0 */
		if (extract_timestamp(au->cur_buf, &e)) {
#ifdef	LOL_EVENTS_DEBUG01
			if (debug) printf("Malformed line:%s\n", au->cur_buf);
#endif	/* LOL_EVENTS_DEBUG01 */
			continue;
		}

		/*
		 * Is this an event we have already been building?
		 */
		built = 0;
		for (i = 0; i <= au->au_lo->maxi; i++) {
			au_lolnode *cur = &au->au_lo->array[i];
			if (cur->status == EBS_BUILDING) {
				if (events_are_equal(&cur->l->e, &e)) {
#ifdef	LOL_EVENTS_DEBUG01
					if (debug) printf("Adding event to building event\n");
#endif	/* LOL_EVENTS_DEBUG01 */
					aup_list_append(cur->l, au->cur_buf,
						au->list_idx, au->line_number);
					au->cur_buf = NULL;
					free((char *)e.host);
					au_check_events(au,  e.sec);
#ifdef	LOL_EVENTS_DEBUG01
					if (debug) print_lol("building",au->au_lo);
#endif	/* LOL_EVENTS_DEBUG01 */
					/* we built something, so break out */
					built++;
					break;
				}
			}
		}
		if (built)
			continue;

		/* So create one */
#ifdef	LOL_EVENTS_DEBUG01
		if (debug) printf("First record in new event, initialize event\n");
#endif	/* LOL_EVENTS_DEBUG01 */
		if ((l=(event_list_t *)malloc(sizeof(event_list_t))) == NULL) {
			free((char *)e.host);
			return -1;
		}
		aup_list_create(l);
		aup_list_set_event(l, &e);
		aup_list_append(l, au->cur_buf, au->list_idx, au->line_number);
		if (au_lol_append(au->au_lo, l) == NULL) {
			free((char *)e.host);
#ifdef	LOL_EVENTS_DEBUG01
			if (debug) printf("error appending to lol\n");
#endif	/* LOL_EVENTS_DEBUG01 */
			return -1;
		}
		au->cur_buf = NULL;
		free((char *)e.host);
		au_check_events(au,  e.sec);
		if ((l = au_get_ready_event(au, 0)) != NULL) {
			rnode *r;

			aup_list_first(l);
			r = aup_list_get_cur(l);
			free_interpretation_list();
			load_interpretation_list(r->interp);
			aup_list_first_field(l);
			au->le = l;
#ifdef	LOL_EVENTS_DEBUG01
			if (debug) print_lol("basic", au->au_lo);
#endif	/* LOL_EVENTS_DEBUG01 */
			return 1;
		}
	}
}