diff options
Diffstat (limited to 'src/main.c')
| -rw-r--r-- | src/main.c | 311 |
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 |
