added client/server sources
This commit is contained in:
parent
21f1af7011
commit
5b370b6a43
14 changed files with 625 additions and 0 deletions
20
ftp/srcs/client/cli_ls.c
Normal file
20
ftp/srcs/client/cli_ls.c
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* cmd_ls.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/11/08 13:43:10 by jhalford #+# #+# */
|
||||
/* Updated: 2017/11/08 13:50:20 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "ftp_client.h"
|
||||
|
||||
int cli_ls(int sock, char **av)
|
||||
{
|
||||
(void)sock;
|
||||
(void)av;
|
||||
return (0);
|
||||
}
|
||||
90
ftp/srcs/client/client.c
Normal file
90
ftp/srcs/client/client.c
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* client.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/04/02 19:18:31 by jhalford #+# #+# */
|
||||
/* Updated: 2017/11/08 15:12:12 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "ftp_client.h"
|
||||
|
||||
int g_debug = 0;
|
||||
|
||||
int g_debug;
|
||||
t_cmd_map g_cli_cmd[] =
|
||||
{
|
||||
{"ls", cli_ls, "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"}, */
|
||||
{0, 0, 0},
|
||||
};
|
||||
|
||||
t_cmd_map *get_cmd(char *cmd)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = -1;
|
||||
while (g_cli_cmd[++i].key)
|
||||
{
|
||||
if (ft_strcmp(g_cli_cmd[i].key, cmd) == 0)
|
||||
return (&g_cli_cmd[i]);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int do_client(int sock)
|
||||
{
|
||||
char *input;
|
||||
t_cmd_map *cmd;
|
||||
char **av;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (!(input = readline("ft_p> ")))
|
||||
return (1);
|
||||
if (*input)
|
||||
{
|
||||
av = ft_split_whitespaces(input);
|
||||
if (!(cmd = get_cmd(av[0])))
|
||||
console_msg(-1, "?Invalid command");
|
||||
else if (cmd->f)
|
||||
{
|
||||
(void)sock;
|
||||
(cmd->f)(sock, av);
|
||||
}
|
||||
else
|
||||
return (0);
|
||||
ft_sstrfree(av);
|
||||
}
|
||||
ft_strdel(&input);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
int port;
|
||||
int sock;
|
||||
|
||||
if (ac != 3)
|
||||
ft_usage(FTP_CLIENT_USAGE, av[0]);
|
||||
port = ft_atoi(av[2]);
|
||||
if ((sock = create_client(av[1], port, "tcp")) < 0)
|
||||
{
|
||||
perror(av[0]);
|
||||
return (1);
|
||||
}
|
||||
do_client(sock);
|
||||
close(sock);
|
||||
return (0);
|
||||
}
|
||||
25
ftp/srcs/server/cmd_cwd.c
Normal file
25
ftp/srcs/server/cmd_cwd.c
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* cmd_cwd.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/11/02 13:36:24 by jhalford #+# #+# */
|
||||
/* Updated: 2017/11/02 15:24:00 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "ftp_server.h"
|
||||
|
||||
int cmd_cwd(t_ftp *ftp, char **av)
|
||||
{
|
||||
if (chdir(av[1]))
|
||||
{
|
||||
console_msg(1, "chdir(%s) failed errno=%i", av[1], errno);
|
||||
ftp_ret(ftp, "550 file not found");
|
||||
}
|
||||
else
|
||||
ftp_ret(ftp, "200 success");
|
||||
return (1);
|
||||
}
|
||||
31
ftp/srcs/server/cmd_list.c
Normal file
31
ftp/srcs/server/cmd_list.c
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* cmd_list.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/11/01 19:22:12 by jhalford #+# #+# */
|
||||
/* Updated: 2017/11/08 17:19:24 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "ftp_server.h"
|
||||
|
||||
int cmd_list(t_ftp *ftp, char **av)
|
||||
{
|
||||
pid_t pid;
|
||||
int status;
|
||||
|
||||
if (dconn_open(ftp) < 0)
|
||||
return (-1);
|
||||
if ((pid = fork()) < 0)
|
||||
perror("fork");
|
||||
else if (pid == 0)
|
||||
{
|
||||
dup2(ftp->d_sock, 1);
|
||||
execl("/bin/ls", "ls", "-lA", av[1], NULL);
|
||||
}
|
||||
waitpid(pid, &status, 0);
|
||||
return (dconn_close(ftp));
|
||||
}
|
||||
48
ftp/srcs/server/cmd_pasv.c
Normal file
48
ftp/srcs/server/cmd_pasv.c
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* cmd_pasv.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/11/08 13:54:57 by jhalford #+# #+# */
|
||||
/* Updated: 2017/11/08 17:15:09 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "ftp_server.h"
|
||||
|
||||
int cmd_pasv(t_ftp *ftp, char **av)
|
||||
{
|
||||
uint16_t port;
|
||||
int sock;
|
||||
struct sockaddr_in sin;
|
||||
|
||||
(void)av;
|
||||
return (ftp_ret(ftp, "502 not implemented"));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||
port = 35000;
|
||||
while (++port < USHRT_MAX)
|
||||
{
|
||||
sin.sin_port = htons(port);
|
||||
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (bind(sock, (const struct sockaddr *)&sin,
|
||||
sizeof(struct sockaddr_in)) == 0
|
||||
&& listen(sock, 3) == 0)
|
||||
{
|
||||
ftp->data_state = DATA_PASV;
|
||||
ftp->dconn.sock = sock;
|
||||
console_msg(1, "listening on %i (PASV)", port);
|
||||
return (ftp_ret(ftp, "227 %i,%i,%i,%i,%i,%i",
|
||||
(ntohl(sin.sin_addr.s_addr) >> (8*3)) & 0xff,
|
||||
(ntohl(sin.sin_addr.s_addr) >> (8*2)) & 0xff,
|
||||
(ntohl(sin.sin_addr.s_addr) >> (8*1)) & 0xff,
|
||||
(ntohl(sin.sin_addr.s_addr) >> (8*0)) & 0xff,
|
||||
(ntohs(sin.sin_port) >> (8*1)) & 0xff,
|
||||
(ntohs(sin.sin_port) >> (8*0)) & 0xff
|
||||
));
|
||||
}
|
||||
}
|
||||
return (ftp_ret(ftp, "500 couldn't find local port"));
|
||||
}
|
||||
39
ftp/srcs/server/cmd_port.c
Normal file
39
ftp/srcs/server/cmd_port.c
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* cmd_port.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/11/01 18:42:50 by jhalford #+# #+# */
|
||||
/* Updated: 2017/11/08 17:17:44 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "ftp_server.h"
|
||||
|
||||
int cmd_port(t_ftp *ftp, char **av)
|
||||
{
|
||||
char **hostport;
|
||||
char buf[INET_ADDRSTRLEN];
|
||||
|
||||
if (!av[1])
|
||||
return (ftp_ret(ftp, "501 syntax error in parameter"));
|
||||
if (ftp->data_state == DATA_PASV)
|
||||
close(ftp->dconn.sock);
|
||||
hostport = ft_strsplit(av[1], ',');
|
||||
ftp->dconn.sin.sin_family = AF_INET;
|
||||
ftp->dconn.sin.sin_port = htons(256 * ft_atoi(hostport[4])
|
||||
+ ft_atoi(hostport[5]));
|
||||
ftp->dconn.sin.sin_addr.s_addr =
|
||||
htonl(
|
||||
256 * 256 * 256 * ft_atoi(hostport[0])
|
||||
+ 256 * 256 * ft_atoi(hostport[1])
|
||||
+ 256 * ft_atoi(hostport[2])
|
||||
+ ft_atoi(hostport[3]));
|
||||
ftp->data_state = DATA_ACTV;
|
||||
console_msg(1, "remote dconn @ %s:%i",
|
||||
inet_ntop(AF_INET, &ftp->dconn.sin.sin_addr, buf, sizeof(struct sockaddr_in)),
|
||||
ntohs(ftp->dconn.sin.sin_port));
|
||||
return (ftp_ret(ftp, "200 ip/port ok"));
|
||||
}
|
||||
23
ftp/srcs/server/cmd_pwd.c
Normal file
23
ftp/srcs/server/cmd_pwd.c
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* pwd.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/11/01 17:39:01 by jhalford #+# #+# */
|
||||
/* Updated: 2017/11/02 14:18:58 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "ftp_server.h"
|
||||
|
||||
int cmd_pwd(t_ftp *ftp, char **av)
|
||||
{
|
||||
char path[200];
|
||||
|
||||
(void)av;
|
||||
getcwd(path, 200);
|
||||
ftp_ret(ftp, "257 \"%s\"", path);
|
||||
return (0);
|
||||
}
|
||||
22
ftp/srcs/server/cmd_quit.c
Normal file
22
ftp/srcs/server/cmd_quit.c
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* cmd_quit.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/11/02 15:20:58 by jhalford #+# #+# */
|
||||
/* Updated: 2017/11/02 15:31:17 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "ftp_server.h"
|
||||
|
||||
int cmd_quit(t_ftp *ftp, char **av)
|
||||
{
|
||||
(void)av;
|
||||
close(ftp->cmd_sock);
|
||||
ftp->cmd_sock = 0;
|
||||
ftp_ret(ftp, "221 service closing control connection");
|
||||
return (1);
|
||||
}
|
||||
42
ftp/srcs/server/cmd_retr.c
Normal file
42
ftp/srcs/server/cmd_retr.c
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* cmd_retr.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/11/02 15:32:28 by jhalford #+# #+# */
|
||||
/* Updated: 2017/11/08 15:12:28 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "ftp_server.h"
|
||||
|
||||
int cmd_retr(t_ftp *ftp, char **av)
|
||||
{
|
||||
int sock;
|
||||
int fd;
|
||||
struct stat buf;
|
||||
char *file;
|
||||
int i;
|
||||
char **split;
|
||||
|
||||
sock = dconn_open(ftp);
|
||||
if ((fd = open(av[1], O_RDONLY)) < 0 || fstat(fd, &buf) < 0)
|
||||
return (ftp_ret(ftp, "550 file not found / no access"));
|
||||
if (buf.st_size)
|
||||
{
|
||||
if ((file = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0))
|
||||
== MAP_FAILED)
|
||||
return (ftp_ret(ftp, "550 mmap failed"));
|
||||
split = ft_strsplit(file, '\n');
|
||||
i = -1;
|
||||
while (split[++i])
|
||||
ftp_send(sock, split[i]);
|
||||
ft_sstrfree(split);
|
||||
munmap(file, buf.st_size);
|
||||
}
|
||||
ftp_ret(ftp, "226 closing dataconn");
|
||||
close(sock);
|
||||
return (0);
|
||||
}
|
||||
33
ftp/srcs/server/cmd_stor.c
Normal file
33
ftp/srcs/server/cmd_stor.c
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* cmd_stor.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/11/02 16:01:54 by jhalford #+# #+# */
|
||||
/* Updated: 2017/11/08 17:09:21 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "ftp_server.h"
|
||||
|
||||
int cmd_stor(t_ftp *ftp, char **av)
|
||||
{
|
||||
int sock;
|
||||
int fd;
|
||||
char *msg;
|
||||
|
||||
sock = dconn_open(ftp);
|
||||
if ((fd = open(av[1], O_WRONLY | O_CREAT, 0644)) < 0)
|
||||
return (ftp_ret(ftp, "550 couldn't open/create file"));
|
||||
while (1)
|
||||
{
|
||||
if (ftp_recv(sock, &msg))
|
||||
break ;
|
||||
write(fd, msg, ft_strlen(msg));
|
||||
ft_strdel(&msg);
|
||||
}
|
||||
dconn_close(ftp);
|
||||
return (0);
|
||||
}
|
||||
30
ftp/srcs/server/cmd_type.c
Normal file
30
ftp/srcs/server/cmd_type.c
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* cmd_file.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/11/01 18:14:51 by jhalford #+# #+# */
|
||||
/* Updated: 2017/11/02 15:49:12 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "ftp_server.h"
|
||||
|
||||
int cmd_type(t_ftp *ftp, char **av)
|
||||
{
|
||||
if (!av[1])
|
||||
ftp_ret(ftp, "501 syntax error in parameter");
|
||||
if (av[1][0] == 'A')
|
||||
{
|
||||
ftp_ret(ftp, "200 type A ok");
|
||||
}
|
||||
else if (av[1][0] == 'I')
|
||||
{
|
||||
ftp_ret(ftp, "200 type A ok");
|
||||
}
|
||||
else
|
||||
ftp_ret(ftp, "500 parameter unrecognized");
|
||||
return (1);
|
||||
}
|
||||
29
ftp/srcs/server/cmd_user.c
Normal file
29
ftp/srcs/server/cmd_user.c
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* cmd_user.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/11/02 14:20:46 by jhalford #+# #+# */
|
||||
/* Updated: 2017/11/08 15:14:02 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "ftp_server.h"
|
||||
|
||||
int cmd_user(t_ftp *ftp, char **av)
|
||||
{
|
||||
ft_strcpy(ftp->username, av[1]);
|
||||
ft_strcpy(ftp->path, REPOPATH);
|
||||
ft_strcat(ftp->path, av[1]);
|
||||
if (mkdir(ftp->path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0
|
||||
&& chdir(ftp->path) < 0)
|
||||
return (ftp_ret(ftp, "530 mkdir/chdir"));
|
||||
if (getcwd(ftp->path, 100) < 0)
|
||||
return (ftp_ret(ftp, "530 getcwd"));
|
||||
ftp_ret(ftp, "230 user '%s' logged in, proceed", ftp->username);
|
||||
console_msg(1, "logon: %s@ftp://%s", ftp->username, ftp->path);
|
||||
ftp->log_state = LOG_YES;
|
||||
return (0);
|
||||
}
|
||||
69
ftp/srcs/server/dconn.c
Normal file
69
ftp/srcs/server/dconn.c
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* dconn.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/11/08 14:55:15 by jhalford #+# #+# */
|
||||
/* Updated: 2017/11/08 17:22:37 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "ftp_server.h"
|
||||
|
||||
static int dconn_open_actv(t_ftp *ftp)
|
||||
{
|
||||
int sock;
|
||||
|
||||
ftp_ret(ftp, "150 about to open data connection");
|
||||
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (connect(sock, (struct sockaddr*)&ftp->dconn.sin,
|
||||
sizeof(struct sockaddr_in)) < 0)
|
||||
{
|
||||
ftp_ret(ftp, "425 can't open data conn");
|
||||
return(-1);
|
||||
}
|
||||
ftp->d_sock = sock;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int dconn_open_pasv(t_ftp *ftp)
|
||||
{
|
||||
int sock;
|
||||
|
||||
ftp_ret(ftp, "150 about to accept");
|
||||
if ((sock = accept(ftp->dconn.sock, NULL, NULL)) < 0)
|
||||
{
|
||||
ftp_ret(ftp, "425 can't open data conn");
|
||||
return(-1);
|
||||
}
|
||||
ftp->d_sock = sock;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int dconn_open(t_ftp *ftp)
|
||||
{
|
||||
if (ftp->d_sock)
|
||||
{
|
||||
ftp_ret(ftp, "125 data connection already open; transfer starting");
|
||||
return (0);
|
||||
}
|
||||
else if (ftp->data_state == DATA_ACTV)
|
||||
return (dconn_open_actv(ftp));
|
||||
else if (ftp->data_state == DATA_PASV)
|
||||
return (dconn_open_pasv(ftp));
|
||||
else
|
||||
{
|
||||
console_msg(1, "dconn_open() called but no dconn available");
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
int dconn_close(t_ftp *ftp)
|
||||
{
|
||||
return (ftp_ret(ftp, "226 closing dataconn"));
|
||||
close(ftp->d_sock);
|
||||
ftp->d_sock = 0;
|
||||
return (0);
|
||||
}
|
||||
124
ftp/srcs/server/server.c
Normal file
124
ftp/srcs/server/server.c
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* server.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/04/02 15:02:48 by jhalford #+# #+# */
|
||||
/* Updated: 2017/11/08 16:39:15 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "ftp_server.h"
|
||||
|
||||
#define FTP_SERVER_USAGE "%s <port>"
|
||||
|
||||
char **g_av = NULL;
|
||||
char g_rootdir[PATH_MAX];
|
||||
|
||||
t_ftp_cmd g_ftp_cmd[] =
|
||||
{
|
||||
{"USER", cmd_user, 0},
|
||||
{"QUIT", cmd_quit, 0},
|
||||
{"RETR", cmd_retr, LOG_YES},
|
||||
{"STOR", cmd_stor, LOG_YES},
|
||||
{"CWD", cmd_cwd, LOG_YES},
|
||||
{"PASV", cmd_pasv, LOG_YES},
|
||||
{"PORT", cmd_port, LOG_YES},
|
||||
{"PWD", cmd_pwd, LOG_YES},
|
||||
{"TYPE", cmd_type, LOG_YES},
|
||||
{"LIST", cmd_list, LOG_YES},
|
||||
{0, 0, 0},
|
||||
};
|
||||
int g_debug = 2;
|
||||
|
||||
int ftp_cmd(t_ftp *ftp)
|
||||
{
|
||||
int i;
|
||||
char *msg;
|
||||
char **av;
|
||||
|
||||
ftp_recv(ftp->cmd_sock, &msg);
|
||||
i = -1;
|
||||
while (g_ftp_cmd[++i].name)
|
||||
{
|
||||
if (ft_strncmp(msg, g_ftp_cmd[i].name,
|
||||
ft_strlen(g_ftp_cmd[i].name)) == 0)
|
||||
{
|
||||
if (ftp->log_state < g_ftp_cmd[i].statelock)
|
||||
{
|
||||
return (ftp_ret(ftp, "530 not logged in"));
|
||||
}
|
||||
if (!(g_ftp_cmd[i].f))
|
||||
break ;
|
||||
else
|
||||
{
|
||||
av = ft_strsplit(msg, ' ');
|
||||
return (g_ftp_cmd[i].f(ftp, av));
|
||||
ft_sstrfree(av);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
ftp_ret(ftp, "502 command not implemented");
|
||||
ft_strdel(&msg);
|
||||
return (1);
|
||||
}
|
||||
|
||||
int ftp_spawn(int sock)
|
||||
{
|
||||
t_ftp ftp;
|
||||
|
||||
ftp.cmd_sock = sock;
|
||||
ftp.log_state = LOG_NONE;
|
||||
ftp.d_sock = 0;
|
||||
ftp.data_state = 0;
|
||||
ftp_ret(&ftp, "220 ready for user");
|
||||
while (ftp.cmd_sock)
|
||||
ftp_cmd(&ftp);
|
||||
close(ftp.cmd_sock);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int ftp_daemon(int sock)
|
||||
{
|
||||
int cs;
|
||||
struct sockaddr_in csin;
|
||||
socklen_t cslen;
|
||||
pid_t pid;
|
||||
|
||||
while (1)
|
||||
{
|
||||
cs = accept(sock, (struct sockaddr*)&csin, &cslen);
|
||||
if ((pid = fork()) < 0)
|
||||
return (-1);
|
||||
if (pid == 0)
|
||||
{
|
||||
close(sock);
|
||||
exit(ftp_spawn(cs));
|
||||
}
|
||||
close(cs);
|
||||
}
|
||||
close(sock);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
int port;
|
||||
int sock;
|
||||
|
||||
g_av = av;
|
||||
getcwd(g_rootdir, PATH_MAX);
|
||||
if (ac != 2)
|
||||
ft_usage(FTP_SERVER_USAGE, av[0]);
|
||||
port = ft_atoi(av[1]);
|
||||
if ((sock = create_server(port, 3, "tcp")) < 0
|
||||
|| ftp_daemon(sock) < 0)
|
||||
{
|
||||
perror(av[0]);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
Loading…
Reference in a new issue