X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=server%2Fsrc%2Fmain.c;h=c1e19d904df51b23e3d88a81c4a19ac2e7d1cb75;hb=ec7b115817aa06ede0c2bf933ccdeeb893fdd831;hp=a3174d124dccc8f0a8a5fdd8a0521c282c53e1ae;hpb=da7ca5e387cf4bb820ca48d13a5fc4376c2474b4;p=reposerve diff --git a/server/src/main.c b/server/src/main.c index a3174d1..c1e19d9 100644 --- a/server/src/main.c +++ b/server/src/main.c @@ -1,23 +1,48 @@ #include #include #include +#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include #include "repo.h" - -#include "md5.h" +#include "client.h" static const char *guess_repo_name(const char *path); +static void sighandler(int s); static int parse_args(int argc, char **argv); -static const char *repo_path, *repo_name; +static const char *repo_name; +static int lis = -1; +static int port = 64357; +static int quit; + +static struct client *clients; + +const char *repo_path; + int main(int argc, char **argv) { + struct sockaddr_in addr; + if(parse_args(argc, argv) == -1) { return 1; } + signal(SIGINT, sighandler); + signal(SIGQUIT, sighandler); + signal(SIGILL, sighandler); + signal(SIGSEGV, sighandler); + signal(SIGTERM, sighandler); + if(repo_init(repo_path) == -1) { return 1; } @@ -31,18 +56,91 @@ int main(int argc, char **argv) printf("Serving %s from %s\n", repo_name, repo_path); - /* DBG */ - { - struct md5_state sum; - int i, count = repo_num_files(); - for(i=0; ichksum, sizeof sum.sum); - printf("%s\tmd5:%s size:%lu mtime:%s", file->path, md5_sumstr(&sum), - (unsigned long)file->size, ctime(&file->mtime)); + 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"); } } + printf("Shutting down\n"); return 0; } @@ -72,6 +170,11 @@ fail: return 0; } +static void sighandler(int s) +{ + quit = 1; +} + static void print_usage(const char *argv0) { printf("Usage: %s [options] [repo path]\n", argv0);