return true;
}
+static bool ad_convert_move_reso(struct adouble *ad,
+ const struct smb_filename *smb_fname)
+{
+ char *map = MAP_FAILED;
+ size_t maplen;
+ ssize_t len;
+ int rc;
+ bool ok;
+
+ if (ad_getentrylen(ad, ADEID_RFORK) == 0) {
+ return true;
+ }
+
+ maplen = ad_getentryoff(ad, ADEID_RFORK) +
+ ad_getentrylen(ad, ADEID_RFORK);
+
+ /* FIXME: direct use of mmap(), vfs_aio_fork does it too */
+ map = mmap(NULL, maplen, PROT_READ|PROT_WRITE, MAP_SHARED,
+ ad->ad_fd, 0);
+ if (map == MAP_FAILED) {
+ DBG_ERR("mmap AppleDouble: %s\n", strerror(errno));
+ return false;
+ }
+
+
+ memmove(map + ADEDOFF_RFORK_DOT_UND,
+ map + ad_getentryoff(ad, ADEID_RFORK),
+ ad_getentrylen(ad, ADEID_RFORK));
+
+ rc = munmap(map, maplen);
+ if (rc != 0) {
+ DBG_ERR("munmap failed: %s\n", strerror(errno));
+ return false;
+ }
+
+ ad_setentryoff(ad, ADEID_RFORK, ADEDOFF_RFORK_DOT_UND);
+
+ ok = ad_pack(ad);
+ if (!ok) {
+ DBG_WARNING("ad_pack [%s] failed\n", smb_fname->base_name);
+ return false;
+ }
+
+ len = sys_pwrite(ad->ad_fd, ad->ad_data, AD_DATASZ_DOT_UND, 0);
+ if (len != AD_DATASZ_DOT_UND) {
+ DBG_ERR("%s: bad size: %zd\n", smb_fname->base_name, len);
+ return false;
+ }
+
+ return true;
+}
+
static bool ad_convert_xattr(struct adouble *ad,
const struct smb_filename *smb_fname,
- char *map)
+ bool *converted_xattr)
{
static struct char_mappings **string_replace_cmaps = NULL;
+ char *map = MAP_FAILED;
+ size_t maplen;
uint16_t i;
+ ssize_t len;
int saved_errno = 0;
NTSTATUS status;
+ int rc;
+ bool ok;
- if (ad->adx_header.adx_num_attrs == 0) {
+ *converted_xattr = false;
+
+ if (ad_getentrylen(ad, ADEID_FINDERI) == ADEDLEN_FINDERI) {
return true;
}
TALLOC_FREE(mappings);
}
+ maplen = ad_getentryoff(ad, ADEID_RFORK) +
+ ad_getentrylen(ad, ADEID_RFORK);
+
+ /* FIXME: direct use of mmap(), vfs_aio_fork does it too */
+ map = mmap(NULL, maplen, PROT_READ|PROT_WRITE, MAP_SHARED,
+ ad->ad_fd, 0);
+ if (map == MAP_FAILED) {
+ DBG_ERR("mmap AppleDouble: %s\n", strerror(errno));
+ return false;
+ }
+
for (i = 0; i < ad->adx_header.adx_num_attrs; i++) {
struct ad_xattr_entry *e = &ad->adx_entries[i];
char *mapped_name = NULL;
!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED))
{
DBG_ERR("string_replace_allocate failed\n");
- return -1;
+ ok = false;
+ goto fail;
}
tmp = mapped_name;
mapped_name = talloc_asprintf(talloc_tos(), ":%s", tmp);
TALLOC_FREE(tmp);
if (mapped_name == NULL) {
- return -1;
+ ok = false;
+ goto fail;
}
stream_name = synthetic_smb_fname(talloc_tos(),
TALLOC_FREE(mapped_name);
if (stream_name == NULL) {
DBG_ERR("synthetic_smb_fname failed\n");
- return -1;
+ ok = false;
+ goto fail;
}
DBG_DEBUG("stream_name: %s\n", smb_fname_str_dbg(stream_name));
TALLOC_FREE(stream_name);
if (!NT_STATUS_IS_OK(status)) {
DBG_ERR("SMB_VFS_CREATE_FILE failed\n");
- return -1;
+ ok = false;
+ goto fail;
}
nwritten = SMB_VFS_PWRITE(fsp,
saved_errno = errno;
close_file(NULL, fsp, ERROR_CLOSE);
errno = saved_errno;
- return -1;
+ ok = false;
+ goto fail;
}
status = close_file(NULL, fsp, NORMAL_CLOSE);
if (!NT_STATUS_IS_OK(status)) {
- return -1;
+ ok = false;
+ goto fail;
}
fsp = NULL;
}
ad_setentrylen(ad, ADEID_FINDERI, ADEDLEN_FINDERI);
- return true;
+
+ ok = ad_pack(ad);
+ if (!ok) {
+ DBG_WARNING("ad_pack [%s] failed\n", smb_fname->base_name);
+ goto fail;
+ }
+
+ len = sys_pwrite(ad->ad_fd, ad->ad_data, AD_DATASZ_DOT_UND, 0);
+ if (len != AD_DATASZ_DOT_UND) {
+ DBG_ERR("%s: bad size: %zd\n", smb_fname->base_name, len);
+ ok = false;
+ goto fail;
+ }
+
+ ok = ad_convert_move_reso(ad, smb_fname);
+ if (!ok) {
+ goto fail;
+ }
+
+ *converted_xattr = true;
+ ok = true;
+
+fail:
+ rc = munmap(map, maplen);
+ if (rc != 0) {
+ DBG_ERR("munmap failed: %s\n", strerror(errno));
+ return false;
+ }
+
+ return ok;
}
static bool ad_convert_finderinfo(struct adouble *ad,
ssize_t nwritten;
NTSTATUS status;
int saved_errno = 0;
+ int cmp;
+
+ cmp = memcmp(ad->ad_filler, AD_FILLER_TAG_OSX, ADEDLEN_FILLER);
+ if (cmp != 0) {
+ return true;
+ }
p_ad = ad_get_entry(ad, ADEID_FINDERI);
if (p_ad == NULL) {
return true;
}
-static bool ad_convert_move_reso(struct adouble *ad,
- const struct smb_filename *smb_fname,
- char *map)
-{
- if (ad_getentrylen(ad, ADEID_RFORK) == 0) {
- return true;
- }
-
- memmove(map + ad_getentryoff(ad, ADEID_FINDERI) + ADEDLEN_FINDERI,
- map + ad_getentryoff(ad, ADEID_RFORK),
- ad_getentrylen(ad, ADEID_RFORK));
-
- ad_setentryoff(ad, ADEID_RFORK,
- ad_getentryoff(ad, ADEID_FINDERI) + ADEDLEN_FINDERI);
-
- return true;
-}
-
/**
* Convert from Apple's ._ file to Netatalk
*
static int ad_convert(struct adouble *ad,
const struct smb_filename *smb_fname)
{
- int rc = 0;
- char *map = MAP_FAILED;
- size_t origlen;
- ssize_t len;
bool ok;
+ bool converted_xattr = false;
- if (ad_getentrylen(ad, ADEID_FINDERI) == ADEDLEN_FINDERI) {
- return 0;
- }
-
- origlen = ad_getentryoff(ad, ADEID_RFORK) +
- ad_getentrylen(ad, ADEID_RFORK);
-
- /* FIXME: direct use of mmap(), vfs_aio_fork does it too */
- map = mmap(NULL, origlen, PROT_READ|PROT_WRITE, MAP_SHARED,
- ad->ad_fd, 0);
- if (map == MAP_FAILED) {
- DEBUG(2, ("mmap AppleDouble: %s\n", strerror(errno)));
- return -1;
- }
-
- ok = ad_convert_xattr(ad, smb_fname, map);
- if (!ok) {
- munmap(map, origlen);
- return -1;
- }
-
- ok = ad_convert_move_reso(ad, smb_fname, map);
+ ok = ad_convert_xattr(ad, smb_fname, &converted_xattr);
if (!ok) {
- munmap(map, origlen);
return -1;
}
- ok = ad_convert_truncate(ad, smb_fname);
- if (!ok) {
- munmap(map, origlen);
- return -1;
- }
-
- rc = munmap(map, origlen);
- if (rc != 0) {
- DBG_ERR("munmap failed: %s\n", strerror(errno));
- return -1;
- }
-
- ok = ad_pack(ad);
- if (!ok) {
- DBG_WARNING("ad_pack [%s] failed\n", smb_fname->base_name);
- return -1;
- }
-
- len = sys_pwrite(ad->ad_fd, ad->ad_data, AD_DATASZ_DOT_UND, 0);
- if (len != AD_DATASZ_DOT_UND) {
- DBG_ERR("%s: bad size: %zd\n", smb_fname->base_name, len);
- return -1;
+ if (converted_xattr) {
+ ok = ad_convert_truncate(ad, smb_fname);
+ if (!ok) {
+ return -1;
+ }
}
ok = ad_convert_finderinfo(ad, smb_fname);