/****************************************************************************
** ui.h extension file, included from the uic-generated form implementation.
**
** If you want to add, delete, or rename functions or slots, use
** Qt Designer to update this file, preserving your code.
**
** You should not define a constructor or destructor in this file.
** Instead, write your code in functions called init() and destroy().
** These will automatically be called by the form's constructor and
** destructor.
*****************************************************************************/
/*

segatex written by Shintaro Fujiwara.
This code is dedicated to my daughter, mone.
*/
/*uninstd.h should be the first.*/
#include <unistd.h>
#include <stdio.h>
#include <time.h>

#include <iostream>
#include <fstream>
#include <string.h>
#include <vector>
#include <algorithm>
#include <map>
#include <boost/regex.hpp>
#include <qfile.h>
#include <qtextedit.h>
/*for segate_show_status()*/
#include <selinux/selinux.h>
#include <selinux/get_default_type.h>
/*for segatex_show_ps()*/
#include <stdlib.h>
/*for segatex_solve_problem()*/
#include <sys/io.h>
//#include <fcntl.h>
//#include <sys/stat.h>
//#include <sys/types.h>
#include <boost/tokenizer.hpp>

/*These should be globals.*/

int log_state = 0;
time_t the_time;
long log_from_time = 0;
int log_from_time_int = 0;

#define MAX_LOG 8460

/*prototype declaration*/
int segatex_set_time_real();
int segatex_set_time_all_real();
void segatex_set_time();
void segatex_set_time_all();
void segatex_yum_update();
void segatex_module_list();
void segatex_load_from_my_policy();
void segatex_remove_my_policy();
void segatex_write_to_my_policy();
void segatex_show_yum_update();
void segatex_show_interface();

void segatex::segatex_remove_my_policy()
{
        using namespace std;
        #define PWD_BUF 8600
        const char* remove_file="./remove_echo";
        ofstream os;
        os.open(remove_file);
        if(os){
                FILE *read_fp;
                #define SIZE_TMP 8192
                char buffer[SIZE_TMP];
                int chars_read;
                memset(buffer, '\0', sizeof(buffer));
                read_fp = popen("semodule -r my_policy_by_segatex", "r");
                if(read_fp != NULL){
                        chars_read = fread(buffer, sizeof(char), SIZE_TMP, read_fp);
                        while(chars_read>0){
                                buffer[chars_read -1] = '\0';
                                //os << "Reading:-" << endl;
                                os << buffer;
                                chars_read= fread(buffer, sizeof(char), SIZE_TMP, read_fp);
                        }
                        pclose(read_fp);
                }
                os.close();
                QFile file( remove_file ); // Read the text from a file
                if ( file.open( IO_ReadOnly ) ) {
                        QTextStream stream( &file );
                        textEdit2->setText( stream.read() );
                }
		status_label_1->setText("Please click module_list button and check policy has been removed !");
        }
}

void segatex::segatex_module_list()
{
        using namespace std;
        #define PWD_BUF 8600
        const char* module_list_file="./module_list";
        ofstream os;
        os.open(module_list_file);
        if(os){
                FILE *read_fp;
                #define SIZE_TMP 8192
                char buffer[SIZE_TMP];
                int chars_read;
                memset(buffer, '\0', sizeof(buffer));
                read_fp = popen("semodule -l", "r");
                if(read_fp != NULL){
                        chars_read = fread(buffer, sizeof(char), SIZE_TMP, read_fp);
                        while(chars_read>0){
                                buffer[chars_read -1] = '\0';
                                //os << "Reading:-" << endl;
                                os << buffer;
                                chars_read= fread(buffer, sizeof(char), SIZE_TMP, read_fp);
                        }
                        pclose(read_fp);
                }
                os.close();
                QFile file( module_list_file ); // Read the text from a file
                if ( file.open( IO_ReadOnly ) ) {
                        QTextStream stream( &file );
                        textEdit2->setText( stream.read() );
                }
        }
}

void segatex::segatex_load_from_my_policy()
{
	using namespace std;
        const char* filename_policy="./my_policy_by_segatex.te";
	ifstream is;
	is.open(filename_policy);
	if(is){
		QFile file( filename_policy ); 
		if ( file.open( IO_ReadOnly ) ) {
			QTextStream stream( &file );
			textEdit2->setText( stream.read() );
		}
		is.close();
	}else{
		;//do nothing
	}
}

void segatex::segatex_write_to_my_policy()
{
	using namespace std;
	const char* my_policy_file="./my_policy_by_segatex.te";
	const char* load_my_policy_file="./load_my_policy";
	ifstream os_pre;
	os_pre.open(my_policy_file);
	if(os_pre){
		os_pre.close();
		ofstream os;
		os.open(load_my_policy_file);
		if(os){
			//int check=chdir(my_data_dir);
			int check=0;
			if(check==0){
				FILE *read_fp_install;
				FILE *read_fp;
				#define SIZE_TMP 8192
				char buffer[SIZE_TMP];
				int chars_read;
				memset(buffer, '\0', sizeof(buffer));
				read_fp_install = popen("make -f /usr/share/selinux/devel/Makefile", "r");
				if(read_fp_install != NULL){
					chars_read = fread(buffer, sizeof(char), SIZE_TMP, read_fp_install);
					while(chars_read>0){
						buffer[chars_read -1] = '\0';
						//os << "Reading:-" << endl;
						os << buffer;
						chars_read= fread(buffer, sizeof(char), SIZE_TMP, read_fp_install);
					}
					pclose(read_fp_install);
				}
				read_fp = popen("semodule -i my_policy_by_segatex.pp", "r");
				if(read_fp != NULL){
					chars_read = fread(buffer, sizeof(char), SIZE_TMP, read_fp);
					while(chars_read>0){
						buffer[chars_read -1] = '\0';
						//os << "Reading:-" << endl;
						os << buffer;
						chars_read= fread(buffer, sizeof(char), SIZE_TMP, read_fp);
					}
					pclose(read_fp);
				}
			}
			os.close();
			QFile file( load_my_policy_file ); // Read the text from a file
				if ( file.open( IO_ReadOnly ) ) {
				QTextStream stream( &file );
				textEdit2->setText( stream.read() );
			}
		status_label_1->setText("Please click module_list button and check policy has been installed !");
		}
	}
}
void segatex::segatex_show_yum_update()
{
        status_label_1->setText("yum install/updating SELinx related rpms. Please wait for a while...");
}

void segatex::segatex_yum_update()
{
	using namespace std;
	#define PWD_BUF 8600
	const char* yum_update_file="./yum_update";
	ofstream os;
	os.open(yum_update_file);
	if(os){
		FILE *read_fp_install;
		FILE *read_fp;
		#define SIZE_TMP 8192
		char buffer[SIZE_TMP];
		int chars_read;
		memset(buffer, '\0', sizeof(buffer));
		read_fp_install = popen("yum -y install selinux-policy* libsepol policycoreutils checkpolicy", "r");
		if(read_fp_install != NULL){
			chars_read = fread(buffer, sizeof(char), SIZE_TMP, read_fp_install);
			while(chars_read>0){
				buffer[chars_read -1] = '\0';
				//os << "Reading:-" << endl;
				os << buffer;
				chars_read= fread(buffer, sizeof(char), SIZE_TMP, read_fp_install);
			}
			pclose(read_fp_install);
		}
		read_fp = popen("yum -y update selinux-policy* libsepol policycoreutils checkpolicy", "r");
		if(read_fp != NULL){
			chars_read = fread(buffer, sizeof(char), SIZE_TMP, read_fp);
			while(chars_read>0){
				buffer[chars_read -1] = '\0';
				//os << "Reading:-" << endl;
				os << buffer;
				chars_read= fread(buffer, sizeof(char), SIZE_TMP, read_fp);
			}
			pclose(read_fp);
		}
		os.close();
		QFile file( yum_update_file ); // Read the text from a file
		if ( file.open( IO_ReadOnly ) ) {
			QTextStream stream( &file );
			textEdit1->setText( stream.read() );
		}
	}
}


void segatex::segatex_audit_2_allow()
{
	using namespace std;
	#define PWD_BUF 8600
	const char* audit_2_allow_file="./local.te";
	ofstream os;
	os.open(audit_2_allow_file);
	if(os){
		FILE *read_fp;
		#define SIZE_TMP 8192
		char buffer[SIZE_TMP];
		int chars_read;
		memset(buffer, '\0', sizeof(buffer));
		read_fp = popen("audit2allow -m local -i /var/log/audit/audit.log", "r");
		if(read_fp != NULL){
			chars_read = fread(buffer, sizeof(char), SIZE_TMP, read_fp);
			while(chars_read>0){
				buffer[chars_read -1] = '\0';
				//os << "Reading:-" << endl;
				os << buffer;
				chars_read= fread(buffer, sizeof(char), SIZE_TMP, read_fp);
			}
			pclose(read_fp);
		}
		os.close();
		QFile file( audit_2_allow_file ); // Read the text from a file
		if ( file.open( IO_ReadOnly ) ) {
			QTextStream stream( &file );
			textEdit1->setText( stream.read() );
		}
	}
}

void segatex::segatex_audit_2_why()
{
	using namespace std;
	#define PWD_BUF 8600
	const char* audit_2_why_file="./local_te_why";
	ofstream os;
	os.open(audit_2_why_file);
	if(os){
		FILE *read_fp;
		#define SIZE_TMP 8192
		char buffer[SIZE_TMP];
		int chars_read;
		memset(buffer, '\0', sizeof(buffer));
		read_fp = popen("audit2why < /var/log/audit/audit.log", "r");
		if(read_fp != NULL){
			chars_read = fread(buffer, sizeof(char), SIZE_TMP, read_fp);
			while(chars_read>0){
				buffer[chars_read -1] = '\0';
				//os << "Reading:-" << endl;
				os << buffer;
				chars_read= fread(buffer, sizeof(char), SIZE_TMP, read_fp);
			}
			pclose(read_fp);
		}
		os.close();
		QFile file( audit_2_why_file ); // Read the text from a file
		if ( file.open( IO_ReadOnly ) ) {
			QTextStream stream( &file );
			textEdit1->setText( stream.read() );
		}
	}
}

int segatex::segatex_set_time_real()
{
        log_from_time = time((time_t*)0);
        log_from_time_int = (int)log_from_time;
        log_from_time_int = log_from_time_int - 60*30;
        return log_from_time_int;
}
int segatex::segatex_set_time_all_real()
{
        log_from_time_int = 0;
        return log_from_time_int;
}
void segatex::segatex_set_time()
{
	log_state = 1;
}

void segatex::segatex_set_time_all()
{
	log_state = 0;
}

void segatex::segatex_show_interface()
{
	/*全般的に正規表現の扱いがなれていないため、姑息な手段をとって苦労している...*/

	using namespace std;
	using namespace boost;
	const char* filename="/var/log/audit/audit.log";
	const char* filename_my_log="./audit_log_mine_must_be_here";
        const char* filename_policy="./my_policy_by_segatex.te";
	if(log_state == 0){
		log_from_time_int = segatex::segatex_set_time_all_real(); 
	}
	else if(log_state == 1){
		log_from_time_int = segatex::segatex_set_time_real();
	}
	char buffer_engine[MAX_LOG +1];
        char buffer_c[MAX_LOG];

	//read from engine and store them to v_engine
        const char* filename_engine="./selpaw_interface.csv";

        ifstream is_engine;
        ofstream os_engine_test;
	ofstream os_policy;
        is_engine.open(filename_engine);
	fstream os_my_log(filename_my_log,ios::in | ios::app);
	fstream os_my_log_2(filename_my_log, ios::app);
	//When selpaw_interface.csv is missing.
        if(!is_engine){
		os_policy.open(filename_policy);
		if(os_policy){
			os_policy << "selpaw_interface.csv is missing!!" << endl;
		}
		is_engine.close();
	
		QFile file( filename_policy); // Read the text from a file
		if ( file.open( IO_ReadOnly ) ) {
			QTextStream stream( &file );
			textEdit1->setText( stream.read() );
		}
	//When selpaw_interface.csv exists.
        }else{
		vector<string> v_engine;
		vector<string>::iterator p_engine, p_engine_end;
		do{
			is_engine.getline(buffer_engine, sizeof buffer_engine);
			v_engine.push_back(buffer_engine);
			string buffer_engine_str=buffer_engine;
			//os_engine_test << buffer_engine << endl;
		}while(!is_engine.eof());
		//os_engine_test.close();
		ifstream is;
		is.open(filename);
		//When log is missing.
		if(!is.getline(buffer_c, sizeof buffer_c)){
			os_policy.open(filename_policy);
			if(os_policy){
				os_policy << "There is no line in this log or not running auditd." << endl;
			}
			is.close();
			QFile file( filename_policy); // Read the text from a file
			if ( file.open( IO_ReadOnly ) ) {
				QTextStream stream( &file );
				textEdit1->setText( stream.read() );
			}
		//When log is existing.
		}else{
			vector<string> v;
			vector<string>::iterator p, p_end;

			vector<string> v2;
			vector<string>::iterator p2_v, p2_v_end;
			vector<string> v3;
			vector<string>::iterator p3_v, p3_v_end;
			multimap<string ,string>::iterator p2,p2_end;
			multimap<string ,string>::iterator p2_m,p2_m_end;
			//write to my_log
			char buffer[MAX_LOG];

			//os_my_logをひらいて、最後の行のunixtimeをintに変換して変数に入れておく
			os_my_log.open(filename_my_log);
			if(os_my_log){
				//ログからdeniedメッセージを積む
				do{
					os_my_log.getline(buffer, sizeof buffer);
					v3.push_back(buffer);
				}while(!os_my_log.eof());
			}else{
				;//do nothing
			}
			os_my_log.close();
			string u_time_str = "";
			for(p3_v=v3.begin(); p3_v<v3.end()-1;p3_v++){
				u_time_str = *p3_v;
				//cout << u_time_str << endl;
			}
			const char* u_time = "\\([0-9]{10}";
			//cout << u_time_str << endl;
			const char* u_time_char_pre = u_time_str.c_str();
			regex u_time_exp(u_time);
			cmatch what;
			int u_time_int=0;
			int u_time_present_int=0;
			if(regex_search(u_time_char_pre,what,u_time_exp)){
				string u_time_match = what[0];
				string blank_str="";
				u_time_match=u_time_match.replace(0,1,blank_str);
				//cout << u_time_match << endl;
				const char* u_time_char = u_time_match.c_str();
				u_time_int= atoi(u_time_char);
				//cout << u_time_int << endl;
			}else{
				//cout << "no-match" << endl;
			}

			os_my_log_2.open(filename_my_log);
			if(os_my_log_2){
				const char* words="denied";
				//ログからdeniedメッセージを積む
				do{
					is.getline(buffer, sizeof buffer);
					if(strstr(buffer,words)){
						const char* buffer_const_char= buffer;
						//もしu_time_intよりも大きければ、os_my_logに追記していく
						if(regex_search(buffer_const_char,what,u_time_exp)){
							string u_time_match_present = what[0];
							//cout << u_time_match_present << endl;
							string blank_str="";
							u_time_match_present=u_time_match_present.replace(0,1,blank_str);
							const char* u_time_match_present_char = u_time_match_present.c_str();
							u_time_present_int= atoi(u_time_match_present_char);
							if(u_time_present_int > u_time_int){
								//cout << "u_time_present_int" << u_time_present_int << endl;
								//cout << "u_time_int" << u_time_int << endl;
								//cout << "buffer:" << buffer << endl;
								os_my_log_2 << buffer << endl;
							}
						}else{
							//cout << "no-match" << endl;
						}
					}
				}while(!is.eof());
			}else{
				;//do nothing
			}
			is.close();
			os_my_log_2.close();

			os_my_log.open(filename_my_log);
			//open policy file
			os_policy.open(filename_policy);
			if(os_policy)
			{
				char buffer[MAX_LOG];
				const char* words="denied";
				//マイログからdeniedメッセージを積む
				//ファイルの先頭にポインタを移動しておく
				os_my_log.seekg(ios::beg);
				do{
					os_my_log.getline(buffer, sizeof buffer);
					if(strstr(buffer,words)){
						v.push_back(buffer);
					}
				}while(!os_my_log.eof());
				//if there are no denied log
				if(v.size()==0){
					os_policy << "Your log is perfect !!" << endl;
					os_policy << "You don't have to configure SELinux policy at all !!" << endl;
					QFile file( filename_policy); // Read the text from a file
						if ( file.open( IO_ReadOnly ) ) {
						QTextStream stream( &file );
						textEdit1->setText( stream.read() );
					}
				//if there are any denied log
				}else{
					const char* den = "denied";
					const char* log_time = "audit\\([0-9]{10}";
					const char* scontext = "scontext([^[:blank:]]*)([:blank:])?";
					const char* scontext_rev = "t_[a-z0-9_]([^:]*)?";
					const char* tcontext = "tcontext([^[:blank:]]*)([:blank:])?";
					const char* tcontext_rev = "t_[a-z0-9_]([^:]*)?";
					const char* tclass = "tclass(.*)";
					const char* tclass_2 = "[a-z0-9_]([^=]*)?";
					const char* acc = "\\{(.*)\\}";
					const char* role = ":[a-z0-9_]*_r";

					regex denied_exp(den);
					regex log_time_exp(log_time);
					regex domain_exp(scontext);
					regex domain_rev_exp(scontext_rev);
					regex resource_exp(tcontext);
					regex resource_rev_exp(tcontext_rev);
					regex object_class_exp(tclass);
					regex object_class_exp_2(tclass_2);
					regex access_vector_exp(acc);
					regex role_exp(role);

					string log_time_string = "";
					int log_time_int = 0;
					string policy_selinux = "";
					string allow_pre = "allow";
					string blank_w = " ";
					string colon = ":";
					string semicolon = ";";
					string domain = "";
					string domain_2 = "";
					string resource = "";
					string resource_2 = "";
					string object_class_pre = "";
					string object_class = "";
					string access_vector = "";
					string role_str = "";
					//string blank_str = "";
					//multimap<string, string>macro_pre;
					multimap<string, string> pattern_matched;
					multimap<string, string>::iterator p_pattern_matched;

					multimap<string, string> pattern_not_matched;
					multimap<string, string>::iterator p_pattern_not_matched;
		/*
					multimap<string, string> pattern_matched_objclass;
					multimap<string, string>::iterator p_pattern_matched_objclass;
		*/
					multimap<string, string> pattern_matched_access_vector;
					multimap<string, string>::iterator p_pattern_matched_access_vector;
		/*
					multimap<string, string> pattern_matched_domain;
					multimap<string, string>::iterator p_pattern_matched_domain;
					multimap<string, string> pattern_matched_tclass;
					multimap<string, string>::iterator p_pattern_matched_tclass;
		*/
		//名前は、not_matchedになっているが、全ての状態をマルチマップに必要な組み合わせで入れておく*/
					multimap<string, string> pattern_not_matched_objclass;
					multimap<string, string>::iterator p_pattern_not_matched_objclass;
					multimap<string, string> pattern_not_matched_access_vector;
					multimap<string, string>::iterator p_pattern_not_matched_access_vector;
					multimap<string, string> pattern_not_matched_domain;
					multimap<string, string>::iterator p_pattern_not_matched_domain;
					multimap<string, string> pattern_not_matched_tclass;
					multimap<string, string>::iterator p_pattern_not_matched_tclass;
					multimap<string, string> pattern_allow_not_matched_echo;
					multimap<string, string>::iterator p_pattern_allow_not_matched_echo;
					multimap<string, string> pattern_matched_tclassobjclass_interface;
					multimap<string, string>::iterator p_pattern_matched_tclassobjclass_interface;

					vector<string> v_source_interface_pre;
					vector<string>::iterator p_source_interface_pre, p_source_interface_pre_end;

					vector<string> v_matched_tmp_objclass;
					vector<string>::iterator p_matched_tmp_objclass, p_matched_tmp_objclass_end;
					vector<string> v_matched_objclass_accv;
					vector<string>::iterator p_matched_objclass_accv, p_matched_objclass_accv_end;
					vector<string> v_matched_tmp_domain;
					vector<string>::iterator p_matched_tmp_domain, p_matched_tmp_domain_end;

					vector<string> v_tmp_objclass;
					vector<string>::iterator p_tmp_objclass, p_tmp_objclass_end;
					vector<string> v_accv;
					vector<string>::iterator p_accv, p_accv_end;
					vector<string> v_tmp_domain;
					vector<string>::iterator p_tmp_domain, p_tmp_domain_end;


					vector<string> v_allow_first;
					vector<string>::iterator p_allow_first, p_allow_first_end;
					vector<string> v_allow_last;
					vector<string>::iterator p_allow_last, p_allow_last_end;
					vector<string> v_domain_interface;
					vector<string>::iterator p_domain_interface, p_domain_interface_end;

					vector<string> v_interface_raw;
					vector<string>::iterator p_interface_raw, p_interface_raw_end;

					vector<string> v_role;
					vector<string>::iterator p_role, p_role_end;

					for(p=v.begin(); p<v.end();p++){
						string source_ready = *p;
						//os_policy << source_ready << endl;
						const char* source = source_ready.c_str();
						cmatch what;
						if(regex_search(source,what,denied_exp)){
							if(regex_search(source,what,domain_exp)){
								domain = what[0];
								//os_policy << domain << endl;
								const char* domain_char = domain.c_str();
								if(regex_search(domain_char,what,role_exp)){
									role_str = what[0];
									string blank_str="";
									role_str=role_str.replace(0,1,blank_str);
									v_role.push_back(role_str.c_str());
									//os_policy << role_str << endl;
								}
								int str_length = strlen(domain.c_str());
								int i=str_length;
								string str_rev="";
								string str_rev_all="";
								for(i=str_length;i>0;i--){
									str_rev = domain.substr(i,1);
									str_rev_all = str_rev_all + str_rev;
								}
								const char* str_rev_all_char = str_rev_all.c_str();
								if(regex_search(str_rev_all_char,what,domain_rev_exp)){
									domain_2 = what[0];
									int str_length = strlen(domain_2.c_str());
									int i=str_length;
									string str_rev="";
									string str_rev_all="";
									for(i=str_length;i>=0;i--){
										str_rev = domain_2.substr(i,1);
										str_rev_all = str_rev_all + str_rev;
									}
									domain = str_rev_all;
								}
							}
							if(regex_search(source,what,resource_exp)){
								resource = what[0];
								int str_length = strlen(resource.c_str());
								int i=str_length;
								string str_rev="";
								string str_rev_all="";
								for(i=str_length;i>0;i--){
									str_rev = resource.substr(i,1);
									str_rev_all = str_rev_all + str_rev;
								}
								const char* str_rev_all_char = str_rev_all.c_str();
								if(regex_search(str_rev_all_char,what,resource_rev_exp)){
									resource_2 = what[0];
									int str_length = strlen(resource_2.c_str());
									int i=str_length;
									string str_rev="";
									string str_rev_all="";
									for(i=str_length;i>=0;i--){
										str_rev = resource_2.substr(i,1);
										str_rev_all = str_rev_all + str_rev;
									}
									resource = str_rev_all;
								}
							}
							if(regex_search(source,what,object_class_exp)){
								object_class_pre = what[0];
								int str_length = strlen(object_class_pre.c_str());
								int i=str_length;
								string str_rev="";
								string str_rev_all="";
								for(i=str_length;i>0;i--){
									str_rev = object_class_pre.substr(i,1);
									str_rev_all = str_rev_all + str_rev;
								}
								const char* str_rev_all_char = str_rev_all.c_str();
								if(regex_search(str_rev_all_char,what,object_class_exp_2)){
									object_class = what[0];
									int str_length = strlen(object_class.c_str());
									int i=str_length;
									string str_rev="";
									string str_rev_all="";
									for(i=str_length;i>=0;i--){
										str_rev = object_class.substr(i,1);
										str_rev_all = str_rev_all + str_rev;
									}
									object_class = str_rev_all;
								}
							}
							if(regex_search(source,what,access_vector_exp)){
								access_vector = what[0];
							}
							policy_selinux = allow_pre + blank_w +
								domain + blank_w + resource + colon + object_class + blank_w + access_vector;
							if(regex_search(source,what,log_time_exp)){
								log_time_string = what[0];
								log_time_string = log_time_string.substr(6);
								log_time_int = atoi(log_time_string.c_str());
							}
							if(log_from_time_int <= log_time_int){
								v2.push_back(policy_selinux.c_str());
							}
						  }
					}
					sort(v2.begin(),v2.end());
					p2_v_end = unique(v2.begin(),v2.end());
					const char* m_pre = "(.*):([^[:space:]]*)([:space:])?";
					const char* m_interface_pre = "[a-z]([^[:space:]]*):([^[:space:]]*)([:space:])?";
					const char* m_domain_pre = "[a-z0-9_]*_t";
					const char* m_tclass_pre = "[a-z0-9_]*_t:";
					const char* m_objclass_pre = ":[a-z0-9_]*";
					const char* m_acc = "\\{(.*)\\}";
					const char* m_blank = "[a-z0-9_](.*)[a-z0-9_]";
					regex m_pre_exp(m_pre);
					regex m_interface_pre_exp(m_interface_pre);
					regex m_domain_pre_exp(m_domain_pre);
					regex m_tclass_pre_exp(m_tclass_pre);
					regex m_objclass_pre_exp(m_objclass_pre);
					regex m_access_vector_exp(m_acc);
					regex m_blank_exp(m_blank);
					string source_macro_pre="";
					string source_interface_pre="";
					string source_domain_pre="";
					string source_tclass_pre="";
					string source_objclass_pre="";
					string source_access_vector_pre="";
					string source_interface_pre_prev="";
					string source_interface_engine="";
					string access_vector_m = "";
					string blank_m = "";

					int source_macro_numbers=0;
					for(p2_v=v2.begin(); p2_v < v2.end(); p2_v++){
						string source_macro = *p2_v;

						/*for debug*/
						//生マクロ文
						//os_policy << source_macro << endl;
						/*end for debug*/
						const char* source_m = source_macro.c_str();
						cmatch what;
						if(regex_search(source_m,what,m_domain_pre_exp)){
							source_domain_pre  = what[0];
							/*for debug*/
						//	os_policy << source_domain_pre << endl;	
						} 
						if(regex_search(source_m,what,m_tclass_pre_exp)){
							source_tclass_pre  = what[0];
							int length=strlen(source_tclass_pre.c_str());
							string blank_str="";
							source_tclass_pre=source_tclass_pre.replace(length - 1,1,blank_str);
							/*for debug*/
							//os_policy << source_tclass_pre << endl;	
						} 
						if(regex_search(source_m,what,m_objclass_pre_exp)){
							source_objclass_pre  = what[0];
							string blank_str="";
							source_objclass_pre=source_objclass_pre.replace(0,1,blank_str);
							/*for debug*/
						//	os_policy << source_objclass_pre << endl;	
						} 
						if(regex_search(source_m,what,m_access_vector_exp)){
							source_access_vector_pre  = what[0];
							int length=strlen(source_access_vector_pre.c_str());
							string blank_str="";
							source_access_vector_pre=source_access_vector_pre.replace(length - 2,2,blank_str);
							source_access_vector_pre=source_access_vector_pre.replace(0,2,blank_str);
							/*for debug*/
							//os_policy << source_access_vector_pre << endl;	
						} 
						if(regex_search(source_m,what,m_interface_pre_exp)){
							source_interface_pre  = what[0];
							/*for debug*/
							//os_policy << source_interface_pre << endl;	
							/*end for debug*/
							//ok,これで、httpd_t:file 等がでた。
							if(source_interface_pre != source_interface_pre_prev){
								v_source_interface_pre.push_back(source_interface_pre.c_str());
								source_interface_pre_prev  = what[0];
							}
						} 
						/*マッチしたものも含め、multimapに読み込んでおき、後で取り出す準備をする*/
						pattern_matched.insert(pair<string, string>(source_interface_pre,source_domain_pre));
						pattern_not_matched.insert(pair<string, string>(source_interface_pre,source_macro));
						pattern_not_matched_objclass.insert(pair<string, string>(source_interface_pre,source_objclass_pre));
						pattern_not_matched_access_vector.insert(pair<string, string>(source_objclass_pre,source_access_vector_pre));
						pattern_not_matched_domain.insert(pair<string, string>(source_interface_pre,source_domain_pre));
						pattern_not_matched_tclass.insert(pair<string, string>(source_interface_pre,source_tclass_pre));
						source_macro_numbers++;
					}
					int interface_numbers=0;
					//string was_not_matched = " was not matched !";
					string source_interface_pre_comp="";
					for(p_source_interface_pre=v_source_interface_pre.begin(); p_source_interface_pre < v_source_interface_pre.end(); p_source_interface_pre++){
						//検索文字列は、source_interface_pre すなわち一例：httpd_t:file
						string source_interface_pre = *p_source_interface_pre;
						//os_policy << "source_interface_pre:" << source_interface_pre << endl;
						//const char* m_interface_accv = ":(.*)\\{(.*)\\}";
						const char* m_interface_accv_pre = ":(.*)\\}";
						const char* m_interface_accv = "(:[a-z0-9_]*)[[:space:]]";
						regex m_interface_accv_exp(m_interface_accv);
						regex m_interface_accv_pre_exp(m_interface_accv_pre);
						string source_interface_accv_pre;
						string source_interface_accv;

						cmatch what;
						string blank_str = " ";
						regex re("[a-z0-9_]*,");
						string plus_source_interface_pre = blank_str + source_interface_pre;
						//os_policy << "plus_source_interface_pre:" << plus_source_interface_pre << endl;
						const char* m_engine = plus_source_interface_pre.c_str();
						regex m_interface_engine_exp(m_engine);
						/*read the engine and check*/
						/*エンジンファイルを上から検索する。このforスコープの中に落ちれば、マッチしている*/
						for(p_engine=v_engine.begin(); p_engine < v_engine.end(); p_engine++){
							string source_macro_engine = *p_engine;
							const char* source_m_engine = source_macro_engine.c_str();
							//検索文字列からできたregexは、m_interface_engine_exp すなわち一例：httpd_t:file
							if(regex_search(source_m_engine,what,m_interface_engine_exp)){
								source_interface_engine  = what[0];
								//segatex2.05時加筆。問題がわかった！！tmp_t:fileとかが、つぎにxxx_tmp_t:fileにも引っかかってしまうのである。ということで、上のように、始めに空白を付けて検索してみた。
								//os_policy << source_interface_pre ;
								//os_policy << " matched !!" << endl;
								
								/*interface all sentence*/
								//os_policy << source_macro_engine << endl;
								/*end interface all sentence*/
								/*ここでは、マッチした場合インタフェースが持つobjectclassのアクセスベクタをマルチマップに積む*/
								if(regex_search(source_m_engine,what,m_interface_accv_pre_exp)){
									source_interface_accv_pre  = what[0];
									const char* source_interface_accv_pre_str = source_interface_accv_pre.c_str();
									//os_policy << source_interface_accv_pre << endl;
									if(regex_search(source_interface_accv_pre_str,what,m_interface_accv_exp)){
										source_interface_accv  = what[0];
										int length=strlen(source_interface_accv.c_str());
										string blank_str="";
										source_interface_accv=source_interface_accv.replace(length,1,blank_str);
										source_interface_accv=source_interface_accv.replace(0,1,blank_str);
										//os_policy << source_interface_accv << endl;
										//v_matched_objclass_accv.push_back(source_interface_accv.c_str());
									}
									int length=strlen(source_interface_accv_pre.c_str());
									string blank_str="";
									string bracket_first_str="{";
									source_interface_accv_pre=source_interface_accv_pre.replace(length -1,1,blank_str);
									int bracket_first_position=source_interface_accv_pre.find_first_of(bracket_first_str);
									source_interface_accv_pre=source_interface_accv_pre.replace(0,bracket_first_position + 1,blank_str);
									//os_policy << source_interface_accv_pre << endl;
									regex tmp_re("[[:space:]]([^[:space:]]*)[a-z0-9_]*");
									string::const_iterator it=source_interface_accv_pre.begin(), end=source_interface_accv_pre.end();
									while(it != end){
										smatch result;
										if( !regex_search(it, end, result, tmp_re)){
											break;
										}
										//os_policy << "interface_core<" << source_interface_accv << ":" << result.str() << ">" << endl;
										pattern_matched_access_vector.insert(pair<string, string>(source_interface_accv,result.str()));
										it = result[0].second;
									}
								}
								/*インタフェースの持つobjectclassのアクセスベクタ積みはここまで*/
								if(regex_search( source_macro_engine, re )){
									string::const_iterator it=source_macro_engine.begin(), end=source_macro_engine.end();
									int i=0;
									string check_str = ":";
									string bracket_first_str = "(";
									string bracket_last_str = ")";
									while( it != end){
										//マッチする箇所を先頭から順に列挙
										smatch result;
										if( !regex_search(it, end, result, re)){
											break;
										}
										//os_policy << result.str() << endl;
										it = result[0].second;
										if(i==2){
											//ここで、httpd_t:file 等を、multimapからさがして、domainに変換し、matchedのベクタに積むとできあがり。
											//とおもったら、interfaceはもっと広いので、interface自身をベクタに積んで、もう一回エンジンにかけてobjectclass,access_vectorを出す必要があったぞ
											int length=strlen(result.str().c_str());
											//2.03加筆部分（空白行が入るのを防ぐため）
											if(length >1){
												string blank_str="";
												string interface_raw_str=result.str().replace(length -1,1,blank_str);
												v_interface_raw.push_back(interface_raw_str.c_str());
												//os_policy << interface_raw_str << ":" <<endl;
												p_pattern_not_matched_domain=pattern_not_matched_domain.find(source_interface_pre);
												if(p_pattern_not_matched_domain != pattern_not_matched_domain.end()){
													do{
														int length=strlen(result.str().c_str());
														string blank_str="";
														string result_str=result.str().replace(length -1,1,blank_str);
														
														//string domain_interface_echo = result.str() + bracket_first_str + p_pattern_not_matched_domain->second + bracket_last_str;  
														string domain_interface_echo = result_str + bracket_first_str + p_pattern_not_matched_domain->second + bracket_last_str;  
														//ここでインタフェース(ドメイン)を積んでいる
														v_domain_interface.push_back(domain_interface_echo.c_str());
														//os_policy << result.str() << "(" << p_pattern_not_matched_domain->second << ")" << endl;
														p_pattern_not_matched_domain++;
													}while(p_pattern_not_matched_domain != pattern_not_matched_domain.upper_bound(source_interface_pre));
												}
											}
											//pattern_matched_tclassobjclass_interface.insert(pair<string, string>(source_interface_pre,result.str()));
										}
										//os_policy << i << endl;
										i++;
									}
									interface_numbers++;
						//			os_policy << interface_numbers << endl;
								}
							}
							/*マッチしたときのobjclass typeを出すために、準備する。*/
							/*ここでまとめて、ベクタコンテナに積んでおき、後からソートユニークして出す*/
							if(source_interface_pre_comp != source_interface_pre){
								p_pattern_not_matched_objclass=pattern_not_matched_objclass.find(source_interface_pre);
								if(p_pattern_not_matched_objclass != pattern_not_matched_objclass.end()){
									do{
										//os_policy << "matchしたobjclass:" << p_pattern_not_matched_objclass->second << ";" << endl;
										v_matched_tmp_objclass.push_back(p_pattern_not_matched_objclass->second.c_str());
										p_pattern_not_matched_objclass++;
									}while(p_pattern_not_matched_objclass != pattern_not_matched_objclass.upper_bound(source_interface_pre));
								}
								p_pattern_not_matched_domain=pattern_not_matched_domain.find(source_interface_pre);
								if(p_pattern_not_matched_domain != pattern_not_matched_domain.end()){
									do{
										//os_policy << p_pattern_not_matched_domain->second << endl;
										v_matched_tmp_domain.push_back(p_pattern_not_matched_domain->second.c_str());
										p_pattern_not_matched_domain++;
									}while(p_pattern_not_matched_domain != pattern_not_matched_domain.upper_bound(source_interface_pre));
								}
								p_pattern_not_matched_tclass=pattern_not_matched_tclass.find(source_interface_pre);
								if(p_pattern_not_matched_tclass != pattern_not_matched_tclass.end()){
									do{
										//os_policy << p_pattern_not_matched_tclass->second << endl;
										v_matched_tmp_domain.push_back(p_pattern_not_matched_tclass->second.c_str());
										p_pattern_not_matched_tclass++;
									}while(p_pattern_not_matched_tclass != pattern_not_matched_tclass.upper_bound(source_interface_pre));
								}
							}
							source_interface_pre_comp = source_interface_pre;
						}
						//マッチしなかったときの救済策で、生allow文を出す為の準備
						//os_policy << source_interface_pre ;
						//os_policy << " was_not_matched !!!!!!!!"<< endl;
						/*マッチしなかった奴は、ここでまとめて、ベクタコンテナに積んでおき、後からソートユニークして出す*/	
						p_pattern_not_matched_objclass=pattern_not_matched_objclass.find(source_interface_pre);
						if(p_pattern_not_matched_objclass != pattern_not_matched_objclass.end()){
							do{
								//os_policy << "matcheしなかったobjclass:" << p_pattern_not_matched_objclass->second << ";" << endl;
								// 2回目は、826行目
								v_tmp_objclass.push_back(p_pattern_not_matched_objclass->second.c_str());
								p_pattern_not_matched_objclass++;
							}while(p_pattern_not_matched_objclass != pattern_not_matched_objclass.upper_bound(source_interface_pre));
						}
						p_pattern_not_matched_domain=pattern_not_matched_domain.find(source_interface_pre);
						if(p_pattern_not_matched_domain != pattern_not_matched_domain.end()){
							do{
						//		os_policy << p_pattern_not_matched_domain->second << endl;
								v_tmp_domain.push_back(p_pattern_not_matched_domain->second.c_str());
								p_pattern_not_matched_domain++;
							}while(p_pattern_not_matched_domain != pattern_not_matched_domain.upper_bound(source_interface_pre));
						}
						p_pattern_not_matched_tclass=pattern_not_matched_tclass.find(source_interface_pre);
						if(p_pattern_not_matched_tclass != pattern_not_matched_tclass.end()){
							do{
						//		os_policy << p_pattern_not_matched_tclass->second << endl;
								v_tmp_domain.push_back(p_pattern_not_matched_tclass->second.c_str());
								p_pattern_not_matched_tclass++;
							}while(p_pattern_not_matched_tclass != pattern_not_matched_tclass.upper_bound(source_interface_pre));
						}
					}
					/*end read the engine agin and check...*/
					sort(v_interface_raw.begin(),v_interface_raw.end());
					p_interface_raw_end=unique(v_interface_raw.begin(),v_interface_raw.end());

					/*2回目の検索取りこぼし分、というか、インタフェースが持っているもの*/
					/*segatex2.04加筆部分一回engineを新しくつくってから検索かけたいので*/
					vector<string> v_engine_selected;
					vector<string>::iterator p_engine_selected, p_engine_selected_end;
					for(p_interface_raw=v_interface_raw.begin(); p_interface_raw < v_interface_raw.end(); p_interface_raw++){
						string source_interface_raw = *p_interface_raw;
						//os_policy << source_interface_raw << endl;
						const char* m_source_interface_raw = source_interface_raw.c_str();
						regex m_source_interface_raw_exp(m_source_interface_raw);
						for(p_engine=v_engine.begin(); p_engine < v_engine.end(); p_engine++){
							string source_engine_original = *p_engine;
							const char* source_engine_original_str = source_engine_original.c_str();
							cmatch what;
							if(regex_search(source_engine_original_str,what,m_source_interface_raw_exp)){
								v_engine_selected.push_back(source_engine_original.c_str());
							}
						}
					}
					sort(v_engine_selected.begin(),v_engine_selected.end());
					p_engine_selected_end=unique(v_engine_selected.begin(),v_engine_selected.end());


					/*end read the engine agin and check...*/
					/*2回目の検索取りこぼし分、というか、インタフェースが持っているもの*/
					/*ここは気を付けないと、何が出てくるかわからない。まあ、エンジンがしょぼいといってしまえばそれまでだが。*/



					const char* m_domain_interface_h = "[a-z][a-z0-9_]*_t:";
					const char* m_domain_interface_h_204 = "allow(.*)_t";
					const char* m_domain_interface_h_204_2 = "[[:space:]][a-z][a-z0-9_]*_t";
					const char* m_objclass_interface_h = ":.*?\\{";
					const char* m_objclass_interface_h_dash = ":[a-z0-9_]*";
					const char* m_objclass_interface_h2 = ":(.*)([^[:space:]*])[[:space:]]";
					//これで、{{}}というのをとらないようにしなければ無理っぽいので、下でやるか
					//segatex2.05時加筆（上記が仇になっていた）
					const char* m_accv_interface_h = "\\{(.*)\\}";
					const char* m_accv_interface_h_special = "\\{(.*)\\}:";
					const char* m_accv_interface_h2 = "[[:space:]][a-z0-9_]*;,";
					string blank_str="";
					string space_str=" ";
					string tiruda_str="~";
					regex m_domain_interface_h_exp(m_domain_interface_h);
					regex m_domain_interface_h_204_exp(m_domain_interface_h_204);
					regex m_domain_interface_h_204_2_exp(m_domain_interface_h_204_2);
					regex m_objclass_interface_h_exp(m_objclass_interface_h);
					regex m_objclass_interface_h_dash_exp(m_objclass_interface_h_dash);
					regex m_objclass_interface_h2_exp(m_objclass_interface_h2);
					regex m_accv_interface_h_exp(m_accv_interface_h);
					regex m_accv_interface_h_special_exp(m_accv_interface_h_special);
					regex m_accv_interface_h2_exp(m_accv_interface_h2);
					//read the engine and check
					//エンジンファイルを上から検索する。このforスコープの中に落ちれば、マッチしている
					//もう一回、取りこぼしたobjectclassを検索する
					string domain_interface_h;
					string domain_interface_h_204_2;
					string objclass_interface_h;
					string objclass_interface_h2;
					string accv_interface_h;
					string accv_interface_h2;
					//検査済みエンジン部エンジン部を検索する
	//int v_engine_size=v_engine.size();
	//os_policy << v_engine_size << endl;
					//2.04加筆部分このへんを改修した。
					//2.05では、selfというobjclassをどうするかが問題になります...(segatex2.05時加筆、(というか、そんなのない？解決))...。
					for(p_engine_selected=v_engine_selected.begin(); p_engine_selected < v_engine_selected.end(); p_engine_selected++){
						string source_engine = *p_engine_selected;
						const char* source_engine_str = source_engine.c_str();
						cmatch what;
						//os_policy << source_engine << endl;
						
						//ここだけは細工が必要
						if(regex_search(source_engine_str,what,m_domain_interface_h_204_exp)){
							domain_interface_h = what[0];
							const char* domain_interface_h_str = domain_interface_h.c_str();
							//os_policy << source_engine << endl;
							//os_policy << domain_interface_h << endl;
							if(regex_search(domain_interface_h_str,what,m_domain_interface_h_204_2_exp)){
								domain_interface_h_204_2 = what[0];
								//os_policy << source_engine << endl;
								//os_policy << domain_interface_h << endl;
								domain_interface_h_204_2=domain_interface_h_204_2.replace(0,1,blank_str);
								//domainも積んでおく。
								//ここでは、v_matched_tmp_domainに積む。
								v_matched_tmp_domain.push_back(domain_interface_h_204_2.c_str());
								//os_policy << domain_interface_h_204_2 << endl;	
							}
							////////int length=strlen(domain_interface_h.c_str());
							////////domain_interface_h=domain_interface_h.replace(length-1,1,blank_str);
							//domainも積んでおく。
							//ここでは、v_matched_tmp_domainに積む。
							//v_matched_tmp_domain.push_back(domain_interface_h.c_str());
							//os_policy << domain_interface_h << endl;	
						}
						if(regex_search(source_engine_str,what,m_objclass_interface_h_exp)){
							objclass_interface_h = what[0];
							const char* objclass_interface_h_cstr=objclass_interface_h.c_str();
							if(regex_search(objclass_interface_h_cstr,what,m_objclass_interface_h_dash_exp)){
								objclass_interface_h = what[0];
							}
							objclass_interface_h=objclass_interface_h.replace(0,1,blank_str);
							//os_policy << "objclass_interface_h" << objclass_interface_h << ":" << endl;
							//v_tmp_objclassは、実は検索のキーとなるので、あぶれた(インタフェースが持っている)
							//objclassも積んでおかないとダメ。
							//ここでは、v_matched_tmp_objclassに積み、あとでv_tmp_objclassに加える
							v_matched_tmp_objclass.push_back(objclass_interface_h.c_str());
							objclass_interface_h = objclass_interface_h + space_str ;
						}else{
							//バージョン2.03加筆部分（）else句にしてなかったので、大変な事になっていた...
							//バージョン2.02加筆部分（アクセスベクタは{}で囲まれているわけでは無い）
							if(regex_search(source_engine_str,what,m_objclass_interface_h2_exp)){
								objclass_interface_h2 = what[0];
								objclass_interface_h2=objclass_interface_h2.replace(0,1,blank_str);
								int length=strlen(objclass_interface_h2.c_str());
								objclass_interface_h2=objclass_interface_h2.replace(length-1,1,blank_str);
								//os_policy << "objclasss_interface_h2" << objclass_interface_h2 << ":" << endl;	
								//v_tmp_objclassは、実は検索のキーとなるので、あぶれた(インタフェースが持っている)
								//objclassも積んでおかないとダメ。
								//ここでは、v_matched_tmp_objclassに積み、あとでv_tmp_objclassに加える
								v_matched_tmp_objclass.push_back(objclass_interface_h2.c_str());
								objclass_interface_h2 = objclass_interface_h2 + space_str ;
							}
						}
						//segatex2.05時加筆。まずチェックしてから、積むことにしました。
						if(regex_search(source_engine_str,what,m_accv_interface_h_special_exp)){
										//変なのは積まない
						}else{
							if(regex_search(source_engine_str,what,m_accv_interface_h_exp)){
								//ここは要注意
								accv_interface_h = what[0];
								string bracket_first_str="{";
								string bracket_last_str="{";
								accv_interface_h=accv_interface_h.replace(0,1,blank_str);
								int length=strlen(accv_interface_h.c_str());
								accv_interface_h=accv_interface_h.replace(length -1,1,blank_str);
								//os_policy << accv_interface_h << endl;	
								//segatex2.05時加筆（うーん、まだ上だな）
								regex tmp_re("[[:space:]]([^[:space:]]*)[a-z0-9_]*");
								regex tmp_re2("[[:space:]][a-z0-9_]*_t");
								string::const_iterator it=accv_interface_h.begin(), end=accv_interface_h.end();
								while(it != end-1){
									smatch result;
									if( !regex_search(it, end, result, tmp_re)){
										break;
									}
									if((result.str() != " {")&&(result.str() != " }")){
										const char* result_str_cstr = result.str().c_str();
										if(regex_search(result_str_cstr,what,tmp_re2)){
											//変なのは積まない
										}else{
											pattern_matched_access_vector.insert(pair<string, string>(objclass_interface_h,result.str()));
											//segatex2.05時加筆（ここですでに変なのがつまれていました。さらに上ですね）
											//os_policy << "interface<" <<objclass_interface_h << ":" << result.str() << ">" << endl;
										}
									}

									//os_policy << "interfaceがもっているobjclass:" << objclass_interface_h << ";"<< endl;
									v_matched_tmp_objclass.push_back(objclass_interface_h.c_str());
									it = result[0].second;
								}
							}
						}
						//バージョン2.02加筆部分（アクセスベクタは{}で囲まれているわけでは無い）
						if(regex_search(source_engine_str,what,m_accv_interface_h2_exp)){
							accv_interface_h2 = what[0];
							int length=strlen(accv_interface_h2.c_str());
							accv_interface_h2=accv_interface_h2.replace(length -2,2,blank_str);
							//os_policy << accv_interface_h2 << endl;
							//os_policy << "interface2<" <<objclass_interface_h2 << ":" << accv_interface_h2 << ">" << endl;
							pattern_matched_access_vector.insert(pair<string, string>(objclass_interface_h2,accv_interface_h2));
						}
					}
					is.close();

					/*class の所だけは、アクセスベクタを取りまとめるために処理をしてから出す。*/
					/*別に貯めておいた、tmp_strで、pattern_not_matched_access_vectorというmultimapを検索する*/
					/*tmp_strにmultimapの第２属性が引っかかれば、アクセスベクタに貯める*/
					/*tmp_strに何回も引っかかれば、}を待って、貯めておく*/
					/*その際、インタフェースにマッチしたものもまとめておく*/
					/*まとめ方は、インタフェースを探せなかった変数に、探せたものを積んでいく方式でやる*/

					/*まず、検索文字列であるobjclassをまとめる*/
					int v_matched_tmp_objclass_size=v_matched_tmp_objclass.size();
					for(int i=0;i < v_matched_tmp_objclass_size;i++){
						v_tmp_objclass.push_back(v_matched_tmp_objclass[i].c_str());
						string test = v_matched_tmp_objclass[i];
						//os_policy << "test:" << test << endl;
					}
					/*次に、検索される側であるmultimapをまとめる*/
					/*multimapのイテレータを使って...*/
					p_pattern_matched_access_vector=pattern_matched_access_vector.begin();
					do{

						string objclass_matched_echo = p_pattern_matched_access_vector->first;
						string accv_matched_echo = p_pattern_matched_access_vector->second;
						//segatex2.05時メモ（ここでおかしいのを発見した元は上の方だけど）
						//os_policy << "final<" << objclass_matched_echo << ":" << accv_matched_echo << ">" << endl;
						string blank_str="";
						string space_first_str=" ";
						int length=strlen(objclass_matched_echo.c_str());
						objclass_matched_echo=objclass_matched_echo.replace(length -1,1,blank_str);
						int space_first_position=accv_matched_echo.find_first_of(space_first_str);
						accv_matched_echo=accv_matched_echo.replace(0,space_first_position + 1,blank_str);
						pattern_not_matched_access_vector.insert(pair<string, string>(objclass_matched_echo,accv_matched_echo));
						p_pattern_matched_access_vector++;
					}while(p_pattern_matched_access_vector != pattern_matched_access_vector.end());

					sort(v_tmp_objclass.begin(),v_tmp_objclass.end());
					p_tmp_objclass_end=unique(v_tmp_objclass.begin(),v_tmp_objclass.end());

					os_policy << "####################################################" << endl;
					os_policy << "##### This file was generated by segatex2.09" << endl;
					os_policy << "####################################################" << endl;
					os_policy << "module my_policy_by_segatex 1.0.0;" << endl << endl;
					os_policy << "require {" << endl;
					string p_pattern_not_matched_objclass_pre=*v_tmp_objclass.begin();
					for(p_tmp_objclass=v_tmp_objclass.begin(); p_tmp_objclass < p_tmp_objclass_end; p_tmp_objclass++){
						string tmp_str= *p_tmp_objclass;
						//os_policy << "tmp_str:" << tmp_str << endl;
						/*ここでは、マッチしなかったのと、したのと、インタフェースが持っているobjclassのaccess_vectorを導出している*/
						p_pattern_not_matched_access_vector=pattern_not_matched_access_vector.find(tmp_str);
						if(p_pattern_not_matched_access_vector != pattern_not_matched_access_vector.end()){
							os_policy << "	class " << p_pattern_not_matched_access_vector->first << " { " ;
							do{
								if(p_pattern_not_matched_access_vector->first == p_pattern_not_matched_objclass_pre){
									/*こういうのが入らないように*/
									cmatch what;
									regex tmp_re3("(.*)\\$(.*)");
									if(regex_search(p_pattern_not_matched_access_vector->second.c_str(),what,tmp_re3)){
										/*何もしない*/
									}else{
										//os_policy << p_pattern_not_matched_access_vector->second << " ";
										v_accv.push_back(p_pattern_not_matched_access_vector->second.c_str());
									}
								}
								p_pattern_not_matched_objclass_pre = p_pattern_not_matched_access_vector->first;
								p_pattern_not_matched_access_vector++;
							}while(p_pattern_not_matched_access_vector != pattern_not_matched_access_vector.upper_bound(tmp_str));
							sort(v_accv.begin(),v_accv.end());
							p_accv_end=unique(v_accv.begin(),v_accv.end());
							for(p_accv=v_accv.begin(); p_accv < p_accv_end; p_accv++){
								string accv_str= *p_accv;
								os_policy << accv_str << " ";
							}
							os_policy << "};" << endl;
							v_accv.clear();
						}
					}

					/*type は、domainとtclassを取りまとめて出す*/
					/*その際、インタフェースにマッチしたのとマッチしなかったのをまとめておく*/
					int v_matched_tmp_domain_size=v_matched_tmp_domain.size();
					for(int i=0;i < v_matched_tmp_domain_size;i++){
						v_tmp_domain.push_back(v_matched_tmp_domain[i].c_str());
						string test = v_matched_tmp_domain[i];
						//os_policy << test << endl;
					}
					sort(v_tmp_domain.begin(),v_tmp_domain.end());
					p_tmp_domain_end=unique(v_tmp_domain.begin(),v_tmp_domain.end());
					for(p_tmp_domain=v_tmp_domain.begin();p_tmp_domain < p_tmp_domain_end; p_tmp_domain++){
						string dom_str = *p_tmp_domain;
						os_policy << "	type " << dom_str << ";" << endl;
					}
					//roleを出す
					sort(v_role.begin(),v_role.end());
					p_role_end=unique(v_role.begin(),v_role.end());
					for(p_role=v_role.begin(); p_role < p_role_end; p_role++){
						string role_tmp_str= *p_role;
						os_policy << "	role " << role_tmp_str << ";" << endl;
					}
					os_policy << "};" << endl << endl;
					/*マッチしなかった生allow文を出す*/
					cmatch what;
					const char* m_snmfp = "(.*):([^[:space:]]*)([:space:])?";
					const char* m_acc_comp = "\\{(.*)\\}";
					regex m_snmfp_exp(m_snmfp);
					regex m_acc_comp_exp(m_acc_comp);
					//read the sentence and devide
					for(p2_v=v2.begin();p2_v < p2_v_end; p2_v++){
						string source_not_match_final_pre = *p2_v;
						const char* m_source_not_match_final_pre = source_not_match_final_pre.c_str();
						string allow_first  = what[0];
						string allow_last  = what[0];
						if(regex_search(m_source_not_match_final_pre,what,m_snmfp_exp)){
							allow_first  = what[0];
							v_allow_first.push_back(allow_first.c_str());
							//os_policy << allow_first << endl;
						if(regex_search(m_source_not_match_final_pre,what,m_acc_comp_exp)){
							allow_last  = what[0];
							int length=strlen(allow_last.c_str());
							string blank_str="";
							allow_last=allow_last.replace(length - 2,2,blank_str);
							allow_last=allow_last.replace(0,2,blank_str);
							//os_policy << allow_last << endl;
						}
							//マルチマップに積んでおく
							pattern_allow_not_matched_echo.insert(pair<string, string>(allow_first,allow_last));
						}
					}
					/*allow backup_t sysadm_devpts_t:chr_fileというv_allow_firstを元手に、
					pattern_allow_not_matched_echoを検索する
					上のとほとんど同じだが、一回表示するのがちょっと違う
					*/
					sort(v_allow_first.begin(),v_allow_first.end());
					p_allow_first_end=unique(v_allow_first.begin(),v_allow_first.end());
					string p_allow_first_str=*v_allow_first.begin();
					for(p_allow_first=v_allow_first.begin(); p_allow_first < p_allow_first_end; p_allow_first++){
						string tmp_str= *p_allow_first;
						//os_policy << "tmp_str" << tmp_str << endl;
						p_pattern_allow_not_matched_echo=pattern_allow_not_matched_echo.find(tmp_str);
						if(p_pattern_allow_not_matched_echo != pattern_allow_not_matched_echo.end()){
							//この辺姑息だけど、まあいいか
							os_policy << p_pattern_allow_not_matched_echo->first << " { " ;
							if(p_pattern_allow_not_matched_echo != pattern_allow_not_matched_echo.begin()){
								os_policy <<  p_pattern_allow_not_matched_echo->second.c_str() << " ";
							}
							//合致していれば、アクセスベクタを貯めて
							do{
								if(p_pattern_allow_not_matched_echo->first == p_allow_first_str){
									v_allow_last.push_back(p_pattern_allow_not_matched_echo->second.c_str());
								}
								p_allow_first_str = p_pattern_allow_not_matched_echo->first;
								p_pattern_allow_not_matched_echo++;
							}while(p_pattern_allow_not_matched_echo != pattern_allow_not_matched_echo.upper_bound(tmp_str));
							sort(v_allow_last.begin(),v_allow_last.end());
							p_allow_last_end=unique(v_allow_last.begin(),v_allow_last.end());
							for(p_allow_last=v_allow_last.begin(); p_allow_last < p_allow_last_end; p_allow_last++){
								string allow_last_str= *p_allow_last;
								os_policy << allow_last_str << " ";
							}
							os_policy << "};" << endl;
							v_allow_last.clear();
						}
					}
					//インタフェースを出す
					sort(v_domain_interface.begin(),v_domain_interface.end());
					p_domain_interface_end=unique(v_domain_interface.begin(),v_domain_interface.end());
					for(p_domain_interface=v_domain_interface.begin(); p_domain_interface < p_domain_interface_end; p_domain_interface++){
						string domain_interface_echo_final = *p_domain_interface;	
						os_policy << domain_interface_echo_final << endl;
					}
					//when selpaw_interface.csv was existing and there are any denied log
					QFile file( filename_policy); // Read the text from a file
					if ( file.open( IO_ReadOnly ) ) {
						QTextStream stream( &file );
						textEdit1->setText( stream.read() );
					}
				}
				//end of !v.size()==0
			}
			os_policy.close();
		}
		//is.close();
		os_my_log.close();
	}
	is_engine.close();
	os_policy.close();
}
