1
0
forked from bip/bip

[FEATURE] /quote bip backlog [n]

/quote bip backlog triggers a log replay.
With the optional argument n in hours, you can request a backlog of a
few hours.
This commit is contained in:
Arnaud Cornet 2009-01-17 14:16:31 +01:00
parent 26eb9c28d7
commit fe251f72b5
5 changed files with 87 additions and 43 deletions

View File

@ -1988,6 +1988,8 @@ void adm_bip_help(struct link_client *ic, int admin, const char *subhelp)
bip_notify(ic, "/BIP ON_CONNECT_SEND # Clears on_connect_send"); bip_notify(ic, "/BIP ON_CONNECT_SEND # Clears on_connect_send");
bip_notify(ic, "/BIP AWAY_NICK <nick> # Set away nick"); bip_notify(ic, "/BIP AWAY_NICK <nick> # Set away nick");
bip_notify(ic, "/BIP AWAY_NICK # clear away nick"); bip_notify(ic, "/BIP AWAY_NICK # clear away nick");
bip_notify(ic, "/BIP BACKLOG [n] # backlog text of the n last "
"hours");
} else if (admin && strcasecmp(subhelp, "RELOAD") == 0) { } else if (admin && strcasecmp(subhelp, "RELOAD") == 0) {
bip_notify(ic, "/BIP RELOAD (admin only) :"); bip_notify(ic, "/BIP RELOAD (admin only) :");
bip_notify(ic, " Reloads bip configuration file and apply " bip_notify(ic, " Reloads bip configuration file and apply "
@ -2237,6 +2239,15 @@ int adm_bip(bip_t *bip, struct link_client *ic, struct line *line, int privmsg)
bip_notify(ic, "-- AWAY_NICK command needs zero or one" bip_notify(ic, "-- AWAY_NICK command needs zero or one"
" argument"); " argument");
} }
} else if (irc_line_elem_case_equals(line, privmsg + 1, "BACKLOG")) {
if (irc_line_count(line) == privmsg + 2) {
irc_cli_backlog(ic, 0);
} else if (irc_line_count(line) == privmsg + 3) {
int hours = atoi(irc_line_elem(line, privmsg + 2));
irc_cli_backlog(ic, hours);
} else {
bip_notify(ic, "-- BACKLOG takes 0 or one argument");
}
} else if (admin && irc_line_elem_case_equals(line, privmsg + 1, } else if (admin && irc_line_elem_case_equals(line, privmsg + 1,
"ADD_CONN")) { "ADD_CONN")) {
if (irc_line_count(line) != privmsg + 4) { if (irc_line_count(line) != privmsg + 4) {

View File

@ -650,7 +650,7 @@ static void irc_cli_make_join(struct link_client *ic)
} }
} }
static void irc_cli_backlog(struct link_client *ic) void irc_cli_backlog(struct link_client *ic, int hours)
{ {
struct user *user; struct user *user;
@ -664,17 +664,25 @@ static void irc_cli_backlog(struct link_client *ic)
return; return;
} }
if (hours != 0) {
/* have some limit */
if (hours > 24 * 366)
hours = 24 * 366;
}
list_t *backlogl; list_t *backlogl;
char *bl; char *bl;
list_t *bllines;
backlogl = log_backlogs(LINK(ic)->log); backlogl = log_backlogs(LINK(ic)->log);
while ((bl = list_remove_first(backlogl))) { while ((bl = list_remove_first(backlogl))) {
list_t *bllines; bllines = backlog_lines(LINK(ic)->log, bl,
bllines = backlog_lines_from_last_mark(LINK(ic)->log, bl, LINK(ic)->l_server->nick, hours);
LINK(ic)->l_server->nick); if (bllines) {
mylog(LOG_INFO, "backlogging: %s", bl); mylog(LOG_INFO, "backlogging: %s", bl);
write_lines(CONN(ic), bllines); write_lines(CONN(ic), bllines);
list_free(bllines); list_free(bllines);
}
free(bl); free(bl);
} }
list_free(backlogl); list_free(backlogl);
@ -787,7 +795,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); irc_cli_backlog(ic, 0);
log_client_connected(LINK(ic)->log); log_client_connected(LINK(ic)->log);
free(init_nick); free(init_nick);

View File

@ -263,6 +263,7 @@ 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); char *nick_from_ircmask(const char *mask);
void irc_cli_backlog(struct link_client *ic, int hours);
#define BIP_FAKEMASK "!bip@bip.bip.bip" #define BIP_FAKEMASK "!bip@bip.bip.bip"
#endif #endif

View File

@ -16,6 +16,7 @@
#include "irc.h" #include "irc.h"
#include "util.h" #include "util.h"
#include <sys/time.h> #include <sys/time.h>
#include <stdio.h>
extern int errno; extern int errno;
extern int log_level; extern int log_level;
@ -292,7 +293,6 @@ static int log_add_file(log_t *logdata, const char *destination,
store->name = bip_strdup(destination); store->name = bip_strdup(destination);
store->skip_advance = 0; store->skip_advance = 0;
hash_insert(&logdata->logfgs, destination, store); hash_insert(&logdata->logfgs, destination, store);
list_it_init(&store->file_group, &store->file_it);
} }
if (!conf_log && logdata->user->backlog) { if (!conf_log && logdata->user->backlog) {
@ -302,6 +302,8 @@ static int log_add_file(log_t *logdata, const char *destination,
if (lf) { if (lf) {
list_add_last(&store->file_group, lf); list_add_last(&store->file_group, lf);
if (list_it_item(&store->file_it) == NULL)
list_it_init_last(&store->file_group, &store->file_it);
store->file_offset = lf->len; store->file_offset = lf->len;
} }
return 1; return 1;
@ -912,8 +914,20 @@ char *log_beautify(log_t *logdata, const char *buf, const char *storename,
return ret; return ret;
} }
static time_t compute_time(const char *buf)
{
struct tm tm;
int err;
err = sscanf(buf, "%2d-%2d-%4d %2d:%2d:%2d", &tm.tm_mday, &tm.tm_mon,
&tm.tm_year, &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
if (err != 6)
return (time_t)-1;
tm.tm_year -= 1900;
return mktime(&tm);
}
static int log_backread_file(log_t *log, logstore_t *store, logfile_t *lf, static int log_backread_file(log_t *log, logstore_t *store, logfile_t *lf,
list_t *res, const char *dest) list_t *res, const char *dest, time_t start)
{ {
char *buf, *logbr; char *buf, *logbr;
int close = 0; int close = 0;
@ -931,7 +945,7 @@ static int log_backread_file(log_t *log, logstore_t *store, logfile_t *lf,
close = 1; close = 1;
} }
if (list_get_first(&store->file_group) == lf) { if (!start && list_it_item(&store->file_it) == lf) {
mylog(LOG_DEBUG, "Seeking %s to %d", lf->filename, mylog(LOG_DEBUG, "Seeking %s to %d", lf->filename,
store->file_offset); store->file_offset);
if (fseek(lf->file, store->file_offset, SEEK_SET)) { if (fseek(lf->file, store->file_offset, SEEK_SET)) {
@ -968,6 +982,15 @@ static int log_backread_file(log_t *log, logstore_t *store, logfile_t *lf,
if (buf[0] == 0 || buf[0] == '\n') if (buf[0] == 0 || buf[0] == '\n')
continue; continue;
if (start != 0) {
time_t linetime = compute_time(buf);
/* parse error, don't backlog */
if (linetime == (time_t)-1)
continue;
/* too old line, don't backlog */
if (linetime < start)
continue;
}
logbr = log_beautify(log, buf, store->name, dest); logbr = log_beautify(log, buf, store->name, dest);
if (logbr) if (logbr)
list_add_last(res, logbr); list_add_last(res, logbr);
@ -1010,14 +1033,15 @@ static list_t *log_backread(log_t *log, const char *storename, const char *dest)
return NULL; return NULL;
} }
list_iterator_t file_it; list_iterator_t file_it = store->file_it;
logfile_t *logf; logfile_t *logf;
ret = list_new(NULL); ret = list_new(NULL);
for (list_it_init(&store->file_group, &file_it); for (file_it = store->file_it;
(logf = list_it_item(&file_it)); (logf = list_it_item(&file_it));
list_it_next(&file_it)) { list_it_next(&file_it)) {
if (!log_backread_file(log, store, logf, ret, dest)) { if (!log_backread_file(log, store, logf, ret, dest,
(time_t)0)) {
log_reinit(store); log_reinit(store);
return ret; return ret;
} }
@ -1213,29 +1237,26 @@ int log_parse_date(char *strdate, int *year, int *month, int *mday, int *hour,
return ret; return ret;
} }
logfile_t *logstore_get_file_at(logstore_t *store, time_t at) void logstore_get_file_at(logstore_t *store, time_t at, list_iterator_t *li)
{ {
list_iterator_t li; for (list_it_init(&store->file_group, li); list_it_item(li);
list_it_next(li)) {
for (list_it_init(&store->file_group, &li); list_it_item(&li); logfile_t *lf = list_it_item(li);
list_it_next(&li)) {
logfile_t *lf = list_it_item(&li);
if (mktime(&lf->last_log) > at) if (mktime(&lf->last_log) > at)
return lf; return;
} }
return NULL;
} }
#if 0 static list_t *log_backread_hours(log_t *log, const char *storename,
list_t *backlog_hours(log_t *log, const char *storename, int hours) const char *dest, int hours)
{ {
time_t blstarttime, linetime; time_t blstarttime;
struct timeval tv; struct timeval tv;
struct tm tm;
logstore_t *store; logstore_t *store;
logfile_t *lf; logfile_t *logf;
const char *line; list_t *ret;
list_iterator_t file_it;
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
if (tv.tv_sec <= 3600 * 24 * hours) if (tv.tv_sec <= 3600 * 24 * hours)
@ -1243,36 +1264,38 @@ list_t *backlog_hours(log_t *log, const char *storename, int hours)
blstarttime = tv.tv_sec - 3600 * 24 * hours; blstarttime = tv.tv_sec - 3600 * 24 * hours;
store = hash_get(&log->logfgs, storename); store = hash_get(&log->logfgs, storename);
lf = logstore_get_file_at(store, blstarttime);
foreach_logline(lf, line) { ret = list_new(NULL);
log_parse_date(line, &tm.tm_year, &tm.tm_mon, &tm.tm_mday, for (logstore_get_file_at(store, blstarttime, &file_it);
&tm.tm_hour, &tm.tm_min, &tm.tm_sec); (logf = list_it_item(&file_it));
tm.tm_year -= 1900; list_it_next(&file_it)) {
tm.tm_isdst = -1; if (!log_backread_file(log, store, logf, ret, dest,
blstarttime)) {
linetime = mktime(&tm); log_reinit(store);
if (linetime > blstarttime) { return ret;
} }
} }
return ret;
} }
#endif
list_t *backlog_lines_from_last_mark(log_t *log, const char *bl, list_t *backlog_lines(log_t *log, const char *bl, const char *cli_nick,
const char *cli_nick) int hours)
{ {
list_t *ret; list_t *ret;
struct line l; struct line l;
const char *dest; const char *dest;
ret = list_new(NULL); ret = NULL;
if (ischannel(*bl)) if (ischannel(*bl))
dest = bl; dest = bl;
else else
dest = cli_nick; dest = cli_nick;
if (log_has_backlog(log, bl)) { if (log_has_backlog(log, bl)) {
ret = log_backread(log, bl, dest); if (hours == 0)
ret = log_backread(log, bl, dest);
else
ret = log_backread_hours(log, bl, dest, hours);
/* /*
* This exception is cosmetic, but you want it. * This exception is cosmetic, but you want it.
* Most of the time, you get backlog from your own nick for * Most of the time, you get backlog from your own nick for

View File

@ -103,5 +103,6 @@ int check_dir(char *filename, int is_fatal);
void log_reset_store(log_t *log, const char *storename); void log_reset_store(log_t *log, const char *storename);
list_t *log_backlogs(log_t *log); list_t *log_backlogs(log_t *log);
list_t *backlog_lines_from_last_mark(log_t *log, const char *bl, const char *); list_t *backlog_lines(log_t *log, const char *bl, const char *cli_nick,
int hours);
#endif #endif