X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;ds=sidebyside;f=Usermode%2FApplications%2Firc_src%2Fmain.c;h=e3e2af489d05ad983af78cc348ddd18111753d0f;hb=fcb22b3d1770e7f441385198cde6ddda3953e38b;hp=2599127d395a297b5483c3bf8e282c13056ecbd4;hpb=290e4ae772b09cec3bdbc28f12791529637ff2d8;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 2599127d..e3e2af48 --- a/Usermode/Applications/irc_src/main.c +++ b/Usermode/Applications/irc_src/main.c @@ -1,307 +1,220 @@ -/* - * Acess2 IRC Client - */ -#include -#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[]); - int 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; - tReadline *readline_info; - - 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"); - ProcessIncoming(&srv); - - writef(srv.FD, "USER %s %s %s : %s\n", gsUsername, gsHostname, gsRemoteAddress, gsRealName); - writef(srv.FD, "NICK %s\n", gsNickname); - - printf("Processing\n"); - - readline_info = Readline_Init(1); - - for( ;; ) - { - fd_set readfds; - int rv; - - FD_ZERO(&readfds); - FD_SET(0, &readfds); // stdin - FD_SET(srv.FD, &readfds); - - rv = select(srv.FD+1, &readfds, 0, 0, NULL); - if( rv == -1 ) break; - - if(FD_ISSET(0, &readfds)) - { - // User input - char *cmd = Readline_NonBlock(readline_info); - if( cmd ) - { - // TODO: Implement windows / proper commands, but meh - if( cmd[0] ) - writef(srv.FD, "%s\n", cmd); - free(cmd); - } - } - - // Server response - if(FD_ISSET(srv.FD, &readfds)) - { - if( ProcessIncoming(&srv) != 0 ) { - // Oops, error - break; - } - } - } - - 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; - - if( !Src ) return NULL; - - 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 = 0; - 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 - */ -int 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 - #if NON_BLOCK_READ - while( (len = ioctl(Server->FD, 8, NULL)) > 0 ) - { - #endif - // Read data - len = read(Server->FD, BUFSIZ - Server->ReadPos, &Server->InBuf[Server->ReadPos]); - if( len == -1 ) { - return -1; - } - 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 ) { - // Update the read position - // InBuf ReadPos ptr ReadPos+len - // | old | new used | new unused | - Server->ReadPos = len + Server->ReadPos - (ptr - Server->InBuf); - // Copy stuff back (moving "new unused" to the start of the buffer) - memcpy(Server->InBuf, ptr, Server->ReadPos); - } - else { - Server->ReadPos = 0; - } - #if NON_BLOCK_READ - } - #endif - - return 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 "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); +} + +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", 1, giTerminal_Height-1); + + SetCursorPos(giTerminal_Height-1, 1); + printf("[(status)] "); + + // 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) +// gWindow_Status.Server = Server_Connect( "Freenode", "89.16.176.16", 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 ); + + if( !starting_server ) + return -1; + + Windows_SetStatusServer(starting_server); + + MainLoop(); + + Servers_CloseAll("Client closing"); + + return 0; +} + +int MainLoop(void) +{ + SetCursorPos(giTerminal_Height-1, 1); + printf("[(status)] "); + fflush(stdout); + + 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[0;0H"); // 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; +} +