Mysql —— C语言链接mysql数据库,命令行形式(getopt()函数),用户、用户组增删改查(用户组表内有用户控制的策略字段)

函数说明——getopt():

函数说明 getopt()用来分析命令行参数。参数argc和argv分别代表参数个数和内容,跟main()函数的命令行参数是一样的。

optstring中的指定的内容的意义(例如getopt(argc, argv, "ab:c:de::");)
1.单个字符,表示选项(如下例中的abcde各为一个选项)。
2.单个字符后接一个冒号:表示该选项后必须跟一个参数。参数紧跟在选项后或者以空格隔开。该参数的指针赋给optarg(如下例中的b:c:)。
3 单个字符后跟两个冒号,表示该选项后可以跟一个参数,也可以不跟。如果跟一个参数,参数必须紧跟在选项后不能以空格隔开。该参数的指针赋给optarg。(如上例中的e::,如果没有跟参数,则optarg = NULL)

数据库内定义的表,以及每个表的字段:

Mysql —— C语言链接mysql数据库,命令行形式(getopt()函数),用户、用户组增删改查(用户组表内有用户控制的策略字段)_第1张图片

表内字段的截图:

Mysql —— C语言链接mysql数据库,命令行形式(getopt()函数),用户、用户组增删改查(用户组表内有用户控制的策略字段)_第2张图片

Mysql —— C语言链接mysql数据库,命令行形式(getopt()函数),用户、用户组增删改查(用户组表内有用户控制的策略字段)_第3张图片

Mysql —— C语言链接mysql数据库,命令行形式(getopt()函数),用户、用户组增删改查(用户组表内有用户控制的策略字段)_第4张图片

命令行操作样式-h打印信息:

[root@localhost workwork]# ./userGroupUser users -h

Usage:
-----------------------------------------
	-S	show , show user information!
	-A	add , add user information!
	-D	delete , delete user information!
	-E	edit , edit user information!
	-h	help , display this help note!
	-n 	name , user`s name!
	-p	password ,  user`s password!
	-a	authentication ,  authentication type(0:pass 1:KEY 2:third)!
	-g(+)	group ,  the group to which the user belongs to!
	-e(+)	enable ,  usergroups`s enable type(0:enable 1:disable)!
	-o(+)	policy ,  usergroups`s policy type!
	-r(+)	remark ,  remark!

可以进行的操作:

显示操作: -S

//-S显示名为xxx用户具体信息(所在组、改组定义了什么策略) 提示必须加-n参数
./userGroupUser users -S //显示用户表 用户组表 所有信息
./userGroupUser users -S -n root //显示用户表内 name=root的用户的信息
						//可以显示该用户对应用户组内 所在的组 定义的策略信息

[root@localhost workwork]# ./userGroupUser users -S

Mysql —— C语言链接mysql数据库,命令行形式(getopt()函数),用户、用户组增删改查(用户组表内有用户控制的策略字段)_第5张图片

[root@localhost workwork]# ./userGroupUser users -S -n root


新增操作: -A

/* 全:./userGroupUser users -A s -n test3 -p test3 -a 2 -groot -rasdc*/
/**添加用户  (-g(+) group ; -r(+) remark)**/  
//新增用户的时候必须有-n|-p|-a选项  name password authentication
//一次性输入所有选项也是错误的  需要为每个参数赋值
	// printf("ADD -- Please enter necessary parameters -n|-p|-a,and assign a value to each parameter!\n");
//-g的参数必须紧跟 否则改用户会默认加入root组;
//-r的参数必须紧跟 否则判定为输入为空
//当-g选项没有加参数时候 默认该用户属于root组;
//-g后的参数不存在则加入失败,提示该用户组不存在
./userGroupUser users -A -n ddf -p aa -a 1//添加用户 name=ddf authentication=1 默认加到用户组root
		//insert into users values(7,'ddf','aa','2018-7-2 16:23:39',1,1,' ','KEY认证需要的文件','');
./userGroupUser users -A -n dds -a 1 -p sd -rkj -gaa //添加用户 name=dds authentication=1 group=aa	
		//insert into users values(6,'dds','sd','2018-7-2 16:20:33',1,1,' ','KEY认证需要的文件','kj');
		//-g后的参数 用户组名不存在不允许加入users usergroups表
/**添加用户组  (-e(+) enable; -o(+) policy; -r(+) remark)**/
/*全: ./userGroupUser usergroups -A  -n dd -e1 -oWEB,HTTP  -rddWH*/  
//新增用户时候有必须参数-n选项 name
//只有-n参数时候 策略状态( enable_type_)为0  默认策略( policy_type_)为所有策略资源
//其他参数 -e(+) 策略状态enable; -o(+)策略类型policy; -r(+) 标记内容remark 
./userGroupUser usergroups -A //提示 Please enter other parameters when you want to add someone!!
./userGroupUser usergroups -A -n aa //用户组表中添加name=aa policy默认如下 remark默认为空 的用户组信息
		//insert into usergroups values(2,'aa','2018-7-2 16:14:19',0,'GET,HEAD,POST,PUT,DELETE,OPTIONS','')
./userGroupUser usergroups -A -n aa -oGET -rasd //向用户组中添加 name=aa policy=GET remark=asd的用户
		//insert into usergroups values(2,'aa','2018-7-2 16:14:46',0,'GET','asd');

# ./userGroupUser usergroups -A  -n dd -e1 -oWEB,HTTP  -rusername-name-dd

# ./userGroupUser users -A s -n test3 -p test3 -a 2 -gdd -ras

Mysql —— C语言链接mysql数据库,命令行形式(getopt()函数),用户、用户组增删改查(用户组表内有用户控制的策略字段)_第6张图片

修改操作: -E

/**修改用户**/
/*全:./userGroupUser users -E -n test33 -p test33 -a 1 -gaa -rtest3totest33  where name test3 password test3*/
//修改用户操作必须有where name password 字符;且where后个数需为偶数; name password参数需参数值
//判断要进行改的用户是不是管理员用户,禁止对管理员用户进行任何操作
//参数 :-n newname;-p newpassword;-a authentication; -ggroup; -rremark; 
./userGroupUser users -E -n test22 where name test2 password test2 //把名为test2密码为test2的用户名改为test22
/**修改用户组**/
/*全:./userGroupUser usergroups -E -n aaa -e1 -oGET,HEAD -raatoaaa  where name aa*/
//修改用户组操作必须有where name字符;且where后个数需为偶数; name 参数需参数值
//判断要进行改的用户是不是管理员用户,禁止对管理员用户进行任何操作
//参数 : -n newname;-eenabled ; -opolicy; -rremark;
./userGroupUser usergroups -E -n AA where name aa//把aa用户名改为AA
./userGroupUser usergroups -E -n csa -e1 -oAAA,WEB,HTTP -rAAA where name aaa
		//修改 用户组name为aaa为   name=csa enable=1 policy=AAA,WEB,HTTP  remark=AAA

# ./userGroupUser users -E -n test34 -p test33 -a 0 -groot -rtest3totest34  where name test3 password test3

Mysql —— C语言链接mysql数据库,命令行形式(getopt()函数),用户、用户组增删改查(用户组表内有用户控制的策略字段)_第7张图片

# ./userGroupUser usergroups -E -n ddd -e0 -oGET,HEAD -rddtoddd  where name dd

Mysql —— C语言链接mysql数据库,命令行形式(getopt()函数),用户、用户组增删改查(用户组表内有用户控制的策略字段)_第8张图片

删除操作: -D

./userGroupUser users -D // 提示 Please enter other parameters when you want to add someone!!
./userGroupUser users -D -n root -p r	//root用户不允许删除 
						//name或passwd 不正确不允许删除 						
./userGroupUser usergroups -D //提示 Please enter other parameters when you want to add someone!!
./userGroupUser usergroups -D -n as//判断是否有用户属于该用户组  若有用户属于该用户组 不允许删除该用户组
		//root 用户组不允许删除

# ./userGroupUser users -D -n test34 -p test33

Mysql —— C语言链接mysql数据库,命令行形式(getopt()函数),用户、用户组增删改查(用户组表内有用户控制的策略字段)_第9张图片

# ./userGroupUser usergroups -D -n ddd

Mysql —— C语言链接mysql数据库,命令行形式(getopt()函数),用户、用户组增删改查(用户组表内有用户控制的策略字段)_第10张图片

所有的命令:

代码下载链接:https://download.csdn.net/download/weixin_42167759/10523075

/********************************************
 * 编译命令:gcc userGroupUser.c -lmysqlclient -o userGroupUser
 * 执行命令:./db
 * ******************************************/
#include 
#include 
#include 
#include 
#include 
#include "mysql/mysql.h"

MYSQL *g_conn;//mysql 链接  
MYSQL_RES *g_res;//mysql 记录集  
MYSQL_ROW g_row;//字符串数组,mysql 记录行

const char *g_host_name = "localhost";
const char *g_user_name = "root";
const char *g_password = "asdfgh";
const char *g_db_name = "test";
const unsigned int g_db_port = 3306;

#define MAX_BUF_SIZE 1024 //缓冲区最大字节数
#define ALL_POLICY_RESOURCES  "GET,HEAD,POST,PUT,DELETE,OPTIONS" //所有策略资源
#define IF_AND_ENDIF 0 //测试代码的注释
char sql[MAX_BUF_SIZE];
char Time[MAX_BUF_SIZE];
int auty;
int polistate = 0; //用户组策略 默认状态是开启的

int iNum_rows = 0;//mysql语句执行结果返回行数赋初值  
int flag = 0;//管理员权限开关  
int i = 1;//系统运行开关  

//登录使用的结构体
struct Login
{
	char name[24];
	char password[20];
}login;
//用户组对应策略的开关  (0:enable 1:disabled)
enum poliState{poliEnable,poliDisable};
//认证的方式  口令认证、KEY认证、第三方认证
enum authType{Passauth=0,Keyauth=1,Thpaauth=2};
//增删改查的操作控制
enum {
	MODE_SHOW = 1,  //show
	MODE_ADD,  //add
	MODE_DELETE, //delete
	MODE_EDIT, //deit
	MODE_HELP = 100,   //help
	PARAMETER_ERROR = 200
};
//操作使用的结构体  
struct Operation  
{  
	char tables[24];  
	char name[24];  
	char passwd[20];  
	char role[24];  
	char remark[20];  
	char group[255];  
	char authtype[255]; //可以根据变量的类型 做认证操作
	char passauth[255];
	char keyauth[255];
	char policy[255]; //输入的策略
	char oldname[255];//修改操作中用于校验的用户名
	char oldpass[255];//修改操作中用于校验的密码
}ope;
/****************************************************
 * time : 20180622
 * addby : swj
 * function :print_mysql_error() 打印错误信息
 * ******************************************************/
void print_mysql_error(const char *msg)
{
	if(msg)
		printf("%s: %s\n",msg,mysql_error(g_conn));
	else
		puts(mysql_error(g_conn));
}
/****************************************************
 * time : 20180622
 * addby : swj
 * function :executesql() 执行sql语句,成功返回0,失败返回-1 
 ******************************************************/
int executesql(const char * sql)
{
	if(mysql_real_query(g_conn,sql,strlen(sql)))
		return -1;
	return 0;
}
/****************************************************
 * time : 20180622
 * addby : swj
 * function :init_mysql() 初始化链接
 ******************************************************/
int init_mysql()
{
	//init the database connection 
	g_conn = mysql_init(NULL);
	//connection the database 
	if(!mysql_real_connect(g_conn,g_host_name,g_user_name,g_password,g_db_name,g_db_port,NULL,0))
		return -1;//链接失败
	if(executesql("set names utf8"))
		return -1;
	return 0; //返回成功
}

/****************************************************
 * time : 20180622
 * addby : swj
 * function :create_database()  选择数据库 没有的时候 创建数据;有的时候 进去数据库 
 * ******************************************************/
void create_database()
{
	sprintf(sql,"use workDatable");
	if(executesql(sql) == -1)
	{
		puts("create database");
		executesql("create database workDatable;");
		print_mysql_error(NULL);
		puts("choice database");
		executesql("use workDatable;");
		print_mysql_error(NULL);
		puts("!!!Initialize the success!!!");
	}
	else
	{
		executesql("use workDatable;");
		print_mysql_error(NULL);
	}

}
/****************************************************
 * time : 20180622
 * addby : swj
 * function :create_table()  创建表 
 * ******************************************************/
void create_table()
{
	sprintf(sql,"show tables;");
	executesql(sql);
	g_res = mysql_store_result(g_conn);
	//	printf("g_res = %d\n",g_res);
	iNum_rows = mysql_num_rows(g_res);
	//	printf("iNum_rows = %d\n",iNum_rows);
	if(iNum_rows == 0)
	{
		puts("create users table");
		executesql("create table users(id_ int(11) unsigned primary key auto_increment,name_ char(255) not null unique,password_ char(32) not null,create_time_ datetime,creator_id_ int(11) unsigned,auth_type_ int(11) not null,dyn_sn_ char(10),dyn_pass_sn_ text,remark_ varchar(200),foreign key(creator_id_) references users(id_));");
		puts("create usergroups table");	
		executesql("create table usergroups(id_ int(11) unsigned primary key auto_increment,name_ char(255) not null unique,create_time_ datetime,enable_type_ int(11) not null,policy_type_ char(255),remark_ varchar(200));");		
		puts("create userGroupUser table");
		executesql("create table userGroupUser(user_id_ int(11) unsigned,usergroup_id_ int(11) unsigned,primary key(user_id_,usergroup_id_),foreign key(user_id_) references users(id_),foreign key(usergroup_id_ ) references usergroups (id_));");
	}
	mysql_free_result(g_res);//释放结果集	
}
/****************************************************
 * time : 20180622
 * addby : swj
 * function :init_administrator() 初始化管理员账户
 * 		 管理员用户名:root  密码:root
 * ******************************************************/
void init_administrator()
{
	//查询users表
	sprintf(sql,"select * from users where id_='1' and name_='root';");
	executesql(sql);
	g_res = mysql_store_result(g_conn);
	iNum_rows = mysql_num_rows(g_res);
	if(iNum_rows == 0)
	{
		puts("Init Administrtor User");
		//插入管理员用户
		//printf("Passauth = %d\n",Passauth);
		sprintf(sql,"insert into users values(1,'root','root','2017-08-18 12:21:11',1,0,'','','0:VIP 1:local pwd 2:local cert');");  
		//0:VIP 1:local pwd 2:local cert 4:2-fa/ cert+pw 5:2-fa / dyn + pw');
		executesql(sql);
	}
	mysql_free_result(g_res); //释放结果集
	//查询usergroups表
	sprintf(sql,"select * from usergroups where id_='1' and name_='root';");
	executesql(sql);
	g_res = mysql_store_result(g_conn);
	iNum_rows = mysql_num_rows(g_res);
	if(iNum_rows == 0)
	{
		puts("Init Administrtor usergroups");
		//插入管理员所在用户组
		sprintf(sql,"insert into usergroups values(1,'root','2017-06-26 12:21:11',0,'GHPPDOP','0:enable 1:disabled');");  
		executesql(sql);
	}
	mysql_free_result(g_res); //释放结果集
	//查询userGroupUser表
	sprintf(sql,"select * from userGroupUser where user_id_='1' and usergroup_id_='1';");
	executesql(sql);
	g_res = mysql_store_result(g_conn);
	iNum_rows = mysql_num_rows(g_res);
	if(iNum_rows == 0)
	{
		puts("Init userGroupUser");
		//插入管理员用户所在组
		sprintf(sql,"insert into userGroupUser values(1,1);");
		executesql(sql);
	}
	mysql_free_result(g_res); // 释放结果集 
}
/****************************************************
 * time : 20180629
 * addby : swj
 * function :displayAll()  显示所有表的信息	
 * ******************************************************/
void displayAll()
{
	//查询users表  
	sprintf(sql,"select * from users;");  
	executesql(sql);  
	g_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集 
	iNum_rows = mysql_num_rows(g_res); // 得到记录的行数  
	int iNum_fields = mysql_num_fields(g_res); // 得到记录的列数  
	printf("☆ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ★ ☆ ★ ☆ ★ ☆ ★ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ★ ☆ ★ ☆ ★ ☆ ★ ☆"); 
	printf("\n\t\033[31m+-----+-------+------------------------+----------------------+--------------+---------------------+\033[0m");	
	printf("\n\t\033[41;32m|                                     ---users  table---                                           |\033[0m");
	printf("\n\t\033[31m+-----+-------+------------------------+----------------------+--------------+---------------------+\033[0m");

	puts("\n\tid_  | name_ |password_| create_time_     |creator_id_ | auth_type_  |dyn_sn_| dyn_pass_sn_ |remark_   ");  
	while((g_row=mysql_fetch_row(g_res)))  // 打印结果集
		printf("\n\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",g_row[0],g_row[1],g_row[2],g_row[3],g_row[4],g_row[5],g_row[6],g_row[7],g_row[8]);  
	//查询usergroups表  
	sprintf(sql,"select * from usergroups;");  
	executesql(sql);  
	g_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地,mysql_use_result直接使用服务器上的记录集 
	iNum_rows = mysql_num_rows(g_res); // 得到记录的行数  
	iNum_fields = mysql_num_fields(g_res); // 得到记录的列数
	printf("\n\n  ☆ ★ ☆ ★  ☆ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ★ ☆ ★ ☆ ★ ☆ ★ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ☆ ★ ");   
	printf("\n\t\033[31m+-----+-------+------------------------------------------+--------------+---------------------+\033[0m");	
	printf("\n\t\033[46;31m|           ------------------------usergroups table------------------------                  |\033[0m");
	printf("\n\t\033[31m+-----+-------+------------------------------------------+--------------+---------------------+\033[0m");
	puts("\n\tid_  | name_ |      create_time_       | enable_type_ | policy_type_  |remark_   ");  
	while((g_row=mysql_fetch_row(g_res)))  // 打印结果集
		printf("\n\t%s\t%s\t%s\t%s\t\t%s\t\t%s\t\n",g_row[0],g_row[1],g_row[2],g_row[3],g_row[4],g_row[5]);  
	mysql_free_result(g_res);
}
/****************************************************
 * time : 20180702
 * addby : swj
 * function :displayUser()  显示所有表的信息	
 * ******************************************************/
void displayUser()
{
	//根据用户名 找用户所属于的组 找该用户的策略
	//根据用户名 在用户表中找到用户id
	sprintf(sql,"select id_ from users where name_='%s';",ope.name);
	executesql(sql);
	g_res = mysql_store_result(g_conn);
	iNum_rows = mysql_num_rows(g_res);
	int iNum_fields = mysql_num_fields(g_res);
	while((g_row=mysql_fetch_row(g_res))){
#if IF_AND_ENDIF
		printf("g_row[0] = %s\n",g_row[0]);
#endif
		//根据用户id找到 在用户用户组关系表中找到 用户组id 
		sprintf(sql,"select usergroup_id_ from userGroupUser where user_id_=%s;",g_row[0]);
		executesql(sql);
		g_res = mysql_store_result(g_conn);
		iNum_rows = mysql_num_rows(g_res);
		int iNum_fields = mysql_num_fields(g_res);
		while((g_row=mysql_fetch_row(g_res))){
#if IF_AND_ENDIF
			printf("g_row[0] = %s\n",g_row[0]);
#endif
			//根据用户组id找 在用户组表中找到 用户组规定的策略	用户组名称	
#if IF_AND_ENDIF
			//sprintf(sql,"select policy_type_ from usergroups where id_=%s;",g_row[0]);//只找策略
#endif
			sprintf(sql,"select * from usergroups where id_=%s;",g_row[0]);
			executesql(sql);
			g_res = mysql_store_result(g_conn);
			iNum_rows = mysql_num_rows(g_res);
			iNum_fields = mysql_num_fields(g_res);
			while((g_row=mysql_fetch_row(g_res))){
#if IF_AND_ENDIF
				//	printf("g_row[0] = %s\n",g_row[0]); //只找策略
				//	sprintf(ope.policy,"%s",g_row[0]); //只找策略
				//	printf("g_row[1]=%s g_row[4]=%s\n",g_row[1],g_row[4]);
#endif
				sprintf(ope.policy,"%s",g_row[4]); 
				sprintf(ope.group,"%s",g_row[1]); 
			}
		}
	}
	//显示某一用户 或者用户组信息 参数中必须加-n参数								i
	if(strlen(ope.name) == 0)
	{
		printf("When you want to display sombody,please enter necessary parameters -n!\n");
		return;
	}
	sprintf(sql,"select * from %s where name_='%s';",ope.tables,ope.name);
	executesql(sql);
	g_res = mysql_store_result(g_conn);
	iNum_rows = mysql_num_rows(g_res); // 得到记录的行数  
	if(iNum_rows == 0)
		puts("\n\t\t\tNo such person!");
	else
	{
		if(strcmp(ope.tables,"users") == 0){
			int iNum_fields = mysql_num_fields(g_res); // 得到记录的列数  
			puts("\n\n\t id_  | name_ |password_| create_time_     |creator_id_ | auth_type_  |dyn_sn_| dyn_pass_sn_ |remark_ | group_ |policy_type_  ");
			while((g_row=mysql_fetch_row(g_res)))  // 打印结果集
				printf("\n\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",g_row[0],g_row[1],g_row[2],g_row[3],g_row[4],g_row[5],g_row[6],g_row[7],g_row[8],ope.group,ope.policy);
		}else{
			int iNum_fields = mysql_num_fields(g_res); // 得到记录的列数  
			puts("\n\n\tid_  | name_ |      create_time_       | enable_type_ | policy_type_  |remark_   ");
			while((g_row=mysql_fetch_row(g_res)))  // 打印结果集
				printf("\n\t%s\t%s\t%s\t%s\t\t%s\t\t%s\t\n",g_row[0],g_row[1],g_row[2],g_row[3],g_row[4],g_row[5]);

		}
	}
	mysql_free_result(g_res);
}
/****************************************************
 *  * time : 20180702
 * addby : swj
 * function :add_usergroup_msg() 添加用户组信息函数
 * ******************************************************/
void add_usergroup_msg()
{
	char NEWID[20];
	if((strlen(ope.name)==0))
	{
		printf("add_usergroup_msg -- Please enter necessary parameters -n,and assign a value to the parameter!\n");
		return;
	}
	//根据当前已有用户的行数判断,新建的用户id应为Id_中最大值+1
	sprintf(sql,"select (@id_:=id_+1) as idnum_,usergroups.* from usergroups where id_ = (select max(id_) from usergroups);");
	executesql(sql);
	g_res = mysql_store_result(g_conn);
	iNum_rows = mysql_num_rows(g_res); // 得到记录的行数  
	while((g_row = mysql_fetch_row(g_res))){
		sprintf(NEWID,"%s",g_row[0]);
	}
	//增加时候,若改用户名存在(给出用户存在的提示信息)
	sprintf(sql,"select id_ from usergroups where name_='%s';",ope.name);
	executesql(sql);
	g_res = mysql_store_result(g_conn);
	iNum_rows = mysql_num_rows(g_res);
	if(iNum_rows != 0)
	{
		puts("\n\t\t\t!!!Username already exists !!!! ");
		return ;
	}
	//获取系统时间,作为创建时间
	time_t temp;
	struct tm *t;
	time(&temp);
	t = localtime(&temp);
	sprintf(Time,"%d-%d-%d %d:%d:%d",t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
	//输入用户组 策略的状态 (0:enable 1:disabled)
#if IF_AND_ENDIF
	printf("polistate = %d\n",polistate);
#endif
	//输入策略 	如果-o为空 未输入具体 则添加所有策略
	if(strlen(ope.policy) == 0)
	{
		sprintf(ope.policy, ALL_POLICY_RESOURCES);
	}
#if IF_AND_ENDIF		
	printf("ope.group = %s\n",ope.policy);
#endif
	sprintf(sql,"insert into usergroups values(%s,'%s','%s',%d,'%s','%s');",NEWID,ope.name,Time,polistate,ope.policy,ope.remark);
#if IF_AND_ENDIF
	printf("%s\n",sql);
#endif
	executesql(sql);
	printf("\n\t\t\tADD ------- SUCCESS!!!\n");
	mysql_free_result(g_res);
}
/****************************************************
 * time : 201800702
 * addby : swj
 * function :add_user_msg() 添加用户信息函数
 * ******************************************************/
void add_user_msg(){
	char ID[20];
	char NEWID[20];
	if((strlen(ope.name)==0) || (strlen(ope.passwd)==0) || (strlen(ope.authtype)==0))
	{
		printf("add_user_msg -- Please enter necessary parameters -n|-p|-a,and assign a value to each parameter!\n");
		return;
	}
	//根据当前已有用户的行数判断,新建的用户id应为Id_中最大值+1
	sprintf(sql,"select (@id_:=id_+1) as idnum_,users.* from users where id_ = (select max(id_) from users);");
	executesql(sql);
	g_res = mysql_store_result(g_conn);
	iNum_rows = mysql_num_rows(g_res); // 得到记录的行数  
	while((g_row = mysql_fetch_row(g_res))){
		sprintf(NEWID,"%s",g_row[0]);
	}
	//增加时候,若改用户名存在(给出用户存在的提示信息)
	sprintf(sql,"select id_ from users where name_='%s';",ope.name);
	executesql(sql);
	g_res = mysql_store_result(g_conn);
	iNum_rows = mysql_num_rows(g_res);
	if(iNum_rows != 0)
	{
		puts("\n\t\t\t!!!Username already exists !!!! ");
		return ;
	}
	//获取系统时间,作为创建时间
	time_t temp;
	struct tm *t;
	time(&temp);
	t = localtime(&temp);
	sprintf(Time,"%d-%d-%d %d:%d:%d",t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
	//通过root用户名字获取用户id,作为创建者id使用	
	sprintf(sql,"select id_ from users where name_='root';");
	executesql(sql);
	g_res = mysql_store_result(g_conn);
	iNum_rows = mysql_num_rows(g_res);
	int iNum_fields = mysql_num_fields(g_res);
	while((g_row=mysql_fetch_row(g_res))){
		sprintf(ID,"%s",g_row[0]);
	}
	sprintf(sql,"insert into users values(%s,'%s','%s','%s',%s,%d,'%s','%s','%s');",NEWID,ope.name,ope.passwd,Time,ID,auty,ope.passauth,ope.keyauth,ope.remark);
#if IF_AND_ENDIF
	printf("%s\n",sql);
#endif
	executesql(sql);
	//输入用户所属的组  如果没有-g选项 则默认属于root用户组
	if(strlen(ope.group) == 0)
	{
		sprintf(ope.group, "root");
	}
	sprintf(sql,"select id_ from usergroups where name_='%s';",ope.group);
	executesql(sql);
	g_res = mysql_store_result(g_conn);
	iNum_rows = mysql_num_rows(g_res);
#if IF_AND_ENDIF
	printf("iNum_rows =%d\n",iNum_rows);
#endif
	//用户组组名不存在 -g后的参数不存在 不添加此用户
	if(iNum_rows == 0)
	{
		sprintf(sql,"delete from users where id_=%s;",NEWID);
		executesql(sql);
		printf("Assign the correct parameter value to -g(usergroup name not exit)!\n");
		return ;
	}
	iNum_fields = mysql_num_fields(g_res);
	while((g_row=mysql_fetch_row(g_res))){
		//将用户id与用户组id写入 用户与用户组角色表
		sprintf(sql,"insert into userGroupUser values(%s,%s);",NEWID,g_row[0]);
		executesql(sql);
#if IF_AND_ENDIF
		printf("%s\n",sql);
#endif
	}
	printf("\n\t\t\tADD ------- SUCCESS!!!\n");
	mysql_free_result(g_res);
}
/****************************************************
 * time : 201800702
 * addby : swj
 * function :del_user_msg() 添加用户信息函数
 * ******************************************************/
void del_usergroup_msg()
{
	char ID[20];
	if(strlen(ope.name)== 0)
	{
		printf("del_usergroup_mag -- Please enter necessary parameters -n,and assign a value to the parameter!\n");
		return;
	}
	//判断要进行删改的用户是不是管理员用户,禁止对管理员用户进行删改操作
	if(strcmp(ope.name,"root") == 0)
	{
		puts("\n\t\t\tAdministrator user deletion is prohibited");
		return ;
	}
	//通过用户名查看用户组表中是否有该用户组
	sprintf(sql,"select id_ from usergroups where name_='%s';",ope.name);
	executesql(sql);
	g_res = mysql_store_result(g_conn);
	iNum_rows = mysql_num_rows(g_res); // 得到记录的行数  
	int iNum_fields = mysql_num_fields(g_res);
	//将该用户组id取出来备用
	while((g_row=mysql_fetch_row(g_res))){
		sprintf(ID,"%s",g_row[0]);
	}
	//没有查到
	if(iNum_rows == 0)
	{
		puts("\n\t\t\t!!!No such person!!!");
		puts("\n\t\t\t!!!Please check the name or password enterd!!!");
		return ;                                        
	}
	//判断是否有用户属于该用户组  若有用户属于该用户组 不允许删除该用户组
	sprintf(sql,"select user_id_ from userGroupUser where usergroup_id_=%s;",ID);
	executesql(sql);
	g_res = mysql_store_result(g_conn);
	iNum_rows = mysql_num_rows(g_res); // 得到记录的行数
	if(iNum_rows != 0)
	{
		puts("\n\t\t\tBe quoted!User belongs to that user group!");
		puts("\n\t\t\tIt`s can`t be delete !");
		return ;
	}else{
		sprintf(sql,"delete from usergroups where id_=%s;",ID);
		executesql(sql);
	}
	printf("\n\t\t\tDELETE ------- SUCCESS!!!\n");
	mysql_free_result(g_res);
}
/****************************************************
 * time : 201800702
 * addby : swj
 * function :del_user_msg() 添加用户信息函数
 * ******************************************************/
void del_user_msg()
{
	char ID[20];
	if((strlen(ope.name)==0) || (strlen(ope.passwd)==0))
	{
		printf("del_user_mag -- Please enter necessary parameters -n|-p,and assign a value to each parameter!\n");
		return;
	}
	//判断要进行删改的用户是不是管理员用户,禁止对管理员用户进行删改操作
	if(strcmp(ope.name,"root") == 0)
	{
		puts("\n\t\t\tAdministrator user deletion is prohibited");
		return ;
	}
	//通过用户名和密码查看用户表中是否有该用户
	sprintf(sql,"select id_ from users where name_='%s' and password_='%s';",ope.name,ope.passwd);
	executesql(sql);
	g_res = mysql_store_result(g_conn);
	iNum_rows = mysql_num_rows(g_res); // 得到记录的行数  
	int iNum_fields = mysql_num_fields(g_res);
	//将该用户id取出来备用
	while((g_row=mysql_fetch_row(g_res))){
		sprintf(ID,"%s",g_row[0]);
	}
	if(iNum_rows == 0)
	{
		puts("\n\t\t\t!!!No such person!!!");
		puts("\n\t\t\t!!!Please check the name or password enterd!!!");
		return;                                        
	}
	//需要先删除用户 用户组表 关系当中的信息,才可删除用户表中的信息
	sprintf(sql,"delete from userGroupUser where user_id_=%s;",ID);
	executesql(sql);
	sprintf(sql,"delete from users where id_=%s;",ID);
	executesql(sql);
	printf("\n\t\t\tDELETE ------- SUCCESS!!!\n");
	mysql_free_result(g_res);
}
/****************************************************
 * time : 20180704
 * addby : swj
 * function :edi_usergroup_msg()     修改用户组表中用户的信息
 * ******************************************************/
edi_usergroup_msg()
{
#if IF_AND_ENDIF
	printf("ope.tables=%s ope.oldname=%s\n",ope.tables,ope.oldname);
	printf("ope.name = %s\n",ope.name);
	printf("ope.policy = %s\n",ope.policy);
	printf("ope.remark = %s\n",ope.remark);
#endif
	char ID[20];
	//通过用户名和密码查看用户组表中是否有该用户 
	sprintf(sql,"select id_ from usergroups where name_='%s';",ope.oldname);
	executesql(sql);
	g_res = mysql_store_result(g_conn);
	iNum_rows = mysql_num_rows(g_res); // 得到记录的行数  
	int iNum_fields = mysql_num_fields(g_res);
	//将该用户id取出来备用
	while((g_row=mysql_fetch_row(g_res))){
		sprintf(ID,"%s",g_row[0]);
	}
	//printf("ID = %s\n",ID);
	if(iNum_rows == 0)
	{
		puts("\n\t\t\t!!!No such person!!!");
		puts("\n\t\t\t!!!Please check the name or password enterd!!!");
		return;
	}
	//判断要进行改的用户是不是管理员用户,禁止对管理员用户进行操作
	if(strcmp(ope.oldname,"root") == 0)
	{
		puts("\n\t\t\tForbid action other password change for administrator user groups!\n");
		return;
	}
	//修改用户组名称
	if(strlen(ope.name) != 0)
	{
		sprintf(sql,"update usergroups set name_='%s' where id_=%s",ope.name,ID);
		executesql(sql);
	}	
	//修改策略状态
	if(polistate == 0)
	{
		sprintf(sql,"update usergroups set enable_type_=%d where id_=%s",polistate,ID);
                executesql(sql);
	}else{
		sprintf(sql,"update usergroups set enable_type_=%d where id_=%s",polistate,ID);
                executesql(sql);
	}
	//修改策略的内容
	if(strlen(ope.policy) != 0)
	{
		sprintf(sql,"update usergroups set policy_type_='%s' where id_=%s",ope.policy,ID);
		executesql(sql);
	}	
	//修改用户组的备注信息
	if(strlen(ope.remark) != 0)
	{
		sprintf(sql,"update usergroups set remark_='%s' where id_=%s",ope.remark,ID);
		executesql(sql);
	}	
	printf("\n\t\t\tEDIT ------- SUCCESS!!!\n");
}
/****************************************************
 * time : 20180703
 * addby : swj
 * function :edi_user_msg()     修改用户表中用户的信息
 * ******************************************************/
edi_user_msg()
{
	char ID[20];
	//通过用户名和密码查看用户表中是否有该用户 
	sprintf(sql,"select id_ from users where name_='%s' and password_='%s';",ope.oldname,ope.oldpass);
	executesql(sql);
	g_res = mysql_store_result(g_conn);
	iNum_rows = mysql_num_rows(g_res); // 得到记录的行数  
	int iNum_fields = mysql_num_fields(g_res);
	//将该用户id取出来备用
	while((g_row=mysql_fetch_row(g_res))){
		sprintf(ID,"%s",g_row[0]);
	}
#if IF_AND_ENDIF
	printf("ID = %s\n",ID);
#endif
	if(iNum_rows == 0)
	{
		puts("\n\t\t\t!!!No such person!!!");
		puts("\n\t\t\t!!!Please check the name or password enterd!!!");
		return;
	}
	//修改用户密码
	if(strlen(ope.passwd) != 0)
	{
		sprintf(sql,"update users set password_='%s' where id_=%s;",ope.passwd,ID);
		executesql(sql);
	}
	//判断要进行改的用户是不是管理员用户,禁止对管理员用户进行除修改密码以外操作
	if(strcmp(ope.oldname,"root") == 0)
	{
		puts("\n\t\t\tForbid action other password change for administrator users!\n");
		return;
	}
	//修改用户名
	if(strlen(ope.name) != 0)
	{
		sprintf(sql,"update users set name_='%s' where id_=%s",ope.name,ID);
		executesql(sql);
	}	
	//修改认证方式
	if(strlen(ope.authtype) != 0)
	{
		if(strcmp(ope.authtype,"Passauth") == 0)
		{
			auty = Passauth;
			sprintf(ope.authtype,"Passauth");
			sprintf(ope.passauth,"INSERT口令认证需要的口令");
			sprintf(ope.keyauth," ");
		}else if(strcmp(ope.authtype,"Keyauth") == 0){
			auty = Keyauth;
			sprintf(ope.authtype,"Keyauth");
			sprintf(ope.passauth," ");
			sprintf(ope.keyauth,"KEY认证需要的文件");
		}else if(strcmp(ope.authtype,"Thpaauth") == 0){
			auty = Thpaauth;
			sprintf(ope.authtype,"Thpaauth");
			sprintf(ope.passauth," ");
			sprintf(ope.keyauth," ");
		}else{printf("Error authentication type you choice!\n");}
		sprintf(sql,"update users set auth_type_=%d where id_=%s;",auty,ID);executesql(sql);
		sprintf(sql,"update users set dyn_sn_='%s'  where id_=%s;",ope.passauth,ID);executesql(sql);
		sprintf(sql,"update users set dyn_pass_sn_='%s' where id_=%s;",ope.keyauth,ID);executesql(sql);
	}	
	//修改用户的备注信息
	if(strlen(ope.remark) != 0)
	{
		sprintf(sql,"update users set remark_='%s' where id_=%s",ope.remark,ID);
		executesql(sql);
	}	

	//修改用户所属组
	//先判断要更改的用户组的名字是否存在 存在则在usergroups表中取出改用户组id 不存在 提示先添加改用户组
	if(strlen(ope.group) != 0)
	{
		sprintf(sql,"select id_ from usergroups where name_='%s';",ope.group);
		executesql(sql);
		g_res = mysql_store_result(g_conn);
		iNum_rows = mysql_num_rows(g_res); // 得到记录的行数
		iNum_fields = mysql_num_fields(g_res);
		if(iNum_rows == 0){printf("Please add a user group named '%s' first!\n",ope.group);}
		//被修改用户的id为之前定义的ID  更新用户与用户组关系表中ID对应的用户组id
		while((g_row=mysql_fetch_row(g_res))){
			sprintf(sql,"update userGroupUser set usergroup_id_='%s' where user_id_=%s;",g_row[0],ID);
#if IF_AND_ENDIF
			printf("%s\n",sql);
#endif
			executesql(sql);	
		}
	}
	printf("\n\t\t\tEDIT ------- SUCCESS!!!\n");
}
/****************************************************
 * time : 20180629
 * addby : swj
 * function :print_help() 显示帮助菜单
 * ******************************************************/
void print_help()
{
	//./filename operate [tablename] [option] 
	printf("Usage:\n-----------------------------------------\n");
	printf("\t-S\tshow , show user information!\n");
	//-s所有表的信息   -suser_name 用户策略的信息(需要有参数-n时候 才可以)  -stable_name 所选表的信息
	printf("\t-A\tadd , add user information!\n");
	printf("\t-D\tdelete , delete user information!\n");
	printf("\t-E\tedit , edit user information!\n");
	printf("\t-h\thelp , display this help note!\n");
	printf("\t-n \tname , user`s name!\n");
	printf("\t-p\tpassword ,  user`s password!\n");
	//printf("\t-t\ttime , user`s create time(eg:2017-08-18 12:21:11)!\n");
	//printf("\t-c\tcreator , user`s creator id!\n");
	printf("\t-a\tauthentication ,  authentication type(0:pass 1:KEY 2:third)!\n");
	printf("\t-g(+)\tgroup ,  the group to which the user belongs to!\n");
	//printf("\t-s\tshibboleth ,  user`s login password!\n");
	//printf("\t-f \tfile ,  user`s login KEY certificate!\n");
	printf("\t-e(+)\tenable ,  usergroups`s enable type(0:enable 1:disable)!\n");
	printf("\t-o(+)\tpolicy ,  usergroups`s policy type!\n");
	printf("\t-r(+)\tremark ,  remark!\n");
}
int main(int argc,char** argv)
{
	int ch;
	int mode = 0;//mode 增删改查 选项的定义
	int flag = 0;//flag 基本操作 是否有 附件条件的判断
	int error = 0;//authentication 参数是否是0|1|2
	//puts("!!!The system is initializing!!!");
	//初始化链接 
	if(init_mysql())
		print_mysql_error(NULL);//当链接数据库时候 有错误 会报错
	//选择数据库 没有的时候 创建数据库  有的时候 进去数据库
	create_database();
	//创建表
	create_table();	
	//初始化管理员账户
	init_administrator();

	if(argc < 2)
	{
		printf("Invalid parameter number,please check your command......\n");
		return -1;
	}
	//printf("argv[1] = %s\n",argv[1]);
	//如果输入的argv[1]不是users usergroups '-t' 提示参数的类型有误
	if((strcmp(argv[1],"users") != 0) && (strcmp(argv[1],"usergroups") != 0) && (strcmp(argv[1],"-h") != 0))
	{
		printf("Invalid parameter type,please check your command......\n");
		return -1;
	}
	//要操作的表写入 结构体
	sprintf(ope.tables,"%s",argv[1]);
	//opterr = 0;
        //-: 按照顺序扫描命令行参数的个数遇到有效选项时会正常处理,而遇到Operands时却是这样处理的:返回1,optarg赋值为Operands的首地址;
        //-:还可以无效选项或者是丢失选项参数错误;
	while((ch=getopt(argc,argv,"-:hSADEn:p:a:r::g::e::o::")) != -1)  
	{
		switch(ch)
		{
			case 'h':
				mode = MODE_HELP;
				break;
			case 'S':
				mode = MODE_SHOW;
				break;
			case 'A':
				mode = MODE_ADD;
				break;
			case 'D':
				mode = MODE_DELETE;
				break;
			case 'E':
				mode = MODE_EDIT;
				break;
			case 'n':
				flag = 1;
				sprintf(ope.name,"%s",optarg); 
				break;
			case 'p':
				flag = 1;
				sprintf(ope.passwd,"%s",optarg); 
				break;
			case 'a':
				flag = 1;
				sprintf(ope.authtype,"%s",optarg); 
				if(strcmp(optarg,"0") == 0)
				{
					auty = Passauth;
					sprintf(ope.authtype,"Passauth");
					sprintf(ope.passauth,"INSERT口令认证需要的口令");
					sprintf(ope.keyauth," ");
				}else if(strcmp(optarg,"1") == 0){
					auty = Keyauth;
					sprintf(ope.authtype,"Keyauth");
					sprintf(ope.passauth," ");
					sprintf(ope.keyauth,"KEY认证需要的文件");
				}else if(strcmp(optarg,"2") == 0){
					auty = Thpaauth;	
					sprintf(ope.authtype,"Thpaauth");
					sprintf(ope.passauth," ");
					sprintf(ope.keyauth," ");
				}else{error = 1;/*printf("Error type you choice!\n");*/}
				break;
			case 'r':
				flag = 1;
				if(optarg != NULL){ sprintf(ope.remark,"%s",optarg);}
				break;
			case 'g':
				flag = 1;
				if(optarg != NULL){sprintf(ope.group,"%s",optarg);}
				break;
			case 'e':
				flag = 1;
				if(optarg != NULL){
					if(strcmp(optarg,"0") == 0)
						{
							polistate = poliEnable;
					}else if(strcmp(optarg,"1") == 0){
						polistate = poliDisable;
					}else{error = 2;/*printf("Only allowed to enter 0 or 1(0:enable 1:disable)!\n");*/}
				}
				break;
			case 'o':
				flag = 1;
				if(optarg != NULL){sprintf(ope.policy,"%s",optarg);}
				break;
			default:
				//printf("Get unknow option(%c),operation abort...\n",ch);
				break;							
		}
                if(ch == 63) //?   无法识别的选项的判断                
                {
                        printf("./a.out: invalid option -- '%c'\n\n",optopt);
                }
                if(ch == 58) //:   丢失选项参数的判断               
                {
                        printf("./a.out: option requires an argument -- '%c'\n",optopt);
                }
		//如果是help参数 直接跳出不需要检测其他参数	
		if(mode == MODE_HELP)
			break;
	}
#if IF_AND_ENDIF
	printf("mode = %d\n",mode);
	printf("flag = %d\n",flag);
	printf("error = %d\n",error);
#endif
#if IF_AND_ENDIF
	printf("switch(mode) ---- ope.table=%s  ope.name=%s\n",ope.tables,ope.name);			
	printf("switch(mode) ---- ope.passwd=%s  ope.authtype=%s\n",ope.passwd,ope.authtype);			
	printf("switch(mode) ---- ope.group=%s  ope.remark=%s\n",ope.group,ope.remark);			
#endif
	//检测参数是否正确(未定义? 必须的参数未写入)
	if(error == 1)
	{
		printf("The paeameter '-a' Only allows to enter 0 or 1 or 2 after you know it(0:pass 1:KEY 2:third)!\n");
		return;
	}
	if(error == 2)
	{
		printf("The paeameter '-e' Only allows to enter 0 or 1 after you know it(0:enable 1:disable)!\n");
		return;
	}
	switch(mode)
	{	
		case MODE_HELP:
			print_help();
			break;
		case MODE_SHOW:
			if(flag == 1)	
			{
				displayUser();
			}else{
				displayAll();
			}
			break;
		case MODE_ADD:
			if(flag == 1)	
			{
				if(error == 1){printf("Error authentication type you choice!\n");break;}
				if(strcmp(ope.tables,"users") == 0){
					add_user_msg();
				}else{
					add_usergroup_msg();
				}
			}else{
				printf("Please enter other parameters when you want to add someone!! \n");
			}
			break;
		case MODE_DELETE:
			if(flag == 1)
			{
				if(strcmp(ope.tables,"users") == 0){
					del_user_msg();
				}else{
					del_usergroup_msg();
				}
			}else{
				printf("Please enter other parameters when you want to add someone!! \n");
			}
			break;
		case MODE_EDIT:
			if(flag == 1)
			{
#if IF_AND_ENDIF
				printf("argc = %d\n",argc);
#endif
				//i用于遍历命令行字符串 j记录'where'字符后有参数个数  m标记'where'后的参数内容
				int i = 0,j = 0,m = 0;
				int nv = 0,pv = 0;
				int whereflag = 0,nameflag = 0,passflag = 0;
				for(i=0;i 0) && (m <= argc)) //	'name'字符在'where'字符之后
					{
						if(strcmp(argv[i],"name") == 0)
						{
							nameflag = 1;
							nv = i;
#if IF_AND_ENDIF
							printf("nv = %d  argv[nv+1]=%s\n",nv,argv[nv+1]);
#endif
							//如果'name'字符后有值 则把nv值设置为1并把之前的用户名name 赋值给ope.oldname
							if(argv[nv+1] != NULL){sprintf(ope.oldname,"%s",argv[nv+1]);nv = 1;}
						}
						if(strcmp(argv[i],"password") == 0)
						{
							passflag = 1;
							pv = i;
							if(argv[pv+1] != NULL){sprintf(ope.oldpass,"%s",argv[pv+1]);pv = 1;}
						}
						m++;
					}
				}
				//printf("whereflag = %d\n",whereflag);
				//判断命令行内是否有'where'字符
				if(whereflag == 0)
				{
					printf("Modification operations must have 'where' characters!\n");
					break;
				}
				//判断 where 后 的参数个数为偶数个
				printf("j = %d\n",j);
				if((j>0) && (j % 2 == 0)){
				}else{
					printf("Incorrect number of parameters after 'where' character(Even number)!\n");break;
				}
				//判断命令行内'where'字符后 是否有'name'字符
				//printf("nameflag = %d\n",nameflag);
				if(nameflag == 0)
				{
					printf("The 'where' character must be followed by a 'name' character!\n");
					break;
				}
				//判断'name'字符后是否有值
				if(nv != 1){printf("Must have a value after the 'name' parameter!\n");break;}

				if(strcmp(ope.tables,"users") == 0){
					//判断命令行内'where'字符后 是否有'password'字符
					if(passflag == 0)
					{
						printf("The 'where' character must be followed by a 'password' character!\n");
						break;
					}
					//判断'password'字符后是否有值
					if(pv != 1){printf("Must have a value after the 'password' parameter!\n");break;}
#if IF_AND_ENDIF
					printf("ope.oldname = %s\n",ope.oldname);
					printf("ope.oldpass = %s\n",ope.oldpass);
					printf("ope.tables = %s  ope.name = %s\n",ope.tables,ope.name);
#endif
					edi_user_msg();
				}else{
					edi_usergroup_msg();
				}
			}else{
				printf("Please enter other parameters when you want to edit someone!! \n");
			}	
			break;
		default:
			printf("Please enter other parameters(eg:-h|-S|-A|-D|-E)!!\n");
			break;
	}
	mysql_close(g_conn);
	return EXIT_SUCCESS;
}



你可能感兴趣的:(C,语言,数据库,对字符串的操作,getopt(),c,mysql,命令行,用户,用户组)