/* 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 #include #include #include #include #include #include // 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; }