devbox@COMPUTEC The Computec development blog

21Jul/100

Coldfusion UDF to create & CHMOD a full directory path

The following problem has come up during a file caching implementation: We've got a directory /var/www/MYCACHE; our filecaching mechanism uses a key-based directory structure to store files there. So let's suppose our key would be 123456789, we'd like to store the file 123456789.cache under /var/www/MYCACHE/123/123456/123456789.cache. This would make sure that no directory needs to hold more than 1,000 nodes.

All would be well if we could be sure that the user jrun (i.e. the user that owns our ColdFusion process) was indeed the only user ever to access this directory structure. In our case we want to be able to access this structure with PHP, too, which runs as mod_php on the webserver, thus as user www-data. To avoid permission problems, we want to assign a permission of 0777 to all directories in the structure upon creation.

You'll need at least JDK 1.6 for this to work:

<cffunction name="createWRXPath" 
	access="public" 
	returntype="boolean" 
	output="no">
 
	<cfargument name="strPath" 
		type="string" 
		required="yes" 
		hint="an absolute physical path 
		to a directory, not a file">
 
	<cfargument name="iMinDepth" 
		type="numeric" 
		required="no" 
		default="4" 
		hint="minimum depth to set permissions">
 
	<cfscript>
 
		var local = structNew();
 
		local.strPath = GetDirectoryFromPath(
			JavaCast('string',arguments.strPath));
 
		local.objFile = CreateObject('java'
			,'java.io.File').init(local.strPath);
 
		if (arguments.iMinDepth gt 4) {
			local.iMinDepth = arguments.iMinDepth;
			} else {
			local.iMinDepth = 4;			
		} // end if (arguments.iMinDepth gt 4)
 
		// create the path
		local.objFile.mkdirs();
 
		// if that hasn't succeeded, return false
		if (not DirectoryExists(local.strPath)) return false;
 
		local.l = ListLen(local.strPath,'/');
 
		local.strPartPath = '/';
 
		// now descend into the path from top down, 
		//   set permissions for every directory lower 
		//  than level iMinDepth
 
		for (local.i=1; local.i lte local.l; local.i++) {
 
			local.strPartPath &= 
				ListGetAt(local.strPath,local.i,'/') & '/';
 
			if (local.i gte local.iMinDepth) {				
				local.objFile = CreateObject('java'
					,'java.io.File').init(
					    local.strPartPath);
 
				local.objFile.setReadable(TRUE,FALSE);				
				local.objFile.setWritable(TRUE,FALSE);
				local.objFile.setExecutable(TRUE,FALSE);
 
			} // end if (local.i gte local.iMinDepth)
 
		} // end for (local.i=1; local.i lte local.l; local.i++)
 
		return TRUE;
 
	</cfscript>
 
</cffunction>

Example for usage:

<cfscript>	
	variables.strFile  = '/var/www/MYCACHE/123/123456/123456789.cache';
	variables.strPath  = GetDirectoryFromPath(variables.strFile);
	variables.bSuccess = createWRXPath(variables.strPath,4);	
	writeOutput(variables.bSuccess);
</cfscript>

Comments (0) Trackbacks (0)

No comments yet.


Leave a comment

(required)

No trackbacks yet.