#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
#include <limits.h>
#include <time.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <netinet/in.h>
#include "repo.h"
-
-#include "md5.h"
+#include "client.h"
static const char *guess_repo_name(const char *path);
static int parse_args(int argc, char **argv);
static const char *repo_path, *repo_name;
+static int lis = -1;
+static int port = 64357;
+
+static struct client *clients;
int main(int argc, char **argv)
{
+ struct sockaddr_in addr;
+
if(parse_args(argc, argv) == -1) {
return 1;
}
printf("Serving %s from %s\n", repo_name, repo_path);
- /* DBG */
- {
- struct md5_state sum;
- int i, count = repo_num_files();
- for(i=0; i<count; i++) {
- struct repo_file *file = repo_file(i);
- memcpy(sum.sum, file->chksum, 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;
+ }
+
+ 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(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;
+ close(tmp->s);
+ free(tmp);
+ continue;
+ }
+ }
+ c = c->next;
+ }
+ clients = dummy.next;
+
+ if(FD_ISSET(lis, &rdset)) {
+ if((s = accept(lis, 0, 0)) == -1) {
+ perror("failed to accept connection");
+ continue;
+ }
+ if(!(c = malloc(sizeof *c))) {
+ perror("failed to allocate memory for client structure");
+ close(s);
+ continue;
+ }
+ c->s = s;
+ c->next = clients;
+ clients = c;
}
}