1*a9643ea8Slogwang #include <stdio.h> 2*a9643ea8Slogwang #include <stdlib.h> 3*a9643ea8Slogwang #include <stdint.h> 4*a9643ea8Slogwang #include <strings.h> 5*a9643ea8Slogwang #include <sys/types.h> 6*a9643ea8Slogwang #include <sys/socket.h> 7*a9643ea8Slogwang #include <arpa/inet.h> 8*a9643ea8Slogwang #include <errno.h> 9*a9643ea8Slogwang #include <assert.h> 10*a9643ea8Slogwang 11*a9643ea8Slogwang #include "ff_config.h" 12*a9643ea8Slogwang #include "ff_api.h" 13*a9643ea8Slogwang 14*a9643ea8Slogwang #define MAX_EVENTS 512 15*a9643ea8Slogwang 16*a9643ea8Slogwang /* kevent set */ 17*a9643ea8Slogwang struct kevent kevSet; 18*a9643ea8Slogwang /* events */ 19*a9643ea8Slogwang struct kevent events[MAX_EVENTS]; 20*a9643ea8Slogwang /* kq */ 21*a9643ea8Slogwang int kq; 22*a9643ea8Slogwang int sockfd; 23*a9643ea8Slogwang 24*a9643ea8Slogwang char html[] = 25*a9643ea8Slogwang "HTTP/1.1 200 OK\r\n" 26*a9643ea8Slogwang "Server: F-Stack\r\n" 27*a9643ea8Slogwang "Date: Sat, 25 Feb 2017 09:26:33 GMT\r\n" 28*a9643ea8Slogwang "Content-Type: text/html\r\n" 29*a9643ea8Slogwang "Content-Length: 439\r\n" 30*a9643ea8Slogwang "Last-Modified: Tue, 21 Feb 2017 09:44:03 GMT\r\n" 31*a9643ea8Slogwang "Connection: keep-alive\r\n" 32*a9643ea8Slogwang "Accept-Ranges: bytes\r\n" 33*a9643ea8Slogwang "\r\n" 34*a9643ea8Slogwang "<!DOCTYPE html>\r\n" 35*a9643ea8Slogwang "<html>\r\n" 36*a9643ea8Slogwang "<head>\r\n" 37*a9643ea8Slogwang "<title>Welcome to F-Stack!</title>\r\n" 38*a9643ea8Slogwang "<style>\r\n" 39*a9643ea8Slogwang " body { \r\n" 40*a9643ea8Slogwang " width: 35em;\r\n" 41*a9643ea8Slogwang " margin: 0 auto; \r\n" 42*a9643ea8Slogwang " font-family: Tahoma, Verdana, Arial, sans-serif;\r\n" 43*a9643ea8Slogwang " }\r\n" 44*a9643ea8Slogwang "</style>\r\n" 45*a9643ea8Slogwang "</head>\r\n" 46*a9643ea8Slogwang "<body>\r\n" 47*a9643ea8Slogwang "<h1>Welcome to F-Stack!</h1>\r\n" 48*a9643ea8Slogwang "\r\n" 49*a9643ea8Slogwang "<p>For online documentation and support please refer to\r\n" 50*a9643ea8Slogwang "<a href=\"http://F-Stack.org/\">F-Stack.org</a>.<br/>\r\n" 51*a9643ea8Slogwang "\r\n" 52*a9643ea8Slogwang "<p><em>Thank you for using F-Stack.</em></p>\r\n" 53*a9643ea8Slogwang "</body>\r\n" 54*a9643ea8Slogwang "</html>"; 55*a9643ea8Slogwang 56*a9643ea8Slogwang int loop(void *arg) 57*a9643ea8Slogwang { 58*a9643ea8Slogwang /* Wait for events to happen */ 59*a9643ea8Slogwang unsigned nevents = ff_kevent(kq, NULL, 0, events, MAX_EVENTS, NULL); 60*a9643ea8Slogwang unsigned i; 61*a9643ea8Slogwang 62*a9643ea8Slogwang for (i = 0; i < nevents; ++i) { 63*a9643ea8Slogwang struct kevent event = events[i]; 64*a9643ea8Slogwang int clientfd = (int)event.ident; 65*a9643ea8Slogwang 66*a9643ea8Slogwang /* Handle disconnect */ 67*a9643ea8Slogwang if (event.flags & EV_EOF) { 68*a9643ea8Slogwang 69*a9643ea8Slogwang /* Simply close socket */ 70*a9643ea8Slogwang ff_close(clientfd); 71*a9643ea8Slogwang 72*a9643ea8Slogwang fprintf(stderr, "A client has left the server...,fd:%d\n", clientfd); 73*a9643ea8Slogwang } else if (clientfd == sockfd) { 74*a9643ea8Slogwang int nclientfd = ff_accept(sockfd, NULL, NULL); 75*a9643ea8Slogwang 76*a9643ea8Slogwang assert(nclientfd > 0); 77*a9643ea8Slogwang 78*a9643ea8Slogwang /* Add to event list */ 79*a9643ea8Slogwang kevSet.data = 0; 80*a9643ea8Slogwang kevSet.fflags = 0; 81*a9643ea8Slogwang kevSet.filter = EVFILT_READ; 82*a9643ea8Slogwang kevSet.flags = EV_ADD; 83*a9643ea8Slogwang kevSet.ident = nclientfd; 84*a9643ea8Slogwang kevSet.udata = NULL; 85*a9643ea8Slogwang 86*a9643ea8Slogwang assert(ff_kevent(kq, &kevSet, 1, NULL, 0, NULL) == 0); 87*a9643ea8Slogwang 88*a9643ea8Slogwang fprintf(stderr, "A new client connected to the server..., fd:%d\n", nclientfd); 89*a9643ea8Slogwang 90*a9643ea8Slogwang } else if (event.filter == EVFILT_READ) { 91*a9643ea8Slogwang char buf[256]; 92*a9643ea8Slogwang size_t readlen = ff_read(clientfd, buf, sizeof(buf)); 93*a9643ea8Slogwang 94*a9643ea8Slogwang fprintf(stderr, "bytes %zu are available to read...,fd:%d\n", (size_t)event.data, clientfd); 95*a9643ea8Slogwang 96*a9643ea8Slogwang ff_write(clientfd, html, sizeof(html)); 97*a9643ea8Slogwang 98*a9643ea8Slogwang } else { 99*a9643ea8Slogwang fprintf(stderr, "unknown event: %8.8X\n", event.flags); 100*a9643ea8Slogwang } 101*a9643ea8Slogwang } 102*a9643ea8Slogwang } 103*a9643ea8Slogwang 104*a9643ea8Slogwang int main(int argc, char * argv[]) 105*a9643ea8Slogwang { 106*a9643ea8Slogwang char *conf; 107*a9643ea8Slogwang if (argc < 2) { 108*a9643ea8Slogwang conf = "./config.ini"; 109*a9643ea8Slogwang } else { 110*a9643ea8Slogwang conf = argv[1]; 111*a9643ea8Slogwang } 112*a9643ea8Slogwang 113*a9643ea8Slogwang ff_init(conf, argc, argv); 114*a9643ea8Slogwang 115*a9643ea8Slogwang int sockfd = ff_socket(AF_INET, SOCK_STREAM, 0); 116*a9643ea8Slogwang printf("sockfd:%d\n", sockfd); 117*a9643ea8Slogwang if (sockfd < 0) 118*a9643ea8Slogwang printf("ff_socket failed\n"); 119*a9643ea8Slogwang 120*a9643ea8Slogwang struct sockaddr_in my_addr; 121*a9643ea8Slogwang bzero(&my_addr, sizeof(my_addr)); 122*a9643ea8Slogwang my_addr.sin_family = AF_INET; 123*a9643ea8Slogwang my_addr.sin_port = htons(80); 124*a9643ea8Slogwang my_addr.sin_addr.s_addr = htonl(INADDR_ANY); 125*a9643ea8Slogwang 126*a9643ea8Slogwang int ret = ff_bind(sockfd, (struct linux_sockaddr *)&my_addr, sizeof(my_addr)); 127*a9643ea8Slogwang if (ret < 0) { 128*a9643ea8Slogwang printf("ff_bind failed\n"); 129*a9643ea8Slogwang } 130*a9643ea8Slogwang 131*a9643ea8Slogwang ret = ff_listen(sockfd, MAX_EVENTS); 132*a9643ea8Slogwang if (ret < 0) { 133*a9643ea8Slogwang printf("ff_listen failed\n"); 134*a9643ea8Slogwang } 135*a9643ea8Slogwang 136*a9643ea8Slogwang kevSet.data = MAX_EVENTS; 137*a9643ea8Slogwang kevSet.fflags = 0; 138*a9643ea8Slogwang kevSet.filter = EVFILT_READ; 139*a9643ea8Slogwang kevSet.flags = EV_ADD; 140*a9643ea8Slogwang kevSet.ident = sockfd; 141*a9643ea8Slogwang kevSet.udata = NULL; 142*a9643ea8Slogwang 143*a9643ea8Slogwang assert((kq = ff_kqueue()) > 0); 144*a9643ea8Slogwang 145*a9643ea8Slogwang /* Update kqueue */ 146*a9643ea8Slogwang ff_kevent(kq, &kevSet, 1, NULL, 0, NULL); 147*a9643ea8Slogwang 148*a9643ea8Slogwang ff_run(loop, NULL); 149*a9643ea8Slogwang return 0; 150*a9643ea8Slogwang } 151*a9643ea8Slogwang 152*a9643ea8Slogwang 153