X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FApplications%2Firc_src%2Fmain.c;h=6169519c6e5ce92df6b833897032b0cc9a3a5c17;hb=13078002b01ee4f63eb2001d2ef479a2a006ea32;hp=4fce928b3fada4e4e9d4da1cdfbf401621eb0560;hpb=57ffa414b54cb6b90a1154c30e8f2328fed8e670;p=tpg%2Facess2.git diff --git a/Usermode/Applications/irc_src/main.c b/Usermode/Applications/irc_src/main.c old mode 100644 new mode 100755 index 4fce928b..6169519c --- a/Usermode/Applications/irc_src/main.c +++ b/Usermode/Applications/irc_src/main.c @@ -1,252 +1,227 @@ -/* - * Acess2 IRC Client - */ -#include -#include -#include -#include -#include - -#define BUFSIZ 1023 - -// === TYPES === -typedef struct sServer { - int FD; - char InBuf[BUFSIZ+1]; - int ReadPos; -} tServer; - -// === PROTOTYPES === - int ParseArguments(int argc, const char *argv[]); -void ProcessIncoming(tServer *Server); - int writef(int FD, const char *Format, ...); - int OpenTCP(const char *AddressString, short PortNumber); - -// === GLOBALS === -char *gsUsername = "root"; -char *gsHostname = "acess"; -char *gsRemoteAddress = NULL; -char *gsRealName = "Acess2 IRC Client"; -char *gsNickname = "acess"; -short giRemotePort = 6667; - -// ==== CODE ==== -int main(int argc, const char *argv[], const char *envp[]) -{ - int tmp; - tServer srv; - - memset(&srv, 0, sizeof(srv)); - - // Parse Command line - // - Sets the server configuration globals - if( (tmp = ParseArguments(argc, argv)) ) { - return tmp; - } - - // Connect to the remove server - srv.FD = OpenTCP( gsRemoteAddress, giRemotePort ); - if( srv.FD == -1 ) { - fprintf(stderr, "Unable to create socket\n"); - return -1; - } - - printf("Connection opened\n"); - - writef(srv.FD, "USER %s %s %s : %s\n", gsUsername, gsHostname, gsRemoteAddress, gsRealName); - writef(srv.FD, "NICK %s", gsNickname); - - ProcessIncoming(&srv); - - close(srv.FD); - return 0; -} - -/** - * \todo Actually implement correctly :) - */ -int ParseArguments(int argc, const char *argv[]) -{ - gsRemoteAddress = "130.95.13.18"; // irc.ucc.asn.au - - return 0; -} - -void Cmd_PRIVMSG(tServer *Server, const char *Dest, const char *Src, const char *Message) -{ - printf("%p: %s => %s\t%s\n", Server, Src, Dest, Message); -} - -/** - * \brief Read a space-separated value from a string - */ -char *GetValue(char *Src, int *Ofs) -{ - int pos = *Ofs; - char *ret = Src + pos; - char *end; - - while( *ret == ' ' ) ret ++; - - end = strchr(ret, ' '); - if( end ) { - *end = '\0'; - } - else { - end = ret + strlen(ret) - 1; - } - *Ofs = end - Src + 1; - - return ret; -} - -/** - */ -void ParseServerLine(tServer *Server, char *Line) -{ - int pos; - char *ident, *cmd; - if( *Line == ':' ) { - // Message - ident = GetValue(Line, &pos); - pos ++; // Space - cmd = GetValue(Line, &pos); - - if( strcmp(cmd, "PRIVMSG") == 0 ) { - char *dest, *message; - pos ++; - dest = GetValue(Line, &pos); - pos ++; - if( Line[pos] == ':' ) { - message = Line + pos + 1; - } - else { - message = GetValue(Line, &pos); - } - Cmd_PRIVMSG(Server, dest, ident, message); - } - } - else { - // Command to client - } -} - -/** - * \brief Process incoming lines from the server - */ -void ProcessIncoming(tServer *Server) -{ - char *ptr, *newline; - int len; - - // While there is data in the buffer, read it into user memory and - // process it line by line - // ioctl#8 on a TCP client gets the number of bytes in the recieve buffer - // - Used to avoid blocking - while( ioctl(Server->FD, 8, NULL) ) - { - // Read data - len = read(Server->FD, BUFSIZ - Server->ReadPos, Server->InBuf + Server->ReadPos); - Server->InBuf[Server->ReadPos + len] = '\0'; - - // Break into lines - ptr = Server->InBuf; - while( (newline = strchr(ptr, '\n')) ) - { - *newline = '\0'; - printf("%s\n", ptr); - ParseServerLine(Server, ptr); - ptr = newline + 1; - } - - // Handle incomplete lines - if( ptr - Server->InBuf < len + Server->ReadPos ) { - Server->ReadPos = ptr - Server->InBuf; - memcpy(Server->InBuf, ptr, Server->ReadPos); - } - else { - Server->ReadPos = 0; - } - } -} - -/** - * \brief Write a formatted string to a file descriptor - * - */ -int writef(int FD, const char *Format, ...) -{ - va_list args; - int len; - - va_start(args, Format); - len = vsnprintf(NULL, 1000, Format, args); - va_end(args); - - { - char buf[len+1]; - va_start(args, Format); - vsnprintf(buf, len+1, Format, args); - va_end(args); - - return write(FD, len, buf); - } -} - -/** - * \brief Initialise a TCP connection to \a AddressString on port \a PortNumber - */ -int OpenTCP(const char *AddressString, short PortNumber) -{ - int fd, addrType; - char *iface; - char addrBuffer[8]; - - // Parse IP Address - addrType = Net_ParseAddress(AddressString, addrBuffer); - if( addrType == 0 ) { - fprintf(stderr, "Unable to parse '%s' as an IP address\n", AddressString); - return -1; - } - - // Finds the interface for the destination address - iface = Net_GetInterface(addrType, addrBuffer); - if( iface == NULL ) { - fprintf(stderr, "Unable to find a route to '%s'\n", AddressString); - return -1; - } - - printf("iface = '%s'\n", iface); - - // Open client socket - // TODO: Move this out to libnet? - { - int len = snprintf(NULL, 100, "/Devices/ip/%s/tcpc", iface); - char path[len+1]; - snprintf(path, 100, "/Devices/ip/%s/tcpc", iface); - fd = open(path, OPENFLAG_READ|OPENFLAG_WRITE); - } - - free(iface); - - if( fd == -1 ) { - fprintf(stderr, "Unable to open TCP Client for reading\n"); - return -1; - } - - // Set remote port and address - printf("Setting port and remote address\n"); - ioctl(fd, 5, &PortNumber); - ioctl(fd, 6, addrBuffer); - - // Connect - printf("Initiating connection\n"); - if( ioctl(fd, 7, NULL) == 0 ) { - // Shouldn't happen :( - fprintf(stderr, "Unable to start connection\n"); - return -1; - } - - // Return descriptor - return fd; -} +/* + * Acess2 IRC Client + */ +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "input.h" +#include "window.h" +#include "server.h" + +// === TYPES === + +// === PROTOTYPES === + int main(int argc, const char *argv[], const char *envp[]); + int MainLoop(void); + int ParseArguments(int argc, const char *argv[]); +// --- +void Redraw_Screen(void); +// --- Helpers +void Exit(const char *Reason); + int writef(int FD, const char *Format, ...); + int OpenTCP(const char *AddressString, short PortNumber); +char *GetValue(char *Str, int *Ofs); + +// === GLOBALS === +const char *gsExitReason = "No reason [BUG]"; + +// ==== CODE ==== +void ExitHandler(void) +{ + printf("\x1B[?1047l"); + printf("Quit: %s\n", gsExitReason); + + // stty +echo,canon + struct ptymode mode = {.InputMode = 0, .OutputMode = 0}; + mode.InputMode = PTYIMODE_CANON|PTYIMODE_ECHO; + _SysIOCtl(0, PTY_IOCTL_SETMODE, &mode); +} + +void Exit(const char *Reason) +{ + gsExitReason = (Reason ? Reason : "User Requested"); + exit( (Reason ? 1 : 0) ); +} + +int main(int argc, const char *argv[], const char *envp[]) +{ + int tmp; + + // Parse Command line + if( (tmp = ParseArguments(argc, argv)) ) return tmp; + + atexit(ExitHandler); + + ACurses_Init(); + + printf("\x1B[?1047h"); + printf("\x1B[%i;%ir", 2, giTerminal_Height-2); + + // HACK: Static server entry + // UCC (University [of Western Australia] Computer Club) IRC Server +// tServer *starting_server = Server_Connect( "UCC", "130.95.13.18", 6667 ); + // Freenode (#osdev) + tServer *starting_server = Server_Connect( "Freenode", "84.240.3.129", 6667 ); + // Local servers +// gWindow_Status.Server = Server_Connect( "VMHost", "10.0.2.2", 6667 ); +// gWindow_Status.Server = Server_Connect( "BitlBee", "192.168.1.39", 6667 ); + + Windows_SetStatusServer(starting_server); + Windows_RepaintCurrent(); + SetCursorPos(giTerminal_Height-1, 1); + printf("[(status)] "); + + MainLoop(); + + Servers_CloseAll("Client closing"); + + return 0; +} + +int MainLoop(void) +{ + SetCursorPos(giTerminal_Height, 1); + printf("[(status)] "); + fflush(stdout); + + // stty -echo,canon + struct ptymode mode = {.InputMode = 0, .OutputMode = 0}; + _SysIOCtl(0, PTY_IOCTL_SETMODE, &mode); + + for( ;; ) + { + fd_set readfds, errorfds; + int nfds = 1; + + FD_ZERO(&readfds); + FD_ZERO(&errorfds); + + Input_FillSelect(&nfds, &readfds); + Servers_FillSelect(&nfds, &readfds, &errorfds); + + int rv = _SysSelect(nfds, &readfds, 0, &errorfds, NULL, 0); + if( rv < 0 ) break; + + // user input + Input_HandleSelect(nfds, &readfds); + + // Server response + Servers_HandleSelect(nfds, &readfds, &errorfds); + } + return 0; +} + +/** + * \todo Actually implement correctly :) + */ +int ParseArguments(int argc, const char *argv[]) +{ + return 0; +} + +void Redraw_Screen(void) +{ + printf("\x1B[2J"); // Clear screen + printf("\x1B[H"); // Reset cursor + + Windows_RepaintCurrent(); +} + +/** + * \brief Write a formatted string to a file descriptor + * + */ +int writef(int FD, const char *Format, ...) +{ + va_list args; + int len; + + va_start(args, Format); + len = vsnprintf(NULL, 0, Format, args); + va_end(args); + + { + char buf[len+1]; + va_start(args, Format); + vsnprintf(buf, len+1, Format, args); + va_end(args); + + return _SysWrite(FD, buf, len); + } +} + +/** + * \brief Initialise a TCP connection to \a AddressString on port \a PortNumber + */ +int OpenTCP(const char *AddressString, short PortNumber) +{ + int fd, addrType; + char addrBuffer[8]; + + // Parse IP Address + addrType = Net_ParseAddress(AddressString, addrBuffer); + if( addrType == 0 ) { + fprintf(stderr, "Unable to parse '%s' as an IP address\n", AddressString); + _SysDebug("Unable to parse '%s' as an IP address\n", AddressString); + return -1; + } + + // Finds the interface for the destination address + fd = Net_OpenSocket(addrType, addrBuffer, "tcpc"); + if( fd == -1 ) { + fprintf(stderr, "Unable to open TCP Client to '%s'\n", AddressString); + _SysDebug("Unable to open TCP client to '%s'\n", AddressString); + return -1; + } + + // Set remote port and address +// printf("Setting port and remote address\n"); + _SysIOCtl(fd, 5, &PortNumber); + _SysIOCtl(fd, 6, addrBuffer); + + // Connect +// printf("Initiating connection\n"); + if( _SysIOCtl(fd, 7, NULL) == 0 ) { + // Shouldn't happen :( + fprintf(stderr, "Unable to start connection\n"); + return -1; + } + + // Return descriptor + return fd; +} + +/** + * \brief Read a space-separated value from a string + */ +char *GetValue(char *Src, int *Ofs) +{ + int pos = *Ofs; + char *ret = Src + pos; + char *end; + + if( !Src ) return NULL; + + while( *ret == ' ' ) ret ++; + + end = strchr(ret, ' '); + if( end ) { + *end = '\0'; + } + else { + end = ret + strlen(ret) - 1; + } + + end ++ ; + while( *ret == ' ' ) end ++; + *Ofs = end - Src; + + return ret; +} +