+ if(!(lis = socket(PF_INET, SOCK_STREAM, 0))) {
+ fprintf(stderr, "failed to create socket: %s\n", strerror(errno));
+ return 1;
+ }
+ fcntl(lis, F_SETFL, fcntl(lis, F_GETFL) | O_NONBLOCK);
+
+ memset(&addr, 0, sizeof addr);
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(port);
+ addr.sin_addr.s_addr = INADDR_ANY;
+
+ if(bind(lis, (struct sockaddr*)&addr, sizeof addr) == -1) {
+ fprintf(stderr, "failed to bind listening socket to port %d\n", port);
+ return 1;
+ }
+ listen(lis, 8);
+
+ for(;;) {
+ int res, max_fd, s;
+ fd_set rdset;
+ struct client *c, dummy;
+
+ FD_SET(lis, &rdset);
+ max_fd = lis;
+
+ c = clients;
+ while(c) {
+ FD_SET(c->s, &rdset);
+ if(c->s > max_fd) max_fd = c->s;
+ c = c->next;
+ }
+
+ if((res = select(max_fd + 1, &rdset, 0, 0, 0)) == -1 && errno != EINTR) {
+ perror("select failed");
+ break;
+ }
+ if(quit) break;
+ if(res <= 0) continue;
+
+ dummy.next = clients;
+ c = &dummy;
+ while(c->next) {
+ if(FD_ISSET(c->next->s, &rdset)) {
+ if(handle_client(c->next) == -1) {
+ struct client *tmp = c->next;
+ c->next = tmp->next;
+
+ printf("Client %s disconnected\n", tmp->addr ? tmp->addr : "unknown");
+ close(tmp->s);
+ free(tmp->addr);
+ free(tmp);
+ continue;
+ }
+ }
+ c = c->next;
+ }
+ clients = dummy.next;
+
+ if(FD_ISSET(lis, &rdset)) {
+ struct sockaddr_in addr;
+ unsigned int addrsz = sizeof addr;
+
+ if((s = accept(lis, (struct sockaddr*)&addr, &addrsz)) == -1) {
+ perror("failed to accept connection");
+ continue;
+ }
+ fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK);
+
+ if(!(c = calloc(1, sizeof *c))) {
+ perror("failed to allocate memory for client structure");
+ close(s);
+ continue;
+ }
+ c->s = s;
+ c->next = clients;
+ c->addr = strdup(inet_ntoa(addr.sin_addr));
+ clients = c;
+
+ send_string(c, "reposerve-0.1 protocol:0\n");
+
+ printf("Connection from: %s\n", c->addr ? c->addr : "unknown");