Usermode/irc - New code working, glitches on wrapped messages (swapping windows might...
[tpg/acess2.git] / Usermode / Applications / irc_src / main.c
1 /*
2  * Acess2 IRC Client
3  */
4 #include <acess/sys.h>
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <net.h>
9 #include <stdarg.h>
10 #include <acess/devices/pty.h>
11
12 #include "common.h"
13 #include "input.h"
14 #include "window.h"
15 #include "server.h"
16
17 // === TYPES ===
18
19 // === PROTOTYPES ===
20  int    main(int argc, const char *argv[], const char *envp[]);
21  int    MainLoop(void);
22  int    ParseArguments(int argc, const char *argv[]);
23 // --- 
24 void    Redraw_Screen(void);
25 // --- Helpers
26 void    Exit(const char *Reason);
27  int    writef(int FD, const char *Format, ...);
28  int    OpenTCP(const char *AddressString, short PortNumber);
29 char    *GetValue(char *Str, int *Ofs);
30
31 // === GLOBALS ===
32 const char      *gsExitReason = "No reason [BUG]";
33
34 // ==== CODE ====
35 void ExitHandler(void)
36 {
37         printf("\x1B[?1047l");
38         printf("Quit: %s\n", gsExitReason);
39
40         // stty +echo,canon
41         struct ptymode  mode = {.InputMode = 0, .OutputMode = 0};
42         mode.InputMode = PTYIMODE_CANON|PTYIMODE_ECHO;
43         _SysIOCtl(0, PTY_IOCTL_SETMODE, &mode);
44 }
45
46 void Exit(const char *Reason)
47 {
48         gsExitReason = (Reason ? Reason : "User Requested");
49         exit( (Reason ? 1 : 0) );
50 }
51
52 int main(int argc, const char *argv[], const char *envp[])
53 {
54          int    tmp;
55         
56         // Parse Command line
57         if( (tmp = ParseArguments(argc, argv)) )        return tmp;
58         
59         atexit(ExitHandler);
60         
61         ACurses_Init();
62         
63         printf("\x1B[?1047h");
64         printf("\x1B[%i;%ir", 2, giTerminal_Height-2);
65         
66         // HACK: Static server entry
67         // UCC (University [of Western Australia] Computer Club) IRC Server
68 //      tServer *starting_server = Server_Connect( "UCC", "130.95.13.18", 6667 );
69         // Freenode (#osdev)
70         tServer *starting_server = Server_Connect( "Freenode", "84.240.3.129", 6667 );
71         // Local servers
72 //      gWindow_Status.Server = Server_Connect( "VMHost", "10.0.2.2", 6667 );
73 //      gWindow_Status.Server = Server_Connect( "BitlBee", "192.168.1.39", 6667 );
74         
75         Windows_SetStatusServer(starting_server);
76         Windows_RepaintCurrent();
77         SetCursorPos(giTerminal_Height-1, 1);
78         printf("[(status)] ");
79         
80         MainLoop();
81
82         Servers_CloseAll("Client closing");
83         
84         return 0;
85 }
86
87 int MainLoop(void)
88 {
89         SetCursorPos(giTerminal_Height, 1);
90         printf("[(status)] ");
91         fflush(stdout);
92         
93         // stty -echo,canon
94         struct ptymode  mode = {.InputMode = 0, .OutputMode = 0};
95         _SysIOCtl(0, PTY_IOCTL_SETMODE, &mode);
96         
97         for( ;; )
98         {
99                 fd_set  readfds, errorfds;
100                  int    nfds = 1;
101                 
102                 FD_ZERO(&readfds);
103                 FD_ZERO(&errorfds);
104                 
105                 Input_FillSelect(&nfds, &readfds);
106                 Servers_FillSelect(&nfds, &readfds, &errorfds);
107                 
108                 int rv = _SysSelect(nfds, &readfds, 0, &errorfds, NULL, 0);
109                 if( rv < 0 )    break;
110                 
111                 // user input
112                 Input_HandleSelect(nfds, &readfds);
113                 
114                 // Server response
115                 Servers_HandleSelect(nfds, &readfds, &errorfds);
116         }
117         return 0;
118 }
119
120 /**
121  * \todo Actually implement correctly :)
122  */
123 int ParseArguments(int argc, const char *argv[])
124 {
125         return 0;
126 }
127
128 void Redraw_Screen(void)
129 {
130         printf("\x1B[2J");      // Clear screen
131         printf("\x1B[H");       // Reset cursor
132
133         Windows_RepaintCurrent();
134 }
135
136 /**
137  * \brief Write a formatted string to a file descriptor
138  * 
139  */
140 int writef(int FD, const char *Format, ...)
141 {
142         va_list args;
143          int    len;
144         
145         va_start(args, Format);
146         len = vsnprintf(NULL, 0, Format, args);
147         va_end(args);
148         
149         {
150                 char    buf[len+1];
151                 va_start(args, Format);
152                 vsnprintf(buf, len+1, Format, args);
153                 va_end(args);
154                 
155                 return _SysWrite(FD, buf, len);
156         }
157 }
158
159 /**
160  * \brief Initialise a TCP connection to \a AddressString on port \a PortNumber
161  */
162 int OpenTCP(const char *AddressString, short PortNumber)
163 {
164          int    fd, addrType;
165         char    addrBuffer[8];
166         
167         // Parse IP Address
168         addrType = Net_ParseAddress(AddressString, addrBuffer);
169         if( addrType == 0 ) {
170                 fprintf(stderr, "Unable to parse '%s' as an IP address\n", AddressString);
171                 _SysDebug("Unable to parse '%s' as an IP address\n", AddressString);
172                 return -1;
173         }
174         
175         // Finds the interface for the destination address
176         fd = Net_OpenSocket(addrType, addrBuffer, "tcpc");
177         if( fd == -1 ) {
178                 fprintf(stderr, "Unable to open TCP Client to '%s'\n", AddressString);
179                 _SysDebug("Unable to open TCP client to '%s'\n", AddressString);
180                 return -1;
181         }
182         
183         // Set remote port and address
184 //      printf("Setting port and remote address\n");
185         _SysIOCtl(fd, 5, &PortNumber);
186         _SysIOCtl(fd, 6, addrBuffer);
187         
188         // Connect
189 //      printf("Initiating connection\n");
190         if( _SysIOCtl(fd, 7, NULL) == 0 ) {
191                 // Shouldn't happen :(
192                 fprintf(stderr, "Unable to start connection\n");
193                 return -1;
194         }
195         
196         // Return descriptor
197         return fd;
198 }
199
200 /**
201  * \brief Read a space-separated value from a string
202  */
203 char *GetValue(char *Src, int *Ofs)
204 {
205          int    pos = *Ofs;
206         char    *ret = Src + pos;
207         char    *end;
208         
209         if( !Src )      return NULL;
210         
211         while( *ret == ' ' )    ret ++;
212         
213         end = strchr(ret, ' ');
214         if( end ) {
215                 *end = '\0';
216         }
217         else {
218                 end = ret + strlen(ret) - 1;
219         }
220         
221         end ++ ;
222         while( *ret == ' ' )    end ++;
223         *Ofs = end - Src;
224         
225         return ret;
226 }
227

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