Форум русскоязычного сообщества Ubuntu


Увидели сообщение с непонятной ссылкой, спам, непристойность или оскорбление?
Воспользуйтесь ссылкой «Сообщить модератору» рядом с сообщением!

Автор Тема: Открытие разных форм в зависимости от переданных параметров и их разбор  (Прочитано 2152 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Mixim

  • Автор темы
  • Участник
  • *
  • Сообщений: 114
    • Просмотр профиля
Разбираюсь с Qt\Qt Creator. Предполагается, что реализуемую программу будут использовать два вида пользователей: администраторы и обычные юЗвери. В зависимости от того, кто запустил программу, должна открываться либо Form, либо MainForm(разные окна). Для этого пишу в main.cpp:
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

   
    if(argv[0]!="admin")
    {
        Form form;
        form.changePushButtonTitle(argv[0]);
    }
    else
    {
        MainWindow w;
        w.show();
    }
   
    return a.exec();
}
Теперь хочу запустить это приложение с параметрами и посмотреть как оно отработает. В Qt Creator не нашел пункта "Запуск с параметрами", поэтому открываю Gnome Commander, перехожу в директорию с файлом "untilled" и в его командной строке пишу просто "untilled"(как это было в TotalCommander под Win), но реакции ровно ноль. Пытался писать "exec untilled", "execute untilled", но безрезультатно :idiot2:. Просто кликаю по исполняемому файлу "untilled" и приложение запускается.
Подскажите пожалуйста, верно ли будут обрабатываться передаваемые параметры и каким образом можно запустить программу с их передачей?
« Последнее редактирование: 27 Июля 2012, 02:13:01 от Mixim »

Оффлайн hippi90

  • Активист
  • *
  • Сообщений: 433
    • Просмотр профиля

Оффлайн Mixim

  • Автор темы
  • Участник
  • *
  • Сообщений: 114
    • Просмотр профиля

Оффлайн Mixim

  • Автор темы
  • Участник
  • *
  • Сообщений: 114
    • Просмотр профиля
Пытаюсь на тестовом примере опробовать указанный код. В main.cpp пишу:
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    MainWindow2 *w2;
    MainWindow *w1;

    char *str="ad";


    if(argv[argc-1]==str)
    {
        w1=new MainWindow();
        w1->myShow(argv[argc-1]);
    }
    else
    {
        w2=new MainWindow2();
        w2->show();
    }

    /*MainWindow2 w;
    w.show();*/
   
    return a.exec();
}
Запускаю вот так, т.е. без параметров:
Цитировать
./untitled2
- как и должно, открывается MainWindow2.
Запускаю следующим образом:
Цитировать
./untitled2 ad
-открывается снова MainWindow2! Ничего не понимаю - параметр же равен ad, но почему то запускается не MainWindow, а MainWindow2.
Пробую написать ad в кавычках:
Цитировать
./untitled2 "ad"
Но и так запускается MainWindow2! Прошу помощи, что делаю не так? Подозреваю, что ошибка в задании значения переменной str.

Оффлайн Чистый

  • Почётный модератор
  • Старожил
  • *
  • Сообщений: 3473
  • nix - вот оно счастье...
    • Просмотр профиля
а вы вывидите в консоль вот это:
argv[argc-1]и посмотрите почему не совпадает, я например не понимаю зачем вы -1 делаете?

даже если вы запускаете приложение без аргументов то приложение все равно запускается c одним аргументом, который содержит путь к исполняемому файлу....
« Последнее редактирование: 22 Июля 2012, 12:26:24 от Чистый »
Тестовый репозиторий kdeNeur ppa:devcode/kdeneur
各々が死ぬことをどのように決定する

Оффлайн hippi90

  • Активист
  • *
  • Сообщений: 433
    • Просмотр профиля
man getopt вам в помощь.
И да, argv[0] - это название программы, argv[1..argc] - это параметры командной строки.

Оффлайн Mixim

  • Автор темы
  • Участник
  • *
  • Сообщений: 114
    • Просмотр профиля
я например не понимаю зачем вы -1 делаете?
hippi90 ответил на этот вопрос:
man getopt вам в помощь.
И да, argv[0] - это название программы, argv[1..argc] - это параметры командной строки.
Всем спасибо за помощь. Реализовал следующим образом:
const char *adAccess="ad";
        const char *login="login";
        const char *password="password";

    MainWindow *mainWindow=NULL;
    MainWindow2 *mainWindow2=NULL;

    //если передали четыре и более аргументов для запуска программы
    if(argc>=4)
    {
        //проверяем наименование доступа
        if(strcmp(argv[1], adAccess)==0)
        {
            //если хотят получить доступ от имени администратора, то проверяем логин и пароль
            if( (strcmp(argv[2], login)==0) && (strcmp(argv[3], password)==0) )
            {
                mainWindow2=new MainWindow2();
                mainWindow2->show();
            }
            //если проверка на комбинацию логин/пароль не пройдена, выводим окно ошибок
            else
            {
                ErrorWindow *errorWindow = new ErrorWindow();
                errorWindow->show();
            }
        }
        //если наименование доступа неизвестно, то выводим окно ошибок
        else
        {
            ErrorWindow *errorWindow = new ErrorWindow();
                errorWindow->show();
        }
    }
    //если аргументов меньше 4, то просто открываем главное окно
    else
    {
        mainWindow=new MainWindow();
        mainWindow->setWindowFlags(Qt::FramelessWindowHint);
        mainWindow->showFullScreen();
    }
Вроде бы все работает ровно так, как и нужно.
Отдельное спасибо hippi90 :coolsmiley:
« Последнее редактирование: 24 Июля 2012, 11:05:26 от Mixim »

Оффлайн Чистый

  • Почётный модератор
  • Старожил
  • *
  • Сообщений: 3473
  • nix - вот оно счастье...
    • Просмотр профиля
я не понимаю почему вы это делаете в вашем случае, а не вообще, так как вы не знаете кол-во аргументов переданных программе, и если их больше чем один то и сравниваете предпоследний, что есть не правильно с точки зрения логики работы и грамотного программирования, посмотрите как это сделано в нормальных приложениях и как там идет парсинг аргументов приложения.... благо OpenSource позволяет подсмотреть .... ну и хранить пароль админа в коде программы не безопасно.....
Тестовый репозиторий kdeNeur ppa:devcode/kdeneur
各々が死ぬことをどのように決定する

Оффлайн Mixim

  • Автор темы
  • Участник
  • *
  • Сообщений: 114
    • Просмотр профиля
посмотрите как это сделано в нормальных приложениях и как там идет парсинг аргументов приложения.... благо OpenSource позволяет подсмотреть .... ну и хранить пароль админа в коде программы не безопасно.....
Знаю, наглость, но: нельзя ли было бы услышать хотя бы наименование Qt-приложения, в котором можно посмотреть парсинг аргументов. Насчет:
хранить пароль админа в коде программы не безопасно.....
это был очень-очень черновой вариант, предполагаю вынести логины\пароли в конфигурационный файл, т.е. считываю данные из конфига с помощью QSettings, но это еще менее безопасно(любой человек, получивший доступ к Linux с моей программой сможет скопировать/прочитать файл), поэтому вновь небольшая наглость: каким образом лучше хранить комбинацию логин/пароль в Qt-программе?
P.S.Немного отошел от темы
« Последнее редактирование: 26 Июля 2012, 11:48:08 от Mixim »

Оффлайн Чистый

  • Почётный модератор
  • Старожил
  • *
  • Сообщений: 3473
  • nix - вот оно счастье...
    • Просмотр профиля
Тестовый репозиторий kdeNeur ppa:devcode/kdeneur
各々が死ぬことをどのように決定する

Оффлайн hippi90

  • Активист
  • *
  • Сообщений: 433
    • Просмотр профиля
это был очень-очень черновой вариант, предполагаю вынести логины\пароли в конфигурационный файл, т.е. считываю данные из конфига с помощью QSettings, но это еще менее безопасно(любой человек, получивший доступ к Linux с моей программой сможет скопировать/прочитать файл), поэтому вновь небольшая наглость: каким образом лучше хранить комбинацию логин/пароль в Qt-программе?

Храните не пароль, а его хеш. Хранить можно как в конфигурационном файле, так и в специальном хранилище (например, BerkleyDB, которая есть по-умолчанию в любом *nix). Соответственно, процедура проверки пароля будет выглядеть как-то так (в псевдокоде):
password = getPasswordFromArgs(argv);
password_hash = getSHA1Hash(password);
real_pasword_hash = loadPasswordHashFromInternalStore();

if (password_hash == real_password_hash)
showAdminMainForm();
else
showUserMainForm();
Настоящий пароль не упоминается нигде ни в коде программы, ни в каких-либо конфигурационных файлах, тем самым исключается возможность его кражи.

Оффлайн Чистый

  • Почётный модератор
  • Старожил
  • *
  • Сообщений: 3473
  • nix - вот оно счастье...
    • Просмотр профиля
но остается возможность подменить хэш на заранее известный.... Ну это так спор что появилось раньше яйцо или курица...
Тестовый репозиторий kdeNeur ppa:devcode/kdeneur
各々が死ぬことをどのように決定する

Оффлайн Mixim

  • Автор темы
  • Участник
  • *
  • Сообщений: 114
    • Просмотр профиля
Храните не пароль, а его хеш. Хранить можно как в конфигурационном файле, так и в специальном хранилище (например, BerkleyDB, которая есть по-умолчанию в любом *nix). Соответственно, процедура проверки пароля будет выглядеть как-то так (в псевдокоде):
Спасибо еще раз. Полностью согласен с:
Настоящий пароль не упоминается нигде ни в коде программы, ни в каких-либо конфигурационных файлах, тем самым исключается возможность его кражи.
Однако предполагается, что программа будет взаимодействовать с сервером - необходим дополнительный логин/пароль для работы с ним. Думаю, что сервер врятли позволит передавать просто хэш пароля(ему нужен чистый логин/пароль) и поэтому каким образом хранить логин/пароль для него :idiot2:?
« Последнее редактирование: 27 Июля 2012, 02:17:43 от Mixim »

Оффлайн hippi90

  • Активист
  • *
  • Сообщений: 433
    • Просмотр профиля
Однако предполагается, что программа будет взаимодействовать с сервером - необходим дополнительный логин/пароль для работы с ним. Думаю, что сервер врятли позволит передавать просто хэш пароля(ему нужен чистый логин/пароль) и поэтому каким образом хранить логин/пароль для него :idiot2:?
Какая бы у вас ни была задача, кто-то из программистов уже с ней сталкивался - это, практически, аксиома. Следовательно, где-то уже есть готовые рецепты, и надо их только найти. Для безопасного общения клиент-сервер разработан протокол SSL/TLS, реализованный в разных библиотеках, в частности OpenSSL.

 

Страница сгенерирована за 0.03 секунд. Запросов: 25.