From 499e106341ef2e5e964e60870da371bb64d043d1 Mon Sep 17 00:00:00 2001 From: jpandre Date: Sat, 16 Aug 2008 15:17:47 +0000 Subject: [PATCH] Adapted to ntfs-3g.1.2812 --- AUTHORS | 1 + include/ntfs-3g/attrib.h | 3 +- include/ntfs-3g/compat.h | 13 ++- include/ntfs-3g/inode.h | 17 ++-- include/ntfs-3g/volume.h | 4 - libntfs-3g/attrib.c | 31 +++---- libntfs-3g/compat.c | 187 +++++++++++++++++++++++++++++++++++++-- libntfs-3g/index.c | 6 +- libntfs-3g/inode.c | 2 + libntfs-3g/win32_io.c | 4 + src/ntfs-3g.c | 116 +++++++++--------------- 11 files changed, 271 insertions(+), 113 deletions(-) diff --git a/AUTHORS b/AUTHORS index 242aea05..a56a1ef4 100644 --- a/AUTHORS +++ b/AUTHORS @@ -5,6 +5,7 @@ Jean-Pierre Andre Alon Bar-Lev Dominique L Bouix Csaba Henk +Bernhard Kaindl Erik Larsson Alejandro Pulver Szabolcs Szakacsits diff --git a/include/ntfs-3g/attrib.h b/include/ntfs-3g/attrib.h index 7352511b..7425d12c 100644 --- a/include/ntfs-3g/attrib.h +++ b/include/ntfs-3g/attrib.h @@ -186,7 +186,8 @@ struct _ntfs_attr { }; /** - * enum ntfs_attr_state_bits - bits for the state field in the ntfs_attr structure + * enum ntfs_attr_state_bits - bits for the state field in the ntfs_attr + * structure */ typedef enum { NA_Initialized, /* 1: structure is initialized. */ diff --git a/include/ntfs-3g/compat.h b/include/ntfs-3g/compat.h index 74d555cf..148f8b75 100644 --- a/include/ntfs-3g/compat.h +++ b/include/ntfs-3g/compat.h @@ -27,13 +27,20 @@ #include "config.h" #endif -#ifdef WINDOWS - #ifndef HAVE_FFS -#define HAVE_FFS extern int ffs(int i); #endif /* HAVE_FFS */ +#ifndef HAVE_DAEMON +extern int daemon(int nochdir, int noclose); +#endif /* HAVE_DAEMON */ + +#ifndef HAVE_STRSEP +extern char *strsep(char **stringp, const char *delim); +#endif /* HAVE_STRSEP */ + +#ifdef WINDOWS + #define HAVE_STDIO_H /* mimic config.h */ #define HAVE_STDARG_H diff --git a/include/ntfs-3g/inode.h b/include/ntfs-3g/inode.h index fe5f1820..53670779 100644 --- a/include/ntfs-3g/inode.h +++ b/include/ntfs-3g/inode.h @@ -128,12 +128,14 @@ struct _ntfs_inode { inode of the base mft record. */ }; - /* Temp: for directory handling */ - void *private_data; /* ntfs_dt containing this inode */ - int ref_count; - /* Below fields are valid only for base inode. */ - s64 data_size; /* Data size stored in the filename index. */ + + /* + * These two fields are used to sync filename index and guaranteed to be + * correct, however value in index itself maybe wrong (windows itself + * do not update them properly). + */ + s64 data_size; /* Data size of unnamed DATA attribute. */ s64 allocated_size; /* Allocated size stored in the filename index. (NOTE: Equal to allocated size of the unnamed data attribute for normal or @@ -141,6 +143,11 @@ struct _ntfs_inode { of the unnamed data attribute for sparse or compressed files.) */ + /* + * These four fields are copy of relevant fields from + * STANDARD_INFORMATION attribute and used to sync it and FILE_NAME + * attribute in the index. + */ time_t creation_time; time_t last_data_change_time; time_t last_mft_change_time; diff --git a/include/ntfs-3g/volume.h b/include/ntfs-3g/volume.h index fff7f547..bb2bc40c 100644 --- a/include/ntfs-3g/volume.h +++ b/include/ntfs-3g/volume.h @@ -239,10 +239,6 @@ struct _ntfs_volume { struct CACHE_HEADER *legacy_cache; #endif - /* Temp: for directory handling */ - void *private_data; /* ntfs_dir for . */ - void *private_bmp1; /* ntfs_bmp for $MFT/$BITMAP */ - void *private_bmp2; /* ntfs_bmp for $Bitmap */ }; extern ntfs_volume *ntfs_volume_alloc(void); diff --git a/libntfs-3g/attrib.c b/libntfs-3g/attrib.c index 4e7a2bd1..b89e0df6 100644 --- a/libntfs-3g/attrib.c +++ b/libntfs-3g/attrib.c @@ -506,7 +506,7 @@ void ntfs_attr_close(ntfs_attr *na) * @na: ntfs attribute for which to map (part of) a runlist * @vcn: map runlist part containing this vcn * - * Map the part of a runlist containing the @vcn of an the ntfs attribute @na. + * Map the part of a runlist containing the @vcn of the ntfs attribute @na. * * Return 0 on success and -1 on error with errno set to the error code. */ @@ -549,8 +549,8 @@ int ntfs_attr_map_runlist(ntfs_attr *na, VCN vcn) * ntfs_attr_map_whole_runlist - map the whole runlist of an ntfs attribute * @na: ntfs attribute for which to map the runlist * - * Map the whole runlist of an the ntfs attribute @na. For an attribute made - * up of only one attribute extent this is the same as calling + * Map the whole runlist of the ntfs attribute @na. For an attribute made up + * of only one attribute extent this is the same as calling * ntfs_attr_map_runlist(na, 0) but for an attribute with multiple extents this * will map the runlist fragments from each of the extents thus giving access * to the entirety of the disk allocation of an attribute. @@ -2998,7 +2998,7 @@ int ntfs_attr_record_rm(ntfs_attr_search_ctx *ctx) NInoAttrListClearDirty(base_ni); } - /* Free MFT record, if it isn't contain attributes. */ + /* Free MFT record, if it doesn't contain attributes. */ if (le32_to_cpu(ctx->mrec->bytes_in_use) - le16_to_cpu(ctx->mrec->attrs_offset) == 8) { if (ntfs_mft_record_free(ni->vol, ni)) { @@ -3260,9 +3260,9 @@ rm_attr_err_out: (ATTR_RECORD*)((u8*)attr_ni->mrec + offset), 0)) ntfs_log_perror("Failed to remove just added attribute #2"); free_err_out: - /* Free MFT record, if it isn't contain attributes. */ + /* Free MFT record, if it doesn't contain attributes. */ if (le32_to_cpu(attr_ni->mrec->bytes_in_use) - - le32_to_cpu(attr_ni->mrec->attrs_offset) == 8) + le16_to_cpu(attr_ni->mrec->attrs_offset) == 8) if (ntfs_mft_record_free(attr_ni->vol, attr_ni)) ntfs_log_perror("Failed to free MFT record"); err_out: @@ -4325,7 +4325,7 @@ retry: */ first_lcn = ntfs_rl_vcn_to_lcn(na->rl, stop_vcn); if (first_lcn == LCN_EINVAL) { - err = EIO; + errno = EIO; ntfs_log_perror("Bad runlist"); goto put_err_out; } @@ -4349,8 +4349,7 @@ retry: continue; } - err = ntfs_attr_update_meta(a, na, m, ctx); - switch (err) { + switch (ntfs_attr_update_meta(a, na, m, ctx)) { case -1: return -1; case -2: goto retry; case -3: goto put_err_out; @@ -4360,7 +4359,6 @@ retry: mp_size = ntfs_get_size_for_mapping_pairs(na->ni->vol, na->rl, stop_vcn); if (mp_size <= 0) { - err = errno; ntfs_log_perror("%s: get MP size failed", __FUNCTION__); goto put_err_out; } @@ -4419,8 +4417,8 @@ retry: if (ntfs_attr_record_resize(m, a, le16_to_cpu(a->mapping_pairs_offset) + mp_size)) { + errno = EIO; ntfs_log_perror("Failed to resize attribute"); - err = EIO; goto put_err_out; } } @@ -4444,7 +4442,6 @@ retry: stop_vcn, &stop_vcn)) finished_build = TRUE; if (!finished_build && errno != ENOSPC) { - err = errno; ntfs_log_perror("Failed to build mapping pairs"); goto put_err_out; } @@ -4452,7 +4449,6 @@ retry: } /* Check whether error occurred. */ if (errno != ENOENT) { - err = errno; ntfs_log_perror("%s: Attribute lookup failed", __FUNCTION__); goto put_err_out; } @@ -4468,14 +4464,12 @@ retry: continue; /* Remove unused attribute record. */ if (ntfs_attr_record_rm(ctx)) { - err = errno; ntfs_log_perror("Could not remove unused attr"); goto put_err_out; } ntfs_attr_reinit_search_ctx(ctx); } if (errno != ENOENT) { - err = errno; ntfs_log_perror("%s: Attr lookup failed", __FUNCTION__); goto put_err_out; } @@ -4492,14 +4486,12 @@ retry: mp_size = ntfs_get_size_for_mapping_pairs(na->ni->vol, na->rl, stop_vcn); if (mp_size <= 0) { - err = errno; ntfs_log_perror("%s: get mp size failed", __FUNCTION__); goto put_err_out; } /* Allocate new mft record. */ ni = ntfs_mft_record_alloc(na->ni->vol, base_ni); if (!ni) { - err = errno; ntfs_log_perror("Could not allocate new MFT record"); goto put_err_out; } @@ -4524,6 +4516,7 @@ retry: ntfs_log_perror("Could not add attribute extent"); if (ntfs_mft_record_free(na->ni->vol, ni)) ntfs_log_perror("Could not free MFT record"); + errno = err; goto put_err_out; } a = (ATTR_RECORD*)((u8*)m + err); @@ -4536,6 +4529,7 @@ retry: ntfs_log_perror("Failed to build MP"); if (ntfs_mft_record_free(na->ni->vol, ni)) ntfs_log_perror("Couldn't free MFT record"); + errno = err; goto put_err_out; } a->highest_vcn = cpu_to_sle64(stop_vcn - 1); @@ -4551,7 +4545,6 @@ out: put_err_out: if (ctx) ntfs_attr_put_search_ctx(ctx); - errno = err; goto out; } #undef NTFS_VCN_DELETE_MARK @@ -4916,7 +4909,7 @@ rollback: ntfs_log_perror("Couldn't truncate runlist. Rollback failed"); } else { /* Prepare to mapping pairs update. */ - na->allocated_size = org_alloc_size << vol->cluster_size_bits; + na->allocated_size = org_alloc_size; /* Restore mapping pairs. */ if (ntfs_attr_update_mapping_pairs(na, 0 /*na->allocated_size >> vol->cluster_size_bits*/)) { diff --git a/libntfs-3g/compat.c b/libntfs-3g/compat.c index 4d8c41a4..63114a48 100644 --- a/libntfs-3g/compat.c +++ b/libntfs-3g/compat.c @@ -20,16 +20,12 @@ * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef WINDOWS - #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "compat.h" -/* TODO: Add check for FFS in the configure script... (AIA) */ - #ifndef HAVE_FFS /** * ffs - Find the first set bit in an int @@ -69,5 +65,186 @@ int ffs(int x) } #endif /* HAVE_FFS */ -#endif /* WINDOWS */ +#ifndef HAVE_DAEMON +/* ************************************************************ + * From: src.opensolaris.org + * src/lib/libresolv2/common/bsd/daemon.c + */ +/* + * Copyright (c) 1997-2000 by Sun Microsystems, Inc. + * All rights reserved. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static const char sccsid[] = "@(#)daemon.c 8.1 (Berkeley) 6/4/93"; +static const char rcsid[] = "$Id: compat.c,v 1.1.1.1.2.1 2008-08-16 15:17:44 jpandre Exp $"; +#endif /* LIBC_SCCS and not lint */ + +/* + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_FCNTL_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif + +int daemon(int nochdir, int noclose) { + int fd; + + switch (fork()) { + case -1: + return (-1); + case 0: + break; + default: + _exit(0); + } + + if (setsid() == -1) + return (-1); + + if (!nochdir) + (void)chdir("/"); + + if (!noclose && (fd = open("/dev/null", O_RDWR, 0)) != -1) { + (void)dup2(fd, 0); + (void)dup2(fd, 1); + (void)dup2(fd, 2); + if (fd > 2) + (void)close (fd); + } + return (0); +} +/* + * End: src/lib/libresolv2/common/bsd/daemon.c + *************************************************************/ +#endif /* HAVE_DAEMON */ + +#ifndef HAVE_STRSEP +/* ************************************************************ + * From: src.opensolaris.org + * src/lib/libresolv2/common/bsd/strsep.c + */ +/* + * Copyright (c) 1997, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static const char sccsid[] = "strsep.c 8.1 (Berkeley) 6/4/93"; +static const char rcsid[] = "$Id: compat.c,v 1.1.1.1.2.1 2008-08-16 15:17:44 jpandre Exp $"; +#endif /* LIBC_SCCS and not lint */ + +/* + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_STRING_H +#include +#endif +#ifdef HAVE_STDIO_H +#include +#endif + +/* + * Get next token from string *stringp, where tokens are possibly-empty + * strings separated by characters from delim. + * + * Writes NULs into the string at *stringp to end tokens. + * delim need not remain constant from call to call. + * On return, *stringp points past the last NUL written (if there might + * be further tokens), or is NULL (if there are definitely no more tokens). + * + * If *stringp is NULL, strsep returns NULL. + */ +char *strsep(char **stringp, const char *delim) { + char *s; + const char *spanp; + int c, sc; + char *tok; + + if ((s = *stringp) == NULL) + return (NULL); + for (tok = s;;) { + c = *s++; + spanp = delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *stringp = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} + +/* + * End: src/lib/libresolv2/common/bsd/strsep.c + *************************************************************/ +#endif /* HAVE_STRSEP */ diff --git a/libntfs-3g/index.c b/libntfs-3g/index.c index 56c583df..209a39cb 100644 --- a/libntfs-3g/index.c +++ b/libntfs-3g/index.c @@ -1419,21 +1419,21 @@ static int ntfs_ib_split(ntfs_index_context *icx, INDEX_BLOCK *ib) return ret; } - /* JPA static */ int ntfs_ie_add(ntfs_index_context *icx, INDEX_ENTRY *ie) { INDEX_HEADER *ih; int allocated_size, new_size; int ret = STATUS_ERROR; - + +#ifdef DEBUG /* removed by JPA to make function usable for security indexes char *fn; - fn = ntfs_ie_filename_get(ie); ntfs_log_trace("file: '%s'\n", fn); ntfs_attr_name_free(&fn); */ +#endif while (1) { diff --git a/libntfs-3g/inode.c b/libntfs-3g/inode.c index 536b3f39..f5abb197 100644 --- a/libntfs-3g/inode.c +++ b/libntfs-3g/inode.c @@ -275,6 +275,8 @@ err_out: * If it is an extent inode, we disconnect it from its base inode before we * destroy it. * + * It is OK to pass NULL to this function, it is just noop in this case. + * * Return 0 on success or -1 on error with errno set to the error code. On * error, @ni has not been freed. The user should attempt to handle the error * and call ntfs_inode_close() again. The following error codes are defined: diff --git a/libntfs-3g/win32_io.c b/libntfs-3g/win32_io.c index 90a7bda2..ed9fa521 100644 --- a/libntfs-3g/win32_io.c +++ b/libntfs-3g/win32_io.c @@ -52,6 +52,10 @@ typedef struct ntfs_volume ntfs_volume; #include "types.h" #include "device.h" +#ifndef MAX_PATH +#define MAX_PATH 1024 +#endif + #ifndef NTFS_BLOCK_SIZE #define NTFS_BLOCK_SIZE 512 #define NTFS_BLOCK_SIZE_BITS 9 diff --git a/src/ntfs-3g.c b/src/ntfs-3g.c index ec6eafa6..d8c91841 100644 --- a/src/ntfs-3g.c +++ b/src/ntfs-3g.c @@ -75,6 +75,14 @@ #include #endif +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_MKDEV_H +#include +#endif + +#include "compat.h" #include "attrib.h" #include "inode.h" #include "volume.h" @@ -376,18 +384,16 @@ static int ntfs_fuse_getattr(const char *org_path, struct stat *stbuf) int res = 0; ntfs_inode *ni; ntfs_attr *na; - ntfs_volume *vol; char *path = NULL; ntfschar *stream_name; int stream_name_len; struct SECURITY_CONTEXT security; - vol = ctx->vol; stream_name_len = ntfs_fuse_parse_path(org_path, &path, &stream_name); if (stream_name_len < 0) return stream_name_len; memset(stbuf, 0, sizeof(struct stat)); - ni = ntfs_pathname_to_inode(vol, NULL, path); + ni = ntfs_pathname_to_inode(ctx->vol, NULL, path); if (!ni) { res = -errno; goto exit; @@ -630,15 +636,13 @@ static int ntfs_fuse_readdir(const char *path, void *buf, struct fuse_file_info *fi __attribute__((unused))) { ntfs_fuse_fill_context_t fill_ctx; - ntfs_volume *vol; ntfs_inode *ni; s64 pos = 0; int err = 0; - vol = ctx->vol; fill_ctx.filler = filler; fill_ctx.buf = buf; - ni = ntfs_pathname_to_inode(vol, NULL, path); + ni = ntfs_pathname_to_inode(ctx->vol, NULL, path); if (!ni) return -errno; if (ntfs_readdir(ni, &pos, &fill_ctx, @@ -653,7 +657,6 @@ static int ntfs_fuse_readdir(const char *path, void *buf, static int ntfs_fuse_open(const char *org_path, struct fuse_file_info *fi) { - ntfs_volume *vol; ntfs_inode *ni; ntfs_attr *na; int res = 0; @@ -666,8 +669,7 @@ static int ntfs_fuse_open(const char *org_path, stream_name_len = ntfs_fuse_parse_path(org_path, &path, &stream_name); if (stream_name_len < 0) return stream_name_len; - vol = ctx->vol; - ni = ntfs_pathname_to_inode(vol, NULL, path); + ni = ntfs_pathname_to_inode(ctx->vol, NULL, path); if (ni) { na = ntfs_attr_open(ni, AT_DATA, stream_name, stream_name_len); if (na) { @@ -765,7 +767,6 @@ exit: static int ntfs_fuse_write(const char *org_path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi __attribute__((unused))) { - ntfs_volume *vol; ntfs_inode *ni = NULL; ntfs_attr *na = NULL; char *path = NULL; @@ -777,8 +778,7 @@ static int ntfs_fuse_write(const char *org_path, const char *buf, size_t size, res = stream_name_len; goto out; } - vol = ctx->vol; - ni = ntfs_pathname_to_inode(vol, NULL, path); + ni = ntfs_pathname_to_inode(ctx->vol, NULL, path); if (!ni) { res = -errno; goto exit; @@ -789,17 +789,18 @@ static int ntfs_fuse_write(const char *org_path, const char *buf, size_t size, goto exit; } while (size) { - res = ntfs_attr_pwrite(na, offset, size, buf); - if (res < (s64)size) - ntfs_log_perror("ntfs_attr_pwrite partial write (%lld: " - "%lld <> %d)", (long long)offset, (long long)size, res); - if (res <= 0) { + s64 ret = ntfs_attr_pwrite(na, offset, size, buf); + if (0 <= ret && ret < (s64)size) + ntfs_log_perror("ntfs_attr_pwrite partial write to '%s'" + " (%lld: %lld <> %lld)", path, (long long)offset, + (long long)size, ret); + if (ret <= 0) { res = -errno; goto exit; } - size -= res; - offset += res; - total += res; + size -= ret; + offset += ret; + total += ret; } res = total; if (res > 0) @@ -822,7 +823,6 @@ out: static int ntfs_fuse_trunc(const char *org_path, off_t size, BOOL chkwrite) { - ntfs_volume *vol; ntfs_inode *ni = NULL; ntfs_attr *na = NULL; int res; @@ -834,8 +834,7 @@ static int ntfs_fuse_trunc(const char *org_path, off_t size, BOOL chkwrite) stream_name_len = ntfs_fuse_parse_path(org_path, &path, &stream_name); if (stream_name_len < 0) return stream_name_len; - vol = ctx->vol; - ni = ntfs_pathname_to_inode(vol, NULL, path); + ni = ntfs_pathname_to_inode(ctx->vol, NULL, path); if (!ni) goto exit; @@ -1166,29 +1165,7 @@ static int ntfs_fuse_create_stream(const char *path, return res; } -static int ntfs_fuse_create_file(const char *org_path, mode_t mode, - struct fuse_file_info *fi __attribute__((unused))) -{ - char *path = NULL; - ntfschar *stream_name; - int stream_name_len; - int res; - - stream_name_len = ntfs_fuse_parse_path(org_path, &path, &stream_name); - if (stream_name_len < 0) - return stream_name_len; - if (!stream_name_len) - res = ntfs_fuse_create(path, mode, 0, NULL); - else - res = ntfs_fuse_create_stream(path, stream_name, - stream_name_len); - free(path); - if (stream_name_len) - free(stream_name); - return res; -} - -static int ntfs_fuse_mknod(const char *org_path, mode_t mode, dev_t dev) +static int ntfs_fuse_mknod_common(const char *org_path, mode_t mode, dev_t dev) { char *path = NULL; ntfschar *stream_name; @@ -1214,6 +1191,17 @@ exit: return res; } +static int ntfs_fuse_mknod(const char *path, mode_t mode, dev_t dev) +{ + return ntfs_fuse_mknod_common(path, mode, dev); +} + +static int ntfs_fuse_create_file(const char *path, mode_t mode, + struct fuse_file_info *fi __attribute__((unused))) +{ + return ntfs_fuse_mknod_common(path, mode, 0); +} + static int ntfs_fuse_symlink(const char *to, const char *from) { if (ntfs_fuse_is_named_data_stream(from)) @@ -1616,17 +1604,13 @@ static const int nf_ns_xattr_preffix_len = 5; static int ntfs_fuse_listxattr(const char *path, char *list, size_t size) { ntfs_attr_search_ctx *actx = NULL; - ntfs_volume *vol; ntfs_inode *ni; char *to = list; int ret = 0; if (ctx->streams != NF_STREAMS_INTERFACE_XATTR) return -EOPNOTSUPP; - vol = ctx->vol; - if (!vol) - return -ENODEV; - ni = ntfs_pathname_to_inode(vol, NULL, path); + ni = ntfs_pathname_to_inode(ctx->vol, NULL, path); if (!ni) return -errno; actx = ntfs_attr_get_search_ctx(ni, NULL); @@ -1680,17 +1664,13 @@ static int ntfs_fuse_getxattr_windows(const char *path, const char *name, char *value, size_t size) { ntfs_attr_search_ctx *actx = NULL; - ntfs_volume *vol; ntfs_inode *ni; char *to = value; int ret = 0; if (strcmp(name, "ntfs.streams.list")) return -EOPNOTSUPP; - vol = ctx->vol; - if (!vol) - return -ENODEV; - ni = ntfs_pathname_to_inode(vol, NULL, path); + ni = ntfs_pathname_to_inode(ctx->vol, NULL, path); if (!ni) return -errno; actx = ntfs_attr_get_search_ctx(ni, NULL); @@ -1746,7 +1726,6 @@ exit: static int ntfs_fuse_getxattr(const char *path, const char *name, char *value, size_t size) { - ntfs_volume *vol; ntfs_inode *ni; ntfs_attr *na = NULL; ntfschar *lename = NULL; @@ -1759,10 +1738,7 @@ static int ntfs_fuse_getxattr(const char *path, const char *name, if (strncmp(name, nf_ns_xattr_preffix, nf_ns_xattr_preffix_len) || strlen(name) == (size_t)nf_ns_xattr_preffix_len) return -ENODATA; - vol = ctx->vol; - if (!vol) - return -ENODEV; - ni = ntfs_pathname_to_inode(vol, NULL, path); + ni = ntfs_pathname_to_inode(ctx->vol, NULL, path); if (!ni) return -errno; lename_len = ntfs_mbstoucs(name + nf_ns_xattr_preffix_len, &lename); @@ -1796,7 +1772,6 @@ exit: static int ntfs_fuse_setxattr(const char *path, const char *name, const char *value, size_t size, int flags) { - ntfs_volume *vol; ntfs_inode *ni; ntfs_attr *na = NULL; ntfschar *lename = NULL; @@ -1807,10 +1782,7 @@ static int ntfs_fuse_setxattr(const char *path, const char *name, if (strncmp(name, nf_ns_xattr_preffix, nf_ns_xattr_preffix_len) || strlen(name) == (size_t)nf_ns_xattr_preffix_len) return -EACCES; - vol = ctx->vol; - if (!vol) - return -ENODEV; - ni = ntfs_pathname_to_inode(vol, NULL, path); + ni = ntfs_pathname_to_inode(ctx->vol, NULL, path); if (!ni) return -errno; lename_len = ntfs_mbstoucs(name + nf_ns_xattr_preffix_len, &lename); @@ -1854,7 +1826,6 @@ exit: static int ntfs_fuse_removexattr(const char *path, const char *name) { - ntfs_volume *vol; ntfs_inode *ni; ntfschar *lename = NULL; int res = 0, lename_len; @@ -1865,10 +1836,7 @@ static int ntfs_fuse_removexattr(const char *path, const char *name) if (strncmp(name, nf_ns_xattr_preffix, nf_ns_xattr_preffix_len) || strlen(name) == (size_t)nf_ns_xattr_preffix_len) return -ENODATA; - vol = ctx->vol; - if (!vol) - return -ENODEV; - ni = ntfs_pathname_to_inode(vol, NULL, path); + ni = ntfs_pathname_to_inode(ctx->vol, NULL, path); if (!ni) return -errno; lename_len = ntfs_mbstoucs(name + nf_ns_xattr_preffix_len, &lename); @@ -2579,7 +2547,7 @@ static void setup_logging(char *parsed_options) opts.device, (ctx->ro) ? "Read-Only" : "Read-Write", ctx->vol->vol_name, ctx->vol->major_ver, ctx->vol->minor_ver); - ntfs_log_info("Cmdline options: %s\n", opts.options); + ntfs_log_info("Cmdline options: %s\n", opts.options ? opts.options : ""); ntfs_log_info("Mount options: %s\n", parsed_options); } @@ -2645,15 +2613,17 @@ int main(int argc, char *argv[]) if (drop_privs()) goto err_out; #endif - if (stat(opts.device, &sbuf)) { ntfs_log_perror("Failed to access '%s'", opts.device); err = NTFS_VOLUME_NO_PRIVILEGE; goto err_out; } + +#if !(defined(__sun) && defined (__SVR4)) /* Always use fuseblk for block devices unless it's surely missing. */ if (S_ISBLK(sbuf.st_mode) && (fstype != FSTYPE_FUSE)) ctx->blkdev = TRUE; +#endif #ifndef FUSE_INTERNAL if (getuid() && ctx->blkdev) {