struct Channel *chptr;
};
+struct ModeBuf {
+ unsigned int mb_add; /* Modes to add */
+ unsigned int mb_rem; /* Modes to remove */
+ struct Client *mb_source; /* Source of MODE changes */
+ struct Client *mb_connect; /* Connection of MODE changes */
+ struct Channel *mb_channel; /* Channel they affect */
+ unsigned int mb_dest; /* Destination of MODE changes */
+ unsigned int mb_count; /* Number of modes w/args */
+ struct {
+ unsigned int mbm_type; /* Type of argument */
+ union {
+ unsigned int mbma_uint; /* A limit */
+ char *mbma_string; /* A string */
+ struct Client *mbma_client; /* A client */
+ } mbm_arg; /* The mode argument */
+ } mb_modeargs[MAXMODEPARAMS];
+ /* A mode w/args */
+};
+
+#define MODEBUF_DEST_CHANNEL 0x01 /* Mode is flushed to channel */
+/* #define MODEBUF_DEST_SERVER 0x02 / * Mode is flushed to server */
+
+#define MB_TYPE(mb, i) ((mb)->mb_modeargs[(i)].mbm_type)
+#define MB_UINT(mb, i) ((mb)->mb_modeargs[(i)].mbm_arg.mbma_uint)
+#define MB_STRING(mb, i) ((mb)->mb_modeargs[(i)].mbm_arg.mbma_string)
+#define MB_CLIENT(mb, i) ((mb)->mb_modeargs[(i)].mbm_arg.mbma_client)
+
extern struct Channel* GlobalChannelList;
extern int LocalChanOperMode;
extern void list_next_channels(struct Client *cptr, int nr);
extern void send_user_joins(struct Client *cptr, struct Client *user);
+extern void modebuf_init(struct ModeBuf *mbuf, struct Client *source,
+ struct Client *connect, struct Channel *chan,
+ unsigned int dest);
+extern void modebuf_mode(struct ModeBuf *mbuf, unsigned int mode);
+extern void modebuf_mode_uint(struct ModeBuf *mbuf, unsigned int mode,
+ unsigned int uint);
+extern void modebuf_mode_string(struct ModeBuf *mbuf, unsigned int mode,
+ char *string);
+extern void modebuf_mode_client(struct ModeBuf *mbuf, unsigned int mode,
+ struct Client *client);
+extern void modebuf_flush(struct ModeBuf *mbuf);
#endif /* INCLUDED_channel_h */
}
}
}
+
+void
+modebuf_init(struct ModeBuf *mbuf, struct Client *source,
+ struct Client *connect, struct Channel *chan, unsigned int dest)
+{
+ int i;
+
+ assert(0 != mbuf);
+ assert(0 != source);
+ assert(0 != chan);
+ assert(0 != dest);
+
+ mbuf->mb_add = 0;
+ mbuf->mb_rem = 0;
+ mbuf->mb_source = source;
+ mbuf->mb_connect = connect;
+ mbuf->mb_channel = chan;
+ mbuf->mb_dest = dest;
+ mbuf->mb_count = 0;
+
+ for (i = 0; i < MAXMODEPARAMS; i++) {
+ MB_TYPE(mbuf, i) = 0;
+ MB_UINT(mbuf, i) = 0;
+ }
+}
+
+void
+modebuf_mode(struct ModeBuf *mbuf, unsigned int mode)
+{
+ assert(0 != mbuf);
+ assert(0 != (mode & (MODE_ADD | MODE_DEL)));
+
+ mode &= (MODE_ADD | MODE_DEL | MODE_PRIVATE | MODE_SECRET | MODE_MODERATED |
+ MODE_TOPICLIMIT | MODE_INVITEONLY | MODE_NOPRIVMSGS);
+
+ if (mode & MODE_ADD) {
+ mbuf->mb_rem &= ~mode;
+ mbuf->mb_add |= mode;
+ } else {
+ mbuf->mb_add &= ~mode;
+ mbuf->mb_rem |= mode;
+ }
+}
+
+void
+modebuf_mode_uint(struct ModeBuf *mbuf, unsigned int mode, unsigned int uint)
+{
+ assert(0 != mbuf);
+ assert(0 != (mode & (MODE_ADD | MODE_DEL)));
+
+ MB_TYPE(mbuf, mbuf->mb_count) = mode;
+ MB_UINT(mbuf, mbuf->mb_count) = uint;
+
+ if (++mbuf->mb_count >= 6)
+ modebuf_flush(mbuf);
+}
+
+void
+modebuf_mode_string(struct ModeBuf *mbuf, unsigned int mode, char *string)
+{
+ assert(0 != mbuf);
+ assert(0 != (mode & (MODE_ADD | MODE_DEL)));
+
+ MB_TYPE(mbuf, mbuf->mb_count) = mode;
+ MB_STRING(mbuf, mbuf->mb_count) = string;
+
+ if (++mbuf->mb_count >= 6)
+ modebuf_flush(mbuf);
+}
+
+void
+modebuf_mode_client(struct ModeBuf *mbuf, unsigned int mode,
+ struct Client *client)
+{
+ assert(0 != mbuf);
+ assert(0 != (mode & (MODE_ADD | MODE_DEL)));
+
+ MB_TYPE(mbuf, mbuf->mb_count) = mode;
+ MB_CLIENT(mbuf, mbuf->mb_count) = client;
+
+ if (++mbuf->mb_count >= 6)
+ modebuf_flush(mbuf);
+}
+
+static void
+build_string(char *strptr, int *strptr_i, char *str)
+{
+ strptr[(*strptr_i)++] = ' ';
+
+ while (strptr[(*strptr_i)++] = *str)
+ ; /* very simple strcat */
+}
+
+void
+modebuf_flush(struct ModeBuf *mbuf)
+{
+ static int flags[] = {
+/* MODE_CHANOP, 'o', */
+/* MODE_VOICE, 'v', */
+ MODE_PRIVATE, 'p',
+ MODE_SECRET, 's',
+ MODE_MODERATED, 'm',
+ MODE_TOPICLIMIT, 't',
+ MODE_INVITEONLY, 'i',
+ MODE_NOPRIVMSGS, 'n',
+/* MODE_KEY, 'k', */
+/* MODE_BAN, 'b', */
+/* MODE_LIMIT, 'l', */
+ 0x0, 0x0
+ };
+ int i;
+ int *flag_p;
+
+ char addbuf[20] = "+";
+ int addbuf_i = 1;
+ char rembuf[20] = "-";
+ int rembuf_i = 1;
+ char *bufptr;
+ int *bufptr_i;
+
+ char addstr[MODEBUFLEN] = "";
+ int addstr_i = 0;
+ char remstr[MODEBUFLEN] = "";
+ int remstr_i = 0;
+ char *strptr;
+ int *strptr_i;
+
+ char limitbuf[10];
+
+ assert(0 != mbuf);
+
+ for (flag_p = flags; flag_p[0]; flag_p += 2) {
+ if (*flag_p & mbuf->mb_add)
+ addbuf[addbuf_i++] = flag_p[1];
+ else if (*flag_p & mbuf->mb_rem)
+ rembuf[rembuf_i++] = flag_p[1];
+ }
+
+ if (addbuf_i == 1)
+ addbuf[0] = '\0';
+ if (rembuf_i == 1)
+ rembuf[0] = '\0';
+
+ for (i = 0; i < mbuf->mb_count; i++) {
+ if (MB_TYPE(mbuf, i) & MODE_ADD) {
+ bufptr = addbuf;
+ bufptr_i = &addbuf_i;
+ } else {
+ bufptr = rembuf;
+ bufptr_i = &rembuf_i;
+ }
+
+ if (MB_TYPE(mbuf, i) & MODE_CHANOP)
+ bufptr[(*bufptr_i)++] = 'o';
+ else if (MB_TYPE(mbuf, i) & MODE_VOICE)
+ bufptr[(*bufptr_i)++] = 'v';
+ else if (MB_TYPE(mbuf, i) & MODE_KEY)
+ bufptr[(*bufptr_i)++] = 'k';
+ else if (MB_TYPE(mbuf, i) & MODE_BAN)
+ bufptr[(*bufptr_i)++] = 'b';
+ else if (MB_TYPE(mbuf, i) & MODE_LIMIT) {
+ bufptr[(*bufptr_i)++] = 'l';
+
+ sprintf_irc(limitbuf, "%d", MB_UINT(mbuf, i));
+ }
+ }
+
+ if (mbuf->mb_dest & MODEBUF_DEST_CHANNEL) {
+ for (i = 0; i < mbuf->mb_count; i++) {
+ if (MB_TYPE(mbuf, i) & MODE_ADD) {
+ strptr = addstr;
+ strptr_i = &addstr_i;
+ } else {
+ strptr = remstr;
+ strptr_i = &remstr_i;
+ }
+
+ if (MB_TYPE(mbuf, i) & (MODE_CHANOP | MODE_VOICE))
+ build_string(strptr, strptr_i, MB_CLIENT(mbuf, i)->name);
+ else if (MB_TYPE(mbuf, i) & (MODE_KEY | MODE_BAN))
+ build_string(strptr, strptr_i, MB_STRING(mbuf, i));
+ else if (MB_TYPE(mbuf, i) & MODE_LIMIT)
+ build_string(strptr, strptr_i, limitbuf);
+ }
+
+ sendto_channel_butserv(mbuf->mb_channel, mbuf->mb_source,
+ ":%s MODE %s %s%s%s%s", mbuf->mb_source->name,
+ mbuf->mb_channel->name, addbuf, rembuf, addstr,
+ remstr);
+ }
+
+ mbuf->mb_count = 0;
+
+ for (i = 0; i < MAXMODEPARAMS; i++) {
+ MB_TYPE(mbuf, i) = 0;
+ MB_UINT(mbuf, i) = 0;
+ }
+}
+