]> git.ozlabs.org Git - ccan-lca-2011.git/blob - ccan/oserver/oserver.c
5a40ff98cce90c8c96908da83ff497d1bed921d1
[ccan-lca-2011.git] / ccan / oserver / oserver.c
1 #include <ccan/oserver/oserver.h>
2 #include <ccan/read_write_all/read_write_all.h>
3 #include <sys/types.h>
4 #include <sys/socket.h>
5 #include <netinet/in.h>
6 #include <netinet/tcp.h>
7 #include <err.h>
8 #include <stdio.h>
9 #include <unistd.h>
10 #include <ctype.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 void oserver_serve(int fd)
15 {
16         char buf[1024];
17         unsigned int i;
18
19         for (i = 0; i < sizeof(buf)-1; i++) {
20                 if (read(fd, &buf[i], 1) != 1)
21                         errx(1, "Client disconnected");
22                 if (buf[i] == '\n' || buf[i] == '\r')
23                         break;
24                 buf[i] = toupper(buf[i]);
25         }
26         buf[i] = '\0';
27
28         if (!write_all(fd, "Louder, like this: '",
29                        strlen("Louder, like this: '"))
30             || !write_all(fd, buf, i)
31             || !write_all(fd, "'\r\n", strlen("'\r\n")))
32                 err(1, "Write failed");
33         exit(0);
34 }
35
36 int oserver_setup(void)
37 {
38         int sockfd;
39         int one = 1;
40         union {
41                 struct sockaddr addr;
42                 struct sockaddr_in in;
43         } u;
44
45         sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
46         if (sockfd < 0)
47                 err(1, "Creating TCP socket");
48
49         if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
50                 warn("Setting socket reuse");
51
52         u.in.sin_family = AF_INET;
53         u.in.sin_port = htons(OSERVER_PORT);
54         u.in.sin_addr.s_addr = INADDR_ANY;
55         if (bind(sockfd, &u.addr, sizeof(u.in)) == -1)
56                 err(1, "Binding TCP socket");
57
58         if (listen(sockfd, 0) != 0)
59                 err(1, "Listening on TCP socket");
60         return sockfd;
61 }