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

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