3 #include <sys/socket.h>
8 static int handle_client_setup(struct client *c);
9 static int send_server_info(struct client *c);
11 static struct client *clist;
15 struct client *c = malloc(sizeof *c);
17 printlog("failed to allocate memory for new client\n");
20 memset(c, 0, sizeof *c);
22 c->state = CLIENT_SETUP;
29 int remove_client(int s)
32 struct client *iter = &dummy;
36 if(iter->next->sock == s) {
37 struct client *tmp = iter->next;
38 iter->next = tmp->next;
47 /* remove all clients with closed invalid sockets */
48 int remove_closed(void)
52 struct client *iter = &dummy;
56 if(iter->next->sock == -1) {
57 struct client *tmp = iter->next;
58 iter->next = tmp->next;
68 struct client *find_client_sock(int s)
70 struct client *c = clist;
71 while(c && c->sock != s) {
77 struct client *get_clients(void)
82 void free_clients(void)
85 struct client *c = clist;
92 /* --- client comms --- */
94 /* handles all communications with clients */
95 int handle_client(struct client *c)
97 if(c->state == CLIENT_SETUP) {
98 if(handle_client_setup(c) == -1) {
101 if(c->bufsz <= 0) { /* consumed all data, done */
106 /* TODO handle client requests ... */
111 /* handles data coming from a client in the CLIENT_SETUP state */
112 static int handle_client_setup(struct client *c)
114 int rd, auth_name_len, auth_data_len, fullsz, must_swap = 0;
115 struct xconn_setup_header *setup;
116 char *start = c->inbuf + c->bufsz;
117 int avail = CLIENT_BUF_SIZE - c->bufsz;
119 if((rd = recv(c->sock, start, avail, 0)) <= 0) {
124 if(c->bufsz < sizeof(struct xconn_setup_header)) {
125 return 0; /* need more data */
128 setup = (struct xconn_setup_header*)c->inbuf;
129 if(setup->byteorder == 'B') {
131 auth_name_len = ntohs(setup->auth_name_length);
132 auth_data_len = ntohs(setup->auth_data_length);
135 auth_name_len = setup->auth_name_length;
136 auth_data_len = setup->auth_data_length;
139 /* take padding to the next 32bit-aligned address into account */
140 auth_name_len = (auth_name_len + 3) & 0xfffc;
141 auth_data_len = (auth_data_len + 3) & 0xfffc;
142 fullsz = sizeof(struct xconn_setup_header) + auth_name_len + auth_data_len;
144 if(c->bufsz < fullsz) {
145 return 0; /* more to read... */
148 /* ok we've read it all, act on it... */
151 printlog("big endian client, protocol: %d.%d\n", ntohs(setup->proto_major), ntohs(setup->proto_minor));
153 printlog("little endian client, protocol: %d.%d\n", setup->proto_major, setup->proto_minor);
155 /* TODO send response */
156 c->state = CLIENT_ACTIVE;
158 if(c->bufsz > fullsz) {
159 int rem = c->bufsz - fullsz;
160 memmove(c->inbuf, c->inbuf + fullsz, rem);
166 static int send_server_info(struct client *c)
168 struct xconn_accept_header *hdr;
170 return -1; /* TODO */