<commit_before>/*
    This file is part of Kandy.

    Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <qfile.h>

#include <kapplication.h>
#include <dcopclient.h>
#include <kaboutdata.h>
#include <kcmdlineargs.h>
#include <klocale.h>
#include <kdebug.h>
#include <kmessagebox.h>

#include "modem.h"
#include "kandy.h"
#include "mobilemain.h"
#include "commandscheduler.h"
#include "kandyprefs.h"

static const char description[] =
    I18N_NOOP("Communicating with your mobile phone.");

static const char version[] = "0.3";

static KCmdLineOptions options[] =
{
   { "terminal", I18N_NOOP("Show terminal window."), 0 },
   { "mobilegui", I18N_NOOP("Show mobile GUI."), 0 },
   { "nogui", I18N_NOOP("Do not show GUI."), 0 },
   { "+[profile]", I18N_NOOP("Filename of command profile file."), 0 },
   KCmdLineLastOption // End of options.
};

void initModem(Modem *modem)
{
  kdDebug(5960) << "Opening serial Device: "
            << KandyPrefs::serialDevice()
            << endl;

  modem->setDevice(KandyPrefs::serialDevice());
  modem->setSpeed(19200);
  modem->setData(8);
  modem->setParity('N');
  modem->setStop(1);

#if 0
  if (!modem->dsrOn()) {
    KMessageBox::sorry(this, i18n("Modem is off."), i18n("Modem Error"));
    modem->close();
    return;
  }
  if (!modem->ctsOn()) {
    KMessageBox::sorry(this, i18n("Modem is busy."), i18n("Modem Error"));
    modem->close();
    return;
  }
#endif

#if 0
  modem->writeLine("");
  usleep(250000);
  modem->flush();
  modem->writeLine("ATZ");
#endif
}

int main(int argc, char **argv)
{
  KAboutData about("kandy", I18N_NOOP("Kandy"), version, description,
                   KAboutData::License_GPL, "(C) 2001 Cornelius Schumacher",0,
                   "http://devel-home.kde.org/~kandy");
  about.addAuthor( "Cornelius Schumacher", 0, "schumacher@kde.org" );
  KCmdLineArgs::init(argc,argv,&about);
  KCmdLineArgs::addCmdLineOptions(options);

  KApplication app;
  KCmdLineArgs *args = KCmdLineArgs::parsedArgs();

  // register ourselves as a dcop client
  app.dcopClient()->registerAs(app.name(),false);

  Modem *modem = new Modem;
  CommandScheduler *scheduler = new CommandScheduler(modem);

  // see if we are starting with session management
  if (app.isRestored()) {
    // TODO: do session management
//      RESTORE(Kandy)
  } else
  {
    // no session.. just start up normally
    Kandy *k = new Kandy(scheduler);

    MobileMain *m = new MobileMain(scheduler);
    if (!args->isSet("gui")) {
    } else {
      if (KandyPrefs::startupTerminalWin() ||
          args->isSet("terminal")) {
        k->show();
      }
      if (KandyPrefs::startupMobileWin() ||
          args->isSet("mobilegui")) {
        m->show();
      }
    }

    if (args->count() == 1) {
      k->load(QFile::decodeName(args->arg(0)));
    } else if (args->count() > 1) {
      args->usage();
    }

    args->clear();

    QObject::connect(k,SIGNAL(showMobileWin()),m,SLOT(show()));
    QObject::connect(m,SIGNAL(showTerminalWin()),k,SLOT(show()));
    QObject::connect(m,SIGNAL(showPreferencesWin()),
                     k,SLOT(optionsPreferences()));
    QObject::connect(m,SIGNAL(modemConnect()),k,SLOT(modemConnect()));
    QObject::connect(m,SIGNAL(modemDisconnect()),k,SLOT(modemDisconnect()));
    QObject::connect(k,SIGNAL(connectStateChanged(bool)),
                     m,SLOT(setConnected(bool)));

    QObject::connect( modem, SIGNAL( errorMessage( const QString & ) ),
                      k, SLOT( showErrorMessage( const QString & ) ) );

    initModem(modem);

    if (KandyPrefs::startupModem()) k->modemConnect();
  }

  return app.exec();
}
<commit_msg><commit_after>/*
    This file is part of Kandy.

    Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <qfile.h>

#include <kapplication.h>
#include <dcopclient.h>
#include <kaboutdata.h>
#include <kcmdlineargs.h>
#include <klocale.h>
#include <kdebug.h>
#include <kmessagebox.h>

#include "modem.h"
#include "kandy.h"
#include "mobilemain.h"
#include "commandscheduler.h"
#include "kandyprefs.h"

static const char description[] =
    I18N_NOOP("Communicating with your mobile phone.");

static const char version[] = "0.3";

static KCmdLineOptions options[] =
{
   { "terminal", I18N_NOOP("Show terminal window."), 0 },
   { "mobilegui", I18N_NOOP("Show mobile GUI."), 0 },
   { "nogui", I18N_NOOP("Do not show GUI."), 0 },
   { "+[profile]", I18N_NOOP("Filename of command profile file."), 0 },
   KCmdLineLastOption // End of options.
};

void initModem(Modem *modem)
{
  kdDebug(5960) << "Opening serial Device: "
            << KandyPrefs::serialDevice()
            << endl;

  modem->setDevice(KandyPrefs::serialDevice());
  modem->setSpeed(19200);
  modem->setData(8);
  modem->setParity('N');
  modem->setStop(1);

#if 0
  if (!modem->dsrOn()) {
    KMessageBox::sorry(this, i18n("Modem is off."), i18n("Modem Error"));
    modem->close();
    return;
  }
  if (!modem->ctsOn()) {
    KMessageBox::sorry(this, i18n("Modem is busy."), i18n("Modem Error"));
    modem->close();
    return;
  }
#endif

#if 0
  modem->writeLine("");
  usleep(250000);
  modem->flush();
  modem->writeLine("ATZ");
#endif
}

int main(int argc, char **argv)
{
  KAboutData about("kandy", I18N_NOOP("Kandy"), version, description,
                   KAboutData::License_GPL, "(C) 2001 Cornelius Schumacher",0,
                   "http://kandy.kde.org");
  about.addAuthor( "Cornelius Schumacher", 0, "schumacher@kde.org" );
  KCmdLineArgs::init(argc,argv,&about);
  KCmdLineArgs::addCmdLineOptions(options);

  KApplication app;
  KCmdLineArgs *args = KCmdLineArgs::parsedArgs();

  // register ourselves as a dcop client
  app.dcopClient()->registerAs(app.name(),false);

  Modem *modem = new Modem;
  CommandScheduler *scheduler = new CommandScheduler(modem);

  // see if we are starting with session management
  if (app.isRestored()) {
    // TODO: do session management
//      RESTORE(Kandy)
  } else
  {
    // no session.. just start up normally
    Kandy *k = new Kandy(scheduler);

    MobileMain *m = new MobileMain(scheduler);
    if (!args->isSet("gui")) {
    } else {
      if (KandyPrefs::startupTerminalWin() ||
          args->isSet("terminal")) {
        k->show();
      }
      if (KandyPrefs::startupMobileWin() ||
          args->isSet("mobilegui")) {
        m->show();
      }
    }

    if (args->count() == 1) {
      k->load(QFile::decodeName(args->arg(0)));
    } else if (args->count() > 1) {
      args->usage();
    }

    args->clear();

    QObject::connect(k,SIGNAL(showMobileWin()),m,SLOT(show()));
    QObject::connect(m,SIGNAL(showTerminalWin()),k,SLOT(show()));
    QObject::connect(m,SIGNAL(showPreferencesWin()),
                     k,SLOT(optionsPreferences()));
    QObject::connect(m,SIGNAL(modemConnect()),k,SLOT(modemConnect()));
    QObject::connect(m,SIGNAL(modemDisconnect()),k,SLOT(modemDisconnect()));
    QObject::connect(k,SIGNAL(connectStateChanged(bool)),
                     m,SLOT(setConnected(bool)));

    QObject::connect( modem, SIGNAL( errorMessage( const QString & ) ),
                      k, SLOT( showErrorMessage( const QString & ) ) );

    initModem(modem);

    if (KandyPrefs::startupModem()) k->modemConnect();
  }

  return app.exec();
}
<|endoftext|>


<commit_before>/*
    main.cpp

    This file is part of Kleopatra, the KDE keymanager
    Copyright (c) 2001,2002,2004 Klar�vdalens Datakonsult AB

    Kleopatra is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    Kleopatra is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include <config-kleopatra.h>

#include "aboutdata.h"
#include "systemtrayicon.h"
#ifdef KLEO_BUILD_OLD_MAINWINDOW
# include "certmanager.h"
#else
# include "mainwindow.h"
# include <commands/refreshkeyscommand.h>
#endif

#include "libkleo/kleo/cryptobackendfactory.h"

#include <utils/kdpipeiodevice.h>
#include <utils/log.h>
#ifdef Q_OS_WIN
#include <utils/gnupg-registry.h>
#endif

#ifdef HAVE_USABLE_ASSUAN
# include "kleo-assuan.h"
# include <uiserver/uiserver.h>
# include <uiserver/assuancommand.h>
# include <uiserver/echocommand.h>
# include <uiserver/decryptcommand.h>
# include <uiserver/verifycommand.h>
# include <uiserver/decryptverifyfilescommand.h>
# include <uiserver/decryptfilescommand.h>
# include <uiserver/verifyfilescommand.h>
# include <uiserver/prepencryptcommand.h>
# include <uiserver/encryptcommand.h>
# include <uiserver/signcommand.h>
# include <uiserver/signencryptfilescommand.h>
#else
namespace Kleo {
    class UiServer;
}
#endif

#include <models/keycache.h>

#include <kcmdlineargs.h>
#include <kmessagebox.h>
#include <klocale.h>
#include <kglobal.h>
#include <kiconloader.h>
#include <ksplashscreen.h>
#include <KUniqueApplication>

#include <QDebug>
#include <QFile>
#include <QTextDocument> // for Qt::escape
#include <QProcess>
#include <QSystemTrayIcon>
#include <QMenu>
#include <QAction>

#include <boost/shared_ptr.hpp>

#ifdef Q_OS_WIN
#include <windows.h>
#endif

#include <memory>
#include <cassert>

namespace {
    template <typename T>
    boost::shared_ptr<T> make_shared_ptr( T * t ) {
        return t ? boost::shared_ptr<T>( t ) : boost::shared_ptr<T>() ;
    }
}

#ifdef Q_OS_WIN

static void checkForInvalidRegistryEntries( QWidget* msgParent )
{
    std::auto_ptr<const char> value( read_w32_registry_string( HKEY_CURRENT_USER, "Software\\GNU\\GnuPG", "gpgProgram" ) );
    if ( !value )
        return;
    if ( KMessageBox::questionYesNo( msgParent,
                                     i18n( "Kleopatra detected an obsolete registry key (\"HKLM\\GNU\\GnuPG\\gpgProgram\"),"
                                           "added by either previous gpg4win versions or applications such as WinPT or EnigMail."
                                           "Keeping the entry might lead to problems during operations (old GnuPG backend being used)."
                                           "It is advised to delete the key." ),
                                     i18n( "Old Registry Entries Detected" ),
                                     i18n( "Delete Registry Key" ),
                                     KStandardGuiItem::cancel(),
                                     "doNotWarnAboutRegistryEntriesAgain" ) != KMessageBox::Yes )
        return;
    LONG result = RegDeleteKey( HKEY_CURRENT_USER, "Software\\GNU\\GnuPG\\gpgProgram" );
    if ( result == ERROR_SUCCESS )
        return;
    KMessageBox::error( msgParent,
                        i18n( "Could not delete the key \"HKLM\\GNU\\GnuPG\\gpgProgram\" from the registry." ),
                        i18n( "Error Deleting Key" ) );
}
#endif // Q_OS_WIN

static QString environmentVariable( const QString& var, const QString& defaultValue=QString() )
{
    const QStringList env = QProcess::systemEnvironment();
    Q_FOREACH ( const QString& i, env )
    {
        if ( !i.startsWith( var + '=' ) )
            continue;

        const int equalPos = i.indexOf( '=' );
        assert( equalPos >= 0 );
        return i.mid( equalPos + 1 );
    }
    return defaultValue;
}

static void setupLogging()
{
    const QString envOptions = environmentVariable( "KLEOPATRA_LOGOPTIONS", "io" );
    const bool logAll = envOptions.trimmed() == "all";
    const QStringList options = envOptions.split( ',' );

    const QString dir = environmentVariable( "KLEOPATRA_LOGDIR" );
    if ( dir.isEmpty() )
        return;
    std::auto_ptr<QFile> logFile( new QFile( dir + "/kleo-log" ) );
    if ( !logFile->open( QIODevice::WriteOnly | QIODevice::Append ) ) {
        qDebug() << "Could not open file for logging: " << dir + "/kleo-log\nLogging disabled";
        return;
    }

    Kleo::Log::mutableInstance()->setOutputDirectory( dir );
    if ( logAll || options.contains( "io" ) )
        Kleo::Log::mutableInstance()->setIOLoggingEnabled( true );
    qInstallMsgHandler( Kleo::Log::messageHandler );

#ifdef HAVE_USABLE_ASSUAN
    if ( logAll || options.contains( "pipeio" ) )
        KDPipeIODevice::setDebugLevel( KDPipeIODevice::Debug );

    assuan_set_assuan_log_stream( Kleo::Log::instance()->logFile() );
#endif
}

#ifndef KLEO_BUILD_OLD_MAINWINDOW
static void fillKeyCache( KSplashScreen * splash, Kleo::UiServer * server ) {

  QEventLoop loop;
  Kleo::RefreshKeysCommand * cmd = new Kleo::RefreshKeysCommand( 0 );
  QObject::connect( cmd, SIGNAL(finished()), &loop, SLOT(quit()) );
#ifdef HAVE_USABLE_ASSUAN
  QObject::connect( cmd, SIGNAL(finished()), server, SLOT(enableCryptoCommands()) );
#else
  Q_UNUSED( server );
#endif
  splash->showMessage( i18n("Loading certificate cache...") );
  cmd->start();
  loop.exec();
  splash->showMessage( i18n("Certificate cache loaded.") );
}
#endif

int main( int argc, char** argv )
{
  AboutData aboutData;

  KCmdLineArgs::init(argc, argv, &aboutData);

  KCmdLineOptions options;
#ifdef KLEO_BUILD_OLD_MAINWINDOW
  options.add("external", ki18n("Search for external certificates initially"));
  options.add("query ", ki18n("Initial query string"));
#else
  options.add("daemon", ki18n("Run UI server only, hide main window"));
#endif
  options.add("import-certificate ", ki18n("Name of certificate file to import"));
#ifdef HAVE_USABLE_ASSUAN
  options.add("uiserver-socket <argument>", ki18n("Location of the socket the ui server is listening on" ) );
#endif

  KCmdLineArgs::addCmdLineOptions( options );

  // pin KeyCache to a shared_ptr to define it's minimum lifetime:
  const boost::shared_ptr<Kleo::PublicKeyCache> publicKeyCache = Kleo::PublicKeyCache::mutableInstance();
  const boost::shared_ptr<Kleo::SecretKeyCache> secretKeyCache = Kleo::SecretKeyCache::mutableInstance();

  const boost::shared_ptr<Kleo::Log> log = Kleo::Log::mutableInstance();

  setupLogging();

  KUniqueApplication app;

  KCmdLineArgs *args = KCmdLineArgs::parsedArgs();

  KGlobal::locale()->insertCatalog( "libkleopatra" );
  KIconLoader::global()->addAppDir( "libkleopatra" );
  KIconLoader::global()->addAppDir( "kdepim" );

#ifndef KLEO_BUILD_OLD_MAINWINDOW
  SystemTrayIconFor<MainWindow> sysTray;
  sysTray.show();
#endif

  KSplashScreen splash( UserIcon( "kleopatra_splashscreen" ), Qt::WindowStaysOnTopHint );

  int rc;
#ifdef HAVE_USABLE_ASSUAN
  try {
      Kleo::UiServer server( args->getOption("uiserver-socket") );

      server.enableCryptoCommands( false );

# ifndef KLEO_BUILD_OLD_MAINWINDOW
      QObject::connect( &server, SIGNAL(startKeyManagerRequested()),
                        &sysTray, SLOT(openOrRaiseMainWindow()) );
# endif

#define REGISTER( Command ) server.registerCommandFactory( boost::shared_ptr<Kleo::AssuanCommandFactory>( new Kleo::GenericAssuanCommandFactory<Kleo::Command> ) )
      REGISTER( DecryptCommand );
      REGISTER( DecryptFilesCommand );
      REGISTER( DecryptVerifyFilesCommand );
      REGISTER( EchoCommand );
      REGISTER( EncryptCommand );
      REGISTER( EncryptFilesCommand );
      REGISTER( EncryptSignFilesCommand );
      REGISTER( PrepEncryptCommand );
      REGISTER( SignCommand );
      REGISTER( SignEncryptFilesCommand );
      REGISTER( SignFilesCommand );
      REGISTER( VerifyCommand );
      REGISTER( VerifyFilesCommand );
#undef REGISTER

      server.start();

# ifndef KLEO_BUILD_OLD_MAINWINDOW
      sysTray.setToolTip( i18n( "Kleopatra UI Server listening on %1", server.socketName() ) );
# endif
#endif

#ifdef KLEO_BUILD_OLD_MAINWINDOW
      if( !Kleo::CryptoBackendFactory::instance()->smime() ) {
          KMessageBox::error(0,
                             i18n( "<qt>The crypto plugin could not be initialized.
"
                                   "Certificate Manager will terminate now.</qt>") );
          return -2;
      }

      splash.show();

      CertManager* manager = new CertManager( args->isSet("external"),
                                              args->getOption("query"),
                                              args->getOption("import-certificate") );
      manager->show();
      splash.finish( manager );
#else

      const bool daemon = args->isSet("daemon");

      if ( !daemon )
          splash.show();
#ifdef HAVE_USABLE_ASSUAN
      fillKeyCache( &splash, &server );
#else
      fillKeyCache( &splash, 0 );
#endif

      if ( !daemon ) {
          MainWindow* mainWindow = new MainWindow;
          mainWindow->show();
          sysTray.setMainWindow( mainWindow );
          splash.finish( mainWindow );
#if Q_OS_WIN
          checkForInvalidRegistryEntries( mainWindow );
#endif // Q_OS_WIN
      }

#endif

      args->clear();
      QApplication::setQuitOnLastWindowClosed( false );
      rc = app.exec();

#ifdef HAVE_USABLE_ASSUAN
# ifndef KLEO_BUILD_OLD_MAINWINDOW
      QObject::disconnect( &server, SIGNAL(startKeyManagerRequested()),
                           &sysTray, SLOT(openOrRaiseMainWindow()) );
#endif

      server.stop();
      server.waitForStopped();
  } catch ( const std::exception & e ) {
      QMessageBox::information( 0, i18n("GPG UI Server Error"),
                                i18n("<qt>The Kleopatra GPG UI Server Module couldn't be initialized.
"
                                     "The error given was: %1
"
                                     "You can use Kleopatra as a certificate manager, but cryptographic plugins that "
                                     "rely on a GPG UI Server being present might not work correctly, or at all.</qt>",
                                     Qt::escape( QString::fromUtf8( e.what() ) ) ));
      rc = app.exec();
  }
#endif

    return rc;
}
<commit_msg>compile<commit_after>/*
    main.cpp

    This file is part of Kleopatra, the KDE keymanager
    Copyright (c) 2001,2002,2004 Klar�vdalens Datakonsult AB

    Kleopatra is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    Kleopatra is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include <config-kleopatra.h>

#include "aboutdata.h"
#include "systemtrayicon.h"
#ifdef KLEO_BUILD_OLD_MAINWINDOW
# include "certmanager.h"
#else
# include "mainwindow.h"
# include <commands/refreshkeyscommand.h>
#endif

#include "libkleo/kleo/cryptobackendfactory.h"

#include <utils/kdpipeiodevice.h>
#include <utils/log.h>
#ifdef Q_OS_WIN
#include <utils/gnupg-registry.h>
#endif

#ifdef HAVE_USABLE_ASSUAN
# include "kleo-assuan.h"
# include <uiserver/uiserver.h>
# include <uiserver/assuancommand.h>
# include <uiserver/echocommand.h>
# include <uiserver/decryptcommand.h>
# include <uiserver/verifycommand.h>
# include <uiserver/decryptverifyfilescommand.h>
# include <uiserver/decryptfilescommand.h>
# include <uiserver/verifyfilescommand.h>
# include <uiserver/prepencryptcommand.h>
# include <uiserver/encryptcommand.h>
# include <uiserver/signcommand.h>
# include <uiserver/signencryptfilescommand.h>
#else
namespace Kleo {
    class UiServer;
}
#endif

#include <models/keycache.h>

#include <kcmdlineargs.h>
#include <kmessagebox.h>
#include <klocale.h>
#include <kglobal.h>
#include <kiconloader.h>
#include <ksplashscreen.h>
#include <KUniqueApplication>

#include <QDebug>
#include <QFile>
#include <QTextDocument> // for Qt::escape
#include <QProcess>
#include <QSystemTrayIcon>
#include <QMenu>
#include <QAction>

#include <boost/shared_ptr.hpp>

#ifdef Q_OS_WIN
#include <windows.h>
#endif

#include <memory>
#include <cassert>

namespace {
    template <typename T>
    boost::shared_ptr<T> make_shared_ptr( T * t ) {
        return t ? boost::shared_ptr<T>( t ) : boost::shared_ptr<T>() ;
    }
}

#ifdef Q_OS_WIN

static void checkForInvalidRegistryEntries( QWidget* msgParent )
{
    std::auto_ptr<const char> value( read_w32_registry_string( "HKEY_CURRENT_USER", "Software\\GNU\\GnuPG", "gpgProgram" ) );
    if ( !value.get() )
        return;
    if ( KMessageBox::questionYesNo( msgParent,
                                     i18n( "Kleopatra detected an obsolete registry key (\"HKCU\\GNU\\GnuPG\\gpgProgram\"),"
                                           "added by either previous gpg4win versions or applications such as WinPT or EnigMail."
                                           "Keeping the entry might lead to problems during operations (old GnuPG backend being used)."
                                           "It is advised to delete the key." ),
                                     i18n( "Old Registry Entries Detected" ),
                                     KGuiItem( i18n( "Delete Registry Key" ) ),
                                     KStandardGuiItem::cancel(),
                                     "doNotWarnAboutRegistryEntriesAgain" ) != KMessageBox::Yes )
        return;
    const LONG result = RegDeleteKey( HKEY_CURRENT_USER, "Software\\GNU\\GnuPG\\gpgProgram" );
    if ( result == ERROR_SUCCESS )
        return;
    KMessageBox::error( msgParent,
                        i18n( "Could not delete the key \"HKCU\\GNU\\GnuPG\\gpgProgram\" from the registry." ),
                        i18n( "Error Deleting Key" ) );
}
#endif // Q_OS_WIN

static QString environmentVariable( const QString& var, const QString& defaultValue=QString() )
{
    const QStringList env = QProcess::systemEnvironment();
    Q_FOREACH ( const QString& i, env )
    {
        if ( !i.startsWith( var + '=' ) )
            continue;

        const int equalPos = i.indexOf( '=' );
        assert( equalPos >= 0 );
        return i.mid( equalPos + 1 );
    }
    return defaultValue;
}

static void setupLogging()
{
    const QString envOptions = environmentVariable( "KLEOPATRA_LOGOPTIONS", "io" );
    const bool logAll = envOptions.trimmed() == "all";
    const QStringList options = envOptions.split( ',' );

    const QString dir = environmentVariable( "KLEOPATRA_LOGDIR" );
    if ( dir.isEmpty() )
        return;
    std::auto_ptr<QFile> logFile( new QFile( dir + "/kleo-log" ) );
    if ( !logFile->open( QIODevice::WriteOnly | QIODevice::Append ) ) {
        qDebug() << "Could not open file for logging: " << dir + "/kleo-log\nLogging disabled";
        return;
    }

    Kleo::Log::mutableInstance()->setOutputDirectory( dir );
    if ( logAll || options.contains( "io" ) )
        Kleo::Log::mutableInstance()->setIOLoggingEnabled( true );
    qInstallMsgHandler( Kleo::Log::messageHandler );

#ifdef HAVE_USABLE_ASSUAN
    if ( logAll || options.contains( "pipeio" ) )
        KDPipeIODevice::setDebugLevel( KDPipeIODevice::Debug );

    assuan_set_assuan_log_stream( Kleo::Log::instance()->logFile() );
#endif
}

#ifndef KLEO_BUILD_OLD_MAINWINDOW
static void fillKeyCache( KSplashScreen * splash, Kleo::UiServer * server ) {

  QEventLoop loop;
  Kleo::RefreshKeysCommand * cmd = new Kleo::RefreshKeysCommand( 0 );
  QObject::connect( cmd, SIGNAL(finished()), &loop, SLOT(quit()) );
#ifdef HAVE_USABLE_ASSUAN
  QObject::connect( cmd, SIGNAL(finished()), server, SLOT(enableCryptoCommands()) );
#else
  Q_UNUSED( server );
#endif
  splash->showMessage( i18n("Loading certificate cache...") );
  cmd->start();
  loop.exec();
  splash->showMessage( i18n("Certificate cache loaded.") );
}
#endif

int main( int argc, char** argv )
{
  AboutData aboutData;

  KCmdLineArgs::init(argc, argv, &aboutData);

  KCmdLineOptions options;
#ifdef KLEO_BUILD_OLD_MAINWINDOW
  options.add("external", ki18n("Search for external certificates initially"));
  options.add("query ", ki18n("Initial query string"));
#else
  options.add("daemon", ki18n("Run UI server only, hide main window"));
#endif
  options.add("import-certificate ", ki18n("Name of certificate file to import"));
#ifdef HAVE_USABLE_ASSUAN
  options.add("uiserver-socket <argument>", ki18n("Location of the socket the ui server is listening on" ) );
#endif

  KCmdLineArgs::addCmdLineOptions( options );

  // pin KeyCache to a shared_ptr to define it's minimum lifetime:
  const boost::shared_ptr<Kleo::PublicKeyCache> publicKeyCache = Kleo::PublicKeyCache::mutableInstance();
  const boost::shared_ptr<Kleo::SecretKeyCache> secretKeyCache = Kleo::SecretKeyCache::mutableInstance();

  const boost::shared_ptr<Kleo::Log> log = Kleo::Log::mutableInstance();

  setupLogging();

  KUniqueApplication app;

  KCmdLineArgs *args = KCmdLineArgs::parsedArgs();

  KGlobal::locale()->insertCatalog( "libkleopatra" );
  KIconLoader::global()->addAppDir( "libkleopatra" );
  KIconLoader::global()->addAppDir( "kdepim" );

#ifndef KLEO_BUILD_OLD_MAINWINDOW
  SystemTrayIconFor<MainWindow> sysTray;
  sysTray.show();
#endif

  KSplashScreen splash( UserIcon( "kleopatra_splashscreen" ), Qt::WindowStaysOnTopHint );

  int rc;
#ifdef HAVE_USABLE_ASSUAN
  try {
      Kleo::UiServer server( args->getOption("uiserver-socket") );

      server.enableCryptoCommands( false );

# ifndef KLEO_BUILD_OLD_MAINWINDOW
      QObject::connect( &server, SIGNAL(startKeyManagerRequested()),
                        &sysTray, SLOT(openOrRaiseMainWindow()) );
# endif

#define REGISTER( Command ) server.registerCommandFactory( boost::shared_ptr<Kleo::AssuanCommandFactory>( new Kleo::GenericAssuanCommandFactory<Kleo::Command> ) )
      REGISTER( DecryptCommand );
      REGISTER( DecryptFilesCommand );
      REGISTER( DecryptVerifyFilesCommand );
      REGISTER( EchoCommand );
      REGISTER( EncryptCommand );
      REGISTER( EncryptFilesCommand );
      REGISTER( EncryptSignFilesCommand );
      REGISTER( PrepEncryptCommand );
      REGISTER( SignCommand );
      REGISTER( SignEncryptFilesCommand );
      REGISTER( SignFilesCommand );
      REGISTER( VerifyCommand );
      REGISTER( VerifyFilesCommand );
#undef REGISTER

      server.start();

# ifndef KLEO_BUILD_OLD_MAINWINDOW
      sysTray.setToolTip( i18n( "Kleopatra UI Server listening on %1", server.socketName() ) );
# endif
#endif

#ifdef KLEO_BUILD_OLD_MAINWINDOW
      if( !Kleo::CryptoBackendFactory::instance()->smime() ) {
          KMessageBox::error(0,
                             i18n( "<qt>The crypto plugin could not be initialized.
"
                                   "Certificate Manager will terminate now.</qt>") );
          return -2;
      }

      splash.show();

      CertManager* manager = new CertManager( args->isSet("external"),
                                              args->getOption("query"),
                                              args->getOption("import-certificate") );
      manager->show();
      splash.finish( manager );
#else

      const bool daemon = args->isSet("daemon");

      if ( !daemon )
          splash.show();
#ifdef HAVE_USABLE_ASSUAN
      fillKeyCache( &splash, &server );
#else
      fillKeyCache( &splash, 0 );
#endif

      if ( !daemon ) {
          MainWindow* mainWindow = new MainWindow;
          mainWindow->show();
          sysTray.setMainWindow( mainWindow );
          splash.finish( mainWindow );
#ifdef Q_OS_WIN
          checkForInvalidRegistryEntries( mainWindow );
#endif // Q_OS_WIN
      }

#endif

      args->clear();
      QApplication::setQuitOnLastWindowClosed( false );
      rc = app.exec();

#ifdef HAVE_USABLE_ASSUAN
# ifndef KLEO_BUILD_OLD_MAINWINDOW
      QObject::disconnect( &server, SIGNAL(startKeyManagerRequested()),
                           &sysTray, SLOT(openOrRaiseMainWindow()) );
#endif

      server.stop();
      server.waitForStopped();
  } catch ( const std::exception & e ) {
      QMessageBox::information( 0, i18n("GPG UI Server Error"),
                                i18n("<qt>The Kleopatra GPG UI Server Module couldn't be initialized.
"
                                     "The error given was: %1
"
                                     "You can use Kleopatra as a certificate manager, but cryptographic plugins that "
                                     "rely on a GPG UI Server being present might not work correctly, or at all.</qt>",
                                     Qt::escape( QString::fromUtf8( e.what() ) ) ));
      rc = app.exec();
  }
#endif

    return rc;
}
<|endoftext|>


<commit_before>#define _JNI_IMPLEMENTATION_ 1
#include <jni.h>
#include <dlfcn.h>
#include <pthread.h>
#include <assert.h>
#include "KrapsRDD.h"
#include <unistd.h>

static pthread_mutex_t dllMutex = PTHREAD_MUTEX_INITIALIZER;

typedef KrapsIterator* (*iterator_constructor_t)(JNIEnv* env);

static JavaVM* jvm;

struct KrapsRDD
{
    void* dll;
    KrapsIterator* iterator;

    void* next() {
    	return iterator->next();
    }

    KrapsRDD(void* so, KrapsIterator* iter) : dll(so), iterator(iter) {}
    ~KrapsRDD() {
        delete iterator;
        dlclose(dll);
    }
};

class KrapsCluster
{
  public:
    Cluster* cluster;
    char** nodes;

  public:
    void start(JNIEnv* env, jobjectArray hosts, jint nodeId) {
        int nNodes = env->GetArrayLength(hosts);
        nodes = new char*[nNodes];
        for (int i = 0; i < nNodes; i++) {
            jstring host = (jstring)env->GetObjectArrayElement(hosts, i % nNodes);
            char const* hostName = env->GetStringUTFChars(host, 0);
            nodes[i] = new char[strlen(hostName) + 8];
            sprintf(nodes[i], "%s:%d", hostName, 5001 + i);
            env->ReleaseStringUTFChars(host, hostName);
        }
        cluster = new Cluster(nodeId, nNodes, nodes);
        cluster->userData = NULL;
    }

    void stop()
    {
        for (size_t i = 0; i < cluster->nNodes; i++) {
            delete nodes[i];
        }
        delete[] nodes;
        delete cluster;
    }
};

extern "C" {

JNIEXPORT
JavaVM*

JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *vm, void *reserved)
{
    jvm = vm;
    return JNI_VERSION_1_2;
}

JNIEXPORT jlong Java_kraps_KrapsRDD_createIterator(JNIEnv* env, jobject self, jlong kraps, jint queryId, jobjectArray sparkInputs)
{
    char buf[256];
    sprintf(buf, "libQ%d.so", queryId);
//    fprintf(stdout, "Library name: %s\n", buf);
//
//    char cwd[1024];
//	if (getcwd(cwd, sizeof(cwd)) != NULL)
//	   fprintf(stdout, "Current working dir: %s\n", cwd);
//	else
//	   perror("getcwd() error");

	pthread_mutex_lock(&dllMutex);
    void* dll = dlopen(buf, RTLD_NOW | RTLD_GLOBAL);

    assert(dll != NULL);
    sprintf(buf, "getQ%dIterator", queryId);
    iterator_constructor_t constructor = (iterator_constructor_t)dlsym(dll, buf);
    assert(constructor != NULL);
	pthread_mutex_unlock(&dllMutex);

    JavaContext ctx(env, jvm, sparkInputs);
    Cluster* cluster = Cluster::instance.get();
    if (cluster == NULL) {
        cluster = ((KrapsCluster*)kraps)->cluster;
        Cluster::instance.set(cluster);
    } else {
		assert(cluster == ((KrapsCluster*)kraps)->cluster);
	}
    cluster->userData = &ctx;

    return (jlong)(size_t)new KrapsRDD(dll, constructor(env));
}

JNIEXPORT jlong Java_kraps_KrapsRDD_nextRow(JNIEnv* env, jobject self, jlong kraps, jlong iterator, jobjectArray sparkInputs)
{
    KrapsRDD* rdd = (KrapsRDD*)iterator;
    JavaContext ctx(env, jvm, sparkInputs);
    Cluster* cluster = Cluster::instance.get();
    if (cluster == NULL) {
        cluster = ((KrapsCluster*)kraps)->cluster;
        Cluster::instance.set(cluster);
    }
    cluster->userData = &ctx;
    void* row = rdd->next();
    if (row != NULL) {
        return (jlong)(size_t)row;
    }
    cluster->barrier();
    delete rdd;
    return 0;
}

JNIEXPORT jlong Java_kraps_KrapsCluster_00024_start(JNIEnv* env, jobject self, jobjectArray hosts, jint nodeId)
{
    KrapsCluster* cluster = new KrapsCluster();
    cluster->start(env, hosts, nodeId);
    return (jlong)(size_t)cluster;
}

JNIEXPORT void Java_kraps_KrapsCluster_00024_stop(JNIEnv* env, jobject self, jlong kraps)
{
    KrapsCluster* cluster = (KrapsCluster*)kraps;
    cluster->stop();
    delete cluster;
}

}
<commit_msg>Correctly set JVM context<commit_after>#define _JNI_IMPLEMENTATION_ 1
#include <jni.h>
#include <dlfcn.h>
#include <pthread.h>
#include <assert.h>
#include "KrapsRDD.h"
#include <unistd.h>

static pthread_mutex_t dllMutex = PTHREAD_MUTEX_INITIALIZER;

typedef KrapsIterator* (*iterator_constructor_t)(JNIEnv* env);

static JavaVM* jvm;

struct KrapsRDD
{
    void* dll;
    KrapsIterator* iterator;

    void* next() {
    	return iterator->next();
    }

    KrapsRDD(void* so, KrapsIterator* iter) : dll(so), iterator(iter) {}
    ~KrapsRDD() {
        delete iterator;
        dlclose(dll);
    }
};

class KrapsCluster
{
  public:
    Cluster* cluster;
    char** nodes;

  public:
    void start(JNIEnv* env, jobjectArray hosts, jint nodeId) {
        int nNodes = env->GetArrayLength(hosts);
        nodes = new char*[nNodes];
        for (int i = 0; i < nNodes; i++) {
            jstring host = (jstring)env->GetObjectArrayElement(hosts, i % nNodes);
            char const* hostName = env->GetStringUTFChars(host, 0);
            nodes[i] = new char[strlen(hostName) + 8];
            sprintf(nodes[i], "%s:%d", hostName, 5001 + i);
            env->ReleaseStringUTFChars(host, hostName);
        }
        cluster = new Cluster(nodeId, nNodes, nodes);
        cluster->userData = NULL;
    }

    void stop()
    {
        for (size_t i = 0; i < cluster->nNodes; i++) {
            delete nodes[i];
        }
        delete[] nodes;
        delete cluster;
    }
};

extern "C" {

JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *vm, void *reserved)
{
    jvm = vm;
    return JNI_VERSION_1_2;
}

JNIEXPORT jlong Java_kraps_KrapsRDD_createIterator(JNIEnv* env, jobject self, jlong kraps, jint queryId, jobjectArray sparkInputs)
{
    char buf[256];
    sprintf(buf, "libQ%d.so", queryId);
//    fprintf(stdout, "Library name: %s\n", buf);
//
//    char cwd[1024];
//	if (getcwd(cwd, sizeof(cwd)) != NULL)
//	   fprintf(stdout, "Current working dir: %s\n", cwd);
//	else
//	   perror("getcwd() error");

	pthread_mutex_lock(&dllMutex);
    void* dll = dlopen(buf, RTLD_NOW | RTLD_GLOBAL);

    assert(dll != NULL);
    sprintf(buf, "getQ%dIterator", queryId);
    iterator_constructor_t constructor = (iterator_constructor_t)dlsym(dll, buf);
    assert(constructor != NULL);
	pthread_mutex_unlock(&dllMutex);

    JavaContext ctx(env, jvm, sparkInputs);
    Cluster* cluster = Cluster::instance.get();
    if (cluster == NULL) {
        cluster = ((KrapsCluster*)kraps)->cluster;
        Cluster::instance.set(cluster);
    } else {
		assert(cluster == ((KrapsCluster*)kraps)->cluster);
	}
    cluster->userData = &ctx;

    return (jlong)(size_t)new KrapsRDD(dll, constructor(env));
}

JNIEXPORT jlong Java_kraps_KrapsRDD_nextRow(JNIEnv* env, jobject self, jlong kraps, jlong iterator, jobjectArray sparkInputs)
{
    KrapsRDD* rdd = (KrapsRDD*)iterator;
    JavaContext ctx(env, jvm, sparkInputs);
    Cluster* cluster = Cluster::instance.get();
    if (cluster == NULL) {
        cluster = ((KrapsCluster*)kraps)->cluster;
        Cluster::instance.set(cluster);
    }
    cluster->userData = &ctx;
    void* row = rdd->next();
    if (row != NULL) {
        return (jlong)(size_t)row;
    }
    cluster->barrier();
    delete rdd;
    return 0;
}

JNIEXPORT jlong Java_kraps_KrapsCluster_00024_start(JNIEnv* env, jobject self, jobjectArray hosts, jint nodeId)
{
    KrapsCluster* cluster = new KrapsCluster();
    cluster->start(env, hosts, nodeId);
    return (jlong)(size_t)cluster;
}

JNIEXPORT void Java_kraps_KrapsCluster_00024_stop(JNIEnv* env, jobject self, jlong kraps)
{
    KrapsCluster* cluster = (KrapsCluster*)kraps;
    cluster->stop();
    delete cluster;
}

}
<|endoftext|>


<commit_before>#include <sch/S_Polyhedron/Polyhedron_algorithms.h>

#include <sch/File_Parsing/SimplestParsing.h>

#include <fstream>
#include <stdexcept>
#include <string>

using namespace sch;

Polyhedron_algorithms::Polyhedron_algorithms(void)
    : fastVertexes_(0x0),
      lastVertexes_(0x0),
      numberOfVertices_(0)
{

}

Polyhedron_algorithms::Polyhedron_algorithms(const Polyhedron_algorithms &p)
  :triangles_(p.triangles_)
  ,fastVertexes_(0x0)
  ,lastVertexes_(0x0)
{
  for (unsigned i=0; i<p.vertexes_.size(); ++i)
  {
    vertexes_.push_back(p.vertexes_[i]->clone());
  }

  updateVertexNeighbors();

  updateFastArrays();
}

Polyhedron_algorithms::~Polyhedron_algorithms(void)
{
  if (fastVertexes_!=NULL)
  {
    delete[] fastVertexes_;
  }
  for (unsigned int i=0; i<vertexes_.size(); ++i)
  {
    delete vertexes_[i];
  }
}

const Polyhedron_algorithms& Polyhedron_algorithms::operator =(const Polyhedron_algorithms &p)
{
  if (this==&p)
  {
    return *this;
  }
  else
  {
    clear();
    triangles_=p.triangles_;

    for (unsigned i=0; i<p.vertexes_.size(); ++i)
    {
      vertexes_.push_back(p.vertexes_[i]->clone());
    }

    updateVertexNeighbors();

    updateFastArrays();

    return *this;
  }
}

void Polyhedron_algorithms::openFromFile(const std::string &filename)
{
  clear();

  std::ifstream is(filename.c_str());
  if(!is.is_open())
  {
    std::stringstream errmsg;
    errmsg << "EXCEPTION: Unable to open File " << filename << std::endl;
    throw std::invalid_argument(errmsg.str());
  }

  std::string line;

  // Discard first line
  std::getline(is, line);
  size_t nr_vertexes;
  size_t nr_faces;
  is>>nr_vertexes; //get the number of points
  vertexes_.reserve(nr_vertexes);
  is>>nr_faces;
  triangles_.reserve(nr_faces);
  // Discard the last number
  std::getline(is, line);
  for (size_t g=0; g<nr_vertexes; g++)
  {
    Scalar y[3];
    is >> y[0] >> y[1] >> y[2];//get the coords

    S_PolyhedronVertex *v;
    v=new S_PolyhedronVertex();
    v->setCoordinates(y[0],y[1],y[2]);
    v->setNumber(unsigned (vertexes_.size()));
    vertexes_.push_back(v);

  }

  //get the normals
  const size_t normalSearchLen = 13;
  const char normalSearch[normalSearchLen + 1] = "    - normal:";
  const size_t verticesSearchLen = 15;
  const char verticesSearch[verticesSearchLen + 1] = "    - vertices:";
  while(std::getline(is, line).good())
  {
    if(line.substr(0, normalSearchLen) == normalSearch)
    {
      std::stringstream ss;
      ss << line.substr(normalSearchLen);
      Scalar y[3];

      PolyhedronTriangle t;

      ss>>y[0];
      ss>>y[1];
      ss>>y[2];

      t.normal.Set(y[0],y[1],y[2]);
      t.normal.normalize();

      while(std::getline(is, line).good())
      {
        if(line.substr(0, verticesSearchLen) == verticesSearch)
        {
          std::stringstream ss;
          ss << line.substr(verticesSearchLen);
          char c = '\0';
          while(c!='p' && ss.good()) { ss.get(c); }
          ss >> t.a;
          c = '\0';
          while(c!='p' && ss.good()) { ss.get(c); }
          ss >> t.b;
          c = '\0';
          while(c!='p' && ss.good()) { ss.get(c); }
          ss >> t.c;

          //updatingNeighbors
          vertexes_[t.a]->addNeighbor(vertexes_[t.b]);
          vertexes_[t.a]->addNeighbor(vertexes_[t.c]);

          vertexes_[t.b]->addNeighbor(vertexes_[t.a]);
          vertexes_[t.b]->addNeighbor(vertexes_[t.c]);

          vertexes_[t.c]->addNeighbor(vertexes_[t.a]);
          vertexes_[t.c]->addNeighbor(vertexes_[t.b]);

          triangles_.push_back(t);

          break;
        }
      }
    }
  }

  for (unsigned int i=0; i<vertexes_.size(); i++)
  {
    vertexes_[i]->updateFastArrays();
  }

  deleteVertexesWithoutNeighbors();
}

void Polyhedron_algorithms::updateVertexNeighbors()
{
  for (unsigned i=0; i<triangles_.size(); ++i)
  {
    //updatingNeighbors
    vertexes_[triangles_[i].a]->addNeighbor(vertexes_[triangles_[i].b]);
    vertexes_[triangles_[i].a]->addNeighbor(vertexes_[triangles_[i].c]);

    vertexes_[triangles_[i].b]->addNeighbor(vertexes_[triangles_[i].a]);
    vertexes_[triangles_[i].b]->addNeighbor(vertexes_[triangles_[i].c]);

    vertexes_[triangles_[i].c]->addNeighbor(vertexes_[triangles_[i].a]);
    vertexes_[triangles_[i].c]->addNeighbor(vertexes_[triangles_[i].b]);
  }

  for (unsigned i=0; i<vertexes_.size(); ++i)
  {
    vertexes_[i]->updateFastArrays();
  }
}

void Polyhedron_algorithms::clear()
{
  for (unsigned int i=0; i<vertexes_.size(); ++i)
  {
    delete vertexes_[i];
  }
  vertexes_.clear();
  triangles_.clear();
  updateFastArrays();
}

void Polyhedron_algorithms::clearNeighbors()
{
  for (unsigned i=0; i<vertexes_.size(); ++i)
  {
    vertexes_[i]->clearNeighbors();
    vertexes_[i]->updateFastArrays();
  }
}

void Polyhedron_algorithms::updateFastArrays()
{
  if (fastVertexes_!=NULL)
  {
    delete[] fastVertexes_;
  }
  numberOfVertices_ = unsigned(vertexes_.size());
  if (numberOfVertices_ > 0)
  {
    fastVertexes_ = new S_PolyhedronVertex *[numberOfVertices_];
    for (unsigned int i = 0; i < numberOfVertices_; ++i)
    {
      fastVertexes_[i]=vertexes_[i];
    }

    lastVertexes_ = &(fastVertexes_[numberOfVertices_]);
  }
  else
  {
    fastVertexes_=lastVertexes_=NULL;
  }
}

Point3 Polyhedron_algorithms::naiveSupport(const Vector3&v)const
{
  S_PolyhedronVertex** current;

  current=fastVertexes_;

  Scalar supportH=(*current)->supportH(v);

  Vector3 best=(*current)->getCoordinates();

  current++;

  for (unsigned i = 1; i < numberOfVertices_; i++, current++)
  {
    if ((*current)->supportH(v) > supportH)
    {
      supportH = (*current)->supportH(v);
      best = (*current)->getCoordinates();
    }
  }

  return best;
}

Point3 Polyhedron_algorithms::support(const Vector3&v,int &lastFeature)const
{
  S_PolyhedronVertex* current;
  Scalar supportH;

  if (lastFeature==-1)
  {
    current=*fastVertexes_;
  }
  else
  {
    current=fastVertexes_[lastFeature];
  }

  bool b=current->isHere(v);

  while (!b)
  {
    supportH= current->getNextVertexH();
    current = current->getNextVertex();
    b=current->isHere(v,supportH);
  }

  lastFeature=current->getNumber();

  return current->getCoordinates();

}

void Polyhedron_algorithms::deleteVertexesWithoutNeighbors()
{
  int *cache=new int[vertexes_.size()];
  std::vector<S_PolyhedronVertex*> v;
  int index=0;

  for (unsigned i=0; i<vertexes_.size(); ++i)
  {
    if (vertexes_[i]->getNumNeighbors()>0)
    {
      v.push_back(vertexes_[i]);
      vertexes_[i]->setNumber(index);
      cache[i]=index++;
    }
    else
    {
      delete vertexes_[i];
      cache[i]=-1;
    }
  }

  for (unsigned i=0; i<triangles_.size(); ++i)
  {
    triangles_[i].a=cache[triangles_[i].a];
    triangles_[i].b=cache[triangles_[i].b];
    triangles_[i].c=cache[triangles_[i].c];
  }

  vertexes_=v;

  updateFastArrays();

  delete[] cache;

}
<commit_msg>[polyhedron] Ensure the polyhedron is not empty when running computations<commit_after>#include <sch/S_Polyhedron/Polyhedron_algorithms.h>

#include <sch/File_Parsing/SimplestParsing.h>

#include <fstream>
#include <stdexcept>
#include <string>

using namespace sch;

Polyhedron_algorithms::Polyhedron_algorithms(void)
    : fastVertexes_(0x0),
      lastVertexes_(0x0),
      numberOfVertices_(0)
{

}

Polyhedron_algorithms::Polyhedron_algorithms(const Polyhedron_algorithms &p)
  :triangles_(p.triangles_)
  ,fastVertexes_(0x0)
  ,lastVertexes_(0x0)
{
  for (unsigned i=0; i<p.vertexes_.size(); ++i)
  {
    vertexes_.push_back(p.vertexes_[i]->clone());
  }

  updateVertexNeighbors();

  updateFastArrays();
}

Polyhedron_algorithms::~Polyhedron_algorithms(void)
{
  if (fastVertexes_!=NULL)
  {
    delete[] fastVertexes_;
  }
  for (unsigned int i=0; i<vertexes_.size(); ++i)
  {
    delete vertexes_[i];
  }
}

const Polyhedron_algorithms& Polyhedron_algorithms::operator =(const Polyhedron_algorithms &p)
{
  if (this==&p)
  {
    return *this;
  }
  else
  {
    clear();
    triangles_=p.triangles_;

    for (unsigned i=0; i<p.vertexes_.size(); ++i)
    {
      vertexes_.push_back(p.vertexes_[i]->clone());
    }

    updateVertexNeighbors();

    updateFastArrays();

    return *this;
  }
}

void Polyhedron_algorithms::openFromFile(const std::string &filename)
{
  clear();

  std::ifstream is(filename.c_str());
  if(!is.is_open())
  {
    std::stringstream errmsg;
    errmsg << "EXCEPTION: Unable to open File " << filename << std::endl;
    throw std::invalid_argument(errmsg.str());
  }

  std::string line;

  // Discard first line
  std::getline(is, line);
  size_t nr_vertexes;
  size_t nr_faces;
  is>>nr_vertexes; //get the number of points
  vertexes_.reserve(nr_vertexes);
  is>>nr_faces;
  triangles_.reserve(nr_faces);
  // Discard the last number
  std::getline(is, line);
  for (size_t g=0; g<nr_vertexes; g++)
  {
    Scalar y[3];
    is >> y[0] >> y[1] >> y[2];//get the coords

    S_PolyhedronVertex *v;
    v=new S_PolyhedronVertex();
    v->setCoordinates(y[0],y[1],y[2]);
    v->setNumber(unsigned (vertexes_.size()));
    vertexes_.push_back(v);

  }

  //get the normals
  const size_t normalSearchLen = 13;
  const char normalSearch[normalSearchLen + 1] = "    - normal:";
  const size_t verticesSearchLen = 15;
  const char verticesSearch[verticesSearchLen + 1] = "    - vertices:";
  while(std::getline(is, line).good())
  {
    if(line.substr(0, normalSearchLen) == normalSearch)
    {
      std::stringstream ss;
      ss << line.substr(normalSearchLen);
      Scalar y[3];

      PolyhedronTriangle t;

      ss>>y[0];
      ss>>y[1];
      ss>>y[2];

      t.normal.Set(y[0],y[1],y[2]);
      t.normal.normalize();

      while(std::getline(is, line).good())
      {
        if(line.substr(0, verticesSearchLen) == verticesSearch)
        {
          std::stringstream ss;
          ss << line.substr(verticesSearchLen);
          char c = '\0';
          while(c!='p' && ss.good()) { ss.get(c); }
          ss >> t.a;
          c = '\0';
          while(c!='p' && ss.good()) { ss.get(c); }
          ss >> t.b;
          c = '\0';
          while(c!='p' && ss.good()) { ss.get(c); }
          ss >> t.c;

          //updatingNeighbors
          vertexes_[t.a]->addNeighbor(vertexes_[t.b]);
          vertexes_[t.a]->addNeighbor(vertexes_[t.c]);

          vertexes_[t.b]->addNeighbor(vertexes_[t.a]);
          vertexes_[t.b]->addNeighbor(vertexes_[t.c]);

          vertexes_[t.c]->addNeighbor(vertexes_[t.a]);
          vertexes_[t.c]->addNeighbor(vertexes_[t.b]);

          triangles_.push_back(t);

          break;
        }
      }
    }
  }

  for (unsigned int i=0; i<vertexes_.size(); i++)
  {
    vertexes_[i]->updateFastArrays();
  }

  deleteVertexesWithoutNeighbors();
}

void Polyhedron_algorithms::updateVertexNeighbors()
{
  for (unsigned i=0; i<triangles_.size(); ++i)
  {
    //updatingNeighbors
    vertexes_[triangles_[i].a]->addNeighbor(vertexes_[triangles_[i].b]);
    vertexes_[triangles_[i].a]->addNeighbor(vertexes_[triangles_[i].c]);

    vertexes_[triangles_[i].b]->addNeighbor(vertexes_[triangles_[i].a]);
    vertexes_[triangles_[i].b]->addNeighbor(vertexes_[triangles_[i].c]);

    vertexes_[triangles_[i].c]->addNeighbor(vertexes_[triangles_[i].a]);
    vertexes_[triangles_[i].c]->addNeighbor(vertexes_[triangles_[i].b]);
  }

  for (unsigned i=0; i<vertexes_.size(); ++i)
  {
    vertexes_[i]->updateFastArrays();
  }
}

void Polyhedron_algorithms::clear()
{
  for (unsigned int i=0; i<vertexes_.size(); ++i)
  {
    delete vertexes_[i];
  }
  vertexes_.clear();
  triangles_.clear();
  updateFastArrays();
}

void Polyhedron_algorithms::clearNeighbors()
{
  for (unsigned i=0; i<vertexes_.size(); ++i)
  {
    vertexes_[i]->clearNeighbors();
    vertexes_[i]->updateFastArrays();
  }
}

void Polyhedron_algorithms::updateFastArrays()
{
  if (fastVertexes_!=NULL)
  {
    delete[] fastVertexes_;
  }
  numberOfVertices_ = unsigned(vertexes_.size());
  if (numberOfVertices_ > 0)
  {
    fastVertexes_ = new S_PolyhedronVertex *[numberOfVertices_];
    for (unsigned int i = 0; i < numberOfVertices_; ++i)
    {
      fastVertexes_[i]=vertexes_[i];
    }

    lastVertexes_ = &(fastVertexes_[numberOfVertices_]);
  }
  else
  {
    fastVertexes_=lastVertexes_=NULL;
  }
}

Point3 Polyhedron_algorithms::naiveSupport(const Vector3&v)const
{
  S_PolyhedronVertex** current;

  current=fastVertexes_;

  Scalar supportH=(*current)->supportH(v);

  Vector3 best=(*current)->getCoordinates();

  current++;

  for (unsigned i = 1; i < numberOfVertices_; i++, current++)
  {
    if ((*current)->supportH(v) > supportH)
    {
      supportH = (*current)->supportH(v);
      best = (*current)->getCoordinates();
    }
  }

  return best;
}

Point3 Polyhedron_algorithms::support(const Vector3&v,int &lastFeature)const
{
  S_PolyhedronVertex* current;
  Scalar supportH;

  if (numberOfVertices_==0)
  {
    std::stringstream errmsg;
    errmsg << "The polyhedron is empty, impossible to compute support function " << std::endl;
    throw std::length_error(errmsg.str());
  }

  if (lastFeature==-1)
  {
    current=*fastVertexes_;
  }
  else
  {
    current=fastVertexes_[lastFeature];
  }

  bool b=current->isHere(v);

  while (!b)
  {
    supportH= current->getNextVertexH();
    current = current->getNextVertex();
    b=current->isHere(v,supportH);
  }

  lastFeature=current->getNumber();

  return current->getCoordinates();

}

void Polyhedron_algorithms::deleteVertexesWithoutNeighbors()
{
  int *cache=new int[vertexes_.size()];
  std::vector<S_PolyhedronVertex*> v;
  int index=0;

  for (unsigned i=0; i<vertexes_.size(); ++i)
  {
    if (vertexes_[i]->getNumNeighbors()>0)
    {
      v.push_back(vertexes_[i]);
      vertexes_[i]->setNumber(index);
      cache[i]=index++;
    }
    else
    {
      delete vertexes_[i];
      cache[i]=-1;
    }
  }

  for (unsigned i=0; i<triangles_.size(); ++i)
  {
    triangles_[i].a=cache[triangles_[i].a];
    triangles_[i].b=cache[triangles_[i].b];
    triangles_[i].c=cache[triangles_[i].c];
  }

  vertexes_=v;

  updateFastArrays();

  delete[] cache;

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: documentdigitalsignatures.cxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: mmi $ $Date: 2004-08-12 02:29:20 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <documentdigitalsignatures.hxx>
#include <xmlsecurity/digitalsignaturesdialog.hxx>
#include <xmlsecurity/certificateviewer.hxx>
#include <xmlsecurity/macrosecurity.hxx>
#include <xmlsecurity/baseencoding.hxx>
#include <xmlsecurity/biginteger.hxx>

#include <../dialogs/resourcemanager.hxx>

#ifndef _COM_SUN_STAR_EMBED_XSTORAGE_HPP_
#include <com/sun/star/embed/XStorage.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_ELEMENTMODES_HPP_
#include <com/sun/star/embed/ElementModes.hpp>
#endif
#ifndef INCLUDED_SVTOOLS_SECURITYOPTIONS_HXX
#include <svtools/securityoptions.hxx>
#endif

using namespace ::com::sun::star;
using namespace ::com::sun::star;

DocumentDigitalSignatures::DocumentDigitalSignatures( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory> rxMSF )
{
    mxMSF = rxMSF;
}

sal_Bool DocumentDigitalSignatures::SignDocumentContent( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage ) throw (::com::sun::star::uno::RuntimeException)
{
    return ImplViewSignatures( rxStorage, SignatureModeDocumentContent, false );
}

::com::sun::star::uno::Sequence< ::com::sun::star::security::DocumentSignaturesInformation > DocumentDigitalSignatures::VerifyDocumentContentSignatures( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage ) throw (::com::sun::star::uno::RuntimeException)
{
    return ImplVerifySignatures( rxStorage, SignatureModeDocumentContent );
}

void DocumentDigitalSignatures::ShowDocumentContentSignatures( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage ) throw (::com::sun::star::uno::RuntimeException)
{
    ImplViewSignatures( rxStorage, SignatureModeDocumentContent, true );
}

sal_Bool DocumentDigitalSignatures::SignScriptingContent( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage ) throw (::com::sun::star::uno::RuntimeException)
{
    return ImplViewSignatures( rxStorage, SignatureModeMacros, false );
}

::com::sun::star::uno::Sequence< ::com::sun::star::security::DocumentSignaturesInformation > DocumentDigitalSignatures::VerifyScriptingContentSignatures( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage ) throw (::com::sun::star::uno::RuntimeException)
{
    return ImplVerifySignatures( rxStorage, SignatureModeMacros );
}

void DocumentDigitalSignatures::ShowScriptingContentSignatures( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage ) throw (::com::sun::star::uno::RuntimeException)
{
    ImplViewSignatures( rxStorage, SignatureModeMacros, true );
}

sal_Bool DocumentDigitalSignatures::SignPackage( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage ) throw (::com::sun::star::uno::RuntimeException)
{
    return ImplViewSignatures( rxStorage, SignatureModePackage, false );
}

::com::sun::star::uno::Sequence< ::com::sun::star::security::DocumentSignaturesInformation > DocumentDigitalSignatures::VerifyPackageSignatures( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage ) throw (::com::sun::star::uno::RuntimeException)
{
    return ImplVerifySignatures( rxStorage, SignatureModePackage );
}

void DocumentDigitalSignatures::ShowPackageSignatures( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage ) throw (::com::sun::star::uno::RuntimeException)
{
    ImplViewSignatures( rxStorage, SignatureModePackage, true );
}

sal_Bool DocumentDigitalSignatures::ImplViewSignatures( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage, DocumentSignatureMode eMode, bool bReadOnly ) throw (::com::sun::star::uno::RuntimeException)
{
    DigitalSignaturesDialog aSignaturesDialog( NULL, mxMSF, eMode, bReadOnly );

    bool bInit = aSignaturesDialog.Init( rtl::OUString() );
    DBG_ASSERT( bInit, "Error initializing security context!" );
    if ( bInit )
    {
        aSignaturesDialog.SetStorage( rxStorage );
        aSignaturesDialog.Execute();
    }

    return aSignaturesDialog.SignaturesChanged();
}

com::sun::star::uno::Sequence< ::com::sun::star::security::DocumentSignaturesInformation > DocumentDigitalSignatures::ImplVerifySignatures( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage, DocumentSignatureMode eMode ) throw (::com::sun::star::uno::RuntimeException)
{
    XMLSignatureHelper aSignatureHelper( mxMSF );
    aSignatureHelper.Init( rtl::OUString() );
    aSignatureHelper.SetStorage( rxStorage );

    aSignatureHelper.StartMission();

    SignatureStreamHelper aStreamHelper = DocumentSignatureHelper::OpenSignatureStream( rxStorage, embed::ElementModes::READ, eMode );
    if ( aStreamHelper.xSignatureStream.is() )
    {
        uno::Reference< io::XInputStream > xInputStream( aStreamHelper.xSignatureStream, uno::UNO_QUERY );
        aSignatureHelper.ReadAndVerifySignature( xInputStream );
    }

    aSignatureHelper.EndMission();

    aStreamHelper.Clear();

    uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > xSecEnv = aSignatureHelper.GetSecurityEnvironment();

    SignatureInformations aSignInfos = aSignatureHelper.GetSignatureInformations();
    int nInfos = aSignInfos.size();
    ::com::sun::star::uno::Sequence< ::com::sun::star::security::DocumentSignaturesInformation > aInfos(nInfos);

    if ( nInfos )
    {
        std::vector< rtl::OUString > aElementsToBeVerified = DocumentSignatureHelper::CreateElementList( rxStorage, ::rtl::OUString(), eMode );
        for( int n = 0; n < nInfos; ++n )
        {
            const SignatureInformation& rInfo = aSignInfos[n];
            aInfos[n].Signer = xSecEnv->getCertificate( rInfo.ouX509IssuerName, numericStringToBigInteger( rInfo.ouX509SerialNumber ) );
            if ( !aInfos[n].Signer.is() )
                aInfos[n].Signer = xSecEnv->createCertificateFromAscii( rInfo.ouX509Certificate ) ;

            // MM : the ouDate and ouTime fields have been replaced with stDateTime (com::sun::star::util::DataTime)
            /*
            aInfos[n].SignatureDate = String( rInfo.ouDate ).ToInt32();
            aInfos[n].SignatureTime = String( rInfo.ouTime ).ToInt32();
            */

            DBG_ASSERT( rInfo.nStatus != STATUS_INIT, "Signature not processed!" );

            aInfos[n].SignatureIsValid = ( rInfo.nStatus == STATUS_VERIFY_SUCCEED );

            if ( aInfos[n].SignatureIsValid )
            {
                // Can only be valid if ALL streams are signed, which means real stream count == signed stream count
                int nRealCount = 0;
                for ( int i = rInfo.vSignatureReferenceInfors.size(); i; )
                {
                    const SignatureReferenceInformation& rInf = rInfo.vSignatureReferenceInfors[--i];
                    // There is also an extra entry of type TYPE_SAMEDOCUMENT_REFERENCE because of signature date.
                    if ( ( rInf.nType == TYPE_BINARYSTREAM_REFERENCE ) || ( rInf.nType == TYPE_XMLSTREAM_REFERENCE ) )
                        nRealCount++;
                }
                aInfos[n].SignatureIsValid = ( aElementsToBeVerified.size() == nRealCount );
            }

        }
    }
    return aInfos;

}

void DocumentDigitalSignatures::manageTrustedSources(  ) throw (::com::sun::star::uno::RuntimeException)
{
    XMLSignatureHelper aSignatureHelper( mxMSF );
    aSignatureHelper.Init( rtl::OUString() );
    MacroSecurity aDlg( NULL, aSignatureHelper.GetSecurityEnvironment() );
    aDlg.Execute();
}

void DocumentDigitalSignatures::ShowCertificate( const ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate >& _Certificate ) throw (::com::sun::star::uno::RuntimeException)
{
    XMLSignatureHelper aSignatureHelper( mxMSF );
    aSignatureHelper.Init( rtl::OUString() );
    CertificateViewer aViewer( NULL, aSignatureHelper.GetSecurityEnvironment(), _Certificate );
    aViewer.Execute();

}

::sal_Bool DocumentDigitalSignatures::isAuthorTrusted( const ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate >& Author ) throw (::com::sun::star::uno::RuntimeException)
{
    return sal_False;
}

::sal_Bool DocumentDigitalSignatures::isLocationTrusted( const ::rtl::OUString& Location ) throw (::com::sun::star::uno::RuntimeException)
{
    return sal_False;
}

void DocumentDigitalSignatures::addAuthorToTrustedSources( const ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate >& Author ) throw (::com::sun::star::uno::RuntimeException)
{
    SvtSecurityOptions aSecOpts;

    SvtSecurityOptions::Certificate aNewCert( 3 );
    aNewCert[ 0 ] = Author->getIssuerName();
    aNewCert[ 1 ] = bigIntegerToNumericString( Author->getSerialNumber() );
    aNewCert[ 2 ] = baseEncode( Author->getEncoded(), BASE64 );

    uno::Sequence< SvtSecurityOptions::Certificate > aTrustedAuthors = aSecOpts.GetTrustedAuthors();
    sal_Int32 nCnt = aTrustedAuthors.getLength();
    aTrustedAuthors.realloc( nCnt + 1 );
    aTrustedAuthors[ nCnt ] = aNewCert;

    aSecOpts.SetTrustedAuthors( aTrustedAuthors );
}

void DocumentDigitalSignatures::addLocationToTrustedSources( const ::rtl::OUString& Location ) throw (::com::sun::star::uno::RuntimeException)
{
    SvtSecurityOptions aSecOpt;

    ::com::sun::star::uno::Sequence< ::rtl::OUString > aSecURLs = aSecOpt.GetSecureURLs();
    sal_Int32 nCnt = aSecURLs.getLength();
    aSecURLs.realloc( nCnt + 1 );
    aSecURLs[ nCnt ] = Location;

    aSecOpt.SetSecureURLs( aSecURLs );
}

rtl::OUString DocumentDigitalSignatures::GetImplementationName() throw (uno::RuntimeException)
{
    return rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) );
}

uno::Sequence< rtl::OUString > DocumentDigitalSignatures::GetSupportedServiceNames() throw (cssu::RuntimeException)
{
    uno::Sequence < rtl::OUString > aRet(1);
    rtl::OUString* pArray = aRet.getArray();
    pArray[0] =  rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) );
    return aRet;
}

com::sun::star::uno::Reference< com::sun::star::uno::XInterface > DocumentDigitalSignatures_CreateInstance(
    const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rSMgr) throw ( com::sun::star::uno::Exception )
{
    return (cppu::OWeakObject*) new DocumentDigitalSignatures( rSMgr );
}
<commit_msg>fix: #i33090# isLocationTrusted() implemented<commit_after>/*************************************************************************
 *
 *  $RCSfile: documentdigitalsignatures.cxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: pb $ $Date: 2004-08-20 08:41:20 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <documentdigitalsignatures.hxx>
#include <xmlsecurity/digitalsignaturesdialog.hxx>
#include <xmlsecurity/certificateviewer.hxx>
#include <xmlsecurity/macrosecurity.hxx>
#include <xmlsecurity/baseencoding.hxx>
#include <xmlsecurity/biginteger.hxx>

#include <../dialogs/resourcemanager.hxx>

#ifndef _COM_SUN_STAR_EMBED_XSTORAGE_HPP_
#include <com/sun/star/embed/XStorage.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_ELEMENTMODES_HPP_
#include <com/sun/star/embed/ElementModes.hpp>
#endif
#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif
#ifndef INCLUDED_SVTOOLS_SECURITYOPTIONS_HXX
#include <svtools/securityoptions.hxx>
#endif

using namespace ::com::sun::star;
using namespace ::com::sun::star;

DocumentDigitalSignatures::DocumentDigitalSignatures( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory> rxMSF )
{
    mxMSF = rxMSF;
}

sal_Bool DocumentDigitalSignatures::SignDocumentContent( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage ) throw (::com::sun::star::uno::RuntimeException)
{
    return ImplViewSignatures( rxStorage, SignatureModeDocumentContent, false );
}

::com::sun::star::uno::Sequence< ::com::sun::star::security::DocumentSignaturesInformation > DocumentDigitalSignatures::VerifyDocumentContentSignatures( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage ) throw (::com::sun::star::uno::RuntimeException)
{
    return ImplVerifySignatures( rxStorage, SignatureModeDocumentContent );
}

void DocumentDigitalSignatures::ShowDocumentContentSignatures( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage ) throw (::com::sun::star::uno::RuntimeException)
{
    ImplViewSignatures( rxStorage, SignatureModeDocumentContent, true );
}

sal_Bool DocumentDigitalSignatures::SignScriptingContent( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage ) throw (::com::sun::star::uno::RuntimeException)
{
    return ImplViewSignatures( rxStorage, SignatureModeMacros, false );
}

::com::sun::star::uno::Sequence< ::com::sun::star::security::DocumentSignaturesInformation > DocumentDigitalSignatures::VerifyScriptingContentSignatures( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage ) throw (::com::sun::star::uno::RuntimeException)
{
    return ImplVerifySignatures( rxStorage, SignatureModeMacros );
}

void DocumentDigitalSignatures::ShowScriptingContentSignatures( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage ) throw (::com::sun::star::uno::RuntimeException)
{
    ImplViewSignatures( rxStorage, SignatureModeMacros, true );
}

sal_Bool DocumentDigitalSignatures::SignPackage( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage ) throw (::com::sun::star::uno::RuntimeException)
{
    return ImplViewSignatures( rxStorage, SignatureModePackage, false );
}

::com::sun::star::uno::Sequence< ::com::sun::star::security::DocumentSignaturesInformation > DocumentDigitalSignatures::VerifyPackageSignatures( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage ) throw (::com::sun::star::uno::RuntimeException)
{
    return ImplVerifySignatures( rxStorage, SignatureModePackage );
}

void DocumentDigitalSignatures::ShowPackageSignatures( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage ) throw (::com::sun::star::uno::RuntimeException)
{
    ImplViewSignatures( rxStorage, SignatureModePackage, true );
}

sal_Bool DocumentDigitalSignatures::ImplViewSignatures( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage, DocumentSignatureMode eMode, bool bReadOnly ) throw (::com::sun::star::uno::RuntimeException)
{
    DigitalSignaturesDialog aSignaturesDialog( NULL, mxMSF, eMode, bReadOnly );

    bool bInit = aSignaturesDialog.Init( rtl::OUString() );
    DBG_ASSERT( bInit, "Error initializing security context!" );
    if ( bInit )
    {
        aSignaturesDialog.SetStorage( rxStorage );
        aSignaturesDialog.Execute();
    }

    return aSignaturesDialog.SignaturesChanged();
}

com::sun::star::uno::Sequence< ::com::sun::star::security::DocumentSignaturesInformation > DocumentDigitalSignatures::ImplVerifySignatures( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage, DocumentSignatureMode eMode ) throw (::com::sun::star::uno::RuntimeException)
{
    XMLSignatureHelper aSignatureHelper( mxMSF );
    aSignatureHelper.Init( rtl::OUString() );
    aSignatureHelper.SetStorage( rxStorage );

    aSignatureHelper.StartMission();

    SignatureStreamHelper aStreamHelper = DocumentSignatureHelper::OpenSignatureStream( rxStorage, embed::ElementModes::READ, eMode );
    if ( aStreamHelper.xSignatureStream.is() )
    {
        uno::Reference< io::XInputStream > xInputStream( aStreamHelper.xSignatureStream, uno::UNO_QUERY );
        aSignatureHelper.ReadAndVerifySignature( xInputStream );
    }

    aSignatureHelper.EndMission();

    aStreamHelper.Clear();

    uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > xSecEnv = aSignatureHelper.GetSecurityEnvironment();

    SignatureInformations aSignInfos = aSignatureHelper.GetSignatureInformations();
    int nInfos = aSignInfos.size();
    ::com::sun::star::uno::Sequence< ::com::sun::star::security::DocumentSignaturesInformation > aInfos(nInfos);

    if ( nInfos )
    {
        std::vector< rtl::OUString > aElementsToBeVerified = DocumentSignatureHelper::CreateElementList( rxStorage, ::rtl::OUString(), eMode );
        for( int n = 0; n < nInfos; ++n )
        {
            const SignatureInformation& rInfo = aSignInfos[n];
            aInfos[n].Signer = xSecEnv->getCertificate( rInfo.ouX509IssuerName, numericStringToBigInteger( rInfo.ouX509SerialNumber ) );
            if ( !aInfos[n].Signer.is() )
                aInfos[n].Signer = xSecEnv->createCertificateFromAscii( rInfo.ouX509Certificate ) ;

            // MM : the ouDate and ouTime fields have been replaced with stDateTime (com::sun::star::util::DataTime)
            /*
            aInfos[n].SignatureDate = String( rInfo.ouDate ).ToInt32();
            aInfos[n].SignatureTime = String( rInfo.ouTime ).ToInt32();
            */

            DBG_ASSERT( rInfo.nStatus != STATUS_INIT, "Signature not processed!" );

            aInfos[n].SignatureIsValid = ( rInfo.nStatus == STATUS_VERIFY_SUCCEED );

            if ( aInfos[n].SignatureIsValid )
            {
                // Can only be valid if ALL streams are signed, which means real stream count == signed stream count
                int nRealCount = 0;
                for ( int i = rInfo.vSignatureReferenceInfors.size(); i; )
                {
                    const SignatureReferenceInformation& rInf = rInfo.vSignatureReferenceInfors[--i];
                    // There is also an extra entry of type TYPE_SAMEDOCUMENT_REFERENCE because of signature date.
                    if ( ( rInf.nType == TYPE_BINARYSTREAM_REFERENCE ) || ( rInf.nType == TYPE_XMLSTREAM_REFERENCE ) )
                        nRealCount++;
                }
                aInfos[n].SignatureIsValid = ( aElementsToBeVerified.size() == nRealCount );
            }

        }
    }
    return aInfos;

}

void DocumentDigitalSignatures::manageTrustedSources(  ) throw (::com::sun::star::uno::RuntimeException)
{
    XMLSignatureHelper aSignatureHelper( mxMSF );
    aSignatureHelper.Init( rtl::OUString() );
    MacroSecurity aDlg( NULL, aSignatureHelper.GetSecurityEnvironment() );
    aDlg.Execute();
}

void DocumentDigitalSignatures::ShowCertificate( const ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate >& _Certificate ) throw (::com::sun::star::uno::RuntimeException)
{
    XMLSignatureHelper aSignatureHelper( mxMSF );
    aSignatureHelper.Init( rtl::OUString() );
    CertificateViewer aViewer( NULL, aSignatureHelper.GetSecurityEnvironment(), _Certificate );
    aViewer.Execute();

}

::sal_Bool DocumentDigitalSignatures::isAuthorTrusted( const ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate >& Author ) throw (::com::sun::star::uno::RuntimeException)
{
    return sal_False;
}

::sal_Bool DocumentDigitalSignatures::isLocationTrusted( const ::rtl::OUString& Location ) throw (::com::sun::star::uno::RuntimeException)
{
    sal_Bool bFound = sal_False;
    INetURLObject aLocObj( Location );

    SvtSecurityOptions aSecOpt;
    ::com::sun::star::uno::Sequence< ::rtl::OUString > aSecURLs = aSecOpt.GetSecureURLs();
    sal_Int32 nCnt = aSecURLs.getLength();
    const ::rtl::OUString* pSecURLs = aSecURLs.getConstArray();
    const ::rtl::OUString* pSecURLsEnd = pSecURLs + aSecURLs.getLength();
    for ( ; pSecURLs != pSecURLsEnd; ++pSecURLs )
    {
        INetURLObject aSecURL( *pSecURLs );
        if ( aSecURL == aLocObj )
        {
            bFound = sal_True;
            break;
        }
    }

    return bFound;
}

void DocumentDigitalSignatures::addAuthorToTrustedSources( const ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate >& Author ) throw (::com::sun::star::uno::RuntimeException)
{
    SvtSecurityOptions aSecOpts;

    SvtSecurityOptions::Certificate aNewCert( 3 );
    aNewCert[ 0 ] = Author->getIssuerName();
    aNewCert[ 1 ] = bigIntegerToNumericString( Author->getSerialNumber() );
    aNewCert[ 2 ] = baseEncode( Author->getEncoded(), BASE64 );

    uno::Sequence< SvtSecurityOptions::Certificate > aTrustedAuthors = aSecOpts.GetTrustedAuthors();
    sal_Int32 nCnt = aTrustedAuthors.getLength();
    aTrustedAuthors.realloc( nCnt + 1 );
    aTrustedAuthors[ nCnt ] = aNewCert;

    aSecOpts.SetTrustedAuthors( aTrustedAuthors );
}

void DocumentDigitalSignatures::addLocationToTrustedSources( const ::rtl::OUString& Location ) throw (::com::sun::star::uno::RuntimeException)
{
    SvtSecurityOptions aSecOpt;

    ::com::sun::star::uno::Sequence< ::rtl::OUString > aSecURLs = aSecOpt.GetSecureURLs();
    sal_Int32 nCnt = aSecURLs.getLength();
    aSecURLs.realloc( nCnt + 1 );
    aSecURLs[ nCnt ] = Location;

    aSecOpt.SetSecureURLs( aSecURLs );
}

rtl::OUString DocumentDigitalSignatures::GetImplementationName() throw (uno::RuntimeException)
{
    return rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) );
}

uno::Sequence< rtl::OUString > DocumentDigitalSignatures::GetSupportedServiceNames() throw (cssu::RuntimeException)
{
    uno::Sequence < rtl::OUString > aRet(1);
    rtl::OUString* pArray = aRet.getArray();
    pArray[0] =  rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) );
    return aRet;
}

com::sun::star::uno::Reference< com::sun::star::uno::XInterface > DocumentDigitalSignatures_CreateInstance(
    const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rSMgr) throw ( com::sun::star::uno::Exception )
{
    return (cppu::OWeakObject*) new DocumentDigitalSignatures( rSMgr );
}
<|endoftext|>


<commit_before>#include "PcapDevice.h"
#include "Logger.h"
#include <pcap.h>

namespace pcpp
{

IPcapDevice::~IPcapDevice()
{
}

bool IPcapDevice::setFilter(std::string filterAsString)
{
	LOG_DEBUG("Filter to be set: '%s'", filterAsString.c_str());
	if (!m_DeviceOpened)
	{
		LOG_ERROR("Device not Opened!! cannot set filter");
		return false;
	}

	struct bpf_program prog;
	LOG_DEBUG("Compiling the filter '%s'", filterAsString.c_str());
	if (pcap_compile(m_PcapDescriptor, &prog, filterAsString.c_str(), 1, 0) < 0)
	{
		/*
		* Print out appropriate text, followed by the error message
		* generated by the packet capture library.
		*/
		LOG_ERROR("Error compiling filter. Error message is: %s", pcap_geterr(m_PcapDescriptor));
		return false;
	}

	LOG_DEBUG("Setting the compiled filter");
	if (pcap_setfilter(m_PcapDescriptor, &prog) < 0)
	{
		/*
		 * Print out error. The format will be the prefix string,
		 * created above, followed by the error message that the packet
		 * capture library generates.
		 */
		LOG_ERROR("Error setting a compiled filter. Error message is: %s", pcap_geterr(m_PcapDescriptor));
		return false;
	}

	LOG_DEBUG("Filter set successfully");

	return true;
}

bool IPcapDevice::clearFilter()
{
	return setFilter("");
}

bool IPcapDevice::verifyFilter(std::string filterAsString)
{
	struct bpf_program prog;
	LOG_DEBUG("Compiling the filter '%s'", filterAsString.c_str());
	if (pcap_compile_nopcap(9000, pcpp::LINKTYPE_ETHERNET, &prog, filterAsString.c_str(), 1, 0) < 0)
	{
		return false;
	}

	return true;
}

bool IPcapDevice::matchPacketWithFilter(std::string filterAsString, RawPacket* rawPacket)
{
	static std::string curFilter = "";
	static struct bpf_program prog;
	if (curFilter != filterAsString)
	{
		LOG_DEBUG("Compiling the filter '%s'", filterAsString.c_str());
		pcap_freecode(&prog);
		if (pcap_compile_nopcap(9000, pcpp::LINKTYPE_ETHERNET, &prog, filterAsString.c_str(), 1, 0) < 0)
		{
			return false;
		}

		curFilter = filterAsString;
	}

	struct pcap_pkthdr pktHdr;
	pktHdr.caplen = rawPacket->getRawDataLen();
	pktHdr.len = rawPacket->getRawDataLen();
	pktHdr.ts = rawPacket->getPacketTimeStamp();

	return (pcap_offline_filter(&prog, &pktHdr, rawPacket->getRawData()) != 0);
}

std::string IPcapDevice::getPcapLibVersionInfo()
{
	return std::string(pcap_lib_version());
}

} // namespace pcpp
<commit_msg>Bugfix #166 - memory leak in IPcapDevice::setFilter()<commit_after>#include "PcapDevice.h"
#include "Logger.h"
#include <pcap.h>

namespace pcpp
{

IPcapDevice::~IPcapDevice()
{
}

bool IPcapDevice::setFilter(std::string filterAsString)
{
	LOG_DEBUG("Filter to be set: '%s'", filterAsString.c_str());
	if (!m_DeviceOpened)
	{
		LOG_ERROR("Device not Opened!! cannot set filter");
		return false;
	}

	struct bpf_program prog;
	LOG_DEBUG("Compiling the filter '%s'", filterAsString.c_str());
	if (pcap_compile(m_PcapDescriptor, &prog, filterAsString.c_str(), 1, 0) < 0)
	{
		/*
		* Print out appropriate text, followed by the error message
		* generated by the packet capture library.
		*/
		LOG_ERROR("Error compiling filter. Error message is: %s", pcap_geterr(m_PcapDescriptor));
		pcap_freecode(&prog);
		return false;
	}

	LOG_DEBUG("Setting the compiled filter");
	if (pcap_setfilter(m_PcapDescriptor, &prog) < 0)
	{
		/*
		 * Print out error. The format will be the prefix string,
		 * created above, followed by the error message that the packet
		 * capture library generates.
		 */
		LOG_ERROR("Error setting a compiled filter. Error message is: %s", pcap_geterr(m_PcapDescriptor));
		pcap_freecode(&prog);
		return false;
	}

	LOG_DEBUG("Filter set successfully");

	pcap_freecode(&prog);

	return true;
}

bool IPcapDevice::clearFilter()
{
	return setFilter("");
}

bool IPcapDevice::verifyFilter(std::string filterAsString)
{
	struct bpf_program prog;
	LOG_DEBUG("Compiling the filter '%s'", filterAsString.c_str());
	if (pcap_compile_nopcap(9000, pcpp::LINKTYPE_ETHERNET, &prog, filterAsString.c_str(), 1, 0) < 0)
	{
		return false;
	}

	return true;
}

bool IPcapDevice::matchPacketWithFilter(std::string filterAsString, RawPacket* rawPacket)
{
	static std::string curFilter = "";
	static struct bpf_program prog;
	if (curFilter != filterAsString)
	{
		LOG_DEBUG("Compiling the filter '%s'", filterAsString.c_str());
		pcap_freecode(&prog);
		if (pcap_compile_nopcap(9000, pcpp::LINKTYPE_ETHERNET, &prog, filterAsString.c_str(), 1, 0) < 0)
		{
			return false;
		}

		curFilter = filterAsString;
	}

	struct pcap_pkthdr pktHdr;
	pktHdr.caplen = rawPacket->getRawDataLen();
	pktHdr.len = rawPacket->getRawDataLen();
	pktHdr.ts = rawPacket->getPacketTimeStamp();

	return (pcap_offline_filter(&prog, &pktHdr, rawPacket->getRawData()) != 0);
}

std::string IPcapDevice::getPcapLibVersionInfo()
{
	return std::string(pcap_lib_version());
}

} // namespace pcpp
<|endoftext|>


<commit_before>/**
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef __STOUT_OS_OSX_HPP__
#define __STOUT_OS_OSX_HPP__

// This file contains OSX-only OS utilities.
#ifndef __APPLE__
#error "stout/os/osx.hpp is only available on OSX systems."
#endif

#include <libproc.h>

#include <sys/sysctl.h>
#include <sys/types.h> // For pid_t.

#include <queue>
#include <set>

#include <stout/error.hpp>
#include <stout/none.hpp>
#include <stout/strings.hpp>

#include <stout/os/process.hpp>
#include <stout/os/sysctl.hpp>

namespace os {

inline Result<Process> process(pid_t pid)
{
  const Try<std::vector<kinfo_proc> >& processes =
    os::sysctl(CTL_KERN, KERN_PROC, KERN_PROC_PID, pid).table(1);

  if (processes.isError()) {
    return Error("Failed to get process via sysctl: " + processes.error());
  } else if (processes.get().size() != 1) {
    return None();
  }

  const kinfo_proc process = processes.get()[0];

  // The command line from 'process.kp_proc.p_comm' only includes the
  // first 16 characters from "arg0" (i.e., the canonical executable
  // name). We can try to get "argv" via some sysctl magic. This first
  // requires determining "argc" via KERN_PROCARGS2 followed by the
  // actual arguments via KERN_PROCARGS. This is still insufficient
  // with insufficient privilege (e.g., not being root). If we were
  // only interested in the "executable path" (i.e., the first
  // argument to 'exec' but none of the arguments) we could use
  // proc_pidpath() instead.
  Option<std::string> command = None();

  // Alternative implemenations using KERN_PROCARGS2:
  // https://bitbucket.org/flub/psi-win32/src/d38f288de3b8/src/arch/macosx/macosx_process.c#cl-552
  // https://gist.github.com/nonowarn/770696

#ifdef KERN_PROCARGS2
  // Looking at the source code of XNU (the Darwin kernel for OS X:
  // www.opensource.apple.com/source/xnu/xnu-1699.24.23/bsd/kern/kern_sysctl.c),
  // it appears as though KERN_PROCARGS2 writes 'argc' as the first
  // word of the returned bytes.
  Try<std::string> args = os::sysctl(CTL_KERN, KERN_PROCARGS2, pid).string();

  if (args.isSome()) {
    int argc = *((int*) args.get().data());

    if (argc > 0) {
      // Now grab the arguments.
      args = os::sysctl(CTL_KERN, KERN_PROCARGS, pid).string();

      if (args.isSome()) {
        // At this point 'args' contains the parameters to 'exec'
        // delimited by null bytes, i.e., "executable path", then
        // "arg0" (the canonical executable name), then "arg1", then
        // "arg2", etc. Sometimes there are no arguments (argc = 1) so
        // all we care about is the "executable path", but when there
        // are arguments we grab "arg0" and on assuming that "arg0"
        // really is the canonical executable name.

        // Tokenize the args by the null byte ('\0').
        std::vector<std::string> tokens =
          strings::tokenize(args.get(), std::string(1, '\0'));

        if (!tokens.empty()) {
          if (argc == 1) {
            // When there are no arguments, all we care about is the
            // "executable path".
            command = tokens[0];
          } else if (argc > 1) {
            // When there are arguments, we skip the "executable path"
            // and just grab "arg0" -> "argN", assuming "arg0" is the
            // canonical executable name. In the case that we didn't
            // get enough tokens back from KERN_PROCARGS the following
            // code will end up just keeping 'command' None (i.e.,
            // tokens.size() will be <= 0).
            tokens.erase(tokens.begin()); // Remove path.

            // In practice it appeared that we might get an 'argc'
            // which is greater than 'tokens.size()' which caused us
            // to get an invalid iterator from 'tokens.begin() +
            // argc', thus we now check that condition here.
            if (argc <= tokens.size()) {
              tokens.erase(tokens.begin() + argc, tokens.end());
            }

            // If any tokens are left, consider them the command!
            if (tokens.size() > 0) {
              command = strings::join(" ", tokens);
            }
          }
        }
      }
    }
  }
#endif

  // We also use proc_pidinfo() to get memory and CPU usage.
  // NOTE: There are several pitfalls to using proc_pidinfo().
  // In particular:
  //   -This will not work for many root processes.
  //   -This may not work for processes owned by other users.
  //   -However, this always works for processes owned by the same user.
  // This beats using task_for_pid(), which only works for the same pid.
  // For further discussion around these issues,
  // see: http://code.google.com/p/psutil/issues/detail?id=297
  proc_taskinfo task;
  int size = proc_pidinfo(pid, PROC_PIDTASKINFO, 0, &task, sizeof(task));

  // It appears that zombie processes on OS X do not have sessions and
  // result in ESRCH.
  int session = getsid(pid);

  if (size != sizeof(task)) {
    return Process(process.kp_proc.p_pid,
                   process.kp_eproc.e_ppid,
                   process.kp_eproc.e_pgid,
                   session > 0 ? session : Option<pid_t>::none(),
                   None(),
                   None(),
                   None(),
                   command.get(std::string(process.kp_proc.p_comm)),
                   process.kp_proc.p_stat & SZOMB);
  } else {
    return Process(process.kp_proc.p_pid,
                   process.kp_eproc.e_ppid,
                   process.kp_eproc.e_pgid,
                   session > 0 ? session : Option<pid_t>::none(),
                   Bytes(task.pti_resident_size),
                   Nanoseconds(task.pti_total_user),
                   Nanoseconds(task.pti_total_system),
                   command.get(std::string(process.kp_proc.p_comm)),
                   process.kp_proc.p_stat & SZOMB);
  }
}

inline Try<std::set<pid_t> > pids()
{
  const Try<int>& maxproc = os::sysctl(CTL_KERN, KERN_MAXPROC).integer();

  if (maxproc.isError()) {
    return Error(maxproc.error());
  }

  const Try<std::vector<kinfo_proc> >& processes =
    os::sysctl(CTL_KERN, KERN_PROC, KERN_PROC_ALL).table(maxproc.get());

  if (processes.isError()) {
    return Error(processes.error());
  }

  std::set<pid_t> result;
  foreach (const kinfo_proc& process, processes.get()) {
    result.insert(process.kp_proc.p_pid);
  }
  return result;
}

} // namespace os {

#endif // __STOUT_OS_OSX_HPP__
<commit_msg>Fixed comparison between signed and unsigned.<commit_after>/**
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef __STOUT_OS_OSX_HPP__
#define __STOUT_OS_OSX_HPP__

// This file contains OSX-only OS utilities.
#ifndef __APPLE__
#error "stout/os/osx.hpp is only available on OSX systems."
#endif

#include <libproc.h>

#include <sys/sysctl.h>
#include <sys/types.h> // For pid_t.

#include <queue>
#include <set>

#include <stout/error.hpp>
#include <stout/none.hpp>
#include <stout/strings.hpp>

#include <stout/os/process.hpp>
#include <stout/os/sysctl.hpp>

namespace os {

inline Result<Process> process(pid_t pid)
{
  const Try<std::vector<kinfo_proc> >& processes =
    os::sysctl(CTL_KERN, KERN_PROC, KERN_PROC_PID, pid).table(1);

  if (processes.isError()) {
    return Error("Failed to get process via sysctl: " + processes.error());
  } else if (processes.get().size() != 1) {
    return None();
  }

  const kinfo_proc process = processes.get()[0];

  // The command line from 'process.kp_proc.p_comm' only includes the
  // first 16 characters from "arg0" (i.e., the canonical executable
  // name). We can try to get "argv" via some sysctl magic. This first
  // requires determining "argc" via KERN_PROCARGS2 followed by the
  // actual arguments via KERN_PROCARGS. This is still insufficient
  // with insufficient privilege (e.g., not being root). If we were
  // only interested in the "executable path" (i.e., the first
  // argument to 'exec' but none of the arguments) we could use
  // proc_pidpath() instead.
  Option<std::string> command = None();

  // Alternative implemenations using KERN_PROCARGS2:
  // https://bitbucket.org/flub/psi-win32/src/d38f288de3b8/src/arch/macosx/macosx_process.c#cl-552
  // https://gist.github.com/nonowarn/770696

#ifdef KERN_PROCARGS2
  // Looking at the source code of XNU (the Darwin kernel for OS X:
  // www.opensource.apple.com/source/xnu/xnu-1699.24.23/bsd/kern/kern_sysctl.c),
  // it appears as though KERN_PROCARGS2 writes 'argc' as the first
  // word of the returned bytes.
  Try<std::string> args = os::sysctl(CTL_KERN, KERN_PROCARGS2, pid).string();

  if (args.isSome()) {
    int argc = *((int*) args.get().data());

    if (argc > 0) {
      // Now grab the arguments.
      args = os::sysctl(CTL_KERN, KERN_PROCARGS, pid).string();

      if (args.isSome()) {
        // At this point 'args' contains the parameters to 'exec'
        // delimited by null bytes, i.e., "executable path", then
        // "arg0" (the canonical executable name), then "arg1", then
        // "arg2", etc. Sometimes there are no arguments (argc = 1) so
        // all we care about is the "executable path", but when there
        // are arguments we grab "arg0" and on assuming that "arg0"
        // really is the canonical executable name.

        // Tokenize the args by the null byte ('\0').
        std::vector<std::string> tokens =
          strings::tokenize(args.get(), std::string(1, '\0'));

        if (!tokens.empty()) {
          if (argc == 1) {
            // When there are no arguments, all we care about is the
            // "executable path".
            command = tokens[0];
          } else if (argc > 1) {
            // When there are arguments, we skip the "executable path"
            // and just grab "arg0" -> "argN", assuming "arg0" is the
            // canonical executable name. In the case that we didn't
            // get enough tokens back from KERN_PROCARGS the following
            // code will end up just keeping 'command' None (i.e.,
            // tokens.size() will be <= 0).
            tokens.erase(tokens.begin()); // Remove path.

            // In practice it appeared that we might get an 'argc'
            // which is greater than 'tokens.size()' which caused us
            // to get an invalid iterator from 'tokens.begin() +
            // argc', thus we now check that condition here.
            if (static_cast<size_t>(argc) <= tokens.size()) {
              tokens.erase(tokens.begin() + argc, tokens.end());
            }

            // If any tokens are left, consider them the command!
            if (tokens.size() > 0) {
              command = strings::join(" ", tokens);
            }
          }
        }
      }
    }
  }
#endif

  // We also use proc_pidinfo() to get memory and CPU usage.
  // NOTE: There are several pitfalls to using proc_pidinfo().
  // In particular:
  //   -This will not work for many root processes.
  //   -This may not work for processes owned by other users.
  //   -However, this always works for processes owned by the same user.
  // This beats using task_for_pid(), which only works for the same pid.
  // For further discussion around these issues,
  // see: http://code.google.com/p/psutil/issues/detail?id=297
  proc_taskinfo task;
  int size = proc_pidinfo(pid, PROC_PIDTASKINFO, 0, &task, sizeof(task));

  // It appears that zombie processes on OS X do not have sessions and
  // result in ESRCH.
  int session = getsid(pid);

  if (size != sizeof(task)) {
    return Process(process.kp_proc.p_pid,
                   process.kp_eproc.e_ppid,
                   process.kp_eproc.e_pgid,
                   session > 0 ? session : Option<pid_t>::none(),
                   None(),
                   None(),
                   None(),
                   command.get(std::string(process.kp_proc.p_comm)),
                   process.kp_proc.p_stat & SZOMB);
  } else {
    return Process(process.kp_proc.p_pid,
                   process.kp_eproc.e_ppid,
                   process.kp_eproc.e_pgid,
                   session > 0 ? session : Option<pid_t>::none(),
                   Bytes(task.pti_resident_size),
                   Nanoseconds(task.pti_total_user),
                   Nanoseconds(task.pti_total_system),
                   command.get(std::string(process.kp_proc.p_comm)),
                   process.kp_proc.p_stat & SZOMB);
  }
}

inline Try<std::set<pid_t> > pids()
{
  const Try<int>& maxproc = os::sysctl(CTL_KERN, KERN_MAXPROC).integer();

  if (maxproc.isError()) {
    return Error(maxproc.error());
  }

  const Try<std::vector<kinfo_proc> >& processes =
    os::sysctl(CTL_KERN, KERN_PROC, KERN_PROC_ALL).table(maxproc.get());

  if (processes.isError()) {
    return Error(processes.error());
  }

  std::set<pid_t> result;
  foreach (const kinfo_proc& process, processes.get()) {
    result.insert(process.kp_proc.p_pid);
  }
  return result;
}

} // namespace os {

#endif // __STOUT_OS_OSX_HPP__
<|endoftext|>