2023-08-02 15:03:27 -04:00
|
|
|
/* irc.c - IRC interface
|
|
|
|
|
|
|
|
Probotic is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License version 3 only as
|
|
|
|
published by the Free Software Foundation.
|
|
|
|
|
|
|
|
Probotic 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 version 3 for more details.
|
|
|
|
|
|
|
|
The above copyright notice, this permission notice and the word
|
|
|
|
"NIGGER" shall be included in all copies or substantial portions
|
|
|
|
of the Software.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
version 3 + NIGGER along with Probotic.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2023-08-03 02:16:39 -04:00
|
|
|
#include <assert.h>
|
2023-08-02 15:27:59 -04:00
|
|
|
#include <stdio.h>
|
2023-08-02 15:03:27 -04:00
|
|
|
#include <stdarg.h>
|
2023-08-02 15:27:59 -04:00
|
|
|
#include <string.h>
|
2023-08-03 23:27:25 -04:00
|
|
|
#include <time.h>
|
|
|
|
#include <stdlib.h>
|
2023-08-02 15:27:59 -04:00
|
|
|
|
|
|
|
#include "api.h"
|
|
|
|
#include "error.h"
|
2023-08-03 23:39:15 -04:00
|
|
|
#include "irc.h"
|
2023-08-03 23:27:25 -04:00
|
|
|
#include "irccolors.h"
|
2023-08-03 23:39:15 -04:00
|
|
|
#include "parse.h"
|
|
|
|
|
|
|
|
char const * help_msg =
|
|
|
|
IRC_GREEN "!help " IRC_STOP " : This message\n"
|
|
|
|
IRC_GREEN "!remind " IRC_STOP " : Dump current assignment\n"
|
|
|
|
IRC_GREEN "!reroll " IRC_STOP " : Rerolls assignment\n"
|
|
|
|
IRC_GREEN "!set_repo <link>" IRC_STOP " : Sets project repository link\n"
|
|
|
|
IRC_GREEN "!raw <sql> " IRC_STOP " : Execute raw SQL\n"
|
|
|
|
IRC_GREEN "!dump " IRC_STOP " : List all possible projects\n"
|
|
|
|
IRC_GREEN "!request " IRC_STOP " : Request personal project\n"
|
|
|
|
IRC_GREEN "!remind " IRC_STOP " : Prints your assignment\n";
|
|
|
|
|
|
|
|
char const * fmsg =
|
|
|
|
"%s\x2C\x20\x79\x6F\x75\x20\x61\x72\x65\x20\x66\x61\x67\x67"
|
|
|
|
"\x6F\x74\x20\x66\x6F\x72\x20\x74\x68\x61\x74\x20\x6F\x70"
|
|
|
|
"\x69\x6E\x69\x6F\x6E\x2E";
|
2023-08-02 15:03:27 -04:00
|
|
|
|
2023-08-02 16:38:32 -04:00
|
|
|
#define PREFIX_COMMAND_CHAR '!'
|
2023-08-03 23:27:25 -04:00
|
|
|
#define PREFIX_CHANNEL_COMMAND_CHAR '%'
|
2023-08-02 16:38:32 -04:00
|
|
|
|
2023-08-02 15:03:27 -04:00
|
|
|
irc_session_t * session;
|
|
|
|
irc_callbacks_t callbacks;
|
|
|
|
|
2023-08-03 23:27:25 -04:00
|
|
|
char * current_username = NULL;
|
|
|
|
int f = -1;
|
2023-08-02 15:03:27 -04:00
|
|
|
|
2023-08-03 02:16:39 -04:00
|
|
|
#define IRCMSG(msg) irc_cmd_msg(session, creds.channel, msg)
|
2023-08-02 15:03:27 -04:00
|
|
|
|
2023-08-02 23:24:30 -04:00
|
|
|
DECL char *
|
2023-08-02 15:03:27 -04:00
|
|
|
get_username(const char * origin)
|
|
|
|
{
|
|
|
|
const char USERNAME_TERMINATOR = '!';
|
|
|
|
int i = 0;
|
|
|
|
char * r;
|
|
|
|
while (origin[i] != USERNAME_TERMINATOR)
|
|
|
|
{ i++; }
|
|
|
|
r = (char *) malloc(i + 1);
|
|
|
|
strncpy(r, origin, i);
|
|
|
|
r[i] = '\00';
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2023-08-02 23:24:30 -04:00
|
|
|
DECL void
|
2023-08-02 16:38:32 -04:00
|
|
|
ircmsg(const char* fmt,
|
|
|
|
...)
|
2023-08-02 15:03:27 -04:00
|
|
|
{
|
2023-08-03 23:27:25 -04:00
|
|
|
if(!strcmp(fmt, "") || fmt == NULL){ return; }
|
2023-08-02 15:03:27 -04:00
|
|
|
va_list args;
|
|
|
|
char * fmtdmsg;
|
2023-08-03 23:27:25 -04:00
|
|
|
char * swp;
|
2023-08-02 15:03:27 -04:00
|
|
|
|
|
|
|
va_start(args, fmt);
|
|
|
|
if(vasprintf(&fmtdmsg, fmt, args) == -1)
|
|
|
|
{ exit(1); }
|
|
|
|
|
|
|
|
puts(fmtdmsg);
|
2023-08-03 23:27:25 -04:00
|
|
|
const char* delim = "\n";
|
|
|
|
char* data = strtok(fmtdmsg, delim);
|
|
|
|
do{
|
|
|
|
swp = irc_color_convert_to_mirc(data);
|
|
|
|
IRCMSG(swp);
|
|
|
|
free(swp);
|
|
|
|
}while((data = strtok(NULL, delim), data));
|
2023-08-02 15:03:27 -04:00
|
|
|
|
|
|
|
free(fmtdmsg);
|
|
|
|
va_end(args);
|
|
|
|
}
|
|
|
|
|
2023-08-02 23:24:30 -04:00
|
|
|
DECL void
|
2023-08-02 15:03:27 -04:00
|
|
|
event_connect(irc_session_t * session,
|
|
|
|
const char * event,
|
|
|
|
const char * origin,
|
|
|
|
const char ** params,
|
|
|
|
unsigned int count)
|
|
|
|
{
|
|
|
|
(void) event;
|
|
|
|
(void) origin;
|
|
|
|
(void) params;
|
|
|
|
(void) count;
|
2023-08-03 02:16:39 -04:00
|
|
|
/* msg ChanServ IDENTIFY? */
|
|
|
|
irc_cmd_join(session, creds.channel, 0);
|
2023-08-02 15:03:27 -04:00
|
|
|
}
|
|
|
|
|
2023-08-02 23:24:30 -04:00
|
|
|
DECL void
|
2023-08-02 15:03:27 -04:00
|
|
|
event_channel(irc_session_t * session,
|
2023-08-02 16:38:32 -04:00
|
|
|
char const * event,
|
|
|
|
char const * origin,
|
|
|
|
char const ** params,
|
2023-08-02 15:03:27 -04:00
|
|
|
unsigned int count)
|
|
|
|
{
|
2023-08-02 16:38:32 -04:00
|
|
|
/* char const * channel = params[0]; */
|
|
|
|
char const * message = params[1];
|
2023-08-02 15:03:27 -04:00
|
|
|
(void) session;
|
|
|
|
(void) event;
|
|
|
|
(void) origin;
|
2023-08-02 16:38:32 -04:00
|
|
|
/* (void) channel; */
|
2023-08-02 15:03:27 -04:00
|
|
|
(void) message;
|
|
|
|
(void) count;
|
|
|
|
/* parses the command */
|
2023-08-03 23:27:25 -04:00
|
|
|
switch(*message){
|
|
|
|
case PREFIX_CHANNEL_COMMAND_CHAR:
|
|
|
|
current_username = strdup(creds.channel);
|
|
|
|
break;
|
|
|
|
case PREFIX_COMMAND_CHAR:
|
|
|
|
current_username = get_username(origin);
|
|
|
|
break;
|
2023-08-02 15:03:27 -04:00
|
|
|
}
|
2023-08-03 23:27:25 -04:00
|
|
|
if(!current_username || *(message+1) == '\00'){ return; }
|
|
|
|
--f;
|
|
|
|
if(f == 0){ ircmsg(fmsg, current_username); }
|
|
|
|
parse_command(message+1);
|
2023-08-02 16:38:32 -04:00
|
|
|
free(current_username);
|
2023-08-03 23:27:25 -04:00
|
|
|
current_username = NULL;
|
2023-08-02 15:03:27 -04:00
|
|
|
}
|
|
|
|
|
2023-08-03 05:15:20 -04:00
|
|
|
DECL int
|
2023-08-03 02:16:39 -04:00
|
|
|
init(void)
|
2023-08-02 15:03:27 -04:00
|
|
|
{
|
2023-08-03 23:27:25 -04:00
|
|
|
srand(time(NULL));
|
2023-08-02 15:27:59 -04:00
|
|
|
if(api_init())
|
|
|
|
{ ERR(DB_ERROR, "Error initializing database."); }
|
2023-08-02 15:03:27 -04:00
|
|
|
memset(&callbacks, 0, sizeof(callbacks));
|
|
|
|
callbacks.event_connect = event_connect;
|
|
|
|
callbacks.event_channel = event_channel;
|
|
|
|
session = irc_create_session(&callbacks);
|
|
|
|
if (!session)
|
2023-08-03 22:36:49 -04:00
|
|
|
{
|
|
|
|
ERRMSG("Error creating IRC session");
|
|
|
|
goto fail;
|
|
|
|
}
|
2023-08-03 02:16:39 -04:00
|
|
|
assert(creds.username != NULL);
|
|
|
|
assert(creds.server != NULL);
|
|
|
|
irc_connect(session,
|
|
|
|
creds.server, creds.port, creds.password,
|
|
|
|
creds.username, creds.username, creds.username);
|
2023-08-03 22:36:49 -04:00
|
|
|
creds_free_password();
|
2023-08-03 02:16:39 -04:00
|
|
|
atexit(rope);
|
2023-08-03 05:15:20 -04:00
|
|
|
return 0;
|
2023-08-03 22:36:49 -04:00
|
|
|
fail:
|
|
|
|
creds_free_password();
|
|
|
|
return 1;
|
2023-08-03 05:15:20 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
DECL int
|
|
|
|
loop(void)
|
|
|
|
{
|
2023-08-03 02:16:39 -04:00
|
|
|
/* We should figure out how the failure happens so we can tell the user that. */
|
|
|
|
if (irc_run(session) != 0)
|
|
|
|
{ ERR(1, "Error running IRC session\nPossible issue: bad URL,"
|
|
|
|
" no network connection, bad port, refused connection."); }
|
2023-08-02 15:03:27 -04:00
|
|
|
return 0;
|
|
|
|
}
|