Professional C__ - Marc Gregoire [439]
Launching an external process causes a big overhead because a complete new process has to be created. You shouldn’t use it when you need to call the external process often. In this password encryption example, it is OK, because you can assume that a log file will only contain a few password lines.
The strategy for the script is to loop over every line of a file looking for lines that contain a password prompt. The script will write a new file, userlog.out, which contains the same text as the source file, except that all passwords are encrypted. The first step is to open the input file for reading and the output file for writing. Then, the script needs to loop over all the lines in the file. Each line in turn is placed in a variable called $line.
open (INPUT, "userlog.txt") or die "Couldn't open input file!";
open (OUTPUT, ">userlog.out") or die "Couldn't open output file!";
while ($line = ) {
Code snippet from Perl\processLog.pl
Next, the current line is checked against a regular expression to see if this particular line contains the Password: prompt. If it does, Perl will store the password in the variable $1.
if ($line =~ m/^Password: (.*)/) {
Since a match has been found, the script calls the encryptString program with the detected password to obtain an encrypted version of it. The output of the program is stored in the $result variable, and the result status code from the program is stored in the variable $?. The script checks $? and quits immediately if there is a problem. If everything is okay, the password line is written to the output file with the encrypted password instead of the original one.
$result = './encryptString $1';
if ($? != 0) { exit(-1) }
print OUTPUT "Password: $result\n";
If the current line is not a password prompt, the script writes the line as is to the output file. At the end of the loop, it closes both files and exits.
} else {
print OUTPUT "$line";
}
}
close (INPUT);
close (OUTPUT);
That’s it. The only other required piece is the actual C++ program. Implementation of a cryptographic algorithm is beyond the scope of this book. The important piece is the main() function because it accepts the string that should be encrypted as an argument.
Arguments are contained in the argv array of C-style strings. You should always consult the argc parameter before accessing an element of argv. If argc is 1, there is one element in the argument list and it is accessible as argv[0]. The 0th element of the argv array is generally the name of the program, so actual parameters begin at argv[1].
Following is the main() function for a C++ program that encrypts the input string. Notice that the program returns 0 for success and non-0 for failure, as is standard in Unix:
int main(int argc, char* argv[])
{
if (argc < 2) {
cerr << "Usage: " << argv[0] << " string-to-be-encrypted" << endl;
return -1;
}
cout << encrypt(argv[1]);
return 0;
}
Code snippet from Perl\encryptString.cpp
There is actually a blatant security hole in this code. When the to-be-encrypted string is passed to the C++ program as a command-line argument, it may be visible to other users through the process table. A more secure way to get the information into the C++ program would be to send it through standard input, which is the forte of the expect scripting language.
Now that you’ve seen how easily C++ programs can be incorporated into scripting languages, you can combine the strengths of the two languages for your own projects. You can use a scripting language to interact with the OS and control the flow of the script, and a traditional programming language for the heavy lifting.
This example is just to demonstrate how to use Perl and C++ together. C++11 includes a regular expression library, which makes it very easy to