Lots of structural changes.

Move backlog options to user statment.
Drop ircise, to go towards real SIGHUP support.
This commit is contained in:
Arnaud Cornet 2007-09-02 14:59:19 +02:00
parent 7c4667bf1d
commit 909fe5e1c1
11 changed files with 387 additions and 462 deletions

3
NEWS
View File

@ -0,0 +1,3 @@
02-09-2007: as of now log parameters go in the user {} statment. This brakes
every config and there is no backwrads compatibility as of now.
Lots of internal changes, expect crashes.

94
configure vendored
View File

@ -652,11 +652,11 @@ AMDEPBACKSLASH
CCDEPMODE
am__fastdepCC_TRUE
am__fastdepCC_FALSE
YACC
YFLAGS
LEX
LEX_OUTPUT_ROOT
LEXLIB
YACC
YFLAGS
DEBUG_TRUE
DEBUG_FALSE
OIDENTD_TRUE
@ -3343,49 +3343,6 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
for ac_prog in 'bison -y' byacc
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
{ echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
if test "${ac_cv_prog_YACC+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$YACC"; then
ac_cv_prog_YACC="$YACC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
ac_cv_prog_YACC="$ac_prog"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
fi
fi
YACC=$ac_cv_prog_YACC
if test -n "$YACC"; then
{ echo "$as_me:$LINENO: result: $YACC" >&5
echo "${ECHO_T}$YACC" >&6; }
else
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
test -n "$YACC" && break
done
test -n "$YACC" || YACC="yacc"
for ac_prog in flex lex
do
@ -3594,6 +3551,49 @@ fi
if test "$LEX" = :; then
LEX=${am_missing_run}flex
fi
for ac_prog in 'bison -y' byacc
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
{ echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
if test "${ac_cv_prog_YACC+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$YACC"; then
ac_cv_prog_YACC="$YACC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
ac_cv_prog_YACC="$ac_prog"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
fi
fi
YACC=$ac_cv_prog_YACC
if test -n "$YACC"; then
{ echo "$as_me:$LINENO: result: $YACC" >&5
echo "${ECHO_T}$YACC" >&6; }
else
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
test -n "$YACC" && break
done
test -n "$YACC" || YACC="yacc"
CFLAGS="-O2 -W -Wall"
@ -4528,11 +4528,11 @@ AMDEPBACKSLASH!$AMDEPBACKSLASH$ac_delim
CCDEPMODE!$CCDEPMODE$ac_delim
am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim
am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim
YACC!$YACC$ac_delim
YFLAGS!$YFLAGS$ac_delim
LEX!$LEX$ac_delim
LEX_OUTPUT_ROOT!$LEX_OUTPUT_ROOT$ac_delim
LEXLIB!$LEXLIB$ac_delim
YACC!$YACC$ac_delim
YFLAGS!$YFLAGS$ac_delim
DEBUG_TRUE!$DEBUG_TRUE$ac_delim
DEBUG_FALSE!$DEBUG_FALSE$ac_delim
OIDENTD_TRUE!$OIDENTD_TRUE$ac_delim

View File

@ -3,8 +3,8 @@ AM_CONFIG_HEADER(src/config.h)
AM_INIT_AUTOMAKE(bip,0.6.0)
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_YACC
AM_PROG_LEX
AC_PROG_YACC
CFLAGS="-O2 -W -Wall"

View File

@ -38,23 +38,6 @@ log_level = 3;
# Sets the frequency (in seconds) of log syncing (real write to kernel)
#log_sync_interval = 5;
# Makes bip send the log of each channel and privates while
# you were not connected to the proxy upon connection.
#backlog = true; # enable backlog
backlog_lines = 10; # number of lines in backlog, 0 means no limit
backlog_always = true; # backlog even lines already backlogged
#backlog_no_timestamp = false; # Disables time stamps if you find them ugly.
# If blreset_on_talk talking on an irc network has the same effect of issuing
# /bip blreset, meaning that stuffed logged before the command won't be read
# back on backlog
#blreset_on_talk = false;
# If bl_msg_only is true, only channel and private messages will be backlogged
# upon the reconnection of a client. Default is false, thus joins, parts, quits,
# nick changes, topic changes, ... are backlogged
#backlog_msg_only = false;
# Network definition, a name and server info
network {
name = "iiens";
@ -90,7 +73,8 @@ user {
# The name in bip of the user
# This is used by bip only
name = "bip4ever";
# this user's password (md5(md5("tata"))) with seed - generated by bipmkpw
# this user's password (md5(md5("tata"))) with seed - generated by
# bipmkpw
password = "3880f2b39b3b9cb507b052b695d2680859bfc327";
# SSL certificates checking mode for user:
@ -118,6 +102,26 @@ user {
default_user = "bip4ever";
default_realname = "bip4ever";
# Makes bip send the log of each channel and privates while
# you were not connected to the proxy upon connection.
#backlog = true; # enable backlog
backlog_lines = 10; # number of lines in backlog, 0 means
# no limit
backlog_always = true; # backlog even lines already backlogged
#backlog_no_timestamp = false; # Disables time stamps if you find them
# ugly.
# If blreset_on_talk talking on an irc network has the same effect of
# issuing /bip blreset, meaning that stuffed logged before the command
# won't be read back on backlog
#blreset_on_talk = false;
# If bl_msg_only is true, only channel and private messages will be
# backlogged upon the reconnection of a client. Default is false, thus
# joins, parts, quits, nick changes, topic changes, ... are backlogged
#backlog_msg_only = false;
# A user can have mutiple connections to irc networks.
# define a connection:
connection {

430
src/bip.c
View File

@ -25,12 +25,27 @@
#include "bip.h"
#include "line.h"
#define MOVE_STRING(dest, src) do {\
if (dest)\
free(dest);\
(dest) = (src);\
(src) = NULL;\
} while(0)
#define FREE(a) free(a); (a) = NULL;
#define MAYFREE(a) do { \
if (a) { \
free(a); \
(a) = NULL; \
} \
} while(0);
int sighup = 0;
char *conf_log_root;
char *conf_log_format;
int conf_log_level;
char *conf_ip;
unsigned short conf_port;
int conf_css;
@ -39,10 +54,7 @@ char *conf_ssl_certfile;
#endif
int conf_daemonize;
char *conf_pid_file;
hash_t conf_networks;
hash_t conf_users;
char *conf_biphome;
hash_t adm_users;
/* log options, for sure the trickiest :) */
/* no backlog at all */
@ -50,20 +62,14 @@ int conf_backlog = 0;
extern int conf_memlog;
int conf_log = 0;
int conf_log_system = 0;
/* number of lines in backlog */
int conf_backlog_lines = 10;
int conf_backlog_no_timestamp = 0;
/* backlog even lines already backlogged */
int conf_always_backlog = 0;
int conf_log_sync_interval = 0;
int conf_blreset_on_talk = 0;
int conf_bl_msg_only = 0;
list_t *parse_conf(FILE *file);
static void conf_die(char *fmt, ...);
#ifdef HAVE_LIBSSL
int adm_trust(struct link_client *ic, struct line *line);
#endif
static char *get_tuple_value(list_t *tuple_l, int lex);
static void hash_binary(char *hex, unsigned char **password, unsigned int *seed)
{
@ -93,18 +99,10 @@ static void hash_binary(char *hex, unsigned char **password, unsigned int *seed)
*password = md5;
}
void server_free(struct server *s)
{
free(s->host);
free(s);
}
static int add_server(list_t *serverl, list_t *data)
static int add_server(struct server *s, list_t *data)
{
struct tuple *t;
struct server *s;
s = calloc(sizeof(struct server), 1);
s->port = 6667; /* default port */
while ((t = list_remove_first(data))) {
@ -124,7 +122,6 @@ static int add_server(list_t *serverl, list_t *data)
conf_die("Server conf: host not set");
return 0;
}
list_add_last(serverl, s);
return 1;
}
@ -304,29 +301,34 @@ void bad_quit(int i)
exit(i);
}
void c_network_free(struct c_network *on)
{
struct server *s;
free(on->name);
s = list_remove_first(&on->serverl);
free(s->host);
free(on);
}
static int add_network(list_t *data)
static int add_network(bip_t *bip, list_t *data)
{
struct tuple *t;
struct c_network *n;
struct c_network *old_n;
int r;
struct network *n;
int i;
n = calloc(sizeof(struct c_network), 1);
list_init(&n->serverl, NULL);
char *name = get_tuple_value(data, LEX_NAME);
if (name == NULL) {
conf_die("Network with no name");
return 0;
}
n = hash_get(&bip->networks, name);
if (n) {
for (i = 0; i < n->serverc; i++)
free(n->serverv[i].host);
free(n->serverv);
n->serverv = NULL;
n->serverc = 0;
} else {
n = calloc(sizeof(struct network), 1);
hash_insert(&bip->networks, name, n);
}
while ((t = list_remove_first(data))) {
switch (t->type) {
case LEX_NAME:
n->name = t->pdata;
MOVE_STRING(n->name, t->pdata);
break;
#ifdef HAVE_LIBSSL
case LEX_SSL:
@ -334,224 +336,198 @@ static int add_network(list_t *data)
break;
#endif
case LEX_SERVER:
r = add_server(&n->serverl, t->pdata);
n->serverv = realloc(n->serverv, (n->serverc + 1)
* sizeof(struct server));
n->serverc++;
add_server(&n->serverv[n->serverc - 1], t->pdata);
free(t->pdata);
if (!r)
return 0;
t->pdata = NULL;
break;
default:
conf_die("unknown keyword in network statement");
if (t->type == TUPLE_STR)
free(t->pdata);
return 0;
break;
}
if (t->type == TUPLE_STR && t->pdata)
free(t->pdata);
free(t);
}
if (!n->name) {
conf_die("Network with no name");
return 1;
}
static int add_connection(bip_t *bip, struct user *user, list_t *data)
{
struct tuple *t;
struct link *l;
struct chan_info *ci;
char *name = get_tuple_value(data, LEX_NAME);
if (name == NULL) {
conf_die("Connection with no name");
return 0;
}
old_n = hash_get(&conf_networks, n->name);
if (old_n) {
hash_remove(&conf_networks, n->name);
c_network_free(old_n);
l = hash_get(&user->connections, name);
if (!l) {
l = irc_link_new();
hash_insert(&user->connections, name, l);
list_add_last(&bip->link_list, l);
l->user = user;
l->log = log_new(user, name);
} else {
#warning "CODEME (user switch..)"
l->network = NULL;
}
hash_insert(&conf_networks, n->name, n);
return 1;
}
static int add_channel(list_t *channell, list_t *data)
{
struct tuple *t;
struct c_channel *c;
c = calloc(sizeof(struct c_channel), 1);
while ((t = list_remove_first(data))) {
switch (t->type) {
case LEX_NAME:
c->name = t->pdata;
break;
case LEX_KEY:
c->key = t->pdata;
break;
default:
conf_die("unknown keyword in channel statement");
if (t->type == TUPLE_STR)
free(t->pdata);
return 0;
break;
}
free(t);
}
if (!c->name)
conf_die("channel wo a name !");
list_add_last(channell, c);
return 1;
}
void c_connection_free(struct c_connection *c)
{
/* XXX network free! */
free(c->user);
free(c->password);
free(c->vhost);
struct c_channel *chan;
while ((chan = list_remove_first(&c->channell))) {
free(chan->name);
if (chan->key)
free(chan->key);
free(chan);
}
free(c->away_nick);
free(c->no_client_away_msg);
char *s;
while ((s = list_remove_first(&c->on_connect_send)))
free(s);
}
static int add_connection(list_t *connectionl, list_t *data,
list_t *old_c_connl)
{
struct tuple *t;
struct c_connection *c, *old_c = NULL;
int r;
c = calloc(sizeof(struct c_connection), 1);
list_init(&c->channell, NULL);
list_init(&c->on_connect_send, NULL);
while ((t = list_remove_first(data))) {
switch (t->type) {
case LEX_NAME:
c->name = t->pdata;
MOVE_STRING(l->name, t->pdata);
break;
case LEX_NETWORK:
c->network = hash_get(&conf_networks, t->pdata);
if (!c->network) {
free(c);
conf_die("networkd:%s used but not defined\n",
l->network = hash_get(&bip->networks, t->pdata);
if (!l->network) {
conf_die("Undefined network %s.\n",
t->pdata);
return 0;
}
break;
case LEX_NICK:
if (!is_valid_nick(t->pdata))
conf_die("Invalid nickname (%s)", t->pdata);
c->nick = t->pdata;
conf_die("Invalid nickname %s.", t->pdata);
MOVE_STRING(l->connect_nick, t->pdata);
break;
case LEX_USER:
c->user = t->pdata;
MOVE_STRING(l->username, t->pdata);
break;
case LEX_REALNAME:
c->realname = t->pdata;
MOVE_STRING(l->realname, t->pdata);
break;
case LEX_PASSWORD:
c->password = t->pdata;
MOVE_STRING(l->s_password, t->pdata);
break;
case LEX_VHOST:
c->vhost = t->pdata;
MOVE_STRING(l->vhost, t->pdata);
break;
case LEX_CHANNEL:
r = add_channel(&c->channell, t->pdata);
free(t->pdata);
if (!r)
return 0;
ci = calloc(sizeof(struct chan_info), 1);
ci->name = get_tuple_value(t->pdata, LEX_NAME);
ci->key = get_tuple_value(t->pdata, LEX_KEY);
hash_insert(&l->chan_infos, ci->name, ci);
list_add_last(&l->chan_infos_order, ci);
break;
case LEX_FOLLOW_NICK:
c->follow_nick = t->ndata;
l->follow_nick = t->ndata;
break;
case LEX_IGN_FIRST_NICK:
c->ignore_first_nick = t->ndata;
l->ignore_first_nick = t->ndata;
break;
case LEX_AWAY_NICK:
c->away_nick = t->pdata;
MOVE_STRING(l->away_nick, t->pdata);
break;
case LEX_NO_CLIENT_AWAY_MSG:
c->no_client_away_msg = t->pdata;
MOVE_STRING(l->no_client_away_msg, t->pdata);
break;
case LEX_ON_CONNECT_SEND:
list_add_last(&c->on_connect_send, t->pdata);
list_add_last(&l->on_connect_send, t->pdata);
break;
default:
conf_die("unknown keyword in connection statement");
if (t->type == TUPLE_STR)
free(t->pdata);
return 0;
}
if (t->type == TUPLE_STR && t->pdata)
free(t->pdata);
free(t);
}
/* checks that can only be here, or must */
if (!c->network) {
if (!l->network)
conf_die("Missing network in connection block");
return 0;
}
list_add_last(connectionl, c);
if (old_c_connl) {
old_c = list_remove_first(old_c_connl);
if (old_c)
c_connection_free(old_c);
}
return 1;
}
void c_user_free(struct c_user *cu)
static char *get_tuple_value(list_t *tuple_l, int lex)
{
free(cu->name);
free(cu->password);
#ifdef HAVE_LIBSSL
free(cu->ssl_check_store);
#endif
struct c_connection *con;
while ((con = list_remove_first(&cu->connectionl)))
c_connection_free(con);
free(cu);
struct tuple *t;
list_iterator_t it;
for (list_it_init(tuple_l, &it); (t = list_it_item(&it));
list_it_next(&it)) {
if (t->type == lex)
return t->pdata;
}
return NULL;
}
static int add_user(list_t *data)
static int add_user(bip_t *bip, list_t *data)
{
int r;
struct tuple *t;
struct c_user *u;
struct c_user *old_u = 0;
struct user *u;
u = calloc(sizeof(struct c_user), 1);
list_init(&u->connectionl, NULL);
char *name = get_tuple_value(data, LEX_NAME);
if (name == NULL) {
conf_die("User with no name");
return 0;
}
u = hash_get(&bip->users, name);
if (!u) {
u = calloc(sizeof(struct user), 1);
hash_insert(&bip->users, name, u);
hash_init(&u->connections, HASH_NOCASE);
} else {
FREE(u->name);
FREE(u->password);
FREE(u->default_nick);
FREE(u->default_username);
FREE(u->default_realname);
#ifdef HAVE_LIBSSL
FREE(u->ssl_check_store);
#endif
}
while ((t = list_remove_first(data))) {
switch (t->type) {
case LEX_NAME:
u->name = t->pdata;
old_u = hash_get(&conf_users, u->name);
MOVE_STRING(u->name, t->pdata);
break;
case LEX_PASSWORD:
hash_binary(t->pdata, &u->password, &u->seed);
free(t->pdata);
break;
case LEX_DEFAULT_NICK:
u->default_nick = t->pdata;
MOVE_STRING(u->default_nick, t->pdata);
break;
case LEX_DEFAULT_USER:
u->default_user = t->pdata;
MOVE_STRING(u->default_username, t->pdata);
break;
case LEX_DEFAULT_REALNAME:
u->default_realname = t->pdata;
MOVE_STRING(u->default_realname, t->pdata);
break;
case LEX_ALWAYS_BACKLOG:
u->always_backlog = t->ndata;
break;
case LEX_BACKLOG:
u->backlog = t->ndata;
break;
case LEX_BL_MSG_ONLY:
u->bl_msg_only = t->ndata;
break;
case LEX_BACKLOG_LINES:
u->backlog_lines = t->ndata;
break;
case LEX_BACKLOG_NO_TIMESTAMP:
u->backlog_no_timestamp = t->ndata;
break;
case LEX_BLRESET_ON_TALK:
u->blreset_on_talk = t->ndata;
break;
case LEX_CONNECTION:
if (!u->name)
conf_die("name statement must be first in user"
"block");
if (!old_u)
r = add_connection(&u->connectionl, t->pdata,
NULL);
else
r = add_connection(&u->connectionl, t->pdata,
&old_u->connectionl);
r = add_connection(bip, u, t->pdata);
free(t->pdata);
if (!r)
return 0;
@ -570,34 +546,24 @@ static int add_user(list_t *data)
#endif
default:
conf_die("Uknown keyword in user statement");
if (t->type == TUPLE_STR)
free(t->pdata);
break;
}
if (t->type == TUPLE_STR && t->pdata)
free(t->pdata);
free(t);
}
if (!u->name) {
conf_die("User w/o a name!");
return 0;
}
if (!u->password) {
conf_die("Missing password in user block");
return 0;
}
if (old_u) {
hash_remove(&conf_users, u->name);
c_user_free(old_u);
}
hash_insert(&conf_users, u->name, u);
return 1;
}
int fireup(FILE *conf)
int fireup(bip_t *bip, FILE *conf)
{
struct tuple *t;
list_t *l;
int r;
conf_start();
@ -610,6 +576,7 @@ int fireup(FILE *conf)
case LEX_LOG_SYNC_INTERVAL:
conf_log_sync_interval = t->ndata;
break;
/*
case LEX_ALWAYS_BACKLOG:
conf_always_backlog = t->ndata;
break;
@ -619,35 +586,33 @@ int fireup(FILE *conf)
case LEX_BL_MSG_ONLY:
conf_bl_msg_only = t->ndata;
break;
case LEX_LOG:
conf_log = t->ndata;
break;
case LEX_LOG_SYSTEM:
conf_log_system = t->ndata;
break;
case LEX_BACKLOG_LINES:
conf_backlog_lines = t->ndata;
break;
case LEX_BACKLOG_NO_TIMESTAMP:
conf_backlog_no_timestamp = t->ndata;
break;
case LEX_BLRESET_ON_TALK:
conf_blreset_on_talk = t->ndata;
break;
*/
case LEX_LOG:
conf_log = t->ndata;
break;
case LEX_LOG_SYSTEM:
conf_log_system = t->ndata;
break;
case LEX_LOG_ROOT:
if (conf_log_root)
free(conf_log_root);
conf_log_root = t->pdata;
MOVE_STRING(conf_log_root, t->pdata);
break;
case LEX_LOG_FORMAT:
if (conf_log_format)
free(conf_log_format);
conf_log_format = t->pdata;
MOVE_STRING(conf_log_format, t->pdata);
break;
case LEX_LOG_LEVEL:
conf_log_level = t->ndata;
break;
case LEX_IP:
if (conf_ip)
free(conf_ip);
conf_ip = t->pdata;
MOVE_STRING(conf_ip, t->pdata);
break;
case LEX_PORT:
conf_port = t->ndata;
@ -656,44 +621,36 @@ int fireup(FILE *conf)
conf_css = t->ndata;
break;
case LEX_PID_FILE:
if (conf_pid_file)
free(conf_pid_file);
conf_pid_file = t->pdata;
break;
case LEX_BLRESET_ON_TALK:
conf_blreset_on_talk = t->ndata;
MOVE_STRING(conf_pid_file, t->pdata);
break;
case LEX_NETWORK:
r = add_network(t->pdata);
add_network(bip, t->pdata);
list_free(t->pdata);
if (!r)
return 0;
break;
case LEX_USER:
r = add_user(t->pdata);
add_user(bip, t->pdata);
list_free(t->pdata);
if (!r)
return 0;
break;
default:
if (t->type == TUPLE_STR)
free(t->pdata);
conf_die("Config error in base config (%d)", t->type);
return 0;
}
if (t->type == TUPLE_STR && t->pdata)
free(t->pdata);
free(t);
}
free(root_list);
root_list = NULL;
#warning move me
#if 0
if (conf_backlog && !conf_log) {
if (conf_backlog_lines == 0) {
conf_die("You must set conf_backlog_lines if "
"conf_log = false and "
"conf_backlog = true");
return 0;
}
}
#endif
if (!conf_log)
conf_memlog = 1;
@ -752,6 +709,7 @@ int fireup(FILE *conf)
return 1;
}
#if 0
void ircize(bip_t *bip)
{
hash_iterator_t it;
@ -813,12 +771,6 @@ void ircize(bip_t *bip)
} else {
mylog(LOG_DEBUGVERB, "old connection: \"%s\"",
c->name);
#define MAYFREE(a) do { \
if (a) { \
free(a); \
(a) = NULL; \
} \
} while(0);
MAYFREE(link->away_nick);
MAYFREE(link->password);
MAYFREE(link->user);
@ -907,13 +859,14 @@ void ircize(bip_t *bip)
}
}
}
#endif
int main(int argc, char **argv)
{
FILE *conf = NULL;
char *confpath = NULL;
int ch;
int r,fd;
int r, fd;
char buf[30];
bip_t bip;
@ -924,10 +877,6 @@ int main(int argc, char **argv)
conf_port = 7778;
conf_css = 0;
hash_init(&adm_users, HASH_NOCASE);
hash_init(&conf_users, HASH_NOCASE);
hash_init(&conf_networks, HASH_NOCASE);
signal(SIGPIPE, SIG_IGN);
signal(SIGHUP, reload_config);
signal(SIGINT, bad_quit);
@ -940,7 +889,6 @@ int main(int argc, char **argv)
conf_backlog = 1;
conf_log = 1;
conf_log_system = 1;
conf_backlog_lines = 100;
conf_log_sync_interval = 5;
conf_daemonize = 1;
conf_global_log_file = stderr;
@ -984,7 +932,7 @@ int main(int argc, char **argv)
fatal("%s config file not found", confpath);
}
r = fireup(conf);
r = fireup(&bip, conf);
fclose(conf);
if (!r) {
fatal("%s", conf_errstr);
@ -1007,8 +955,6 @@ int main(int argc, char **argv)
fatal("Could not create listening socket");
for (;;) {
if (r)
ircize(&bip);
if (conf_error)
mylog(LOG_ERROR, "conf error: %s", conf_errstr);
@ -1019,7 +965,7 @@ int main(int argc, char **argv)
conf = fopen(confpath, "r");
if (!conf)
fatal("%s config file not found", confpath);
r = fireup(conf);
fireup(&bip, conf);
fclose(conf);
}
return 1;
@ -1028,20 +974,20 @@ int main(int argc, char **argv)
void write_user_list(connection_t *c, char *dest)
{
hash_iterator_t it;
list_iterator_t lit;
hash_iterator_t lit;
char buf[4096];
WRITE_LINE2(c, P_IRCMASK, "PRIVMSG", dest, "bip user list:");
for (hash_it_init(&conf_users, &it); hash_it_item(&it);
for (hash_it_init(&_bip->users, &it); hash_it_item(&it);
hash_it_next(&it)) {
struct c_user *u = hash_it_item(&it);
struct user *u = hash_it_item(&it);
snprintf(buf, 4095, "* %s:", u->name);
buf[4095] = 0;
WRITE_LINE2(c, P_IRCMASK, "PRIVMSG", dest, buf);
for (list_it_init(&u->connectionl, &lit); list_it_item(&lit);
list_it_next(&lit)) {
struct c_connection *con = list_it_item(&lit);
for (hash_it_init(&u->connections, &lit); hash_it_item(&lit);
hash_it_next(&lit)) {
struct link *con = hash_it_item(&lit);
snprintf(buf, 4095, " - %s", con->name);
buf[4095] = 0;
WRITE_LINE2(c, P_IRCMASK, "PRIVMSG", dest, buf);
@ -1075,7 +1021,7 @@ int ssl_check_trust(struct link_client *ic)
char fpstr[EVP_MAX_MD_SIZE * 3 + 20];
unsigned int fplen;
int i;
if(!LINK(ic)->untrusted_certs ||
sk_X509_num(LINK(ic)->untrusted_certs) <= 0)
return 0;

View File

@ -14,36 +14,13 @@
#ifndef BIP_H
#define BIP_H
struct c_network
{
char *name;
#ifdef HAVE_LIBSSL
int ssl;
#endif
list_t serverl;
};
struct c_user
{
char *name;
unsigned char *password;
unsigned int seed;
char *default_user;
char *default_nick;
char *default_realname;
#ifdef HAVE_LIBSSL
int ssl_check_mode;
char *ssl_check_store;
#endif
list_t connectionl;
};
#if 0
struct c_connection
{
char *name;
struct c_network *network;
char *realname, *user, *nick;
char *password; /* server pass */
char *password; /* server pass */
char *vhost;
unsigned short source_port;
list_t channell;
@ -62,6 +39,7 @@ struct c_channel
char *name;
char *key;
};
#endif
#ifdef HAVE_LIBSSL
int adm_trust(struct link_client *ic, struct line *line);

View File

@ -109,28 +109,13 @@ command:
| LEX_IP LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_IP, $3); }
| LEX_PORT LEX_EQ LEX_INT { $$ = tuple_i_new(LEX_PORT, $3); }
| LEX_CSS LEX_EQ LEX_BOOL { $$ = tuple_i_new(LEX_CSS, $3); }
| LEX_BACKLOG_LINES LEX_EQ LEX_INT { $$ = tuple_i_new(LEX_BACKLOG_LINES,
$3); }
| LEX_BACKLOG_NO_TIMESTAMP LEX_EQ LEX_BOOL {
$$ = tuple_i_new(LEX_BACKLOG_NO_TIMESTAMP, $3);
}
| LEX_BACKLOG LEX_EQ LEX_BOOL { $$ = tuple_i_new(LEX_BACKLOG,
$3); }
| LEX_BL_MSG_ONLY LEX_EQ LEX_BOOL {
$$ = tuple_i_new(LEX_BL_MSG_ONLY, $3);
}
| LEX_LOG LEX_EQ LEX_BOOL { $$ = tuple_i_new(LEX_LOG, $3); }
| LEX_LOG_SYSTEM LEX_EQ LEX_BOOL { $$ = tuple_i_new(LEX_LOG_SYSTEM, $3); }
| LEX_ALWAYS_BACKLOG LEX_EQ LEX_BOOL { $$ = tuple_i_new(
LEX_ALWAYS_BACKLOG, $3); }
| LEX_LOG_SYNC_INTERVAL LEX_EQ LEX_INT { $$ = tuple_i_new(
LEX_LOG_SYNC_INTERVAL, $3); }
LEX_LOG_SYNC_INTERVAL, $3); }
| LEX_PID_FILE LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_PID_FILE, $3); }
| LEX_BLRESET_ON_TALK LEX_EQ LEX_BOOL {
$$ = tuple_i_new(LEX_BLRESET_ON_TALK, $3);
}
| LEX_NETWORK LEX_LBRA network LEX_RBRA { $$ = tuple_l_new(LEX_NETWORK,
$3); }
$3); }
| LEX_USER LEX_LBRA user LEX_RBRA { $$ = tuple_l_new(LEX_USER, $3); }
network:
@ -141,7 +126,7 @@ net_command:
LEX_NAME LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_NAME, $3); }
| LEX_SSL LEX_EQ LEX_BOOL { $$ = tuple_i_new(LEX_SSL, $3); }
| LEX_SERVER LEX_LBRA server LEX_RBRA {
$$ = tuple_l_new(LEX_SERVER, $3); }
$$ = tuple_l_new(LEX_SERVER, $3); }
user:
{ $$ = list_new(NULL); }
@ -151,19 +136,34 @@ usr_command:
LEX_NAME LEX_EQ LEX_STRING {
$$ = tuple_s_new(LEX_NAME, $3); }
| LEX_PASSWORD LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_PASSWORD,
$3); }
$3); }
| LEX_SSL_CHECK_MODE LEX_EQ LEX_STRING { $$ = tuple_s_new(
LEX_SSL_CHECK_MODE, $3); }
LEX_SSL_CHECK_MODE, $3); }
| LEX_SSL_CHECK_STORE LEX_EQ LEX_STRING { $$ = tuple_s_new(
LEX_SSL_CHECK_STORE, $3); }
LEX_SSL_CHECK_STORE, $3); }
| LEX_DEFAULT_USER LEX_EQ LEX_STRING {
$$ = tuple_s_new(LEX_DEFAULT_USER, $3); }
| LEX_DEFAULT_NICK LEX_EQ LEX_STRING {
$$ = tuple_s_new(LEX_DEFAULT_NICK, $3); }
| LEX_DEFAULT_REALNAME LEX_EQ LEX_STRING {
$$ = tuple_s_new(LEX_DEFAULT_REALNAME, $3); }
| LEX_BACKLOG_LINES LEX_EQ LEX_INT {
$$ = tuple_i_new(LEX_BACKLOG_LINES, $3);
}
| LEX_BACKLOG_NO_TIMESTAMP LEX_EQ LEX_BOOL {
$$ = tuple_i_new(LEX_BACKLOG_NO_TIMESTAMP, $3);
}
| LEX_BACKLOG LEX_EQ LEX_BOOL { $$ = tuple_i_new(LEX_BACKLOG, $3); }
| LEX_BLRESET_ON_TALK LEX_EQ LEX_BOOL {
$$ = tuple_i_new(LEX_BLRESET_ON_TALK, $3);
}
| LEX_BL_MSG_ONLY LEX_EQ LEX_BOOL {
$$ = tuple_i_new(LEX_BL_MSG_ONLY, $3);
}
| LEX_ALWAYS_BACKLOG LEX_EQ LEX_BOOL { $$ = tuple_i_new(
LEX_ALWAYS_BACKLOG, $3); }
| LEX_CONNECTION LEX_LBRA connection LEX_RBRA {
$$ = tuple_l_new(LEX_CONNECTION, $3); }
$$ = tuple_l_new(LEX_CONNECTION, $3); }
connection:
{ $$ = list_new(NULL); }
@ -173,18 +173,18 @@ connection:
con_command:
LEX_NAME LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_NAME, $3); }
| LEX_NETWORK LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_NETWORK,
$3); }
$3); }
| LEX_NICK LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_NICK, $3); }
| LEX_USER LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_USER, $3); }
| LEX_REALNAME LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_REALNAME,
$3); }
$3); }
| LEX_PASSWORD LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_PASSWORD,
$3); }
$3); }
| LEX_VHOST LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_VHOST, $3); }
| LEX_SOURCE_PORT LEX_EQ LEX_INT {
$$ = tuple_i_new(LEX_SOURCE_PORT, $3); }
| LEX_AWAY_NICK LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_AWAY_NICK,
$3); }
$3); }
| LEX_FOLLOW_NICK LEX_EQ LEX_BOOL {
$$ = tuple_i_new(LEX_FOLLOW_NICK, $3); }
| LEX_IGN_FIRST_NICK LEX_EQ LEX_BOOL { $$ = tuple_i_new(

View File

@ -696,7 +696,8 @@ static int irc_cli_startup(bip_t *bip, struct link_client *ic,
struct link *l = list_it_item(&it);
if (strcmp(user, l->username) == 0 &&
strcmp(connname, l->name) == 0) {
if (chash_cmp(pass, l->password, l->seed) == 0) {
if (chash_cmp(pass, l->user->password,
l->user->seed) == 0) {
bind_to_link(l, ic);
break;
}
@ -849,7 +850,7 @@ static int irc_cli_privmsg(struct link_client *ic, struct line *line)
if (strcmp(line->elemv[1], "-bip") == 0)
return adm_bip(ic, line, 1);
if (conf_blreset_on_talk)
if (LINK(ic)->user->blreset_on_talk)
adm_blreset(ic);
return OK_COPY_CLI;
}
@ -1799,12 +1800,18 @@ static int irc_generic_quit(struct link_server *server, struct line *line)
static void irc_server_startup(struct link_server *ircs)
{
char *nick;
char *username, *realname;
if (LINK(ircs)->s_password)
WRITE_LINE1(CONN(ircs), NULL, "PASS", LINK(ircs)->s_password);
WRITE_LINE4(CONN(ircs), NULL, "USER", LINK(ircs)->user, "0", "*",
LINK(ircs)->real_name);
username = LINK(ircs)->username;
if (!username)
username = LINK(ircs)->user->default_username;
realname = LINK(ircs)->realname;
if (!realname)
realname = LINK(ircs)->user->default_realname;
WRITE_LINE4(CONN(ircs), NULL, "USER", username, "0", "*", realname);
nick = ircs->nick;
if (LINK(ircs)->away_nick && LINK(ircs)->l_clientc == 0) {
@ -1816,6 +1823,9 @@ static void irc_server_startup(struct link_server *ircs)
|| nick == NULL) {
if (nick)
free(nick);
if (!LINK(ircs)->connect_nick)
LINK(ircs)->connect_nick =
strdup(LINK(ircs)->user->default_nick);
nick = strdup(LINK(ircs)->connect_nick);
}
@ -1826,8 +1836,8 @@ static void irc_server_startup(struct link_server *ircs)
static void server_next(struct link *l)
{
l->cur_server++;
if (l->cur_server >= l->serverc)
l->cur_server -= l->serverc;
if (l->cur_server >= l->network->serverc)
l->cur_server = 0;
}
static struct link_client *irc_accept_new(connection_t *conn)
@ -1976,11 +1986,11 @@ connection_t *irc_server_connect(struct link *link)
connection_t *conn;
mylog(LOG_INFO, "Connecting user '%s' to network '%s' using server "
"%s:%d", link->username, link->name,
link->serverv[link->cur_server]->host,
link->serverv[link->cur_server]->port);
conn = connection_new(link->serverv[link->cur_server]->host,
link->serverv[link->cur_server]->port,
"%s:%d", link->user->name, link->name,
link->network->serverv[link->cur_server].host,
link->network->serverv[link->cur_server].port);
conn = connection_new(link->network->serverv[link->cur_server].host,
link->network->serverv[link->cur_server].port,
link->vhost, link->bind_port,
#ifdef HAVE_LIBSSL
link->s_ssl, link->ssl_check_mode,
@ -2154,7 +2164,7 @@ void oidentd_dump(list_t *connl)
fprintf(f, "to %s fport %d from %s lport %d {\n",
remoteip, remoteport, localip,
localport);
fprintf(f, "\treply \"%s\"\n", l->user);
fprintf(f, "\treply \"%s\"\n", l->username);
fprintf(f, "}\n");
free(localip);
free(remoteip);
@ -2198,47 +2208,9 @@ void bip_init(bip_t *bip)
list_init(&bip->link_list, list_ptr_cmp);
list_init(&bip->conn_list, list_ptr_cmp);
list_init(&bip->connecting_client_list, list_ptr_cmp);
}
void bip_recover_sighup(bip_t *bip)
{
/* gcc */
(void)bip;
/*
* Merge with already connected data, happens on SIGHUP
*/
#if 0
list_iterator_t it;
for (list_it_init(ll, &it); list_it_item(&it); list_it_next(&it)) {
struct link *link = list_it_item(&it);
if (link->l_server)
list_add_last(&connl, CONN(link->l_server));
else
list_add_last(&reconnectl, link);
if (link->l_clientc) {
int i;
for (i = 0; i < link->l_clientc; i++) {
struct link_client *c;
c = link->l_clientv[i];
list_add_last(&connl, CONN(c));
if (TYPE(c) == IRC_TYPE_LOGING_CLIENT)
list_add_last(&connecting_c, c);
if (TYPE(c) == IRC_TYPE_CLIENT)
list_add_last(&connected_c, c);
}
}
}
if (conf_error && reloading_client) {
char *nick;
if (LINK(reloading_client)->l_server)
nick = LINK(reloading_client)->l_server->nick;
else
nick = LINK(reloading_client)->prev_nick;
WRITE_LINE2(CONN(reloading_client), P_IRCMASK, "PRIVMSG", nick,
conf_errstr);
reloading_client = NULL;
}
#endif
hash_init(&bip->users, HASH_NOCASE);
hash_init(&bip->networks, HASH_NOCASE);
}
/* Called each second. */
@ -2382,11 +2354,8 @@ void irc_main(bip_t *bip)
/* XXX: This one MUST be first */
/* TODO: maybe not anymore, check */
printf("%p\n", bip->listener);
list_add_first(&bip->conn_list, bip->listener);
bip_recover_sighup(bip);
while (!sighup) {
connection_t *conn;
@ -2406,9 +2375,8 @@ void irc_main(bip_t *bip)
if (nc)
oidentd_dump(&bip->conn_list);
#endif
while ((conn = list_remove_first(ready))) {
while ((conn = list_remove_first(ready)))
bip_on_event(bip, conn);
}
list_free(ready);
}
while (list_remove_first(&bip->conn_list))

View File

@ -62,20 +62,54 @@ struct channel {
#define IRC_TYPE_LOGING_CLIENT (2)
#define IRC_TYPE_TRUST_CLIENT (3)
struct user {
/** client connection static data **/
char *name;
unsigned char *password;
unsigned int seed;
/* common link options */
char *default_nick;
char *default_username;
char *default_realname;
/* backlog options */
int backlog;
int backlog_lines;
int always_backlog;
int bl_msg_only;
int backlog_no_timestamp;
int blreset_on_talk;
hash_t connections;
};
struct network
{
char *name;
#ifdef HAVE_LIBSSL
int ssl;
#endif
int serverc;
struct server *serverv;
};
struct link {
char *name; /* id */
char *name; /* id */
/** link live data **/
struct link_server *l_server;
int l_clientc;
struct link_client **l_clientv;
/* we honnor the /who from clients one client at a time, this is the
struct log *log;
/* we honnor the /who from clients one client at a time, this is the
* client that is /who-ing. Now for bans too */
struct link_client *who_client;
struct log *log;
/* server related live stuff */
int s_state;
int s_conn_attempt;
@ -97,20 +131,15 @@ struct link {
hash_t chan_infos; /* channels we want */
list_t chan_infos_order; /* for order only */
/** client connection static data **/
char *username;
unsigned char *password;
unsigned int seed;
struct user *user;
/** server connection static data **/
/* server list */
int serverc;
struct server **serverv;
struct network *network;
int cur_server;
char *user;
char *real_name;
char *username;
char *realname;
char *s_password;
char *connect_nick;
@ -204,6 +233,9 @@ typedef struct bip {
list_t link_list;
/* connecting clients */
list_t connecting_client_list;
hash_t networks;
hash_t users;
} bip_t;
void bip_init(bip_t *bip);

View File

@ -24,13 +24,6 @@ extern int conf_log;
int conf_memlog = 1;
/* conf_always_backlog => conf_backlog_lines != 0 */
extern int conf_backlog;
extern int conf_backlog_lines;
extern int conf_always_backlog;
extern int conf_bl_msg_only;
extern int conf_backlog_no_timestamp;
int log_set_backlog_offset(log_t *logdata, char *dest);
static int _log_write(log_t *logdata, logfilegroup_t *lf, char *d, char *str);
void logfile_free(logfile_t *lf);
@ -153,7 +146,7 @@ char *log_build_filename(log_t *logdata, char *destination)
snprintf(month, 3, "%02d", now->tm_mon + 1);
snprintf(logfile, MAX_PATH_LEN, "%s/%s", conf_log_root,
conf_log_format);
replace_var(logfile, "%u", logdata->user, MAX_PATH_LEN);
replace_var(logfile, "%u", logdata->user->name, MAX_PATH_LEN);
replace_var(logfile, "%n", logdata->network, MAX_PATH_LEN);
replace_var(logfile, "%c", dest, MAX_PATH_LEN);
replace_var(logfile, "%Y", year, MAX_PATH_LEN);
@ -328,7 +321,7 @@ logfilegroup_t *log_find_file(log_t *logdata, char *destination)
time(&t);
ltime = localtime(&t);
lf = list_get_last(&lfg->file_group);
if (ltime->tm_mday != lf->last_log.tm_mday) {
if (ltime->tm_mday != lf->last_log.tm_mday) {
logfile_t *oldlf;
/* day changed, we might want to rotate logfile */
@ -351,7 +344,7 @@ logfilegroup_t *log_find_file(log_t *logdata, char *destination)
}
free(filename);
if (!conf_backlog) {
if (!logdata->user->backlog) {
/* remove oldlf from file_group */
if (list_remove_first(&lfg->file_group) != oldlf)
fatal("internal log_find_file 2");
@ -617,7 +610,7 @@ void log_client_none_connected(log_t *logdata)
logdata->connected = 0;
if (conf_always_backlog)
if (logdata->user->always_backlog)
return;
@ -638,10 +631,10 @@ void log_advance_backlogs(log_t* ld, logfilegroup_t *lfg)
{
int c;
(void)ld;
if (!conf_backlog || conf_backlog_lines == 0)
if (!ld->user->backlog || ld->user->backlog_lines == 0)
return;
if (lfg->skip_advance < conf_backlog_lines) {
if (lfg->skip_advance < ld->user->backlog_lines) {
lfg->skip_advance++;
return;
}
@ -708,7 +701,7 @@ int log_has_backlog(log_t *logdata, char *destination)
* 01-08-2005 10:46:11 < * jj!john@thebox.ofjj.net
*/
char *log_beautify(char *buf, char *dest)
char *log_beautify(log_t *logdata, char *buf, char *dest)
{
int action = 0;
char *p;
@ -736,7 +729,7 @@ char *log_beautify(char *buf, char *dest)
lots = p - sots;
p++;
if (strncmp(p, "-!-", 3) == 0) {
if (conf_bl_msg_only)
if (logdata->user->bl_msg_only)
return NULL;
else
return _log_wrap(dest, buf);
@ -849,7 +842,7 @@ char *log_beautify(char *buf, char *dest)
strcpy(p, " -> ");
p += strlen(" -> ");
}
if (conf_backlog_no_timestamp == 0) {
if (logdata->user->backlog_no_timestamp == 0) {
memcpy(p, sots, lots);
p += lots;
*p++ = '>';
@ -879,7 +872,7 @@ char *log_backread(log_t *logdata, char *destination, int *skip)
*skip = 0;
if (!conf_always_backlog && logdata->connected)
if (!logdata->user->always_backlog && logdata->connected)
return NULL;
lfg = hash_get(&logdata->logfgs, destination);
@ -941,7 +934,7 @@ next_file:
}
for(;;) {
c = fgetc(lf->file);
if (!conf_always_backlog)
if (!logdata->user->always_backlog)
lf->backlog_offset++;
if (c == EOF || c == '\n' || pos == LOGLINE_MAXLEN) {
/* change file if we reach EOF, if pos == maxlen
@ -951,11 +944,11 @@ next_file:
mylog(LOG_DEBUG, "logline too long");
if (c == EOF || pos == LOGLINE_MAXLEN) {
mylog(LOG_DEBUGVERB, "EOF: %s (%d)!",
lf->filename,
conf_always_backlog);
lf->filename,
logdata->user->always_backlog);
list_it_next(&logdata->file_it);
if (!conf_always_backlog) {
if (!logdata->user->always_backlog) {
list_remove_first(
&lfg->file_group);
logfile_free(lf);
@ -972,7 +965,7 @@ next_file:
*skip = 1;
return buf;
}
ret = log_beautify(buf, destination);
ret = log_beautify(logdata, buf, destination);
if (ret == NULL) {
pos = 0;
continue;
@ -1002,14 +995,14 @@ next_file:
free(buf);
return NULL;
}
if (!conf_always_backlog)
if (!logdata->user->always_backlog)
lf->backlog_offset++;
if (c != '\n')
buf[pos++] = c;
for(;;) {
c = fgetc(lf->file);
if (!conf_always_backlog)
if (!logdata->user->always_backlog)
lf->backlog_offset++;
if (c == EOF || c == '\n' || pos == LOGLINE_MAXLEN) {
if (pos == LOGLINE_MAXLEN) {
@ -1022,14 +1015,14 @@ next_file:
return NULL;
}
if (!conf_always_backlog && c == EOF)
if (!logdata->user->always_backlog && c == EOF)
lf->backlog_offset--;
buf[pos] = 0;
if (pos == 0) {
*skip = 1;
return buf;
}
ret = log_beautify(buf, destination);
ret = log_beautify(logdata, buf, destination);
if (ret == NULL) {
pos = 0;
continue;
@ -1070,10 +1063,10 @@ static int _log_write(log_t *logdata, logfilegroup_t *lfg, char *destination,
str[LOGLINE_MAXLEN] = 0;
if (lfg->memlog) {
char *r = log_beautify(str, destination);
char *r = log_beautify(logdata, str, destination);
if (r != NULL) {
list_add_last(lfg->memlog, r);
if (lfg->memc == conf_backlog_lines)
if (lfg->memc == logdata->user->backlog_lines)
free(list_remove_first(lfg->memlog));
else
lfg->memc++;
@ -1092,7 +1085,7 @@ static int _log_write(log_t *logdata, logfilegroup_t *lfg, char *destination,
if (nbwrite != len + 1)
mylog(LOG_ERROR, "Error writing to %s logfile", lf->filename);
lf->len += nbwrite;
if (!logdata->connected || conf_always_backlog)
if (!logdata->connected || logdata->user->always_backlog)
log_advance_backlogs(logdata, lfg);
return nbwrite;
}
@ -1134,14 +1127,14 @@ void log_flush_all(void)
}
}
log_t *log_new(char *user, char *network)
log_t *log_new(struct user *user, char *network)
{
log_t *logdata;
logdata = (log_t*)calloc(sizeof(log_t), 1);
if (!logdata)
fatal("out of memory");
logdata->user = strdup(user);
logdata->user = user;
logdata->network = strdup(network);
hash_init(&logdata->logfgs, HASH_NOCASE);
logdata->buffer = (char *)malloc((LOGLINE_MAXLEN + 1) * sizeof(char));

View File

@ -51,16 +51,17 @@ typedef struct logfilegroup
typedef struct log {
hash_t logfgs;
char *network;
char *user;
char *buffer;
int connected;
int backlogging;
list_iterator_t file_it;
int lastfile_seeked;
struct user *user;
} log_t;
void log_close_all(log_t *logdata);
log_t *log_new(char *user, char *network);
log_t *log_new(struct user *user, char *network);
void logdata_free(log_t *logdata);
int log_compare_files(logfile_t *f1, char *f2);