Usermode/irc - Rework into multiple files
[tpg/acess2.git] / Usermode / Applications / irc_src / main.c
index 1ca53c2..e3e2af4 100755 (executable)
@@ -6,94 +6,41 @@
 #include <stdio.h>
 #include <string.h>
 #include <net.h>
-#include <readline.h>
-#include <acess/devices/pty.h>
 #include <stdarg.h>
 
-// === TYPES ===
-typedef struct sServer {
-       struct sServer  *Next;
-        int    FD;
-       char    InBuf[BUFSIZ+1];
-        int    ReadPos;
-       char    Name[];
-} tServer;
-
-typedef struct sMessage
-{
-       struct sMessage *Next;
-       time_t  Timestamp;
-       tServer *Server;
-        int    Type;
-       char    *Source;        // Pointer into `Data`
-       char    Data[];
-}      tMessage;
+#include "common.h"
+#include "input.h"
+#include "window.h"
+#include "server.h"
 
-typedef struct sWindow
-{
-       struct sWindow  *Next;
-       tMessage        *Messages;
-       tServer *Server;        //!< Canonical server (can be NULL)
-        int    ActivityLevel;
-       char    Name[]; // Channel name / remote user
-}      tWindow;
-
-enum eMessageTypes
-{
-       MSG_TYPE_NULL,
-       MSG_TYPE_SERVER,        // Server message
-       
-       MSG_TYPE_NOTICE,        // NOTICE command
-       MSG_TYPE_JOIN,  // JOIN command
-       MSG_TYPE_PART,  // PART command
-       MSG_TYPE_QUIT,  // QUIT command
-       
-       MSG_TYPE_STANDARD,      // Standard line
-       MSG_TYPE_ACTION,        // /me
-       
-       MSG_TYPE_UNK
-};
+// === TYPES ===
 
 // === PROTOTYPES ===
  int   main(int argc, const char *argv[], const char *envp[]);
  int   MainLoop(void);
  int   ParseArguments(int argc, const char *argv[]);
- int   ParseUserCommand(char *String);
 // --- 
-tServer        *Server_Connect(const char *Name, const char *AddressString, short PortNumber);
-tMessage       *Message_AppendF(tServer *Server, int Type, const char *Source, const char *Dest, const char *Message, ...) __attribute__((format(__printf__,5,6)));
-tMessage       *Message_Append(tServer *Server, int Type, const char *Source, const char *Dest, const char *Message);
-tWindow        *Window_Create(tServer *Server, const char *Name);
 void   Redraw_Screen(void);
-
- int   ProcessIncoming(tServer *Server);
 // --- Helpers
-void   SetCursorPos(int Row, int Col);
+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);
-static inline int      isdigit(int ch);
 
 // === GLOBALS ===
-char   *gsUsername = "user";
-char   *gsHostname = "acess";
-char   *gsRealName = "Acess2 IRC Client";
-char   *gsNickname = "acess";
-tServer        *gpServers;
-tWindow        gWindow_Status = {
-       NULL, NULL, NULL,       // No next, empty list, no server
-       0, {""} // No activity, empty name (rendered as status)
-};
-tWindow        *gpWindows = &gWindow_Status;
-tWindow        *gpCurrentWindow = &gWindow_Status;
- int   giTerminal_Width = 80;
- int   giTerminal_Height = 25;
+const char     *gsExitReason = "No reason [BUG]";
 
 // ==== CODE ====
 void ExitHandler(void)
 {
        printf("\x1B[?1047l");
-       printf("Quit\n");
+       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[])
@@ -105,40 +52,31 @@ int main(int argc, const char *argv[], const char *envp[])
        
        atexit(ExitHandler);
        
-       if( _SysIOCtl(1, DRV_IOCTL_TYPE, NULL) != DRV_TYPE_TERMINAL ) {
-               fprintf(stderr, "note: assuming 80x25, can't get terminal dimensions\n");
-               giTerminal_Width = 80;
-               giTerminal_Height = 25;
-       }
-       else {
-               struct ptydims  dims;
-               _SysIOCtl(1, PTY_IOCTL_GETDIMS, &dims);
-               giTerminal_Width = dims.W;
-               giTerminal_Height = dims.H;
-       }
+       ACurses_Init();
        
        printf("\x1B[?1047h");
-       printf("\x1B[%i;%ir", 0, giTerminal_Height-1);
+       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
-       gWindow_Status.Server = Server_Connect( "UCC", "130.95.13.18", 6667 );
+       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( !gWindow_Status.Server )
+       if( !starting_server )
                return -1;
        
-       MainLoop();
+       Windows_SetStatusServer(starting_server);
        
-       for( tServer *srv = gpServers; srv; srv = srv->Next )
-               _SysClose(srv->FD);
+       MainLoop();
+
+       Servers_CloseAll("Client closing");
        
        return 0;
 }
@@ -149,73 +87,25 @@ int MainLoop(void)
        printf("[(status)] ");
        fflush(stdout);
        
-       tReadline *readline_info = Readline_Init(1);
-       
        for( ;; )
        {
                fd_set  readfds, errorfds;
-                int    maxFD = 0;
+                int    nfds = 1;
                
                FD_ZERO(&readfds);
                FD_ZERO(&errorfds);
-               FD_SET(0, &readfds);    // stdin
                
-               fflush(stdout);
+               Input_FillSelect(&nfds, &readfds);
+               Servers_FillSelect(&nfds, &readfds, &errorfds);
                
-               // Fill server FDs in fd_set
-               for( tServer *srv = gpServers; srv; srv = srv->Next )
-               {
-                       FD_SET(srv->FD, &readfds);
-                       FD_SET(srv->FD, &errorfds);
-                       if( srv->FD > maxFD )
-                               maxFD = srv->FD;
-               }
+               int rv = _SysSelect(nfds, &readfds, 0, &errorfds, NULL, 0);
+               if( rv < 0 )    break;
                
-               int rv = _SysSelect(maxFD+1, &readfds, 0, &errorfds, NULL, 0);
-               if( rv == -1 )  break;
-               
-               if(FD_ISSET(0, &readfds))
-               {
-                       // User input
-                       char    *cmd = Readline_NonBlock(readline_info);
-                       if( cmd )
-                       {
-                               if( cmd[0] )
-                               {
-                                       ParseUserCommand(cmd);
-                               }
-                               free(cmd);
-                               // Prompt
-                               SetCursorPos(giTerminal_Height-1, 1);
-                               printf("\x1B[2K");      // Clear line
-                               if( gpCurrentWindow->Name[0] )
-                                       printf("[%s:%s] ",
-                                               gpCurrentWindow->Server->Name, gpCurrentWindow->Name);
-                               else
-                                       printf("[(status)] ");
-                       }
-               }
+               // user input
+               Input_HandleSelect(nfds, &readfds);
                
                // Server response
-               for( tServer *srv = gpServers; srv; srv = srv->Next )
-               {
-                       if(FD_ISSET(srv->FD, &readfds))
-                       {
-                               if( ProcessIncoming(srv) != 0 ) {
-                                       // Oops, error
-                                       _SysDebug("ProcessIncoming failed on FD%i (Server %p %s)",
-                                               srv->FD, srv, srv->Name);
-                                       return 1;
-                               }
-                       }
-                       
-                       if(FD_ISSET(srv->FD, &errorfds))
-                       {
-                               _SysDebug("Error on FD%i (Server %p %s)",
-                                       srv->FD, srv, srv->Name);
-                               return 1;
-                       }
-               }
+               Servers_HandleSelect(nfds, &readfds, &errorfds);
        }
        return 0;
 }
@@ -228,547 +118,12 @@ int ParseArguments(int argc, const char *argv[])
        return 0;
 }
 
-
-void Cmd_join(char *ArgString)
-{
-        int    pos=0;
-       char    *channel_name = GetValue(ArgString, &pos);
-       
-       if( gpCurrentWindow->Server )
-       {
-               gpCurrentWindow = Window_Create(gpCurrentWindow->Server, channel_name);
-               Redraw_Screen();
-               writef(gpCurrentWindow->Server->FD, "JOIN :%s\n", channel_name);
-       }
-}
-
-void Cmd_quit(char *ArgString)
-{
-       const char *quit_message = ArgString;
-       if( quit_message == NULL || quit_message[0] == '\0' )
-               quit_message = "/quit - Acess2 IRC Client";
-       
-       for( tServer *srv = gpServers; srv; srv = srv->Next )
-       {
-               writef(srv->FD, "QUIT :%s\n", quit_message);
-       }
-       
-       exit(0);
-}
-
-void Cmd_window(char *ArgString)
-{
-        int    pos = 0;
-       char    *window_id = GetValue(ArgString, &pos);
-        int    window_num = atoi(window_id);
-       
-       if( window_num > 0 )
-       {
-               tWindow *win;
-               window_num --;  // Move to base 0
-               // Get `window_num`th window
-               for( win = gpWindows; win && window_num--; win = win->Next );
-               if( win ) {
-                       gpCurrentWindow = win;
-                       Redraw_Screen();
-               }
-               // Otherwise, silently ignore
-       }
-       else
-       {
-               window_num = 1;
-               for( tWindow *win = gpWindows; win; win = win->Next, window_num ++ )
-               {
-                       if( win->Name[0] ) {
-                               Message_AppendF(NULL, MSG_TYPE_SERVER, "client", "",
-                                       "%i: %s/%s", window_num, win->Server->Name, win->Name);
-                       }
-                       else {
-                               Message_AppendF(NULL, MSG_TYPE_SERVER, "client", "",
-                                       "%i: (status)", window_num);
-                       }
-               }
-       }
-}
-
-const struct {
-       const char *Name;
-       void    (*Fcn)(char *ArgString);
-} caCommands[] = {
-       {"join", Cmd_join},
-       {"quit", Cmd_quit},
-       {"window", Cmd_window},
-       {"win",    Cmd_window},
-       {"w",      Cmd_window},
-};
-const int ciNumCommands = sizeof(caCommands)/sizeof(caCommands[0]);
-
-/**
- * \brief Handle a line from the prompt
- */
-int ParseUserCommand(char *String)
-{
-       if( String[0] == '/' )
-       {
-               char    *command;
-                int    pos = 0;
-               
-               command = GetValue(String, &pos)+1;
-
-               // TODO: Prefix matches
-                int    cmdIdx = -1;
-               for( int i = 0; i < ciNumCommands; i ++ )
-               {
-                       if( strcmp(command, caCommands[i].Name) == 0 ) {
-                               cmdIdx = i;
-                               break;
-                       }
-               }
-               if( cmdIdx != -1 ) {
-                       caCommands[cmdIdx].Fcn(String+pos);
-               }
-               else
-               {
-                       Message_AppendF(NULL, MSG_TYPE_SERVER, "client", "", "Unknown command %s", command);
-               }
-       }
-       else
-       {
-               // Message
-               // - Only send if server is valid and window name is non-empty
-               if( gpCurrentWindow->Server && gpCurrentWindow->Name[0] )
-               {
-                       Message_Append(gpCurrentWindow->Server, MSG_TYPE_STANDARD,
-                               gsNickname, gpCurrentWindow->Name, String);
-                       writef(gpCurrentWindow->Server->FD,
-                               "PRIVMSG %s :%s\n", gpCurrentWindow->Name,
-                               String
-                               );
-               }
-       }
-       
-       return 0;
-}
-
-/**
- * \brief Connect to a server
- */
-tServer *Server_Connect(const char *Name, const char *AddressString, short PortNumber)
-{
-       tServer *ret;
-       
-       ret = calloc(1, sizeof(tServer) + strlen(Name) + 1);
-       
-       strcpy(ret->Name, Name);
-       
-       // Connect to the remove server
-       ret->FD = OpenTCP( AddressString, PortNumber );
-       if( ret->FD == -1 ) {
-               fprintf(stderr, "%s: Unable to create socket\n", Name);
-               return NULL;
-       }
-       
-       // Append to open list
-       ret->Next = gpServers;
-       gpServers = ret;
-       
-       // Read some initial data
-       Message_Append(NULL, MSG_TYPE_SERVER, Name, "", "Connection opened");
-       ProcessIncoming(ret);
-       
-       // Identify
-       writef(ret->FD, "USER %s %s %s : %s\n", gsUsername, gsHostname, AddressString, gsRealName);
-       writef(ret->FD, "NICK %s\n", gsNickname);
-       Message_Append(NULL, MSG_TYPE_SERVER, Name, "", "Identified");
-       //printf("%s: Identified\n", Name);
-       
-       return ret;
-}
-
-tMessage *Message_AppendF(tServer *Server, int Type, const char *Source, const char *Dest, const char *Message, ...)
-{
-       va_list args;
-        int    len;
-       va_start(args, Message);
-       len = vsnprintf(NULL, 0, Message, args);
-       va_end(args);
-       
-       char    buf[len+1];
-       va_start(args, Message);
-       vsnprintf(buf, len+1, Message, args);
-       va_end(args);
-       
-       return Message_Append(Server, Type, Source, Dest, buf);
-}
-
-tMessage *Message_Append(tServer *Server, int Type, const char *Source, const char *Dest, const char *Message)
-{
-       tWindow *win = NULL;
-        int    msgLen = strlen(Message);
-       
-       // Server==NULL indicates an internal message
-       if( Server == NULL || Source[0] == '\0' )
-       {
-               win = &gWindow_Status;
-       }
-       // Determine if it's a channel or PM
-       else if( Dest[0] == '#' || Dest[0] == '&' )     // TODO: Better determining here
-       {
-               for(win = gpWindows; win; win = win->Next)
-               {
-                       if( win->Server == Server && strcmp(win->Name, Dest) == 0 )
-                       {
-                               break;
-                       }
-               }
-               if( !win ) {
-                       //win = Window_Create(Server, Dest);
-                       win = &gWindow_Status;  // Stick it in the status window, just in case
-               }
-       }
-       #if 0
-       else if( strcmp(Dest, Server->Nick) != 0 )
-       {
-               // Umm... message for someone who isn't us?
-               win = &gWindow_Status;  // Stick it in the status window, just in case
-       }
-       #endif
-       // Server message?
-       else if( strchr(Source, '.') )  // TODO: And again, less hack please
-       {
-               #if 1
-               for(win = gpWindows; win; win = win->Next)
-               {
-                       if( win->Server == Server && strcmp(win->Name, Source) == 0 )
-                       {
-                               break;
-                       }
-               }
-               #endif
-               if( !win ) {
-                       win = &gWindow_Status;
-               }
-               
-               // Set source to the server name (instead of the hostname)
-               Source = Server->Name;
-       }
-       // Private message
-       else
-       {
-               for(win = gpWindows; win; win = win->Next)
-               {
-                       if( win->Server == Server && strcmp(win->Name, Source) == 0 )
-                       {
-                               break;
-                       }
-               }
-               if( !win ) {
-                       win = Window_Create(Server, Dest);
-               }
-       }
-
-       // Create message cache 
-       _SysDebug("Win (%s) msg: <%s> %s", win->Name, Source, Message);
-       tMessage        *ret;
-       ret = malloc( sizeof(tMessage) + msgLen + 1 + strlen(Source) + 1 );
-       ret->Source = ret->Data + msgLen + 1;
-       strcpy(ret->Source, Source);
-       strcpy(ret->Data, Message);
-       ret->Type = Type;
-       ret->Server = Server;
-       
-       // Append to window message list
-       ret->Next = win->Messages;
-       win->Messages = ret;
-       
-       // Print now if current window
-       if( win == gpCurrentWindow )
-       {
-               printf("\33[s");
-               printf("\33[T");        // Scroll down 1 (free space below)
-               SetCursorPos(giTerminal_Height-2, 1);
-                int    prefixlen = strlen(Source) + 3;
-                int    avail = giTerminal_Width - prefixlen;
-                int    msglen = strlen(Message);
-               printf("[%s] %.*s", Source, avail, Message);
-               while( msglen > avail ) {
-                       msglen -= avail;
-                       Message += avail;
-                       printf("\33[T");
-                       SetCursorPos(giTerminal_Height-2, prefixlen+1);
-                       printf("%.*s", avail, Message);
-               }
-               printf("\x1b[u");
-       }
-       
-       return ret;
-}
-
-tWindow *Window_Create(tServer *Server, const char *Name)
-{
-       tWindow *ret, *prev = NULL;
-        int    num = 1;
-       
-       // Get the end of the list
-       // TODO: Cache this instead
-       for( ret = gpCurrentWindow; ret; prev = ret, ret = ret->Next )
-               num ++;
-       
-       ret = malloc(sizeof(tWindow) + strlen(Name) + 1);
-       ret->Messages = NULL;
-       ret->Server = Server;
-       ret->ActivityLevel = 1;
-       strcpy(ret->Name, Name);
-       
-       if( prev ) {
-               ret->Next = prev->Next;
-               prev->Next = ret;
-       }
-       else {  // Shouldn't happen really
-               ret->Next = gpWindows;
-               gpWindows = ret;
-       }
-       
-//     printf("Win %i %s:%s created\n", num, Server->Name, Name);
-       
-       return ret;
-}
-
 void Redraw_Screen(void)
 {
-        int    y = 0;
-       tMessage        *msg;
-
        printf("\x1B[2J");      // Clear screen
        printf("\x1B[0;0H");    // Reset cursor
 
-       msg = gpCurrentWindow->Messages;
-       
-       // TODO: Title bar?
-
-       // Note: This renders from the bottom up
-       for( y = giTerminal_Height - 1; y -- && msg; msg = msg->Next)
-       {
-                int    msglen = strlen(msg->Data);
-                int    prefix_len = 3 + strlen(msg->Source);
-                int    line_avail = giTerminal_Width - prefix_len;
-                int    i = 0, done = 0;
-               
-               y -= msglen / line_avail;       // Extra lines (y-- above handles the 1 line case)
-               SetCursorPos(y, 1);
-               printf("[%s] ", msg->Source);
-               
-               while(done < msglen) {
-                       done += printf("%.*s", line_avail, msg->Data+done);
-                       i ++;
-                       SetCursorPos(y+i, prefix_len+1);
-               }
-       }
-
-       // Bottom line is rendered by the prompt
-}
-
-void Cmd_PRIVMSG(tServer *Server, const char *Dest, const char *Src, const char *Message)
-{
-       Message_Append(Server, MSG_TYPE_STANDARD, Dest, Src, Message);
-       //printf("<%s:%s:%s> %s\n", Server->Name, Dest, Src, Message);
-}
-
-void ParseServerLine_Numeric(tServer *Server, const char *ident, int Num, char *Line)
-{
-        int    pos = 0;
-       const char *message;
-       const char *user = GetValue(Line, &pos);
-       
-       if( Line[pos] == ':' ) {
-               message = Line + pos + 1;
-       }
-       else {
-               message = GetValue(Line, &pos);
-       }
-       
-       switch(Num)
-       {
-       case 332:       // Topic
-               user = message; // Channel
-               message = Line + pos + 1;       // Topic
-               Message_AppendF(Server, MSG_TYPE_SERVER, user, user, "Topic: %s", message);
-               break;
-       case 333:       // Topic set by
-               user = message; // Channel
-               message = GetValue(Line, &pos); // User
-               GetValue(Line, &pos);   // Timestamp
-               Message_AppendF(Server, MSG_TYPE_SERVER, user, user, "Set by %s", message);
-               break;
-       case 353:       // /NAMES list
-               // <user> = <channel> :list
-               // '=' was eaten in and set to message
-               user = GetValue(Line, &pos);    // Actually channel
-               message = Line + pos + 1;       // List
-               Message_AppendF(Server, MSG_TYPE_SERVER, user, user, "Names: %s", message);
-               break;
-       case 366:       // end of /NAMES list
-               // <user> <channel> :msg
-               user = message;
-               message = Line + pos + 1;
-               Message_Append(Server, MSG_TYPE_SERVER, user, user, message);
-               break;
-       case 372:       // MOTD Data
-       case 375:       // MOTD Start
-       case 376:       // MOTD End
-               
-       default:
-               //printf("[%s] %i %s\n", Server->Name, num, message);
-               Message_Append(Server, MSG_TYPE_SERVER, ident, user, message);
-               break;
-       }
-}
-
-void ParseServerLine_String(tServer *Server, const char *ident, const char *cmd, char *Line)
-{
-        int    pos = 0;
-       _SysDebug("ident=%s,cmd=%s,Line=%s", ident, cmd, Line);
-       if( strcmp(cmd, "NOTICE") == 0 )
-       {
-               const char *class = GetValue(Line, &pos);
-               _SysDebug("NOTICE class='%s'", class);
-               
-               const char *message = (Line[pos] == ':') ? Line + pos + 1 : GetValue(Line, &pos);
-               
-               //printf("[%s] NOTICE %s: %s\n", Server->Name, ident, message);
-               char *ident_bang = strchr(ident, '!');
-               if( ident_bang ) {
-                       *ident_bang = '\0';
-               }
-               Message_Append(Server, MSG_TYPE_NOTICE, ident, "", message);
-       }
-       else if( strcmp(cmd, "PRIVMSG") == 0 )
-       {
-               const char *dest = GetValue(Line, &pos);
-               const char *message = (Line[pos] == ':') ? Line + pos + 1 : GetValue(Line, &pos);
-
-               // TODO: Catch when the privmsg is addressed to the user
-
-//             Cmd_PRIVMSG(Server, dest, ident, message);
-               char *ident_bang = strchr(ident, '!');
-               if( ident_bang ) {
-                       *ident_bang = '\0';
-               }
-               Message_Append(Server, MSG_TYPE_STANDARD, ident, dest, message);
-       }
-       else if( strcmp(cmd, "JOIN" ) == 0 )
-       {
-               const char      *channel = Line + pos + 1;
-               
-               Message_AppendF(Server, MSG_TYPE_JOIN, "", channel, "%s has joined", ident);
-               //Window_Create(Server, channel);
-       }
-       else if( strcmp(cmd, "PART" ) == 0 )
-       {
-               const char      *channel = Line + pos + 1;
-               
-               Message_AppendF(Server, MSG_TYPE_PART, "", channel, "%s has left", ident);
-               //Window_Create(Server, channel);
-       }
-       else
-       {
-               Message_AppendF(Server, MSG_TYPE_SERVER, "", "", "Unknown message %s (%s)", cmd, Line);
-       }
-}
-
-/**
- */
-void ParseServerLine(tServer *Server, char *Line)
-{
-        int    pos = 0;
-
-       _SysDebug("[%s] %s", Server->Name, Line);       
-       
-       // Message?
-       if( *Line == ':' )
-       {
-               pos ++;
-               const char *ident = GetValue(Line, &pos);       // Ident (user or server)
-               const char *cmd = GetValue(Line, &pos);
-               
-               // Numeric command
-               if( isdigit(cmd[0]) && isdigit(cmd[1]) && isdigit(cmd[2]) )
-               {
-                        int    num;
-                       num  = (cmd[0] - '0') * 100;
-                       num += (cmd[1] - '0') * 10;
-                       num += (cmd[2] - '0') * 1;
-
-                       ParseServerLine_Numeric(Server, ident, num, Line+pos);
-               }
-               else
-               {
-                       ParseServerLine_String(Server, ident, cmd, Line+pos);
-               }
-       }
-       else {
-               const char *cmd = GetValue(Line, &pos);
-               
-               if( strcmp(cmd, "PING") == 0 ) {
-                       writef(Server->FD, "PONG %s\n", Line+pos);
-               }
-               else {
-                       // Command to client
-                       Message_AppendF(NULL, MSG_TYPE_UNK, "", "", "Client Command: %s", Line);
-               }
-       }
-}
-
-/**
- * \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 = _SysIOCtl(Server->FD, 8, NULL)) > 0 )
-       {
-       #endif
-               // Read data
-               len = _SysRead(Server->FD, &Server->InBuf[Server->ReadPos], BUFSIZ - 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';
-                       if( newline[-1] == '\r' )       newline[-1] = '\0';
-                       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;
+       Windows_RepaintCurrent();
 }
 
 /**
@@ -863,12 +218,3 @@ char *GetValue(char *Src, int *Ofs)
        return ret;
 }
 
-void SetCursorPos(int Row, int Col)
-{
-       printf("\x1B[%i;%iH", Row, Col);
-}
-
-static inline int isdigit(int ch)
-{
-       return '0' <= ch && ch < '9';
-}

UCC git Repository :: git.ucc.asn.au