/* secondserver.c, 2009-07-05, Dade Murphy * a simple program to connect and listen to client apps * Goals: * -listen & accept * -multithreaded maybe * -maybe implement some irc? http? ftp? * -daemonizable * -protocols? UDP? TCP? maybe SCTP? * */ #include /* the venerable io library */ #include /* offers the endian conversion functions */ #include /* we all like to know what the errors are, no? */ #include /* i dont know why this is here, i'll find out eventually i guess */ #include /* cant make network apps without sockets now, can we? */ #include /* i'm sure this has a very good reason for being here */ #include /* for dns and shit */ #include /* provides close() and i dont know what else */ #include /* for, you know, signals. clearly. */ #include /* for bzero */ #include /* for epoll. obviously. */ #define MAXEVENTS 10 volatile sig_atomic_t sig_continue = 1; int makeListenSocket(char *node, char *port) ; void sighandler(int signal); int main(int argc, char * argv[]) { /*Variable initialization segment. */ extern volatile sig_atomic_t sig_continue; struct sockaddr_storage reqsas; socklen_t saslen = sizeof(reqsas); int lifd; /* fd for the listening socket */ int confd[10]; int epfd; /* a lovely epoll file descriptor */ size_t recv_size; char received[512]; int rvar; /* a variable to hold function returns, error checking and whatnot */ struct epoll_event ev, events[10]; /* set up SigInt handling */ if(signal(SIGINT, &sighandler) == SIG_IGN) signal(SIGINT, SIG_IGN); /* now that we've created the listening socket * we'll get the polling system all set up. */ epfd = epoll_create(0); if(epfd < 0) { perror("epoll_create failed. Everything dies nao"); exit(1); } lifd = makeListenSocket(NULL, "7777"); if(lifd < 0) { printf("omfg, something faaaaailed\n"); exit(2); } ev.events = EPOLLIN; ev.data.fd = lifd; epoll_ctl(epfd, EPOLL_CTL_ADD, lifd, &ev); if( (confd[0] = accept(lifd, (struct sockaddr *) &reqsas, &saslen) ) < 0 ) { perror("accept"); } /*TODO implement epoll */ while( sig_continue ) { epoll_wait(efd, recv_size = recv(confd[0], received, 511, 0); printf("%512s\n", received); bzero(received, 512); } close(epfd); close(rvar); close(lifd); } /* returns a lovely listenning socket on node:port, node would usually be left blank */ int makeListenSocket(char *node, char *port) { extern int errno; int retdumpster; int sockfd; struct addrinfo aiHints, *results; aiHints.ai_flags = AI_PASSIVE; /* this plus a NULL hostname will produce a sockaddr appropriate for a server socket */ aiHints.ai_family = AF_UNSPEC; /* or AF_INET for ip4 or AF_INET6 for ip6 */ aiHints.ai_socktype = SOCK_STREAM; /* yay TCP (probably, there be no guarantees */ aiHints.ai_protocol = 0; /* couldnt find anything to put here, should be harmless */ aiHints.ai_addrlen = (size_t) 0; /* not important at this point */ aiHints.ai_addr = NULL; /* pointer to our future sockaddr */ aiHints.ai_canonname = NULL; /* irrelevant at this point */ aiHints.ai_next = 0; retdumpster = getaddrinfo(node, port, &aiHints, &results); if(retdumpster) { errno = 0; perror(gai_strerror(retdumpster)); return -1; } if( (sockfd = socket( ((struct addrinfo) *results).ai_family, ((struct addrinfo) *results).ai_socktype, ((struct addrinfo) *results).ai_protocol)) < 0 ) { perror("socket() - "); return -2; } if( (retdumpster = bind(sockfd, (struct sockaddr *) ((struct addrinfo) *results).ai_addr , (size_t) ((struct addrinfo) *results).ai_addrlen)) ) { perror("bind() - " ); return -3; } if( (retdumpster = listen(sockfd, 5) ) ) { perror("listen - "); return -4; } freeaddrinfo(results); return sockfd; } void sighandler(int signum) { /*TODO finish sighandler */ extern volatile sig_atomic_t sig_continue; sig_continue = 0; signal(SIGINT, SIG_DFL); printf("Stop triggered. If it doesnt work, ^c again.\n"); }