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
szaka 2007-12-15 09:17:17 +00:00
parent fc53b9bcb9
commit a1402b3c3e
5 changed files with 105 additions and 36 deletions

View File

@ -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 */

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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_ */