aboutsummaryrefslogtreecommitdiff
path: root/src/irc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/irc.c')
-rw-r--r--src/irc.c173
1 files changed, 173 insertions, 0 deletions
diff --git a/src/irc.c b/src/irc.c
new file mode 100644
index 0000000..a9b8ffb
--- /dev/null
+++ b/src/irc.c
@@ -0,0 +1,173 @@
+/* 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.
+
+ You should have received a copy of the GNU General Public License
+ version 3 along with Probotic.
+
+*/
+
+VARDECL 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";
+
+VARDECL 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";
+
+#define PREFIX_COMMAND_CHAR '!'
+#define PREFIX_CHANNEL_COMMAND_CHAR '%'
+
+VARDECL irc_session_t * session;
+VARDECL irc_callbacks_t callbacks;
+
+VARDECL char * current_username = NULL;
+/* Do you have any idea how many things this breaks? */
+int stupid_shit = -1;
+
+#define IRCMSG(msg) irc_cmd_msg(session, creds.channel, msg)
+
+DECL char *
+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;
+}
+
+DECL void
+ircmsg(const char* fmt,
+ ...)
+{
+ if(!strcmp(fmt, "") || fmt == NULL){ return; }
+ va_list args;
+ char * fmtdmsg;
+ char * swp;
+
+ va_start(args, fmt);
+ if(vasprintf(&fmtdmsg, fmt, args) == -1)
+ { exit(1); }
+
+ puts(fmtdmsg);
+ 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));
+
+ free(fmtdmsg);
+ va_end(args);
+}
+
+DECL void
+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;
+ /* msg ChanServ IDENTIFY? */
+ irc_cmd_join(session, creds.channel, 0);
+ if(is_no_assignment(creds.channel)){
+ ircmsg(IRC_RED "No assignment for this channel. Finding a new..." IRC_STOP);
+ random_assign(creds.channel);
+ }
+ ircmsg(remind(creds.channel));
+}
+
+DECL void
+event_channel(irc_session_t * session,
+ char const * event,
+ char const * origin,
+ char const ** params,
+ unsigned int count)
+{
+ /* char const * channel = params[0]; */
+ char const * message = params[1];
+ (void) session;
+ (void) event;
+ (void) origin;
+ /* (void) channel; */
+ (void) message;
+ (void) count;
+ /* parses the command */
+ switch(*message){
+ case PREFIX_CHANNEL_COMMAND_CHAR:
+ current_username = strdup(creds.channel);
+ break;
+ case PREFIX_COMMAND_CHAR:
+ current_username = get_username(origin);
+ break;
+ }
+ if(!current_username || *(message+1) == '\00'){ return; }
+ --stupid_shit;
+ if(stupid_shit == 0)
+ { ircmsg(fmsg, current_username); }
+ parse_command(message+1);
+ free(current_username);
+ current_username = NULL;
+}
+
+DECL int
+init(void)
+{
+ srand(time(NULL));
+ if(api_init())
+ { ERR(DB_ERROR, "Error initializing database."); }
+ memset(&callbacks, 0, sizeof(callbacks));
+ callbacks.event_connect = event_connect;
+ callbacks.event_channel = event_channel;
+ session = irc_create_session(&callbacks);
+ if (!session)
+ {
+ ERRMSG("Error creating IRC session");
+ goto fail;
+ }
+ assert(creds.username != NULL);
+ assert(creds.server != NULL);
+ irc_connect(session,
+ creds.server, creds.port, creds.password,
+ creds.username, creds.username, creds.username);
+ creds_free_password();
+ atexit(rope);
+ return 0;
+fail:
+ creds_free_password();
+ return 1;
+}
+
+DECL int
+loop(void)
+{
+ /* 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."); }
+ return 0;
+}