Merge pull request #41 from wulf7/master
Thanks for your work! Looks good to me.
This commit is contained in:
commit
a7ab64c7e4
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash
|
||||
#!/bin/sh
|
||||
|
||||
# exit on errors
|
||||
set -e
|
||||
|
|
32
configure.ac
32
configure.ac
|
@ -38,7 +38,7 @@ PKG_CHECK_MODULES(
|
|||
dnl Configurable temporary directory
|
||||
AC_ARG_WITH(
|
||||
[tmpdir],
|
||||
[AS_HELP_STRING([--with-tmpdir@<:=DIR@:>@],
|
||||
[AS_HELP_STRING([--with-tmpdir=DIR],
|
||||
[Directory for temporary files, defaults to /tmp])],
|
||||
[tmpdir="$withval"],
|
||||
[tmpdir="/tmp"]
|
||||
|
@ -49,6 +49,35 @@ AC_DEFINE_UNQUOTED(
|
|||
[Directory for temporary files]
|
||||
)
|
||||
|
||||
dnl Configurable USB device path
|
||||
case $os_name in
|
||||
Linux)
|
||||
usb_devpath="/dev/bus/usb/%u/%u"
|
||||
;;
|
||||
FreeBSD)
|
||||
usb_devpath="/dev/usb/%u.%u.0"
|
||||
;;
|
||||
*)
|
||||
usb_devpath="%u/%u"
|
||||
;;
|
||||
esac
|
||||
AC_ARG_WITH(
|
||||
[usbdev],
|
||||
[AS_HELP_STRING([--with-usbdev=FILE],
|
||||
[USB device path. String in sscanf() format])],
|
||||
[usb_devpath="$withval"],
|
||||
[]
|
||||
)
|
||||
if test "x$usb_devpath" != "x%u/%u"; then
|
||||
AC_DEFINE_UNQUOTED(
|
||||
[USB_DEVPATH],
|
||||
["$usb_devpath"],
|
||||
[USB device path format string]
|
||||
)
|
||||
else
|
||||
AC_MSG_WARN([Mounting by real device path is not supported. Fallback to <bus>/<device> notation]);
|
||||
fi
|
||||
|
||||
AC_OUTPUT([
|
||||
makefile
|
||||
src/makefile
|
||||
|
@ -62,6 +91,7 @@ AC_MSG_NOTICE([
|
|||
|
||||
prefix: ${prefix}
|
||||
tmpdir: ${tmpdir}
|
||||
usbdev: ${usb_devpath}
|
||||
|
||||
Now type 'make' to build $PACKAGE
|
||||
])
|
||||
|
|
|
@ -30,7 +30,7 @@ print version
|
|||
.SS "SIMPLE-MTPFS options:"
|
||||
.TP
|
||||
\fB\-l\fR \fB\-\-list\-devices\fR
|
||||
list available MTP devices
|
||||
list available MTP devices. Supports \fB<device>\fR option
|
||||
.TP
|
||||
\fB\-\-device\fR
|
||||
select device no. to mount
|
||||
|
|
|
@ -161,18 +161,14 @@ SMTPFileSystem::SMTPFileSystemOptions::SMTPFileSystemOptions()
|
|||
, m_enable_move(false)
|
||||
, m_list_devices(false)
|
||||
, m_device_no(1)
|
||||
#ifdef HAVE_LIBUSB1
|
||||
, m_device_file(nullptr)
|
||||
#endif // HAVE_LIBUSB1
|
||||
, m_mount_point(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
SMTPFileSystem::SMTPFileSystemOptions::~SMTPFileSystemOptions()
|
||||
{
|
||||
#ifdef HAVE_LIBUSB1
|
||||
free(static_cast<void*>(m_device_file));
|
||||
#endif // HAVE_LIBUSB1
|
||||
free(static_cast<void*>(m_mount_point));
|
||||
}
|
||||
|
||||
|
@ -184,22 +180,16 @@ int SMTPFileSystem::SMTPFileSystemOptions::opt_proc(void *data, const char *arg,
|
|||
SMTPFileSystemOptions *options = static_cast<SMTPFileSystemOptions*>(data);
|
||||
|
||||
if (key == FUSE_OPT_KEY_NONOPT) {
|
||||
#ifdef HAVE_LIBUSB1
|
||||
if (options->m_mount_point && !options->m_device_file) {
|
||||
options->m_device_file = options->m_mount_point;
|
||||
options->m_mount_point = nullptr;
|
||||
} else if (options->m_mount_point && options->m_device_file) {
|
||||
if (options->m_mount_point && options->m_device_file) {
|
||||
// Unknown positional argument supplied
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if (options->m_mount_point) {
|
||||
// Unknown positional argument supplied
|
||||
return -1;
|
||||
if (options->m_device_file) {
|
||||
fuse_opt_add_opt(&options->m_mount_point, arg);
|
||||
return 0;
|
||||
}
|
||||
#endif //HAVE_LIBUSB1
|
||||
|
||||
fuse_opt_add_opt(&options->m_mount_point, arg);
|
||||
fuse_opt_add_opt(&options->m_device_file, arg);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
@ -298,6 +288,11 @@ bool SMTPFileSystem::parseOptions(int argc, char **argv)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (m_options.m_device_file && !m_options.m_mount_point) {
|
||||
m_options.m_mount_point = m_options.m_device_file;
|
||||
m_options.m_device_file = nullptr;
|
||||
}
|
||||
|
||||
if (!m_options.m_mount_point) {
|
||||
logerr("Mount point missing.\n");
|
||||
m_options.m_good = false;
|
||||
|
@ -314,13 +309,11 @@ bool SMTPFileSystem::parseOptions(int argc, char **argv)
|
|||
|
||||
--m_options.m_device_no;
|
||||
|
||||
#ifdef HAVE_LIBUSB1
|
||||
// device file and -- device are mutually exclusive, fail if both set
|
||||
if (m_options.m_device_no && m_options.m_device_file) {
|
||||
m_options.m_good = false;
|
||||
return false;
|
||||
}
|
||||
#endif // HAVE_LIBUSB1
|
||||
|
||||
m_options.m_good = true;
|
||||
return true;
|
||||
|
@ -332,17 +325,14 @@ void SMTPFileSystem::printHelp() const
|
|||
struct fuse_operations tmp_operations;
|
||||
memset(&tmp_operations, 0, sizeof(tmp_operations));
|
||||
std::cerr << "usage: " << smtpfs_basename(m_args.argv[0])
|
||||
#ifdef HAVE_LIBUSB1
|
||||
<< " <source>"
|
||||
#endif // HAVE_LIBUSB1
|
||||
<< " mountpoint [options]\n\n"
|
||||
<< " <source> mountpoint [options]\n\n"
|
||||
<< "general options:\n"
|
||||
<< " -o opt,[opt...] mount options\n"
|
||||
<< " -h --help print help\n"
|
||||
<< " -V --version print version\n\n"
|
||||
<< "simple-mtpfs options:\n"
|
||||
<< " -v --verbose verbose output, implies -f\n"
|
||||
<< " -l --list-devices print available devices\n"
|
||||
<< " -l --list-devices print available devices. Supports <source> option\n"
|
||||
<< " --device select a device number to mount\n"
|
||||
<< " -o enable-move enable the move operations\n\n";
|
||||
fuse_opt_add_arg(&args, m_args.argv[0]);
|
||||
|
@ -366,7 +356,9 @@ void SMTPFileSystem::printVersion() const
|
|||
|
||||
bool SMTPFileSystem::listDevices() const
|
||||
{
|
||||
return MTPDevice::listDevices(m_options.m_verbose);
|
||||
const std::string dev_file = m_options.m_device_file ? m_options.m_device_file : "";
|
||||
|
||||
return MTPDevice::listDevices(m_options.m_verbose, dev_file);
|
||||
}
|
||||
|
||||
bool SMTPFileSystem::exec()
|
||||
|
@ -387,14 +379,11 @@ bool SMTPFileSystem::exec()
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBUSB1
|
||||
if (m_options.m_device_file) {
|
||||
// Try to use device file first, if provided
|
||||
if (!m_device.connect(m_options.m_device_file))
|
||||
return false;
|
||||
} else
|
||||
#endif // HAVE_LIBUSB1
|
||||
{
|
||||
} else {
|
||||
// Connect to MTP device by order number, if no device file supplied
|
||||
if (!m_device.connect(m_options.m_device_no))
|
||||
return false;
|
||||
|
|
|
@ -41,9 +41,7 @@ private:
|
|||
int m_enable_move;
|
||||
int m_list_devices;
|
||||
int m_device_no;
|
||||
#ifdef HAVE_LIBUSB1
|
||||
char *m_device_file;
|
||||
#endif // HAVE_LIBUSB1
|
||||
char *m_mount_point;
|
||||
|
||||
SMTPFileSystemOptions();
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
extern "C" {
|
||||
# include <unistd.h>
|
||||
|
@ -79,7 +80,7 @@ bool MTPDevice::connect(LIBMTP_raw_device_t *dev)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool MTPDevice::connect(int dev_no)
|
||||
bool MTPDevice::connect_priv(int dev_no, const std::string &dev_file)
|
||||
{
|
||||
if (m_device) {
|
||||
logerr("Already connected.\n");
|
||||
|
@ -95,12 +96,6 @@ bool MTPDevice::connect(int dev_no)
|
|||
&raw_devices, &raw_devices_cnt);
|
||||
StreamHelper::on();
|
||||
|
||||
if (dev_no < 0 || dev_no >= raw_devices_cnt) {
|
||||
logerr("Can not connect to device no. ", dev_no + 1, ".\n");
|
||||
free(static_cast<void*>(raw_devices));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (err != LIBMTP_ERROR_NONE) {
|
||||
switch(err) {
|
||||
case LIBMTP_ERROR_NO_DEVICE_ATTACHED:
|
||||
|
@ -124,6 +119,31 @@ bool MTPDevice::connect(int dev_no)
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifndef HAVE_LIBUSB1
|
||||
if (!dev_file.empty()) {
|
||||
uint8_t bnum, dnum;
|
||||
dev_no = raw_devices_cnt;
|
||||
|
||||
if (smtpfs_usb_devpath(dev_file, &bnum, &dnum))
|
||||
for (dev_no = 0; dev_no < raw_devices_cnt; ++dev_no)
|
||||
if (bnum == raw_devices[dev_no].bus_location &&
|
||||
dnum == raw_devices[dev_no].devnum)
|
||||
break;
|
||||
|
||||
if (dev_no == raw_devices_cnt) {
|
||||
logerr("Can not open such device '", dev_file, "'.\n");
|
||||
free(static_cast<void*>(raw_devices));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif // !HAVE_LIBUSB1
|
||||
|
||||
if (dev_no < 0 || dev_no >= raw_devices_cnt) {
|
||||
logerr("Can not connect to device no. ", dev_no + 1, ".\n");
|
||||
free(static_cast<void*>(raw_devices));
|
||||
return false;
|
||||
}
|
||||
|
||||
LIBMTP_raw_device_t *raw_device = &raw_devices[dev_no];
|
||||
|
||||
#ifdef HAVE_LIBUSB1
|
||||
|
@ -154,6 +174,11 @@ bool MTPDevice::connect(int dev_no)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool MTPDevice::connect(int dev_no)
|
||||
{
|
||||
return connect_priv(dev_no, std::string());
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBUSB1
|
||||
bool MTPDevice::connect(const std::string &dev_file)
|
||||
{
|
||||
|
@ -168,12 +193,10 @@ bool MTPDevice::connect(const std::string &dev_file)
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBUSB1
|
||||
// Try to reset USB device, so we don't wait until LIBMTP times out.
|
||||
// We do this every time we are about to mount a device, but better
|
||||
// connect on first try, than wait for 60s timeout.
|
||||
smtpfs_reset_device(raw_device);
|
||||
#endif // HAVE_LIBUSB1
|
||||
|
||||
bool rval = connect(raw_device);
|
||||
|
||||
|
@ -182,6 +205,11 @@ bool MTPDevice::connect(const std::string &dev_file)
|
|||
|
||||
return rval;
|
||||
}
|
||||
#else
|
||||
bool MTPDevice::connect(const std::string &dev_file)
|
||||
{
|
||||
return connect_priv(-1, dev_file);
|
||||
}
|
||||
#endif
|
||||
|
||||
void MTPDevice::disconnect()
|
||||
|
@ -617,7 +645,7 @@ MTPDevice::Capabilities MTPDevice::getCapabilities(const MTPDevice &device)
|
|||
return capabilities;
|
||||
}
|
||||
|
||||
bool MTPDevice::listDevices(bool verbose)
|
||||
bool MTPDevice::listDevices(bool verbose, const std::string &dev_file)
|
||||
{
|
||||
int raw_devices_cnt;
|
||||
LIBMTP_raw_device_t *raw_devices;
|
||||
|
@ -634,7 +662,16 @@ bool MTPDevice::listDevices(bool verbose)
|
|||
return false;
|
||||
}
|
||||
|
||||
uint8_t bnum, dnum;
|
||||
if (!dev_file.empty() && !smtpfs_usb_devpath(dev_file, &bnum, &dnum)) {
|
||||
std::cerr << "Can not open such device '" << dev_file << "'.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < raw_devices_cnt; ++i) {
|
||||
if (!dev_file.empty() &&
|
||||
!(bnum == raw_devices[i].bus_location && dnum == raw_devices[i].devnum))
|
||||
continue;
|
||||
std::cout << i + 1 << ": "
|
||||
<< (raw_devices[i].device_entry.vendor ? raw_devices[i].device_entry.vendor : "Unknown vendor ")
|
||||
<< (raw_devices[i].device_entry.product ? raw_devices[i].device_entry.product : "Unknown product")
|
||||
|
|
|
@ -85,7 +85,7 @@ public:
|
|||
|
||||
Capabilities getCapabilities() const;
|
||||
|
||||
static bool listDevices(bool verbose = false);
|
||||
static bool listDevices(bool verbose, const std::string &dev_file);
|
||||
|
||||
private:
|
||||
void criticalEnter() { m_device_mutex.lock(); }
|
||||
|
@ -94,6 +94,7 @@ private:
|
|||
bool enumStorages();
|
||||
|
||||
static Capabilities getCapabilities(const MTPDevice &device);
|
||||
bool connect_priv(int dev_no, const std::string &dev_file);
|
||||
|
||||
private:
|
||||
LIBMTP_mtpdevice_t *m_device;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <config.h>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#ifdef HAVE_LIBUSB1
|
||||
# include <iomanip>
|
||||
|
@ -78,11 +79,6 @@ void StreamHelper::off()
|
|||
s_enabled = true;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBUSB1
|
||||
const char smtpfs_path_delimiter = '/';
|
||||
const std::string smtpfs_devbususb = "/dev/bus/usb/";
|
||||
#endif // HAVE_LIBUSB1
|
||||
|
||||
std::string smtpfs_dirname(const std::string &path)
|
||||
{
|
||||
char *str = strdup(path.c_str());
|
||||
|
@ -156,6 +152,25 @@ bool smtpfs_remove_dir(const std::string &dirname)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool smtpfs_usb_devpath(const std::string &path, uint8_t *bnum, uint8_t *dnum)
|
||||
{
|
||||
unsigned int bus, dev;
|
||||
#ifdef USB_DEVPATH
|
||||
std::string realpath(smtpfs_realpath(path));
|
||||
if (realpath.empty() ||
|
||||
sscanf(realpath.c_str(), USB_DEVPATH, &bus, &dev) != 2)
|
||||
#endif
|
||||
if (sscanf(path.c_str(), "%u/%u", &bus, &dev) != 2)
|
||||
return false;
|
||||
|
||||
if (bus > 255 || dev > 255)
|
||||
return false;
|
||||
|
||||
*bnum = bus;
|
||||
*dnum = dev;
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBUSB1
|
||||
LIBMTP_raw_device_t *smtpfs_raw_device_new_priv(libusb_device *usb_device)
|
||||
{
|
||||
|
@ -189,10 +204,13 @@ LIBMTP_raw_device_t *smtpfs_raw_device_new_priv(libusb_device *usb_device)
|
|||
|
||||
LIBMTP_raw_device_t *smtpfs_raw_device_new(const std::string &path)
|
||||
{
|
||||
uint8_t bnum, dnum;
|
||||
if (!smtpfs_usb_devpath(path, &bnum, &dnum))
|
||||
return nullptr;
|
||||
|
||||
if (libusb_init(NULL) != 0)
|
||||
return nullptr;
|
||||
|
||||
std::string dev_path(smtpfs_realpath(path));
|
||||
libusb_device **dev_list;
|
||||
ssize_t num_devs = libusb_get_device_list(NULL, &dev_list);
|
||||
if (!num_devs) {
|
||||
|
@ -203,17 +221,8 @@ LIBMTP_raw_device_t *smtpfs_raw_device_new(const std::string &path)
|
|||
libusb_device *dev = nullptr;
|
||||
for (auto i = 0; i < num_devs; ++i) {
|
||||
dev = dev_list[i];
|
||||
uint8_t bnum = libusb_get_bus_number(dev_list[i]);
|
||||
uint8_t dnum = libusb_get_device_address(dev_list[i]);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << smtpfs_devbususb
|
||||
<< std::setw(3) << std::setfill('0')
|
||||
<< static_cast<uint16_t>(bnum) << "/"
|
||||
<< std::setw(3) << std::setfill('0')
|
||||
<< static_cast<uint16_t>(dnum);
|
||||
|
||||
if (ss.str() == dev_path)
|
||||
if (bnum == libusb_get_bus_number(dev_list[i]) &&
|
||||
dnum == libusb_get_device_address(dev_list[i]))
|
||||
break;
|
||||
dev = nullptr;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#define SIMPLE_MTPFS_UTIL
|
||||
|
||||
#include <config.h>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#ifdef HAVE_LIBUSB1
|
||||
|
@ -47,6 +48,7 @@ std::string smtpfs_get_tmpdir();
|
|||
bool smtpfs_create_dir(const std::string &dirname);
|
||||
bool smtpfs_remove_dir(const std::string &dirname);
|
||||
bool smtpfs_check_dir(const std::string &path);
|
||||
bool smtpfs_usb_devpath(const std::string &path, uint8_t *bnum, uint8_t *dnum);
|
||||
|
||||
#ifdef HAVE_LIBUSB1
|
||||
LIBMTP_raw_device_t *smtpfs_raw_device_new(const std::string &path);
|
||||
|
|
Loading…
Reference in New Issue