<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://wiki.darenet.org/skins/common/feed.css?12"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://wiki.darenet.org/index.php?action=history&amp;feed=atom&amp;title=ircu_api_-_modebuf</id>
		<title>ircu api - modebuf - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.darenet.org/index.php?action=history&amp;feed=atom&amp;title=ircu_api_-_modebuf"/>
		<link rel="alternate" type="text/html" href="http://wiki.darenet.org/index.php?title=ircu_api_-_modebuf&amp;action=history"/>
		<updated>2026-05-20T06:11:49Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.15.1</generator>

	<entry>
		<id>http://wiki.darenet.org/index.php?title=ircu_api_-_modebuf&amp;diff=2275&amp;oldid=prev</id>
		<title>Secretagent:&amp;#32;New page: &lt;pre&gt;Generating and parsing channel mode strings is often a very complicated process.  The ModeBuf interface, along with the associated mode parsing functions, attempt to make this much mo...</title>
		<link rel="alternate" type="text/html" href="http://wiki.darenet.org/index.php?title=ircu_api_-_modebuf&amp;diff=2275&amp;oldid=prev"/>
				<updated>2008-04-25T04:05:11Z</updated>
		
		<summary type="html">&lt;p&gt;New page: &amp;lt;pre&amp;gt;Generating and parsing channel mode strings is often a very complicated process.  The ModeBuf interface, along with the associated mode parsing functions, attempt to make this much mo...&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;pre&amp;gt;Generating and parsing channel mode strings is often a very&lt;br /&gt;
complicated process.  The ModeBuf interface, along with the associated&lt;br /&gt;
mode parsing functions, attempt to make this much more programmatic.&lt;br /&gt;
The interface to the functions in this suite is itself very&lt;br /&gt;
complicated, unfortunately, though most of the complication is in the&lt;br /&gt;
effects of various flags on the operation of the functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;struct&amp;gt;&lt;br /&gt;
struct ModeBuf;&lt;br /&gt;
&lt;br /&gt;
This structure is used to accumulate and describe several mode&lt;br /&gt;
changes.  None of its fields are directly or indirectly accessible to&lt;br /&gt;
the application; a struct ModeBuf is only suitable for passing to the&lt;br /&gt;
modebuf_*() suite of functions.  ModeBuf structures must be allocated&lt;br /&gt;
by the caller.&lt;br /&gt;
&amp;lt;/struct&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;function&amp;gt;&lt;br /&gt;
void modebuf_init(struct ModeBuf *mbuf, struct Client *source,&lt;br /&gt;
		  struct Client *connect, struct Channel *chan,&lt;br /&gt;
		  unsigned int dest);&lt;br /&gt;
&lt;br /&gt;
This function initializes a caller-allocated ModeBuf, _mbuf_, with the&lt;br /&gt;
given parameters.  If the mode should not be sent to a particular&lt;br /&gt;
server, perhaps because it was received from that server, that server&lt;br /&gt;
should be specified by the _connect_ parameter.  The channel the mode&lt;br /&gt;
change will take place on is given by the _chan_ parameter, and the&lt;br /&gt;
disposition of the mode is given by the _dest_ parameter, which is the&lt;br /&gt;
binary OR of the MODEBUF_DEST_* flags described below.&lt;br /&gt;
&amp;lt;/function&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;macro&amp;gt;&lt;br /&gt;
#define MODEBUF_DEST_CHANNEL	0x0001	/* Mode is flushed to channel */&lt;br /&gt;
&lt;br /&gt;
This flag, when set in a call to modebuf_init(), causes the accumulated&lt;br /&gt;
mode change to be sent to the channel (in client&amp;lt;-&amp;gt;server protocol, of&lt;br /&gt;
course).&lt;br /&gt;
&amp;lt;/macro&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;macro&amp;gt;&lt;br /&gt;
#define MODEBUF_DEST_SERVER	0x0002	/* Mode is flushed to server */&lt;br /&gt;
&lt;br /&gt;
If other servers should be made aware of the mode change, this flag&lt;br /&gt;
should be passed to modebuf_init().  One time when the mode change may&lt;br /&gt;
not be passed is when processing the mode in a BURST message.&lt;br /&gt;
&amp;lt;/macro&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;macro&amp;gt;&lt;br /&gt;
#define MODEBUF_DEST_OPMODE	0x0100	/* Send server mode as OPMODE */&lt;br /&gt;
&lt;br /&gt;
This flag is used to tell the modebuf_*() suite to send an OPMODE&lt;br /&gt;
message to other servers, rather than an ordinary MODE message.&lt;br /&gt;
&amp;lt;/macro&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;macro&amp;gt;&lt;br /&gt;
#define MODEBUF_DEST_DEOP	0x0200	/* Deop the offender */&lt;br /&gt;
&lt;br /&gt;
When bouncing a mode change, giving this flag to modebuf_init() causes&lt;br /&gt;
the originating user to be deopped on the channel as part of the mode&lt;br /&gt;
bounce.&lt;br /&gt;
&amp;lt;/macro&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;macro&amp;gt;&lt;br /&gt;
#define MODEBUF_DEST_BOUNCE	0x0400	/* Bounce the modes */&lt;br /&gt;
&lt;br /&gt;
When a mode change is illegitimate, that is, when it originates from a&lt;br /&gt;
user that is not (as far as this server knows) a channel operator, the&lt;br /&gt;
mode change should be bounced.  This involves reversing the sense of&lt;br /&gt;
the mode and sending it back to the originating server.  This flag is&lt;br /&gt;
used to tell the modebuf_*() suite to do just that.&lt;br /&gt;
&amp;lt;/macro&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;macro&amp;gt;&lt;br /&gt;
#define MODEBUF_DEST_LOG	0x0800	/* Log the mode changes to OPATH */&lt;br /&gt;
&lt;br /&gt;
The OPMODE command is reserved for IRC operators.  When it is used,&lt;br /&gt;
the server should log the command for accountability purposes.  This&lt;br /&gt;
flag, given to modebuf_init(), will cause the ModeBuf system to log&lt;br /&gt;
the exact mode change to a log file.&lt;br /&gt;
&amp;lt;/macro&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;macro&amp;gt;&lt;br /&gt;
#define MODEBUF_DEST_HACK2	0x2000	/* Send a HACK(2) notice, reverse */&lt;br /&gt;
&lt;br /&gt;
When a remote user that this server does not think is a channel&lt;br /&gt;
operator proceeds to change a channel mode, that mode must be&lt;br /&gt;
bounced.  In addition, in order to provide some debugging capability,&lt;br /&gt;
a server notice may be sent, called a &amp;quot;HACK(2)&amp;quot; notice.  Passing&lt;br /&gt;
modebuf_init() this flag causes that notice to be sent.&lt;br /&gt;
&amp;lt;/macro&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;macro&amp;gt;&lt;br /&gt;
#define MODEBUF_DEST_HACK3	0x4000	/* Send a HACK(3) notice, TS == 0 */&lt;br /&gt;
&lt;br /&gt;
When the origin of a mode change is a server, we should always accept&lt;br /&gt;
the mode change.  To provide accountability, however, a server notice&lt;br /&gt;
should be sent.  This flag will cause the server to generate a&lt;br /&gt;
&amp;quot;HACK(3)&amp;quot; notice.&lt;br /&gt;
&amp;lt;/macro&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;macro&amp;gt;&lt;br /&gt;
#define MODEBUF_DEST_HACK4	0x8000	/* Send a HACK(4) notice, TS == 0 */&lt;br /&gt;
&lt;br /&gt;
Some servers are special.  When a server that has a U-line issues a&lt;br /&gt;
mode change, we send a &amp;quot;HACK(4)&amp;quot; message to differentiate it from an&lt;br /&gt;
ordinary server changing a channel mode.  This is the flag that must&lt;br /&gt;
be passed to modebuf_init() to cause that behavior.&lt;br /&gt;
&amp;lt;/macro&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;function&amp;gt;&lt;br /&gt;
void modebuf_mode(struct ModeBuf *mbuf, unsigned int mode);&lt;br /&gt;
&lt;br /&gt;
Certain channel modes take no arguments.  Those mode changes can be&lt;br /&gt;
fed to the ModeBuf system using modebuf_mode().  The _mode_ parameter&lt;br /&gt;
is a bit mask of the mode changes, and must have one of MODE_ADD or&lt;br /&gt;
MODE_DEL set.&lt;br /&gt;
&amp;lt;/function&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;function&amp;gt;&lt;br /&gt;
void modebuf_mode_uint(struct ModeBuf *mbuf, unsigned int mode,&lt;br /&gt;
		       unsigned int uint);&lt;br /&gt;
&lt;br /&gt;
One channel mode, the &amp;quot;limit&amp;quot; mode (&amp;quot;+l&amp;quot;), takes a single integer&lt;br /&gt;
argument.  This limit can be fed to the ModeBuf system with the&lt;br /&gt;
modebuf_mode_uint() function.  The _mode_ parameter must be the binary&lt;br /&gt;
OR of one of MODE_ADD or MODE_DEL with the MODE_LIMIT flag.  The&lt;br /&gt;
_uint_ parameter specifies the limit.&lt;br /&gt;
&amp;lt;/function&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;function&amp;gt;&lt;br /&gt;
void modebuf_mode_string(struct ModeBuf *mbuf, unsigned int mode,&lt;br /&gt;
			 char *string, int free);&lt;br /&gt;
&lt;br /&gt;
Some channel modes take a string parameter.  These can be fed to&lt;br /&gt;
ModeBuf with modebuf_mode_string().  The _mode_ parameter should be&lt;br /&gt;
the binary OR of one of MODE_ADD or MODE_DEL with the flag for the&lt;br /&gt;
mode.  The _string_ parameter specifies the string, and the _free_&lt;br /&gt;
parameter indicates whether the ModeBuf system should call MyFree() on&lt;br /&gt;
the string once it is done with it.&lt;br /&gt;
&amp;lt;/function&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;function&amp;gt;&lt;br /&gt;
void modebuf_mode_client(struct ModeBuf *mbuf, unsigned int mode,&lt;br /&gt;
			 struct Client *client);&lt;br /&gt;
&lt;br /&gt;
The remaining channel modes take a parameter specifying a client.&lt;br /&gt;
These can be fed to ModeBuf with modebuf_mode_client().  The _mode_&lt;br /&gt;
parameter should be the binary OR of one of MODE_ADD or MODE_DEL with&lt;br /&gt;
the flag for the mode.  The _client_ parameter should be a pointer to&lt;br /&gt;
a struct Client specifying which client the mode is supposed to act&lt;br /&gt;
upon.&lt;br /&gt;
&amp;lt;/function&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;function&amp;gt;&lt;br /&gt;
int modebuf_flush(struct ModeBuf *mbuf);&lt;br /&gt;
&lt;br /&gt;
This function simply flushes the contents of the struct ModeBuf&lt;br /&gt;
specified by _mbuf_ to the appropriate destinations, as was specified&lt;br /&gt;
by the _dest_ parameter in the call to modebuf_init().  This function&lt;br /&gt;
returns 0 for the convenience of callers that must return an integer.&lt;br /&gt;
&amp;lt;/function&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;function&amp;gt;&lt;br /&gt;
void modebuf_extract(struct ModeBuf *mbuf, char *buf);&lt;br /&gt;
&lt;br /&gt;
One use of the ModeBuf within ircd requires the ability to pull a&lt;br /&gt;
simple mode string out of the struct ModeBuf for use elsewhere.  This&lt;br /&gt;
can be accomplished with this function.  The _buf_ parameter should be&lt;br /&gt;
large enough to accommodate the simple mode string.&lt;br /&gt;
&amp;lt;/function&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;function&amp;gt;&lt;br /&gt;
void mode_ban_invalidate(struct Channel *chan);&lt;br /&gt;
&lt;br /&gt;
Looking up bans affecting a particular user can be a fairly expensive&lt;br /&gt;
operation, so the server caches the result of the lookup.  Should the&lt;br /&gt;
ban list for a channel change, all the cached results must be&lt;br /&gt;
invalidated to force rechecking.  This may be done with the&lt;br /&gt;
mode_ban_invalidate() function, which acts upon the channel given by&lt;br /&gt;
_chan_.&lt;br /&gt;
&amp;lt;/function&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;function&amp;gt;&lt;br /&gt;
void mode_invite_clear(struct Channel *chan);&lt;br /&gt;
&lt;br /&gt;
When a channel that was invite-only has the &amp;quot;+i&amp;quot; channel mode removed,&lt;br /&gt;
the invite list that the server keeps is no longer necessary.  The&lt;br /&gt;
mode_invite_clear() function flushes that invite list for the channel&lt;br /&gt;
given by _chan_, reclaiming the memory used by the invite list.&lt;br /&gt;
&amp;lt;/function&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;function&amp;gt;&lt;br /&gt;
int mode_parse(struct ModeBuf *mbuf, struct Client *cptr, struct Client *sptr,&lt;br /&gt;
	       struct Channel *chptr, int parc, char *parv[],&lt;br /&gt;
	       unsigned int flags);&lt;br /&gt;
&lt;br /&gt;
This function parses a mode change command, given by the contents of&lt;br /&gt;
_parv[]_, and under the control of _flags_.  The channel being modified&lt;br /&gt;
is given by _chptr_, the source of the change is given by _sptr_, and&lt;br /&gt;
the connection the change was received from is given by _cptr_.  The&lt;br /&gt;
_parc_ parameter gives the count of the number of elements in the&lt;br /&gt;
_parv[]_ array.  The ModeBuf must have already been initialized by a&lt;br /&gt;
call to modebuf_init(), described above.  For more information on&lt;br /&gt;
_flags_, see the MODE_PARSE_* macros described below.  This function&lt;br /&gt;
returns an integer indicating the number of elements of _parv[]_ it&lt;br /&gt;
used.  The modebuf_flush() function must be called upon return from&lt;br /&gt;
mode_parse() to flush the mode changes to the channel.&lt;br /&gt;
&amp;lt;/function&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;macro&amp;gt;&lt;br /&gt;
#define MODE_PARSE_SET		0x01	/* actually set channel modes */&lt;br /&gt;
&lt;br /&gt;
When this flag is passed to mode_parse(), the channel mode being&lt;br /&gt;
parsed will actually be effected on the channel.&lt;br /&gt;
&amp;lt;/macro&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;macro&amp;gt;&lt;br /&gt;
#define MODE_PARSE_STRICT	0x02	/* +m +n +t style not supported */&lt;br /&gt;
&lt;br /&gt;
Users are permitted to send complicated mode commands like &amp;quot;MODE #foo&lt;br /&gt;
+m +n +t +k foo +i&amp;quot;; servers are not.  Passing this flag to&lt;br /&gt;
mode_parse() causes it to strictly enforce this restriction.&lt;br /&gt;
&amp;lt;/macro&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;macro&amp;gt;&lt;br /&gt;
#define MODE_PARSE_FORCE	0x04	/* force the mode to be applied */&lt;br /&gt;
&lt;br /&gt;
Some mode changes are not permitted under normal circumstances.  When&lt;br /&gt;
this flag is passed to mode_parse(), these mode changes will be&lt;br /&gt;
accepted.&lt;br /&gt;
&amp;lt;/macro&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;macro&amp;gt;&lt;br /&gt;
#define MODE_PARSE_BOUNCE	0x08	/* we will be bouncing the modes */&lt;br /&gt;
&lt;br /&gt;
This flag warns mode_parse() that the mode is to be bounced.  This&lt;br /&gt;
will cause it to systematically feed each mode into ModeBuf in order&lt;br /&gt;
for that interface to generate the proper bounce messages.&lt;br /&gt;
&amp;lt;/macro&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;macro&amp;gt;&lt;br /&gt;
#define MODE_PARSE_NOTOPER	0x10	/* send &amp;quot;not chanop&amp;quot; to user */&lt;br /&gt;
&lt;br /&gt;
This flag is used to warn mode_parse() that the user generating the&lt;br /&gt;
mode change is not a channel operator.  If the user attempts to change&lt;br /&gt;
a mode, an appropriate error message will be sent to the user (once).&lt;br /&gt;
&amp;lt;/macro&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;macro&amp;gt;&lt;br /&gt;
#define MODE_PARSE_NOTMEMBER	0x20	/* send &amp;quot;not member&amp;quot; to user */&lt;br /&gt;
&lt;br /&gt;
This flag is used to warn mode_parse() that the user generating the&lt;br /&gt;
mode change is not even on the channel.  If the user attempts to&lt;br /&gt;
change a mode, an appropriate error message will be sent to the user&lt;br /&gt;
(once).&lt;br /&gt;
&amp;lt;/macro&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;macro&amp;gt;&lt;br /&gt;
#define MODE_PARSE_WIPEOUT	0x40	/* wipe out +k and +l during burst */&lt;br /&gt;
&lt;br /&gt;
When this flag is passed to mode_parse(), the channel key and limit&lt;br /&gt;
will be reversed if the mode string doesn't update them.  This is used&lt;br /&gt;
for processing BURST messages.&lt;br /&gt;
&amp;lt;/macro&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;macro&amp;gt;&lt;br /&gt;
#define MODE_PARSE_BURST	0x80	/* be even more strict w/extra args */&lt;br /&gt;
&lt;br /&gt;
The BURST message is even more strict than a standard MODE message.&lt;br /&gt;
Processing *must* stop after reading the mode string itself, or&lt;br /&gt;
mode_parse() could gobble up arguments not intended for it.  This flag&lt;br /&gt;
tells mode_parse() about this restriction.&lt;br /&gt;
&amp;lt;/macro&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;authors&amp;gt;&lt;br /&gt;
Kev &amp;lt;klmitch@mit.edu&amp;gt;&lt;br /&gt;
&amp;lt;/authors&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;changelog&amp;gt;&lt;br /&gt;
[2001-6-15 Kev] Initial documentation of the ModeBuf and mode parsing&lt;br /&gt;
subsystems.&lt;br /&gt;
&amp;lt;/changelog&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:IRCu API|Modebuf]]&lt;/div&gt;</summary>
		<author><name>Secretagent</name></author>	</entry>

	</feed>