Merge pull request #41 from wulf7/master

Thanks for your work! Looks good to me.
This commit is contained in:
Peter Hatina 2015-09-03 14:20:09 +02:00
commit a7ab64c7e4
9 changed files with 126 additions and 60 deletions

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/bin/sh
# exit on errors
set -e

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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