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