aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bitlbee.c2
-rw-r--r--bitlbee.conf7
-rw-r--r--conf.c19
-rw-r--r--conf.h1
-rwxr-xr-xconfigure2
-rw-r--r--irc.c17
-rw-r--r--lib/events.h4
-rw-r--r--lib/events_libevent.c51
-rw-r--r--protocols/jabber/conference.c48
-rw-r--r--protocols/jabber/iq.c19
-rw-r--r--protocols/jabber/jabber.c6
-rw-r--r--protocols/jabber/jabber.h3
-rw-r--r--protocols/jabber/jabber_util.c53
-rw-r--r--protocols/jabber/presence.c9
-rw-r--r--protocols/oscar/msgcookie.c15
-rw-r--r--unix.c21
16 files changed, 192 insertions, 85 deletions
diff --git a/bitlbee.c b/bitlbee.c
index 3d8a0310..3f488b46 100644
--- a/bitlbee.c
+++ b/bitlbee.c
@@ -292,6 +292,8 @@ static gboolean bitlbee_io_new_client( gpointer data, gint fd, b_input_condition
get the same random numbers as the parent/siblings. */
srand( time( NULL ) ^ getpid() );
+ b_main_init();
+
/* Close the listening socket, we're a client. */
close( global.listen_socket );
b_event_remove( global.listen_watch_source_id );
diff --git a/bitlbee.conf b/bitlbee.conf
index e5e0f7de..d9f878c8 100644
--- a/bitlbee.conf
+++ b/bitlbee.conf
@@ -19,6 +19,13 @@
##
# RunMode = Inetd
+## User:
+##
+## If BitlBee is started by root as a daemon, it can drop root privileges,
+## and change to the specified user.
+##
+# User = bitlbee
+
## DaemonPort/DaemonInterface:
##
## For daemon mode, you can specify on what interface and port the daemon
diff --git a/conf.c b/conf.c
index 1768866b..e1a44710 100644
--- a/conf.c
+++ b/conf.c
@@ -62,6 +62,7 @@ conf_t *conf_load( int argc, char *argv[] )
conf->motdfile = g_strdup( ETCDIR "/motd.txt" );
conf->ping_interval = 180;
conf->ping_timeout = 300;
+ conf->user = NULL;
conf->max_filetransfer_size = G_MAXUINT;
proxytype = 0;
@@ -76,7 +77,7 @@ conf_t *conf_load( int argc, char *argv[] )
fprintf( stderr, "Warning: Unable to read configuration file `%s'.\n", CONF_FILE );
}
- while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:hR:" ) ) >= 0 )
+ while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:hR:u:" ) ) >= 0 )
/* ^^^^ Just to make sure we skip this step from the REHASH handler. */
{
if( opt == 'i' )
@@ -132,6 +133,7 @@ conf_t *conf_load( int argc, char *argv[] )
" -I Classic/InetD mode. (Default)\n"
" -D Daemon mode. (Still EXPERIMENTAL!)\n"
" -F Forking daemon. (one process per client)\n"
+ " -u Run daemon as specified user.\n"
" -P Specify PID-file (not for inetd mode)\n"
" -i Specify the interface (by IP address) to listen on.\n"
" (Default: 0.0.0.0 (any interface))\n"
@@ -151,6 +153,11 @@ conf_t *conf_load( int argc, char *argv[] )
mode anyway!) */
ipc_master_set_statefile( optarg );
}
+ else if( opt == 'u' )
+ {
+ g_free( conf->user );
+ conf->user = g_strdup( optarg );
+ }
}
if( conf->configdir[strlen(conf->configdir)-1] != '/' )
@@ -192,10 +199,12 @@ static int conf_loadini( conf_t *conf, char *file )
}
else if( g_strcasecmp( ini->key, "daemoninterface" ) == 0 )
{
+ g_free( conf->iface );
conf->iface = g_strdup( ini->value );
}
else if( g_strcasecmp( ini->key, "daemonport" ) == 0 )
{
+ g_free( conf->port );
conf->port = g_strdup( ini->value );
}
else if( g_strcasecmp( ini->key, "authmode" ) == 0 )
@@ -209,14 +218,17 @@ static int conf_loadini( conf_t *conf, char *file )
}
else if( g_strcasecmp( ini->key, "authpassword" ) == 0 )
{
+ g_free( conf->auth_pass );
conf->auth_pass = g_strdup( ini->value );
}
else if( g_strcasecmp( ini->key, "operpassword" ) == 0 )
{
+ g_free( conf->oper_pass );
conf->oper_pass = g_strdup( ini->value );
}
else if( g_strcasecmp( ini->key, "hostname" ) == 0 )
{
+ g_free( conf->hostname );
conf->hostname = g_strdup( ini->value );
}
else if( g_strcasecmp( ini->key, "configdir" ) == 0 )
@@ -281,6 +293,11 @@ static int conf_loadini( conf_t *conf, char *file )
g_free( url );
}
+ else if( g_strcasecmp( ini->key, "user" ) == 0 )
+ {
+ g_free( conf->user );
+ conf->user = g_strdup( ini->value );
+ }
else
{
fprintf( stderr, "Error: Unknown setting `%s` in configuration file.\n", ini->key );
diff --git a/conf.h b/conf.h
index c88c8303..b30d10e2 100644
--- a/conf.h
+++ b/conf.h
@@ -48,6 +48,7 @@ typedef struct conf
char **migrate_storage;
int ping_interval;
int ping_timeout;
+ char *user;
size_t max_filetransfer_size;
} conf_t;
diff --git a/configure b/configure
index b84f3947..15e22623 100755
--- a/configure
+++ b/configure
@@ -134,7 +134,7 @@ EOF
if [ "$debug" = "1" ]; then
[ -z "$CFLAGS" ] && CFLAGS=-g
echo 'DEBUG=1' >> Makefile.settings
- echo '#define DEBUG' >> config.h
+ CFLAGS="$CFLAGS -DDEBUG"
else
[ -z "$CFLAGS" ] && CFLAGS="-O2 -fno-strict-aliasing"
fi
diff --git a/irc.c b/irc.c
index 96f75073..736ae863 100644
--- a/irc.c
+++ b/irc.c
@@ -323,11 +323,22 @@ void irc_process( irc_t *irc )
break;
}
- if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
+ if( ( cs = set_getstr( &irc->set, "charset" ) ) )
{
conv[IRC_MAX_LINE] = 0;
- if( do_iconv( cs, "UTF-8", lines[i], conv, 0, IRC_MAX_LINE - 2 ) != -1 )
- lines[i] = conv;
+ if( do_iconv( cs, "UTF-8", lines[i], conv, 0, IRC_MAX_LINE - 2 ) == -1 )
+ {
+ if( irc->status & USTATUS_LOGGED_IN )
+ irc_usermsg( irc, "ERROR: Charset mismatch detected. The charset "
+ "setting is currently set to %s, so please make "
+ "sure your IRC client will send and accept text in "
+ "that charset, or tell BitlBee which charset to "
+ "expect by changing the charset setting. See "
+ "`help set charset' for more information. Your "
+ "message was ignored.", cs );
+ *conv = 0;
+ }
+ lines[i] = conv;
}
if( ( cmd = irc_parse_line( lines[i] ) ) == NULL )
diff --git a/lib/events.h b/lib/events.h
index 0588547f..4baea7b6 100644
--- a/lib/events.h
+++ b/lib/events.h
@@ -44,7 +44,7 @@
#include <glib.h>
#include <gmodule.h>
-/* The conditions you can pass to gaim_input_add()/that will be passed to
+/* The conditions you can pass to b_input_add()/that will be passed to
the given callback function. */
typedef enum {
GAIM_INPUT_READ = 1 << 1,
@@ -57,7 +57,7 @@ typedef gboolean (*b_event_handler)(gpointer data, gint fd, b_input_condition co
#define GAIM_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL)
#define GAIM_ERR_COND (G_IO_HUP | G_IO_ERR | G_IO_NVAL)
-// #define event_debug( x... ) printf( x )
+/* #define event_debug( x... ) printf( x ) */
#define event_debug( x... )
/* Call this once when the program starts. It'll initialize the event handler
diff --git a/lib/events_libevent.c b/lib/events_libevent.c
index f2b4d15c..d3403152 100644
--- a/lib/events_libevent.c
+++ b/lib/events_libevent.c
@@ -31,12 +31,12 @@
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
-#include "proxy.h"
-
#include <sys/time.h>
#include <event.h>
+#include "proxy.h"
-static guint id_next;
+static void b_main_restart();
+static guint id_next = 1;
static GHashTable *id_hash;
static int quitting = 0;
@@ -47,6 +47,9 @@ static int quitting = 0;
static GHashTable *read_hash;
static GHashTable *write_hash;
+struct event_base *leh;
+struct event_base *old_leh;
+
struct b_event_data
{
guint id;
@@ -58,9 +61,16 @@ struct b_event_data
void b_main_init()
{
- event_init();
+ if( leh != NULL )
+ {
+ /* Clean up the hash tables? */
+
+ b_main_restart();
+ old_leh = leh;
+ }
+
+ leh = event_init();
- id_next = 1;
id_hash = g_hash_table_new( g_int_hash, g_int_equal );
read_hash = g_hash_table_new( g_int_hash, g_int_equal );
write_hash = g_hash_table_new( g_int_hash, g_int_equal );
@@ -68,19 +78,40 @@ void b_main_init()
void b_main_run()
{
- event_dispatch();
+ /* This while loop is necessary to exit the event loop and start a
+ different one (necessary for ForkDaemon mode). */
+ while( event_base_dispatch( leh ) == 0 && !quitting )
+ {
+ if( old_leh != NULL )
+ {
+ /* For some reason this just isn't allowed...
+ Possibly a bug in older versions, will see later.
+ event_base_free( old_leh ); */
+ old_leh = NULL;
+ }
+
+ event_debug( "New event loop.\n" );
+ }
}
-void b_main_quit()
+static void b_main_restart()
{
struct timeval tv;
- /* libevent sometimes generates events before really quitting,
+ memset( &tv, 0, sizeof( struct timeval ) );
+ event_base_loopexit( leh, &tv );
+
+ event_debug( "b_main_restart()\n" );
+}
+
+void b_main_quit()
+{
+ /* Tell b_main_run() that it shouldn't restart the loop. Also,
+ libevent sometimes generates events before really quitting,
we want to stop them. */
quitting = 1;
- memset( &tv, 0, sizeof( struct timeval ) );
- event_loopexit( &tv );
+ b_main_restart();
}
static void b_event_passthrough( int fd, short event, void *data )
diff --git a/protocols/jabber/conference.c b/protocols/jabber/conference.c
index 008bbe63..c5bc0e68 100644
--- a/protocols/jabber/conference.c
+++ b/protocols/jabber/conference.c
@@ -23,6 +23,8 @@
#include "jabber.h"
+static xt_status jabber_chat_join_failed( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );
+
struct groupchat *jabber_chat_join( struct im_connection *ic, char *room, char *nick, char *password )
{
struct jabber_chat *jc;
@@ -34,14 +36,13 @@ struct groupchat *jabber_chat_join( struct im_connection *ic, char *room, char *
node = xt_new_node( "x", NULL, NULL );
xt_add_attr( node, "xmlns", XMLNS_MUC );
node = jabber_make_packet( "presence", NULL, roomjid, node );
+ jabber_cache_add( ic, node, jabber_chat_join_failed );
if( !jabber_write_packet( ic, node ) )
{
g_free( roomjid );
- xt_free_node( node );
return NULL;
}
- xt_free_node( node );
jc = g_new0( struct jabber_chat, 1 );
jc->name = jabber_normalize( room );
@@ -64,6 +65,45 @@ struct groupchat *jabber_chat_join( struct im_connection *ic, char *room, char *
return c;
}
+static xt_status jabber_chat_join_failed( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
+{
+ struct jabber_error *err;
+ struct jabber_buddy *bud;
+ char *room;
+
+ room = xt_find_attr( orig, "to" );
+ if( ( bud = jabber_buddy_by_jid( ic, room, 0 ) ) )
+ jabber_chat_free( jabber_chat_by_jid( ic, bud->bare_jid ) );
+
+ err = jabber_error_parse( xt_find_node( node->children, "error" ), XMLNS_STANZA_ERROR );
+ if( err )
+ {
+ imcb_error( ic, "Error joining groupchat %s: %s%s%s",
+ bud->bare_jid, err->code, err->text ? ": " : "",
+ err->text ? err->text : "" );
+ jabber_error_free( err );
+ }
+
+ return XT_HANDLED;
+}
+
+struct groupchat *jabber_chat_by_jid( struct im_connection *ic, const char *name )
+{
+ char *normalized = jabber_normalize( name );
+ struct groupchat *ret;
+ struct jabber_chat *jc;
+
+ for( ret = ic->groupchats; ret; ret = ret->next )
+ {
+ jc = ret->data;
+ if( strcmp( normalized, jc->name ) == 0 )
+ break;
+ }
+ g_free( normalized );
+
+ return ret;
+}
+
void jabber_chat_free( struct groupchat *c )
{
struct jabber_chat *jc = c->data;
@@ -147,7 +187,7 @@ void jabber_chat_pkt_presence( struct im_connection *ic, struct jabber_buddy *bu
struct jabber_chat *jc;
char *s;
- if( ( chat = jabber_chat_by_name( ic, bud->bare_jid ) ) == NULL )
+ if( ( chat = jabber_chat_by_jid( ic, bud->bare_jid ) ) == NULL )
{
/* How could this happen?? We could do kill( self, 11 )
now or just wait for the OS to do it. :-) */
@@ -249,7 +289,7 @@ void jabber_chat_pkt_message( struct im_connection *ic, struct jabber_buddy *bud
return;
}
- else if( ( chat = jabber_chat_by_name( ic, bud->bare_jid ) ) == NULL )
+ else if( ( chat = jabber_chat_by_jid( ic, bud->bare_jid ) ) == NULL )
{
/* How could this happen?? We could do kill( self, 11 )
now or just wait for the OS to do it. :-) */
diff --git a/protocols/jabber/iq.c b/protocols/jabber/iq.c
index 77def222..8cf6c7f1 100644
--- a/protocols/jabber/iq.c
+++ b/protocols/jabber/iq.c
@@ -30,7 +30,6 @@ static xt_status jabber_iq_display_vcard( struct im_connection *ic, struct xt_no
xt_status jabber_pkt_iq( struct xt_node *node, gpointer data )
{
struct im_connection *ic = data;
- struct jabber_data *jd = ic->proto_data;
struct xt_node *c, *reply = NULL;
char *type, *s;
int st, pack = 1;
@@ -46,23 +45,7 @@ xt_status jabber_pkt_iq( struct xt_node *node, gpointer data )
if( strcmp( type, "result" ) == 0 || strcmp( type, "error" ) == 0 )
{
- struct jabber_cache_entry *entry;
-
- if( ( s = xt_find_attr( node, "id" ) ) == NULL ||
- strncmp( s, jd->cached_id_prefix, strlen( jd->cached_id_prefix ) ) != 0 )
- {
- /* Silently ignore it, without an ID (or a non-cache
- ID) we don't know how to handle the packet and we
- probably don't have to. */
- return XT_HANDLED;
- }
-
- entry = g_hash_table_lookup( jd->node_cache, s );
-
- if( entry == NULL )
- imcb_log( ic, "WARNING: Received IQ-%s packet with unknown/expired ID %s!", type, s );
- else if( entry->func )
- return entry->func( ic, node, entry->node );
+ return jabber_cache_handle_packet( ic, node );
}
else if( strcmp( type, "get" ) == 0 )
{
diff --git a/protocols/jabber/jabber.c b/protocols/jabber/jabber.c
index 1f4f42ea..98d2dadf 100644
--- a/protocols/jabber/jabber.c
+++ b/protocols/jabber/jabber.c
@@ -225,8 +225,6 @@ static void jabber_generate_id_hash( struct jabber_data *jd )
s = base64_encode( binbuf, 9 );
jd->cached_id_prefix = g_strdup_printf( "%s%s", JABBER_CACHED_ID, s );
g_free( s );
-
- printf( "%s\n", jd->cached_id_prefix );
}
static void jabber_logout( struct im_connection *ic )
@@ -271,7 +269,7 @@ static int jabber_buddy_msg( struct im_connection *ic, char *who, char *message,
if( g_strcasecmp( who, JABBER_XMLCONSOLE_HANDLE ) == 0 )
return jabber_write( ic, message, strlen( message ) );
- if( ( s = strchr( who, '=' ) ) && jabber_chat_by_name( ic, s + 1 ) )
+ if( ( s = strchr( who, '=' ) ) && jabber_chat_by_jid( ic, s + 1 ) )
bud = jabber_buddy_by_ext_jid( ic, who, 0 );
else
bud = jabber_buddy_by_jid( ic, who, 0 );
@@ -398,7 +396,7 @@ static struct groupchat *jabber_chat_join_( struct im_connection *ic, char *room
{
if( strchr( room, '@' ) == NULL )
imcb_error( ic, "Invalid room name: %s", room );
- else if( jabber_chat_by_name( ic, room ) )
+ else if( jabber_chat_by_jid( ic, room ) )
imcb_error( ic, "Already present in chat `%s'", room );
else
return jabber_chat_join( ic, room, nick, password );
diff --git a/protocols/jabber/jabber.h b/protocols/jabber/jabber.h
index 45082fee..c518f541 100644
--- a/protocols/jabber/jabber.h
+++ b/protocols/jabber/jabber.h
@@ -226,6 +226,7 @@ void jabber_cache_add( struct im_connection *ic, struct xt_node *node, jabber_ca
struct xt_node *jabber_cache_get( struct im_connection *ic, char *id );
void jabber_cache_entry_free( gpointer entry );
void jabber_cache_clean( struct im_connection *ic );
+xt_status jabber_cache_handle_packet( struct im_connection *ic, struct xt_node *node );
const struct jabber_away_state *jabber_away_state_by_code( char *code );
const struct jabber_away_state *jabber_away_state_by_name( char *name );
void jabber_buddy_ask( struct im_connection *ic, char *handle );
@@ -248,7 +249,6 @@ struct jabber_buddy *jabber_buddy_by_jid( struct im_connection *ic, char *jid, g
struct jabber_buddy *jabber_buddy_by_ext_jid( struct im_connection *ic, char *jid, get_buddy_flags_t flags );
int jabber_buddy_remove( struct im_connection *ic, char *full_jid );
int jabber_buddy_remove_bare( struct im_connection *ic, char *bare_jid );
-struct groupchat *jabber_chat_by_name( struct im_connection *ic, const char *name );
time_t jabber_get_timestamp( struct xt_node *xt );
struct jabber_error *jabber_error_parse( struct xt_node *node, char *xmlns );
void jabber_error_free( struct jabber_error *err );
@@ -271,6 +271,7 @@ gboolean sasl_supported( struct im_connection *ic );
/* conference.c */
struct groupchat *jabber_chat_join( struct im_connection *ic, char *room, char *nick, char *password );
+struct groupchat *jabber_chat_by_jid( struct im_connection *ic, const char *name );
void jabber_chat_free( struct groupchat *c );
int jabber_chat_msg( struct groupchat *ic, char *message, int flags );
int jabber_chat_topic( struct groupchat *c, char *topic );
diff --git a/protocols/jabber/jabber_util.c b/protocols/jabber/jabber_util.c
index 6bb65878..7350eaf4 100644
--- a/protocols/jabber/jabber_util.c
+++ b/protocols/jabber/jabber_util.c
@@ -184,6 +184,36 @@ gboolean jabber_cache_clean_entry( gpointer key, gpointer entry_, gpointer nullp
}
}
+xt_status jabber_cache_handle_packet( struct im_connection *ic, struct xt_node *node )
+{
+ struct jabber_data *jd = ic->proto_data;
+ struct jabber_cache_entry *entry;
+ char *s;
+
+ if( ( s = xt_find_attr( node, "id" ) ) == NULL ||
+ strncmp( s, jd->cached_id_prefix, strlen( jd->cached_id_prefix ) ) != 0 )
+ {
+ /* Silently ignore it, without an ID (or a non-cache
+ ID) we don't know how to handle the packet and we
+ probably don't have to. */
+ return XT_HANDLED;
+ }
+
+ entry = g_hash_table_lookup( jd->node_cache, s );
+
+ if( entry == NULL )
+ {
+ imcb_log( ic, "WARNING: Received %s-%s packet with unknown/expired ID %s!",
+ node->name, xt_find_attr( node, "type" ) ? : "(no type)", s );
+ }
+ else if( entry->func )
+ {
+ return entry->func( ic, node, entry->node );
+ }
+
+ return XT_HANDLED;
+}
+
const struct jabber_away_state jabber_away_state_list[] =
{
{ "away", "Away" },
@@ -594,23 +624,6 @@ int jabber_buddy_remove_bare( struct im_connection *ic, char *bare_jid )
}
}
-struct groupchat *jabber_chat_by_name( struct im_connection *ic, const char *name )
-{
- char *normalized = jabber_normalize( name );
- struct groupchat *ret;
- struct jabber_chat *jc;
-
- for( ret = ic->groupchats; ret; ret = ret->next )
- {
- jc = ret->data;
- if( strcmp( normalized, jc->name ) == 0 )
- break;
- }
- g_free( normalized );
-
- return ret;
-}
-
time_t jabber_get_timestamp( struct xt_node *xt )
{
struct tm tp, utc;
@@ -662,10 +675,14 @@ time_t jabber_get_timestamp( struct xt_node *xt )
struct jabber_error *jabber_error_parse( struct xt_node *node, char *xmlns )
{
- struct jabber_error *err = g_new0( struct jabber_error, 1 );
+ struct jabber_error *err;
struct xt_node *c;
char *s;
+ if( node == NULL )
+ return NULL;
+
+ err = g_new0( struct jabber_error, 1 );
err->type = xt_find_attr( node, "type" );
for( c = node->children; c; c = c->next )
diff --git a/protocols/jabber/presence.c b/protocols/jabber/presence.c
index 5abdc449..c3d7dced 100644
--- a/protocols/jabber/presence.c
+++ b/protocols/jabber/presence.c
@@ -39,7 +39,7 @@ xt_status jabber_pkt_presence( struct xt_node *node, gpointer data )
if( ( s = strchr( from, '/' ) ) )
{
*s = 0;
- if( jabber_chat_by_name( ic, from ) )
+ if( jabber_chat_by_jid( ic, from ) )
is_chat = 1;
*s = '/';
}
@@ -163,8 +163,10 @@ xt_status jabber_pkt_presence( struct xt_node *node, gpointer data )
}
else if( strcmp( type, "error" ) == 0 )
{
- struct jabber_error *err;
+ return jabber_cache_handle_packet( ic, node );
+ /*
+ struct jabber_error *err;
if( ( c = xt_find_node( node->children, "error" ) ) )
{
err = jabber_error_parse( c, XMLNS_STANZA_ERROR );
@@ -172,8 +174,7 @@ xt_status jabber_pkt_presence( struct xt_node *node, gpointer data )
err->code, err->text ? ": " : "",
err->text ? err->text : "" );
jabber_error_free( err );
- }
- /* What else to do with it? */
+ } */
}
return XT_HANDLED;
diff --git a/protocols/oscar/msgcookie.c b/protocols/oscar/msgcookie.c
index d3c91a94..efeb8cbf 100644
--- a/protocols/oscar/msgcookie.c
+++ b/protocols/oscar/msgcookie.c
@@ -130,21 +130,6 @@ aim_msgcookie_t *aim_checkcookie(aim_session_t *sess, const guint8 *cookie, int
return NULL;
}
-#if 0 /* debugging feature */
-int aim_dumpcookie(aim_msgcookie_t *cookie)
-{
-
- if (!cookie)
- return -EINVAL;
-
- printf("\tCookie at %p: %d/%s with %p, next %p\n",
- cookie, cookie->type, cookie->cookie,
- cookie->data, cookie->next);
-
- return 0;
-}
-#endif
-
/**
* aim_cookie_free - free an aim_msgcookie_t struct
* @sess: session to remove the cookie from
diff --git a/unix.c b/unix.c
index 0abf43ea..75ffcf95 100644
--- a/unix.c
+++ b/unix.c
@@ -33,6 +33,7 @@
#include <unistd.h>
#include <sys/time.h>
#include <sys/wait.h>
+#include <pwd.h>
global_t global; /* Against global namespace pollution */
@@ -44,8 +45,6 @@ int main( int argc, char *argv[], char **envp )
char *old_cwd = NULL;
struct sigaction sig, old;
- memset( &global, 0, sizeof( global_t ) );
-
log_init();
CONF_FILE = g_strdup( CONF_FILE_DEF );
global.conf = conf_load( argc, argv );
@@ -86,12 +85,26 @@ int main( int argc, char *argv[], char **envp )
if( i != 0 )
return( i );
+ if( ( global.conf->user && *global.conf->user ) &&
+ ( global.conf->runmode == RUNMODE_DAEMON ||
+ global.conf->runmode == RUNMODE_FORKDAEMON ) &&
+ ( !getuid() || !geteuid() ) )
+ {
+ struct passwd *pw = NULL;
+ pw = getpwnam( global.conf->user );
+ if( pw )
+ {
+ setgid( pw->pw_gid );
+ setuid( pw->pw_uid );
+ }
+ }
+
global.storage = storage_init( global.conf->primary_storage, global.conf->migrate_storage );
- if ( global.storage == NULL) {
+ if( global.storage == NULL )
+ {
log_message( LOGLVL_ERROR, "Unable to load storage backend '%s'", global.conf->primary_storage );
return( 1 );
}
-
/* Catch some signals to tell the user what's happening before quitting */
memset( &sig, 0, sizeof( sig ) );