This commit is contained in:
Your Name 2024-07-01 01:04:57 +03:00
parent fb64e2bbdd
commit f207924062

View File

@ -14,20 +14,26 @@
#define SEND_TIMEOUT 1 #define SEND_TIMEOUT 1
#define RECV_TIMEOUT 2 #define RECV_TIMEOUT 2
#define BUFLEN 1024 * 1024 #define MSG1 "Server is very busy.\n"
#define MSG1 "Server very loaded.\n" #define MSG2 "The file is very large.\n"
#define MSG2 "File very big.\n" #define MSG3 "No such file.\n"
#define MSG3 "Closing connection.\n" #define MSG4 "No namespace available.\n"
#define MSG4 "No such file.\n"
#ifndef VERSION
#define VERSION "1"
#endif
int iport = 8080; int iport = 8080;
int oport = 8081; int oport = 8081;
size_t max_clients = 15; 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; size_t name_len = 15;
char *dir = ".";
char *dir = ".";
char *prog_name; char *prog_name;
char *motd;
int ifd; int ifd;
size_t ifd_clients; size_t ifd_clients;
@ -93,7 +99,7 @@ char *rand_string(void) {
} }
char *rand_name(void) { char *rand_name(void) {
while (1) { for (int i = 0; i < 10; i++) {
char *filename = rand_string(); char *filename = rand_string();
if (filename == NULL) if (filename == NULL)
continue; continue;
@ -104,6 +110,8 @@ char *rand_name(void) {
free(filename); free(filename);
} }
return NULL;
} }
int send_str(int fd, char *str, ssize_t size, int flag) { 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) { void upload(int cfd, pid_t par) {
int ret = -1; int ret = -1;
int ffd = -1; int ffd = -1;
char *buf = NULL;
/* Send and create filename */
char *filename = rand_name(); char *filename = rand_name();
if (filename == NULL) {
send(cfd, MSG4, sizeof(MSG4), 0);
goto UPL_ERROR;
}
if (send(cfd, filename, strlen(filename), 0) < 0) if (send(cfd, filename, strlen(filename), 0) < 0)
goto UPL_ERROR; goto UPL_ERROR;
@ -143,11 +158,14 @@ void upload(int cfd, pid_t par) {
if (ffd < 0) if (ffd < 0)
goto UPL_ERROR; goto UPL_ERROR;
char buf[BUFLEN + 1]; /* Sending */
buf = malloc(buf_size + 1);
if (buf == NULL)
goto UPL_ERROR;
size_t tbytes = 0; size_t tbytes = 0;
while (1) { 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)) if (rbytes < 0 && (errno != EAGAIN || errno != EINTR))
goto UPL_ERROR; goto UPL_ERROR;
@ -166,16 +184,19 @@ void upload(int cfd, pid_t par) {
ret = 0; ret = 0;
/* Clear */
UPL_ERROR: UPL_ERROR:
if (buf != NULL)
free(buf);
if (ffd != -1) if (ffd != -1)
close(ffd); close(ffd);
send_str(cfd, MSG3, sizeof(MSG3), WRITE);
close(cfd);
if (ret == -1) if (ret == -1)
fprintf(stderr, "%s: input thread: %s: %s\n", prog_name, filename, strerror(errno)); fprintf(stderr, "%s: input thread: %s: %s\n", prog_name, filename, strerror(errno));
free(filename); free(filename);
close(cfd);
kill(par, SIGUSR1); kill(par, SIGUSR1);
exit(0); exit(0);
} }
@ -183,6 +204,7 @@ UPL_ERROR:
void load(int cfd, pid_t par) { void load(int cfd, pid_t par) {
int ret = -1; int ret = -1;
int ffd = -1; int ffd = -1;
char *buf = NULL;
/* Get filename */ /* Get filename */
char *filename = malloc(name_len + 1); char *filename = malloc(name_len + 1);
@ -207,8 +229,8 @@ void load(int cfd, pid_t par) {
/* INFO */ /* INFO */
if (!strcmp(filename, "INFO")) { if (!strcmp(filename, "INFO")) {
char msg[64]; char msg[336];
int ret2 = snprintf(msg, sizeof(msg), "Max file size: %zuMB\nMax clients in thread: %zu\n", max_size, max_clients); 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)) if (send_str(cfd, msg, (ssize_t)ret2, SEND))
goto LD_ERROR; goto LD_ERROR;
@ -217,16 +239,20 @@ void load(int cfd, pid_t par) {
goto LD_ERROR; goto LD_ERROR;
} }
/* Open and send */ /* Open */
ffd = open(filename, O_RDONLY); ffd = open(filename, O_RDONLY);
if (ffd < 0) { if (ffd < 0) {
send_str(cfd, MSG4, sizeof(MSG4), SEND); send_str(cfd, MSG3, sizeof(MSG3), SEND);
goto LD_ERROR; goto LD_ERROR;
} }
char buf[BUFLEN + 1]; /* Sending */
buf = malloc(buf_size + 1);
if (buf == NULL)
goto LD_ERROR;
while (1) { while (1) {
rbytes = read(ffd, buf, sizeof(buf)); rbytes = read(ffd, buf, buf_size);
if (rbytes < 0 && (errno != EAGAIN || errno != EINTR)) if (rbytes < 0 && (errno != EAGAIN || errno != EINTR))
goto LD_ERROR; goto LD_ERROR;
@ -239,16 +265,20 @@ void load(int cfd, pid_t par) {
ret = 0; ret = 0;
/* Clear */
LD_ERROR: LD_ERROR:
if (buf != NULL)
free(buf);
if (ffd != -1) if (ffd != -1)
close(ffd); close(ffd);
sleep(1);
close(cfd);
if (ret == -1) if (ret == -1)
fprintf(stderr, "%s: output thread: %s: %s\n", prog_name, filename, strerror(errno)); fprintf(stderr, "%s: output thread: %s: %s\n", prog_name, filename, strerror(errno));
free(filename); free(filename);
sleep(1);
close(cfd);
kill(par, SIGUSR2); kill(par, SIGUSR2);
exit(0); exit(0);
} }
@ -315,7 +345,7 @@ int main(int argc, char **argv) {
signal(SIGCHLD, SIG_IGN); signal(SIGCHLD, SIG_IGN);
int opt; 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) { switch (opt) {
case 'i': case 'i':
iport = atoi(optarg); iport = atoi(optarg);
@ -341,8 +371,25 @@ int main(int argc, char **argv) {
sscanf(optarg, "%zu", &name_len); sscanf(optarg, "%zu", &name_len);
break; 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: 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; return 0;
} }
} }