[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:
parent
26eb9c28d7
commit
fe251f72b5
11
src/bip.c
11
src/bip.c
@ -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) {
|
||||||
|
24
src/irc.c
24
src/irc.c
@ -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);
|
||||||
|
@ -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
|
||||||
|
91
src/log.c
91
src/log.c
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user