#include "main.h" #include "session.h" #include "user.h" #include #include #include #include #include #include #include #include #include #include void server_main_loop(server_data_t *s_d) { fd_set readfds; int i, sr; session *connections[MAX_CONNECTIONS]; for (i = 0; i < MAX_CONNECTIONS; i++) { connections[i] = NULL; } int maxfd, res; for (;;) { FD_ZERO(&readfds); FD_SET(s_d->ls, &readfds); maxfd = s_d->ls; for (i = 0; i < MAX_CONNECTIONS; i++) { if (connections[i] != NULL) { FD_SET(i, &readfds); if (i > maxfd) maxfd = i; /* active uploads/downloads */ if (connections[i]->fd > -1) { int fd = connections[i]->fd; FD_SET(fd, &readfds); if (fd > maxfd) maxfd = fd; } } } sr = select(maxfd + 1, &readfds, NULL, NULL, NULL); if (sr == -1) { perror("select"); exit(6); } if (FD_ISSET(s_d->ls, &readfds)) { if (-1 == accept_client(s_d->ls, connections, s_d->welcome_message)) { fprintf(stderr, "Can't accept connection, error: %d\n", errno); } } for (i = 0; i < MAX_CONNECTIONS; i++) { /* download/upload file */ if (connections[i] != NULL && (connections[i]->state == OP_UPLOAD || connections[i]->state == OP_DOWNLOAD)) { if (connections[i]->fd > -1 && FD_ISSET(connections[i]->fd, &readfds)) { perform_session_action(connections[i], NULL, s_d); } } else if (connections[i] != NULL && FD_ISSET(i, &readfds)) { /* server/client requests */ session *sess = connections[i]; char *line; res = session_do_read(sess, &line); if (line != NULL && res) { perform_session_action(sess, line, s_d); free(line); if (sess->state == ERR) { close_session(connections, i); } } if (res == 0) { close_session(connections, i); } } } } } char *get_welcome_mes() { int fd = open(WELCOME_FILE_NAME, O_RDONLY); if (fd == -1) { perror(WELCOME_FILE_NAME); exit(7); } int filesize = lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); char *welcome_message = mmap(NULL, filesize, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); if (welcome_message == MAP_FAILED) { perror(WELCOME_FILE_NAME); close(fd); exit(5); } close(fd); return welcome_message; } int start_server() { int res; int ls = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in s_addr; s_addr.sin_family = AF_INET; s_addr.sin_port = htons(PORT); s_addr.sin_addr.s_addr = htonl(INADDR_ANY); int opt = 1; setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); res = bind(ls, (struct sockaddr *)&s_addr, sizeof(s_addr)); if (res == -1) { perror("bind"); exit(3); } res = listen(ls, LISTEN_QLEN); if (res == -1) { perror("listen"); exit(4); } return ls; } void prepare_start(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(1); } if (-1 == chdir(argv[1])) { perror(argv[1]); exit(2); } }