#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <unistd.h>
#include <stdarg.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <getopt.h>
#include "dxyh.h"
#include "dxyh_thread.h"
#include "ftpd.h"
#include "error.h"
#include "record.h"
extern log_t *logfd;
static void ftpd_usage(void);
static void ftpd_verbose(void);
static void ftpd_help(void);
static void ftpd_sig_chld(int signo);
static void ftpd_sig_int(int signo);
static void ftpd_chld_sig_quit(int signo);
static int ftpd_ctrl_conn_handler(int ctrlfd);
static const char *ftpd_serv_resp_num2msg(int num);
int ftpd_send_resp(int ctrlfd, int num, ...);
static int ftpd_do_request(int ctrlfd, char *buff);
static int ftpd_do_auth(int ctrlfd, char *cmd);
static int ftpd_do_user(int ctrlfd, char *cmd);
static int ftpd_do_pass(int ctrlfd, char *cmd);
static int ftpd_do_pwd(int ctrlfd, char *cmd);
static int ftpd_do_cwd(int ctrlfd, char *cmd);
static int ftpd_do_list(int ctrlfd, char *cmd);
static int ftpd_do_syst(int ctrlfd, char *cmd);
static int ftpd_do_size(int ctrlfd, char *cmd);
static int ftpd_do_dele(int ctrlfd, char *cmd);
static int ftpd_do_rmd(int ctrlfd, char *cmd);
static int ftpd_do_retr(int ctrlfd, char *cmd);
static int ftpd_do_stor(int ctrlfd, char *cmd);
static int ftpd_do_pasv(int ctrlfd, char *cmd);
static int ftpd_do_nlst(int ctrlfd, char *cmd);
static int ftpd_do_port(int ctrlfd, char *cmd);
static int ftpd_do_type(int ctrlfd, char *cmd);
static int ftpd_do_quit(int ctrlfd, char *cmd);
static int ftpd_do_mkd(int ctrlfd, char *cmd);
static int ftpd_get_port_mode_ipport(char *cmd,
in_addr_t *ip, uint16_t *port);
static int ftpd_get_connfd(void);
static int ftpd_get_list_stuff(char buff[], size_t len);
static int get_file_info(const char *filename,
char buff[], size_t len);
static int dir_path_ok(const char *dir_path);
static void ftpd_close_all_fds(void);
static void parent_atlast(void);
static void pr_cpu_time(void);
static void ptransfer(const char *direction, long bytes,
const struct timeval *t0,
const struct timeval *t1);
static int add2pids(pid_t pid);
static void dele_from_pids(pid_t pid);
int ftpd_debug_on;
int ftpd_record_on;
int ftpd_quit_flag;
int ftpd_hash_print;
int ftpd_tick_print;
uint16_t ftpd_serv_port;
char ftpd_cur_dir[PATH_MAX];
int ftpd_cur_pasv_fd;
int ftpd_cur_pasv_connfd;
int ftpd_cur_port_fd;
int ftpd_cur_type;
const struct ftpd_user_st *ftpd_cur_user;
int ftpd_nchild;
pid_t pids[MAX_CHIHLD_NUM];
const struct ftpd_cmd_st ftpd_cmds[] = {
{ "AUTH", ftpd_do_auth },
{ "USER", ftpd_do_user },
{ "PASS", ftpd_do_pass },
{ "PWD", ftpd_do_pwd },
{ "XPWD", ftpd_do_pwd },
{ "CWD", ftpd_do_cwd },
{ "LIST", ftpd_do_list },
{ "MKD", ftpd_do_mkd },
{ "XMKD", ftpd_do_mkd },
{ "SYST", ftpd_do_syst },
{ "SIZE", ftpd_do_size },
{ "DELE", ftpd_do_dele },
{ "RMD", ftpd_do_rmd },
{ "TYPE", ftpd_do_type },
{ "RETR", ftpd_do_retr },
{ "STOR", ftpd_do_stor },
{ "NLST", ftpd_do_nlst },
{ "PASV", ftpd_do_pasv },
{ "PORT", ftpd_do_port },
{ "QUIT", ftpd_do_quit },
{ NULL, NULL },
};
const struct ftpd_user_st ftpd_users[] = {
{ "anonymous", "" },
{ "ftp", "" },
{ "dengxiayehu", "123456" }
};
const char ftpd_serv_resps[][256] = {
"150 %s" FTPD_LINE_END,
"200 %s" FTPD_LINE_END,
"213 Size of \"%s\" is %ld." FTPD_LINE_END,
"215 Linux Type." FTPD_LINE_END,
"220 Ftpd" FTPD_VER " ready for new user." FTPD_LINE_END,
"221 Goodbye." FTPD_LINE_END,
"226 %s" FTPD_LINE_END,
"227 Entering Passive Mode (%d,%d,%d,%d,%d,%d)." FTPD_LINE_END,
"230 Login successful." FTPD_LINE_END,
"250 Directory successfully changed." FTPD_LINE_END,
"257 %s" FTPD_LINE_END,
"331 %s" FTPD_LINE_END,
"350 %s" FTPD_LINE_END,
"500 %s" FTPD_LINE_END,
"530 %s" FTPD_LINE_END,
"550 %s" FTPD_LINE_END
};
/*
* show msg in debug mode
*/
void ftpd_debug(const char *file, int line,
const char *fmt, ...)
{
if (ftpd_debug_on) {
va_list ap;
int off = 0;
char buff[MAXLINE];
off = snprintf(buff, sizeof(buff), "(%s:%d:%ld) ",
file, line, (long) getpid());
/* for security, you should prefer vsprintf to vsnprintf */
va_start(ap, fmt);
vsnprintf(buff + off, sizeof(buff) - off, fmt, ap);
va_end(ap);
/* make sure the print won't be disturbed */
my_lock_mutex_wait();
fprintf(stderr, buff);
my_lock_mutex_release();
}
}
/*
* initialization, add parent-process's init stuff here
*/
void ftpd_init(void)
{
int i;
ftpd_debug_on = OFF; /* default is OFF*/
ftpd_record_on = OFF;
ftpd_hash_print = OFF;
ftpd_tick_print = OFF;
ftpd_quit_flag = 0;
ftpd_serv_port = SERV_PORT; /* defiend in dxyh.h, 9877 as def */
ftpd_cur_port_fd = -1; /* port sockfd */
ftpd_cur_pasv_fd = -1; /* passive sockfd */
ftpd_cur_pasv_connfd = -1;
ftpd_cur_type = TYPE_A;
pids[0] = getpid();
for (i = 1; i < MAX_CHIHLD_NUM; ++i)
pids[i] = -1;
ftpd_nchild = 0;
Signal(SIGPIPE, SIG_IGN); /* ignore signal SIG_INT */
Signal(SIGCHLD, ftpd_sig_chld); /* install other signals' handler */
Signal(SIGINT, ftpd_sig_int);
my_lock_mutex_init(); /* initialize the mutex-lock */
atexit(parent_atlast); /* show something or do some cleanup */
}
/*
* handle the args
*
* -d/--debug --> open debug mode
* -p/--port [port#] --> specify the listen port (9877 as default)
* -r/--record["filenam"] --> open log mode ("logfile.txt" as default)
* -h/--help --> show help
* -v/--verbose --> show version
*
* @argc:
* @argv: the args passed to main func
*/
void ftpd_parse_args(int argc, char **argv)
{
int do_verbose, do_help;
int err_flg;
char c, log_filename[PATH_MAX];
struct option longopts[] = {
{ "port", required_argument, NULL, 'p' },
{ "debug", no_argument, NULL, 'd' },
{ "record", optional_argument, NULL, 'r' },
{ "verbose", no_argument, &do_verbose, 1 },
{ "help", no_argument, &do_help, 1 },
{ 0, 0, 0, 0 }
};
do_verbose = OFF;
do_help = OFF;
err_flg = 0;
while ((c = getopt_long(argc, argv, ":hr::vp:dW;", longopts, NULL)) != -1) {
switch (c) {
case 'd':
ftpd_debug_on = ON;
ftpd_hash_print = ON; /* show '#' within transfer */
ftpd_tick_print = ON; /* try it, you will know */
break;
case 'r':
strcpy(log_filename, optarg ? optarg : FTPD_DEF_LOGFILE);
ftpd_record_on = ON;
break;
case 'v':
do_verbose = ON;
break;
case 'h':
do_help = ON;
break;
case 'p':
if (0 == (ftpd_serv_port = (uint16_t) atoi(optarg)))
err_flg = 1;
break;
case 0:
break;
case ':':
err_msg("%s: option `-%c' requires an argument",
argv[0], optopt);
err_flg = 1;
break;
case '?':
default:
err_msg("%s: %c: unknow option", argv[0], optopt);
err_flg = 1;
break;
}
}
if (err_flg) {
ftpd_usage();
exit(EXIT_FAILURE);
} else if (do_help) {
ftpd_help();
exit(EXIT_SUCCESS);
}
else if (do_verbose) {
ftpd_verbose();
exit(EXIT_SUCCESS);
}
if (ftpd_record_on) {
if (NULL == (logfd = log_open(log_filename, LOG_DEFAULT))) {
FTPD_DEBUG("Cannot open logfile \"%s\"", log_filename);
exit(EXIT_FAILURE);
}
FTPD_DEBUG_LOG(INFO, "Prepare to log in \"%s\" ok.\n",
log_filename);
}
FTPD_DEBUG("serv port %u\n", ftpd_serv_port);
}
/*
* show usage when an error occurs
*/
static void ftpd_usage(void)
{
printf("usage: ftpd_main [-p <port#>] [-r[\"filenam\"]][-v] [-d] [-h]\n");
}
/*
* show version
*/
static void ftpd_verbose(void)
{
printf("A simple ftp server.\n"
"It can support some of the most
ftpd.zip_ftpd
版权申诉
194 浏览量
2022-07-14
02:52:41
上传
评论
收藏 41KB ZIP 举报
御道御小黑
- 粉丝: 61
- 资源: 1万+
最新资源
- IMG_0694.GIF
- 基于图像的三维模型重建C++源代码+文档说明(高分课程设计)
- 基于聚焦法的工件立体测量方案,根据数据进行三维重建 使用HALCON处理图像,MATLAB拟合数据+源代码+数据集+效果图
- 锄战三国村 修改:货币使用不减 v1.10(2) 原创 (中文).apk
- 基于python实现的单目双目视觉三维重建+源代码+图像图片(高分课程设计)
- 基于C+++OPENCV的全景图像拼接源码(课程设计)
- 基于Python+OpenCV对多张图片进行全景图像拼接,消除鬼影,消除裂缝+源代码+文档说明+界面截图(高分课程设计)
- 基于C++实现的全景图像拼接源码(课程设计)
- 基于SIFT特征点提取和RASIC算法实现全景图像拼接python源码+文档说明+界面截图+详细注释(95分以上课程大作业)
- 基于matlab实现眼部判别的疲劳检测系统+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈