summaryrefslogtreecommitdiff
Diffstat
-rwxr-xr-xAndroid.mk138
-rwxr-xr-xAndroid.mk.bak89
-rwxr-xr-xCREDITS20
-rwxr-xr-xINSTALL200
-rwxr-xr-xMakefile715
-rwxr-xr-xMakefile.am106
-rwxr-xr-xMakefile.in955
-rwxr-xr-xNEWS4
-rwxr-xr-xREADME80
-rwxr-xr-xTODO.ntfsprogs126
-rwxr-xr-xaclocal.m47091
-rwxr-xr-xcompile21
-rwxr-xr-xconfig.guess292
-rw-r--r--[-rwxr-xr-x]config.h165
-rwxr-xr-xconfig.h.in110
-rwxr-xr-xconfig.log3290
-rwxr-xr-xconfig.status1220
-rwxr-xr-xconfig.sub104
-rwxr-xr-xconfigure26448
-rwxr-xr-xconfigure.ac291
-rwxr-xr-xdepcomp87
-rwxr-xr-xinclude/Makefile.in181
-rwxr-xr-xinclude/fuse-lite/Makefile.in112
-rwxr-xr-xinclude/fuse-lite/fuse.h61
-rwxr-xr-xinclude/fuse-lite/fuse_common.h49
-rwxr-xr-xinclude/fuse-lite/fuse_kernel.h6
-rwxr-xr-xinclude/fuse-lite/fuse_lowlevel.h20
-rwxr-xr-xinclude/ntfs-3g/Makefile.am4
-rwxr-xr-xinclude/ntfs-3g/Makefile.in163
-rwxr-xr-xinclude/ntfs-3g/acls.h3
-rwxr-xr-xinclude/ntfs-3g/attrib.h50
-rwxr-xr-xinclude/ntfs-3g/cache.h7
-rwxr-xr-xinclude/ntfs-3g/compat.h6
-rwxr-xr-xinclude/ntfs-3g/compress.h6
-rwxr-xr-xinclude/ntfs-3g/debug.h4
-rwxr-xr-xinclude/ntfs-3g/device.h18
-rwxr-xr-xinclude/ntfs-3g/device_io.h21
-rwxr-xr-xinclude/ntfs-3g/dir.h11
-rwxr-xr-xinclude/ntfs-3g/layout.h32
-rwxr-xr-xinclude/ntfs-3g/lcnalloc.h1
-rwxr-xr-xinclude/ntfs-3g/logging.h3
-rwxr-xr-xinclude/ntfs-3g/mst.h3
-rwxr-xr-xinclude/ntfs-3g/ntfstime.h12
-rwxr-xr-xinclude/ntfs-3g/param.h72
-rwxr-xr-xinclude/ntfs-3g/realpath.h24
-rwxr-xr-xinclude/ntfs-3g/runlist.h3
-rwxr-xr-xinclude/ntfs-3g/security.h20
-rwxr-xr-xinclude/ntfs-3g/types.h8
-rwxr-xr-xinclude/ntfs-3g/unistr.h13
-rwxr-xr-xinclude/ntfs-3g/volume.h78
-rwxr-xr-xinclude/ntfs-3g/xattrs.h75
-rwxr-xr-xinstall-sh5
-rwxr-xr-xlibfuse-lite/Makefile.am3
-rwxr-xr-xlibfuse-lite/Makefile.in188
-rwxr-xr-xlibfuse-lite/fuse.c418
-rwxr-xr-xlibfuse-lite/fuse_kern_chan.c2
-rwxr-xr-xlibfuse-lite/fuse_lowlevel.c53
-rwxr-xr-xlibfuse-lite/fuse_opt.c20
-rwxr-xr-xlibfuse-lite/fuse_session.c12
-rwxr-xr-xlibfuse-lite/fusermount.c97
-rwxr-xr-xlibfuse-lite/helper.c21
-rwxr-xr-xlibfuse-lite/mount.c486
-rwxr-xr-xlibfuse-lite/mount_util.c246
-rwxr-xr-xlibfuse-lite/mount_util.h11
-rwxr-xr-xlibntfs-3g/Makefile.am15
-rwxr-xr-xlibntfs-3g/Makefile.in420
-rwxr-xr-xlibntfs-3g/acls.c219
-rwxr-xr-xlibntfs-3g/attrib.c1205
-rwxr-xr-xlibntfs-3g/bootsect.c4
-rwxr-xr-xlibntfs-3g/cache.c7
-rwxr-xr-xlibntfs-3g/compress.c962
-rwxr-xr-xlibntfs-3g/device.c252
-rwxr-xr-xlibntfs-3g/dir.c374
-rwxr-xr-xlibntfs-3g/efs.c217
-rwxr-xr-xlibntfs-3g/index.c30
-rwxr-xr-xlibntfs-3g/inode.c46
-rwxr-xr-xlibntfs-3g/lcnalloc.c36
-rw-r--r--libntfs-3g/libntfs-3g.pc10
-rw-r--r--libntfs-3g/libntfs-3g.script.so2
-rwxr-xr-xlibntfs-3g/logfile.c23
-rwxr-xr-xlibntfs-3g/logging.c24
-rwxr-xr-xlibntfs-3g/mft.c12
-rwxr-xr-xlibntfs-3g/mst.c24
-rwxr-xr-xlibntfs-3g/object_id.c9
-rwxr-xr-xlibntfs-3g/realpath.c103
-rwxr-xr-xlibntfs-3g/reparse.c67
-rwxr-xr-xlibntfs-3g/runlist.c62
-rwxr-xr-xlibntfs-3g/security.c345
-rwxr-xr-xlibntfs-3g/unistr.c244
-rwxr-xr-xlibntfs-3g/unix_io.c19
-rwxr-xr-xlibntfs-3g/volume.c365
-rwxr-xr-xlibntfs-3g/win32_io.c708
-rwxr-xr-xlibntfs-3g/xattrs.c791
-rwxr-xr-xlibtool9301
-rwxr-xr-xltmain.sh8439
-rwxr-xr-xm4/libtool.m47377
-rwxr-xr-xm4/ltoptions.m4368
-rwxr-xr-xm4/ltsugar.m4123
-rwxr-xr-xm4/ltversion.m423
-rwxr-xr-xm4/lt~obsolete.m492
-rwxr-xr-xmissing49
-rwxr-xr-xntfsprogs/Makefile.am154
-rwxr-xr-xntfsprogs/Makefile.in1199
-rwxr-xr-xntfsprogs/attrdef.c168
-rwxr-xr-xntfsprogs/attrdef.h7
-rwxr-xr-xntfsprogs/boot.c268
-rwxr-xr-xntfsprogs/boot.h7
-rwxr-xr-xntfsprogs/cluster.c118
-rwxr-xr-xntfsprogs/cluster.h39
-rwxr-xr-xntfsprogs/list.h194
-rw-r--r--ntfsprogs/mkntfs.8290
-rwxr-xr-xntfsprogs/mkntfs.8.in290
-rwxr-xr-xntfsprogs/mkntfs.c5177
-rw-r--r--ntfsprogs/ntfscat.8136
-rwxr-xr-xntfsprogs/ntfscat.8.in136
-rwxr-xr-xntfsprogs/ntfscat.c440
-rwxr-xr-xntfsprogs/ntfscat.h46
-rwxr-xr-xntfsprogs/ntfsck.c883
-rw-r--r--ntfsprogs/ntfsclone.8391
-rwxr-xr-xntfsprogs/ntfsclone.8.in391
-rwxr-xr-xntfsprogs/ntfsclone.c2701
-rw-r--r--ntfsprogs/ntfscluster.8124
-rwxr-xr-xntfsprogs/ntfscluster.8.in124
-rwxr-xr-xntfsprogs/ntfscluster.c563
-rwxr-xr-xntfsprogs/ntfscluster.h63
-rw-r--r--ntfsprogs/ntfscmp.877
-rwxr-xr-xntfsprogs/ntfscmp.8.in77
-rwxr-xr-xntfsprogs/ntfscmp.c1012
-rw-r--r--ntfsprogs/ntfscp.8111
-rwxr-xr-xntfsprogs/ntfscp.8.in111
-rwxr-xr-xntfsprogs/ntfscp.c590
-rwxr-xr-xntfsprogs/ntfsdecrypt.c1436
-rwxr-xr-xntfsprogs/ntfsdump_logfile.c779
-rw-r--r--ntfsprogs/ntfsfix.881
-rwxr-xr-xntfsprogs/ntfsfix.8.in81
-rwxr-xr-xntfsprogs/ntfsfix.c1657
-rw-r--r--ntfsprogs/ntfsinfo.889
-rwxr-xr-xntfsprogs/ntfsinfo.8.in89
-rwxr-xr-xntfsprogs/ntfsinfo.c2384
-rw-r--r--ntfsprogs/ntfslabel.8118
-rwxr-xr-xntfsprogs/ntfslabel.8.in118
-rwxr-xr-xntfsprogs/ntfslabel.c458
-rw-r--r--ntfsprogs/ntfsls.8172
-rwxr-xr-xntfsprogs/ntfsls.8.in172
-rwxr-xr-xntfsprogs/ntfsls.c717
-rwxr-xr-xntfsprogs/ntfsmftalloc.c368
-rwxr-xr-xntfsprogs/ntfsmove.c923
-rwxr-xr-xntfsprogs/ntfsmove.h46
-rw-r--r--ntfsprogs/ntfsprogs.869
-rwxr-xr-xntfsprogs/ntfsprogs.8.in69
-rw-r--r--ntfsprogs/ntfsresize.8326
-rwxr-xr-xntfsprogs/ntfsresize.8.in326
-rwxr-xr-xntfsprogs/ntfsresize.c4497
-rwxr-xr-xntfsprogs/ntfstruncate.c809
-rw-r--r--ntfsprogs/ntfsundelete.8324
-rwxr-xr-xntfsprogs/ntfsundelete.8.in324
-rwxr-xr-xntfsprogs/ntfsundelete.c2490
-rwxr-xr-xntfsprogs/ntfsundelete.h112
-rwxr-xr-xntfsprogs/ntfswipe.c2131
-rwxr-xr-xntfsprogs/ntfswipe.h54
-rwxr-xr-xntfsprogs/sd.c607
-rwxr-xr-xntfsprogs/sd.h11
-rwxr-xr-xntfsprogs/utils.c1184
-rwxr-xr-xntfsprogs/utils.h137
-rwxr-xr-xprog.IAB1071
-rwxr-xr-xprog.IAD5
-rwxr-xr-xprog.IMB466
-rwxr-xr-xprog.IMD2
-rwxr-xr-xprog.PFI2
-rwxr-xr-xprog.PO1
-rwxr-xr-xprog.PR14
-rwxr-xr-xprog.PRI219
-rwxr-xr-xprog.PS979
-rwxr-xr-xprog.SearchResults3
-rwxr-xr-xprog.WK39
-rwxr-xr-xsrc/Makefile.am86
-rwxr-xr-xsrc/Makefile.in938
-rwxr-xr-xsrc/lowntfs-3g.c1538
-rw-r--r--src/ntfs-3g.8448
-rwxr-xr-xsrc/ntfs-3g.8.in217
-rwxr-xr-xsrc/ntfs-3g.c1357
-rw-r--r--src/ntfs-3g.probe.881
-rwxr-xr-xsrc/ntfs-3g.probe.8.in4
-rwxr-xr-xsrc/ntfs-3g.probe.c9
-rw-r--r--src/ntfs-3g.secaudit.8184
-rwxr-xr-xsrc/ntfs-3g.secaudit.8.in15
-rw-r--r--src/ntfs-3g.usermap.896
-rwxr-xr-xsrc/ntfs-3g_common.c745
-rwxr-xr-xsrc/ntfs-3g_common.h185
-rwxr-xr-xsrc/secaudit.c673
-rwxr-xr-xsrc/secaudit.h32
-rwxr-xr-xsrc/usermap.c3
-rw-r--r--[-rwxr-xr-x]stamp-h10
193 files changed, 80411 insertions, 44563 deletions
diff --git a/src/ntfs-3g_common.c b/src/ntfs-3g_common.c
new file mode 100755
index 0000000..ca805d6
--- a/dev/null
+++ b/src/ntfs-3g_common.c
@@ -0,0 +1,745 @@
+/**
+ * ntfs-3g_common.c - Common definitions for ntfs-3g and lowntfs-3g.
+ *
+ * Copyright (c) 2010-2012 Jean-Pierre Andre
+ * Copyright (c) 2010 Erik Larsson
+ *
+ * This program/include file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program/include file is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (in the main directory of the NTFS-3G
+ * distribution in the file COPYING); if not, write to the Free Software
+ * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include <getopt.h>
+#include <fuse.h>
+
+#include "inode.h"
+#include "security.h"
+#include "xattrs.h"
+#include "ntfs-3g_common.h"
+#include "realpath.h"
+#include "misc.h"
+
+const char xattr_ntfs_3g[] = "ntfs-3g.";
+
+const char nf_ns_user_prefix[] = "user.";
+const int nf_ns_user_prefix_len = sizeof(nf_ns_user_prefix) - 1;
+const char nf_ns_system_prefix[] = "system.";
+const int nf_ns_system_prefix_len = sizeof(nf_ns_system_prefix) - 1;
+const char nf_ns_security_prefix[] = "security.";
+const int nf_ns_security_prefix_len = sizeof(nf_ns_security_prefix) - 1;
+const char nf_ns_trusted_prefix[] = "trusted.";
+const int nf_ns_trusted_prefix_len = sizeof(nf_ns_trusted_prefix) - 1;
+
+static const char nf_ns_alt_xattr_efsinfo[] = "user.ntfs.efsinfo";
+
+static const char def_opts[] = "allow_other,nonempty,";
+
+ /*
+ * Table of recognized options
+ * Their order may be significant
+ * The options invalid in some configuration should still
+ * be present, so that an error can be returned
+ */
+const struct DEFOPTION optionlist[] = {
+ { "ro", OPT_RO, FLGOPT_APPEND | FLGOPT_BOGUS },
+ { "noatime", OPT_NOATIME, FLGOPT_BOGUS },
+ { "atime", OPT_ATIME, FLGOPT_BOGUS },
+ { "relatime", OPT_RELATIME, FLGOPT_BOGUS },
+ { "delay_mtime", OPT_DMTIME, FLGOPT_DECIMAL | FLGOPT_OPTIONAL },
+ { "fake_rw", OPT_FAKE_RW, FLGOPT_BOGUS },
+ { "fsname", OPT_FSNAME, FLGOPT_NOSUPPORT },
+ { "no_def_opts", OPT_NO_DEF_OPTS, FLGOPT_BOGUS },
+ { "default_permissions", OPT_DEFAULT_PERMISSIONS, FLGOPT_BOGUS },
+ { "permissions", OPT_PERMISSIONS, FLGOPT_BOGUS },
+ { "acl", OPT_ACL, FLGOPT_BOGUS },
+ { "umask", OPT_UMASK, FLGOPT_OCTAL },
+ { "fmask", OPT_FMASK, FLGOPT_OCTAL },
+ { "dmask", OPT_DMASK, FLGOPT_OCTAL },
+ { "uid", OPT_UID, FLGOPT_DECIMAL },
+ { "gid", OPT_GID, FLGOPT_DECIMAL },
+ { "show_sys_files", OPT_SHOW_SYS_FILES, FLGOPT_BOGUS },
+ { "hide_hid_files", OPT_HIDE_HID_FILES, FLGOPT_BOGUS },
+ { "hide_dot_files", OPT_HIDE_DOT_FILES, FLGOPT_BOGUS },
+ { "ignore_case", OPT_IGNORE_CASE, FLGOPT_BOGUS },
+ { "windows_names", OPT_WINDOWS_NAMES, FLGOPT_BOGUS },
+ { "compression", OPT_COMPRESSION, FLGOPT_BOGUS },
+ { "nocompression", OPT_NOCOMPRESSION, FLGOPT_BOGUS },
+ { "silent", OPT_SILENT, FLGOPT_BOGUS },
+ { "recover", OPT_RECOVER, FLGOPT_BOGUS },
+ { "norecover", OPT_NORECOVER, FLGOPT_BOGUS },
+ { "remove_hiberfile", OPT_REMOVE_HIBERFILE, FLGOPT_BOGUS },
+ { "sync", OPT_SYNC, FLGOPT_BOGUS | FLGOPT_APPEND },
+ { "big_writes", OPT_BIG_WRITES, FLGOPT_BOGUS },
+ { "locale", OPT_LOCALE, FLGOPT_STRING },
+ { "nfconv", OPT_NFCONV, FLGOPT_BOGUS },
+ { "nonfconv", OPT_NONFCONV, FLGOPT_BOGUS },
+ { "streams_interface", OPT_STREAMS_INTERFACE, FLGOPT_STRING },
+ { "user_xattr", OPT_USER_XATTR, FLGOPT_BOGUS },
+ { "noauto", OPT_NOAUTO, FLGOPT_BOGUS },
+ { "debug", OPT_DEBUG, FLGOPT_BOGUS },
+ { "no_detach", OPT_NO_DETACH, FLGOPT_BOGUS },
+ { "remount", OPT_REMOUNT, FLGOPT_BOGUS },
+ { "blksize", OPT_BLKSIZE, FLGOPT_STRING },
+ { "inherit", OPT_INHERIT, FLGOPT_BOGUS },
+ { "addsecurids", OPT_ADDSECURIDS, FLGOPT_BOGUS },
+ { "staticgrps", OPT_STATICGRPS, FLGOPT_BOGUS },
+ { "usermapping", OPT_USERMAPPING, FLGOPT_STRING },
+ { "xattrmapping", OPT_XATTRMAPPING, FLGOPT_STRING },
+ { "efs_raw", OPT_EFS_RAW, FLGOPT_BOGUS },
+ { (const char*)NULL, 0, 0 } /* end marker */
+} ;
+
+#define STRAPPEND_MAX_INSIZE 8192
+#define strappend_is_large(x) ((x) > STRAPPEND_MAX_INSIZE)
+
+int ntfs_strappend(char **dest, const char *append)
+{
+ char *p;
+ size_t size_append, size_dest = 0;
+
+ if (!dest)
+ return -1;
+ if (!append)
+ return 0;
+
+ size_append = strlen(append);
+ if (*dest)
+ size_dest = strlen(*dest);
+
+ if (strappend_is_large(size_dest) || strappend_is_large(size_append)) {
+ errno = EOVERFLOW;
+ ntfs_log_perror("%s: Too large input buffer", EXEC_NAME);
+ return -1;
+ }
+
+ p = (char*)realloc(*dest, size_dest + size_append + 1);
+ if (!p) {
+ ntfs_log_perror("%s: Memory realloction failed", EXEC_NAME);
+ return -1;
+ }
+
+ *dest = p;
+ strcpy(*dest + size_dest, append);
+
+ return 0;
+}
+
+/*
+ * Insert an option before ",fsname="
+ * This is for keeping "fsname" as the last option, because on
+ * Solaris device names may contain commas.
+ */
+
+int ntfs_strinsert(char **dest, const char *append)
+{
+ char *p, *q;
+ size_t size_append, size_dest = 0;
+
+ if (!dest)
+ return -1;
+ if (!append)
+ return 0;
+
+ size_append = strlen(append);
+ if (*dest)
+ size_dest = strlen(*dest);
+
+ if (strappend_is_large(size_dest) || strappend_is_large(size_append)) {
+ errno = EOVERFLOW;
+ ntfs_log_perror("%s: Too large input buffer", EXEC_NAME);
+ return -1;
+ }
+
+ p = (char*)malloc(size_dest + size_append + 1);
+ if (!p) {
+ ntfs_log_perror("%s: Memory reallocation failed", EXEC_NAME);
+ return -1;
+ }
+ strcpy(p, *dest);
+ q = strstr(p, ",fsname=");
+ if (q) {
+ strcpy(q, append);
+ q = strstr(*dest, ",fsname=");
+ if (q)
+ strcat(p, q);
+ free(*dest);
+ *dest = p;
+ } else {
+ free(*dest);
+ *dest = p;
+ strcpy(*dest + size_dest, append);
+ }
+ return 0;
+}
+
+static int bogus_option_value(char *val, const char *s)
+{
+ if (val) {
+ ntfs_log_error("'%s' option shouldn't have value.\n", s);
+ return -1;
+ }
+ return 0;
+}
+
+static int missing_option_value(char *val, const char *s)
+{
+ if (!val) {
+ ntfs_log_error("'%s' option should have a value.\n", s);
+ return -1;
+ }
+ return 0;
+}
+
+char *parse_mount_options(ntfs_fuse_context_t *ctx,
+ const struct ntfs_options *popts, BOOL low_fuse)
+{
+ char *options, *s, *opt, *val, *ret = NULL;
+ const char *orig_opts = popts->options;
+ BOOL no_def_opts = FALSE;
+ int default_permissions = 0;
+ int permissions = 0;
+ int acl = 0;
+ int want_permissions = 0;
+ int intarg;
+ const struct DEFOPTION *poptl;
+
+ ctx->secure_flags = 0;
+#ifdef HAVE_SETXATTR /* extended attributes interface required */
+ ctx->efs_raw = FALSE;
+#endif /* HAVE_SETXATTR */
+ ctx->compression = DEFAULT_COMPRESSION;
+ options = strdup(orig_opts ? orig_opts : "");
+ if (!options) {
+ ntfs_log_perror("%s: strdup failed", EXEC_NAME);
+ return NULL;
+ }
+
+ s = options;
+ while (s && *s && (val = strsep(&s, ","))) {
+ opt = strsep(&val, "=");
+ poptl = optionlist;
+ while (poptl->name && strcmp(poptl->name,opt))
+ poptl++;
+ if (poptl->name) {
+ if ((poptl->flags & FLGOPT_BOGUS)
+ && bogus_option_value(val, opt))
+ goto err_exit;
+ if ((poptl->flags & FLGOPT_OCTAL)
+ && (!val
+ || !sscanf(val, "%o", &intarg))) {
+ ntfs_log_error("'%s' option needs an octal value\n",
+ opt);
+ goto err_exit;
+ }
+ if (poptl->flags & FLGOPT_DECIMAL) {
+ if ((poptl->flags & FLGOPT_OPTIONAL) && !val)
+ intarg = 0;
+ else
+ if (!val
+ || !sscanf(val, "%i", &intarg)) {
+ ntfs_log_error("'%s' option "
+ "needs a decimal value\n",
+ opt);
+ goto err_exit;
+ }
+ }
+ if ((poptl->flags & FLGOPT_STRING)
+ && missing_option_value(val, opt))
+ goto err_exit;
+
+ switch (poptl->type) {
+ case OPT_RO :
+ case OPT_FAKE_RW :
+ ctx->ro = TRUE;
+ break;
+ case OPT_NOATIME :
+ ctx->atime = ATIME_DISABLED;
+ break;
+ case OPT_ATIME :
+ ctx->atime = ATIME_ENABLED;
+ break;
+ case OPT_RELATIME :
+ ctx->atime = ATIME_RELATIVE;
+ break;
+ case OPT_DMTIME :
+ if (!intarg)
+ intarg = DEFAULT_DMTIME;
+ ctx->dmtime = intarg*10000000LL;
+ break;
+ case OPT_NO_DEF_OPTS :
+ no_def_opts = TRUE; /* Don't add default options. */
+ ctx->silent = FALSE; /* cancel default silent */
+ break;
+ case OPT_DEFAULT_PERMISSIONS :
+ default_permissions = 1;
+ break;
+ case OPT_PERMISSIONS :
+ permissions = 1;
+ break;
+#if POSIXACLS
+ case OPT_ACL :
+ acl = 1;
+ break;
+#endif
+ case OPT_UMASK :
+ ctx->dmask = ctx->fmask = intarg;
+ want_permissions = 1;
+ break;
+ case OPT_FMASK :
+ ctx->fmask = intarg;
+ want_permissions = 1;
+ break;
+ case OPT_DMASK :
+ ctx->dmask = intarg;
+ want_permissions = 1;
+ break;
+ case OPT_UID :
+ ctx->uid = intarg;
+ want_permissions = 1;
+ break;
+ case OPT_GID :
+ ctx->gid = intarg;
+ want_permissions = 1;
+ break;
+ case OPT_SHOW_SYS_FILES :
+ ctx->show_sys_files = TRUE;
+ break;
+ case OPT_HIDE_HID_FILES :
+ ctx->hide_hid_files = TRUE;
+ break;
+ case OPT_HIDE_DOT_FILES :
+ ctx->hide_dot_files = TRUE;
+ break;
+ case OPT_WINDOWS_NAMES :
+ ctx->windows_names = TRUE;
+ break;
+ case OPT_IGNORE_CASE :
+ if (low_fuse)
+ ctx->ignore_case = TRUE;
+ else {
+ ntfs_log_error("'%s' is an unsupported option.\n",
+ poptl->name);
+ goto err_exit;
+ }
+ break;
+ case OPT_COMPRESSION :
+ ctx->compression = TRUE;
+ break;
+ case OPT_NOCOMPRESSION :
+ ctx->compression = FALSE;
+ break;
+ case OPT_SILENT :
+ ctx->silent = TRUE;
+ break;
+ case OPT_RECOVER :
+ ctx->recover = TRUE;
+ break;
+ case OPT_NORECOVER :
+ ctx->recover = FALSE;
+ break;
+ case OPT_REMOVE_HIBERFILE :
+ ctx->hiberfile = TRUE;
+ break;
+ case OPT_SYNC :
+ ctx->sync = TRUE;
+ break;
+#ifdef FUSE_CAP_BIG_WRITES
+ case OPT_BIG_WRITES :
+ ctx->big_writes = TRUE;
+ break;
+#endif
+ case OPT_LOCALE :
+ ntfs_set_char_encoding(val);
+ break;
+#if defined(__APPLE__) || defined(__DARWIN__)
+#ifdef ENABLE_NFCONV
+ case OPT_NFCONV :
+ if (ntfs_macosx_normalize_filenames(1)) {
+ ntfs_log_error("ntfs_macosx_normalize_filenames(1) failed!\n");
+ goto err_exit;
+ }
+ break;
+ case OPT_NONFCONV :
+ if (ntfs_macosx_normalize_filenames(0)) {
+ ntfs_log_error("ntfs_macosx_normalize_filenames(0) failed!\n");
+ goto err_exit;
+ }
+ break;
+#endif /* ENABLE_NFCONV */
+#endif /* defined(__APPLE__) || defined(__DARWIN__) */
+ case OPT_STREAMS_INTERFACE :
+ if (!strcmp(val, "none"))
+ ctx->streams = NF_STREAMS_INTERFACE_NONE;
+ else if (!strcmp(val, "xattr"))
+ ctx->streams = NF_STREAMS_INTERFACE_XATTR;
+ else if (!strcmp(val, "openxattr"))
+ ctx->streams = NF_STREAMS_INTERFACE_OPENXATTR;
+ else if (!low_fuse && !strcmp(val, "windows"))
+ ctx->streams = NF_STREAMS_INTERFACE_WINDOWS;
+ else {
+ ntfs_log_error("Invalid named data streams "
+ "access interface.\n");
+ goto err_exit;
+ }
+ break;
+ case OPT_USER_XATTR :
+ ctx->streams = NF_STREAMS_INTERFACE_XATTR;
+ break;
+ case OPT_NOAUTO :
+ /* Don't pass noauto option to fuse. */
+ break;
+ case OPT_DEBUG :
+ ctx->debug = TRUE;
+ ntfs_log_set_levels(NTFS_LOG_LEVEL_DEBUG);
+ ntfs_log_set_levels(NTFS_LOG_LEVEL_TRACE);
+ break;
+ case OPT_NO_DETACH :
+ ctx->no_detach = TRUE;
+ break;
+ case OPT_REMOUNT :
+ ntfs_log_error("Remounting is not supported at present."
+ " You have to umount volume and then "
+ "mount it once again.\n");
+ goto err_exit;
+ case OPT_BLKSIZE :
+ ntfs_log_info("WARNING: blksize option is ignored "
+ "because ntfs-3g must calculate it.\n");
+ break;
+ case OPT_INHERIT :
+ /*
+ * do not overwrite inherited permissions
+ * in create()
+ */
+ ctx->inherit = TRUE;
+ break;
+ case OPT_ADDSECURIDS :
+ /*
+ * create security ids for files being read
+ * with an individual security attribute
+ */
+ ctx->secure_flags |= (1 << SECURITY_ADDSECURIDS);
+ break;
+ case OPT_STATICGRPS :
+ /*
+ * use static definition of groups
+ * for file access control
+ */
+ ctx->secure_flags |= (1 << SECURITY_STATICGRPS);
+ break;
+ case OPT_USERMAPPING :
+ ctx->usermap_path = strdup(val);
+ if (!ctx->usermap_path) {
+ ntfs_log_error("no more memory to store "
+ "'usermapping' option.\n");
+ goto err_exit;
+ }
+ break;
+#ifdef HAVE_SETXATTR /* extended attributes interface required */
+#ifdef XATTR_MAPPINGS
+ case OPT_XATTRMAPPING :
+ ctx->xattrmap_path = strdup(val);
+ if (!ctx->xattrmap_path) {
+ ntfs_log_error("no more memory to store "
+ "'xattrmapping' option.\n");
+ goto err_exit;
+ }
+ break;
+#endif /* XATTR_MAPPINGS */
+ case OPT_EFS_RAW :
+ ctx->efs_raw = TRUE;
+ break;
+#endif /* HAVE_SETXATTR */
+ case OPT_FSNAME : /* Filesystem name. */
+ /*
+ * We need this to be able to check whether filesystem
+ * mounted or not.
+ * (falling through to default)
+ */
+ default :
+ ntfs_log_error("'%s' is an unsupported option.\n",
+ poptl->name);
+ goto err_exit;
+ }
+ if ((poptl->flags & FLGOPT_APPEND)
+ && (ntfs_strappend(&ret, poptl->name)
+ || ntfs_strappend(&ret, ",")))
+ goto err_exit;
+ } else { /* Probably FUSE option. */
+ if (ntfs_strappend(&ret, opt))
+ goto err_exit;
+ if (val) {
+ if (ntfs_strappend(&ret, "="))
+ goto err_exit;
+ if (ntfs_strappend(&ret, val))
+ goto err_exit;
+ }
+ if (ntfs_strappend(&ret, ","))
+ goto err_exit;
+ }
+ }
+ if (!no_def_opts && ntfs_strappend(&ret, def_opts))
+ goto err_exit;
+ if ((default_permissions || (permissions && !acl))
+ && ntfs_strappend(&ret, "default_permissions,"))
+ goto err_exit;
+ /* The atime options exclude each other */
+ if (ctx->atime == ATIME_RELATIVE && ntfs_strappend(&ret, "relatime,"))
+ goto err_exit;
+ else if (ctx->atime == ATIME_ENABLED && ntfs_strappend(&ret, "atime,"))
+ goto err_exit;
+ else if (ctx->atime == ATIME_DISABLED && ntfs_strappend(&ret, "noatime,"))
+ goto err_exit;
+
+ if (ntfs_strappend(&ret, "fsname="))
+ goto err_exit;
+ if (ntfs_strappend(&ret, popts->device))
+ goto err_exit;
+ if (permissions && !acl)
+ ctx->secure_flags |= (1 << SECURITY_DEFAULT);
+ if (acl)
+ ctx->secure_flags |= (1 << SECURITY_ACL);
+ if (want_permissions)
+ ctx->secure_flags |= (1 << SECURITY_WANTED);
+ if (ctx->ro)
+ ctx->secure_flags &= ~(1 << SECURITY_ADDSECURIDS);
+exit:
+ free(options);
+ return ret;
+err_exit:
+ free(ret);
+ ret = NULL;
+ goto exit;
+}
+
+/**
+ * parse_options - Read and validate the programs command line
+ * Read the command line, verify the syntax and parse the options.
+ *
+ * Return: 0 success, -1 error.
+ */
+int ntfs_parse_options(struct ntfs_options *popts, void (*usage)(void),
+ int argc, char *argv[])
+{
+ int c;
+
+ static const char *sopt = "-o:hnvV";
+ static const struct option lopt[] = {
+ { "options", required_argument, NULL, 'o' },
+ { "help", no_argument, NULL, 'h' },
+ { "no-mtab", no_argument, NULL, 'n' },
+ { "verbose", no_argument, NULL, 'v' },
+ { "version", no_argument, NULL, 'V' },
+ { NULL, 0, NULL, 0 }
+ };
+
+ opterr = 0; /* We'll handle the errors, thank you. */
+
+ while ((c = getopt_long(argc, argv, sopt, lopt, NULL)) != -1) {
+ switch (c) {
+ case 1: /* A non-option argument */
+ if (!popts->device) {
+ popts->device = ntfs_malloc(PATH_MAX + 1);
+ if (!popts->device)
+ return -1;
+
+ /* Canonicalize device name (mtab, etc) */
+ popts->arg_device = optarg;
+ if (!ntfs_realpath_canonicalize(optarg,
+ popts->device)) {
+ ntfs_log_perror("%s: Failed to access "
+ "volume '%s'", EXEC_NAME, optarg);
+ free(popts->device);
+ popts->device = NULL;
+ return -1;
+ }
+ } else if (!popts->mnt_point) {
+ popts->mnt_point = optarg;
+ } else {
+ ntfs_log_error("%s: You must specify exactly one "
+ "device and exactly one mount "
+ "point.\n", EXEC_NAME);
+ return -1;
+ }
+ break;
+ case 'o':
+ if (popts->options)
+ if (ntfs_strappend(&popts->options, ","))
+ return -1;
+ if (ntfs_strappend(&popts->options, optarg))
+ return -1;
+ break;
+ case 'h':
+ usage();
+ exit(9);
+ case 'n':
+ /*
+ * no effect - automount passes it, meaning 'no-mtab'
+ */
+ break;
+ case 'v':
+ /*
+ * We must handle the 'verbose' option even if
+ * we don't use it because mount(8) passes it.
+ */
+ break;
+ case 'V':
+ ntfs_log_info("%s %s %s %d\n", EXEC_NAME, VERSION,
+ FUSE_TYPE, fuse_version());
+ exit(0);
+ default:
+ ntfs_log_error("%s: Unknown option '%s'.\n", EXEC_NAME,
+ argv[optind - 1]);
+ return -1;
+ }
+ }
+
+ if (!popts->device) {
+ ntfs_log_error("%s: No device is specified.\n", EXEC_NAME);
+ return -1;
+ }
+ if (!popts->mnt_point) {
+ ntfs_log_error("%s: No mountpoint is specified.\n", EXEC_NAME);
+ return -1;
+ }
+
+ return 0;
+}
+
+#ifdef HAVE_SETXATTR
+
+int ntfs_fuse_listxattr_common(ntfs_inode *ni, ntfs_attr_search_ctx *actx,
+ char *list, size_t size, BOOL prefixing)
+{
+ int ret = 0;
+ char *to = list;
+#ifdef XATTR_MAPPINGS
+ BOOL accepted;
+ const struct XATTRMAPPING *item;
+#endif /* XATTR_MAPPINGS */
+
+ /* first list the regular user attributes (ADS) */
+ while (!ntfs_attr_lookup(AT_DATA, NULL, 0, CASE_SENSITIVE,
+ 0, NULL, 0, actx)) {
+ char *tmp_name = NULL;
+ int tmp_name_len;
+
+ if (!actx->attr->name_length)
+ continue;
+ tmp_name_len = ntfs_ucstombs(
+ (ntfschar *)((u8*)actx->attr +
+ le16_to_cpu(actx->attr->name_offset)),
+ actx->attr->name_length, &tmp_name, 0);
+ if (tmp_name_len < 0) {
+ ret = -errno;
+ goto exit;
+ }
+ /*
+ * When using name spaces, do not return
+ * security, trusted or system attributes
+ * (filtered elsewhere anyway)
+ * otherwise insert "user." prefix
+ */
+ if (prefixing) {
+ if ((strlen(tmp_name) > sizeof(xattr_ntfs_3g))
+ && !strncmp(tmp_name,xattr_ntfs_3g,
+ sizeof(xattr_ntfs_3g)-1))
+ tmp_name_len = 0;
+ else
+ ret += tmp_name_len
+ + nf_ns_user_prefix_len + 1;
+ } else
+ ret += tmp_name_len + 1;
+ if (size && tmp_name_len) {
+ if ((size_t)ret <= size) {
+ if (prefixing) {
+ strcpy(to, nf_ns_user_prefix);
+ to += nf_ns_user_prefix_len;
+ }
+ strncpy(to, tmp_name, tmp_name_len);
+ to += tmp_name_len;
+ *to = 0;
+ to++;
+ } else {
+ free(tmp_name);
+ ret = -ERANGE;
+ goto exit;
+ }
+ }
+ free(tmp_name);
+ }
+#ifdef XATTR_MAPPINGS
+ /* now append the system attributes mapped to user space */
+ for (item=ni->vol->xattr_mapping; item; item=item->next) {
+ switch (item->xattr) {
+ case XATTR_NTFS_EFSINFO :
+ accepted = ni->vol->efs_raw
+ && (ni->flags & FILE_ATTR_ENCRYPTED);
+ break;
+ case XATTR_NTFS_REPARSE_DATA :
+ accepted = (ni->flags & FILE_ATTR_REPARSE_POINT)
+ != const_cpu_to_le32(0);
+ break;
+// TODO : we are supposed to only return xattrs which are set
+// this is more complex for OBJECT_ID and DOS_NAME
+ default : accepted = TRUE;
+ break;
+ }
+ if (accepted) {
+ ret += strlen(item->name) + 1;
+ if (size) {
+ if ((size_t)ret <= size) {
+ strcpy(to, item->name);
+ to += strlen(item->name);
+ *to++ = 0;
+ } else {
+ ret = -ERANGE;
+ goto exit;
+ }
+ }
+#else /* XATTR_MAPPINGS */
+ /* List efs info xattr for encrypted files */
+ if (ni->vol->efs_raw && (ni->flags & FILE_ATTR_ENCRYPTED)) {
+ ret += sizeof(nf_ns_alt_xattr_efsinfo);
+ if ((size_t)ret <= size) {
+ memcpy(to, nf_ns_alt_xattr_efsinfo,
+ sizeof(nf_ns_alt_xattr_efsinfo));
+ to += sizeof(nf_ns_alt_xattr_efsinfo);
+#endif /* XATTR_MAPPINGS */
+ }
+ }
+exit :
+ return (ret);
+}
+
+#endif /* HAVE_SETXATTR */