Version 4.0 of the API is currently implemented.
.LP
Database specific data may contain plugin information.
+This manpage details the
+.BR slapd (8)
+configuration statements that affect the loading of SLAPI \fIplugins\fP.
.LP
Arguments that should be replaced by actual text are shown in brackets <>.
+.LP
The structure of the plugin directives is
.TP
.B plugin "<type> <lib_path> <init_function> [<arguments>]"
The optional
.BR <arguments>
list is passed to the init function.
+.TP
+.B pluginlog <file>
+Specify an alternative path for the plugin log file (default is
+LOCALSTATEDIR/error).
+.TP
+.B modulepath <pathspec>
+This statement sets the module load path for dynamically loadable
+backends, as described in
+.BR slapd.conf (5);
+however, since both the dynamically loadable backends
+and the SLAPI plugins use the same underlying library (libtool's ltdl)
+its value also affects the plugin search path.
+In general the search path is made of colon-separated paths; usually
+the user-defined path is searched first; then the value of the
+\fILTDL_LIBRARY_PATH\fP environment variable, if defined, is used;
+finally, the systemi-specific dynamic load path is attempted (e.g. on
+Linux the value of the environment variable \fILD_LIBRARY_PATH\fP).
+Please carefully read the documentation of ltdl because its behavior
+is very platform dependent.
.SH FILES
.TP
ETCDIR/slapd.conf
backend.lo database.lo thread.lo conn.lo rww.lo log.lo \
operation.lo sent.lo listener.lo time.lo
-LDAP_INCDIR= ../../../include
+LDAP_INCDIR= ../../../include
LDAP_LIBDIR= ../../../libraries
BUILD_OPT = "--enable-monitor"
LIBBASE = back_monitor
-XINCPATH = -I.. -I$(srcdir)/..
+XINCPATH = -I.. -I$(srcdir)/.. -I../slapi
XDEFS = $(MODULES_CPPFLAGS)
all-local-lib: ../.backend
#include <stdio.h>
#include "slap.h"
+#include "slapi-plugin.h"
#include "back-monitor.h"
+#if defined(LDAP_SLAPI)
+static int monitor_back_add_plugin( Backend *be, Entry *e );
+#endif /* defined(LDAP_SLAPI) */
+
int
monitor_subsys_database_init(
BackendDB *be
}
if ( slap_str2ad( "seeAlso", &ad_seeAlso, &text ) != LDAP_SUCCESS ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, CRIT,
+ "monitor_subsys_database_init: "
+ "unable to find 'seeAlso' attribute description\n",
+ 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "monitor_subsys_database_init: "
+ "unable to find 'seeAlso' attribute description\n",
+ 0, 0, 0 );
+#endif
return( -1 );
}
return( -1 );
}
+#if defined(LDAP_SLAPI)
+ monitor_back_add_plugin( be, e );
+#endif /* defined(LDAP_SLAPI) */
+
e_tmp = e;
}
return( 0 );
}
+#if defined(LDAP_SLAPI)
+static int
+monitor_back_add_plugin( Backend *be, Entry *e_database )
+{
+ Slapi_PBlock *pCurrentPB;
+ int i, rc = LDAP_SUCCESS;
+
+ if ( slapi_x_pblock_get_first( be, &pCurrentPB ) != LDAP_SUCCESS ) {
+ /*
+ * LDAP_OTHER is returned if no plugins are installed
+ */
+ rc = LDAP_OTHER;
+ goto done;
+ }
+
+ i = 0;
+ do {
+ Slapi_PluginDesc *srchdesc;
+ char buf[1024];
+ struct berval bv;
+
+ rc = slapi_pblock_get( pCurrentPB, SLAPI_PLUGIN_DESCRIPTION,
+ &srchdesc );
+ if ( rc != LDAP_SUCCESS ) {
+ goto done;
+ }
+
+ snprintf( buf, sizeof(buf),
+ "plugin %d name: %s; "
+ "vendor: %s; "
+ "version: %s; "
+ "description: %s",
+ i,
+ srchdesc->spd_id,
+ srchdesc->spd_vendor,
+ srchdesc->spd_version,
+ srchdesc->spd_description );
+
+ bv.bv_val = buf;
+ bv.bv_len = strlen( buf );
+ attr_merge_one( e_database, monitor_ad_desc, &bv );
+
+ i++;
+
+ } while ( ( slapi_x_pblock_get_next( &pCurrentPB ) == LDAP_SUCCESS )
+ && ( pCurrentPB != NULL ) );
+
+done:
+ return rc;
+}
+#endif /* defined(LDAP_SLAPI) */
#endif /* !defined( LDAP_SLAPI ) */
+ /* Netscape plugins */
+ } else if ( strcasecmp( cargv[0], "pluginlog" ) == 0 ) {
+#if defined( LDAP_SLAPI )
+ if ( cargc < 2 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONFIG, INFO,
+ "%s: line %d: missing file name "
+ "in pluginlog <filename> line.\n",
+ fname, lineno, 0 );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: missing file name "
+ "in pluginlog <filename> line.\n",
+ fname, lineno, 0 );
+#endif
+ return( 1 );
+ }
+ if ( slapi_log_file != NULL ) {
+ ch_free( slapi_log_file );
+ }
+
+ slapi_log_file = ch_strdup( cargv[1] );
+#endif /* !defined( LDAP_SLAPI ) */
/* pass anything else to the current backend info/db config routine */
} else {
LIB_DEFS = -DSLAPI_LIBRARY
-SRCS= plugin.c slapi_pblock.c slapi_utils.c printmsg.c slapi_ops.c $(@PLAT@_SRCS)
-OBJS= plugin.lo slapi_pblock.lo slapi_utils.lo printmsg.lo slapi_ops.lo $(@PLAT@_SRCS)
+SRCS= plugin.c slapi_pblock.c slapi_utils.c printmsg.c slapi_ops.c \
+ $(@PLAT@_SRCS)
+OBJS= plugin.lo slapi_pblock.lo slapi_utils.lo printmsg.lo slapi_ops.lo \
+ $(@PLAT@_SRCS)
XSRCS= version.c
return -1;
}
+ if ( ldap_pvt_thread_mutex_init( &slapi_printmessage_mutex ) ) {
+ return -1;
+ }
+
+ slapi_log_file = ch_strdup( LDAP_RUNDIR LDAP_DIRSEP "errors" );
+ if ( slapi_log_file == NULL ) {
+ return -1;
+ }
+
return 0;
}
#include <ldap_pvt_thread.h>
/* Single threads access to routine */
-static ldap_pvt_thread_mutex_t PrintMessage_mutex;
-static int PrintMessage_mutex_inited = 0;
-
-static void
-InitMutex ()
-{
- if (PrintMessage_mutex_inited == 0) {
- PrintMessage_mutex_inited = 1;
- ldap_pvt_thread_mutex_init(&PrintMessage_mutex);
- }
-}
+ldap_pvt_thread_mutex_t slapi_printmessage_mutex;
+const char *slapi_log_file = NULL;
+int slapi_log_level = SLAPI_LOG_PLUGIN;
int
vLogError(
- int level,
- char *subsystem,
- char *fmt,
- va_list arglist )
+ int level,
+ char *subsystem,
+ char *fmt,
+ va_list arglist )
{
- int rc = 0;
- char *tmpFmt;
- FILE * fp = NULL;
- char *p, *sval;
- int ival;
+ int rc = 0;
+ FILE *fp = NULL;
- char timeStr[100];
- struct tm *ltm;
- time_t currentTime;
+ char timeStr[100];
+ struct tm *ltm;
+ time_t currentTime;
- tmpFmt = fmt;
- fmt = (char*)ch_calloc(strlen(subsystem) + strlen(tmpFmt) + 3, 1);
- sprintf(fmt, "%s: %s", subsystem, tmpFmt);
+ assert( subsystem != NULL );
+ assert( fmt != NULL );
- InitMutex() ;
- ldap_pvt_thread_mutex_lock( &PrintMessage_mutex ) ;
+ ldap_pvt_thread_mutex_lock( &slapi_printmessage_mutex ) ;
/* for now, we log all severities */
- if ( 1 ) {
- fp = fopen( LDAP_RUNDIR LDAP_DIRSEP "errors", "a" );
- if (fp == NULL)
- fp = fopen( "errors", "a" );
-
- if ( fp != NULL) {
- while ( lockf(fileno(fp), F_LOCK, 0 ) != 0 ) {}
-
- time (¤tTime);
- ltm = localtime( ¤tTime );
- strftime( timeStr, sizeof(timeStr), "%x %X ", ltm );
- fprintf(fp, timeStr);
- for (p = fmt; *p; p++) {
- if (*p != '%') {
- fprintf(fp, "%c", *p);
- continue;
- }
- switch(*++p) {
- case 'd':
- ival = va_arg( arglist, int);
- fprintf(fp, "%d", ival);
- break;
- case 's':
- for (sval = va_arg(arglist, char *); *sval; sval++)
- fprintf(fp, "%c", *sval);
- break;
- default:
- fprintf(fp, "%c", *p);
- break;
-
- }
- }
-
- fflush(fp);
-
- lockf( fileno(fp), F_ULOCK, 0 );
-
- fclose(fp);
- } else {
-#if 0 /* unused */
- int save_errno = (int)errno;
-#endif /* unused */
- rc = ( -1);
+ if ( level <= slapi_log_level ) {
+ fp = fopen( slapi_log_file, "a" );
+ if ( fp == NULL) {
+ rc = -1;
+ goto done;
+ }
+
+ /*
+ * FIXME: could block
+ */
+ while ( lockf( fileno( fp ), F_LOCK, 0 ) != 0 ) {
+ /* DO NOTHING */ ;
}
+
+ time( ¤tTime );
+ ltm = localtime( ¤tTime );
+ strftime( timeStr, sizeof(timeStr), "%x %X", ltm );
+ fputs( timeStr, fp );
+
+ fprintf( fp, " %s: ", subsystem );
+ vfprintf( fp, fmt, arglist );
+ if ( fmt[ strlen( fmt ) - 1 ] != '\n' ) {
+ fputs( "\n", fp );
+ }
+ fflush( fp );
+
+ lockf( fileno( fp ), F_ULOCK, 0 );
+
+ fclose( fp );
+
} else {
- rc = ( -1);
+ rc = -1;
}
- ldap_pvt_thread_mutex_unlock( &PrintMessage_mutex );
- ch_free(fmt);
+done:
+ ldap_pvt_thread_mutex_unlock( &slapi_printmessage_mutex );
- return (rc);
+ return rc;
}
#endif /* LDAP_SLAPI */
}
+/*
+ * OpenLDAP extension
+ */
+int
+slapi_x_pblock_get_first( Backend *be, Slapi_PBlock **pb )
+{
+#if defined(LDAP_SLAPI)
+ assert( pb );
+ *pb = (Slapi_PBlock *)be->be_pb;
+ return (*pb == NULL ? LDAP_OTHER : LDAP_SUCCESS);
+#else /* LDAP_SLAPI */
+ return LDAP_OTHER;
+#endif /* LDAP_SLAPI */
+}
+
+/*
+ * OpenLDAP extension
+ */
+int
+slapi_x_pblock_get_next( Slapi_PBlock **pb )
+{
+#if defined(LDAP_SLAPI)
+ assert( pb );
+ return slapi_pblock_get( *pb, SLAPI_IBM_PBLOCK, pb );
+#else /* LDAP_SLAPI */
+ return LDAP_OTHER;
+#endif /* LDAP_SLAPI */
+}
+
int slapi_pblock_delete_param(Slapi_PBlock *p, int param);
void slapi_pblock_clear(Slapi_PBlock *pb);
+/*
+ * OpenLDAP extensions
+ */
+int slapi_x_pblock_get_first( Backend *be, Slapi_PBlock **pb );
+int slapi_x_pblock_get_next( Slapi_PBlock **pb );
+
#endif /* SLAPI_PBLOCK_H */
extern ldap_pvt_thread_mutex_t slapi_hn_mutex;
extern ldap_pvt_thread_mutex_t slapi_time_mutex;
+extern ldap_pvt_thread_mutex_t slapi_printmessage_mutex;
+extern const char *slapi_log_file;
+extern int slapi_log_level;
#endif /* _SLAPI_UTILS_H */