aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cmd.c283
-rw-r--r--src/irc.c1
-rw-r--r--src/irc.h4
-rw-r--r--src/main.c11
4 files changed, 288 insertions, 11 deletions
diff --git a/src/cmd.c b/src/cmd.c
index 7c757b7..0e56705 100644
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -1,5 +1,7 @@
#include <atari.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include "irc.h"
#include "addrs.h"
#include "screen.h"
@@ -7,24 +9,68 @@
/* A "command" is actually anything the user types, whether or
not it starts with a /character. */
+char *command, *arg1, *arg2, *arg3;
static char *target;
-static const char *command;
-static char slashcmd[10];
-static char *slasharg;
-static void cmd_chan_text(void) {
- char s;
+static void do_color(void);
+static void do_info(void);
+static void do_j(void);
+static void do_list(void);
+static void do_me(void);
+static void do_msg(void);
+static void do_part(void);
+static void do_ping(void);
+static void do_query(void);
+static void do_quit(void);
+static void do_quote(void);
+static void do_ver(void);
+
+typedef struct {
+ char *cmd;
+ void (*func)(void);
+ char req_arg;
+} cmd_t;
+/* future commands:
+ OP DEOP VOICE DEVOICE KICK BAN KB IGNORE UNIGNORE MODE
+ */
+cmd_t command_defs[] = {
+ { "COLOR", do_color, 1 },
+ { "INFO", do_info, 0 },
+ { "J", do_j, 1 },
+ { "JOIN", do_j, 1 },
+ { "LIST", do_list, 1 },
+ { "M", do_msg, 1 },
+ { "ME", do_me, 1 },
+ { "MSG", do_msg, 1 },
+ { "PART", do_part, 0 },
+ { "PING", do_ping, 0 },
+ { "Q", do_query, 1 },
+ { "QUERY", do_query, 1 },
+ { "QUIT", do_quit, 0 },
+ { "QUOTE", do_quote, 1 },
+ { "VER", do_ver, 0 },
+ { "VERSION", do_ver, 0 },
+ { 0, 0 }
+};
+
+cmd_t *cmd_def;
+
+static void cmd_chan_text(void) {
scr_activate(scr_current);
/* 0x02 = ^B = enable bold */
scr_print_active("<\x02");
scr_print_active(usernick);
scr_print_active("\x02");
- if(!s) {
+
+ /*
+ if(!scr_current) {
scr_print_active("/");
scr_print_active(target);
}
+ */
+
scr_print_active("> ");
scr_print_active(command);
scr_eol_active();
@@ -36,20 +82,237 @@ static void cmd_chan_text(void) {
txbuf_send();
}
+
+///
+static void err_marker(void) {
+ scr_print_current("\x02***\x02 ");
+}
+
+static void err_arg_req(void) {
+ err_marker();
+ scr_print_current(cmd_def->cmd);
+ scr_print_current(" requires an argument\n");
+}
+
+static void err_no_scr_target(void) {
+ err_marker();
+ scr_print_current("No channel/nick for screen\n");
+}
+
+static void err_target_req(void) {
+ err_marker();
+ scr_print_current(cmd_def->cmd);
+ scr_print_current(" requires target channel/nick\n");
+}
+
+/* arg points to something like:
+ "part #channel I'm outta here\0"
+ after nextarg(), arg points to "part\0" only, and ret points
+ to "#channel I'm outta here\0". */
+static char *nextarg(char *arg) {
+ /* iterate over the first word */
+ while(*arg && *arg != ' ')
+ arg++;
+
+ /* if we found a space, replace it with a null terminator */
+ if(*arg)
+ *arg++ = 0;
+ else
+ return 0; /* found no space, there's no next arg! */
+
+ /* skip space(s) */
+ while(*arg && *arg == ' ')
+ arg++;
+
+ if(*arg)
+ return arg;
+
+ return 0;
+}
+
+static void do_j(void) {
+ /* TODO: add to channel list, once we have one */
+ txbuf_set_str2("JOIN ", arg1);
+ txbuf_send();
+}
+
+static void do_quit(void) {
+ txbuf_set_str("QUIT");
+ if(arg1)
+ txbuf_append_str2(" :", arg1);
+ txbuf_send();
+}
+
+static void do_part(void) {
+ if(arg1[0] == '#') {
+ target = arg1;
+ arg2 = nextarg(arg1);
+ } else {
+ arg2 = arg1;
+ }
+
+ if(!target) {
+ err_target_req();
+ return;
+ }
+
+ txbuf_set_str2("PART ", target);
+ if(arg2)
+ txbuf_append_str2(" :", arg2);
+ txbuf_send();
+}
+
+static void do_server_info(void) {
+ txbuf_send_str("INFO");
+}
+
+static void do_server_ping(void) {
+ txbuf_send_str("PING 0xdeadbeef");
+}
+
+static void do_ctcp_ping(void) {
+ txbuf_set_str3("PRIVMSG ", arg1, " :\x01");
+ txbuf_append_str("PING 0xdeadbeef\x01");
+ txbuf_send();
+}
+
+static void do_ctcp_info(void) {
+ txbuf_set_str3("PRIVMSG ", arg1, " :\x01");
+ txbuf_append_str("CLIENTINFO\x01");
+ txbuf_send();
+}
+
+static void do_ctcp_ver(void) {
+ txbuf_set_str3("PRIVMSG ", arg1, " :\x01");
+ txbuf_append_str("VERSION\x01");
+ txbuf_send();
+}
+
+static void do_me(void) {
+ if(!target) {
+ err_target_req();
+ return;
+ }
+
+ txbuf_set_str3("PRIVMSG ", target, " \x01:");
+ txbuf_append_str2(arg1, "\x01");
+ txbuf_send();
+}
+
+static void do_ping(void) {
+ if(arg1)
+ do_ctcp_ping();
+ else
+ do_server_ping();
+}
+
+static void do_list(void) {
+ txbuf_set_str2("LIST ", arg1);
+ txbuf_send();
+}
+
+static void do_info(void) {
+ if(arg1)
+ do_ctcp_info();
+ else
+ do_server_info();
+}
+
+static void do_quote(void) {
+ txbuf_send_str(arg1);
+}
+
+static void do_ver(void) {
+ if(arg1)
+ do_ctcp_ver();
+ else
+ txbuf_send_str("VERSION");
+}
+
+static void do_color(void) {
+ arg2 = nextarg(arg1);
+ OS.color2 = atoi(arg1);
+ if(arg2)
+ OS.color1 = atoi(arg2);
+}
+
+static void do_query(void) {
+ if(scr_create(arg1, 1) == 0xff) {
+ err_marker();
+ scr_print_current("Can't create query, all screens in use\n");
+ return;
+ }
+ scr_print_current("Starting conversation with ");
+ scr_print_current(arg1);
+ scr_print_current("\n");
+}
+
+static void do_msg(void) {
+ char s;
+ arg2 = nextarg(arg1);
+ if(arg2) {
+ // TODO: print message to screen!
+ // s = scr_getbyname(arg1);
+ // if(!s) s = SCR_PRIV;
+ txbuf_set_str3("PRIVMSG ", arg1, " :");
+ txbuf_append_str(arg2);
+ txbuf_send();
+ } else {
+ err_arg_req();
+ }
+}
+
+static int cmd_local(void) {
+ arg1 = nextarg(command);
+
+ scr_print_current("command: ");
+ scr_print_current(command);
+ scr_print_current("\n");
+
+ for(cmd_def = &command_defs[0]; cmd_def->cmd; cmd_def++) {
+ if(streq_i(command, cmd_def->cmd)) {
+ if(cmd_def->req_arg && !arg1) {
+ err_arg_req();
+ } else {
+ (*(cmd_def->func))();
+ }
+ scr_print_current("(did local command)\n");
+ return 1;
+ }
+ }
+
+ scr_print_current("(not a local command)\n");
+ return 0;
+}
+
+static void cmd_remote(void) {
+ txbuf_set_str(command);
+ if(arg1) {
+ txbuf_append_str2(" ", arg1);
+ }
+ txbuf_send();
+}
+///
+
+
+
static void cmd_slash(void) {
- txbuf_send_str(command + 1);
+ command++;
+ if(!cmd_local())
+ cmd_remote();
}
-void cmd_command(const char *cmd) {
+void cmd_command(char *cmd) {
command = cmd;
target = scr_get_cur_name();
- if(*cmd == '/')
+ if(cmd[0] == '/' && cmd[1] && cmd[1] != '/')
cmd_slash();
else if(target)
cmd_chan_text();
- else scr_print_current("*** You are not in a channel\n");
+ else
+ err_no_scr_target();
}
void cmd_execute(void) {
diff --git a/src/irc.c b/src/irc.c
index 238da87..7bb1bf6 100644
--- a/src/irc.c
+++ b/src/irc.c
@@ -164,6 +164,7 @@ static void do_mode(void) {
scr_print_active(" ");
scr_print_active(msg_args[i]);
}
+ if(msg_text) scr_print_active(msg_text);
scr_eol_active();
}
diff --git a/src/irc.h b/src/irc.h
index 4e28899..8590314 100644
--- a/src/irc.h
+++ b/src/irc.h
@@ -20,6 +20,8 @@ void txbuf_init(void);
/* appends a string to the transmit buffer, updates txbuflen. */
void txbuf_append_str(const char *str);
+void txbuf_append_str2(const char *s1, const char *s2);
+void txbuf_append_str3(const char *s1, const char *s2, const char *s3);
/* clears the transmit buffer, then appends a string to it. */
void txbuf_set_str(const char *str);
@@ -53,5 +55,5 @@ void irc_loop(void);
void print_errnum(void);
/**** cmd.c */
-void cmd_command(const char *cmd);
+void cmd_command(char *cmd);
void cmd_execute(void);
diff --git a/src/main.c b/src/main.c
index 03e9a0a..664b0ed 100644
--- a/src/main.c
+++ b/src/main.c
@@ -62,6 +62,17 @@ void txbuf_append_str(const char *str) {
}
}
+void txbuf_append_str2(const char *s1, const char *s2) {
+ txbuf_append_str(s1);
+ txbuf_append_str(s2);
+}
+
+void txbuf_append_str3(const char *s1, const char *s2, const char *s3) {
+ txbuf_append_str(s1);
+ txbuf_append_str(s2);
+ txbuf_append_str(s3);
+}
+
void txbuf_set_str(const char *str) {
txbuf_init();
txbuf_append_str(str);