2021-03-11 12:48:15 -05:00
/*
2021-03-11 20:48:32 -05:00
* Dictionary bot .
*
* Code adapted from :
*
2021-03-11 12:48:15 -05:00
* < https : //gist.github.com/enile8/2424514>
* < https : //www.rosettacode.org/wiki/Write_entire_file#C>
* < https : //rosettacode.org/wiki/Read_entire_file#C>
* libircclient - 1.10 / examples / spammer . c
*
2021-03-11 20:48:32 -05:00
* And surely others .
*
2021-03-11 12:48:15 -05:00
* Copyright ( C ) 2004 - 2009 Georgy Yunaev gyunaev @ ulduzsoft . com
* Copyright ( C ) 2021 Bubblegumdrop < Bubblegumdrop @ lain . church >
*
* This example is free , and not covered by LGPL license . There is no
* restriction applied to their modification , redistribution , using and so on .
* You can study them , modify them , use them in your own program - either
* completely or partially . By using it you may give me some credits in your
* program , but you don ' t have to .
*
* DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
* Version 2 , December 2004
*
* Copyright ( C ) 2004 Sam Hocevar < sam @ hocevar . net >
* Copyright ( C ) 2021 Bubblegumdrop < Bubblegumdrop @ lain . church >
*
* Everyone is permitted to copy and distribute verbatim or modified
* copies of this license document , and changing it is allowed as long
* as the name is changed .
*
* DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
* TERMS AND CONDITIONS FOR COPYING , DISTRIBUTION AND MODIFICATION
*
* 0. You just DO WHAT THE FUCK YOU WANT TO .
*/
2021-03-11 17:23:43 -05:00
# define _POSIX_C_SOURCE 200809L /* strtok_r, strndup */
2021-03-11 12:48:15 -05:00
# include <string.h>
# include <assert.h> /* assert */
# include <errno.h>
2021-03-11 17:23:43 -05:00
# include <getopt.h> /* getopt */
2021-03-11 12:48:15 -05:00
# include <stdio.h> /* size_t */
# include <unistd.h> /* getopt */
# include "libircclient.h"
# include "data.h"
# include "db.h"
# include "events.h"
# include "levenshtein.h"
2021-03-11 20:48:32 -05:00
# include "strings.h"
2021-03-11 12:48:15 -05:00
# include "threads.h"
# ifndef UNUSED
# define UNUSED(x) (void)(x)
# endif
2021-03-11 17:23:43 -05:00
extern void install_signal_handler ( void ) ;
2021-03-11 12:48:15 -05:00
char F_IRC_THREAD = STOPPED ;
char F_MAIN_THREAD = STOPPED ;
2021-03-11 17:23:43 -05:00
irc_session_t * irc_session = NULL ;
2021-03-11 20:48:32 -05:00
const char create_db_query [ ] = " create table if not exists quotedb (date_added text not null, added_by text not null, channel text not null, subject text not null, words text not null) " ;
THREAD_FUNCTION ( IrcSessionThread ) {
2021-03-11 12:48:15 -05:00
const char * server ;
2021-03-11 17:23:43 -05:00
struct irc_ctx_t * ctx ;
2021-03-11 20:48:32 -05:00
irc_callbacks_t callbacks ;
2021-03-11 17:23:43 -05:00
ctx = ( struct irc_ctx_t * ) arg ;
2021-03-11 12:48:15 -05:00
assert ( NULL ! = ctx ) ;
server = ctx - > server ;
assert ( NULL ! = server ) ;
assert ( NULL ! = ctx - > nick ) ;
assert ( NULL ! = ctx - > channel ) ;
while ( RUNNING = = F_IRC_THREAD ) {
/* Initialize the callbacks */
memset ( & callbacks , 0 , sizeof ( callbacks ) ) ;
/* Set up the callbacks we will use */
callbacks . event_channel = event_channel ;
callbacks . event_connect = event_connect ;
callbacks . event_join = event_join ;
callbacks . event_nick = event_nick ;
callbacks . event_numeric = event_numeric ;
/* And create the IRC session; 0 means error */
2021-03-11 17:23:43 -05:00
irc_session = irc_create_session ( & callbacks ) ;
if ( ! irc_session ) {
2021-03-11 20:48:32 -05:00
fprintf ( stderr , string_connect_failure , irc_strerror ( irc_errno ( irc_session ) ) ) ;
2021-03-11 17:23:43 -05:00
F_IRC_THREAD = STOPPED ;
2021-03-11 12:48:15 -05:00
}
2021-03-11 17:23:43 -05:00
irc_set_ctx ( irc_session , ctx ) ;
irc_option_set ( irc_session , LIBIRC_OPTION_STRIPNICKS ) ;
2021-03-11 12:48:15 -05:00
/* If the port number is specified in the server string, use the port 0 so it gets parsed */
if ( strchr ( server , ' : ' ) ! = 0 )
2021-03-11 17:23:43 -05:00
ctx - > port = 0 ;
2021-03-11 12:48:15 -05:00
/*
* To handle the " SSL certificate verify failed " from command line we allow passing # # in front
* of the server name , and in this case tell libircclient not to verify the cert
*/
if ( server [ 0 ] = = ' # ' & & server [ 0 ] = = ' # ' ) {
/* Skip the first character as libircclient needs only one # for SSL support, i.e. #irc.freenode.net */
server + + ;
2021-03-11 17:23:43 -05:00
irc_option_set ( irc_session , LIBIRC_OPTION_SSL_NO_VERIFY ) ;
2021-03-11 12:48:15 -05:00
}
/* Initiate the IRC server connection */
2021-03-11 17:23:43 -05:00
if ( irc_connect ( irc_session , server , ctx - > port , 0 , ctx - > nick , 0 , 0 ) ) {
2021-03-11 20:48:32 -05:00
fprintf ( stderr , string_connect_failure , irc_strerror ( irc_errno ( irc_session ) ) ) ;
2021-03-11 17:23:43 -05:00
F_IRC_THREAD = STOPPED ;
2021-03-11 12:48:15 -05:00
}
/* and run into forever loop, generating events */
2021-03-11 17:23:43 -05:00
if ( irc_run ( irc_session ) ) {
2021-03-11 20:48:32 -05:00
fprintf ( stderr , string_connect_failure , irc_strerror ( irc_errno ( irc_session ) ) ) ;
2021-03-11 17:23:43 -05:00
F_IRC_THREAD = STOPPED ;
2021-03-11 12:48:15 -05:00
}
2021-03-11 20:48:32 -05:00
irc_destroy_session ( irc_session ) ;
irc_session = NULL ;
2021-03-11 12:48:15 -05:00
}
2021-03-11 17:23:43 -05:00
F_MAIN_THREAD = STOPPED ;
2021-03-11 20:48:32 -05:00
# ifdef _WIN32
return 0 ;
# else
2021-03-11 17:23:43 -05:00
return NULL ;
2021-03-11 20:48:32 -05:00
# endif
2021-03-11 12:48:15 -05:00
}
2021-03-11 17:23:43 -05:00
int main ( int argc , char * argv [ ] ) {
2021-03-11 20:48:32 -05:00
int rc ;
int opt ;
const char * db_name ;
const char * query_str ;
const char * filename ;
sqlite3 * db ;
2021-03-11 17:23:43 -05:00
struct irc_ctx_t ctx ;
2021-03-11 12:48:15 -05:00
thread_id_t tid ;
#if 0
const char * s1 = " rosettacode " ;
const char * s2 = " raisethysword " ;
printf ( " distance between `%s' and `%s': %d \n " , s1 , s2 , levenshtein ( s1 , s2 ) ) ;
# endif
2021-03-11 20:48:32 -05:00
install_signal_handler ( ) ;
2021-03-11 12:48:15 -05:00
db_name = " familyGuy.sqlite3 " ;
2021-03-11 20:48:32 -05:00
query_str = NULL ;
filename = NULL ;
rc = - 1 ;
db = NULL ;
2021-03-11 17:23:43 -05:00
memset ( & ctx , 0 , sizeof ( struct irc_ctx_t ) ) ;
ctx . port = 6667 ;
2021-03-11 20:48:32 -05:00
while ( ( opt = getopt ( argc , argv , " c:d:f:hn:p:q:s: " ) ) ! = - 1 ) {
2021-03-11 12:48:15 -05:00
switch ( opt ) {
2021-03-11 20:48:32 -05:00
case ' c ' :
ctx . channel = optarg ;
2021-03-11 12:48:15 -05:00
break ;
case ' d ' :
db_name = optarg ;
break ;
2021-03-11 20:48:32 -05:00
case ' f ' :
filename = optarg ;
break ;
case ' n ' :
ctx . nick = optarg ;
break ;
2021-03-11 17:23:43 -05:00
case ' p ' :
ctx . port = atoi ( optarg ) ;
break ;
2021-03-11 20:48:32 -05:00
case ' q ' :
query_str = optarg ;
break ;
case ' s ' :
ctx . server = optarg ;
2021-03-11 12:48:15 -05:00
break ;
case ' h ' :
default :
2021-03-11 20:48:32 -05:00
fprintf ( stderr , string_usage_fmt , argv [ 0 ] ) ;
2021-03-11 12:48:15 -05:00
return - 1 ;
break ;
}
}
if ( NULL ! = db_name ) {
2021-03-11 13:25:53 -05:00
if ( SQLITE_OK = = ( rc = sqlite3_open ( db_name , & db ) ) ) {
2021-03-11 20:48:32 -05:00
printf ( string_opendb_success ) ;
2021-03-11 13:25:53 -05:00
sqlite_version ( db ) ;
2021-03-11 12:48:15 -05:00
}
} else {
2021-03-11 20:48:32 -05:00
fprintf ( stderr , string_opendb_failure , sqlite3_errmsg ( db ) ) ;
2021-03-11 13:25:53 -05:00
return - 1 ;
2021-03-11 12:48:15 -05:00
}
2021-03-11 20:48:32 -05:00
/*run_one(db, create_db_query);*/
2021-03-11 12:48:15 -05:00
2021-03-11 20:48:32 -05:00
if ( NULL ! = query_str ) {
rc = run_one ( db , query_str ) ;
} else if ( NULL ! = filename ) {
rc = run_script ( db , filename ) ;
2021-03-11 12:48:15 -05:00
} else if ( argc = = 4 ) {
2021-03-11 20:48:32 -05:00
if ( argc > 1 )
ctx . server = argv [ 1 ] ;
if ( argc > 2 )
ctx . nick = argv [ 2 ] ;
if ( argc > 3 )
ctx . channel = argv [ 3 ] ;
if ( ! ctx . server | | ! ctx . nick | | ! ctx . channel ) {
fprintf ( stderr , string_usage_fmt , argv [ 0 ] ) ;
return - 1 ;
}
2021-03-11 17:23:43 -05:00
F_IRC_THREAD = RUNNING ;
F_MAIN_THREAD = RUNNING ;
2021-03-11 20:48:32 -05:00
if ( CREATE_THREAD ( & tid , IrcSessionThread , & ctx ) ) {
printf ( string_ircthread_failure , strerror ( errno ) ) ;
2021-03-11 12:48:15 -05:00
} else {
2021-03-11 20:48:32 -05:00
printf ( string_ircthread_success ) ;
2021-03-11 12:48:15 -05:00
}
while ( RUNNING = = F_MAIN_THREAD ) {
sleep ( 1 ) ;
}
2021-03-11 20:48:32 -05:00
F_IRC_THREAD = STOPPED ;
F_SPAM_THREADS = STOPPED ;
rc = 0 ;
2021-03-11 12:48:15 -05:00
} else {
2021-03-11 20:48:32 -05:00
fprintf ( stderr , string_usage_fmt , argv [ 0 ] ) ;
return - 1 ;
2021-03-11 12:48:15 -05:00
}
2021-03-11 17:23:43 -05:00
2021-03-11 12:48:15 -05:00
sqlite3_close ( db ) ;
2021-03-11 20:48:32 -05:00
return rc ;
2021-03-11 12:48:15 -05:00
}