rev |
line source |
nuclear@2
|
1 #include <stdio.h>
|
nuclear@2
|
2 #include <stdlib.h>
|
nuclear@2
|
3 #include <string.h>
|
nuclear@2
|
4 #include <errno.h>
|
nuclear@2
|
5 #include <assert.h>
|
nuclear@2
|
6 #include <unistd.h>
|
nuclear@2
|
7 #include <fcntl.h>
|
nuclear@2
|
8 #include <sys/socket.h>
|
nuclear@2
|
9 #include <arpa/inet.h>
|
nuclear@2
|
10 #include "srv.h"
|
nuclear@2
|
11 #include "dynarr.h"
|
nuclear@2
|
12
|
nuclear@2
|
13 static int lis_sock = -1, max_socket = -1;
|
nuclear@2
|
14 static int *csock;
|
nuclear@2
|
15
|
nuclear@2
|
16 int srv_init(int port)
|
nuclear@2
|
17 {
|
nuclear@2
|
18 struct sockaddr_in addr;
|
nuclear@2
|
19
|
nuclear@2
|
20 if(lis_sock != -1) {
|
nuclear@2
|
21 fprintf(stderr, "%s: already running\n", __func__);
|
nuclear@2
|
22 return -1;
|
nuclear@2
|
23 }
|
nuclear@2
|
24
|
nuclear@2
|
25 if((lis_sock = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
|
nuclear@2
|
26 fprintf(stderr, "%s: failed to create listening socket\n", __func__);
|
nuclear@2
|
27 return -1;
|
nuclear@2
|
28 }
|
nuclear@2
|
29 if(!(csock = dynarr_alloc(1, sizeof *csock))) {
|
nuclear@2
|
30 fprintf(stderr, "%s: failed to allocate client socket array\n", __func__);
|
nuclear@2
|
31 return -1;
|
nuclear@2
|
32 }
|
nuclear@2
|
33 csock[0] = lis_sock;
|
nuclear@2
|
34 max_socket = lis_sock;
|
nuclear@2
|
35
|
nuclear@2
|
36 fcntl(lis_sock, F_SETFD, fcntl(lis_sock, F_GETFD) | O_NONBLOCK);
|
nuclear@2
|
37
|
nuclear@2
|
38 memset(&addr, 0, sizeof addr);
|
nuclear@2
|
39 addr.sin_family = AF_INET;
|
nuclear@2
|
40 addr.sin_port = htons(port);
|
nuclear@2
|
41 addr.sin_addr.s_addr = INADDR_ANY;
|
nuclear@2
|
42 if(bind(lis_sock, (struct sockaddr*)&addr, sizeof addr) == -1) {
|
nuclear@2
|
43 fprintf(stderr, "%s: failed to bind port %d\n", __func__, port);
|
nuclear@2
|
44 close(lis_sock);
|
nuclear@2
|
45 lis_sock = -1;
|
nuclear@2
|
46 return -1;
|
nuclear@2
|
47 }
|
nuclear@2
|
48
|
nuclear@2
|
49 return 0;
|
nuclear@2
|
50 }
|
nuclear@2
|
51
|
nuclear@2
|
52 void srv_shutdown(void)
|
nuclear@2
|
53 {
|
nuclear@2
|
54 int i, sz = dynarr_size(csock);
|
nuclear@2
|
55 for(i=0; i<sz; i++) {
|
nuclear@2
|
56 close(csock[i]);
|
nuclear@2
|
57 }
|
nuclear@2
|
58 dynarr_free(csock);
|
nuclear@2
|
59 csock = 0;
|
nuclear@2
|
60 lis_sock = -1;
|
nuclear@2
|
61 max_socket = -1;
|
nuclear@2
|
62 }
|
nuclear@2
|
63
|
nuclear@2
|
64 int srv_num_sockets(void)
|
nuclear@2
|
65 {
|
nuclear@2
|
66 return dynarr_size(csock);
|
nuclear@2
|
67 }
|
nuclear@2
|
68
|
nuclear@2
|
69 int *srv_sockets(void)
|
nuclear@2
|
70 {
|
nuclear@2
|
71 return csock;
|
nuclear@2
|
72 }
|
nuclear@2
|
73
|
nuclear@2
|
74 int srv_max_socket(void)
|
nuclear@2
|
75 {
|
nuclear@2
|
76 return max_socket;
|
nuclear@2
|
77 }
|
nuclear@2
|
78
|
nuclear@2
|
79 int srv_handle(int s)
|
nuclear@2
|
80 {
|
nuclear@2
|
81 static char buf[1024];
|
nuclear@2
|
82 int sz;
|
nuclear@2
|
83
|
nuclear@2
|
84 if(s == lis_sock) {
|
nuclear@2
|
85 /* incoming connection */
|
nuclear@2
|
86 struct sockaddr_in addr;
|
nuclear@2
|
87 int addr_size;
|
nuclear@2
|
88
|
nuclear@2
|
89 if((s = accept(lis_sock, (struct sockaddr*)&addr, (int*)&addr_size)) == -1) {
|
nuclear@2
|
90 fprintf(stderr, "%s: failed to accept incoming connection\n", __func__);
|
nuclear@2
|
91 return -1;
|
nuclear@2
|
92 }
|
nuclear@2
|
93 printf("%s: incoming connection from %s:%d\n", __func__,
|
nuclear@2
|
94 inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
|
nuclear@2
|
95 csock = dynarr_push(csock, &s);
|
nuclear@2
|
96 assert(csock);
|
nuclear@2
|
97 return 0;
|
nuclear@2
|
98 }
|
nuclear@2
|
99
|
nuclear@2
|
100 /* handle client */
|
nuclear@2
|
101 while((sz = read(s, buf, sizeof buf - 1)) > 0) {
|
nuclear@2
|
102 printf("%s: got data: %s\n", __func__, buf);
|
nuclear@2
|
103 }
|
nuclear@2
|
104 if(sz < 0 && errno != EAGAIN) {
|
nuclear@2
|
105 /* client closed connection probably */
|
nuclear@2
|
106 int i, num_clients = dynarr_size(csock);
|
nuclear@2
|
107 printf("%s: removing client\n", __func__);
|
nuclear@2
|
108 close(s);
|
nuclear@2
|
109 for(i=0; i<num_clients; i++) {
|
nuclear@2
|
110 if(csock[i] == s) {
|
nuclear@2
|
111 csock[i] = csock[num_clients - 1];
|
nuclear@2
|
112 csock = dynarr_pop(csock);
|
nuclear@2
|
113 break;
|
nuclear@2
|
114 }
|
nuclear@2
|
115 }
|
nuclear@2
|
116 assert(i < num_clients);
|
nuclear@2
|
117 }
|
nuclear@2
|
118 return 0;
|
nuclear@2
|
119 }
|
nuclear@2
|
120
|
nuclear@2
|
121 void srv_send_frame(unsigned char *frame, int xsz, int ysz)
|
nuclear@2
|
122 {
|
nuclear@2
|
123 }
|