1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-07-08 13:43:13 +02:00

First attempt at parse_chanmode(), meant for 3rd party module coders.. and

who knows it may be useful for ourselves too.
This commit is contained in:
Bram Matthys
2014-05-29 22:05:15 +02:00
parent d4271a0c72
commit 65d5569ef0
3 changed files with 147 additions and 0 deletions
+1
View File
@@ -746,3 +746,4 @@ extern MODVAR char *IsupportStrings[];
extern void finish_auth(aClient *acptr);
extern void read_packet(int fd, int revents, void *data);
extern void sendto_realops_and_log(char *fmt, ...);
extern int parse_chanmode(ParseMode *pm, char *modebuf_in, char *parabuf_in);
+12
View File
@@ -1757,6 +1757,18 @@ typedef struct {
unsigned parameters : 1;
} aCtab;
/** Parse channel mode */
typedef struct _parsemode ParseMode;
struct _parsemode {
int what;
char modechar;
char *param;
Cmode *extm;
char *modebuf; /* curr pos */
char *parabuf; /* curr pos */
char buf[512]; /* internal parse buffer */
};
#if 1
/* TODO: move to module / dynamic storage */
/** A jointhrottle item, this is a double linked list.
+134
View File
@@ -1454,3 +1454,137 @@ void set_channel_mlock(aClient *cptr, aClient *sptr, aChannel *chptr, const char
BadPtr(chptr->mode_lock) ? "" : chptr->mode_lock);
}
}
/** Parse a channelmode line.
* @in pm A ParseMode struct, used to return values and to maintain internal state.
* @in modebuf_in Buffer pointing to mode characters (eg: +snk-l)
* @in parabuf_in Buffer pointing to all parameters (eg: key 123)
* @retval Returns 1 if we have valid data to return, 0 if at end of mode line.
* @example
*
* ParseMode pm;
* int ret;
* for (ret = parse_chanmode(&pm, modebuf, parabuf); ret; ret = parse_chanmode(&pm, NULL, NULL))
* {
* ircd_log(LOG_ERROR, "Got %c%c %s",
* pm.what == MODE_ADD ? '+' : '-',
* pm.modechar,
* pm.param ? pm.param : "");
* }
*/
int parse_chanmode(ParseMode *pm, char *modebuf_in, char *parabuf_in)
{
if (modebuf_in)
{
/* Initialize */
memset(pm, 0, sizeof(ParseMode));
pm->modebuf = modebuf_in;
pm->parabuf = parabuf_in;
pm->what = MODE_ADD;
}
while(1)
{
if (*pm->modebuf == '\0')
return 0;
else if (*pm->modebuf == '+')
{
pm->what = MODE_ADD;
pm->modebuf++;
continue;
}
else if (*pm->modebuf == '-')
{
pm->what = MODE_DEL;
pm->modebuf++;
continue;
}
else
{
aCtab *tab = &cFlagTab[0];
int i;
int eatparam = 0;
/* Set some defaults */
pm->extm = NULL;
pm->modechar = *pm->modebuf;
pm->param = NULL;
while (tab->mode != 0x0)
{
if (tab->flag == *pm->modebuf)
break;
tab++;
}
if (tab->mode)
{
/* INTERNAL MODE */
if (tab->parameters)
{
if ((pm->what == MODE_DEL) && (tab->flag == 'l'))
eatparam = 0; /* -l is special: no parameter required */
else
eatparam = 1; /* all other internal parameter modes do require a parameter on unset */
}
} else {
/* EXTENDED CHANNEL MODE */
int found = 0;
for (i=0; i <= Channelmode_highest; i++)
if (Channelmode_Table[i].flag == *pm->modebuf)
break;
if (!found)
{
/* Not found. Will be ignored, just move on.. */
pm->modebuf++;
continue;
}
pm->extm = &Channelmode_Table[i];
if (Channelmode_Table[i].paracount == 1)
{
if (pm->what == MODE_ADD)
eatparam = 1;
else if (Channelmode_Table[i].unset_with_param)
eatparam = 1;
/* else 0 (if MODE_DEL && !unset_with_param) */
}
}
if (eatparam)
{
/* Hungry.. */
if (pm->parabuf && *pm->parabuf)
{
char *start, *end;
for (; *pm->parabuf == ' '; pm->parabuf++); /* skip whitespace */
start = pm->parabuf;
if (*pm->parabuf == '\0')
{
pm->modebuf++;
continue; /* invalid, got mode but no parameter available */
}
end = strchr(start, ' ');
/* copy start .. end (where end may be null, then just copy all) */
if (end)
{
pm->parabuf = end + 1; /* point to next param, or \0 */
if (end - start + 1 > sizeof(pm->buf))
end = start + sizeof(pm->buf); /* 'never' reached */
strlcpy(pm->buf, start, end - start + 1);
}
else
{
strlcpy(pm->buf, start, sizeof(pm->buf));
pm->parabuf = pm->parabuf + strlen(pm->parabuf); /* point to \0 at end */
}
pm->param = pm->buf;
} else {
pm->modebuf++;
continue; /* invalid, got mode but no parameter available */
}
}
}
pm->modebuf++; /* advance pointer */
return 1;
}
}