new: ntfs-3g exit() value is set according to the type of mount error (e.g.
not ntfs, corrupted, access denied, hibernated, unclean journal, etc)master
parent
fc53b9bcb9
commit
a1402b3c3e
|
@ -78,6 +78,21 @@ typedef enum {
|
|||
|
||||
extern int ntfs_check_if_mounted(const char *file, unsigned long *mnt_flags);
|
||||
|
||||
typedef enum {
|
||||
NTFS_VOLUME_OK = 0,
|
||||
NTFS_VOLUME_SYNTAX_ERROR = 11,
|
||||
NTFS_VOLUME_NOT_NTFS = 12,
|
||||
NTFS_VOLUME_CORRUPT = 13,
|
||||
NTFS_VOLUME_HIBERNATED = 14,
|
||||
NTFS_VOLUME_UNCLEAN_UNMOUNT = 15,
|
||||
NTFS_VOLUME_LOCKED = 16,
|
||||
NTFS_VOLUME_RAID = 17,
|
||||
NTFS_VOLUME_UNKNOWN_REASON = 18,
|
||||
NTFS_VOLUME_NO_PRIVILEGE = 19,
|
||||
NTFS_VOLUME_OUT_OF_MEMORY = 20,
|
||||
NTFS_VOLUME_FUSE_ERROR = 21
|
||||
} ntfs_volume_status;
|
||||
|
||||
/**
|
||||
* enum ntfs_volume_state_bits -
|
||||
*
|
||||
|
@ -222,5 +237,7 @@ extern int ntfs_logfile_reset(ntfs_volume *vol);
|
|||
|
||||
extern int ntfs_volume_write_flags(ntfs_volume *vol, const u16 flags);
|
||||
|
||||
extern int ntfs_volume_error(int err);
|
||||
|
||||
#endif /* defined _NTFS_VOLUME_H */
|
||||
|
||||
|
|
|
@ -1484,3 +1484,39 @@ err_out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int ntfs_volume_error(int err)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (err) {
|
||||
case 0:
|
||||
ret = NTFS_VOLUME_OK;
|
||||
break;
|
||||
case EINVAL:
|
||||
ret = NTFS_VOLUME_NOT_NTFS;
|
||||
break;
|
||||
case EIO:
|
||||
ret = NTFS_VOLUME_CORRUPT;
|
||||
break;
|
||||
case EPERM:
|
||||
ret = NTFS_VOLUME_HIBERNATED;
|
||||
break;
|
||||
case EOPNOTSUPP:
|
||||
ret = NTFS_VOLUME_UNCLEAN_UNMOUNT;
|
||||
break;
|
||||
case EBUSY:
|
||||
ret = NTFS_VOLUME_LOCKED;
|
||||
break;
|
||||
case ENXIO:
|
||||
ret = NTFS_VOLUME_RAID;
|
||||
break;
|
||||
case EACCES:
|
||||
ret = NTFS_VOLUME_NO_PRIVILEGE;
|
||||
break;
|
||||
default:
|
||||
ret = NTFS_VOLUME_UNKNOWN_REASON;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -1629,23 +1629,28 @@ static int ntfs_open(const char *device, char *mntpoint)
|
|||
if (ctx->force)
|
||||
flags |= MS_FORCE;
|
||||
|
||||
ctx->vol = utils_mount_volume(device, mntpoint, flags);
|
||||
if (!ctx->vol)
|
||||
return -1;
|
||||
ctx->vol = ntfs_mount(device, flags);
|
||||
if (!ctx->vol) {
|
||||
ntfs_log_perror("Failed to mount '%s'", device);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
ctx->vol->free_clusters = ntfs_attr_get_free_bits(ctx->vol->lcnbmp_na);
|
||||
if (ctx->vol->free_clusters < 0) {
|
||||
ntfs_log_perror("Failed to read NTFS $Bitmap");
|
||||
return -1;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
ctx->vol->free_mft_records = ntfs_get_nr_free_mft_records(ctx->vol);
|
||||
if (ctx->vol->free_mft_records < 0) {
|
||||
ntfs_log_perror("Failed to calculate free MFT records");
|
||||
return -1;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
err_out:
|
||||
return ntfs_volume_error(errno);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *parse_mount_options(const char *orig_opts)
|
||||
|
@ -2227,28 +2232,31 @@ int main(int argc, char *argv[])
|
|||
fuse_fstype fstype = FSTYPE_UNKNOWN;
|
||||
struct stat sbuf;
|
||||
uid_t uid, euid;
|
||||
int err = 10;
|
||||
int err;
|
||||
|
||||
utils_set_locale();
|
||||
ntfs_log_set_handler(ntfs_log_handler_stderr);
|
||||
|
||||
if (parse_options(argc, argv)) {
|
||||
usage();
|
||||
return 1;
|
||||
return NTFS_VOLUME_SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
if (ntfs_fuse_init())
|
||||
return 2;
|
||||
return NTFS_VOLUME_OUT_OF_MEMORY;
|
||||
|
||||
parsed_options = parse_mount_options(opts.options ? opts.options : "");
|
||||
if (!parsed_options)
|
||||
if (!parsed_options) {
|
||||
err = NTFS_VOLUME_SYNTAX_ERROR;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
uid = getuid();
|
||||
euid = geteuid();
|
||||
|
||||
if (setuid(euid)) {
|
||||
ntfs_log_perror("Failed to set user ID to %d", euid);
|
||||
err = NTFS_VOLUME_NO_PRIVILEGE;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
|
@ -2262,13 +2270,15 @@ int main(int argc, char *argv[])
|
|||
|
||||
if (stat(opts.device, &sbuf)) {
|
||||
ntfs_log_perror("Failed to access '%s'", opts.device);
|
||||
err = NTFS_VOLUME_NO_PRIVILEGE;
|
||||
goto err_out;
|
||||
}
|
||||
/* Always use fuseblk for block devices unless it's surely missing. */
|
||||
if (S_ISBLK(sbuf.st_mode) && (fstype != FSTYPE_FUSE))
|
||||
ctx->blkdev = TRUE;
|
||||
|
||||
if (ntfs_open(opts.device, opts.mnt_point))
|
||||
err = ntfs_open(opts.device, opts.mnt_point);
|
||||
if (err)
|
||||
goto err_out;
|
||||
|
||||
if (ctx->blkdev) {
|
||||
|
@ -2278,14 +2288,19 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
fh = mount_fuse(parsed_options);
|
||||
if (!fh)
|
||||
if (!fh) {
|
||||
err = NTFS_VOLUME_FUSE_ERROR;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (setuid(uid)) {
|
||||
ntfs_log_perror("Failed to set user ID to %d", uid);
|
||||
ntfs_log_perror("Failed to drop privilege (uid to %d)", uid);
|
||||
err = NTFS_VOLUME_NO_PRIVILEGE;
|
||||
goto err_umount;
|
||||
}
|
||||
|
||||
ctx->mounted = TRUE;
|
||||
|
||||
#if defined(linux) || defined(__uClinux__)
|
||||
if (S_ISBLK(sbuf.st_mode) && (fstype == FSTYPE_FUSE))
|
||||
ntfs_log_info(fuse26_kmod_msg);
|
||||
|
@ -2317,6 +2332,7 @@ err_umount:
|
|||
fuse_unmount(opts.mnt_point, ctx->fc);
|
||||
fuse_destroy(fh);
|
||||
err_out:
|
||||
utils_mount_error(opts.device, opts.mnt_point, err);
|
||||
ntfs_close();
|
||||
free(ctx);
|
||||
free(parsed_options);
|
||||
|
|
42
src/utils.c
42
src/utils.c
|
@ -84,6 +84,10 @@ static const char *fakeraid_msg =
|
|||
"different device under /dev/mapper/, (e.g. /dev/mapper/nvidia_eahaabcc1)\n"
|
||||
"to mount NTFS. Please see the 'dmraid' documentation for help.\n";
|
||||
|
||||
static const char *access_denied_msg =
|
||||
"Please check the volume and the NTFS-3G binary permissions, the mounting\n"
|
||||
"user and group ID, and the mount options.\n";
|
||||
|
||||
static const char *forced_mount_msg =
|
||||
"\n"
|
||||
" mount -t ntfs-3g %s %s -o force\n"
|
||||
|
@ -109,34 +113,32 @@ int utils_set_locale(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
ntfs_volume *utils_mount_volume(const char *volume, const char *mntpoint,
|
||||
unsigned long flags)
|
||||
void utils_mount_error(const char *volume, const char *mntpoint, int err)
|
||||
{
|
||||
ntfs_volume *vol;
|
||||
|
||||
vol = ntfs_mount(volume, flags);
|
||||
if (!vol) {
|
||||
|
||||
ntfs_log_perror("Failed to mount '%s'", volume);
|
||||
|
||||
if (errno == EINVAL)
|
||||
switch (err) {
|
||||
case NTFS_VOLUME_NOT_NTFS:
|
||||
ntfs_log_error(invalid_ntfs_msg, volume);
|
||||
else if (errno == EIO)
|
||||
break;
|
||||
case NTFS_VOLUME_CORRUPT:
|
||||
ntfs_log_error("%s", corrupt_volume_msg);
|
||||
else if (errno == EPERM)
|
||||
break;
|
||||
case NTFS_VOLUME_HIBERNATED:
|
||||
ntfs_log_error("%s", hibernated_volume_msg);
|
||||
else if (errno == EOPNOTSUPP) {
|
||||
break;
|
||||
case NTFS_VOLUME_UNCLEAN_UNMOUNT:
|
||||
ntfs_log_error(unclean_journal_msg);
|
||||
ntfs_log_error(forced_mount_msg, volume, mntpoint,
|
||||
ntfs_log_error(forced_mount_msg, volume, mntpoint,
|
||||
volume, mntpoint);
|
||||
} else if (errno == EBUSY)
|
||||
break;
|
||||
case NTFS_VOLUME_LOCKED:
|
||||
ntfs_log_error("%s", opened_volume_msg);
|
||||
else if (errno == ENXIO)
|
||||
break;
|
||||
case NTFS_VOLUME_RAID:
|
||||
ntfs_log_error("%s", fakeraid_msg);
|
||||
|
||||
return NULL;
|
||||
break;
|
||||
case NTFS_VOLUME_NO_PRIVILEGE:
|
||||
ntfs_log_error(access_denied_msg, volume);
|
||||
break;
|
||||
}
|
||||
|
||||
return vol;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,8 +32,6 @@ extern const char *ntfs_home;
|
|||
extern const char *ntfs_gpl;
|
||||
|
||||
int utils_set_locale(void);
|
||||
|
||||
ntfs_volume *utils_mount_volume(const char *device, const char *mntpoint,
|
||||
unsigned long flags);
|
||||
void utils_mount_error(const char *vol, const char *mntpoint, int err);
|
||||
|
||||
#endif /* _NTFS_UTILS_H_ */
|
||||
|
|
Loading…
Reference in New Issue