1987da915Sopenharmony_ci/**
2987da915Sopenharmony_ci * ntfs-3g.probe - Probe NTFS volume mountability
3987da915Sopenharmony_ci *
4987da915Sopenharmony_ci * Copyright (c) 2007-2009 Szabolcs Szakacsits
5987da915Sopenharmony_ci *
6987da915Sopenharmony_ci * This program is free software; you can redistribute it and/or modify
7987da915Sopenharmony_ci * it under the terms of the GNU General Public License as published by
8987da915Sopenharmony_ci * the Free Software Foundation; either version 2 of the License, or
9987da915Sopenharmony_ci * (at your option) any later version.
10987da915Sopenharmony_ci *
11987da915Sopenharmony_ci * This program is distributed in the hope that it will be useful,
12987da915Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
13987da915Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14987da915Sopenharmony_ci * GNU General Public License for more details.
15987da915Sopenharmony_ci *
16987da915Sopenharmony_ci * You should have received a copy of the GNU General Public License
17987da915Sopenharmony_ci * along with this program (in the main directory of the NTFS-3G
18987da915Sopenharmony_ci * distribution in the file COPYING); if not, write to the Free Software
19987da915Sopenharmony_ci * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20987da915Sopenharmony_ci */
21987da915Sopenharmony_ci
22987da915Sopenharmony_ci#include "config.h"
23987da915Sopenharmony_ci
24987da915Sopenharmony_ci#ifdef HAVE_STDLIB_H
25987da915Sopenharmony_ci#include <stdlib.h>
26987da915Sopenharmony_ci#endif
27987da915Sopenharmony_ci#ifdef HAVE_STRING_H
28987da915Sopenharmony_ci#include <string.h>
29987da915Sopenharmony_ci#endif
30987da915Sopenharmony_ci#ifdef HAVE_ERRNO_H
31987da915Sopenharmony_ci#include <errno.h>
32987da915Sopenharmony_ci#endif
33987da915Sopenharmony_ci#include <getopt.h>
34987da915Sopenharmony_ci
35987da915Sopenharmony_ci#include "compat.h"
36987da915Sopenharmony_ci#include "volume.h"
37987da915Sopenharmony_ci#include "misc.h"
38987da915Sopenharmony_ci
39987da915Sopenharmony_citypedef enum {
40987da915Sopenharmony_ci	PROBE_UNSET,
41987da915Sopenharmony_ci	PROBE_READONLY,
42987da915Sopenharmony_ci	PROBE_READWRITE
43987da915Sopenharmony_ci} probe_t;
44987da915Sopenharmony_ci
45987da915Sopenharmony_cistatic struct options {
46987da915Sopenharmony_ci	probe_t  probetype;
47987da915Sopenharmony_ci	char	 *device;
48987da915Sopenharmony_ci} opts;
49987da915Sopenharmony_ci
50987da915Sopenharmony_cistatic const char *EXEC_NAME = "ntfs-3g.probe";
51987da915Sopenharmony_ci
52987da915Sopenharmony_cistatic const char *usage_msg =
53987da915Sopenharmony_ci"\n"
54987da915Sopenharmony_ci"%s %s - Probe NTFS volume mountability\n"
55987da915Sopenharmony_ci"\n"
56987da915Sopenharmony_ci"Copyright (C) 2007 Szabolcs Szakacsits\n"
57987da915Sopenharmony_ci"\n"
58987da915Sopenharmony_ci"Usage:    %s <--readonly|--readwrite> <device|image_file>\n"
59987da915Sopenharmony_ci"\n"
60987da915Sopenharmony_ci"Example:  ntfs-3g.probe --readwrite /dev/sda1\n"
61987da915Sopenharmony_ci"\n"
62987da915Sopenharmony_ci"%s";
63987da915Sopenharmony_ci
64987da915Sopenharmony_cistatic int ntfs_open(const char *device)
65987da915Sopenharmony_ci{
66987da915Sopenharmony_ci	ntfs_volume *vol;
67987da915Sopenharmony_ci	unsigned long flags = 0;
68987da915Sopenharmony_ci	int ret = NTFS_VOLUME_OK;
69987da915Sopenharmony_ci
70987da915Sopenharmony_ci	if (opts.probetype == PROBE_READONLY)
71987da915Sopenharmony_ci		flags |= NTFS_MNT_RDONLY;
72987da915Sopenharmony_ci
73987da915Sopenharmony_ci	vol = ntfs_mount(device, flags);
74987da915Sopenharmony_ci	if (!vol)
75987da915Sopenharmony_ci		ret = ntfs_volume_error(errno);
76987da915Sopenharmony_ci
77987da915Sopenharmony_ci	if (ret == 0 && ntfs_umount(vol, FALSE) == -1)
78987da915Sopenharmony_ci		ret = ntfs_volume_error(errno);
79987da915Sopenharmony_ci
80987da915Sopenharmony_ci	return ret;
81987da915Sopenharmony_ci}
82987da915Sopenharmony_ci
83987da915Sopenharmony_cistatic void usage(void)
84987da915Sopenharmony_ci{
85987da915Sopenharmony_ci	ntfs_log_info(usage_msg, EXEC_NAME, VERSION, EXEC_NAME, ntfs_home);
86987da915Sopenharmony_ci}
87987da915Sopenharmony_ci
88987da915Sopenharmony_cistatic int parse_options(int argc, char *argv[])
89987da915Sopenharmony_ci{
90987da915Sopenharmony_ci	int c;
91987da915Sopenharmony_ci
92987da915Sopenharmony_ci	static const char *sopt = "-hrw";
93987da915Sopenharmony_ci	static const struct option lopt[] = {
94987da915Sopenharmony_ci		{ "readonly",	no_argument,	NULL, 'r' },
95987da915Sopenharmony_ci		{ "readwrite",	no_argument,	NULL, 'w' },
96987da915Sopenharmony_ci		{ "help",	no_argument,	NULL, 'h' },
97987da915Sopenharmony_ci		{ NULL,		0,		NULL,  0  }
98987da915Sopenharmony_ci	};
99987da915Sopenharmony_ci
100987da915Sopenharmony_ci	opterr = 0; /* We handle errors. */
101987da915Sopenharmony_ci	opts.probetype = PROBE_UNSET;
102987da915Sopenharmony_ci
103987da915Sopenharmony_ci	while ((c = getopt_long(argc, argv, sopt, lopt, NULL)) != -1) {
104987da915Sopenharmony_ci		switch (c) {
105987da915Sopenharmony_ci		case 1:	/* A non-option argument */
106987da915Sopenharmony_ci			if (!opts.device) {
107987da915Sopenharmony_ci				opts.device = ntfs_malloc(PATH_MAX + 1);
108987da915Sopenharmony_ci				if (!opts.device)
109987da915Sopenharmony_ci					return -1;
110987da915Sopenharmony_ci
111987da915Sopenharmony_ci				strncpy(opts.device, optarg, PATH_MAX);
112987da915Sopenharmony_ci				opts.device[PATH_MAX] = 0;
113987da915Sopenharmony_ci			} else {
114987da915Sopenharmony_ci				ntfs_log_error("%s: You must specify exactly "
115987da915Sopenharmony_ci					       "one device\n", EXEC_NAME);
116987da915Sopenharmony_ci				return -1;
117987da915Sopenharmony_ci			}
118987da915Sopenharmony_ci			break;
119987da915Sopenharmony_ci		case 'h':
120987da915Sopenharmony_ci			usage();
121987da915Sopenharmony_ci			exit(0);
122987da915Sopenharmony_ci		case 'r':
123987da915Sopenharmony_ci			opts.probetype = PROBE_READONLY;
124987da915Sopenharmony_ci			break;
125987da915Sopenharmony_ci		case 'w':
126987da915Sopenharmony_ci			opts.probetype = PROBE_READWRITE;
127987da915Sopenharmony_ci			break;
128987da915Sopenharmony_ci		default:
129987da915Sopenharmony_ci			ntfs_log_error("%s: Unknown option '%s'.\n", EXEC_NAME,
130987da915Sopenharmony_ci				       argv[optind - 1]);
131987da915Sopenharmony_ci			return -1;
132987da915Sopenharmony_ci		}
133987da915Sopenharmony_ci	}
134987da915Sopenharmony_ci
135987da915Sopenharmony_ci	if (!opts.device) {
136987da915Sopenharmony_ci		ntfs_log_error("ERROR: %s: Device is missing\n", EXEC_NAME);
137987da915Sopenharmony_ci		return -1;
138987da915Sopenharmony_ci	}
139987da915Sopenharmony_ci
140987da915Sopenharmony_ci	if (opts.probetype == PROBE_UNSET) {
141987da915Sopenharmony_ci		ntfs_log_error("ERROR: %s: Probe type is missing\n", EXEC_NAME);
142987da915Sopenharmony_ci		return -1;
143987da915Sopenharmony_ci	}
144987da915Sopenharmony_ci
145987da915Sopenharmony_ci	return 0;
146987da915Sopenharmony_ci}
147987da915Sopenharmony_ci
148987da915Sopenharmony_ciint main(int argc, char *argv[])
149987da915Sopenharmony_ci{
150987da915Sopenharmony_ci	int err;
151987da915Sopenharmony_ci
152987da915Sopenharmony_ci	ntfs_log_set_handler(ntfs_log_handler_stderr);
153987da915Sopenharmony_ci
154987da915Sopenharmony_ci	if (parse_options(argc, argv)) {
155987da915Sopenharmony_ci		usage();
156987da915Sopenharmony_ci		exit(NTFS_VOLUME_SYNTAX_ERROR);
157987da915Sopenharmony_ci	}
158987da915Sopenharmony_ci
159987da915Sopenharmony_ci	err = ntfs_open(opts.device);
160987da915Sopenharmony_ci
161987da915Sopenharmony_ci	free(opts.device);
162987da915Sopenharmony_ci	if (err)
163987da915Sopenharmony_ci		exit(err);
164987da915Sopenharmony_ci	return (0);
165987da915Sopenharmony_ci}
166987da915Sopenharmony_ci
167