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");
}
#if 0
TODO
} 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");
}
TODO network info
#endif
} else {
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;
}
adm_follow_nick(ic, irc_line_elem(line, privmsg + 2));
} else if (strcasecmp(line->elemv[privmsg + 1],
"IGNORE_FIRST_NICK") == 0) {
} else if (irc_line_elem_case_equals(line, privmsg + 1,
"IGNORE_FIRST_NICK")) {
if (irc_line_count(line) != privmsg + 3) {
bip_notify(ic, "-- IGNORE_FIRST_NICK "
"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)
{
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 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);
list_t *read_lines(connection_t *cn, int *error);
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);
void irc_server_shutdown(struct link_server *s);
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
#define OIDENTD_FILENAME ".oidentd.conf"
@ -81,9 +82,9 @@ struct channel *channel_new(const char *name)
return chan;
}
char *nick_from_ircmask(char *mask)
char *nick_from_ircmask(const char *mask)
{
char *nick = mask;
const char *nick = mask;
char *ret;
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)
{
int i;
LINK(server)->s_state = IRCS_CONNECTED;
LINK(server)->s_conn_attempt = 0;
mylog(LOG_INFO, "Connected user %s to %s", LINK(server)->user->name,
LINK(server)->name);
mylog(LOG_INFO, "Connected to server %s for user %s",
LINK(server)->name, LINK(server)->user->name);
irc_server_join(server);
log_connected(LINK(server)->log);
@ -238,15 +240,16 @@ static void irc_server_connected(struct link_server *server)
free(LINK(server)->cli_nick);
LINK(server)->cli_nick = NULL;
}
/* basic helper for nickserv and co */
list_iterator_t itocs;
for (list_it_init(&LINK(server)->on_connect_send, &itocs);
list_it_item(&itocs); list_it_next(&itocs)) {
ssize_t len = strlen(list_it_item(&itocs)) + 2;
char *str = bip_malloc(len + 1);
sprintf(str, "%s\r\n", (char *)list_it_item(&itocs));
write_line(CONN(server), str);
free(str);
ssize_t len = strlen(list_it_item(&itocs)) + 2;
char *str = bip_malloc(len + 1);
sprintf(str, "%s\r\n", (char *)list_it_item(&itocs));
write_line(CONN(server), str);
free(str);
}
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
* about this damn ircmask...
: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)
{
(void)server;
if (!irc_line_include(line, 7))
if (!irc_line_include(line, 6))
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)) {
struct channel *channel;
struct nick *nick;
@ -283,6 +306,7 @@ static int irc_352(struct link_server *server, struct line *line)
return OK_COPY_WHO;
}
#endif
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) {
size_t nicklen = strlen(server->nick);
char *newnick = bip_malloc(nicklen + 2);
strcpy(newnick, server->nick);
if (strlen(server->nick) < 9) {
strcat(newnick, "`");
} else if (newnick[7] != '`') {
if (newnick[8] != '`') {
newnick[8] = '`';
newnick[9] = 0;
} else {
newnick[7] = '`';
newnick[9] = 0;
}
} else {
newnick[8] = rand() * ('z' - 'a') / RAND_MAX +
'a';
if (newnick[7] != '`') {
if (newnick[8] != '`') {
newnick[8] = '`';
} else {
newnick[7] = '`';
}
} else {
newnick[8] = rand() *
('z' - 'a') / RAND_MAX + 'a';
}
newnick[9] = 0;
}
free(server->nick);
server->nick = newnick;
ls_set_nick(server, newnick);
WRITE_LINE1(CONN(server), NULL, "NICK", server->nick);
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 */
static void irc_send_join(struct link_client *ic, struct channel *chan)
{
char *ircmask; /* fake an irc mask for rbot */
struct user *user;
char *ircmask;
user = LINK(ic)->user;
if (!user)
fatal("irc_send_join: No user associated");
/* user ircmask here for rbot */
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);
strcat(ircmask, "!bip@bip.bip.bip");
strcat(ircmask, BIP_FAKEMASK);
WRITE_LINE1(CONN(ic), ircmask, "JOIN", chan->name);
free(ircmask);
if (chan->topic)
WRITE_LINE3(CONN(ic), P_SERV, "332", LINK(ic)->l_server->nick,
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,
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)
{
char *tmp;
char *l;
tmp = (char *)irc_line_elem(line, 1);
line->elemv[1] = nick;
l = irc_line_to_string(line);
l = irc_line_to_string_to(line, nick);
write_line(c, l);
free(l);
line->elemv[1] = tmp;
}
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))
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,
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_backlog(ic);
log_client_connected(LINK(ic)->log);
free(init_nick);
@ -1559,17 +1580,20 @@ static int irc_mode(struct link_server *server, struct line *line)
int add = 1;
unsigned cur_arg = 0;
struct nick *nick;
char **elemv;
int elemc;
if (!irc_line_include(line, 2))
return ERR_PROTOCOL;
/* nick mode change */
if (irc_line_elem_equals(line, 1, server->nick)) {
irc_line_extract_args(line, 3, &elemv, &elemc);
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_line_elem(line, 2), elemv, elemc);
irc_line_free_args(elemv, elemc);
irc_user_mode(server, line);
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 */
if (!channel)
return ERR_PROTOCOL;
irc_line_extract_args(line, 3, &elemv, &elemc);
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_line_elem(line, 2), elemv, elemc);
irc_line_free_args(elemv, elemc);
/*
* 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)
{
if (LINK(server)->s_state == IRCS_CONNECTED)
log_privmsg(LINK(server)->log, line->origin, irc_line_elem(line, 1),
irc_line_elem(line, 2));
if (!irc_line_include(line, 2))
return ERR_PROTOCOL;
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);
return OK_COPY;
}
@ -1874,6 +1902,33 @@ static int irc_generic_quit(struct link_server *server, struct line *line)
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)
{
char *nick;
@ -1906,7 +1961,7 @@ static void irc_server_startup(struct link_server *ircs)
nick = bip_strdup(LINK(ircs)->connect_nick);
}
ircs->nick = nick;
ls_set_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);
hash_it_next(&hi))
channel_free(hash_it_item(&hi));
hash_init(&server->channels, HASH_NOCASE);
hash_clean(&server->channels);
if (CONN(server)) {
connection_free(CONN(server));

View File

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

View File

@ -19,6 +19,11 @@ void irc_line_init(struct line *l)
memset(l, 0, sizeof(struct line));
}
void _irc_line_deinit(struct line *l)
{
free(l->elemv);
}
struct line *irc_line_new()
{
struct line *l;
@ -103,6 +108,19 @@ char *irc_line_to_string(struct line *l)
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)
{
return line->elemc;
@ -205,3 +223,30 @@ void irc_line_free(struct line *l)
free(l->origin);
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; \
_irc_line_append(&l, com); \
irc_line_write(&l, con); \
free(l.elemv); \
_irc_line_deinit(&l); \
} while(0)
#define WRITE_LINE1(con, org, com, a) \
@ -34,7 +34,7 @@
_irc_line_append(&l, com); \
_irc_line_append(&l, a); \
irc_line_write(&l, con); \
free(l.elemv); \
_irc_line_deinit(&l); \
} while(0)
#define WRITE_LINE2(con, org, com, a1, a2) \
@ -46,7 +46,7 @@
_irc_line_append(&l, a1); \
_irc_line_append(&l, a2); \
irc_line_write(&l, con); \
free(l.elemv); \
_irc_line_deinit(&l); \
} while(0)
#define WRITE_LINE3(con, org, com, a1, a2, a3) \
@ -59,7 +59,7 @@
_irc_line_append(&l, a2); \
_irc_line_append(&l, a3); \
irc_line_write(&l, con); \
free(l.elemv); \
_irc_line_deinit(&l); \
} while(0)
#define WRITE_LINE4(con, org, com, a1, a2, a3, a4) \
@ -73,7 +73,7 @@
_irc_line_append(&l, a3); \
_irc_line_append(&l, a4); \
irc_line_write(&l, con); \
free(l.elemv); \
_irc_line_deinit(&l); \
} while(0)
struct line {
@ -84,11 +84,13 @@ struct line {
};
void irc_line_init(struct line *l);
void _irc_line_deinit(struct line *l);
struct line *irc_line_new();
void irc_line_write(struct line *l, connection_t *c);
void irc_line_append(struct line *l, const char *s);
struct line *irc_line(char *str);
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);
struct line *irc_line_dup(struct line *line);
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);
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);
void irc_line_extract_args(struct line *line, int from,
char ***elemv, int *elemc);
void irc_line_free_args(char **elemv, int elemc);
#endif

133
src/log.c
View File

@ -24,7 +24,6 @@ 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, const char *d,
const char *str);
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 PMSG_ARROW " \002->\002 "
int check_dir(char *filename, int is_fatal)
{
int err;
@ -119,13 +117,13 @@ void replace_var(char *str, char *var, char *value, unsigned int max)
char *pos;
unsigned int lenvar = strlen(var);
unsigned int lenval = strlen(value);
while((pos = strstr(str, var))) {
/* Make room */
if (strlen(str) + (lenval - lenvar) >= max)
if (strlen(str) + lenval - lenvar >= max)
return;
memmove(pos + lenval, pos + lenvar,
(strlen(pos + lenvar) + 1)*sizeof(char));
memcpy(pos, value, lenval*sizeof(char));
memmove(pos + lenval, pos + lenvar, strlen(pos + lenvar) + 1);
memcpy(pos, value, lenval);
}
}
@ -282,9 +280,6 @@ logfilegroup_t *log_find_file(log_t *logdata, const char *destination)
struct tm *ltime;
struct link *l;
if (!ischannel(*destination))
destination = "privates";
lfg = hash_get(&logdata->logfgs, destination);
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);
}
static void _log_privmsg(log_t *logdata, const char *ircmask, int src,
const char *destination, const char *message)
static void do_log_privmsg(log_t *logdata, const char *storage, int src,
const char *from, const char *message)
{
char dir = '<';
if (!ircmask)
ircmask = "Server message";
if (!from)
from = "Server message";
if (src)
dir = '>';
@ -450,40 +445,34 @@ static void _log_privmsg(log_t *logdata, const char *ircmask, int src,
return;
msg = bip_strdup(real_message);
*(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,
ircmask, msg + 8);
} else {
snprintf(logdata->buffer, LOGLINE_MAXLEN,
"%s (%s) %c * %s %s", timestamp(),
destination, dir, ircmask, msg + 8);
}
from, msg + 8);
free(msg);
} else {
if (ischannel(*destination) || strchr(destination, '@')) {
snprintf(logdata->buffer, LOGLINE_MAXLEN,
snprintf(logdata->buffer, LOGLINE_MAXLEN,
"%s %c %s: %s", timestamp(), dir,
ircmask, message);
} else {
snprintf(logdata->buffer, LOGLINE_MAXLEN,
"%s %c %s (%s): %s", timestamp(),
dir, ircmask, destination, message);
}
from, 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,
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,
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,
@ -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,
const char *modes, const const char **modargv, int modargc)
const char *modes, char **modargv, int modargc)
{
int i;
char *tmpbuf = bip_malloc(LOGLINE_MAXLEN + 1);
@ -599,9 +588,14 @@ void log_disconnected(log_t *logdata)
void log_ping_timeout(log_t *logdata)
{
list_t *l = log_backlogs(logdata);
char *s;
snprintf(logdata->buffer, LOGLINE_MAXLEN,
"%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);
}
@ -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);
@ -824,7 +818,7 @@ char *log_beautify(log_t *logdata, const char *buf, const char *dest)
lod = strlen(dest);
}
if (out && strcmp(dest, "privates") == 0) {
if (out && !ischannel(*dest)) {
const char *stmp;
size_t ltmp;
@ -889,7 +883,7 @@ char *log_beautify(log_t *logdata, const char *buf, const char *dest)
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;
size_t pos = 0;
@ -1206,3 +1200,68 @@ void log_free(log_t *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;
} log_t;
void log_close_all(log_t *logdata);
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, 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);
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);
const char *modes, 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);
@ -96,12 +94,15 @@ void log_disconnected(log_t *logdata);
void log_ping_timeout(log_t *logdata);
void log_client_disconnected(log_t *logdata);
void log_client_connected(log_t *logdata);
char *log_backread(log_t *logdata, char *destination, int *skip);
int log_has_backlog(log_t *logdata, char *destination);
char *log_backread(log_t *logdata, const char *destination, int *skip);
int log_has_backlog(log_t *logdata, const char *destination);
void log_flush_all(void);
void log_client_none_connected(log_t *logdata);
void log_reset(logfilegroup_t *);
int check_dir(char *filename, int is_fatal);
void log_reinit_all(log_t *logdata);
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

View File

@ -444,10 +444,17 @@ void list_free(list_t *t)
void list_append(list_t *src, list_t *dest)
{
list_iterator_t it;
for (list_it_init(src, &it); list_it_item(&it); list_it_next(&it))
list_add_last(dest, list_it_item(&it));
if (dest->last == NULL)
return;
if (src->first == NULL) {
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;
}
char *hash_it_key(hash_iterator_t *h)
const char *hash_it_key(hash_iterator_t *h)
{
struct hash_item *hi;
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));
}
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)
{
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_free(list_t *t);
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);
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_next(hash_iterator_t *hi);
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);
list_t *hash_keys(hash_t *hash);
int is_valid_nick(char *str);
int is_valid_username(char *str);