diff --git a/lib/arguments.cpp b/lib/arguments.cpp index fffbf9fa..6f859f0c 100644 --- a/lib/arguments.cpp +++ b/lib/arguments.cpp @@ -124,9 +124,8 @@ QString arguments::help() .arg(help) .arg(i->need_db ? "*" : " "); } - s += "\n" - "[*] Needs a database. Either from the commandline\n" - " or as default database\n"; + s += "\n[*]" + splitQstring(sizeof("[*] ") -1, width, + QString("Needs a database. Either from the commandline or as default database")) + "\n"; return s; } @@ -142,20 +141,20 @@ int arguments::parse(int argc, char *argv[]) for (i = 0; i < cnt; ++i) opts[i].fillOption(long_opts +i); + opterr = 0; /* Parse cmdline options argv */ while (true) { int optind = 0; - result = getopt_long_only(argc, argv, "", long_opts, &optind); + result = getopt_long_only(argc, argv, ":", long_opts, &optind); if (result) break; const arg_option i = opts[optind]; - found_options[i.long_opt] = i.arg_type == file_argument ? - filename2QString(optarg) : QString(optarg); + found_options[i.long_opt] = QString::fromUtf8(optarg); if (i.need_db) need_db = true; } for (i = optind; i < argc; ++i) { - QString file = filename2QString(argv[i]); + QString file = QString::fromUtf8(argv[i]); if (!has("database") && file.endsWith(".xdb")) { /* No database given, but here is an xdb file * Try to be clever. @@ -165,9 +164,25 @@ int arguments::parse(int argc, char *argv[]) files << file; } } + if (result == ':') { + result_string = QString("Missing option argument for '%1'") + .arg(argv[optind-1]); + } + if (result == '?') { + result_string = QString("Invalid option: '%1'") + .arg(argv[optind-1]); + } + if (result == -1) + result = 0; + return result; } +QString arguments::resultString() const +{ + return result_string; +} + arguments::arguments(int argc, char *argv[]) { long_opts = NULL; diff --git a/lib/arguments.h b/lib/arguments.h index 55c83092..4aa1710e 100644 --- a/lib/arguments.h +++ b/lib/arguments.h @@ -43,6 +43,7 @@ class arguments QStringList files; struct option *long_opts; bool need_db; + QString result_string; public: static bool is_console(int argc, char *argv[]); @@ -58,6 +59,7 @@ class arguments int parse(int argc, char *argv[]); QStringList getFiles() const; int getResult() const; + QString resultString() const; bool needDb() const; }; #endif diff --git a/lib/func.cpp b/lib/func.cpp index cbcc3745..e3e2c7c5 100644 --- a/lib/func.cpp +++ b/lib/func.cpp @@ -46,6 +46,9 @@ #if defined(Q_OS_WIN32) #include #include +#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING +#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x04 +#endif #else #include #define getch() getchar() @@ -56,18 +59,15 @@ QString currentDB; int console_write(FILE *fp, const QByteArray &ba) { + if (ba.size() == 0) + return 0; #if defined(Q_OS_WIN32) - static int got_console; - if (!got_console) { - if (AttachConsole(-1) || AllocConsole()) - got_console = 1; - } - HANDLE out = GetStdHandle(fp == stderr ? - STD_ERROR_HANDLE : STD_OUTPUT_HANDLE); - - if (out != INVALID_HANDLE_VALUE) { + HANDLE con = GetStdHandle(fp == stderr ? STD_ERROR_HANDLE : + STD_OUTPUT_HANDLE); + if (con != INVALID_HANDLE_VALUE) { QString string = QString::fromUtf8(ba); - WriteConsoleW(out, string.utf16(), string.size(), NULL, NULL); + WriteConsoleW(con, string.utf16(), string.size(), NULL, NULL); + //return 0; } #endif fputs(ba.constData(), fp); @@ -86,6 +86,8 @@ Passwd readPass() t.c_lflag &= ~(ECHO | ICANON); if (tcsetattr(0, TCSAFLUSH, &t)) throw errorEx(strerror(errno)); +#else + qFatal("Password input not supported"); #endif while(1) { char p = getch(); @@ -223,13 +225,14 @@ const QString getPrefix() static QString specialFolder(int csidl) { LPITEMIDLIST pidl = NULL; - TCHAR buf[255] = ""; + wchar_t buf[MAX_PATH] = L""; if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, csidl, &pidl))) - SHGetPathFromIDList(pidl, buf); + SHGetPathFromIDListW(pidl, buf); - qDebug() << "Special Folder" << csidl << buf; - return QFileInfo(buf).canonicalFilePath(); + QString f = QString::fromWCharArray(buf); + qDebug() << "Special Folder" << csidl << f; + return QFileInfo(f).canonicalFilePath(); } #endif @@ -357,15 +360,6 @@ QString getFullFilename(const QString & filename, const QString & selectedFilter return rv; } -QString filename2QString(const char *fname) -{ -#if defined(Q_OS_WIN32) - return QString::fromLocal8Bit(fname); -#else - return QString::fromUtf8(fname); -#endif -} - QString hostId() { static QString id; @@ -380,14 +374,14 @@ QString hostId() ULONG dwGuid = sizeof guid; HKEY hKey; - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_CRYPTO, 0, + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, REG_CRYPTO, 0, KEY_READ, &hKey) != ERROR_SUCCESS) { XCA_WARN("Registry Key: '" REG_CRYPTO "' not found"); } else { - if (RegQueryValueEx(hKey, REG_GUID, NULL, NULL, + if (RegQueryValueExA(hKey, REG_GUID, NULL, NULL, guid, &dwGuid) != ERROR_SUCCESS) { XCA_WARN("Registry Key: '" REG_CRYPTO "\\" REG_GUID - "' not found"); + "' not found"); } } RegCloseKey(hKey); diff --git a/lib/func.h b/lib/func.h index 14fe6d7c..43a8d1d9 100644 --- a/lib/func.h +++ b/lib/func.h @@ -55,7 +55,6 @@ const QStringList getLibExtensions(); QString hostId(); QString formatHash(const QByteArray &data, QString sep = ":", int width = 2); -QString filename2QString(const char *fname); QString compressFilename(const QString &filename, int maxlen = 50); QString asn1ToQString(const ASN1_STRING *str, bool quote = false); diff --git a/lib/main.cpp b/lib/main.cpp index 15e0f4a7..e603262e 100644 --- a/lib/main.cpp +++ b/lib/main.cpp @@ -83,24 +83,16 @@ void myMsgOutput(QtMsgType type, const char *msg) console_write(stderr, QString(COL_YELL "%1%2 %3:" COL_RESET " %4\n") .arg(el/1000, 4) .arg((el%1000)/100, 2, 10, QChar('0')) - .arg(severity).arg(msg).toUtf8()); + .arg(severity).arg(QString::fromUtf8(msg)).toUtf8()); } #if QT_VERSION >= 0x050000 void myMessageOutput(QtMsgType t, const QMessageLogContext &, const QString &m) { - myMsgOutput(t, CCHAR(m)); + myMsgOutput(t, m.toUtf8().constData()); } #endif -QCoreApplication *createApplication(int &argc, char *argv[]) -{ - if (arguments::is_console(argc, argv)) { - return new QCoreApplication(argc, argv); - } - return new XcaApplication(argc, argv); -} - static void cmd_version(FILE *fp) { console_write(fp, QString(XCA_TITLE "\nVersion %1\n") @@ -114,10 +106,10 @@ static void cmd_help(int exitcode = EXIT_SUCCESS, const char *msg = NULL) QString s; cmd_version(fp); - s = QString("\nUsage %1 ...\n\n%2") + s = QString("\nUsage %1 ...\n\n%2\n") .arg(xca_name).arg(arguments::help()); if (msg) - s += QString("\nCmdline Error: %1\n").arg(msg); + s += QString("\nError: %1\n").arg(msg); console_write(fp, s.toUtf8()); exit(exitcode); @@ -151,15 +143,16 @@ static database_model* read_cmdline(int argc, char *argv[]) if (cmd_opts.has("verbose")) debug = 1; - if (cmd_opts.getResult() == '?') - cmd_help(EXIT_FAILURE); + if (cmd_opts.getResult() != 0) + cmd_help(EXIT_FAILURE, cmd_opts.resultString().toUtf8()); if (cmd_opts.has("database")) models = new database_model(cmd_opts["database"], sqlpw); cmdline_items = new pki_multi(); - foreach(QString file, cmd_opts.getFiles()) + foreach(QString file, cmd_opts.getFiles()) { + qDebug() << "Probe" << file; cmdline_items->probeAnything(file); if (cmd_opts.needDb() && !models) { @@ -278,35 +271,65 @@ static database_model* read_cmdline(int argc, char *argv[]) int main(int argc, char *argv[]) { - if (argc > 0) - xca_name = argv[0]; - -#if defined(Q_OS_WIN32) - SetUnhandledExceptionFilter(w32_segfault); -#else - signal(SIGSEGV, segv_handler_gui); -#endif - - QDir().mkpath(getUserSettingsDir()); - #if QT_VERSION < 0x050000 qInstallMsgHandler(myMsgOutput); #else qInstallMessageHandler(myMessageOutput); #endif +#if defined(Q_OS_WIN32) + AttachConsole(-1); + + int wargc; + wchar_t **wargv = CommandLineToArgvW(GetCommandLineW(), &wargc); + if (wargv && wargc) { + int i; + if (argc != wargc) + qWarning() << "argc != wargc" << argc << wargc; + if (argc > wargc) + argc = wargc; + qDebug() << "wargc" << wargc << argc; + for (i = 0; i < argc; i++) { + QString s = QString::fromWCharArray(wargv[i]); + QByteArray ba = s.toUtf8(); + argv[i] = strdup(ba.constData()); + qDebug() << "wargv" << i << argv[i] << s; + } + argv[i] = NULL; + LocalFree(wargv); + } + SetUnhandledExceptionFilter(w32_segfault); +#else + signal(SIGSEGV, segv_handler_gui); +#endif + if (argc > 0) + xca_name = argv[0]; Entropy entropy; Settings.clear(); - QCoreApplication *core = createApplication(argc, argv); + bool console_only = arguments::is_console(argc, argv); + XcaApplication *gui; +#if !defined(Q_OS_WIN32) + if (console_only) { + new QCoreApplication(argc, argv); + gui = NULL; + } else +#endif + { + /* On windows, always instantiate a GUI app */ + gui = new XcaApplication(argc, argv); + } + + QDir().mkpath(getUserSettingsDir()); initOIDs(); - XcaApplication *gui = qobject_cast(core); + for (int i=0; i < argc; i++) + qDebug() << "wargv" << argc << i << argv[i]; try { database_model *models = read_cmdline(argc, argv); - if (gui) { mainwin = new MainWindow(models); + if (gui && !console_only) { gui->setMainwin(mainwin); mainwin->importMulti(cmdline_items, 1); cmdline_items = NULL; @@ -328,6 +351,8 @@ int main(int argc, char *argv[]) << pki->getIntName(); delete mainwin; delete gui; - +#if defined(Q_OS_WIN32) + FreeConsole(); +#endif return EXIT_SUCCESS; } diff --git a/widgets/PwDialog.cpp b/widgets/PwDialog.cpp index e4b12e18..e1d30baf 100644 --- a/widgets/PwDialog.cpp +++ b/widgets/PwDialog.cpp @@ -36,7 +36,11 @@ static int hex2bin(QString &x, Passwd *final) enum open_result PwDialog::execute(pass_info *p, Passwd *passwd, bool write, bool abort) { - if (IS_GUI_APP) { +#warning merge ifdefs +#if !defined(Q_OS_WIN32) + if (IS_GUI_APP) +#endif + { PwDialog *dlg = new PwDialog(p, write); if (abort) dlg->addAbortButton(); @@ -47,9 +51,11 @@ enum open_result PwDialog::execute(pass_info *p, Passwd *passwd, throw pw_exit; return result; } - console_write(stdout, QString(COL_CYAN "%1" COL_LRED "\n%2:" COL_RESET) +#if !defined(Q_OS_WIN32) + console_write(stdout, QString(COL_CYAN "%1\n" COL_LRED "%2:" COL_RESET) .arg(p->getDescription()).arg(tr("Password")).toUtf8()); *passwd = readPass(); +#endif return pw_ok; }