+ if ( lutil_atolx( &l, c->argv[1], 0 ) != 0 ) {
+ fprintf( stderr, "%s: "
+ "invalid kbyte \"%s\" in \"checkpoint\".\n",
+ c->log, c->argv[1] );
+ return 1;
+ }
+ bdb->bi_txn_cp_kbyte = l;
+ if ( lutil_atolx( &l, c->argv[2], 0 ) != 0 ) {
+ fprintf( stderr, "%s: "
+ "invalid minutes \"%s\" in \"checkpoint\".\n",
+ c->log, c->argv[2] );
+ return 1;
+ }
+ bdb->bi_txn_cp_min = l;
+ /* If we're in server mode and time-based checkpointing is enabled,
+ * submit a task to perform periodic checkpoints.
+ */
+ if ((slapMode & SLAP_SERVER_MODE) && bdb->bi_txn_cp_min ) {
+ struct re_s *re = bdb->bi_txn_cp_task;
+ if ( re ) {
+ re->interval.tv_sec = bdb->bi_txn_cp_min * 60;
+ } else {
+ if ( c->be->be_suffix == NULL || BER_BVISNULL( &c->be->be_suffix[0] ) ) {
+ fprintf( stderr, "%s: "
+ "\"checkpoint\" must occur after \"suffix\".\n",
+ c->log );
+ return 1;
+ }
+ ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
+ bdb->bi_txn_cp_task = ldap_pvt_runqueue_insert( &slapd_rq,
+ bdb->bi_txn_cp_min * 60, bdb_checkpoint, bdb,
+ LDAP_XSTRING(bdb_checkpoint), c->be->be_suffix[0].bv_val );
+ ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
+ }
+ }
+ } break;
+
+ case BDB_CONFIG: {
+ char *ptr = c->line;
+ struct berval bv;
+
+ if ( c->op == SLAP_CONFIG_ADD ) {
+ ptr += STRLENOF("dbconfig");
+ while (!isspace((unsigned char)*ptr)) ptr++;
+ while (isspace((unsigned char)*ptr)) ptr++;
+ }
+
+ if ( bdb->bi_flags & BDB_IS_OPEN ) {
+ bdb->bi_flags |= BDB_UPD_CONFIG;
+ c->cleanup = bdb_cf_cleanup;
+ } else {
+ /* If we're just starting up...
+ */
+ FILE *f;
+ /* If a DB_CONFIG file exists, or we don't know the path
+ * to the DB_CONFIG file, ignore these directives
+ */
+ if (( bdb->bi_flags & BDB_HAS_CONFIG ) || !bdb->bi_db_config_path )
+ break;
+ f = fopen( bdb->bi_db_config_path, "a" );
+ if ( f ) {
+ /* FIXME: EBCDIC probably needs special handling */
+ fprintf( f, "%s\n", ptr );
+ fclose( f );
+ }
+ }
+ ber_str2bv( ptr, 0, 1, &bv );
+ ber_bvarray_add( &bdb->bi_db_config, &bv );
+ }
+ break;
+
+ case BDB_CRYPTFILE:
+ rc = lutil_get_filed_password( c->value_string, &bdb->bi_db_crypt_key );
+ if ( rc == 0 ) {
+ bdb->bi_db_crypt_file = c->value_string;
+ }
+ break;
+
+ /* Cannot set key if file was already set */
+ case BDB_CRYPTKEY:
+ if ( bdb->bi_db_crypt_file ) {
+ rc = 1;
+ } else {
+ bdb->bi_db_crypt_key = c->value_bv;
+ }
+ break;
+
+ case BDB_DIRECTORY: {
+ FILE *f;
+ char *ptr, *testpath;
+ int len;
+
+ len = strlen( c->value_string );
+ testpath = ch_malloc( len + STRLENOF(LDAP_DIRSEP) + STRLENOF("DUMMY") + 1 );
+ ptr = lutil_strcopy( testpath, c->value_string );
+ *ptr++ = LDAP_DIRSEP[0];
+ strcpy( ptr, "DUMMY" );
+ f = fopen( testpath, "w" );
+ if ( f ) {
+ fclose( f );
+ unlink( testpath );
+ }
+ ch_free( testpath );
+ if ( !f ) {
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid path: %s",
+ c->log, strerror( errno ));
+ Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
+ return -1;
+ }
+
+ if ( bdb->bi_dbenv_home )
+ ch_free( bdb->bi_dbenv_home );
+ bdb->bi_dbenv_home = c->value_string;
+
+ /* See if a DB_CONFIG file already exists here */
+ if ( bdb->bi_db_config_path )
+ ch_free( bdb->bi_db_config_path );
+ bdb->bi_db_config_path = ch_malloc( len +
+ STRLENOF(LDAP_DIRSEP) + STRLENOF("DB_CONFIG") + 1 );
+ ptr = lutil_strcopy( bdb->bi_db_config_path, bdb->bi_dbenv_home );
+ *ptr++ = LDAP_DIRSEP[0];
+ strcpy( ptr, "DB_CONFIG" );
+
+ f = fopen( bdb->bi_db_config_path, "r" );
+ if ( f ) {
+ bdb->bi_flags |= BDB_HAS_CONFIG;
+ fclose(f);
+ }
+ }