2 * Copyright (C) 1995, 1997-1999 Jeffrey A. Uphoff
3 * Modified by Olaf Kirch, 1996.
4 * Modified by H.J. Lu, 1998.
5 * Modified by Lon Hohberger, Oct. 2000.
6 * - Fixed memory leaks, run-off-end problems, etc.
12 * Simple list management for notify list
27 * LH - The linked list code had some bugs. Used this to help debug
31 plist(notify_list *head, int en)
33 /* case where we ran off the end */
36 printf("Entry %d: %s\n",en, NL_MON_NAME(head));
37 plist(head->next, ++en);
41 nlist_print(notify_list **head)
43 printf("--- Begin notify list dump ---\n");
45 printf("--- End notify list dump ---\n");
50 * Allocate memory and set up a new notify list entry.
53 nlist_new(char *my_name, char *mon_name, int state)
57 if (!(new = (notify_list *) xmalloc(sizeof(notify_list))))
59 memset(new, 0, sizeof(*new));
61 NL_TIMES(new) = MAX_TRIES;
62 NL_STATE(new) = state;
63 if (!(NL_MY_NAME(new) = xstrdup(my_name))
64 || !(NL_MON_NAME(new) = xstrdup(mon_name))) {
66 free(NL_MY_NAME(new));
75 * Insert *entry into a notify list at the point specified by
76 * **head. This can be in the middle. However, we do not handle
77 * list _append_ in this function; rather, the only place we should
78 * have to worry about this case is in nlist_insert_timer below.
79 * - entry must not be NULL.
82 nlist_insert(notify_list **head, notify_list *entry)
86 * Cases where we're prepending a non-empty list
87 * or inserting possibly in the middle somewhere (eg,
88 * nlist_insert_timer...)
90 entry->next = (*head); /* Forward pointer */
91 entry->prev = (*head)->prev; /* Back pointer */
92 (*head)->prev = entry; /* head's new back pointer */
95 /* Common to all cases, including new list creation */
96 *head = entry; /* New head */
104 * (re)insert *entry into notify_list **head. This requires that
105 * NL_WHEN(entry) has been set (usually, this is time() + 5 seconds).
106 * - entry must not be NULL
108 * LH - This used to cause (a) a memory leak and (b) dropped notify-list
109 * entries. The pointer ran off the end of the list, and changed the
110 * head-end to point to the new, one-entry list. All other entries became garbage.
112 * FIXME: Optimize this function. (I'll work on it - LH)
115 nlist_insert_timer(notify_list **head, notify_list *entry)
117 notify_list *spot = *head, /* Insertion location */
118 /* ...Start at head */
119 *back = NULL; /* Back pointer */
122 /* Find first entry with higher timeout value or end of list */
123 while (spot && NL_WHEN(spot) <= NL_WHEN(entry)) {
125 * Keep the back pointer in case we
126 * run off the end... (see below)
132 if (spot == (*head)) {
134 * case where we're prepending an empty or non-empty
135 * list or inserting in the middle somewhere. Pass
136 * the real head of the list, since we'll be changing
137 * during the insert...
139 nlist_insert(head, entry);
141 /* all other cases - don't move the real head pointer */
142 nlist_insert(&spot, entry);
145 * If spot == entry, then spot was NULL when we called
146 * nlist_insert. This happened because we had run off
147 * the end of the list. Append entry to original list.
157 * Remove *entry from the list pointed to by **head.
158 * Do not destroy *entry. This is normally done before
159 * a re-insertion with a timer, but can be done anywhere.
160 * - entry must not be NULL.
163 nlist_remove(notify_list **head, notify_list *entry)
165 notify_list *prev = entry->prev,
173 /* Case(s) where entry isn't at the front */
176 /* cases where entry is at the front */
180 entry->next = entry->prev = NULL;
187 * Clone an entry in the notify list -
188 * - entry must not be NULL
191 nlist_clone(notify_list *entry)
195 new = nlist_new(NL_MY_NAME(entry), NL_MON_NAME(entry), NL_STATE(entry));
196 NL_MY_PROG(new) = NL_MY_PROG(entry);
197 NL_MY_VERS(new) = NL_MY_VERS(entry);
198 NL_MY_PROC(new) = NL_MY_PROC(entry);
199 NL_ADDR(new) = NL_ADDR(entry);
200 memcpy(NL_PRIV(new), NL_PRIV(entry), SM_PRIV_SIZE);
206 * Destroy an entry in a notify list and free the memory.
207 * If *head is NULL, just free the entry. This would be
208 * done only when we know entry isn't in any list.
209 * - entry must not be NULL.
212 nlist_free(notify_list **head, notify_list *entry)
215 nlist_remove(head, entry);
216 if (NL_MY_NAME(entry))
217 free(NL_MY_NAME(entry));
218 if (NL_MON_NAME(entry))
219 free(NL_MON_NAME(entry));
224 * Destroy an entire notify list
227 nlist_kill(notify_list **head)
230 nlist_free(head, *head);
234 * Walk a list looking for a matching name in the NL_MON_NAME field.
237 nlist_gethost(notify_list *list, char *host, int myname)
241 for (lp = list; lp; lp = lp->next) {
242 if (matchhostname(host, myname? NL_MY_NAME(lp) : NL_MON_NAME(lp)))
246 return (notify_list *) NULL;