2002-09-04 08:40:29 +00:00
/* NeoStats - IRC Statistical Services
2004-01-14 11:36:37 +00:00
* * Copyright ( c ) 1999 - 2004 Adam Rutter , Justin Hammond
2002-09-04 08:40:29 +00:00
* * http : //www.neostats.net/
* *
* * Portions Copyright ( c ) 2000 - 2001 ^ Enigma ^
* *
* * This program is free software ; you can redistribute it and / or modify
* * it under the terms of the GNU General Public License as published by
* * the Free Software Foundation ; either version 2 of the License , or
* * ( at your option ) any later version .
* *
* * This program is distributed in the hope that it will be useful ,
* * but WITHOUT ANY WARRANTY ; without even the implied warranty of
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* * GNU General Public License for more details .
* *
* * You should have received a copy of the GNU General Public License
* * along with this program ; if not , write to the Free Software
* * Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307
* * USA
* *
* * NeoStats CVS Identification
2003-09-22 15:04:15 +00:00
* * $ Id $
2002-02-28 04:49:10 +00:00
*/
2000-02-03 23:45:51 +00:00
2003-10-10 23:07:30 +00:00
/** @file dl.c
* @ brief module functions
*/
2000-02-03 23:45:51 +00:00
# include <dlfcn.h>
# include <stdio.h>
# include <stdlib.h>
2003-11-05 15:00:12 +00:00
# include "stats.h"
2000-02-03 23:45:51 +00:00
# include "dl.h"
2002-02-28 07:54:13 +00:00
# include "hash.h"
2000-03-29 13:05:57 +00:00
# include "config.h"
2003-04-11 09:26:31 +00:00
# include "log.h"
2004-02-21 07:22:02 +00:00
# include "dns.h"
2003-12-30 11:28:27 +00:00
# ifdef SQLSRV
# include "sqlsrv/rta.h"
# endif
2003-04-11 09:26:31 +00:00
2004-01-23 22:39:09 +00:00
# define MAX_CMD_LINE_LENGTH 350
2003-11-03 13:57:11 +00:00
/** @brief Module list
2003-10-10 23:07:30 +00:00
*
*/
2003-11-03 13:57:11 +00:00
Module * ModList [ NUM_MODULES ] ;
2003-10-10 23:07:30 +00:00
2003-11-18 11:51:09 +00:00
char segv_location [ SEGV_LOCATION_BUFSIZE ] ;
char segv_inmodule [ SEGV_INMODULE_BUFSIZE ] ;
2003-11-28 20:50:40 +00:00
int del_all_bot_cmds ( ModUser * bot_ptr ) ;
2003-11-18 11:51:09 +00:00
/* @brief Module hash list */
static hash_t * mh ;
/* @brief Module Socket List hash */
hash_t * sockh ;
/* @brief Module Timer hash list */
static hash_t * th ;
/* @brief Module Bot hash list */
static hash_t * bh ;
/* @brief Module Chan Bot hash list */
static hash_t * bch ;
2003-12-30 11:28:27 +00:00
# ifdef SQLSRV
char sqlbuf [ BUFSIZE ] ;
void * display_module_name ( void * tbl , char * col , char * sql , void * row ) {
Module * mod_ptr = row ;
strlcpy ( sqlbuf , mod_ptr - > info - > module_name , MAX_MOD_NAME ) ;
return sqlbuf ;
}
void * display_module_desc ( void * tbl , char * col , char * sql , void * row ) {
Module * mod_ptr = row ;
strlcpy ( sqlbuf , mod_ptr - > info - > module_description , BUFSIZE ) ;
return sqlbuf ;
}
void * display_module_version ( void * tbl , char * col , char * sql , void * row ) {
Module * mod_ptr = row ;
if ( mod_ptr - > isnewstyle = = 1 ) {
strlcpy ( sqlbuf , mod_ptr - > info - > module_version , BUFSIZE ) ;
return sqlbuf ;
} else {
bzero ( sqlbuf , BUFSIZE ) ;
return sqlbuf ;
}
}
void * display_module_builddate ( void * tbl , char * col , char * sql , void * row ) {
Module * mod_ptr = row ;
if ( mod_ptr - > isnewstyle = = 1 ) {
ircsnprintf ( sqlbuf , BUFSIZE , " %s - %s " , mod_ptr - > info - > module_build_date , mod_ptr - > info - > module_build_time ) ;
return sqlbuf ;
} else {
bzero ( sqlbuf , BUFSIZE ) ;
return sqlbuf ;
}
}
void * display_core_info ( void * tbl , char * col , char * sql , void * row ) {
2004-02-20 15:43:28 +00:00
ircsnprintf ( sqlbuf , BUFSIZE , " %s " , me . versionfull ) ;
2003-12-30 11:28:27 +00:00
return sqlbuf ;
}
COLDEF neo_modulecols [ ] = {
{
" modules " ,
" name " ,
RTA_STR ,
MAX_MOD_NAME ,
offsetof ( struct Module , info ) ,
RTA_READONLY ,
display_module_name ,
NULL ,
" The name of the Module "
} ,
{
" modules " ,
" description " ,
RTA_STR ,
BUFSIZE ,
offsetof ( struct Module , info ) ,
RTA_READONLY ,
display_module_desc ,
NULL ,
" The Module Description "
} ,
{
" modules " ,
" version " ,
RTA_STR ,
BUFSIZE ,
offsetof ( struct Module , info ) ,
RTA_READONLY ,
display_module_version ,
NULL ,
" The module version "
} ,
{
" modules " ,
" builddate " ,
RTA_STR ,
BUFSIZE ,
offsetof ( struct Module , info ) ,
RTA_READONLY ,
display_module_builddate ,
NULL ,
" The module build date "
} ,
{
" modules " ,
" coreinfo " ,
RTA_STR ,
BUFSIZE ,
offsetof ( struct Module , info ) ,
RTA_READONLY ,
display_core_info ,
NULL ,
" The NeoStats core Version "
} ,
} ;
TBLDEF neo_modules = {
" modules " ,
NULL , /* for now */
sizeof ( struct Module ) ,
0 ,
TBL_HASH ,
neo_modulecols ,
sizeof ( neo_modulecols ) / sizeof ( COLDEF ) ,
" " ,
" The list of Modules loaded by NeoStats "
} ;
# endif /* SQLSRV */
2004-02-02 20:19:17 +00:00
void * ns_dlsym ( void * handle , const char * name )
{
# ifdef NEED_UNDERSCORE_PREFIX
char sym [ 128 ] ;
void * ret ;
ret = dlsym ( ( int * ) handle , name ) ;
if ( ret = = NULL ) {
ircsnprintf ( sym , 128 , " _%s " , name ) ;
return ( dlsym ( ( int * ) handle , sym ) ) ;
}
return ret ;
# else
return ( dlsym ( ( int * ) handle , name ) ) ;
# endif
}
2003-12-30 11:28:27 +00:00
2004-02-02 20:19:17 +00:00
void * ns_dlopen ( const char * file , int mode )
{
return ( dlopen ( file , mode ) ) ;
}
2003-12-30 11:28:27 +00:00
2004-02-02 20:19:17 +00:00
int ns_dlclose ( void * handle )
{
return ( dlclose ( handle ) ) ;
}
char * ns_dlerror ( void )
{
2004-02-04 18:47:24 +00:00
return ( ( char * ) dlerror ( ) ) ;
2004-02-02 20:19:17 +00:00
}
2003-12-30 11:28:27 +00:00
2003-10-07 15:00:03 +00:00
/** @brief Initialise module list hashes
*
* For core use only , initialises module list hashes
*
* @ param none
*
* @ return none
*/
2003-10-14 15:03:55 +00:00
int
2003-11-18 11:51:09 +00:00
InitModuleHash ( )
2003-06-13 13:11:50 +00:00
{
2003-09-18 12:21:32 +00:00
SET_SEGV_LOCATION ( ) ;
2003-07-30 13:58:22 +00:00
mh = hash_create ( NUM_MODULES , 0 , 0 ) ;
2003-10-14 15:03:55 +00:00
if ( ! mh )
return NS_FAILURE ;
2003-07-30 13:58:22 +00:00
bh = hash_create ( B_TABLE_SIZE , 0 , 0 ) ;
2003-10-14 15:03:55 +00:00
if ( ! bh )
return NS_FAILURE ;
2003-07-30 13:58:22 +00:00
th = hash_create ( T_TABLE_SIZE , 0 , 0 ) ;
2003-10-14 15:03:55 +00:00
if ( ! th )
return NS_FAILURE ;
2003-07-30 13:58:22 +00:00
bch = hash_create ( C_TABLE_SIZE , 0 , 0 ) ;
2003-10-14 15:03:55 +00:00
if ( ! bch )
return NS_FAILURE ;
2003-07-30 13:58:22 +00:00
sockh = hash_create ( me . maxsocks , 0 , 0 ) ;
2003-10-14 15:03:55 +00:00
if ( ! sockh )
return NS_FAILURE ;
2003-12-30 11:28:27 +00:00
# ifdef SQLSRV
/* add the module hash to the sql library */
neo_modules . address = mh ;
rta_add_table ( & neo_modules ) ;
# endif
2003-10-14 15:03:55 +00:00
return NS_SUCCESS ;
2002-03-18 05:46:15 +00:00
}
2000-02-22 03:32:32 +00:00
2004-01-31 06:26:56 +00:00
void finiModuleHash ( ) {
hash_destroy ( mh ) ;
hash_destroy ( bh ) ;
hash_destroy ( th ) ;
hash_destroy ( bch ) ;
hash_destroy ( sockh ) ;
}
2003-11-18 11:51:09 +00:00
# ifdef DEBUG
void verify_hashes ( void )
{
if ( hash_verify ( sockh ) = = 0 ) {
nlog ( LOG_CRITICAL , LOG_CORE , " Eeeek, Corruption of the socket hash " ) ;
}
if ( hash_verify ( mh ) = = 0 ) {
nlog ( LOG_CRITICAL , LOG_CORE , " Eeeek, Corruption of the Module hash " ) ;
}
if ( hash_verify ( bh ) = = 0 ) {
nlog ( LOG_CRITICAL , LOG_CORE , " Eeeek, Corruption of the Bot hash " ) ;
}
if ( hash_verify ( th ) = = 0 ) {
nlog ( LOG_CRITICAL , LOG_CORE , " Eeeek, Corruption of the Timer hash " ) ;
}
}
# endif /* DEBUG */
2003-10-07 15:00:03 +00:00
/** @brief create new timer
2003-10-06 16:33:42 +00:00
*
2003-10-07 15:00:03 +00:00
* For core use only , creates a timer
*
* @ param timer_name the name of new timer
*
* @ return pointer to new timer on success , NULL on error
*/
2003-11-18 11:51:09 +00:00
static ModTimer *
2003-07-30 13:58:22 +00:00
new_timer ( char * timer_name )
2000-02-22 03:32:32 +00:00
{
2003-11-18 11:51:09 +00:00
ModTimer * mod_tmr ;
2002-02-28 07:54:13 +00:00
hnode_t * tn ;
2003-09-23 11:57:07 +00:00
2003-09-18 12:21:32 +00:00
SET_SEGV_LOCATION ( ) ;
2004-01-14 22:50:24 +00:00
nlog ( LOG_DEBUG2 , LOG_CORE , " new_timer: %s " , timer_name ) ;
2003-11-18 11:51:09 +00:00
mod_tmr = malloc ( sizeof ( ModTimer ) ) ;
2003-11-23 21:36:35 +00:00
strlcpy ( mod_tmr - > timername , timer_name , MAX_MOD_NAME ) ;
2003-11-18 11:51:09 +00:00
tn = hnode_create ( mod_tmr ) ;
2003-07-30 13:58:22 +00:00
if ( hash_isfull ( th ) ) {
2004-01-14 22:50:24 +00:00
nlog ( LOG_WARNING , LOG_CORE , " new_timer: couldn't add new timer, hash is full! " ) ;
2002-02-28 07:54:13 +00:00
return NULL ;
}
2003-11-03 13:57:11 +00:00
hash_insert ( th , tn , timer_name ) ;
2003-11-18 11:51:09 +00:00
return mod_tmr ;
2000-02-22 03:32:32 +00:00
}
2003-10-07 15:00:03 +00:00
/** @brief find timer
2003-10-06 16:33:42 +00:00
*
2003-10-07 15:00:03 +00:00
* For core use only , finds a timer in the current list of timers
*
* @ param timer_name the name of timer to find
*
* @ return pointer to timer if found , NULL if not found
*/
2003-11-18 11:51:09 +00:00
ModTimer *
2003-07-30 13:58:22 +00:00
findtimer ( char * timer_name )
2003-06-13 13:11:50 +00:00
{
2002-02-28 07:54:13 +00:00
hnode_t * tn ;
2003-06-13 13:11:50 +00:00
2003-07-30 13:58:22 +00:00
tn = hash_lookup ( th , timer_name ) ;
2003-06-13 13:11:50 +00:00
if ( tn )
2003-11-18 11:51:09 +00:00
return ( ModTimer * ) hnode_get ( tn ) ;
2002-02-28 07:54:13 +00:00
return NULL ;
2000-02-22 03:32:32 +00:00
}
2003-07-30 13:58:22 +00:00
2003-10-07 15:00:03 +00:00
/** @brief add a timer to the timer list
2003-10-06 16:33:42 +00:00
*
2003-10-07 15:00:03 +00:00
* For module use . Adds a timer with the given function to the timer list
*
* @ param func_name the name of function to register with this timer
* @ param timer_name the name of timer to register
* @ param mod_name the name of module registering the timer
* @ param interval the interval at which the timer triggers in seconds
*
2003-11-03 13:57:11 +00:00
* @ return NS_SUCCESS if added , NS_FAILURE if not
2003-10-07 15:00:03 +00:00
*/
2003-07-30 13:58:22 +00:00
int
add_mod_timer ( char * func_name , char * timer_name , char * mod_name , int interval )
2003-06-13 13:11:50 +00:00
{
2003-11-18 11:51:09 +00:00
ModTimer * mod_tmr ;
2000-02-03 23:45:51 +00:00
2003-09-18 12:21:32 +00:00
SET_SEGV_LOCATION ( ) ;
2004-02-02 20:19:17 +00:00
if ( ns_dlsym ( ( int * ) get_dl_handle ( mod_name ) , func_name ) = = NULL ) {
2003-12-07 21:36:59 +00:00
nlog ( LOG_WARNING , LOG_CORE , " %s: Timer %s Function %s doesn't exist " , mod_name , timer_name , func_name ) ;
2003-11-03 13:57:11 +00:00
return NS_FAILURE ;
2003-07-30 13:58:22 +00:00
}
2003-11-18 11:51:09 +00:00
mod_tmr = new_timer ( timer_name ) ;
if ( mod_tmr ) {
mod_tmr - > interval = interval ;
mod_tmr - > lastrun = me . now ;
strlcpy ( mod_tmr - > modname , mod_name , MAX_MOD_NAME ) ;
2004-02-02 20:19:17 +00:00
mod_tmr - > function = ns_dlsym ( ( int * ) get_dl_handle ( mod_name ) , func_name ) ;
2004-01-14 22:50:24 +00:00
nlog ( LOG_DEBUG2 , LOG_CORE , " add_mod_timer: Registered Module %s with timer for Function %s " , mod_name , func_name ) ;
2003-11-03 13:57:11 +00:00
return NS_SUCCESS ;
2002-02-28 07:54:13 +00:00
}
2003-11-03 13:57:11 +00:00
return NS_FAILURE ;
2000-02-03 23:45:51 +00:00
}
2003-10-07 15:00:03 +00:00
/** @brief delete a timer from the timer list
2003-10-06 16:33:42 +00:00
*
2003-10-07 15:00:03 +00:00
* For module use . Deletes a timer with the given name from the timer list
*
* @ param timer_name the name of timer to delete
*
2003-11-03 13:57:11 +00:00
* @ return NS_SUCCESS if deleted , NS_FAILURE if not found
2003-10-07 15:00:03 +00:00
*/
2003-07-30 13:58:22 +00:00
int
del_mod_timer ( char * timer_name )
2003-06-13 13:11:50 +00:00
{
2003-11-18 11:51:09 +00:00
ModTimer * mod_tmr ;
2002-02-28 07:54:13 +00:00
hnode_t * tn ;
2003-10-06 16:33:42 +00:00
2003-09-18 12:21:32 +00:00
SET_SEGV_LOCATION ( ) ;
2003-07-30 13:58:22 +00:00
tn = hash_lookup ( th , timer_name ) ;
2002-02-28 07:54:13 +00:00
if ( tn ) {
2003-11-18 11:51:09 +00:00
mod_tmr = hnode_get ( tn ) ;
2004-01-14 22:50:24 +00:00
nlog ( LOG_DEBUG2 , LOG_CORE , " del_mod_timer: Unregistered Timer function %s from Module %s " , timer_name , mod_tmr - > modname ) ;
2003-07-30 13:58:22 +00:00
hash_delete ( th , tn ) ;
hnode_destroy ( tn ) ;
2003-11-18 11:51:09 +00:00
free ( mod_tmr ) ;
2003-11-03 13:57:11 +00:00
return NS_SUCCESS ;
2003-06-13 13:11:50 +00:00
}
2003-11-03 13:57:11 +00:00
return NS_FAILURE ;
2000-02-03 23:45:51 +00:00
}
2003-12-14 21:57:45 +00:00
/** @brief delete all timers from the timer list for given module
*
* For core use .
*
* @ param
*
* @ return NS_SUCCESS if deleted , NS_FAILURE if not found
*/
int
del_mod_timers ( char * module_name )
{
ModTimer * mod_tmr ;
hnode_t * modnode ;
hscan_t hscan ;
hash_scan_begin ( & hscan , th ) ;
while ( ( modnode = hash_scan_next ( & hscan ) ) ! = NULL ) {
mod_tmr = hnode_get ( modnode ) ;
2004-01-27 13:32:54 +00:00
if ( ! ircstrcasecmp ( mod_tmr - > modname , module_name ) ) {
2004-01-14 22:50:24 +00:00
nlog ( LOG_DEBUG1 , LOG_CORE , " del_mod_timers: Module %s has timer %s Registered. Deleting.. " , module_name , mod_tmr - > timername ) ;
2003-12-14 21:57:45 +00:00
del_mod_timer ( mod_tmr - > timername ) ;
}
}
return NS_SUCCESS ;
}
2003-11-20 22:23:03 +00:00
/** @brief delete a timer from the timer list
*
* For module use . Deletes a timer with the given name from the timer list
*
* @ param timer_name the name of timer to delete
*
* @ return NS_SUCCESS if deleted , NS_FAILURE if not found
*/
int
change_mod_timer_interval ( char * timer_name , int interval )
{
ModTimer * mod_tmr ;
hnode_t * tn ;
SET_SEGV_LOCATION ( ) ;
tn = hash_lookup ( th , timer_name ) ;
if ( tn ) {
mod_tmr = hnode_get ( tn ) ;
mod_tmr - > interval = interval ;
2004-01-14 22:50:24 +00:00
nlog ( LOG_DEBUG2 , LOG_CORE , " change_mod_timer_interval: Changing timer interval for %s from Module %s " , timer_name , mod_tmr - > modname ) ;
2003-11-20 22:23:03 +00:00
return NS_SUCCESS ;
}
return NS_FAILURE ;
}
2003-10-07 15:00:03 +00:00
/** @brief list timers in use
2003-10-06 16:33:42 +00:00
*
2003-10-07 15:00:03 +00:00
* NeoStats command to list the current timers from IRC
*
* @ param u pointer to user structure of the user issuing the request
*
* @ return none
*/
2003-11-27 22:49:10 +00:00
int
2003-11-18 11:51:09 +00:00
list_timers ( User * u , char * * av , int ac )
2003-06-13 13:11:50 +00:00
{
2003-11-18 11:51:09 +00:00
ModTimer * mod_tmr = NULL ;
2002-02-28 07:54:13 +00:00
hscan_t ts ;
hnode_t * tn ;
2003-09-18 12:21:32 +00:00
SET_SEGV_LOCATION ( ) ;
2003-07-30 13:58:22 +00:00
prefmsg ( u - > nick , s_Services , " Module timer List: " ) ;
hash_scan_begin ( & ts , th ) ;
while ( ( tn = hash_scan_next ( & ts ) ) ! = NULL ) {
2003-11-18 11:51:09 +00:00
mod_tmr = hnode_get ( tn ) ;
prefmsg ( u - > nick , s_Services , " %s:-------------------------------- " , mod_tmr - > modname ) ;
prefmsg ( u - > nick , s_Services , " Module Timer Name: %s " , mod_tmr - > timername ) ;
prefmsg ( u - > nick , s_Services , " Module Interval: %d " , mod_tmr - > interval ) ;
2004-02-04 18:47:24 +00:00
prefmsg ( u - > nick , s_Services , " Time till next Run: %ld " , ( long ) ( mod_tmr - > interval - ( me . now - mod_tmr - > lastrun ) ) ) ;
2003-07-30 13:58:22 +00:00
}
prefmsg ( u - > nick , s_Services , " End of Module timer List " ) ;
2003-11-27 22:49:10 +00:00
return 0 ;
2003-06-13 13:11:50 +00:00
}
2000-03-02 01:31:24 +00:00
2003-11-18 11:51:09 +00:00
/** @brief run pending module timer functions
*
* NeoStats command to run pending timer functions
*
* @ param none
*
* @ return none
*/
void
run_mod_timers ( void )
{
ModTimer * mod_tmr = NULL ;
hscan_t ts ;
hnode_t * tn ;
/* First, lets see if any modules have a function that is due to run..... */
hash_scan_begin ( & ts , th ) ;
while ( ( tn = hash_scan_next ( & ts ) ) ! = NULL ) {
SET_SEGV_LOCATION ( ) ;
mod_tmr = hnode_get ( tn ) ;
if ( me . now - mod_tmr - > lastrun > mod_tmr - > interval ) {
strlcpy ( segv_location , mod_tmr - > modname , SEGV_LOCATION_BUFSIZE ) ;
if ( setjmp ( sigvbuf ) = = 0 ) {
2004-01-30 21:27:43 +00:00
SET_SEGV_INMODULE ( mod_tmr - > modname ) ;
2004-02-19 22:03:55 +00:00
nlog ( LOG_DEBUG3 , LOG_CORE , " run_mod_timers: Running timer %s for module %s " , mod_tmr - > timername , mod_tmr - > modname ) ;
2003-11-18 11:51:09 +00:00
if ( mod_tmr - > function ( ) < 0 ) {
2004-01-14 22:50:24 +00:00
nlog ( LOG_DEBUG2 , LOG_CORE , " run_mod_timers: Deleting Timer %s for Module %s as requested " , mod_tmr - > timername , mod_tmr - > modname ) ;
2003-11-18 11:51:09 +00:00
hash_scan_delete ( th , tn ) ;
hnode_destroy ( tn ) ;
free ( mod_tmr ) ;
} else {
mod_tmr - > lastrun = ( int ) me . now ;
}
2004-01-30 21:27:43 +00:00
CLEAR_SEGV_INMODULE ( ) ;
2003-11-18 11:51:09 +00:00
} else {
2004-01-14 22:50:24 +00:00
nlog ( LOG_CRITICAL , LOG_CORE , " run_mod_timers: setjmp() failed, can't call module %s \n " , mod_tmr - > modname ) ;
2003-11-18 11:51:09 +00:00
}
}
}
}
2003-10-07 15:00:03 +00:00
/** @brief create a new socket
2003-10-06 16:33:42 +00:00
*
2003-10-07 15:00:03 +00:00
* For core use only , creates a new socket for a module
*
* @ param sock_name the name of the socket to create
*
* @ return pointer to created socket on success , NULL on error
*/
2003-11-18 11:51:09 +00:00
static ModSock *
2003-07-30 13:58:22 +00:00
new_sock ( char * sock_name )
2000-03-02 01:31:24 +00:00
{
2003-11-18 11:51:09 +00:00
ModSock * mod_sock ;
2002-02-28 07:54:13 +00:00
hnode_t * sn ;
2002-02-28 04:49:10 +00:00
2003-09-18 12:21:32 +00:00
SET_SEGV_LOCATION ( ) ;
2004-01-14 22:50:24 +00:00
nlog ( LOG_DEBUG2 , LOG_CORE , " new_sock: %s " , sock_name ) ;
2003-11-18 11:51:09 +00:00
mod_sock = smalloc ( sizeof ( ModSock ) ) ;
2003-11-23 21:36:35 +00:00
strlcpy ( mod_sock - > sockname , sock_name , MAX_MOD_NAME ) ;
2003-11-18 11:51:09 +00:00
sn = hnode_create ( mod_sock ) ;
2003-07-30 13:58:22 +00:00
if ( hash_isfull ( sockh ) ) {
2004-01-14 22:50:24 +00:00
nlog ( LOG_CRITICAL , LOG_CORE , " new_sock: socket hash is full, can't add a new socket " ) ;
2002-02-28 07:54:13 +00:00
return NULL ;
}
2003-11-18 11:51:09 +00:00
hash_insert ( sockh , sn , mod_sock - > sockname ) ;
return mod_sock ;
2000-03-02 01:31:24 +00:00
}
2003-10-10 23:07:30 +00:00
/** \fn @brief find socket
2003-10-06 16:33:42 +00:00
*
2003-10-07 15:00:03 +00:00
* For core use only , finds a socket in the current list of socket
*
* @ param sock_name the name of socket to find
*
* @ return pointer to socket if found , NULL if not found
2003-10-10 23:07:30 +00:00
*/
2003-11-18 11:51:09 +00:00
ModSock *
2003-07-30 13:58:22 +00:00
findsock ( char * sock_name )
2003-06-13 13:11:50 +00:00
{
2002-02-28 07:54:13 +00:00
hnode_t * sn ;
2003-10-06 16:33:42 +00:00
2003-07-30 13:58:22 +00:00
sn = hash_lookup ( sockh , sock_name ) ;
2003-06-13 13:11:50 +00:00
if ( sn )
2003-07-30 13:58:22 +00:00
return hnode_get ( sn ) ;
2002-02-28 07:54:13 +00:00
return NULL ;
2000-03-02 01:31:24 +00:00
}
2002-02-28 07:54:13 +00:00
2003-10-07 15:00:03 +00:00
/** @brief add a socket to the socket list
2003-10-06 16:33:42 +00:00
*
2003-10-07 15:00:03 +00:00
* For core use . Adds a socket with the given functions to the socket list
*
* @ param readfunc the name of read function to register with this socket
* @ param writefunc the name of write function to register with this socket
* @ param errfunc the name of error function to register with this socket
* @ param sock_name the name of socket to register
* @ param socknum the socket number to register with this socket
* @ param mod_name the name of module registering the socket
*
* @ return pointer to socket if found , NULL if not found
*/
2003-07-30 13:58:22 +00:00
int
add_socket ( char * readfunc , char * writefunc , char * errfunc , char * sock_name , int socknum , char * mod_name )
2003-06-13 13:11:50 +00:00
{
2003-11-18 11:51:09 +00:00
ModSock * mod_sock ;
2000-03-02 01:31:24 +00:00
2003-09-18 12:21:32 +00:00
SET_SEGV_LOCATION ( ) ;
2002-07-30 04:26:28 +00:00
if ( readfunc ) {
2004-02-02 20:19:17 +00:00
if ( ns_dlsym ( ( int * ) get_dl_handle ( mod_name ) , readfunc ) = = NULL ) {
2004-01-14 22:50:24 +00:00
nlog ( LOG_WARNING , LOG_CORE , " add_socket: read socket function doesn't exist = %s (%s) " , readfunc , mod_name ) ;
2003-11-03 13:57:11 +00:00
return NS_FAILURE ;
2002-07-30 04:26:28 +00:00
}
}
if ( writefunc ) {
2004-02-02 20:19:17 +00:00
if ( ns_dlsym ( ( int * ) get_dl_handle ( mod_name ) , writefunc ) = = NULL ) {
2004-01-14 22:50:24 +00:00
nlog ( LOG_WARNING , LOG_CORE , " add_socket: write socket function doesn't exist = %s (%s) " , writefunc , mod_name ) ;
2003-11-03 13:57:11 +00:00
return NS_FAILURE ;
2002-07-30 04:26:28 +00:00
}
2002-02-28 07:54:13 +00:00
}
2002-07-30 04:26:28 +00:00
if ( errfunc ) {
2004-02-02 20:19:17 +00:00
if ( ns_dlsym ( ( int * ) get_dl_handle ( mod_name ) , errfunc ) = = NULL ) {
2004-01-14 22:50:24 +00:00
nlog ( LOG_WARNING , LOG_CORE , " add_socket: error socket function doesn't exist = %s (%s) " , errfunc , mod_name ) ;
2003-11-03 13:57:11 +00:00
return NS_FAILURE ;
2002-07-30 04:26:28 +00:00
}
2003-06-13 13:11:50 +00:00
}
2003-11-18 11:51:09 +00:00
mod_sock = new_sock ( sock_name ) ;
mod_sock - > sock_no = socknum ;
strlcpy ( mod_sock - > modname , mod_name , MAX_MOD_NAME ) ;
2004-02-02 20:19:17 +00:00
mod_sock - > readfnc = ns_dlsym ( ( int * ) get_dl_handle ( mod_name ) , readfunc ) ;
mod_sock - > writefnc = ns_dlsym ( ( int * ) get_dl_handle ( mod_name ) , writefunc ) ;
mod_sock - > errfnc = ns_dlsym ( ( int * ) get_dl_handle ( mod_name ) , errfunc ) ;
2003-11-18 11:51:09 +00:00
mod_sock - > socktype = SOCK_STANDARD ;
2003-11-03 13:57:11 +00:00
2004-01-14 22:50:24 +00:00
nlog ( LOG_DEBUG2 , LOG_CORE , " add_socket: Registered Module %s with Standard Socket functions %s " , mod_name , mod_sock - > sockname ) ;
2003-11-03 13:57:11 +00:00
return NS_SUCCESS ;
}
/** @brief add a poll interface to the socket list
*
* For core use . Adds a socket with the given functions to the socket list
*
* @ param beforepoll the name of function to call before we select
* @ param afterpoll the name of the function to call after we select
* @ param sock_name the name of socket to register
* @ param mod_name the name of module registering the socket
*
* @ return pointer to socket if found , NULL if not found
*/
int
add_sockpoll ( char * beforepoll , char * afterpoll , char * sock_name , char * mod_name , void * data )
{
2003-11-18 11:51:09 +00:00
ModSock * mod_sock ;
2003-11-03 13:57:11 +00:00
SET_SEGV_LOCATION ( ) ;
if ( beforepoll ) {
2004-02-02 20:19:17 +00:00
if ( ns_dlsym ( ( int * ) get_dl_handle ( mod_name ) , beforepoll ) = = NULL ) {
2004-01-14 22:50:24 +00:00
nlog ( LOG_WARNING , LOG_CORE , " add_sockpoll: read socket function doesn't exist = %s (%s) " , beforepoll , mod_name ) ;
2003-11-03 13:57:11 +00:00
return NS_FAILURE ;
}
}
if ( afterpoll ) {
2004-02-02 20:19:17 +00:00
if ( ns_dlsym ( ( int * ) get_dl_handle ( mod_name ) , afterpoll ) = = NULL ) {
2004-01-14 22:50:24 +00:00
nlog ( LOG_WARNING , LOG_CORE , " add_sockpoll: write socket function doesn't exist = %s (%s) " , afterpoll , mod_name ) ;
2003-11-03 13:57:11 +00:00
return NS_FAILURE ;
}
}
2003-11-18 11:51:09 +00:00
mod_sock = new_sock ( sock_name ) ;
strlcpy ( mod_sock - > modname , mod_name , MAX_MOD_NAME ) ;
mod_sock - > socktype = SOCK_POLL ;
2004-02-02 20:19:17 +00:00
mod_sock - > beforepoll = ns_dlsym ( ( int * ) get_dl_handle ( mod_name ) , beforepoll ) ;
mod_sock - > afterpoll = ns_dlsym ( ( int * ) get_dl_handle ( mod_name ) , afterpoll ) ;
2003-11-18 11:51:09 +00:00
mod_sock - > data = data ;
2004-01-14 22:50:24 +00:00
nlog ( LOG_DEBUG2 , LOG_CORE , " add_sockpoll: Registered Module %s with Poll Socket functions %s " , mod_name , mod_sock - > sockname ) ;
2003-11-03 13:57:11 +00:00
return NS_SUCCESS ;
2000-03-02 01:31:24 +00:00
}
2003-10-07 15:00:03 +00:00
/** @brief delete a socket from the socket list
2003-10-06 16:33:42 +00:00
*
2003-10-07 15:00:03 +00:00
* For module use . Deletes a socket with the given name from the socket list
*
* @ param socket_name the name of socket to delete
*
2003-11-03 13:57:11 +00:00
* @ return NS_SUCCESS if deleted , NS_FAILURE if not found
2003-10-07 15:00:03 +00:00
*/
2003-07-30 13:58:22 +00:00
int
del_socket ( char * sock_name )
2003-06-13 13:11:50 +00:00
{
2003-11-18 11:51:09 +00:00
ModSock * mod_sock ;
2002-02-28 07:54:13 +00:00
hnode_t * sn ;
2003-10-06 16:33:42 +00:00
2003-09-18 12:21:32 +00:00
SET_SEGV_LOCATION ( ) ;
2003-07-30 13:58:22 +00:00
sn = hash_lookup ( sockh , sock_name ) ;
2002-02-28 07:54:13 +00:00
if ( sn ) {
2003-11-18 11:51:09 +00:00
mod_sock = hnode_get ( sn ) ;
2004-01-14 22:50:24 +00:00
nlog ( LOG_DEBUG2 , LOG_CORE , " del_socket: Unregistered Socket function %s from Module %s " , sock_name , mod_sock - > modname ) ;
2003-07-30 13:58:22 +00:00
hash_scan_delete ( sockh , sn ) ;
hnode_destroy ( sn ) ;
2003-11-18 11:51:09 +00:00
free ( mod_sock ) ;
2003-11-03 13:57:11 +00:00
return NS_SUCCESS ;
2003-06-13 13:11:50 +00:00
}
2003-11-03 13:57:11 +00:00
return NS_FAILURE ;
2000-03-02 01:31:24 +00:00
}
2003-12-14 21:57:45 +00:00
/** @brief delete a socket from the socket list
*
* For module use . Deletes a socket with the given name from the socket list
*
* @ param socket_name the name of socket to delete
*
* @ return NS_SUCCESS if deleted , NS_FAILURE if not found
*/
int
del_sockets ( char * module_name )
{
ModSock * mod_sock ;
hnode_t * modnode ;
hscan_t hscan ;
hash_scan_begin ( & hscan , sockh ) ;
while ( ( modnode = hash_scan_next ( & hscan ) ) ! = NULL ) {
mod_sock = hnode_get ( modnode ) ;
2004-01-27 13:32:54 +00:00
if ( ! ircstrcasecmp ( mod_sock - > modname , module_name ) ) {
2004-01-14 22:50:24 +00:00
nlog ( LOG_DEBUG1 , LOG_CORE , " del_sockets: Module %s had Socket %s Registered. Deleting.. " , module_name , mod_sock - > sockname ) ;
2003-12-14 21:57:45 +00:00
del_socket ( mod_sock - > sockname ) ;
}
}
return NS_SUCCESS ;
}
2003-10-07 15:00:03 +00:00
/** @brief list sockets in use
2003-10-06 16:33:42 +00:00
*
2003-10-07 15:00:03 +00:00
* NeoStats command to list the current sockets from IRC
*
* @ param u pointer to user structure of the user issuing the request
*
* @ return none
*/
2003-11-27 22:49:10 +00:00
int
2003-11-18 11:51:09 +00:00
list_sockets ( User * u , char * * av , int ac )
2003-06-13 13:11:50 +00:00
{
2003-11-18 11:51:09 +00:00
ModSock * mod_sock = NULL ;
2002-02-28 07:54:13 +00:00
hscan_t ss ;
hnode_t * sn ;
2003-09-18 12:21:32 +00:00
SET_SEGV_LOCATION ( ) ;
2003-12-04 15:47:53 +00:00
prefmsg ( u - > nick , s_Services , " Sockets List: (%d) " , ( int ) hash_count ( sockh ) ) ;
2003-07-30 13:58:22 +00:00
hash_scan_begin ( & ss , sockh ) ;
while ( ( sn = hash_scan_next ( & ss ) ) ! = NULL ) {
2003-11-18 11:51:09 +00:00
mod_sock = hnode_get ( sn ) ;
prefmsg ( u - > nick , s_Services , " %s:-------------------------------- " , mod_sock - > modname ) ;
prefmsg ( u - > nick , s_Services , " Socket Name: %s " , mod_sock - > sockname ) ;
if ( mod_sock - > socktype = = SOCK_STANDARD ) {
prefmsg ( u - > nick , s_Services , " Socket Number: %d " , mod_sock - > sock_no ) ;
2003-11-03 13:57:11 +00:00
} else {
prefmsg ( u - > nick , s_Services , " Poll Interface " ) ;
}
2003-07-30 13:58:22 +00:00
}
prefmsg ( u - > nick , s_Services , " End of Socket List " ) ;
2003-11-27 22:49:10 +00:00
return 0 ;
2003-06-13 13:11:50 +00:00
}
2000-03-02 01:31:24 +00:00
2003-10-10 23:07:30 +00:00
/** @brief Add a bot to a channel
2003-10-06 16:33:42 +00:00
*
2003-10-10 23:07:30 +00:00
* @ param bot string containing bot name
* @ param chan string containing channel name
*
* @ return none
2003-10-06 16:33:42 +00:00
*/
void
2003-07-30 13:58:22 +00:00
add_bot_to_chan ( char * bot , char * chan )
2003-06-13 13:11:50 +00:00
{
2002-07-12 09:11:31 +00:00
hnode_t * cbn ;
2003-11-18 11:51:09 +00:00
ModChanBot * mod_chan_bot ;
2003-06-13 13:11:50 +00:00
lnode_t * bmn ;
2002-07-12 09:11:31 +00:00
char * botname ;
2003-10-06 16:33:42 +00:00
2003-07-30 13:58:22 +00:00
cbn = hash_lookup ( bch , chan ) ;
2002-07-12 09:11:31 +00:00
if ( ! cbn ) {
2003-11-18 11:51:09 +00:00
mod_chan_bot = malloc ( sizeof ( ModChanBot ) ) ;
strlcpy ( mod_chan_bot - > chan , chan , CHANLEN ) ;
mod_chan_bot - > bots = list_create ( B_TABLE_SIZE ) ;
cbn = hnode_create ( mod_chan_bot ) ;
2003-07-30 13:58:22 +00:00
if ( hash_isfull ( bch ) ) {
nlog ( LOG_CRITICAL , LOG_CORE , " eek, bot channel hash is full " ) ;
2002-07-17 05:25:39 +00:00
return ;
}
2003-11-18 11:51:09 +00:00
hash_insert ( bch , cbn , mod_chan_bot - > chan ) ;
2002-07-12 09:11:31 +00:00
} else {
2003-11-18 11:51:09 +00:00
mod_chan_bot = hnode_get ( cbn ) ;
2002-07-12 09:11:31 +00:00
}
2003-11-18 11:51:09 +00:00
if ( list_isfull ( mod_chan_bot - > bots ) ) {
2004-01-14 22:50:24 +00:00
nlog ( LOG_CRITICAL , LOG_CORE , " add_bot_to_chan: bot channel list is full adding channel %s " , chan ) ;
2002-07-12 09:11:31 +00:00
return ;
}
2003-07-30 13:58:22 +00:00
botname = sstrdup ( bot ) ;
bmn = lnode_create ( botname ) ;
2003-11-18 11:51:09 +00:00
list_append ( mod_chan_bot - > bots , bmn ) ;
2002-07-12 09:11:31 +00:00
return ;
}
2003-10-10 23:07:30 +00:00
/** @brief delete a bot from a channel
2003-10-06 16:33:42 +00:00
*
2003-10-10 23:07:30 +00:00
* @ param bot string containing bot name
* @ param chan string containing channel name
*
* @ return none
2003-10-06 16:33:42 +00:00
*/
void
2003-07-30 13:58:22 +00:00
del_bot_from_chan ( char * bot , char * chan )
2003-06-13 13:11:50 +00:00
{
2002-07-12 09:11:31 +00:00
hnode_t * cbn ;
2003-11-18 11:51:09 +00:00
ModChanBot * mod_chan_bot ;
2002-07-12 09:11:31 +00:00
lnode_t * bmn ;
2003-11-07 13:02:02 +00:00
char * botname ;
2003-10-06 16:33:42 +00:00
2003-07-30 13:58:22 +00:00
cbn = hash_lookup ( bch , chan ) ;
2002-07-12 09:11:31 +00:00
if ( ! cbn ) {
2004-01-12 18:46:56 +00:00
nlog ( LOG_WARNING , LOG_CORE , " del_bot_from_chan: can't find channel %s for botchanhash " , chan ) ;
2002-07-12 09:11:31 +00:00
return ;
}
2003-11-18 11:51:09 +00:00
mod_chan_bot = hnode_get ( cbn ) ;
bmn = list_find ( mod_chan_bot - > bots , bot , comparef ) ;
2002-07-12 09:11:31 +00:00
if ( ! bmn ) {
2004-01-12 18:46:56 +00:00
nlog ( LOG_WARNING , LOG_CORE , " del_bot_from_chan: can't find bot %s in %s in botchanhash " , bot , chan ) ;
2002-07-12 09:11:31 +00:00
return ;
}
2003-11-18 11:51:09 +00:00
list_delete ( mod_chan_bot - > bots , bmn ) ;
2003-11-07 13:02:02 +00:00
botname = lnode_get ( bmn ) ;
free ( botname ) ;
lnode_destroy ( bmn ) ;
2003-11-18 11:51:09 +00:00
if ( list_isempty ( mod_chan_bot - > bots ) ) {
2003-06-13 13:11:50 +00:00
/* delete the hash and list because its all over */
2003-07-30 13:58:22 +00:00
hash_delete ( bch , cbn ) ;
2003-11-18 11:51:09 +00:00
list_destroy ( mod_chan_bot - > bots ) ;
free ( mod_chan_bot - > chan ) ;
2003-07-30 13:58:22 +00:00
hnode_destroy ( cbn ) ;
2002-07-12 09:11:31 +00:00
}
2003-06-13 13:11:50 +00:00
}
2002-07-12 09:11:31 +00:00
2003-10-10 23:07:30 +00:00
/** @brief send a message to a channel bot
2003-10-06 16:33:42 +00:00
*
2003-10-10 23:07:30 +00:00
* @ param origin
2003-11-18 11:51:09 +00:00
* @ param av ( note chan string in av [ 0 ] )
2003-10-10 23:07:30 +00:00
* @ param ac
*
* @ return none
2003-10-06 16:33:42 +00:00
*/
void
2003-11-18 11:51:09 +00:00
bot_chan_message ( char * origin , char * * av , int ac )
2003-06-13 13:11:50 +00:00
{
2002-07-12 09:11:31 +00:00
hnode_t * cbn ;
2003-11-18 11:51:09 +00:00
ModChanBot * mod_chan_bot ;
2002-07-12 09:11:31 +00:00
lnode_t * bmn ;
2003-11-18 11:51:09 +00:00
ModUser * mod_usr ;
2003-10-06 16:33:42 +00:00
2003-11-18 11:51:09 +00:00
cbn = hash_lookup ( bch , av [ 0 ] ) ;
2002-07-12 09:11:31 +00:00
if ( ! cbn ) {
2003-08-18 15:20:21 +00:00
/* this isn't bad, just means our bot parted the channel? */
2004-01-12 18:46:56 +00:00
nlog ( LOG_DEBUG1 , LOG_CORE , " bot_chan_message: can't find channel %s " , av [ 0 ] ) ;
2002-07-12 09:11:31 +00:00
return ;
}
2003-11-18 11:51:09 +00:00
mod_chan_bot = hnode_get ( cbn ) ;
bmn = list_first ( mod_chan_bot - > bots ) ;
2002-07-12 09:11:31 +00:00
while ( bmn ) {
2003-11-18 11:51:09 +00:00
mod_usr = findbot ( lnode_get ( bmn ) ) ;
if ( mod_usr - > chanfunc ) {
2004-01-12 18:46:56 +00:00
nlog ( LOG_DEBUG2 , LOG_CORE , " bot_chan_message: running module for chanmessage %s " , av [ 0 ] ) ;
2004-01-22 20:51:30 +00:00
SET_SEGV_INMODULE ( mod_usr - > modname ) ;
2003-11-18 11:51:09 +00:00
mod_usr - > chanfunc ( origin , av , ac ) ;
2004-01-22 20:51:30 +00:00
CLEAR_SEGV_INMODULE ( ) ;
2002-07-12 09:11:31 +00:00
}
2003-11-18 11:51:09 +00:00
bmn = list_next ( mod_chan_bot - > bots , bmn ) ;
2002-07-12 09:11:31 +00:00
}
}
2004-01-23 22:39:09 +00:00
/** @brief send a message to a channel bot
*
* @ param origin
* @ param av ( note chan string in av [ 0 ] )
* @ param ac
*
* @ return none
*/
2004-02-21 21:59:09 +00:00
int
2004-01-23 22:39:09 +00:00
bot_message ( char * origin , char * * av , int ac )
{
2004-02-21 21:59:09 +00:00
int ret = NS_SUCCESS ;
2004-01-23 22:39:09 +00:00
User * u ;
2004-02-06 20:07:07 +00:00
User * bot_user ;
2004-01-23 22:39:09 +00:00
ModUser * mod_usr ;
2004-02-06 20:58:23 +00:00
char * * argv ;
int argc = 0 ;
int i ;
2004-01-23 22:39:09 +00:00
2004-07-17 06:10:52 +00:00
if ( ac < 2 ) {
nlog ( LOG_WARNING , LOG_CORE , " Invalid String passed to Bot_message " ) ;
return NS_FAILURE ;
}
2004-01-23 22:39:09 +00:00
/* Check command length */
if ( strnlen ( av [ 1 ] , MAX_CMD_LINE_LENGTH ) > = MAX_CMD_LINE_LENGTH ) {
prefmsg ( origin , s_Services , " command line too long! " ) ;
notice ( s_Services , " %s tried to send a very LARGE command, we told them to shove it! " , origin ) ;
2004-02-21 21:59:09 +00:00
return NS_SUCCESS ;
2004-01-23 22:39:09 +00:00
}
u = finduser ( origin ) ;
2004-01-26 23:34:28 +00:00
if ( ! u ) {
2004-02-21 21:59:09 +00:00
return NS_SUCCESS ;
2004-01-26 23:34:28 +00:00
}
2004-01-23 22:39:09 +00:00
if ( flood ( u ) ) {
2004-02-21 21:59:09 +00:00
return NS_SUCCESS ;
2004-01-23 22:39:09 +00:00
}
2004-02-06 20:07:07 +00:00
bot_user = finduser ( av [ 0 ] ) ;
if ( ! bot_user ) {
2004-02-28 23:14:22 +00:00
nlog ( LOG_DEBUG1 , LOG_CORE , " bot_message: bot %s not found " , av [ 0 ] ) ;
2004-02-21 21:59:09 +00:00
return NS_SUCCESS ;
2004-02-06 20:07:07 +00:00
}
mod_usr = findbot ( bot_user - > nick ) ;
2004-01-23 22:39:09 +00:00
/* Check to see if any of the Modules have this nick Registered */
if ( ! mod_usr ) {
2004-02-28 23:14:22 +00:00
nlog ( LOG_DEBUG1 , LOG_CORE , " bot_message: mod_usr %s not found " , bot_user - > nick ) ;
2004-02-21 21:59:09 +00:00
return NS_SUCCESS ;
2004-01-23 22:39:09 +00:00
}
2004-02-28 23:14:22 +00:00
nlog ( LOG_DEBUG1 , LOG_CORE , " bot_message: bot %s " , mod_usr - > nick ) ;
2004-01-23 22:39:09 +00:00
SET_SEGV_LOCATION ( ) ;
if ( setjmp ( sigvbuf ) = = 0 ) {
2004-01-30 21:27:43 +00:00
SET_SEGV_INMODULE ( mod_usr - > modname ) ;
2004-01-23 22:39:09 +00:00
if ( mod_usr - > function ) {
2004-02-06 20:58:23 +00:00
AddStringToList ( & argv , bot_user - > nick , & argc ) ;
for ( i = 1 ; i < ac ; i + + ) {
AddStringToList ( & argv , av [ i ] , & argc ) ;
}
2004-02-06 21:00:58 +00:00
mod_usr - > function ( u - > nick , argv , argc ) ;
2004-02-06 20:58:23 +00:00
free ( argv ) ;
2004-01-30 21:27:43 +00:00
} else {
2004-02-28 23:14:22 +00:00
#if 0
2004-01-23 23:05:10 +00:00
/* Trap CTCP commands and silently drop them to avoid unknown command errors
2004-01-30 21:27:43 +00:00
* Why bother ? Well we might be able to use some of them in the future
* so this is mainly a test and we may want to pass some of this onto
* SecureServ for a quick trojan check so log attempts to give an indication
* of usage .
*/
2004-01-23 23:05:10 +00:00
if ( av [ 1 ] [ 0 ] = = ' \1 ' ) {
char * buf ;
buf = joinbuf ( av , ac , 1 ) ;
2004-02-06 20:58:23 +00:00
nlog ( LOG_NORMAL , LOG_MOD , " %s requested CTCP %s " , u - > nick , buf ) ;
2004-01-23 23:05:10 +00:00
free ( buf ) ;
2004-02-21 21:59:09 +00:00
return NS_SUCCESS ;
2004-01-23 23:05:10 +00:00
}
2004-02-28 23:14:22 +00:00
# endif
2004-01-23 22:39:09 +00:00
if ( ! u ) {
2004-02-06 20:58:23 +00:00
nlog ( LOG_WARNING , LOG_CORE , " Unable to finduser %s (%s) " , u - > nick , mod_usr - > nick ) ;
2004-01-23 22:39:09 +00:00
} else {
2004-02-06 20:58:23 +00:00
AddStringToList ( & argv , bot_user - > nick , & argc ) ;
for ( i = 1 ; i < ac ; i + + ) {
AddStringToList ( & argv , av [ i ] , & argc ) ;
}
2004-02-26 22:29:04 +00:00
if ( mod_usr - > botcmds ) {
ret = run_bot_cmd ( mod_usr , u , argv , argc ) ;
} else {
ret = NS_FAILURE ;
}
2004-02-06 20:58:23 +00:00
free ( argv ) ;
2004-01-23 22:39:09 +00:00
}
}
2004-01-30 21:27:43 +00:00
CLEAR_SEGV_INMODULE ( ) ;
2004-01-23 22:39:09 +00:00
}
2004-02-21 21:59:09 +00:00
return ret ;
2004-01-23 22:39:09 +00:00
}
2003-10-10 23:07:30 +00:00
/** @brief dump list of module bots and channels
2003-10-06 16:33:42 +00:00
*
2003-10-10 23:07:30 +00:00
* @ param u
*
* @ return none
2003-10-06 16:33:42 +00:00
*/
2003-11-27 22:49:10 +00:00
int
2003-11-18 11:51:09 +00:00
list_bot_chans ( User * u , char * * av , int ac )
2003-06-13 13:11:50 +00:00
{
2002-07-12 09:11:31 +00:00
hscan_t hs ;
hnode_t * hn ;
lnode_t * ln ;
2003-11-18 11:51:09 +00:00
ModChanBot * mod_chan_bot ;
2003-10-06 16:33:42 +00:00
2003-07-30 13:58:22 +00:00
prefmsg ( u - > nick , s_Services , " BotChanDump: " ) ;
hash_scan_begin ( & hs , bch ) ;
while ( ( hn = hash_scan_next ( & hs ) ) ! = NULL ) {
2003-11-18 11:51:09 +00:00
mod_chan_bot = hnode_get ( hn ) ;
prefmsg ( u - > nick , s_Services , " %s:-------------------------------- " , mod_chan_bot - > chan ) ;
ln = list_first ( mod_chan_bot - > bots ) ;
2002-07-12 09:11:31 +00:00
while ( ln ) {
2003-12-04 15:47:53 +00:00
prefmsg ( u - > nick , s_Services , " Bot Name: %s " , ( char * ) lnode_get ( ln ) ) ;
2003-11-18 11:51:09 +00:00
ln = list_next ( mod_chan_bot - > bots , ln ) ;
2002-07-12 09:11:31 +00:00
}
}
2003-11-27 22:49:10 +00:00
return 0 ;
2002-07-12 09:11:31 +00:00
}
2000-03-02 01:31:24 +00:00
2003-10-10 23:07:30 +00:00
/** @brief create a new bot
2003-10-06 16:33:42 +00:00
*
2003-10-10 23:07:30 +00:00
* @ param bot_name string containing bot name
*
* @ return none
2003-10-06 16:33:42 +00:00
*/
2003-11-18 11:51:09 +00:00
static ModUser *
2003-07-30 13:58:22 +00:00
new_bot ( char * bot_name )
2000-02-22 03:32:32 +00:00
{
2003-11-18 11:51:09 +00:00
ModUser * mod_usr ;
2002-02-28 07:54:13 +00:00
hnode_t * bn ;
2003-10-06 16:33:42 +00:00
2003-09-18 12:21:32 +00:00
SET_SEGV_LOCATION ( ) ;
2004-01-14 22:50:24 +00:00
nlog ( LOG_DEBUG2 , LOG_CORE , " new_bot: %s " , bot_name ) ;
2003-11-18 11:51:09 +00:00
mod_usr = malloc ( sizeof ( ModUser ) ) ;
2003-11-23 21:36:35 +00:00
strlcpy ( mod_usr - > nick , bot_name , MAXNICK ) ;
2003-11-18 11:51:09 +00:00
bn = hnode_create ( mod_usr ) ;
2003-07-30 13:58:22 +00:00
if ( hash_isfull ( bh ) ) {
chanalert ( s_Services , " Warning ModuleBotlist is full " ) ;
2002-02-28 07:54:13 +00:00
return NULL ;
}
2003-11-18 11:51:09 +00:00
hash_insert ( bh , bn , mod_usr - > nick ) ;
return mod_usr ;
2000-02-22 03:32:32 +00:00
}
2003-07-30 13:58:22 +00:00
2003-10-10 23:07:30 +00:00
/** @brief
2003-10-06 16:33:42 +00:00
*
2003-10-10 23:07:30 +00:00
* @ param
*
* @ return
2003-10-06 16:33:42 +00:00
*/
2003-11-28 21:06:08 +00:00
ModUser *
2003-07-30 13:58:22 +00:00
add_mod_user ( char * nick , char * mod_name )
2003-06-13 13:11:50 +00:00
{
2003-11-18 11:51:09 +00:00
ModUser * mod_usr ;
Module * mod_ptr ;
2003-06-13 13:11:50 +00:00
hnode_t * mn ;
2002-02-28 07:54:13 +00:00
2003-09-18 12:21:32 +00:00
SET_SEGV_LOCATION ( ) ;
2003-07-30 13:58:22 +00:00
mn = hash_lookup ( mh , mod_name ) ;
2002-02-28 07:54:13 +00:00
if ( mn ) {
2003-11-18 11:51:09 +00:00
mod_ptr = hnode_get ( mn ) ;
2003-11-23 21:36:35 +00:00
if ( mod_ptr ) {
/* add a brand new user */
mod_usr = new_bot ( nick ) ;
2003-11-28 21:06:08 +00:00
if ( mod_usr ) {
strlcpy ( mod_usr - > modname , mod_name , MAX_MOD_NAME ) ;
2004-02-02 20:19:17 +00:00
mod_usr - > function = ns_dlsym ( mod_ptr - > dl_handle , " __BotMessage " ) ;
mod_usr - > chanfunc = ns_dlsym ( mod_ptr - > dl_handle , " __ChanMessage " ) ;
2004-02-26 22:39:59 +00:00
mod_usr - > botcmds = NULL ;
2003-11-28 21:06:08 +00:00
return mod_usr ;
}
2003-11-23 21:36:35 +00:00
}
2002-02-28 07:54:13 +00:00
}
2004-01-14 22:50:24 +00:00
nlog ( LOG_WARNING , LOG_CORE , " add_mod_user: Couldn't Add ModuleBot to List " ) ;
2003-11-28 21:06:08 +00:00
return NULL ;
2002-02-28 07:54:13 +00:00
}
2004-01-23 22:39:09 +00:00
/** @brief
*
* @ param
*
* @ return
*/
ModUser *
add_neostats_mod_user ( char * nick )
{
ModUser * mod_usr ;
SET_SEGV_LOCATION ( ) ;
/* add a brand new user */
mod_usr = new_bot ( nick ) ;
if ( mod_usr ) {
2004-01-30 21:27:43 +00:00
#if 0
2004-01-23 22:39:09 +00:00
strlcpy ( mod_usr - > modname , " NeoStats " , MAX_MOD_NAME ) ;
2004-01-30 21:27:43 +00:00
# else
mod_usr - > modname [ 0 ] = 0 ;
# endif
2004-01-23 22:39:09 +00:00
mod_usr - > function = NULL ;
mod_usr - > chanfunc = NULL ;
mod_usr - > botcmds = hash_create ( - 1 , 0 , 0 ) ;
return mod_usr ;
}
nlog ( LOG_WARNING , LOG_CORE , " add_neostats_mod_user: Couldn't Add ModuleBot to List " ) ;
return NULL ;
}
2003-10-10 23:07:30 +00:00
/** @brief
2003-10-06 16:33:42 +00:00
*
2003-10-10 23:07:30 +00:00
* @ param
*
* @ return
2003-10-06 16:33:42 +00:00
*/
2003-11-18 11:51:09 +00:00
ModUser *
2003-07-30 13:58:22 +00:00
findbot ( char * bot_name )
2003-06-13 13:11:50 +00:00
{
2002-02-28 07:54:13 +00:00
hnode_t * bn ;
2003-06-13 13:11:50 +00:00
2003-09-18 12:21:32 +00:00
SET_SEGV_LOCATION ( ) ;
2004-02-06 19:33:50 +00:00
2004-02-06 20:12:13 +00:00
bn = hash_lookup ( bh , bot_name ) ;
if ( bn ) {
return ( ModUser * ) hnode_get ( bn ) ;
2003-06-13 13:11:50 +00:00
}
2000-03-29 13:05:57 +00:00
return NULL ;
2000-02-22 03:32:32 +00:00
}
2003-10-10 23:07:30 +00:00
/** @brief
2003-10-06 16:33:42 +00:00
*
2003-10-10 23:07:30 +00:00
* @ param
*
* @ return
2003-10-06 16:33:42 +00:00
*/
2003-07-30 13:58:22 +00:00
int
del_mod_user ( char * bot_name )
2003-06-13 13:11:50 +00:00
{
2003-11-18 11:51:09 +00:00
ModUser * mod_usr ;
2002-02-28 07:54:13 +00:00
hnode_t * bn ;
2003-06-13 13:11:50 +00:00
2003-09-18 12:21:32 +00:00
SET_SEGV_LOCATION ( ) ;
2003-07-30 13:58:22 +00:00
bn = hash_lookup ( bh , bot_name ) ;
2002-02-28 07:54:13 +00:00
if ( bn ) {
2003-07-30 13:58:22 +00:00
hash_delete ( bh , bn ) ;
2003-11-18 11:51:09 +00:00
mod_usr = hnode_get ( bn ) ;
2003-11-28 20:50:40 +00:00
del_all_bot_cmds ( mod_usr ) ;
2003-07-30 13:58:22 +00:00
hnode_destroy ( bn ) ;
2003-11-18 11:51:09 +00:00
free ( mod_usr ) ;
2003-11-03 13:57:11 +00:00
return NS_SUCCESS ;
2003-06-13 13:11:50 +00:00
}
2003-11-03 13:57:11 +00:00
return NS_FAILURE ;
2000-02-22 03:32:32 +00:00
}
2000-02-03 23:45:51 +00:00
2003-10-10 23:07:30 +00:00
/** @brief
2003-10-06 16:33:42 +00:00
*
2003-10-10 23:07:30 +00:00
* @ param
*
* @ return
2003-10-06 16:33:42 +00:00
*/
2003-07-30 13:58:22 +00:00
int
bot_nick_change ( char * oldnick , char * newnick )
2000-02-03 23:45:51 +00:00
{
User * u ;
2003-11-18 11:51:09 +00:00
ModUser * mod_usr_new , * mod_usr ;
2002-02-28 07:54:13 +00:00
2003-09-18 12:21:32 +00:00
SET_SEGV_LOCATION ( ) ;
2000-02-03 23:45:51 +00:00
/* First, try to find out if the newnick is unique! */
2003-07-30 13:58:22 +00:00
u = finduser ( oldnick ) ;
2000-02-03 23:45:51 +00:00
if ( ! u ) {
2003-07-30 13:58:22 +00:00
nlog ( LOG_WARNING , LOG_CORE , " A non-registered bot(%s) attempted to change its nick to %s " , oldnick , newnick ) ;
2003-11-03 13:57:11 +00:00
return NS_FAILURE ;
2003-06-13 13:11:50 +00:00
}
2003-07-30 13:58:22 +00:00
u = finduser ( newnick ) ;
2003-06-13 13:11:50 +00:00
if ( ! u ) {
2003-11-18 11:51:09 +00:00
if ( ( mod_usr = findbot ( oldnick ) ) ! = NULL ) {
2003-07-30 13:58:22 +00:00
nlog ( LOG_DEBUG3 , LOG_CORE , " Bot %s Changed its nick to %s " , oldnick , newnick ) ;
2003-11-18 11:51:09 +00:00
mod_usr_new = new_bot ( newnick ) ;
2003-06-13 13:11:50 +00:00
2003-10-06 16:33:42 +00:00
/* add a brand new user */
2003-11-18 11:51:09 +00:00
strlcpy ( mod_usr_new - > nick , newnick , MAXNICK ) ;
strlcpy ( mod_usr_new - > modname , mod_usr - > modname , MAX_MOD_NAME ) ;
mod_usr_new - > function = mod_usr - > function ;
2003-06-13 13:11:50 +00:00
2003-10-06 16:33:42 +00:00
/* Now Delete the Old bot nick */
2003-07-30 13:58:22 +00:00
del_mod_user ( oldnick ) ;
snick_cmd ( oldnick , newnick ) ;
2003-11-03 13:57:11 +00:00
return NS_SUCCESS ;
2002-02-28 07:54:13 +00:00
}
2003-06-13 13:11:50 +00:00
}
2003-07-30 13:58:22 +00:00
nlog ( LOG_NOTICE , LOG_CORE , " Couldn't find Bot Nick %s in Bot list " , oldnick ) ;
2003-11-03 13:57:11 +00:00
return NS_FAILURE ;
2000-02-22 03:32:32 +00:00
}
2000-02-03 23:45:51 +00:00
2003-10-10 23:07:30 +00:00
/** @brief
2003-10-06 16:33:42 +00:00
*
2003-10-10 23:07:30 +00:00
* @ param
*
* @ return
2003-10-06 16:33:42 +00:00
*/
2003-11-27 22:49:10 +00:00
int
2003-11-18 11:51:09 +00:00
list_bots ( User * u , char * * av , int ac )
2003-06-13 13:11:50 +00:00
{
2003-11-18 11:51:09 +00:00
ModUser * mod_usr ;
2002-02-28 07:54:13 +00:00
hnode_t * bn ;
hscan_t bs ;
2003-10-06 16:33:42 +00:00
2003-09-18 12:21:32 +00:00
SET_SEGV_LOCATION ( ) ;
2003-07-30 13:58:22 +00:00
prefmsg ( u - > nick , s_Services , " Module Bot List: " ) ;
hash_scan_begin ( & bs , bh ) ;
while ( ( bn = hash_scan_next ( & bs ) ) ! = NULL ) {
2003-11-18 11:51:09 +00:00
mod_usr = hnode_get ( bn ) ;
2004-02-21 16:20:53 +00:00
if ( mod_usr - > modname [ 0 ] = = 0 ) {
prefmsg ( u - > nick , s_Services , " NeoStats " ) ;
prefmsg ( u - > nick , s_Services , " Bots: %s " , mod_usr - > nick ) ;
} else {
prefmsg ( u - > nick , s_Services , " Module: %s " , mod_usr - > modname ) ;
prefmsg ( u - > nick , s_Services , " Module Bots: %s " , mod_usr - > nick ) ;
}
2003-07-30 13:58:22 +00:00
}
prefmsg ( u - > nick , s_Services , " End of Module Bot List " ) ;
2003-11-27 22:49:10 +00:00
return 0 ;
2003-06-13 13:11:50 +00:00
}
2003-12-14 21:57:45 +00:00
/** @brief del_bots
*
*
*
* @ return none
*/
int del_bots ( char * module_name )
{
ModUser * mod_usr ;
hnode_t * modnode ;
hscan_t hscan ;
hash_scan_begin ( & hscan , bh ) ;
while ( ( modnode = hash_scan_next ( & hscan ) ) ! = NULL ) {
mod_usr = hnode_get ( modnode ) ;
2004-01-27 13:32:54 +00:00
if ( ! ircstrcasecmp ( mod_usr - > modname , module_name ) ) {
2003-12-14 21:57:45 +00:00
nlog ( LOG_DEBUG1 , LOG_CORE , " Module %s had bot %s Registered. Deleting.. " , module_name , mod_usr - > nick ) ;
del_bot ( mod_usr - > nick , " Module Unloaded " ) ;
}
}
return NS_SUCCESS ;
}
2003-11-18 11:51:09 +00:00
/** @brief ModuleEvent
*
*
*
* @ return none
*/
void
ModuleEvent ( char * event , char * * av , int ac )
{
Module * module_ptr ;
EventFnList * ev_list ;
hscan_t ms ;
hnode_t * mn ;
SET_SEGV_LOCATION ( ) ;
hash_scan_begin ( & ms , mh ) ;
while ( ( mn = hash_scan_next ( & ms ) ) ! = NULL ) {
module_ptr = hnode_get ( mn ) ;
ev_list = module_ptr - > event_list ;
if ( ev_list ) {
while ( ev_list - > cmd_name ! = NULL ) {
/* This goes through each Command */
2004-01-27 13:32:54 +00:00
if ( ! ircstrcasecmp ( ev_list - > cmd_name , event ) ) {
2003-12-02 19:17:12 +00:00
nlog ( LOG_DEBUG1 , LOG_CORE , " Running Module %s for Command %s -> %s " , module_ptr - > info - > module_name , event , ev_list - > cmd_name ) ;
2003-11-18 11:51:09 +00:00
SET_SEGV_LOCATION ( ) ;
if ( setjmp ( sigvbuf ) = = 0 ) {
2004-01-30 21:27:43 +00:00
SET_SEGV_INMODULE ( module_ptr - > info - > module_name ) ;
ev_list - > function ( av , ac ) ;
CLEAR_SEGV_INMODULE ( ) ;
2003-11-18 11:51:09 +00:00
} else {
nlog ( LOG_CRITICAL , LOG_CORE , " setjmp() Failed, Can't call Module %s \n " , module_ptr - > info - > module_name ) ;
}
SET_SEGV_LOCATION ( ) ;
# ifndef VALGRIND
break ;
# endif
}
ev_list + + ;
}
}
}
}
/** @brief
*
*
*
* @ return none
*/
void
ModuleFunction ( int cmdptr , char * cmd , char * origin , char * * av , int ac )
{
Module * module_ptr ;
Functions * fn_list ;
hscan_t ms ;
hnode_t * mn ;
2003-12-09 22:17:09 +00:00
SET_SEGV_LOCATION ( ) ;
2003-11-18 11:51:09 +00:00
hash_scan_begin ( & ms , mh ) ;
while ( ( mn = hash_scan_next ( & ms ) ) ! = NULL ) {
module_ptr = hnode_get ( mn ) ;
fn_list = module_ptr - > function_list ;
2003-12-14 21:57:45 +00:00
if ( fn_list ) {
while ( fn_list - > cmd_name ! = NULL ) {
/* This goes through each Command */
2003-11-18 11:51:09 +00:00
if ( fn_list - > srvmsg = = cmdptr ) {
2003-12-14 21:57:45 +00:00
if ( ! strcmp ( fn_list - > cmd_name , cmd ) ) {
nlog ( LOG_DEBUG1 , LOG_CORE , " Running Module %s for Function %s " , module_ptr - > info - > module_name , fn_list - > cmd_name ) ;
SET_SEGV_LOCATION ( ) ;
if ( setjmp ( sigvbuf ) = = 0 ) {
2004-01-30 21:27:43 +00:00
SET_SEGV_INMODULE ( module_ptr - > info - > module_name ) ;
2003-12-14 21:57:45 +00:00
fn_list - > function ( origin , av , ac ) ;
2004-01-30 21:27:43 +00:00
CLEAR_SEGV_INMODULE ( ) ;
2003-12-14 21:57:45 +00:00
}
SET_SEGV_LOCATION ( ) ;
break ;
2003-11-18 11:51:09 +00:00
}
}
2003-12-14 21:57:45 +00:00
fn_list + + ;
2003-11-18 11:51:09 +00:00
}
2003-12-14 21:57:45 +00:00
}
}
}
/** @brief
*
*
*
* @ return none
*/
void
2004-01-25 23:38:53 +00:00
ModulesVersion ( const char * nick , const char * remoteserver )
2003-12-14 21:57:45 +00:00
{
Module * module_ptr ;
hscan_t ms ;
hnode_t * mn ;
SET_SEGV_LOCATION ( ) ;
hash_scan_begin ( & ms , mh ) ;
while ( ( mn = hash_scan_next ( & ms ) ) ! = NULL ) {
module_ptr = hnode_get ( mn ) ;
if ( module_ptr - > isnewstyle & & module_ptr - > function_list = = NULL ) {
2004-01-25 23:38:53 +00:00
numeric ( RPL_VERSION , nick ,
2003-12-14 21:57:45 +00:00
" Module %s version: %s %s %s " ,
module_ptr - > info - > module_name , module_ptr - > info - > module_version ,
module_ptr - > info - > module_build_date , module_ptr - > info - > module_build_time ) ;
2003-11-18 11:51:09 +00:00
}
}
}
2003-10-10 23:07:30 +00:00
/** @brief
2003-10-06 16:33:42 +00:00
*
2003-10-10 23:07:30 +00:00
* @ param
*
* @ return
2003-10-06 16:33:42 +00:00
*/
2003-07-30 13:58:22 +00:00
int
2003-10-06 16:33:42 +00:00
load_module ( char * modfilename , User * u )
2003-06-13 13:11:50 +00:00
{
2002-03-06 14:44:28 +00:00
# ifndef HAVE_LIBDL
const char * dl_error ;
2003-10-07 15:00:03 +00:00
# else /* HAVE_LIBDL */
2002-03-11 08:02:40 +00:00
char * dl_error ;
2003-10-07 15:00:03 +00:00
# endif /* HAVE_LIBDL */
2002-03-11 08:02:40 +00:00
void * dl_handle ;
2000-02-04 04:52:45 +00:00
int do_msg ;
2003-01-15 14:18:47 +00:00
char path [ 255 ] ;
2003-11-03 13:57:11 +00:00
char loadmodname [ 255 ] ;
2002-07-04 11:02:28 +00:00
char * * av ;
int ac = 0 ;
2003-07-11 13:43:27 +00:00
int i = 0 ;
2003-12-14 21:57:45 +00:00
int isnewstyle = 1 ;
2003-10-10 23:07:30 +00:00
# ifdef OLD_MODULE_EXPORT_SUPPORT
2003-11-18 11:51:09 +00:00
ModuleInfo * ( * mod_get_info ) ( ) = NULL ;
2003-06-13 13:11:50 +00:00
Functions * ( * mod_get_funcs ) ( ) = NULL ;
EventFnList * ( * mod_get_events ) ( ) = NULL ;
2003-10-10 23:07:30 +00:00
# endif /* OLD_MODULE_EXPORT_SUPPORT */
2003-11-18 11:51:09 +00:00
ModuleInfo * mod_info_ptr = NULL ;
2000-02-03 23:45:51 +00:00
Functions * mod_funcs_ptr = NULL ;
EventFnList * event_fn_ptr = NULL ;
2002-02-28 07:54:13 +00:00
Module * mod_ptr = NULL ;
hnode_t * mn ;
2003-12-14 21:57:45 +00:00
int ( * ModInit ) ( int modnum , int apiver ) ;
2003-08-07 12:31:43 +00:00
2003-09-18 12:21:32 +00:00
SET_SEGV_LOCATION ( ) ;
2000-02-04 04:52:45 +00:00
if ( u = = NULL ) {
do_msg = 0 ;
} else {
do_msg = 1 ;
}
2003-11-03 13:57:11 +00:00
strlcpy ( loadmodname , modfilename , 255 ) ;
strlwr ( loadmodname ) ;
ircsnprintf ( path , 255 , " %s/%s.so " , MOD_PATH , loadmodname ) ;
2004-02-02 20:19:17 +00:00
dl_handle = ns_dlopen ( path , RTLD_NOW | | RTLD_GLOBAL ) ;
2002-02-28 07:54:13 +00:00
if ( ! dl_handle ) {
2004-02-02 20:19:17 +00:00
dl_error = ns_dlerror ( ) ;
2003-09-18 11:22:03 +00:00
if ( do_msg ) {
2003-10-06 16:33:42 +00:00
prefmsg ( u - > nick , s_Services , " Couldn't Load Module: %s %s " , dl_error , path ) ;
2003-09-18 11:22:03 +00:00
}
2003-10-06 16:33:42 +00:00
nlog ( LOG_WARNING , LOG_CORE , " Couldn't Load Module: %s %s " , dl_error , path ) ;
2003-11-03 13:57:11 +00:00
return NS_FAILURE ;
2000-02-03 23:45:51 +00:00
}
2003-10-07 15:00:03 +00:00
/* new system */
2004-02-02 20:19:17 +00:00
mod_info_ptr = ns_dlsym ( dl_handle , " __module_info " ) ;
2003-10-07 15:00:03 +00:00
# ifdef OLD_MODULE_EXPORT_SUPPORT
if ( mod_info_ptr = = NULL ) {
/* old system */
2003-12-14 21:57:45 +00:00
isnewstyle = 0 ;
2004-02-02 20:19:17 +00:00
mod_get_info = ns_dlsym ( dl_handle , " __module_get_info " ) ;
2002-03-06 14:44:28 +00:00
# ifndef HAVE_LIBDL
2003-10-07 15:00:03 +00:00
if ( mod_get_info = = NULL ) {
2004-02-02 20:19:17 +00:00
dl_error = ns_dlerror ( ) ;
2003-10-07 15:00:03 +00:00
# else /* HAVE_LIBDL */
2004-02-02 20:19:17 +00:00
if ( ( dl_error = ns_dlerror ( ) ) ! = NULL ) {
2003-10-07 15:00:03 +00:00
# endif /* HAVE_LIBDL */
if ( do_msg ) {
prefmsg ( u - > nick , s_Services , " Couldn't Load Module: %s %s " , dl_error , path ) ;
}
nlog ( LOG_WARNING , LOG_CORE , " Couldn't Load Module: %s %s " , dl_error , path ) ;
2004-02-02 20:19:17 +00:00
ns_dlclose ( dl_handle ) ;
2003-11-03 13:57:11 +00:00
return NS_FAILURE ;
2003-10-07 15:00:03 +00:00
}
mod_info_ptr = ( * mod_get_info ) ( ) ;
if ( mod_info_ptr = = NULL ) {
2004-02-02 20:19:17 +00:00
ns_dlclose ( dl_handle ) ;
2003-10-07 15:00:03 +00:00
nlog ( LOG_WARNING , LOG_CORE , " Module has no info structure: %s " , path ) ;
2003-11-03 13:57:11 +00:00
return NS_FAILURE ;
2003-10-07 15:00:03 +00:00
}
}
# else /* OLD_MODULE_EXPORT_SUPPORT */
# ifndef HAVE_LIBDL
if ( mod_info_ptr = = NULL ) {
2004-02-02 20:19:17 +00:00
dl_error = ns_dlerror ( ) ;
2003-10-07 15:00:03 +00:00
# else /* HAVE_LIBDL */
2004-02-02 20:19:17 +00:00
if ( ( dl_error = ns_dlerror ( ) ) ! = NULL ) {
2003-10-07 15:00:03 +00:00
# endif /* HAVE_LIBDL */
2003-09-18 11:22:03 +00:00
if ( do_msg ) {
2003-10-06 16:33:42 +00:00
prefmsg ( u - > nick , s_Services , " Couldn't Load Module: %s %s " , dl_error , path ) ;
2003-09-18 11:22:03 +00:00
}
2003-10-06 16:33:42 +00:00
nlog ( LOG_WARNING , LOG_CORE , " Couldn't Load Module: %s %s " , dl_error , path ) ;
2004-02-02 20:19:17 +00:00
ns_dlclose ( dl_handle ) ;
2003-11-03 13:57:11 +00:00
return NS_FAILURE ;
2003-10-06 16:33:42 +00:00
}
2003-10-07 15:00:03 +00:00
# endif /* OLD_MODULE_EXPORT_SUPPORT */
2003-12-14 21:57:45 +00:00
2003-10-07 15:00:03 +00:00
/* new system */
2004-02-02 20:19:17 +00:00
mod_funcs_ptr = ns_dlsym ( dl_handle , " __module_functions " ) ;
2003-10-07 15:00:03 +00:00
# ifdef OLD_MODULE_EXPORT_SUPPORT
if ( mod_funcs_ptr = = NULL ) {
/* old system */
2004-02-02 20:19:17 +00:00
mod_get_funcs = ns_dlsym ( dl_handle , " __module_get_functions " ) ;
2003-12-14 21:57:45 +00:00
/* no error check here - this one isn't essential to the functioning of the module */
if ( mod_get_funcs ) {
mod_funcs_ptr = ( * mod_get_funcs ) ( ) ;
2003-09-18 11:22:03 +00:00
}
2003-10-06 16:33:42 +00:00
}
2003-10-07 15:00:03 +00:00
# endif /* OLD_MODULE_EXPORT_SUPPORT */
2000-02-03 23:45:51 +00:00
2003-10-07 15:00:03 +00:00
/* new system */
2004-02-02 20:19:17 +00:00
event_fn_ptr = ns_dlsym ( dl_handle , " __module_events " ) ;
2003-10-07 15:00:03 +00:00
# ifdef OLD_MODULE_EXPORT_SUPPORT
if ( event_fn_ptr = = NULL )
{
/* old system */
2004-02-02 20:19:17 +00:00
mod_get_events = ns_dlsym ( dl_handle , " __module_get_events " ) ;
2003-10-07 15:00:03 +00:00
/* no error check here - this one isn't essential to the functioning of the module */
2000-02-03 23:45:51 +00:00
2003-10-07 15:00:03 +00:00
if ( mod_get_events )
event_fn_ptr = ( * mod_get_events ) ( ) ;
}
# endif
2000-02-03 23:45:51 +00:00
/* Check that the Module hasn't already been loaded */
2003-07-30 13:58:22 +00:00
if ( hash_lookup ( mh , mod_info_ptr - > module_name ) ) {
2004-02-02 20:19:17 +00:00
ns_dlclose ( dl_handle ) ;
2003-06-13 13:11:50 +00:00
if ( do_msg )
2003-07-30 13:58:22 +00:00
prefmsg ( u - > nick , s_Services , " Module %s already Loaded, Can't Load 2 Copies " , mod_info_ptr - > module_name ) ;
2003-11-03 13:57:11 +00:00
return NS_FAILURE ;
2000-02-03 23:45:51 +00:00
}
2003-06-13 13:11:50 +00:00
2003-07-30 13:58:22 +00:00
mod_ptr = ( Module * ) smalloc ( sizeof ( Module ) ) ;
2002-02-28 07:54:13 +00:00
2003-07-30 13:58:22 +00:00
mn = hnode_create ( mod_ptr ) ;
if ( hash_isfull ( mh ) ) {
2003-09-18 11:22:03 +00:00
if ( do_msg ) {
2003-07-30 13:58:22 +00:00
chanalert ( s_Services , " Module List is Full. Can't Load any more modules " ) ;
prefmsg ( u - > nick , s_Services , " Module List is Full, Can't Load any more Modules " ) ;
2003-09-18 11:22:03 +00:00
}
2004-02-02 20:19:17 +00:00
ns_dlclose ( dl_handle ) ;
2003-07-30 13:58:22 +00:00
free ( mod_ptr ) ;
2003-11-03 13:57:11 +00:00
return NS_FAILURE ;
2002-02-28 07:54:13 +00:00
} else {
2003-07-30 13:58:22 +00:00
hash_insert ( mh , mn , mod_info_ptr - > module_name ) ;
2000-02-03 23:45:51 +00:00
}
2003-09-29 12:46:22 +00:00
nlog ( LOG_DEBUG1 , LOG_CORE , " Module Internal name: %s " , mod_info_ptr - > module_name ) ;
nlog ( LOG_DEBUG1 , LOG_CORE , " Module description: %s " , mod_info_ptr - > module_description ) ;
2000-02-03 23:45:51 +00:00
mod_ptr - > info = mod_info_ptr ;
2000-12-10 06:25:51 +00:00
mod_ptr - > function_list = mod_funcs_ptr ;
2000-02-03 23:45:51 +00:00
mod_ptr - > dl_handle = dl_handle ;
2003-11-18 11:51:09 +00:00
mod_ptr - > event_list = event_fn_ptr ;
2003-12-14 21:57:45 +00:00
mod_ptr - > isnewstyle = isnewstyle ;
2000-02-03 23:45:51 +00:00
2003-07-11 13:43:27 +00:00
/* assign a module number to this module */
i = 0 ;
2003-11-03 13:57:11 +00:00
while ( ModList [ i ] ! = NULL )
2003-07-30 13:58:22 +00:00
i + + ;
2003-07-11 13:43:27 +00:00
/* no need to check for overflow of NUM_MODULES, as its done above */
2003-11-03 13:57:11 +00:00
ModList [ i ] = mod_ptr ;
nlog ( LOG_DEBUG1 , LOG_CORE , " Assigned %d to Module %s for ModuleNum " , i , mod_ptr - > info - > module_name ) ;
2003-07-30 13:58:22 +00:00
2004-02-26 22:07:32 +00:00
/* Module side user authentication for SecureServ helpers */
2004-02-29 22:32:29 +00:00
mod_ptr - > mod_auth_cb = ns_dlsym ( ( int * ) dl_handle , " __ModuleAuth " ) ;
2004-02-26 22:07:32 +00:00
2003-10-07 15:00:03 +00:00
/* call __ModInit (replacement for library __init() call */
2004-02-02 20:19:17 +00:00
ModInit = ns_dlsym ( ( int * ) dl_handle , " __ModInit " ) ;
2003-12-14 21:57:45 +00:00
if ( ModInit ) {
2004-02-19 21:54:50 +00:00
int err ;
2003-09-18 12:21:32 +00:00
SET_SEGV_LOCATION ( ) ;
2003-09-29 12:46:22 +00:00
SET_SEGV_INMODULE ( mod_ptr - > info - > module_name ) ;
2004-02-19 21:54:50 +00:00
err = ( * ModInit ) ( i , API_VER ) ;
if ( err = = NS_ERR_VERSION ) {
nlog ( LOG_NORMAL , LOG_CORE , " Module %s was built with an old version of NeoStats. Please recompile %s. " , mod_ptr - > info - > module_name , mod_ptr - > info - > module_name ) ;
unload_module ( mod_ptr - > info - > module_name , NULL ) ;
return NS_FAILURE ;
}
else if ( err < 1 ) {
2003-11-03 13:57:11 +00:00
nlog ( LOG_NORMAL , LOG_CORE , " Unable to load module %s. See %s.log for further information. " , mod_ptr - > info - > module_name , mod_ptr - > info - > module_name ) ;
unload_module ( mod_ptr - > info - > module_name , NULL ) ;
return NS_FAILURE ;
2003-08-07 12:31:43 +00:00
}
2003-09-29 12:46:22 +00:00
CLEAR_SEGV_INMODULE ( ) ;
2004-01-30 21:27:43 +00:00
SET_SEGV_LOCATION ( ) ;
2003-08-07 12:31:43 +00:00
}
2000-02-03 23:45:51 +00:00
/* Let this module know we are online if we are! */
2000-12-10 06:25:51 +00:00
if ( me . onchan = = 1 ) {
2003-06-13 13:11:50 +00:00
while ( event_fn_ptr - > cmd_name ! = NULL ) {
2004-01-27 13:32:54 +00:00
if ( ! ircstrcasecmp ( event_fn_ptr - > cmd_name , EVENT_ONLINE ) ) {
2003-07-30 13:58:22 +00:00
AddStringToList ( & av , me . s - > name , & ac ) ;
2003-09-18 12:21:32 +00:00
SET_SEGV_LOCATION ( ) ;
2003-09-29 12:46:22 +00:00
SET_SEGV_INMODULE ( mod_ptr - > info - > module_name ) ;
2003-07-30 13:58:22 +00:00
event_fn_ptr - > function ( av , ac ) ;
2003-09-29 12:46:22 +00:00
CLEAR_SEGV_INMODULE ( ) ;
2004-01-30 21:27:43 +00:00
SET_SEGV_LOCATION ( ) ;
2003-07-30 13:58:22 +00:00
free ( av ) ;
2000-12-10 06:25:51 +00:00
break ;
}
event_fn_ptr + + ;
}
}
2003-09-18 11:22:03 +00:00
if ( do_msg ) {
2003-07-30 13:58:22 +00:00
prefmsg ( u - > nick , s_Services , " Module %s Loaded, Description: %s " , mod_info_ptr - > module_name , mod_info_ptr - > module_description ) ;
globops ( me . name , " %s Module Loaded " , mod_info_ptr - > module_name ) ;
2003-09-18 11:22:03 +00:00
}
2003-11-03 13:57:11 +00:00
return NS_SUCCESS ;
2002-03-18 05:46:15 +00:00
}
2003-10-06 16:33:42 +00:00
2003-10-10 23:07:30 +00:00
/** @brief
2003-10-06 16:33:42 +00:00
*
2003-10-10 23:07:30 +00:00
* @ param
*
* @ return
2003-10-06 16:33:42 +00:00
*/
int
2003-07-30 13:58:22 +00:00
get_dl_handle ( char * mod_name )
2003-06-13 13:11:50 +00:00
{
2003-11-18 11:51:09 +00:00
Module * mod_ptr ;
2002-02-28 07:54:13 +00:00
hnode_t * mn ;
2003-10-06 16:33:42 +00:00
2003-07-30 13:58:22 +00:00
mn = hash_lookup ( mh , mod_name ) ;
2002-02-28 07:54:13 +00:00
if ( mn ) {
2003-11-18 11:51:09 +00:00
mod_ptr = hnode_get ( mn ) ;
return ( int ) mod_ptr - > dl_handle ;
2002-02-27 11:19:15 +00:00
}
return 0 ;
}
2003-10-06 16:33:42 +00:00
2003-10-10 23:07:30 +00:00
/** @brief
2003-10-06 16:33:42 +00:00
*
2003-10-10 23:07:30 +00:00
* @ param
*
* @ return
2003-10-06 16:33:42 +00:00
*/
int
2003-07-30 13:58:22 +00:00
get_mod_num ( char * mod_name )
2003-07-11 13:43:27 +00:00
{
int i ;
2003-10-06 16:33:42 +00:00
for ( i = 0 ; i < NUM_MODULES ; i + + ) {
2003-11-03 13:57:11 +00:00
if ( ModList [ i ] ! = NULL ) {
2004-01-27 13:32:54 +00:00
if ( ! ircstrcasecmp ( ModList [ i ] - > info - > module_name , mod_name ) ) {
2003-07-11 13:43:27 +00:00
return i ;
}
}
}
/* if we get here, it wasn't found */
2004-01-12 18:46:56 +00:00
nlog ( LOG_DEBUG1 , LOG_CORE , " get_mod_num: can't find %s in module number list " , mod_name ) ;
2003-11-03 13:57:11 +00:00
return NS_FAILURE ;
2003-10-10 23:07:30 +00:00
}
2002-02-27 11:19:15 +00:00
2004-02-26 22:07:32 +00:00
/** @brief
*
* @ param
*
* @ return
*/
Module *
get_mod_ptr ( char * mod_name )
{
int i ;
for ( i = 0 ; i < NUM_MODULES ; i + + ) {
if ( ModList [ i ] ! = NULL ) {
if ( ! ircstrcasecmp ( ModList [ i ] - > info - > module_name , mod_name ) ) {
return ModList [ i ] ;
}
}
}
/* if we get here, it wasn't found */
nlog ( LOG_DEBUG1 , LOG_CORE , " get_mod_ptr: can't find %s in module number list " , mod_name ) ;
return NULL ;
}
2003-10-10 23:07:30 +00:00
/** @brief
2003-10-06 16:33:42 +00:00
*
2003-10-10 23:07:30 +00:00
* @ param
*
* @ return
2003-10-06 16:33:42 +00:00
*/
2003-11-27 22:49:10 +00:00
int
2003-11-18 11:51:09 +00:00
list_modules ( User * u , char * * av , int ac )
2003-06-13 13:11:50 +00:00
{
2000-02-03 23:45:51 +00:00
Module * mod_ptr = NULL ;
2002-02-28 07:54:13 +00:00
hnode_t * mn ;
hscan_t hs ;
2003-06-13 13:11:50 +00:00
2003-09-18 12:21:32 +00:00
SET_SEGV_LOCATION ( ) ;
2003-07-30 13:58:22 +00:00
hash_scan_begin ( & hs , mh ) ;
while ( ( mn = hash_scan_next ( & hs ) ) ! = NULL ) {
mod_ptr = hnode_get ( mn ) ;
prefmsg ( u - > nick , s_Services , " Module: %s (%s) " , mod_ptr - > info - > module_name , mod_ptr - > info - > module_version ) ;
prefmsg ( u - > nick , s_Services , " Module Description: %s " , mod_ptr - > info - > module_description ) ;
prefmsg ( u - > nick , s_Services , " Module Number: %d " , get_mod_num ( mod_ptr - > info - > module_name ) ) ;
}
prefmsg ( u - > nick , s_Services , " End of Module List " ) ;
2003-11-27 22:49:10 +00:00
return 0 ;
2003-06-13 13:11:50 +00:00
}
2000-02-03 23:45:51 +00:00
2003-10-10 23:07:30 +00:00
/** @brief
2003-10-06 16:33:42 +00:00
*
2003-10-10 23:07:30 +00:00
* @ param
*
* @ return
2003-10-06 16:33:42 +00:00
*/
2003-07-30 13:58:22 +00:00
int
unload_module ( char * module_name , User * u )
2003-06-13 13:11:50 +00:00
{
2003-11-18 11:51:09 +00:00
Module * mod_ptr ;
2002-02-28 07:54:13 +00:00
hnode_t * modnode ;
2003-07-11 13:43:27 +00:00
int i ;
2003-12-14 21:57:45 +00:00
void ( * ModFini ) ( ) ;
2003-08-07 12:31:43 +00:00
2003-09-18 12:21:32 +00:00
SET_SEGV_LOCATION ( ) ;
2003-09-23 11:57:07 +00:00
/* Check to see if this Module is loaded.... */
2003-07-30 13:58:22 +00:00
modnode = hash_lookup ( mh , module_name ) ;
2003-04-15 14:03:44 +00:00
if ( modnode ) {
2003-07-30 13:58:22 +00:00
chanalert ( s_Services , " Unloading Module %s " , module_name ) ;
2003-04-15 14:03:44 +00:00
} else {
if ( u ) {
2003-10-10 23:07:30 +00:00
prefmsg ( u - > nick , s_Services , " Couldn't Find Module %s Loaded, Try /msg %s modlist " , module_name , s_Services ) ;
2003-07-30 13:58:22 +00:00
chanalert ( s_Services , " %s tried to Unload %s but its not loaded " , u - > nick , module_name ) ;
2003-04-15 14:03:44 +00:00
}
2003-11-03 13:57:11 +00:00
return NS_FAILURE ;
2003-04-15 14:03:44 +00:00
}
2002-02-28 07:54:13 +00:00
2004-02-21 07:22:02 +00:00
/* canx any DNS queries running */
canx_dns ( module_name ) ;
2003-09-23 11:57:07 +00:00
/* Check to see if this Module has any timers registered.... */
2003-12-14 21:57:45 +00:00
del_mod_timers ( module_name ) ;
2002-02-28 07:54:13 +00:00
/* check if the module had a socket registered... */
2003-12-14 21:57:45 +00:00
del_sockets ( module_name ) ;
2000-02-04 02:54:12 +00:00
2003-09-23 11:57:07 +00:00
/* Remove module.... */
2003-07-30 13:58:22 +00:00
modnode = hash_lookup ( mh , module_name ) ;
2002-02-28 07:54:13 +00:00
if ( modnode ) {
2003-07-30 13:58:22 +00:00
nlog ( LOG_DEBUG1 , LOG_CORE , " Deleting Module %s from ModHash " , module_name ) ;
globops ( me . name , " %s Module Unloaded " , module_name ) ;
2003-07-11 13:43:27 +00:00
2003-07-30 13:58:22 +00:00
i = get_mod_num ( module_name ) ;
2003-07-11 13:43:27 +00:00
2003-11-18 11:51:09 +00:00
mod_ptr = hnode_get ( modnode ) ;
2004-01-31 06:26:56 +00:00
/* Remove from the module hash so we dont call events for this module during hte signoff*/
hash_delete ( mh , modnode ) ;
2003-10-07 15:00:03 +00:00
/* call __ModFini (replacement for library __fini() call */
2004-02-02 20:19:17 +00:00
ModFini = ns_dlsym ( ( int * ) mod_ptr - > dl_handle , " __ModFini " ) ;
2003-12-14 21:57:45 +00:00
if ( ModFini ) {
2004-01-30 21:27:43 +00:00
SET_SEGV_INMODULE ( module_name ) ;
2003-12-14 21:57:45 +00:00
( * ModFini ) ( ) ;
2004-01-30 21:27:43 +00:00
CLEAR_SEGV_INMODULE ( ) ;
2003-08-07 12:31:43 +00:00
}
2004-01-31 06:26:56 +00:00
2003-12-14 23:40:22 +00:00
/* now, see if this Module has any bots with it
* we delete the modules * after * we call ModFini , so the bot
* can still send messages generated from ModFini calls */
2003-12-14 22:09:12 +00:00
del_bots ( module_name ) ;
2003-11-03 13:57:11 +00:00
2003-07-30 13:58:22 +00:00
hnode_destroy ( modnode ) ;
2003-10-06 16:33:42 +00:00
/* Close module */
2003-09-29 12:46:22 +00:00
SET_SEGV_INMODULE ( module_name ) ;
2003-11-05 15:00:12 +00:00
# ifndef VALGRIND
2004-02-02 20:19:17 +00:00
ns_dlclose ( mod_ptr - > dl_handle ) ;
2003-11-05 15:00:12 +00:00
# endif
2003-09-29 12:46:22 +00:00
CLEAR_SEGV_INMODULE ( ) ;
2003-07-11 13:43:27 +00:00
if ( i > = 0 ) {
2003-07-30 13:58:22 +00:00
nlog ( LOG_DEBUG1 , LOG_CORE , " Freeing %d from Module Numbers " , i ) ;
2003-07-11 13:43:27 +00:00
/* free the module number */
2003-11-03 13:57:11 +00:00
ModList [ i ] = NULL ;
2003-07-11 13:43:27 +00:00
}
2003-11-18 11:51:09 +00:00
free ( mod_ptr ) ;
2003-11-03 13:57:11 +00:00
return NS_SUCCESS ;
2003-06-13 13:11:50 +00:00
}
2003-11-03 13:57:11 +00:00
return NS_FAILURE ;
2000-02-03 23:45:51 +00:00
}
2003-10-06 16:33:42 +00:00
2003-10-10 23:07:30 +00:00
/** @brief unload all loaded modules
*
* For core use only , unloads all loaded modules
*
* @ param user pointer to user unloading modules or NULL if system unload
*
* @ return none
*/
2003-11-03 13:57:11 +00:00
void unload_modules ( void )
2003-10-07 12:16:32 +00:00
{
2003-10-10 23:07:30 +00:00
Module * mod_ptr ;
2003-10-07 12:16:32 +00:00
hscan_t ms ;
hnode_t * mn ;
/* Unload the Modules */
hash_scan_begin ( & ms , mh ) ;
while ( ( mn = hash_scan_next ( & ms ) ) ! = NULL ) {
mod_ptr = hnode_get ( mn ) ;
2003-11-03 13:57:11 +00:00
unload_module ( mod_ptr - > info - > module_name , NULL ) ;
2003-10-07 12:16:32 +00:00
}
}