Make setthetime() static per the prototype.
[dragonfly.git] / contrib / isc-dhcp / common / dispatch.c
1 /* dispatch.c
2
3    Network input dispatcher... */
4
5 /*
6  * Copyright (c) 1995-2002 Internet Software Consortium.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of The Internet Software Consortium nor the names
19  *    of its contributors may be used to endorse or promote products derived
20  *    from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
23  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
27  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  * This software has been written for the Internet Software Consortium
37  * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
38  * To learn more about the Internet Software Consortium, see
39  * ``http://www.isc.org/''.  To learn more about Vixie Enterprises,
40  * see ``http://www.vix.com''.   To learn more about Nominum, Inc., see
41  * ``http://www.nominum.com''.
42  *
43  * $Id: dispatch.c,v 1.63.2.3 2002/11/17 02:26:57 dhankins Exp $ Copyright (c) 1995-2002 The Internet Software Consortium.  All rights reserved.
44  * $FreeBSD: src/contrib/isc-dhcp/common/dispatch.c,v 1.4 2003/08/10 22:01:37 mbr Exp $
45  * $DragonFly: src/contrib/isc-dhcp/common/Attic/dispatch.c,v 1.2 2003/10/11 21:14:17 dillon Exp $
46  */
47
48
49 #include "dhcpd.h"
50
51 struct timeout *timeouts;
52 static struct timeout *free_timeouts;
53
54 #ifdef ENABLE_POLLING_MODE
55 extern int polling_interval;
56 #endif
57
58 void set_time (u_int32_t t)
59 {
60         /* Do any outstanding timeouts. */
61         if (cur_time != t) {
62                 cur_time = t;
63                 process_outstanding_timeouts ((struct timeval *)0);
64         }
65 }
66
67 struct timeval *process_outstanding_timeouts (struct timeval *tvp)
68 {
69         /* Call any expired timeouts, and then if there's
70            still a timeout registered, time out the select
71            call then. */
72       another:
73         if (timeouts) {
74                 struct timeout *t;
75                 if (timeouts -> when <= cur_time) {
76                         t = timeouts;
77                         timeouts = timeouts -> next;
78                         (*(t -> func)) (t -> what);
79                         if (t -> unref)
80                                 (*t -> unref) (&t -> what, MDL);
81                         t -> next = free_timeouts;
82                         free_timeouts = t;
83                         goto another;
84                 }
85                 if (tvp) {
86                         tvp -> tv_sec = timeouts -> when;
87                         tvp -> tv_usec = 0;
88                 }
89                 return tvp;
90         } else
91                 return (struct timeval *)0;
92 }
93
94 /* Wait for packets to come in using select().   When one does, call
95    receive_packet to receive the packet and possibly strip hardware
96    addressing information from it, and then call through the
97    bootp_packet_handler hook to try to do something with it. */
98
99 void dispatch ()
100 {
101         struct timeval tv, *tvp;
102 #ifdef ENABLE_POLLING_MODE
103         struct timeval *tvp_new;
104 #endif
105         isc_result_t status;
106         TIME cur_time;
107
108         tvp = NULL;
109 #ifdef ENABLE_POLLING_MODE
110         tvp_new = NULL;
111 #endif
112         /* Wait for a packet or a timeout... XXX */
113         do {
114                 tvp = process_outstanding_timeouts (&tv);
115 #ifdef ENABLE_POLLING_MODE
116                 GET_TIME (&cur_time);
117                 add_timeout(cur_time + polling_interval, state_polling, 0, 0, 0);
118                 tvp_new = process_outstanding_timeouts(&tv);
119                 if (tvp != NULL && (tvp -> tv_sec > tvp_new -> tv_sec))
120                         tvp = tvp_new;
121 #endif /* ENABLE_POLLING_MODE */
122                 status = omapi_one_dispatch (0, tvp);
123         } while (status == ISC_R_TIMEDOUT || status == ISC_R_SUCCESS);
124         log_fatal ("omapi_one_dispatch failed: %s -- exiting.",
125                    isc_result_totext (status));
126 }
127
128 void add_timeout (when, where, what, ref, unref)
129         TIME when;
130         void (*where) PROTO ((void *));
131         void *what;
132         tvref_t ref;
133         tvunref_t unref;
134 {
135         struct timeout *t, *q;
136
137         /* See if this timeout supersedes an existing timeout. */
138         t = (struct timeout *)0;
139         for (q = timeouts; q; q = q -> next) {
140                 if ((where == NULL || q -> func == where) &&
141                     q -> what == what) {
142                         if (t)
143                                 t -> next = q -> next;
144                         else
145                                 timeouts = q -> next;
146                         break;
147                 }
148                 t = q;
149         }
150
151         /* If we didn't supersede a timeout, allocate a timeout
152            structure now. */
153         if (!q) {
154                 if (free_timeouts) {
155                         q = free_timeouts;
156                         free_timeouts = q -> next;
157                 } else {
158                         q = ((struct timeout *)
159                              dmalloc (sizeof (struct timeout), MDL));
160                         if (!q)
161                                 log_fatal ("add_timeout: no memory!");
162                 }
163                 memset (q, 0, sizeof *q);
164                 q -> func = where;
165                 q -> ref = ref;
166                 q -> unref = unref;
167                 if (q -> ref)
168                         (*q -> ref)(&q -> what, what, MDL);
169                 else
170                         q -> what = what;
171         }
172
173         q -> when = when;
174
175         /* Now sort this timeout into the timeout list. */
176
177         /* Beginning of list? */
178         if (!timeouts || timeouts -> when > q -> when) {
179                 q -> next = timeouts;
180                 timeouts = q;
181                 return;
182         }
183
184         /* Middle of list? */
185         for (t = timeouts; t -> next; t = t -> next) {
186                 if (t -> next -> when > q -> when) {
187                         q -> next = t -> next;
188                         t -> next = q;
189                         return;
190                 }
191         }
192
193         /* End of list. */
194         t -> next = q;
195         q -> next = (struct timeout *)0;
196 }
197
198 void cancel_timeout (where, what)
199         void (*where) PROTO ((void *));
200         void *what;
201 {
202         struct timeout *t, *q;
203
204         /* Look for this timeout on the list, and unlink it if we find it. */
205         t = (struct timeout *)0;
206         for (q = timeouts; q; q = q -> next) {
207                 if (q -> func == where && q -> what == what) {
208                         if (t)
209                                 t -> next = q -> next;
210                         else
211                                 timeouts = q -> next;
212                         break;
213                 }
214                 t = q;
215         }
216
217         /* If we found the timeout, put it on the free list. */
218         if (q) {
219                 if (q -> unref)
220                         (*q -> unref) (&q -> what, MDL);
221                 q -> next = free_timeouts;
222                 free_timeouts = q;
223         }
224 }
225
226 #if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
227 void cancel_all_timeouts ()
228 {
229         struct timeout *t, *n;
230         for (t = timeouts; t; t = n) {
231                 n = t -> next;
232                 if (t -> unref && t -> what)
233                         (*t -> unref) (&t -> what, MDL);
234                 t -> next = free_timeouts;
235                 free_timeouts = t;
236         }
237 }
238
239 void relinquish_timeouts ()
240 {
241         struct timeout *t, *n;
242         for (t = free_timeouts; t; t = n) {
243                 n = t -> next;
244                 dfree (t, MDL);
245         }
246 }
247 #endif