diff --git a/ftp/Makefile b/ftp/Makefile index 99ac4ca8..4702696a 100644 --- a/ftp/Makefile +++ b/ftp/Makefile @@ -34,15 +34,21 @@ SERVER_OBJ = $(OBJ_DIR)server.o CLIENT_OBJ = $(OBJ_DIR)client.o $(OBJ_DIR)cli_do_help.o SRC_BASE = \ -cli_do_debug.c\ -cli_do_get.c\ -cli_do_help.c\ -cli_do_local.c\ -cli_output.c\ client.c\ +cli_do_sh.c\ +cli_do_cd.c\ +cli_do_get.c\ +cli_do_put.c\ +cli_do_help.c\ +cli_do_debug.c\ +cli_do_local.c\ +read_req.c\ console_msg.c\ req_init.c\ serv_do_get.c\ +serv_do_put.c\ +serv_do_sh.c\ +serv_do_cd.c\ server.c SRCS = $(addprefix $(SRC_DIR), $(SRC_BASE)) diff --git a/ftp/includes/ft_p.h b/ftp/includes/ft_p.h index 58f06fae..a1441292 100644 --- a/ftp/includes/ft_p.h +++ b/ftp/includes/ft_p.h @@ -17,10 +17,10 @@ # define FTP_CLIENT_USAGE "%s " # define MAXLINE 256 -# define MAXSIZE 512 # include "libft.h" # include +# include # include # include @@ -38,6 +38,9 @@ struct s_cmd_map enum e_ftp { REQUEST_FILE = 100, + REQUEST_PUT, + REQUEST_SH, + REQUEST_CD, CMD_NOT_SUPPORTED = 150, CMD_SUPPORTED = 160, FILENAME_OK = 700, @@ -47,6 +50,8 @@ enum e_ftp ERR_READ, ERR_STAT, ERR_MMAP, + CMD_SUCCESS = 900, + CMD_FAIL, }; extern char **g_av; @@ -58,15 +63,23 @@ int ftp_spawn(int sock); int ftp_cmd(int sock, int req); int serv_do_get(int sock); +int serv_do_put(int sock); +int serv_do_sh(int sock); +int serv_do_cd(int sock); -int console_msg(int level, char *str, ...); +int read_req(int sock); t_cmd_map *get_cmd(char *cmd); -int cli_output(int req, char *name, char *msg); +int console_msg(int level, char *str, ...); + +int cli_do_sh(int sock, char **av); +int cli_do_get(int sock, char **av); +int cli_do_put(int sock, char **av); +int cli_do_cd(int sock, char **av); + int cli_do_help(int sock, char **av); int cli_do_debug(int sock, char **av); -int cli_do_get(int sock, char **av); int cli_do_local(int sock, char **av); -int req_init(int sock, int req, char *name); +int req_init(int sock, int req); #endif diff --git a/ftp/libft b/ftp/libft index 9f7aef26..eef212b3 160000 --- a/ftp/libft +++ b/ftp/libft @@ -1 +1 @@ -Subproject commit 9f7aef265fee9fac8318cc7e23ef6b9411c1af45 +Subproject commit eef212b3f00ca01d912f1aeff26726c0d98bdbe8 diff --git a/ftp/srcs/cli_do_cd.c b/ftp/srcs/cli_do_cd.c new file mode 100644 index 00000000..b448b166 --- /dev/null +++ b/ftp/srcs/cli_do_cd.c @@ -0,0 +1,11 @@ +#include "ft_p.h" + +int cli_do_cd(int sock, char **av) +{ + if (!av[1] || av[2]) + return (console_msg(-1, "usage: cd ")); + if (req_init(sock, REQUEST_CD)) + return (1); + write(sock, av[1], ft_strlen(av[1])); + return (0); +} diff --git a/ftp/srcs/cli_do_debug.c b/ftp/srcs/cli_do_debug.c index e739d531..2bc66692 100644 --- a/ftp/srcs/cli_do_debug.c +++ b/ftp/srcs/cli_do_debug.c @@ -18,9 +18,9 @@ int cli_do_debug(int sock, char **av) else { console_msg(-1, "%s: bad debugging value", av[1]); - return (1); + return (-1); } console_msg(0, "Debugging %s (g_debug = %i)", g_debug ? "on" : "off", g_debug); - return (0); + return (-1); } diff --git a/ftp/srcs/cli_do_get.c b/ftp/srcs/cli_do_get.c index 88890254..c5557226 100644 --- a/ftp/srcs/cli_do_get.c +++ b/ftp/srcs/cli_do_get.c @@ -3,42 +3,29 @@ int cli_do_get(int sock, char **av) { int rep; - int num_blks; - int num_last_blk; - int i; int fd; - (void)av; if (!av[1] || av[2]) return (console_msg(-1, "usage: get ")); - if (req_init(sock, REQUEST_FILE, "PORT")) + if (req_init(sock, REQUEST_FILE)) return (1); write(sock, av[1], ft_strlen(av[1])); - read(sock, (char*)&rep, sizeof(rep)); - if (ntohs(rep) != FILENAME_OK) - { - cli_output(REQUEST_FILE, "PORT", "no such file"); + + rep = read_req(sock); + if (rep != FILENAME_OK) return (1); - } + rep = htons(TRANSFER_START); if ((fd = open_new(av[1], O_WRONLY | O_TRUNC | O_APPEND)) < 0) rep = htons(ABORT); write(sock, (char*)&rep, sizeof(rep)); + if (rep != htons(TRANSFER_START)) return (1); - net_get(sock, (char*)&num_blks, sizeof(num_blks)); - net_get(sock, (char*)&num_last_blk, sizeof(num_last_blk)); - num_blks = ntohs(num_blks); - num_last_blk = ntohs(num_last_blk); - if (g_debug > 3) - { - console_msg(3, "received num_blks=[%i]", num_blks); - console_msg(3, "received num_last_blk=[%i]", num_last_blk); - } - i = -1; - while (++i < num_blks - 1) - net_get_fd(sock, fd, MAXSIZE); - if (num_last_blk) - net_get_fd(sock, fd, num_last_blk); + + console_msg(1, "TRANSFER_START"); + net_get_large(sock, fd); + console_msg(1, "TRANSFER DONE"); + return (0); } diff --git a/ftp/srcs/cli_do_help.c b/ftp/srcs/cli_do_help.c index cc3f6ed5..b920cd74 100644 --- a/ftp/srcs/cli_do_help.c +++ b/ftp/srcs/cli_do_help.c @@ -22,5 +22,5 @@ int cli_do_help(int sock, char **av) while (g_cli_cmd[++i].key) console_msg(0, "%s\t%s", g_cli_cmd[i].key, g_cli_cmd[i].help); } - return (0); + return (-1); } diff --git a/ftp/srcs/cli_do_local.c b/ftp/srcs/cli_do_local.c index 699ba9f1..8de8dbef 100644 --- a/ftp/srcs/cli_do_local.c +++ b/ftp/srcs/cli_do_local.c @@ -4,25 +4,10 @@ char **environ; int cli_do_local(int sock, char **av) { - pid_t pid; - char *cmd[4]; + char *command; (void)sock; - av++; - if ((pid = fork()) < 0) - return (1); - if (pid == 0) - { - cmd[0] = "/bin/sh"; - cmd[1] = "-c"; - cmd[2] = ft_sstrcat(av, ' '); - cmd[3] = NULL; - console_msg(3, "inside pid cmd=[%s]", cmd[2]); - execve(cmd[0], cmd, environ); - console_msg(3, "execve(2) error: %s", strerror(errno)); - exit(42); - } - console_msg(3, "waiting for local command"); - waitpid(pid, NULL, 0); - return (0); + command = ft_strsepjoin(av + 1, ' '); + system(command); + return (-1); } diff --git a/ftp/srcs/cli_do_put.c b/ftp/srcs/cli_do_put.c new file mode 100644 index 00000000..65f2ac3e --- /dev/null +++ b/ftp/srcs/cli_do_put.c @@ -0,0 +1,31 @@ +#include "ft_p.h" + +int cli_do_put(int sock, char **av) +{ + int req; + int fd; + struct stat stat; + char *file; + + if (!av[1] || av[2]) + return (console_msg(-1, "usage: put ")); + else if ((fd = open(av[1], O_RDONLY)) < 0) + return (console_msg(-1, "no such file")); + else if ((fstat(fd, &stat)) < 0) + return (console_msg(-1, "fstat error")); + else if ((file = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) + == MAP_FAILED) + return (console_msg(-1, "mmap error")); + + if (req_init(sock, REQUEST_PUT)) + return (1); + + write(sock, av[1], ft_strlen(av[1])); + + req = read_req(sock); + if (req != TRANSFER_START) + return (1); + + net_send_large(sock, file, stat.st_size); + return (0); +} diff --git a/ftp/srcs/cli_do_sh.c b/ftp/srcs/cli_do_sh.c new file mode 100644 index 00000000..10b72d89 --- /dev/null +++ b/ftp/srcs/cli_do_sh.c @@ -0,0 +1,26 @@ +#include "ft_p.h" + +int cli_do_sh(int sock, char **av) +{ + char *command; + char buf[MAXLINE]; + int ret; + + command = ft_strsepjoin(av, ' '); + + if (req_init(sock, REQUEST_SH)) + return (1); + + console_msg(1, "sending '%s' to server", command); + write(sock, command, ft_strlen(command)); + + while ((ret = read(sock, &buf, MAXLINE))) + { + buf[ret] = 0; + ft_printf("%s", buf); + if (ret < MAXLINE) + break ; + } + ft_strdel(&command); + return (0); +} diff --git a/ftp/srcs/cli_output.c b/ftp/srcs/cli_output.c index 35d29caf..2d780ad4 100644 --- a/ftp/srcs/cli_output.c +++ b/ftp/srcs/cli_output.c @@ -1,7 +1,11 @@ #include "ft_p.h" -int cli_output(int req, char *name, char *msg) +int read_req() { - ft_printf("%i %s %s\n", req, name, msg); - return (0); + int req; + + if (read(sock, (char*)&req, sizeof(req)) < 0) + return(1); + console_msg(0, "%i RECEIVED", req); + return (req); } diff --git a/ftp/srcs/client.c b/ftp/srcs/client.c index ec59b314..ae8f9230 100644 --- a/ftp/srcs/client.c +++ b/ftp/srcs/client.c @@ -17,11 +17,16 @@ int g_debug = 0; int g_debug; t_cmd_map g_cli_cmd[] = { + {"ls", cli_do_sh, "list contents of remote directory"}, + {"cd", cli_do_cd, "change remote working directory"}, + {"get", cli_do_get, "receive file"}, + {"put", cli_do_put, "send one file"}, + {"pwd", cli_do_sh, "print working directory on remote machine"}, + {"quit", NULL, "terminate ftp session and exit"}, + {"?", cli_do_help, "print local help information"}, {"l", cli_do_local, "execute a local command"}, {"debug", cli_do_debug, "toggle/set debugging mode"}, - {"get", cli_do_get, "receive file"}, - {"quit", NULL, "terminate ftp session and exit"}, {0, 0, 0}, }; @@ -54,7 +59,10 @@ int do_client(int sock) if (!(cmd = get_cmd(av[0]))) console_msg(-1, "?Invalid command"); else if (cmd->f) - (cmd->f)(sock, av); + { + if ((cmd->f)(sock, av) >= 0) + read_req(sock); + } else return (0); ft_sstrfree(av); diff --git a/ftp/srcs/read_req.c b/ftp/srcs/read_req.c new file mode 100644 index 00000000..971450ae --- /dev/null +++ b/ftp/srcs/read_req.c @@ -0,0 +1,12 @@ +#include "ft_p.h" + +int read_req(int sock) +{ + int req; + + if (read(sock, (char*)&req, sizeof(req)) < 0) + return(0); + req = ntohs(req); + console_msg(0, "%i RECEIVED", req); + return (req); +} diff --git a/ftp/srcs/req_init.c b/ftp/srcs/req_init.c index f2494583..e2a62db6 100644 --- a/ftp/srcs/req_init.c +++ b/ftp/srcs/req_init.c @@ -1,19 +1,13 @@ #include "ft_p.h" -int req_init(int sock, int req, char *name) +int req_init(int sock, int req) { int rep; int net_req; net_req = htons(req); + tcflush(sock, TCIFLUSH); write(sock, (char*)&net_req, sizeof(net_req)); - read(sock, (char*)&rep, sizeof(rep)); - rep = ntohs(rep); - if (rep == CMD_SUPPORTED) - cli_output(req, name, "command succesful"); - else if (rep == CMD_NOT_SUPPORTED) - cli_output(req, name, "command not supported"); - else - cli_output(req, name, "unexpected response"); - return (rep == CMD_SUPPORTED ? 0 : 1); + rep = read_req(sock); + return (rep != CMD_SUPPORTED); } diff --git a/ftp/srcs/serv_do_cd.c b/ftp/srcs/serv_do_cd.c new file mode 100644 index 00000000..0f8e98b7 --- /dev/null +++ b/ftp/srcs/serv_do_cd.c @@ -0,0 +1,17 @@ +#include "ft_p.h" + +int serv_do_cd(int sock) +{ + char *oldpwd; + char path[MAXLINE]; + int ret; + + if ((ret = read(sock, path, MAXLINE)) < 0) + return (CMD_FAIL); + + DG("received 'cd %s' command", path); + + oldpwd = getcwd(NULL, 0); + (void)oldpwd; + return(chdir(path) ? CMD_FAIL : CMD_SUCCESS); +} diff --git a/ftp/srcs/serv_do_get.c b/ftp/srcs/serv_do_get.c index af9ebcc8..7d589691 100644 --- a/ftp/srcs/serv_do_get.c +++ b/ftp/srcs/serv_do_get.c @@ -8,11 +8,7 @@ int serv_do_get(int sock) int fd; struct stat stat; char *file; - int num_blks; - int num_last_blk; - int i; - DG("%i file requested", REQUEST_FILE); ft_bzero(&fname, MAXLINE); rep = htons(FILENAME_OK); file = NULL; @@ -28,29 +24,16 @@ int serv_do_get(int sock) write(sock, (char*)&rep, sizeof(rep)); if (ntohs(rep) != FILENAME_OK) - return (1); - if (read(sock, (char*)&req, sizeof(req)) < 0) - rep = htons(ERR_READ); - DG("start transfer command, %d, received", ntohs(req)); + return (CMD_FAIL); - num_blks = htons(stat.st_size / MAXSIZE + 1); - num_last_blk = htons(stat.st_size % MAXSIZE); - DG("telling client file has [%i] blocks", ntohs(num_blks)); - if (net_send(sock, (char*)&num_blks, sizeof(num_blks))) - DG("ACK not received on num_blks"); - DG("telling client last block has [%i] bytes", ntohs(num_last_blk)); - if (net_send(sock, (char*)&num_last_blk, sizeof(num_blks))) - DG("ACK not received on size of last block"); + DG("GOING TO READ_REQ"); + req = read_req(sock); + if (req != TRANSFER_START) + return (CMD_FAIL); - num_blks = ntohs(num_blks); - num_last_blk = ntohs(num_last_blk); - i = -1; - while (++i < num_blks - 1) - net_send(sock, file + i * MAXSIZE, MAXSIZE); - if (num_last_blk) - net_send(sock, file + i * MAXSIZE, MAXSIZE); + net_send_large(sock, file, stat.st_size); if (file && munmap(file, stat.st_size) < 0) rep = htons(ERR_MMAP); - return (0); + return (CMD_SUCCESS); } diff --git a/ftp/srcs/serv_do_put.c b/ftp/srcs/serv_do_put.c new file mode 100644 index 00000000..ae941221 --- /dev/null +++ b/ftp/srcs/serv_do_put.c @@ -0,0 +1,23 @@ +#include "ft_p.h" + +int serv_do_put(int sock) +{ + char fname[MAXLINE]; + int rep; + int fd; + + ft_bzero(&fname, MAXLINE); + + rep = htons(TRANSFER_START); + if (read(sock, fname, MAXLINE) < 0) + rep = htons(ABORT); + else if ((fd = open_new(fname, O_WRONLY | O_TRUNC | O_APPEND)) < 0) + rep = htons(ABORT); + + write(sock, (char*)&rep, sizeof(rep)); + if (rep != htons(TRANSFER_START)) + return (CMD_FAIL); + + net_get_large(sock, fd); + return (CMD_SUCCESS); +} diff --git a/ftp/srcs/serv_do_sh.c b/ftp/srcs/serv_do_sh.c new file mode 100644 index 00000000..c7dfafb9 --- /dev/null +++ b/ftp/srcs/serv_do_sh.c @@ -0,0 +1,23 @@ +#include "ft_p.h" + +int serv_do_sh(int sock) +{ + char command[MAXLINE]; + int ret; + + if ((ret = read(sock, command, MAXLINE)) < 0) + return (CMD_FAIL); + command[ret] = 0; + DG("received '%s' command", command); + if (fork() == 0) + { + dup2(sock, 1); + system(command); + exit(0); + } + DG("waiting for command"); + wait(0); + DG("finished waiting for command"); + return (CMD_SUCCESS); +} + diff --git a/ftp/srcs/server.c b/ftp/srcs/server.c index be3d790e..6027a47c 100644 --- a/ftp/srcs/server.c +++ b/ftp/srcs/server.c @@ -18,6 +18,9 @@ char **g_av = NULL; t_itof g_ftp_cmd[] = { {REQUEST_FILE, serv_do_get}, + {REQUEST_PUT, serv_do_put}, + {REQUEST_SH, serv_do_sh}, + {REQUEST_CD, serv_do_cd}, {0, 0}, }; @@ -34,8 +37,10 @@ int ftp_cmd(int sock, int req) { if (!(g_ftp_cmd[i].f)) break ; + DG("%i CMD_SUPPORTED", CMD_SUPPORTED); + write(sock, (char *)&msg_ok, sizeof(msg_ok)); + msg_ok = ntohs((g_ftp_cmd[i].f)(sock)); write(sock, (char *)&msg_ok, sizeof(msg_ok)); - (g_ftp_cmd[i].f)(sock); return (0); } } @@ -47,14 +52,13 @@ int ftp_cmd(int sock, int req) int ftp_spawn(int sock) { int req; - int r; DG("new connection"); - while ((r = read(sock, (char*)&req, sizeof(req))) > 0) + while ((req = read_req(sock))) { - req = ntohs(req); - DG("request code [%i]", req); + DG("==== %i NEW REQUEST ====", req); ftp_cmd(sock, req); + DG("==== DONE ===="); } DG("end of connection"); close(sock);