24#include <sys/statvfs.h>
31#define MAX_BUF_LEN 1024
38 bool shouldPrint,
bool skipMount) :
39 m_shouldPrint(shouldPrint), m_supportedTypes(supportedTypes), m_mountPoint(
40 mountPath), m_deviceNode(), m_partitionNode(), m_skipMount(
46 error =
"Supported filesytem type(supportedTypes) parameter is empty!";
47 throw std::invalid_argument(error.c_str());
53 error =
"Path to mount(mountPath) parameter is empty!";
54 throw std::invalid_argument(error.c_str());
79 struct udev_device *parent,
const char *subsystem)
81 struct udev_device *child = NULL;
82 struct udev_enumerate *enumerate = udev_enumerate_new(udev);
83 udev_enumerate_add_match_parent(enumerate, parent);
84 udev_enumerate_add_match_subsystem(enumerate, subsystem);
85 udev_enumerate_scan_devices(enumerate);
86 struct udev_list_entry *devices = udev_enumerate_get_list_entry(enumerate);
87 struct udev_list_entry *entry;
88 udev_list_entry_foreach(entry, devices)
90 const char *path = udev_list_entry_get_name(entry);
91 child = udev_device_new_from_syspath(udev, path);
94 udev_enumerate_unref(enumerate);
101 struct udev_enumerate *enumerate = udev_enumerate_new(udev);
102 udev_enumerate_add_match_subsystem(enumerate,
"scsi");
103 udev_enumerate_add_match_property(enumerate,
"DEVTYPE",
"scsi_device");
104 udev_enumerate_scan_devices(enumerate);
105 struct udev_list_entry *devices = udev_enumerate_get_list_entry(enumerate);
106 struct udev_list_entry *entry;
108 udev_list_entry_foreach(entry, devices)
110 if (deviceID.empty())
112 const char *path = udev_list_entry_get_name(entry);
113 struct udev_device *scsi = udev_device_new_from_syspath(udev, path);
118 struct udev_device *usb =
119 udev_device_get_parent_with_subsystem_devtype(scsi,
"usb",
121 if (block && scsiDisk && usb)
123 deviceID.assign(udev_device_get_devnode(block));
127 udev_device_unref(block);
131 udev_device_unref(scsiDisk);
133 udev_device_unref(scsi);
136 udev_enumerate_unref(enumerate);
144 struct udev *udev = udev_new();
147 if (devicePath.length())
154 std::cout <<
"Device Node is ==========>>>" <<
m_deviceNode << std::endl;
165 bool isSupportedFs =
false;
169 if (highPartition.
m_size > 0)
193 else if (!usbMountPath.empty())
206 printf(
"USB mount path is empty\n");
247 if (!deviceNode.empty())
249 vector<StorageMinimalInfo> partitions =
getPartitions(deviceNode);
250 for (uint32_t count = 0; count < partitions.size(); count++)
252 if (highCapacityPartition.
m_size < partitions[count].m_size)
254 highCapacityPartition = partitions[count];
260 std::cout <<
"High Capacity Partition is " << highCapacityPartition.
m_partition <<
" == " << highCapacityPartition.
m_fsType <<
" === " << highCapacityPartition.
m_size << std::endl;
262 return highCapacityPartition;
281 std::vector<StorageMinimalInfo> partitions;
283 string listPartitionCommand =
285 +
" -b --noheadings --raw -o NAME,SIZE,FSTYPE | awk '$1~/.*[0-9]+$/ && $7==\"\"'";
290 }
catch (std::runtime_error &e)
292 printf(
"list partition error: %s\n", e.what());
295 if (cmdResponse.empty())
304 istringstream issResponse(cmdResponse);
306 while (getline(issResponse, line))
310 int ret = sscanf(line.c_str(),
"%s %s %s", name, size, fstype);
316 partitions.push_back(
329 if (storageMountCheck.length())
345 printf(
"Privilege mount did not work\n");
356 printf(
"Non-Privilege mount did not work\n");
367 if (deviceNode.length())
379 printf(
"No Partitions found to mount\n");
393 struct stat st = { 0 };
399 perror(
"directory cannot be created\n");
403 int64_t mountStatus = mount(storageDevice.
m_partition.c_str(),
406 if (mountStatus == 0)
410 printf(
"Mount successful\n");
418 printf(
"mount unsuccessful(%" PRId64
") %s -> %s\n", mountStatus,
423 if (mountStatus == EBUSY)
425 error =
"Mountpoint busy. Let's retry in next " + to_string(retryLimit)
431 error =
"Mount error: " + to_string(errno);
435 printf(
"%s\n", error.c_str());
437 if (retryLimit-- == 0)
443 printf(
"mount retry left %" PRIu8
"\n", retryLimit);
454 "udisksctl mount --no-user-interaction -b "
458 printf(
"cmdResponse %s\n", cmdResponse.c_str());
464 }
catch (std::runtime_error &e)
466 printf(
"mount error: %s\n", e.what());
478 error =
"Unmount busy";
482 error =
"Unmount error: " + to_string(errno);
486 printf(
"%s\n", error.c_str());
492 printf(
"Unmount successful\n");
507 }
catch (std::runtime_error &e)
509 printf(
"unmount error: %s\n", e.what());
527 string ejectCommand =
"";
543 "lsblk " + devicePartitionNode +
" --noheadings -o MOUNTPOINT",
548 std::cout<<
"\t mountPath ->" <<mountPath.c_str()<<std::endl;
550 if (mountPath.length()
552 "not a block device"))
557 }
catch (std::runtime_error &e)
559 printf(
"lsblk error: %s\n", e.what());
566 std::string deviceName = devicePartitionNode.substr(
567 devicePartitionNode.rfind(
"/") + 1);
568 std::ifstream mountsFile(
"/proc/mounts");
571 perror(
"Failed to open mounts file");
575 while (std::getline(mountsFile, line))
577 std::istringstream iss(line);
578 std::string dev_name, dir_name, type;
579 if (iss >> dev_name >> dir_name >> type)
581 if (dev_name == devicePartitionNode)
591 uint64_t &totalCapacityInMB)
604 printf(
"stat.f_bsize=%" PRIu64
"\n stat.f_frsize=%" PRIu64
"\n stat.f_bfree=%" PRIu64
"\n "
605 "stat.f_blocks=%" PRIu64
"\n", stat.f_bsize, stat.f_frsize,
606 stat.f_bfree, stat.f_blocks);
608 uint64_t sz = stat.f_bsize;
611 printf(
"int sz = stat.f_bsize; === %" PRIu64
" = %" PRIu64
"\n", sz, stat.f_bsize);
612 printf(
"sz *= stat.f_bfree === %" PRIu64
" *= %" PRIu64
"\n", sz, stat.f_bfree);
615 freeSpaceInMB = sz >> 20;
618 printf(
"int freeSpaceInMB = sz >> 20 === int %" PRId64
" = %" PRId64
" >> 20\n",
625 printf(
"sz = stat.f_bsize; === %" PRId64
" = %" PRId64
";\n", sz, stat.f_bsize);
632 printf(
"sz *= stat.f_blocks; === %" PRIu64
" *= %" PRIu64
";\n", sz,
636 totalCapacityInMB = sz >> 20;
640 printf(
"int totalSpaceInMB = sz >> 20; === int %" PRIu64
" = "
641 "%" PRIu64
" >> 20;\n", totalCapacityInMB, sz);
650 if (path.length() && stat(path.c_str(), &buffer) == 0)
652 if (S_ISBLK(buffer.st_mode))
static STORAGE_TYPE getEnum(std::string typeStr)
bool isDeviceNodeConnected()
std::vector< StorageMinimalInfo > getPartitions(std::string devpath)
string findMountDeviceBylsblk(string devicePartitionNode)
bool unMountWithoutPrivilege()
std::vector< STORAGE_TYPE > m_supportedTypes
bool unMountWithPrivilege()
bool getStorageInfo(uint64_t &freeSpaceInMB, uint64_t &totalCapacityInMB)
virtual string insertCheck()
virtual bool ejectDevice()
StorageUSB(std::string mountPath, std::vector< STORAGE_TYPE > supportedTypes, bool shouldPrint, bool skipMount=false)
virtual string mountDevice()
std::string getMountPath()
string findMountedDevice(string devicePartitionNode)
std::string m_partitionNode
struct udev_device * getChildDevice(struct udev *udev, struct udev_device *parent, const char *subsystem)
StorageMinimalInfo getHighCapacityPartition(std::string deviceNode)
bool mountWithoutPrivilege(StorageMinimalInfo storageDevice)
STORAGE_STATE getStatus()
std::string enumerateDevices(struct udev *udev)
bool mountUSBDevice(StorageMinimalInfo storageDevice, uint8_t retryLimit=3)
bool mountDeviceNode(string deviceNode)
bool mountWithPrivilege(StorageMinimalInfo storageDevice, uint8_t retryLimit=3)
virtual bool isUnsafeEject()
static string trim(string str)
static string exec(const string &cmd, bool debug=false)
static bool caseInsensitiveSearch(std::string const str, std::string const pattern)
@ STORAGE_INSERTED_UNMOUNTED