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