From a19419ccae6dd6f3be010ab28063d7c779d0b6e3 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 28 Sep 2024 16:55:35 +0300 Subject: [PATCH] fixed --- plainbin.c | 243 ++++++++++++++++++++++------------------------------- 1 file changed, 101 insertions(+), 142 deletions(-) diff --git a/plainbin.c b/plainbin.c index 159bc27..56cfae8 100644 --- a/plainbin.c +++ b/plainbin.c @@ -20,7 +20,7 @@ #define MSG4 "No namespace available.\n" #ifndef VERSION -#define VERSION "1.2.1" +#define VERSION "1.2.2" #endif typedef struct { @@ -44,12 +44,15 @@ typedef struct { } CFG; CFG cfg = {.max_clients = 15, .max_size = 1, .buf_size = 32000, .name_len = 15, .dir = "."}; -/* Server sockets */ -int ifd; -size_t ifd_clients; +typedef struct { + int fd; + char *buf; + char *filename; +} CLIENT_THREAD; +int ifd; int ofd; -size_t ofd_clients; +size_t clients; enum { OUTPUT, @@ -68,15 +71,15 @@ int new_server(const int port, const int backlog) { struct timeval tout = {.tv_sec = RECV_TIMEOUT, .tv_usec = 0}; if (setsockopt(listen_fd, SOL_SOCKET, SO_RCVTIMEO, &tout, sizeof(tout)) < 0) - goto NS_ERROR; + goto NEW_SOCKET_ERROR; tout.tv_sec = SEND_TIMEOUT; if (setsockopt(listen_fd, SOL_SOCKET, SO_SNDTIMEO, &tout, sizeof(tout)) < 0) - goto NS_ERROR; + goto NEW_SOCKET_ERROR; int reuse = 1; if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEPORT, &reuse, sizeof(reuse)) < 0) - goto NS_ERROR; + goto NEW_SOCKET_ERROR; struct sockaddr_in serv_addr; serv_addr.sin_family = AF_INET; @@ -84,57 +87,48 @@ int new_server(const int port, const int backlog) { serv_addr.sin_port = htons(port); if (bind(listen_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) - goto NS_ERROR; + goto NEW_SOCKET_ERROR; if (listen(listen_fd, backlog) < 0) - goto NS_ERROR; + goto NEW_SOCKET_ERROR; return listen_fd; -NS_ERROR: +NEW_SOCKET_ERROR: close(listen_fd); return -1; } -char *rand_string(void) { - char abc[] = "asdfghjklzxcvbnmqwertyuiopQWERTYUIOPASDFGHJKLZXCVBNM1234567890"; - char *res = malloc(cfg.name_len + 1); - if (res == NULL) - return NULL; +char rand_name(char *buf) { + const char abc[] = "asdfghjklzxcvbnmqwertyuiopQWERTYUIOPASDFGHJKLZXCVBNM1234567890"; - for (size_t i = 0; i < cfg.name_len; i++) - res[i] = abc[rand() % (sizeof(abc) - 1)]; - - res[cfg.name_len] = '\0'; - return res; -} - -char *rand_name(void) { for (int i = 0; i < 1000; i++) { - char *filename = rand_string(); - if (filename == NULL) - continue; + for (size_t i = 0; i < cfg.name_len; i++) + buf[i] = abc[rand() % (sizeof(abc) - 1)]; + + buf[cfg.name_len] = '\n'; + buf[cfg.name_len + 1] = '\0'; struct stat sb; - if (stat(filename, &sb) < 0) - return filename; + if (stat(buf, &sb) < 0) + return 1; - free(filename); + return 0; } - return NULL; + return 1; } int send_str(int fd, char *str, ssize_t size, int flag) { while (size) { ssize_t ret = 0; if (flag) - ret = send(fd, str, size, 0); + ret = send(fd, str, size, MSG_NOSIGNAL); else ret = write(fd, str, size); - if (ret < 0 && !(errno == EAGAIN || errno == EINTR)) + if (ret < 0) return 1; else if (ret == 0) @@ -147,153 +141,93 @@ int send_str(int fd, char *str, ssize_t size, int flag) { return 0; } -void upload(int cfd, pid_t par) { - int ffd = -1; - char *buf = NULL; - - /* Send and create filename */ - char *filename = rand_name(); - if (filename == NULL) { - send(cfd, MSG4, sizeof(MSG4), 0); - goto UPL_ERROR; +void upload(CLIENT_THREAD *CT) { + if (rand_name(CT->filename)) { + send(CT->fd, MSG4, sizeof(MSG4), 0); + return; } - if (send(cfd, filename, strlen(filename), 0) < 0) - goto UPL_ERROR; + if (send(CT->fd, CT->filename, strlen(CT->filename), 0) < 0) + return; - if (send(cfd, "\n", 1, 0) < 0) - goto UPL_ERROR; - - ffd = open(filename, O_CREAT | O_WRONLY, 0666); + /* Create file */ + int ffd = open(CT->filename, O_CREAT | O_WRONLY, 0666); if (ffd < 0) - goto UPL_ERROR; - - /* Sending */ - buf = malloc(cfg.buf_size + 1); - if (buf == NULL) - goto UPL_ERROR; + goto UPLOAD_ERROR; size_t tbytes = 0; while (1) { - ssize_t rbytes = recv(cfd, buf, cfg.buf_size, 0); - if (rbytes < 0 && !(errno == EAGAIN || errno == EINTR)) - goto UPL_ERROR; + ssize_t rbytes = recv(CT->fd, CT->buf, cfg.buf_size, MSG_NOSIGNAL); + if (rbytes < 0 && errno != EINTR) + goto UPLOAD_ERROR; else if (rbytes == 0) break; tbytes += (size_t)rbytes; if (tbytes / 1024 / 1024 >= cfg.max_size) { - send_str(cfd, MSG2, sizeof(MSG2), WRITE); + send_str(CT->fd, MSG2, sizeof(MSG2), WRITE); break; } - if (send_str(ffd, buf, rbytes, WRITE)) - goto UPL_ERROR; + if (send_str(ffd, CT->buf, rbytes, WRITE)) + goto UPLOAD_ERROR; } - /* Clear */ -UPL_ERROR: - if (buf) - free(buf); - +UPLOAD_ERROR: if (ffd != -1) close(ffd); - - if (filename) - free(filename); - - close(cfd); - kill(par, SIGUSR1); - exit(0); } -void load(int cfd, pid_t par) { - int ffd = -1; - char *buf = NULL; - - /* For INFO cmd */ - cfg.name_len += 4; - - /* Get filename */ - char *filename = malloc(cfg.name_len + 1); - if (filename == NULL) - goto LD_ERROR; - - ssize_t rbytes = recv(cfd, filename, cfg.name_len, 0); +void load(CLIENT_THREAD *CT) { + ssize_t rbytes = recv(CT->fd, CT->filename, cfg.name_len, 0); if (rbytes <= 0) - goto LD_ERROR; + return; - filename[rbytes] = '\0'; - char *ptr = strchr(filename, '\n'); + CT->filename[rbytes] = '\0'; + char *ptr = strchr(CT->filename, '\n'); if (ptr) *ptr = '\0'; - if (strstr(filename, ".") || strstr(filename, "/")) - goto LD_ERROR; + if (strstr(CT->filename, ".") || strstr(CT->filename, "/")) + return; /* INFO */ - if (!strcmp(filename, "INFO")) { + if (!strcmp(CT->filename, "INFO")) { char msg[336]; - int ret = snprintf(msg, sizeof(msg), "Max file size: %zuMB\nMax clients in thread: %zu\nBuffer size: %zu\nMOTD: %s\n", cfg.max_size, cfg.max_clients, cfg.buf_size, (cfg.motd) ? cfg.motd : ""); + int ret = snprintf(msg, sizeof(msg), "Max file size: %zuMB\nMax clients: %zu\nBuffer size: %zu\nMOTD: %s\n", cfg.max_size, cfg.max_clients, cfg.buf_size, (cfg.motd) ? cfg.motd : ""); - if (send_str(cfd, msg, (ssize_t)ret, SEND)) - goto LD_ERROR; - - goto LD_ERROR; + send_str(CT->fd, msg, (ssize_t)ret, SEND); + return; } /* Open */ - ffd = open(filename, O_RDONLY); + int ffd = open(CT->filename, O_RDONLY); if (ffd < 0) { - send_str(cfd, MSG3, sizeof(MSG3), SEND); - goto LD_ERROR; + send_str(CT->fd, MSG3, sizeof(MSG3), SEND); + goto LOAD_ERROR; } - /* Sending */ - buf = malloc(cfg.buf_size + 1); - if (buf == NULL) - goto LD_ERROR; - while (1) { - rbytes = read(ffd, buf, cfg.buf_size); - if (rbytes < 0 && !(errno == EAGAIN || errno == EINTR)) - goto LD_ERROR; + rbytes = read(ffd, CT->buf, cfg.buf_size); + if (rbytes < 0 && errno != EINTR) + goto LOAD_ERROR; else if (rbytes == 0) break; - if (send_str(cfd, buf, rbytes, SEND)) - goto LD_ERROR; + if (send_str(CT->fd, CT->buf, rbytes, SEND)) + goto LOAD_ERROR; } - /* Clear */ -LD_ERROR: - if (buf) - free(buf); - +LOAD_ERROR: if (ffd != -1) close(ffd); - - if (filename) - free(filename); - - sleep(1); - close(cfd); - kill(par, SIGUSR2); - exit(0); } void sig_handler(int sig) { - if (sig == SIGUSR1) { - if (ifd_clients) - ifd_clients--; - } - - else if (sig == SIGUSR2) { - if (ofd_clients) - ofd_clients--; - } + if (sig == SIGUSR1 && clients) + clients--; else { close(ifd); @@ -314,21 +248,41 @@ void Proc(int fd, int flag) { if (cfd < 0) continue; - if (flag == INPUT && ifd_clients < cfg.max_clients) { - ifd_clients++; + printf("%d\n", clients); + if (clients < cfg.max_clients) { + clients++; if (fork() == 0) { close(fd); - upload(cfd, par); - } - } - else if (flag == OUTPUT && ofd_clients < cfg.max_clients) { - ofd_clients++; + /* Allocate buffers */ + char *buf = malloc(cfg.buf_size); + char *filename = malloc(cfg.name_len + 1); + if (filename == NULL || buf == NULL) { + if (filename != NULL) + free(filename); - if (fork() == 0) { - close(fd); - load(cfd, par); + if (buf != NULL) + free(buf); + + exit(1); + } + + /* Start functions */ + CLIENT_THREAD CT = {.fd = cfd, .buf = buf, .filename = filename}; + if (flag == INPUT) + upload(&CT); + + else if (flag == OUTPUT) + load(&CT); + + /* Clean */ + sleep(1); + + free(buf); + close(cfd); + kill(par, SIGUSR1); + exit(0); } } @@ -343,10 +297,10 @@ int main(int argc, char **argv) { srand(time(NULL)); signal(SIGUSR1, sig_handler); - signal(SIGUSR2, sig_handler); signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); signal(SIGCHLD, SIG_IGN); + signal(SIGPIPE, SIG_IGN); int backlog = 1; int iport = 8080; @@ -378,6 +332,11 @@ int main(int argc, char **argv) { case 'n': sscanf(optarg, "%zu", &cfg.name_len); + if (cfg.name_len < 4) { + fprintf(stderr, "%s: name lenght can not be less than 4\n", argv[0]); + return 1; + } + break; case 'b':