X-Git-Url: https://arthur.barton.de/gitweb/?a=blobdiff_plain;f=src%2Fngircd%2Frendezvous.c;h=2d9ae6993d08b1c5666a5fda10161016f111c57e;hb=a988bbc86aed404b7bcfdbceafc030ea4bc5ecab;hp=323b07df26d1233f1772b91752427ebdab7abfb0;hpb=9ab97b29ae9457d7ba370202f9f5dd97fdf07b54;p=ngircd-alex.git diff --git a/src/ngircd/rendezvous.c b/src/ngircd/rendezvous.c index 323b07df..2d9ae699 100644 --- a/src/ngircd/rendezvous.c +++ b/src/ngircd/rendezvous.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2003 by Alexander Barton (alex@barton.de) + * Copyright (c)2001-2004 by Alexander Barton (alex@barton.de) * * 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 @@ -8,16 +8,20 @@ * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. * - * Rendezvous service registration (using Mach Ports, e.g. Mac OS X) + * Rendezvous service registration. + * + * Supported APIs are: + * - Apple Mac OS X + * - Howl */ #include "portab.h" -#ifdef RENDEZVOUS +#ifdef ZEROCONF -static char UNUSED id[] = "$Id: rendezvous.c,v 1.2 2003/03/27 01:24:32 alex Exp $"; +static char UNUSED id[] = "$Id: rendezvous.c,v 1.8 2006/05/10 21:24:01 alex Exp $"; #include "imp.h" #include @@ -34,6 +38,10 @@ static char UNUSED id[] = "$Id: rendezvous.c,v 1.2 2003/03/27 01:24:32 alex Exp #include #endif +#ifdef HAVE_RENDEZVOUS_RENDEZVOUS_H +#include +#endif + #include "defines.h" #include "log.h" @@ -41,73 +49,128 @@ static char UNUSED id[] = "$Id: rendezvous.c,v 1.2 2003/03/27 01:24:32 alex Exp #include "rendezvous.h" +#if defined(HAVE_DNSSERVICEREGISTRATIONCREATE) +# define APPLE +#elif defined(HAVE_SW_DISCOVERY_INIT) +# define HOWL +#else +# error "Can't detect Rendezvous API!?" +#endif + + +#define MAX_RENDEZVOUS 1000 + typedef struct _service { + char Desc[CLIENT_ID_LEN]; +#ifdef APPLE dns_service_discovery_ref Discovery_Ref; mach_port_t Mach_Port; - CHAR Desc[CLIENT_ID_LEN]; +#endif +#ifdef HOWL + sw_discovery_oid Id; +#endif } SERVICE; +static SERVICE My_Rendezvous[MAX_RENDEZVOUS]; -LOCAL VOID Registration_Reply_Handler( DNSServiceRegistrationReplyErrorType ErrCode, VOID *Context ); -LOCAL VOID Unregister( INT Idx ); +static void Unregister( int Idx ); + + +/* -- Apple API -- */ + +#ifdef APPLE -#define MAX_RENDEZVOUS 1000 #define MAX_MACH_MSG_SIZE 512 +static void Registration_Reply_Handler( DNSServiceRegistrationReplyErrorType ErrCode, void *Context ); + +#endif /* Apple */ + + +/* -- Howl API -- */ + +#ifdef HOWL + +static sw_discovery My_Discovery_Session = NULL; +static sw_salt My_Salt; + +static sw_result HOWL_API Registration_Reply_Handler( sw_discovery Session, sw_discovery_publish_status Status, sw_discovery_oid Id, sw_opaque Extra ); -LOCAL SERVICE My_Rendezvous[MAX_RENDEZVOUS]; +#endif /* Howl */ -GLOBAL VOID Rendezvous_Init( VOID ) +GLOBAL void Rendezvous_Init( void ) { /* Initialize structures */ - INT i; + int i; - for( i = 0; i < MAX_RENDEZVOUS; i++ ) +#ifdef HOWL + if( sw_discovery_init( &My_Discovery_Session ) != SW_OKAY ) { - My_Rendezvous[i].Discovery_Ref = 0; - My_Rendezvous[i].Mach_Port = 0; + Log( LOG_EMERG, "Can't initialize Rendezvous (Howl): sw_discovery_init() failed!" ); + Log( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME ); + exit( 1 ); + } + + if( sw_discovery_salt( My_Discovery_Session, &My_Salt ) != SW_OKAY ) + { + Log( LOG_EMERG, "Can't initialize Rendezvous (Howl): sw_discovery_salt() failed!" ); + Log( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME ); + exit( 1 ); } +#endif + + for( i = 0; i < MAX_RENDEZVOUS; i++ ) My_Rendezvous[i].Desc[0] = '\0'; } /* Rendezvous_Init */ -GLOBAL VOID Rendezvous_Exit( VOID ) +GLOBAL void Rendezvous_Exit( void ) { /* Clean up & exit module */ - INT i; + int i; for( i = 0; i < MAX_RENDEZVOUS; i++ ) { - if( My_Rendezvous[i].Discovery_Ref ) Unregister( i ); + if( My_Rendezvous[i].Desc[0] ) Unregister( i ); } + +#ifdef HOWL + sw_discovery_fina( My_Discovery_Session ); +#endif } /* Rendezvous_Exit */ -GLOBAL BOOLEAN Rendezvous_Register( CHAR *Name, CHAR *Type, UINT Port ) +/** + * Register ZeroConf service + */ +GLOBAL bool Rendezvous_Register( char *Name, char *Type, UINT16 Port ) { - /* Register new service */ + int i; - INT i; + if (Conf_NoZeroConf) + return; /* Search free port structure */ - for( i = 0; i < MAX_RENDEZVOUS; i++ ) if( ! My_Rendezvous[i].Discovery_Ref ) break; + for( i = 0; i < MAX_RENDEZVOUS; i++ ) if( ! My_Rendezvous[i].Desc[0] ) break; if( i >= MAX_RENDEZVOUS ) { Log( LOG_ERR, "Can't register \"%s\" with Rendezvous: limit (%d) reached!", Name, MAX_RENDEZVOUS ); - return FALSE; + return false; } strlcpy( My_Rendezvous[i].Desc, Name, sizeof( My_Rendezvous[i].Desc )); +#ifdef APPLE /* Register new service */ - My_Rendezvous[i].Discovery_Ref = DNSServiceRegistrationCreate( Name, Type, "", htonl( Port ), "", Registration_Reply_Handler, My_Rendezvous[i].Desc ); + My_Rendezvous[i].Discovery_Ref = DNSServiceRegistrationCreate( Name, Type, "", htonl( Port ), "", Registration_Reply_Handler, &My_Rendezvous[i] ); if( ! My_Rendezvous[i].Discovery_Ref ) { Log( LOG_ERR, "Can't register \"%s\" with Rendezvous: can't register service!", My_Rendezvous[i].Desc ); - return FALSE; + My_Rendezvous[i].Desc[0] = '\0'; + return false; } /* Get and save the corresponding Mach Port */ @@ -117,28 +180,39 @@ GLOBAL BOOLEAN Rendezvous_Register( CHAR *Name, CHAR *Type, UINT Port ) Log( LOG_ERR, "Can't register \"%s\" with Rendezvous: got no Mach Port!", My_Rendezvous[i].Desc ); /* Here we actually leek a descriptor :-( */ My_Rendezvous[i].Discovery_Ref = 0; - return FALSE; + My_Rendezvous[i].Desc[0] = '\0'; + return false; } +#endif /* Apple */ + +#ifdef HOWL + if( sw_discovery_publish( My_Discovery_Session, 0, Name, Type, NULL, NULL, Port, NULL, 0, Registration_Reply_Handler, &My_Rendezvous[i], &My_Rendezvous[i].Id ) != SW_OKAY ) + { + Log( LOG_ERR, "Can't register \"%s\" with Rendezvous: can't register service!", My_Rendezvous[i].Desc ); + My_Rendezvous[i].Desc[0] = '\0'; + return false; + } +#endif /* Howl */ Log( LOG_DEBUG, "Rendezvous: Registering \"%s\" ...", My_Rendezvous[i].Desc ); - return TRUE; + return true; } /* Rendezvous_Register */ -GLOBAL BOOLEAN Rendezvous_Unregister( CHAR *Name ) +GLOBAL bool Rendezvous_Unregister( char *Name ) { /* Unregister service from rendezvous */ - INT i; - BOOLEAN ok; + int i; + bool ok; - ok = FALSE; + ok = false; for( i = 0; i < MAX_RENDEZVOUS; i++ ) { if( strcmp( Name, My_Rendezvous[i].Desc ) == 0 ) { Unregister( i ); - ok = TRUE; + ok = true; } } @@ -146,26 +220,27 @@ GLOBAL BOOLEAN Rendezvous_Unregister( CHAR *Name ) } /* Rendezvous_Unregister */ -GLOBAL VOID Rendezvous_UnregisterListeners( VOID ) +GLOBAL void Rendezvous_UnregisterListeners( void ) { /* Unregister all our listening sockets from Rendezvous */ - INT i; + int i; for( i = 0; i < MAX_RENDEZVOUS; i++ ) { - if( My_Rendezvous[i].Discovery_Ref ) Unregister( i ); + if( My_Rendezvous[i].Desc[0] ) Unregister( i ); } } /* Rendezvous_UnregisterListeners */ -GLOBAL VOID Rendezvous_Handler( VOID ) +GLOBAL void Rendezvous_Handler( void ) { /* Handle all Rendezvous stuff; this function must be called * periodically from the run loop of the main program */ - INT i; - CHAR buffer[MAX_MACH_MSG_SIZE]; +#ifdef APPLE + int i; + char buffer[MAX_MACH_MSG_SIZE]; mach_msg_return_t result; mach_msg_header_t *msg; @@ -180,20 +255,53 @@ GLOBAL VOID Rendezvous_Handler( VOID ) /* Handle message */ if( result == MACH_MSG_SUCCESS ) DNSServiceDiscovery_handleReply( msg ); #ifdef DEBUG - else if( result != MACH_RCV_TIMED_OUT ) Log( LOG_DEBUG, "mach_msg(): %ld", (LONG)result ); -#endif + else if( result != MACH_RCV_TIMED_OUT ) Log( LOG_DEBUG, "mach_msg(): %ld", (long)result ); +#endif /* Debug */ } +#endif /* Apple */ + +#ifdef HOWL + sw_ulong msecs = 10; + sw_salt_step( My_Salt, &msecs ); +#endif } /* Rendezvous_Handler */ -LOCAL VOID Registration_Reply_Handler( DNSServiceRegistrationReplyErrorType ErrCode, VOID *Context ) +static void Unregister( int Idx ) { - CHAR txt[50]; + /* Unregister service */ + +#ifdef APPLE + DNSServiceDiscoveryDeallocate( My_Rendezvous[Idx].Discovery_Ref ); +#endif /* Apple */ + +#ifdef HOWL + if( sw_discovery_cancel( My_Discovery_Session, My_Rendezvous[Idx].Id ) != SW_OKAY ) + { + Log( LOG_ERR, "Rendezvous: Failed to unregister \"%s\"!", My_Rendezvous[Idx].Desc ); + return; + } +#endif /* Howl */ + + Log( LOG_INFO, "Unregistered \"%s\" from Rendezvous.", My_Rendezvous[Idx].Desc ); + My_Rendezvous[Idx].Desc[0] = '\0'; +} /* Unregister */ + + +/* -- Apple API -- */ + +#ifdef APPLE + + +static void Registration_Reply_Handler( DNSServiceRegistrationReplyErrorType ErrCode, void *Context ) +{ + SERVICE *s = (SERVICE *)Context; + char txt[50]; if( ErrCode == kDNSServiceDiscoveryNoError ) { /* Success! */ - Log( LOG_INFO, "Successfully registered \"%s\" with Rendezvous.", Context ? Context : "NULL" ); + Log( LOG_INFO, "Successfully registered \"%s\" with Rendezvous.", s->Desc ); return; } @@ -206,24 +314,59 @@ LOCAL VOID Registration_Reply_Handler( DNSServiceRegistrationReplyErrorType ErrC strcpy( txt, "name conflict!" ); break; default: - sprintf( txt, "error code %ld!", (LONG)ErrCode ); + snprintf(txt, sizeof txt, "error code %ld!", + (long)ErrCode); } - Log( LOG_INFO, "Can't register \"%s\" with Rendezvous: %s", Context ? Context : "NULL", txt ); + Log( LOG_INFO, "Can't register \"%s\" with Rendezvous: %s", s->Desc, txt ); + s->Desc[0] = '\0'; } /* Registration_Reply_Handler */ -LOCAL VOID Unregister( INT Idx ) +#endif /* Apple */ + + +/* -- Howl API -- */ + +#ifdef HOWL + + +static sw_result HOWL_API Registration_Reply_Handler( sw_discovery Session, sw_discovery_publish_status Status, UNUSED sw_discovery_oid Id, sw_opaque Extra ) { - /* Unregister service */ + SERVICE *s = (SERVICE *)Extra; + char txt[50]; - DNSServiceDiscoveryDeallocate( My_Rendezvous[Idx].Discovery_Ref ); - Log( LOG_INFO, "Unregistered \"%s\" from Rendezvous.", My_Rendezvous[Idx].Desc ); - My_Rendezvous[Idx].Discovery_Ref = 0; -} /* Unregister */ + assert( Session == My_Discovery_Session ); + assert( Extra != NULL ); + + if( Status == SW_DISCOVERY_PUBLISH_STARTED || Status == SW_DISCOVERY_PUBLISH_STOPPED ) + { + /* Success! */ + Log( LOG_INFO, "Successfully registered \"%s\" with Rendezvous.", s->Desc ); + return SW_OKAY; + } + + switch( Status ) + { + case SW_DISCOVERY_PUBLISH_NAME_COLLISION: + strcpy( txt, "name conflict!" ); + break; + default: + snprintf(txt, sizeof txt, "error code %ld!", + (long)Status); + } + + Log( LOG_INFO, "Can't register \"%s\" with Rendezvous: %s", s->Desc, txt ); + s->Desc[0] = '\0'; + + return SW_OKAY; +} /* Registration_Reply_Handler */ + + +#endif /* Howl */ -#endif /* RENDEZVOUS */ +#endif /* ZEROCONF */ /* -eof- */