Ejemplo n.º 1
0
  int DNS::connect( const std::string& host, unsigned short port, const LogSink& logInstance )
  {
    int fd = getSocket();
    if( fd < 0 )
      return fd;

    struct hostent* h;
    if( ( h = gethostbyname( host.c_str() ) ) == 0 )
    {
      cleanup();
      return -ConnDnsError;
    }

    struct sockaddr_in target;
    target.sin_family = AF_INET;
    target.sin_port = htons( port );

    if( h->h_length != sizeof( struct in_addr ) )
    {
      cleanup();
      return -ConnDnsError;
    }
    else
    {
      memcpy( &target.sin_addr, h->h_addr, sizeof( struct in_addr ) );
    }

#ifndef _WIN32_WCE
    std::ostringstream oss;
#endif

    memset( target.sin_zero, '\0', 8 );
    if( ::connect( fd, (struct sockaddr *)&target, sizeof( struct sockaddr ) ) == 0 )
    {
#ifndef _WIN32_WCE
      oss << "connecting to " << host.c_str()
          << " (" << inet_ntoa( target.sin_addr ) << ":" << port << ")";
      logInstance.dbg( LogAreaClassDns, oss.str() );
#endif
      return fd;
    }

#ifndef _WIN32_WCE
    oss << "connection to " << host.c_str()
         << " (" << inet_ntoa( target.sin_addr ) << ":" << port << ") failed";
    logInstance.dbg( LogAreaClassDns, oss.str() );
#endif

    closeSocket( fd );
    return -ConnConnectionRefused;
  }
Ejemplo n.º 2
0
  int DNS::connect( const std::string& host, int port, const LogSink& logInstance )
  {
    struct addrinfo hints, *servinfo, *p;
    int rv = 0;
    int fd = 0;

    memset( &hints, 0, sizeof( hints ) );
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;

    if( ( rv = getaddrinfo( host.c_str(), util::int2string( port ).c_str(), &hints, &servinfo ) ) != 0 )
    {
      logInstance.dbg( LogAreaClassDns, "getaddrinfo() failed for " + host + "." );
      return -ConnDnsError;
    }

    for( p = servinfo; p != 0; p = p->ai_next )
    {
      if( ( fd = getSocket( p->ai_family, p->ai_socktype, p->ai_protocol, logInstance ) ) == -1 )
      {
        continue;
      }

      if( ::connect( fd, p->ai_addr, p->ai_addrlen ) == -1 )
      {
        closeSocket( fd, logInstance );
        continue;
      }

      break;
    }

    if( p == 0 )
    {
      freeaddrinfo( servinfo );
      std::string message = "Connection to " + host + ":" + util::int2string( port ) + " failed. "
#if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
      "WSAGetLastError: " + util::int2string( ::WSAGetLastError() );
#else
      "errno: " + util::int2string( errno ) + ": " + strerror( errno );
#endif
      logInstance.dbg( LogAreaClassDns, message );
      return -ConnConnectionRefused;
    }

    freeaddrinfo( servinfo );
    return fd;
  }
Ejemplo n.º 3
0
 DNS::HostMap DNS::resolve( const std::string& service, const std::string& proto,
                            const std::string& domain, const LogSink& logInstance )
 {
   logInstance.warn( LogAreaClassDns, "notice: gloox does not support SRV "
                       "records on this platform. Using A records instead." );
   return defaultHostMap( domain, logInstance );
 }
Ejemplo n.º 4
0
  int DNS::connect( const std::string& host, const LogSink& logInstance )
  {
    struct addrinfo* results = 0;

    resolve( &results, host, logInstance );
    if( !results )
    {
      logInstance.err( LogAreaClassDns, "host not found: " + host );
      return -ConnDnsError;
    }

    struct addrinfo* runp = results;
    while( runp )
    {
      int fd = DNS::connect( runp, logInstance );
      if( fd >= 0 )
        return fd;

      runp = runp->ai_next;
    }

    freeaddrinfo( results );

    return -ConnConnectionRefused;
  }
Ejemplo n.º 5
0
  int DNS::getSocket( int af, int socktype, int proto, const LogSink& logInstance )
  {
#if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
    SOCKET fd;
#else
    int fd;
#endif
    if( ( fd = socket( af, socktype, proto ) ) == INVALID_SOCKET )
    {
      std::string message = "getSocket( "
          + util::int2string( af ) + ", "
          + util::int2string( socktype ) + ", "
          + util::int2string( proto )
          + " ) failed. "
#if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
          "WSAGetLastError: " + util::int2string( ::WSAGetLastError() );
#else
          "errno: " + util::int2string( errno ) + ": " + strerror( errno );
#endif
      logInstance.dbg( LogAreaClassDns, message );

      cleanup( logInstance );
      return -ConnConnectionRefused;
    }

#ifdef HAVE_SETSOCKOPT
    int timeout = 5000;
    int reuseaddr = 1;
    setsockopt( fd, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof( timeout ) );
    setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, (char*)&reuseaddr, sizeof( reuseaddr ) );
#endif

    return (int)fd;
  }
Ejemplo n.º 6
0
  int DNS::connect( const std::string& domain, const LogSink& logInstance )
  {
    logInstance.log( LogLevelWarning, LogAreaClassDns,
                     "note: gloox does not support SRV records on this platform." );

    return DNS::connect( domain, XMPP_PORT, logInstance );
  }
Ejemplo n.º 7
0
  int DNS::connect( const std::string& domain, int port, const LogSink& logInstance )
  {
#ifdef WIN32
    WSADATA wsaData;
    if( WSAStartup( MAKEWORD( 1, 1 ), &wsaData ) != 0 )
      return -DNS_COULD_NOT_RESOLVE;
#endif

    struct protoent* prot;
    if( ( prot = getprotobyname( "tcp" ) ) == 0 )
    {
      cleanup();
      return -DNS_COULD_NOT_RESOLVE;
    }

    int fd;
    if( ( fd = socket( PF_INET, SOCK_STREAM, prot->p_proto ) ) == -1 )
    {
      cleanup();
      return -DNS_COULD_NOT_CONNECT;
    }

    struct hostent *h;
    if( ( h = gethostbyname( domain.c_str() ) ) == 0 )
    {
      cleanup();
      return -DNS_COULD_NOT_RESOLVE;
    }

    struct sockaddr_in target;
    target.sin_family = AF_INET;
    target.sin_port = htons( port );

    if( h->h_length != sizeof( struct in_addr ) )
    {
      cleanup();
      return -DNS_COULD_NOT_RESOLVE;
    }
    else
    {
      memcpy( &target.sin_addr, h->h_addr, sizeof( struct in_addr ) );
    }

    std::ostringstream oss;
    oss << "resolved " << domain.c_str() << " to: " << inet_ntoa( target.sin_addr );
    logInstance.log( LogLevelDebug, LogAreaClassDns, oss.str() );

    memset( target.sin_zero, '\0', 8 );
    if( ::connect( fd, (struct sockaddr *)&target, sizeof( struct sockaddr ) ) == 0 )
      return fd;

#ifndef WIN32
    close( fd );
#else
    closesocket( fd );
    cleanup();
#endif
    return -DNS_COULD_NOT_CONNECT;
  }
Ejemplo n.º 8
0
void
test_single_thread(int count) 
{
    Log::createIt(logSink); 
    test_log(*Log::it(), count);

    std::time_t time = std::time(0);
    time += 3600*24;
    logSink->rotate(time);
    test_log(*Log::it(), count);

    time += 3600*24;
    logSink->rotate(time);
    test_log(*Log::it(), count);

    Log::destroyIt();
}
Ejemplo n.º 9
0
  int DNS::connect( const std::string& domain, const LogSink& logInstance )
  {
    HostMap hosts = resolve( domain );
    if( hosts.size() == 0 )
      return -DNS_NO_HOSTS_FOUND;

    struct protoent* prot;
    if( ( prot = getprotobyname( "tcp" ) ) == 0)
      return -DNS_COULD_NOT_RESOLVE;

    int fd;
    if( ( fd = socket( PF_INET, SOCK_STREAM, prot->p_proto ) ) == -1 )
      return -DNS_COULD_NOT_RESOLVE;

    struct hostent *h;
    struct sockaddr_in target;
    target.sin_family = AF_INET;
    int ret = 0;
    HostMap::const_iterator it = hosts.begin();
    for( ; it != hosts.end(); ++it )
    {
      int port;
      if( (*it).second == 0 )
        port = XMPP_PORT;
      else
        port = (*it).second;

      target.sin_port = htons( port );
      if( ( h = gethostbyname( (*it).first.c_str() ) ) == 0 )
      {
        ret = -DNS_COULD_NOT_RESOLVE;
        continue;
      }

      in_addr *addr = (in_addr*)malloc( sizeof( in_addr ) );
      memcpy( addr, h->h_addr, sizeof( in_addr ) );
      char *tmp = inet_ntoa( *addr );
      free( addr );
      std::ostringstream oss;
      oss << "resolved " << (*it).first.c_str() <<  " to: " << tmp << ":" << port;
      logInstance.log( LogLevelDebug, LogAreaClassDns, oss.str() );

      if( inet_aton( tmp, &(target.sin_addr) ) == 0 )
        continue;

      memset( target.sin_zero, '\0', 8 );
      if( ::connect( fd, (struct sockaddr *)&target, sizeof( struct sockaddr ) ) == 0 )
        return fd;

      close( fd );
    }
    if( ret )
      return ret;

    return -DNS_COULD_NOT_CONNECT;
  }
Ejemplo n.º 10
0
  int DNS::connect( struct addrinfo* res, const LogSink& logInstance )
  {
    if( !res )
      return -1;

    int fd = getSocket( res->ai_family, res->ai_socktype, res->ai_protocol, logInstance );
    if( fd < 0 )
      return fd;

    if( ::connect( fd, res->ai_addr, res->ai_addrlen ) == 0 )
    {
      char ip[NI_MAXHOST];
      char port[NI_MAXSERV];

      if( getnameinfo( res->ai_addr, res->ai_addrlen,
                       ip, sizeof( ip ),
                       port, sizeof( port ),
                       NI_NUMERICHOST | NI_NUMERICSERV ) )
      {
        //FIXME do we need to handle this? How? Can it actually happen at all?
//         printf( "could not get numeric hostname");
      }

      if( res->ai_canonname )
        logInstance.dbg( LogAreaClassDns, std::string( "Connecting to " ).append( res->ai_canonname ).append( " (" ).append( ip ).append( "), port  " ).append( port ) );
      else
        logInstance.dbg( LogAreaClassDns, std::string( "Connecting to " ).append( ip ).append( ":" ).append( port ) );

      return fd;
    }

    std::string message = "connect() failed. "
#if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
        "WSAGetLastError: " + util::int2string( ::WSAGetLastError() );
#else
        "errno: " + util::int2string( errno ) + ": " + strerror( errno );
#endif
    logInstance.dbg( LogAreaClassDns, message );

    closeSocket( fd, logInstance );
    return -ConnConnectionRefused;
  }
Ejemplo n.º 11
0
 void DNS::resolve( struct addrinfo** res, const std::string& service, const std::string& proto,
                    const std::string& domain, const LogSink& logInstance )
 {
   logInstance.dbg( LogAreaClassDns, "Resolving: _" +  service + "._" + proto + "." + domain );
   struct addrinfo hints;
   if( proto == "tcp" )
     hints.ai_socktype = SOCK_STREAM;
   else if( proto == "udp" )
     hints.ai_socktype = SOCK_DGRAM;
   else
   {
     logInstance.err( LogAreaClassDns, "Unknown/Invalid protocol: " + proto );
   }
   memset( &hints, '\0', sizeof( hints ) );
   hints.ai_flags = AI_ADDRCONFIG | AI_CANONNAME;
   hints.ai_socktype = SOCK_STREAM;
   int e = getaddrinfo( domain.c_str(), service.c_str(), &hints, res );
   if( e )
     logInstance.err( LogAreaClassDns, "getaddrinfo() failed" );
 }
Ejemplo n.º 12
0
int main( int /*argc*/, char** /*argv*/ )
{
  int fail = 0;
  std::string name;
  LogSink ls;
  FakeConnection* fc = new FakeConnection();
  ConnectionBOSH* cb = new ConnectionBOSH( fc, ls, "example.net" ,"example.net" );
  FakeClientBase* fcb = new FakeClientBase( cb );
  ls.registerLogHandler( LogLevelDebug, LogAreaAll, fcb );



  // -------
  name = "connect";
  fc->setTest( 1 );
  cb->connect();
  fcb->doLoop();
  if( 1 )
  {
    ++fail;
//     printf( "test '%s' failed\n", name.c_str() );
  }


  delete cb;
  delete fcb;


  if( fail == 0 )
  {
    printf( "ConnectionBOSH: OK\n" );
    return 0;
  }
  else
  {
    printf( "ConnectionBOSH: %d test(s) failed\n", fail );
    return 1;
  }


}
Ejemplo n.º 13
0
  void DNS::cleanup( const LogSink& logInstance )
  {
#if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
    if( WSACleanup() != 0 )
    {
      logInstance.dbg( LogAreaClassDns, "WSACleanup() failed. WSAGetLastError: "
          + util::int2string( ::WSAGetLastError() ) );
    }
#else
    (void)logInstance;
#endif
  }
Ejemplo n.º 14
0
 static void GLAPIENTRY _gl_debug_proc(
   GLenum source,
   GLenum type,
   GLuint id,
   GLenum severity,
   GLsizei length,
   const GLchar* message,
   GLvoid* user_param) {
     LogSink* self = static_cast<LogSink*>(user_param);
     assert(self);
     if(self->_callback) {
         CallbackData data;
         data.source = DebugOutputARBSource(source);
         data.type = DebugOutputARBType(type);
         data.id = id;
         data.severity = DebugOutputARBSeverity(severity);
         data.length = length;
         data.message = message;
         self->_callback(data);
     }
 }
Ejemplo n.º 15
0
  DNS::HostMap DNS::defaultHostMap( const std::string& domain, const LogSink& logInstance )
  {
    HostMap server;

    logInstance.warn( LogAreaClassDns, "notice: no SRV record found for "
                                          + domain + ", using default port." );

    if( !domain.empty() )
      server[domain] = XMPP_PORT;

    return server;
  }
Ejemplo n.º 16
0
  int DNS::getSocket( const LogSink& logInstance )
  {
#if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
    WSADATA wsaData;
    if( WSAStartup( MAKEWORD( 1, 1 ), &wsaData ) != 0 )
    {
      logInstance.dbg( LogAreaClassDns, "WSAStartup() failed. WSAGetLastError: "
                                        + util::int2string( ::WSAGetLastError() ) );
      return -ConnDnsError;
    }
#endif

    int protocol = IPPROTO_TCP;
#if !defined( __APPLE__ )  // Sandboxing on Apple doesn't like you to use getprotobyname
    struct protoent* prot;
    if( ( prot = getprotobyname( "tcp" ) ) != 0 )
    {
      protocol = prot->p_proto;
    }
    else
    {
      std::string message = "getprotobyname( \"tcp\" ) failed. "
#if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
          "WSAGetLastError: " + util::int2string( ::WSAGetLastError() )
#else
          "errno: " + util::int2string( errno ) + ": " + strerror( errno );
#endif
          + ". Falling back to IPPROTO_TCP: " + util::int2string( IPPROTO_TCP );
      logInstance.dbg( LogAreaClassDns, message );

      // Do not return an error. We'll fall back to IPPROTO_TCP.
    }
#endif // !defined( __APPLE__ )

    return getSocket( PF_INET, SOCK_STREAM, protocol, logInstance );
  }
Ejemplo n.º 17
0
int main() {
    logSink = LogSinkImpl::create("/tmp", "testnew");
    logSink->start();
    // logSink->write_direct('E', "[TEST] ", "This is\nmultiline\nprotobuf error");

    Timer start;

#   ifdef LINKO_LOG_MT
    test_multi_thread();
#   else
    test_single_thread(10000);
    test_single_thread_old(10000);
#   endif

    int dur = Timer::now() - start;
    std::cout << "Test finished in " << dur << " usec" << std::endl;
}
Ejemplo n.º 18
0
  void DNS::closeSocket( int fd, const LogSink& logInstance )
  {
#if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
    int result = closesocket( fd );
#else
    int result = close( fd );
#endif

    if( result != 0 )
    {
      std::string message = "closeSocket() failed. "
#if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
          "WSAGetLastError: " + util::int2string( ::WSAGetLastError() );
#else
          "errno: " + util::int2string( errno ) + ": " + strerror( errno );
#endif
      logInstance.dbg( LogAreaClassDns, message );
    }
  }
Ejemplo n.º 19
0
  int DNS::connect( struct addrinfo* res, const LogSink& logInstance )
  {
    if( !res )
      return -1;

    int fd = getSocket( res->ai_family, res->ai_socktype, res->ai_protocol );
    if( fd < 0 )
      return fd;

    if( ::connect( fd, res->ai_addr, res->ai_addrlen ) == 0 )
    {
      char ip[NI_MAXHOST];
      char port[NI_MAXSERV];

      if( getnameinfo( res->ai_addr, sizeof( sockaddr ),
                       ip, sizeof( ip ),
                       port, sizeof( port ),
                       NI_NUMERICHOST | NI_NUMERICSERV ) )
      {
        //FIXME do we need to handle this? How? Can it actually happen at all?
//         printf( "could not get numeric hostname");
      }

      std::ostringstream oss;
      oss << "Connecting to ";
      if( res->ai_canonname )
      {
        oss << res->ai_canonname;
        oss << " (" << ip << "), port " << port;
      }
      else
      {
        oss << ip << ":" << port;
      }
      logInstance.dbg( LogAreaClassDns, oss.str() );
      return fd;
    }

    closeSocket( fd );
    return -ConnConnectionRefused;
  }
Ejemplo n.º 20
0
  DNS::HostMap DNS::resolve( const std::string& service, const std::string& proto,
                             const std::string& domain, const LogSink& logInstance )
  {
    const std::string dname = "_" +  service + "._" + proto + "." + domain;
    bool error = false;

    DNS::HostMap servers;
    DNS_RECORD* pRecord = NULL;
    DNS_STATUS status = DnsQuery_UTF8( dname.c_str(), DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &pRecord, NULL );
    if( status == ERROR_SUCCESS )
    {
      // NOTE: DnsQuery_UTF8 and DnsQuery_A really should have been defined with
      // PDNS_RECORDA instead of PDNS_RECORD, since that's what it is (even with _UNICODE defined).
      // We'll correct for that mistake with a cast.
      DNS_RECORDA* pRec = (DNS_RECORDA*)pRecord;
      do
      {
        if( pRec->wType == DNS_TYPE_SRV )
        {
          servers[pRec->Data.SRV.pNameTarget] = pRec->Data.SRV.wPort;
        }
        pRec = pRec->pNext;
      }
      while( pRec != NULL );
      DnsRecordListFree( pRecord, DnsFreeRecordList );
    }
    else
    {
      logInstance.warn( LogAreaClassDns, "DnsQuery_UTF8() failed: " + util::int2string( status ) );
      error = true;
    }

    if( error || !servers.size() )
    {
      servers = defaultHostMap( domain, logInstance );
    }

    return servers;
  }
Ejemplo n.º 21
0
void
test_multi_thread()
{
    boost::thread thr1(mt_test_proc);
#   if 1
    boost::thread thr2(mt_test_proc);
    boost::thread thr3(mt_test_proc);
    boost::thread thr4(mt_test_proc);
    boost::thread thr5(mt_test_proc);
    
    sleep(4);
    std::time_t time = std::time(0);
    time += 3600*24;
    logSink->rotate(time);
    
    thr5.join();
    thr4.join();
    thr3.join();
    thr2.join();
#   endif
    thr1.join();
}
Ejemplo n.º 22
0
TEST(Logger, Basic)
{
    InterlinkedTestNodesWithSysClock nodes;

    uavcan::Logger logger(nodes.a);

    ASSERT_EQ(uavcan::protocol::debug::LogLevel::ERROR, logger.getLevel());

    LogSink sink;

    // Will fail - types are not registered
    uavcan::GlobalDataTypeRegistry::instance().reset();
    ASSERT_GT(0, logger.logError("foo", "Error (fail - type is not registered)"));
    ASSERT_EQ(0, logger.logDebug("foo", "Debug (ignored - low logging level)"));

    ASSERT_FALSE(logger.getExternalSink());
    logger.setExternalSink(&sink);
    ASSERT_EQ(&sink, logger.getExternalSink());

    uavcan::GlobalDataTypeRegistry::instance().reset();
    uavcan::DefaultDataTypeRegistrator<uavcan::protocol::debug::LogMessage> _reg1;

    SubscriberWithCollector<uavcan::protocol::debug::LogMessage> log_sub(nodes.b);
    ASSERT_LE(0, log_sub.start());

    // Sink test
    ASSERT_EQ(0, logger.logDebug("foo", "Debug (ignored due to low logging level)"));
    ASSERT_TRUE(sink.msgs.empty());

    sink.level = uavcan::protocol::debug::LogLevel::DEBUG;
    ASSERT_EQ(0, logger.logDebug("foo", "Debug (sink only)"));
    ASSERT_TRUE(sink.popMatchByLevelAndText(uavcan::protocol::debug::LogLevel::DEBUG, "foo", "Debug (sink only)"));

    ASSERT_LE(0, logger.logError("foo", "Error"));
    nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(10));
    ASSERT_TRUE(log_sub.collector.msg.get());
    ASSERT_EQ(log_sub.collector.msg->level.value, uavcan::protocol::debug::LogLevel::ERROR);
    ASSERT_EQ(log_sub.collector.msg->source, "foo");
    ASSERT_EQ(log_sub.collector.msg->text, "Error");

    logger.setLevel(uavcan::protocol::debug::LogLevel::DEBUG);
    ASSERT_LE(0, logger.logWarning("foo", "Warning"));
    nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(10));
    ASSERT_EQ(log_sub.collector.msg->level.value, uavcan::protocol::debug::LogLevel::WARNING);
    ASSERT_EQ(log_sub.collector.msg->source, "foo");
    ASSERT_EQ(log_sub.collector.msg->text, "Warning");

    ASSERT_LE(0, logger.logInfo("foo", "Info"));
    nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(10));
    ASSERT_EQ(log_sub.collector.msg->level.value, uavcan::protocol::debug::LogLevel::INFO);
    ASSERT_EQ(log_sub.collector.msg->source, "foo");
    ASSERT_EQ(log_sub.collector.msg->text, "Info");

    ASSERT_LE(0, logger.logDebug("foo", "Debug"));
    nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(10));
    ASSERT_EQ(log_sub.collector.msg->level.value, uavcan::protocol::debug::LogLevel::DEBUG);
    ASSERT_EQ(log_sub.collector.msg->source, "foo");
    ASSERT_EQ(log_sub.collector.msg->text, "Debug");

    ASSERT_TRUE(sink.popMatchByLevelAndText(uavcan::protocol::debug::LogLevel::ERROR,   "foo", "Error"));
    ASSERT_TRUE(sink.popMatchByLevelAndText(uavcan::protocol::debug::LogLevel::WARNING, "foo", "Warning"));
    ASSERT_TRUE(sink.popMatchByLevelAndText(uavcan::protocol::debug::LogLevel::INFO,    "foo", "Info"));
    ASSERT_TRUE(sink.popMatchByLevelAndText(uavcan::protocol::debug::LogLevel::DEBUG,   "foo", "Debug"));
}
Ejemplo n.º 23
0
VOID ServLog::Refresh()
{
	LOG_SINK_TYPE OldActiveLogSinks = 0;
	LOG_SINK_TYPE NewActiveLogSinks = Config::GetActiveLogSinks();
	ULONG         Index;
	ServLog       *Inst = ServLog::GetInstance();

	//
	// Save off the original active log sinks
	//
	OldActiveLogSinks = Inst->ActiveSinkTypes;

	//
	// Walk each individual type, checking to see whether or not it's been
	// enabled.
	//
	for (Index = 0;
	     Index < (sizeof(LogSinkTypes) / sizeof(LOG_SINK_TYPE));
	     Index++)
	{
		// 
		// If this log sink type is enabled and was not previously enabled, we
		// instantiate it and add it to the list of active sinks.
		//
		if ((NewActiveLogSinks & LogSinkTypes[Index]) &&
		    (!(OldActiveLogSinks & LogSinkTypes[Index])))
		{
			LogSink *Sink = LogSink::create(
					LogSinkTypes[Index]);

			Log(LOG_SEV_INFO, TEXT("Enabling log sink type %lu."),
					LogSinkTypes[Index]);

			//
			// Add it to the list.
			//
			if (Sink)
				Inst->SinkList.push_back(
						Sink);
		}
		//
		// Otherwise, if the original log sink had this sink type enabled, we may
		// either need to remove it from the list of active sinks (if it's no
		// longer in the new set), or we may need to refresh its settings.
		//
		else if (OldActiveLogSinks & LogSinkTypes[Index])
		{
			std::list<LogSink *>::iterator It;

			for (It = Inst->SinkList.begin();
			     It != Inst->SinkList.end();
			     It++)
			{
				//
				// Did we find the type we're looking for?  If not, continue.
				//
				if ((*It)->GetType() != LogSinkTypes[Index])
					continue;

				LogSink *Sink = (*It);

				//
				// If this log sink type is no longer in the active set, then we
				// must remove it from the list of active log sinks.
				//
				if (!(NewActiveLogSinks & LogSinkTypes[Index]))
				{
					Inst->SinkList.erase(It);

					Log(LOG_SEV_INFO, TEXT("Disabling log sink type %lu."),
							LogSinkTypes[Index]);

					LogSink::destroy(
							Sink);

					break;
				}
				//
				// Otherwise, if it's been enabled and is still enabled, refresh it to
				// make sure everything is still good to go.
				//
				else
				{
					Log(LOG_SEV_INFO, TEXT("Refreshing log sink type %lu."),
							LogSinkTypes[Index]);

					Sink->Refresh();
				}
			}
		}
	}

	//
	// Update the active log sinks bitvector.
	//
	Inst->ActiveSinkTypes = NewActiveLogSinks;
}