From ef861c17bf212f79b709d4e337c5b2977d9be76c Mon Sep 17 00:00:00 2001 From: "Kevin L. Mitchell" Date: Fri, 15 Jun 2001 20:53:40 +0000 Subject: [PATCH] Author: Kev Log message: Finished up the events API documentation; wrote documentation for gline, ircd_snprintf, motd, msgq, privileges, and the send functions. Still to document: modebuf, mode_parse(), joinbuf, and jupe. git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@504 c9e4aea6-c8fd-4c43-8297-357d70d61c8c --- doc/api/events.txt | 272 ++++++++++++++++++++++++++++++++++++ doc/api/gline.txt | 283 ++++++++++++++++++++++++++++++++++++++ doc/api/ircd_snprintf.txt | 268 ++++++++++++++++++++++++++++++++++++ doc/api/motd.txt | 74 ++++++++++ doc/api/msgq.txt | 195 ++++++++++++++++++++++++++ doc/api/privileges.txt | 91 ++++++++++++ doc/api/send.txt | 231 +++++++++++++++++++++++++++++++ 7 files changed, 1414 insertions(+) create mode 100644 doc/api/gline.txt create mode 100644 doc/api/ircd_snprintf.txt create mode 100644 doc/api/motd.txt create mode 100644 doc/api/msgq.txt create mode 100644 doc/api/privileges.txt create mode 100644 doc/api/send.txt diff --git a/doc/api/events.txt b/doc/api/events.txt index 9e83036..cadfa70 100644 --- a/doc/api/events.txt +++ b/doc/api/events.txt @@ -535,10 +535,282 @@ but may only be called once, since it uses function static storage to store the flag strings. + +int sig_signal(struct Signal* sig); + +This macro returns the signal number for the given struct Signal. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +enum TimerType t_type(struct Timer* tim); + +This macro returns the type of the given timer. + + + +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. + + + +time_t t_expire(struct Timer* tim); + +This macro returns the absolute time at which the timer will next +expire. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +enum EventType ev_type(struct Event* ev); + +This macro simply returns the type of the event _ev_. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +const char* engine_name(void); + +This function is used to retrieve the name of the engine presently +being used by the events subsystem. + + + +void gen_ref_inc(void* gen); + +This macro increments the reference count of the generator _gen_, +preventing it from simply disappearing without warning. + + + +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. + + Kev +[2001-6-14 Kev] Finished initial description of the events subsystem. + [2001-6-13 Kev] Initial description of the events subsystem. diff --git a/doc/api/gline.txt b/doc/api/gline.txt new file mode 100644 index 0000000..4da9eb5 --- /dev/null +++ b/doc/api/gline.txt @@ -0,0 +1,283 @@ +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. + + +#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. + + + +#define GLINE_ACTIVE 0x0001 + +This flag is used to indicate that a given G-line is globally active. + + + +#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. + + + +#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. + + + +#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. + + + +#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. + + + +#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. + + + +#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. + + + +#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. + + + +#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. + + + +#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. + + + +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. + + + +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. + + + +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. + + + +int GlineIsIpMask(struct Gline* g); + +This macro returns a non-zero value if the G-line is an IP mask. + + + +int GlineIsBadChan(struct Gline* g); + +This macro returns a non-zero value if a G-line actually represents a +BADCHAN. + + + +int GlineIsLocal(struct Gline* g); + +This macro returns a non-zero value if a G-line is local only. + + + +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. + + + +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. + + + +char* GlineReason(struct Gline* g); + +This macro returns the reason that was given when the G-line was set. + + + +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. + + + +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). + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +void gline_free(struct Gline *gline); + +This function releases all storage associated with a given G-line. + + + +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_. + + + +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. + + + +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. + + + +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. + + + +Kev + + + +[2001-6-15 Kev] Initial documentation for the G-line API. + diff --git a/doc/api/ircd_snprintf.txt b/doc/api/ircd_snprintf.txt new file mode 100644 index 0000000..ee9b7f2 --- /dev/null +++ b/doc/api/ircd_snprintf.txt @@ -0,0 +1,268 @@ +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 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 argument; if 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 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. + + + +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. + + + +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_. + + + +Kev + + + +[2001-6-15 Kev] Initial documentation of the ircd_snprintf family of +functions. + diff --git a/doc/api/motd.txt b/doc/api/motd.txt new file mode 100644 index 0000000..5d54cf4 --- /dev/null +++ b/doc/api/motd.txt @@ -0,0 +1,74 @@ +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. + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +Kev + + + +[2001-6-15 Kev] Initial documentation of the MOTD interface. + diff --git a/doc/api/msgq.txt b/doc/api/msgq.txt new file mode 100644 index 0000000..cfa6ef6 --- /dev/null +++ b/doc/api/msgq.txt @@ -0,0 +1,195 @@ +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 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 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 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 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. + + + +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. + + + +unsigned int MsgQLength(struct MsgQ* mq); + +This macro returns the number of bytes in a particular user's message +queue. + + + +unsigned int MsgQCount(struct MsgQ* mq); + +This macro returns the number of messages in a particular user's +message queue. + + + +void MsgQClear(struct MsgQ* mq); + +This macro simply clears the content of a particular message queue. +NOTE: This macro evaluates its argument twice. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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_. + + + +Kev + + + +[2001-6-15 Kev] Initial documentation for the MsgQ functions. + diff --git a/doc/api/privileges.txt b/doc/api/privileges.txt new file mode 100644 index 0000000..dd8697a --- /dev/null +++ b/doc/api/privileges.txt @@ -0,0 +1,91 @@ +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 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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +Kev + + + +[2001-6-15 Kev] Initial documentation of the privileges system. + diff --git a/doc/api/send.txt b/doc/api/send.txt new file mode 100644 index 0000000..ebf09e8 --- /dev/null +++ b/doc/api/send.txt @@ -0,0 +1,231 @@ +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. + + +#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. + + + +#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. + + + +#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. + + + +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. + + + +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. + + + +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(). + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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. + + + +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_. + + + +#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. + + + +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. + + + +Kev + + + +[2001-6-15 Kev] Initial documentation for the send functions. + -- 2.20.1