From a11e2127d5b52df08da06a0d2a511319c5dd6c6c Mon Sep 17 00:00:00 2001
From: andyceo <andyceo@yandex.ru>
Date: Tue, 12 Jun 2012 19:27:54 +0400
Subject: [PATCH] bugfix #1068266 - right permissions on parent folders for
 recursive mkdir

---
 core/includes/file.inc |   41 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 39 insertions(+), 2 deletions(-)

diff --git a/core/includes/file.inc b/core/includes/file.inc
index 133d64f..f0741f6 100644
--- a/core/includes/file.inc
+++ b/core/includes/file.inc
@@ -2322,12 +2322,49 @@ function drupal_mkdir($uri, $mode = NULL, $recursive = FALSE, $context = NULL) {
     $mode = variable_get('file_chmod_directory', 0775);
   }
 
+  // Determine already existing part of $uri, we must not apply chmod for that part.
+  // We need to do so before directories will be created recursively.
+  if ($recursive) {
+    $uri_flat = $uri; // $uri_flat - $uri without schema prefix
+    $uri_existing = '';  // already existing part of $uri (determine later)
+
+    // check the case if $uri with schema
+    $scheme = file_uri_scheme($uri);
+    if ($scheme && file_stream_wrapper_valid_scheme($scheme)) {
+      $uri_flat = drupal_substr($uri, drupal_strlen($scheme) + 3); // +3 mean :// after scheme
+      $uri_existing = $scheme . '://';
+    }
+    $uri_flat = rtrim($uri_flat, '/\\');
+
+    foreach (explode('/', $uri_flat) as $uri_element) {
+      $uri_existing .= $uri_element . '/';
+      if (!is_dir($uri_existing)) { // find first absent directory and then exit
+        $uri_existing = drupal_substr($uri_existing, 0, - 2 - drupal_strlen($uri_element)); // -2 mean slashes
+        $uri_flat = -1; // set the flag
+        break;
+      }
+    }
+  }
+
   if (!isset($context)) {
-    return mkdir($uri, $mode, $recursive);
+    $success = mkdir($uri, $mode, $recursive);
   }
   else {
-    return mkdir($uri, $mode, $recursive, $context);
+    $success = mkdir($uri, $mode, $recursive, $context);
   }
+
+  // Process directories, created recursively, with chmod.
+  // @see http://drupal.org/node/1068266
+  if ($success && $recursive && isset($uri_flat) && $uri_flat == -1) {
+    $uri_flat = drupal_substr($uri, drupal_strlen($uri_existing));
+    $uri_flat = trim($uri_flat, '/\\');
+    foreach (explode('/', $uri_flat) as $uri_element) {
+      $uri_existing .= '/' . $uri_element;
+      drupal_chmod($uri_existing, $mode);
+    }
+  }
+
+  return $success;
 }
 
 /**
-- 
1.7.9.5

