[Fedora-directory-commits] ldapserver/ldap/servers/plugins/replication cl5_api.c, 1.17, 1.18 cl5_api.h, 1.7, 1.8 cl5_config.c, 1.6, 1.7

Richard Allen Megginson (rmeggins) fedora-directory-commits at redhat.com
Tue Oct 16 21:22:49 UTC 2007


Author: rmeggins

Update of /cvs/dirsec/ldapserver/ldap/servers/plugins/replication
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv3313/ldapserver/ldap/servers/plugins/replication

Modified Files:
	cl5_api.c cl5_api.h cl5_config.c 
Log Message:
Resolves: bug 185602
Bug Description: Netscape Console allows instance directory to be set as change log
Reviewed by: nkinder (Thanks!)
Fix Description: 1) When removing the changelog files and directories, only remove the actual db related files - version, guardian, *db4, log.*, and __db.* - This should take care of the cases where the changelog was already created in an existing directory.
2) Disallow adding/changing a changelog db directory if it already exists and is not empty
Platforms tested: RHEL5 x86_64
Flag Day: no
Doc impact: no
QA impact: should be covered by regular nightly and manual testing
New Tests integrated into TET: none



Index: cl5_api.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/replication/cl5_api.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- cl5_api.c	12 Oct 2007 17:22:54 -0000	1.17
+++ cl5_api.c	16 Oct 2007 21:22:47 -0000	1.18
@@ -3835,6 +3835,39 @@
 	}
 }
 
+/* see if the given file is a changelog db file */
+static int
+_cl5IsDbFile(const char *fname)
+{
+	char *ptr = NULL;
+	if (!fname || !*fname) {
+		return 0;
+	}
+
+	if (!strcmp(fname, GUARDIAN_FILE)) {
+		return 1;
+	}
+
+	if (!strcmp(fname, VERSION_FILE)) {
+		return 1;
+	}
+
+	if (_cl5FileEndsWith(fname, DB_EXTENSION)) {
+		return 1;
+	}
+
+	if (_cl5IsLogFile(fname)) {
+		return 1;
+	}
+
+	ptr = strstr(fname, "__db.");
+	if (ptr == fname) { /* begins with __db. */
+		return 1;
+	}
+
+	return 0; /* not a filename we recognize as being associated with the db */
+}
+
 /* state lock must be locked */
 static int  _cl5Delete (const char *clDir, int rmDir)
 {
@@ -3842,6 +3875,7 @@
 	char  filename[MAXPATHLEN + 1];
 	PRDirEntry *entry = NULL;
 	int rc;
+	int dirisempty = 1;
 
 	/* remove all files in the directory and the directory */
 	dir = PR_OpenDir(clDir);
@@ -3860,6 +3894,13 @@
 		{
 			break;
 		}
+		if (!_cl5IsDbFile(entry->name)) {
+			slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, 
+							"_cl5Delete: Skipping file [%s/%s] because it is not a changelogdb file.\n",
+							clDir, entry->name);
+			dirisempty = 0; /* skipped at least one file - dir not empty */
+			continue;
+		}
 		PR_snprintf(filename, MAXPATHLEN, "%s/%s", clDir, entry->name);
 		rc = PR_Delete(filename);
 		if (rc != PR_SUCCESS)
@@ -3879,7 +3920,7 @@
 		return CL5_SYSTEM_ERROR;
 	}
 		
-	if (rmDir)
+	if (rmDir && dirisempty)
 	{
 		rc = PR_RmDir (clDir);
 		if (rc != 0)
@@ -3889,6 +3930,10 @@
 					clDir, errno);
 			return CL5_SYSTEM_ERROR;
 		}
+	} else if (rmDir && !dirisempty) {
+		slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, 
+						"_cl5Delete: changelog dir (%s) is not empty - cannot remove\n",
+						clDir);
 	}
 			
 	return CL5_SUCCESS;
@@ -6770,3 +6815,35 @@
 #endif
     return rval;
 }
+
+int
+cl5DbDirIsEmpty(const char *dir)
+{
+	PRDir *prDir;
+	PRDirEntry *prDirEntry;
+	int isempty = 1;
+
+	if (!dir || !*dir) {
+		return isempty;
+	}
+	/* assume failure means it does not exist - other failure
+	   cases will be handled by code which attempts to create the
+	   db in this directory */
+	if (PR_Access(dir, PR_ACCESS_EXISTS)) {
+		return isempty;
+	}
+	prDir = PR_OpenDir(dir);
+	if (prDir == NULL) {
+		return isempty; /* assume failure means does not exist */
+	}
+	while (NULL != (prDirEntry = PR_ReadDir(prDir, PR_SKIP_DOT | PR_SKIP_DOT_DOT))) {
+		if (NULL == prDirEntry->name) {	/* NSPR doesn't behave like the docs say it should */
+			break;
+		}
+		isempty = 0; /* found at least one "real" file */
+		break;
+	}
+	PR_CloseDir(prDir);
+
+	return isempty;
+}


Index: cl5_api.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/replication/cl5_api.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- cl5_api.h	15 Mar 2007 21:40:34 -0000	1.7
+++ cl5_api.h	16 Oct 2007 21:22:47 -0000	1.8
@@ -519,4 +519,13 @@
 int cl5_is_diskfull();
 int cl5_diskspace_is_available();
 
+/* Name: cl5DbDirIsEmpty
+   Description: See if the given cldb directory is empty or doesn't yet exist.
+   Parameters:	dir - Contains the name of the directory.
+   Return:		TRUE - directory does not exist or is empty, is NULL, or is
+                       an empty string
+				FALSE - otherwise
+*/
+int cl5DbDirIsEmpty(const char *dir);
+
 #endif


Index: cl5_config.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/replication/cl5_config.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- cl5_config.c	10 Nov 2006 23:45:17 -0000	1.6
+++ cl5_config.c	16 Oct 2007 21:22:47 -0000	1.7
@@ -205,6 +205,20 @@
 		goto done;	
 	}	
 
+	if (!cl5DbDirIsEmpty(config.dir))
+	{
+		*returncode = 1;
+		if (returntext)
+		{
+			PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
+						"The changelog directory [%s] already exists and is not empty.  "
+						"Please choose a directory that does not exist or is empty.\n",
+						config.dir);
+		}
+		
+		goto done;
+	}
+
 	/* start the changelog */
 	rc = cl5Open (config.dir, &config.dbconfig);
 	if (rc != CL5_SUCCESS)
@@ -450,6 +464,20 @@
 		if (strcmp (currentDir, config.dir) != 0)
 #endif
 		{
+			if (!cl5DbDirIsEmpty(config.dir))
+			{
+				*returncode = 1;
+				if (returntext)
+				{
+					PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
+								"The changelog directory [%s] already exists and is not empty.  "
+								"Please choose a directory that does not exist or is empty.\n",
+								config.dir);
+				}
+
+				goto done;
+			}
+
 			if (!_is_absolutepath(config.dir) || (CL5_SUCCESS != cl5CreateDirIfNeeded(config.dir)))
 			{
 				*returncode = 1;




More information about the Fedora-directory-commits mailing list