/*
 * Copyright (C) 1995, 1997-1999 Jeffrey A. Uphoff
 * Modified by Olaf Kirch, 1996.
 * Modified by H.J. Lu, 1998.
 * Modified by Lon Hohberger, Oct. 2000.
 *   - Fixed memory leaks, run-off-end problems, etc.
 *
 * NSM for Linux.
 */

/*
 * Simple list management for notify list
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <string.h>
#include "statd.h"
#include "notlist.h"


#ifdef DEBUG
/* 
 * LH - The linked list code had some bugs.  Used this to help debug
 * new code. 
 */
static void 
plist(notify_list *head, int en)
{
	/* case where we ran off the end */
	if (!head) return;

	printf("Entry %d: %s\n",en, NL_MON_NAME(head));
	plist(head->next, ++en);
}

static void 
nlist_print(notify_list **head)
{
	printf("--- Begin notify list dump ---\n");
	plist(*head,1);
	printf("--- End notify list dump ---\n");
}
#endif /* DEBUG */

/* 
 * Allocate memory and set up a new notify list entry.
 */
notify_list * 
nlist_new(char *my_name, char *mon_name, int state)
{
	notify_list	*new;

	new = (notify_list *) xmalloc(sizeof(notify_list));
	memset(new, 0, sizeof(*new));

	NL_TIMES(new) = MAX_TRIES;
	NL_STATE(new) = state;
	NL_MY_NAME(new) = xstrdup(my_name);
	NL_MON_NAME(new) = xstrdup(mon_name);

	return new;
}

/*
 * Insert *entry into a notify list at the point specified by
 * **head.  This can be in the middle.  However, we do not handle
 * list _append_ in this function; rather, the only place we should
 * have to worry about this case is in nlist_insert_timer below.
 * - entry must not be NULL.
 */
void 
nlist_insert(notify_list **head, notify_list *entry)
{
	if (*head) {
		/* 
		 * Cases where we're prepending a non-empty list
		 * or inserting possibly in the middle somewhere (eg,
		 * nlist_insert_timer...)
		 */
		entry->next = (*head);		/* Forward pointer */
		entry->prev = (*head)->prev;	/* Back pointer */
		(*head)->prev = entry;		/* head's new back pointer */
	}

	/* Common to all cases, including new list creation */
	*head = entry;			/* New head */

#ifdef DEBUG
	nlist_print(head);
#endif
}

/* 
 * (re)insert *entry into notify_list **head.  This requires that
 * NL_WHEN(entry) has been set (usually, this is time() + 5 seconds).
 * - entry must not be NULL
 *
 * LH - This used to cause (a) a memory leak and (b) dropped notify-list
 * entries.  The pointer ran off the end of the list, and changed the 
 * head-end to point to the new, one-entry list.  All other entries became garbage.
 *
 * FIXME: Optimize this function. (I'll work on it - LH)
 */
void 
nlist_insert_timer(notify_list **head, notify_list *entry)
{
	notify_list 	*spot = *head,	 	/* Insertion location */
						/* ...Start at head */
			*back = NULL;		/* Back pointer */


	/* Find first entry with higher timeout value or end of list */
	while (spot && NL_WHEN(spot) <= NL_WHEN(entry)) {
		/* 
		 * Keep the back pointer in case we 
		 * run off the end...  (see below)
		 */
		back = spot;
		spot = spot->next;
	}

	if (spot == (*head)) {
		/* 
		 * case where we're prepending an empty or non-empty
		 * list or inserting in the middle somewhere.  Pass 
		 * the real head of the list, since we'll be changing 
		 * during the insert... 
		 */
		nlist_insert(head, entry);
	} else {
		/* all other cases - don't move the real head pointer */
		nlist_insert(&spot, entry);

		/* 
		 * If spot == entry, then spot was NULL when we called
		 * nlist_insert.  This happened because we had run off 
		 * the end of the list.  Append entry to original list.
		 */
		if (spot == entry) {
			back->next = entry;
			entry->prev = back;
		}
	}
}

/* 
 * Remove *entry from the list pointed to by **head.
 * Do not destroy *entry.  This is normally done before
 * a re-insertion with a timer, but can be done anywhere.
 * - entry must not be NULL.
 */
void 
nlist_remove(notify_list **head, notify_list *entry)
{
	notify_list	*prev = entry->prev,
			*next = entry->next;

	if (next) {
		next->prev = prev;
	}

	if (prev) {
		/* Case(s) where entry isn't at the front */
		prev->next = next; 
	} else {
		/* cases where entry is at the front */
		*head = next;
	}

	entry->next = entry->prev = NULL;
#ifdef DEBUG
	nlist_print(head);
#endif
}

/* 
 * Clone an entry in the notify list -
 * - entry must not be NULL
 */
notify_list *
nlist_clone(notify_list *entry)
{
	notify_list	*new;

	new = nlist_new(NL_MY_NAME(entry), NL_MON_NAME(entry), NL_STATE(entry));
	NL_MY_PROG(new) = NL_MY_PROG(entry);
	NL_MY_VERS(new) = NL_MY_VERS(entry);
	NL_MY_PROC(new) = NL_MY_PROC(entry);
	memcpy(NL_PRIV(new), NL_PRIV(entry), SM_PRIV_SIZE);

	return new;
}

/* 
 * Destroy an entry in a notify list and free the memory.
 * If *head is NULL, just free the entry.  This would be
 * done only when we know entry isn't in any list.
 * - entry must not be NULL.
 */
void 
nlist_free(notify_list **head, notify_list *entry)
{
	if (head && (*head))
		nlist_remove(head, entry);
	if (NL_MY_NAME(entry))
		free(NL_MY_NAME(entry));
	if (NL_MON_NAME(entry))
		free(NL_MON_NAME(entry));
	free(entry->dns_name);
	free(entry);
}

/* 
 * Destroy an entire notify list 
 */
void 
nlist_kill(notify_list **head)
{
	while (*head)
		nlist_free(head, *head);
}

/*
 * Walk a list looking for a matching name in the NL_MON_NAME field.
 */
notify_list *
nlist_gethost(notify_list *list, char *host, int myname)
{
	notify_list	*lp;

	for (lp = list; lp; lp = lp->next) {
		if (statd_matchhostname(host,
				myname? NL_MY_NAME(lp) : NL_MON_NAME(lp)))
			return lp;
	}

	return (notify_list *) NULL;
}
