int MTPDevice::dirRename(const std::string &oldpath, const std::string &newpath) { const std::string tmp_old_basename(smtpfs_basename(oldpath)); const std::string tmp_old_dirname(smtpfs_dirname(oldpath)); const std::string tmp_new_basename(smtpfs_basename(newpath)); const std::string tmp_new_dirname(smtpfs_dirname(newpath)); const TypeDir *dir_parent = dirFetchContent(tmp_old_dirname); const TypeDir *dir_to_rename = dir_parent ? dir_parent->dir(tmp_old_basename) : nullptr; if (!dir_parent || !dir_to_rename || dir_parent->id() == 0) { logerr("Can not rename '", tmp_old_basename, "' to '", tmp_new_basename, "'.\n"); return -EINVAL; } if (tmp_old_dirname != tmp_new_dirname) { logerr("Can not move '", oldpath, "' to '", newpath, "'.\n"); return -EINVAL; } LIBMTP_folder_t *folder = dir_to_rename->toLIBMTPFolder(); criticalEnter(); int ret = LIBMTP_Set_Folder_Name(m_device, folder, tmp_new_basename.c_str()); criticalLeave(); free(static_cast<void*>(folder->name)); free(static_cast<void*>(folder)); if (ret != 0) { logerr("Could not rename '", oldpath, "' to '", tmp_new_basename, "'.\n"); LIBMTP_Dump_Errorstack(m_device); LIBMTP_Clear_Errorstack(m_device); return -EINVAL; } const_cast<TypeDir*>(dir_to_rename)->setName(tmp_new_basename); logmsg("Directory '", oldpath, "' renamed to '", tmp_new_basename, "'.\n"); return 0; }
int main(int argc, char const *argv[]) { LIBMTP_Init(); printf("Searching for device...\n"); LIBMTP_mtpdevice_t* device = LIBMTP_Get_First_Device(); if (!device) { printf("Oops, no devices!\n"); return 1; } /* Warning! This id is just for test! Remove it and put your value */ const int id = 10494; int r = 0; LIBMTP_BeginEditObject(device, id); char s[64] = "The quick brown fox jumps over lazy dog\n"; printf("Calling for LIBMTP_SendPartialObject...\n"); r = LIBMTP_SendPartialObject(device, id, 0, (unsigned char *)s, strlen(s)); if (r < 0) { printf("Oops, an error!\n"); goto cleanup; } else printf("LIBMTP_SendPartialObject done successfully!\n"); LIBMTP_EndEditObject(device, id); cleanup: LIBMTP_Dump_Errorstack(device); LIBMTP_Clear_Errorstack(device); LIBMTP_Release_Device(device); return r < 0 ? -1 : 0; }
int MTPDevice::dirRemove(const std::string &path) { const std::string tmp_basename(smtpfs_basename(path)); const std::string tmp_dirname(smtpfs_dirname(path)); const TypeDir *dir_parent = dirFetchContent(tmp_dirname); const TypeDir *dir_to_remove = dir_parent ? dir_parent->dir(tmp_basename) : nullptr; if (!dir_parent || !dir_to_remove || dir_parent->id() == 0) { logerr("No such directory '", path, "' to remove.\n"); return -ENOENT; } if (!dir_to_remove->isEmpty()) return -ENOTEMPTY; criticalEnter(); int rval = LIBMTP_Delete_Object(m_device, dir_to_remove->id()); criticalLeave(); if (rval != 0){ logerr("Could not remove the directory '", path, "'.\n"); LIBMTP_Dump_Errorstack(m_device); LIBMTP_Clear_Errorstack(m_device); return -EINVAL; } const_cast<TypeDir*>(dir_parent)->removeDir(*dir_to_remove); logmsg("Folder '", path, "' removed.\n"); return 0; }
int MTPDevice::filePull(const std::string &src, const std::string &dst) { const std::string src_basename(smtpfs_basename(src)); const std::string src_dirname(smtpfs_dirname(src)); const TypeDir *dir_parent = dirFetchContent(src_dirname); const TypeFile *file_to_fetch = dir_parent ? dir_parent->file(src_basename) : nullptr; if (!dir_parent) { logerr("Can not fetch '", src, "'.\n"); return -EINVAL; } if (!file_to_fetch) { logerr("No such file '", src, "'.\n"); return -ENOENT; } if (file_to_fetch->size() == 0) { int fd = ::creat(dst.c_str(), S_IRUSR | S_IWUSR); ::close(fd); } else { logmsg("Started fetching '", src, "'.\n"); criticalEnter(); int rval = LIBMTP_Get_File_To_File(m_device, file_to_fetch->id(), dst.c_str(), nullptr, nullptr); criticalLeave(); if (rval != 0) { logerr("Could not fetch file '", src, "'.\n"); LIBMTP_Dump_Errorstack(m_device); LIBMTP_Clear_Errorstack(m_device); return -ENOENT; } } logmsg("File fetched '", src, "'.\n"); return 0; }
int MTPDevice::fileRename(const std::string &oldpath, const std::string &newpath) { const std::string tmp_old_basename(smtpfs_basename(oldpath)); const std::string tmp_old_dirname(smtpfs_dirname(oldpath)); const std::string tmp_new_basename(smtpfs_basename(newpath)); const std::string tmp_new_dirname(smtpfs_dirname(newpath)); const TypeDir *dir_parent = dirFetchContent(tmp_old_dirname); const TypeFile *file_to_rename = dir_parent ? dir_parent->file(tmp_old_basename) : nullptr; if (!dir_parent || !file_to_rename || tmp_old_dirname != tmp_new_dirname) { logerr("Can not rename '", oldpath, "' to '", tmp_new_basename, "'.\n"); return -EINVAL; } LIBMTP_file_t *file = file_to_rename->toLIBMTPFile(); criticalEnter(); int rval = LIBMTP_Set_File_Name(m_device, file, tmp_new_basename.c_str()); criticalLeave(); free(static_cast<void*>(file->filename)); free(static_cast<void*>(file)); if (rval > 0) { logerr("Could not rename '", oldpath, "' to '", newpath, "'.\n"); LIBMTP_Dump_Errorstack(m_device); LIBMTP_Clear_Errorstack(m_device); return -EINVAL; } const_cast<TypeFile*>(file_to_rename)->setName(tmp_new_basename); logmsg("File '", oldpath, "' renamed to '", tmp_new_basename, "'.\n"); return 0; }
static void prune_empty_folders(LIBMTP_mtpdevice_t *device, LIBMTP_file_t *files, LIBMTP_folder_t *folderlist, int do_delete) { if(folderlist==NULL) return; if(folderlist->child == NULL) { int found = 0; LIBMTP_file_t *file; file = files; while (file != NULL) { if(file->parent_id == folderlist->folder_id) { found = 1; break; } file = file->next; } if(found == 0) { printf("empty folder %u (%s)\n",folderlist->folder_id,folderlist->name); if(do_delete) { if (LIBMTP_Delete_Object(device,folderlist->folder_id) != 0) { printf("Couldn't delete folder %u\n",folderlist->folder_id); LIBMTP_Dump_Errorstack(device); LIBMTP_Clear_Errorstack(device); } } } } prune_empty_folders(device,files,folderlist->child,do_delete); prune_empty_folders(device,files,folderlist->sibling,do_delete); }
bool MTPDevice::connect(LIBMTP_raw_device_t *dev) { if (m_device) { logerr("Already connected.\n"); return true; } // Do not output LIBMTP debug stuff StreamHelper::off(); m_device = LIBMTP_Open_Raw_Device_Uncached(dev); StreamHelper::on(); if (!m_device) { LIBMTP_Dump_Errorstack(m_device); return false; } if (!enumStorages()) return false; // Retrieve capabilities. m_capabilities = MTPDevice::getCapabilities(*this); logmsg("Connected.\n"); return true; }
int MTPDevice::dirCreateNew(const std::string &path) { const std::string tmp_basename(smtpfs_basename(path)); const std::string tmp_dirname(smtpfs_dirname(path)); const TypeDir *dir_parent = dirFetchContent(tmp_dirname); if (!dir_parent || dir_parent->id() == 0) { logerr("Can not remove directory '", path, "'.\n"); return -EINVAL; } char *c_name = strdup(tmp_basename.c_str()); criticalEnter(); uint32_t new_id = LIBMTP_Create_Folder(m_device, c_name, dir_parent->id(), dir_parent->storageid()); criticalLeave(); if (new_id == 0) { logerr("Could not create directory '", path, "'.\n"); LIBMTP_Dump_Errorstack(m_device); LIBMTP_Clear_Errorstack(m_device); } else { const_cast<TypeDir*>(dir_parent)->addDir(TypeDir(new_id, dir_parent->id(), dir_parent->storageid(), tmp_basename)); logmsg("Directory '", path, "' created.\n"); } free(static_cast<void*>(c_name)); return new_id != 0 ? 0 : -EINVAL; }
void getfile_function(char * from_path,char * to_path) { int id = parse_path (from_path,files,folders); if (id > 0) { printf("Getting %s to %s\n",from_path,to_path); if (LIBMTP_Get_File_To_File(device, id, to_path, progress, NULL) != 0 ) { printf("\nError getting file from MTP device.\n"); LIBMTP_Dump_Errorstack(device); LIBMTP_Clear_Errorstack(device); } } }
bool MTPDevice::enumStorages() { criticalEnter(); LIBMTP_Clear_Errorstack(m_device); if (LIBMTP_Get_Storage(m_device, LIBMTP_STORAGE_SORTBY_NOTSORTED) < 0) { std::cerr << "Could not retrieve device storage.\n"; std::cerr << "For android phones make sure the screen is unlocked.\n"; logerr("Could not retrieve device storage. Exiting.\n"); LIBMTP_Dump_Errorstack(m_device); LIBMTP_Clear_Errorstack(m_device); return false; } criticalLeave(); return true; }
int MTPDevice::filePush(const std::string &src, const std::string &dst) { const std::string dst_basename(smtpfs_basename(dst)); const std::string dst_dirname(smtpfs_dirname(dst)); const TypeDir *dir_parent = dirFetchContent(dst_dirname); const TypeFile *file_to_remove = dir_parent ? dir_parent->file(dst_basename) : nullptr; if (dir_parent && file_to_remove) { criticalEnter(); int rval = LIBMTP_Delete_Object(m_device, file_to_remove->id()); criticalLeave(); if (rval != 0) { logerr("Can not upload '", src, "' to '", dst, "'.\n"); return -EINVAL; } } struct stat file_stat; stat(src.c_str(), &file_stat); TypeFile file_to_upload(0, dir_parent->id(), dir_parent->storageid(), dst_basename, static_cast<uint64_t>(file_stat.st_size), 0); LIBMTP_file_t *f = file_to_upload.toLIBMTPFile(); if (file_stat.st_size) logmsg("Started uploading '", dst, "'.\n"); criticalEnter(); int rval = LIBMTP_Send_File_From_File(m_device, src.c_str(), f, nullptr, nullptr); criticalLeave(); if (rval != 0) { logerr("Could not upload file '", src, "'.\n"); LIBMTP_Dump_Errorstack(m_device); LIBMTP_Clear_Errorstack(m_device); rval = -EINVAL; } else { file_to_upload.setId(f->item_id); file_to_upload.setParent(f->parent_id); file_to_upload.setStorage(f->storage_id); file_to_upload.setName(std::string(f->filename)); file_to_upload.setModificationDate(file_stat.st_mtime); if (file_to_remove) const_cast<TypeDir*>(dir_parent)->replaceFile(*file_to_remove, file_to_upload); else const_cast<TypeDir*>(dir_parent)->addFile(file_to_upload); } free(static_cast<void*>(f->filename)); free(static_cast<void*>(f)); logmsg("File '", dst, (file_stat.st_size ? " uploaded" : " created"), ".\n"); return rval; }
void Plugin::handleUploadFinished () { auto watcher = dynamic_cast<QFutureWatcher<UploadInfo>*> (sender ()); watcher->deleteLater (); const auto& info = watcher->result (); qDebug () << "send result:" << info.Res_; if (info.Res_) { LIBMTP_Dump_Errorstack (info.Device_); LIBMTP_Clear_Errorstack (info.Device_); } AppendAlbum (info.Device_, info.Track_, info.Info_); LIBMTP_destroy_track_t (info.Track_); emit uploadFinished (info.LocalPath_, QFile::NoError, {}); }
int main (int argc, char **argv) { LIBMTP_mtpdevice_t *device; int ret; fprintf(stdout, "libmtp version: " LIBMTP_VERSION_STRING "\n\n"); LIBMTP_Init(); device = LIBMTP_Get_First_Device(); if (device == NULL) { printf("No devices.\n"); return 0; } printf("I will now format your device. This means that\n"); printf("all content (and licenses) will be lost forever.\n"); printf("you will not be able to undo this operation.\n"); printf("Continue? (y/n)\n"); if (prompt() == 0) { // This will just format the first storage. ret = LIBMTP_Format_Storage(device, device->storage); } else { printf("Aborted.\n"); ret = 0; } if ( ret != 0 ) { printf("Failed to format device.\n"); LIBMTP_Dump_Errorstack(device); LIBMTP_Clear_Errorstack(device); LIBMTP_Release_Device(device); return 1; } LIBMTP_Release_Device(device); printf("OK.\n"); return 0; }
bool MTPDevice::connect(const std::string &dev_file) { if (m_device) { logerr("Already connected.\n"); return true; } LIBMTP_raw_device_t *raw_device = smtpfs_raw_device_new(dev_file); if (!raw_device) { logerr("Can not open such device '", dev_file, "'.\n"); 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 // Do not output LIBMTP debug stuff StreamHelper::off(); m_device = LIBMTP_Open_Raw_Device_Uncached(raw_device); StreamHelper::on(); smtpfs_raw_device_free(raw_device); if (!m_device) { LIBMTP_Dump_Errorstack(m_device); return false; } if (!enumStorages()) return false; logmsg("Connected.\n"); return true; }
static void dump_plinfo(LIBMTP_mtpdevice_t *device, LIBMTP_playlist_t *pl) { uint32_t i; printf("Playlist ID: %d\n", pl->playlist_id); if (pl->name != NULL) printf(" Name: %s\n", pl->name); printf(" Parent ID: %d\n", pl->parent_id); printf(" Tracks:\n"); for (i = 0; i < pl->no_tracks; i++) { LIBMTP_track_t *track; track = LIBMTP_Get_Trackmetadata(device, pl->tracks[i]); if (track != NULL) { printf(" %u: %s - %s\n", pl->tracks[i], track->artist, track->title); LIBMTP_destroy_track_t(track); } else { printf(" %u: INVALID TRACK REFERENCE!\n", pl->tracks[i]); LIBMTP_Dump_Errorstack(device); LIBMTP_Clear_Errorstack(device); } } }
bool MTPDevice::connect_priv(int dev_no, const std::string &dev_file) { if (m_device) { logerr("Already connected.\n"); return true; } int raw_devices_cnt; LIBMTP_raw_device_t *raw_devices; // Do not output LIBMTP debug stuff StreamHelper::off(); LIBMTP_error_number_t err = LIBMTP_Detect_Raw_Devices( &raw_devices, &raw_devices_cnt); StreamHelper::on(); if (err != LIBMTP_ERROR_NONE) { switch(err) { case LIBMTP_ERROR_NO_DEVICE_ATTACHED: logerr("No raw devices found.\n"); break; case LIBMTP_ERROR_CONNECTING: logerr("There has been an error connecting. Exiting.\n"); break; case LIBMTP_ERROR_MEMORY_ALLOCATION: logerr("Encountered a Memory Allocation Error. Exiting.\n"); break; case LIBMTP_ERROR_GENERAL: logerr("General error occured. Exiting.\n"); break; case LIBMTP_ERROR_USB_LAYER: logerr("USB Layer error occured. Exiting.\n"); break; default: break; } 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]; // Do not output LIBMTP debug stuff StreamHelper::off(); m_device = LIBMTP_Open_Raw_Device_Uncached(raw_device); StreamHelper::on(); free(static_cast<void*>(raw_devices)); if (!m_device) { LIBMTP_Dump_Errorstack(m_device); return false; } if (!enumStorages()) return false; // Retrieve capabilities. m_capabilities = MTPDevice::getCapabilities(*this); logmsg("Connected.\n"); return true; }
int main(int argc, char **argv) { int mainret = 0; if (argc < 2) { fprintf(stderr, "usage: %s [-d] mountpoint\n", argv[0]); exit(1); } char *mount_point = argv[1]; argc -= 1; argv += 1; // LIBMTP_Set_Debug(LIBMTP_DEBUG_PTP | LIBMTP_DEBUG_DATA); LIBMTP_Init(); LIBMTP_error_number_t mtperr; LIBMTP_raw_device_t *rawdevs; int nrawdev; mtperr = LIBMTP_Detect_Raw_Devices(&rawdevs, &nrawdev); switch (mtperr) { case LIBMTP_ERROR_NO_DEVICE_ATTACHED: fprintf(stderr, "no raw devices\n"); exit(0); case LIBMTP_ERROR_CONNECTING: fprintf(stderr, "ERROR connecting\n"); exit(1); case LIBMTP_ERROR_MEMORY_ALLOCATION: fprintf(stderr, "ERROR memory allocation\n"); exit(1); case LIBMTP_ERROR_NONE: break; default: fprintf(stderr, "ERROR unknown\n"); exit(1); } printf("%d raw devices:\n", nrawdev); int i; for (i = 0; i < nrawdev; ++i) { printf(" device #%d: %s: %s (%04X:%04X) @ bus %d, dev %d\n", i, rawdevs[i].device_entry.vendor, rawdevs[i].device_entry.product, rawdevs[i].device_entry.vendor_id, rawdevs[i].device_entry.product_id, rawdevs[i].bus_location, rawdevs[i].devnum); } mtpfuse_t ctx; memset(&ctx, 0, sizeof(ctx)); printf("opening raw device #0...\n"); ctx.dev = LIBMTP_Open_Raw_Device_Uncached(&rawdevs[0]); if (!ctx.dev) { fprintf(stderr, "ERROR opening raw device #0\n"); exit(1); } LIBMTP_Dump_Errorstack(ctx.dev); LIBMTP_Clear_Errorstack(ctx.dev); char *name = LIBMTP_Get_Friendlyname(ctx.dev); printf("opened raw device %s.\n", name); int ret = LIBMTP_Get_Storage(ctx.dev, LIBMTP_STORAGE_SORTBY_NOTSORTED); if (ret != 0) { fprintf(stderr, "ERROR get %s's storage:\n", name); LIBMTP_Dump_Errorstack(ctx.dev); mainret = 1; goto done; } printf("device's storage:\n"); LIBMTP_devicestorage_t *storage; for (storage = ctx.dev->storage, i = 0; storage; storage = storage->next, ++i) { printf(" storage #%d: %d - %s\n", i, storage->id, storage->StorageDescription); } if (i <= 0) { fprintf(stderr, "there is no storage that is usable.\n"); mainret = 1; goto done; } mainret = fuse_main(argc, argv, &mtpfuse_ops, &ctx); done: LIBMTP_Release_Device(ctx.dev); return mainret; }
int main (int argc, char **argv) { int opt; extern int optind; extern char *optarg; LIBMTP_mtpdevice_t *device = NULL; int fd; uint32_t id = 0; uint64_t filesize; uint8_t *imagedata = NULL; char *path = NULL; char *rest; struct stat statbuff; int ret; fprintf(stdout, "libmtp version: " LIBMTP_VERSION_STRING "\n\n"); while ( (opt = getopt(argc, argv, "hi:")) != -1 ) { switch (opt) { case 'h': usage(); case 'i': id = strtoul(optarg, &rest, 0); break; default: usage(); } } argc -= optind; argv += optind; if ( argc != 1 ) { printf("You need to pass a filename.\n"); usage(); } path = argv[0]; if ( stat(path, &statbuff) == -1 ) { fprintf(stderr, "%s: ", path); perror("stat"); exit(1); } filesize = (uint64_t) statbuff.st_size; imagedata = malloc(filesize * sizeof(uint16_t)); #ifdef __WIN32__ if ( (fd = open(path, O_RDONLY|O_BINARY) == -1) ) { #else if ( (fd = open(path, O_RDONLY)) == -1) { #endif printf("Couldn't open image file %s (%s)\n",path,strerror(errno)); return 1; } else { read(fd, imagedata, filesize); close(fd); } LIBMTP_Init(); device = LIBMTP_Get_First_Device(); if (device == NULL) { printf("No devices.\n"); return 0; } LIBMTP_filesampledata_t *thumb = LIBMTP_new_filesampledata_t(); int i; thumb->data = malloc(sizeof(uint16_t) * filesize); for (i = 0; i < filesize; i++) { thumb->data[i] = imagedata[i]; } thumb->size = filesize; thumb->filetype = LIBMTP_FILETYPE_JPEG; ret = LIBMTP_Send_Representative_Sample(device,id,thumb); if (ret != 0) { printf("Couldn't send thumbnail\n"); LIBMTP_Dump_Errorstack(device); LIBMTP_Clear_Errorstack(device); } free(imagedata); LIBMTP_destroy_filesampledata_t(thumb); LIBMTP_Release_Device(device); printf("OK.\n"); return 0; }
int main (int argc, char **argv) { LIBMTP_raw_device_t * rawdevices; int numrawdevices; LIBMTP_error_number_t err; int i; int opt; extern int optind; extern char *optarg; while ((opt = getopt(argc, argv, "d")) != -1 ) { switch (opt) { case 'd': LIBMTP_Set_Debug(LIBMTP_DEBUG_PTP | LIBMTP_DEBUG_DATA); break; } } argc -= optind; argv += optind; LIBMTP_Init(); fprintf(stdout, "libmtp version: " LIBMTP_VERSION_STRING "\n\n"); fprintf(stdout, "Listing raw device(s)\n"); err = LIBMTP_Detect_Raw_Devices(&rawdevices, &numrawdevices); switch(err) { case LIBMTP_ERROR_NO_DEVICE_ATTACHED: fprintf(stdout, " No raw devices found.\n"); return 0; case LIBMTP_ERROR_CONNECTING: fprintf(stderr, "Detect: There has been an error connecting. Exiting\n"); return 1; case LIBMTP_ERROR_MEMORY_ALLOCATION: fprintf(stderr, "Detect: Encountered a Memory Allocation Error. Exiting\n"); return 1; case LIBMTP_ERROR_NONE: { int i; fprintf(stdout, " Found %d device(s):\n", numrawdevices); for (i = 0; i < numrawdevices; i++) { if (rawdevices[i].device_entry.vendor != NULL || rawdevices[i].device_entry.product != NULL) { fprintf(stdout, " %s: %s (%04x:%04x) @ bus %d, dev %d\n", rawdevices[i].device_entry.vendor, rawdevices[i].device_entry.product, rawdevices[i].device_entry.vendor_id, rawdevices[i].device_entry.product_id, rawdevices[i].bus_location, rawdevices[i].devnum); } else { fprintf(stdout, " %04x:%04x @ bus %d, dev %d\n", rawdevices[i].device_entry.vendor_id, rawdevices[i].device_entry.product_id, rawdevices[i].bus_location, rawdevices[i].devnum); } } } break; case LIBMTP_ERROR_GENERAL: default: fprintf(stderr, "Unknown connection error.\n"); return 1; } /* Iterate over connected MTP devices */ fprintf(stdout, "Attempting to connect device(s)\n"); for (i = 0; i < numrawdevices; i++) { LIBMTP_mtpdevice_t *device; LIBMTP_devicestorage_t *storage; char *friendlyname; char *syncpartner; char *sectime; char *devcert; uint16_t *filetypes; uint16_t filetypes_len; uint8_t maxbattlevel; uint8_t currbattlevel; int ret; device = LIBMTP_Open_Raw_Device_Uncached(&rawdevices[i]); if (device == NULL) { fprintf(stderr, "Unable to open raw device %d\n", i); continue; } LIBMTP_Dump_Errorstack(device); LIBMTP_Clear_Errorstack(device); LIBMTP_Dump_Device_Info(device); printf("MTP-specific device properties:\n"); // The friendly name friendlyname = LIBMTP_Get_Friendlyname(device); if (friendlyname == NULL) { fprintf(stdout, " Friendly name: (NULL)\n"); } else { fprintf(stdout, " Friendly name: %s\n", friendlyname); free(friendlyname); } syncpartner = LIBMTP_Get_Syncpartner(device); if (syncpartner == NULL) { fprintf(stdout, " Synchronization partner: (NULL)\n"); } else { fprintf(stdout, " Synchronization partner: %s\n", syncpartner); free(syncpartner); } // Some battery info ret = LIBMTP_Get_Batterylevel(device, &maxbattlevel, &currbattlevel); if (ret == 0) { fprintf(stdout, " Battery level %d of %d (%d%%)\n",currbattlevel, maxbattlevel, (int) ((float) currbattlevel/ (float) maxbattlevel * 100.0)); } else { // Silently ignore. Some devices does not support getting the // battery level. LIBMTP_Clear_Errorstack(device); } ret = LIBMTP_Get_Supported_Filetypes(device, &filetypes, &filetypes_len); if (ret == 0) { uint16_t i; printf("libmtp supported (playable) filetypes:\n"); for (i = 0; i < filetypes_len; i++) { fprintf(stdout, " %s\n", LIBMTP_Get_Filetype_Description(filetypes[i])); } } else { LIBMTP_Dump_Errorstack(device); LIBMTP_Clear_Errorstack(device); } // Secure time XML fragment ret = LIBMTP_Get_Secure_Time(device, §ime); if (ret == 0 && sectime != NULL) { fprintf(stdout, "\nSecure Time:\n%s\n", sectime); free(sectime); } else { // Silently ignore - there may be devices not supporting secure time. LIBMTP_Clear_Errorstack(device); } // Device certificate XML fragment if (rawdevices[i].device_entry.vendor_id == 0x041e) { /* * This code is currently disabled except for vendors we * know does support it: all devices say that * they support getting a device certificate but a lot of * them obviously doesn't, instead they crash when you try * to obtain it. */ ret = LIBMTP_Get_Device_Certificate(device, &devcert); if (ret == 0 && devcert != NULL) { fprintf(stdout, "\nDevice Certificate:\n%s\n", devcert); free(devcert); } else { fprintf(stdout, "Unable to acquire device certificate, perhaps this device " "does not support this\n"); LIBMTP_Dump_Errorstack(device); LIBMTP_Clear_Errorstack(device); } } /* Try to get Media player device info XML file... */ /* Loop over storages */ for (storage = device->storage; storage != 0; storage = storage->next) { LIBMTP_file_t *files; /* Get file listing for the root directory, no other dirs */ files = LIBMTP_Get_Files_And_Folders(device, storage->id, 0); if (files != NULL) { LIBMTP_file_t *file, *tmp; file = files; while (file != NULL) { if (!strcmp(file->filename, "WMPInfo.xml") || !strcmp(file->filename, "WMPinfo.xml") || !strcmp(file->filename, "default-capabilities.xml")) { if (file->item_id != 0) { /* Dump this file */ FILE *xmltmp = tmpfile(); int tmpfiledescriptor = fileno(xmltmp); if (tmpfiledescriptor != -1) { int ret = LIBMTP_Get_Track_To_File_Descriptor(device, file->item_id, tmpfiledescriptor, NULL, NULL); if (ret == 0) { uint8_t *buf = NULL; uint32_t readbytes; buf = malloc(XML_BUFSIZE); if (buf == NULL) { printf("Could not allocate %08x bytes...\n", XML_BUFSIZE); LIBMTP_Dump_Errorstack(device); LIBMTP_Clear_Errorstack(device); free(rawdevices); return 1; } lseek(tmpfiledescriptor, 0, SEEK_SET); readbytes = read(tmpfiledescriptor, (void*) buf, XML_BUFSIZE); if (readbytes >= 2 && readbytes < XML_BUFSIZE) { fprintf(stdout, "\n%s file contents:\n", file->filename); dump_xml_fragment(buf, readbytes); } else { perror("Unable to read file"); LIBMTP_Dump_Errorstack(device); LIBMTP_Clear_Errorstack(device); } free(buf); } else { LIBMTP_Dump_Errorstack(device); LIBMTP_Clear_Errorstack(device); } fclose(xmltmp); } } } tmp = file; file = file->next; LIBMTP_destroy_file_t(tmp); } } } LIBMTP_Release_Device(device); } /* End For Loop */ free(rawdevices); printf("OK.\n"); return 0; }
bool MTPDevice::connect(int dev_no) { if (m_device) { logerr("Already connected.\n"); return true; } int raw_devices_cnt; LIBMTP_raw_device_t *raw_devices; // Do not output LIBMTP debug stuff StreamHelper::off(); LIBMTP_error_number_t err = LIBMTP_Detect_Raw_Devices( &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: logerr("No raw devices found.\n"); break; case LIBMTP_ERROR_CONNECTING: logerr("There has been an error connecting. Exiting.\n"); break; case LIBMTP_ERROR_MEMORY_ALLOCATION: logerr("Encountered a Memory Allocation Error. Exiting.\n"); break; case LIBMTP_ERROR_GENERAL: logerr("General error occured. Exiting.\n"); break; case LIBMTP_ERROR_USB_LAYER: logerr("USB Layer error occured. Exiting.\n"); break; default: break; } return false; } LIBMTP_raw_device_t *raw_device = &raw_devices[dev_no]; #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 // Do not output LIBMTP debug stuff StreamHelper::off(); m_device = LIBMTP_Open_Raw_Device_Uncached(raw_device); StreamHelper::on(); free(static_cast<void*>(raw_devices)); if (!m_device) { LIBMTP_Dump_Errorstack(m_device); return false; } if (!enumStorages()) return false; logmsg("Connected.\n"); return true; }
int main (int argc, char **argv) { LIBMTP_raw_device_t * rawdevices; int numrawdevices; LIBMTP_error_number_t err; int i; int opt; extern int optind; extern char *optarg; while ((opt = getopt(argc, argv, "d")) != -1 ) { switch (opt) { case 'd': LIBMTP_Set_Debug(LIBMTP_DEBUG_PTP | LIBMTP_DEBUG_DATA); break; } } argc -= optind; argv += optind; LIBMTP_Init(); err = LIBMTP_Detect_Raw_Devices(&rawdevices, &numrawdevices); switch(err) { case LIBMTP_ERROR_NO_DEVICE_ATTACHED: fprintf(stdout, " No raw devices found.\n"); return 0; case LIBMTP_ERROR_CONNECTING: fprintf(stderr, "Detect: There has been an error connecting. Exiting\n"); return 1; case LIBMTP_ERROR_MEMORY_ALLOCATION: fprintf(stderr, "Detect: Encountered a Memory Allocation Error. Exiting\n"); return 1; case LIBMTP_ERROR_NONE: break; case LIBMTP_ERROR_GENERAL: default: fprintf(stderr, "Unknown connection error.\n"); return 1; } /* Iterate over connected MTP devices */ fprintf(stdout, "Attempting to connect device(s)\n"); for (i = 0; i < numrawdevices; i++) { LIBMTP_mtpdevice_t *device; LIBMTP_devicestorage_t *storage; char *friendlyname; int ret; device = LIBMTP_Open_Raw_Device_Uncached(&rawdevices[i]); if (device == NULL) { fprintf(stderr, "Unable to open raw device %d\n", i); continue; } LIBMTP_Dump_Errorstack(device); LIBMTP_Clear_Errorstack(device); friendlyname = LIBMTP_Get_Friendlyname(device); if (friendlyname == NULL) { printf("Device: (NULL)\n"); } else { printf("Device: %s\n", friendlyname); free(friendlyname); } /* Get all storages for this device */ ret = LIBMTP_Get_Storage(device, LIBMTP_STORAGE_SORTBY_NOTSORTED); if (ret != 0) { perror("LIBMTP_Get_Storage()"); goto bailout; } /* Loop over storages */ for (storage = device->storage; storage != 0; storage = storage->next) { fprintf(stdout, "Storage: %s\n", storage->StorageDescription); recursive_file_tree(device, storage, 0, 0); } bailout: LIBMTP_Release_Device(device); } /* End For Loop */ free(rawdevices); printf("OK.\n"); return 0; }
int main (int argc, char **argv) { LIBMTP_mtpdevice_t *device_list, *iter; LIBMTP_file_t *files; fprintf(stdout, "libmtp version: " LIBMTP_VERSION_STRING "\n\n"); LIBMTP_Init(); switch(LIBMTP_Get_Connected_Devices(&device_list)) { case LIBMTP_ERROR_NO_DEVICE_ATTACHED: fprintf(stdout, "mtp-files: No Devices have been found\n"); return 0; case LIBMTP_ERROR_CONNECTING: fprintf(stderr, "mtp-files: There has been an error connecting. Exit\n"); return 1; case LIBMTP_ERROR_MEMORY_ALLOCATION: fprintf(stderr, "mtp-files: Memory Allocation Error. Exit\n"); return 1; /* Unknown general errors - This should never execute */ case LIBMTP_ERROR_GENERAL: default: fprintf(stderr, "mtp-files: Unknown error, please report " "this to the libmtp developers\n"); return 1; /* Successfully connected at least one device, so continue */ case LIBMTP_ERROR_NONE: fprintf(stdout, "mtp-files: Successfully connected\n"); fflush(stdout); } /* iterate through connected MTP devices */ for(iter = device_list; iter != NULL; iter = iter->next) { char *friendlyname; /* Echo the friendly name so we know which device we are working with */ friendlyname = LIBMTP_Get_Friendlyname(iter); if (friendlyname == NULL) { printf("Listing File Information on Device with name: (NULL)\n"); } else { printf("Listing File Information on Device with name: %s\n", friendlyname); free(friendlyname); } /* Get track listing. */ files = LIBMTP_Get_Filelisting_With_Callback(iter, NULL, NULL); if (files == NULL) { printf("No files.\n"); LIBMTP_Dump_Errorstack(iter); LIBMTP_Clear_Errorstack(iter); } else { LIBMTP_file_t *file, *tmp; file = files; while (file != NULL) { dump_fileinfo(file); tmp = file; file = file->next; LIBMTP_destroy_file_t(tmp); } } } LIBMTP_Release_Device_List(device_list); printf("OK.\n"); exit (0); }
static int add_track_to_album(LIBMTP_album_t *albuminfo, LIBMTP_track_t *trackmeta) { LIBMTP_album_t *album; LIBMTP_album_t *album_orig; LIBMTP_album_t *found_album = NULL; int ret; /* Look for the album */ album = LIBMTP_Get_Album_List(device); album_orig = album; while(album != NULL) { if ((album->name != NULL && album->artist != NULL && !strcmp(album->name, albuminfo->name) && !strcmp(album->artist, albuminfo->artist)) || (album->name != NULL && album->composer != NULL && !strcmp(album->name, albuminfo->name) && !strcmp(album->composer, albuminfo->composer))) { /* Disconnect this album for later use */ found_album = album; album = album->next; found_album->next = NULL; } else { album = album->next; } } if (found_album == NULL) { printf("Could not find Album. Retrying with only Album name\n"); album = album_orig; while(album != NULL) { if ((album->name != NULL) && !strcmp(album->name, albuminfo->name) ){ /* Disconnect this album for later use */ found_album = album; album = album->next; found_album->next = NULL; } else { album = album->next; } } } if (found_album != NULL) { uint32_t *tracks; tracks = (uint32_t *)malloc((found_album->no_tracks+1) * sizeof(uint32_t)); printf("Album \"%s\" found: updating...\n", found_album->name); if (!tracks) { printf("failed malloc in add_track_to_album()\n"); return 1; } found_album->no_tracks++; if (found_album->tracks != NULL) { memcpy(tracks, found_album->tracks, found_album->no_tracks * sizeof(uint32_t)); free(found_album->tracks); } tracks[found_album->no_tracks-1] = trackmeta->item_id; found_album->tracks = tracks; ret = LIBMTP_Update_Album(device, found_album); } else { uint32_t *trackid; trackid = (uint32_t *)malloc(sizeof(uint32_t)); *trackid = trackmeta->item_id; albuminfo->tracks = trackid; albuminfo->no_tracks = 1; albuminfo->storage_id = trackmeta->storage_id; printf("Album doesn't exist: creating...\n"); ret = LIBMTP_Create_New_Album(device, albuminfo); /* albuminfo will be destroyed later by caller */ } /* Delete the earlier retrieved Album list */ album=album_orig; while(album!=NULL){ LIBMTP_album_t *tmp; tmp = album; album = album->next; LIBMTP_destroy_album_t(tmp); } if (ret != 0) { printf("Error creating or updating album.\n"); printf("(This could be due to that your device does not support albums.)\n"); LIBMTP_Dump_Errorstack(device); LIBMTP_Clear_Errorstack(device); } else { printf("success!\n"); } return ret; }
int main (int argc, char **argv) { int opt; extern int optind; extern char *optarg; LIBMTP_mtpdevice_t *device = NULL; int idcount = 0; uint32_t *ids = NULL; uint32_t *tmp = NULL; char *playlistname = NULL; char *rest; uint32_t storageid = 0; uint32_t parentid = 0; fprintf(stdout, "libmtp version: " LIBMTP_VERSION_STRING "\n\n"); while ( (opt = getopt(argc, argv, "hn:i:s:p:")) != -1 ) { switch (opt) { case 'h': usage(); case 'i': idcount++; if ((tmp = realloc(ids, sizeof(uint32_t) * (idcount))) == NULL) { printf("realloc failed\n"); return 1; } ids = tmp; ids[(idcount-1)] = strtoul(optarg, &rest, 0); break; case 'n': playlistname = strdup(optarg); break; case 's': storageid = (uint32_t) strtoul(optarg, NULL, 0); break; case 'p': parentid = (uint32_t) strtoul(optarg, NULL, 0); break; default: usage(); } } argc -= optind; argv += optind; if ( playlistname == NULL) { printf("You need to supply a playlist name.\n"); usage(); } if (idcount == 0) { printf("You need to supply one or more track IDs\n"); usage(); } LIBMTP_Init(); device = LIBMTP_Get_First_Device(); if (device == NULL) { printf("No devices.\n"); return 0; } LIBMTP_playlist_t *playlist = LIBMTP_new_playlist_t(); playlist->name = playlistname; playlist->no_tracks = idcount; playlist->tracks = ids; playlist->parent_id = parentid; playlist->storage_id = storageid; int ret = LIBMTP_Create_New_Playlist(device,playlist); if (ret != 0) { printf("Couldn't create playlist object\n"); LIBMTP_Dump_Errorstack(device); LIBMTP_Clear_Errorstack(device); } else { printf("Created new playlist: %u\n", playlist->playlist_id); } LIBMTP_Release_Device(device); printf("OK.\n"); return 0; }
int sendtrack_function(char * from_path, char * to_path, char *partist, char *palbumartist, char *ptitle, char *pgenre, char *palbum, char *pcomposer, uint16_t tracknum, uint16_t length, uint16_t year, uint32_t storageid, uint16_t quiet) { char *filename, *parent; char artist[80], albumartist[80], title[80], genre[80], album[80], composer[80]; char num[80]; uint64_t filesize; uint32_t parent_id = 0; struct stat sb; LIBMTP_track_t *trackmeta; LIBMTP_album_t *albuminfo; int ret; printf("Sending track %s to %s\n", from_path, to_path); trackmeta = LIBMTP_new_track_t(); albuminfo = LIBMTP_new_album_t(); parent = dirname(strdup(to_path)); filename = basename(strdup(to_path)); parent_id = parse_path (parent,files,folders); if (parent_id == -1) { printf("Parent folder could not be found, skipping\n"); return 1; } if (stat(from_path, &sb) == -1) { fprintf(stderr, "%s: ", from_path); perror("stat"); return 1; } if (!S_ISREG(sb.st_mode)) return 0; filesize = sb.st_size; trackmeta->filetype = find_filetype (from_path); if (!LIBMTP_FILETYPE_IS_TRACK(trackmeta->filetype)) { printf("Not a valid track codec: \"%s\"\n", LIBMTP_Get_Filetype_Description(trackmeta->filetype)); return 1; } if ((ptitle == NULL) && (quiet == 0)) { if ( (ptitle = prompt("Title", title, 80, 0)) != NULL ) if (!strlen(ptitle)) ptitle = NULL; } if ((palbum == NULL) && (quiet == 0)) { if ( (palbum = prompt("Album", album, 80, 0)) != NULL ) if (!strlen(palbum)) palbum = NULL; } if ((palbumartist == NULL) && (quiet == 0)) { if ( (palbumartist = prompt("Album artist", albumartist, 80, 0)) != NULL ) if (!strlen(palbumartist)) palbumartist = NULL; } if ((partist == NULL) && (quiet == 0)) { if ( (partist = prompt("Artist", artist, 80, 0)) != NULL ) if (!strlen(partist)) partist = NULL; } if ((pcomposer == NULL) && (quiet == 0)) { if ( (pcomposer = prompt("Writer or Composer", composer, 80, 0)) != NULL ) if (!strlen(pcomposer)) pcomposer = NULL; } if ((pgenre == NULL) && (quiet == 0)) { if ( (pgenre = prompt("Genre", genre, 80, 0)) != NULL ) if (!strlen(pgenre)) pgenre = NULL; } if ((tracknum == 0) && (quiet == 0)) { char *pnum; if ( (pnum = prompt("Track number", num, 80, 0)) == NULL ) tracknum = 0; else tracknum = strtoul(pnum, 0, 10); } if ((year == 0) && (quiet == 0)) { char *pnum; if ( (pnum = prompt("Year", num, 80, 0)) == NULL ) year = 0; else year = strtoul(pnum, 0, 10); } if ((length == 0) && (quiet == 0)) { char *pnum; if ( (pnum = prompt("Length", num, 80, 0)) == NULL ) length = 0; else length = strtoul(pnum, 0, 10); } printf("Sending track:\n"); printf("Codec: %s\n", LIBMTP_Get_Filetype_Description(trackmeta->filetype)); if (ptitle) { printf("Title: %s\n", ptitle); trackmeta->title = strdup(ptitle); } if (palbum) { printf("Album: %s\n", palbum); trackmeta->album = strdup(palbum); albuminfo->name = strdup(palbum); } if (palbumartist) { printf("Album artist: %s\n", palbumartist); albuminfo->artist = strdup(palbumartist); } if (partist) { printf("Artist: %s\n", partist); trackmeta->artist = strdup(partist); if (palbumartist == NULL) albuminfo->artist = strdup(partist); } if (pcomposer) { printf("Writer or Composer: %s\n", pcomposer); trackmeta->composer = strdup(pcomposer); albuminfo->composer = strdup(pcomposer); } if (pgenre) { printf("Genre: %s\n", pgenre); trackmeta->genre = strdup(pgenre); albuminfo->genre = strdup(pgenre); } if (year > 0) { char tmp[80]; printf("Year: %d\n", year); snprintf(tmp, sizeof(tmp)-1, "%4d0101T0000.0", year); tmp[sizeof(tmp)-1] = '\0'; trackmeta->date = strdup(tmp); } if (tracknum > 0) { printf("Track no: %d\n", tracknum); trackmeta->tracknumber = tracknum; } if (length > 0) { printf("Length: %d\n", length); // Multiply by 1000 since this is in milliseconds trackmeta->duration = length * 1000; } // We should always have this if (filename != NULL) { trackmeta->filename = strdup(filename); } trackmeta->filesize = filesize; trackmeta->parent_id = parent_id; { int rc; char *desc = NULL; LIBMTP_devicestorage_t *pds = NULL; if (0 != (rc=LIBMTP_Get_Storage(device, LIBMTP_STORAGE_SORTBY_NOTSORTED))) { perror("LIBMTP_Get_Storage()"); exit(-1); } for (pds = device->storage; pds != NULL; pds = pds->next) { if (pds->id == storageid) { desc = strdup(pds->StorageDescription); break; } } if (NULL != desc) { printf("Storage ID: %s (%u)\n", desc, storageid); free(desc); } else printf("Storage ID: %u\n", storageid); trackmeta->storage_id = storageid; } printf("Sending track...\n"); ret = LIBMTP_Send_Track_From_File(device, from_path, trackmeta, progress, NULL); printf("\n"); if (ret != 0) { printf("Error sending track.\n"); LIBMTP_Dump_Errorstack(device); LIBMTP_Clear_Errorstack(device); ret = 1; } else { printf("New track ID: %d\n", trackmeta->item_id); } /* Add here add to album call */ if (palbum) ret = add_track_to_album(albuminfo, trackmeta); LIBMTP_destroy_album_t(albuminfo); LIBMTP_destroy_track_t(trackmeta); return ret; }
int MTPDevice::rename(const std::string &oldpath, const std::string &newpath) { #ifndef SMTPFS_MOVE_BY_SET_OBJECT_PROPERTY const std::string tmp_old_basename(smtpfs_basename(oldpath)); const std::string tmp_old_dirname(smtpfs_dirname(oldpath)); const std::string tmp_new_dirname(smtpfs_dirname(newpath)); if (tmp_old_dirname != tmp_new_dirname) return -EINVAL; const TypeDir *dir_parent = dirFetchContent(tmp_old_dirname); if (!dir_parent || dir_parent->id() == 0) return -EINVAL; const TypeDir *dir_to_rename = dir_parent->dir(tmp_old_basename); if (dir_to_rename) return dirRename(oldpath, newpath); else return fileRename(oldpath, newpath); #else const std::string tmp_old_basename(smtpfs_basename(oldpath)); const std::string tmp_old_dirname(smtpfs_dirname(oldpath)); const std::string tmp_new_basename(smtpfs_basename(newpath)); const std::string tmp_new_dirname(smtpfs_dirname(newpath)); const TypeDir *dir_old_parent = dirFetchContent(tmp_old_dirname); const TypeDir *dir_new_parent = dirFetchContent(tmp_new_dirname); const TypeDir *dir_to_rename = dir_old_parent ? dir_old_parent->dir(tmp_old_basename) : nullptr; const TypeFile *file_to_rename = dir_old_parent ? dir_old_parent->file(tmp_old_basename) : nullptr; logdebug("dir_to_rename: ", dir_to_rename, "\n"); logdebug("file_to_rename: ", file_to_rename, "\n"); if (!dir_old_parent || !dir_new_parent || dir_old_parent->id() == 0) return -EINVAL; const TypeBasic *object_to_rename = dir_to_rename ? static_cast<const TypeBasic*>(dir_to_rename) : static_cast<const TypeBasic*>(file_to_rename); logdebug("object_to_rename: ", object_to_rename, "\n"); logdebug("object_to_rename->id(): ", object_to_rename->id(), "\n"); if (!object_to_rename) { logerr("No such file or directory to rename/move!\n"); return -ENOENT; } if (tmp_old_dirname != tmp_new_dirname) { criticalEnter(); int rval = LIBMTP_Set_Object_u32(m_device, object_to_rename->id(), LIBMTP_PROPERTY_ParentObject, dir_new_parent->id()); criticalLeave(); if (rval != 0) { logerr("Could not move '", oldpath, "' to '", newpath, "'.\n"); LIBMTP_Dump_Errorstack(m_device); LIBMTP_Clear_Errorstack(m_device); return -EINVAL; } const_cast<TypeBasic*>(object_to_rename)->setParent(dir_new_parent->id()); } if (tmp_old_basename != tmp_new_basename) { criticalEnter(); int rval = LIBMTP_Set_Object_String(m_device, object_to_rename->id(), LIBMTP_PROPERTY_Name, tmp_new_basename.c_str()); criticalLeave(); if (rval != 0) { logerr("Could not rename '", oldpath, "' to '", newpath, "'.\n"); LIBMTP_Dump_Errorstack(m_device); LIBMTP_Clear_Errorstack(m_device); return -EINVAL; } } return 0; #endif }
int main (int argc, char **argv) { LIBMTP_raw_device_t *rawdevices; int numrawdevices; int i; LIBMTP_Init(); printf("Attempting to connect device(s)\n"); switch (LIBMTP_Detect_Raw_Devices(&rawdevices, &numrawdevices)) { case LIBMTP_ERROR_NO_DEVICE_ATTACHED: printf("mtp-folders: no devices found\n"); return 0; case LIBMTP_ERROR_CONNECTING: fprintf(stderr, "mtp-folders: There has been an error connecting. Exit\n"); return 1; case LIBMTP_ERROR_MEMORY_ALLOCATION: fprintf(stderr, "mtp-folders: Memory Allocation Error. Exit\n"); return 1; /* Unknown general errors - This should never execute */ case LIBMTP_ERROR_GENERAL: default: fprintf(stderr, "mtp-folders: Unknown error, please report " "this to the libmtp developers\n"); return 1; /* Successfully connected at least one device, so continue */ case LIBMTP_ERROR_NONE: printf("mtp-folders: Successfully connected\n"); } /* iterate through connected MTP devices */ for (i = 0; i < numrawdevices; i++) { LIBMTP_mtpdevice_t *device; LIBMTP_devicestorage_t *storage; char *friendlyname; int ret; device = LIBMTP_Open_Raw_Device(&rawdevices[i]); if (device == NULL) { fprintf(stderr, "Unable to open raw device %d\n", i); continue; } /* Echo the friendly name so we know which device we are working with */ friendlyname = LIBMTP_Get_Friendlyname(device); if (friendlyname == NULL) { printf("Friendly name: (NULL)\n"); } else { printf("Friendly name: %s\n", friendlyname); free(friendlyname); } LIBMTP_Dump_Errorstack(device); LIBMTP_Clear_Errorstack(device); /* Get all storages for this device */ ret = LIBMTP_Get_Storage(device, LIBMTP_STORAGE_SORTBY_NOTSORTED); if (ret != 0) { perror("LIBMTP_Get_Storage()\n"); LIBMTP_Dump_Errorstack(device); LIBMTP_Clear_Errorstack(device); continue; } /* Loop over storages, dump folder for each one */ for (storage = device->storage; storage != 0; storage = storage->next) { LIBMTP_folder_t *folders; printf("Storage: %s\n", storage->StorageDescription); folders = LIBMTP_Get_Folder_List_For_Storage(device, storage->id); if (folders == NULL) { fprintf(stdout, "No folders found\n"); LIBMTP_Dump_Errorstack(device); LIBMTP_Clear_Errorstack(device); } else { dump_folder_list(folders,0); } LIBMTP_destroy_folder_t(folders); } LIBMTP_Release_Device(device); } free(rawdevices); printf("OK.\n"); return 0; }
void Plugin::AppendAlbum (LIBMTP_mtpdevice_t *device, LIBMTP_track_t *track, const UnmountableFileInfo& info) { auto albuminfo = LIBMTP_new_album_t (); albuminfo->artist = strdup (info.Artist_.toUtf8 ().constData ()); albuminfo->name = strdup (info.Album_.toUtf8 ().constData ()); albuminfo->genre = strdup (info.Genres_.join ("; ").toUtf8 ().constData ()); auto album = LIBMTP_Get_Album_List (device); auto albumOrig = album; decltype (album) foundAlbum = nullptr, resultingAlgum = nullptr; while (album) { if (album->name && (album->artist || album->composer) && QString::fromUtf8 (album->name) == info.Album_ && (QString::fromUtf8 (album->artist) == info.Artist_ || QString::fromUtf8 (album->composer) == info.Artist_)) { foundAlbum = album; album = album->next; foundAlbum->next = nullptr; } else album = album->next; } if (foundAlbum) { auto tracks = static_cast<uint32_t*> (malloc ((foundAlbum->no_tracks + 1) * sizeof (uint32_t))); ++foundAlbum->no_tracks; if (foundAlbum->tracks) { memcpy (tracks, foundAlbum->tracks, foundAlbum->no_tracks * sizeof (uint32_t)); free (foundAlbum->tracks); } tracks [foundAlbum->no_tracks - 1] = track->item_id; foundAlbum->tracks = tracks; if (LIBMTP_Update_Album (device, foundAlbum)) { LIBMTP_Dump_Errorstack (device); LIBMTP_Clear_Errorstack (device); } resultingAlgum = foundAlbum; } else { auto trackId = static_cast<uint32_t*> (malloc (sizeof (uint32_t))); *trackId = track->item_id; albuminfo->tracks = trackId; albuminfo->no_tracks = 1; albuminfo->storage_id = track->storage_id; if (LIBMTP_Create_New_Album (device, albuminfo)) { LIBMTP_Dump_Errorstack (device); LIBMTP_Clear_Errorstack (device); } resultingAlgum = albuminfo; } SetAlbumArt (device, resultingAlgum, info.AlbumArtPath_); while (albumOrig) { auto tmp = albumOrig; albumOrig = albumOrig->next; LIBMTP_destroy_album_t (tmp); } LIBMTP_destroy_album_t (albuminfo); }