Проблема с шифрованием файлов в каталоге на Linux - PullRequest
0 голосов
/ 25 декабря 2010

Я протестировал часть программы для шифрования, и она отлично работает для отдельных файлов или даже для таких вещей, как «файл1, файл2, файл3», но не работает с каталогами. Код выглядит хорошо для меня, однако при выполнении он вызывает ошибку сегментации.

Предполагается зашифровать файлы в каталоге и записать их в тот же каталог с новым расширением (старое имя + ".wbf") и расшифровать с удалением расширения на противоположное. Я собираюсь опубликовать только те части кода, которые имеют дело с файлами, функция do_crypt, которая работает с отдельными файлами, прекрасно работает, и я думаю, что это не источник моих проблем.

    // 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;

    }*/

}

Ответы [ 2 ]

2 голосов
/ 25 декабря 2010

В вашей функции LS много проблем.Во-первых, вы должны заставить его возвращать vector<string> напрямую, а не упаковывать данные в string, используя запятую для разделения значения.Это избавит вас от вызова функции explode и не прервется, если каталог содержит имя файла с запятой в нем (это допустимое имя в Linux).

Но большая проблема (то естьв результате) ваш segfault - это строка return 0.Поскольку ваша функция объявлена ​​для возврата объекта string, а класс string имеет неявный конструктор из const char*, это интерпретируется компилятором как return string(NULL).И когда вызывается с указателем NULL, этот конструктор вызывает исключение logic_error.Поскольку вы не уловили исключение, среда выполнения C ++ вызывает функцию abort.Эта функция вызывает отклонение по умолчанию, чтобы остановить выполнение (и, если включено, генерировать coredump, чтобы разрешить отладочную отладку).

Вы должны хотя бы переписать свою функцию LS следующим образом:

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 string();
    }
    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 explosive;
}

Или, лучше, измените его подпись, чтобы получить vector<string>, и перепишите его так:

vector<string> LS (string dir)
{
    DIR *dp;
    vector<string> files;
    struct dirent *dirp;
    if ((dp = opendir(dir.c_str())) != NULL)
    {
        while ((dirp = readdir(dp)) != NULL)
        {
            files.push_back(string(dirp->d_name));
        }
        closedir(dp);
    }
    else
    {
        cout << "Error (" << errno << ") opening " << dir << endl;
    }
    return files;
}
2 голосов
/ 25 декабря 2010

if ((dp = opendir(dir.c_str())) = NULL)

Я думаю, вы имеете в виду == NULL

...