diff --git a/plainbin.c b/plainbin.c index d8573ae..8d08e41 100644 --- a/plainbin.c +++ b/plainbin.c @@ -14,20 +14,26 @@ #define SEND_TIMEOUT 1 #define RECV_TIMEOUT 2 -#define BUFLEN 1024 * 1024 -#define MSG1 "Server very loaded.\n" -#define MSG2 "File very big.\n" -#define MSG3 "Closing connection.\n" -#define MSG4 "No such file.\n" +#define MSG1 "Server is very busy.\n" +#define MSG2 "The file is very large.\n" +#define MSG3 "No such file.\n" +#define MSG4 "No namespace available.\n" + +#ifndef VERSION +#define VERSION "1" +#endif int iport = 8080; int oport = 8081; size_t max_clients = 15; -size_t max_size = 500; +size_t max_size = 1; +size_t buf_size = 32000; size_t name_len = 15; -char *dir = "."; +char *dir = "."; char *prog_name; +char *motd; + int ifd; size_t ifd_clients; @@ -93,7 +99,7 @@ char *rand_string(void) { } char *rand_name(void) { - while (1) { + for (int i = 0; i < 10; i++) { char *filename = rand_string(); if (filename == NULL) continue; @@ -104,6 +110,8 @@ char *rand_name(void) { free(filename); } + + return NULL; } int send_str(int fd, char *str, ssize_t size, int flag) { @@ -131,8 +139,15 @@ int send_str(int fd, char *str, ssize_t size, int flag) { void upload(int cfd, pid_t par) { int ret = -1; 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; + } + if (send(cfd, filename, strlen(filename), 0) < 0) goto UPL_ERROR; @@ -143,11 +158,14 @@ void upload(int cfd, pid_t par) { if (ffd < 0) goto UPL_ERROR; - char buf[BUFLEN + 1]; + /* Sending */ + buf = malloc(buf_size + 1); + if (buf == NULL) + goto UPL_ERROR; size_t tbytes = 0; while (1) { - ssize_t rbytes = recv(cfd, buf, sizeof(buf), 0); + ssize_t rbytes = recv(cfd, buf, buf_size, 0); if (rbytes < 0 && (errno != EAGAIN || errno != EINTR)) goto UPL_ERROR; @@ -166,16 +184,19 @@ void upload(int cfd, pid_t par) { ret = 0; + /* Clear */ UPL_ERROR: + if (buf != NULL) + free(buf); + if (ffd != -1) close(ffd); - send_str(cfd, MSG3, sizeof(MSG3), WRITE); - close(cfd); if (ret == -1) fprintf(stderr, "%s: input thread: %s: %s\n", prog_name, filename, strerror(errno)); - free(filename); + + close(cfd); kill(par, SIGUSR1); exit(0); } @@ -183,6 +204,7 @@ UPL_ERROR: void load(int cfd, pid_t par) { int ret = -1; int ffd = -1; + char *buf = NULL; /* Get filename */ char *filename = malloc(name_len + 1); @@ -207,8 +229,8 @@ void load(int cfd, pid_t par) { /* INFO */ if (!strcmp(filename, "INFO")) { - char msg[64]; - int ret2 = snprintf(msg, sizeof(msg), "Max file size: %zuMB\nMax clients in thread: %zu\n", max_size, max_clients); + char msg[336]; + int ret2 = snprintf(msg, sizeof(msg), "Max file size: %zuMB\nMax clients in thread: %zu\nBuffer size: %zu\nMOTD: %s\n", max_size, max_clients, buf_size, (motd) ? motd : ""); if (send_str(cfd, msg, (ssize_t)ret2, SEND)) goto LD_ERROR; @@ -217,16 +239,20 @@ void load(int cfd, pid_t par) { goto LD_ERROR; } - /* Open and send */ + /* Open */ ffd = open(filename, O_RDONLY); if (ffd < 0) { - send_str(cfd, MSG4, sizeof(MSG4), SEND); + send_str(cfd, MSG3, sizeof(MSG3), SEND); goto LD_ERROR; } - char buf[BUFLEN + 1]; + /* Sending */ + buf = malloc(buf_size + 1); + if (buf == NULL) + goto LD_ERROR; + while (1) { - rbytes = read(ffd, buf, sizeof(buf)); + rbytes = read(ffd, buf, buf_size); if (rbytes < 0 && (errno != EAGAIN || errno != EINTR)) goto LD_ERROR; @@ -239,16 +265,20 @@ void load(int cfd, pid_t par) { ret = 0; + /* Clear */ LD_ERROR: + if (buf != NULL) + free(buf); + if (ffd != -1) close(ffd); - sleep(1); - close(cfd); if (ret == -1) fprintf(stderr, "%s: output thread: %s: %s\n", prog_name, filename, strerror(errno)); - free(filename); + + sleep(1); + close(cfd); kill(par, SIGUSR2); exit(0); } @@ -315,7 +345,7 @@ int main(int argc, char **argv) { signal(SIGCHLD, SIG_IGN); int opt; - while ((opt = getopt(argc, argv, "i:o:m:d:s:n:")) != -1) { + while ((opt = getopt(argc, argv, "i:o:m:d:s:n:b:t:V")) != -1) { switch (opt) { case 'i': iport = atoi(optarg); @@ -341,8 +371,25 @@ int main(int argc, char **argv) { sscanf(optarg, "%zu", &name_len); break; + case 'b': + sscanf(optarg, "%zu", &buf_size); + break; + + case 't': + if (strlen(optarg) > 256) { + fprintf(stderr, "%s: MOTD very long\n", prog_name); + return 1; + } + + motd = optarg; + break; + + case 'V': + puts("Version: " VERSION "\nWritten under WTFPL License."); + return 0; + default: - printf("%s [iomds] - Simple file sharing server\n\t-i NUM Input port\tdefault: %d\n\t-o NUM Output port\tdefault: %d\n\t-m NUM Max clients\tdefault: %zu\n\t-d DIR Word directory\tdefault: %s\n\t-s NUM Max file size\tdefault: %zuMB\n\t-n NUM Filename length\tdefault: %zu\n", prog_name, iport, oport, max_clients, dir, max_size, name_len); + printf("%s [iomdsnbtV] - Simple file sharing server\n\t-i NUM Input port\tdefault: %d\n\t-o NUM Output port\tdefault: %d\n\t-m NUM Max clients\tdefault: %zu\n\t-d DIR Word directory\tdefault: %s\n\t-s NUM Max file size\tdefault: %zuMB\n\t-n NUM Filename length\tdefault: %zu\n\t-b NUM Buffer size\tdefault: %zuB\n\t-t STR Set MOTD\n\t-V Print version and license\n", prog_name, iport, oport, max_clients, dir, max_size, name_len, buf_size); return 0; } }