Use ftruncate() in samba 3.3. - susmb - mounting of SMB/CIFS shares via FUSE | |
git clone git://git.codemadness.org/susmb | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit c5e4d004aa80f05e98f0e8af1a77849696f76b0c | |
parent d3ac58484d569b375cf84a6dd03fcf0d48cf1725 | |
Author: Geoff Johnstone <[email protected]> | |
Date: Fri, 10 Apr 2009 19:17:59 +0100 | |
Use ftruncate() in samba 3.3. | |
Diffstat: | |
M samba30_compat.c | 38 +++++++++++++++++++++++++++++… | |
M samba32_compat.c | 38 +++++++++++++++++++++++++++++… | |
M samba33_compat.c | 6 ++++++ | |
M samba3x-compat.h | 1 + | |
M usmb_file.c | 70 +++++++++--------------------… | |
5 files changed, 103 insertions(+), 50 deletions(-) | |
--- | |
diff --git a/samba30_compat.c b/samba30_compat.c | |
@@ -26,3 +26,41 @@ int usmb_statfs (const char *path UNUSED, struct statvfs *vf… | |
return -ENOSYS; | |
} | |
+ | |
+int compat_truncate (const char *path UNUSED, SMBCFILE *file, off_t size) | |
+{ | |
+ /* Windows doesn't support truncation so we implement a limited version: | |
+ * 0 == size => create a new file for writing. | |
+ * current size == size => succeed. | |
+ * else return -ENOSYS. | |
+ */ | |
+ | |
+ if (0 == size) | |
+ { | |
+ char *url = make_url (path); | |
+ if (NULL == url) | |
+ return -ENOMEM; | |
+ | |
+ SMBCFILE *file_ = smbc_getFunctionOpen (ctx) (ctx, url, | |
+ O_WRONLY | O_TRUNC, 0); | |
+ if (NULL == file_) | |
+ { | |
+ free_errno (url); | |
+ return -errno; | |
+ } | |
+ | |
+ smbc_getFunctionClose (ctx) (ctx, file_); | |
+ free (url); | |
+ | |
+ return 0; | |
+ } | |
+ | |
+ struct stat st; | |
+ int ret = usmb_getattr (path, &st); | |
+ | |
+ if (0 != ret) | |
+ return ret; | |
+ | |
+ return (size == st.st_size) ? 0 : -ENOSYS; | |
+} | |
+ | |
diff --git a/samba32_compat.c b/samba32_compat.c | |
@@ -41,3 +41,41 @@ int usmb_statfs (const char *path, struct statvfs *vfs) | |
return ret; | |
} | |
+ | |
+int compat_truncate (const char *path UNUSED, SMBCFILE *file, off_t size) | |
+{ | |
+ /* Windows doesn't support truncation so we implement a limited version: | |
+ * 0 == size => create a new file for writing. | |
+ * current size == size => succeed. | |
+ * else return -ENOSYS. | |
+ */ | |
+ | |
+ if (0 == size) | |
+ { | |
+ char *url = make_url (path); | |
+ if (NULL == url) | |
+ return -ENOMEM; | |
+ | |
+ SMBCFILE *file_ = smbc_getFunctionOpen (ctx) (ctx, url, | |
+ O_WRONLY | O_TRUNC, 0); | |
+ if (NULL == file_) | |
+ { | |
+ free_errno (url); | |
+ return -errno; | |
+ } | |
+ | |
+ smbc_getFunctionClose (ctx) (ctx, file_); | |
+ free (url); | |
+ | |
+ return 0; | |
+ } | |
+ | |
+ struct stat st; | |
+ int ret = usmb_getattr (path, &st); | |
+ | |
+ if (0 != ret) | |
+ return ret; | |
+ | |
+ return (size == st.st_size) ? 0 : -ENOSYS; | |
+} | |
+ | |
diff --git a/samba33_compat.c b/samba33_compat.c | |
@@ -41,3 +41,9 @@ int usmb_statfs (const char *path, struct statvfs *vfs) | |
return ret; | |
} | |
+ | |
+int compat_truncate (const char *path UNUSED, SMBCFILE *file, off_t size) | |
+{ | |
+ return (0 > smbc_getFunctionFtruncate (ctx) (ctx, file, size)) ? -errno : 0; | |
+} | |
+ | |
diff --git a/samba3x-compat.h b/samba3x-compat.h | |
@@ -30,6 +30,7 @@ | |
int usmb_statfs (const char *path UNUSED, struct statvfs *vfs UNUSED); | |
+ int compat_truncate (const char *path, SMBCFILE *file, off_t size); | |
#ifndef HAVE_SAMBA32 | |
diff --git a/usmb_file.c b/usmb_file.c | |
@@ -296,49 +296,6 @@ int usmb_utimes (const char *filename, const struct timesp… | |
#endif | |
-int usmb_truncate (const char *filename, off_t offset) | |
-{ | |
- /* Windows doesn't support truncation so we implement a limited version: | |
- * 0 == offset => create a new file for writing. | |
- * current size == offset => succeed. | |
- * else return -ENOSYS. | |
- */ | |
- | |
- DEBUG (fprintf (stderr, "truncate (%s, %llu)\n", filename, offset)); | |
- | |
- if (NULL == filename) | |
- return -EINVAL; | |
- | |
- if (0 == offset) | |
- { | |
- char *url = make_url (filename); | |
- if (NULL == url) | |
- return -ENOMEM; | |
- | |
- SMBCFILE *file = smbc_getFunctionOpen (ctx) (ctx, url, | |
- O_WRONLY | O_TRUNC, 0); | |
- if (NULL == file) | |
- { | |
- free_errno (url); | |
- return -errno; | |
- } | |
- | |
- smbc_getFunctionClose (ctx) (ctx, file); | |
- free (url); | |
- | |
- return 0; | |
- } | |
- | |
- struct stat st; | |
- int ret = usmb_getattr (filename, &st); | |
- | |
- if (0 != ret) | |
- return ret; | |
- | |
- return (offset == st.st_size) ? 0 : -ENOSYS; | |
-} | |
- | |
- | |
int usmb_chmod (const char *filename, mode_t mode) | |
{ | |
char *url = make_url (filename); | |
@@ -352,18 +309,31 @@ int usmb_chmod (const char *filename, mode_t mode) | |
} | |
-#if 0 | |
-// smbc_chown isn't implemented in libsmbclient | |
-int usmb_chown (const char *filename, uid_t owner, uid_t group) | |
+int usmb_truncate (const char *filename, off_t offset) | |
{ | |
char *url = make_url (filename); | |
if (NULL == url) | |
return -ENOMEM; | |
- DEBUG (fprintf (stderr, "chown (%s, %d, %d)\n", url, owner, group)); | |
- int ret = | |
- (0 > smbc_getFunctionChown (ctx) (ctx, url, owner, group)) ? -errno : 0; | |
+ SMBCFILE *file = smbc_getFunctionOpen (ctx) (ctx, url, O_WRONLY, 0); | |
+ if (NULL == file) | |
+ { | |
+ int ret = -errno; | |
+ free (url); | |
+ return ret; | |
+ } | |
+ | |
+ int ret = compat_truncate (filename, file, offset); | |
+ | |
+ smbc_getFunctionClose (ctx) (ctx, file); | |
free (url); | |
return ret; | |
} | |
-#endif | |
+ | |
+ | |
+int usmb_ftruncate (const char *path, off_t size, | |
+ struct fuse_file_info *fi) | |
+{ | |
+ return compat_truncate (path, fd_to_smbcfile (fi->fh), size); | |
+} | |
+ |