Linux网络编程综合运用之MiniFtp实现(六)
间隔了一周时间没写了,由于今年的股势行情貌似不错的样子,对于对股市完全不懂的我也在蠢蠢欲动,所以最近一周业余时间在“不务正业”-----学习炒股。发现学习它其实挺费神的,满脑子都是走势图,而且是神经有点受刺激的感觉,发现这个坚决不能在上班时间去想这事,不然会非常影响情绪,毕境对于普通老百姓来讲经济来源还主要是来源于工作,专职炒股也不适合像我这样笨拙的人,不过可以业余有时间学习学习,入市那还是得非常非常谨慎,所以放下它,接着来学习技术这才是王道,言归正传。
上一次对字符串工具模块进行了封装,这次主要是对"参数配置模块"的封装,FTP中有很多配置相关的选项,不可能硬编码到代码中,而应该将它们配置到配置文件当中,像vsftpd的配置文件如下:


而对于miniftpd所有的参数配置项如下:

对于上面这些变量应该是与对应的配置项进行一一对应的,所以需要定义三张表格来进行一一对应:
|
配置文件中的配置项与配置项变量对应关系表 |
|
static struct parseconf_bool_setting { const char *p_setting_name; int *p_variable; } parseconf_bool_array[] = { { "pasv_enable", &tunable_pasv_enable }, { "port_enable", &tunable_port_enable }, { NULL, NULL } }; |
|
static struct parseconf_uint_setting { const char *p_setting_name; unsigned int *p_variable; } parseconf_uint_array[] = { { "listen_port", &tunable_listen_port }, { "max_clients", &tunable_max_clients }, { "max_per_ip", &tunable_max_per_ip }, { "accept_timeout", &tunable_accept_timeout }, { "connect_timeout", &tunable_connect_timeout }, { "idle_session_timeout", &tunable_idle_session_timeout }, { "data_connection_timeout", &tunable_data_connection_timeout }, { "local_umask", &tunable_local_umask }, { "upload_max_rate", &tunable_upload_max_rate }, { "download_max_rate", &tunable_download_max_rate }, { NULL, NULL } }; |
|
static struct parseconf_str_setting { const char *p_setting_name; const char **p_variable; } parseconf_str_array[] = { { "listen_address", &tunable_listen_address }, { NULL, NULL }//最后这个NULL是为了遍历用的 }; |
下面定义两个操作配置文件的函数:
|
函数 |
说明 |
|
void parseconf_load_file(const char *path); |
加载配置文件 |
|
void parseconf_load_setting(const char *setting); |
将配置项加载到相应的变量 |
下面则开始进行编码,首先先新建配置文件模块文:

tunable.h:对其变量进行声明:
#ifndef _TUNABLE_H_
#define _TUNABLE_H_ extern int tunable_pasv_enable;
extern int tunable_port_enable;
extern unsigned int tunable_listen_port;
extern unsigned int tunable_max_clients;
extern unsigned int tunable_max_per_ip;
extern unsigned int tunable_accept_timeout;
extern unsigned int tunable_connect_timeout;
extern unsigned int tunable_idle_session_timeout;
extern unsigned int tunable_data_connection_timeout;
extern unsigned int tunable_local_umask;
extern unsigned int tunable_upload_max_rate;
extern unsigned int tunable_download_max_rate;
extern const char *tunable_listen_address; #endif /* _TUNABLE_H_ */
tunable.h:
#include "tunable.h" int tunable_pasv_enable = ;
int tunable_port_enable = ;
unsigned int tunable_listen_port = ;
unsigned int tunable_max_clients = ;
unsigned int tunable_max_per_ip = ;
unsigned int tunable_accept_timeout = ;
unsigned int tunable_connect_timeout = ;
unsigned int tunable_idle_session_timeout = ;
unsigned int tunable_data_connection_timeout = ;
unsigned int tunable_local_umask = ;
unsigned int tunable_upload_max_rate = ;
unsigned int tunable_download_max_rate = ;
const char *tunable_listen_address;
另外新建一个配置文件:


接下来还要暴露两个接口出来,对文件和配置项的解析:
|
函数 |
说明 |
|
void parseconf_load_file(const char *path); |
加载配置文件 |
|
void parseconf_load_setting(const char *setting); |
将配置项加载到相应的变量 |
新建一个解析模块来做上面的解析工作:

parseconf.h:
#ifndef _PARSE_CONF_H_
#define _PARSE_CONF_H_ void parseconf_load_file(const char *path);
void parseconf_load_setting(const char *setting); #endif /* _PARSE_CONF_H_ */
parseconf.c:
#include "parseconf.h"
#include "common.h"
#include "tunable.h" void parseconf_load_file(const char *path){ } void parseconf_load_setting(const char *setting){ }
下面来实现这两个函数:


另外,由于fgets函数读取的一行字符包含'\n',所以需要将其去掉,可以用我们之前封装的现成方法:


接下来实现命令行的解析函数,在正式解析之前,需要将配置文件中的配置项与配置项变量对应关系表用代码定义出来,如下:
#include "parseconf.h"
#include "common.h"
#include "tunable.h" static struct parseconf_bool_setting
{
const char *p_setting_name;
int *p_variable;
}
parseconf_bool_array[] =
{
{ "pasv_enable", &tunable_pasv_enable },
{ "port_enable", &tunable_port_enable },
{ NULL, NULL }
}; static struct parseconf_uint_setting
{
const char *p_setting_name;
unsigned int *p_variable;
}
parseconf_uint_array[] =
{
{ "listen_port", &tunable_listen_port },
{ "max_clients", &tunable_max_clients },
{ "max_per_ip", &tunable_max_per_ip },
{ "accept_timeout", &tunable_accept_timeout },
{ "connect_timeout", &tunable_connect_timeout },
{ "idle_session_timeout", &tunable_idle_session_timeout },
{ "data_connection_timeout", &tunable_data_connection_timeout },
{ "local_umask", &tunable_local_umask },
{ "upload_max_rate", &tunable_upload_max_rate },
{ "download_max_rate", &tunable_download_max_rate },
{ NULL, NULL }
}; static struct parseconf_str_setting
{
const char *p_setting_name;
const char **p_variable;
}
parseconf_str_array[] =
{
{ "listen_address", &tunable_listen_address },
{ NULL, NULL }
}; void parseconf_load_file(const char *path){
FILE *fp = fopen(path, "r");
if (fp == NULL)
ERR_EXIT("fopen"); char setting_line[] = {};
while (fgets(setting_line, sizeof(setting_line), fp) != NULL)
{
if (strlen(setting_line) ==
|| setting_line[] == '#'
|| str_all_space(setting_line))
continue; str_trim_crlf(setting_line);
parseconf_load_setting(setting_line);
memset(setting_line, , sizeof(setting_line));
} fclose(fp);
} void parseconf_load_setting(const char *setting){ }
其中各个变量是来自于全局变量tunable.c中。
可见有三种类型的参数,下面一个个来进行解析,对于"pasv_enable=YES"一个配置,可能会写成“ pasv_enable=YES”,所以先去掉左控格:

然后需要将key=pasv_enable;value=YES分隔开,这里可以用之前封装的现成的命令:

但也有可能用户没有配置value,如“pasv_enable=”,所以这是不合法的,也应该做下判断:

接下来,就需要拿这个key在上面的配置表格变量中进行搜索,如果找到了,则将其值赋值给该配置变量,如下:

如果说没有找到话,也就说明当前的配置项不是字符串类型的,这时,还得继续去其它类型的配置项中进行搜寻,如下:

而对于布尔类型,可以有以下几种形式:
AA=YES
AA=yes
AA=TRUE
AA=1
所以,首先将value统一成大写:

当遍历boolean类型配置项中也没有找到时,则需要在无符号整形中进行查找,其中无符号整形有两种形式:一种八进制,以0开头,比如"local_umask=077";另一种是十进制,如:"listen_port=21",所以需要做下判断,代码基本类似:

下面则来编译运行一下,在编译运行之前,需要把新加的模块加入到Makefile中:




上面看已经正常通过了,那还是看不出这些配置信息是否正常读取了,所以下面需要写一个测试程序来检验一下:

编译运行:


再次编译运行:

接下来可以应用某些配置项了:

编译运行:

用FTP客户端连接:

可见这样代码就变成可配置的了,另外配置文件的文件名可以做成宏:

加载时直接用该宏:

好了,经过几周的耽搁先完成到这,之后会慢慢恢复学习。
Linux网络编程综合运用之MiniFtp实现(六)的更多相关文章
- Linux网络编程综合运用之MiniFtp实现(一)
春节过后,万物复苏,在这元宵佳节的前一天,决定继续开启新年的学习计划,生命在于运动,提高源于学习,在经过漫长的Linux网络编程学习后,接下来会以一个综合的小项目来将所学的知识点综合运用,首先是对项目 ...
- Linux网络编程综合运用之MiniFtp实现(四)
从今天开始,正式进入MiniFtp的代码编写阶段了,好兴奋,接下来很长一段时间会将整个实现过程从无到有一点点实现出来,达到综合应用的效果,话不多说正入正题: 这节主要是将基础代码框架搭建好,基于上节介 ...
- Linux网络编程综合运用之MiniFtp实现(九)
上次中实现了FTP命令的映射来避免很多if....else的判断,这次主要是开始实现目录列表的传输,先看一下目前实现的: 数据连接创建好之后则开始进行目录列表的传输了,而要传输目录列表,首先要将目录列 ...
- Linux网络编程综合运用之MiniFtp实现(五)
转眼兴奋的五一小长假就要到来了,在放假前夕还是需要保持一颗淡定的心,上次中已经对miniFTP有基础框架进行了搭建,这次继续进行往上加代码,这次主要还是将经历投射到handle_child()服务进程 ...
- Linux网络编程综合运用之MiniFtp实现(八)
上节中实现了"USER"和"PASS"命令,如下: 事实上FTP是有很多命令组成的,如果就采用上面的这种方法来实现的话,就会有很多if...else if语句, ...
- Linux网络编程综合运用之MiniFtp实现(七)
上节中实现了配置文件的解析,这节来实现用户登录的验证,首先用客户端来登录vsftpd来演示登录的过程: 接着再连接miniftpd,来看下目前的效果: 接下来实现它,与协议相关的模块都是在ftppro ...
- Linux网络编程综合运用之MiniFtp实现(三)
前面已经对FTP相关的一些概念有了基本的认识,接下来就要进入代码编写阶段了,也是非常兴奋的阶段,在开启这个它之前先对项目需求进行一个梳理,对其我们要实现的FTP服务器是一个什么样子. ftp命令列表 ...
- 【深入浅出Linux网络编程】 "开篇 -- 知其然,知其所以然"
[深入浅出Linux网络编程]是一个连载博客,内容源于本人的工作经验,旨在给读者提供靠谱高效的学习途径,不必在零散的互联网资源中浪费精力,快速的掌握Linux网络编程. 连载包含4篇,会陆续编写发出, ...
- 【linux草鞋应用编程系列】_5_ Linux网络编程
一.网络通信简介 第一部分内容,暂时没法描述,内容实在太多,待后续专门的系列文章. 二.linux网络通信 在linux中继承了Unix下“一切皆文件”的思想, 在linux中要实现网 ...
随机推荐
- face_code业务信息不匹配
face_code业务信息不匹配 检查获取 face code时的 appid, mch_id,out_trade_no以及可选的sub_mch_id , 与 face pay 时是否一致.
- java四大名著及idea常用插件
四大名著 <Java编程思想><Think in Java> https://github.com/quanke/think-in-java https://github.co ...
- jenkins publish .net core application to linux server
最近学习Docker与Jenkins, 网上大部分都是关于Jenkins+Git+Docker进行持续远程部署, 我一直在考虑为什么Jenkins和Docker要绑定一块使用, 因为我想单独使用Jen ...
- Quartz.Net—IJob特性
IJob默认情况下是无状态的,和其他系统没有关系 特别是job里面的jobdata每次都是新的.可以无限扩展. PersistJobDataAfterExecution JobData持久化 Job ...
- java当中JDBC当中的transaction例子
[学习笔记] 7.jdbc的transaction例子: import java.sql.*; public class MySQlTransaction1 { public static void ...
- linux服务器安装jdk (手动解压方式安装)
linux服务器安装jdk 使用的是通过手动解压安装的方式,没有通过yum或者apt-get命令安装 准备: 下载一个jdk,版本自选,后缀为(.tar.gz) 开始 创建目录 mkdir /usr/ ...
- C++ 生成随机数总结 & C++ rand 函数使用方法
1. 产生[0,b]之间的随机数 rand()*b / RAND_MAX; 2. 产生[-a,0]之间的随机数 rand()*(-a) / RAND_MAX; 3. 产生[a,b]之间的随机数 a + ...
- AVR单片机教程——闪烁LED
上次我们把LED点亮了.你可能已经试过把 LED_RED 换成其他灯,也可能已经用 led_on() 把所有LED一起点亮了.但是LED点亮以后,程序就退出了,之后LED一直没有暗,直到没有供电.这一 ...
- 机器学习之逻辑回归(Logistic)笔记
在说逻辑回归之前,可以先说一说逻辑回归与线性回归的区别: 逻辑回归与线性回归在学习规则形式上是完全一致的,它们的区别在于hθ(x(i))为什么样的函数 当hθ(x(i))=θTx(i)时,表示的是线性 ...
- sublime text3 关闭更新提醒
Preferences->settings 在Preferences.sublime-setting --User中 增加: "update_check":false,