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/libntfs-3g/volume.c b/libntfs-3g/volume.c
index ecacb18..edd7697 100755
--- a/libntfs-3g/volume.c
+++ b/libntfs-3g/volume.c
@@ -54,6 +54,11 @@
#include <locale.h>
#endif
+#if defined(__sun) && defined (__SVR4)
+#include <sys/mnttab.h>
+#endif
+
+#include "param.h"
#include "compat.h"
#include "volume.h"
#include "attrib.h"
@@ -67,10 +72,11 @@
#include "dir.h"
#include "logging.h"
#include "cache.h"
+#include "realpath.h"
#include "misc.h"
const char *ntfs_home =
-"Ntfs-3g news, support and information: http://ntfs-3g.org\n";
+"News, support and information: http://tuxera.com\n";
static const char *invalid_ntfs_msg =
"The device '%s' doesn't seem to have a valid NTFS.\n"
@@ -87,13 +93,9 @@ static const char *corrupt_volume_msg =
"for more details.\n";
static const char *hibernated_volume_msg =
-"The NTFS partition is hibernated. Please resume and shutdown Windows\n"
-"properly, or mount the volume read-only with the 'ro' mount option, or\n"
-"mount the volume read-write with the 'remove_hiberfile' mount option.\n"
-"For example type on the command line:\n"
-"\n"
-" mount -t ntfs-3g -o remove_hiberfile %s %s\n"
-"\n";
+"The NTFS partition is in an unsafe state. Please resume and shutdown\n"
+"Windows fully (no hibernation or fast restarting), or mount the volume\n"
+"read-only with the 'ro' mount option.\n";
static const char *unclean_journal_msg =
"Write access is denied because the disk wasn't safely powered\n"
@@ -113,7 +115,7 @@ static const char *fakeraid_msg =
static const char *access_denied_msg =
"Please check '%s' and the ntfs-3g binary permissions,\n"
"and the mounting user ID. More explanation is provided at\n"
-"http://ntfs-3g.org/support.html#unprivileged\n";
+"http://tuxera.com/community/ntfs-3g-faq/#unprivileged\n";
/**
* ntfs_volume_alloc - Create an NTFS volume object and initialise it
@@ -202,6 +204,7 @@ static int __ntfs_volume_release(ntfs_volume *v)
ntfs_free_lru_caches(v);
free(v->vol_name);
free(v->upcase);
+ if (v->locase) free(v->locase);
free(v->attrdef);
free(v);
@@ -372,6 +375,12 @@ mft_has_no_attr_list:
/* Done with the $Mft mft record. */
ntfs_attr_put_search_ctx(ctx);
ctx = NULL;
+
+ /* Update the size fields in the inode. */
+ vol->mft_ni->data_size = vol->mft_na->data_size;
+ vol->mft_ni->allocated_size = vol->mft_na->allocated_size;
+ set_nino_flag(vol->mft_ni, KnownSize);
+
/*
* The volume is now setup so we can use all read access functions.
*/
@@ -457,7 +466,8 @@ error_exit:
* Return the allocated volume structure on success and NULL on error with
* errno set to the error code.
*/
-ntfs_volume *ntfs_volume_startup(struct ntfs_device *dev, unsigned long flags)
+ntfs_volume *ntfs_volume_startup(struct ntfs_device *dev,
+ ntfs_mount_flags flags)
{
LCN mft_zone_size, mft_lcn;
s64 br;
@@ -481,21 +491,43 @@ ntfs_volume *ntfs_volume_startup(struct ntfs_device *dev, unsigned long flags)
goto error_exit;
/* Create the default upcase table. */
- vol->upcase_len = 65536;
- vol->upcase = ntfs_malloc(vol->upcase_len * sizeof(ntfschar));
- if (!vol->upcase)
+ vol->upcase_len = ntfs_upcase_build_default(&vol->upcase);
+ if (!vol->upcase_len || !vol->upcase)
goto error_exit;
+
+ /* Default with no locase table and case sensitive file names */
+ vol->locase = (ntfschar*)NULL;
+ NVolSetCaseSensitive(vol);
- ntfs_upcase_table_build(vol->upcase,
- vol->upcase_len * sizeof(ntfschar));
-
- if (flags & MS_RDONLY)
+ /* by default, all files are shown and not marked hidden */
+ NVolSetShowSysFiles(vol);
+ NVolSetShowHidFiles(vol);
+ NVolClearHideDotFiles(vol);
+ /* set default compression */
+#if DEFAULT_COMPRESSION
+ NVolSetCompression(vol);
+#else
+ NVolClearCompression(vol);
+#endif
+ if (flags & NTFS_MNT_RDONLY)
NVolSetReadOnly(vol);
/* ...->open needs bracketing to compile with glibc 2.7 */
if ((dev->d_ops->open)(dev, NVolReadOnly(vol) ? O_RDONLY: O_RDWR)) {
- ntfs_log_perror("Error opening '%s'", dev->d_name);
- goto error_exit;
+ if (!NVolReadOnly(vol) && (errno == EROFS)) {
+ if ((dev->d_ops->open)(dev, O_RDONLY)) {
+ ntfs_log_perror("Error opening read-only '%s'",
+ dev->d_name);
+ goto error_exit;
+ } else {
+ ntfs_log_info("Can only open '%s' as read-only\n",
+ dev->d_name);
+ NVolSetReadOnly(vol);
+ }
+ } else {
+ ntfs_log_perror("Error opening '%s'", dev->d_name);
+ goto error_exit;
+ }
}
/* Attach the device to the volume. */
vol->dev = dev;
@@ -630,6 +662,24 @@ static int ntfs_volume_check_logfile(ntfs_volume *vol)
if (!ntfs_check_logfile(na, &rp) || !ntfs_is_logfile_clean(na, rp))
err = EOPNOTSUPP;
+ /*
+ * If the latest restart page was identified as version
+ * 2.0, then Windows may have kept a cached copy of
+ * metadata for fast restarting, and we should not mount.
+ * Hibernation will be seen the same way on a non
+ * Windows-system partition, so we have to use the same
+ * error code (EPERM).
+ * The restart page may also be identified as version 2.0
+ * when access to the file system is terminated abruptly
+ * by unplugging or power cut, so mounting is also rejected
+ * after such an event.
+ */
+ if (rp
+ && (rp->major_ver == const_cpu_to_le16(2))
+ && (rp->minor_ver == const_cpu_to_le16(0))) {
+ ntfs_log_error("Metadata kept in Windows cache, refused to mount.\n");
+ err = EPERM;
+ }
free(rp);
ntfs_attr_close(na);
out:
@@ -743,7 +793,8 @@ int ntfs_volume_check_hiberfile(ntfs_volume *vol, int verbose)
errno = EPERM;
goto out;
}
- if (memcmp(buf, "hibr", 4) == 0) {
+ if ((memcmp(buf, "hibr", 4) == 0)
+ || (memcmp(buf, "HIBR", 4) == 0)) {
if (verbose)
ntfs_log_error("Windows is hibernated, refused to mount.\n");
errno = EPERM;
@@ -837,7 +888,7 @@ static int fix_txf_data(ntfs_volume *vol)
* @flags is an optional second parameter. The same flags are used as for
* the mount system call (man 2 mount). Currently only the following flag
* is implemented:
- * MS_RDONLY - mount volume read-only
+ * NTFS_MNT_RDONLY - mount volume read-only
*
* The function opens the device @dev and verifies that it contains a valid
* bootsector. Then, it allocates an ntfs_volume structure and initializes
@@ -848,7 +899,7 @@ static int fix_txf_data(ntfs_volume *vol)
* Return the allocated volume structure on success and NULL on error with
* errno set to the error code.
*/
-ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
+ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, ntfs_mount_flags flags)
{
s64 l;
ntfs_volume *vol;
@@ -860,6 +911,7 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
VOLUME_INFORMATION *vinf;
ntfschar *vname;
int i, j, eo;
+ unsigned int k;
u32 u;
vol = ntfs_volume_startup(dev, flags);
@@ -1017,6 +1069,17 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
ntfs_log_perror("Failed to close $UpCase");
goto error_exit;
}
+ /* Consistency check of $UpCase, restricted to plain ASCII chars */
+ k = 0x20;
+ while ((k < vol->upcase_len)
+ && (k < 0x7f)
+ && (le16_to_cpu(vol->upcase[k])
+ == ((k < 'a') || (k > 'z') ? k : k + 'A' - 'a')))
+ k++;
+ if (k < 0x7f) {
+ ntfs_log_error("Corrupted file $UpCase\n");
+ goto io_error_exit;
+ }
/*
* Now load $Volume and set the version information and flags in the
@@ -1164,22 +1227,23 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
* Check for dirty logfile and hibernated Windows.
* We care only about read-write mounts.
*/
- if (!(flags & MS_RDONLY)) {
- if (!(flags & MS_IGNORE_HIBERFILE) &&
+ if (!(flags & (NTFS_MNT_RDONLY | NTFS_MNT_FORENSIC))) {
+ if (!(flags & NTFS_MNT_IGNORE_HIBERFILE) &&
ntfs_volume_check_hiberfile(vol, 1) < 0)
goto error_exit;
if (ntfs_volume_check_logfile(vol) < 0) {
- if (!(flags & MS_RECOVER))
+ /* Always reject cached metadata for now */
+ if (!(flags & NTFS_MNT_RECOVER) || (errno == EPERM))
goto error_exit;
ntfs_log_info("The file system wasn't safely "
"closed on Windows. Fixing.\n");
if (ntfs_logfile_reset(vol))
goto error_exit;
}
- }
/* make $TXF_DATA resident if present on the root directory */
- if (!NVolReadOnly(vol) && fix_txf_data(vol))
- goto error_exit;
+ if (fix_txf_data(vol))
+ goto error_exit;
+ }
return vol;
io_error_exit:
@@ -1195,6 +1259,58 @@ error_exit:
return NULL;
}
+/*
+ * Set appropriate flags for showing NTFS metafiles
+ * or files marked as hidden.
+ * Not set in ntfs_mount() to avoid breaking existing tools.
+ */
+
+int ntfs_set_shown_files(ntfs_volume *vol,
+ BOOL show_sys_files, BOOL show_hid_files,
+ BOOL hide_dot_files)
+{
+ int res;
+
+ res = -1;
+ if (vol) {
+ NVolClearShowSysFiles(vol);
+ NVolClearShowHidFiles(vol);
+ NVolClearHideDotFiles(vol);
+ if (show_sys_files)
+ NVolSetShowSysFiles(vol);
+ if (show_hid_files)
+ NVolSetShowHidFiles(vol);
+ if (hide_dot_files)
+ NVolSetHideDotFiles(vol);
+ res = 0;
+ }
+ if (res)
+ ntfs_log_error("Failed to set file visibility\n");
+ return (res);
+}
+
+/*
+ * Set ignore case mode
+ */
+
+int ntfs_set_ignore_case(ntfs_volume *vol)
+{
+ int res;
+
+ res = -1;
+ if (vol && vol->upcase) {
+ vol->locase = ntfs_locase_table_build(vol->upcase,
+ vol->upcase_len);
+ if (vol->locase) {
+ NVolClearCaseSensitive(vol);
+ res = 0;
+ }
+ }
+ if (res)
+ ntfs_log_error("Failed to set ignore_case mode\n");
+ return (res);
+}
+
/**
* ntfs_mount - open ntfs volume
* @name: name of device/file to open
@@ -1206,7 +1322,7 @@ error_exit:
* @flags is an optional second parameter. The same flags are used as for
* the mount system call (man 2 mount). Currently only the following flags
* is implemented:
- * MS_RDONLY - mount volume read-only
+ * NTFS_MNT_RDONLY - mount volume read-only
*
* The function opens the device or file @name and verifies that it contains a
* valid bootsector. Then, it allocates an ntfs_volume structure and initializes
@@ -1221,7 +1337,7 @@ error_exit:
* soon as the function returns.
*/
ntfs_volume *ntfs_mount(const char *name __attribute__((unused)),
- unsigned long flags __attribute__((unused)))
+ ntfs_mount_flags flags __attribute__((unused)))
{
#ifndef NO_NTFS_DEVICE_DEFAULT_IO_OPS
struct ntfs_device *dev;
@@ -1290,18 +1406,6 @@ int ntfs_umount(ntfs_volume *vol, const BOOL force __attribute__((unused)))
#ifdef HAVE_MNTENT_H
-#ifndef HAVE_REALPATH
-/**
- * realpath - If there is no realpath on the system
- */
-static char *realpath(const char *path, char *resolved_path)
-{
- strncpy(resolved_path, path, PATH_MAX);
- resolved_path[PATH_MAX] = '\0';
- return resolved_path;
-}
-#endif
-
/**
* ntfs_mntent_check - desc
*
@@ -1325,16 +1429,17 @@ static int ntfs_mntent_check(const char *file, unsigned long *mnt_flags)
err = errno;
goto exit;
}
- if (!realpath(file, real_file)) {
+ if (!ntfs_realpath_canonicalize(file, real_file)) {
err = errno;
goto exit;
}
- if (!(f = setmntent(MOUNTED, "r"))) {
+ f = setmntent("/proc/mounts", "r");
+ if (!f && !(f = setmntent(MOUNTED, "r"))) {
err = errno;
goto exit;
}
while ((mnt = getmntent(f))) {
- if (!realpath(mnt->mnt_fsname, real_fsname))
+ if (!ntfs_realpath_canonicalize(mnt->mnt_fsname, real_fsname))
continue;
if (!strcmp(real_file, real_fsname))
break;
@@ -1358,6 +1463,60 @@ exit:
}
return 0;
}
+
+#else /* HAVE_MNTENT_H */
+
+#if defined(__sun) && defined (__SVR4)
+
+static int ntfs_mntent_check(const char *file, unsigned long *mnt_flags)
+{
+ struct mnttab *mnt = NULL;
+ char *real_file = NULL, *real_fsname = NULL;
+ FILE *f;
+ int err = 0;
+
+ real_file = (char*)ntfs_malloc(PATH_MAX + 1);
+ if (!real_file)
+ return -1;
+ real_fsname = (char*)ntfs_malloc(PATH_MAX + 1);
+ mnt = (struct mnttab*)ntfs_malloc(MNT_LINE_MAX + 1);
+ if (!real_fsname || !mnt) {
+ err = errno;
+ goto exit;
+ }
+ if (!ntfs_realpath_canonicalize(file, real_file)) {
+ err = errno;
+ goto exit;
+ }
+ if (!(f = fopen(MNTTAB, "r"))) {
+ err = errno;
+ goto exit;
+ }
+ while (!getmntent(f, mnt)) {
+ if (!ntfs_realpath_canonicalize(mnt->mnt_special, real_fsname))
+ continue;
+ if (!strcmp(real_file, real_fsname)) {
+ *mnt_flags = NTFS_MF_MOUNTED;
+ if (!strcmp(mnt->mnt_mountp, "/"))
+ *mnt_flags |= NTFS_MF_ISROOT;
+ if (hasmntopt(mnt, "ro") && !hasmntopt(mnt, "rw"))
+ *mnt_flags |= NTFS_MF_READONLY;
+ break;
+ }
+ }
+ fclose(f);
+exit:
+ free(mnt);
+ free(real_file);
+ free(real_fsname);
+ if (err) {
+ errno = err;
+ return -1;
+ }
+ return 0;
+}
+
+#endif /* defined(__sun) && defined (__SVR4) */
#endif /* HAVE_MNTENT_H */
/**
@@ -1389,7 +1548,7 @@ int ntfs_check_if_mounted(const char *file __attribute__((unused)),
unsigned long *mnt_flags)
{
*mnt_flags = 0;
-#ifdef HAVE_MNTENT_H
+#if defined(HAVE_MNTENT_H) || (defined(__sun) && defined (__SVR4))
return ntfs_mntent_check(file, mnt_flags);
#else
return 0;
@@ -1571,6 +1730,10 @@ int ntfs_volume_error(int err)
ret = NTFS_VOLUME_CORRUPT;
break;
case EPERM:
+ /*
+ * Hibernation and fast restarting are seen the
+ * same way on a non Windows-system partition.
+ */
ret = NTFS_VOLUME_HIBERNATED;
break;
case EOPNOTSUPP:
@@ -1661,3 +1824,113 @@ int ntfs_volume_get_free_space(ntfs_volume *vol)
}
return (ret);
}
+
+/**
+ * ntfs_volume_rename - change the current label on a volume
+ * @vol: volume to change the label on
+ * @label: the new label
+ * @label_len: the length of @label in ntfschars including the terminating NULL
+ * character, which is mandatory (the value can not exceed 128)
+ *
+ * Change the label on the volume @vol to @label.
+ */
+int ntfs_volume_rename(ntfs_volume *vol, const ntfschar *label, int label_len)
+{
+ ntfs_attr *na;
+ char *old_vol_name;
+ char *new_vol_name = NULL;
+ int new_vol_name_len;
+ int err;
+
+ if (NVolReadOnly(vol)) {
+ ntfs_log_error("Refusing to change label on read-only mounted "
+ "volume.\n");
+ errno = EROFS;
+ return -1;
+ }
+
+ label_len *= sizeof(ntfschar);
+ if (label_len > 0x100) {
+ ntfs_log_error("New label is too long. Maximum %u characters "
+ "allowed.\n",
+ (unsigned)(0x100 / sizeof(ntfschar)));
+ errno = ERANGE;
+ return -1;
+ }
+
+ na = ntfs_attr_open(vol->vol_ni, AT_VOLUME_NAME, AT_UNNAMED, 0);
+ if (!na) {
+ if (errno != ENOENT) {
+ err = errno;
+ ntfs_log_perror("Lookup of $VOLUME_NAME attribute "
+ "failed");
+ goto err_out;
+ }
+
+ /* The volume name attribute does not exist. Need to add it. */
+ if (ntfs_attr_add(vol->vol_ni, AT_VOLUME_NAME, AT_UNNAMED, 0,
+ (const u8*) label, label_len))
+ {
+ err = errno;
+ ntfs_log_perror("Encountered error while adding "
+ "$VOLUME_NAME attribute");
+ goto err_out;
+ }
+ }
+ else {
+ s64 written;
+
+ if (NAttrNonResident(na)) {
+ err = errno;
+ ntfs_log_error("Error: Attribute $VOLUME_NAME must be "
+ "resident.\n");
+ goto err_out;
+ }
+
+ if (na->data_size != label_len) {
+ if (ntfs_attr_truncate(na, label_len)) {
+ err = errno;
+ ntfs_log_perror("Error resizing resident "
+ "attribute");
+ goto err_out;
+ }
+ }
+
+ if (label_len) {
+ written = ntfs_attr_pwrite(na, 0, label_len, label);
+ if (written == -1) {
+ err = errno;
+ ntfs_log_perror("Error when writing "
+ "$VOLUME_NAME data");
+ goto err_out;
+ }
+ else if (written != label_len) {
+ err = EIO;
+ ntfs_log_error("Partial write when writing "
+ "$VOLUME_NAME data.");
+ goto err_out;
+
+ }
+ }
+ }
+
+ new_vol_name_len =
+ ntfs_ucstombs(label, label_len, &new_vol_name, 0);
+ if (new_vol_name_len == -1) {
+ err = errno;
+ ntfs_log_perror("Error while decoding new volume name");
+ goto err_out;
+ }
+
+ old_vol_name = vol->vol_name;
+ vol->vol_name = new_vol_name;
+ free(old_vol_name);
+
+ err = 0;
+err_out:
+ if (na)
+ ntfs_attr_close(na);
+ if (err)
+ errno = err;
+ return err ? -1 : 0;
+}