some progress

This commit is contained in:
Jack Halford 2017-07-25 18:20:34 +02:00
parent 8f3da61851
commit 99972b4f8e
19 changed files with 229 additions and 102 deletions

View file

@ -34,15 +34,21 @@ SERVER_OBJ = $(OBJ_DIR)server.o
CLIENT_OBJ = $(OBJ_DIR)client.o $(OBJ_DIR)cli_do_help.o CLIENT_OBJ = $(OBJ_DIR)client.o $(OBJ_DIR)cli_do_help.o
SRC_BASE = \ SRC_BASE = \
cli_do_debug.c\
cli_do_get.c\
cli_do_help.c\
cli_do_local.c\
cli_output.c\
client.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\ console_msg.c\
req_init.c\ req_init.c\
serv_do_get.c\ serv_do_get.c\
serv_do_put.c\
serv_do_sh.c\
serv_do_cd.c\
server.c server.c
SRCS = $(addprefix $(SRC_DIR), $(SRC_BASE)) SRCS = $(addprefix $(SRC_DIR), $(SRC_BASE))

View file

@ -17,10 +17,10 @@
# define FTP_CLIENT_USAGE "%s <addr> <port>" # define FTP_CLIENT_USAGE "%s <addr> <port>"
# define MAXLINE 256 # define MAXLINE 256
# define MAXSIZE 512
# include "libft.h" # include "libft.h"
# include <stdio.h> # include <stdio.h>
# include <termios.h>
# include <readline/readline.h> # include <readline/readline.h>
# include <sys/mman.h> # include <sys/mman.h>
@ -38,6 +38,9 @@ struct s_cmd_map
enum e_ftp enum e_ftp
{ {
REQUEST_FILE = 100, REQUEST_FILE = 100,
REQUEST_PUT,
REQUEST_SH,
REQUEST_CD,
CMD_NOT_SUPPORTED = 150, CMD_NOT_SUPPORTED = 150,
CMD_SUPPORTED = 160, CMD_SUPPORTED = 160,
FILENAME_OK = 700, FILENAME_OK = 700,
@ -47,6 +50,8 @@ enum e_ftp
ERR_READ, ERR_READ,
ERR_STAT, ERR_STAT,
ERR_MMAP, ERR_MMAP,
CMD_SUCCESS = 900,
CMD_FAIL,
}; };
extern char **g_av; extern char **g_av;
@ -58,15 +63,23 @@ int ftp_spawn(int sock);
int ftp_cmd(int sock, int req); int ftp_cmd(int sock, int req);
int serv_do_get(int sock); 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); 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_help(int sock, char **av);
int cli_do_debug(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 cli_do_local(int sock, char **av);
int req_init(int sock, int req, char *name); int req_init(int sock, int req);
#endif #endif

@ -1 +1 @@
Subproject commit 9f7aef265fee9fac8318cc7e23ef6b9411c1af45 Subproject commit eef212b3f00ca01d912f1aeff26726c0d98bdbe8

11
ftp/srcs/cli_do_cd.c Normal file
View file

@ -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 <path>"));
if (req_init(sock, REQUEST_CD))
return (1);
write(sock, av[1], ft_strlen(av[1]));
return (0);
}

View file

@ -18,9 +18,9 @@ int cli_do_debug(int sock, char **av)
else else
{ {
console_msg(-1, "%s: bad debugging value", av[1]); console_msg(-1, "%s: bad debugging value", av[1]);
return (1); return (-1);
} }
console_msg(0, "Debugging %s (g_debug = %i)", console_msg(0, "Debugging %s (g_debug = %i)",
g_debug ? "on" : "off", g_debug); g_debug ? "on" : "off", g_debug);
return (0); return (-1);
} }

View file

@ -3,42 +3,29 @@
int cli_do_get(int sock, char **av) int cli_do_get(int sock, char **av)
{ {
int rep; int rep;
int num_blks;
int num_last_blk;
int i;
int fd; int fd;
(void)av;
if (!av[1] || av[2]) if (!av[1] || av[2])
return (console_msg(-1, "usage: get <file>")); return (console_msg(-1, "usage: get <file>"));
if (req_init(sock, REQUEST_FILE, "PORT")) if (req_init(sock, REQUEST_FILE))
return (1); return (1);
write(sock, av[1], ft_strlen(av[1])); write(sock, av[1], ft_strlen(av[1]));
read(sock, (char*)&rep, sizeof(rep));
if (ntohs(rep) != FILENAME_OK) rep = read_req(sock);
{ if (rep != FILENAME_OK)
cli_output(REQUEST_FILE, "PORT", "no such file");
return (1); return (1);
}
rep = htons(TRANSFER_START); rep = htons(TRANSFER_START);
if ((fd = open_new(av[1], O_WRONLY | O_TRUNC | O_APPEND)) < 0) if ((fd = open_new(av[1], O_WRONLY | O_TRUNC | O_APPEND)) < 0)
rep = htons(ABORT); rep = htons(ABORT);
write(sock, (char*)&rep, sizeof(rep)); write(sock, (char*)&rep, sizeof(rep));
if (rep != htons(TRANSFER_START)) if (rep != htons(TRANSFER_START))
return (1); return (1);
net_get(sock, (char*)&num_blks, sizeof(num_blks));
net_get(sock, (char*)&num_last_blk, sizeof(num_last_blk)); console_msg(1, "TRANSFER_START");
num_blks = ntohs(num_blks); net_get_large(sock, fd);
num_last_blk = ntohs(num_last_blk); console_msg(1, "TRANSFER DONE");
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);
return (0); return (0);
} }

View file

@ -22,5 +22,5 @@ int cli_do_help(int sock, char **av)
while (g_cli_cmd[++i].key) while (g_cli_cmd[++i].key)
console_msg(0, "%s\t%s", g_cli_cmd[i].key, g_cli_cmd[i].help); console_msg(0, "%s\t%s", g_cli_cmd[i].key, g_cli_cmd[i].help);
} }
return (0); return (-1);
} }

View file

@ -4,25 +4,10 @@ char **environ;
int cli_do_local(int sock, char **av) int cli_do_local(int sock, char **av)
{ {
pid_t pid; char *command;
char *cmd[4];
(void)sock; (void)sock;
av++; command = ft_strsepjoin(av + 1, ' ');
if ((pid = fork()) < 0) system(command);
return (1); 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);
} }

31
ftp/srcs/cli_do_put.c Normal file
View file

@ -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 <file>"));
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);
}

26
ftp/srcs/cli_do_sh.c Normal file
View file

@ -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);
}

View file

@ -1,7 +1,11 @@
#include "ft_p.h" #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); int req;
return (0);
if (read(sock, (char*)&req, sizeof(req)) < 0)
return(1);
console_msg(0, "%i RECEIVED", req);
return (req);
} }

View file

@ -17,11 +17,16 @@ int g_debug = 0;
int g_debug; int g_debug;
t_cmd_map g_cli_cmd[] = 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"}, {"?", cli_do_help, "print local help information"},
{"l", cli_do_local, "execute a local command"}, {"l", cli_do_local, "execute a local command"},
{"debug", cli_do_debug, "toggle/set debugging mode"}, {"debug", cli_do_debug, "toggle/set debugging mode"},
{"get", cli_do_get, "receive file"},
{"quit", NULL, "terminate ftp session and exit"},
{0, 0, 0}, {0, 0, 0},
}; };
@ -54,7 +59,10 @@ int do_client(int sock)
if (!(cmd = get_cmd(av[0]))) if (!(cmd = get_cmd(av[0])))
console_msg(-1, "?Invalid command"); console_msg(-1, "?Invalid command");
else if (cmd->f) else if (cmd->f)
(cmd->f)(sock, av); {
if ((cmd->f)(sock, av) >= 0)
read_req(sock);
}
else else
return (0); return (0);
ft_sstrfree(av); ft_sstrfree(av);

12
ftp/srcs/read_req.c Normal file
View file

@ -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);
}

View file

@ -1,19 +1,13 @@
#include "ft_p.h" #include "ft_p.h"
int req_init(int sock, int req, char *name) int req_init(int sock, int req)
{ {
int rep; int rep;
int net_req; int net_req;
net_req = htons(req); net_req = htons(req);
tcflush(sock, TCIFLUSH);
write(sock, (char*)&net_req, sizeof(net_req)); write(sock, (char*)&net_req, sizeof(net_req));
read(sock, (char*)&rep, sizeof(rep)); rep = read_req(sock);
rep = ntohs(rep); return (rep != CMD_SUPPORTED);
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);
} }

17
ftp/srcs/serv_do_cd.c Normal file
View file

@ -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);
}

View file

@ -8,11 +8,7 @@ int serv_do_get(int sock)
int fd; int fd;
struct stat stat; struct stat stat;
char *file; char *file;
int num_blks;
int num_last_blk;
int i;
DG("%i file requested", REQUEST_FILE);
ft_bzero(&fname, MAXLINE); ft_bzero(&fname, MAXLINE);
rep = htons(FILENAME_OK); rep = htons(FILENAME_OK);
file = NULL; file = NULL;
@ -28,29 +24,16 @@ int serv_do_get(int sock)
write(sock, (char*)&rep, sizeof(rep)); write(sock, (char*)&rep, sizeof(rep));
if (ntohs(rep) != FILENAME_OK) if (ntohs(rep) != FILENAME_OK)
return (1); return (CMD_FAIL);
if (read(sock, (char*)&req, sizeof(req)) < 0)
rep = htons(ERR_READ);
DG("start transfer command, %d, received", ntohs(req));
num_blks = htons(stat.st_size / MAXSIZE + 1); DG("GOING TO READ_REQ");
num_last_blk = htons(stat.st_size % MAXSIZE); req = read_req(sock);
DG("telling client file has [%i] blocks", ntohs(num_blks)); if (req != TRANSFER_START)
if (net_send(sock, (char*)&num_blks, sizeof(num_blks))) return (CMD_FAIL);
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");
num_blks = ntohs(num_blks); net_send_large(sock, file, stat.st_size);
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);
if (file && munmap(file, stat.st_size) < 0) if (file && munmap(file, stat.st_size) < 0)
rep = htons(ERR_MMAP); rep = htons(ERR_MMAP);
return (0); return (CMD_SUCCESS);
} }

23
ftp/srcs/serv_do_put.c Normal file
View file

@ -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);
}

23
ftp/srcs/serv_do_sh.c Normal file
View file

@ -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);
}

View file

@ -18,6 +18,9 @@ char **g_av = NULL;
t_itof g_ftp_cmd[] = t_itof g_ftp_cmd[] =
{ {
{REQUEST_FILE, serv_do_get}, {REQUEST_FILE, serv_do_get},
{REQUEST_PUT, serv_do_put},
{REQUEST_SH, serv_do_sh},
{REQUEST_CD, serv_do_cd},
{0, 0}, {0, 0},
}; };
@ -34,8 +37,10 @@ int ftp_cmd(int sock, int req)
{ {
if (!(g_ftp_cmd[i].f)) if (!(g_ftp_cmd[i].f))
break ; 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)); write(sock, (char *)&msg_ok, sizeof(msg_ok));
(g_ftp_cmd[i].f)(sock);
return (0); return (0);
} }
} }
@ -47,14 +52,13 @@ int ftp_cmd(int sock, int req)
int ftp_spawn(int sock) int ftp_spawn(int sock)
{ {
int req; int req;
int r;
DG("new connection"); DG("new connection");
while ((r = read(sock, (char*)&req, sizeof(req))) > 0) while ((req = read_req(sock)))
{ {
req = ntohs(req); DG("==== %i NEW REQUEST ====", req);
DG("request code [%i]", req);
ftp_cmd(sock, req); ftp_cmd(sock, req);
DG("==== DONE ====");
} }
DG("end of connection"); DG("end of connection");
close(sock); close(sock);