initial commit
[xdos] / src / main.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <ctype.h>
4 #include <sys/socket.h>
5 #include <sys/select.h>
6 #include "proto.h"
7 #include "client.h"
8 #include "logger.h"
9 #include "keyb.h"
10
11 static int init(void);
12 static void cleanup(void);
13 static void handle_key(int key);
14
15 static int lis; /* the listening socket */
16
17 int main(int argc, char **argv)
18 {
19         if(init() == -1) {
20                 return 1;
21         }
22
23         main_loop();
24
25         cleanup();
26         return 0;
27 }
28
29 static int init(void)
30 {
31         struct sockaddr_in sa;
32
33         /* initialize input */
34         if(kb_init(32) == -1) {
35                 printlog("failed to initialize keyboard driver\n");
36                 return -1;
37         }
38
39         /* start network server */
40         if((lis = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
41                 printlog("failed to create listening socket\n");
42                 return -1;
43         }
44
45         memset(&sa, 0, sizeof sa);
46         sa.sin_family = AF_INET;
47         sa.sin_addr.s_addr = INADDR_ANY;
48         sa.sin_port = htons(6000);
49
50         if(bind(lis, (struct sockaddr*)&sa, sizeof sa) == -1) {
51                 printlog("failed to bind socket to port 6000\n");
52                 return -1;
53         }
54         listen(lis, 8);
55
56         return 0;
57 }
58
59 static void cleanup(void)
60 {
61         struct client *iter = get_clients();
62
63         while(iter) {
64                 close(iter->sock);
65                 iter = iter->next;
66         }
67         free_clients();
68
69         kb_shutdown();
70 }
71
72 static int main_loop(void)
73 {
74         for(;;) {
75                 int key;
76                 int s, maxfd;
77                 struct client *c;
78                 struct timeval tv = {0, 0};
79                 fd_set rdset;
80
81                 /* ctrl-alt-backspace quits */
82                 if(kb_isdown(KB_ALT) && kb_isdown(KB_CTRL) && kb_isdown('\b')) {
83                         return 0;
84                 }
85
86                 /* get any key events and process them */
87                 while((key = kb_getkey()) != -1) {
88                         handle_key(key);
89                 }
90
91                 /* construct the socket set of all open sockets */
92                 FD_ZERO(&rdset);
93                 FD_SET(lis, &rdset);
94                 maxfd = lis;
95
96                 c = get_clients();
97                 while(c) {
98                         FD_SET(c->sock, &rdset);
99                         if(c->sock > maxfd)
100                                 maxfd = c->sock;
101                         c = c->next;
102                 }
103
104                 if(select_s(maxfd + 1, &rdset, 0, 0, &tv) == -1) {
105                         continue;
106                 }
107
108                 /* check for any unread messages from clients and call handle_client */
109                 c = get_clients();
110                 while(c) {
111                         if(FD_ISSET(c->sock, &rdset)) {
112                                 if(handle_client(c) == -1) {
113                                         close(c->sock);
114                                         c->sock = -1;   /* this effectively marks it for removal */
115                                 }
116                         }
117                         c = c->next;
118                 }
119
120                 /* accept any new incoming connections on the listening socket */
121                 if(FD_ISSET(lis, &rdset)) {
122                         struct sockaddr_in addr;
123                         int addrlen;
124
125                         if((s = accept(lis, (struct sockaddr*)&addr, &addrlen)) == -1) {
126                                 printlog("failed to accept new connection\n");
127                         } else {
128                                 printlog("new client from host: %s\n", inet_ntoa(addr.sin_addr));
129
130                                 add_client(s);
131                         }
132                 }
133
134                 /* remove any clients with closed sockets */
135                 remove_closed();
136         }
137 }
138
139 static void handle_key(int key)
140 {
141 }