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 new = (notify_list
*) xmalloc(sizeof(notify_list
));
58 memset(new, 0, sizeof(*new));
60 NL_TIMES(new) = MAX_TRIES
;
61 NL_STATE(new) = state
;
62 NL_MY_NAME(new) = xstrdup(my_name
);
63 NL_MON_NAME(new) = xstrdup(mon_name
);
69 * Insert *entry into a notify list at the point specified by
70 * **head. This can be in the middle. However, we do not handle
71 * list _append_ in this function; rather, the only place we should
72 * have to worry about this case is in nlist_insert_timer below.
73 * - entry must not be NULL.
76 nlist_insert(notify_list
**head
, notify_list
*entry
)
80 * Cases where we're prepending a non-empty list
81 * or inserting possibly in the middle somewhere (eg,
82 * nlist_insert_timer...)
84 entry
->next
= (*head
); /* Forward pointer */
85 entry
->prev
= (*head
)->prev
; /* Back pointer */
86 (*head
)->prev
= entry
; /* head's new back pointer */
89 /* Common to all cases, including new list creation */
90 *head
= entry
; /* New head */
98 * (re)insert *entry into notify_list **head. This requires that
99 * NL_WHEN(entry) has been set (usually, this is time() + 5 seconds).
100 * - entry must not be NULL
102 * LH - This used to cause (a) a memory leak and (b) dropped notify-list
103 * entries. The pointer ran off the end of the list, and changed the
104 * head-end to point to the new, one-entry list. All other entries became garbage.
106 * FIXME: Optimize this function. (I'll work on it - LH)
109 nlist_insert_timer(notify_list
**head
, notify_list
*entry
)
111 notify_list
*spot
= *head
, /* Insertion location */
112 /* ...Start at head */
113 *back
= NULL
; /* Back pointer */
116 /* Find first entry with higher timeout value or end of list */
117 while (spot
&& NL_WHEN(spot
) <= NL_WHEN(entry
)) {
119 * Keep the back pointer in case we
120 * run off the end... (see below)
126 if (spot
== (*head
)) {
128 * case where we're prepending an empty or non-empty
129 * list or inserting in the middle somewhere. Pass
130 * the real head of the list, since we'll be changing
131 * during the insert...
133 nlist_insert(head
, entry
);
135 /* all other cases - don't move the real head pointer */
136 nlist_insert(&spot
, entry
);
139 * If spot == entry, then spot was NULL when we called
140 * nlist_insert. This happened because we had run off
141 * the end of the list. Append entry to original list.
151 * Remove *entry from the list pointed to by **head.
152 * Do not destroy *entry. This is normally done before
153 * a re-insertion with a timer, but can be done anywhere.
154 * - entry must not be NULL.
157 nlist_remove(notify_list
**head
, notify_list
*entry
)
159 notify_list
*prev
= entry
->prev
,
167 /* Case(s) where entry isn't at the front */
170 /* cases where entry is at the front */
174 entry
->next
= entry
->prev
= NULL
;
181 * Clone an entry in the notify list -
182 * - entry must not be NULL
185 nlist_clone(notify_list
*entry
)
189 new = nlist_new(NL_MY_NAME(entry
), NL_MON_NAME(entry
), NL_STATE(entry
));
190 NL_MY_PROG(new) = NL_MY_PROG(entry
);
191 NL_MY_VERS(new) = NL_MY_VERS(entry
);
192 NL_MY_PROC(new) = NL_MY_PROC(entry
);
193 NL_ADDR(new) = NL_ADDR(entry
);
194 memcpy(NL_PRIV(new), NL_PRIV(entry
), SM_PRIV_SIZE
);
200 * Destroy an entry in a notify list and free the memory.
201 * If *head is NULL, just free the entry. This would be
202 * done only when we know entry isn't in any list.
203 * - entry must not be NULL.
206 nlist_free(notify_list
**head
, notify_list
*entry
)
209 nlist_remove(head
, entry
);
210 if (NL_MY_NAME(entry
))
211 free(NL_MY_NAME(entry
));
212 if (NL_MON_NAME(entry
))
213 free(NL_MON_NAME(entry
));
214 free(entry
->dns_name
);
219 * Destroy an entire notify list
222 nlist_kill(notify_list
**head
)
225 nlist_free(head
, *head
);
229 * Walk a list looking for a matching name in the NL_MON_NAME field.
232 nlist_gethost(notify_list
*list
, char *host
, int myname
)
236 for (lp
= list
; lp
; lp
= lp
->next
) {
237 if (matchhostname(host
, myname
? NL_MY_NAME(lp
) : NL_MON_NAME(lp
)))
241 return (notify_list
*) NULL
;