File cyrus-imapd-openslp.patch of Package cyrus-imapd.import4736
Index: configure.in
===================================================================
--- configure.in.orig
+++ configure.in
@@ -1193,6 +1193,19 @@ AC_ARG_WITH(drac, [ --with-drac=DIR
fi)
AC_SUBST(DRACLIBS)
+dnl
+dnl Test for OpenSLP
+dnl
+SLPLIBS=
+AC_ARG_WITH(openslp, [ --with-openslp=DIR use OpenSLP library in <DIR> [no] ],
+ if test -d "$withval"; then
+ LDFLAGS="$LDFLAGS -L${withval}"
+ AC_CHECK_LIB(slp, SLPOpen,
+ AC_DEFINE(USE_SLP,[],[Compile with OpenSLP?])
+ SLPLIBS="-lslp")
+ fi)
+AC_SUBST(SLPLIBS)
+
CMU_LIBWRAP
CMU_UCDSNMP
Index: master/Makefile.in
===================================================================
--- master/Makefile.in.orig
+++ master/Makefile.in
@@ -58,7 +58,7 @@ DEPLIBS = @DEPLIBS@
CFLAGS = @CFLAGS@
LDFLAGS = @LDFLAGS@ @COM_ERR_LDFLAGS@
-LIBS = ../lib/libcyrus_min.a @LIB_UCDSNMP@ @LIBS@ @COM_ERR_LIBS@
+LIBS = ../lib/libcyrus_min.a @LIB_UCDSNMP@ @LIBS@ @COM_ERR_LIBS@ @SLPLIBS@
SHELL = /bin/sh
MAKEDEPEND = @MAKEDEPEND@
Index: master/master.c
===================================================================
--- master/master.c.orig
+++ master/master.c
@@ -110,6 +110,10 @@
int deny_severity = LOG_ERR;
#endif
+#ifdef USE_SLP
+#include <slp.h>
+#endif
+
#include "masterconf.h"
#include "master.h"
@@ -119,6 +123,16 @@
#include "util.h"
#include "xmalloc.h"
+#ifdef USE_SLP
+#define URL_MAX 1024
+SLPHandle phslp;
+struct slpurl {
+ char srvurl[URL_MAX];
+ struct slpurl *next;
+};
+struct slpurl *start = NULL;
+#endif
+
enum {
become_cyrus_early = 1,
child_table_size = 10000,
@@ -181,10 +195,41 @@ static struct timeval janitor_mark; /* L
void limit_fds(rlim_t);
void schedule_event(struct event *a);
+#ifdef USE_SLP
+void SLPRegReportCB(SLPHandle hslp, SLPError errcode, void* cookie)
+{
+ /* return the error code in the cookie */
+ *(SLPError*)cookie = errcode;
+
+ /* You could do something else here like print out */
+ /* the errcode, etc. Remember, as a general rule, */
+ /* do not try to do too much in a callback because */
+ /* it is being executed by the same thread that is */
+ /* reading slp packets from the wire. */
+}
+
+void SLPshutdown(void)
+{
+ struct slpurl *ttmp,*tmp = start;
+ SLPError callbackerr;
+ while( tmp ) {
+ syslog(LOG_INFO,"SLPderegister [%s]",tmp->srvurl);
+ SLPDereg(phslp, tmp->srvurl, SLPRegReportCB, &callbackerr);
+ ttmp = tmp;
+ tmp = tmp->next;
+ free(ttmp);
+ }
+ SLPClose(&phslp);
+}
+#endif
+
void fatal(const char *msg, int code)
{
syslog(LOG_CRIT, "%s", msg);
syslog(LOG_NOTICE, "exiting");
+#ifdef USE_SLP
+ SLPshutdown();
+#endif
exit(code);
}
@@ -466,7 +511,90 @@ void service_create(struct service *s)
s->socket = 0;
continue;
}
-
+
+#ifdef USE_SLP
+ if ((!strcmp(s->proto, "tcp")) && s->listen[0] != '/' ) {
+ SLPError err;
+ SLPError callbackerr;
+ char *listen, *service;
+ char *listen_addr;
+ int port;
+ char hname[URL_MAX];
+ char dname[URL_MAX];
+ char turl[URL_MAX];
+ struct slpurl *u;
+ char registered = 0;
+
+
+ /* parse_listen() and resolve_host() are destructive,
+ * so make a work copy of s->listen
+ */
+ listen = xstrdup(s->listen);
+
+ if ((service = parse_listen(listen)) == NULL) {
+ /* listen IS the port */
+ service = listen;
+ listen_addr = NULL;
+ } else {
+ /* s->listen is now just the address */
+ listen_addr = parse_host(listen);
+ if (*listen_addr == '\0')
+ listen_addr = NULL;
+ }
+ port = ntohs(((struct sockaddr_in *)(res)->ai_addr)->sin_port);
+ gethostname(hname,URL_MAX);
+ getdomainname(dname,URL_MAX);
+
+ snprintf(turl,URL_MAX,"service:%s://%s.%s:%d",
+ service,
+ hname, dname,
+ port);
+
+ /* check, whether we already registered the service */
+ u = start;
+ while( u ) {
+ if( ! strcmp(u->srvurl,turl) ) registered = 1;
+ u = u->next;
+ }
+
+ if( ! registered ) {
+ u = (struct slpurl *)calloc(1,sizeof(struct slpurl));
+ if( ! u )
+ fatal("out of memory", EX_UNAVAILABLE);
+
+ strncpy(u->srvurl,turl,URL_MAX);
+
+ if( start == NULL ) {
+ start = u;
+ } else {
+ struct slpurl *tmp = start;
+ while( tmp->next ) tmp = tmp->next;
+ tmp->next = u;
+ }
+ syslog(LOG_INFO,"SLPRegister [%s]",u->srvurl);
+
+ err = SLPReg(phslp,
+ u->srvurl,
+ SLP_LIFETIME_MAXIMUM,
+ 0,
+ "",
+ SLP_TRUE,
+ SLPRegReportCB,
+ &callbackerr );
+
+ if(( err != SLP_OK) || (callbackerr != SLP_OK))
+ {
+ syslog(LOG_ERR,"Error registering service with slp %i",err);
+ }
+
+ if( callbackerr != SLP_OK)
+ {
+ syslog(LOG_ERR,"Error registering service with slp %i",callbackerr);
+ }
+ }
+ }
+#endif
+
s->ready_workers = 0;
s->associate = nsocket;
s->family = res->ai_family;
@@ -1022,6 +1150,9 @@ void sigterm_handler(int sig __attribute
/* tell master agent we're exiting */
snmp_shutdown("cyrusMaster");
#endif
+#ifdef USE_SLP
+ SLPshutdown();
+#endif
syslog(LOG_INFO, "exiting on SIGTERM/SIGINT");
exit(0);
@@ -1876,6 +2007,16 @@ int main(int argc, char **argv)
syslog(LOG_NOTICE, "process started");
+#ifdef USE_SLP
+ {
+ int slperr;
+ if ( (slperr = SLPOpen(NULL, SLP_FALSE, &phslp)) != SLP_OK ) {
+ syslog(LOG_ERR, "SLPOpen() failed, return code: %d", slperr);
+ }
+ }
+#endif
+
+
#if defined(HAVE_UCDSNMP) || defined(HAVE_NETSNMP)
/* initialize SNMP agent */