Skip to content

Commit f924433

Browse files
committed
New IRC parser and utility str array join function
1 parent de67b8f commit f924433

File tree

8 files changed

+90
-19
lines changed

8 files changed

+90
-19
lines changed

src/eggdrop.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,12 @@ enum {
739739
# define STRINGIFY1(x) #x
740740
#endif
741741

742+
#define MAX_IRC_TOKENS 64 // TODO: does this make sense?
743+
typedef struct parsed_irc {
744+
size_t argc;
745+
char *argv[MAX_IRC_TOKENS];
746+
} parsed_irc_t;
747+
742748
#ifdef EGG_TDNS
743749
#include <pthread.h>
744750
#define DTN_TYPE_HOSTBYIP 0

src/misc.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,49 @@ char *newsplit(char **rest)
278278
return r;
279279
}
280280

281+
// modifies original text
282+
// Only usable after from is already split off, does not handle :from keyword text
283+
struct parsed_irc parse_irc(char *text)
284+
{
285+
struct parsed_irc result = {.argc = 0};
286+
287+
while (*text) {
288+
while (*text && *text == ' ') {
289+
*text++ = '\0';
290+
}
291+
if (!*text) {
292+
break;
293+
}
294+
if (*text == ':') {
295+
*text++ = '\0';
296+
result.argv[result.argc++] = text;
297+
break;
298+
} else {
299+
result.argv[result.argc++] = text;
300+
while (*text && *text != ' ') {
301+
text++;
302+
}
303+
}
304+
}
305+
306+
return result;
307+
}
308+
309+
char *join_str_array(char **argv, int argc, char *delim)
310+
{
311+
static char buf[512];
312+
size_t written = 0;
313+
314+
if (!argc) {
315+
buf[0] = '\0';
316+
}
317+
318+
for (int i = 0; i < argc; i++) {
319+
written += snprintf(buf + written, sizeof buf - written, "%s%s", argv[i], i == argc ? "" : delim);
320+
}
321+
return buf;
322+
}
323+
281324
/* maskhost(), modified to support custom mask types, as defined
282325
* by mIRC.
283326
* Does not require a proper hostmask in 's'. Accepts any strings,

src/mod/irc.mod/chan.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2855,20 +2855,32 @@ static void update_chanmodes(mode_info_t *modes, int is_prefix)
28552855
// CHANMODES=eIbq,k,flj,CFLMPQScgimnprstuz
28562856
static int process_chanmodes(char *value)
28572857
{
2858+
mode_type_t modetype = MODETYPE_LIST;
28582859
mode_info_t modes[256];
28592860

28602861
memset(&modes, 0, sizeof modes);
28612862

2862-
for (mode_type_t modetype = MODETYPE_LIST; modetype <= MODETYPE_FLAG; modetype++) {
2863+
while (*value) {
28632864
while (*value && isalnum((unsigned char)*value)) {
28642865
modes[(unsigned char)*value].type = modetype;
28652866
modes[(unsigned char)*value].prefix = '\0';
2867+
debug2("Learned mode type: +%c type %s", *value, MODE_TYPE_STR(modetype));
28662868
value++;
28672869
}
2868-
if ((modetype < MODETYPE_FLAG && *value != ',') || (modetype == MODETYPE_FLAG && *value)) {
2870+
if ((modetype != MODETYPE_FLAG && *value != ',') || (modetype == MODETYPE_FLAG && *value)) {
28692871
return -1;
28702872
}
28712873
value++;
2874+
// next section in order
2875+
if (modetype == MODETYPE_LIST) {
2876+
modetype = MODETYPE_KEY;
2877+
} else if (modetype == MODETYPE_KEY) {
2878+
modetype = MODETYPE_LIMIT;
2879+
} else if (modetype == MODETYPE_LIMIT) {
2880+
modetype = MODETYPE_FLAG;
2881+
} else {
2882+
break;
2883+
}
28722884
}
28732885
update_chanmodes(modes, 0);
28742886
return 0;

src/mod/irc.mod/irc.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,9 +1122,7 @@ static void tell_account_tracking_status(int idx, int details)
11221122

11231123
static void tell_modeparsing_type(int idx, mode_type_t type)
11241124
{
1125-
const char *names[] = {[MODETYPE_FLAG] = "Flag", [MODETYPE_LIST] = "List", [MODETYPE_KEY] = "Key", [MODETYPE_LIMIT] = "Limit", [MODETYPE_PREFIX] = "Prefix"};
1126-
1127-
dprintf(idx, " %s modes: ", names[type]);
1125+
dprintf(idx, " %s modes: %s", MODE_TYPE_STR(type), type == MODETYPE_PREFIX ? "" : "+");
11281126
for (int i = 0; i < 256; i++) {
11291127
if (modecharinfo[i].type == type) {
11301128
dprintf(idx, "%c", i);
@@ -1138,9 +1136,11 @@ static void tell_modeparsing_type(int idx, mode_type_t type)
11381136

11391137
static void tell_modeparsing(int idx)
11401138
{
1141-
for (mode_type_t i = MODETYPE_LIST; i <= MODETYPE_PREFIX; i++) {
1142-
tell_modeparsing_type(idx, i);
1143-
}
1139+
tell_modeparsing_type(idx, MODETYPE_FLAG);
1140+
tell_modeparsing_type(idx, MODETYPE_LIMIT);
1141+
tell_modeparsing_type(idx, MODETYPE_KEY);
1142+
tell_modeparsing_type(idx, MODETYPE_LIST);
1143+
tell_modeparsing_type(idx, MODETYPE_PREFIX);
11441144
}
11451145

11461146
static void irc_report(int idx, int details)

src/mod/irc.mod/irc.h

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,23 @@
3333
#define REVENGE_KICK 1 /* Kicked victim */
3434
#define REVENGE_DEOP 2 /* Took op */
3535

36-
/* Order and values are relied upon */
36+
/* Order and values are relied upon, do not change */
3737
typedef enum mode_type {
38-
MODETYPE_INVALID = 0,
39-
MODETYPE_LIST = 1,
40-
MODETYPE_KEY = 2,
41-
MODETYPE_LIMIT = 3,
42-
MODETYPE_FLAG = 4,
43-
MODETYPE_PREFIX = 5
38+
MODETYPE_INVALID = 0, // invalid, must be 0 for init
39+
MODETYPE_FLAG = 1, // no params
40+
MODETYPE_LIMIT = 2, // param on set only
41+
MODETYPE_KEY = 3, // param always
42+
MODETYPE_LIST = 4, // param always
43+
MODETYPE_PREFIX = 5 // param always
4444
} mode_type_t;
4545

46-
#define MODE_HAS_SET_ARG(c) (modecharinfo[(unsigned char)(c)].type & (MODETYPE_LIST|MODETYPE_KEY|MODETYPE_LIMIT|MODETYPE_PREFIX))
47-
#define MODE_HAS_UNSET_ARG(c) (modecharinfo[(unsigned char)(c)].type & (MODETYPE_LIST|MODETYPE_KEY|MODETYPE_PREFIX))
46+
#define MODE_TYPE_NAMES ((const char *[]){[MODETYPE_FLAG] = "Flag", [MODETYPE_LIST] = "List", [MODETYPE_KEY] = "Key", [MODETYPE_LIMIT] = "Limit", [MODETYPE_PREFIX] = "Prefix"})
47+
48+
#define MODE_TYPE(c) (modecharinfo[(unsigned char)(c)].type)
49+
#define MODE_TYPE_STR(t) ((MODE_TYPE_NAMES)[(t)])
50+
51+
#define MODE_HAS_SET_ARG(c) (MODE_TYPE((c)) >= MODETYPE_LIMIT)
52+
#define MODE_HAS_UNSET_ARG(c) (MODE_TYPE((c)) >= MODETYPE_KEY)
4853
#define MODE_PREFIX(c) (modecharinfo[(unsigned char)(c)].prefix)
4954

5055
typedef struct mode_info {

src/mod/module.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,8 @@ typedef void (*chanout_butfunc)(int, int, const char *, ...) ATTRIBUTE_FORMAT(pr
532532
#define findsock ((int(*)(int))global[327])
533533
/* 328 - 331 */
534534
#define stealth_telnets (*(int *)(global[328]))
535-
535+
#define parse_irc ((parsed_irc_t (*)(char *))global[329])
536+
#define join_str_array ((char *(*)(char **, int, char *))global[330])
536537

537538
/* hostmasking */
538539
#define maskhost(a,b) maskaddr((a),(b),3)

src/modules.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,9 @@ Function global_table[] = {
632632
(Function) dcc_telnet_hostresolved2,
633633
(Function) findsock,
634634
/* 328 - 331 */
635-
(Function) & stealth_telnets /* int */
635+
(Function) & stealth_telnets, /* int */
636+
(Function) parse_irc,
637+
(Function) join_str_array,
636638
};
637639

638640
void init_modules(void)

src/proto.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@ void check_logsize(void);
236236
void splitc(char *, char *, char);
237237
void splitcn(char *, char *, char, size_t);
238238
void remove_crlf(char **);
239+
parsed_irc_t parse_irc(char *);
240+
char *join_str_array(char **argv, int argc, char *delim);
239241
char *newsplit(char **);
240242
char *splitnick(char **);
241243
void stridx(char *, char *, int);

0 commit comments

Comments
 (0)