From c1501510662acec2ddc5f316546cef4f6e0d043f Mon Sep 17 00:00:00 2001 From: Arnaud Cornet Date: Mon, 15 Dec 2008 19:19:27 +0100 Subject: [PATCH] BIG cleanup. check for memory allocation failure, add extra checks all arround. --- src/bip.c | 210 +++++++++++++------------ src/bip.h | 3 +- src/conf.y | 2 + src/connection.c | 4 +- src/irc.c | 396 ++++++++++++++++++++++++----------------------- src/lex.l | 5 +- src/line.c | 78 +++++++--- src/line.h | 15 +- src/log.c | 109 +++++++------ src/log.h | 46 +++--- src/md5.c | 1 + src/util.c | 72 +++++---- src/util.h | 23 +-- 13 files changed, 521 insertions(+), 443 deletions(-) diff --git a/src/bip.c b/src/bip.c index 4553385..12e8c4c 100644 --- a/src/bip.c +++ b/src/bip.c @@ -382,7 +382,7 @@ static int add_network(bip_t *bip, list_t *data) return 1; } -void adm_bip_delconn(bip_t *bip, struct link_client *ic, char *conn_name) +void adm_bip_delconn(bip_t *bip, struct link_client *ic, const char *conn_name) { struct user *user = LINK(ic)->user; struct link *l; @@ -396,8 +396,8 @@ void adm_bip_delconn(bip_t *bip, struct link_client *ic, char *conn_name) link_kill(bip, l); } -void adm_bip_addconn(bip_t *bip, struct link_client *ic, char *conn_name, - char *network_name) +void adm_bip_addconn(bip_t *bip, struct link_client *ic, const char *conn_name, + const char *network_name) { struct user *user = LINK(ic)->user; struct network *network; @@ -417,7 +417,7 @@ void adm_bip_addconn(bip_t *bip, struct link_client *ic, char *conn_name, struct link *l; l = irc_link_new(); - l->name = strdup(conn_name); + l->name = bip_strdup(conn_name); hash_insert(&user->connections, conn_name, l); list_add_last(&bip->link_list, l); l->user = user; @@ -429,7 +429,7 @@ void adm_bip_addconn(bip_t *bip, struct link_client *ic, char *conn_name, #endif -#define SCOPY(member) l->member = (LINK(ic)->member ? strdup(LINK(ic)->member) : NULL) +#define SCOPY(member) l->member = (LINK(ic)->member ? bip_strdup(LINK(ic)->member) : NULL) #define ICOPY(member) l->member = LINK(ic)->member SCOPY(connect_nick); @@ -593,7 +593,7 @@ static int add_connection(bip_t *bip, struct user *user, list_t *data) conf_die(bip, "No nick set and no default nick."); return 0; } - l->connect_nick = strdup(user->default_nick); + l->connect_nick = bip_strdup(user->default_nick); } if (!l->username) { if (!user->default_username) { @@ -601,7 +601,7 @@ static int add_connection(bip_t *bip, struct user *user, list_t *data) "username."); return 0; } - l->username = strdup(user->default_username); + l->username = bip_strdup(user->default_username); } if (!l->realname) { if (!user->default_realname) { @@ -609,7 +609,7 @@ static int add_connection(bip_t *bip, struct user *user, list_t *data) "realname."); return 0; } - l->realname = strdup(user->default_realname); + l->realname = bip_strdup(user->default_realname); } l->in_use = 1; @@ -1147,7 +1147,7 @@ int main(int argc, char **argv) bip_init(&bip); _bip = &bip; - conf_ip = strdup("0.0.0.0"); + conf_ip = bip_strdup("0.0.0.0"); conf_port = 7778; conf_css = 0; @@ -1160,7 +1160,7 @@ int main(int argc, char **argv) signal(SIGXCPU, rlimit_cpu_reached); conf_log_root = NULL; - conf_log_format = strdup(DEFAULT_LOG_FORMAT); + conf_log_format = bip_strdup(DEFAULT_LOG_FORMAT); conf_log_level = DEFAULT_LOG_LEVEL; conf_daemonize = 1; conf_global_log_file = stderr; @@ -1172,13 +1172,13 @@ int main(int argc, char **argv) while ((ch = getopt(argc, argv, "hvnf:s:")) != -1) { switch (ch) { case 'f': - confpath = strdup(optarg); + confpath = bip_strdup(optarg); break; case 'n': conf_daemonize = 0; break; case 's': - conf_biphome = strdup(optarg); + conf_biphome = bip_strdup(optarg); break; case 'v': version(); @@ -1495,7 +1495,7 @@ void adm_list_all_connections(struct link_client *ic) #define STRORNULL(s) ((s) == NULL ? "unset" : (s)) -void adm_info_user(struct link_client *ic, char *name) +void adm_info_user(struct link_client *ic, const char *name) { struct user *u; char buf[RET_STR_LEN + 1]; @@ -1771,10 +1771,10 @@ int adm_trust(struct link_client *ic, struct line *line) return ERR_PROTOCOL; } - if (line->elemc != 3) + if (irc_line_count(line) != 3) return ERR_PROTOCOL; - if (!strcasecmp(line->elemv[2], "OK")) { + if (irc_line_elem_case_equals(line, 2, "OK")) { /* OK, attempt to trust the cert! */ BIO *bio = BIO_new_file(LINK(ic)->user->ssl_check_store, "a+"); X509 *trustcert = sk_X509_shift(LINK(ic)->untrusted_certs); @@ -1789,7 +1789,7 @@ int adm_trust(struct link_client *ic, struct line *line) BIO_free_all(bio); X509_free(trustcert); - } else if (!strcasecmp(line->elemv[2], "NO")) { + } else if (irc_line_elem_case_equals(line, 2, "NO")) { /* NO, discard the cert! */ write_line_fast(CONN(ic), ":irc.bip.net NOTICE pouet " ":==== Certificate discarded.\r\n"); @@ -1847,7 +1847,7 @@ void adm_blreset(struct link_client *ic) bip_notify(ic, "backlog resetted for this network."); } -void adm_follow_nick(struct link_client *ic, char *val) +void adm_follow_nick(struct link_client *ic, const char *val) { struct link *link = LINK(ic); if (strcasecmp(val, "TRUE") == 0) { @@ -1859,7 +1859,7 @@ void adm_follow_nick(struct link_client *ic, char *val) } } -void adm_ignore_first_nick(struct link_client *ic, char *val) +void adm_ignore_first_nick(struct link_client *ic, const char *val) { struct link *link = LINK(ic); if (strcasecmp(val, "TRUE") == 0) { @@ -1877,7 +1877,7 @@ void set_on_connect_send(struct link_client *ic, char *val) char *s; if (val != NULL) { - list_add_last(&link->on_connect_send, strdup(val)); + list_add_last(&link->on_connect_send, bip_strdup(val)); bip_notify(ic, "added to on_connect_send."); } else { s = list_remove_last(&link->on_connect_send); @@ -1893,26 +1893,26 @@ void adm_on_connect_send(struct link_client *ic, struct line *line, { char buf[ON_CONNECT_MAX_STRSIZE]; int t_written = 0; - unsigned int i; + int i; if (!line) { set_on_connect_send(ic, NULL); return; } - if (line->elemc < 3) + if (irc_line_include(line, 2)) return; - for (i = privmsg + 2; i < line->elemc; i++) { + for (i = privmsg + 2; i < irc_line_count(line); i++) { if (t_written) { t_written += snprintf(buf, ON_CONNECT_MAX_STRSIZE - 1 - t_written, - " %s", line->elemv[i]); + " %s", irc_line_elem(line, i)); if (t_written >= ON_CONNECT_MAX_STRSIZE) goto noroom; } else { t_written = snprintf(buf, ON_CONNECT_MAX_STRSIZE - 1, - "%s", line->elemv[i]); + "%s", irc_line_elem(line, i)); if (t_written >= ON_CONNECT_MAX_STRSIZE) goto noroom; } @@ -1926,7 +1926,7 @@ noroom: goto ok; } -void adm_away_nick(struct link_client *ic, char *val) +void adm_away_nick(struct link_client *ic, const char *val) { struct link *link = LINK(ic); if (link->away_nick) { @@ -1934,30 +1934,34 @@ void adm_away_nick(struct link_client *ic, char *val) link->away_nick = NULL; } if (val != NULL) { - link->away_nick = strdup(val); + link->away_nick = bip_strdup(val); bip_notify(ic, "away_nick set."); } else { bip_notify(ic, "away_nick cleared."); } } -void adm_bip_help(struct link_client *ic, int admin, char *subhelp) +void adm_bip_help(struct link_client *ic, int admin, const char *subhelp) { if (subhelp == NULL) { if (admin) { - bip_notify(ic, "/BIP RELOAD # Re-read bip configuration " - "and apply changes."); - bip_notify(ic, "/BIP INFO user # show a user's " - "configuration"); - bip_notify(ic, "/BIP LIST networks|users|connections|all_links" - "|all_connections"); - bip_notify(ic, "/BIP ADD_CONN "); + bip_notify(ic, "/BIP RELOAD # Re-read bip " + "configuration and apply changes."); + bip_notify(ic, "/BIP INFO user " + "# show a user's configuration"); + bip_notify(ic, "/BIP LIST networks|users|connections|" + "all_links|all_connections"); + bip_notify(ic, "/BIP ADD_CONN " + ""); bip_notify(ic, "/BIP DEL_CONN "); } else { bip_notify(ic, "/BIP LIST networks|connections"); } - bip_notify(ic, "/BIP JUMP # jump to next server (in same network)"); - bip_notify(ic, "/BIP BLRESET # reset backlog (this connection only). Add -q flag and the operation is quiet."); + bip_notify(ic, "/BIP JUMP # jump to next server (in same " + "network)"); + bip_notify(ic, "/BIP BLRESET # reset backlog (this " + "connection only). Add -q flag and the " + "operation is quiet."); #ifdef HAVE_LIBSSL bip_notify(ic, "/BIP TRUST # trust this server certificate"); #endif @@ -2052,20 +2056,23 @@ void adm_bip_help(struct link_client *ic, int admin, char *subhelp) } } -int adm_bip(bip_t *bip, struct link_client *ic, struct line *line, - unsigned int privmsg) +int adm_bip(bip_t *bip, struct link_client *ic, struct line *line, int privmsg) { int admin = LINK(ic)->user->admin; if (privmsg) { - char *linestr = line->elemv[2]; - char *ptr = line->elemv[2], *eptr; + char *linestr, *elemstr; + char *ptr, *eptr; int slen; - if (line->elemc != 3) + if (irc_line_count(line) != 3) return OK_FORGET; - line->elemc--; + linestr = irc_line_pop(line); + ptr = linestr; + + /* all elem size <= linestr size */ + elemstr = bip_malloc(strlen(linestr) + 1); while((eptr = strstr(ptr, " "))) { slen = eptr - ptr; @@ -2073,34 +2080,28 @@ int adm_bip(bip_t *bip, struct link_client *ic, struct line *line, ptr++; continue; } - line->elemv = bip_realloc(line->elemv, - (line->elemc + 1) * sizeof(char *)); - line->elemv[line->elemc] = bip_malloc(slen + 1); - memcpy(line->elemv[line->elemc], ptr, slen); - line->elemv[line->elemc][slen] = 0; - line->elemc++; + memcpy(elemstr, ptr, slen); + elemstr[slen] = 0; + irc_line_append(line, elemstr); ptr = eptr + 1; } eptr = ptr + strlen(ptr); slen = eptr - ptr; if (slen != 0) { - line->elemv = bip_realloc(line->elemv, - (line->elemc + 1) * sizeof(char *)); - slen = eptr - ptr; - line->elemv[line->elemc] = bip_malloc(slen + 1); - memcpy(line->elemv[line->elemc], ptr, slen); - line->elemv[line->elemc][slen] = 0; - line->elemc++; + memcpy(elemstr, ptr, slen); + elemstr[slen] = 0; + irc_line_append(line, elemstr); } + free(elemstr); free(linestr); } - if (line->elemc < privmsg + 2) + if (!irc_line_include(line, privmsg + 1)) return OK_FORGET; - mylog(LOG_INFO, "/BIP %s from %s", line->elemv[privmsg + 1], + mylog(LOG_INFO, "/BIP %s from %s", irc_line_elem(line, privmsg + 1), LINK(ic)->user->name); - if (strcasecmp(line->elemv[privmsg + 1], "RELOAD") == 0) { + if (strcasecmp(irc_line_elem(line, privmsg + 1), "RELOAD") == 0) { if (!admin) { bip_notify(ic, "-- You're not allowed to reload bip"); return OK_FORGET; @@ -2108,40 +2109,42 @@ int adm_bip(bip_t *bip, struct link_client *ic, struct line *line, bip_notify(ic, "-- Reloading bip..."); bip->reloading_client = ic; sighup = 1; - } else if (strcasecmp(line->elemv[privmsg + 1], "LIST") == 0) { - if (line->elemc != privmsg + 3) { + } else if (strcasecmp(irc_line_elem(line, privmsg + 1), "LIST") == 0) { + if (irc_line_count(line) != privmsg + 3) { bip_notify(ic, "-- LIST command needs one argument"); return OK_FORGET; } - if (admin && strcasecmp(line->elemv[privmsg + 2], + if (admin && strcasecmp(irc_line_elem(line, privmsg + 2), "users") == 0) { adm_list_users(ic); - } else if (strcasecmp(line->elemv[privmsg + 2], + } else if (strcasecmp(irc_line_elem(line, privmsg + 2), "networks") == 0) { adm_list_networks(ic); - } else if (strcasecmp(line->elemv[privmsg + 2], + } else if (strcasecmp(irc_line_elem(line, privmsg + 2), "connections") == 0) { adm_list_connections(ic, NULL); - } else if (admin && strcasecmp(line->elemv[privmsg + 2], + } else if (admin && strcasecmp(irc_line_elem(line, privmsg + 2), "all_connections") == 0) { adm_list_all_connections(ic); - } else if (admin && strcasecmp(line->elemv[privmsg + 2], + } else if (admin && strcasecmp(irc_line_elem(line, privmsg + 2), "all_links") == 0) { adm_list_all_links(ic); } else { bip_notify(ic, "-- Invalid LIST request"); } - } else if (strcasecmp(line->elemv[privmsg + 1], "INFO") == 0) { - if (line->elemc < privmsg + 3) { - bip_notify(ic, "-- INFO command needs at least one argument"); + } else if (strcasecmp(irc_line_elem(line, privmsg + 1), "INFO") == 0) { + if (!irc_line_include(line, privmsg + 2)) { + bip_notify(ic, "-- INFO command needs at least one " + "argument"); return OK_FORGET; } - if (admin && strcasecmp(line->elemv[privmsg + 2], + if (admin && irc_line_elem_case_equals(line, privmsg + 3, "user") == 0) { - if (line->elemc == privmsg + 4) { - adm_info_user(ic, line->elemv[privmsg + 3]); + if (irc_line_count(line) == privmsg + 4) { + adm_info_user(ic, + irc_line_elem(line, privmsg + 3)); } else { bip_notify(ic, "-- INFO USER command needs one" " argument"); @@ -2150,7 +2153,7 @@ int adm_bip(bip_t *bip, struct link_client *ic, struct line *line, TODO } else if (strcasecmp(line->elemv[privmsg + 2], "network") == 0) { - if (line->elemc == privmsg + 4) { + if (irc_line_count(line) == privmsg + 4) { adm_info_network(ic, line->elemv[privmsg + 3]); } else { bip_notify(ic, "/BIP INFO network needs one " @@ -2160,80 +2163,83 @@ int adm_bip(bip_t *bip, struct link_client *ic, struct line *line, } else { bip_notify(ic, "-- Invalid INFO request"); } - } else if (strcasecmp(line->elemv[privmsg + 1], "JUMP") == 0) { + } else if (irc_line_elem_case_equals(line, privmsg + 1, "JUMP")) { if (LINK(ic)->l_server) { WRITE_LINE1(CONN(LINK(ic)->l_server), NULL, "QUIT", "jumpin' jumpin'"); connection_close(CONN(LINK(ic)->l_server)); } bip_notify(ic, "-- Jumping to next server"); - } else if (strcasecmp(line->elemv[privmsg + 1], "BLRESET") == 0) { + } else if (irc_line_elem_case_equals(line, privmsg + 1, "BLRESET")) { if (line->elemc == privmsg + 3 && - strcmp(line->elemv[privmsg + 2], "-q") == 0) { + irc_line_elem_equals(line, privmsg + 2, "-q")) { log_reinit_all(LINK(ic)->log); } else { adm_blreset(ic); } - } else if (strcasecmp(line->elemv[privmsg + 1], "HELP") == 0) { - if (line->elemc == privmsg + 2) + } else if (irc_line_elem_case_equals(line, privmsg + 1, "HELP")) { + if (irc_line_count(line) == privmsg + 2) adm_bip_help(ic, admin, NULL); - else if (line->elemc == privmsg + 3) - adm_bip_help(ic, admin, line->elemv[privmsg + 2]); + else if (irc_line_count(line) == privmsg + 3) + adm_bip_help(ic, admin, + irc_line_elem(line, privmsg + 2)); else bip_notify(ic, "-- HELP command needs at most one argument"); - } else if (strcasecmp(line->elemv[privmsg + 1], "FOLLOW_NICK") == 0) { - if (line->elemc != privmsg + 3) { + } else if (irc_line_elem_case_equals(line, privmsg + 1, "FOLLOW_NICK")) { + if (irc_line_count(line) != privmsg + 3) { bip_notify(ic, "-- FOLLOW_NICK command needs one argument"); return OK_FORGET; } - adm_follow_nick(ic, line->elemv[privmsg + 2]); + adm_follow_nick(ic, irc_line_elem(line, privmsg + 2)); } else if (strcasecmp(line->elemv[privmsg + 1], "IGNORE_FIRST_NICK") == 0) { - if (line->elemc != privmsg + 3) { + if (irc_line_count(line) != privmsg + 3) { bip_notify(ic, "-- IGNORE_FIRST_NICK " "command needs one argument"); return OK_FORGET; } - adm_ignore_first_nick(ic, line->elemv[privmsg + 2]); - } else if (strcasecmp(line->elemv[privmsg + 1], - "ON_CONNECT_SEND") == 0) { - if (line->elemc == privmsg + 2) { + adm_ignore_first_nick(ic, irc_line_elem(line, privmsg + 2)); + } else if (irc_line_elem_case_equals(line, privmsg + 1, + "ON_CONNECT_SEND")) { + if (irc_line_count(line) == privmsg + 2) { adm_on_connect_send(ic, NULL, 0); - } else if (line->elemc >= privmsg + 3) { + } else if (irc_line_include(line, privmsg + 2)) { adm_on_connect_send(ic, line, privmsg); } else { bip_notify(ic, "-- ON_CONNECT_SEND command needs at " "least one argument"); } - } else if (strcasecmp(line->elemv[privmsg + 1], "AWAY_NICK") == 0) { - if (line->elemc == privmsg + 2) { + } else if (irc_line_elem_case_equals(line, privmsg + 1, "AWAY_NICK")) { + if (irc_line_count(line) == privmsg + 2) { adm_away_nick(ic, NULL); - } else if (line->elemc == privmsg + 3) { - adm_away_nick(ic, line->elemv[privmsg + 2]); + } else if (irc_line_count(line) == privmsg + 3) { + adm_away_nick(ic, irc_line_elem(line, privmsg + 2)); } else { bip_notify(ic, "-- AWAY_NICK command needs zero or one" " argument"); } - } else if (admin && - strcasecmp(line->elemv[privmsg + 1], "ADD_CONN") == 0) { - if (line->elemc != privmsg + 4) { + } else if (admin && irc_line_elem_case_equals(line, privmsg + 1, + "ADD_CONN")) { + if (irc_line_count(line) != privmsg + 4) { bip_notify(ic, "/BIP ADD_CONN " ""); } else { - adm_bip_addconn(bip, ic, line->elemv[privmsg + 2], - line->elemv[privmsg + 3]); + adm_bip_addconn(bip, ic, + irc_line_elem(line, privmsg + 2), + irc_line_elem(line, privmsg + 3)); } - } else if (admin && - strcasecmp(line->elemv[privmsg + 1], "DEL_CONN") == 0) { - if (line->elemc != privmsg + 3) { + } else if (admin && irc_line_elem_case_equals(line, privmsg + 1, + "DEL_CONN")) { + if (irc_line_count(line) != privmsg + 3) { bip_notify(ic, "/BIP DEL_CONN "); } else { - adm_bip_delconn(bip, ic, line->elemv[privmsg + 2]); + adm_bip_delconn(bip, ic, + irc_line_elem(line, privmsg + 2)); } #ifdef HAVE_LIBSSL - } else if (strcasecmp(line->elemv[privmsg + 1], "TRUST") == 0) { + } else if (irc_line_elem_case_equals(line, privmsg + 1, "TRUST")) { return adm_trust(ic, line); #endif } else { diff --git a/src/bip.h b/src/bip.h index b729c2f..d7efe54 100644 --- a/src/bip.h +++ b/src/bip.h @@ -17,8 +17,7 @@ #ifdef HAVE_LIBSSL int adm_trust(struct link_client *ic, struct line *line); #endif -int adm_bip(bip_t *bip, struct link_client *ic, struct line *line, - unsigned int privmsg); +int adm_bip(bip_t *bip, struct link_client *ic, struct line *line, int privmsg); int ssl_check_trust(struct link_client *ic); void adm_blreset(struct link_client *ic); void bip_notify(struct link_client *ic, char *fmt, ...); diff --git a/src/conf.y b/src/conf.y index 28a005d..0c90416 100644 --- a/src/conf.y +++ b/src/conf.y @@ -22,6 +22,8 @@ extern int linec; #define YYMALLOC bip_malloc +extern int yyerror(char *); + int yywrap() { return 1; diff --git a/src/connection.c b/src/connection.c index d4e862e..7f75814 100644 --- a/src/connection.c +++ b/src/connection.c @@ -334,7 +334,7 @@ void write_line_fast(connection_t *cn, char *line) r = write_socket(cn, line); switch (r) { case WRITE_KEEP: - list_add_first(cn->outgoing, strdup(line)); + list_add_first(cn->outgoing, bip_strdup(line)); break; case WRITE_ERROR: cn->connected = CONN_ERROR; @@ -349,7 +349,7 @@ void write_line_fast(connection_t *cn, char *line) void write_line(connection_t *cn, char *line) { - list_add_last(cn->outgoing, strdup(line)); + list_add_last(cn->outgoing, bip_strdup(line)); } list_t *read_lines(connection_t *cn, int *error) diff --git a/src/irc.c b/src/irc.c index 5ca33da..8a7df16 100644 --- a/src/irc.c +++ b/src/irc.c @@ -76,7 +76,7 @@ struct channel *channel_new(const char *name) { struct channel *chan; chan = bip_calloc(sizeof(struct channel), 1); - chan->name = strdup(name); + chan->name = bip_strdup(name); hash_init(&chan->nicks, HASH_NOCASE); return chan; } @@ -93,7 +93,7 @@ char *nick_from_ircmask(char *mask) while (*nick && *nick != '!') nick++; if (!*nick) - return strdup(mask); + return bip_strdup(mask); len = nick - mask; ret = bip_malloc(len + 1); memcpy(ret, mask, len); @@ -259,19 +259,6 @@ static void irc_server_connected(struct link_server *server) } } -static int who_arg_to_ovmask(char *str) -{ - int ovmask = 0; - if (strchr(str, '@')) - ovmask |= NICKOP; - if (strchr(str, '+')) - ovmask |= NICKVOICED; - /* most likely useless */ - if (strchr(str, '%')) - ovmask |= NICKHALFOP; - return ovmask; -} - /* * Given the way irc nets disrespect the rfc, we completely forget * about this damn ircmask... @@ -280,28 +267,20 @@ static int who_arg_to_ovmask(char *str) static int irc_352(struct link_server *server, struct line *line) { (void)server; - if (line->elemc < 8) + if (!irc_line_include(line, 7)) return ERR_PROTOCOL; if (!origin_is_me(line, server)) { struct channel *channel; struct nick *nick; - channel = hash_get(&server->channels, line->elemv[2]); + channel = hash_get(&server->channels, irc_line_elem(line, 2)); if (!channel) return OK_COPY_WHO; - nick = hash_get(&channel->nicks, line->elemv[6]); + nick = hash_get(&channel->nicks, irc_line_elem(line, 6)); if (!nick) return OK_COPY_WHO; - -#if 0 - This causes more problems that it solves - /* it seems halfop status is not reported in whoreply messages - * do we really need to parse this ? */ - nick->ovmask &= NICKHALFOP; - nick->ovmask |= who_arg_to_ovmask(line->elemv[7]); -#endif } return OK_COPY_WHO; @@ -356,33 +335,33 @@ int irc_dispatch_server(bip_t *bip, struct link_server *server, /* shut gcc up */ (void)bip; - if (line->elemc == 0) + if (!irc_line_include(line, 0)) return ERR_PROTOCOL; - if (strcmp(line->elemv[0], "PING") == 0) { - if (line->elemc < 2) + if (irc_line_elem_equals(line, 0, "PING")) { + if (!irc_line_include(line, 1)) return ERR_PROTOCOL; struct line *resp = irc_line_new(); char *resps; irc_line_append(resp, "PONG"); - irc_line_append(resp, line->elemv[1]); + irc_line_append(resp, irc_line_elem(line, 1)); resp->colon = 1; /* it seems some ircds want it */ resps = irc_line_to_string(resp); write_line_fast(CONN(server), resps); irc_line_free(resp); free(resps); ret = OK_FORGET; - } else if (strcmp(line->elemv[0], "PONG") == 0) { + } else if (irc_line_elem_equals(line, 0, "PONG")) { /* not all server reply with PONG * so we blindly assume the PONG is ours. */ - if (line->elemc == 3) { + if (irc_line_count(line) == 3) { if (server->laginit_ts != -1) { irc_compute_lag(server); irc_lag_init(server); } ret = OK_FORGET; } - } else if (strcmp(line->elemv[0], "433") == 0) { + } else if (irc_line_elem_equals(line, 0, "433")) { if (LINK(server)->s_state != IRCS_CONNECTED) { size_t nicklen = strlen(server->nick); char *newnick = bip_malloc(nicklen + 2); @@ -410,20 +389,20 @@ int irc_dispatch_server(bip_t *bip, struct link_server *server, } } else if (LINK(server)->s_state == IRCS_RECONNECTING) { ret = OK_FORGET; - if (strcmp(line->elemv[0], "376") == 0) /* end of motd */ + if (irc_line_elem_equals(line, 0, "376")) /* end of motd */ irc_server_connected(server); - else if (strcmp(line->elemv[0], "422") == 0) /* no motd */ + else if (irc_line_elem_equals(line, 0, "422")) /* no motd */ irc_server_connected(server); } else if (LINK(server)->s_state == IRCS_CONNECTING) { ret = OK_FORGET; - if (strcmp(line->elemv[0], "NOTICE") == 0) { - } else if (strcmp(line->elemv[0], "376") == 0) { + if (irc_line_elem_equals(line, 0, "NOTICE")) { + } else if (irc_line_elem_equals(line, 0, "376")) { /* end of motd */ irc_server_connected(server); list_add_last(&LINK(server)->init_strings, irc_line_dup(line)); - } else if (strcmp(line->elemv[0], "422") == 0) { /* no motd */ + } else if (irc_line_elem_equals(line, 0, "422")) { /* no motd */ irc_server_connected(server); list_add_last(&LINK(server)->init_strings, irc_line_dup(line)); @@ -431,7 +410,7 @@ int irc_dispatch_server(bip_t *bip, struct link_server *server, list_add_last(&LINK(server)->init_strings, irc_line_dup(line)); } - } else if (strcmp(line->elemv[0], "001") == 0) { + } else if (irc_line_elem_equals(line, 0, "001")) { ret = irc_001(server, line); if (LINK(server)->s_state == IRCS_CONNECTING) { if (!list_is_empty(&LINK(server)->init_strings)) @@ -440,39 +419,39 @@ int irc_dispatch_server(bip_t *bip, struct link_server *server, list_add_last(&LINK(server)->init_strings, irc_line_dup(line)); } - } else if (strcmp(line->elemv[0], "JOIN") == 0) { + } else if (irc_line_elem_equals(line, 0, "JOIN")) { ret = irc_join(server, line); - } else if (strcmp(line->elemv[0], "332") == 0) { + } else if (irc_line_elem_equals(line, 0, "332")) { ret = irc_332(server, line); - } else if (strcmp(line->elemv[0], "333") == 0) { + } else if (irc_line_elem_equals(line, 0, "333")) { ret = irc_333(server, line); - } else if (strcmp(line->elemv[0], "352") == 0) { + } else if (irc_line_elem_equals(line, 0, "352")) { ret = irc_352(server, line); - } else if (strcmp(line->elemv[0], "315") == 0) { + } else if (irc_line_elem_equals(line, 0, "315")) { ret = irc_315(server, line); - } else if (strcmp(line->elemv[0], "353") == 0) { + } else if (irc_line_elem_equals(line, 0, "353")) { ret = irc_353(server, line); - } else if (strcmp(line->elemv[0], "366") == 0) { + } else if (irc_line_elem_equals(line, 0, "366")) { ret = irc_366(server, line); - } else if (strcmp(line->elemv[0], "367") == 0) { + } else if (irc_line_elem_equals(line, 0, "367")) { ret = irc_367(server, line); - } else if (strcmp(line->elemv[0], "368") == 0) { + } else if (irc_line_elem_equals(line, 0, "368")) { ret = irc_368(server, line); - } else if (strcmp(line->elemv[0], "PART") == 0) { + } else if (irc_line_elem_equals(line, 0, "PART")) { ret = irc_part(server, line); - } else if (strcmp(line->elemv[0], "MODE") == 0) { + } else if (irc_line_elem_equals(line, 0, "MODE")) { ret = irc_mode(server, line); - } else if (strcmp(line->elemv[0], "TOPIC") == 0) { + } else if (irc_line_elem_equals(line, 0, "TOPIC")) { ret = irc_topic(server, line); - } else if (strcmp(line->elemv[0], "KICK") == 0) { + } else if (irc_line_elem_equals(line, 0, "KICK")) { ret = irc_kick(server, line); - } else if (strcmp(line->elemv[0], "PRIVMSG") == 0) { + } else if (irc_line_elem_equals(line, 0, "PRIVMSG")) { ret = irc_privmsg(server, line); - } else if (strcmp(line->elemv[0], "NOTICE") == 0) { + } else if (irc_line_elem_equals(line, 0, "NOTICE")) { ret = irc_notice(server, line); - } else if (strcmp(line->elemv[0], "QUIT") == 0) { + } else if (irc_line_elem_equals(line, 0, "QUIT")) { ret = irc_quit(server, line); - } else if (strcmp(line->elemv[0], "NICK") == 0) { + } else if (irc_line_elem_equals(line, 0, "NICK")) { ret = irc_nick(server, line); } @@ -564,7 +543,7 @@ static void write_init_string(connection_t *c, struct line *line, char *nick) char *tmp; char *l; - tmp = line->elemv[1]; + tmp = (char *)irc_line_elem(line, 1); line->elemv[1] = nick; l = irc_line_to_string(line); write_line(c, l); @@ -804,7 +783,7 @@ static int irc_cli_startup(bip_t *bip, struct link_client *ic, static int irc_cli_nick(bip_t *bip, struct link_client *ic, struct line *line) { - if (line->elemc != 2) + if (irc_line_count(line) != 2) return ERR_PROTOCOL; if ((ic->state & IRCC_READY) == IRCC_READY) @@ -813,7 +792,7 @@ static int irc_cli_nick(bip_t *bip, struct link_client *ic, struct line *line) ic->state |= IRCC_NICK; if (ic->init_nick) free(ic->init_nick); - ic->init_nick = strdup(line->elemv[1]); + ic->init_nick = bip_strdup(irc_line_elem(line, 1)); if ((ic->state & IRCC_READY) == IRCC_READY) return irc_cli_startup(bip, ic, line); @@ -828,7 +807,7 @@ static int irc_cli_nick(bip_t *bip, struct link_client *ic, struct line *line) static int irc_cli_user(bip_t *bip, struct link_client *ic, struct line *line) { - if (line->elemc != 5) + if (irc_line_count(line) != 5) return ERR_PROTOCOL; if ((ic->state & IRCC_READY) == IRCC_READY) @@ -842,7 +821,7 @@ static int irc_cli_user(bip_t *bip, struct link_client *ic, struct line *line) static int irc_cli_pass(bip_t *bip, struct link_client *ic, struct line *line) { - if (line->elemc != 2) + if (irc_line_count(line) != 2) return ERR_PROTOCOL; if ((ic->state & IRCC_READY) == IRCC_READY) @@ -851,7 +830,7 @@ static int irc_cli_pass(bip_t *bip, struct link_client *ic, struct line *line) ic->state |= IRCC_PASS; if (ic->init_pass) free(ic->init_pass); - ic->init_pass = strdup(line->elemv[1]); + ic->init_pass = bip_strdup(irc_line_elem(line, 1)); if ((ic->state & IRCC_READY) == IRCC_READY) return irc_cli_startup(bip, ic, line); return OK_FORGET; @@ -867,12 +846,12 @@ static int irc_cli_quit(struct link_client *ic, struct line *line) static int irc_cli_privmsg(bip_t *bip, struct link_client *ic, struct line *line) { - if (line->elemc < 3) + if (!irc_line_include(line, 2)) return OK_FORGET; log_cli_privmsg(LINK(ic)->log, LINK(ic)->l_server->nick, - line->elemv[1], line->elemv[2]); - if (strcmp(line->elemv[1], "-bip") == 0) + irc_line_elem(line, 1), irc_line_elem(line, 2)); + if (irc_line_elem_equals(line, 1, "-bip")) return adm_bip(bip, ic, line, 1); if (LINK(ic)->user->blreset_on_talk) @@ -882,10 +861,10 @@ static int irc_cli_privmsg(bip_t *bip, struct link_client *ic, static int irc_cli_notice(struct link_client *ic, struct line *line) { - if (line->elemc < 3) + if (!irc_line_include(line, 2)) return OK_FORGET; log_cli_notice(LINK(ic)->log, LINK(ic)->l_server->nick, - line->elemv[1], line->elemv[2]); + irc_line_elem(line, 1), irc_line_elem(line, 2)); return OK_COPY_CLI; } @@ -914,12 +893,12 @@ static int irc_cli_mode(struct link_client *ic, struct line *line) { struct link *l = LINK(ic); - if (line->elemc != 3) + if (irc_line_count(line) != 3) return OK_COPY; /* This is a wild guess and that sucks. */ - if (strcmp(line->elemv[0], "MODE") != 0 || - strchr(line->elemv[2], 'b') == NULL) + if (!irc_line_elem_equals(line, 0, "MODE") || + strchr(irc_line_elem(line, 2), 'b') == NULL) return OK_COPY; ++ic->who_count; @@ -943,7 +922,7 @@ static int irc_cli_mode(struct link_client *ic, struct line *line) static void irc_notify_disconnection(struct link_server *is) { int i; - LINK(is)->cli_nick = strdup(is->nick); + LINK(is)->cli_nick = bip_strdup(is->nick); for (i = 0; i < LINK(is)->l_clientc; i++) { struct link_client *ic = LINK(is)->l_clientv[i]; @@ -959,7 +938,8 @@ static void irc_notify_disconnection(struct link_server *is) } } -void irc_add_channel_info(struct link_server *ircs, char *chan, char *key) +void irc_add_channel_info(struct link_server *ircs, const char *chan, + const char *key) { struct chan_info *ci; if (!ischannel(*chan)) @@ -969,8 +949,8 @@ void irc_add_channel_info(struct link_server *ircs, char *chan, char *key) if (!ci) { struct chan_info *ci; ci = chan_info_new(); - ci->name = strdup(chan); - ci->key = key ? strdup(key) : NULL; + ci->name = bip_strdup(chan); + ci->key = key ? bip_strdup(key) : NULL; ci->backlog = 1; hash_insert(&LINK(ircs)->chan_infos, chan, ci); list_add_last(&LINK(ircs)->chan_infos_order, ci); @@ -979,19 +959,19 @@ void irc_add_channel_info(struct link_server *ircs, char *chan, char *key) free(ci->key); ci->key = NULL; } - ci->key = key ? strdup(key) : NULL; + ci->key = key ? bip_strdup(key) : NULL; } } static int irc_cli_join(struct link_client *irc, struct line *line) { - if (line->elemc != 2 && line->elemc != 3) + if (irc_line_count(line) != 2 && irc_line_count(line) != 3) return ERR_PROTOCOL; - char *s, *e, *ks, *ke = 0; - s = line->elemv[1]; - if (line->elemc == 3) - ks = line->elemv[2]; + const char *s, *e, *ks, *ke = 0; + s = irc_line_elem(line, 1); + if (irc_line_count(line) == 3) + ks = irc_line_elem(line, 2); else ks = NULL; @@ -1015,7 +995,8 @@ static int irc_cli_join(struct link_client *irc, struct line *line) if (*ke == 0) ks = NULL; } else - kp = ks = NULL; + kp = NULL; + ks = NULL; } irc_add_channel_info(LINK(irc)->l_server, p, kp); @@ -1034,12 +1015,12 @@ static int irc_cli_join(struct link_client *irc, struct line *line) static int irc_cli_part(struct link_client *irc, struct line *line) { - if (line->elemc != 2 && line->elemc != 3) + if (irc_line_count(line) != 2 && irc_line_count(line) != 3) return ERR_PROTOCOL; struct chan_info *ci; if ((ci = hash_remove_if_exists(&LINK(irc)->chan_infos, - line->elemv[1])) != NULL) { + irc_line_elem(line, 1))) != NULL) { list_remove(&LINK(irc)->chan_infos_order, ci); free(ci->name); if (ci->key) @@ -1050,14 +1031,14 @@ static int irc_cli_part(struct link_client *irc, struct line *line) } #ifdef HAVE_LIBSSL -static int irc_dispatch_trust_client(struct link_client *ic, struct line *line) +static int irc_dispatch_trust_client(struct link_client *ic, struct line *line) { int r = OK_COPY; - if (line->elemc < 2) + if (!irc_line_include(line, 1)) return ERR_PROTOCOL; - if (strcasecmp(line->elemv[0], "BIP") == 0 && - strcasecmp(line->elemv[1], "TRUST") == 0) + if (strcasecmp(irc_line_elem(line, 0), "BIP") == 0 && + strcasecmp(irc_line_elem(line, 1), "TRUST") == 0) r = adm_trust(ic, line); return r; @@ -1068,36 +1049,37 @@ static int irc_dispatch_client(bip_t *bip, struct link_client *ic, struct line *line) { int r = OK_COPY; - if (line->elemc == 0) + if (irc_line_count(line) == 0) return ERR_PROTOCOL; - if (strcmp(line->elemv[0], "PING") == 0) { - if (line->elemc < 2) + if (irc_line_elem_equals(line, 0, "PING")) { + if (!irc_line_include(line, 1)) return ERR_PROTOCOL; - WRITE_LINE1(CONN(ic), LINK(ic)->name, "PONG", line->elemv[1]); + WRITE_LINE1(CONN(ic), LINK(ic)->name, "PONG", + irc_line_elem(line, 1)); r = OK_FORGET; } else if (LINK(ic)->s_state != IRCS_CONNECTED) { write_line_fast(CONN(ic), ":irc.bip.net NOTICE pouet " ":ERROR Proxy not connected, please wait " "before sending commands\r\n"); r = OK_FORGET; - } else if (strcasecmp(line->elemv[0], "BIP") == 0) { + } else if (strcasecmp(irc_line_elem(line, 0), "BIP") == 0) { r = irc_cli_bip(bip, ic, line); - } else if (strcmp(line->elemv[0], "JOIN") == 0) { + } else if (irc_line_elem_equals(line, 0, "JOIN")) { r = irc_cli_join(ic, line); - } else if (strcmp(line->elemv[0], "PART") == 0) { + } else if (irc_line_elem_equals(line, 0, "PART")) { r = irc_cli_part(ic, line); - } else if (strcmp(line->elemv[0], "NICK") == 0) { + } else if (irc_line_elem_equals(line, 0, "NICK")) { r = irc_cli_nick(bip, ic, line); - } else if (strcmp(line->elemv[0], "QUIT") == 0) { + } else if (irc_line_elem_equals(line, 0, "QUIT")) { r = irc_cli_quit(ic, line); - } else if (strcmp(line->elemv[0], "PRIVMSG") == 0) { + } else if (irc_line_elem_equals(line, 0, "PRIVMSG")) { r = irc_cli_privmsg(bip, ic, line); - } else if (strcmp(line->elemv[0], "NOTICE") == 0) { + } else if (irc_line_elem_equals(line, 0, "NOTICE")) { r = irc_cli_notice(ic, line); - } else if (strcmp(line->elemv[0], "WHO") == 0) { + } else if (irc_line_elem_equals(line, 0, "WHO")) { r = irc_cli_who(ic, line); - } else if (strcmp(line->elemv[0], "MODE") == 0) { + } else if (irc_line_elem_equals(line, 0, "MODE")) { r = irc_cli_mode(ic, line); } @@ -1130,17 +1112,21 @@ static void irc_copy_cli(struct link_client *src, struct link_client *dest, struct line *line) { char *str; + if (src == dest) return; - if (line->elemc <= 2 || strcmp(line->elemv[0], "PRIVMSG") != 0) { + if (!irc_line_include(line, 1) || + !irc_line_elem_equals(line, 0, "PRIVMSG")) { str = irc_line_to_string(line); write_line(CONN(dest), str); free(str); return; } - if (ischannel(*line->elemv[1]) || LINK(src) != LINK(dest)) { + if (ischannel(*irc_line_elem(line, 1)) || LINK(src) != LINK(dest)) { + if (line->origin) + fatal("internal error: line->origin should be null"); line->origin = LINK(src)->l_server->nick; str = irc_line_to_string(line); line->origin = NULL; @@ -1150,30 +1136,39 @@ static void irc_copy_cli(struct link_client *src, struct link_client *dest, } /* LINK(src) == LINK(dest) */ - size_t len = strlen(line->elemv[2]) + 5; - char *tmp, *oldelem; + size_t len = strlen(irc_line_elem(line, 2)) + 5; + char *tmp; if (len == 0) return; tmp = bip_malloc(len); - snprintf(tmp, len, " -> %s", line->elemv[2]); + snprintf(tmp, len, " -> %s", irc_line_elem(line, 2)); tmp[len - 1] = 0; - line->origin = line->elemv[1]; - /* tricky: */ - line->elemv[1] = LINK(src)->l_server->nick; + struct line *retline = irc_line_new(); - oldelem = line->elemv[2]; - line->elemv[2] = tmp; + retline->origin = bip_strdup(irc_line_elem(line, 1)); + irc_line_append(retline, irc_line_elem(line, 0)); + irc_line_append(retline, LINK(src)->l_server->nick); + irc_line_append(retline, tmp); + free(tmp); + str = irc_line_to_string(retline); + irc_line_free(retline); +#if 0 + /* tricky: */ + irc_line_elem(line, 1) = LINK(src)->l_server->nick; + + oldelem = irc_line_elem(line, 2); + irc_line_elem(line, 2) = tmp; str = irc_line_to_string(line); /* end of trick: */ - line->elemv[1] = line->origin; - line->elemv[2] = oldelem; + irc_line_elem(line, 1) = line->origin; + irc_line_elem(line, 2) = oldelem; line->origin = NULL; +#endif write_line(CONN(dest), str); - free(tmp); free(str); return; } @@ -1181,14 +1176,14 @@ static void irc_copy_cli(struct link_client *src, struct link_client *dest, static int irc_dispatch_loging_client(bip_t *bip, struct link_client *ic, struct line *line) { - if (line->elemc == 0) + if (irc_line_count(line) == 0) return ERR_PROTOCOL; - if (strcmp(line->elemv[0], "NICK") == 0) { + if (irc_line_elem_equals(line, 0, "NICK")) { return irc_cli_nick(bip, ic, line); - } else if (strcmp(line->elemv[0], "USER") == 0) { + } else if (irc_line_elem_equals(line, 0, "USER")) { return irc_cli_user(bip, ic, line); - } else if (strcmp(line->elemv[0], "PASS") == 0) { + } else if (irc_line_elem_equals(line, 0, "PASS")) { return irc_cli_pass(bip, ic, line); } return OK_FORGET; @@ -1236,14 +1231,14 @@ static int origin_is_me(struct line *l, struct link_server *server) static int irc_join(struct link_server *server, struct line *line) { char *s_nick; - char *s_chan; + const char *s_chan; struct channel *channel; struct nick *nick; - if (line->elemc != 2 && line->elemc != 3) + if (irc_line_count(line) != 2 && irc_line_count(line) != 3) return ERR_PROTOCOL; - s_chan = line->elemv[1]; + s_chan = irc_line_elem(line, 1); log_join(LINK(server)->log, line->origin, s_chan); channel = hash_get(&server->channels, s_chan); @@ -1271,17 +1266,17 @@ static int irc_join(struct link_server *server, struct line *line) static int irc_332(struct link_server *server, struct line *line) { struct channel *channel; - if (line->elemc != 4) + if (irc_line_count(line) != 4) return ERR_PROTOCOL; - channel = hash_get(&server->channels, line->elemv[2]); + channel = hash_get(&server->channels, irc_line_elem(line, 2)); /* we can get topic reply for chans we're not on */ if (!channel) return OK_COPY; if (channel->topic) free(channel->topic); - channel->topic = strdup(line->elemv[3]); + channel->topic = bip_strdup(irc_line_elem(line, 3)); log_init_topic(LINK(server)->log, channel->name, channel->topic); return OK_COPY; @@ -1290,10 +1285,10 @@ static int irc_332(struct link_server *server, struct line *line) static int irc_333(struct link_server *server, struct line *line) { struct channel *channel; - if (line->elemc < 3) + if (!irc_line_include(line, 2)) return ERR_PROTOCOL; - channel = hash_get(&server->channels, line->elemv[2]); + channel = hash_get(&server->channels, irc_line_elem(line, 2)); /* we can get topic info reply for chans we're not on */ if (!channel) return OK_COPY; @@ -1301,12 +1296,12 @@ static int irc_333(struct link_server *server, struct line *line) free(channel->creator); if (channel->create_ts) free(channel->create_ts); - if (line->elemc == 5) { - channel->creator = strdup(line->elemv[3]); - channel->create_ts = strdup(line->elemv[4]); + if (irc_line_count(line) == 5) { + channel->creator = bip_strdup(irc_line_elem(line, 3)); + channel->create_ts = bip_strdup(irc_line_elem(line, 4)); } else { - channel->creator = strdup(""); - channel->create_ts = strdup("0"); + channel->creator = bip_strdup(""); + channel->create_ts = bip_strdup("0"); } log_init_topic_time(LINK(server)->log, channel->name, channel->creator, channel->create_ts); @@ -1324,14 +1319,14 @@ static int irc_353(struct link_server *server, struct line *line) { struct channel *channel; struct nick *nick; - char *names, *eon; + const char *names, *eon; size_t len; char *tmp; - if (line->elemc != 5) + if (irc_line_count(line) != 5) return ERR_PROTOCOL; - channel = hash_get(&server->channels, line->elemv[3]); + channel = hash_get(&server->channels, irc_line_elem(line, 3)); /* we can get names reply for chans we're not on */ if (!channel) return OK_COPY; @@ -1347,9 +1342,9 @@ static int irc_353(struct link_server *server, struct line *line) } /* TODO check that type is one of "=" / "*" / "@" */ - channel->type = line->elemv[2][0]; + channel->type = irc_line_elem(line, 2)[0]; - names = line->elemv[4]; + names = irc_line_elem(line, 4); while (*names) { int ovmask = 0; @@ -1404,10 +1399,10 @@ static int irc_366(struct link_server *server, struct line *line) { struct channel *channel; - if (line->elemc != 4) + if (irc_line_count(line) != 4) return ERR_PROTOCOL; - channel = hash_get(&server->channels, line->elemv[2]); + channel = hash_get(&server->channels, irc_line_elem(line, 2)); if (channel && channel->running_names) channel->running_names = 0; return OK_COPY; @@ -1469,14 +1464,14 @@ static void channel_free(struct channel *c) static int irc_part(struct link_server *server, struct line *line) { char *s_nick; - char *s_chan; + const char *s_chan; struct channel *channel; struct nick *nick; - if (line->elemc != 2 && line->elemc != 3) + if (irc_line_count(line) != 2 && irc_line_count(line) != 3) return ERR_PROTOCOL; - s_chan = line->elemv[1]; + s_chan = irc_line_elem(line, 1); channel = hash_get(&server->channels, s_chan); /* we can't get part message for chans we're not on */ @@ -1485,7 +1480,8 @@ static int irc_part(struct link_server *server, struct line *line) if (origin_is_me(line, server)) { log_part(LINK(server)->log, line->origin, s_chan, - line->elemc == 3 ? line->elemv[2] : NULL); + irc_line_count(line) == 3 ? irc_line_elem(line, 2) : + NULL); hash_remove(&server->channels, s_chan); channel_free(channel); @@ -1504,7 +1500,7 @@ static int irc_part(struct link_server *server, struct line *line) free(s_nick); log_part(LINK(server)->log, line->origin, s_chan, - line->elemc == 3 ? line->elemv[2] : NULL); + irc_line_count(line) == 3 ? irc_line_elem(line, 2) : NULL); nick_free(nick); return OK_COPY; @@ -1538,9 +1534,10 @@ static void mode_remove_letter(struct link_server *s, char c) static void irc_user_mode(struct link_server *server, struct line *line) { - char *mode; + const char *mode; int add = 1; - for (mode = line->elemv[2]; *mode; mode++) { + + for (mode = irc_line_elem(line, 2); *mode; mode++) { if (*mode == '-') add = 0; else if (*mode == '+') @@ -1558,40 +1555,44 @@ static void irc_user_mode(struct link_server *server, struct line *line) static int irc_mode(struct link_server *server, struct line *line) { struct channel *channel; - char *mode; + const char *mode; int add = 1; unsigned cur_arg = 0; struct nick *nick; - if (line->elemc < 3) + if (!irc_line_include(line, 2)) return ERR_PROTOCOL; /* nick mode change */ - if (strcmp(line->elemv[1], server->nick) == 0) { - log_mode(LINK(server)->log, line->origin, line->elemv[1], - line->elemv[2], line->elemv + 3, - line->elemc - 3); + if (irc_line_elem_equals(line, 1, server->nick)) { + log_mode(LINK(server)->log, line->origin, + irc_line_elem(line, 1), + irc_line_elem(line, 2), + (const const char **)(line->elemv + 3), + irc_line_count(line) - 3); irc_user_mode(server, line); return OK_COPY; } - if (!ischannel(line->elemv[1][0])) + if (!ischannel(irc_line_elem(line, 1)[0])) return ERR_PROTOCOL; /* channel mode change */ - channel = hash_get(&server->channels, line->elemv[1]); + channel = hash_get(&server->channels, irc_line_elem(line, 1)); /* we can't get mode message for chans we're not on */ if (!channel) return ERR_PROTOCOL; - log_mode(LINK(server)->log, line->origin, line->elemv[1], - line->elemv[2], line->elemv + 3, line->elemc - 3); + log_mode(LINK(server)->log, line->origin, irc_line_elem(line, 1), + irc_line_elem(line, 2), + (const const char **)(line->elemv + 3), + irc_line_count(line) - 3); /* * MODE -a+b.. #channel args * ^ ^ * mode cur_arg */ - for (mode = line->elemv[2]; *mode; mode++) { + for (mode = irc_line_elem(line, 2); *mode; mode++) { switch (*mode) { case '-': add = 0; @@ -1600,16 +1601,16 @@ static int irc_mode(struct link_server *server, struct line *line) add = 1; break; case 'b': - if (cur_arg + 3 >= line->elemc) + if (!irc_line_include(line, cur_arg + 3)) return ERR_PROTOCOL; cur_arg++; break; case 'o': - if (cur_arg + 3 >= line->elemc) + if (!irc_line_include(line, cur_arg + 3)) return ERR_PROTOCOL; nick = hash_get(&channel->nicks, - line->elemv[cur_arg + 3]); + irc_line_elem(line, cur_arg + 3)); if (!nick) return ERR_PROTOCOL; if (add) @@ -1619,11 +1620,11 @@ static int irc_mode(struct link_server *server, struct line *line) cur_arg++; break; case 'h': - if (cur_arg + 3 >= line->elemc) + if (!irc_line_include(line, cur_arg + 3)) return ERR_PROTOCOL; nick = hash_get(&channel->nicks, - line->elemv[cur_arg + 3]); + irc_line_elem(line, cur_arg + 3)); if (!nick) return ERR_PROTOCOL; if (add) @@ -1633,11 +1634,11 @@ static int irc_mode(struct link_server *server, struct line *line) cur_arg++; break; case 'v': - if (cur_arg + 3 >= line->elemc) + if (!irc_line_include(line, cur_arg + 3)) return ERR_PROTOCOL; nick = hash_get(&channel->nicks, - line->elemv[cur_arg + 3]); + irc_line_elem(line, cur_arg + 3)); if (!nick) return ERR_PROTOCOL; if (add) @@ -1648,10 +1649,11 @@ static int irc_mode(struct link_server *server, struct line *line) break; case 'k': if (add) { - if (cur_arg + 3 >= line->elemc) + if (!irc_line_include(line, cur_arg + 3)) return ERR_PROTOCOL; - channel->key = strdup(line->elemv[cur_arg + 3]); + channel->key = bip_strdup( + irc_line_elem(line, cur_arg + 3)); cur_arg++; } else { if (channel->key) { @@ -1668,7 +1670,7 @@ static int irc_mode(struct link_server *server, struct line *line) case 'e': case 'q': case 'I': - if (cur_arg + 3 >= line->elemc) + if (!irc_line_include(line, cur_arg + 3)) return ERR_PROTOCOL; cur_arg++; break; @@ -1689,22 +1691,22 @@ static char *irc_timestamp(void) static int irc_topic(struct link_server *server, struct line *line) { struct channel *channel; - char *topic; + const char *topic; - if (line->elemc != 3) + if (irc_line_count(line) != 3) return ERR_PROTOCOL; - channel = hash_get(&server->channels, line->elemv[1]); + channel = hash_get(&server->channels, irc_line_elem(line, 1)); /* we can't get topic message for chans we're not on */ if (!channel) return ERR_PROTOCOL; - + if (channel->topic) free(channel->topic); - topic = line->elemv[2]; + topic = irc_line_elem(line, 2); if (*topic == ':') topic++; - channel->topic = strdup(topic); + channel->topic = bip_strdup(topic); /* * :arion.oftc.net 333 bip`luser #bipqSDFQE3 @@ -1713,12 +1715,12 @@ static int irc_topic(struct link_server *server, struct line *line) if (channel->creator) free(channel->creator); - channel->creator = strmaydup(line->origin); + channel->creator = bip_strmaydup(line->origin); if (channel->create_ts) free(channel->create_ts); channel->create_ts = irc_timestamp(); - log_topic(LINK(server)->log, line->origin, line->elemv[1], topic); + log_topic(LINK(server)->log, line->origin, irc_line_elem(line, 1), topic); return OK_COPY; } @@ -1727,22 +1729,22 @@ static int irc_kick(struct link_server *server, struct line *line) struct channel *channel; struct nick *nick; - if (line->elemc != 3 && line->elemc != 4) + if (irc_line_count(line) != 3 && irc_line_count(line) != 4) return ERR_PROTOCOL; - channel = hash_get(&server->channels, line->elemv[1]); + channel = hash_get(&server->channels, irc_line_elem(line, 1)); /* we can't get kick message for chans we're not on */ if (!channel) return ERR_PROTOCOL; - nick = hash_get(&channel->nicks, line->elemv[2]); + nick = hash_get(&channel->nicks, irc_line_elem(line, 2)); if (!nick) return ERR_PROTOCOL; if (strcmp(nick->name, server->nick) == 0) { log_kick(LINK(server)->log, line->origin, channel->name, nick->name, - line->elemc == 4 ? line->elemv[3] : NULL); + irc_line_count(line) == 4 ? irc_line_elem(line, 3) : NULL); hash_remove(&server->channels, channel->name); channel_free(channel); @@ -1751,16 +1753,16 @@ static int irc_kick(struct link_server *server, struct line *line) hash_remove(&channel->nicks, nick->name); nick_free(nick); - log_kick(LINK(server)->log, line->origin, line->elemv[1], - line->elemv[2], - line->elemc == 4 ? line->elemv[3] : NULL); + log_kick(LINK(server)->log, line->origin, irc_line_elem(line, 1), + irc_line_elem(line, 2), + irc_line_count(line) == 4 ? irc_line_elem(line, 3) : NULL); return OK_COPY; } static void irc_privmsg_check_ctcp(struct link_server *server, struct line *line) { - if (line->elemc != 3) + if (irc_line_count(line) != 3) return; if (!line->origin) @@ -1768,7 +1770,7 @@ static void irc_privmsg_check_ctcp(struct link_server *server, char *nick; nick = nick_from_ircmask(line->origin); - if (strcmp(line->elemv[2], "\001VERSION\001") == 0) { + if (irc_line_elem_equals(line, 2, "\001VERSION\001")) { WRITE_LINE2(CONN(server), NULL, "NOTICE", nick, "\001VERSION bip-" BIP_VERSION "\001"); } @@ -1778,8 +1780,8 @@ static void irc_privmsg_check_ctcp(struct link_server *server, static int irc_privmsg(struct link_server *server, struct line *line) { if (LINK(server)->s_state == IRCS_CONNECTED) - log_privmsg(LINK(server)->log, line->origin, line->elemv[1], - line->elemv[2]); + log_privmsg(LINK(server)->log, line->origin, irc_line_elem(line, 1), + irc_line_elem(line, 2)); irc_privmsg_check_ctcp(server, line); return OK_COPY; } @@ -1787,8 +1789,8 @@ static int irc_privmsg(struct link_server *server, struct line *line) static int irc_notice(struct link_server *server, struct line *line) { if (LINK(server)->s_state == IRCS_CONNECTED) - log_notice(LINK(server)->log, line->origin, line->elemv[1], - line->elemv[2]); + log_notice(LINK(server)->log, line->origin, + irc_line_elem(line, 1), irc_line_elem(line, 2)); return OK_COPY; } @@ -1804,7 +1806,7 @@ static int irc_nick(struct link_server *server, struct line *line) hash_iterator_t hi; char *org_nick; - if (line->elemc != 2) + if (irc_line_count(line) != 2) return ERR_PROTOCOL; if (!line->origin) @@ -1820,21 +1822,21 @@ static int irc_nick(struct link_server *server, struct line *line) continue; hash_remove(&channel->nicks, org_nick); free(nick->name); - nick->name = strdup(line->elemv[1]); + nick->name = bip_strdup(irc_line_elem(line, 1)); hash_insert(&channel->nicks, nick->name, nick); log_nick(LINK(server)->log, org_nick, channel->name, - line->elemv[1]); + irc_line_elem(line, 1)); } if (origin_is_me(line, server)) { free(server->nick); - server->nick = strdup(line->elemv[1]); + server->nick = bip_strdup(irc_line_elem(line, 1)); if (LINK(server)->follow_nick && (LINK(server)->away_nick == NULL || strcmp(server->nick, LINK(server)->away_nick)) != 0) { free(LINK(server)->connect_nick); - LINK(server)->connect_nick = strdup(server->nick); + LINK(server)->connect_nick = bip_strdup(server->nick); } } @@ -1849,7 +1851,7 @@ static int irc_generic_quit(struct link_server *server, struct line *line) hash_iterator_t hi; char *s_nick; - if (line->elemc != 2 && line->elemc != 1) + if (irc_line_count(line) != 2 && irc_line_count(line) != 1) return ERR_PROTOCOL; if (!line->origin) @@ -1866,7 +1868,7 @@ static int irc_generic_quit(struct link_server *server, struct line *line) nick_free(nick); log_quit(LINK(server)->log, line->origin, channel->name, - line->elemc == 2 ? line->elemv[1] : NULL); + irc_line_include(line, 1) ? irc_line_elem(line, 1) : NULL); } free(s_nick); return OK_COPY; @@ -1892,7 +1894,7 @@ static void irc_server_startup(struct link_server *ircs) if (LINK(ircs)->away_nick && LINK(ircs)->l_clientc == 0) { if (nick) free(nick); - nick = strdup(LINK(ircs)->away_nick); + nick = bip_strdup(LINK(ircs)->away_nick); } if ((!LINK(ircs)->follow_nick && !LINK(ircs)->away_nick) || nick == NULL) { @@ -1900,8 +1902,8 @@ static void irc_server_startup(struct link_server *ircs) free(nick); if (!LINK(ircs)->connect_nick) LINK(ircs)->connect_nick = - strdup(LINK(ircs)->user->default_nick); - nick = strdup(LINK(ircs)->connect_nick); + bip_strdup(LINK(ircs)->user->default_nick); + nick = bip_strdup(LINK(ircs)->connect_nick); } ircs->nick = nick; @@ -2135,7 +2137,7 @@ void irc_server_shutdown(struct link_server *s) return; if (LINK(s)->prev_nick) free(LINK(s)->prev_nick); - LINK(s)->prev_nick = strdup(s->nick); + LINK(s)->prev_nick = bip_strdup(s->nick); } diff --git a/src/lex.l b/src/lex.l index 027844f..260a971 100644 --- a/src/lex.l +++ b/src/lex.l @@ -33,9 +33,10 @@ void dummy_lex_FFS(void) #endif void conf_die(bip_t *, char *, ...); -int yyerror(void) +int yyerror(char *err) { - conf_die(_bip, "Parse error near %s, line %d", yytext, linec + 1); + conf_die(_bip, "Parse error '%s' near '%s', line %d", err, yytext, + linec + 1); conf_error = 1; return 1; } diff --git a/src/line.c b/src/line.c index 54b50e7..0543057 100644 --- a/src/line.c +++ b/src/line.c @@ -27,17 +27,6 @@ struct line *irc_line_new() return l; } -void irc_line_clear(struct line *l) -{ - unsigned i; - for (i = 0; i < l->elemc; i++) - free(l->elemv[i]); - free(l->elemv); - if (l->origin) - free(l->origin); - memset(l, 0, sizeof(struct line)); -} - void irc_line_write(struct line *l, connection_t *c) { char *bytes = irc_line_to_string(l); @@ -47,33 +36,45 @@ void irc_line_write(struct line *l, connection_t *c) struct line *irc_line_dup(struct line *line) { - unsigned i; + int i; struct line *nl = irc_line_new(); - nl->origin = line->origin ? strdup(line->origin) : NULL; + nl->origin = line->origin ? bip_strdup(line->origin) : NULL; nl->elemc = line->elemc; nl->elemv = bip_malloc(sizeof(char *) * line->elemc); for (i = 0; i < line->elemc; i++) - nl->elemv[i] = strdup(line->elemv[i]); + nl->elemv[i] = bip_strdup(line->elemv[i]); nl->colon = line->colon; return nl; } -void _irc_line_append(struct line *l, char *s) +char *irc_line_pop(struct line *l) +{ + char *ret; + + if (irc_line_count(l) == 0) + return NULL; + ret = (char *)l->elemv[l->elemc - 1]; + l->elemc--; + + return ret; +} + +void _irc_line_append(struct line *l, const char *s) { l->elemc++; l->elemv = bip_realloc(l->elemv, l->elemc * sizeof(char *)); - l->elemv[l->elemc - 1] = s; + l->elemv[l->elemc - 1] = (char *)s; } -void irc_line_append(struct line *l, char *s) +void irc_line_append(struct line *l, const char *s) { - _irc_line_append(l, strdup(s)); + _irc_line_append(l, bip_strdup(s)); } char *irc_line_to_string(struct line *l) { size_t len = 0; - unsigned i; + int i; char *ret; if (l->origin) @@ -102,6 +103,35 @@ char *irc_line_to_string(struct line *l) return ret; } +int irc_line_count(struct line *line) +{ + return line->elemc; +} + +int irc_line_include(struct line *line, int elem) +{ + if (elem < 0) + fatal("internal error: irc_line_elem got negative elem"); + return elem < line->elemc; +} + +const char *irc_line_elem(struct line *line, int elem) +{ + if (!irc_line_include(line, elem)) + fatal("internal error: irc_line_elem got too large elem"); + return line->elemv[elem]; +} + +int irc_line_elem_equals(struct line *line, int elem, const char *cmp) +{ + return !strcmp(irc_line_elem(line, elem), cmp); +} + +int irc_line_elem_case_equals(struct line *line, int elem, const char *cmp) +{ + return !strcasecmp(irc_line_elem(line, elem), cmp); +} + /* * takes a null terminated string as input w/o \r\n */ @@ -148,11 +178,12 @@ struct line *irc_line(char *str) space++; } len = space - str; - tmp = line->elemv[curelem] = bip_malloc(len + 1); + tmp = bip_malloc(len + 1); memcpy(tmp, str, len); tmp[len] = 0; if (curelem == 0) - strucase(line->elemv[curelem]); + strucase(tmp); + line->elemv[curelem] = (const char *)tmp; curelem++; @@ -165,9 +196,10 @@ struct line *irc_line(char *str) void irc_line_free(struct line *l) { - unsigned i; + int i; + for (i = 0; i < l->elemc; i++) - free(l->elemv[i]); + free((char *)l->elemv[i]); free(l->elemv); if (l->origin) free(l->origin); diff --git a/src/line.h b/src/line.h index 5d2bce1..1f5f80c 100644 --- a/src/line.h +++ b/src/line.h @@ -78,20 +78,25 @@ struct line { char *origin; - unsigned int elemc; - char **elemv; + int elemc; + const char **elemv; int colon; }; void irc_line_init(struct line *l); struct line *irc_line_new(); -void irc_line_clear(struct line *l); void irc_line_write(struct line *l, connection_t *c); -void irc_line_append(struct line *l, char *s); +void irc_line_append(struct line *l, const char *s); struct line *irc_line(char *str); char *irc_line_to_string(struct line *l); void irc_line_free(struct line *l); struct line *irc_line_dup(struct line *line); -void _irc_line_append(struct line *l, char *s); +void _irc_line_append(struct line *l, const char *s); +int irc_line_include(struct line *line, int elem); +const char *irc_line_elem(struct line *line, int elem); +int irc_line_count(struct line *line); +char *irc_line_pop(struct line *l); +int irc_line_elem_equals(struct line *line, int elem, const char *cmp); +int irc_line_elem_case_equals(struct line *line, int elem, const char *cmp); #endif diff --git a/src/log.c b/src/log.c index 0bf8310..3c5ea2b 100644 --- a/src/log.c +++ b/src/log.c @@ -25,9 +25,10 @@ extern int conf_log; extern FILE *conf_global_log_file; int log_set_backlog_offset(log_t *logdata, char *dest); -static int _log_write(log_t *logdata, logfilegroup_t *lf, char *d, char *str); +static int _log_write(log_t *logdata, logfilegroup_t *lf, const char *d, + const char *str); void logfile_free(logfile_t *lf); -static char *_log_wrap(char *dest, char *line); +static char *_log_wrap(const char *dest, const char *line); #define BOLD_CHAR 0x02 #define LAMESTRING "!bip@bip.bip.bip PRIVMSG " @@ -130,13 +131,13 @@ void replace_var(char *str, char *var, char *value, unsigned int max) } } -char *log_build_filename(log_t *logdata, char *destination) +char *log_build_filename(log_t *logdata, const char *destination) { char *logfile, year[5], day[3], month[3], *tmp, *logdir; int log_format_len; struct tm *now; time_t s; - char *dest = strdup(destination); + char *dest = bip_strdup(destination); strtolower(dest); log_format_len = strlen(conf_log_format); @@ -156,7 +157,7 @@ char *log_build_filename(log_t *logdata, char *destination) replace_var(logfile, "%d", day, MAX_PATH_LEN); replace_var(logfile, "%m", month, MAX_PATH_LEN); - logdir = strdup(logfile); + logdir = bip_strdup(logfile); if (!logdir) fatal("out of memory"); @@ -216,7 +217,7 @@ void log_reinit(logfilegroup_t *lfg) log_reset(lfg); } -static int log_add_file(log_t *logdata, char *destination, char *filename) +static int log_add_file(log_t *logdata, const char *destination, const char *filename) { FILE *f; logfile_t *lf = NULL; @@ -232,7 +233,7 @@ static int log_add_file(log_t *logdata, char *destination, char *filename) lf = bip_malloc(sizeof(logfile_t)); lf->file = f; - lf->filename = strdup(filename); + lf->filename = bip_strdup(filename); if (!lf->filename) fatal("out of memory"); @@ -249,7 +250,7 @@ static int log_add_file(log_t *logdata, char *destination, char *filename) if (!lfg) { lfg = bip_calloc(sizeof(logfilegroup_t), 1); list_init(&lfg->file_group, NULL); - lfg->name = strdup(destination); + lfg->name = bip_strdup(destination); if (!lfg->name) fatal("out of memory"); lfg->skip_advance = 0; @@ -280,7 +281,7 @@ void logfile_free(logfile_t *lf) free(lf); } -logfilegroup_t *log_find_file(log_t *logdata, char *destination) +logfilegroup_t *log_find_file(log_t *logdata, const char *destination) { logfile_t *lf; logfilegroup_t *lfg; @@ -383,7 +384,7 @@ logfilegroup_t *log_find_file(log_t *logdata, char *destination) * There are a lot of snprintf's here without enforcing the last \0 in the * buffer, but _log_write takes care of this for us. */ -void log_join(log_t *logdata, char *ircmask, char *channel) +void log_join(log_t *logdata, const char *ircmask, const char *channel) { snprintf(logdata->buffer, LOGLINE_MAXLEN, "%s -!- %s has joined %s", timestamp(), ircmask, @@ -391,8 +392,8 @@ void log_join(log_t *logdata, char *ircmask, char *channel) log_write(logdata, channel, logdata->buffer); } -void log_part(log_t *logdata, char *ircmask, char *channel, - char *message) +void log_part(log_t *logdata, const const char *ircmask, const char *channel, + const const char *message) { if (message) snprintf(logdata->buffer, LOGLINE_MAXLEN, @@ -405,8 +406,8 @@ void log_part(log_t *logdata, char *ircmask, char *channel, log_write(logdata, channel, logdata->buffer); } -void log_kick(log_t *logdata, char *ircmask, char *channel, - char *who, char *message) +void log_kick(log_t *logdata, const char *ircmask, const char *channel, + const char *who, const char *message) { snprintf(logdata->buffer, LOGLINE_MAXLEN, "%s -!- %s has been kicked by %s [%s]", timestamp(), @@ -414,7 +415,8 @@ void log_kick(log_t *logdata, char *ircmask, char *channel, log_write(logdata, channel, logdata->buffer); } -void log_quit(log_t *logdata, char *ircmask, char *channel, char *message) +void log_quit(log_t *logdata, const char *ircmask, const char *channel, + const char *message) { snprintf(logdata->buffer, LOGLINE_MAXLEN, "%s -!- %s has quit [%s]", timestamp(), ircmask, @@ -422,7 +424,8 @@ void log_quit(log_t *logdata, char *ircmask, char *channel, char *message) log_write(logdata, channel, logdata->buffer); } -void log_nick(log_t *logdata, char *ircmask, char *channel, char *newnick) +void log_nick(log_t *logdata, const char *ircmask, const char *channel, + const char *newnick) { snprintf(logdata->buffer, LOGLINE_MAXLEN, "%s -!- %s is now known as %s", @@ -430,8 +433,8 @@ void log_nick(log_t *logdata, char *ircmask, char *channel, char *newnick) log_write(logdata, channel, logdata->buffer); } -static void _log_privmsg(log_t *logdata, char *ircmask, int src, - char *destination, char *message) +static void _log_privmsg(log_t *logdata, const char *ircmask, int src, + const char *destination, const char *message) { char dir = '<'; if (!ircmask) @@ -446,14 +449,14 @@ static void _log_privmsg(log_t *logdata, char *ircmask, int src, (*(message + strlen(message) - 1) == '\001'))) { char *msg; /* hack for freenode and the like */ - char *real_message = message; + const char *real_message = message; if (*message == '+' || *message == '-') real_message++; if (strncmp(real_message, "\001ACTION ", 8) != 0) return; - msg = strdup(real_message); + msg = bip_strdup(real_message); if (!msg) fatal("out of memory"); *(msg + strlen(msg) - 1) = '\0'; @@ -481,20 +484,20 @@ static void _log_privmsg(log_t *logdata, char *ircmask, int src, log_write(logdata, destination, logdata->buffer); } -void log_privmsg(log_t *logdata, char *ircmask, char *destination, - char *message) +void log_privmsg(log_t *logdata, const char *ircmask, const char *destination, + const char *message) { _log_privmsg(logdata, ircmask, 0, destination, message); } -void log_cli_privmsg(log_t *logdata, char *ircmask, char *destination, - char *message) +void log_cli_privmsg(log_t *logdata, const char *ircmask, + const char *destination, const char *message) { _log_privmsg(logdata, ircmask, 1, destination, message); } -static void _log_notice(log_t *logdata, char *ircmask, int src, - char *destination, char *message) +static void _log_notice(log_t *logdata, const char *ircmask, int src, + const char *destination, const char *message) { char dir = '<'; @@ -515,19 +518,20 @@ static void _log_notice(log_t *logdata, char *ircmask, int src, log_write(logdata, destination, logdata->buffer); } -void log_notice(log_t *logdata, char *ircmask, char *destination, - char *message) +void log_notice(log_t *logdata, const char *ircmask, const char *destination, + const char *message) { _log_notice(logdata, ircmask, 0, destination, message); } -void log_cli_notice(log_t *logdata, char *ircmask, char *destination, - char *message) +void log_cli_notice(log_t *logdata, const char *ircmask, + const char *destination, const char *message) { _log_notice(logdata, ircmask, 1, destination, message); } -void log_topic(log_t *logdata, char *ircmask, char *channel, char *message) +void log_topic(log_t *logdata, const char *ircmask, const char *channel, + const char *message) { snprintf(logdata->buffer, LOGLINE_MAXLEN, "%s -!- %s changed topic of %s to: %s", timestamp(), @@ -535,7 +539,7 @@ void log_topic(log_t *logdata, char *ircmask, char *channel, char *message) log_write(logdata, channel, logdata->buffer); } -void log_init_topic(log_t *logdata, char *channel, char *message) +void log_init_topic(log_t *logdata, const char *channel, const char *message) { snprintf(logdata->buffer, LOGLINE_MAXLEN, "%s -!- Topic for %s: %s", timestamp(), channel, @@ -543,7 +547,8 @@ void log_init_topic(log_t *logdata, char *channel, char *message) log_write(logdata, channel, logdata->buffer); } -void log_init_topic_time(log_t *logdata, char *channel, char *who, char *when) +void log_init_topic_time(log_t *logdata, const char *channel, const char *who, + const char *when) { struct tm *time; char *timestr; @@ -564,13 +569,14 @@ void log_init_topic_time(log_t *logdata, char *channel, char *who, char *when) log_write(logdata, channel, logdata->buffer); } -void log_mode(log_t *logdata, char *ircmask, char *channel, char *modes, - char **modargv, unsigned modargc) +void log_mode(log_t *logdata, const char *ircmask, const char *channel, + const char *modes, const const char **modargv, int modargc) { - unsigned i; + int i; char *tmpbuf = bip_malloc(LOGLINE_MAXLEN + 1); char *tmpbuf2 = bip_malloc(LOGLINE_MAXLEN + 1); char *tmp; + snprintf(tmpbuf, LOGLINE_MAXLEN, "%s -!- mode/%s [%s", timestamp(), channel, modes); for (i = 0; i < modargc; i++) { @@ -734,7 +740,7 @@ int log_has_backlog(log_t *logdata, char *destination) * 01-08-2005 10:46:11 < * jj!john@thebox.ofjj.net */ -char *log_beautify(log_t *logdata, char *buf, char *dest) +char *log_beautify(log_t *logdata, const char *buf, const char *dest) { int action = 0; char *p; @@ -742,7 +748,7 @@ char *log_beautify(log_t *logdata, char *buf, char *dest) * so = startov, lo = lengthov * ts = timestamp, n = sender nick, m = message or action */ - char *sots, *son, *som, *sod = NULL; + const char *sots, *son, *som, *sod = NULL; size_t lots, lon, lom, lod; char *ret; int out; @@ -829,7 +835,7 @@ char *log_beautify(log_t *logdata, char *buf, char *dest) } if (out && strcmp(dest, "privates") == 0) { - char *stmp; + const char *stmp; size_t ltmp; stmp = sod; @@ -931,7 +937,7 @@ char *log_backread(log_t *logdata, char *destination, int *skip) return NULL; } list_it_next(&lfg->backlog_it); - return strdup(ptr); + return bip_strdup(ptr); } if (!conf_log) { @@ -1077,7 +1083,7 @@ next_file: return NULL; } -static char *_log_wrap(char *dest, char *line) +static char *_log_wrap(const char *dest, const char *line) { char *buf; size_t count; @@ -1094,16 +1100,18 @@ static char *_log_wrap(char *dest, char *line) return buf; } -static int _log_write(log_t *logdata, logfilegroup_t *lfg, char *destination, - char *str) +static int _log_write(log_t *logdata, logfilegroup_t *lfg, + const char *destination, const char *str) { size_t nbwrite; size_t len; + static char tmpstr[LOGLINE_MAXLEN + 1]; - str[LOGLINE_MAXLEN] = 0; + strncpy(tmpstr, str, LOGLINE_MAXLEN); + tmpstr[LOGLINE_MAXLEN] = 0; if (lfg->memlog) { - char *r = log_beautify(logdata, str, destination); + char *r = log_beautify(logdata, tmpstr, destination); if (r != NULL) { list_add_last(lfg->memlog, r); if (lfg->memc == logdata->user->backlog_lines) @@ -1118,8 +1126,8 @@ static int _log_write(log_t *logdata, logfilegroup_t *lfg, char *destination, logfile_t *lf = list_get_last(&lfg->file_group); - len = strlen(str); - nbwrite = fwrite(str, sizeof(char), len, lf->file); + len = strlen(tmpstr); + nbwrite = fwrite(tmpstr, sizeof(char), len, lf->file); nbwrite += fwrite("\n", sizeof(char), 1, lf->file); log_updatelast(lf); if (nbwrite != len + 1) @@ -1130,9 +1138,10 @@ static int _log_write(log_t *logdata, logfilegroup_t *lfg, char *destination, return nbwrite; } -void log_write(log_t *logdata, char *destination, char *str) +void log_write(log_t *logdata, const char *destination, const char *str) { logfilegroup_t *lfg = log_find_file(logdata, destination); + if (!lfg) { mylog(LOG_ERROR, "Unable to find/create logfile for '%s'", destination); @@ -1168,13 +1177,13 @@ void log_flush_all(void) } } -log_t *log_new(struct user *user, char *network) +log_t *log_new(struct user *user, const char *network) { log_t *logdata; logdata = (log_t *)bip_calloc(sizeof(log_t), 1); logdata->user = user; - logdata->network = strdup(network); + logdata->network = bip_strdup(network); hash_init(&logdata->logfgs, HASH_NOCASE); logdata->buffer = (char *)bip_malloc(LOGLINE_MAXLEN + 1); logdata->buffer[LOGLINE_MAXLEN - 1] = 0; // debug diff --git a/src/log.h b/src/log.h index 1405b4c..2a16a18 100644 --- a/src/log.h +++ b/src/log.h @@ -62,29 +62,35 @@ typedef struct log { } log_t; void log_close_all(log_t *logdata); -log_t *log_new(struct user *user, char *network); +log_t *log_new(struct user *user, const char *network); void logdata_free(log_t *logdata); int log_compare_files(logfile_t *f1, char *f2); -void log_join(log_t *logdata, char *ircmask, char *channel); -void log_part(log_t *logdata, char *ircmask, char *channel, char *message); -void log_kick(log_t *logdata, char *ircmask, char *channel, char *who, - char *message); -void log_quit(log_t *logdata, char *ircmask, char *channel, char *message); -void log_nick(log_t *logdata, char *ircmask, char *channel, char *newnick); -void log_privmsg(log_t *logdata, char *ircmask, char *destination, - char *message); -void log_notice(log_t *logdata, char *ircmask, char *channel, char *message); -void log_cli_privmsg(log_t *logdata, char *ircmask, char *destination, - char *message); -void log_cli_notice(log_t *logdata, char *ircmask, char *channel, - char *message); -void log_write(log_t *logdata, char *str, char *destination); -void log_mode(log_t *logdata, char *ircmask, char *channel, - char *modes, char **modargv, unsigned modargc); -void log_topic(log_t *logdata, char *ircmask, char *channel, char *message); -void log_init_topic(log_t *logdata, char *channel, char *message); -void log_init_topic_time(log_t *logdata, char *channel, char *who, char *when); +void log_join(log_t *logdata, const char *ircmask, const char *channel); +void log_part(log_t *logdata, const char *ircmask, const char *channel, + const char *message); +void log_kick(log_t *logdata, const char *ircmask, const char *channel, + const char *who, const char *message); +void log_quit(log_t *logdata, const char *ircmask, const char *channel, + const char *message); +void log_nick(log_t *logdata, const char *ircmask, const char *channel, + const char *newnick); +void log_privmsg(log_t *logdata, const char *ircmask, const char *destination, + const char *message); +void log_notice(log_t *logdata, const char *ircmask, const char *channel, + const char *message); +void log_cli_privmsg(log_t *logdata, const char *ircmask, + const char *destination, const char *message); +void log_cli_notice(log_t *logdata, const char *ircmask, const char *channel, + const char *message); +void log_write(log_t *logdata, const char *str, const char *destination); +void log_mode(log_t *logdata, const char *ircmask, const char *channel, + const char *modes, const const char **modargv, int modargc); +void log_topic(log_t *logdata, const char *ircmask, const char *channel, + const char *message); +void log_init_topic(log_t *logdata, const char *channel, const char *message); +void log_init_topic_time(log_t *logdata, const char *channel, const char *who, + const char *when); void log_connected(log_t *logdata); void log_disconnected(log_t *logdata); void log_ping_timeout(log_t *logdata); diff --git a/src/md5.c b/src/md5.c index 93031d2..8f4876b 100644 --- a/src/md5.c +++ b/src/md5.c @@ -22,6 +22,7 @@ #include #include "md5.h" +#include "util.h" #define GET_UINT32(n,b,i) \ { \ diff --git a/src/util.c b/src/util.c index 4141e81..74a8264 100644 --- a/src/util.c +++ b/src/util.c @@ -29,33 +29,45 @@ extern int conf_log_system; extern int errno; extern FILE *conf_global_log_file; +void memory_fatal(void) +{ + fflush(conf_global_log_file); +#define OOMMSG "Out of memory.\n" + fwrite(OOMMSG, 1, strlen(OOMMSG), conf_global_log_file); +#undef OOMMSG + fflush(conf_global_log_file); + exit(28); +} + void *bip_malloc(size_t size) { void *r = malloc(size); - if (!r) { - fprintf(conf_global_log_file, 1, strlen("malloc"), "malloc"); - exit(28); - } + if (!r) + memory_fatal(); return r; } void *bip_calloc(size_t nmemb, size_t size) { void *r = calloc(nmemb, size); - if (!r) { - fprintf(conf_global_log_file, 1, strlen("calloc"), "calloc"); - exit(28); - } + if (!r) + memory_fatal(); return r; } void *bip_realloc(void *ptr, size_t size) { void *r = realloc(ptr, size); - if (size > 0 && ptr == NULL) { - fprintf(conf_global_log_file, 1, strlen("realloc"), "realloc"); - exit(28); - } + if (size > 0 && r == NULL) + memory_fatal(); + return r; +} + +char *bip_strdup(const char *str) +{ + char *r = strdup(str); + if (!r) + memory_fatal(); return r; } @@ -208,21 +220,21 @@ struct list_item { void *ptr; }; -int list_ptr_cmp(void *a, void *b) +int list_ptr_cmp(const void *a, const void *b) { if (a == b) return 0; return -1; } -void list_init(list_t *l, int (*cmp)(void *, void *)) +void list_init(list_t *l, int (*cmp)(const void *, const void *)) { l->first = NULL; l->last = NULL; l->cmp = cmp; } -list_t *list_new(int (*cmp)(void *, void *)) +list_t *list_new(int (*cmp)(const void *, const void *)) { list_t *l; l = bip_malloc(sizeof(list_t)); @@ -325,7 +337,7 @@ void *list_remove_last(list_t *list) return ptr; } -void *list_remove_if_exists(list_t *list, void *ptr) +void *list_remove_if_exists(list_t *list, const void *ptr) { list_iterator_t li; int debug = 0; @@ -347,7 +359,7 @@ void *list_remove_if_exists(list_t *list, void *ptr) return NULL; } -void *list_remove(list_t *list, void *ptr) +void *list_remove(list_t *list, const void *ptr) { void *ret; if (!(ret = list_remove_if_exists(list, ptr))) @@ -355,7 +367,7 @@ void *list_remove(list_t *list, void *ptr) return ret; } -void *list_get(list_t *list, void *ptr) +void *list_get(list_t *list, const void *ptr) { struct list_item *it; @@ -447,7 +459,7 @@ struct hash_item { void *item; }; -static int hash_item_nocase_cmp(struct hash_item *a, char *b) +static int hash_item_nocase_cmp(const struct hash_item *a, const char *b) { return strcasecmp(a->key, b); } @@ -466,11 +478,13 @@ void hash_init(hash_t *h, int options) switch (options) { case HASH_NOCASE: list_init(&h->lists[i], - (int (*)(void*,void*))hash_item_nocase_cmp); + (int (*)(const void*, const void*)) + hash_item_nocase_cmp); break; case HASH_DEFAULT: list_init(&h->lists[i], - (int (*)(void*,void*))hash_item_cmp); + (int (*)(const void*,const void*)) + hash_item_cmp); break; default: fatal("wrong hash option %d", options); @@ -506,7 +520,7 @@ hash_t *hash_new(int options) } /* Now we have a real hash, but we use only the last byte of it :p */ -static unsigned char hash_func(char *pkey) +static unsigned char hash_func(const char *pkey) { char c; unsigned long hash = 5381; /* 5381 & 0xff makes more sense */ @@ -516,7 +530,7 @@ static unsigned char hash_func(char *pkey) return (unsigned char)hash; } -void hash_insert(hash_t *hash, char *key, void *ptr) +void hash_insert(hash_t *hash, const char *key, void *ptr) { struct hash_item *it; @@ -524,12 +538,12 @@ void hash_insert(hash_t *hash, char *key, void *ptr) fatal("Element with key %s already in hash %x\n", key, hash); it = bip_malloc(sizeof(struct hash_item)); - it->key = strdup(key); + it->key = bip_strdup(key); it->item = ptr; list_add_first(&hash->lists[hash_func(key)], it); } -void *hash_get(hash_t *hash, char *key) +void *hash_get(hash_t *hash, const char *key) { struct hash_item *hi; list_t *list = &hash->lists[hash_func(key)]; @@ -539,14 +553,14 @@ void *hash_get(hash_t *hash, char *key) return hi->item; } -void *hash_remove_if_exists(hash_t *hash, char *key) +void *hash_remove_if_exists(hash_t *hash, const char *key) { if (hash_get(hash, key) == NULL) return NULL; return hash_remove(hash, key); } -void *hash_remove(hash_t *hash, char *key) +void *hash_remove(hash_t *hash, const char *key) { struct hash_item *it; void *ptr; @@ -633,11 +647,11 @@ void hash_dump(hash_t *h) printf("%s => %p\n", hash_it_key(&it), hash_it_item(&it)); } -char *strmaydup(char *s) +char *bip_strmaydup(char *s) { if (!s) return s; - return strdup(s); + return bip_strdup(s); } void strucase(char *s) diff --git a/src/util.h b/src/util.h index 0f5b0cf..39a23fb 100644 --- a/src/util.h +++ b/src/util.h @@ -75,12 +75,12 @@ typedef struct hash_iterator { } \ } while(0); -void list_init(list_t *list, int (*cmp)(void*,void*)); -int list_ptr_cmp(void *a, void *b); -list_t *list_new(int (*cmp)(void *, void *)); -void *list_remove(list_t *list, void *ptr); -void *list_remove_if_exists(list_t *list, void *ptr); -void *list_get(list_t *list, void *ptr); +void list_init(list_t *list, int (*cmp)(const void*, const void*)); +int list_ptr_cmp(const void *a, const void *b); +list_t *list_new(int (*cmp)(const void *, const void *)); +void *list_remove(list_t *list, const void *ptr); +void *list_remove_if_exists(list_t *list, const void *ptr); +void *list_get(list_t *list, const void *ptr); void list_add_first(list_t *list, void *ptr); void list_add_first_uniq(list_t *list, void *ptr); void list_add_last(list_t *list, void *ptr); @@ -101,10 +101,10 @@ void hash_init(hash_t *h, int); void hash_free(hash_t *h); void hash_clean(hash_t *h); hash_t *hash_new(int options); -void hash_insert(hash_t *hash, char *key, void *ptr); -void *hash_get(hash_t *, char *key); -void *hash_remove(hash_t *hash, char *key); -void *hash_remove_if_exists(hash_t *hash, char *key); +void hash_insert(hash_t *hash, const char *key, void *ptr); +void *hash_get(hash_t *, const char *key); +void *hash_remove(hash_t *hash, const char *key); +void *hash_remove_if_exists(hash_t *hash, const char *key); int hash_is_empty(hash_t *h); void hash_it_init(hash_t *hash, hash_iterator_t *i); void hash_it_next(hash_iterator_t *hi); @@ -114,7 +114,7 @@ void *hash_it_remove(hash_iterator_t *li); int is_valid_nick(char *str); int is_valid_username(char *str); -char *strmaydup(char *s); +char *bip_strmaydup(char *s); void strucase(char *s); int ischannel(char p); @@ -126,5 +126,6 @@ char *checkmode2text(int v); void *bip_malloc(size_t size); void *bip_calloc(size_t nmemb, size_t size); void *bip_realloc(void *ptr, size_t size); +char *bip_strdup(const char *str); #endif