store the flag strings.
</function>
+<function>
+int sig_signal(struct Signal* sig);
+
+This macro returns the signal number for the given struct Signal.
+</function>
+
+<function>
+void* sig_data(struct Signal* sig);
+
+When a struct Signal is initialized, data that the call-back function
+may find useful is stored in the struct Signal. This macro returns
+that pointer.
+</function>
+
+<function>
+int sig_ed_int(struct Signal* sig);
+
+Engines may find it convenient to associate an integer with a struct
+Signal. This macro may be used to retrieve that integer or, when used
+as an lvalue, to assign a value to it. Engine data must be either an
+int or a void*; use of both is prohibited.
+</function>
+
+<function>
+void* sig_ed_ptr(struct Signal* sig);
+
+Engines may find it convenient to associate a void* pointer with a
+struct Signal. This macro may be used to retrieve that pointer or,
+when used as an lvalue, to assign a value to it. Engine data must be
+either an int or a void*; use of both is prohibited.
+</function>
+
+<function>
+int sig_active(struct Signal* sig);
+
+A signal's active flag is set when initialized by signal_add(). This
+may be used by the application to determine whether or not the signal
+has been initialized yet. If it is, sig_active() returns a non-zero
+value; otherwise, its value is 0.
+</function>
+
+<function>
+void signal_add(struct Signal* signal, EventCallBack call, void* data,
+ int sig);
+
+This function is called to add a signal to the list of signals to be
+monitored. The _signal_ parameter is a pointer is a pointer to a
+struct Signal that is allocated by the application. The _call_
+parameter is a pointer to a function to process any signal events.
+The _data_ parameter is for use of the signal call-back and may be
+zero. The _sig_ parameter is the integer value of the signal to be
+monitored.
+</function>
+
+<function>
+enum TimerType t_type(struct Timer* tim);
+
+This macro returns the type of the given timer.
+</function>
+
+<function>
+time_t t_value(struct Timer* tim);
+
+This macro returns the value that was used when the given timer was
+initialized by the events subsystem. It will contain an absolute time
+if the timer type is TT_ABSOLUTE, and a relative time otherwise.
+</function>
+
+<function>
+time_t t_expire(struct Timer* tim);
+
+This macro returns the absolute time at which the timer will next
+expire.
+</function>
+
+<function>
+void* t_data(struct Timer* tim);
+
+When a struct Timer is initialized, data that the call-back function
+may find useful is stored in the struct Socket. This macro returns
+that pointer.
+</function>
+
+<function>
+int t_ed_int(struct Timer *tim);
+
+Engines may find it convenient to associate an integer with a struct
+Timer. This macro may be used to retrieve that integer or, when used
+as an lvalue, to assign a value to it. Engine data must be either an
+int or a void*; use of both is prohibited.
+</function>
+
+<function>
+void* t_ed_ptr(struct Timer *tim);
+
+Engines may find it convenient to associate a void* pointer with a
+struct Timer. This macro may be used to retrieve that pointer or,
+when used as an lvalue, to assign a value to it. Engine data must be
+either an int or a void*; use of both is prohibited.
+</function>
+
+<function>
+int t_active(struct Timer *tim);
+
+A timer's active flag is set when initialized by timer_add(), and is
+cleared immediately prior to generating an event of type ET_DESTROY.
+This may be used by the application to determine whether or not the
+timer is still in use by the events subsystem. If it is, s_active()
+returns a non-zero value; otherwise, its value is 0.
+</function>
+
+<function>
+void timer_add(struct Timer* timer, EventCallBack call, void* data,
+ enum TimerType type, time_t value);
+
+This function is called to initialize and queue a timer. The _timer_
+parameter is a pointer to a struct Timer that is allocated by the
+application. The _call_ parameter is a pointer to a function to
+process the timer's expiration. The _data_ parameter is for use of
+the timer call-back and may be zero. The _type_ parameter must be one
+of the valid timer types--TT_ABSOLUTE, TT_RELATIVE, or TT_PERIODIC.
+Finally, _value_ is the value for the timer's expiration.
+</function>
+
+<function>
+void timer_del(struct Timer* timer);
+
+When the application no longer needs a TT_PERIODIC timer, or when it
+wishes to stop a TT_ABSOLUTE or TT_RELATIVE timer before its
+expiration, it should call the timer_del() function.
+</function>
+
+<function>
+void timer_chg(struct Timer* timer, enum TimerType type, time_t value);
+
+Occasionally, an application may wish to delay an existing TT_ABSOLUTE
+or TT_RELATIVE timer; this may be done with the timer_chg() function.
+The _type_ parameter must be one of TT_ABSOLUTE or
+TT_RELATIVE--changing the values of TT_PERIODIC timers is not
+supported. The _value_ parameter is the same as would be given to
+timer_add() for that particular type of timer.
+</function>
+
+<function>
+void timer_run(void);
+
+When an engine has finished processing the results of its socket and
+signal checks--just before it loops around to test for more events--it
+should call the timer_run() function to expire any waiting timers.
+</function>
+
+<function>
+time_t timer_next(struct Generators* gen);
+
+Most engines will use a blocking call with a timeout to check for
+socket activity. To determine when the next timer needs to be run,
+and thus to calculate how long the call should block, the engine
+should call timer_next() with the _gen_ parameter passed to the
+_EngineLoop_ function. The timer_next() function returns an absolute
+time, which may have to be massaged into a relative time before the
+engine may use it.
+</function>
+
+<function>
+const char* timer_to_name(enum TimerType type);
+
+This function is defined only when DEBUGMODE is #define'd. It takes
+the given _type_ and returns a string giving that type's name. This
+function may safely be called from Debug() macros.
+</function>
+
+<function>
+enum EventType ev_type(struct Event* ev);
+
+This macro simply returns the type of the event _ev_.
+</function>
+
+<function>
+int ev_data(struct Event* ev);
+
+When an event is generated, a single integer can be passed along as a
+piece of extra information. This can be used, for instance, to carry
+an errno value when an ET_ERROR is generated. This macro simply
+returns that integer.
+</function>
+
+<function>
+struct Socket* ev_socket(struct Event* ev);
+
+If the event was generated by a socket, this macro returns a pointer
+to the struct Socket that generated the event. The results are
+undefined if the event was not generated by a socket.
+</function>
+
+<function>
+struct Signal* ev_signal(struct Event* ev);
+
+If the event was generated by a signal, this macro returns a pointer
+to the struct Signal that generated the event. The results are
+undefined if the event was not generated by a signal.
+</function>
+
+<function>
+struct Timer* ev_timer(struct Event* ev);
+
+If the event was generated by a timer, this macro returns a pointer to
+the struct Timer that generated the event. The results are undefined
+if the event was not generated by a timer.
+</function>
+
+<function>
+void event_init(int max_sockets);
+
+Before any of the functions or macros described here can be called,
+the events subsystem must be initialized by calling event_init(). The
+_max_sockets_ parameter specifies to the events subsystem how many
+sockets it must be able to support; this figure may be used for memory
+allocation by the engines.
+</function>
+
+<function>
+void event_loop(void);
+
+Once the initial sockets are open, signals added, and timers queued,
+the application must call the event_loop() function in order to
+actually begin monitoring those sockets, signals, and timers.
+</function>
+
+<function>
+void event_generate(enum EventType type, void* arg, int data);
+
+This is the function called by the events subsystem to generate
+particular events. The _type_ parameter specifies the type of event
+to generate, and the _arg_ parameter must be a pointer to the event's
+generator. The _data_ parameter may be used for passing such things
+as signal numbers or errno values.
+</function>
+
+<function>
+const char* event_to_name(enum EventType type);
+
+This function is defined only when DEBUGMODE is #define'd. It takes
+the given _type_ and returns a string giving that event type's name.
+This function may safely be called from Debug() macros.
+</function>
+
+<function>
+const char* engine_name(void);
+
+This function is used to retrieve the name of the engine presently
+being used by the events subsystem.
+</function>
+
+<function>
+void gen_ref_inc(void* gen);
+
+This macro increments the reference count of the generator _gen_,
+preventing it from simply disappearing without warning.
+</function>
+
+<function>
+void gen_ref_dec(void* gen);
+
+This macro decrements the reference count of the generator _gen_, and
+releases the memory associated with it by generating at ET_DESTROY
+event if the reference count falls to zero and the generator is marked
+for destruction. No references should be made to the generator after
+calling this macro.
+</function>
+
<authors>
Kev <klmitch@mit.edu>
</authors>
<changelog>
+[2001-6-14 Kev] Finished initial description of the events subsystem.
+
[2001-6-13 Kev] Initial description of the events subsystem.
</changelog>
--- /dev/null
+Some users can be very annoying, as any IRC operator can attest. Some
+can in fact be downright abusive. Sometimes the best way of dealing
+with these users is to ban them from the entire network. The G-line
+system permits this.
+
+G-lines are fairly complicated. A G-line can be active or inactive,
+either locally or globally. It can be a purely local G-line, or
+global. It could be based on IP address or on host name. In short,
+there are many variations on the basic G-line. Worse, there is also
+the concept of a "bad channel," or BADCHAN, that has been tacked onto
+the G-line subsystem, when it should have been a separate command in
+the first place.
+
+Different types of G-lines are differentiated from each other through
+the use of various flags. Some of these flags are maintained solely
+by the G-line subsystem, where as others are passed to various
+functions in the API.
+
+<macro>
+#define GLINE_MAX_EXPIRE 604800 /* max expire: 7 days */
+
+This macro lists the maximum expire time a G-line is permitted to
+have. This value is limited to 7 days to prevent abuse of the system.
+</macro>
+
+<macro>
+#define GLINE_ACTIVE 0x0001
+
+This flag is used to indicate that a given G-line is globally active.
+</macro>
+
+<macro>
+#define GLINE_IPMASK 0x0002
+
+This flag is used to indicate that a given G-line is an IP mask. This
+flag is maintained internally by the G-line subsystem.
+</macro>
+
+<macro>
+#define GLINE_BADCHAN 0x0004
+
+This flag is used to indicate that a given G-line specifies a BADCHAN,
+a channel that users are not permitted to join. This flag is
+maintained internally, but is also used in gline_find() to search for
+a BADCHAN for a particular channel.
+</macro>
+
+<macro>
+#define GLINE_LOCAL 0x0008
+
+This flag is used to indicate that a given G-line is a local G-line.
+Local G-lines do not affect users on other servers.
+</macro>
+
+<macro>
+#define GLINE_ANY 0x0010
+
+This flag is passed to gline_find() to signal that function to return
+any G-line or BADCHAN that matches the passed mask string. It is
+never set on a real G-line.
+</macro>
+
+<macro>
+#define GLINE_FORCE 0x0020
+
+This flag is passed to gline_add() to force the server to accept an
+expire time that might be out of bounds. It is never set on a real
+G-line.
+</macro>
+
+<macro>
+#define GLINE_EXACT 0x0040
+
+This flag is passed to gline_find() to signal that function to return
+only G-lines that exactly match the passed mask string. That is, the
+ircd_strcmp() function is called to compare the G-line to the mask,
+rather than the match() function. This flag is never set on a real
+G-line.
+</macro>
+
+<macro>
+#define GLINE_LDEACT 0x0080 /* locally deactivated */
+
+This flag is set on global G-lines that have been locally
+deactivated. This flag is maintained internally by the G-line
+subsystem.
+</macro>
+
+<macro>
+#define GLINE_GLOBAL 0x0100 /* find only global glines */
+
+This flag is passed to gline_find() or gline_lookup() to specify that
+the caller is only interested in global G-lines. This flag is never
+set on a real G-line.
+</macro>
+
+<macro>
+#define GLINE_LASTMOD 0x0200 /* find only glines with non-zero lastmod */
+
+This flag is passed to gline_find() or gline_lookup() to specify that
+the caller is only interested in G-lines with a non-zero lastmod time,
+that is, G-lines that were not set by a U-lined service. This flag is
+never set on a real G-line.
+</macro>
+
+<struct>
+struct Gline;
+
+The struct Gline describes everything about a given G-line. None of
+its fields may be directly accessed by the application; use the
+functions and macros described below instead.
+</struct>
+
+<function>
+int GlineIsActive(struct Gline* g);
+
+This macro returns a non-zero value if the G-line is active, or 0
+otherwise. If a G-line is locally deactivated, this macro will always
+return 0.
+</function>
+
+<function>
+int GlineIsRemActive(struct Gline* g);
+
+This macro returns a non-zero value if the G-line is active, ignoring
+whether or not it is locally deactivated.
+</function>
+
+<function>
+int GlineIsIpMask(struct Gline* g);
+
+This macro returns a non-zero value if the G-line is an IP mask.
+</function>
+
+<function>
+int GlineIsBadChan(struct Gline* g);
+
+This macro returns a non-zero value if a G-line actually represents a
+BADCHAN.
+</function>
+
+<function>
+int GlineIsLocal(struct Gline* g);
+
+This macro returns a non-zero value if a G-line is local only.
+</function>
+
+<function>
+char* GlineUser(struct Gline* g);
+
+This macro returns the user name associated with the G-line. If the
+G-line represents a BADCHAN, this will contain the channel name.
+</function>
+
+<function>
+char* GlineHost(struct Gline* g);
+
+This macro returns the host name associated with the G-line. If the
+G-line represents a BADCHAN, this will be a NULL pointer.
+</function>
+
+<function>
+char* GlineReason(struct Gline* g);
+
+This macro returns the reason that was given when the G-line was set.
+</function>
+
+<function>
+time_t GlineLastMod(struct Gline* g);
+
+G-lines that were not set by a U-lined service have a modification
+time that must be monotonically increasing. This macro simply returns
+that modification time.
+</function>
+
+<function>
+int gline_propagate(struct Client *cptr, struct Client *sptr,
+ struct Gline *gline);
+
+When a global G-line is set or modified, all other servers must be
+notified of the new G-line. This function takes care of propagating
+the G-line specified by _gline_, originated by the client _sptr_, to
+all servers except _cptr_ (which may be a NULL pointer).
+</function>
+
+<function>
+int gline_add(struct Client *cptr, struct Client *sptr, char *userhost,
+ char *reason, time_t expire, time_t lastmod, unsigned int flags);
+
+This function simply adds a G-line, set by _sptr_ and with a
+_userhost_, _reason_, _expire_, and _lastmod_ as specified. The
+_flags_ parameter is a bit mask consisting of the binary OR of
+GLINE_FORCE, GLINE_LOCAL, or GLINE_ACTIVE, as appropriate. The
+gline_add() function also calls gline_propagate() to propagate the
+G-line, and kills off any local users matching the G-line if it is
+active.
+</function>
+
+<function>
+int gline_activate(struct Client *cptr, struct Client *sptr,
+ struct Gline *gline, time_t lastmod, unsigned int flags);
+
+This function activates the G-line specified by _gline_, setting its
+_lastmod_ time as specified. If _flags_ is GLINE_LOCAL and if the
+G-line is locally deactivated, this function will turn off the local
+deactivation flag, but will not modify _lastmod_. If the G-line is
+globally deactivated, passing this function the GLINE_LOCAL flag will
+have no effect.
+</function>
+
+<function>
+int gline_deactivate(struct Client *cptr, struct Client *sptr,
+ struct Gline *gline, time_t lastmod, unsigned int flags);
+
+This function is similar to gline_activate() except that it
+deactivates the G-line. If the given G-line is local, or if it was
+set by a U-lined service (and GLINE_LOCAL was not passed via _flags_),
+then the G-line is deleted from memory. In all other cases, the
+G-line is simply deactivated, either locally (if GLINE_LOCAL was
+passed via _flags_) or globally. Global deactivation will update the
+_lastmod_ time.
+</function>
+
+<function>
+struct Gline *gline_find(char *userhost, unsigned int flags);
+
+This function looks up a G-line matching the given _userhost_ value,
+under control of the _flags_ parameter. Valid _flags_ that may be
+passed are: GLINE_BADCHAN, GLINE_ANY, GLINE_GLOBAL, GLINE_LASTMOD, or
+GLINE_EXACT, each described above.
+</function>
+
+<function>
+struct Gline *gline_lookup(struct Client *cptr, unsigned int flags);
+
+This function looks up a G-line matching the given client, specified
+by _cptr_, under the control of the _flags_. Valid values for _flags_
+are GLINE_GLOBAL and GLINE_LASTMOD, as described above.
+</function>
+
+<function>
+void gline_free(struct Gline *gline);
+
+This function releases all storage associated with a given G-line.
+</function>
+
+<function>
+void gline_burst(struct Client *cptr);
+
+This function generates a burst of all existing global G-lines and
+BADCHANs and sends them to the server specified by _cptr_.
+</function>
+
+<function>
+int gline_resend(struct Client *cptr, struct Gline *gline);
+
+This function resends the _gline_ to a server specified by _cptr_.
+This may be used if, for instance, it is discovered that a server is
+not synchronized with respect to a particular G-line.
+</function>
+
+<function>
+int gline_list(struct Client *sptr, char *userhost);
+
+This function sends the information about a G-line matching _userhost_
+to the client specified by _sptr_. If _userhost_ is a NULL pointer, a
+list of all G-lines is sent.
+</function>
+
+<function>
+void gline_stats(struct Client *sptr);
+
+This function generates a list of all G-lines, sending them to the
+user _sptr_ by a /STATS G response.
+</function>
+
+<authors>
+Kev <klmitch@mit.edu>
+</authors>
+
+<changelog>
+[2001-6-15 Kev] Initial documentation for the G-line API.
+</changelog>
--- /dev/null
+These functions are intended to be a complete replacement for sprintf
+and sprintf_irc. They are a (nearly) complete reimplementation, and
+of course they're snprintf clones, making it more difficult for
+accidental buffer overflows to crop up.
+
+First off, what's missing? These functions support all ANSI C
+conversion specifiers and selected ones from ISO 9x, with the
+exception of all floating-point conversions. The floating-point
+conversions are tricky, and will likely be dependent on the
+representation of a floating-point number on a particular
+architecture. While that representation is likely to conform to some
+standard, it is not currently used in ircu, so seemed like a good
+thing to omit, given the difficulty of implementing it.
+
+There are two more things missing from this implementation that would
+be required by ANSI; the first is support for multibyte character
+strings, and the second is support for locales, neither of which have
+any relevance for ircu, so again omission seemed to be a good policy.
+Additionally, %#x always causes '0x' (or '0X') to be printed, even if
+the number is zero.
+
+These functions also have some extensions not seen in a
+standards-compliant implementation; technically, the ISO 9x extensions
+fall into this category, for instance. The ISO 9x extensions
+supported are type extensions--%ju, %tu, and %zu, for instance; %qu
+and %hhu are also supported. The extensions added for use in ircu are
+%Tu, which takes a time_t, and the new %C conversion, which inserts
+either a numeric or a nick, dependent on the <dest> parameter. The
+GNU %m extension, which inserts the strerror() string corresponding to
+the current value of errno, is also supported, as is a special %v
+extension, which essentially does a recursive call to ircd_snprintf.
+
+The following description is descended from the Linux man page for the
+printf family of functions.
+
+The format string is composed of zero or more directives: ordinary
+characters (not %), which are copied unchanged to the output stream;
+and conversion specifications, each of which results in fetching zero
+or more subsequent arguments. Each conversion specification is
+introduced by the character %. The arguments must correspond properly
+(after type promotion) with the conversion specifier. After the %,
+the following appear in sequence:
+
+* Zero or more of the following flags:
+
+ # specifying that the value should be converted to an "alternate
+ form." For c, d, i, n, p, s, and u conversions, this option
+ has no effect. For o conversions, the precision of the number
+ is increased to force the first character of the output string
+ to a zero (except if a zero value is printed with an explicit
+ precision of zero). For x and X conversions, the string '0x'
+ (or '0X' for X conversions) is prepended to it. For e, E, f,
+ g, and G conversions, the result will always contain a decimal
+ point, even if no digits follow it (normally, a decimal point
+ appears in the results of those conversions only if a digit
+ follows). For g and G conversions, trailing zeros are not
+ removed from the result as they would otherwise be. For C
+ conversions, if the destination is local and the origin is a
+ user, the nick!user@host form is used.
+
+ 0 specifying zero padding. For all conversions except n, the
+ converted value is padded on the left with zeros rather than
+ blanks. If a precision is given with a numeric conversion (d,
+ i, o, u, i, x, and X), the 0 flag is ignored.
+
+ - (a negative field width flag) indicates the converted value is
+ to be left adjusted on the field boundary. Except for n
+ conversions, the converted value is padded on the right with
+ blanks, rather than on the left with blanks or zeros. A -
+ overrides a 0 if both are given.
+
+ ' ' (a space) specifying that a blank should be left before a
+ positive number produced by a signed conversion (d, e, E, f,
+ g, G, or i).
+
+ + specifying that a sign always be placed before a number
+ produced by a signed conversion. A + overrides a space if
+ both are used.
+
+ : specifying that a struct Client name should be preceded by a
+ ':' character if the destination is a user
+
+* An optional decimal digit string specifying a minimum field width.
+ If the converted value has fewer characters than the field width, it
+ will be padded with spaces on the left (or right, if the
+ left-adjustment flag has been given) to fill out the field width.
+
+* An optional precision, in the form of a period (`.') followed by an
+ optional digit string. If the digit string is omitted, the
+ precision is taken as zero. This gives the minimum number of digits
+ to appear for d, i, o, u, x, and X conversions, the number of digits
+ to appear after the decimal-point for e, E, and f conversions, the
+ maximum number of significant digits for g and G conversions, or the
+ maximum number of characters to be printed from a string for s
+ conversions.
+
+* The optional character h, specifying that a following d, i, o, u, x,
+ or X conversion corresponds to a short int or unsigned short int
+ argument, or that a following n conversion corresponds to a pointer
+ to a short int argument. If the h character is given again, char is
+ used instead of short int.
+
+* The optional character l (ell) specifying that a following d, i, o,
+ u, x, or X conversion applies to a pointer to a long int or unsigned
+ long int argument, or that a following n conversion corresponds to a
+ pointer to a long int argument.
+
+* The character L specifying that a following e, E, f, g, or G
+ conversion corresponds to a long double argument, or a following d,
+ i, o, u, x, or X conversion corresponds to a long long argument.
+ Note that long long is not specified in ANSI C and therefore not
+ portable to all architectures.
+
+* The optional character q. This is equivalent to L.
+
+* A j character specifying that the following integer (d, i, o, u, x,
+ or X) conversion corresponds to an intmax_t argument.
+
+* A t character specifying that the following integer (d, i, o, u, x,
+ or X) conversion corresponds to a ptrdiff_t argument.
+
+* A z character specifying that the following integer (d, i, o, u, x,
+ or X) conversion corresponds to a size_t argument.
+
+* A T character specifying that the following integer (d, i, o, u, x,
+ or X) conversion corresponds to a time_t argument.
+
+* A character that specifies the type of conversion to be applied.
+
+A field width or precision, or both, may be indicated by an asterisk
+`*' instead of a digit string. In this case, an int argument supplies
+the field width or precision. A negative field width is treated as a
+left adjustment flag followed by a positive field width; a negative
+precision is treated as though it were missing.
+
+The conversion specifiers and their meanings are:
+
+ diouxX The int (or appropriate variant) argument is converted
+ to signed decimal (d and i), unsigned octal (o),
+ unsigned decimal (u), or unsigned hexadecimal (x and
+ X) notation. The letters abcdef are used for x
+ conversions; the letters ABCDEF are used for X
+ conversions. The precision, if any, gives the minimum
+ number of digits that must appear; if the converted
+ value requires fewer digits, it is padded on the left
+ with zeros.
+
+ eE [NOT IMPLEMENTED] The double argument is rounded and
+ converted in the style [-]d.dddedd where there is one
+ digit before the decimal-point character and the
+ number of digits after it is equal to the precision;
+ if the precision is missing, it is taken as 6; if the
+ precision is zero, no decimal-point character
+ appears. An E conversion uses the letter E (rather
+ than e) to introduce the exponent. The exponent
+ always contains at least two digits; if the value is
+ zero, the exponent is 00.
+
+ f [NOT IMPLEMENTED] The double argument is rounded and
+ converted to decimal notation in the style
+ [-]ddd.ddd, where the number of digits after the
+ decimal-point character is equal to the precision
+ specification. If the precision is missing, it is
+ taken as 6; if the precision is explicitly zero, no
+ decimal-point character appears. If a decimal point
+ appears, at least one digit appears before it.
+
+ g [NOT IMPLEMENTED] The double argument is converted in
+ style f or e (or E for G conversions). The precision
+ specifies the number of significant digits. If the
+ precision is missing, 6 digits are given; if the
+ precision is zero, it is treated as 1. Style e is
+ used if the exponent from its conversion is less than
+ -4 or greater than or equal to the precision.
+ Trailing zeros are removed from the fractional part of
+ the result; a decimal point appears only if it is
+ followed by at least one digit.
+
+ c The int argument is converted to an unsigned char, and
+ the resulting character is written.
+
+ s The "char *" argument is expected to be a pointer to
+ an array of character type (pointer to a string).
+ Characters from the array are written up to (but not
+ including) a terminating NUL character; if a precision
+ is specified, no more than the number specified are
+ written. If a precision is given, no null character
+ need be present; if the precision is not specified, or
+ is greater than the size of the array, the array must
+ contain a terminating NUL character.
+
+ p The "void *" pointer argument is printed in
+ hexadecimal (as if by %#x or %#lx).
+
+ n The number of characters written so far is stored into
+ the integer indicated by the ``int *'' (or variant)
+ pointer argument. No argument is converted.
+
+ m The error message associated with the current value of
+ errno is printed as if by %s.
+
+ C The client argument identifier is printed under the
+ control of the <dest> argument; if <dest> is NULL or
+ is a user, the client's name (nickname or server name)
+ is printed; otherwise, the client's network numeric is
+ printed.
+
+ H The channel argument identifier (channel name) is
+ printed.
+
+ v The argument given must be a pointer to a struct
+ VarData with vd_format and vd_args must be initialized
+ appropriately. On return, vd_chars will contain the
+ number of characters added to the buffer, and
+ vd_overflow will contain the number of characters that
+ could not be added due to buffer overflow or due to a
+ precision.
+
+ % A `%' is written. No argument is converted. The
+ complete conversion specification is `%%'.
+
+In no case does a non-existent or small field width cause truncation
+of a field; if the result of a conversion is wider than the field
+width, the field is expanded to contain the conversion result.
+
+<struct>
+struct VarData {
+ size_t vd_chars; /* number of characters inserted */
+ size_t vd_overflow; /* number of characters that couldn't be */
+ const char *vd_format; /* format string */
+ va_list vd_args; /* arguments for %v */
+};
+
+This structure is used by the %v conversion specification. The
+_vd_format_ element must contain a format string, and the _vd_args_
+element must be a variable argument list. Upon return from
+ircd_snprintf() or ircd_vsnprintf(), the _vd_chars_ element will
+contain the number of characters that were able to be inserted, and
+the _vd_overflow_ element will contain the number of characters that
+could not be inserted.
+</struct>
+
+<function>
+int ircd_snprintf(struct Client *dest, char *buf, size_t buf_len,
+ const char *format, ...);
+
+This formats the argument list, under control of the _format_, into
+the buffer specified by _buf_, the size of which is specified by
+_buf_len_. The _dest_ parameter is used to determine whether to use a
+numeric or a nickname for %C conversions.
+</function>
+
+<function>
+int ircd_vsnprintf(struct Client *dest, char *buf, size_t buf_len,
+ const char *format, va_list args);
+
+This function is identical to the ircd_snprintf() function except for
+the variable argument list given by _args_.
+</function>
+
+<authors>
+Kev <klmitch@mit.edu>
+</authors>
+
+<changelog>
+[2001-6-15 Kev] Initial documentation of the ircd_snprintf family of
+functions.
+</changelog>
--- /dev/null
+The server has a Message of the Day (MOTD) which is often used for
+describing the Acceptable Usage Policy, where to get help if you have
+problems, and so on. Older versions of ircd had a lot of duplicated
+code, as well as some inefficiencies, all related to sending the
+MOTD. As of u2.10.11, there is an API specifically for MOTDs. This
+API caches the MOTDs in memory for efficiency. Sending a MOTD to a
+client is as simple as calling a single function.
+
+<function>
+void motd_init(void);
+
+This function initializes the MOTD subsystem. It will also read in
+the default MOTD (usually ircd.motd) and the remote MOTD (usually
+remote.motd) files.
+</function>
+
+<function>
+int motd_send(struct Client* cptr);
+
+This function sends an appropriate MOTD to the client specified by
+_cptr_. If _cptr_ is not a local client, the remote MOTD will be
+sent; otherwise, an attempt will be made to find a T-line in the
+configuration file that matches the client. If no T-line can be
+found, the default MOTD will be sent to the client. This function
+returns 0 for the convenience of other functions that must have an
+integer return value.
+</function>
+
+<function>
+void motd_signon(struct Client* cptr);
+
+This function is similar to motd_send(), described above, except that
+it will only send a message to the client indicating when the MOTD was
+last modified if the FEAT_NODEFAULTMOTD feature is set to TRUE.
+</function>
+
+<function>
+void motd_recache(void);
+
+The MOTD system will not automatically detect when MOTD files have
+been modified. This function causes the MOTD system to clear the MOTD
+cache and re-read the files.
+</function>
+
+<function>
+void motd_add(const char *hostmask, const char *path);
+
+This function is used to add a MOTD to be sent to clients possessing a
+given _hostmask_. If _hostmask_ is a numerical string, it is
+interpreted as a connection class.
+</function>
+
+<function>
+void motd_clear(void);
+
+This function clears the list of special MOTDs. Only the default MOTD
+and remote MOTD are not affected by this function.
+</function>
+
+<function>
+void motd_report(struct Client *to);
+
+The motd_report() function sends a list of the T-lines stored in
+memory to the client specified by _to_. Access control should be
+handled by the caller.
+</function>
+
+<authors>
+Kev <klmitch@mit.edu>
+</authors>
+
+<changelog>
+[2001-6-15 Kev] Initial documentation of the MOTD interface.
+</changelog>
--- /dev/null
+Many messages generated by an IRC server are sent to multiple
+recipients. Previous versions of ircd used DBuf to store these
+messages until they could actually be sent. The problem with using a
+DBuf for this, though, is that there are multiple copies of the same
+message hanging around. Another problem is that there is at least one
+strcpy() or equivalent call for each destination the message is sent
+to. A simple solution to this problem is to use messages queues.
+This file documents the MsgQ interface for ircd.
+
+The MsgQ interface is loosely based on the API for DBuf. Although the
+structures are vastly different, most calls, including several of the
+macros, are similar to certain pieces of the DBuf API. This made
+retrofitting ircd with MsgQ support much simpler.
+
+<struct>
+struct MsgCounts {
+ int alloc;
+ int used;
+};
+
+The MsgCounts structure may be used for determining how much memory is
+in use by the MsgQ system. The _alloc_ element is a count of the
+total number of structures (of whatever type) that have been
+allocated; the _used_ element is a count of how many are actually in
+use. MsgQ never releases any of its allocated memory; instead, it
+places unused structures onto a free list.
+</struct>
+
+<struct>
+struct MsgBuf;
+
+The MsgBuf structure contains the actual message, along with a
+reference count and the message's length. None of its fields are
+directly accessible by the application.
+</struct>
+
+<struct>
+struct MsgQ;
+
+The MsgQ structure is a structure allocated by the application that is
+used by the MsgQ system to describe an entire message queue, including
+both normal and priority queues. None of its fields are directly
+accessible by the application.
+</struct>
+
+<global>
+struct MsgCounts msgBufCounts; /* resource count for struct MsgBuf */
+
+This global variable counts the number of MsgBuf structures that have
+been allocated. This may be used to determine how much memory is in
+use by the MsgQ system.
+</global>
+
+<global>
+struct MsgCounts msgCounts; /* resource count for struct Msg */
+
+This global variable counts the number of Msg structures that have
+been allocated. The Msg structure describes the link between a queue
+and a message. It is not accessible to the application, and so not
+further documented here.
+</global>
+
+<function>
+unsigned int MsgQLength(struct MsgQ* mq);
+
+This macro returns the number of bytes in a particular user's message
+queue.
+</function>
+
+<function>
+unsigned int MsgQCount(struct MsgQ* mq);
+
+This macro returns the number of messages in a particular user's
+message queue.
+</function>
+
+<function>
+void MsgQClear(struct MsgQ* mq);
+
+This macro simply clears the content of a particular message queue.
+NOTE: This macro evaluates its argument twice.
+</function>
+
+<function>
+void msgq_init(struct MsgQ *mq);
+
+This function initializes a caller-allocated message queue to be
+empty. Calling this function on a message queue with messages in it
+WILL RESULT IN A MEMORY LEAK.
+</function>
+
+<function>
+void msgq_delete(struct MsgQ *mq, unsigned int length);
+
+This function removes the given number of bytes from the message
+queue. If entire messages have been sent, they will be unlinked from
+the queue. The _length_ parameter does not need to correspond to a
+given message's length; the MsgQ system is able to deal with messages
+that have only partially been sent.
+</function>
+
+<function>
+int msgq_mapiov(const struct MsgQ *mq, struct iovec *iov, int count,
+ unsigned int *len);
+
+The msgq_mapiov() function takes a struct MsgQ (specified by the _mq_
+parameter) and a caller allocated struct iovec array (specified by the
+_iov_ parameter) and maps the contents of the message into the struct
+iovec array. The _count_ parameter must indicate the total number of
+elements available for msgq_mapiov() to use. The _len_ parameter must
+be a pointer to an unsigned int, and upon return from the function
+will contain the total number of bytes that have been mapped into the
+struct iovec array. This function returns the number of struct iovec
+elements that have been filled. For more information about the
+purpose of struct iovec, see your system's man page for the writev()
+function.
+</function>
+
+<function>
+struct MsgBuf *msgq_make(struct Client *dest, const char *format, ...);
+
+This function allocates a struct MsgBuf and calls ircd_vsnprintf()
+with the _dest_ and _format_ parameters to fill it in. Most callers
+should use the send_buffer() function (declared in send.h) to attach
+the struct MsgBuf to a client's message queue.
+</function>
+
+<function>
+struct MsgBuf *msgq_vmake(struct Client *dest, const char *format, va_list vl);
+
+This function is identical to msgq_make() except that it takes a
+va_list (given by the _vl_ parameter) and calls ircd_vsnprintf() to
+format the message.
+</function>
+
+<function>
+void msgq_append(struct Client *dest, struct MsgBuf *mb, const char *format,
+ ...);
+
+Occasionally a caller is not able to completely compute a message
+before calling msgq_make(). When this happens, the msgq_append()
+function may be called to append more text onto the struct MsgBuf
+specified by the _mb_ parameter. As with msgq_make(), the _dest_ and
+_format_ parameters are passed to ircd_vsnprintf(), along with the
+additional arguments.
+</function>
+
+<function>
+void msgq_clean(struct MsgBuf *mb);
+
+As mentioned above, struct MsgBuf includes a reference count. When
+that reference count reaches zero, the structure is released. The
+reference count is set to 1 by msgq_make() and msgq_vmake(). Once a
+given message has been attached to all the queues it needs to be, the
+caller should call the msgq_clean() function to decrement this
+reference count. This function will place the struct MsgBuf back onto
+the free list if it did not get attached to any message queues. The
+msgq_delete() function calls msgq_clean() internally, so the
+application need not call msgq_clean() explicitly afterwards.
+</function>
+
+<function>
+void msgq_add(struct MsgQ *mq, struct MsgBuf *mb, int prio);
+
+This function is used to attach a given struct MsgBuf, as specified by
+the _mb_ parameter, to a given message queue. The _prio_ parameter,
+if non-zero, specifies that the message should be placed on the
+priority queue. This function is called by send_buffer(), defined in
+send.h; most applications should call that function, rather than this
+one.
+</function>
+
+<function>
+void msgq_count_memory(size_t *msg_alloc, size_t *msg_used,
+ size_t *msgbuf_alloc, size_t *msgbuf_used);
+
+This function simply takes the counts kept in msgBufCounts and
+msgCounts and multiplies them by the appropriate structure sizes,
+storing the resulting sizes into its parameters.
+</function>
+
+<function>
+unsigned int msgq_bufleft(struct MsgBuf *mb);
+
+This function is for use in conjunction with msgq_append(). It
+returns the total number of bytes of free storage in the given _mb_.
+</function>
+
+<authors>
+Kev <klmitch@mit.edu>
+</authors>
+
+<changelog>
+[2001-6-15 Kev] Initial documentation for the MsgQ functions.
+</changelog>
--- /dev/null
+Access control becomes more of a problem as you have more and more
+users that need to access certain features. As it stands, ircu has
+only 3 access levels: ordinary user, local operator, and global
+operator. This is hardly enough control, especially over some of the
+more advanced and powerful features, such as G-lines.
+
+Since u2.10.11, ircu includes the concept of privileges. Privileges
+are basically an arbitrarily long bit string. Access to particular
+features is governed by the value of a particular bit of that bit
+string--in other words, privileges are a form of Access Control List.
+This document covers the basic structures and macros used by the
+privileges system.
+
+<struct>
+struct Privs;
+
+The Privs structure stores a privileges bit string and represents a
+user's entire privilege set. This is implemented as a structure,
+rather than as an array of integers, in order to leverage C's
+structure copy.
+</struct>
+
+<function>
+void PrivSet(struct Privs pset, int priv);
+
+This macro sets the privilege specified by _priv_ in the privileges
+structure. This macro evaluates the _priv_ argument twice.
+</function>
+
+<function>
+void PrivClr(struct Privs pset, int priv);
+
+This macro clears the privilege specified by _priv_ in the privileges
+structure. This macro evaluates the _priv_ argument twice.
+</function>
+
+<function>
+int PrivHas(struct Privs pset, int priv);
+
+This macro tests whether the privilege specified by _priv_ is set in
+the privileges structure, returning non-zero if it is. This macro
+evaluates the _priv_ argument twice.
+</function>
+
+<function>
+void GrantPriv(struct Client* cli, int priv);
+
+This macro grants a particular client, specified by _cli_, the
+privilege specified by _priv_. This macro evaluates the _priv_
+argument twice.
+</function>
+
+<function>
+void RevokePriv(struct Client* cli, int priv);
+
+This macro revokes the privilege specified by _priv_ from the client.
+This macro evaluates the _priv_ argument twice.
+</function>
+
+<function>
+int HasPriv(struct Client* cli, int priv);
+
+This macro tests whether the client specified by _cli_ has the
+privilege specified by _priv_, returning non-zero if so. This macro
+evaluates the _priv_ argument twice.
+</function>
+
+<function>
+void client_set_privs(struct Client* client);
+
+The ircu configuration file does not yet support privileges. This
+function thus sets the appropriate privileges for an operator, based
+upon various feature settings. It should be called whenever there is
+a change in a user's IRC operator status.
+</function>
+
+<function>
+int client_report_privs(struct Client *to, struct Client *client);
+
+This function sends the client specified by _to_ a list of the
+privileges that another client has. It returns a value of 0 for the
+convenience of other functions that must return an integer value.
+</function>
+
+<authors>
+Kev <klmitch@mit.edu>
+</authors>
+
+<changelog>
+[2001-6-15 Kev] Initial documentation of the privileges system.
+</changelog>
--- /dev/null
+The send functions are perhaps the most important API in all of ircd;
+without them, communications would not be possible. Most of these
+functions are pretty much stand-alone, although one or two are
+intended for use in conjunction with the MsgQ interface. The send
+functions use the MsgQ interface internally, but for the most part,
+this fact is hidden from the caller.
+
+Command tokenization provides the greatest complication. The
+functions do use ircd_snprintf() internally, so the use of numerics
+doesn't increase that complication. The tokenization issue is dealt
+with by making each function accept two char* pointers, _cmd_ and
+_tok_, in that order, and then defining a CMD_* macro in msg.h that
+contains the message string and the token string in that order. When
+one of these functions is called, it determines whether the
+destination will be a server or a user, then selects the correct one,
+either _cmd_ or _tok_, for that message.
+
+The MsgQ interface provides the concept of a priority queue; messages
+which must be sent as soon as possible, regardless of what other
+messages may already be in the queue. The sendcmdto_prio_one() and
+sendcmdto_flag_butone() functions make use of this priority queue.
+The function send_buffer() also takes a _prio_ argument that should be
+non-zero if the message passed to it should be placed in the priority
+queue.
+
+<macro>
+#define SKIP_DEAF 0x01 /* skip users that are +d */
+
+This flag may be passed to sendcmdto_channel_butone() to cause a
+message passed by that function to skip users that are +d. See the
+documentation for sendcmdto_channel_butone() for more information.
+</macro>
+
+<macro>
+#define SKIP_BURST 0x02 /* skip users that are bursting */
+
+This is another flag that may be passed to
+sendcmdto_channel_butone(). Its purpose is to cause the server to not
+send the message across a link that is still in the "burst" stage of
+network junction. See the documentation for
+sendcmdto_channel_butone() for more information.
+</macro>
+
+<macro>
+#define SKIP_NONOPS 0x04 /* skip users that aren't chanops */
+
+Some messages may need to be passed only to channel operators. This
+flag is passed to sendcmdto_channel_butone() when that is the case.
+See the documentation for sendcmdto_channel_butone() for more
+information.
+</macro>
+
+<function>
+void send_buffer(struct Client* to, struct MsgBuf* buf, int prio);
+
+Some applications may need to build a message piece by piece, directly
+utilizing the MsgQ interface. The function send_buffer() is used when
+that message has been completed to place the message on a client's
+queue. See the documentation for the MsgQ interface for more
+information about struct MsgBuf and the _buf_ parameter.
+</function>
+
+<function>
+void flush_connections(struct Client* cptr);
+
+This function attempts to send all queued data to a client specified
+by _cptr_. If _cptr_ is 0, all clients with non-empty send queues
+will have their queues flushed.
+</function>
+
+<function>
+void send_queued(struct Client *to);
+
+This function attempts to send all queued data to a client specified
+by _to_. The _to_ parameter is not permitted to be 0. This is the
+function called by flush_connections().
+</function>
+
+<function>
+void sendrawto_one(struct Client *to, const char *pattern, ...);
+
+Most of the actual send functions in this API send their data with a
+prefix--the numeric of the origin. This function is used when a
+message should be sent _without_ that prefix. The caller must specify
+the complete message, including the exact command, with the _pattern_
+argument and the variable argument list following it.
+</function>
+
+<function>
+void sendcmdto_one(struct Client *from, const char *cmd, const char *tok,
+ struct Client *to, const char *pattern, ...);
+
+This function is used for sending messages to specific clients. The
+origin of the message is specified using the _from_ parameter; this
+will be used to formulate the origin. As mentioned above, _cmd_ and
+_tok_ are used to determine the command and token to be used. The
+_to_ parameter specifies which client the message should be sent to.
+The origin and command will be formatted and followed by a space; the
+given _pattern_ and the following arguments are passed to
+ircd_snprintf() for formatting.
+</function>
+
+<function>
+void sendcmdto_prio_one(struct Client *from, const char *cmd, const char *tok,
+ struct Client *to, const char *pattern, ...);
+
+This function is identical to sendcmdto_one() except that messages
+formatted using it will be placed onto the priority queue.
+</function>
+
+<function>
+void sendcmdto_serv_butone(struct Client *from, const char *cmd,
+ const char *tok, struct Client *one,
+ const char *pattern, ...);
+
+This function treats its arguments similar to sendcmdto_one() does.
+Messages passed created with this function are sent to all directly
+linked servers except for the _one_ passed. If _one_ is 0, the
+message is sent to all linked servers.
+</function>
+
+<function>
+void sendcmdto_common_channels(struct Client *from, const char *cmd,
+ const char *tok, const char *pattern, ...);
+
+When a user quits IRC, all of the other users on the channels that the
+user is on must receive a single QUIT message. This function formats
+the message, under control of _from_ (for the origin prefix), _cmd_
+and _tok_, and _pattern_ and the variable argument list, and sends
+that message to all local users on the same channels as the user
+specified by _from_. This function does not send any messages across
+server<->server links.
+</function>
+
+<function>
+void sendcmdto_channel_butserv(struct Client *from, const char *cmd,
+ const char *tok, struct Channel *to,
+ const char *pattern, ...);
+
+This function is used to send a command to every local user on a
+particular channel, specified by _to_. No messages are sent across
+the server<->server links.
+</function>
+
+<function>
+void sendcmdto_channel_butone(struct Client *from, const char *cmd,
+ const char *tok, struct Channel *to,
+ struct Client *one, unsigned int skip,
+ const char *pattern, ...);
+
+This function is used mostly for sending PRIVMSG commands to
+particular channels. The users that receive the message are under the
+control of the _skip_ parameter, which is a binary OR of the
+SKIP_DEAF, SKIP_BURST, and SKIP_NONOPS flags, depending on what
+channel users should see the message. This function sends messages
+across both client<->server and server<->server links, as needed. The
+client specified by _one_ will not receive a copy of the message.
+</function>
+
+<function>
+void sendcmdto_flag_butone(struct Client *from, const char *cmd,
+ const char *tok, struct Client *one,
+ unsigned int flag, const char *pattern, ...);
+
+This function is used for sending messages to clients with specific
+user modes set (specified by the _flag_ parameter). Three flags make
+sense for this function: FLAGS_WALLOP (user mode +w), FLAGS_DEBUG
+(user mode +g), and FLAGS_OPER. FLAGS_OPER has a special meaning that
+further restricts distribution of the message only to IRC operators.
+For the purposes of this function, no distinction is made between
+global operators and local operators.
+</function>
+
+<function>
+void sendcmdto_match_butone(struct Client *from, const char *cmd,
+ const char *tok, const char *to,
+ struct Client *one, unsigned int who,
+ const char *pattern, ...);
+
+Certain kinds of global messages may be sent by IRC operators. This
+function implements those global messages. The _to_ parameter is used
+to specify a pattern by which to filter users, while _who_ specifies
+whether that pattern is to be applied to the user's server name or to
+the user's host name. The _who_ parameter may be one of MATCH_SERVER
+or MATCH_HOST; these two macros are defined in s_user.h. The _one_
+parameter will not receive a copy of the message.
+</function>
+
+<function>
+void sendto_opmask_butone(struct Client *one, unsigned int mask,
+ const char *pattern, ...);
+
+The sendto_opmask_butone() function sends a server notice to all
+subscribing users except for _one_. The _mask_ parameter is one of
+the SNO_* values defined in client.h and is used for selection of
+subscribing users.
+</function>
+
+<function>
+void vsendto_opmask_butone(struct Client *one, unsigned int mask,
+ const char *pattern, va_list vl);
+
+The vsendto_opmask_butone() function is identical to the
+sendto_opmask_butone() function except that instead of a variable
+argument list, it takes a va_list, specified by _vl_.
+</function>
+
+<macro>
+#define SND_EXPLICIT 0x40000000 /* first arg is a pattern to use */
+
+When this flag, defined in ircd_reply.h, is combined with the _reply_
+argument to the send_reply() function, the format string send_reply()
+uses is obtained from the first argument in the variable argument list
+passed to that function, rather than from the table of replies.
+</macro>
+
+<function>
+int send_reply(struct Client* to, int reply, ...);
+
+The send_reply() function, declared in ircd_reply.h, is used to send
+clients numeric replies. Unless SND_EXPLICIT is used, the pattern
+will be extracted from a table of replies.
+</function>
+
+<authors>
+Kev <klmitch@mit.edu>
+</authors>
+
+<changelog>
+[2001-6-15 Kev] Initial documentation for the send functions.
+</changelog>