get,debug,help done. net_get/net_send in libft manage data transfer
This commit is contained in:
parent
2772d8d0b3
commit
ebb2a5cefc
16 changed files with 396 additions and 196 deletions
15
ftp/Makefile
15
ftp/Makefile
|
|
@ -29,18 +29,23 @@ INC_DIR = includes/
|
|||
OBJ_DIR = objs/
|
||||
|
||||
SERVER_OBJ = $(OBJ_DIR)server.o
|
||||
CLIENT_OBJ = $(OBJ_DIR)client.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\
|
||||
ftp.c\
|
||||
ftp_cmd.c\
|
||||
console_msg.c\
|
||||
req_init.c\
|
||||
serv_do_get.c\
|
||||
server.c
|
||||
|
||||
SRCS = $(addprefix $(SRC_DIR), $(SRC_BASE))
|
||||
OBJS = $(addprefix $(OBJ_DIR), $(SRC_BASE:.c=.o))
|
||||
OBJS := $(filter-out $(SERVER_OBJ), $(OBJS))
|
||||
OBJS := $(filter-out $(CLIENT_OBJ), $(OBJS))
|
||||
OBJS := $(filter-out $(SERVER_OBJ) $(CLIENT_OBJ), $(OBJS))
|
||||
NB = $(words $(SRC_BASE))
|
||||
INDEX = 0
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
jhalford
|
||||
|
|
@ -15,33 +15,57 @@
|
|||
|
||||
# define FTP_SERVER_USAGE "%s <port>"
|
||||
# define FTP_CLIENT_USAGE "%s <addr> <port>"
|
||||
# define FTP_BUF 1024
|
||||
# define FTP_READ_BUF 1024
|
||||
# define FTP_REPLY_BUF 1024
|
||||
|
||||
# define MAXLINE 256
|
||||
# define MAXSIZE 512
|
||||
|
||||
# include "libft.h"
|
||||
# include <sys/socket.h>
|
||||
# include <netdb.h>
|
||||
# include <netinet/in.h>
|
||||
# include <arpa/inet.h>
|
||||
|
||||
# include <signal.h>
|
||||
|
||||
# include <stdio.h>
|
||||
# include <readline/readline.h>
|
||||
|
||||
typedef struct s_ftp_reply t_ftp_reply;
|
||||
# include <sys/mman.h>
|
||||
|
||||
struct s_ftp_reply
|
||||
typedef struct s_cmd_map t_cmd_map;
|
||||
|
||||
struct s_cmd_map
|
||||
{
|
||||
int code;
|
||||
char *data;
|
||||
char *key;
|
||||
int (*f)();
|
||||
char *help;
|
||||
};
|
||||
|
||||
extern char **g_av;
|
||||
enum e_ftp
|
||||
{
|
||||
REQUEST_FILE = 100,
|
||||
CMD_NOT_SUPPORTED = 150,
|
||||
CMD_SUPPORTED = 160,
|
||||
FILENAME_OK = 700,
|
||||
NO_SUCH_FILE,
|
||||
TRANSFER_START,
|
||||
ABORT = 800,
|
||||
ERR_READ,
|
||||
ERR_STAT,
|
||||
ERR_MMAP,
|
||||
};
|
||||
|
||||
int ftp_daemon(int sock);
|
||||
int ftp_spawn(int cs);
|
||||
int ftp_cmd(char *cmd, t_ftp_reply *reply);
|
||||
extern char **g_av;
|
||||
extern int g_debug;
|
||||
extern t_cmd_map g_cli_cmd[];
|
||||
|
||||
int ftp_daemon(int sock);
|
||||
int ftp_spawn(int sock);
|
||||
int ftp_cmd(int sock, int req);
|
||||
|
||||
int serv_do_get(int sock);
|
||||
|
||||
int console_msg(int level, char *str, ...);
|
||||
t_cmd_map *get_cmd(char *cmd);
|
||||
int cli_output(int req, char *name, char *msg);
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 83fa039e360fc16134f1068c30dd4eb1e1c62d8c
|
||||
Subproject commit 61ecc913bbc31dafab3fff2386e1cbfffd34596a
|
||||
26
ftp/srcs/cli_do_debug.c
Normal file
26
ftp/srcs/cli_do_debug.c
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#include "ft_p.h"
|
||||
|
||||
int g_debug;
|
||||
|
||||
int cli_do_debug(int sock, char **av)
|
||||
{
|
||||
(void)sock;
|
||||
if (av[1] && av[2])
|
||||
return (console_msg(-1, "usage: debug [ on | off | level ]"));
|
||||
if (!av[1])
|
||||
g_debug = !g_debug;
|
||||
else if (ft_strcmp(av[1], "on") == 0)
|
||||
g_debug = 1;
|
||||
else if (ft_strcmp(av[1], "off") == 0)
|
||||
g_debug = 0;
|
||||
else if (ft_stris(av[1], ft_isdigit))
|
||||
g_debug = ft_atoi(av[1]);
|
||||
else
|
||||
{
|
||||
console_msg(-1, "%s: bad debugging value", av[1]);
|
||||
return (1);
|
||||
}
|
||||
console_msg(0, "Debugging %s (g_debug = %i)",
|
||||
g_debug ? "on" : "off", g_debug);
|
||||
return (0);
|
||||
}
|
||||
44
ftp/srcs/cli_do_get.c
Normal file
44
ftp/srcs/cli_do_get.c
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#include "ft_p.h"
|
||||
|
||||
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 <file>"));
|
||||
if (req_init(sock, REQUEST_FILE, "PORT"))
|
||||
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");
|
||||
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)
|
||||
net_get_fd(sock, fd, MAXSIZE);
|
||||
if (num_last_blk)
|
||||
net_get_fd(sock, fd, MAXSIZE);
|
||||
return (0);
|
||||
}
|
||||
26
ftp/srcs/cli_do_help.c
Normal file
26
ftp/srcs/cli_do_help.c
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#include "ft_p.h"
|
||||
|
||||
int cli_do_help(int sock, char **av)
|
||||
{
|
||||
int i;
|
||||
t_cmd_map *cmd;
|
||||
|
||||
(void)sock;
|
||||
(void)av;
|
||||
i = 0;
|
||||
while (av[++i])
|
||||
{
|
||||
if (!(cmd = get_cmd(av[i])))
|
||||
console_msg(-1, "?Invalid ? command `%s'", av[i]);
|
||||
else
|
||||
console_msg(0, "%s\t%s", cmd->key, cmd->help);
|
||||
}
|
||||
if (i == 1)
|
||||
{
|
||||
console_msg(0, "Commands are:");
|
||||
i = -1;
|
||||
while (g_cli_cmd[++i].key)
|
||||
console_msg(0, "%s\n", g_cli_cmd[i].key);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
28
ftp/srcs/cli_do_local.c
Normal file
28
ftp/srcs/cli_do_local.c
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#include "ft_p.h"
|
||||
|
||||
char **environ;
|
||||
|
||||
int cli_do_local(int sock, char **av)
|
||||
{
|
||||
pid_t pid;
|
||||
char *cmd[4];
|
||||
|
||||
(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);
|
||||
}
|
||||
7
ftp/srcs/cli_output.c
Normal file
7
ftp/srcs/cli_output.c
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#include "ft_p.h"
|
||||
|
||||
int cli_output(int req, char *name, char *msg)
|
||||
{
|
||||
ft_printf("%i %s %s\n", req, name, msg);
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -12,74 +12,71 @@
|
|||
|
||||
#include "ft_p.h"
|
||||
|
||||
int create_client(char *addr, int port)
|
||||
{
|
||||
int sock;
|
||||
struct protoent *proto;
|
||||
struct sockaddr_in sin;
|
||||
int g_debug = 0;
|
||||
|
||||
if (!(proto = getprotobyname("tcp")))
|
||||
return (-1);
|
||||
sock = socket(PF_INET, SOCK_STREAM, proto->p_proto);
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(port);
|
||||
sin.sin_addr.s_addr = inet_addr(addr);
|
||||
if (connect(sock, (const struct sockaddr *)&sin, sizeof(sin)) < 0)
|
||||
return (-1);
|
||||
return (sock);
|
||||
int g_debug;
|
||||
t_cmd_map g_cli_cmd[] =
|
||||
{
|
||||
{"?", 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},
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void sigint_nl(int signo)
|
||||
int do_client(int sock)
|
||||
{
|
||||
(void)signo;
|
||||
ft_putchar('\n');
|
||||
signal(SIGINT, SIG_DFL);
|
||||
kill(SIGINT, getpid());
|
||||
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)
|
||||
(cmd->f)(sock, av);
|
||||
else
|
||||
return (0);
|
||||
ft_sstrfree(av);
|
||||
}
|
||||
ft_strdel(&input);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
int port;
|
||||
int sock;
|
||||
char buf[FTP_READ_BUF];
|
||||
char *input;
|
||||
pid_t pid;
|
||||
pid_t client_pid;
|
||||
int status;
|
||||
|
||||
client_pid = getpid();
|
||||
if (ac != 3)
|
||||
ft_usage(FTP_CLIENT_USAGE, av[0]);
|
||||
port = ft_atoi(av[2]);
|
||||
if ((sock = create_client(av[1], port)) < 0)
|
||||
if ((sock = create_client(av[1], port, "tcp")) < 0)
|
||||
{
|
||||
perror(av[0]);
|
||||
return (1);
|
||||
}
|
||||
signal(SIGINT, SIG_IGN);
|
||||
while (1)
|
||||
{
|
||||
if ((pid = fork()) < 0)
|
||||
exit(1);
|
||||
if (pid == 0)
|
||||
{
|
||||
signal(SIGINT, sigint_nl);
|
||||
if (!(input = readline("ft_p> ")))
|
||||
exit(1);
|
||||
if (*input)
|
||||
{
|
||||
write(sock, input, ft_strlen(input));
|
||||
read(sock, buf, FTP_READ_BUF);
|
||||
write(1, buf, ft_strlen(buf));
|
||||
}
|
||||
ft_strdel(&input);
|
||||
tcsetpgrp(STDIN, client_pid);
|
||||
exit(0);
|
||||
}
|
||||
waitpid(pid, &status, 0);
|
||||
if (WEXITSTATUS(status) == 1)
|
||||
return (1);
|
||||
}
|
||||
do_client(sock);
|
||||
close(sock);
|
||||
return (0);
|
||||
}
|
||||
|
|
|
|||
22
ftp/srcs/console_msg.c
Normal file
22
ftp/srcs/console_msg.c
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#include "ft_p.h"
|
||||
|
||||
int g_debug;
|
||||
|
||||
int console_msg(int level, char *str, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, str);
|
||||
if (g_debug >= level)
|
||||
{
|
||||
if (level == -1)
|
||||
ft_printf("{red}");
|
||||
if (level == 0)
|
||||
ft_printf("{blu}");
|
||||
else
|
||||
ft_printf("{mag}");
|
||||
ft_vdprintf(1, str, ap);
|
||||
ft_printf("{eoc}\n");
|
||||
}
|
||||
return (level);
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* ft_p.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/04/03 16:08:44 by jhalford #+# #+# */
|
||||
/* Updated: 2017/04/03 18:24:24 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "ft_p.h"
|
||||
|
||||
char **g_av;
|
||||
|
||||
int ftp_reply(int sock, t_ftp_reply *reply)
|
||||
{
|
||||
write(sock, reply->data, ft_strlen(reply->data));
|
||||
return (0);
|
||||
}
|
||||
|
||||
int ftp_spawn(int cs)
|
||||
{
|
||||
int r;
|
||||
char buf[1024];
|
||||
t_ftp_reply reply;
|
||||
|
||||
ft_printf("{yel}{inv}%i {gre} new connection {eoc}\n", getpid());
|
||||
while ((r = read(cs, buf, FTP_BUF)) > 0)
|
||||
{
|
||||
buf[r] = 0;
|
||||
ft_printf("{yel}{inv}%i {eoc} received %i bytes: [%s]\n", getpid(), r, buf);
|
||||
ft_bzero(&reply, sizeof(reply));
|
||||
ftp_cmd(buf, &reply);
|
||||
ftp_reply(cs, &reply);
|
||||
}
|
||||
ft_printf("{yel}{inv}%i {red} end of connection {eoc}\n", getpid());
|
||||
close(cs);
|
||||
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)
|
||||
{
|
||||
perror(g_av[0]);
|
||||
return (1);
|
||||
}
|
||||
if (pid == 0)
|
||||
exit(ftp_spawn(cs));
|
||||
close(cs);
|
||||
}
|
||||
close(sock);
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* ftp_cmd.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2017/04/03 16:42:58 by jhalford #+# #+# */
|
||||
/* Updated: 2017/04/03 18:42:32 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "ft_p.h"
|
||||
|
||||
t_stof g_ftp_cmdlist[] =
|
||||
{
|
||||
{"ls", NULL},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
int ftp_cmd(char *cmd, t_ftp_reply *reply)
|
||||
{
|
||||
char **av;
|
||||
int i;
|
||||
|
||||
reply->code = 0;
|
||||
av = ft_split_whitespaces(cmd);
|
||||
i = -1;
|
||||
while (g_ftp_cmdlist[++i].key)
|
||||
{
|
||||
if (ft_strcmp(g_ftp_cmdlist[i].key, av[0]) == 0)
|
||||
{
|
||||
ft_asprintf(&reply->data, "%s: Valid command !!!\n", av[0]);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
ft_asprintf(&reply->data, "%s: ?Invalid command\n", av[0]);
|
||||
return (0);
|
||||
}
|
||||
19
ftp/srcs/req_init.c
Normal file
19
ftp/srcs/req_init.c
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#include "ft_p.h"
|
||||
|
||||
int req_init(int sock, int req, char *name)
|
||||
{
|
||||
int rep;
|
||||
int net_req;
|
||||
|
||||
net_req = htons(req);
|
||||
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);
|
||||
}
|
||||
56
ftp/srcs/serv_do_get.c
Normal file
56
ftp/srcs/serv_do_get.c
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#include "ft_p.h"
|
||||
|
||||
int serv_do_get(int sock)
|
||||
{
|
||||
char fname[MAXLINE];
|
||||
int req;
|
||||
int rep;
|
||||
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;
|
||||
if (read(sock, fname, MAXLINE) < 0)
|
||||
rep = htons(ERR_READ);
|
||||
else if ((fd = open(fname, O_RDONLY)) < 0)
|
||||
rep = htons(NO_SUCH_FILE);
|
||||
else if ((fstat(fd, &stat)) < 0)
|
||||
rep = htons(ERR_STAT);
|
||||
else if ((file = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0))
|
||||
== MAP_FAILED)
|
||||
rep = htons(ERR_MMAP);
|
||||
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));
|
||||
|
||||
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");
|
||||
|
||||
num_blks = ntohs(num_blks);
|
||||
num_last_blk = ntohs(num_last_blk);
|
||||
i = -1;
|
||||
while (++i < num_blks)
|
||||
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)
|
||||
rep = htons(ERR_MMAP);
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -14,24 +14,74 @@
|
|||
|
||||
#define FTP_SERVER_USAGE "%s <port>"
|
||||
|
||||
char **g_av = NULL;
|
||||
|
||||
int create_server(int port)
|
||||
char **g_av = NULL;
|
||||
t_itof g_ftp_cmd[] =
|
||||
{
|
||||
int sock;
|
||||
struct protoent *proto;
|
||||
struct sockaddr_in sin;
|
||||
{REQUEST_FILE, serv_do_get},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
if (!(proto = getprotobyname("tcp")))
|
||||
return (-1);
|
||||
sock = socket(PF_INET, SOCK_STREAM, proto->p_proto);
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(port);
|
||||
sin.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
if (bind(sock, (const struct sockaddr *)&sin, sizeof(sin)) < 0)
|
||||
return (-1);
|
||||
listen(sock, 2);
|
||||
return (sock);
|
||||
int ftp_cmd(int sock, int req)
|
||||
{
|
||||
int i;
|
||||
int msg_ok;
|
||||
|
||||
i = -1;
|
||||
msg_ok = htons(CMD_SUPPORTED);
|
||||
while (g_ftp_cmd[++i].id)
|
||||
{
|
||||
if (g_ftp_cmd[i].id == req)
|
||||
{
|
||||
if (!(g_ftp_cmd[i].f))
|
||||
break ;
|
||||
write(sock, (char *)&msg_ok, sizeof(msg_ok));
|
||||
(g_ftp_cmd[i].f)(sock);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
msg_ok = htons(CMD_NOT_SUPPORTED);
|
||||
write(sock, (char *)&msg_ok, sizeof(msg_ok));
|
||||
return (1);
|
||||
}
|
||||
|
||||
int ftp_spawn(int sock)
|
||||
{
|
||||
int req;
|
||||
int r;
|
||||
|
||||
DG("new connection");
|
||||
while ((r = read(sock, (char*)&req, sizeof(req))) > 0)
|
||||
{
|
||||
req = ntohs(req);
|
||||
DG("request code [%i]", req);
|
||||
ftp_cmd(sock, req);
|
||||
}
|
||||
DG("end of connection");
|
||||
close(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)
|
||||
|
|
@ -43,11 +93,11 @@ int main(int ac, char **av)
|
|||
if (ac != 2)
|
||||
ft_usage(FTP_SERVER_USAGE, av[0]);
|
||||
port = ft_atoi(av[1]);
|
||||
if ((sock = create_server(port)) < 0)
|
||||
if ((sock = create_server(port, 3, "tcp")) < 0
|
||||
|| ftp_daemon(sock) < 0)
|
||||
{
|
||||
perror(av[0]);
|
||||
return (1);
|
||||
}
|
||||
ftp_daemon(sock);
|
||||
return (0);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue