I have tested the encryption part of the program and it works just fine for individual files, or even things like “file1,file2,file3” but it doesn’t work with directories. The code looks fine to me, however when executing it gives me a segmentation fault.
It’s supposed to encrypt files in directory and write them in the same directory with a new extension (old name + “.wbf”) and decryption with extension removal upon the opposite. I’m only going to post the parts of code that deal with the files, the do_crypt function that works with individual files works just fine, and I think it’s not the source of my problems.
// PHP explode function
vector<string> explode (string text, char separator)
{
vector<string> split;
int last_trip = 0, pos = 0;
text += separator;
for (pos = 0; pos < text.size(); pos++)
{
if (text[pos] != separator)
{
// continue with iteration
}
else
{
split.push_back(text.substr(last_trip, pos - last_trip));
last_trip = pos + 1;
}
}
return split;
};
// LINUX -- directory listing function
string LS (string dir)
{
DIR *dp;
vector<string> files;
struct dirent *dirp;
if ((dp = opendir(dir.c_str())) = NULL)
{
cout << "Error (" << errno << ") opening " << dir << endl;
//return errno;
}
while ((dirp = readdir(dp)) != NULL)
{
files.push_back(string(dirp->d_name));
}
closedir(dp);
string explosive = "";
for (int i = 0; i < files.size(); i++)
{
explosive += files[i];
if (i != (files.size() - 1)) { explosive += ','; }
}
return 0;
}
// various functions for encryption
int main (int argc, char* argv[])
{
cout << "\t! ENCRYPTR -- File encryption utility written by WBlinder, 2010. !" << endl << endl;
cout << "\t\t\t\tOPTIONS:" << endl;
cout << "\t\t\t1\tCRYPT A FILE" << endl << "\t\t\t2\tDECRYPT A FILE" << endl << endl;
cout << "choice > ";
int opt;
cin >> opt;
string sin, sout;
string dummy; getline(cin, dummy);
/*cout << "input files > ";
cout.clear(); cin.clear();
getline(cin, sin);
vector<string> fin = explode(sin, ',');
cout << "output files > ";
getline(cin, sout);
vector <string> fout = explode(sout, ',');
if (sin.size() != sout.size())
{
cout << "NO. INPUT FILES UNEQUAL NO. OUTPUT FILES" << endl;
return 1;
}*/
string dir;
cout << "dir > ";
getline (cin, dir);
vector<string> input = explode(dir, ',');
vector<string> output = input;
switch (opt)
{
case 1:
for (int i = 0; i < output.size(); i++)
{
output[i] = output[i] + ".wbf";
}
break;
case 2:
for (int i = 0; i < output.size(); i++)
{
output[i] = output[i].substr(0, (output[i].size() - 4));
}
break;
}
cout << "password > ";
getline(cin, key);
cout << "N > ";
cin >> N;
cout << "(768 => fairly secure\t3072 => secure)\nextra rounds > ";
cin >> drop;
for (int brick = 0; brick < input.size(); brick++)
{
do_crypt(opt, dir + input[brick], dir + output[brick]);
}
/*string text;
cout << "text to split: ";
getline (cin, text);
vector<string> tnt = explode(text, '.');
for (int i = 0; i < tnt.size(); i++)
{
cout << i << ": " << tnt[i] << endl;
}*/
}
There is many problem in your
LSfunction. First, you should make it directly return avector<string>instead of packing the data in astringusing a comma to separate value. This would save you a call toexplodefunction, and would not break if the directory contains a filename with a comma in it (which is a valid name on Linux).But the bigger problem (that is causing) your segfault is the
return 0line. Since your function is declared to return astringobject, and sincestringclass has an implicit constructor fromconst char*, this is interpreted by the compiler asreturn string(NULL). And when called with aNULLpointer this constructor raise alogic_errorexception. As you didn’t catch the exception, the C++ runtime call theabortfunction. This function cause a segfault by design in order to stop execution (and if enabled generate a coredump to allow post-morten debugging).You should at least rewritte your
LSfunction like that:Or better, change its signature to return a
vector<string>and rewrite it like that: