⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cl.cpp

📁 STLstlfilt.zip
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		{
			meta = "Y";
			use_meta = true;
		}
		else if (!strnicmp(argv[i], "/width:", 7)  || !strnicmp(argv[i], "-width:", 7))
		{
			output_width = atoi(&argv[i][7]);
		}
		else if (!strnicmp(argv[i], "/lognative", 10) || !strnicmp(argv[i], "-lognative", 10))
		{
			log_native_msgs = true;
		}
		else
		{
			// surround each arg with double quotes to avoid long filename problems
			string nextarg = "\"";			// insert opening quote
											
			char *b = argv[i];
			char *p = strchr(b, '"');		// find next double quote char
			while (p != 0)					// while there is another double quote char...
			{
				*p = '\0';					// copy everything up to (not incl.) the quote
 
				nextarg += b;
				nextarg += "\\\"";			// escape the quote
				b = p + 1;					// keep looking for quotes...
				p = strchr(b, '"');
			}

			nextarg += b;					// copy remainder of the arg text

			int n = nextarg.length() - 1;	// if arg ends with pattern [^\]\,
			if (nextarg[n-1] != '\\' && nextarg[n] == '\\')	// add another backslash so we don't
				nextarg += "\\";			// end up with an escaped " at the end!
			nextarg += "\"";				// insert closing quote
			if (i > 0)						// if not command name, add to args list for filtering
				args += nextarg;
			new_argv[new_argc] = new char[nextarg.length() + 1];	// and build new_argv in case
			strcpy(new_argv[new_argc++], nextarg.c_str());			// we end up spawning CL
		}

		args += " ";
	}

	new_argv[new_argc] = NULL;

	full_filt_cmd += " /width:" + toString(output_width);
	full_filt_cmd += " /iter:" + iterator_policy;
	full_filt_cmd += " /alloc:" + allocator_policy;
	full_filt_cmd += " /func:" + functor_policy;
	full_filt_cmd += " /with:"  + with_policy;
	full_filt_cmd += " /break:" + break_algorithm;
	full_filt_cmd += " /cbreak:" + cbreak;
	full_filt_cmd += " /closewrap:" + closewrap;

	if (use_meta)
		full_filt_cmd += " /meta:" + meta;
		
	full_filt_cmd += " /banner:n";						// disable the Perl script's banner, since
														// we provide the banner in this case
	if (log_native_msgs)
		full_filt_cmd += " /lognative";
						 
	int status;

	log("full_filt_cmd = " + full_filt_cmd);
	
	if (filtering)						
	{
		// Let's just make sure that the Perl interpreter and script are where
		// they're supposed to be:

		struct stat dummy_stat_buf;

		if (stat(perl_exe.c_str(), &dummy_stat_buf) == -1)
		{
			cerr << "Proxy CL: Perl interpreter configured as " << perl_exe <<
								" not present.\nBailing out." << endl;
			exit (1);
		}

		if (stat(filter_script.c_str(), &dummy_stat_buf) == -1)
		{
			cerr << "Proxy CL: Perl script configured as " << filter_script <<
								" not present.\nBailing out." << endl;
			exit (1);
		}

		// Okay, we're in business...

		if (!silent)
			cout << "  ****** {"CL_ID"} STL Message Decryption is ON! ******" << endl;

		// Create some "C" strings to pass to the doWin32Stuff function...

		char *full_filt_cmd_cstr = new char[full_filt_cmd.length() + 1];
		strcpy(full_filt_cmd_cstr, full_filt_cmd.c_str());
												// Create replacement command line
		string cmdline = native_cl + args;	// start with native CL.EXE and append
		log(cmdline);							//		whatever args were passed

		char *cmdline_cstr = new char[cmdline.length() + 1];
		strcpy(cmdline_cstr, cmdline.c_str());

		status = doWin32Stuff(full_filt_cmd_cstr, cmdline_cstr);

		delete [] full_filt_cmd_cstr;
		delete [] cmdline_cstr;
	}
	else
	{
		if (!silent)
			cout << "     ****** {"CL_ID"} STL Message Decryption is Off ******" << endl;

#if DEBUG_CAPABLE
		for (i = 1; i < new_argc; i++)
			log("new_argv[" + toString(i) + "] = '" + new_argv[i] + "'");
#endif
												// if not filtering, use native CL:
		status = _spawnvp(_P_WAIT, native_cl.c_str(), new_argv);

		if (status == -1)
		{
			cerr << "Proxy CL: Failure to start " << native_cl << " (does your PATH include it?)" << endl;
			status = 1;
		}
	}

	for(i = 0; i < new_argc; i++)					// release the "new_argv" dynamic memory
		delete[] new_argv[i];
	delete [] new_argv;

	return status;
}


// This has to be in its own function, since we can't mix __try / __finally
// and string objects in main()...Geez Louise...

int doWin32Stuff(char *full_filt_cmd, char *cmdline)
{
	using namespace std;
    // Get std device handles
    HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    HANDLE hStdError = GetStdHandle(STD_ERROR_HANDLE);
    
    // Create an anonymous pipe for communication between native_cl and Perl
    //
    HANDLE hPipeWrite = NULL;
    HANDLE hPipeRead = NULL;
    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(sa); 
    sa.lpSecurityDescriptor = NULL; 
    sa.bInheritHandle = TRUE;
    if( ! ::CreatePipe(
      &hPipeRead,					// address of variable for read handle 
      &hPipeWrite,					// address of variable for write handle  
      &sa,							// pointer to security attributes 
      0								// number of bytes reserved for pipe 
      ) )
    {
		cerr << "Proxy CL: Failure to create pipe between " << native_cl << " and Perl" << endl;
      return 1;
    }
    
    // Start perl
	//
    PROCESS_INFORMATION pi_perl;
    pi_perl.hProcess = NULL;
    pi_perl.hThread = NULL;
    STARTUPINFO si_perl;
    memset(&si_perl, '\0', sizeof(si_perl));
    si_perl.cb = sizeof(si_perl);
    si_perl.dwFlags = STARTF_USESTDHANDLES;
    si_perl.hStdInput = hPipeRead;	// read side of pipe
    si_perl.hStdOutput = hStdOut;	// stdout of parent
    si_perl.hStdError = hStdOut;	// stderr of parent
    if( ! ::CreateProcess(
      NULL,
	  full_filt_cmd,				// something like: perl stlfilt.pl [/iter:n]
      NULL,							// pointer to process security attributes 
      NULL,							// pointer to thread security attributes 
      TRUE,							// handle inheritance flag 
      0,							// creation flags 
      NULL,							// pointer to new environment block 
      NULL,							// pointer to current directory name 
      &si_perl,						// pointer to STARTUPINFO 
      &pi_perl						// pointer to PROCESS_INFORMATION  
      ) )
    {
      cerr << "Proxy CL: Failure to start perl.exe (check pathname in CL.CPP)" << endl;
      return 1;
    }
    
    // Try-finally block for closing handles and sending EOF to perl.
    //
    PROCESS_INFORMATION pi_cl2 ;
    pi_cl2.hProcess = NULL;
    pi_cl2.hThread = NULL;
    //

	bool bWriteEofSuccess = true;
	
    __try
    {
      // Start native_cl:
      //
      STARTUPINFO si_cl2;
      memset(&si_cl2, '\0', sizeof(si_cl2));
      si_cl2.cb = sizeof(si_cl2);
      si_cl2.dwFlags = STARTF_USESTDHANDLES;
      si_cl2.hStdInput = hStdIn;		// stdin of parent
      si_cl2.hStdOutput = hPipeWrite;	// write side of child-to-parent
      si_cl2.hStdError = hStdError;		// stderr of parent
      if( ! ::CreateProcess(NULL,
        cmdline,
        NULL,							// pointer to process security attributes 
        NULL,							// pointer to thread security attributes 
        TRUE,							// handle inheritance flag 
        0,								// creation flags 
        NULL,							// pointer to new environment block 
        NULL,							// pointer to current directory name 
        &si_cl2,						// pointer to STARTUPINFO 
        &pi_cl2							// pointer to PROCESS_INFORMATION  
        ) )
      {
        cerr << "Proxy CL: Failure to start " << native_cl << " (does your PATH include it?)" << endl;
        return 1;
      }
      

      // Wait for native_cl to finish.
      if( WAIT_FAILED == ::WaitForSingleObject(pi_cl2.hProcess, INFINITE) )
      {
        cerr << "Proxy CL: Failure waiting for " << native_cl << " to terminate" << endl;
        return 1;
      }
    }

	__finally
	{
		if( ! WriteEofToPipe(hPipeWrite) )
		  bWriteEofSuccess = false;
	}
	
    if( !bWriteEofSuccess )
	{
	   puts("Proxy CL: Failure to send EOF to perl.exe");
	   return 1;
	}

    // Wait for perl.exe to finish.
    if( WAIT_FAILED == ::WaitForSingleObject(pi_perl.hProcess, INFINITE) )
    {
      cerr << "Proxy CL: Failure waiting for perl.exe to terminate" << endl;
      return 1;
    }
    
    // Get exit code for native_cl. This is possible because we have not closed
    // the process handle yet.
    //
    DWORD dwExitCode;
    if( ! GetExitCodeProcess(
      pi_cl2.hProcess,		// handle to the process
      &dwExitCode			// address to receive termination status
      ) )
    {
	  cerr << "Proxy CL: Could not get exit code for " << native_cl << endl;
      return 1;
    }
    
    // Close all handles, just to make the point.
    //
    ::CloseHandle(hPipeWrite);
    ::CloseHandle(hPipeRead);
    ::CloseHandle(pi_perl.hProcess);
    ::CloseHandle(pi_perl.hThread);
    ::CloseHandle(pi_cl2.hProcess);
    ::CloseHandle(pi_cl2.hThread);

	return dwExitCode;
}    

BOOL WriteEofToPipe(HANDLE hPipe)
{
	SYSTEM_INFO info;		// Check for > 1 processor...
	GetSystemInfo(&info);
	if (info.dwNumberOfProcessors > 1) 
		Sleep(100);		// Fixes obscure timing problem on dual PIII system

	// We must precede the EOF with an extra newline because we don't
	// know whether CL's output ended with a newline, and EOF without
	// preceding newlines is always iffy. The perlscript ensures that
	// the extra newline is discarded unless the CL output didn't end
	// with a newline, in which case we want to add it.
	//
	DWORD dwNumBytesToWrite = 2;
	DWORD dwNumBytesWritten = 0 ;
	BOOL bWriteRetVal = WriteFile(
	  hPipe,				// handle to file to write to 
	  "\012\032",			// pointer to data to write to file 
	  dwNumBytesToWrite,	// number of bytes to write 
	  &dwNumBytesWritten,	// pointer to number of bytes written 
	  NULL) ;				// addr. of structure needed for overlapped I/O  
	if( ! bWriteRetVal || dwNumBytesToWrite != dwNumBytesWritten )
		  return FALSE;

    ::FlushFileBuffers(hPipe);
    return TRUE;
}

bool hasExt(const std::string &filenam, const std::string extensions[], int nexts)
{
	using namespace std;
	string filename = filenam;
	int length;
	
	int i;

	if (filename.length() < 2)
		return false;
	
					// get rid of trailing whitespace on the filename...
	for (i = filename.length() - 1; i >= 0; i--)
		if (!isspace(filename[i]))
			break;
	filename.resize(length = i + 1);
	
	log(string("hasExt() testing: \"") + filename + "\"");

	for (i = 0; i < nexts; i++)
	{
		int extLen = extensions[i].length();
		log("testing extension:" + extensions[i]);
		if (length >= extLen + 1 &&
			!stricmp(filename.substr(length - extLen).c_str(), extensions[i].c_str()))
		{
			log(string("hasExt() found extension: ") + extensions[i]);
			return true;
		}
	}
	log("hasExt() did not find a matching extension.\n");
	return false;
}
			

// remove trailing whitespace from a string:
void chompSpace(std::string &pathname)
{
	while (isspace(pathname[pathname.length() - 1]))
		pathname.resize(pathname.length() - 1);
}		

// remove trailing slash, if any, from string:
void chompSlash(std::string &pathname)
{
	chompSpace(pathname);				// first remove all trailing whitespace

	char c;
	if ((c = pathname[pathname.length() - 1]) == '/' || c == '\\')
		pathname.resize(pathname.length() - 1);
}

// remove trailing comment, if any:
void stripComment(std::string &txt)
{
	chompSpace(txt);				// first remove all trailing whitespace

	for (int i = txt.length() - 1; i > 1; i--)	// search for semicolon
	{
		if (txt[i] == ';')
		{									// found semicolon; now search for first
			int j;							// non-whitespace before that
			for (j = i - 1; j > 0; j--)
				if (!isspace(txt[j]))
					break;
			txt.resize(j + 1);
			log("just stripped comment. result: \"" + txt + "\"");
			return;
		}
	}
}


// remove quotation marks around pathname, if any:
void stripQuotes(std::string &txt, const std::string &unprocessed_line)
{
	char c;
	char quoteFound = 0;
	int i;
	
	chompSpace(txt);						// first remove all trailing whitespace

	for (i = 0; i < txt.length() && isspace(c = txt[i]); i++)	// skip leading whitespace
		;

	if (i == txt.length())					// null parameter value? Not good.
	{
		std::cerr << "Proxy CL: A parameter value in " + configFile + " is null.\n" +
			 "  All uncommented lines must specify a value.\nBailing out.";
		exit(1);
	}
	
	if (c == '\'' || c == '"')				// allow single or double quotes, as long as
	{										// they match...
		quoteFound = c;
		txt.erase(i, 1);					// delete the opening quote
		c = txt[txt.length() - 1];			// make sure close quote matches open
		if (c == quoteFound)
		{
			txt.resize(txt.length() - 1);	// delete the closing quote
			return;							// and we're done
		}
	}

	if (!quoteFound &&						// now check for funky unmatched quote at end
		(c = txt[txt.length() - 1]) != '\'' && c != '"')
			return;							// OK if none
		
	std::cerr << "Proxy CL: Funky quoting detected in " + configFile + "\n" +
			  "  The offending parameter value:\n  " + 
			  unprocessed_line + "\nProxy CL is bailing out.";
	exit(1);
}


// give pathnames/filenames the full treatment:
void massage_pathname(std::string &txt)
{
	std::string raw(txt);
	stripComment(txt);
	stripQuotes(txt, raw);
	chompSlash(txt);
}


#if DEBUG_CAPABLE
void logit(const std::string &msg)
{
	if (!debug)
		return;
	
	std::ofstream out(debug_log.c_str(), std::ios_base::app);
	if (!out) {
		std::cerr << "Can't append to " << debug_log << ":" << std::endl;
		std::cerr << "Offending message: " << msg << std::endl;
	}
	else
	{
		out << msg << std::endl;
		out.close();
	}
}

std::string toString(int n)
{
	char buf[20];
	sprintf(buf, "%d", n);
	return buf;
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -