4 #include <acess/sys.h>
\r
13 typedef struct sServer {
\r
15 char InBuf[BUFSIZ+1];
\r
19 // === PROTOTYPES ===
\r
20 int ParseArguments(int argc, const char *argv[]);
\r
21 void ProcessIncoming(tServer *Server);
\r
22 int writef(int FD, const char *Format, ...);
\r
23 int OpenTCP(const char *AddressString, short PortNumber);
\r
26 char *gsUsername = "root";
\r
27 char *gsHostname = "acess";
\r
28 char *gsRemoteAddress = NULL;
\r
29 char *gsRealName = "Acess2 IRC Client";
\r
30 char *gsNickname = "acess";
\r
31 short giRemotePort = 6667;
\r
34 int main(int argc, const char *argv[], const char *envp[])
\r
39 memset(&srv, 0, sizeof(srv));
\r
41 // Parse Command line
\r
42 // - Sets the server configuration globals
\r
43 if( (tmp = ParseArguments(argc, argv)) ) {
\r
47 // Connect to the remove server
\r
48 srv.FD = OpenTCP( gsRemoteAddress, giRemotePort );
\r
49 if( srv.FD == -1 ) {
\r
50 fprintf(stderr, "Unable to create socket\n");
\r
54 printf("Connection opened\n");
\r
55 ProcessIncoming(&srv);
\r
57 writef(srv.FD, "USER %s %s %s : %s\n", gsUsername, gsHostname, gsRemoteAddress, gsRealName);
\r
58 writef(srv.FD, "NICK %s\n", gsNickname);
\r
60 printf("Processing\n");
\r
68 FD_SET(0, &readfds); // stdin
\r
69 FD_SET(srv.FD, &readfds);
\r
71 rv = select(srv.FD, &readfds, 0, 0, NULL);
\r
72 if( rv == -1 ) break;
\r
74 if(FD_ISSET(0, &readfds))
\r
80 if(FD_ISSET(srv.FD, &readfds))
\r
82 ProcessIncoming(&srv);
\r
91 * \todo Actually implement correctly :)
\r
93 int ParseArguments(int argc, const char *argv[])
\r
95 gsRemoteAddress = "130.95.13.18"; // irc.ucc.asn.au
\r
100 void Cmd_PRIVMSG(tServer *Server, const char *Dest, const char *Src, const char *Message)
\r
102 printf("%p: %s => %s\t%s\n", Server, Src, Dest, Message);
\r
106 * \brief Read a space-separated value from a string
\r
108 char *GetValue(char *Src, int *Ofs)
\r
111 char *ret = Src + pos;
\r
114 if( !Src ) return NULL;
\r
116 while( *ret == ' ' ) ret ++;
\r
118 end = strchr(ret, ' ');
\r
123 end = ret + strlen(ret) - 1;
\r
125 *Ofs = end - Src + 1;
\r
132 void ParseServerLine(tServer *Server, char *Line)
\r
136 if( *Line == ':' ) {
\r
138 ident = GetValue(Line, &pos);
\r
140 cmd = GetValue(Line, &pos);
\r
142 if( strcmp(cmd, "PRIVMSG") == 0 ) {
\r
143 char *dest, *message;
\r
145 dest = GetValue(Line, &pos);
\r
147 if( Line[pos] == ':' ) {
\r
148 message = Line + pos + 1;
\r
151 message = GetValue(Line, &pos);
\r
153 Cmd_PRIVMSG(Server, dest, ident, message);
\r
157 // Command to client
\r
162 * \brief Process incoming lines from the server
\r
164 void ProcessIncoming(tServer *Server)
\r
166 char *ptr, *newline;
\r
169 // While there is data in the buffer, read it into user memory and
\r
170 // process it line by line
\r
171 // ioctl#8 on a TCP client gets the number of bytes in the recieve buffer
\r
172 // - Used to avoid blocking
\r
174 while( (len = ioctl(Server->FD, 8, NULL)) > 0 )
\r
178 len = read(Server->FD, BUFSIZ - Server->ReadPos, &Server->InBuf[Server->ReadPos]);
\r
179 Server->InBuf[Server->ReadPos + len] = '\0';
\r
181 // Break into lines
\r
182 ptr = Server->InBuf;
\r
183 while( (newline = strchr(ptr, '\n')) )
\r
186 printf("%s\n", ptr);
\r
187 ParseServerLine(Server, ptr);
\r
191 // Handle incomplete lines
\r
192 if( ptr - Server->InBuf < len + Server->ReadPos ) {
\r
193 // Update the read position
\r
194 // InBuf ReadPos ptr ReadPos+len
\r
195 // | old | new used | new unused |
\r
196 Server->ReadPos = len + Server->ReadPos - (ptr - Server->InBuf);
\r
197 // Copy stuff back (moving "new unused" to the start of the buffer)
\r
198 memcpy(Server->InBuf, ptr, Server->ReadPos);
\r
201 Server->ReadPos = 0;
\r
209 * \brief Write a formatted string to a file descriptor
\r
212 int writef(int FD, const char *Format, ...)
\r
217 va_start(args, Format);
\r
218 len = vsnprintf(NULL, 1000, Format, args);
\r
223 va_start(args, Format);
\r
224 vsnprintf(buf, len+1, Format, args);
\r
227 return write(FD, len, buf);
\r
232 * \brief Initialise a TCP connection to \a AddressString on port \a PortNumber
\r
234 int OpenTCP(const char *AddressString, short PortNumber)
\r
238 char addrBuffer[8];
\r
240 // Parse IP Address
\r
241 addrType = Net_ParseAddress(AddressString, addrBuffer);
\r
242 if( addrType == 0 ) {
\r
243 fprintf(stderr, "Unable to parse '%s' as an IP address\n", AddressString);
\r
247 // Finds the interface for the destination address
\r
248 iface = Net_GetInterface(addrType, addrBuffer);
\r
249 if( iface == NULL ) {
\r
250 fprintf(stderr, "Unable to find a route to '%s'\n", AddressString);
\r
254 printf("iface = '%s'\n", iface);
\r
256 // Open client socket
\r
257 // TODO: Move this out to libnet?
\r
259 int len = snprintf(NULL, 100, "/Devices/ip/%s/tcpc", iface);
\r
261 snprintf(path, 100, "/Devices/ip/%s/tcpc", iface);
\r
262 fd = open(path, OPENFLAG_READ|OPENFLAG_WRITE);
\r
268 fprintf(stderr, "Unable to open TCP Client for reading\n");
\r
272 // Set remote port and address
\r
273 printf("Setting port and remote address\n");
\r
274 ioctl(fd, 5, &PortNumber);
\r
275 ioctl(fd, 6, addrBuffer);
\r
278 printf("Initiating connection\n");
\r
279 if( ioctl(fd, 7, NULL) == 0 ) {
\r
280 // Shouldn't happen :(
\r
281 fprintf(stderr, "Unable to start connection\n");
\r
285 // Return descriptor
\r