more cleanups, start of a log refactoring

That changes log format and might breack everything.
This commit is contained in:
Arnaud Cornet 2008-12-18 14:27:16 +01:00
parent fd644b312b
commit 4b723ca479
11 changed files with 322 additions and 134 deletions

View File

@ -2150,15 +2150,7 @@ int adm_bip(bip_t *bip, struct link_client *ic, struct line *line, int privmsg)
" argument"); " argument");
} }
#if 0 #if 0
TODO TODO network info
} else if (strcasecmp(line->elemv[privmsg + 2],
"network") == 0) {
if (irc_line_count(line) == privmsg + 4) {
adm_info_network(ic, line->elemv[privmsg + 3]);
} else {
bip_notify(ic, "/BIP INFO network needs one "
"argument");
}
#endif #endif
} else { } else {
bip_notify(ic, "-- Invalid INFO request"); bip_notify(ic, "-- Invalid INFO request");
@ -2193,8 +2185,8 @@ int adm_bip(bip_t *bip, struct link_client *ic, struct line *line, int privmsg)
return OK_FORGET; return OK_FORGET;
} }
adm_follow_nick(ic, irc_line_elem(line, privmsg + 2)); adm_follow_nick(ic, irc_line_elem(line, privmsg + 2));
} else if (strcasecmp(line->elemv[privmsg + 1], } else if (irc_line_elem_case_equals(line, privmsg + 1,
"IGNORE_FIRST_NICK") == 0) { "IGNORE_FIRST_NICK")) {
if (irc_line_count(line) != privmsg + 3) { if (irc_line_count(line) != privmsg + 3) {
bip_notify(ic, "-- IGNORE_FIRST_NICK " bip_notify(ic, "-- IGNORE_FIRST_NICK "
"command needs one argument"); "command needs one argument");

View File

@ -347,6 +347,11 @@ void write_line_fast(connection_t *cn, char *line)
} }
} }
void write_lines(connection_t *cn, list_t *lines)
{
list_append(cn->outgoing, lines);
}
void write_line(connection_t *cn, char *line) void write_line(connection_t *cn, char *line)
{ {
list_add_last(cn->outgoing, bip_strdup(line)); list_add_last(cn->outgoing, bip_strdup(line));

View File

@ -99,6 +99,7 @@ void connection_free(connection_t *cn);
void connection_close(connection_t *cn); void connection_close(connection_t *cn);
void write_line(connection_t *cn, char *line); void write_line(connection_t *cn, char *line);
void write_lines(connection_t *cn, list_t *lines);
void write_line_fast(connection_t *cn, char *line); void write_line_fast(connection_t *cn, char *line);
list_t *read_lines(connection_t *cn, int *error); list_t *read_lines(connection_t *cn, int *error);
list_t *wait_event(list_t *cn_list, int *msec, int *nc); list_t *wait_event(list_t *cn_list, int *msec, int *nc);

193
src/irc.c
View File

@ -47,6 +47,7 @@ static int irc_367(struct link_server *server, struct line *l);
static int irc_368(struct link_server *server, struct line *l); static int irc_368(struct link_server *server, struct line *l);
void irc_server_shutdown(struct link_server *s); void irc_server_shutdown(struct link_server *s);
static int origin_is_me(struct line *l, struct link_server *server); static int origin_is_me(struct line *l, struct link_server *server);
static void ls_set_nick(struct link_server *ircs, char *nick);
#ifdef HAVE_OIDENTD #ifdef HAVE_OIDENTD
#define OIDENTD_FILENAME ".oidentd.conf" #define OIDENTD_FILENAME ".oidentd.conf"
@ -81,9 +82,9 @@ struct channel *channel_new(const char *name)
return chan; return chan;
} }
char *nick_from_ircmask(char *mask) char *nick_from_ircmask(const char *mask)
{ {
char *nick = mask; const char *nick = mask;
char *ret; char *ret;
size_t len; size_t len;
@ -219,11 +220,12 @@ static void irc_server_join(struct link_server *s)
static void irc_server_connected(struct link_server *server) static void irc_server_connected(struct link_server *server)
{ {
int i; int i;
LINK(server)->s_state = IRCS_CONNECTED; LINK(server)->s_state = IRCS_CONNECTED;
LINK(server)->s_conn_attempt = 0; LINK(server)->s_conn_attempt = 0;
mylog(LOG_INFO, "Connected user %s to %s", LINK(server)->user->name, mylog(LOG_INFO, "Connected to server %s for user %s",
LINK(server)->name); LINK(server)->name, LINK(server)->user->name);
irc_server_join(server); irc_server_join(server);
log_connected(LINK(server)->log); log_connected(LINK(server)->log);
@ -238,15 +240,16 @@ static void irc_server_connected(struct link_server *server)
free(LINK(server)->cli_nick); free(LINK(server)->cli_nick);
LINK(server)->cli_nick = NULL; LINK(server)->cli_nick = NULL;
} }
/* basic helper for nickserv and co */ /* basic helper for nickserv and co */
list_iterator_t itocs; list_iterator_t itocs;
for (list_it_init(&LINK(server)->on_connect_send, &itocs); for (list_it_init(&LINK(server)->on_connect_send, &itocs);
list_it_item(&itocs); list_it_next(&itocs)) { list_it_item(&itocs); list_it_next(&itocs)) {
ssize_t len = strlen(list_it_item(&itocs)) + 2; ssize_t len = strlen(list_it_item(&itocs)) + 2;
char *str = bip_malloc(len + 1); char *str = bip_malloc(len + 1);
sprintf(str, "%s\r\n", (char *)list_it_item(&itocs)); sprintf(str, "%s\r\n", (char *)list_it_item(&itocs));
write_line(CONN(server), str); write_line(CONN(server), str);
free(str); free(str);
} }
if (LINK(server)->l_clientc == 0) { if (LINK(server)->l_clientc == 0) {
@ -263,13 +266,33 @@ static void irc_server_connected(struct link_server *server)
* Given the way irc nets disrespect the rfc, we completely forget * Given the way irc nets disrespect the rfc, we completely forget
* about this damn ircmask... * about this damn ircmask...
:irc.iiens.net 352 pwet * ~a je.suis.t1r.net irc.iiens.net pwet H :0 d :irc.iiens.net 352 pwet * ~a je.suis.t1r.net irc.iiens.net pwet H :0 d
-> nohar!~nohar@haruka.t1r.net
*/ */
static int irc_352(struct link_server *server, struct line *line) static int irc_352(struct link_server *server, struct line *line)
{ {
(void)server; (void)server;
if (!irc_line_include(line, 7)) if (!irc_line_include(line, 6))
return ERR_PROTOCOL; return ERR_PROTOCOL;
#if 0
if (irc_line_elem_case_equals(line, 6, server->nick)) {
const char *nick = server->nick;
const char *iname = irc_line_elem(line, 3);
const char *ihost = irc_line_elem(line, 4);
char *ircmask = bip_malloc(strlen(nick) + strlen(iname) +
strlen(ihost) + 3);
strcpy(ircmask, nick);
strcat(ircmask, "!");
strcat(ircmask, iname);
strcat(ircmask, "@");
strcat(ircmask, ihost);
if (server->ircmask)
free(server->ircmask);
server->ircmask = ircmask;
}
#endif
#if 0
if (!origin_is_me(line, server)) { if (!origin_is_me(line, server)) {
struct channel *channel; struct channel *channel;
struct nick *nick; struct nick *nick;
@ -283,6 +306,7 @@ static int irc_352(struct link_server *server, struct line *line)
return OK_COPY_WHO; return OK_COPY_WHO;
} }
#endif
return OK_COPY_WHO; return OK_COPY_WHO;
} }
@ -365,24 +389,24 @@ int irc_dispatch_server(bip_t *bip, struct link_server *server,
if (LINK(server)->s_state != IRCS_CONNECTED) { if (LINK(server)->s_state != IRCS_CONNECTED) {
size_t nicklen = strlen(server->nick); size_t nicklen = strlen(server->nick);
char *newnick = bip_malloc(nicklen + 2); char *newnick = bip_malloc(nicklen + 2);
strcpy(newnick, server->nick); strcpy(newnick, server->nick);
if (strlen(server->nick) < 9) { if (strlen(server->nick) < 9) {
strcat(newnick, "`"); strcat(newnick, "`");
} else if (newnick[7] != '`') {
if (newnick[8] != '`') {
newnick[8] = '`';
newnick[9] = 0;
} else {
newnick[7] = '`';
newnick[9] = 0;
}
} else { } else {
newnick[8] = rand() * ('z' - 'a') / RAND_MAX + if (newnick[7] != '`') {
'a'; if (newnick[8] != '`') {
newnick[8] = '`';
} else {
newnick[7] = '`';
}
} else {
newnick[8] = rand() *
('z' - 'a') / RAND_MAX + 'a';
}
newnick[9] = 0; newnick[9] = 0;
} }
free(server->nick); ls_set_nick(server, newnick);
server->nick = newnick;
WRITE_LINE1(CONN(server), NULL, "NICK", server->nick); WRITE_LINE1(CONN(server), NULL, "NICK", server->nick);
ret = OK_FORGET; ret = OK_FORGET;
@ -482,19 +506,21 @@ int irc_dispatch_server(bip_t *bip, struct link_server *server,
/* send join and related stuff to client */ /* send join and related stuff to client */
static void irc_send_join(struct link_client *ic, struct channel *chan) static void irc_send_join(struct link_client *ic, struct channel *chan)
{ {
char *ircmask; /* fake an irc mask for rbot */
struct user *user; struct user *user;
char *ircmask;
user = LINK(ic)->user; user = LINK(ic)->user;
if (!user) if (!user)
fatal("irc_send_join: No user associated"); fatal("irc_send_join: No user associated");
/* user ircmask here for rbot */
ircmask = bip_malloc(strlen(LINK(ic)->l_server->nick) + ircmask = bip_malloc(strlen(LINK(ic)->l_server->nick) +
strlen("!bip@bip.bip.bip") + 1); strlen(BIP_FAKEMASK) + 1);
strcpy(ircmask, LINK(ic)->l_server->nick); strcpy(ircmask, LINK(ic)->l_server->nick);
strcat(ircmask, "!bip@bip.bip.bip"); strcat(ircmask, BIP_FAKEMASK);
WRITE_LINE1(CONN(ic), ircmask, "JOIN", chan->name); WRITE_LINE1(CONN(ic), ircmask, "JOIN", chan->name);
free(ircmask); free(ircmask);
if (chan->topic) if (chan->topic)
WRITE_LINE3(CONN(ic), P_SERV, "332", LINK(ic)->l_server->nick, WRITE_LINE3(CONN(ic), P_SERV, "332", LINK(ic)->l_server->nick,
chan->name, chan->topic); chan->name, chan->topic);
@ -517,38 +543,15 @@ static void irc_send_join(struct link_client *ic, struct channel *chan)
WRITE_LINE3(CONN(ic), P_SERV, "366", LINK(ic)->l_server->nick, WRITE_LINE3(CONN(ic), P_SERV, "366", LINK(ic)->l_server->nick,
chan->name, "End of /NAMES list."); chan->name, "End of /NAMES list.");
/* XXX: could be more efficient */
if (!user->backlog) {
mylog(LOG_DEBUG, "Backlog disabled for %s, not backlogging",
user->name);
} else if (log_has_backlog(LINK(ic)->log, chan->name)) {
char *line;
int skip = 0;
while ((line =
log_backread(LINK(ic)->log, chan->name, &skip))) {
if (!skip)
write_line(CONN(ic), line);
free(line);
}
WRITE_LINE2(CONN(ic), P_IRCMASK, "PRIVMSG", chan->name,
"End of backlog.");
} else {
mylog(LOG_DEBUG, "Nothing to backlog for %s/%s",
user->name, chan->name);
}
} }
static void write_init_string(connection_t *c, struct line *line, char *nick) static void write_init_string(connection_t *c, struct line *line, char *nick)
{ {
char *tmp;
char *l; char *l;
tmp = (char *)irc_line_elem(line, 1); l = irc_line_to_string_to(line, nick);
line->elemv[1] = nick;
l = irc_line_to_string(line);
write_line(c, l); write_line(c, l);
free(l); free(l);
line->elemv[1] = tmp;
} }
static void bind_to_link(struct link *l, struct link_client *ic) static void bind_to_link(struct link *l, struct link_client *ic)
@ -654,18 +657,35 @@ static void irc_cli_make_join(struct link_client *ic)
if (!hash_get(&LINK(ic)->chan_infos, chan->name)) if (!hash_get(&LINK(ic)->chan_infos, chan->name))
irc_send_join(ic, chan); irc_send_join(ic, chan);
} }
/* backlog privates */
char *str;
int skip = 0;
while ((str = log_backread(LINK(ic)->log, S_PRIVATES, &skip))) {
if (!skip)
write_line(CONN(ic), str);
free(str);
}
} }
} }
static void irc_cli_backlog(struct link_client *ic)
{
struct user *user;
user = LINK(ic)->user;
if (!user)
fatal("irc_send_join: No user associated");
if (!user->backlog) {
mylog(LOG_DEBUG, "Backlog disabled for %s, not backlogging",
user->name);
return;
}
list_t *backlogl;
char *bl;
backlogl = log_backlogs(LINK(ic)->log);
while ((bl = list_remove_first(backlogl))) {
mylog(LOG_INFO, "backlogging: %s", bl);
write_lines(CONN(ic),
backlog_lines_from_last_mark(LINK(ic)->log, bl));
free(bl);
}
list_free(backlogl);
}
static int irc_cli_startup(bip_t *bip, struct link_client *ic, static int irc_cli_startup(bip_t *bip, struct link_client *ic,
struct line *line) struct line *line)
{ {
@ -774,6 +794,7 @@ static int irc_cli_startup(bip_t *bip, struct link_client *ic,
} }
irc_cli_make_join(ic); irc_cli_make_join(ic);
irc_cli_backlog(ic);
log_client_connected(LINK(ic)->log); log_client_connected(LINK(ic)->log);
free(init_nick); free(init_nick);
@ -1559,17 +1580,20 @@ static int irc_mode(struct link_server *server, struct line *line)
int add = 1; int add = 1;
unsigned cur_arg = 0; unsigned cur_arg = 0;
struct nick *nick; struct nick *nick;
char **elemv;
int elemc;
if (!irc_line_include(line, 2)) if (!irc_line_include(line, 2))
return ERR_PROTOCOL; return ERR_PROTOCOL;
/* nick mode change */ /* nick mode change */
if (irc_line_elem_equals(line, 1, server->nick)) { if (irc_line_elem_equals(line, 1, server->nick)) {
irc_line_extract_args(line, 3, &elemv, &elemc);
log_mode(LINK(server)->log, line->origin, log_mode(LINK(server)->log, line->origin,
irc_line_elem(line, 1), irc_line_elem(line, 1),
irc_line_elem(line, 2), irc_line_elem(line, 2), elemv, elemc);
(const const char **)(line->elemv + 3), irc_line_free_args(elemv, elemc);
irc_line_count(line) - 3);
irc_user_mode(server, line); irc_user_mode(server, line);
return OK_COPY; return OK_COPY;
} }
@ -1582,10 +1606,11 @@ static int irc_mode(struct link_server *server, struct line *line)
/* we can't get mode message for chans we're not on */ /* we can't get mode message for chans we're not on */
if (!channel) if (!channel)
return ERR_PROTOCOL; return ERR_PROTOCOL;
irc_line_extract_args(line, 3, &elemv, &elemc);
log_mode(LINK(server)->log, line->origin, irc_line_elem(line, 1), log_mode(LINK(server)->log, line->origin, irc_line_elem(line, 1),
irc_line_elem(line, 2), irc_line_elem(line, 2), elemv, elemc);
(const const char **)(line->elemv + 3), irc_line_free_args(elemv, elemc);
irc_line_count(line) - 3);
/* /*
* MODE -a+b.. #channel args * MODE -a+b.. #channel args
@ -1779,9 +1804,12 @@ static void irc_privmsg_check_ctcp(struct link_server *server,
static int irc_privmsg(struct link_server *server, struct line *line) static int irc_privmsg(struct link_server *server, struct line *line)
{ {
if (LINK(server)->s_state == IRCS_CONNECTED) if (!irc_line_include(line, 2))
log_privmsg(LINK(server)->log, line->origin, irc_line_elem(line, 1), return ERR_PROTOCOL;
irc_line_elem(line, 2)); if (LINK(server)->s_state == IRCS_CONNECTED) {
log_privmsg(LINK(server)->log, line->origin,
irc_line_elem(line, 1), irc_line_elem(line, 2));
}
irc_privmsg_check_ctcp(server, line); irc_privmsg_check_ctcp(server, line);
return OK_COPY; return OK_COPY;
} }
@ -1874,6 +1902,33 @@ static int irc_generic_quit(struct link_server *server, struct line *line)
return OK_COPY; return OK_COPY;
} }
static void ls_set_nick(struct link_server *ircs, char *nick)
{
if (ircs->nick)
free(ircs->nick);
ircs->nick = nick;
#if 0
if (ircs->ircmask) {
char *eom = strchr(ircs->ircmask, '!');
if (!eom) {
free(ircs->ircmask);
goto fake;
}
eom = bip_strdup(eom);
free(ircs->ircmask);
ircs->ircmask = bip_malloc(strlen(nick) + strlen(eom) + 1);
strcpy(ircs->ircmask, nick);
strcat(ircs->ircmask, eom);
free(eom);
return;
}
fake:
ircs->ircmask = bip_malloc(strlen(nick) + strlen(BIP_FAKEMASK) + 1);
strcpy(ircs->ircmask, nick);
strcat(ircs->ircmask, BIP_FAKEMASK);
#endif
}
static void irc_server_startup(struct link_server *ircs) static void irc_server_startup(struct link_server *ircs)
{ {
char *nick; char *nick;
@ -1906,7 +1961,7 @@ static void irc_server_startup(struct link_server *ircs)
nick = bip_strdup(LINK(ircs)->connect_nick); nick = bip_strdup(LINK(ircs)->connect_nick);
} }
ircs->nick = nick; ls_set_nick(ircs, nick);
WRITE_LINE1(CONN(ircs), NULL, "NICK", ircs->nick); WRITE_LINE1(CONN(ircs), NULL, "NICK", ircs->nick);
} }
@ -1952,7 +2007,7 @@ void server_cleanup(struct link_server *server)
for (hash_it_init(&server->channels, &hi); hash_it_item(&hi); for (hash_it_init(&server->channels, &hi); hash_it_item(&hi);
hash_it_next(&hi)) hash_it_next(&hi))
channel_free(hash_it_item(&hi)); channel_free(hash_it_item(&hi));
hash_init(&server->channels, HASH_NOCASE); hash_clean(&server->channels);
if (CONN(server)) { if (CONN(server)) {
connection_free(CONN(server)); connection_free(CONN(server));

View File

@ -266,5 +266,8 @@ void irc_client_free(struct link_client *);
struct link *irc_link_new(); struct link *irc_link_new();
void link_kill(bip_t *bip, struct link *); void link_kill(bip_t *bip, struct link *);
void unbind_from_link(struct link_client *ic); void unbind_from_link(struct link_client *ic);
char *nick_from_ircmask(const char *mask);
#define BIP_FAKEMASK "!bip@bip.bip.bip"
#endif #endif

View File

@ -19,6 +19,11 @@ void irc_line_init(struct line *l)
memset(l, 0, sizeof(struct line)); memset(l, 0, sizeof(struct line));
} }
void _irc_line_deinit(struct line *l)
{
free(l->elemv);
}
struct line *irc_line_new() struct line *irc_line_new()
{ {
struct line *l; struct line *l;
@ -103,6 +108,19 @@ char *irc_line_to_string(struct line *l)
return ret; return ret;
} }
char *irc_line_to_string_to(struct line *line, char *nick)
{
char *tmp;
char *l;
tmp = (char *)irc_line_elem(line, 1);
line->elemv[1] = nick;
l = irc_line_to_string(line);
line->elemv[1] = tmp;
return l;
}
int irc_line_count(struct line *line) int irc_line_count(struct line *line)
{ {
return line->elemc; return line->elemc;
@ -205,3 +223,30 @@ void irc_line_free(struct line *l)
free(l->origin); free(l->origin);
free(l); free(l);
} }
void irc_line_extract_args(struct line *line, int from,
char ***elemv, int *elemc)
{
int i;
*elemc = irc_line_count(line) - from;
if (*elemc == 0) {
*elemv = NULL;
return;
}
*elemv = bip_malloc(*elemc * sizeof(char *));
for (i = 0; i < *elemc; i++)
*elemv[i] = bip_strdup(irc_line_elem(line, i + from));
}
void irc_line_free_args(char **elemv, int elemc)
{
int i;
if (elemc == 0)
return;
for (i = 0; i < elemc; i++)
free(elemv[i]);
free(elemv);
}

View File

@ -23,7 +23,7 @@
l.origin = org; \ l.origin = org; \
_irc_line_append(&l, com); \ _irc_line_append(&l, com); \
irc_line_write(&l, con); \ irc_line_write(&l, con); \
free(l.elemv); \ _irc_line_deinit(&l); \
} while(0) } while(0)
#define WRITE_LINE1(con, org, com, a) \ #define WRITE_LINE1(con, org, com, a) \
@ -34,7 +34,7 @@
_irc_line_append(&l, com); \ _irc_line_append(&l, com); \
_irc_line_append(&l, a); \ _irc_line_append(&l, a); \
irc_line_write(&l, con); \ irc_line_write(&l, con); \
free(l.elemv); \ _irc_line_deinit(&l); \
} while(0) } while(0)
#define WRITE_LINE2(con, org, com, a1, a2) \ #define WRITE_LINE2(con, org, com, a1, a2) \
@ -46,7 +46,7 @@
_irc_line_append(&l, a1); \ _irc_line_append(&l, a1); \
_irc_line_append(&l, a2); \ _irc_line_append(&l, a2); \
irc_line_write(&l, con); \ irc_line_write(&l, con); \
free(l.elemv); \ _irc_line_deinit(&l); \
} while(0) } while(0)
#define WRITE_LINE3(con, org, com, a1, a2, a3) \ #define WRITE_LINE3(con, org, com, a1, a2, a3) \
@ -59,7 +59,7 @@
_irc_line_append(&l, a2); \ _irc_line_append(&l, a2); \
_irc_line_append(&l, a3); \ _irc_line_append(&l, a3); \
irc_line_write(&l, con); \ irc_line_write(&l, con); \
free(l.elemv); \ _irc_line_deinit(&l); \
} while(0) } while(0)
#define WRITE_LINE4(con, org, com, a1, a2, a3, a4) \ #define WRITE_LINE4(con, org, com, a1, a2, a3, a4) \
@ -73,7 +73,7 @@
_irc_line_append(&l, a3); \ _irc_line_append(&l, a3); \
_irc_line_append(&l, a4); \ _irc_line_append(&l, a4); \
irc_line_write(&l, con); \ irc_line_write(&l, con); \
free(l.elemv); \ _irc_line_deinit(&l); \
} while(0) } while(0)
struct line { struct line {
@ -84,11 +84,13 @@ struct line {
}; };
void irc_line_init(struct line *l); void irc_line_init(struct line *l);
void _irc_line_deinit(struct line *l);
struct line *irc_line_new(); struct line *irc_line_new();
void irc_line_write(struct line *l, connection_t *c); void irc_line_write(struct line *l, connection_t *c);
void irc_line_append(struct line *l, const char *s); void irc_line_append(struct line *l, const char *s);
struct line *irc_line(char *str); struct line *irc_line(char *str);
char *irc_line_to_string(struct line *l); char *irc_line_to_string(struct line *l);
char *irc_line_to_string_to(struct line *line, char *nick);
void irc_line_free(struct line *l); void irc_line_free(struct line *l);
struct line *irc_line_dup(struct line *line); struct line *irc_line_dup(struct line *line);
void _irc_line_append(struct line *l, const char *s); void _irc_line_append(struct line *l, const char *s);
@ -98,5 +100,8 @@ int irc_line_count(struct line *line);
char *irc_line_pop(struct line *l); char *irc_line_pop(struct line *l);
int irc_line_elem_equals(struct line *line, int elem, const char *cmp); 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); int irc_line_elem_case_equals(struct line *line, int elem, const char *cmp);
void irc_line_extract_args(struct line *line, int from,
char ***elemv, int *elemc);
void irc_line_free_args(char **elemv, int elemc);
#endif #endif

133
src/log.c
View File

@ -24,7 +24,6 @@ extern int conf_log;
extern FILE *conf_global_log_file; 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, const char *d, static int _log_write(log_t *logdata, logfilegroup_t *lf, const char *d,
const char *str); const char *str);
void logfile_free(logfile_t *lf); void logfile_free(logfile_t *lf);
@ -34,7 +33,6 @@ static char *_log_wrap(const char *dest, const char *line);
#define LAMESTRING "!bip@bip.bip.bip PRIVMSG " #define LAMESTRING "!bip@bip.bip.bip PRIVMSG "
#define PMSG_ARROW " \002->\002 " #define PMSG_ARROW " \002->\002 "
int check_dir(char *filename, int is_fatal) int check_dir(char *filename, int is_fatal)
{ {
int err; int err;
@ -119,13 +117,13 @@ void replace_var(char *str, char *var, char *value, unsigned int max)
char *pos; char *pos;
unsigned int lenvar = strlen(var); unsigned int lenvar = strlen(var);
unsigned int lenval = strlen(value); unsigned int lenval = strlen(value);
while((pos = strstr(str, var))) { while((pos = strstr(str, var))) {
/* Make room */ /* Make room */
if (strlen(str) + (lenval - lenvar) >= max) if (strlen(str) + lenval - lenvar >= max)
return; return;
memmove(pos + lenval, pos + lenvar, memmove(pos + lenval, pos + lenvar, strlen(pos + lenvar) + 1);
(strlen(pos + lenvar) + 1)*sizeof(char)); memcpy(pos, value, lenval);
memcpy(pos, value, lenval*sizeof(char));
} }
} }
@ -282,9 +280,6 @@ logfilegroup_t *log_find_file(log_t *logdata, const char *destination)
struct tm *ltime; struct tm *ltime;
struct link *l; struct link *l;
if (!ischannel(*destination))
destination = "privates";
lfg = hash_get(&logdata->logfgs, destination); lfg = hash_get(&logdata->logfgs, destination);
if (lfg && !conf_log) if (lfg && !conf_log)
@ -425,13 +420,13 @@ void log_nick(log_t *logdata, const char *ircmask, const char *channel,
log_write(logdata, channel, logdata->buffer); log_write(logdata, channel, logdata->buffer);
} }
static void _log_privmsg(log_t *logdata, const char *ircmask, int src, static void do_log_privmsg(log_t *logdata, const char *storage, int src,
const char *destination, const char *message) const char *from, const char *message)
{ {
char dir = '<'; char dir = '<';
if (!ircmask)
ircmask = "Server message";
if (!from)
from = "Server message";
if (src) if (src)
dir = '>'; dir = '>';
@ -450,40 +445,34 @@ static void _log_privmsg(log_t *logdata, const char *ircmask, int src,
return; return;
msg = bip_strdup(real_message); msg = bip_strdup(real_message);
*(msg + strlen(msg) - 1) = '\0'; *(msg + strlen(msg) - 1) = '\0';
if (ischannel(*destination) || strchr(destination, '@')) { snprintf(logdata->buffer, LOGLINE_MAXLEN,
snprintf(logdata->buffer, LOGLINE_MAXLEN,
"%s %c * %s %s", timestamp(), dir, "%s %c * %s %s", timestamp(), dir,
ircmask, msg + 8); from, msg + 8);
} else {
snprintf(logdata->buffer, LOGLINE_MAXLEN,
"%s (%s) %c * %s %s", timestamp(),
destination, dir, ircmask, msg + 8);
}
free(msg); free(msg);
} else { } else {
if (ischannel(*destination) || strchr(destination, '@')) { snprintf(logdata->buffer, LOGLINE_MAXLEN,
snprintf(logdata->buffer, LOGLINE_MAXLEN,
"%s %c %s: %s", timestamp(), dir, "%s %c %s: %s", timestamp(), dir,
ircmask, message); from, message);
} else {
snprintf(logdata->buffer, LOGLINE_MAXLEN,
"%s %c %s (%s): %s", timestamp(),
dir, ircmask, destination, message);
}
} }
log_write(logdata, destination, logdata->buffer); log_write(logdata, storage, logdata->buffer);
} }
void log_privmsg(log_t *logdata, const char *ircmask, const char *destination, void log_privmsg(log_t *logdata, const char *ircmask, const char *destination,
const char *message) const char *message)
{ {
_log_privmsg(logdata, ircmask, 0, destination, message); if (!ischannel(*destination)) {
char *nick = nick_from_ircmask(ircmask);
do_log_privmsg(logdata, nick, 0, ircmask, message);
free(nick);
} else {
do_log_privmsg(logdata, destination, 0, ircmask, message);
}
} }
void log_cli_privmsg(log_t *logdata, const char *ircmask, void log_cli_privmsg(log_t *logdata, const char *ircmask,
const char *destination, const char *message) const char *destination, const char *message)
{ {
_log_privmsg(logdata, ircmask, 1, destination, message); do_log_privmsg(logdata, destination, 1, ircmask, message);
} }
static void _log_notice(log_t *logdata, const char *ircmask, int src, static void _log_notice(log_t *logdata, const char *ircmask, int src,
@ -560,7 +549,7 @@ void log_init_topic_time(log_t *logdata, const char *channel, const char *who,
} }
void log_mode(log_t *logdata, const char *ircmask, const char *channel, void log_mode(log_t *logdata, const char *ircmask, const char *channel,
const char *modes, const const char **modargv, int modargc) const char *modes, char **modargv, int modargc)
{ {
int i; int i;
char *tmpbuf = bip_malloc(LOGLINE_MAXLEN + 1); char *tmpbuf = bip_malloc(LOGLINE_MAXLEN + 1);
@ -599,9 +588,14 @@ void log_disconnected(log_t *logdata)
void log_ping_timeout(log_t *logdata) void log_ping_timeout(log_t *logdata)
{ {
list_t *l = log_backlogs(logdata);
char *s;
snprintf(logdata->buffer, LOGLINE_MAXLEN, snprintf(logdata->buffer, LOGLINE_MAXLEN,
"%s -!- Ping timeout with server...", timestamp()); "%s -!- Ping timeout with server...", timestamp());
log_write(logdata, "privates", logdata->buffer); while ((s = list_remove_first(l)))
log_write(logdata, s, logdata->buffer);
list_free(l);
log_disconnected(logdata); log_disconnected(logdata);
} }
@ -697,7 +691,7 @@ void log_advance_backlogs(log_t* ld, logfilegroup_t *lfg)
} }
} }
int log_has_backlog(log_t *logdata, char *destination) int log_has_backlog(log_t *logdata, const char *destination)
{ {
logfilegroup_t *lfg = hash_get(&logdata->logfgs, destination); logfilegroup_t *lfg = hash_get(&logdata->logfgs, destination);
@ -824,7 +818,7 @@ char *log_beautify(log_t *logdata, const char *buf, const char *dest)
lod = strlen(dest); lod = strlen(dest);
} }
if (out && strcmp(dest, "privates") == 0) { if (out && !ischannel(*dest)) {
const char *stmp; const char *stmp;
size_t ltmp; size_t ltmp;
@ -889,7 +883,7 @@ char *log_beautify(log_t *logdata, const char *buf, const char *dest)
return ret; return ret;
} }
char *log_backread(log_t *logdata, char *destination, int *skip) char *log_backread(log_t *logdata, const char *destination, int *skip)
{ {
char *buf; char *buf;
size_t pos = 0; size_t pos = 0;
@ -1206,3 +1200,68 @@ void log_free(log_t *log)
free(log); free(log);
} }
list_t *log_backlogs(log_t *log)
{
return hash_keys(&log->logfgs);
}
list_t *backlog_lines_from_last_mark(log_t *log, const char *bl)
{
char *line;
int skip;
list_t *ret;
struct line l;
ret = list_new(NULL);
if (log_has_backlog(log, bl)) {
skip = 0;
while ((line = log_backread(log, bl, &skip))) {
if (!skip)
list_add_last(ret, line);
}
if (ischannel(*bl)) {
/* clean this up */
irc_line_init(&l);
l.origin = P_IRCMASK;
_irc_line_append(&l, "PRIVMSG");
_irc_line_append(&l, bl);
_irc_line_append(&l, "End of backlog");
list_add_last(ret, irc_line_to_string(&l));
_irc_line_deinit(&l);
}
}
return ret;
}
#if 0
for (hash_it_init(&LINK(ic)->l_server->channels, &hi);
hash_it_item(&hi); hash_it_next(&hi)) {
struct channel *chan = (struct channel *)hash_it_item(&hi);
if (log_has_backlog(LINK(ic)->log, chan->name)) {
char *line;
int skip = 0;
while ((line =
log_backread(LINK(ic)->log, chan->name, &skip))) {
if (!skip)
write_line(CONN(ic), line);
free(line);
}
WRITE_LINE2(CONN(ic), P_IRCMASK, "PRIVMSG", chan->name,
"End of backlog.");
} else {
mylog(LOG_DEBUG, "Nothing to backlog for %s/%s",
user->name, chan->name);
}
}
/* backlog privates */
char *str;
int skip = 0;
while ((str = log_backread(LINK(ic)->log, S_PRIVATES, &skip))) {
if (!skip)
write_line(CONN(ic), str);
free(str);
}
#endif

View File

@ -61,10 +61,8 @@ typedef struct log {
struct user *user; struct user *user;
} log_t; } log_t;
void log_close_all(log_t *logdata);
log_t *log_new(struct user *user, const char *network); log_t *log_new(struct user *user, const char *network);
void logdata_free(log_t *logdata); void logdata_free(log_t *logdata);
int log_compare_files(logfile_t *f1, char *f2);
void log_join(log_t *logdata, const char *ircmask, const char *channel); void log_join(log_t *logdata, const char *ircmask, const char *channel);
void log_part(log_t *logdata, const char *ircmask, const char *channel, void log_part(log_t *logdata, const char *ircmask, const char *channel,
@ -85,7 +83,7 @@ void log_cli_notice(log_t *logdata, const char *ircmask, const char *channel,
const char *message); const char *message);
void log_write(log_t *logdata, const char *str, const char *destination); void log_write(log_t *logdata, const char *str, const char *destination);
void log_mode(log_t *logdata, const char *ircmask, const char *channel, void log_mode(log_t *logdata, const char *ircmask, const char *channel,
const char *modes, const const char **modargv, int modargc); const char *modes, char **modargv, int modargc);
void log_topic(log_t *logdata, const char *ircmask, const char *channel, void log_topic(log_t *logdata, const char *ircmask, const char *channel,
const char *message); const char *message);
void log_init_topic(log_t *logdata, const char *channel, const char *message); void log_init_topic(log_t *logdata, const char *channel, const char *message);
@ -96,12 +94,15 @@ void log_disconnected(log_t *logdata);
void log_ping_timeout(log_t *logdata); void log_ping_timeout(log_t *logdata);
void log_client_disconnected(log_t *logdata); void log_client_disconnected(log_t *logdata);
void log_client_connected(log_t *logdata); void log_client_connected(log_t *logdata);
char *log_backread(log_t *logdata, char *destination, int *skip); char *log_backread(log_t *logdata, const char *destination, int *skip);
int log_has_backlog(log_t *logdata, char *destination); int log_has_backlog(log_t *logdata, const char *destination);
void log_flush_all(void); void log_flush_all(void);
void log_client_none_connected(log_t *logdata); void log_client_none_connected(log_t *logdata);
void log_reset(logfilegroup_t *); void log_reset(logfilegroup_t *);
int check_dir(char *filename, int is_fatal);
void log_reinit_all(log_t *logdata); void log_reinit_all(log_t *logdata);
void log_free(log_t *log); void log_free(log_t *log);
int check_dir(char *filename, int is_fatal);
list_t *log_backlogs(log_t *log);
list_t *backlog_lines_from_last_mark(log_t *log, const char *bl);
#endif #endif

View File

@ -444,10 +444,17 @@ void list_free(list_t *t)
void list_append(list_t *src, list_t *dest) void list_append(list_t *src, list_t *dest)
{ {
list_iterator_t it; if (dest->last == NULL)
return;
for (list_it_init(src, &it); list_it_item(&it); list_it_next(&it)) if (src->first == NULL) {
list_add_last(dest, list_it_item(&it)); src->first = dest->first;
src->last = dest->last;
return;
}
dest->first->prev = src->last;
src->last->next = dest->first;
src->last = dest->last;
free(dest);
} }
/* /*
@ -618,7 +625,7 @@ void *hash_it_item(hash_iterator_t *h)
return hi->item; return hi->item;
} }
char *hash_it_key(hash_iterator_t *h) const char *hash_it_key(hash_iterator_t *h)
{ {
struct hash_item *hi; struct hash_item *hi;
hi = list_it_item(&h->lit); hi = list_it_item(&h->lit);
@ -647,6 +654,19 @@ void hash_dump(hash_t *h)
printf("%s => %p\n", hash_it_key(&it), hash_it_item(&it)); printf("%s => %p\n", hash_it_key(&it), hash_it_item(&it));
} }
list_t *hash_keys(hash_t *hash)
{
hash_iterator_t hi;
list_t *ret;
ret = list_new(NULL);
for (hash_it_init(hash, &hi); hash_it_item(&hi); hash_it_next(&hi))
list_add_last(ret, bip_strdup(hash_it_key(&hi)));
return ret;
}
char *bip_strmaydup(char *s) char *bip_strmaydup(char *s)
{ {
if (!s) if (!s)

View File

@ -94,6 +94,7 @@ void *list_it_item(list_iterator_t *ti);
void *list_it_remove(list_iterator_t *li); void *list_it_remove(list_iterator_t *li);
void list_free(list_t *t); void list_free(list_t *t);
void list_copy(list_t *src, list_t *dest); void list_copy(list_t *src, list_t *dest);
/* dest must not be refed after wards */
void list_append(list_t *src, list_t *dest); void list_append(list_t *src, list_t *dest);
int list_is_empty(list_t *l); int list_is_empty(list_t *l);
@ -109,8 +110,9 @@ int hash_is_empty(hash_t *h);
void hash_it_init(hash_t *hash, hash_iterator_t *i); void hash_it_init(hash_t *hash, hash_iterator_t *i);
void hash_it_next(hash_iterator_t *hi); void hash_it_next(hash_iterator_t *hi);
void *hash_it_item(hash_iterator_t *h); void *hash_it_item(hash_iterator_t *h);
char *hash_it_key(hash_iterator_t *h); const char *hash_it_key(hash_iterator_t *h);
void *hash_it_remove(hash_iterator_t *li); void *hash_it_remove(hash_iterator_t *li);
list_t *hash_keys(hash_t *hash);
int is_valid_nick(char *str); int is_valid_nick(char *str);
int is_valid_username(char *str); int is_valid_username(char *str);