--- ./source3/modules/vfs_shadow_copy2.c.orig 2012-05-28 18:28:43.275895785 +0400 +++ ./source3/modules/vfs_shadow_copy2.c 2012-05-28 19:31:31.776907293 +0400 @@ -486,10 +486,12 @@ if (*relpath == '/') relpath++; if (*baseoffset == '/') baseoffset++; - ret = talloc_asprintf(handle->data, "%s/%s/%s/%s", + ret = talloc_asprintf(handle->data, "%s/%s%s%s%s%s", snapdir, snapshot, - baseoffset, + *baseoffset ? "/" : "", + baseoffset, + *relpath ? "/" : "", relpath); DEBUG(6,("convert_shadow2_name: '%s' -> '%s'\n", fname, ret)); talloc_free(tmp_ctx); @@ -688,9 +690,14 @@ const char *fname) { TALLOC_CTX *tmp_ctx; - const char *snapdir, *baseoffset, *basedir, *gmt_start; + const char *snapdir, *baseoffset, *basedir, *relpath, *gmt_start; size_t baselen; - char *ret; + char *ret, *prefix; + + struct tm timestamp; + time_t timestamp_t; + char snapshot[MAXPATHLEN]; + const char *fmt; DEBUG(10, ("shadow_copy2_connectpath called with %s\n", fname)); @@ -727,6 +734,35 @@ return NULL; } + prefix = talloc_asprintf(tmp_ctx, "%s/@GMT-", snapdir); + if (strncmp(fname, prefix, (talloc_get_size(prefix)-1)) == 0) { + /* this looks like as we have already normalized it, leave it untouched*/ + talloc_free(tmp_ctx); + return talloc_strdup(handle->data, fname); + } + + fmt = lp_parm_const_string(SNUM(handle->conn), "shadow", + "format", SHADOW_COPY2_DEFAULT_FORMAT); + + + ZERO_STRUCT(timestamp); + relpath = strptime(fname, SHADOW_COPY2_GMT_FORMAT, ×tamp); + if (relpath == NULL) { + talloc_free(tmp_ctx); + return NULL; + } + + /* relpath is the remaining portion of the path after the @GMT-xxx */ + + if (lp_parm_bool(SNUM(handle->conn), "shadow", "localtime", + SHADOW_COPY2_DEFAULT_LOCALTIME)) + { + timestamp_t = timegm(×tamp); + localtime_r(×tamp_t, ×tamp); + } + + strftime(snapshot, MAXPATHLEN, fmt, ×tamp); + baselen = strlen(basedir); baseoffset = handle->conn->connectpath + baselen; @@ -743,9 +779,10 @@ if (*baseoffset == '/') baseoffset++; - ret = talloc_asprintf(talloc_tos(), "%s/%.*s/%s", + ret = talloc_asprintf(talloc_tos(), "%s/%s%s%s", snapdir, - GMT_NAME_LEN, fname, + snapshot, + *baseoffset ? "/" : "", baseoffset); DEBUG(6,("shadow_copy2_connectpath: '%s' -> '%s'\n", fname, ret)); TALLOC_FREE(tmp_ctx);