aboutsummaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c311
1 files changed, 311 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..81f598e
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,311 @@
+/* FujiNetChat, an IRC client. Based on NetCat and the old FujiChat. */
+
+#define SELF "FujiNetChat"
+#define VERSION "0.0"
+#define BANNER SELF " v" VERSION " (B. Watson)\n"
+
+#define DEF_URL "N:TCP://irc.libera.chat:6667"
+#define DEF_NICK "FNChatTest"
+#define DEF_CHANNEL "##atari"
+
+#include <atari.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <conio.h> // for kbhit() and cgetc()
+#include "conio.h" // our local one.
+#include "nio.h"
+#include "irc.h"
+
+char url[256] = DEF_URL; // URL
+char usernick[32] = DEF_NICK;
+char tmp[8]; // temporary # to string
+unsigned char err; // error code of last operation.
+unsigned char trip=0; // if trip=1, fujinet is asking us for attention.
+bool old_enabled=false; // were interrupts enabled for old vector
+void* old_vprced; // old PROCEED vector, restored on exit.
+unsigned short bw=0; // # of bytes waiting.
+unsigned char rx_buf[MAX_IRC_MSG_LEN]; // RX buffer.
+unsigned char tx_buf[MAX_IRC_MSG_LEN]; // TX buffer.
+unsigned int txbuflen; // TX buffer length
+char channel[32] = DEF_CHANNEL;
+
+/* TODO: user modes (default +iw), fg/bg color... */
+
+extern void ih(); // defined in intr.s
+
+static void strcpy_to_eol(char *dst, const char *src) {
+ while(*src && (*src != CH_EOL)) {
+ *dst++ = *src++;
+ }
+ *dst = '\0';
+}
+
+/**
+ * Get URL from user.
+ */
+void get_config(void) {
+ OS.crsinh = 0;
+
+ putchar(CH_CLR);
+ print(BANNER);
+
+ while(1) {
+ print("\nURL [");
+ print(url);
+ print("]?\n");
+ get_line(tx_buf, sizeof(url) - 1);
+ if(tx_buf[0] != CH_EOL) strcpy_to_eol(url, tx_buf);
+
+ print("Nick [");
+ print(usernick);
+ print("]? ");
+ get_line(tx_buf, sizeof(usernick) - 1);
+ if(tx_buf[0] != CH_EOL) strcpy_to_eol(usernick, tx_buf);
+
+ print("Channel [");
+ print(channel);
+ print("]? ");
+ get_line(tx_buf, sizeof(channel) - 1);
+ if(tx_buf[0] != CH_EOL) strcpy_to_eol(channel, tx_buf);
+
+ /*
+ print("\n\nURL: ");
+ print(url);
+ print("\nNick: ");
+ print(usernick);
+ print("\nChannel: ");
+ print(channel);
+ */
+
+ print("\n\nAre these settings OK [Y/n]? ");
+ if(tolower(cgetc()) != 'n') break;
+ }
+
+ // print("Press Return to connect\n");
+ // cgetc();
+}
+
+/**
+ * Print error
+ */
+void print_error(unsigned char err) {
+ itoa(err, tmp, 10);
+ print(tmp);
+ print("\n");
+}
+
+void txbuf_init(void) {
+ txbuflen = tx_buf[0] = 0;
+}
+
+void txbuf_append_str(const char *str) {
+ while(*str) {
+ tx_buf[txbuflen++] = *str++;
+ }
+}
+
+void txbuf_set_str(const char *str) {
+ txbuf_init();
+ txbuf_append_str(str);
+}
+
+void txbuf_send(void) {
+ if(!txbuflen) return;
+ nwrite(url, tx_buf, txbuflen);
+ txbuf_init();
+}
+
+void txbuf_send_str(const char *str) {
+ txbuf_init();
+ txbuf_append_str(str);
+ txbuf_send();
+}
+
+int fn_connect(void) {
+ print("\n" "Connecting to: ");
+ print(url);
+ print("\n");
+
+ err = nopen(url, FNET_TRANSLATION);
+
+ if(err != SUCCESS) {
+ print("Connection failed: ");
+ print_error(err);
+ return 0;
+ }
+
+ // Open successful, set up interrupt
+ old_vprced = OS.vprced; // save the old interrupt vector
+ old_enabled = PIA.pactl & 1; // keep track of old interrupt state
+ PIA.pactl &= (~1); // Turn off interrupts before changing vector
+ OS.vprced = ih; // Set PROCEED interrupt vector to our interrupt handler.
+ PIA.pactl |= 1; // Indicate to PIA we are ready for PROCEED interrupt.
+
+ return 1;
+}
+
+void fn_disconnect(void) {
+ // Restore old PROCEED interrupt.
+ PIA.pactl &= ~1; // disable interrupts
+ OS.vprced=old_vprced;
+ PIA.pactl |= old_enabled;
+}
+
+int main(void) {
+ OS.lmargn = 0; // Set left margin to 0
+ OS.shflok = 0; // turn off shift-lock.
+ OS.soundr = 0; // Turn off SIO beeping sound
+ cursor(1); // Keep cursor on
+
+ while(1) {
+ get_config();
+ if(fn_connect()) {
+ irc_register();
+ irc_loop();
+ fn_disconnect();
+ }
+ }
+
+ OS.soundr = 3; // Restore SIO beeping sound
+ return 0;
+}
+
+/* cruft from netcat: */
+/**
+ * Main entrypoint
+ */
+#if 0
+int main(int argc, char* argv[])
+{
+ OS.soundr=0; // Turn off SIO beeping sound
+ cursor(1); // Keep cursor on
+
+ while (running==true)
+ {
+ if (get_url(argc, argv))
+ nc();
+ else
+ running=false;
+ }
+
+ OS.soundr=3; // Restore SIO beeping sound
+ return 0;
+}
+#endif
+
+#if 0
+/**
+ * NetCat
+ */
+void nc()
+{
+ OS.lmargn=0; // Set left margin to 0
+ OS.shflok=0; // turn off shift-lock.
+
+ // Attempt open.
+ print("\x9bOpening:\x9b");
+ print(url);
+ print("\x9b");
+
+ err=nopen(url,trans);
+
+ if (err != SUCCESS)
+ {
+ print("OPEN ERROR: ");
+ print_error(err);
+ return;
+ }
+
+ // Open successful, set up interrupt
+ old_vprced = OS.vprced; // save the old interrupt vector
+ old_enabled = PIA.pactl & 1; // keep track of old interrupt state
+ PIA.pactl &= (~1); // Turn off interrupts before changing vector
+ OS.vprced = ih; // Set PROCEED interrupt vector to our interrupt handler.
+ PIA.pactl |= 1; // Indicate to PIA we are ready for PROCEED interrupt.
+
+ // MAIN LOOP ///////////////////////////////////////////////////////////
+
+ while (running==true)
+ {
+ // If key pressed, send it.
+ while (kbhit())
+ {
+ tx_buf[txbuflen++]=cgetc();
+ }
+
+ if (txbuflen>0)
+ {
+ if (echo==true)
+ for (i=0;i<txbuflen;i++)
+ printc(&tx_buf[i]);
+
+ err=nwrite(url,tx_buf,txbuflen); // Send character.
+
+ if (err!=1)
+ {
+ print("WRITE ERROR: ");
+ print_error(err);
+ running=false;
+ continue;
+ }
+ txbuflen=0;
+ }
+
+ if (trip==0) // is nothing waiting for us?
+ continue;
+
+ // Something waiting for us, get status and bytes waiting.
+ err=nstatus(url);
+
+ if (err==136)
+ {
+ print("DISCONNECTED.\x9b");
+ running=false;
+ continue;
+ }
+ else if (err!=1)
+ {
+ print("STATUS ERROR: ");
+ print_error(err);
+ running=false;
+ continue;
+ }
+
+ // Get # of bytes waiting, no more than size of rx_buf
+ bw=OS.dvstat[1]*256+OS.dvstat[0];
+
+ if (bw>sizeof(rx_buf))
+ bw=sizeof(rx_buf);
+
+ if (bw>0)
+ {
+ err=nread(url,rx_buf,bw);
+
+ if (err!=1)
+ {
+ print("READ ERROR: ");
+ print_error(err);
+ running=false;
+ continue;
+ }
+
+ // Print the buffer to screen.
+ printl(rx_buf,bw);
+
+ trip=0;
+ PIA.pactl |= 1; // Flag interrupt as serviced, ready for next one.
+ } // if bw > 0
+ } // while running
+
+ // END MAIN LOOP ///////////////////////////////////////////////////////
+
+ // Restore old PROCEED interrupt.
+ PIA.pactl &= ~1; // disable interrupts
+ OS.vprced=old_vprced;
+ PIA.pactl |= old_enabled;
+
+}
+#endif