+2001-06-06 Kevin L. Mitchell <klmitch@mit.edu>
+
+ * ircd/res.c (init_resolver): don't start DNS expires with a 0
+ relative timeout--if the server starts slow, timeouts could be
+ messy...there's probably a better solution, but this'll do for now
+
+ * ircd/os_solaris.c: _XOPEN_SOURCE doesn't get along with Solaris
+ headers very well; include stropts.h; define an os_set_tos()
+
+ * ircd/os_generic.c (os_set_tos): added an os_set_tos() for
+ os_generic.c
+
+ * ircd/ircd.c: if there are no C-lines, we don't want to have a
+ timer that expires at the absolute time of 0--it kinda blocks all
+ the other timers!
+
+ * ircd/engine_devpoll.c: some includes for open(); declare errcode
+ and codesize in engine_loop()
+
+ * ircd/list.c (free_client): remove bogus check on timer active
+ flag
+
+ * ircd/s_auth.c: pull out destruction code in
+ auth_timeout_request() into an externally-visible
+ destroy_auth_request(); manage cli_auth pointer in client
+ structure; use it for an extra assertion check
+
+ * ircd/list.c: include s_auth.h for destroy_auth_request(); add
+ debugging notices to show flow when deallocating
+ connections/clients; call destroy_auth_request() when free'ing a
+ client that has an auth outstanding; don't free the connection if
+ the process timer is unmarked but still active
+
+ * ircd/ircd_events.c: set GEN_ACTIVE when initializing a generator
+ and reset it before calling the event handler for an ET_DESTROY
+ event
+
+ * include/s_auth.h (destroy_auth_request): declare
+ destroy_auth_request(), which can be used to destroy an
+ outstanding auth request if a client socket goes away before the
+ auth exchange is completed
+
+ * include/ircd_events.h: add an active flag to keep track of
+ whether or not particular generators are active, for the
+ convenience of functions using the API
+
+ * include/client.h: add a pointer for auth requests to struct
+ Connection so we can kill outstanding auth requests if a client
+ socket closes unexpectedly
+
+ * ircd/s_bsd.c: cli_connect() could become 0 during the course of
+ the sock or timer callback; take that into account in the assert
+
+ * ircd/list.c: add magic number checking and setting--magic
+ numbers are zero'd on frees to detect double-frees; add back
+ setting of cli_from() to 0 to break the back-link from the struct
+ Connection (duh)
+
+ * ircd/ircd.c: set me's magic number correctly
+
+ * include/client.h: define magic numbers and accessor/verifier
+ macros
+
+ * ircd/list.c: assert that dealloc_client() is called with
+ cli_connect(cptr) == 0; set cli_connect(cptr) to 0 before calling
+ dealloc_client(); don't mess with cli_from(cptr)
+
+ * ircd/s_bsd.c: only attempt to dealloc a connection if the
+ associated client has already been destroyed, or at least delinked
+
+2001-06-05 Kevin L. Mitchell <klmitch@mit.edu>
+
+ * ircd/list.c (free_client): only try to delete the socket when
+ the fd hasn't already been closed, avoiding a double-free
+
+ * ircd/list.c (free_connection): make sure the client is really
+ gone before doing away with the connection
+
+ * ircd/s_bsd.c: record that socket has been added in con_freeflag
+ field; queue a socket_del() as soon as the socket is close()'d;
+ use con_freeflag & FREEFLAG_TIMER instead of con_timer; clear
+ FREEFLAG_SOCKET on ET_DESTROY event in client_sock_callback(),
+ then dealloc the connection if safe; mark socket as dead when
+ there's a read error or EOF; clear FREEFLAG_TIMER flag upon entry
+ to client_timer_callback(); dealloc connection if safe upon
+ ET_DESTROY event in client_timer_callback()
+
+ * ircd/list.c: use con_freeflag instead of con_timer; only dealloc
+ the connection if both socket and timer have been destroyed;
+ destroy both socket and timer explicitly and carefully
+
+ * include/client.h: replace the con_timer field with a
+ con_freeflag field, to indicate what still needs freeing; define
+ the freeflags
+
+ * ircd/engine_select.c (engine_loop): duh...sockList[i] could
+ become 0
+
+ * ircd/engine_devpoll.c (engine_loop): duh...sockList[i] could
+ become 0
+
+ * ircd/s_bsd.c: add some extra assertions to try to track down a
+ corruption problem
+
+ * ircd/engine_select.c (engine_loop): add an extra assert to try
+ to track down a corruption problem
+
+ * ircd/engine_poll.c (engine_loop): add an extra assert to try to
+ track down a corruption problem
+
+ * ircd/engine_kqueue.c (engine_loop): add an extra assert to try
+ to track down a corruption problem
+
+ * ircd/engine_devpoll.c (engine_loop): skip slots that have become
+ empty during processing; add an extra assert to try to track down
+ a corruption problem
+
+ * ircd/engine_kqueue.c (engine_delete): make sure to zero deleted
+ entries
+
+2001-06-04 Kevin L. Mitchell <klmitch@mit.edu>
+
+ * ircd/s_bsd.c (client_sock_callback): client is no longer
+ blocked, so we must mark it as unblocked
+
+ * ircd/engine_select.c: add Debug() calls galore; add handling for
+ SS_NOTSOCK; use a dummy sock variable to keep things from
+ disappearing on us; correct timeout calculation; update nfds for
+ efficiency
+
+ * ircd/engine_poll.c: use new debugging level (DEBUG_ENGINE);
+ remove a spurious "if (sock)" which will always be true; update
+ nfds for efficiency
+
+ * ircd/engine_kqueue.c: add Debug() calls galore; add handling for
+ SS_NOTSOCK (just in case); correct timeout calculation
+
+ * ircd/engine_devpoll.c: add Debug() calls galore; add handling
+ for SS_NOTSOCK; correct timeout calculation; add EAGAIN handling
+
+ * include/s_debug.h (DEBUG_ENGINE): add new debugging level;
+ pretty-indent numbers
+
+ * ircd/engine_poll.c (engine_loop): break out SS_NOTSOCK
+ case--it's not a socket; the check for writability is most likely
+ not needed, but present for completeness
+
+2001-05-24 Kevin L. Mitchell <klmitch@mit.edu>
+
+ * ircd/s_bsd.c: add Debug messages; call read_packet() even if the
+ no newline flag is set; call read_packet() when the timer expires,
+ regardless of what's in the buffer--read_packet() should be able
+ to deal properly
+
+ * ircd/IPcheck.c (ip_registry_connect_succeeded): correct a NOTICE
+ sent to clients to include the client nickname (duh)
+
+ * ircd/ircd_events.c: don't destroy a timer if it's already marked
+ for destruction; replace a missing ! in socket_del()
+
+ * ircd/engine_poll.c (engine_loop): reference a temporary variable
+ so we don't have to worry about sockList[i] going away
+
+ * ircd/s_bsd.c (client_sock_callback): add Debug messages
+
+ * ircd/s_auth.c: add Debug messages all over the place
+
+ * ircd/ircd_events.c: add and edit some Debug messages; add a list
+ of routines to convert some of the enums and flags from numbers
+ into human-readable strings for the Debug messages
+
+ * ircd/engine_poll.c: hack some Debug messages to use the new name
+ conversion routines in ircd_events.c; add an extra assert for a
+ condition that shouldn't ever happen; apparently recv() can return
+ EAGAIN when poll() returns readable--I wonder why...
+
+ * include/ircd_events.h: declare some helper routines under
+ DEBUGMODE
+
+2001-05-23 Kevin L. Mitchell <klmitch@mit.edu>
+
+ * ircd/s_bsd.c (client_sock_callback): add an extra assertion
+ check
+
+ * ircd/s_auth.c: add more Debug messages
+
+ * ircd/list.c (make_client): add an extra assertion check
+
+ * ircd/ircd_events.c (socket_events): don't call the engine events
+ changer if we haven't actually made any changes to the event mask
+
+ * ircd/uping.c: add some Debug messages
+
+ * ircd/s_stats.c: document new /STATS e
+
+ * ircd/s_err.c: add RPL_STATSENGINE to report the engine name
+
+ * ircd/s_bsd.c: remove static client_timer variable; in
+ read_packet(), if there's still data in the client's recvQ after
+ parsing, add a 2 second timer (con_proc); fix the ET_DESTROY case
+ of client_sock_callback to handle destroying the timer properly;
+ rewrote client_timer_callback from scratch to be called on an
+ individual client
+
+ * ircd/m_stats.c: add /STATS e to report the engine name
+
+ * ircd/list.c: deal with con_timer field in struct Connection
+ properly; correct a core-level bug in remove_client_from_list--if
+ the client is the only one in the list, we try to update
+ GlobalClientList's cli_prev pointer--not good
+
+ * ircd/ircd.c: remove call to init_client_timer()
+
+ * ircd/engine_poll.c: made Debug messages more uniform by
+ prepending "poll:" to them all; corrected an off-by-one error that
+ caused poll_count to be 1 less than the actual count and removed
+ my work-around; added Debug messages to indicate which socket is
+ being checked and what the results are
+
+ * ircd/Makefile.in: ran a make depend
+
+ * include/s_bsd.h: remove init_client_timer(), since we're doing
+ it differently now
+
+ * include/numeric.h (RPL_STATSENGINE): a stats reply to report the
+ engine name
+
+ * include/ircd_policy.h (HEAD_IN_SAND_STATS_E): turn off /stats e
+ reports for non-opers
+
+ * include/client.h: add con_timer and con_proc fields to struct
+ Connection and define accessor macros--con_timer marks that
+ con_proc contains a valid timer, and con_proc is used to pace user
+ data
+
+ * ircd/s_bsd.c (close_connection): let free_client() destroy the
+ socket
+
+ * ircd/s_auth.c (start_auth): add a Debug call to indicate when
+ auth has begun on a client
+
+ * ircd/ircd_events.c: ensure that event_execute() is called with a
+ non-NULL event; modify event_add() macro to properly zero list
+ bits; modify gen_dequeue() to not try to clip it out of a list
+ it's already been clipped out of; change signal socket
+ initialization to use state SS_NOTSOCK; permit timeout values of
+ 0 in add_timer(); add many Debug calls; change socket_del() and
+ timer_del() to always set the GEN_DESTROY flag; use GEN_MARKED in
+ timer_run() instead of GEN_DESTROY so that event_generate() will
+ pass on the events; remove the switch and replace with a simpler
+ if-then-else tree in timer_run(); don't allow destroyed sockets to
+ be destroyed again, nor their states or event masks to be changed
+
+ * ircd/ircd.c: initialize "running" to 1
+
+ * ircd/engine_poll.c: deal with SS_NOTSOCK "sockets"; add Debug
+ messages all over the place; fix a counting problem in
+ engine_add(); turn wait into a signed integer and set it to -1
+ only if timer_next() returns 0; adjust wait time to be relative;
+ don't call gen_ref_dec() if socket disappeared while we were
+ processing it
+
+ * include/ircd_events.h: the pipe for signals is not a socket, so
+ we must mark it as such--added SS_NOTSOCK for that special socket;
+ events won't be generated if GEN_DESTROY is on, so add GEN_MARKED
+ for the benefit of timer_run()
+
+ * configure.in: add --enable-pedantic and --enable-warnings to
+ turn on (and off) -Wall -pedantic in CFLAGS
+
2001-05-21 Kevin L. Mitchell <klmitch@mit.edu>
* ircd/s_conf.c: change "s_addr" element accesses to "address"
* include/s_conf.h: on some systems, "s_addr" is a macro; use
"address" instead
+2001-05-18 Kevin L. Mitchell <klmitch@mit.edu>
+
+ * ircd/engine_kqueue.c: include ircd_alloc.h; set_or_clear returns
+ void in this file; add a missing semi-colon; declare errcode,
+ codesize
+
+ * ircd/uping.c (uping_sender_callback): it's pptr, not uping
+
+ * ircd/s_user.c (register_user): comment out spurious reference to
+ nextping
+
+ * ircd/s_serv.c (server_estab): comment out spurious reference to
+ nextping
+
+ * ircd/s_conf.c (read_configuration_file): comment out spurious
+ reference to nextping and nextconnect
+
+ * ircd/s_bsd.c: comment out some spurious references to formerly
+ global (now non-existant) variables; correct a couple of typos
+
+ * ircd/s_auth.c: pre-declare some functions referenced in the
+ callback; correct a typo
+
+ * ircd/res.c (start_resolver): pass errno value of ENFILE
+
+ * ircd/listener.c (accept_connection): you know your API is messed
+ up when...variables that shouldn't have been global crop up in
+ other files
+
+ * ircd/list.c (free_client): substitution of == for =
+
+ * ircd/ircd_signal.c: include assert.h for assertion checking;
+ check ev_data() to find out what signal generated event
+
+ * ircd/ircd_events.c: some references to the variable "timer"
+ should have been references to the variable "ptr"
+
+ * ircd/engine_select.c: it's struct fd_set, not struct fdset;
+ ev_timer(ev) is already a timer pointer; declare codesize as a
+ size_t to correct signedness issue; use timer_next(), not
+ time_next()
+
+ * ircd/engine_poll.c: ev_timer(ev) is already a timer pointer;
+ select fd out of struct pollfd in assertion checking; declare
+ errcode and codesize; use timer_next(), not time_next()
+
+ * ircd/engine_kqueue.c: ev_timer(ev) is already a timer pointer;
+ use function timer_next(), not time_next()
+
+ * ircd/engine_devpoll.c: ev_timer(ev) is already a timer pointer;
+ use function timer_next(), not time_next()
+
+ * ircd/Makefile.in (IRCD_SRC): add ircd_events.c to the list of
+ compiled sources; do make depend
+
+ * include/list.h: pre-declare struct Connection
+
+ * include/ircd_events.h (gen_ref_inc): cast to the right structure
+ name
+
+ * include/s_auth.h: duh; missing */
+
+2001-05-10 Kevin L. Mitchell <klmitch@mit.edu>
+
+ * ircd/send.c: update write events status after sending data or
+ accumulating data to be sent
+
+ * ircd/m_list.c (m_list): update write events status after
+ canceling a running /list
+
+ * ircd/channel.c (list_next_channels): update write events status
+ after listing a few channels
+
+ * ircd/s_bsd.c: extensive changes to update to new events model;
+ remove on_write_unblocked() and the two implementations of
+ read_message(), which have been deprecated by this change
+
+ * ircd/s_auth.c: set the socket events we're interested in for
+ clients; simplify some logic that does the connect_nonb followed
+ by the socket_add
+
+ * ircd/list.c: define free_connection() to free a connection
+ that's become freeable once the struct Socket has been
+ deallocated; fix up free_client() to take this new behavior into
+ account
+
+ * ircd/ircd.c: call init_client_timer()
+
+ * include/s_bsd.h: declare new REGISTER_ERROR_MESSAGE when unable
+ to register connect-in-progress with events system; declare
+ init_client_timer() (HACK!) to preserve rate-limiting behavior
+
+ * include/list.h: declare new free_connection()
+
+ * include/client.h: add a struct Socket to struct Connection
+
+2001-05-09 Kevin L. Mitchell <klmitch@mit.edu>
+
+ * ircd/ircd_signal.c: massage the handlers for SIGHUP, SIGINT, and
+ SIGTERM into event callbacks; perform the actions in the
+ callbacks, since they're not called in the context of the signal;
+ set up the signal callbacks in the event engine
+
+ * ircd/ircd_events.c (signal_callback): we're supposed to look for
+ a specific signal; don't generate an event if there is no signal
+ structure for it
+
+ * ircd/ircd.c: nuke nextconnect and nextping and replace them with
+ connect_timer and ping_timer; massage try_connections() and
+ check_pings() into timer callbacks that re-add themselves at the
+ right time; remove ircd.c's "event_loop()"; initialize the event
+ system and the connect_timer and ping_timer
+
+ * ircd/uping.c: correct a couple more typos
+
+ * ircd/s_auth.c: rework to use new events system
+
+ * ircd/os_solaris.c (os_connect_nonb): update to new interface
+
+ * ircd/os_openbsd.c (os_connect_nonb): update to new interface
+
+ * ircd/os_linux.c (os_connect_nonb): update to new interface
+
+ * ircd/os_generic.c (os_connect_nonb): update to new interface
+
+ * ircd/os_bsd.c (os_connect_nonb): update to new interface
+
+ * include/s_auth.h: remove deprecated members of struct
+ AuthRequest, replacing them with struct Socket and struct Timer
+ structures; add flags to indicate when these structures have been
+ released by the event system; remove the deprecated
+ timeout_auth_queries()
+
+ * include/ircd_osdep.h (os_connect_nonb): connect could complete
+ immediately, so change the interface to handle that possibility
+
+ * ircd/uping.c (uping_server): noticed and corrected a typo
+
+ * ircd/listener.c: set up to use ircd_event's struct Socket by
+ adding an socket_add() call to inetport(), replacing
+ free_listener() with socket_del() in close_listener(), and
+ reworking accept_connection to be called as the callback
+
+ * ircd/ircd.c: add a call to IPcheck_init()
+
+ * ircd/IPcheck.c: remove IPcheck_expire(); rework
+ ip_registry_expire() to be called from a timer; write
+ IPcheck_init() to set up the expiration timer (hard-coded for a
+ 60-second expiration time)
+
+ * include/listener.h: add a struct Socket to the struct Listener;
+ remove accept_connection()
+
+ * include/IPcheck.h: add IPcheck_init(), remove IPcheck_expire()
+
+2001-05-08 Kevin L. Mitchell <klmitch@mit.edu>
+
+ * ircd/ircd_events.c: include config.h; use USE_KQUEUE and
+ USE_DEVPOLL instead of HAVE_KQUEUE and HAVE_DEVPOLL_H
+
+ * ircd/engine_select.c: include config.h; set FD_SETSIZE to
+ MAXCONNECTIONS, not IRCD_FD_SETSIZE...
+
+ * ircd/engine_poll.c: include config.h
+
+ * ircd/engine_kqueue.c: include config.h
+
+ * ircd/engine_devpoll.c: include config.h
+
+ * ircd/Makefile.in: include engine sources in compilation and make
+ depend steps
+
+ * configure.in: add checks for enabling the /dev/poll- and
+ kqueue-based engines
+
+ * acconfig.h: add lines for USE_DEVPOLL and USE_KQUEUE
+
+ * ircd/Makefile.in: work in the engine sources
+
2001-05-07 Kevin L. Mitchell <klmitch@mit.edu>
* ircd/m_settime.c: include ircd_snprintf.h
* ircd/send.c (sendcmdto_flag_butone): if FLAGS_OPER is or'd with
flag, send only to appropriate opers
+2001-04-13 Kevin L. Mitchell <klmitch@mit.edu>
+
+ * ircd/uping.c: refit to use the new events interface
+
+ * ircd/res.c: refit to use the new events interface
+
+ * ircd/ircd_events.c: create timer_chg(), which permits a
+ (non-periodic) timer's expire time to be modified; change the
+ logic in timer_run() so that timers that were re-added while the
+ event was being processed will not be destroyed prematurely
+
+ * include/uping.h: include the events header, declare some extra
+ fields in struct UPing, remove timeout value, and define some
+ flags for marking which cleanup items have yet to be done
+
+ * include/ircd_events.h: add a prototype for timer_chg() to change
+ the expire time of a running timer
+
2001-03-13 Joseph Bongaarts <foxxe@wtfs.net>
* ircd/os_openbsd.c: Tweaked the openbsd hack a bit.
* ircd/ircd_features.c: default LOCOP_KILL to TRUE--oops...
+2001-01-16 Kevin L. Mitchell <klmitch@mit.edu>
+
+ * ircd/ircd_events.c (timer_run): it's possible that the timer got
+ deleted during the callback processing, so don't go to the bother
+ of requeuing it if the destroy flag is set
+
+ * ircd/engine_select.c: define FD_SETSIZE to be IRCD_FD_SETSIZE
+ out of config.h if this is a *BSD; include errno.h (oops);
+ decrement error count after an hour using a timer; use FD_SETSIZE
+ constant instead of IRCD_FD_SETSIZE constant; fill in event
+ processing code
+
+ * ircd/engine_poll.c: include errno.h (oops); decrement error
+ count after an hour using a timer; fill in event processing code
+
+ * ircd/engine_kqueue.c: include errno.h (oops); decrement error
+ count after an hour using a timer; assert events filter is either
+ EVFILT_READ or EVFILT_WRITE; fill in event processing code
+
+ * ircd/engine_devpoll.c: include errno.h (oops); decrement error
+ count after an hour using a timer; fill in event processing code
+
2001-01-15 Kevin L. Mitchell <klmitch@mit.edu>
* ircd/client.c: fixed feattab; basically, when I changed features
privileges together; also fixed a bug in the antiprivs masking
loop in client_set_privs()--last index wouldn't get parsed
+2001-01-11 Kevin L. Mitchell <klmitch@mit.edu>
+
+ * ircd/ircd_events.c: call event_generate() with new data
+ argument; make it set that field in struct Event; make
+ socket_add() return the value of the eng_add callback
+
+ * ircd/engine_select.c: make engine_add() return a
+ successful/unsuccessful status; add bounds-checking outside of an
+ assert; use accessor macros; use log_write(), not the deprecated
+ ircd_log(); add an assert to engine_loop() to double-check for
+ data structure corruption
+
+ * ircd/engine_poll.c: make engine_add() return a
+ successful/unsuccessful status; add bounds-checking outside of an
+ assert; use accessor macros; use log_write(), not the deprecated
+ ircd_log(); add an assert to engine_loop() to double-check for
+ data structure corruption
+
+ * ircd/engine_kqueue.c: implementation of an engine for kqueue()
+
+ * ircd/engine_devpoll.c: implementation of an engine for /dev/poll
+
+ * include/ircd_events.h: define some accessor macros; add ev_data
+ to struct Event for certain important data--errno values, for
+ instance; make EngineAdd callback tell us if it was successful or
+ not; add extra argument to event_generate(); make socket_add()
+ return the status from EngineAdd
+
+2001-01-10 Kevin L. Mitchell <klmitch@mit.edu>
+
+ * ircd/ircd_events.c: pass initializer information about how many
+ total _filedescriptors_ may be opened at once
+
+ * ircd/ircd.c: use exported "running" instead of unexported
+ thisServer.running
+
+ * ircd/engine_select.c: implementation of an event engine based on
+ select()
+
+ * ircd/engine_poll.c: implementation of an event engine based on
+ poll()
+
+ * include/ircd_events.h: pass the engine initializer an integer
+ specifing how many _filedescriptors_ may be opened at once
+
+ * include/ircd.h: running has to be exported for the engine_*
+ event loops
+
+2001-01-09 Kevin L. Mitchell <klmitch@mit.edu>
+
+ * ircd/ircd_events.c: include some needed headers; add some
+ comments; make evEngines[] const; bundle sig_sock and sig_fd into
+ a struct named sigInfo; rework struct evInfo to have a queue of
+ _generators_, and only when threaded; added a gen_init() function
+ to centralize generator initialization; fix various compile-time
+ errors; rework event_add() for new queueing scheme and checked for
+ compile-time errors; add casts where needed; spell evEngines[]
+ correctly; make engine_name() return const char*
+
+ * include/ircd_events.h: type EventCallBack depends on struct
+ Event, so pre-declare it; put _event_ queue into generators, and
+ only when threaded; give engine data a union to store both ints
+ and pointers; make engine name a const; fix gen_ref_dec() macro;
+ make engine_name() return a const char*
+
+ * ircd/ircd_events.c: gen_dequeue() is now exported, so move it
+ down with the non-static functions; modify event_execute() to use
+ the new gen_ref_dec() to simplify code; make sure event_generate()
+ does not generate new events for generators marked for destruction
+
+ * include/ircd_events.h: the engines, at least, may need to modify
+ reference counts to keep generators from going away while
+ something still points at them, so add reference counter
+ manipulators and export gen_dequeue() for them
+
+ * ircd/ircd_events.c: set up the list of engines to try; set up
+ the signal struct Socket; rename netInfo to evInfo; move static
+ functions near the beginning of the file; do away with
+ signal_signal() (since we no longer keep a signal count ourselves)
+ and call event_generate() directly from signal_callback--also
+ renamed some functions; allow signal_callback() to read up to
+ SIGS_PER_SOCK at once from the signal pipe; add event_init() to
+ initialize the entire event system; add event_loop() to call the
+ engine's event loop; initialize new struct GenHeader member,
+ gh_engdata; remove timer_next(); add socket_add() function to add
+ a socket; add socket_del() to mark a socket for deletion; add
+ socket_state() to transition a socket between states; add
+ socket_events() to set what events we're interested in on the
+ socket; add engine_name() to retrieve event engine's name
+
+ * include/ircd_events.h: add engine data field to struct
+ GenHeader; rename SOCK_ACTION_REMOVE to SOCK_ACTION_DEL; add a
+ note about states vs s_events; remove signal count; fold union
+ Generator back into struct Event; remove count members from struct
+ Generators; redefine engine callbacks to not take a struct
+ Engine*; add explanatory comments to callback definitions; add
+ some engine callbacks to handle operations; remove struct Engine
+ flag member--can detect single flag from eng_signal member; add
+ event_init(), event_loop(), engine_name(), and the socket_*()
+ functions; make timer_next() a macro to avoid a function call
+
+2001-01-08 Kevin L. Mitchell <klmitch@mit.edu>
+
+ * include/ircd_events.h: rename to ircd_events.h, since it handles
+ events, not just networking stuff; add signal support; more
+ structural rearrangement
+
+ * ircd/ircd_events.c: rename to ircd_events.c, since it handles
+ events, not just networking stuff; add signal support; more
+ structural rearrangement
+
+2001-01-07 Kevin L. Mitchell <klmitch@mit.edu>
+
+ * ircd/ircd_network.c: implement timer API; add reference counts
+ appropriately
+
+ * include/ircd_network.h: firm up some pieces of the interface;
+ split out members everything has into a separate structure; add
+ reference counts; add timer API
+
+2001-01-06 Kevin L. Mitchell <klmitch@mit.edu>
+
+ * ircd/ircd_network.c: static data and event manipulation
+ functions for new event processing system
+
+ * include/ircd_network.h: data structures for new event processing
+ system
+
2001-01-03 Kevin L. Mitchell <klmitch@mit.edu>
* ircd/whowas.c: Completely re-did the old allocation scheme by
définissent DEBUGMODE. Recompiler l'ircd, et metez-le à la main comme: ircd
- t - x9. Ceci écrira un point la sortie à votre écran, montrant
probablement pourquoi il ne commence pas.
-
changed by modifying /proc/sys/net/ipv4/route/max_size.
A patch to select is also recommended if you have regular poll/select
-errors.
\ No newline at end of file
+errors.
/* Define to force the poll() function to be used */
#undef USE_POLL
+/* Define to enable the /dev/poll engine */
+#undef USE_DEVPOLL
+/* Define to enable the kqueue engine */
+#undef USE_KQUEUE
/* Define to enable various debugging code in the server; DO NOT USE
* THIS ON PRODUCTION SERVERS ON PAIN OF DELINKING!
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: config.h.in,v 1.1 2001-05-07 21:21:17 kev Exp $
+ * $Id: config.h.in,v 1.2 2001-06-07 00:29:46 kev Exp $
*/
/* Define to `int' if <sys/types.h> doesn't define. */
/* Define if you have the <poll.h> header file. */
#undef HAVE_POLL_H
+/* Define if you have the <sys/devpoll.h> header file. */
+#undef HAVE_SYS_DEVPOLL_H
+
+/* Define if you have the <sys/event.h> header file. */
+#undef HAVE_SYS_EVENT_H
+
/* Define if you have the nsl library (-lnsl). */
#undef HAVE_LIBNSL
/* Force inlining for a few critical functions */
#undef FORCEINLINE
+/* Define to enable the /dev/poll engine */
+#undef USE_DEVPOLL
+
+/* Define to enable the kqueue engine */
+#undef USE_KQUEUE
+
/* Domain name to be used for some statistics gathering */
#undef DOMAINNAME
--disable-symbols Disable debugging symbols (remove -g from CFLAGS)"
ac_help="$ac_help
--enable-profile Enable profiling support (add -pg to CFLAGS)"
+ac_help="$ac_help
+ --enable-pedantic Enable pedantic warnings (add -pedantic to CFLAGS)"
+ac_help="$ac_help
+ --enable-warnings Enable warnings (add -Wall to CFLAGS)"
ac_help="$ac_help
--disable-inlines Disable inlining for a few critical functions"
+ac_help="$ac_help
+ --enable-devpoll Enable the experimental /dev/poll-based engine"
+ac_help="$ac_help
+ --enable-kqueue Enable the experimental kqueue-based engine"
ac_help="$ac_help
--with-symlink=name Name to give the symlink; if name is "no," no
symlink will be created."
fi
echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:605: checking host system type" >&5
+echo "configure:613: checking host system type" >&5
host_alias=$host
case "$host_alias" in
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:629: checking for $ac_word" >&5
+echo "configure:637: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:659: checking for $ac_word" >&5
+echo "configure:667: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "cl", so it can be a program name with args.
set dummy cl; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:710: checking for $ac_word" >&5
+echo "configure:718: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:742: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:750: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
cat > conftest.$ac_ext << EOF
-#line 753 "configure"
+#line 761 "configure"
#include "confdefs.h"
main(){return(0);}
EOF
-if { (eval echo configure:758: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:766: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
ac_cv_prog_cc_works=yes
# If we can't run a trivial program, we are probably using a cross compiler.
if (./conftest; exit) 2>/dev/null; then
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:784: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:792: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
cross_compiling=$ac_cv_prog_cc_cross
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:789: checking whether we are using GNU C" >&5
+echo "configure:797: checking whether we are using GNU C" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
yes;
#endif
EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:798: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:806: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes
else
ac_cv_prog_gcc=no
ac_save_CFLAGS="$CFLAGS"
CFLAGS=
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:817: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:825: checking whether ${CC-cc} accepts -g" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
echo $ac_n "checking for ${CC-cc} option to accept ANSI C""... $ac_c" 1>&6
-echo "configure:853: checking for ${CC-cc} option to accept ANSI C" >&5
+echo "configure:861: checking for ${CC-cc} option to accept ANSI C" >&5
if eval "test \"`echo '$''{'am_cv_prog_cc_stdc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
do
CC="$ac_save_CC $ac_arg"
cat > conftest.$ac_ext <<EOF
-#line 869 "configure"
+#line 877 "configure"
#include "confdefs.h"
#include <stdarg.h>
#include <stdio.h>
; return 0; }
EOF
-if { (eval echo configure:906: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:914: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
am_cv_prog_cc_stdc="$ac_arg"; break
else
# If -pg was already there, force profiling to be enabled
unet_cv_enable_profile=yes
fi
+if test x"$CFLAGS" != x; then
+ unet_old_cflags=$CFLAGS
+ CFLAGS=`echo "$CFLAGS" | sed -e 's/-Wall//g'`
+fi
+if test x"$CFLAGS" != x"$unet_old_cflags"; then
+ # If -Wall was already there, force warnings to be enabled
+ unet_cv_enable_warnings=yes
+fi
+if test x"$CFLAGS" != x; then
+ unet_old_cflags=$CFLAGS
+ CFLAGS=`echo "$CFLAGS" | sed -e 's/-pedantic//g'`
+fi
+if test x"$CFLAGS" != x"$unet_old_cflags"; then
+ # If -pedantic was already there, force pedatic to be enabled
+ unet_cv_enable_pedantic=yes
+fi
echo $ac_n "checking for library containing crypt""... $ac_c" 1>&6
-echo "configure:955: checking for library containing crypt" >&5
+echo "configure:979: checking for library containing crypt" >&5
if eval "test \"`echo '$''{'ac_cv_search_crypt'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_func_search_save_LIBS="$LIBS"
ac_cv_search_crypt="no"
cat > conftest.$ac_ext <<EOF
-#line 962 "configure"
+#line 986 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
crypt()
; return 0; }
EOF
-if { (eval echo configure:973: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:997: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_search_crypt="none required"
else
test "$ac_cv_search_crypt" = "no" && for i in descrypt crypt; do
LIBS="-l$i $ac_func_search_save_LIBS"
cat > conftest.$ac_ext <<EOF
-#line 984 "configure"
+#line 1008 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
crypt()
; return 0; }
EOF
-if { (eval echo configure:995: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1019: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_search_crypt="-l$i"
break
# Most operating systems have gethostbyname() in the default searched
# libraries (i.e. libc):
echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6
-echo "configure:1020: checking for gethostbyname" >&5
+echo "configure:1044: checking for gethostbyname" >&5
if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1025 "configure"
+#line 1049 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char gethostbyname(); below. */
; return 0; }
EOF
-if { (eval echo configure:1048: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1072: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_gethostbyname=yes"
else
echo "$ac_t""no" 1>&6
# Some OSes (eg. Solaris) place it in libnsl:
echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6
-echo "configure:1067: checking for gethostbyname in -lnsl" >&5
+echo "configure:1091: checking for gethostbyname in -lnsl" >&5
ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lnsl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1075 "configure"
+#line 1099 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
gethostbyname()
; return 0; }
EOF
-if { (eval echo configure:1086: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1110: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
echo "$ac_t""no" 1>&6
# Some strange OSes (SINIX) have it in libsocket:
echo $ac_n "checking for gethostbyname in -lsocket""... $ac_c" 1>&6
-echo "configure:1113: checking for gethostbyname in -lsocket" >&5
+echo "configure:1137: checking for gethostbyname in -lsocket" >&5
ac_lib_var=`echo socket'_'gethostbyname | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lsocket $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1121 "configure"
+#line 1145 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
gethostbyname()
; return 0; }
EOF
-if { (eval echo configure:1132: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1156: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
# AC_CHECK_LIB's API is essentially broken so the following
# ugliness is necessary:
echo $ac_n "checking for gethostbyname in -lsocket""... $ac_c" 1>&6
-echo "configure:1161: checking for gethostbyname in -lsocket" >&5
+echo "configure:1185: checking for gethostbyname in -lsocket" >&5
ac_lib_var=`echo socket'_'gethostbyname | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lsocket -lnsl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1169 "configure"
+#line 1193 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
gethostbyname()
; return 0; }
EOF
-if { (eval echo configure:1180: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1204: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
else
echo "$ac_t""no" 1>&6
echo $ac_n "checking for gethostbyname in -lresolv""... $ac_c" 1>&6
-echo "configure:1199: checking for gethostbyname in -lresolv" >&5
+echo "configure:1223: checking for gethostbyname in -lresolv" >&5
ac_lib_var=`echo resolv'_'gethostbyname | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lresolv $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1207 "configure"
+#line 1231 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
gethostbyname()
; return 0; }
EOF
-if { (eval echo configure:1218: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1242: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
fi
echo $ac_n "checking for socket""... $ac_c" 1>&6
-echo "configure:1257: checking for socket" >&5
+echo "configure:1281: checking for socket" >&5
if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1262 "configure"
+#line 1286 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char socket(); below. */
; return 0; }
EOF
-if { (eval echo configure:1285: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1309: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_socket=yes"
else
else
echo "$ac_t""no" 1>&6
echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6
-echo "configure:1303: checking for socket in -lsocket" >&5
+echo "configure:1327: checking for socket in -lsocket" >&5
ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lsocket $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1311 "configure"
+#line 1335 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
socket()
; return 0; }
EOF
-if { (eval echo configure:1322: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1346: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
else
echo "$ac_t""no" 1>&6
echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6
-echo "configure:1348: checking for socket in -lsocket" >&5
+echo "configure:1372: checking for socket in -lsocket" >&5
ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lsocket -lnsl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1356 "configure"
+#line 1380 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
socket()
; return 0; }
EOF
-if { (eval echo configure:1367: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1391: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
echo $ac_n "checking for library containing res_mkquery""... $ac_c" 1>&6
-echo "configure:1395: checking for library containing res_mkquery" >&5
+echo "configure:1419: checking for library containing res_mkquery" >&5
if eval "test \"`echo '$''{'ac_cv_search_res_mkquery'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_func_search_save_LIBS="$LIBS"
ac_cv_search_res_mkquery="no"
cat > conftest.$ac_ext <<EOF
-#line 1402 "configure"
+#line 1426 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
res_mkquery()
; return 0; }
EOF
-if { (eval echo configure:1413: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1437: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_search_res_mkquery="none required"
else
test "$ac_cv_search_res_mkquery" = "no" && for i in resolv; do
LIBS="-l$i $ac_func_search_save_LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1424 "configure"
+#line 1448 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
res_mkquery()
; return 0; }
EOF
-if { (eval echo configure:1435: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1459: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_search_res_mkquery="-l$i"
break
fi
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1457: checking how to run the C preprocessor" >&5
+echo "configure:1481: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
-#line 1472 "configure"
+#line 1496 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1478: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1502: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
-#line 1489 "configure"
+#line 1513 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1495: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1519: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
rm -rf conftest*
CPP="${CC-cc} -nologo -E"
cat > conftest.$ac_ext <<EOF
-#line 1506 "configure"
+#line 1530 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1512: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1536: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
echo "$ac_t""$CPP" 1>&6
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1537: checking for ANSI C header files" >&5
+echo "configure:1561: checking for ANSI C header files" >&5
if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1542 "configure"
+#line 1566 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
#include <float.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1550: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1574: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 1567 "configure"
+#line 1591 "configure"
#include "confdefs.h"
#include <string.h>
EOF
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 1585 "configure"
+#line 1609 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
:
else
cat > conftest.$ac_ext <<EOF
-#line 1606 "configure"
+#line 1630 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
exit (0); }
EOF
-if { (eval echo configure:1617: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1641: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
:
else
fi
-for ac_hdr in poll.h
+for ac_hdr in poll.h sys/devpoll.h sys/event.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1644: checking for $ac_hdr" >&5
+echo "configure:1668: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1649 "configure"
+#line 1673 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1654: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1678: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
-echo "configure:1682: checking whether byte ordering is bigendian" >&5
+echo "configure:1706: checking whether byte ordering is bigendian" >&5
if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_cv_c_bigendian=unknown
# See if sys/param.h defines the BYTE_ORDER macro.
cat > conftest.$ac_ext <<EOF
-#line 1689 "configure"
+#line 1713 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/param.h>
#endif
; return 0; }
EOF
-if { (eval echo configure:1700: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1724: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
# It does; now see whether it defined to BIG_ENDIAN or not.
cat > conftest.$ac_ext <<EOF
-#line 1704 "configure"
+#line 1728 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/param.h>
#endif
; return 0; }
EOF
-if { (eval echo configure:1715: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1739: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_bigendian=yes
else
{ echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
else
cat > conftest.$ac_ext <<EOF
-#line 1735 "configure"
+#line 1759 "configure"
#include "confdefs.h"
main () {
/* Are we little or big endian? From Harbison&Steele. */
exit (u.c[sizeof (long) - 1] == 1);
}
EOF
-if { (eval echo configure:1748: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1772: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_c_bigendian=no
else
fi
echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:1772: checking for size_t" >&5
+echo "configure:1796: checking for size_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1777 "configure"
+#line 1801 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
fi
echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-echo "configure:1805: checking whether time.h and sys/time.h may both be included" >&5
+echo "configure:1829: checking whether time.h and sys/time.h may both be included" >&5
if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1810 "configure"
+#line 1834 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/time.h>
struct tm *tp;
; return 0; }
EOF
-if { (eval echo configure:1819: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1843: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_time=yes
else
fi
echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6
-echo "configure:1840: checking whether struct tm is in sys/time.h or time.h" >&5
+echo "configure:1864: checking whether struct tm is in sys/time.h or time.h" >&5
if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1845 "configure"
+#line 1869 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <time.h>
struct tm *tp; tp->tm_sec;
; return 0; }
EOF
-if { (eval echo configure:1853: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1877: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_struct_tm=time.h
else
fi
echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
-echo "configure:1874: checking for uid_t in sys/types.h" >&5
+echo "configure:1898: checking for uid_t in sys/types.h" >&5
if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1879 "configure"
+#line 1903 "configure"
#include "confdefs.h"
#include <sys/types.h>
EOF
fi
echo $ac_n "checking size of short""... $ac_c" 1>&6
-echo "configure:1908: checking size of short" >&5
+echo "configure:1932: checking size of short" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
{ echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
else
cat > conftest.$ac_ext <<EOF
-#line 1916 "configure"
+#line 1940 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
exit(0);
}
EOF
-if { (eval echo configure:1927: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1951: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_sizeof_short=`cat conftestval`
else
echo $ac_n "checking size of int""... $ac_c" 1>&6
-echo "configure:1947: checking size of int" >&5
+echo "configure:1971: checking size of int" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
{ echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
else
cat > conftest.$ac_ext <<EOF
-#line 1955 "configure"
+#line 1979 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
exit(0);
}
EOF
-if { (eval echo configure:1966: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1990: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_sizeof_int=`cat conftestval`
else
echo $ac_n "checking size of long""... $ac_c" 1>&6
-echo "configure:1986: checking size of long" >&5
+echo "configure:2010: checking size of long" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
{ echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
else
cat > conftest.$ac_ext <<EOF
-#line 1994 "configure"
+#line 2018 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
exit(0);
}
EOF
-if { (eval echo configure:2005: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2029: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_sizeof_long=`cat conftestval`
else
echo $ac_n "checking size of void *""... $ac_c" 1>&6
-echo "configure:2025: checking size of void *" >&5
+echo "configure:2049: checking size of void *" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_void_p'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
{ echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
else
cat > conftest.$ac_ext <<EOF
-#line 2033 "configure"
+#line 2057 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
exit(0);
}
EOF
-if { (eval echo configure:2044: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2068: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_sizeof_void_p=`cat conftestval`
else
if test "$ac_cv_sizeof_int" = 2 ; then
echo $ac_n "checking for int16_t""... $ac_c" 1>&6
-echo "configure:2065: checking for int16_t" >&5
+echo "configure:2089: checking for int16_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_int16_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2070 "configure"
+#line 2094 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
fi
echo $ac_n "checking for u_int16_t""... $ac_c" 1>&6
-echo "configure:2098: checking for u_int16_t" >&5
+echo "configure:2122: checking for u_int16_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_u_int16_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2103 "configure"
+#line 2127 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
elif test "$ac_cv_sizeof_short" = 2 ; then
echo $ac_n "checking for int16_t""... $ac_c" 1>&6
-echo "configure:2132: checking for int16_t" >&5
+echo "configure:2156: checking for int16_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_int16_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2137 "configure"
+#line 2161 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
fi
echo $ac_n "checking for u_int16_t""... $ac_c" 1>&6
-echo "configure:2165: checking for u_int16_t" >&5
+echo "configure:2189: checking for u_int16_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_u_int16_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2170 "configure"
+#line 2194 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
fi
if test "$ac_cv_sizeof_int" = 4 ; then
echo $ac_n "checking for int32_t""... $ac_c" 1>&6
-echo "configure:2202: checking for int32_t" >&5
+echo "configure:2226: checking for int32_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_int32_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2207 "configure"
+#line 2231 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
fi
echo $ac_n "checking for u_int32_t""... $ac_c" 1>&6
-echo "configure:2235: checking for u_int32_t" >&5
+echo "configure:2259: checking for u_int32_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_u_int32_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2240 "configure"
+#line 2264 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
elif test "$ac_cv_sizeof_short" = 4 ; then
echo $ac_n "checking for int32_t""... $ac_c" 1>&6
-echo "configure:2269: checking for int32_t" >&5
+echo "configure:2293: checking for int32_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_int32_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2274 "configure"
+#line 2298 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
fi
echo $ac_n "checking for u_int32_t""... $ac_c" 1>&6
-echo "configure:2302: checking for u_int32_t" >&5
+echo "configure:2326: checking for u_int32_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_u_int32_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2307 "configure"
+#line 2331 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
elif test "$ac_cv_sizeof_long" = 4 ; then
echo $ac_n "checking for int32_t""... $ac_c" 1>&6
-echo "configure:2336: checking for int32_t" >&5
+echo "configure:2360: checking for int32_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_int32_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2341 "configure"
+#line 2365 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
fi
echo $ac_n "checking for u_int32_t""... $ac_c" 1>&6
-echo "configure:2369: checking for u_int32_t" >&5
+echo "configure:2393: checking for u_int32_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_u_int32_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2374 "configure"
+#line 2398 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
{ echo "configure: error: Cannot find a type with size of 32 bits" 1>&2; exit 1; }
fi
+echo $ac_n "checking for kqueue""... $ac_c" 1>&6
+echo "configure:2430: checking for kqueue" >&5
+if eval "test \"`echo '$''{'ac_cv_func_kqueue'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2435 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char kqueue(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char kqueue();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_kqueue) || defined (__stub___kqueue)
+choke me
+#else
+kqueue();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2458: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_kqueue=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_kqueue=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'kqueue`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+fi
+
echo $ac_n "checking for restartable system calls""... $ac_c" 1>&6
-echo "configure:2407: checking for restartable system calls" >&5
+echo "configure:2479: checking for restartable system calls" >&5
if eval "test \"`echo '$''{'ac_cv_sys_restartable_syscalls'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
{ echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
else
cat > conftest.$ac_ext <<EOF
-#line 2415 "configure"
+#line 2487 "configure"
#include "confdefs.h"
/* Exit 0 (true) if wait returns something other than -1,
i.e. the pid of the child, which means that wait was restarted
}
EOF
-if { (eval echo configure:2433: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2505: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_sys_restartable_syscalls=yes
else
echo $ac_n "checking for donuts""... $ac_c" 1>&6
-echo "configure:2457: checking for donuts" >&5
+echo "configure:2529: checking for donuts" >&5
echo "$ac_t""yes" 1>&6
for ac_prog in gawk mawk nawk awk
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2465: checking for $ac_word" >&5
+echo "configure:2537: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
done
echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:2495: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:2567: checking whether ${MAKE-make} sets \${MAKE}" >&5
set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:2533: checking for a BSD compatible install" >&5
+echo "configure:2605: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
-echo "configure:2586: checking whether ln -s works" >&5
+echo "configure:2658: checking whether ln -s works" >&5
if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2611: checking for $ac_word" >&5
+echo "configure:2683: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_RMPROG'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2652: checking for $ac_word" >&5
+echo "configure:2724: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_SHPROG'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
echo $ac_n "checking for posix non-blocking""... $ac_c" 1>&6
-echo "configure:2690: checking for posix non-blocking" >&5
+echo "configure:2762: checking for posix non-blocking" >&5
if eval "test \"`echo '$''{'unet_cv_sys_nonblocking_posix'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
{ echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
else
cat > conftest.$ac_ext <<EOF
-#line 2698 "configure"
+#line 2770 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/socket.h>
exit(1);
}
EOF
-if { (eval echo configure:2724: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2796: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
unet_cv_sys_nonblocking_posix=yes
else
else
echo $ac_n "checking for bsd non-blocking""... $ac_c" 1>&6
-echo "configure:2746: checking for bsd non-blocking" >&5
+echo "configure:2818: checking for bsd non-blocking" >&5
if eval "test \"`echo '$''{'unet_cv_sys_nonblocking_bsd'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
{ echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
else
cat > conftest.$ac_ext <<EOF
-#line 2754 "configure"
+#line 2826 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/socket.h>
exit(1);
}
EOF
-if { (eval echo configure:2780: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2852: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
unet_cv_sys_nonblocking_bsd=yes
else
fi
fi
echo $ac_n "checking for posix signals""... $ac_c" 1>&6
-echo "configure:2808: checking for posix signals" >&5
+echo "configure:2880: checking for posix signals" >&5
if eval "test \"`echo '$''{'unet_cv_sys_signal_posix'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2813 "configure"
+#line 2885 "configure"
#include "confdefs.h"
#include <signal.h>
int main() {
sigaction(SIGTERM, (struct sigaction *)0L, (struct sigaction *)0L)
; return 0; }
EOF
-if { (eval echo configure:2820: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2892: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
unet_cv_sys_signal_posix=yes
else
else
echo $ac_n "checking for bsd reliable signals""... $ac_c" 1>&6
-echo "configure:2840: checking for bsd reliable signals" >&5
+echo "configure:2912: checking for bsd reliable signals" >&5
if eval "test \"`echo '$''{'unet_cv_sys_signal_bsd'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
{ echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
else
cat > conftest.$ac_ext <<EOF
-#line 2848 "configure"
+#line 2920 "configure"
#include "confdefs.h"
#include <signal.h>
int calls = 0;
exit (0);
}
EOF
-if { (eval echo configure:2866: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2938: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
unet_cv_sys_signal_bsd=yes
else
fi
echo $ac_n "checking if the compiler understands -pipe""... $ac_c" 1>&6
-echo "configure:2895: checking if the compiler understands -pipe" >&5
+echo "configure:2967: checking if the compiler understands -pipe" >&5
unet_cv_pipe_flags="$ac_cv_prog_gcc"
if test "$ac_cv_prog_gcc" = no; then
OLDCFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -pipe"
cat > conftest.$ac_ext <<EOF
-#line 2901 "configure"
+#line 2973 "configure"
#include "confdefs.h"
int main() {
; return 0; }
EOF
-if { (eval echo configure:2908: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2980: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
unet_cv_pipe_flags=yes
else
echo $ac_n "checking for OS-dependent information""... $ac_c" 1>&6
-echo "configure:2928: checking for OS-dependent information" >&5
+echo "configure:3000: checking for OS-dependent information" >&5
case "$host" in
*-linux*)
echo "$ac_t""Linux ($host) found." 1>&6
echo $ac_n "checking whether to enable use of poll()""... $ac_c" 1>&6
-echo "configure:2982: checking whether to enable use of poll()" >&5
+echo "configure:3054: checking whether to enable use of poll()" >&5
# Check whether --enable-poll or --disable-poll was given.
if test "${enable_poll+set}" = set; then
enableval="$enable_poll"
#define USE_POLL
EOF
+ ENGINE_C=engine_poll.c
+else
+ ENGINE_C=engine_select.c
fi
+
echo $ac_n "checking whether to enable debug mode""... $ac_c" 1>&6
-echo "configure:3012: checking whether to enable debug mode" >&5
+echo "configure:3088: checking whether to enable debug mode" >&5
# Check whether --enable-debug or --disable-debug was given.
if test "${enable_debug+set}" = set; then
enableval="$enable_debug"
fi
echo $ac_n "checking whether to enable asserts""... $ac_c" 1>&6
-echo "configure:3036: checking whether to enable asserts" >&5
+echo "configure:3112: checking whether to enable asserts" >&5
# Check whether --enable-asserts or --disable-asserts was given.
if test "${enable_asserts+set}" = set; then
enableval="$enable_asserts"
fi
echo $ac_n "checking whether to enable debugging symbols""... $ac_c" 1>&6
-echo "configure:3060: checking whether to enable debugging symbols" >&5
+echo "configure:3136: checking whether to enable debugging symbols" >&5
# Check whether --enable-symbols or --disable-symbols was given.
if test "${enable_symbols+set}" = set; then
enableval="$enable_symbols"
fi
echo $ac_n "checking whether to enable profiling support (gprof)""... $ac_c" 1>&6
-echo "configure:3081: checking whether to enable profiling support (gprof)" >&5
+echo "configure:3157: checking whether to enable profiling support (gprof)" >&5
# Check whether --enable-profile or --disable-profile was given.
if test "${enable_profile+set}" = set; then
enableval="$enable_profile"
CFLAGS="-pg $CFLAGS"
fi
+echo $ac_n "checking whether to enable pedantic compiler warnings""... $ac_c" 1>&6
+echo "configure:3178: checking whether to enable pedantic compiler warnings" >&5
+# Check whether --enable-pedantic or --disable-pedantic was given.
+if test "${enable_pedantic+set}" = set; then
+ enableval="$enable_pedantic"
+ unet_cv_enable_pedantic=$enable_pedantic
+else
+ if eval "test \"`echo '$''{'unet_cv_enable_pedantic'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ unet_cv_enable_pedantic=no
+fi
+
+fi
+
+echo "$ac_t""$unet_cv_enable_pedantic" 1>&6
+
+if test x"$unet_cv_enable_pedantic" = xyes; then
+ CFLAGS="-pedantic $CFLAGS"
+fi
+
+echo $ac_n "checking whether to enable compiler warnings""... $ac_c" 1>&6
+echo "configure:3199: checking whether to enable compiler warnings" >&5
+# Check whether --enable-warnings or --disable-warnings was given.
+if test "${enable_warnings+set}" = set; then
+ enableval="$enable_warnings"
+ unet_cv_enable_warnings=$enable_warnings
+else
+ if eval "test \"`echo '$''{'unet_cv_enable_warnings'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ unet_cv_enable_warnings=no
+fi
+
+fi
+
+echo "$ac_t""$unet_cv_enable_warnings" 1>&6
+
+if test x"$unet_cv_enable_warnings" = xyes; then
+ CFLAGS="-Wall $CFLAGS"
+fi
+
echo $ac_n "checking whether to enable inlining for a few critical functions""... $ac_c" 1>&6
-echo "configure:3102: checking whether to enable inlining for a few critical functions" >&5
+echo "configure:3220: checking whether to enable inlining for a few critical functions" >&5
# Check whether --enable-inlines or --disable-inlines was given.
if test "${enable_inlines+set}" = set; then
enableval="$enable_inlines"
fi
+echo $ac_n "checking whether to enable the /dev/poll event engine""... $ac_c" 1>&6
+echo "configure:3244: checking whether to enable the /dev/poll event engine" >&5
+# Check whether --enable-devpoll or --disable-devpoll was given.
+if test "${enable_devpoll+set}" = set; then
+ enableval="$enable_devpoll"
+ unet_cv_enable_devpoll=$enable_devpoll
+else
+ if eval "test \"`echo '$''{'unet_cv_enable_devpoll'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ unet_cv_enable_devpoll=no
+fi
+
+fi
+
+
+if test x"$ac_cv_header_sys_devpoll_h" = xno; then
+ unet_cv_enable_devpoll=no
+fi
+
+echo "$ac_t""$unet_cv_enable_devpoll" 1>&6
+
+if test x"$unet_cv_enable_devpoll" != xno; then
+ cat >> confdefs.h <<\EOF
+#define USE_DEVPOLL
+EOF
+
+ ENGINE_C="engine_devpoll.c $ENGINE_C"
+fi
+
+echo $ac_n "checking whether to enable the kqueue event engine""... $ac_c" 1>&6
+echo "configure:3274: checking whether to enable the kqueue event engine" >&5
+# Check whether --enable-kqueue or --disable-kqueue was given.
+if test "${enable_kqueue+set}" = set; then
+ enableval="$enable_kqueue"
+ unet_cv_enable_kqueue=$enable_kqueue
+else
+ if eval "test \"`echo '$''{'unet_cv_enable_kqueue'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ unet_cv_enable_kqueue=no
+fi
+
+fi
+
+
+if test x"$ac_cv_header_sys_event_h" = xno -o x"$ac_cv_func_kqueue" = xno; then
+ unet_cv_enable_kqueue=no
+fi
+
+echo "$ac_t""$unet_cv_enable_kqueue" 1>&6
+
+if test x"$unet_cv_enable_kqueue" != xno; then
+ cat >> confdefs.h <<\EOF
+#define USE_KQUEUE
+EOF
+
+ ENGINE_C="engine_kqueue.c $ENGINE_C"
+fi
+
echo $ac_n "checking what name to give the symlink""... $ac_c" 1>&6
-echo "configure:3126: checking what name to give the symlink" >&5
+echo "configure:3304: checking what name to give the symlink" >&5
# Check whether --with-symlink or --without-symlink was given.
if test "${with_symlink+set}" = set; then
withval="$with_symlink"
echo $ac_n "checking what permissions to set on the installed binary""... $ac_c" 1>&6
-echo "configure:3158: checking what permissions to set on the installed binary" >&5
+echo "configure:3336: checking what permissions to set on the installed binary" >&5
# Check whether --with-mode or --without-mode was given.
if test "${with_mode+set}" = set; then
withval="$with_mode"
unet_uid=`id | sed -e 's/.*uid=[0-9]*(//' -e 's/).*//' 2> /dev/null`
echo $ac_n "checking which user should own the installed binary""... $ac_c" 1>&6
-echo "configure:3184: checking which user should own the installed binary" >&5
+echo "configure:3362: checking which user should own the installed binary" >&5
# Check whether --with-owner or --without-owner was given.
if test "${with_owner+set}" = set; then
withval="$with_owner"
unet_gid=`id | sed -e 's/.*gid=[0-9]*(//' -e 's/).*//' 2> /dev/null`
echo $ac_n "checking which group should own the installed binary""... $ac_c" 1>&6
-echo "configure:3210: checking which group should own the installed binary" >&5
+echo "configure:3388: checking which group should own the installed binary" >&5
# Check whether --with-group or --without-group was given.
if test "${with_group+set}" = set; then
withval="$with_group"
fi
fi
echo $ac_n "checking for site domain name""... $ac_c" 1>&6
-echo "configure:3242: checking for site domain name" >&5
+echo "configure:3420: checking for site domain name" >&5
# Check whether --with-domain or --without-domain was given.
if test "${with_domain+set}" = set; then
withval="$with_domain"
echo $ac_n "checking if chroot operation is desired""... $ac_c" 1>&6
-echo "configure:3272: checking if chroot operation is desired" >&5
+echo "configure:3450: checking if chroot operation is desired" >&5
# Check whether --with-chroot or --without-chroot was given.
if test "${with_chroot+set}" = set; then
withval="$with_chroot"
exec_prefix=$unet_save_exec_prefix
echo $ac_n "checking where the binary will be for /restart""... $ac_c" 1>&6
-echo "configure:3320: checking where the binary will be for /restart" >&5
+echo "configure:3498: checking where the binary will be for /restart" >&5
if test x"$unet_cv_with_symlink" = xno; then
unet_spath="$unet_bindir/ircd"
else
echo $ac_n "checking what the data directory should be""... $ac_c" 1>&6
-echo "configure:3342: checking what the data directory should be" >&5
+echo "configure:3520: checking what the data directory should be" >&5
# Check whether --with-dpath or --without-dpath was given.
if test "${with_dpath+set}" = set; then
withval="$with_dpath"
echo $ac_n "checking where the default configuration file resides""... $ac_c" 1>&6
-echo "configure:3385: checking where the default configuration file resides" >&5
+echo "configure:3563: checking where the default configuration file resides" >&5
# Check whether --with-cpath or --without-cpath was given.
if test "${with_cpath+set}" = set; then
withval="$with_cpath"
echo $ac_n "checking where to put the debugging log if debugging enabled""... $ac_c" 1>&6
-echo "configure:3427: checking where to put the debugging log if debugging enabled" >&5
+echo "configure:3605: checking where to put the debugging log if debugging enabled" >&5
# Check whether --with-lpath or --without-lpath was given.
if test "${with_lpath+set}" = set; then
withval="$with_lpath"
unet_maxcon=`ulimit -Hn`
unet_maxcon=`expr $unet_maxcon - 4`
echo $ac_n "checking max connections""... $ac_c" 1>&6
-echo "configure:3473: checking max connections" >&5
+echo "configure:3651: checking max connections" >&5
# Check whether --with-maxcon or --without-maxcon was given.
if test "${with_maxcon+set}" = set; then
withval="$with_maxcon"
s%@RMPROG@%$RMPROG%g
s%@SHPROG@%$SHPROG%g
s%@OSDEP_C@%$OSDEP_C%g
+s%@ENGINE_C@%$ENGINE_C%g
s%@INSTALL_RULE@%$INSTALL_RULE%g
s%@SYMLINK@%$SYMLINK%g
s%@IRCDMODE@%$IRCDMODE%g
# If -pg was already there, force profiling to be enabled
unet_cv_enable_profile=yes
fi
+dnl Notice the -Wall flag and deal accordingly
+if test x"$CFLAGS" != x; then
+ unet_old_cflags=$CFLAGS
+ CFLAGS=`echo "$CFLAGS" | sed -e 's/-Wall//g'`
+fi
+if test x"$CFLAGS" != x"$unet_old_cflags"; then
+ # If -Wall was already there, force warnings to be enabled
+ unet_cv_enable_warnings=yes
+fi
+dnl Notice the -pedantic flag and deal accordingly
+if test x"$CFLAGS" != x; then
+ unet_old_cflags=$CFLAGS
+ CFLAGS=`echo "$CFLAGS" | sed -e 's/-pedantic//g'`
+fi
+if test x"$CFLAGS" != x"$unet_old_cflags"; then
+ # If -pedantic was already there, force pedatic to be enabled
+ unet_cv_enable_pedantic=yes
+fi
dnl Checks for libraries.
dnl Checks for header files.
AC_HEADER_STDC
-AC_CHECK_HEADERS(poll.h)
+AC_CHECK_HEADERS(poll.h sys/devpoll.h sys/event.h)
dnl Checks for typedefs, structures, and compiler characteristics
dnl AC_C_CONST
unet_CHECK_TYPE_SIZES
dnl Checks for library functions.
+AC_CHECK_FUNC(kqueue)
dnl Do we have restarting syscalls ?
AC_SYS_RESTARTABLE_SYSCALLS
if test x"$unet_cv_enable_poll" = xyes; then
AC_DEFINE([USE_POLL], , [Specify whether or not to use poll()])
+ ENGINE_C=engine_poll.c
+else
+ ENGINE_C=engine_select.c
fi
+AC_SUBST(ENGINE_C)
dnl Now look for --enable-debug
AC_MSG_CHECKING([whether to enable debug mode])
CFLAGS="-pg $CFLAGS"
fi
+dnl Now check for --enable-pedantic
+AC_MSG_CHECKING([whether to enable pedantic compiler warnings])
+AC_ARG_ENABLE([pedantic],
+[ --enable-pedantic Enable pedantic warnings (add -pedantic to CFLAGS)],
+[unet_cv_enable_pedantic=$enable_pedantic],
+[AC_CACHE_VAL(unet_cv_enable_pedantic,
+[unet_cv_enable_pedantic=no])])
+AC_MSG_RESULT([$unet_cv_enable_pedantic])
+
+if test x"$unet_cv_enable_pedantic" = xyes; then
+ CFLAGS="-pedantic $CFLAGS"
+fi
+
+dnl Now check for --enable-warnings
+AC_MSG_CHECKING([whether to enable compiler warnings])
+AC_ARG_ENABLE([warnings],
+[ --enable-warnings Enable warnings (add -Wall to CFLAGS)],
+[unet_cv_enable_warnings=$enable_warnings],
+[AC_CACHE_VAL(unet_cv_enable_warnings,
+[unet_cv_enable_warnings=no])])
+AC_MSG_RESULT([$unet_cv_enable_warnings])
+
+if test x"$unet_cv_enable_warnings" = xyes; then
+ CFLAGS="-Wall $CFLAGS"
+fi
+
dnl --disable-inlines check...
AC_MSG_CHECKING([whether to enable inlining for a few critical functions])
AC_ARG_ENABLE([inlines],
AC_DEFINE([FORCEINLINE], , [Force inlining for a few critical functions])
fi
+dnl --enable-devpoll check...
+AC_MSG_CHECKING([whether to enable the /dev/poll event engine])
+AC_ARG_ENABLE([devpoll],
+[ --enable-devpoll Enable the experimental /dev/poll-based engine],
+[unet_cv_enable_devpoll=$enable_devpoll],
+[AC_CACHE_VAL(unet_cv_enable_devpoll,
+[unet_cv_enable_devpoll=no])])
+
+if test x"$ac_cv_header_sys_devpoll_h" = xno; then
+ unet_cv_enable_devpoll=no
+fi
+
+AC_MSG_RESULT([$unet_cv_enable_devpoll])
+
+if test x"$unet_cv_enable_devpoll" != xno; then
+ AC_DEFINE([USE_DEVPOLL], , [Define to enable the /dev/poll engine])
+ ENGINE_C="engine_devpoll.c $ENGINE_C"
+fi
+
+dnl --enable-kqueue check...
+AC_MSG_CHECKING([whether to enable the kqueue event engine])
+AC_ARG_ENABLE([kqueue],
+[ --enable-kqueue Enable the experimental kqueue-based engine],
+[unet_cv_enable_kqueue=$enable_kqueue],
+[AC_CACHE_VAL(unet_cv_enable_kqueue,
+[unet_cv_enable_kqueue=no])])
+
+if test x"$ac_cv_header_sys_event_h" = xno -o x"$ac_cv_func_kqueue" = xno; then
+ unet_cv_enable_kqueue=no
+fi
+
+AC_MSG_RESULT([$unet_cv_enable_kqueue])
+
+if test x"$unet_cv_enable_kqueue" != xno; then
+ AC_DEFINE([USE_KQUEUE], , [Define to enable the kqueue engine])
+ ENGINE_C="engine_kqueue.c $ENGINE_C"
+fi
+
dnl --with-symlink lets us set the name of the symlink; defaults to "ircd"
AC_MSG_CHECKING([what name to give the symlink])
AC_ARG_WITH([symlink],
/*
* Prototypes
*/
+extern void IPcheck_init(void);
extern int IPcheck_local_connect(struct in_addr ip, time_t* next_target_out);
extern void IPcheck_connect_fail(struct in_addr ip);
extern void IPcheck_connect_succeeded(struct Client *cptr);
extern int IPcheck_remote_connect(struct Client *cptr, int is_burst);
extern void IPcheck_disconnect(struct Client *cptr);
extern unsigned short IPcheck_nr(struct Client* cptr);
-extern void IPcheck_expire();
#endif /* INCLUDED_ipcheck_h */
#ifndef INCLUDED_msgq_h
#include "msgq.h"
#endif
+#ifndef INCLUDED_ircd_events_h
+#include "ircd_events.h"
+#endif
#ifndef INCLUDED_ircd_handler_h
#include "ircd_handler.h"
#endif
struct DNSReply;
struct hostent;
struct Privs;
+struct AuthRequest;
/*
* Structures
* to which the allocation is tied to! *Never* refer to
* these fields, if (from != self).
*/
+ unsigned long con_magic; /* magic number */
struct Connection* con_next; /* Next connection with queued data */
struct Connection** con_prev_p; /* What points to us */
struct Client* con_client; /* Client associated with connection */
unsigned int con_count; /* Amount of data in buffer */
int con_fd; /* >= 0, for local clients */
+ int con_freeflag; /* indicates if connection can be freed */
int con_error; /* last socket level error for client */
unsigned int con_snomask; /* mask for server messages */
time_t con_nextnick; /* Next time a nick change is allowed */
char con_passwd[PASSWDLEN + 1];
char con_buffer[BUFSIZE]; /* Incoming message buffer; or the error that
caused this clients socket to be `dead' */
+ struct Socket con_socket; /* socket descriptor for client */
+ struct Timer con_proc; /* process latent messages from client */
+ struct AuthRequest* con_auth; /* auth request for client */
};
+#define CONNECTION_MAGIC 0x12f955f3
+
struct Client {
+ unsigned long cli_magic; /* magic number */
struct Client* cli_next; /* link in GlobalClientList */
struct Client* cli_prev; /* link in GlobalClientList */
struct Client* cli_hnext; /* link in hash table bucket or this */
char cli_info[REALLEN + 1]; /* Free form additional client information */
};
+#define CLIENT_MAGIC 0x4ca08286
+
+#define cli_verify(cli) ((cli)->cli_magic == CLIENT_MAGIC)
+#define cli_magic(cli) ((cli)->cli_magic)
#define cli_next(cli) ((cli)->cli_next)
#define cli_prev(cli) ((cli)->cli_prev)
#define cli_hnext(cli) ((cli)->cli_hnext)
#define cli_count(cli) ((cli)->cli_connect->con_count)
#define cli_fd(cli) ((cli)->cli_connect->con_fd)
+#define cli_freeflag(cli) ((cli)->cli_connect->con_freeflag)
#define cli_error(cli) ((cli)->cli_connect->con_error)
#define cli_snomask(cli) ((cli)->cli_connect->con_snomask)
#define cli_nextnick(cli) ((cli)->cli_connect->con_nextnick)
#define cli_sockhost(cli) ((cli)->cli_connect->con_sockhost)
#define cli_passwd(cli) ((cli)->cli_connect->con_passwd)
#define cli_buffer(cli) ((cli)->cli_connect->con_buffer)
+#define cli_socket(cli) ((cli)->cli_connect->con_socket)
+#define cli_proc(cli) ((cli)->cli_connect->con_proc)
+#define cli_auth(cli) ((cli)->cli_connect->con_auth)
+#define con_verify(con) ((con)->con_magic == CONNECTION_MAGIC)
+#define con_magic(con) ((con)->con_magic)
#define con_next(con) ((con)->con_next)
#define con_prev_p(con) ((con)->con_prev_p)
#define con_client(con) ((con)->con_client)
#define con_count(con) ((con)->con_count)
#define con_fd(con) ((con)->con_fd)
+#define con_freeflag(con) ((con)->con_freeflag)
#define con_error(con) ((con)->con_error)
#define con_snomask(con) ((con)->con_snomask)
#define con_nextnick(con) ((con)->con_nextnick)
#define con_sockhost(con) ((con)->con_sockhost)
#define con_passwd(con) ((con)->con_passwd)
#define con_buffer(con) ((con)->con_buffer)
+#define con_socket(con) ((con)->con_socket)
+#define con_proc(con) ((con)->con_proc)
+#define con_auth(con) ((con)->con_auth)
#define STAT_CONNECTING 0x001 /* connecting to another server */
#define STAT_HANDSHAKE 0x002 /* pass - server sent */
#define ClearWallops(x) (cli_flags(x) &= ~FLAGS_WALLOP)
#define ClearServNotice(x) (cli_flags(x) &= ~FLAGS_SERVNOTICE)
+/* free flags */
+#define FREEFLAG_SOCKET 0x0001 /* socket needs to be freed */
+#define FREEFLAG_TIMER 0x0002 /* timer needs to be freed */
+
/* server notice stuff */
#define SNO_ADD 1
extern char* configfile;
extern int debuglevel;
extern char* debugmode;
+extern int running;
#endif /* INCLUDED_ircd_h */
--- /dev/null
+#ifndef INCLUDED_ircd_events_h
+#define INCLUDED_ircd_events_h
+/*
+ * IRC - Internet Relay Chat, include/ircd_events.h
+ * Copyright (C) 2001 Kevin L. Mitchell <klmitch@mit.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ */
+
+#ifndef INCLUDED_config_h
+#include "config.h"
+#endif
+#ifndef INCLUDED_sys_types_h
+#include <sys/types.h> /* time_t */
+#define INCLUDED_sys_types_h
+#endif
+
+struct Event;
+
+typedef void (*EventCallBack)(struct Event*);
+
+enum SocketState {
+ SS_CONNECTING, /* Connection in progress on socket */
+ SS_LISTENING, /* Socket is a listening socket */
+ SS_CONNECTED, /* Socket is a connected socket */
+ SS_DATAGRAM, /* Socket is a datagram socket */
+ SS_CONNECTDG, /* Socket is a connected datagram socket */
+ SS_NOTSOCK /* Socket isn't a socket at all */
+};
+
+enum TimerType {
+ TT_ABSOLUTE, /* timer that runs at a specific time */
+ TT_RELATIVE, /* timer that runs so many seconds in the future */
+ TT_PERIODIC /* timer that runs periodically */
+};
+
+enum EventType {
+ ET_READ, /* Readable event detected */
+ ET_WRITE, /* Writable event detected */
+ ET_ACCEPT, /* Connection can be accepted */
+ ET_CONNECT, /* Connection completed */
+ ET_EOF, /* End-of-file on connection */
+ ET_ERROR, /* Error condition detected */
+ ET_SIGNAL, /* A signal was received */
+ ET_EXPIRE, /* A timer expired */
+ ET_DESTROY /* The generator is being destroyed */
+};
+
+struct GenHeader {
+ struct GenHeader* gh_next; /* linked list of generators */
+ struct GenHeader** gh_prev_p;
+#ifdef IRCD_THREADED
+ struct GenHeader* gh_qnext; /* linked list of generators in queue */
+ struct GenHeader** gh_qprev_p;
+ struct Event* gh_head; /* head of event queue */
+ struct Event* gh_tail; /* tail of event queue */
+#endif
+ unsigned int gh_flags; /* generator flags */
+ unsigned int gh_ref; /* reference count */
+ EventCallBack gh_call; /* generator callback function */
+ void* gh_data; /* extra data */
+ union {
+ void* ed_ptr; /* engine data == pointer */
+ int ed_int; /* engine data == integer */
+ } gh_engdata;/* engine data */
+};
+
+#define GEN_DESTROY 0x0001 /* generator is to be destroyed */
+#define GEN_MARKED 0x0002 /* generator is marked for destruction */
+#define GEN_ACTIVE 0x0004 /* generator is active */
+
+struct Socket {
+ struct GenHeader s_header; /* generator information */
+ enum SocketState s_state; /* state socket's in */
+ unsigned int s_events; /* events socket is interested in */
+ int s_fd; /* file descriptor for socket */
+};
+
+#define SOCK_EVENT_READABLE 0x0001 /* interested in readable */
+#define SOCK_EVENT_WRITABLE 0x0002 /* interested in writable */
+
+#define SOCK_EVENT_MASK (SOCK_EVENT_READABLE | SOCK_EVENT_WRITABLE)
+
+#define SOCK_ACTION_SET 0x0000 /* set interest set as follows */
+#define SOCK_ACTION_ADD 0x1000 /* add to interest set */
+#define SOCK_ACTION_DEL 0x2000 /* remove from interest set */
+
+#define SOCK_ACTION_MASK 0x3000 /* mask out the actions */
+
+#define s_state(sock) ((sock)->s_state)
+#define s_events(sock) ((sock)->s_events)
+#define s_fd(sock) ((sock)->s_fd)
+#define s_data(sock) ((sock)->s_header.gh_data)
+#define s_ed_int(sock) ((sock)->s_header.gh_engdata.ed_int)
+#define s_ed_ptr(sock) ((sock)->s_header.gh_engdata.ed_ptr)
+#define s_active(sock) ((sock)->s_header.gh_flags & GEN_ACTIVE)
+
+/* Note: The socket state overrides the socket event mask; that is, if
+ * it's an SS_CONNECTING socket, the engine selects its own definition
+ * of what that looks like and ignores s_events. s_events is meaningful
+ * only for SS_CONNECTED, SS_DATAGRAM, and SS_CONNECTDG, but may be set
+ * prior to the state transition, if desired.
+ */
+
+struct Signal {
+ struct GenHeader sig_header; /* generator information */
+ int sig_signal; /* signal number */
+};
+
+#define sig_signal(sig) ((sig)->sig_signal)
+#define sig_data(sig) ((sig)->sig_header.gh_data)
+#define sig_ed_int(sig) ((sig)->sig_header.gh_engdata.ed_int)
+#define sig_ed_ptr(sig) ((sig)->sig_header.gh_engdata.ed_ptr)
+#define sig_active(sig) ((sig)->sig_header.gh_flags & GEN_ACTIVE)
+
+struct Timer {
+ struct GenHeader t_header; /* generator information */
+ enum TimerType t_type; /* what type of timer this is */
+ time_t t_value; /* value timer was added with */
+ time_t t_expire; /* time at which timer expires */
+};
+
+#define t_type(tim) ((tim)->t_type)
+#define t_value(tim) ((tim)->t_value)
+#define t_expire(tim) ((tim)->t_expire)
+#define t_data(tim) ((tim)->t_header.gh_data)
+#define t_ed_int(tim) ((tim)->t_header.gh_engdata.ed_int)
+#define t_ed_ptr(tim) ((tim)->t_header.gh_engdata.ed_ptr)
+#define t_active(tim) ((tim)->t_header.gh_flags & GEN_ACTIVE)
+
+struct Event {
+ struct Event* ev_next; /* linked list of events on queue */
+ struct Event** ev_prev_p;
+ enum EventType ev_type; /* Event type */
+ int ev_data; /* extra data, like errno value */
+ union {
+ struct GenHeader* gen_header; /* Generator header */
+ struct Socket* gen_socket; /* Socket generating event */
+ struct Signal* gen_signal; /* Signal generating event */
+ struct Timer* gen_timer; /* Timer generating event */
+ } ev_gen; /* object generating event */
+};
+
+#define ev_type(ev) ((ev)->ev_type)
+#define ev_data(ev) ((ev)->ev_data)
+#define ev_socket(ev) ((ev)->ev_gen.gen_socket)
+#define ev_signal(ev) ((ev)->ev_gen.gen_signal)
+#define ev_timer(ev) ((ev)->ev_gen.gen_timer)
+
+struct Generators {
+ struct Socket* g_socket; /* list of socket generators */
+ struct Signal* g_signal; /* list of signal generators */
+ struct Timer* g_timer; /* list of timer generators */
+};
+
+/* returns 1 if successfully initialized, 0 if not */
+typedef int (*EngineInit)(int);
+
+/* Tell engine about new signal; set to 0 if engine doesn't know signals */
+typedef void (*EngineSignal)(struct Signal*);
+
+/* Tell engine about new socket */
+typedef int (*EngineAdd)(struct Socket*);
+
+/* Tell engine about socket's new_state */
+typedef void (*EngineState)(struct Socket*, enum SocketState new_state);
+
+/* Tell engine about socket's new_events */
+typedef void (*EngineEvents)(struct Socket*, unsigned int new_events);
+
+/* Tell engine a socket's going away */
+typedef void (*EngineDelete)(struct Socket*);
+
+/* The actual event loop */
+typedef void (*EngineLoop)(struct Generators*);
+
+struct Engine {
+ const char* eng_name; /* a name for the engine */
+ EngineInit eng_init; /* initialize engine */
+ EngineSignal eng_signal; /* express interest in a signal */
+ EngineAdd eng_add; /* express interest in a socket */
+ EngineState eng_state; /* mention a change in state to engine */
+ EngineEvents eng_events; /* express interest in socket events */
+ EngineDelete eng_closing; /* socket is being closed */
+ EngineLoop eng_loop; /* actual event loop */
+};
+
+#define gen_ref_inc(gen) (((struct GenHeader*) (gen))->gh_ref++)
+#define gen_ref_dec(gen) \
+do { \
+ struct GenHeader* _gen = (struct GenHeader*) (gen); \
+ if (!--_gen->gh_ref && (_gen->gh_flags & GEN_DESTROY)) { \
+ gen_dequeue(_gen); \
+ event_generate(ET_DESTROY, _gen, 0); \
+ } \
+} while (0)
+
+void gen_dequeue(void* arg);
+
+void event_init(int max_sockets);
+void event_loop(void);
+void event_generate(enum EventType type, void* arg, int data);
+
+void timer_add(struct Timer* timer, EventCallBack call, void* data,
+ enum TimerType type, time_t value);
+void timer_del(struct Timer* timer);
+void timer_chg(struct Timer* timer, enum TimerType type, time_t value);
+void timer_run(void);
+#define timer_next(gen) ((gen)->g_timer ? (gen)->g_timer->t_expire : 0)
+
+void signal_add(struct Signal* signal, EventCallBack call, void* data,
+ int sig);
+
+int socket_add(struct Socket* sock, EventCallBack call, void* data,
+ enum SocketState state, unsigned int events, int fd);
+void socket_del(struct Socket* sock);
+void socket_state(struct Socket* sock, enum SocketState state);
+void socket_events(struct Socket* sock, unsigned int events);
+
+const char* engine_name(void);
+
+#ifdef DEBUGMODE
+/* These routines pretty-print names for states and types for debug printing */
+
+const char* state_to_name(enum SocketState state);
+const char* timer_to_name(enum TimerType type);
+const char* event_to_name(enum EventType type);
+const char* gen_flags(unsigned int flags);
+const char* sock_flags(unsigned int flags);
+
+#endif /* DEBUGMODE */
+
+#endif /* INCLUDED_ircd_events_h */
extern IOResult os_recvfrom_nonb(int fd, char* buf, unsigned int len,
unsigned int* length_out,
struct sockaddr_in* from_out);
-extern int os_connect_nonb(int fd, const struct sockaddr_in* sin);
+extern IOResult os_connect_nonb(int fd, const struct sockaddr_in* sin);
extern int os_set_fdlimit(unsigned int max_descriptors);
extern int os_set_listen(int fd, int backlog);
extern int os_set_nonblocking(int fd);
#define HEAD_IN_SAND_STATS_R
#define HEAD_IN_SAND_STATS_D
#define HEAD_IN_SAND_STATS_d
+#define HEAD_IN_SAND_STATS_E
#define HEAD_IN_SAND_STATS_t
#define HEAD_IN_SAND_STATS_T
#define HEAD_IN_SAND_STATS_U
#endif
struct Client;
+struct Connection;
struct Channel;
struct ConfItem;
extern struct SLink *find_user_link(struct SLink *lp, struct Client *ptr);
extern void init_list(void);
extern struct Client *make_client(struct Client *from, int status);
+extern void free_connection(struct Connection *con);
extern void free_client(struct Client *cptr);
extern struct Server *make_server(struct Client *cptr);
extern void remove_client_from_list(struct Client *cptr);
#ifndef INCLUDED_ircd_defs_h
#include "ircd_defs.h" /* HOSTLEN */
#endif
+#ifndef INCLUDED_ircd_events_h
+#include "ircd_events.h"
+#endif
#ifndef INCLUDED_sys_types_h
#include <sys/types.h> /* size_t, broken BSD system headers */
#define INCLUDED_sys_types_h
time_t last_accept; /* last time listener accepted */
struct in_addr addr; /* virtual address or INADDR_ANY */
struct in_addr mask; /* listener hostmask */
+ struct Socket socket; /* describe socket to event system */
};
extern struct Listener* ListenerPollList; /* GLOBAL - listener list */
-extern void accept_connection(struct Listener* listener);
extern void add_listener(int port, const char* vaddr_ip,
const char* mask, int is_server,
int is_hidden);
#define RPL_SERVLIST 234 /* unused */
#define RPL_SERVLISTEND 235 /* unused */
+#define RPL_STATSENGINE 237 /* Undernet engine name */
#define RPL_STATSFLINE 238 /* Undernet feature lines */
/* RPL_STATSIAUTH 239 IRCnet extension */
/* RPL_STATSVLINE 240 IRCnet extension */
#include <sys/types.h>
#define INCLUDED_sys_types_h
#endif
+#ifndef INCLUDED_ircd_events_h
+#include "ircd_events.h"
+#endif
struct Client;
struct Client* client; /* pointer to client struct for request */
unsigned int flags; /* current state of request */
int fd; /* file descriptor for auth queries */
- int index; /* select / poll index */
- time_t timeout; /* time when query expires */
+ struct Socket socket; /* socket descriptor for auth queries */
+ struct Timer timeout; /* timeout timer for auth queries */
};
/*
#define AM_AUTH_PENDING 0x02
#define AM_DNS_PENDING 0x04
+#define AM_SOCKET 0x40 /* socket structure not destroyed */
+#define AM_TIMEOUT 0x80 /* timer structure not destroyed */
+
+#define AM_FREE_MASK (AM_SOCKET | AM_TIMEOUT)
+
#define SetDNSPending(x) ((x)->flags |= AM_DNS_PENDING)
#define ClearDNSPending(x) ((x)->flags &= ~AM_DNS_PENDING)
#define IsDNSPending(x) ((x)->flags & AM_DNS_PENDING)
extern struct AuthRequest* AuthPollList; /* GLOBAL - auth queries pending io */
extern void start_auth(struct Client *);
-extern void timeout_auth_queries(time_t now);
extern void read_auth_reply(struct AuthRequest* req);
extern void send_auth_query(struct AuthRequest* req);
-extern void remove_auth_request(struct AuthRequest *req);
+extern void destroy_auth_request(struct AuthRequest *req, int send_reports);
#endif /* INCLUDED_s_auth_h */
extern const char* const CONNECT_ERROR_MSG;
extern const char* const SETBUFS_ERROR_MSG;
extern const char* const TOS_ERROR_MSG;
+extern const char* const REGISTER_ERROR_MSG;
extern int HighestFd;
extern void close_connections(int close_stderr);
extern int init_connection_limits(void);
extern void set_virtual_host(struct in_addr addr);
+extern void update_write(struct Client* cptr);
#endif /* INCLUDED_s_bsd_h */
/*
* defined debugging levels
*/
-#define DEBUG_FATAL 0
-#define DEBUG_ERROR 1 /* report_error() and other errors that are found */
-#define DEBUG_NOTICE 3
-#define DEBUG_DNS 4 /* used by all DNS related routines - a *lot* */
-#define DEBUG_INFO 5 /* general useful info */
-#define DEBUG_NUM 6 /* numerics */
-#define DEBUG_SEND 7 /* everything that is sent out */
-#define DEBUG_DEBUG 8 /* everything that is received */
-#define DEBUG_MALLOC 9 /* malloc/free calls */
-#define DEBUG_LIST 10 /* debug list use */
+#define DEBUG_FATAL 0
+#define DEBUG_ERROR 1 /* report_error() and other errors that are found */
+#define DEBUG_NOTICE 3
+#define DEBUG_DNS 4 /* used by all DNS related routines - a *lot* */
+#define DEBUG_INFO 5 /* general useful info */
+#define DEBUG_NUM 6 /* numerics */
+#define DEBUG_SEND 7 /* everything that is sent out */
+#define DEBUG_DEBUG 8 /* everything that is received */
+#define DEBUG_MALLOC 9 /* malloc/free calls */
+#define DEBUG_LIST 10 /* debug list use */
+#define DEBUG_ENGINE 11 /* debug event engine; can dump gigabyte logs */
/*
* proto types
#ifndef INCLUDED_ircd_defs_h
#include "ircd_defs.h"
#endif
+#ifndef INCLUDED_ircd_events_h
+#include "ircd_events.h"
+#endif
struct Client;
struct ConfItem;
char active; /* ping active flag */
struct Client* client; /* who requested the pings */
time_t lastsent; /* when last ping was sent */
- time_t timeout; /* current ping timeout time */
int ms_min; /* minimum time in milliseconds */
int ms_ave; /* average time in milliseconds */
int ms_max; /* maximum time in milliseconds */
int index; /* index into poll array */
+ struct Socket socket; /* socket structure */
+ struct Timer sender; /* timer telling when next to send a ping */
+ struct Timer killer; /* timer to kill us */
+ unsigned int freeable; /* zero when structure can be free()'d */
char name[HOSTLEN + 1]; /* server name to poing */
char buf[BUFSIZE]; /* buffer to hold ping times */
};
+#define UPING_PENDING_SOCKET 0x01 /* pending socket destruction event */
+#define UPING_PENDING_SENDER 0x02 /* pending sender destruction event */
+#define UPING_PENDING_KILLER 0x04 /* pending killer destruction event */
+
extern int UPingFileDescriptor;
extern int uping_init(void);
#include "msg.h"
#include "numnicks.h" /* NumNick, NumServ (GODMODE) */
#include "ircd_alloc.h"
+#include "ircd_events.h"
#include "s_debug.h" /* Debug */
#include "s_user.h" /* TARGET_DELAY */
#include "send.h"
static struct IPRegistryEntry* hashTable[IP_REGISTRY_TABLE_SIZE];
static struct IPRegistryEntry* freeList = 0;
+static struct Timer expireTimer;
+
static unsigned int ip_registry_hash(unsigned int ip)
{
return ((ip >> 16) ^ ip) & (IP_REGISTRY_TABLE_SIZE - 1);
}
}
-/*
- * ip_registry_expire
- */
-static void ip_registry_expire()
+/* Callback to run an expiry of the IPcheck registry */
+static void ip_registry_expire(struct Event* ev)
{
int i;
struct IPRegistryEntry* entry;
struct IPRegistryEntry* entry_next;
+ assert(ET_EXPIRE == ev_type(ev));
+ assert(0 != ev_timer(ev));
+
for (i = 0; i < IP_REGISTRY_TABLE_SIZE; ++i) {
for (entry = hashTable[i]; entry; entry = entry_next) {
entry_next = entry->next;
}
}
+/*
+ * IPcheck_init()
+ *
+ * Initializes the registry timer
+ */
+void IPcheck_init(void)
+{
+ timer_add(&expireTimer, ip_registry_expire, 0, TT_PERIODIC, 60);
+}
+
/*
* IPcheck_local_connect
*
free_targets = entry->target->count;
tr = " tr";
}
- sendcmdto_one(&me, CMD_NOTICE, cptr, ":on %u ca %u(%u) ft %u(%u)%s",
- entry->connected, entry->attempts, IPCHECK_CLONE_LIMIT,
+ sendcmdto_one(&me, CMD_NOTICE, cptr, "%C :on %u ca %u(%u) ft %u(%u)%s",
+ cptr, entry->connected, entry->attempts, IPCHECK_CLONE_LIMIT,
free_targets, STARTTARGETS, tr);
}
assert(0 != cptr);
return ip_registry_count(cli_ip(cptr).s_addr);
}
-
-void IPcheck_expire()
-{
- static time_t next_expire = 0;
- if (next_expire < CurrentTime) {
- ip_registry_expire();
- next_expire = CurrentTime + 60;
- }
-}
-
-
TOUCH = touch
GREP = grep
OSDEP_C = @OSDEP_C@
+ENGINE_C = @ENGINE_C@
@SET_MAKE@
BINDIR = @bindir@
os_generic.c \
os_solaris.c
+ENGINE_SRC = \
+ engine_devpoll.c \
+ engine_poll.c \
+ engine_kqueue.c \
+ engine_select.c
+
IRCD_SRC = \
IPcheck.c \
channel.c \
hash.c \
ircd.c \
ircd_alloc.c \
+ ircd_events.c \
ircd_features.c \
ircd_log.c \
ircd_relay.c \
whocmds.c \
whowas.c
-SRC = ${IRCD_SRC} ${OSDEP_C}
+SRC = ${IRCD_SRC} ${OSDEP_C} ${ENGINE_C}
OBJS = ${SRC:%.c=%.o}
-DEP_SRC = ${IRCD_SRC} ${OSDEP_SRC}
+DEP_SRC = ${IRCD_SRC} ${OSDEP_SRC} ${ENGINE_SRC}
all:
( cd ..; make -f Makefile )
IPcheck.o: IPcheck.c ../config.h ../include/IPcheck.h \
../include/client.h ../include/ircd_defs.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
- ../include/struct.h ../include/msg.h ../include/numnicks.h \
- ../include/ircd_alloc.h ../include/s_debug.h ../include/s_user.h \
- ../include/send.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/ircd.h ../include/struct.h ../include/msg.h \
+ ../include/numnicks.h ../include/ircd_alloc.h ../include/fda.h \
+ ../include/s_debug.h ../include/s_user.h ../include/send.h
channel.o: channel.c ../config.h ../include/channel.h \
../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
- ../include/ircd_chattr.h ../include/ircd_features.h \
- ../include/ircd_log.h ../include/ircd_reply.h \
- ../include/ircd_snprintf.h ../include/ircd_string.h ../include/list.h \
- ../include/match.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/querycmds.h ../include/s_bsd.h \
- ../include/s_conf.h ../include/s_debug.h ../include/s_misc.h \
- ../include/s_user.h ../include/send.h ../include/sprintf_irc.h \
- ../include/support.h ../include/sys.h ../include/whowas.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_alloc.h ../include/fda.h ../include/ircd_chattr.h \
+ ../include/ircd_features.h ../include/ircd_log.h \
+ ../include/ircd_reply.h ../include/ircd_snprintf.h \
+ ../include/ircd_string.h ../include/list.h ../include/match.h \
+ ../include/msg.h ../include/numeric.h ../include/numnicks.h \
+ ../include/querycmds.h ../include/s_bsd.h ../include/s_conf.h \
+ ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \
+ ../include/send.h ../include/sprintf_irc.h ../include/support.h \
+ ../include/sys.h ../include/whowas.h
class.o: class.c ../config.h ../include/class.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_alloc.h ../include/ircd_features.h \
- ../include/ircd_reply.h ../include/list.h ../include/numeric.h \
- ../include/s_conf.h ../include/s_debug.h ../include/send.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
+ ../include/ircd_features.h ../include/ircd_reply.h ../include/list.h \
+ ../include/numeric.h ../include/s_conf.h ../include/s_debug.h \
+ ../include/send.h
client.o: client.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/class.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_features.h \
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/class.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
../include/ircd_reply.h ../include/list.h ../include/numeric.h \
../include/s_conf.h ../include/s_debug.h ../include/send.h
crule.o: crule.c ../config.h ../include/crule.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_alloc.h ../include/ircd_chattr.h \
- ../include/ircd_string.h ../include/match.h ../include/s_bsd.h \
- ../include/s_debug.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
+ ../include/ircd_chattr.h ../include/ircd_string.h ../include/match.h \
+ ../include/s_bsd.h ../include/s_debug.h
dbuf.o: dbuf.c ../config.h ../include/dbuf.h ../include/ircd_alloc.h \
- ../include/ircd_chattr.h ../include/ircd_features.h ../include/send.h \
- ../include/sys.h
+ ../include/fda.h ../include/ircd_chattr.h ../include/ircd_features.h \
+ ../include/send.h ../include/sys.h
fda.o: fda.c ../config.h
fileio.o: fileio.c ../config.h ../include/fileio.h \
- ../include/ircd_alloc.h
+ ../include/ircd_alloc.h ../include/fda.h
gline.o: gline.c ../config.h ../include/gline.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_alloc.h ../include/ircd_log.h ../include/ircd_reply.h \
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
+ ../include/ircd_log.h ../include/ircd_reply.h \
../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
../include/numeric.h ../include/s_bsd.h ../include/s_debug.h \
../include/s_misc.h ../include/send.h ../include/support.h \
../include/msg.h ../include/numnicks.h ../include/sys.h
hash.o: hash.c ../config.h ../include/hash.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/channel.h \
- ../include/ircd_chattr.h ../include/ircd_string.h ../include/ircd.h \
- ../include/struct.h ../include/msg.h ../include/send.h \
- ../include/support.h ../include/sys.h
+ ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/channel.h ../include/ircd_chattr.h \
+ ../include/ircd_string.h ../include/ircd.h ../include/struct.h \
+ ../include/msg.h ../include/send.h ../include/support.h \
+ ../include/sys.h
ircd.o: ircd.c ../config.h ../include/ircd.h ../include/struct.h \
../include/ircd_defs.h ../include/IPcheck.h ../include/class.h \
../include/client.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/crule.h ../include/hash.h \
- ../include/ircd_alloc.h ../include/ircd_features.h \
- ../include/ircd_log.h ../include/ircd_reply.h \
- ../include/ircd_signal.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/jupe.h ../include/list.h \
- ../include/match.h ../include/motd.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/parse.h \
- ../include/res.h ../include/s_auth.h ../include/s_bsd.h \
- ../include/s_conf.h ../include/s_debug.h ../include/s_misc.h \
- ../include/send.h ../include/sys.h ../include/uping.h \
- ../include/userload.h ../include/version.h ../include/whowas.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/crule.h \
+ ../include/hash.h ../include/ircd_alloc.h ../include/fda.h \
+ ../include/ircd_features.h ../include/ircd_log.h \
+ ../include/ircd_reply.h ../include/ircd_signal.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/jupe.h \
+ ../include/list.h ../include/match.h ../include/motd.h \
+ ../include/msg.h ../include/numeric.h ../include/numnicks.h \
+ ../include/parse.h ../include/res.h ../include/s_auth.h \
+ ../include/s_bsd.h ../include/s_conf.h ../include/s_debug.h \
+ ../include/s_misc.h ../include/send.h ../include/sys.h \
+ ../include/uping.h ../include/userload.h ../include/version.h \
+ ../include/whowas.h
ircd_alloc.o: ircd_alloc.c ../config.h ../include/ircd_alloc.h \
- ../include/ircd_string.h ../include/ircd_chattr.h \
+ ../include/fda.h ../include/ircd_string.h ../include/ircd_chattr.h \
../include/s_debug.h ../include/ircd_defs.h
+ircd_events.o: ircd_events.c ../config.h ../include/ircd_events.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_defs.h \
+ ../include/ircd_alloc.h ../include/fda.h ../include/ircd_log.h \
+ ../include/ircd_snprintf.h ../include/s_debug.h
ircd_features.o: ircd_features.c ../config.h \
../include/ircd_features.h ../include/channel.h \
../include/ircd_defs.h ../include/class.h ../include/client.h \
- ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
- ../include/hash.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_alloc.h ../include/ircd_log.h ../include/ircd_reply.h \
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
+ ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
+ ../include/ircd_log.h ../include/ircd_reply.h \
../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
../include/motd.h ../include/msg.h ../include/numeric.h \
../include/numnicks.h ../include/random.h ../include/s_bsd.h \
../include/support.h ../include/sys.h ../include/whowas.h
ircd_log.o: ircd_log.c ../config.h ../include/ircd_log.h \
../include/client.h ../include/ircd_defs.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/ircd_alloc.h \
- ../include/ircd_reply.h ../include/ircd_snprintf.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/ircd.h \
- ../include/struct.h ../include/numeric.h ../include/s_debug.h \
- ../include/send.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/ircd_alloc.h ../include/fda.h ../include/ircd_reply.h \
+ ../include/ircd_snprintf.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/ircd.h ../include/struct.h \
+ ../include/numeric.h ../include/s_debug.h ../include/send.h
ircd_relay.o: ircd_relay.c ../config.h ../include/ircd_relay.h \
../include/channel.h ../include/ircd_defs.h ../include/client.h \
- ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
- ../include/hash.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_chattr.h ../include/ircd_reply.h \
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
+ ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_chattr.h ../include/ircd_reply.h \
../include/ircd_string.h ../include/match.h ../include/msg.h \
../include/numeric.h ../include/numnicks.h ../include/s_debug.h \
../include/s_misc.h ../include/s_user.h ../include/send.h
ircd_reply.o: ircd_reply.c ../config.h ../include/ircd_reply.h \
../include/client.h ../include/ircd_defs.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_snprintf.h ../include/msg.h \
- ../include/numeric.h ../include/s_conf.h ../include/s_debug.h \
- ../include/send.h
-ircd_signal.o: ircd_signal.c ../config.h ../include/ircd_signal.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_defs.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_snprintf.h \
+ ../include/msg.h ../include/numeric.h ../include/s_conf.h \
+ ../include/s_debug.h ../include/send.h
+ircd_signal.o: ircd_signal.c ../config.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_defs.h ../include/ircd_events.h \
+ ../include/ircd_signal.h ../include/s_conf.h
ircd_snprintf.o: ircd_snprintf.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/channel.h \
- ../include/ircd_snprintf.h ../include/struct.h
+ ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/channel.h ../include/ircd_snprintf.h ../include/struct.h
ircd_string.o: ircd_string.c ../config.h ../include/ircd_string.h \
../include/ircd_chattr.h ../include/ircd_defs.h ../include/ircd_log.h \
chattr.tab.c
ircd_xopen.o: ircd_xopen.c ../config.h ../include/ircd_xopen.h
jupe.o: jupe.c ../config.h ../include/jupe.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_alloc.h ../include/ircd_log.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/match.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_bsd.h \
- ../include/s_misc.h ../include/send.h ../include/support.h \
- ../include/sys.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+ ../include/fda.h ../include/ircd_log.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
+ ../include/msg.h ../include/numeric.h ../include/numnicks.h \
+ ../include/s_bsd.h ../include/s_misc.h ../include/send.h \
+ ../include/support.h ../include/sys.h
list.o: list.c ../config.h ../include/list.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_alloc.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h \
- ../include/listener.h ../include/match.h ../include/numeric.h \
- ../include/res.h ../include/s_bsd.h ../include/s_conf.h \
- ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \
- ../include/send.h ../include/support.h ../include/whowas.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/listener.h ../include/match.h \
+ ../include/numeric.h ../include/res.h ../include/s_auth.h \
+ ../include/s_bsd.h ../include/s_conf.h ../include/s_debug.h \
+ ../include/s_misc.h ../include/s_user.h ../include/send.h \
+ ../include/support.h ../include/whowas.h
listener.o: listener.c ../config.h ../include/listener.h \
- ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_alloc.h \
- ../include/ircd_features.h ../include/ircd_osdep.h \
+ ../include/ircd_defs.h ../include/ircd_events.h ../include/client.h \
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+ ../include/fda.h ../include/ircd_features.h ../include/ircd_osdep.h \
../include/ircd_reply.h ../include/ircd_string.h \
../include/ircd_chattr.h ../include/numeric.h ../include/s_bsd.h \
../include/s_conf.h ../include/s_misc.h ../include/send.h \
../include/sprintf_irc.h ../include/sys.h
m_admin.o: m_admin.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_reply.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \
- ../include/s_user.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+ ../include/msg.h ../include/numeric.h ../include/numnicks.h \
+ ../include/s_conf.h ../include/s_user.h
m_away.o: m_away.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_alloc.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_user.h \
- ../include/send.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/s_user.h ../include/send.h
m_burst.o: m_burst.c ../config.h ../include/channel.h \
../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/list.h ../include/match.h \
- ../include/msg.h ../include/numeric.h ../include/numnicks.h \
- ../include/s_conf.h ../include/s_misc.h ../include/send.h \
- ../include/support.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_alloc.h ../include/fda.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \
+ ../include/match.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/s_conf.h ../include/s_misc.h \
+ ../include/send.h ../include/support.h
m_clearmode.o: m_clearmode.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/channel.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+ ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/channel.h ../include/hash.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
../include/ircd_features.h ../include/ircd_log.h \
../include/ircd_reply.h ../include/ircd_string.h \
../include/ircd_chattr.h ../include/list.h ../include/msg.h \
../include/support.h
m_close.o: m_close.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_reply.h ../include/numeric.h ../include/s_bsd.h \
- ../include/send.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_reply.h ../include/numeric.h \
+ ../include/s_bsd.h ../include/send.h
m_connect.o: m_connect.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/crule.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
- ../include/ircd_log.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/jupe.h \
- ../include/match.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/s_bsd.h ../include/s_conf.h \
- ../include/s_user.h ../include/send.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/crule.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_features.h ../include/ircd_log.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/jupe.h ../include/match.h \
+ ../include/msg.h ../include/numeric.h ../include/numnicks.h \
+ ../include/s_bsd.h ../include/s_conf.h ../include/s_user.h \
+ ../include/send.h
m_cprivmsg.o: m_cprivmsg.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/s_user.h
+ ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/s_user.h
m_create.o: m_create.c ../config.h ../include/channel.h \
../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_debug.h \
- ../include/s_misc.h ../include/s_user.h ../include/send.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/s_debug.h ../include/s_misc.h \
+ ../include/s_user.h ../include/send.h
m_defaults.o: m_defaults.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_reply.h ../include/numeric.h ../include/numnicks.h \
- ../include/send.h ../include/supported.h ../include/channel.h \
- ../include/version.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_reply.h ../include/numeric.h \
+ ../include/numnicks.h ../include/send.h ../include/supported.h \
+ ../include/channel.h ../include/version.h
m_destruct.o: m_destruct.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/send.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/send.h
m_desynch.o: m_desynch.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/s_bsd.h ../include/send.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/s_bsd.h \
+ ../include/send.h
m_die.o: m_die.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
../include/numnicks.h ../include/s_bsd.h ../include/send.h
m_endburst.o: m_endburst.c ../config.h ../include/channel.h \
../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/send.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/send.h
m_error.o: m_error.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_alloc.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_debug.h \
- ../include/s_misc.h ../include/send.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+ ../include/fda.h ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \
+ ../include/s_debug.h ../include/s_misc.h ../include/send.h
m_get.o: m_get.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_features.h \
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
../include/ircd_reply.h ../include/ircd_string.h \
../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \
../include/send.h
m_gline.o: m_gline.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/gline.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/match.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \
- ../include/s_misc.h ../include/send.h ../include/support.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/gline.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_features.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
+ ../include/msg.h ../include/numeric.h ../include/numnicks.h \
+ ../include/s_conf.h ../include/s_misc.h ../include/send.h \
+ ../include/support.h
m_help.o: m_help.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/send.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/send.h
m_info.o: m_info.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
../include/numnicks.h ../include/s_misc.h ../include/s_user.h \
../include/s_conf.h ../include/send.h ../include/version.h
m_invite.o: m_invite.c ../config.h ../include/channel.h \
../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \
- ../include/msg.h ../include/numeric.h ../include/numnicks.h \
- ../include/s_user.h ../include/send.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/list.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/s_user.h \
+ ../include/send.h
m_ison.o: m_ison.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/numeric.h ../include/send.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h \
+ ../include/numeric.h ../include/send.h
m_join.o: m_join.c ../config.h ../include/channel.h \
../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/gline.h \
- ../include/hash.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_chattr.h ../include/ircd_features.h \
- ../include/ircd_reply.h ../include/ircd_string.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_debug.h \
- ../include/s_user.h ../include/send.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/gline.h ../include/hash.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_chattr.h \
+ ../include/ircd_features.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/s_debug.h ../include/s_user.h \
+ ../include/send.h
m_jupe.o: m_jupe.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/jupe.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/match.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \
- ../include/s_misc.h ../include/send.h ../include/support.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/jupe.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_features.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
+ ../include/msg.h ../include/numeric.h ../include/numnicks.h \
+ ../include/s_conf.h ../include/s_misc.h ../include/send.h \
+ ../include/support.h
m_kick.o: m_kick.c ../config.h ../include/channel.h \
../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/send.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/send.h
m_kill.o: m_kill.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_misc.h \
- ../include/send.h ../include/whowas.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_log.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/s_misc.h ../include/send.h \
+ ../include/whowas.h
m_links.o: m_links.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_policy.h ../include/ircd_reply.h \
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_policy.h ../include/ircd_reply.h \
../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
../include/msg.h ../include/numeric.h ../include/numnicks.h \
../include/s_user.h ../include/send.h
m_list.o: m_list.c ../config.h ../include/channel.h \
../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
- ../include/ircd_chattr.h ../include/ircd_features.h \
- ../include/ircd_log.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/send.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_alloc.h ../include/fda.h ../include/ircd_chattr.h \
+ ../include/ircd_features.h ../include/ircd_log.h \
+ ../include/ircd_reply.h ../include/ircd_string.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/s_bsd.h \
+ ../include/send.h
m_lusers.o: m_lusers.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
../include/numnicks.h ../include/querycmds.h \
../include/ircd_features.h ../include/s_user.h ../include/s_serv.h \
../include/send.h
m_map.o: m_map.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_policy.h ../include/ircd_reply.h \
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_policy.h ../include/ircd_reply.h \
../include/ircd_snprintf.h ../include/ircd_string.h \
../include/ircd_chattr.h ../include/list.h ../include/match.h \
../include/msg.h ../include/numeric.h ../include/s_user.h \
../include/ircd_features.h
m_mode.o: m_mode.c ../config.h ../include/handlers.h \
../include/channel.h ../include/ircd_defs.h ../include/client.h \
- ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
- ../include/hash.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
+ ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
../include/numnicks.h ../include/s_conf.h ../include/s_debug.h \
../include/s_user.h ../include/send.h
m_motd.o: m_motd.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
../include/ircd_chattr.h ../include/match.h ../include/motd.h \
../include/msg.h ../include/numeric.h ../include/numnicks.h \
../include/s_conf.h ../include/class.h ../include/s_user.h \
../include/send.h
m_names.o: m_names.c ../config.h ../include/channel.h \
../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_user.h \
- ../include/send.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/s_user.h ../include/send.h
m_nick.o: m_nick.c ../config.h ../include/IPcheck.h \
../include/client.h ../include/ircd_defs.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \
- ../include/ircd_reply.h ../include/ircd_string.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_debug.h \
- ../include/s_misc.h ../include/s_user.h ../include/send.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_chattr.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/s_debug.h ../include/s_misc.h \
+ ../include/s_user.h ../include/send.h
m_notice.o: m_notice.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd_chattr.h \
- ../include/ircd_relay.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/match.h ../include/msg.h \
- ../include/numeric.h ../include/send.h ../include/handlers.h
+ ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/ircd_chattr.h ../include/ircd_relay.h \
+ ../include/ircd_reply.h ../include/ircd_string.h ../include/match.h \
+ ../include/msg.h ../include/numeric.h ../include/send.h \
+ ../include/handlers.h
m_oper.o: m_oper.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_features.h ../include/ircd_log.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/ircd_xopen.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/querycmds.h \
- ../include/s_conf.h ../include/s_debug.h ../include/s_user.h \
- ../include/s_misc.h ../include/send.h ../include/support.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
+ ../include/ircd_log.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h \
+ ../include/ircd_xopen.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/querycmds.h ../include/s_conf.h \
+ ../include/s_debug.h ../include/s_user.h ../include/s_misc.h \
+ ../include/send.h ../include/support.h
m_opmode.o: m_opmode.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/channel.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
+ ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/channel.h ../include/hash.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_features.h \
../include/ircd_reply.h ../include/ircd_string.h \
../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
../include/numnicks.h ../include/send.h
m_part.o: m_part.c ../config.h ../include/channel.h \
../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h \
- ../include/numeric.h ../include/numnicks.h ../include/send.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \
+ ../include/send.h
m_pass.o: m_pass.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/send.h
+ ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/send.h
m_ping.o: m_ping.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/ircd.h \
- ../include/struct.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/s_debug.h ../include/send.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/ircd.h ../include/struct.h \
+ ../include/msg.h ../include/numeric.h ../include/numnicks.h \
+ ../include/s_debug.h ../include/send.h
m_pong.o: m_pong.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/s_user.h ../include/send.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/s_user.h \
+ ../include/send.h
m_privmsg.o: m_privmsg.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_chattr.h ../include/ircd_features.h \
- ../include/ircd_relay.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/match.h ../include/msg.h \
- ../include/numeric.h ../include/send.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_chattr.h \
+ ../include/ircd_features.h ../include/ircd_relay.h \
+ ../include/ircd_reply.h ../include/ircd_string.h ../include/match.h \
+ ../include/msg.h ../include/numeric.h ../include/send.h
m_privs.o: m_privs.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \
- ../include/send.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h \
+ ../include/numeric.h ../include/numnicks.h ../include/send.h
m_proto.o: m_proto.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_alloc.h ../include/ircd_chattr.h \
- ../include/ircd_reply.h ../include/ircd_string.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_debug.h \
- ../include/s_misc.h ../include/send.h ../include/supported.h \
- ../include/channel.h ../include/version.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
+ ../include/ircd_chattr.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/s_debug.h ../include/s_misc.h \
+ ../include/send.h ../include/supported.h ../include/channel.h \
+ ../include/version.h
m_quit.o: m_quit.c ../config.h ../include/channel.h \
../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/struct.h ../include/s_misc.h \
- ../include/ircd_reply.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/struct.h \
+ ../include/s_misc.h ../include/ircd_reply.h
m_rehash.o: m_rehash.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_log.h ../include/ircd_reply.h \
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \
../include/ircd_string.h ../include/ircd_chattr.h ../include/motd.h \
../include/numeric.h ../include/s_conf.h ../include/send.h
m_reset.o: m_reset.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_features.h \
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
../include/ircd_reply.h ../include/ircd_string.h \
../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \
../include/send.h
m_restart.o: m_restart.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_log.h ../include/ircd_reply.h \
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \
../include/ircd_string.h ../include/ircd_chattr.h \
../include/numeric.h ../include/numnicks.h ../include/send.h
m_rping.o: m_rping.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/opercmds.h ../include/s_user.h \
- ../include/send.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/opercmds.h \
+ ../include/s_user.h ../include/send.h
m_rpong.o: m_rpong.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/opercmds.h ../include/send.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/opercmds.h \
+ ../include/send.h
m_server.o: m_server.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_log.h ../include/ircd_features.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/jupe.h ../include/list.h \
- ../include/match.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/querycmds.h ../include/s_bsd.h \
- ../include/s_conf.h ../include/s_debug.h ../include/s_misc.h \
- ../include/s_serv.h ../include/send.h ../include/userload.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_log.h \
+ ../include/ircd_features.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/jupe.h \
+ ../include/list.h ../include/match.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/querycmds.h \
+ ../include/s_bsd.h ../include/s_conf.h ../include/s_debug.h \
+ ../include/s_misc.h ../include/s_serv.h ../include/send.h \
+ ../include/userload.h
m_set.o: m_set.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_features.h \
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
../include/ircd_reply.h ../include/ircd_string.h \
../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \
../include/send.h
m_settime.o: m_settime.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_features.h \
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
+ ../include/ircd_reply.h ../include/ircd_snprintf.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \
+ ../include/msg.h ../include/numeric.h ../include/numnicks.h \
+ ../include/s_user.h ../include/send.h
+m_silence.o: m_silence.c ../config.h ../include/channel.h \
+ ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
../include/ircd_reply.h ../include/ircd_string.h \
../include/ircd_chattr.h ../include/list.h ../include/msg.h \
../include/numeric.h ../include/numnicks.h ../include/s_user.h \
../include/send.h
-m_silence.o: m_silence.c ../config.h ../include/channel.h \
- ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \
- ../include/msg.h ../include/numeric.h ../include/numnicks.h \
- ../include/s_user.h ../include/send.h
m_squit.o: m_squit.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_chattr.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/numeric.h ../include/numnicks.h \
- ../include/match.h ../include/s_debug.h ../include/s_misc.h \
- ../include/s_user.h ../include/send.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \
+ ../include/ircd_reply.h ../include/ircd_string.h ../include/numeric.h \
+ ../include/numnicks.h ../include/match.h ../include/s_debug.h \
+ ../include/s_misc.h ../include/s_user.h ../include/send.h
m_stats.o: m_stats.c ../config.h ../include/handlers.h \
../include/s_stats.h ../include/channel.h ../include/ircd_defs.h \
../include/class.h ../include/client.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/gline.h \
- ../include/hash.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_alloc.h ../include/ircd_chattr.h \
- ../include/ircd_features.h ../include/ircd_policy.h \
- ../include/ircd_reply.h ../include/ircd_string.h ../include/list.h \
- ../include/listener.h ../include/match.h ../include/motd.h \
- ../include/msg.h ../include/numeric.h ../include/numnicks.h \
- ../include/opercmds.h ../include/s_bsd.h ../include/s_conf.h \
- ../include/s_debug.h ../include/s_misc.h ../include/s_serv.h \
- ../include/s_user.h ../include/send.h ../include/userload.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/gline.h ../include/hash.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
+ ../include/ircd_chattr.h ../include/ircd_features.h \
+ ../include/ircd_policy.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/list.h ../include/listener.h \
+ ../include/match.h ../include/motd.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/opercmds.h \
+ ../include/s_bsd.h ../include/s_conf.h ../include/s_debug.h \
+ ../include/s_misc.h ../include/s_serv.h ../include/s_user.h \
+ ../include/send.h ../include/userload.h
m_time.o: m_time.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
../include/numnicks.h ../include/s_misc.h ../include/s_user.h \
../include/send.h
m_topic.o: m_topic.c ../config.h ../include/channel.h \
../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/send.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/send.h
m_trace.o: m_trace.c ../config.h ../include/class.h \
../include/client.h ../include/ircd_defs.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/match.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/s_bsd.h \
+ ../include/s_conf.h ../include/s_user.h ../include/send.h \
+ ../include/version.h
+m_uping.o: m_uping.c ../config.h ../include/client.h \
+ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
../include/msg.h ../include/numeric.h ../include/numnicks.h \
- ../include/s_bsd.h ../include/s_conf.h ../include/s_user.h \
- ../include/send.h ../include/version.h
-m_uping.o: m_uping.c ../config.h ../include/client.h \
- ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/match.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \
- ../include/s_user.h ../include/send.h ../include/uping.h
+ ../include/s_conf.h ../include/s_user.h ../include/send.h \
+ ../include/uping.h
m_user.o: m_user.c ../config.h ../include/handlers.h \
../include/client.h ../include/ircd_defs.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_chattr.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/numeric.h ../include/numnicks.h \
- ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \
- ../include/send.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \
+ ../include/ircd_reply.h ../include/ircd_string.h ../include/numeric.h \
+ ../include/numnicks.h ../include/s_debug.h ../include/s_misc.h \
+ ../include/s_user.h ../include/send.h
m_userhost.o: m_userhost.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h \
- ../include/numeric.h ../include/s_user.h ../include/struct.h
+ ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/numeric.h ../include/s_user.h \
+ ../include/struct.h
m_userip.o: m_userip.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h \
- ../include/numeric.h ../include/s_user.h ../include/struct.h
+ ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/numeric.h ../include/s_user.h \
+ ../include/struct.h
m_version.o: m_version.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_features.h \
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
../include/ircd_reply.h ../include/ircd_string.h \
../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
../include/numnicks.h ../include/s_debug.h ../include/s_user.h \
../include/version.h
m_wallchops.o: m_wallchops.c ../config.h ../include/channel.h \
../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_user.h \
- ../include/send.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/s_user.h ../include/send.h
m_wallops.o: m_wallops.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
- ../include/numeric.h ../include/send.h
+ ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+ ../include/send.h
m_wallusers.o: m_wallusers.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
- ../include/numeric.h ../include/send.h
+ ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+ ../include/send.h
m_who.o: m_who.c ../config.h ../include/channel.h \
../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \
- ../include/ircd_log.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/match.h ../include/numeric.h \
- ../include/numnicks.h ../include/send.h ../include/support.h \
- ../include/whocmds.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_chattr.h ../include/ircd_log.h \
+ ../include/ircd_reply.h ../include/ircd_string.h ../include/match.h \
+ ../include/numeric.h ../include/numnicks.h ../include/send.h \
+ ../include/support.h ../include/whocmds.h
m_whois.o: m_whois.c ../config.h ../include/channel.h \
../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_policy.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/match.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_user.h \
- ../include/send.h ../include/whocmds.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_policy.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
+ ../include/msg.h ../include/numeric.h ../include/numnicks.h \
+ ../include/s_user.h ../include/send.h ../include/whocmds.h
m_whowas.o: m_whowas.c ../config.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/s_user.h ../include/s_misc.h \
- ../include/send.h ../include/whowas.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/s_user.h \
+ ../include/s_misc.h ../include/send.h ../include/whowas.h
match.o: match.c ../config.h ../include/match.h \
../include/ircd_chattr.h
motd.o: motd.c ../config.h ../include/motd.h ../include/class.h \
../include/client.h ../include/ircd_defs.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/fileio.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
- ../include/ircd_features.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
- ../include/msg.h ../include/numeric.h ../include/numnicks.h \
- ../include/s_conf.h ../include/s_debug.h ../include/s_user.h \
- ../include/send.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/fileio.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_alloc.h ../include/fda.h ../include/ircd_features.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/match.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \
+ ../include/s_debug.h ../include/s_user.h ../include/send.h
msgq.o: msgq.c ../config.h ../include/msgq.h ../include/ircd_defs.h \
- ../include/ircd_alloc.h ../include/ircd_snprintf.h \
+ ../include/ircd_alloc.h ../include/fda.h ../include/ircd_snprintf.h \
../include/s_debug.h
numnicks.o: numnicks.c ../config.h ../include/numnicks.h \
../include/client.h ../include/ircd_defs.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_alloc.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/match.h ../include/s_bsd.h \
- ../include/s_debug.h ../include/s_misc.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+ ../include/fda.h ../include/ircd_string.h ../include/ircd_chattr.h \
+ ../include/match.h ../include/s_bsd.h ../include/s_debug.h \
+ ../include/s_misc.h
opercmds.o: opercmds.c ../config.h ../include/opercmds.h \
../include/class.h ../include/client.h ../include/ircd_defs.h \
- ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/listener.h ../include/match.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \
- ../include/send.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
+ ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_chattr.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/listener.h ../include/match.h \
+ ../include/msg.h ../include/numeric.h ../include/numnicks.h \
+ ../include/s_conf.h ../include/send.h
packet.o: packet.c ../config.h ../include/packet.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_chattr.h ../include/parse.h ../include/s_bsd.h \
- ../include/s_misc.h ../include/send.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_chattr.h ../include/parse.h \
+ ../include/s_bsd.h ../include/s_misc.h ../include/send.h
parse.o: parse.c ../config.h ../include/parse.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/channel.h ../include/handlers.h \
- ../include/hash.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_alloc.h ../include/ircd_chattr.h \
- ../include/ircd_features.h ../include/ircd_policy.h \
- ../include/ircd_reply.h ../include/ircd_string.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/opercmds.h \
- ../include/querycmds.h ../include/res.h ../include/s_bsd.h \
- ../include/s_conf.h ../include/s_debug.h ../include/s_misc.h \
- ../include/s_numeric.h ../include/s_user.h ../include/send.h \
- ../include/sys.h ../include/whocmds.h ../include/whowas.h
+ ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/channel.h ../include/handlers.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+ ../include/fda.h ../include/ircd_chattr.h ../include/ircd_features.h \
+ ../include/ircd_policy.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/msg.h ../include/numeric.h \
+ ../include/numnicks.h ../include/opercmds.h ../include/querycmds.h \
+ ../include/res.h ../include/s_bsd.h ../include/s_conf.h \
+ ../include/s_debug.h ../include/s_misc.h ../include/s_numeric.h \
+ ../include/s_user.h ../include/send.h ../include/sys.h \
+ ../include/whocmds.h ../include/whowas.h
querycmds.o: querycmds.c ../config.h ../include/querycmds.h \
../include/ircd_features.h
random.o: random.c ../config.h ../include/random.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd_log.h \
- ../include/ircd_reply.h ../include/send.h
+ ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/ircd_log.h ../include/ircd_reply.h ../include/send.h
res.o: res.c ../config.h ../include/res.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_alloc.h ../include/ircd_log.h ../include/ircd_osdep.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
- ../include/s_bsd.h ../include/s_debug.h ../include/s_misc.h \
- ../include/send.h ../include/sprintf_irc.h ../include/support.h \
- ../include/sys.h
-s_auth.o: s_auth.c ../config.h ../include/s_auth.h ../include/client.h \
- ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/IPcheck.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_alloc.h ../include/ircd_chattr.h \
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
+ ../include/ircd_log.h ../include/ircd_osdep.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
+ ../include/numeric.h ../include/s_bsd.h ../include/s_debug.h \
+ ../include/s_misc.h ../include/send.h ../include/sprintf_irc.h \
+ ../include/support.h ../include/sys.h
+s_auth.o: s_auth.c ../config.h ../include/s_auth.h \
+ ../include/ircd_events.h ../include/client.h ../include/ircd_defs.h \
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+ ../include/IPcheck.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_alloc.h ../include/fda.h ../include/ircd_chattr.h \
../include/ircd_features.h ../include/ircd_log.h \
../include/ircd_osdep.h ../include/ircd_string.h ../include/list.h \
../include/numeric.h ../include/querycmds.h ../include/res.h \
../include/send.h ../include/sprintf_irc.h ../include/sys.h
s_bsd.o: s_bsd.c ../config.h ../include/s_bsd.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/IPcheck.h ../include/channel.h \
- ../include/class.h ../include/hash.h ../include/ircd_log.h \
- ../include/ircd_features.h ../include/ircd_osdep.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/ircd.h ../include/struct.h \
- ../include/list.h ../include/listener.h ../include/msg.h \
- ../include/numeric.h ../include/numnicks.h ../include/packet.h \
- ../include/parse.h ../include/querycmds.h ../include/res.h \
- ../include/s_auth.h ../include/s_conf.h ../include/s_debug.h \
- ../include/s_misc.h ../include/s_user.h ../include/send.h \
- ../include/sprintf_irc.h ../include/support.h ../include/sys.h \
- ../include/uping.h ../include/version.h
+ ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/IPcheck.h ../include/channel.h ../include/class.h \
+ ../include/hash.h ../include/ircd_log.h ../include/ircd_features.h \
+ ../include/ircd_osdep.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h ../include/ircd.h \
+ ../include/struct.h ../include/list.h ../include/listener.h \
+ ../include/msg.h ../include/numeric.h ../include/numnicks.h \
+ ../include/packet.h ../include/parse.h ../include/querycmds.h \
+ ../include/res.h ../include/s_auth.h ../include/s_conf.h \
+ ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \
+ ../include/send.h ../include/sprintf_irc.h ../include/support.h \
+ ../include/sys.h ../include/uping.h ../include/version.h
s_conf.o: s_conf.c ../config.h ../include/s_conf.h \
../include/IPcheck.h ../include/class.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/crule.h \
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/crule.h \
../include/ircd_features.h ../include/fileio.h ../include/gline.h \
../include/hash.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_alloc.h ../include/ircd_chattr.h \
+ ../include/ircd_alloc.h ../include/fda.h ../include/ircd_chattr.h \
../include/ircd_log.h ../include/ircd_reply.h \
../include/ircd_snprintf.h ../include/ircd_string.h ../include/list.h \
../include/listener.h ../include/match.h ../include/motd.h \
s_debug.o: s_debug.c ../config.h ../include/s_debug.h \
../include/ircd_defs.h ../include/channel.h ../include/class.h \
../include/client.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd_alloc.h \
- ../include/ircd_features.h ../include/ircd_log.h \
- ../include/ircd_osdep.h ../include/ircd_reply.h ../include/ircd.h \
- ../include/struct.h ../include/list.h ../include/numeric.h \
- ../include/numnicks.h ../include/res.h ../include/s_bsd.h \
- ../include/s_conf.h ../include/send.h ../include/sys.h \
- ../include/whowas.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd_alloc.h ../include/fda.h ../include/ircd_features.h \
+ ../include/ircd_log.h ../include/ircd_osdep.h ../include/ircd_reply.h \
+ ../include/ircd.h ../include/struct.h ../include/list.h \
+ ../include/numeric.h ../include/numnicks.h ../include/res.h \
+ ../include/s_bsd.h ../include/s_conf.h ../include/send.h \
+ ../include/sys.h ../include/whowas.h
s_err.o: s_err.c ../config.h ../include/numeric.h ../include/s_debug.h \
../include/ircd_defs.h ../include/sprintf_irc.h
s_misc.o: s_misc.c ../config.h ../include/s_misc.h \
../include/IPcheck.h ../include/channel.h ../include/ircd_defs.h \
../include/client.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
- ../include/struct.h ../include/ircd_alloc.h ../include/ircd_log.h \
- ../include/ircd_policy.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \
- ../include/match.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/parse.h ../include/querycmds.h \
- ../include/ircd_features.h ../include/res.h ../include/s_bsd.h \
- ../include/s_conf.h ../include/s_debug.h ../include/s_user.h \
- ../include/send.h ../include/sprintf_irc.h ../include/support.h \
- ../include/sys.h ../include/uping.h ../include/userload.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+ ../include/fda.h ../include/ircd_log.h ../include/ircd_policy.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/list.h ../include/match.h \
+ ../include/msg.h ../include/numeric.h ../include/numnicks.h \
+ ../include/parse.h ../include/querycmds.h ../include/ircd_features.h \
+ ../include/res.h ../include/s_bsd.h ../include/s_conf.h \
+ ../include/s_debug.h ../include/s_user.h ../include/send.h \
+ ../include/sprintf_irc.h ../include/support.h ../include/sys.h \
+ ../include/uping.h ../include/userload.h
s_numeric.o: s_numeric.c ../config.h ../include/s_numeric.h \
../include/channel.h ../include/ircd_defs.h ../include/client.h \
- ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
- ../include/hash.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_snprintf.h ../include/numnicks.h ../include/send.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
+ ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_snprintf.h ../include/numnicks.h \
+ ../include/send.h
s_serv.o: s_serv.c ../config.h ../include/s_serv.h \
../include/IPcheck.h ../include/channel.h ../include/ircd_defs.h \
../include/client.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/gline.h ../include/hash.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
- ../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/ircd_snprintf.h \
- ../include/ircd_xopen.h ../include/jupe.h ../include/list.h \
- ../include/match.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/parse.h ../include/querycmds.h \
- ../include/ircd_features.h ../include/s_bsd.h ../include/s_conf.h \
- ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \
- ../include/send.h ../include/sprintf_irc.h ../include/sys.h \
- ../include/userload.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/gline.h \
+ ../include/hash.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_alloc.h ../include/fda.h ../include/ircd_reply.h \
+ ../include/ircd_string.h ../include/ircd_chattr.h \
+ ../include/ircd_snprintf.h ../include/ircd_xopen.h ../include/jupe.h \
+ ../include/list.h ../include/match.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/parse.h \
+ ../include/querycmds.h ../include/ircd_features.h ../include/s_bsd.h \
+ ../include/s_conf.h ../include/s_debug.h ../include/s_misc.h \
+ ../include/s_user.h ../include/send.h ../include/sprintf_irc.h \
+ ../include/sys.h ../include/userload.h
s_stats.o: s_stats.c ../config.h ../include/s_stats.h \
../include/class.h ../include/client.h ../include/ircd_defs.h \
- ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \
- ../include/ircd_log.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/listener.h ../include/match.h \
- ../include/msg.h ../include/numeric.h ../include/numnicks.h \
- ../include/s_conf.h ../include/s_user.h ../include/send.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
+ ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_chattr.h ../include/ircd_log.h \
+ ../include/ircd_reply.h ../include/ircd_string.h \
+ ../include/listener.h ../include/match.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \
+ ../include/s_user.h ../include/send.h
s_user.o: s_user.c ../config.h ../include/s_user.h \
../include/IPcheck.h ../include/channel.h ../include/ircd_defs.h \
../include/class.h ../include/client.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/gline.h \
- ../include/hash.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_alloc.h ../include/ircd_chattr.h \
- ../include/ircd_features.h ../include/ircd_log.h \
- ../include/ircd_policy.h ../include/ircd_reply.h \
- ../include/ircd_string.h ../include/list.h ../include/match.h \
- ../include/motd.h ../include/msg.h ../include/numeric.h \
- ../include/numnicks.h ../include/parse.h ../include/querycmds.h \
- ../include/random.h ../include/s_bsd.h ../include/s_conf.h \
- ../include/s_debug.h ../include/s_misc.h ../include/s_serv.h \
- ../include/send.h ../include/sprintf_irc.h ../include/support.h \
- ../include/supported.h ../include/sys.h ../include/userload.h \
- ../include/version.h ../include/whowas.h ../include/handlers.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/gline.h ../include/hash.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
+ ../include/ircd_chattr.h ../include/ircd_features.h \
+ ../include/ircd_log.h ../include/ircd_policy.h \
+ ../include/ircd_reply.h ../include/ircd_string.h ../include/list.h \
+ ../include/match.h ../include/motd.h ../include/msg.h \
+ ../include/numeric.h ../include/numnicks.h ../include/parse.h \
+ ../include/querycmds.h ../include/random.h ../include/s_bsd.h \
+ ../include/s_conf.h ../include/s_debug.h ../include/s_misc.h \
+ ../include/s_serv.h ../include/send.h ../include/sprintf_irc.h \
+ ../include/support.h ../include/supported.h ../include/sys.h \
+ ../include/userload.h ../include/version.h ../include/whowas.h \
+ ../include/handlers.h
send.o: send.c ../config.h ../include/send.h ../include/channel.h \
../include/ircd_defs.h ../include/class.h ../include/client.h \
- ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
- ../include/ircd.h ../include/struct.h ../include/ircd_snprintf.h \
- ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \
- ../include/match.h ../include/msg.h ../include/numnicks.h \
- ../include/s_bsd.h ../include/s_debug.h ../include/s_misc.h \
- ../include/s_user.h ../include/sprintf_irc.h ../include/sys.h
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
+ ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_snprintf.h ../include/ircd_string.h \
+ ../include/ircd_chattr.h ../include/list.h ../include/match.h \
+ ../include/msg.h ../include/numnicks.h ../include/s_bsd.h \
+ ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \
+ ../include/sprintf_irc.h ../include/sys.h
sprintf_irc.o: sprintf_irc.c ../config.h ../include/sprintf_irc.h \
../include/sys.h
support.o: support.c ../config.h ../include/support.h \
../include/ircd_snprintf.h ../include/s_bsd.h ../include/s_debug.h \
../include/send.h ../include/sprintf_irc.h ../include/sys.h
uping.o: uping.c ../config.h ../include/uping.h ../include/ircd_defs.h \
- ../include/client.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_alloc.h ../include/ircd_log.h ../include/ircd_osdep.h \
+ ../include/ircd_events.h ../include/client.h ../include/dbuf.h \
+ ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
+ ../include/ircd_log.h ../include/ircd_osdep.h \
../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
../include/msg.h ../include/numeric.h ../include/numnicks.h \
../include/s_bsd.h ../include/s_conf.h ../include/s_debug.h \
../include/sys.h
userload.o: userload.c ../config.h ../include/userload.h \
../include/client.h ../include/ircd_defs.h ../include/dbuf.h \
- ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
- ../include/struct.h ../include/msg.h ../include/numnicks.h \
- ../include/querycmds.h ../include/ircd_features.h ../include/s_misc.h \
- ../include/send.h ../include/sys.h
+ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+ ../include/ircd.h ../include/struct.h ../include/msg.h \
+ ../include/numnicks.h ../include/querycmds.h \
+ ../include/ircd_features.h ../include/s_misc.h ../include/send.h \
+ ../include/sys.h
whocmds.o: whocmds.c ../config.h ../include/whocmds.h \
../include/channel.h ../include/ircd_defs.h ../include/client.h \
- ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
- ../include/hash.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_chattr.h ../include/ircd_reply.h \
+ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
+ ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_chattr.h ../include/ircd_reply.h \
../include/ircd_string.h ../include/list.h ../include/match.h \
../include/numeric.h ../include/numnicks.h ../include/querycmds.h \
../include/ircd_features.h ../include/random.h ../include/s_bsd.h \
../include/whowas.h ../include/msg.h
whowas.o: whowas.c ../config.h ../include/whowas.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
- ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
- ../include/ircd_alloc.h ../include/ircd_chattr.h \
- ../include/ircd_features.h ../include/ircd_string.h ../include/list.h \
- ../include/numeric.h ../include/s_debug.h ../include/s_misc.h \
- ../include/s_user.h ../include/send.h ../include/support.h \
- ../include/sys.h ../include/msg.h
+ ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
+ ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \
+ ../include/ircd_chattr.h ../include/ircd_features.h \
+ ../include/ircd_string.h ../include/list.h ../include/numeric.h \
+ ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \
+ ../include/send.h ../include/support.h ../include/sys.h \
+ ../include/msg.h
os_bsd.o: os_bsd.c ../config.h ../include/ircd_osdep.h \
../include/msgq.h ../include/ircd_defs.h
os_linux.o: os_linux.c ../config.h ../include/ircd_osdep.h \
../include/msgq.h ../include/ircd_defs.h
os_solaris.o: os_solaris.c ../config.h ../include/ircd_osdep.h \
../include/msgq.h ../include/ircd_defs.h
+engine_devpoll.o: engine_devpoll.c ../config.h \
+ ../include/ircd_events.h ../include/ircd.h ../include/struct.h \
+ ../include/ircd_defs.h ../include/ircd_alloc.h ../include/fda.h \
+ ../include/ircd_log.h ../include/s_debug.h
+engine_poll.o: engine_poll.c ../config.h ../include/ircd_events.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_defs.h \
+ ../include/ircd_alloc.h ../include/fda.h ../include/ircd_log.h \
+ ../include/s_debug.h
+engine_kqueue.o: engine_kqueue.c ../config.h ../include/ircd_events.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_defs.h \
+ ../include/ircd_alloc.h ../include/fda.h ../include/ircd_log.h \
+ ../include/s_debug.h
+engine_select.o: engine_select.c ../config.h ../include/ircd_events.h \
+ ../include/ircd.h ../include/struct.h ../include/ircd_defs.h \
+ ../include/ircd_log.h ../include/s_debug.h
(cli_listing(cptr))->chptr = chptr;
chptr->mode.mode |= MODE_LISTED;
}
+
+ update_write(cptr);
}
/*
--- /dev/null
+/*
+ * IRC - Internet Relay Chat, ircd/engine_devpoll.c
+ * Copyright (C) 2001 Kevin L. Mitchell <klmitch@mit.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ */
+#include "config.h"
+
+#include "ircd_events.h"
+
+#include "ircd.h"
+#include "ircd_alloc.h"
+#include "ircd_log.h"
+#include "s_debug.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/devpoll.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#define DEVPOLL_ERROR_THRESHOLD 20 /* after 20 devpoll errors, restart */
+#define ERROR_EXPIRE_TIME 3600 /* expire errors after an hour */
+
+#define POLLS_PER_DEVPOLL 20 /* get 20 pollfd's per turn */
+
+/* Figure out what bits to set for read */
+#if defined(POLLMSG) && defined(POLLIN) && defined(POLLRDNORM)
+# define POLLREADFLAGS (POLLMSG|POLLIN|POLLRDNORM)
+#elif defined(POLLIN) && defined(POLLRDNORM)
+# define POLLREADFLAGS (POLLIN|POLLRDNORM)
+#elif defined(POLLIN)
+# define POLLREADFLAGS POLLIN
+#elif defined(POLLRDNORM)
+# define POLLREADFLAGS POLLRDNORM
+#endif
+
+/* Figure out what bits to set for write */
+#if defined(POLLOUT) && defined(POLLWRNORM)
+# define POLLWRITEFLAGS (POLLOUT|POLLWRNORM)
+#elif defined(POLLOUT)
+# define POLLWRITEFLAGS POLLOUT
+#elif defined(POLLWRNORM)
+# define POLLWRITEFLAGS POLLWRNORM
+#endif
+
+/* Figure out what bits indicate errors */
+#ifdef POLLHUP
+# define POLLERRORS (POLLHUP|POLLERR)
+#else
+# define POLLERRORS POLLERR
+#endif
+
+static struct Socket** sockList;
+static int devpoll_max;
+static int devpoll_fd;
+
+static int errors = 0;
+static struct Timer clear_error;
+
+/* decrements the error count once per hour */
+static void
+error_clear(struct Event* ev)
+{
+ if (!--errors) /* remove timer when error count reaches 0 */
+ timer_del(ev_timer(ev));
+}
+
+/* initialize the devpoll engine */
+static int
+engine_init(int max_sockets)
+{
+ int i;
+
+ if ((devpoll_fd = open("/dev/poll", O_RDWR)) < 0) {
+ log_write(LS_SYSTEM, L_WARNING, 0,
+ "/dev/poll engine cannot open device: %m");
+ return 0; /* engine cannot be initialized; defer */
+ }
+
+ /* allocate necessary memory */
+ sockList = (struct Socket**) MyMalloc(sizeof(struct Socket*) * max_sockets);
+
+ /* initialize the data */
+ for (i = 0; i < max_sockets; i++)
+ sockList[i] = 0;
+
+ devpoll_max = max_sockets; /* number of sockets allocated */
+
+ return 1;
+}
+
+/* Figure out what events go with a given state */
+static unsigned int
+state_to_events(enum SocketState state, unsigned int events)
+{
+ switch (state) {
+ case SS_CONNECTING: /* connecting socket */
+ return SOCK_EVENT_WRITABLE;
+ break;
+
+ case SS_LISTENING: /* listening socket */
+ case SS_NOTSOCK: /* our signal socket */
+ return SOCK_EVENT_READABLE;
+ break;
+
+ case SS_CONNECTED: case SS_DATAGRAM: case SS_CONNECTDG:
+ return events; /* ordinary socket */
+ break;
+ }
+
+ /*NOTREACHED*/
+ return 0;
+}
+
+/* Reset the desired events */
+static void
+set_events(struct Socket* sock, unsigned int events)
+{
+ struct pollfd pfd;
+
+ pfd.fd = s_fd(sock);
+
+ if (s_ed_int(sock)) { /* is one in /dev/poll already? */
+ pfd.events = POLLREMOVE; /* First, remove old pollfd */
+
+ Debug((DEBUG_ENGINE, "devpoll: Removing old entry for socket %d [%p]",
+ s_fd(sock), sock));
+
+ if (write(devpoll_fd, &pfd, sizeof(pfd)) != sizeof(pfd)) {
+ event_generate(ET_ERROR, sock, errno); /* report error */
+ return;
+ }
+
+ s_ed_int(sock) = 0; /* mark that it's gone */
+ }
+
+ if (!(events & SOCK_EVENT_MASK)) /* no events, so stop here */
+ return;
+
+ pfd.events = 0; /* Now, set up new pollfd... */
+ if (events & SOCK_EVENT_READABLE)
+ pfd.events |= POLLREADFLAGS; /* look for readable conditions */
+ if (events & SOCK_EVENT_WRITABLE)
+ pfd.events |= POLLWRITEFLAGS; /* look for writable conditions */
+
+ Debug((DEBUG_ENGINE, "devpoll: Registering interest on %d [%p] (state %s, "
+ "mask [%s])", s_fd(sock), sock, state_to_name(s_state(sock)),
+ sock_flags(s_events(sock))));
+
+ if (write(devpoll_fd, &pfd, sizeof(pfd)) != sizeof(pfd)) {
+ event_generate(ET_ERROR, sock, errno); /* report error */
+ return;
+ }
+
+ s_ed_int(sock) = 1; /* mark that we've added a pollfd */
+}
+
+/* add a socket to be listened on */
+static int
+engine_add(struct Socket* sock)
+{
+ assert(0 != sock);
+ assert(0 == sockList[s_fd(sock)]);
+
+ /* bounds-check... */
+ if (s_fd(sock) >= devpoll_max) {
+ log_write(LS_SYSTEM, L_ERROR, 0,
+ "Attempt to add socket %d (> %d) to event engine", s_fd(sock),
+ devpoll_max);
+ return 0;
+ }
+
+ sockList[s_fd(sock)] = sock; /* add to list */
+
+ Debug((DEBUG_ENGINE, "devpoll: Adding socket %d [%p], state %s, to engine",
+ s_fd(sock), sock, state_to_name(s_state(sock))));
+
+ /* set the correct events */
+ set_events(sock, state_to_events(s_state(sock), s_events(sock)));
+
+ return 1; /* success */
+}
+
+/* socket switching to new state */
+static void
+engine_state(struct Socket* sock, enum SocketState new_state)
+{
+ assert(0 != sock);
+ assert(sock == sockList[s_fd(sock)]);
+
+ Debug((DEBUG_ENGINE, "devpoll: Changing state for socket %p to %s", sock,
+ state_to_name(new_state)));
+
+ /* set the correct events */
+ set_events(sock, state_to_events(new_state, s_events(sock)));
+}
+
+/* socket events changing */
+static void
+engine_events(struct Socket* sock, unsigned int new_events)
+{
+ assert(0 != sock);
+ assert(sock == sockList[s_fd(sock)]);
+
+ Debug((DEBUG_ENGINE, "devpoll: Changing event mask for socket %p to [%s]",
+ sock, sock_flags(new_events)));
+
+ /* set the correct events */
+ set_events(sock, state_to_events(s_state(sock), new_events));
+}
+
+/* socket going away */
+static void
+engine_delete(struct Socket* sock)
+{
+ assert(0 != sock);
+ assert(sock == sockList[s_fd(sock)]);
+
+ Debug((DEBUG_ENGINE, "devpoll: Deleting socket %d [%p], state %s",
+ s_fd(sock), sock, state_to_name(s_state(sock))));
+
+ set_events(sock, 0); /* get rid of the socket */
+
+ sockList[s_fd(sock)] = 0; /* zero the socket list entry */
+}
+
+/* engine event loop */
+static void
+engine_loop(struct Generators* gen)
+{
+ struct dvpoll dopoll;
+ struct pollfd polls[POLLS_PER_DEVPOLL];
+ struct Socket* sock;
+ int nfds;
+ int i;
+ int errcode;
+ size_t codesize;
+
+ while (running) {
+ dopoll.dp_fds = polls; /* set up the struct dvpoll */
+ dopoll.dp_nfds = POLLS_PER_DEVPOLL;
+
+ /* calculate the proper timeout */
+ dopoll.dp_timeout = timer_next(gen) ?
+ (timer_next(gen) - CurrentTime) * 1000 : -1;
+
+ Debug((DEBUG_INFO, "devpoll: delay: %Tu (%Tu) %d", timer_next(gen),
+ CurrentTime, dopoll.dp_timeout));
+
+ /* check for active files */
+ nfds = ioctl(devpoll_fd, DP_POLL, &dopoll);
+
+ CurrentTime = time(0); /* set current time... */
+
+ if (nfds < 0) {
+ if (errno != EINTR) { /* ignore interrupts */
+ /* Log the poll error */
+ log_write(LS_SOCKET, L_ERROR, 0, "ioctl(DP_POLL) error: %m");
+ if (!errors++)
+ timer_add(&clear_error, error_clear, 0, TT_PERIODIC,
+ ERROR_EXPIRE_TIME);
+ else if (errors > DEVPOLL_ERROR_THRESHOLD) /* too many errors... */
+ server_restart("too many /dev/poll errors");
+ }
+ /* old code did a sleep(1) here; with usage these days,
+ * that may be too expensive
+ */
+ continue;
+ }
+
+ for (i = 0; i < nfds; i++) {
+ assert(-1 < polls[i].fd);
+ assert(0 != sockList[polls[i].fd]);
+ assert(s_fd(sockList[polls[i].fd]) == polls[i].fd);
+
+ sock = sockList[polls[i].fd];
+ if (!sock) /* slots may become empty while processing events */
+ continue;
+
+ gen_ref_inc(sock); /* can't have it going away on us */
+
+ Debug((DEBUG_ENGINE, "devpoll: Checking socket %p (fd %d) state %s, "
+ "events %s", sock, s_fd(sock), state_to_name(s_state(sock)),
+ sock_flags(s_events(sock))));
+
+ if (s_state(sock) != SS_NOTSOCK) {
+ errcode = 0; /* check for errors on socket */
+ codesize = sizeof(errcode);
+ if (getsockopt(s_fd(sock), SOL_SOCKET, SO_ERROR, &errcode,
+ &codesize) < 0)
+ errcode = errno; /* work around Solaris implementation */
+
+ if (errcode) { /* an error occurred; generate an event */
+ Debug((DEBUG_ENGINE, "devpoll: Error %d on fd %d, socket %p",
+ errcode, s_fd(sock), sock));
+ event_generate(ET_ERROR, sock, errcode);
+ gen_ref_dec(sock); /* careful not to leak reference counts */
+ continue;
+ }
+ }
+
+ switch (s_state(sock)) {
+ case SS_CONNECTING:
+ if (polls[i].revents & POLLWRITEFLAGS) { /* connection completed */
+ Debug((DEBUG_ENGINE, "devpoll: Connection completed"));
+ event_generate(ET_CONNECT, sock, 0);
+ }
+ break;
+
+ case SS_LISTENING:
+ if (polls[i].revents & POLLREADFLAGS) { /* connect. to be accept. */
+ Debug((DEBUG_ENGINE, "devpoll: Ready for accept"));
+ event_generate(ET_ACCEPT, sock, 0);
+ }
+ break;
+
+ case SS_NOTSOCK:
+ if (polls[i].revents & POLLREADFLAGS) { /* data on socket */
+ /* can't peek; it's not a socket */
+ Debug((DEBUG_ENGINE, "devpoll: non-socket readable"));
+ event_generate(ET_READ, sock, 0);
+ }
+ break;
+
+ case SS_CONNECTED:
+ if (polls[i].revents & POLLREADFLAGS) { /* data on socket */
+ char c;
+
+ switch (recv(s_fd(sock), &c, 1, MSG_PEEK)) { /* check EOF */
+ case -1: /* error occurred?!? */
+ if (errno == EAGAIN) {
+ Debug((DEBUG_ENGINE, "devpoll: Resource temporarily "
+ "unavailable?"));
+ continue;
+ }
+ Debug((DEBUG_ENGINE, "devpoll: Uncaught error!"));
+ event_generate(ET_ERROR, sock, errno);
+ break;
+
+ case 0: /* EOF from client */
+ Debug((DEBUG_ENGINE, "devpoll: EOF from client"));
+ event_generate(ET_EOF, sock, 0);
+ break;
+
+ default: /* some data can be read */
+ Debug((DEBUG_ENGINE, "devpoll: Data to be read"));
+ event_generate(ET_READ, sock, 0);
+ break;
+ }
+ }
+ if (polls[i].revents & POLLWRITEFLAGS) { /* socket writable */
+ Debug((DEBUG_ENGINE, "devpoll: Data can be written"));
+ event_generate(ET_WRITE, sock, 0);
+ }
+ break;
+
+ case SS_DATAGRAM: case SS_CONNECTDG:
+ if (polls[i].revents & POLLREADFLAGS) { /* socket readable */
+ Debug((DEBUG_ENGINE, "devpoll: Datagram to be read"));
+ event_generate(ET_READ, sock, 0);
+ }
+ if (polls[i].revents & POLLWRITEFLAGS) { /* socket writable */
+ Debug((DEBUG_ENGINE, "devpoll: Datagram can be written"));
+ event_generate(ET_WRITE, sock, 0);
+ }
+ break;
+ }
+
+ assert(s_fd(sock) == polls[i].fd);
+
+ gen_ref_dec(sock); /* we're done with it */
+ }
+
+ timer_run(); /* execute any pending timers */
+ }
+}
+
+struct Engine engine_devpoll = {
+ "/dev/poll", /* Engine name */
+ engine_init, /* Engine initialization function */
+ 0, /* Engine signal registration function */
+ engine_add, /* Engine socket registration function */
+ engine_state, /* Engine socket state change function */
+ engine_events, /* Engine socket events mask function */
+ engine_delete, /* Engine socket deletion function */
+ engine_loop /* Core engine event loop */
+};
--- /dev/null
+/*
+ * IRC - Internet Relay Chat, ircd/engine_kqueue.c
+ * Copyright (C) 2001 Kevin L. Mitchell <klmitch@mit.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ */
+#include "config.h"
+
+#include "ircd_events.h"
+
+#include "ircd.h"
+#include "ircd_alloc.h"
+#include "ircd_log.h"
+#include "s_debug.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <signal.h>
+#include <sys/event.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#define KQUEUE_ERROR_THRESHOLD 20 /* after 20 kqueue errors, restart */
+#define ERROR_EXPIRE_TIME 3600 /* expire errors after an hour */
+
+#define POLLS_PER_KQUEUE 20 /* get 20 kevents per turn */
+
+static struct Socket** sockList;
+static int kqueue_max;
+static int kqueue_id;
+
+static int errors = 0;
+static struct Timer clear_error;
+
+/* decrements the error count once per hour */
+static void
+error_clear(struct Event* ev)
+{
+ if (!--errors) /* remove timer when error count reaches 0 */
+ timer_del(ev_timer(ev));
+}
+
+/* initialize the kqueue engine */
+static int
+engine_init(int max_sockets)
+{
+ int i;
+
+ if ((kqueue_id = kqueue()) < 0) { /* initialize... */
+ log_write(LS_SYSTEM, L_WARNING, 0,
+ "kqueue() engine cannot initialize: %m");
+ return 0;
+ }
+
+ /* allocate necessary memory */
+ sockList = (struct Socket**) MyMalloc(sizeof(struct Socket*) * max_sockets);
+
+ /* initialize the data */
+ for (i = 0; i < max_sockets; i++)
+ sockList[i] = 0;
+
+ kqueue_max = max_sockets; /* number of sockets allocated */
+
+ return 1; /* success! */
+}
+
+/* add a signel to be watched for */
+static void
+engine_signal(struct Signal* sig)
+{
+ struct kevent sigevent;
+ struct sigaction act;
+
+ assert(0 != signal);
+
+ Debug((DEBUG_ENGINE, "kqueue: Adding filter for signal %d [%p]",
+ sig_signal(sig), sig));
+
+ sigevent.ident = sig_signal(sig); /* set up the kqueue event */
+ sigevent.filter = EVFILT_SIGNAL; /* looking for signals... */
+ sigevent.flags = EV_ADD | EV_ENABLE; /* add and enable it */
+ sigevent.fflags = 0;
+ sigevent.data = 0;
+ sigevent.udata = sig; /* store our user data */
+
+ if (kevent(kqueue_id, &sigevent, 1, 0, 0, 0) < 0) { /* add event */
+ log_write(LS_SYSTEM, L_WARNING, 0, "Unable to trap signal %d",
+ sig_signal(sig));
+ return;
+ }
+
+ act.sa_handler = SIG_IGN; /* ignore the signal */
+ act.sa_flags = 0;
+ sigemptyset(&act.sa_mask);
+ sigaction(sig_signal(sig), &act, 0);
+}
+
+/* Figure out what events go with a given state */
+static unsigned int
+state_to_events(enum SocketState state, unsigned int events)
+{
+ switch (state) {
+ case SS_CONNECTING: /* connecting socket */
+ return SOCK_EVENT_WRITABLE;
+ break;
+
+ case SS_LISTENING: /* listening socket */
+ case SS_NOTSOCK: /* our signal socket--just in case */
+ return SOCK_EVENT_READABLE;
+ break;
+
+ case SS_CONNECTED: case SS_DATAGRAM: case SS_CONNECTDG:
+ return events; /* ordinary socket */
+ break;
+ }
+
+ /*NOTREACHED*/
+ return 0;
+}
+
+/* Activate kqueue filters as appropriate */
+static void
+set_or_clear(struct Socket* sock, unsigned int clear, unsigned int set)
+{
+ int i = 0;
+ struct kevent chglist[2];
+
+ assert(0 != sock);
+ assert(-1 < s_fd(sock));
+
+ if ((clear ^ set) & SOCK_EVENT_READABLE) { /* readable has changed */
+ chglist[i].ident = s_fd(sock); /* set up the change list */
+ chglist[i].filter = EVFILT_READ; /* readable filter */
+ chglist[i].flags = EV_ADD; /* adding it */
+ chglist[i].fflags = 0;
+ chglist[i].data = 0;
+ chglist[i].udata = 0; /* I love udata, but it can't really be used here */
+
+ if (set & SOCK_EVENT_READABLE) /* it's set */
+ chglist[i].flags |= EV_ENABLE;
+ else /* clear it */
+ chglist[i].flags |= EV_DISABLE;
+
+ i++; /* advance to next element */
+ }
+
+ if ((clear ^ set) & SOCK_EVENT_WRITABLE) { /* writable has changed */
+ chglist[i].ident = s_fd(sock); /* set up the change list */
+ chglist[i].filter = EVFILT_WRITE; /* writable filter */
+ chglist[i].flags = EV_ADD; /* adding it */
+ chglist[i].fflags = 0;
+ chglist[i].data = 0;
+ chglist[i].udata = 0;
+
+ if (set & SOCK_EVENT_WRITABLE) /* it's set */
+ chglist[i].flags |= EV_ENABLE;
+ else /* clear it */
+ chglist[i].flags |= EV_DISABLE;
+
+ i++; /* advance count... */
+ }
+
+ if (kevent(kqueue_id, chglist, i, 0, 0, 0) < 0)
+ event_generate(ET_ERROR, sock, errno); /* report error */
+}
+
+/* add a socket to be listened on */
+static int
+engine_add(struct Socket* sock)
+{
+ assert(0 != sock);
+ assert(0 == sockList[s_fd(sock)]);
+
+ /* bounds-check... */
+ if (sock->s_fd >= kqueue_max) {
+ log_write(LS_SYSTEM, L_ERROR, 0,
+ "Attempt to add socket %d (> %d) to event engine", s_fd(sock),
+ kqueue_max);
+ return 0;
+ }
+
+ sockList[s_fd(sock)] = sock; /* add to list */
+
+ Debug((DEBUG_ENGINE, "kqueue: Adding socket %d [%p], state %s, to engine",
+ s_fd(sock), sock, state_to_name(s_state(sock))));
+
+ /* Add socket to queue */
+ set_or_clear(sock, 0, state_to_events(s_state(sock), s_events(sock)));
+
+ return 1; /* success */
+}
+
+/* socket switching to new state */
+static void
+engine_state(struct Socket* sock, enum SocketState new_state)
+{
+ assert(0 != sock);
+ assert(sock == sockList[s_fd(sock)]);
+
+ Debug((DEBUG_ENGINE, "kqueue: Changing state for socket %p to %s", sock,
+ state_to_name(new_state)));
+
+ /* set the correct events */
+ set_or_clear(sock,
+ state_to_events(s_state(sock), s_events(sock)), /* old state */
+ state_to_events(new_state, s_events(sock))); /* new state */
+
+}
+
+/* socket events changing */
+static void
+engine_events(struct Socket* sock, unsigned int new_events)
+{
+ assert(0 != sock);
+ assert(sock == sockList[s_fd(sock)]);
+
+ Debug((DEBUG_ENGINE, "kqueue: Changing event mask for socket %p to [%s]",
+ sock, sock_flags(new_events)));
+
+ /* set the correct events */
+ set_or_clear(sock,
+ state_to_events(s_state(sock), s_events(sock)), /* old events */
+ state_to_events(s_state(sock), new_events)); /* new events */
+}
+
+/* socket going away */
+static void
+engine_delete(struct Socket* sock)
+{
+ struct kevent dellist[2];
+
+ assert(0 != sock);
+ assert(sock == sockList[s_fd(sock)]);
+
+ Debug((DEBUG_ENGINE, "kqueue: Deleting socket %d [%p], state %s",
+ s_fd(sock), sock, state_to_name(s_state(sock))));
+
+ dellist[0].ident = s_fd(sock); /* set up the delete list */
+ dellist[0].filter = EVFILT_READ; /* readable filter */
+ dellist[0].flags = EV_DELETE; /* delete it */
+ dellist[0].fflags = 0;
+ dellist[0].data = 0;
+ dellist[0].udata = 0;
+
+ dellist[1].ident = s_fd(sock);
+ dellist[1].filter = EVFILT_WRITE; /* writable filter */
+ dellist[1].flags = EV_DELETE; /* delete it */
+ dellist[1].fflags = 0;
+ dellist[1].data = 0;
+ dellist[1].udata = 0;
+
+ /* make it all go away */
+ if (kevent(kqueue_id, dellist, 2, 0, 0, 0) < 0)
+ log_write(LS_SOCKET, L_WARNING, 0,
+ "Unable to delete kevent items for socket %d", s_fd(sock));
+
+ sockList[s_fd(sock)] = 0;
+}
+
+/* engine event loop */
+static void
+engine_loop(struct Generators* gen)
+{
+ struct kevent events[POLLS_PER_KQUEUE];
+ struct Socket* sock;
+ struct timespec wait;
+ int nevs;
+ int i;
+ int errcode;
+ size_t codesize;
+
+ while (running) {
+ /* set up the sleep time */
+ wait.tv_sec = timer_next(gen) ? (timer_next(gen) - CurrentTime) : -1;
+ wait.tv_nsec = 0;
+
+ Debug((DEBUG_INFO, "kqueue: delay: %Tu (%Tu) %Tu", timer_next(gen),
+ CurrentTime, wait.tv_sec));
+
+ /* check for active events */
+ nevs = kevent(kqueue_id, 0, 0, events, POLLS_PER_KQUEUE,
+ wait.tv_sec < 0 ? 0 : &wait);
+
+ CurrentTime = time(0); /* set current time... */
+
+ if (nevs < 0) {
+ if (errno != EINTR) { /* ignore kevent interrupts */
+ /* Log the kqueue error */
+ log_write(LS_SOCKET, L_ERROR, 0, "kevent() error: %m");
+ if (!errors++)
+ timer_add(&clear_error, error_clear, 0, TT_PERIODIC,
+ ERROR_EXPIRE_TIME);
+ else if (errors > KQUEUE_ERROR_THRESHOLD) /* too many errors... */
+ server_restart("too many kevent errors");
+ }
+ /* old code did a sleep(1) here; with usage these days,
+ * that may be too expensive
+ */
+ continue;
+ }
+
+ for (i = 0; i < nevs; i++) {
+ if (events[i].filter == EVFILT_SIGNAL) {
+ /* it's a signal; deal appropriately */
+ event_generate(ET_SIGNAL, events[i].udata, events[i].ident);
+ continue; /* skip socket processing loop */
+ }
+
+ assert(events[i].filter == EVFILT_READ ||
+ events[i].filter == EVFILT_WRITE);
+
+ sock = sockList[events[i].ident];
+ if (!sock) /* slots may become empty while processing events */
+ continue;
+
+ assert(s_fd(sock) == events[i].ident);
+
+ gen_ref_inc(sock); /* can't have it going away on us */
+
+ Debug((DEBUG_ENGINE, "kqueue: Checking socket %p (fd %d) state %s, "
+ "events %s", sock, s_fd(sock), state_to_name(s_state(sock)),
+ sock_flags(s_events(sock))));
+
+ if (s_state(sock) != SS_NOTSOCK) {
+ errcode = 0; /* check for errors on socket */
+ codesize = sizeof(errcode);
+ if (getsockopt(s_fd(sock), SOL_SOCKET, SO_ERROR, &errcode,
+ &codesize) < 0)
+ errcode = errno; /* work around Solaris implementation */
+
+ if (errcode) { /* an error occurred; generate an event */
+ Debug((DEBUG_ENGINE, "kqueue: Error %d on fd %d, socket %p", errcode,
+ s_fd(sock), sock));
+ event_generate(ET_ERROR, sock, errcode);
+ gen_ref_dec(sock); /* careful not to leak reference counts */
+ continue;
+ }
+ }
+
+ switch (s_state(sock)) {
+ case SS_CONNECTING:
+ if (events[i].filter == EVFILT_WRITE) { /* connection completed */
+ Debug((DEBUG_ENGINE, "kqueue: Connection completed"));
+ event_generate(ET_CONNECT, sock, 0);
+ }
+ break;
+
+ case SS_LISTENING:
+ if (events[i].filter == EVFILT_READ) { /* connect. to be accept. */
+ Debug((DEBUG_ENGINE, "kqueue: Ready for accept"));
+ event_generate(ET_ACCEPT, sock, 0);
+ }
+ break;
+
+ case SS_NOTSOCK: /* doing nothing socket-specific */
+ case SS_CONNECTED:
+ if (events[i].filter == EVFILT_READ) { /* data on socket */
+ Debug((DEBUG_ENGINE, "kqueue: EOF or data to be read"));
+ event_generate(events[i].flags & EV_EOF ? ET_EOF : ET_READ, sock, 0);
+ }
+ if (events[i].filter == EVFILT_WRITE) { /* socket writable */
+ Debug((DEBUG_ENGINE, "kqueue: Data can be written"));
+ event_generate(ET_WRITE, sock, 0);
+ }
+ break;
+
+ case SS_DATAGRAM: case SS_CONNECTDG:
+ if (events[i].filter == EVFILT_READ) { /* socket readable */
+ Debug((DEBUG_ENGINE, "kqueue: Datagram to be read"));
+ event_generate(ET_READ, sock, 0);
+ }
+ if (events[i].filter == EVFILT_WRITE) { /* socket writable */
+ Debug((DEBUG_ENGINE, "kqueue: Datagram can be written"));
+ event_generate(ET_WRITE, sock, 0);
+ }
+ break;
+ }
+
+ assert(s_fd(sock) == events[i].ident);
+
+ gen_ref_dec(sock); /* we're done with it */
+ }
+
+ timer_run(); /* execute any pending timers */
+ }
+}
+
+struct Engine engine_kqueue = {
+ "kqueue()", /* Engine name */
+ engine_init, /* Engine initialization function */
+ engine_signal, /* Engine signal registration function */
+ engine_add, /* Engine socket registration function */
+ engine_state, /* Engine socket state change function */
+ engine_events, /* Engine socket events mask function */
+ engine_delete, /* Engine socket deletion function */
+ engine_loop /* Core engine event loop */
+};
--- /dev/null
+/*
+ * IRC - Internet Relay Chat, ircd/engine_poll.c
+ * Copyright (C) 2001 Kevin L. Mitchell <klmitch@mit.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ */
+#include "config.h"
+
+#include "ircd_events.h"
+
+#include "ircd.h"
+#include "ircd_alloc.h"
+#include "ircd_log.h"
+#include "s_debug.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#define POLL_ERROR_THRESHOLD 20 /* after 20 poll errors, restart */
+#define ERROR_EXPIRE_TIME 3600 /* expire errors after an hour */
+
+/* Figure out what bits to set for read */
+#if defined(POLLMSG) && defined(POLLIN) && defined(POLLRDNORM)
+# define POLLREADFLAGS (POLLMSG|POLLIN|POLLRDNORM)
+#elif defined(POLLIN) && defined(POLLRDNORM)
+# define POLLREADFLAGS (POLLIN|POLLRDNORM)
+#elif defined(POLLIN)
+# define POLLREADFLAGS POLLIN
+#elif defined(POLLRDNORM)
+# define POLLREADFLAGS POLLRDNORM
+#endif
+
+/* Figure out what bits to set for write */
+#if defined(POLLOUT) && defined(POLLWRNORM)
+# define POLLWRITEFLAGS (POLLOUT|POLLWRNORM)
+#elif defined(POLLOUT)
+# define POLLWRITEFLAGS POLLOUT
+#elif defined(POLLWRNORM)
+# define POLLWRITEFLAGS POLLWRNORM
+#endif
+
+/* Figure out what bits indicate errors */
+#ifdef POLLHUP
+# define POLLERRORS (POLLHUP|POLLERR)
+#else
+# define POLLERRORS POLLERR
+#endif
+
+static struct Socket** sockList;
+static struct pollfd* pollfdList;
+static unsigned int poll_count;
+static unsigned int poll_max;
+
+static int errors = 0;
+static struct Timer clear_error;
+
+/* decrements the error count once per hour */
+static void
+error_clear(struct Event* ev)
+{
+ if (!--errors) /* remove timer when error count reaches 0 */
+ timer_del(ev_timer(ev));
+}
+
+/* initialize the poll engine */
+static int
+engine_init(int max_sockets)
+{
+ int i;
+
+ /* allocate necessary memory */
+ sockList = (struct Socket**) MyMalloc(sizeof(struct Socket*) * max_sockets);
+ pollfdList = (struct pollfd*) MyMalloc(sizeof(struct pollfd) * max_sockets);
+
+ /* initialize the data */
+ for (i = 0; i < max_sockets; i++) {
+ sockList[i] = 0;
+ pollfdList[i].fd = -1;
+ pollfdList[i].events = 0;
+ pollfdList[i].revents = 0;
+ }
+
+ poll_count = 0; /* nothing in set */
+ poll_max = max_sockets; /* number of sockets allocated */
+
+ return 1;
+}
+
+/* Figure out what events go with a given state */
+static unsigned int
+state_to_events(enum SocketState state, unsigned int events)
+{
+ switch (state) {
+ case SS_CONNECTING: /* connecting socket */
+ return SOCK_EVENT_WRITABLE;
+ break;
+
+ case SS_LISTENING: /* listening socket */
+ case SS_NOTSOCK: /* our signal socket */
+ return SOCK_EVENT_READABLE;
+ break;
+
+ case SS_CONNECTED: case SS_DATAGRAM: case SS_CONNECTDG:
+ return events; /* ordinary socket */
+ break;
+ }
+
+ /*NOTREACHED*/
+ return 0;
+}
+
+/* Toggle bits in the pollfd structs correctly */
+static void
+set_or_clear(int idx, unsigned int clear, unsigned int set)
+{
+ if ((clear ^ set) & SOCK_EVENT_READABLE) { /* readable has changed */
+ if (set & SOCK_EVENT_READABLE) /* it's set */
+ pollfdList[idx].events |= POLLREADFLAGS;
+ else /* clear it */
+ pollfdList[idx].events &= ~POLLREADFLAGS;
+ }
+
+ if ((clear ^ set) & SOCK_EVENT_WRITABLE) { /* writable has changed */
+ if (set & SOCK_EVENT_WRITABLE) /* it's set */
+ pollfdList[idx].events |= POLLWRITEFLAGS;
+ else /* clear it */
+ pollfdList[idx].events &= ~POLLWRITEFLAGS;
+ }
+}
+
+/* add a socket to be listened on */
+static int
+engine_add(struct Socket* sock)
+{
+ int i;
+
+ assert(0 != sock);
+
+ for (i = 0; sockList[i] && i < poll_count; i++) /* Find an empty slot */
+ ;
+
+ Debug((DEBUG_ENGINE, "poll: Looking at slot %d, contents %p", i,
+ sockList[i]));
+
+ if (i >= poll_count) { /* ok, need to allocate another off the list */
+ if (poll_count >= poll_max) { /* bounds-check... */
+ log_write(LS_SYSTEM, L_ERROR, 0,
+ "Attempt to add socket %d (> %d) to event engine", sock->s_fd,
+ poll_max);
+ return 0;
+ }
+
+ i = poll_count++;
+ Debug((DEBUG_ENGINE, "poll: Allocating a new slot: %d", i));
+ }
+
+ s_ed_int(sock) = i; /* set engine data */
+ sockList[i] = sock; /* enter socket into data structures */
+ pollfdList[i].fd = s_fd(sock);
+
+ Debug((DEBUG_ENGINE, "poll: Adding socket %d to engine on %d [%p], state %s",
+ s_fd(sock), s_ed_int(sock), sock, state_to_name(s_state(sock))));
+
+ /* set the appropriate bits */
+ set_or_clear(i, 0, state_to_events(s_state(sock), s_events(sock)));
+
+ return 1; /* success */
+}
+
+/* socket switching to new state */
+static void
+engine_state(struct Socket* sock, enum SocketState new_state)
+{
+ assert(0 != sock);
+ assert(sock == sockList[s_ed_int(sock)]);
+ assert(s_fd(sock) == pollfdList[s_ed_int(sock)].fd);
+
+ Debug((DEBUG_ENGINE, "poll: Changing state for socket %p to %s", sock,
+ state_to_name(new_state)));
+
+ /* set the correct events */
+ set_or_clear(s_ed_int(sock),
+ state_to_events(s_state(sock), s_events(sock)), /* old state */
+ state_to_events(new_state, s_events(sock))); /* new state */
+}
+
+/* socket events changing */
+static void
+engine_events(struct Socket* sock, unsigned int new_events)
+{
+ assert(0 != sock);
+ assert(sock == sockList[s_ed_int(sock)]);
+ assert(s_fd(sock) == pollfdList[s_ed_int(sock)].fd);
+
+ Debug((DEBUG_ENGINE, "poll: Changing event mask for socket %p to [%s]", sock,
+ sock_flags(new_events)));
+
+ /* set the correct events */
+ set_or_clear(s_ed_int(sock),
+ state_to_events(s_state(sock), s_events(sock)), /* old events */
+ state_to_events(s_state(sock), new_events)); /* new events */
+}
+
+/* socket going away */
+static void
+engine_delete(struct Socket* sock)
+{
+ assert(0 != sock);
+ assert(sock == sockList[s_ed_int(sock)]);
+ assert(s_fd(sock) == pollfdList[s_ed_int(sock)].fd);
+
+ Debug((DEBUG_ENGINE, "poll: Deleting socket %d (%d) [%p], state %s",
+ s_fd(sock), s_ed_int(sock), sock, state_to_name(s_state(sock))));
+
+ /* clear the events */
+ pollfdList[s_ed_int(sock)].fd = -1;
+ pollfdList[s_ed_int(sock)].events = 0;
+
+ /* zero the socket list entry */
+ sockList[s_ed_int(sock)] = 0;
+
+ /* update poll_count */
+ while (poll_count > 0 && sockList[poll_count - 1] == 0)
+ poll_count--;
+}
+
+/* socket event loop */
+static void
+engine_loop(struct Generators* gen)
+{
+ int wait;
+ int nfds;
+ int i;
+ int errcode;
+ size_t codesize;
+ struct Socket *sock;
+
+ while (running) {
+ wait = timer_next(gen) ? (timer_next(gen) - CurrentTime) * 1000 : -1;
+
+ Debug((DEBUG_INFO, "poll: delay: %Tu (%Tu) %d", timer_next(gen),
+ CurrentTime, wait));
+
+ /* check for active files */
+ nfds = poll(pollfdList, poll_count, wait);
+
+ CurrentTime = time(0); /* set current time... */
+
+ if (nfds < 0) {
+ if (errno != EINTR) { /* ignore poll interrupts */
+ /* Log the poll error */
+ log_write(LS_SOCKET, L_ERROR, 0, "poll() error: %m");
+ if (!errors++)
+ timer_add(&clear_error, error_clear, 0, TT_PERIODIC,
+ ERROR_EXPIRE_TIME);
+ else if (errors > POLL_ERROR_THRESHOLD) /* too many errors... */
+ server_restart("too many poll errors");
+ }
+ /* old code did a sleep(1) here; with usage these days,
+ * that may be too expensive
+ */
+ continue;
+ }
+
+ for (i = 0; nfds && i < poll_count; i++) {
+ if (!(sock = sockList[i])) /* skip empty socket elements */
+ continue;
+
+ assert(s_fd(sock) == pollfdList[i].fd);
+
+ gen_ref_inc(sock); /* can't have it going away on us */
+
+ Debug((DEBUG_ENGINE, "poll: Checking socket %p (fd %d, index %d, "
+ "state %s, events %s", sock, s_fd(sock), i,
+ state_to_name(s_state(sock)), sock_flags(s_events(sock))));
+
+ if (s_state(sock) != SS_NOTSOCK) {
+ errcode = 0; /* check for errors on socket */
+ codesize = sizeof(errcode);
+ if (getsockopt(s_fd(sock), SOL_SOCKET, SO_ERROR, &errcode,
+ &codesize) < 0)
+ errcode = errno; /* work around Solaris implementation */
+
+ if (errcode) { /* an error occurred; generate an event */
+ Debug((DEBUG_ENGINE, "poll: Error %d on fd %d (index %d), socket %p",
+ errcode, s_fd(sock), i, sock));
+ event_generate(ET_ERROR, sock, errcode);
+ gen_ref_dec(sock); /* careful not to leak ref counts */
+ nfds--;
+ continue;
+ }
+ }
+
+ switch (s_state(sock)) {
+ case SS_CONNECTING:
+ if (pollfdList[i].revents & POLLWRITEFLAGS) { /* connect completed */
+ Debug((DEBUG_ENGINE, "poll: Connection completed"));
+ event_generate(ET_CONNECT, sock, 0);
+ nfds--;
+ }
+ break;
+
+ case SS_LISTENING:
+ if (pollfdList[i].revents & POLLREADFLAGS) { /* ready for accept */
+ Debug((DEBUG_ENGINE, "poll: Ready for accept"));
+ event_generate(ET_ACCEPT, sock, 0);
+ nfds--;
+ }
+ break;
+
+ case SS_NOTSOCK:
+ if (pollfdList[i].revents & POLLREADFLAGS) { /* data on socket */
+ /* can't peek; it's not a socket */
+ Debug((DEBUG_ENGINE, "poll: non-socket readable"));
+ event_generate(ET_READ, sock, 0);
+ nfds--;
+ }
+ break;
+
+ case SS_CONNECTED:
+ if (pollfdList[i].revents & POLLREADFLAGS) { /* data on socket */
+ char c;
+
+ switch (recv(s_fd(sock), &c, 1, MSG_PEEK)) { /* check EOF */
+ case -1: /* error occurred?!? */
+ if (errno == EAGAIN) {
+ Debug((DEBUG_ENGINE, "poll: Resource temporarily unavailable?"));
+ continue;
+ }
+ Debug((DEBUG_ENGINE, "poll: Uncaught error!"));
+ event_generate(ET_ERROR, sock, errno);
+ break;
+
+ case 0: /* EOF from client */
+ Debug((DEBUG_ENGINE, "poll: EOF from client"));
+ event_generate(ET_EOF, sock, 0);
+ break;
+
+ default: /* some data can be read */
+ Debug((DEBUG_ENGINE, "poll: Data to be read"));
+ event_generate(ET_READ, sock, 0);
+ break;
+ }
+ }
+ if (pollfdList[i].revents & POLLWRITEFLAGS) { /* socket writable */
+ Debug((DEBUG_ENGINE, "poll: Data can be written"));
+ event_generate(ET_WRITE, sock, 0);
+ }
+ if (pollfdList[i].revents & (POLLREADFLAGS | POLLWRITEFLAGS))
+ nfds--;
+ break;
+
+ case SS_DATAGRAM: case SS_CONNECTDG:
+ if (pollfdList[i].revents & POLLREADFLAGS) { /* socket readable */
+ Debug((DEBUG_ENGINE, "poll: Datagram to be read"));
+ event_generate(ET_READ, sock, 0);
+ }
+ if (pollfdList[i].revents & POLLWRITEFLAGS) { /* socket writable */
+ Debug((DEBUG_ENGINE, "poll: Datagram can be written"));
+ event_generate(ET_WRITE, sock, 0);
+ }
+ if (pollfdList[i].revents & (POLLREADFLAGS | POLLWRITEFLAGS))
+ nfds--;
+ break;
+ }
+
+ assert(s_fd(sock) == pollfdList[i].fd);
+
+ gen_ref_dec(sock); /* we're done with it */
+ }
+
+ timer_run(); /* execute any pending timers */
+ }
+}
+
+struct Engine engine_poll = {
+ "poll()", /* Engine name */
+ engine_init, /* Engine initialization function */
+ 0, /* Engine signal registration function */
+ engine_add, /* Engine socket registration function */
+ engine_state, /* Engine socket state change function */
+ engine_events, /* Engine socket events mask function */
+ engine_delete, /* Engine socket deletion function */
+ engine_loop /* Core engine event loop */
+};
--- /dev/null
+/*
+ * IRC - Internet Relay Chat, ircd/engine_select.c
+ * Copyright (C) 2001 Kevin L. Mitchell <klmitch@mit.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ */
+#include "config.h"
+
+#include "ircd_events.h"
+
+#include "ircd.h"
+#include "ircd_log.h"
+#include "s_debug.h"
+
+/* On BSD, define FD_SETSIZE to what we want before including sys/types.h */
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__bsdi__)
+# if !defined(FD_SETSIZE)
+# define FD_SETSIZE MAXCONNECTIONS
+# endif
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#define SELECT_ERROR_THRESHOLD 20 /* after 20 select errors, restart */
+#define ERROR_EXPIRE_TIME 3600 /* expire errors after an hour */
+
+static struct Socket* sockList[FD_SETSIZE];
+static int highest_fd;
+static fd_set global_read_set;
+static fd_set global_write_set;
+
+static int errors = 0;
+static struct Timer clear_error;
+
+/* decrements the error count once per hour */
+static void
+error_clear(struct Event* ev)
+{
+ if (!--errors) /* remove timer when error count reaches 0 */
+ timer_del(ev_timer(ev));
+}
+
+/* initialize the select engine */
+static int
+engine_init(int max_sockets)
+{
+ int i;
+
+ if (max_sockets > FD_SETSIZE) { /* too many sockets */
+ log_write(LS_SYSTEM, L_WARNING, 0,
+ "select() engine cannot handle %d sockets (> %d)",
+ max_sockets, FD_SETSIZE);
+ return 0;
+ }
+
+ FD_ZERO(&global_read_set); /* zero the global fd sets */
+ FD_ZERO(&global_write_set);
+
+ for (i = 0; i < FD_SETSIZE; i++) /* zero the sockList */
+ sockList[i] = 0;
+
+ highest_fd = -1; /* No fds in set */
+
+ return 1; /* initialization successful */
+}
+
+/* Figure out what events go with a given state */
+static unsigned int
+state_to_events(enum SocketState state, unsigned int events)
+{
+ switch (state) {
+ case SS_CONNECTING: /* connecting socket */
+ return SOCK_EVENT_WRITABLE;
+ break;
+
+ case SS_LISTENING: /* listening socket */
+ case SS_NOTSOCK: /* our signal socket */
+ return SOCK_EVENT_READABLE;
+ break;
+
+ case SS_CONNECTED: case SS_DATAGRAM: case SS_CONNECTDG:
+ return events; /* ordinary socket */
+ break;
+ }
+
+ /*NOTREACHED*/
+ return 0;
+}
+
+/* Toggle bits in the global fd sets appropriately */
+static void
+set_or_clear(int fd, unsigned int clear, unsigned int set)
+{
+ if ((clear ^ set) & SOCK_EVENT_READABLE) { /* readable has changed */
+ if (set & SOCK_EVENT_READABLE) /* it's set */
+ FD_SET(fd, &global_read_set);
+ else /* clear it */
+ FD_CLR(fd, &global_read_set);
+ }
+
+ if ((clear ^ set) & SOCK_EVENT_WRITABLE) { /* writable has changed */
+ if (set & SOCK_EVENT_WRITABLE) /* it's set */
+ FD_SET(fd, &global_write_set);
+ else /* clear it */
+ FD_CLR(fd, &global_write_set);
+ }
+}
+
+/* add a socket to be listened on */
+static int
+engine_add(struct Socket* sock)
+{
+ assert(0 != sock);
+ assert(0 == sockList[s_fd(sock)]);
+
+ /* bounds-check... */
+ if (s_fd(sock) >= FD_SETSIZE) {
+ log_write(LS_SYSTEM, L_ERROR, 0,
+ "Attempt to add socket %d (> %d) to event engine", s_fd(sock),
+ FD_SETSIZE);
+ return 0;
+ }
+
+ sockList[s_fd(sock)] = sock; /* add to list */
+
+ if (s_fd(sock) >= highest_fd) /* update highest_fd */
+ highest_fd = s_fd(sock);
+
+ Debug((DEBUG_ENGINE, "select: Adding socket %d to engine [%p], state %s",
+ s_fd(sock), sock, state_to_name(s_state(sock))));
+
+ /* set the fd set bits */
+ set_or_clear(s_fd(sock), 0, state_to_events(s_state(sock), s_events(sock)));
+
+ return 1; /* success */
+}
+
+/* socket switching to new state */
+static void
+engine_state(struct Socket* sock, enum SocketState new_state)
+{
+ assert(0 != sock);
+ assert(sock == sockList[s_fd(sock)]);
+
+ Debug((DEBUG_ENGINE, "select: Changing state for socket %p to %s", sock,
+ state_to_name(new_state)));
+
+ /* set the correct events */
+ set_or_clear(s_fd(sock),
+ state_to_events(s_state(sock), s_events(sock)), /* old state */
+ state_to_events(new_state, s_events(sock))); /* new state */
+}
+
+/* socket events changing */
+static void
+engine_events(struct Socket* sock, unsigned int new_events)
+{
+ assert(0 != sock);
+ assert(sock == sockList[s_fd(sock)]);
+
+ Debug((DEBUG_ENGINE, "select: Changing event mask for socket %p to [%s]",
+ sock, sock_flags(new_events)));
+
+ /* set the correct events */
+ set_or_clear(s_fd(sock),
+ state_to_events(s_state(sock), s_events(sock)), /* old events */
+ state_to_events(s_state(sock), new_events)); /* new events */
+}
+
+/* socket going away */
+static void
+engine_delete(struct Socket* sock)
+{
+ assert(0 != sock);
+ assert(sock == sockList[s_fd(sock)]);
+
+ Debug((DEBUG_ENGINE, "select: Deleting socket %d [%p], state %s", s_fd(sock),
+ sock, state_to_name(s_state(sock))));
+
+ FD_CLR(s_fd(sock), &global_read_set); /* clear event set bits */
+ FD_CLR(s_fd(sock), &global_write_set);
+
+ sockList[s_fd(sock)] = 0; /* zero the socket list entry */
+
+ while (highest_fd > -1 && sockList[highest_fd] == 0) /* update highest_fd */
+ highest_fd--;
+}
+
+/* engine event loop */
+static void
+engine_loop(struct Generators* gen)
+{
+ struct timeval wait;
+ fd_set read_set;
+ fd_set write_set;
+ int nfds;
+ int i;
+ int errcode;
+ size_t codesize;
+ struct Socket *sock;
+
+ while (running) {
+ read_set = global_read_set; /* all hail structure copy!! */
+ write_set = global_write_set;
+
+ /* set up the sleep time */
+ wait.tv_sec = timer_next(gen) ? (timer_next(gen) - CurrentTime) : -1;
+ wait.tv_usec = 0;
+
+ Debug((DEBUG_INFO, "select: delay: %Tu (%Tu) %Tu", timer_next(gen),
+ CurrentTime, wait.tv_sec));
+
+ /* check for active files */
+ nfds = select(highest_fd + 1, &read_set, &write_set, 0,
+ wait.tv_sec < 0 ? 0 : &wait);
+
+ CurrentTime = time(0); /* set current time... */
+
+ if (nfds < 0) {
+ if (errno != EINTR) { /* ignore select interrupts */
+ /* Log the select error */
+ log_write(LS_SOCKET, L_ERROR, 0, "select() error: %m");
+ if (!errors++)
+ timer_add(&clear_error, error_clear, 0, TT_PERIODIC,
+ ERROR_EXPIRE_TIME);
+ else if (errors > SELECT_ERROR_THRESHOLD) /* too many errors... */
+ server_restart("too many select errors");
+ }
+ /* old code did a sleep(1) here; with usage these days,
+ * that may be too expensive
+ */
+ continue;
+ }
+
+ for (i = 0; nfds && i <= highest_fd; i++) {
+ if (!(sock = sockList[i])) /* skip empty socket elements */
+ continue;
+
+ assert(s_fd(sock) == i);
+
+ gen_ref_inc(sock); /* can't have it going away on us */
+
+ Debug((DEBUG_ENGINE, "select: Checking socket %p (fd %d) state %s, "
+ "events %s", sock, i, state_to_name(s_state(sock)),
+ sock_flags(s_events(sock))));
+
+ if (s_state(sock) != SS_NOTSOCK) {
+ errcode = 0; /* check for errors on socket */
+ codesize = sizeof(errcode);
+ if (getsockopt(i, SOL_SOCKET, SO_ERROR, &errcode, &codesize) < 0)
+ errcode = errno; /* work around Solaris implementation */
+
+ if (errcode) { /* an error occurred; generate an event */
+ Debug((DEBUG_ENGINE, "select: Error %d on fd %d, socket %p", errcode,
+ i, sock));
+ event_generate(ET_ERROR, sock, errcode);
+ gen_ref_dec(sock); /* careful not to leak reference counts */
+ continue;
+ }
+ }
+
+ switch (s_state(sock)) {
+ case SS_CONNECTING:
+ if (FD_ISSET(i, &write_set)) { /* connection completed */
+ Debug((DEBUG_ENGINE, "select: Connection completed"));
+ event_generate(ET_CONNECT, sock, 0);
+ nfds--;
+ continue;
+ }
+ break;
+
+ case SS_LISTENING:
+ if (FD_ISSET(i, &read_set)) { /* connection to be accepted */
+ Debug((DEBUG_ENGINE, "select: Ready for accept"));
+ event_generate(ET_ACCEPT, sock, 0);
+ nfds--;
+ }
+ break;
+
+ case SS_NOTSOCK:
+ if (FD_ISSET(i, &read_set)) { /* data on socket */
+ /* can't peek; it's not a socket */
+ Debug((DEBUG_ENGINE, "select: non-socket readable"));
+ event_generate(ET_READ, sock, 0);
+ nfds--;
+ }
+ break;
+
+ case SS_CONNECTED:
+ if (FD_ISSET(i, &read_set)) { /* data to be read from socket */
+ char c;
+
+ switch (recv(i, &c, 1, MSG_PEEK)) { /* check for EOF */
+ case -1: /* error occurred?!? */
+ if (errno == EAGAIN) {
+ Debug((DEBUG_ENGINE, "select: Resource temporarily "
+ "unavailable?"));
+ continue;
+ }
+ Debug((DEBUG_ENGINE, "select: Uncaught error!"));
+ event_generate(ET_ERROR, sock, errno);
+ break;
+
+ case 0: /* EOF from client */
+ Debug((DEBUG_ENGINE, "select: EOF from client"));
+ event_generate(ET_EOF, sock, 0);
+ break;
+
+ default: /* some data can be read */
+ Debug((DEBUG_ENGINE, "select: Data to be read"));
+ event_generate(ET_READ, sock, 0);
+ break;
+ }
+ }
+ if (FD_ISSET(i, &write_set)) { /* data can be written to socket */
+ Debug((DEBUG_ENGINE, "select: Data can be written"));
+ event_generate(ET_WRITE, sock, 0);
+ }
+ if (FD_ISSET(i, &read_set) || FD_ISSET(i, &write_set))
+ nfds--;
+ break;
+
+ case SS_DATAGRAM: case SS_CONNECTDG:
+ if (FD_ISSET(i, &read_set)) { /* data to be read from socket */
+ Debug((DEBUG_ENGINE, "select: Datagram to be read"));
+ event_generate(ET_READ, sock, 0);
+ }
+ if (FD_ISSET(i, &write_set)) { /* data can be written to socket */
+ Debug((DEBUG_ENGINE, "select: Datagram can be written"));
+ event_generate(ET_WRITE, sock, 0);
+ }
+ if (FD_ISSET(i, &read_set) || FD_ISSET(i, &write_set))
+ nfds--;
+ break;
+ }
+
+ assert(s_fd(sock) == i);
+
+ gen_ref_dec(sock); /* we're done with it */
+ }
+
+ timer_run(); /* execute any pending timers */
+ }
+}
+
+struct Engine engine_select = {
+ "select()", /* Engine name */
+ engine_init, /* Engine initialization function */
+ 0, /* Engine signal registration function (none) */
+ engine_add, /* Engine socket registration function */
+ engine_state, /* Engine socket state change function */
+ engine_events, /* Engine socket events mask function */
+ engine_delete, /* Engine socket deletion function */
+ engine_loop /* Core engine event loop */
+};
#include "crule.h"
#include "hash.h"
#include "ircd_alloc.h"
+#include "ircd_events.h"
#include "ircd_features.h"
#include "ircd_log.h"
#include "ircd_reply.h"
char *debugmode = ""; /* Server debug level */
static char *dpath = DPATH;
-time_t nextconnect = 1; /* time for next try_connections call */
-time_t nextping = 1; /* same as above for check_pings() */
+static struct Timer connect_timer; /* timer structure for try_connections() */
+static struct Timer ping_timer; /* timer structure for check_pings() */
static struct Daemon thisServer = { 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0 };
+int running = 1;
/*----------------------------------------------------------------------------
log_write(LS_SYSTEM, L_CRIT, 0, "Server terminating: %s", message);
flush_connections(0);
close_connections(1);
- thisServer.running = 0;
+ running = 0;
}
* function should be made latest. (No harm done if this
* is called earlier or later...)
*--------------------------------------------------------------------------*/
-static time_t try_connections(void) {
+static void try_connections(struct Event* ev) {
struct ConfItem* aconf;
struct Client* cptr;
struct ConfItem** pconf;
struct Jupe* ajupe;
unsigned int con_class = 0;
+ assert(ET_EXPIRE == ev_type(ev));
+ assert(0 != ev_timer(ev));
+
connecting = FALSE;
Debug((DEBUG_NOTICE, "Connection check at : %s", myctime(CurrentTime)));
for (aconf = GlobalConfList; aconf; aconf = aconf->next) {
con_conf->name);
}
+ if (next == 0)
+ next = CurrentTime + feature_int(FEAT_CONNECTFREQUENCY);
+
Debug((DEBUG_NOTICE, "Next connection check : %s", myctime(next)));
- return(next);
+
+ timer_add(&connect_timer, try_connections, 0, TT_ABSOLUTE, next);
}
* get right down to it. Can't really be done until the server is more
* modular, however...
*--------------------------------------------------------------------------*/
-static time_t check_pings(void) {
- int expire = 0;
+static void check_pings(struct Event* ev) {
+ int expire = 0;
int next_check = CurrentTime;
int max_ping = 0;
int i;
+ assert(ET_EXPIRE == ev_type(ev));
+ assert(0 != ev_timer(ev));
+
next_check += feature_int(FEAT_PINGFREQUENCY);
/* Scan through the client table */
feature_int(FEAT_CONNECTTIMEOUT);
Debug((DEBUG_DEBUG, "check_pings(%s)=status:%s limit: %d current: %d",
- cli_name(cptr), (cli_flags(cptr) & FLAGS_PINGSENT) ? "[Ping Sent]" : "[]",
+ cli_name(cptr),
+ (cli_flags(cptr) & FLAGS_PINGSENT) ? "[Ping Sent]" : "[]",
max_ping, (int)(CurrentTime - cli_lasttime(cptr))));
/* If it was a server, then tell ops about it. */
if (IsServer(cptr) || IsConnecting(cptr) || IsHandshake(cptr))
sendto_opmask_butone(0, SNO_OLDSNO,
- "No response from %s, closing link", cli_name(cptr));
+ "No response from %s, closing link",
+ cli_name(cptr));
exit_client_msg(cptr, cptr, &me, "Ping timeout");
continue;
}
Debug((DEBUG_DEBUG, "[%i] check_pings() again in %is",
CurrentTime, next_check-CurrentTime));
- return next_check;
+ timer_add(&ping_timer, check_pings, 0, TT_ABSOLUTE, next_check);
}
setsid();
}
-
-/*----------------------------------------------------------------------------
- * event_loop
- *--------------------------------------------------------------------------*/
-static void event_loop(void) {
- time_t nextdnscheck = 0;
- time_t delay = 0;
-
- thisServer.running = 1;
- while (thisServer.running) {
- /* We only want to connect if a connection is due, not every time through.
- * Note, if there are no active C lines, this call to Tryconnections is
- * made once only; it will return 0. - avalon
- */
- if (nextconnect && CurrentTime >= nextconnect)
- nextconnect = try_connections();
-
- /* DNS checks. One to timeout queries, one for cache expiries. */
- nextdnscheck = timeout_resolver(CurrentTime);
-
- /* Take the smaller of the two 'timed' event times as the time of next
- * event (stops us being late :) - avalon
- * WARNING - nextconnect can return 0!
- */
- if (nextconnect)
- delay = IRCD_MIN(nextping, nextconnect);
- else
- delay = nextping;
-
- delay = IRCD_MIN(nextdnscheck, delay) - CurrentTime;
-
- /* Adjust delay to something reasonable [ad hoc values] (one might think
- * something more clever here... --msa) We don't really need to check that
- * often and as long as we don't delay too long, everything should be ok.
- * waiting too long can cause things to timeout... i.e. PINGS -> a
- * disconnection :( - avalon
- */
- if (delay < 1)
- read_message(1);
- else
- read_message(IRCD_MIN(delay, feature_int(FEAT_TIMESEC)));
-
- /* ...perhaps should not do these loops every time, but only if there is
- * some chance of something happening (but, note that conf->hold times may
- * be changed elsewhere--so precomputed next event time might be too far
- * away... (similarly with ping times) --msa
- */
- if (CurrentTime >= nextping)
- nextping = check_pings();
-
- /* timeout pending queries that haven't been responded to */
- timeout_auth_queries(CurrentTime);
-
- IPcheck_expire();
-
- if (GlobalRehashFlag) {
- rehash(&me, 1);
- GlobalRehashFlag = 0;
- }
-
- if (GlobalRestartFlag)
- server_restart("caught signal: SIGINT");
- }
-}
-
/*----------------------------------------------------------------------------
* check_file_access: random helper function to make sure that a file is
* accessible in a certain way, and complain if not.
debug_init(thisServer.bootopt & BOOT_TTY);
daemon_init(thisServer.bootopt & BOOT_TTY);
+ event_init(MAXCONNECTIONS);
setup_signals();
feature_init(); /* initialize features... */
uping_init();
+ IPcheck_init();
+ timer_add(&connect_timer, try_connections, 0, TT_RELATIVE, 1);
+ timer_add(&ping_timer, check_pings, 0, TT_RELATIVE, 1);
+
CurrentTime = time(NULL);
SetMe(&me);
+ cli_magic(&me) = CLIENT_MAGIC;
cli_from(&me) = &me;
make_server(&me);
--- /dev/null
+/*
+ * IRC - Internet Relay Chat, ircd/ircd_events.c
+ * Copyright (C) 2001 Kevin L. Mitchell <klmitch@mit.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ */
+#include "config.h"
+
+#include "ircd_events.h"
+
+#include "ircd.h"
+#include "ircd_alloc.h"
+#include "ircd_log.h"
+#include "ircd_snprintf.h"
+#include "s_debug.h"
+
+#include <assert.h>
+#include <signal.h>
+#include <unistd.h>
+
+#define SIGS_PER_SOCK 10 /* number of signals to process per socket
+ readable event */
+
+#ifdef USE_KQUEUE
+extern struct Engine engine_kqueue;
+#define ENGINE_KQUEUE &engine_kqueue,
+#else
+#define ENGINE_KQUEUE
+#endif /* USE_KQUEUE */
+
+#ifdef USE_DEVPOLL
+extern struct Engine engine_devpoll;
+#define ENGINE_DEVPOLL &engine_devpoll,
+#else
+#define ENGINE_DEVPOLL
+#endif /* USE_DEVPOLL */
+
+#ifdef USE_POLL
+extern struct Engine engine_poll;
+#define ENGINE_FALLBACK &engine_poll,
+#else
+extern struct Engine engine_select;
+#define ENGINE_FALLBACK &engine_select,
+#endif /* USE_POLL */
+
+/* list of engines to try */
+static const struct Engine *evEngines[] = {
+ ENGINE_KQUEUE
+ ENGINE_DEVPOLL
+ ENGINE_FALLBACK
+ 0
+};
+
+/* signal routines pipe data */
+static struct {
+ int fd; /* signal routine's fd */
+ struct Socket sock; /* and its struct Socket */
+} sigInfo = { -1 };
+
+/* All the thread info */
+static struct {
+ struct Generators gens; /* List of all generators */
+ struct Event* events_free; /* struct Event free list */
+ unsigned int events_alloc; /* count of allocated struct Events */
+ const struct Engine* engine; /* core engine being used */
+#ifdef IRCD_THREADED
+ struct GenHeader* genq_head; /* head of generator event queue */
+ struct GenHeader* genq_tail; /* tail of generator event queue */
+ unsigned int genq_count; /* count of generators on queue */
+#endif
+} evInfo = {
+ { 0, 0, 0 },
+ 0, 0, 0
+#ifdef IRCD_THREADED
+ , 0, 0, 0
+#endif
+};
+
+/* Initialize a struct GenHeader */
+static void
+gen_init(struct GenHeader* gen, EventCallBack call, void* data,
+ struct GenHeader* next, struct GenHeader** prev_p)
+{
+ assert(0 != gen);
+
+ gen->gh_next = next;
+ gen->gh_prev_p = prev_p;
+#ifdef IRCD_THREADED
+ gen->gh_qnext = 0;
+ gen->gh_qprev_p = 0;
+ gen->gh_head = 0;
+ gen->gh_tail = 0;
+#endif
+ gen->gh_flags = GEN_ACTIVE;
+ gen->gh_ref = 0;
+ gen->gh_call = call;
+ gen->gh_data = data;
+ gen->gh_engdata.ed_int = 0;
+
+ if (prev_p) { /* Going to link into list? */
+ if (next) /* do so */
+ next->gh_prev_p = &gen->gh_next;
+ *prev_p = gen;
+ }
+}
+
+/* Execute an event; optimizations should inline this */
+static void
+event_execute(struct Event* event)
+{
+ assert(0 != event);
+ assert(0 == event->ev_prev_p); /* must be off queue first */
+ assert(event->ev_gen.gen_header->gh_flags & GEN_ACTIVE);
+
+ if (event->ev_type == ET_DESTROY) /* turn off active flag *before* destroy */
+ event->ev_gen.gen_header->gh_flags &= ~GEN_ACTIVE;
+
+ (*event->ev_gen.gen_header->gh_call)(event); /* execute the event */
+
+ /* The logic here is very careful; if the event was an ET_DESTROY,
+ * then we must assume the generator is now invalid; fortunately, we
+ * don't need to do anything to it if so. Otherwise, we decrement
+ * the reference count; if reference count goes to zero, AND we need
+ * to destroy the generator, THEN we generate a DESTROY event.
+ */
+ if (event->ev_type != ET_DESTROY)
+ gen_ref_dec(event->ev_gen.gen_header);
+
+ event->ev_gen.gen_header = 0; /* clear event data */
+ event->ev_type = ET_DESTROY;
+
+ event->ev_next = evInfo.events_free; /* add to free list */
+ evInfo.events_free = event;
+}
+
+#ifndef IRCD_THREADED
+/* we synchronously execute the event when not threaded */
+#define event_add(event) \
+do { \
+ struct Event* _ev = (event); \
+ _ev->ev_next = 0; \
+ _ev->ev_prev_p = 0; \
+ event_execute(_ev); \
+} while (0)
+
+#else
+/* add an event to the work queue */
+/* This is just a placeholder; don't expect ircd to be threaded soon */
+/* There should be locks all over the place in here */
+static void
+event_add(struct Event* event)
+{
+ struct GenHeader* gen;
+
+ assert(0 != event);
+
+ gen = event->ev_gen.gen_header;
+
+ /* First, place event on generator's event queue */
+ event->ev_next = 0;
+ if (gen->gh_head) {
+ assert(0 != gen->gh_tail);
+
+ event->ev_prev_p = &gen->gh_tail->ev_next;
+ gen->gh_tail->ev_next = event;
+ gen->gh_tail = event;
+ } else { /* queue was empty */
+ assert(0 == gen->gh_tail);
+
+ event->ev_prev_p = &gen->gh_head;
+ gen->gh_head = event;
+ gen->gh_tail = event;
+ }
+
+ /* Now, if the generator isn't on the queue yet... */
+ if (!gen->gh_qprev_p) {
+ gen->gh_qnext = 0;
+ if (evInfo.genq_head) {
+ assert(0 != evInfo.genq_tail);
+
+ gen->gh_qprev_p = &evInfo.genq_tail->gh_qnext;
+ evInfo.genq_tail->gh_qnext = gen;
+ evInfo.genq_tail = gen;
+ } else { /* queue was empty */
+ assert(0 == evInfo.genq_tail);
+
+ gen->gh_qprev_p = &evInfo.genq_head;
+ evInfo.genq_head = gen;
+ evInfo.genq_tail = gen;
+ }
+
+ /* We'd also have to signal the work crew here */
+ }
+}
+#endif /* IRCD_THREADED */
+
+/* Place a timer in the correct spot on the queue */
+static void
+timer_enqueue(struct Timer* timer)
+{
+ struct Timer** ptr_p;
+
+ assert(0 != timer);
+ assert(0 == timer->t_header.gh_prev_p); /* not already on queue */
+
+ /* Calculate expire time */
+ switch (timer->t_type) {
+ case TT_ABSOLUTE: /* no need to consider it relative */
+ timer->t_expire = timer->t_value;
+ break;
+
+ case TT_RELATIVE: case TT_PERIODIC: /* relative timer */
+ timer->t_expire = timer->t_value + CurrentTime;
+ break;
+ }
+
+ /* Find a slot to insert timer */
+ for (ptr_p = &evInfo.gens.g_timer; ;
+ ptr_p = (struct Timer**) &(*ptr_p)->t_header.gh_next)
+ if (!*ptr_p || timer->t_expire < (*ptr_p)->t_expire)
+ break;
+
+ /* link it in the right place */
+ timer->t_header.gh_next = (struct GenHeader*) *ptr_p;
+ timer->t_header.gh_prev_p = (struct GenHeader**) ptr_p;
+ if (*ptr_p)
+ (*ptr_p)->t_header.gh_prev_p = &timer->t_header.gh_next;
+ *ptr_p = timer;
+}
+
+/* signal handler for writing signal notification to pipe */
+static void
+signal_handler(int sig)
+{
+ unsigned char c;
+
+ assert(sigInfo.fd >= 0);
+
+ c = (unsigned char) sig; /* only write 1 byte to identify sig */
+
+ write(sigInfo.fd, &c, 1);
+}
+
+/* callback for signal "socket" events */
+static void
+signal_callback(struct Event* event)
+{
+ unsigned char sigstr[SIGS_PER_SOCK];
+ int sig, n_sigs, i;
+ struct Signal* ptr;
+
+ assert(event->ev_type == ET_READ); /* readable events only */
+
+ n_sigs = read(event->ev_gen.gen_socket->s_fd, sigstr, sizeof(sigstr));
+
+ for (i = 0; i < n_sigs; i++) {
+ sig = (int) sigstr[i]; /* get signal */
+
+ for (ptr = evInfo.gens.g_signal; ptr;
+ ptr = (struct Signal*) ptr->sig_header.gh_next)
+ if (ptr->sig_signal == sig) /* find its descriptor... */
+ break;
+
+ if (ptr)
+ event_generate(ET_SIGNAL, ptr, sig); /* generate signal event */
+ }
+}
+
+/* Remove something from its queue */
+void
+gen_dequeue(void* arg)
+{
+ struct GenHeader* gen = (struct GenHeader*) arg;
+
+ if (gen->gh_next) /* clip it out of the list */
+ gen->gh_next->gh_prev_p = gen->gh_prev_p;
+ if (gen->gh_prev_p)
+ *gen->gh_prev_p = gen->gh_next;
+
+ gen->gh_next = 0; /* mark that it's not in the list anymore */
+ gen->gh_prev_p = 0;
+}
+
+/* Initializes the event system */
+void
+event_init(int max_sockets)
+{
+ int i, p[2];
+
+ for (i = 0; evEngines[i]; i++) { /* look for an engine... */
+ assert(0 != evEngines[i]->eng_name);
+ assert(0 != evEngines[i]->eng_init);
+
+ if ((*evEngines[i]->eng_init)(max_sockets))
+ break; /* Found an engine that'll work */
+ }
+
+ assert(0 != evEngines[i]);
+
+ evInfo.engine = evEngines[i]; /* save engine */
+
+ if (!evInfo.engine->eng_signal) { /* engine can't do signals */
+ if (pipe(p)) {
+ log_write(LS_SYSTEM, L_CRIT, 0, "Failed to open signal pipe");
+ exit(8);
+ }
+
+ sigInfo.fd = p[1]; /* write end of pipe */
+ socket_add(&sigInfo.sock, signal_callback, 0, SS_NOTSOCK,
+ SOCK_EVENT_READABLE, p[0]); /* read end of pipe */
+ }
+}
+
+/* Do the event loop */
+void
+event_loop(void)
+{
+ assert(0 != evInfo.engine);
+ assert(0 != evInfo.engine->eng_loop);
+
+ (*evInfo.engine->eng_loop)(&evInfo.gens);
+}
+
+/* Generate an event and add it to the queue (or execute it) */
+void
+event_generate(enum EventType type, void* arg, int data)
+{
+ struct Event* ptr;
+ struct GenHeader* gen = (struct GenHeader*) arg;
+
+ assert(0 != gen);
+
+ /* don't create events (other than ET_DESTROY) for destroyed generators */
+ if (type != ET_DESTROY && (gen->gh_flags & GEN_DESTROY))
+ return;
+
+ Debug((DEBUG_LIST, "Generating event type %s for generator %p (%s)",
+ event_to_name(type), gen, gen_flags(gen->gh_flags)));
+
+ if ((ptr = evInfo.events_free))
+ evInfo.events_free = ptr->ev_next; /* pop one off the freelist */
+ else { /* allocate another structure */
+ ptr = (struct Event*) MyMalloc(sizeof(struct Event));
+ evInfo.events_alloc++; /* count of allocated events */
+ }
+
+ ptr->ev_type = type; /* Record event type */
+ ptr->ev_data = data;
+
+ ptr->ev_gen.gen_header = (struct GenHeader*) gen;
+ ptr->ev_gen.gen_header->gh_ref++;
+
+ event_add(ptr); /* add event to queue */
+}
+
+/* Add a timer to be processed */
+void
+timer_add(struct Timer* timer, EventCallBack call, void* data,
+ enum TimerType type, time_t value)
+{
+ assert(0 != timer);
+ assert(0 != call);
+
+ Debug((DEBUG_LIST, "Adding timer %p; time out %Tu (type %s)", timer, value,
+ timer_to_name(type)));
+
+ /* initialize a timer... */
+ gen_init((struct GenHeader*) timer, call, data, 0, 0);
+
+ timer->t_type = type;
+ timer->t_value = value;
+ timer->t_expire = 0;
+
+ timer_enqueue(timer); /* and enqueue it */
+}
+
+/* Remove a timer from the processing queue */
+void
+timer_del(struct Timer* timer)
+{
+ assert(0 != timer);
+
+ if (timer->t_header.gh_flags & GEN_MARKED)
+ return; /* timer already marked for destruction */
+
+ timer->t_header.gh_flags |= GEN_DESTROY;
+
+ Debug((DEBUG_LIST, "Deleting timer %p (type %s)", timer,
+ timer_to_name(timer->t_type)));
+
+ if (!timer->t_header.gh_ref) { /* not in use; destroy right now */
+ gen_dequeue(timer);
+ event_generate(ET_DESTROY, timer, 0);
+ }
+}
+
+/* Change the time a timer expires */
+void
+timer_chg(struct Timer* timer, enum TimerType type, time_t value)
+{
+ assert(0 != timer);
+ assert(0 != value);
+ assert(TT_PERIODIC != timer->t_type);
+ assert(TT_PERIODIC != type);
+
+ Debug((DEBUG_LIST, "Changing timer %p from type %s timeout %Tu to type %s "
+ "timeout %Tu", timer, timer_to_name(timer->t_type), timer->t_value,
+ timer_to_name(type), value));
+
+ gen_dequeue(timer); /* remove the timer from the queue */
+
+ timer->t_type = type; /* Set the new type and value */
+ timer->t_value = value;
+ timer->t_expire = 0;
+
+ timer_enqueue(timer); /* re-queue the timer */
+}
+
+/* Execute all expired timers */
+void
+timer_run(void)
+{
+ struct Timer* ptr;
+ struct Timer* next = 0;
+
+ /* go through queue... */
+ for (ptr = evInfo.gens.g_timer; ptr; ptr = next) {
+ next = (struct Timer*) ptr->t_header.gh_next;
+ if (CurrentTime < ptr->t_expire)
+ break; /* processed all pending timers */
+
+ gen_dequeue(ptr); /* must dequeue timer here */
+ if (ptr->t_type == TT_ABSOLUTE || ptr->t_type == TT_RELATIVE) {
+ Debug((DEBUG_LIST, "Marking timer %p for later destruction", ptr));
+ ptr->t_header.gh_flags |= GEN_MARKED; /* mark for destruction */
+ }
+ event_generate(ET_EXPIRE, ptr, 0); /* generate expire event */
+
+ if (ptr->t_header.gh_flags & (GEN_MARKED | GEN_DESTROY)) {
+ Debug((DEBUG_LIST, "Destroying timer %p", ptr));
+ event_generate(ET_DESTROY, ptr, 0);
+ } else if (ptr->t_type == TT_PERIODIC) {
+ Debug((DEBUG_LIST, "Re-enqueuing periodic timer %p", ptr));
+ timer_enqueue(ptr); /* re-queue periodic timer */
+ }
+ }
+}
+
+/* Adds a signal to the event callback system */
+void
+signal_add(struct Signal* signal, EventCallBack call, void* data, int sig)
+{
+ struct sigaction act;
+
+ assert(0 != signal);
+ assert(0 != call);
+ assert(0 != evInfo.engine);
+
+ /* set up struct */
+ gen_init((struct GenHeader*) signal, call, data,
+ (struct GenHeader*) evInfo.gens.g_signal,
+ (struct GenHeader**) &evInfo.gens.g_signal);
+
+ signal->sig_signal = sig;
+
+ if (evInfo.engine->eng_signal)
+ (*evInfo.engine->eng_signal)(signal); /* tell engine */
+ else {
+ act.sa_handler = signal_handler; /* set up signal handler */
+ act.sa_flags = 0;
+ sigemptyset(&act.sa_mask);
+ sigaction(sig, &act, 0);
+ }
+}
+
+/* Adds a socket to the event system */
+int
+socket_add(struct Socket* sock, EventCallBack call, void* data,
+ enum SocketState state, unsigned int events, int fd)
+{
+ assert(0 != sock);
+ assert(0 != call);
+ assert(fd >= 0);
+ assert(0 != evInfo.engine);
+ assert(0 != evInfo.engine->eng_add);
+
+ /* set up struct */
+ gen_init((struct GenHeader*) sock, call, data,
+ (struct GenHeader*) evInfo.gens.g_socket,
+ (struct GenHeader**) &evInfo.gens.g_socket);
+
+ sock->s_state = state;
+ sock->s_events = events & SOCK_EVENT_MASK;
+ sock->s_fd = fd;
+
+ return (*evInfo.engine->eng_add)(sock); /* tell engine about it */
+}
+
+/* deletes (or marks for deletion) a socket */
+void
+socket_del(struct Socket* sock)
+{
+ assert(0 != sock);
+ assert(!(sock->s_header.gh_flags & GEN_DESTROY));
+ assert(0 != evInfo.engine);
+ assert(0 != evInfo.engine->eng_closing);
+
+ /* tell engine socket is going away */
+ (*evInfo.engine->eng_closing)(sock);
+
+ sock->s_header.gh_flags |= GEN_DESTROY;
+
+ if (!sock->s_header.gh_ref) { /* not in use; destroy right now */
+ gen_dequeue(sock);
+ event_generate(ET_DESTROY, sock, 0);
+ }
+}
+
+/* Sets the socket state to something else */
+void
+socket_state(struct Socket* sock, enum SocketState state)
+{
+ assert(0 != sock);
+ assert(0 != evInfo.engine);
+ assert(0 != evInfo.engine->eng_state);
+
+ /* assertions for invalid socket state transitions */
+ assert(sock->s_state != state); /* not changing states ?! */
+ assert(sock->s_state != SS_LISTENING); /* listening socket to...?! */
+ assert(sock->s_state != SS_CONNECTED); /* connected socket to...?! */
+ /* connecting socket now connected */
+ assert(sock->s_state != SS_CONNECTING || state == SS_CONNECTED);
+ /* unconnected datagram socket now connected */
+ assert(sock->s_state != SS_DATAGRAM || state == SS_CONNECTDG);
+ /* connected datagram socket now unconnected */
+ assert(sock->s_state != SS_CONNECTDG || state == SS_DATAGRAM);
+
+ if (sock->s_header.gh_flags & GEN_DESTROY) /* socket's been destroyed */
+ return;
+
+ /* tell engine we're changing socket state */
+ (*evInfo.engine->eng_state)(sock, state);
+
+ sock->s_state = state; /* set new state */
+}
+
+/* sets the events a socket's interested in */
+void
+socket_events(struct Socket* sock, unsigned int events)
+{
+ unsigned int new_events = 0;
+
+ assert(0 != sock);
+ assert(0 != evInfo.engine);
+ assert(0 != evInfo.engine->eng_events);
+
+ if (sock->s_header.gh_flags & GEN_DESTROY) /* socket's been destroyed */
+ return;
+
+ switch (events & SOCK_ACTION_MASK) {
+ case SOCK_ACTION_SET: /* set events to given set */
+ new_events = events & SOCK_EVENT_MASK;
+ break;
+
+ case SOCK_ACTION_ADD: /* add some events */
+ new_events = sock->s_events | (events & SOCK_EVENT_MASK);
+ break;
+
+ case SOCK_ACTION_DEL: /* remove some events */
+ new_events = sock->s_events & ~(events & SOCK_EVENT_MASK);
+ break;
+ }
+
+ if (sock->s_events == new_events)
+ return; /* no changes have been made */
+
+ /* tell engine about event mask change */
+ (*evInfo.engine->eng_events)(sock, new_events);
+
+ sock->s_events = new_events; /* set new events */
+}
+
+/* Returns an engine's name for informational purposes */
+const char*
+engine_name(void)
+{
+ assert(0 != evInfo.engine);
+ assert(0 != evInfo.engine->eng_name);
+
+ return evInfo.engine->eng_name;
+}
+
+#ifdef DEBUGMODE
+/* These routines pretty-print names for states and types for debug printing */
+
+#define NS(TYPE) \
+struct { \
+ char *name; \
+ TYPE value; \
+}
+
+#define NM(name) { #name, name }
+
+#define NE { 0, 0 }
+
+const char*
+state_to_name(enum SocketState state)
+{
+ int i;
+ NS(enum SocketState) map[] = {
+ NM(SS_CONNECTING),
+ NM(SS_LISTENING),
+ NM(SS_CONNECTED),
+ NM(SS_DATAGRAM),
+ NM(SS_CONNECTDG),
+ NM(SS_NOTSOCK),
+ NE
+ };
+
+ for (i = 0; map[i].name; i++)
+ if (map[i].value == state)
+ return map[i].name;
+
+ return "Undefined socket state";
+}
+
+const char*
+timer_to_name(enum TimerType type)
+{
+ int i;
+ NS(enum TimerType) map[] = {
+ NM(TT_ABSOLUTE),
+ NM(TT_RELATIVE),
+ NM(TT_PERIODIC),
+ NE
+ };
+
+ for (i = 0; map[i].name; i++)
+ if (map[i].value == type)
+ return map[i].name;
+
+ return "Undefined timer type";
+}
+
+const char*
+event_to_name(enum EventType type)
+{
+ int i;
+ NS(enum EventType) map[] = {
+ NM(ET_READ),
+ NM(ET_WRITE),
+ NM(ET_ACCEPT),
+ NM(ET_CONNECT),
+ NM(ET_EOF),
+ NM(ET_ERROR),
+ NM(ET_SIGNAL),
+ NM(ET_EXPIRE),
+ NM(ET_DESTROY),
+ NE
+ };
+
+ for (i = 0; map[i].name; i++)
+ if (map[i].value == type)
+ return map[i].name;
+
+ return "Undefined event type";
+}
+
+const char*
+gen_flags(unsigned int flags)
+{
+ int i, loc = 0;
+ static char buf[256];
+ NS(unsigned int) map[] = {
+ NM(GEN_DESTROY),
+ NM(GEN_MARKED),
+ NE
+ };
+
+ buf[0] = '\0';
+
+ for (i = 0; map[i].name; i++)
+ if (map[i].value & flags) {
+ if (loc != 0)
+ buf[loc++] = ' ';
+ loc += ircd_snprintf(0, buf + loc, sizeof(buf) - loc, "%s", map[i].name);
+ if (loc >= sizeof(buf))
+ return buf; /* overflow case */
+ }
+
+ return buf;
+}
+
+const char*
+sock_flags(unsigned int flags)
+{
+ int i, loc = 0;
+ static char buf[256];
+ NS(unsigned int) map[] = {
+ NM(SOCK_EVENT_READABLE),
+ NM(SOCK_EVENT_WRITABLE),
+ NM(SOCK_ACTION_SET),
+ NM(SOCK_ACTION_ADD),
+ NM(SOCK_ACTION_DEL),
+ NE
+ };
+
+ buf[0] = '\0';
+
+ for (i = 0; map[i].name; i++)
+ if (map[i].value & flags) {
+ if (loc != 0)
+ buf[loc++] = ' ';
+ loc += ircd_snprintf(0, buf + loc, sizeof(buf) - loc, "%s", map[i].name);
+ if (loc >= sizeof(buf))
+ return buf; /* overflow case */
+ }
+
+ return buf;
+}
+
+#endif /* DEBUGMODE */
*/
#include "config.h"
-#include "ircd_signal.h"
#include "ircd.h"
+#include "ircd_events.h"
+#include "ircd_signal.h"
+#include "s_conf.h"
+#include <assert.h>
#include <signal.h>
static struct tag_SignalCounter {
unsigned int hup;
} SignalCounter;
-void sigalrm_handler(int sig)
+static struct Signal sig_hup;
+static struct Signal sig_int;
+static struct Signal sig_term;
+
+static void sigalrm_handler(int sig)
{
++SignalCounter.alrm;
}
-void sigterm_handler(int sig)
+static void sigterm_callback(struct Event* ev)
{
+ assert(0 != ev_signal(ev));
+ assert(ET_SIGNAL == ev_type(ev));
+ assert(SIGTERM == sig_signal(ev_signal(ev)));
+ assert(SIGTERM == ev_data(ev));
+
server_die("received signal SIGTERM");
}
-static void sighup_handler(int sig)
+static void sighup_callback(struct Event* ev)
{
+ assert(0 != ev_signal(ev));
+ assert(ET_SIGNAL == ev_type(ev));
+ assert(SIGHUP == sig_signal(ev_signal(ev)));
+ assert(SIGHUP == ev_data(ev));
+
++SignalCounter.hup;
- GlobalRehashFlag = 1;
+ rehash(&me, 1);
}
-static void sigint_handler(int sig)
+static void sigint_callback(struct Event* ev)
{
- GlobalRestartFlag = 1;
+ assert(0 != ev_signal(ev));
+ assert(ET_SIGNAL == ev_type(ev));
+ assert(SIGINT == sig_signal(ev_signal(ev)));
+ assert(SIGINT == ev_data(ev));
+
+ server_restart("caught signal: SIGINT");
}
void setup_signals(void)
act.sa_handler = sigalrm_handler;
sigaction(SIGALRM, &act, 0);
- sigemptyset(&act.sa_mask);
-
- act.sa_handler = sighup_handler;
- sigaction(SIGHUP, &act, 0);
-
- act.sa_handler = sigint_handler;
- sigaction(SIGINT, &act, 0);
-
- act.sa_handler = sigterm_handler;
- sigaction(SIGTERM, &act, 0);
+ signal_add(&sig_hup, sighup_callback, 0, SIGHUP);
+ signal_add(&sig_int, sigint_callback, 0, SIGINT);
+ signal_add(&sig_term, sigterm_callback, 0, SIGTERM);
#ifdef HAVE_RESTARTABLE_SYSCALLS
/*
#include "match.h"
#include "numeric.h"
#include "res.h"
+#include "s_auth.h"
#include "s_bsd.h"
#include "s_conf.h"
#include "s_debug.h"
static void dealloc_client(struct Client* cptr)
{
+ assert(cli_verify(cptr));
+ assert(0 == cli_connect(cptr));
+
#ifdef DEBUGMODE
--clients.inuse;
#endif
cli_next(cptr) = clientFreeList;
clientFreeList = cptr;
+
+ cli_magic(cptr) = 0;
}
static struct Connection* alloc_connection(void)
static void dealloc_connection(struct Connection* con)
{
+ assert(con_verify(con));
+
+ Debug((DEBUG_LIST, "Deallocating connection %p", con));
+
if (con_dns_reply(con))
--(con_dns_reply(con)->ref_count);
if (-1 < con_fd(con))
con_next(con) = connectionFreeList;
connectionFreeList = con;
+
+ con_magic(con) = 0;
}
/*
struct Client* cptr = 0;
struct Connection* con = 0;
+ assert(!from || cli_verify(from));
+
cptr = alloc_client();
assert(0 != cptr);
+ assert(!cli_magic(cptr));
+ assert(0 == from || 0 != cli_connect(from));
if (!from) { /* local client, allocate a struct Connection */
con = alloc_connection();
assert(0 != con);
+ assert(!con_magic(con));
+ con_magic(con) = CONNECTION_MAGIC;
con_fd(con) = -1; /* initialize struct Connection */
+ con_freeflag(con) = 0;
con_nextnick(con) = CurrentTime - NICK_DELAY;
con_nexttarget(con) = CurrentTime - (TARGET_DELAY * (STARTTARGETS - 1));
con_handler(con) = UNREGISTERED_HANDLER;
con = cli_connect(from); /* use 'from's connection */
assert(0 != con);
+ assert(con_verify(con));
+ cli_magic(cptr) = CLIENT_MAGIC;
cli_connect(cptr) = con; /* set the connection and other fields */
cli_status(cptr) = status;
cli_hnext(cptr) = cptr;
return cptr;
}
+void free_connection(struct Connection* con)
+{
+ if (!con)
+ return;
+
+ assert(con_verify(con));
+ assert(0 == con_client(con));
+
+ dealloc_connection(con); /* deallocate the connection */
+}
+
void free_client(struct Client* cptr)
{
if (!cptr)
/*
* forget to remove the client from the hash table?
*/
+ assert(cli_verify(cptr));
assert(cli_hnext(cptr) == cptr);
- if (cli_from(cptr) == cptr) /* in other words, we're local */
- dealloc_connection(cli_connect(cptr)); /* deallocate the connection... */
- dealloc_client(cptr); /* deallocate the client */
+ Debug((DEBUG_LIST, "Freeing client %s [%p], connection %p", cli_name(cptr),
+ cptr, cli_connect(cptr)));
+
+ if (cli_auth(cptr))
+ destroy_auth_request(cli_auth(cptr), 0);
+
+ if (cli_from(cptr) == cptr) { /* in other words, we're local */
+ cli_from(cptr) = 0;
+ /* timer must be marked as not active */
+ if (!cli_freeflag(cptr) && !t_active(&(cli_proc(cptr))))
+ dealloc_connection(cli_connect(cptr)); /* connection not open anymore */
+ else {
+ if (-1 < cli_fd(cptr) && cli_freeflag(cptr) & FREEFLAG_SOCKET)
+ socket_del(&(cli_socket(cptr))); /* queue a socket delete */
+ if (cli_freeflag(cptr) & FREEFLAG_TIMER)
+ timer_del(&(cli_proc(cptr))); /* queue a timer delete */
+ }
+ }
+
+ cli_connect(cptr) = 0;
+
+ dealloc_client(cptr); /* actually destroy the client */
}
struct Server *make_server(struct Client *cptr)
{
struct Server *serv = cli_serv(cptr);
+ assert(cli_verify(cptr));
+
if (!serv)
{
serv = (struct Server*) MyMalloc(sizeof(struct Server));
*/
void remove_client_from_list(struct Client *cptr)
{
+ assert(cli_verify(cptr));
+ assert(con_verify(cli_connect(cptr)));
+
if (cli_prev(cptr))
cli_next(cli_prev(cptr)) = cli_next(cptr);
else {
GlobalClientList = cli_next(cptr);
- cli_prev(GlobalClientList) = 0;
+ if (GlobalClientList)
+ cli_prev(GlobalClientList) = 0;
}
if (cli_next(cptr))
cli_prev(cli_next(cptr)) = cli_prev(cptr);
*/
void add_client_to_list(struct Client *cptr)
{
+ assert(cli_verify(cptr));
/*
* Since we always insert new clients to the top of the list,
* this should mean the "me" is the bottom most item in the list.
#include "client.h"
#include "ircd.h"
#include "ircd_alloc.h"
+#include "ircd_events.h"
#include "ircd_features.h"
#include "ircd_osdep.h"
#include "ircd_reply.h"
struct Listener* ListenerPollList = 0;
+static void accept_connection(struct Event* ev);
+
static struct Listener* make_listener(int port, struct in_addr addr)
{
struct Listener* listener =
if (!os_set_tos(fd,feature_int((listener->server)?FEAT_TOS_SERVER : FEAT_TOS_CLIENT))) {
report_error(TOS_ERROR_MSG, get_listener_name(listener), errno);
}
+
+ if (!socket_add(&listener->socket, accept_connection, (void*) listener,
+ SS_LISTENING, 0, fd)) {
+ /* Error should already have been reported to the logs */
+ close(fd);
+ return 0;
+ }
+
listener->fd = fd;
return 1;
}
if (-1 < listener->fd)
close(listener->fd);
- free_listener(listener);
+ socket_del(&listener->socket);
}
/*
/*
* accept_connection - accept a connection on a listener
*/
-void accept_connection(struct Listener* listener)
+static void accept_connection(struct Event* ev)
{
+ struct Listener* listener;
struct sockaddr_in addr = { 0 };
unsigned int addrlen = sizeof(struct sockaddr_in);
int fd;
- assert(0 != listener);
+ assert(0 != ev_socket(ev));
+ assert(0 != s_data(ev_socket(ev)));
- listener->last_accept = CurrentTime;
- /*
- * There may be many reasons for error return, but
- * in otherwise correctly working environment the
- * probable cause is running out of file descriptors
- * (EMFILE, ENFILE or others?). The man pages for
- * accept don't seem to list these as possible,
- * although it's obvious that it may happen here.
- * Thus no specific errors are tested at this
- * point, just assume that connections cannot
- * be accepted until some old is closed first.
- */
- if (-1 == (fd = accept(listener->fd, (struct sockaddr*) &addr, &addrlen))) {
- /* Lotsa admins seem to have problems with not giving enough file descriptors
- * to their server so we'll add a generic warning mechanism here. If it
- * turns out too many messages are generated for meaningless reasons we
- * can filter them back.
+ listener = s_data(ev_socket(ev));
+
+ if (ev_type(ev) == ET_DESTROY) /* being destroyed */
+ free_listener(listener);
+ else {
+ assert(ev_type(ev) == ET_ACCEPT);
+
+ listener->last_accept = CurrentTime;
+ /*
+ * There may be many reasons for error return, but
+ * in otherwise correctly working environment the
+ * probable cause is running out of file descriptors
+ * (EMFILE, ENFILE or others?). The man pages for
+ * accept don't seem to list these as possible,
+ * although it's obvious that it may happen here.
+ * Thus no specific errors are tested at this
+ * point, just assume that connections cannot
+ * be accepted until some old is closed first.
*/
- sendto_opmask_butone(0, SNO_TCPCOMMON, "Unable to accept connection: %m");
- return;
- }
- /*
- * check for connection limit
- */
- if (fd > MAXCLIENTS - 1) {
- ++ServerStats->is_ref;
- send(fd, "ERROR :All connections in use\r\n", 32, 0);
- close(fd);
- return;
- }
- /*
- * check to see if listener is shutting down
- */
- if (!listener->active) {
- ++ServerStats->is_ref;
- send(fd, "ERROR :Use another port\r\n", 25, 0);
- close(fd);
- return;
- }
- /*
- * check to see if connection is allowed for this address mask
- */
- if (!connection_allowed((const char*) &addr, (const char*) &listener->mask)) {
- ++ServerStats->is_ref;
- send(fd, "ERROR :Use another port\r\n", 25, 0);
- close(fd);
- return;
- }
+ if (-1 == (fd = accept(listener->fd, (struct sockaddr*) &addr,
+ &addrlen))) {
+ /* Lotsa admins seem to have problems with not giving enough file
+ * descriptors to their server so we'll add a generic warning mechanism
+ * here. If it turns out too many messages are generated for
+ * meaningless reasons we can filter them back.
+ */
+ sendto_opmask_butone(0, SNO_TCPCOMMON,
+ "Unable to accept connection: %m");
+ return;
+ }
+ /*
+ * check for connection limit
+ */
+ if (fd > MAXCLIENTS - 1) {
+ ++ServerStats->is_ref;
+ send(fd, "ERROR :All connections in use\r\n", 32, 0);
+ close(fd);
+ return;
+ }
+ /*
+ * check to see if listener is shutting down
+ */
+ if (!listener->active) {
+ ++ServerStats->is_ref;
+ send(fd, "ERROR :Use another port\r\n", 25, 0);
+ close(fd);
+ return;
+ }
+ /*
+ * check to see if connection is allowed for this address mask
+ */
+ if (!connection_allowed((const char*) &addr,
+ (const char*) &listener->mask)) {
+ ++ServerStats->is_ref;
+ send(fd, "ERROR :Use another port\r\n", 25, 0);
+ close(fd);
+ return;
+ }
#if 0
- /*
- * check conf for ip address access
- */
- if (!conf_connect_allowed(addr.sin_addr)) {
- ++ServerStats->is_ref;
- send(fd, "ERROR :Not authorized\r\n", 23, 0);
- close(fd);
- return;
- }
+ /*
+ * check conf for ip address access
+ */
+ if (!conf_connect_allowed(addr.sin_addr)) {
+ ++ServerStats->is_ref;
+ send(fd, "ERROR :Not authorized\r\n", 23, 0);
+ close(fd);
+ return;
+ }
#endif
- ++ServerStats->is_ac;
- nextping = CurrentTime;
+ ++ServerStats->is_ac;
+/* nextping = CurrentTime; */
- add_connection(listener, fd);
+ add_connection(listener, fd);
+ }
}
-
-
#include "msg.h"
#include "numeric.h"
#include "numnicks.h"
+#include "s_bsd.h"
#include "send.h"
#include <assert.h>
MyFree(cli_listing(sptr));
cli_listing(sptr) = 0;
send_reply(sptr, RPL_LISTEND);
+ update_write(sptr);
if (parc < 2)
return 0; /* Let LIST abort a listing. */
}
#include "ircd.h"
#include "ircd_alloc.h"
#include "ircd_chattr.h"
+#include "ircd_events.h"
#include "ircd_features.h"
#include "ircd_policy.h"
#include "ircd_reply.h"
#endif
break;
+ case 'E':
+ case 'e': /* report engine name */
+#ifdef HEAD_IN_SAND_STATS_E
+ return m_not_oper(sptr,cptr,parc,parv);
+#else
+ send_reply(sptr, RPL_STATSENGINE, engine_name());
+#endif
+ break;
+
case 'G':
case 'g': /* send glines */
#ifdef HEAD_IN_SAND_STATS_G
case 'c':
report_configured_links(sptr, CONF_SERVER);
break;
+ case 'E':
+ case 'e': /* report engine name */
+ send_reply(sptr, RPL_STATSENGINE, engine_name());
+ break;
case 'G':
case 'g': /* send glines */
gline_stats(sptr);
case 'c':
report_configured_links(sptr, CONF_SERVER);
break;
+ case 'E':
+ case 'e': /* report engine name */
+ send_reply(sptr, RPL_STATSENGINE, engine_name());
+ break;
case 'G':
case 'g': /* send glines */
gline_stats(sptr);
return IO_FAILURE;
}
-int os_connect_nonb(int fd, const struct sockaddr_in* sin)
+IOResult os_connect_nonb(int fd, const struct sockaddr_in* sin)
{
- if (connect(fd, (struct sockaddr*) sin, sizeof(struct sockaddr_in))) {
- if (errno != EINPROGRESS)
- return 0;
- }
- return 1;
+ if (connect(fd, (struct sockaddr*) sin, sizeof(struct sockaddr_in)))
+ return (errno == EINPROGRESS) ? IO_BLOCKED : IO_FAILURE;
+ return IO_SUCCESS;
}
int os_get_sockname(int fd, struct sockaddr_in* sin_out)
(const char*) &opt, sizeof(opt)));
}
+int os_set_tos(int fd,int tos)
+{
+#if defined(IP_TOS) && defined(IPPROTO_IP)
+ unsigned int opt = tos;
+ return (0 == setsockopt(fd, IPPROTO_IP, IP_TOS, &opt, sizeof(opt)));
+#else
+ return 1;
+#endif
+}
+
int os_disable_options(int fd)
{
#if defined(IP_OPTIONS) && defined(IPPROTO_IP)
return IO_FAILURE;
}
-int os_connect_nonb(int fd, const struct sockaddr_in* sin)
+IOResult os_connect_nonb(int fd, const struct sockaddr_in* sin)
{
- if (connect(fd, (struct sockaddr*) sin, sizeof(struct sockaddr_in))) {
- if (errno != EINPROGRESS)
- return 0;
- }
- return 1;
+ if (connect(fd, (struct sockaddr*) sin, sizeof(struct sockaddr_in)))
+ return (errno == EINPROGRESS) ? IO_BLOCKED : IO_FAILURE;
+ return IO_SUCCESS;
}
int os_get_sockname(int fd, struct sockaddr_in* sin_out)
}
-int os_connect_nonb(int fd, const struct sockaddr_in* sin)
+IOResult os_connect_nonb(int fd, const struct sockaddr_in* sin)
{
- if (connect(fd, (const struct sockaddr*) sin, sizeof(struct sockaddr_in))) {
- if (errno != EINPROGRESS)
- return 0;
- }
- return 1;
+ if (connect(fd, (const struct sockaddr*) sin, sizeof(struct sockaddr_in)))
+ return (errno == EINPROGRESS) ? IO_BLOCKED : IO_FAILURE;
+ return IO_SUCCESS;
}
int os_get_sockname(int fd, struct sockaddr_in* sin_out)
return IO_FAILURE;
}
-int os_connect_nonb(int fd, const struct sockaddr_in* sin)
+IOResult os_connect_nonb(int fd, const struct sockaddr_in* sin)
{
- if (connect(fd, (struct sockaddr*) sin, sizeof(struct sockaddr_in))) {
- if (errno != EINPROGRESS)
- return 0;
- }
- return 1;
+ if (connect(fd, (struct sockaddr*) sin, sizeof(struct sockaddr_in)))
+ return (errno == EINPROGRESS) ? IO_BLOCKED : IO_FAILURE;
+ return IO_SUCCESS;
}
int os_get_sockname(int fd, struct sockaddr_in* sin_out)
*/
#include "config.h"
-#define _XOPEN_SOURCE /* make limits.h #define IOV_MAX */
-
#include "ircd_osdep.h"
#include "msgq.h"
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
+#include <stropts.h>
#include <sys/filio.h>
#include <sys/ioctl.h>
#include <sys/param.h>
(const char*) &opt, sizeof(opt)));
}
+int os_set_tos(int fd,int tos)
+{
+ unsigned int opt = tos;
+ return (0 == setsockopt(fd, IPPROTO_IP, IP_TOS, &opt, sizeof(opt)));
+}
+
int os_disable_options(int fd)
{
return (0 == setsockopt(fd, IPPROTO_IP, IP_OPTIONS, NULL, 0));
return IO_FAILURE;
}
-int os_connect_nonb(int fd, const struct sockaddr_in* sin)
+IOResult os_connect_nonb(int fd, const struct sockaddr_in* sin)
{
- if (connect(fd, (struct sockaddr*) sin, sizeof(struct sockaddr_in))) {
- if (errno != EINPROGRESS)
- return 0;
- }
- return 1;
+ if (connect(fd, (struct sockaddr*) sin, sizeof(struct sockaddr_in)))
+ return (errno == EINPROGRESS) ? IO_BLOCKED : IO_FAILURE;
+ return IO_SUCCESS;
}
int os_get_sockname(int fd, struct sockaddr_in* sin_out)
#include "client.h"
#include "ircd.h"
#include "ircd_alloc.h"
+#include "ircd_events.h"
#include "ircd_log.h"
#include "ircd_osdep.h"
#include "ircd_reply.h"
int ResolverFileDescriptor = -1; /* GLOBAL - used in s_bsd.c */
+static struct Socket resSock; /* Socket describing resolver */
+static struct Timer resExpireDNS; /* Timer for DNS expiration */
+static struct Timer resExpireCache; /* Timer for cache expiration */
+
static time_t nextDNSCheck = 0;
static time_t nextCacheExpire = 1;
static void add_request(struct ResRequest* request);
static void rem_request(struct ResRequest* request);
static struct ResRequest* make_request(const struct DNSQuery* query);
+static time_t timeout_query_list(time_t now);
+static time_t expire_cache(time_t now);
static void rem_cache(struct CacheEntry*);
static void do_query_name(const struct DNSQuery* query,
const char* name,
return (0);
}
+/* Socket callback for resolver */
+static void res_callback(struct Event* ev)
+{
+ assert(ev_type(ev) == ET_READ);
+
+ resolver_read();
+}
+
/*
* start_resolver - do everything we need to read the resolv.conf file
* and initialize the resolver file descriptor if needed
if (!os_set_nonblocking(ResolverFileDescriptor))
report_error("Resolver: error setting non-blocking for %s: %s",
cli_name(&me), errno);
+ if (!socket_add(&resSock, res_callback, 0, SS_DATAGRAM,
+ SOCK_EVENT_READABLE, ResolverFileDescriptor))
+ report_error("Resolver: unable to queue resolver file descriptor for %s",
+ cli_name(&me), ENFILE);
}
}
+/* Call the query timeout function */
+static void expire_DNS_callback(struct Event* ev)
+{
+ time_t next;
+
+ next = timeout_query_list(CurrentTime);
+
+ timer_add(&resExpireDNS, expire_DNS_callback, 0, TT_ABSOLUTE, next);
+}
+
+/* Call the cache expire function */
+static void expire_cache_callback(struct Event* ev)
+{
+ time_t next;
+
+ next = expire_cache(CurrentTime);
+
+ timer_add(&resExpireCache, expire_cache_callback, 0, TT_ABSOLUTE, next);
+}
+
/*
* init_resolver - initialize resolver and resolver library
*/
requestListHead = requestListTail = 0;
+ /* initiate the resolver timers */
+ timer_add(&resExpireDNS, expire_DNS_callback, 0, TT_RELATIVE, 1);
+ timer_add(&resExpireCache, expire_cache_callback, 0, TT_RELATIVE, 1);
+
errno = h_errno = 0;
start_resolver();
#include "ircd.h"
#include "ircd_alloc.h"
#include "ircd_chattr.h"
+#include "ircd_events.h"
#include "ircd_features.h"
#include "ircd_log.h"
#include "ircd_osdep.h"
enum { AUTH_TIMEOUT = 60 };
+static void release_auth_client(struct Client* client);
+static void unlink_auth_request(struct AuthRequest* request,
+ struct AuthRequest** list);
+void free_auth_request(struct AuthRequest* auth);
+
+/*
+ * auth_timeout - timeout a given auth request
+ */
+static void auth_timeout_callback(struct Event* ev)
+{
+ struct AuthRequest* auth;
+
+ assert(0 != ev_timer(ev));
+ assert(0 != t_data(ev_timer(ev)));
+
+ auth = t_data(ev_timer(ev));
+
+ if (ev_type(ev) == ET_DESTROY) { /* being destroyed */
+ auth->flags &= ~AM_TIMEOUT;
+
+ if (!(auth->flags & AM_FREE_MASK)) {
+ Debug((DEBUG_LIST, "Freeing auth from timeout callback; %p [%p]", auth,
+ ev_timer(ev)));
+ MyFree(auth); /* done with it, finally */
+ }
+ } else {
+ assert(ev_type(ev) == ET_EXPIRE);
+
+ destroy_auth_request(auth, 1);
+ }
+}
+
+/*
+ * auth_sock_callback - called when an event occurs on the socket
+ */
+static void auth_sock_callback(struct Event* ev)
+{
+ struct AuthRequest* auth;
+
+ assert(0 != ev_socket(ev));
+ assert(0 != s_data(ev_socket(ev)));
+
+ auth = s_data(ev_socket(ev));
+
+ switch (ev_type(ev)) {
+ case ET_DESTROY: /* being destroyed */
+ auth->flags &= ~AM_SOCKET;
+
+ if (!(auth->flags & AM_FREE_MASK)) {
+ Debug((DEBUG_LIST, "Freeing auth from sock callback; %p [%p]", auth,
+ ev_socket(ev)));
+ MyFree(auth); /* done with it finally */
+ }
+ break;
+
+ case ET_CONNECT: /* socket connection completed */
+ Debug((DEBUG_LIST, "Connection completed for auth %p [%p]; sending query",
+ auth, ev_socket(ev)));
+ socket_state(&auth->socket, SS_CONNECTED);
+ send_auth_query(auth);
+ break;
+
+ case ET_READ: /* socket is readable */
+ case ET_EOF: /* end of file on socket */
+ case ET_ERROR: /* error on socket */
+ Debug((DEBUG_LIST, "Auth socket %p [%p] readable", auth, ev_socket(ev)));
+ read_auth_reply(auth);
+ break;
+
+ default:
+#ifndef NDEBUG
+ abort(); /* unrecognized event */
+#endif
+ break;
+ }
+}
+
+/*
+ * destroy_auth_request - stop an auth request completely
+ */
+void destroy_auth_request(struct AuthRequest* auth, int send_reports)
+{
+ struct AuthRequest** authList;
+
+ if (IsDoingAuth(auth)) {
+ authList = &AuthPollList;
+ if (-1 < auth->fd) {
+ close(auth->fd);
+ auth->fd = -1;
+ socket_del(&auth->socket);
+ }
+
+ if (send_reports && IsUserPort(auth->client))
+ sendheader(auth->client, REPORT_FAIL_ID);
+ } else
+ authList = &AuthIncompleteList;
+
+ if (IsDNSPending(auth)) {
+ delete_resolver_queries(auth);
+ if (send_reports && IsUserPort(auth->client))
+ sendheader(auth->client, REPORT_FAIL_DNS);
+ }
+
+ if (send_reports)
+ log_write(LS_RESOLVER, L_INFO, 0, "DNS/AUTH timeout %s",
+ get_client_name(auth->client, HIDE_IP));
+
+ release_auth_client(auth->client);
+ unlink_auth_request(auth, authList);
+ free_auth_request(auth);
+}
+
/*
* make_auth_request - allocate a new auth request
*/
(struct AuthRequest*) MyMalloc(sizeof(struct AuthRequest));
assert(0 != auth);
memset(auth, 0, sizeof(struct AuthRequest));
+ auth->flags = AM_TIMEOUT;
auth->fd = -1;
auth->client = client;
- auth->timeout = CurrentTime + AUTH_TIMEOUT;
+ cli_auth(client) = auth;
+ timer_add(&auth->timeout, auth_timeout_callback, (void*) auth, TT_RELATIVE,
+ AUTH_TIMEOUT);
return auth;
}
*/
void free_auth_request(struct AuthRequest* auth)
{
- if (-1 < auth->fd)
+ if (-1 < auth->fd) {
close(auth->fd);
- MyFree(auth);
+ Debug((DEBUG_LIST, "Deleting auth socket for %p", auth->client));
+ socket_del(&auth->socket);
+ }
+ Debug((DEBUG_LIST, "Deleting auth timeout timer for %p", auth->client));
+ timer_del(&auth->timeout);
}
/*
static void release_auth_client(struct Client* client)
{
assert(0 != client);
+ cli_auth(client) = 0;
cli_lasttime(client) = cli_since(client) = CurrentTime;
if (cli_fd(client) > HighestFd)
HighestFd = cli_fd(client);
LocalClientArray[cli_fd(client)] = client;
add_client_to_list(client);
+ socket_events(&(cli_socket(client)), SOCK_ACTION_SET | SOCK_EVENT_READABLE);
Debug((DEBUG_INFO, "Auth: release_auth_client %s@%s[%s]",
cli_username(client), cli_sockhost(client), cli_sock_ip(client)));
}
assert(0 != auth);
close(auth->fd);
auth->fd = -1;
+ socket_del(&auth->socket);
if (IsUserPort(auth->client))
sendheader(auth->client, REPORT_FAIL_ID);
struct sockaddr_in remote_addr;
struct sockaddr_in local_addr;
int fd;
+ IOResult result;
assert(0 != auth);
assert(0 != auth->client);
remote_addr.sin_port = htons(113);
remote_addr.sin_family = AF_INET;
- if (!os_connect_nonb(fd, &remote_addr)) {
+ if ((result = os_connect_nonb(fd, &remote_addr)) == IO_FAILURE ||
+ !socket_add(&auth->socket, auth_sock_callback, (void*) auth,
+ result == IO_SUCCESS ? SS_CONNECTED : SS_CONNECTING,
+ SOCK_EVENT_READABLE, fd)) {
ServerStats->is_abad++;
/*
* No error report from this...
return 0;
}
+ auth->flags |= AM_SOCKET;
auth->fd = fd;
SetAuthConnect(auth);
+ if (result == IO_SUCCESS)
+ send_auth_query(auth); /* this does a SetAuthPending(auth) for us */
+
return 1;
}
auth = make_auth_request(client);
assert(0 != auth);
+ Debug((DEBUG_INFO, "Beginning auth request on client %p", client));
+
if (!feature_bool(FEAT_NODNS)) {
if (LOOPBACK == inet_netof(cli_ip(client)))
strcpy(cli_sockhost(client), cli_name(&me));
HOSTLEN);
if (IsUserPort(auth->client))
sendheader(client, REPORT_FIN_DNSC);
+ Debug((DEBUG_LIST, "DNS entry for %p was cached", auth->client));
} else
SetDNSPending(auth);
}
}
- if (start_auth_query(auth))
+ if (start_auth_query(auth)) {
+ Debug((DEBUG_LIST, "identd query for %p initiated successfully",
+ auth->client));
link_auth_request(auth, &AuthPollList);
- else if (IsDNSPending(auth))
+ } else if (IsDNSPending(auth)) {
+ Debug((DEBUG_LIST, "identd query for %p not initiated successfully; "
+ "waiting on DNS", auth->client));
link_auth_request(auth, &AuthIncompleteList);
- else {
+ } else {
+ Debug((DEBUG_LIST, "identd query for %p not initiated successfully; "
+ "no DNS pending; releasing immediately", auth->client));
free_auth_request(auth);
release_auth_client(client);
}
}
-/*
- * timeout_auth_queries - timeout resolver and identd requests
- * allow clients through if requests failed
- */
-void timeout_auth_queries(time_t now)
-{
- struct AuthRequest* auth;
- struct AuthRequest* auth_next = 0;
-
- for (auth = AuthPollList; auth; auth = auth_next) {
- auth_next = auth->next;
- if (auth->timeout < CurrentTime) {
- if (-1 < auth->fd) {
- close(auth->fd);
- auth->fd = -1;
- }
-
- if (IsUserPort(auth->client))
- sendheader(auth->client, REPORT_FAIL_ID);
- if (IsDNSPending(auth)) {
- delete_resolver_queries(auth);
- if (IsUserPort(auth->client))
- sendheader(auth->client, REPORT_FAIL_DNS);
- }
- log_write(LS_RESOLVER, L_INFO, 0, "DNS/AUTH timeout %s",
- get_client_name(auth->client, HIDE_IP));
-
- release_auth_client(auth->client);
- unlink_auth_request(auth, &AuthPollList);
- free_auth_request(auth);
- }
- }
- for (auth = AuthIncompleteList; auth; auth = auth_next) {
- auth_next = auth->next;
- if (auth->timeout < CurrentTime) {
- delete_resolver_queries(auth);
- if (IsUserPort(auth->client))
- sendheader(auth->client, REPORT_FAIL_DNS);
- log_write(LS_RESOLVER, L_INFO, 0, "DNS timeout %s",
- get_client_name(auth->client, HIDE_IP));
-
- release_auth_client(auth->client);
- unlink_auth_request(auth, &AuthIncompleteList);
- free_auth_request(auth);
- }
- }
-}
-
/*
* send_auth_query - send the ident server a query giving "theirport , ourport"
* The write is only attempted *once* so it is deemed to be a fail if the
assert(0 != auth);
assert(0 != auth->client);
+ assert(auth = cli_auth(auth->client));
if (IO_SUCCESS == os_recv_nonb(auth->fd, buf, BUFSIZE, &len)) {
buf[len] = '\0';
+ Debug((DEBUG_LIST, "Auth %p [%p] reply: %s", auth, &auth->socket, buf));
username = check_ident_reply(buf);
+ Debug((DEBUG_LIST, "Username: %s", username));
}
close(auth->fd);
auth->fd = -1;
+ Debug((DEBUG_LIST, "Deleting auth [%p] socket %p", auth, &auth->socket));
+ socket_del(&auth->socket);
ClearAuth(auth);
if (!EmptyString(username)) {
const char* const NONB_ERROR_MSG = "error setting non-blocking for %s: %s";
const char* const PEERNAME_ERROR_MSG = "getpeername failed for %s: %s";
const char* const POLL_ERROR_MSG = "poll error for %s: %s";
+const char* const REGISTER_ERROR_MSG = "registering %s: %s";
const char* const REUSEADDR_ERROR_MSG = "error setting SO_REUSEADDR for %s: %s";
const char* const SELECT_ERROR_MSG = "select error for %s: %s";
const char* const SETBUFS_ERROR_MSG = "error setting buffer size for %s: %s";
const char* const TOS_ERROR_MSG = "error setting TOS for %s: %s";
+static void client_sock_callback(struct Event* ev);
+static void client_timer_callback(struct Event* ev);
+
#if !defined(USE_POLL)
#if FD_SETSIZE < (MAXCONNECTIONS + 4)
/*
static int connect_inet(struct ConfItem* aconf, struct Client* cptr)
{
static struct sockaddr_in sin;
+ IOResult result;
assert(0 != aconf);
assert(0 != cptr);
/*
bind(cli_fd(cptr), (struct sockaddr*) &VirtualHost,
sizeof(VirtualHost))) {
report_error(BIND_ERROR_MSG, cli_name(cptr), errno);
+ close(cli_fd(cptr));
+ cli_fd(cptr) = -1;
return 0;
}
if (!os_set_sockbufs(cli_fd(cptr), SERVER_TCP_WINDOW)) {
cli_error(cptr) = errno;
report_error(SETBUFS_ERROR_MSG, cli_name(cptr), errno);
+ close(cli_fd(cptr));
+ cli_fd(cptr) = -1;
return 0;
}
/*
if (!os_set_nonblocking(cli_fd(cptr))) {
cli_error(cptr) = errno;
report_error(NONB_ERROR_MSG, cli_name(cptr), errno);
+ close(cli_fd(cptr));
+ cli_fd(cptr) = -1;
return 0;
}
- if (!os_connect_nonb(cli_fd(cptr), &sin)) {
+ if ((result = os_connect_nonb(cli_fd(cptr), &sin)) == IO_FAILURE) {
cli_error(cptr) = errno;
report_error(CONNECT_ERROR_MSG, cli_name(cptr), errno);
+ close(cli_fd(cptr));
+ cli_fd(cptr) = -1;
return 0;
}
+ if (!socket_add(&(cli_socket(cptr)), client_sock_callback,
+ (void*) cli_connect(cptr),
+ (result == IO_SUCCESS) ? SS_CONNECTED : SS_CONNECTING,
+ SOCK_EVENT_READABLE, cli_fd(cptr))) {
+ cli_error(cptr) = ENFILE;
+ report_error(REGISTER_ERROR_MSG, cli_name(cptr), ENFILE);
+ close(cli_fd(cptr));
+ cli_fd(cptr) = -1;
+ return 0;
+ }
+ cli_freeflag(cptr) |= FREEFLAG_SOCKET;
return 1;
}
sendto_opmask_butone(0, SNO_OLDSNO, "Lost Server Line for %s", cli_name(cptr));
return 0;
}
+ if (s_state(&(cli_socket(cptr))) == SS_CONNECTING)
+ socket_state(&(cli_socket(cptr)), SS_CONNECTED);
if (!EmptyString(aconf->passwd))
sendrawto_one(cptr, MSG_PASS " :%s", aconf->passwd);
aconf->hold += ((aconf->hold - cli_since(cptr) >
feature_int(FEAT_HANGONGOODLINK)) ?
feature_int(FEAT_HANGONRETRYDELAY) : ConfConFreq(aconf));
- if (nextconnect > aconf->hold)
- nextconnect = aconf->hold;
+/* if (nextconnect > aconf->hold) */
+/* nextconnect = aconf->hold; */
}
}
else if (IsUser(cptr)) {
flush_connections(cptr);
LocalClientArray[cli_fd(cptr)] = 0;
close(cli_fd(cptr));
+ socket_del(&(cli_socket(cptr))); /* queue a socket delete */
cli_fd(cptr) = -1;
}
cli_flags(cptr) |= FLAGS_DEADSOCKET;
const char* const throttle_message =
"ERROR :Your host is trying to (re)connect too fast -- throttled\r\n";
/* 12345678901234567890123456789012345679012345678901234567890123456 */
+ const char* const register_message =
+ "ERROR :Unable to complete your registration\r\n";
assert(0 != listener);
cli_nexttarget(new_client) = next_target;
cli_fd(new_client) = fd;
+ if (!socket_add(&(cli_socket(new_client)), client_sock_callback,
+ (void*) cli_connect(new_client), SS_CONNECTED, 0, fd)) {
+ ++ServerStats->is_ref;
+ write(fd, register_message, strlen(register_message));
+ close(fd);
+ cli_fd(new_client) = -1;
+ return;
+ }
+ cli_freeflag(new_client) |= FREEFLAG_SOCKET;
cli_listener(new_client) = listener;
++listener->ref_count;
start_auth(new_client);
}
+/*
+ * update_write
+ *
+ * Determines whether to tell the events engine we're interested in
+ * writable events
+ */
+void update_write(struct Client* cptr)
+{
+ /* If there are messages that need to be sent along, or if the client
+ * is in the middle of a /list, then we need to tell the engine that
+ * we're interested in writable events--otherwise, we need to drop
+ * that interest.
+ */
+ socket_events(&(cli_socket(cptr)),
+ ((MsgQLength(&cli_sendQ(cptr)) || cli_listing(cptr)) ?
+ SOCK_ACTION_ADD : SOCK_ACTION_DEL) | SOCK_EVENT_WRITABLE);
+}
/*
* read_packet
else if (CPTR_KILLED == client_dopacket(cptr, dolen))
return CPTR_KILLED;
}
- }
- return 1;
-}
-static int on_write_unblocked(struct Client* cptr)
-{
- /*
- * ...room for writing, empty some queue then...
- */
- cli_flags(cptr) &= ~FLAGS_BLOCKED;
- if (IsConnecting(cptr)) {
- if (!completed_connection(cptr))
- return 0;
- }
- else if (cli_listing(cptr) && MsgQLength(&(cli_sendQ(cptr))) < 2048)
- list_next_channels(cptr, 64);
- send_queued(cptr);
- return 1;
-}
-
-/*
- * Select / Poll Read Algorithm for ircd
- *
- * We need to check the file descriptors for all the different types
- * of things that use them, so check for reads on everything but connects
- * and writes on connects and descriptors that are blocked
- *
- * for each (client in local) {
- * if (not connecting)
- * check for read;
- * if (connecting or blocked)
- * check for write;
- * }
- * wait for activity;
- *
- * for each (client in local) {
- * if (there are descriptors to check) {
- * if (write activity)
- * send data;
- * if (read activity)
- * read data;
- * }
- * process data read;
- * }
- * Note we must always process data read whether or not there has been
- * read activity or file descriptors set, since data is buffered by the client.
- */
-
-
-#ifdef USE_POLL
-
-/*
- * poll macros
- */
-#if defined(POLLMSG) && defined(POLLIN) && defined(POLLRDNORM)
-# define POLLREADFLAGS (POLLMSG|POLLIN|POLLRDNORM)
-#else
-# if defined(POLLIN) && defined(POLLRDNORM)
-# define POLLREADFLAGS (POLLIN|POLLRDNORM)
-# else
-# if defined(POLLIN)
-# define POLLREADFLAGS POLLIN
-# else
-# if defined(POLLRDNORM)
-# define POLLREADFLAGS POLLRDNORM
-# endif
-# endif
-# endif
-#endif
-
-#if defined(POLLOUT) && defined(POLLWRNORM)
-#define POLLWRITEFLAGS (POLLOUT|POLLWRNORM)
-#else
-# if defined(POLLOUT)
-# define POLLWRITEFLAGS POLLOUT
-# else
-# if defined(POLLWRNORM)
-# define POLLWRITEFLAGS POLLWRNORM
-# endif
-# endif
-#endif
-
-#ifdef POLLHUP
-#define POLLERRORS (POLLHUP|POLLERR)
-#else
-#define POLLERRORS POLLERR
-#endif
-
-/*
- * NOTE: pfd and pfd_count are local variable names in read_message
- */
-#define PFD_SETR(xfd) \
- do { CHECK_ADD_PFD(xfd) pfd->events |= POLLREADFLAGS; } while(0)
-#define PFD_SETW(xfd) \
- do { CHECK_ADD_PFD(xfd) pfd->events |= POLLWRITEFLAGS; } while(0)
-
-#define CHECK_ADD_PFD(xfd) \
- if (pfd->fd != xfd) { \
- pfd = &poll_fds[pfd_count++]; \
- poll_fds[pfd_count].fd = -1; \
- pfd->fd = xfd; \
- pfd->events = 0; \
- }
-
-/*
- * Check all connections for new connections and input data that is to be
- * processed. Also check for connections with data queued and whether we can
- * write it out.
- *
- * Don't ever use ZERO for `delay', unless you mean to poll and then
- * you have to have sleep/wait somewhere else in the code.--msa
- */
-int read_message(time_t delay)
-{
- struct pollfd poll_fds[MAXCONNECTIONS + 1];
- struct Client* cptr;
- struct Listener* listener = 0;
- struct AuthRequest* auth = 0;
- struct AuthRequest* auth_next = 0;
- struct UPing* uping = 0;
- struct UPing* uping_next = 0;
- time_t delay2 = delay;
- int nfds;
- int length;
- int i;
- int res = 0;
- int pfd_count;
- struct pollfd* pfd;
- struct pollfd* res_pfd;
- struct pollfd* uping_pfd;
- int read_ready;
- int write_ready;
-
- unsigned int timeout;
-
- for ( ; ; ) {
- pfd_count = 0;
- pfd = poll_fds;
- res_pfd = 0;
- uping_pfd = 0;
- pfd->fd = -1;
-
- if (-1 < ResolverFileDescriptor) {
- PFD_SETR(ResolverFileDescriptor);
- res_pfd = pfd;
- }
- if (-1 < UPingFileDescriptor) {
- PFD_SETR(UPingFileDescriptor);
- uping_pfd = pfd;
- }
- /*
- * add uping descriptors
- */
- for (uping = uping_begin(); uping; uping = uping_next) {
- uping_next = uping->next;
- if (uping->active) {
- delay2 = 1;
- if (uping->lastsent && CurrentTime > uping->timeout) {
- uping_end(uping);
- continue;
- }
- uping->index = pfd_count;
- PFD_SETR(uping->fd);
- }
- }
- /*
- * add auth file descriptors
- */
- for (auth = AuthPollList; auth; auth = auth->next) {
- assert(-1 < auth->fd);
- auth->index = pfd_count;
- if (IsAuthConnect(auth))
- PFD_SETW(auth->fd);
- else
- PFD_SETR(auth->fd);
- }
- /*
- * add listener file descriptors
- */
- for (listener = ListenerPollList; listener; listener = listener->next) {
- assert(-1 < listener->fd);
- /*
- * pfd_count is incremented by PFD_SETR so we need to save the
- * index first
- */
- listener->index = pfd_count;
- PFD_SETR(listener->fd);
- }
-
- for (i = HighestFd; -1 < i; --i) {
- if ((cptr = LocalClientArray[i])) {
-
- if (DBufLength(&(cli_recvQ(cptr))))
- delay2 = 1;
- if (DBufLength(&(cli_recvQ(cptr))) < 4088 || IsServer(cptr)) {
- PFD_SETR(i);
- }
- if (MsgQLength(&(cli_sendQ(cptr))) || IsConnecting(cptr) ||
- (cli_listing(cptr) && MsgQLength(&(cli_sendQ(cptr))) < 2048)) {
- PFD_SETW(i);
- }
- }
- }
-
- Debug((DEBUG_INFO, "poll: %d %d", delay, delay2));
-
- timeout = (IRCD_MIN(delay2, delay)) * 1000;
-
- nfds = poll(poll_fds, pfd_count, timeout);
-
- CurrentTime = time(0);
- if (-1 < nfds)
- break;
-
- if (EINTR == errno)
- return -1;
- report_error(POLL_ERROR_MSG, cli_name(&me), errno);
- ++res;
- if (res > 5)
- server_restart("too many poll errors");
- sleep(1);
- CurrentTime = time(0);
- }
-
- if (uping_pfd && (uping_pfd->revents & (POLLREADFLAGS | POLLERRORS))) {
- uping_echo();
- --nfds;
- }
- /*
- * check uping replies
- */
- for (uping = uping_begin(); uping; uping = uping_next) {
- uping_next = uping->next;
- if (uping->active) {
- assert(-1 < uping->index);
- if (poll_fds[uping->index].revents) {
- uping_read(uping);
- if (0 == --nfds)
- break;
- }
- else if (CurrentTime > uping->lastsent) {
- uping->lastsent = CurrentTime;
- uping_send(uping);
- }
- }
- }
-
- if (res_pfd && (res_pfd->revents & (POLLREADFLAGS | POLLERRORS))) {
- resolver_read();
- --nfds;
- }
- /*
- * check auth queries
- */
- for (auth = AuthPollList; auth; auth = auth_next) {
- auth_next = auth->next;
- i = auth->index;
- /*
- * check for any event, we only ask for one at a time
- */
- if (poll_fds[i].revents) {
- if (IsAuthConnect(auth))
- send_auth_query(auth);
- else
- read_auth_reply(auth);
- if (0 == --nfds)
- break;
- }
- }
- /*
- * check listeners
- */
- for (listener = ListenerPollList; listener; listener = listener->next) {
- i = listener->index;
- if (poll_fds[i].revents) {
- accept_connection(listener);
- if (0 == --nfds)
- break;
+ /* If there's still data to process, wait 2 seconds first */
+ if (DBufLength(&(cli_recvQ(cptr))) && !NoNewLine(cptr) &&
+ !(cli_freeflag(cptr) & FREEFLAG_TIMER)) {
+ Debug((DEBUG_LIST, "Adding client process timer for %C", cptr));
+ cli_freeflag(cptr) |= FREEFLAG_TIMER;
+ timer_add(&(cli_proc(cptr)), client_timer_callback, cli_connect(cptr),
+ TT_RELATIVE, 2);
}
}
- /*
- * i contains the next non-auth/non-listener index, since we put the
- * resolver, auth and listener, file descriptors in poll_fds first,
- * the very next one should be the start of the clients
- */
- pfd = &poll_fds[++i];
-
- for ( ; (i < pfd_count); ++i, ++pfd) {
- if (!(cptr = LocalClientArray[pfd->fd]))
- continue;
- read_ready = write_ready = 0;
-
- if (0 < nfds && pfd->revents) {
- --nfds;
-
- read_ready = pfd->revents & POLLREADFLAGS;
- write_ready = pfd->revents & POLLWRITEFLAGS;
-
- if (pfd->revents & POLLERRORS) {
- if (pfd->events & POLLREADFLAGS)
- ++read_ready;
- if (pfd->events & POLLWRITEFLAGS)
- ++write_ready;
- }
- }
- if (write_ready) {
- if (!on_write_unblocked(cptr) || IsDead(cptr)) {
- const char* msg = (cli_error(cptr)) ? strerror(cli_error(cptr)) : cli_info(cptr);
- if (!msg)
- msg = "Unknown error";
- exit_client(cptr, cptr, &me, msg);
- continue;
- }
- }
- length = 1; /* for fall through case */
- if ((!NoNewLine(cptr) || read_ready) && !IsDead(cptr)) {
- if (CPTR_KILLED == (length = read_packet(cptr, read_ready)))
- continue;
- }
-#if 0
- /* Bullshit, why would we want to flush sockets while using non-blocking?
- * This uses > 4% cpu! --Run */
- if (length > 0)
- flush_connections(poll_cptr[i]);
-#endif
- if (IsDead(cptr)) {
- const char* msg = (cli_error(cptr)) ? strerror(cli_error(cptr)) : cli_info(cptr);
- if (!msg)
- msg = "Unknown error";
- exit_client(cptr, cptr, &me, (char*) msg);
- continue;
- }
- if (length > 0)
- continue;
- cli_flags(cptr) |= FLAGS_DEADSOCKET;
- /*
- * ...hmm, with non-blocking sockets we might get
- * here from quite valid reasons, although.. why
- * would select report "data available" when there
- * wasn't... So, this must be an error anyway... --msa
- * actually, EOF occurs when read() returns 0 and
- * in due course, select() returns that fd as ready
- * for reading even though it ends up being an EOF. -avalon
- */
- Debug((DEBUG_ERROR, "READ ERROR: fd = %d %d %d", pfd->fd, errno, length));
-
- if ((IsServer(cptr) || IsHandshake(cptr)) && cli_error(cptr) == 0 && length == 0)
- exit_client_msg(cptr, cptr, &me, "Server %s closed the connection (%s)",
- cli_name(cptr), cli_serv(cptr)->last_error_msg);
- else {
- const char* msg = (cli_error(cptr)) ? strerror(cli_error(cptr)) : "EOF from client";
- if (!msg)
- msg = "Unknown error";
- exit_client_msg(cptr, cptr, &me, "Read error: %s", msg);
- }
- }
- return 0;
-}
-#else /* USE_SELECT */
-
-/*
- * Check all connections for new connections and input data that is to be
- * processed. Also check for connections with data queued and whether we can
- * write it out.
- *
- * Don't ever use ZERO for `delay', unless you mean to poll and then
- * you have to have sleep/wait somewhere else in the code.--msa
- */
-int read_message(time_t delay)
-{
- struct Client* cptr;
- struct Listener* listener;
- struct AuthRequest* auth = 0;
- struct AuthRequest* auth_next = 0;
- struct UPing* uping;
- struct UPing* uping_next;
- int nfds;
- struct timeval wait;
- time_t delay2 = delay;
- unsigned int usec = 0;
- int res = 0;
- int length;
- int i;
- int read_ready;
- fd_set read_set;
- fd_set write_set;
-
- for ( ; ; )
- {
- FD_ZERO(&read_set);
- FD_ZERO(&write_set);
-
- if (-1 < ResolverFileDescriptor)
- FD_SET(ResolverFileDescriptor, &read_set);
- if (-1 < UPingFileDescriptor)
- FD_SET(UPingFileDescriptor, &read_set);
- /*
- * set up uping file descriptors
- */
- for (uping = uping_begin(); uping; uping = uping_next) {
- uping_next = uping->next;
- if (uping->active) {
- delay2 = 1;
- if (uping->lastsent && CurrentTime > uping->timeout) {
- uping_end(uping);
- continue;
- }
- assert(-1 < uping->fd);
- FD_SET(uping->fd, &read_set);
- }
- }
- /*
- * set auth file descriptors
- */
- for (auth = AuthPollList; auth; auth = auth->next) {
- assert(-1 < auth->fd);
- if (IsAuthConnect(auth))
- FD_SET(auth->fd, &write_set);
- else /* if (IsAuthPending(auth)) */
- FD_SET(auth->fd, &read_set);
- }
- /*
- * set listener file descriptors
- */
- for (listener = ListenerPollList; listener; listener = listener->next) {
- assert(-1 < listener->fd);
- FD_SET(listener->fd, &read_set);
- }
-
- for (i = HighestFd; i > -1; --i) {
- if ((cptr = LocalClientArray[i])) {
- if (DBufLength(&(cli_recvQ(cptr))))
- delay2 = 1;
- if (DBufLength(&(cli_recvQ(cptr))) < 4088 || IsServer(cptr))
- FD_SET(i, &read_set);
- if (MsgQLength(&(cli_sendQ(cptr))) || IsConnecting(cptr) ||
- (cli_listing(cptr) && MsgQLength(&(cli_sendQ(cptr))) < 2048))
- FD_SET(i, &write_set);
- }
- }
-
- wait.tv_sec = IRCD_MIN(delay2, delay);
- wait.tv_usec = usec;
-
- Debug((DEBUG_INFO, "select: %d %d", delay, delay2));
-
- nfds = select(FD_SETSIZE, &read_set, &write_set, 0, &wait);
-
- CurrentTime = time(0);
-
- if (-1 < nfds)
- break;
-
- if (errno == EINTR)
- return -1;
- report_error(SELECT_ERROR_MSG, cli_name(&me), errno);
- if (++res > 5)
- server_restart("too many select errors");
- sleep(1);
- CurrentTime = time(0);
- }
-
- if (-1 < UPingFileDescriptor && FD_ISSET(UPingFileDescriptor, &read_set)) {
- uping_echo();
- --nfds;
- }
- for (uping = uping_begin(); uping; uping = uping_next) {
- uping_next = uping->next;
- if (uping->active) {
- assert(-1 < uping->fd);
- if (FD_ISSET(uping->fd, &read_set)) {
- uping_read(uping);
- if (0 == --nfds)
- break;
- }
- else if (CurrentTime > uping->lastsent) {
- uping->lastsent = CurrentTime;
- uping_send(uping);
- }
- }
- }
- if (-1 < ResolverFileDescriptor && FD_ISSET(ResolverFileDescriptor, &read_set)) {
- resolver_read();
- --nfds;
- }
- /*
- * Check fd sets for the auth fd's (if set and valid!) first
- * because these can not be processed using the normal loops below.
- * -avalon
- */
- for (auth = AuthPollList; auth; auth = auth_next) {
- auth_next = auth->next;
- assert(-1 < auth->fd);
- if (IsAuthConnect(auth) && FD_ISSET(auth->fd, &write_set)) {
- send_auth_query(auth);
- if (0 == --nfds)
- break;
- }
- else if (FD_ISSET(auth->fd, &read_set)) {
- read_auth_reply(auth);
- if (0 == --nfds)
- break;
- }
- }
- /*
- * next accept connections from active listeners
- */
- for (listener = ListenerPollList; listener; listener = listener->next) {
- assert(-1 < listener->fd);
- if (0 < nfds && FD_ISSET(listener->fd, &read_set))
- accept_connection(listener);
- }
-
- for (i = HighestFd; -1 < i; --i) {
- if (!(cptr = LocalClientArray[i]))
- continue;
- read_ready = 0;
- if (0 < nfds) {
- if (FD_ISSET(i, &write_set)) {
- --nfds;
- if (!on_write_unblocked(cptr) || IsDead(cptr)) {
- const char* msg = (cli_error(cptr)) ? strerror(cli_error(cptr)) : cli_info(cptr);
- if (!msg)
- msg = "Unknown error";
- if (FD_ISSET(i, &read_set))
- --nfds;
- exit_client(cptr, cptr, &me, msg);
- continue;
- }
- }
- if ((read_ready = FD_ISSET(i, &read_set)))
- --nfds;
- }
- length = 1; /* for fall through case */
- if ((!NoNewLine(cptr) || read_ready) && !IsDead(cptr)) {
- if (CPTR_KILLED == (length = read_packet(cptr, read_ready)))
- continue;
- }
- if (IsDead(cptr)) {
- const char* msg = (cli_error(cptr)) ? strerror(cli_error(cptr)) : cli_info(cptr);
- if (!msg)
- msg = "Unknown error";
- exit_client(cptr, cptr, &me, msg);
- continue;
- }
- if (length > 0)
- continue;
-
- /*
- * ...hmm, with non-blocking sockets we might get
- * here from quite valid reasons, although.. why
- * would select report "data available" when there
- * wasn't... So, this must be an error anyway... --msa
- * actually, EOF occurs when read() returns 0 and
- * in due course, select() returns that fd as ready
- * for reading even though it ends up being an EOF. -avalon
- */
- Debug((DEBUG_ERROR, "READ ERROR: fd = %d %d %d", i, cli_error(cptr), length));
-
- if ((IsServer(cptr) || IsHandshake(cptr)) && cli_error(cptr) == 0 && length == 0)
- exit_client_msg(cptr, cptr, &me, "Server %s closed the connection (%s)",
- cli_name(cptr), cli_serv(cptr)->last_error_msg);
- else {
- const char* msg = (cli_error(cptr)) ? strerror(cli_error(cptr)) : "EOF from client";
- if (!msg)
- msg = "Unknown error";
- exit_client_msg(cptr, cptr, &me, "Read error: %s", msg);
- }
- }
- return 0;
+ return 1;
}
-#endif /* USE_SELECT */
-
/*
* connect_server - start or complete a connection to another server
* returns true (1) if successful, false (0) otherwise
*/
add_client_to_list(cptr);
hAddClient(cptr);
- nextping = CurrentTime;
+/* nextping = CurrentTime; */
- return 1;
+ return (s_state(&cli_socket(cptr)) == SS_CONNECTED) ?
+ completed_connection(cptr) : 1;
}
/*
SetYXXServerName(&me, conf->numeric);
}
+/*
+ * Process events on a client socket
+ */
+static void client_sock_callback(struct Event* ev)
+{
+ struct Client* cptr;
+ struct Connection* con;
+ char *fmt = "%s";
+ char *fallback = 0;
+
+ assert(0 != ev_socket(ev));
+ assert(0 != s_data(ev_socket(ev)));
+
+ con = s_data(ev_socket(ev));
+
+ assert(0 != con_client(con) || ev_type(ev) == ET_DESTROY);
+
+ cptr = con_client(con);
+
+ assert(0 == cptr || con == cli_connect(cptr));
+
+ switch (ev_type(ev)) {
+ case ET_DESTROY:
+ con_freeflag(con) &= ~FREEFLAG_SOCKET;
+
+ if (!con_freeflag(con) && !cptr)
+ free_connection(con);
+ break;
+
+ case ET_CONNECT: /* socket connection completed */
+ if (!completed_connection(cptr) || IsDead(cptr))
+ fallback = cli_info(cptr);
+ break;
+
+ case ET_ERROR: /* an error occurred */
+ fallback = cli_info(cptr);
+ cli_error(cptr) = ev_data(ev);
+ if (s_state(&(con_socket(con))) == SS_CONNECTING) {
+ completed_connection(cptr);
+ break;
+ }
+ /*FALLTHROUGH*/
+ case ET_EOF: /* end of file on socket */
+ Debug((DEBUG_ERROR, "READ ERROR: fd = %d %d", cli_fd(cptr),
+ cli_error(cptr)));
+ cli_flags(cptr) |= FLAGS_DEADSOCKET;
+ if ((IsServer(cptr) || IsHandshake(cptr)) && cli_error(cptr) == 0) {
+ exit_client_msg(cptr, cptr, &me, "Server %s closed the connection (%s)",
+ cli_name(cptr), cli_serv(cptr)->last_error_msg);
+ return;
+ } else {
+ fmt = "Read error: %s";
+ fallback = "EOF from client";
+ }
+ break;
+
+ case ET_WRITE: /* socket is writable */
+ cli_flags(cptr) &= ~FLAGS_BLOCKED;
+ if (cli_listing(cptr) && MsgQLength(&(cli_sendQ(cptr))) < 2048)
+ list_next_channels(cptr, 64);
+ Debug((DEBUG_SEND, "Sending queued data to %C", cptr));
+ send_queued(cptr);
+ break;
+
+ case ET_READ: /* socket is readable */
+ if (!IsDead(cptr)) {
+ Debug((DEBUG_DEBUG, "Reading data from %C", cptr));
+ if (read_packet(cptr, 1) == 0) /* error while reading packet */
+ fallback = "EOF from client";
+ }
+ break;
+
+ default:
+#ifndef NDEBUG
+ abort(); /* unrecognized event */
+#endif
+ break;
+ }
+
+ assert(0 == cptr || 0 == cli_connect(cptr) || con == cli_connect(cptr));
+
+ if (fallback) {
+ const char* msg = (cli_error(cptr)) ? strerror(cli_error(cptr)) : fallback;
+ if (!msg)
+ msg = "Unknown error";
+ exit_client_msg(cptr, cptr, &me, fmt, msg);
+ }
+}
+
+/*
+ * Process a timer on client socket
+ */
+static void client_timer_callback(struct Event* ev)
+{
+ struct Client* cptr;
+ struct Connection* con;
+
+ assert(0 != ev_timer(ev));
+ assert(0 != t_data(ev_timer(ev)));
+ assert(ET_DESTROY == ev_type(ev) || ET_EXPIRE == ev_type(ev));
+
+ con = t_data(ev_timer(ev));
+ assert(0 != con_client(con) || ev_type(ev) == ET_DESTROY);
+
+ cptr = con_client(con);
+
+ assert(0 == cptr || con == cli_connect(cptr));
+
+ con_freeflag(con) &= ~FREEFLAG_TIMER; /* timer has expired... */
+
+ if (ev_type(ev)== ET_DESTROY) {
+ if (!con_freeflag(con) && !cptr)
+ free_connection(con); /* client is being destroyed */
+ } else {
+ Debug((DEBUG_LIST, "Client process timer for %C expired; processing",
+ cptr));
+ read_packet(cptr, 0); /* read_packet will re-add timer if needed */
+ }
+
+ assert(0 == cptr || 0 == cli_connect(cptr) || con == cli_connect(cptr));
+}
if (aconf)
free_conf(aconf);
fbclose(file);
- nextping = nextconnect = CurrentTime;
+/* nextping = nextconnect = CurrentTime; */
feature_mark(); /* reset unmarked features */
return 1;
}
/* 236 */
{ 0 },
/* 237 */
- { 0 },
+ { RPL_STATSENGINE, "%s :Event loop engine", "237" },
/* 238 */
{ RPL_STATSFLINE, "%c %s %s", "238" },
/* 239 */
SetBurst(cptr);
- nextping = CurrentTime;
+/* nextping = CurrentTime; */
/*
* NOTE: check for acptr->user == cptr->serv->user is necessary to insure
"g - Global bans (G-lines).",
"k - Local bans (K-Lines).",
"o - Operator information.",
+ "e - Report server event loop engine.",
"f - Feature settings.",
"m - Message usage information.",
"t - Local connection statistics (Total SND/RCV, etc).",
m_lusers(sptr, sptr, 1, parv);
update_load();
motd_signon(sptr);
- nextping = CurrentTime;
+/* nextping = CurrentTime; */
if (cli_snomask(sptr) & SNO_NOISY)
set_snomask(sptr, cli_snomask(sptr) & SNO_NOISY, SNO_ADD);
IPcheck_connect_succeeded(sptr);
if ((len = deliver_it(to, &(cli_sendQ(to))))) {
msgq_delete(&(cli_sendQ(to)), len);
cli_lastsq(to) = MsgQLength(&(cli_sendQ(to))) / 1024;
- if (IsBlocked(to))
+ if (IsBlocked(to)) {
+ update_write(to);
return;
+ }
}
else {
if (IsDead(to)) {
/* Ok, sendq is now empty... */
client_drop_sendq(cli_connect(to));
+ update_write(to);
}
void send_buffer(struct Client* to, struct MsgBuf* buf, int prio)
msgq_add(&(cli_sendQ(to)), buf, prio);
client_add_sendq(cli_connect(to), &send_queues);
+ update_write(to);
/*
* Update statistics. The following is slightly incorrect
#include "client.h"
#include "ircd.h"
#include "ircd_alloc.h"
+#include "ircd_events.h"
#include "ircd_log.h"
#include "ircd_osdep.h"
#include "ircd_string.h"
static struct UPing* pingList = 0;
int UPingFileDescriptor = -1; /* UDP listener socket for upings */
+static struct Socket upingSock;
+
/*
* pings_begin - iterator function for ping list
*/
}
}
+/* Called when the event engine detects activity on the UPing socket */
+static void uping_echo_callback(struct Event* ev)
+{
+ assert(ev_type(ev) == ET_READ);
+
+ uping_echo();
+}
+
/*
* Setup a UDP socket and listen for incoming packets
*/
close(fd);
return -1;
}
+ if (!socket_add(&upingSock, uping_echo_callback, 0, SS_DATAGRAM,
+ SOCK_EVENT_READABLE, fd)) {
+ Debug((DEBUG_ERROR, "UPING: Unable to queue fd to event system"));
+ close(fd);
+ return -1;
+ }
UPingFileDescriptor = fd;
return fd;
}
}
+/* Callback when socket has data to read */
+static void uping_read_callback(struct Event* ev)
+{
+ struct UPing *pptr;
+
+ assert(0 != ev_socket(ev));
+ assert(0 != s_data(ev_socket(ev)));
+
+ pptr = s_data(ev_socket(ev));
+
+ Debug((DEBUG_SEND, "uping_read_callback called, %p (%d)", pptr,
+ ev_type(ev)));
+
+ if (ev_type(ev) == ET_DESTROY) { /* being destroyed */
+ pptr->freeable &= ~UPING_PENDING_SOCKET;
+
+ if (!pptr->freeable)
+ MyFree(pptr); /* done with it, finally */
+ } else {
+ assert(ev_type(ev) == ET_READ);
+
+ uping_read(pptr); /* read uping response */
+ }
+}
+
+/* Callback to send another ping */
+static void uping_sender_callback(struct Event* ev)
+{
+ struct UPing *pptr;
+
+ assert(0 != ev_timer(ev));
+ assert(0 != t_data(ev_timer(ev)));
+
+ pptr = t_data(ev_timer(ev));
+
+ Debug((DEBUG_SEND, "uping_sender_callback called, %p (%d)", pptr,
+ ev_type(ev)));
+
+ if (ev_type(ev) == ET_DESTROY) { /* being destroyed */
+ pptr->freeable &= ~UPING_PENDING_SENDER;
+
+ if (!pptr->freeable)
+ MyFree(pptr); /* done with it, finally */
+ } else {
+ assert(ev_type(ev) == ET_EXPIRE);
+
+ pptr->lastsent = CurrentTime; /* store last ping time */
+ uping_send(pptr); /* send a ping */
+
+ if (pptr->sent == pptr->count) /* done sending pings, don't send more */
+ timer_del(ev_timer(ev));
+ }
+}
+
+/* Callback to kill a ping */
+static void uping_killer_callback(struct Event* ev)
+{
+ struct UPing *pptr;
+
+ assert(0 != ev_timer(ev));
+ assert(0 != t_data(ev_timer(ev)));
+
+ pptr = t_data(ev_timer(ev));
+
+ Debug((DEBUG_SEND, "uping_killer_callback called, %p (%d)", pptr,
+ ev_type(ev)));
+
+ if (ev_type(ev) == ET_DESTROY) { /* being destroyed */
+ pptr->freeable &= ~UPING_PENDING_KILLER;
+
+ if (!pptr->freeable)
+ MyFree(pptr); /* done with it, finally */
+ } else {
+ assert(ev_type(ev) == ET_EXPIRE);
+
+ uping_end(pptr); /* <FUDD>kill the uping, kill the uping!</FUDD> */
+ }
+}
+
/*
* start_ping
*/
{
assert(0 != pptr);
+ timer_add(&pptr->sender, uping_sender_callback, (void*) pptr,
+ TT_PERIODIC, 1);
+ timer_add(&pptr->killer, uping_killer_callback, (void*) pptr,
+ TT_RELATIVE, UPINGTIMEOUT);
+ pptr->freeable |= UPING_PENDING_SENDER | UPING_PENDING_KILLER;
+
sendcmdto_one(&me, CMD_NOTICE, pptr->client, "%C :Sending %d ping%s to %s",
pptr->client, pptr->count, (pptr->count == 1) ? "" : "s",
pptr->name);
- pptr->timeout = CurrentTime + UPINGTIMEOUT;
pptr->active = 1;
}
pptr->ms_min = pingtime;
if (pingtime > pptr->ms_max)
pptr->ms_max = pingtime;
-
- pptr->timeout = CurrentTime + UPINGTIMEOUT;
- Debug((DEBUG_SEND, "read_ping: %d bytes, ti %lu: [%s %s] %lu ms",
- len, pptr->timeout, buf, (buf + strlen(buf) + 1), pingtime));
+ timer_chg(&pptr->killer, TT_RELATIVE, UPINGTIMEOUT);
s = pptr->buf + strlen(pptr->buf);
sprintf(s, " %u", pingtime);
assert(0 != pptr);
memset(pptr, 0, sizeof(struct UPing));
+ if (!socket_add(&pptr->socket, uping_read_callback, (void*) pptr,
+ SS_DATAGRAM, SOCK_EVENT_READABLE, fd)) {
+ sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :UPING: Can't queue fd for "
+ "reading", sptr);
+ close(fd);
+ MyFree(pptr);
+ return 0;
+ }
+
pptr->fd = fd;
pptr->sin.sin_port = htons(port);
pptr->sin.sin_addr.s_addr = aconf->ipnum.s_addr;
pptr->count = IRCD_MIN(20, count);
pptr->client = sptr;
pptr->index = -1;
+ pptr->freeable = UPING_PENDING_SOCKET;
strcpy(pptr->name, aconf->name);
pptr->next = pingList;
uping_erase(pptr);
if (pptr->client)
ClearUPing(pptr->client);
- MyFree(pptr);
+ if (pptr->freeable & UPING_PENDING_SOCKET)
+ socket_del(&pptr->socket);
+ if (pptr->freeable & UPING_PENDING_SENDER)
+ timer_del(&pptr->sender);
+ if (pptr->freeable & UPING_PENDING_KILLER)
+ timer_del(&pptr->killer);
}
void uping_cancel(struct Client *sptr, struct Client* acptr)