Support mounting by device file on non Linux OS

- it`s possible to supply device path sscanf format string
  at configure stage. FreeBSD`s one supplied
- it`s possible to use <bus>/<device> format as a fallback option
This commit is contained in:
Vladimir Kondratiev 2015-08-23 12:11:10 +03:00
parent c117d9e1ac
commit 4febe686c0
4 changed files with 67 additions and 31 deletions

View File

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

@ -20,6 +20,7 @@
#include <sstream>
#include <vector>
#include <cstring>
#include <cstdint>
#include <cstdlib>
extern "C" {
# include <unistd.h>
@ -120,14 +121,14 @@ bool MTPDevice::connect_priv(int dev_no, const std::string &dev_file)
#ifndef HAVE_LIBUSB1
if (!dev_file.empty()) {
std::string dev_path(smtpfs_realpath(dev_file));
uint8_t bnum, dnum;
dev_no = raw_devices_cnt;
for (dev_no = 0; dev_no < raw_devices_cnt; ++dev_no) {
std::string usb_devpath = smtpfs_usb_devpath(
raw_devices[dev_no].bus_location, raw_devices[dev_no].devnum);
if (usb_devpath == dev_path)
break;
}
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");
@ -648,7 +649,6 @@ bool MTPDevice::listDevices(bool verbose, const std::string &dev_file)
{
int raw_devices_cnt;
LIBMTP_raw_device_t *raw_devices;
std::string dev_path;
// Do not output LIBMTP debug stuff
StreamHelper::off();
@ -662,17 +662,15 @@ bool MTPDevice::listDevices(bool verbose, const std::string &dev_file)
return false;
}
if (!dev_file.empty()) {
dev_path = smtpfs_realpath(dev_file);
if (dev_path.empty()) {
std::cerr << "Can not open such device '" << dev_file << "'.\n";
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() &&
dev_path != smtpfs_usb_devpath(raw_devices[i].bus_location, raw_devices[i].devnum))
!(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 ")

View File

@ -16,6 +16,7 @@
* ***** END LICENSE BLOCK ***** */
#include <config.h>
#include <cstdio>
#include <cstring>
#ifdef HAVE_LIBUSB1
# include <iomanip>
@ -78,9 +79,6 @@ void StreamHelper::off()
s_enabled = true;
}
const char smtpfs_path_delimiter = '/';
const std::string smtpfs_devbususb = "/dev/bus/usb/";
std::string smtpfs_dirname(const std::string &path)
{
char *str = strdup(path.c_str());
@ -154,15 +152,23 @@ bool smtpfs_remove_dir(const std::string &dirname)
return true;
}
std::string smtpfs_usb_devpath(uint8_t bnum, uint8_t dnum)
bool smtpfs_usb_devpath(const std::string &path, uint8_t *bnum, uint8_t *dnum)
{
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);
return ss.str();
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
@ -198,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) {
@ -212,9 +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]);
if (smtpfs_usb_devpath(bnum, dnum) == dev_path)
if (bnum == libusb_get_bus_number(dev_list[i]) &&
dnum == libusb_get_device_address(dev_list[i]))
break;
dev = nullptr;
}

View File

@ -44,11 +44,11 @@ std::string smtpfs_dirname(const std::string &path);
std::string smtpfs_basename(const std::string &path);
std::string smtpfs_realpath(const std::string &path);
std::string smtpfs_get_tmpdir();
std::string smtpfs_usb_devpath(uint8_t bnum, uint8_t dnum);
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);