int main (int argc, char **argv) { int do_delete = 0; int opt; fprintf(stdout, "libmtp version: " LIBMTP_VERSION_STRING "\n\n"); while ( (opt = getopt(argc, argv, "d")) != -1 ) { switch (opt) { case 'd': do_delete = 1; break; default: break; } } if(do_delete == 0) { printf("This is a dummy run. No folders will be deleted.\n"); printf("To delete folders, use the '-d' option.\n"); } LIBMTP_mtpdevice_t *device; LIBMTP_folder_t *folders; LIBMTP_file_t *files; LIBMTP_Init(); device = LIBMTP_Get_First_Device(); if (device == NULL) { printf("No devices.\n"); exit (0); } files = LIBMTP_Get_Filelisting_With_Callback(device,NULL,NULL); folders = LIBMTP_Get_Folder_List(device); if(folders == NULL) { printf("No folders found\n"); } else { prune_empty_folders(device,files,folders,do_delete); } LIBMTP_destroy_folder_t(folders); LIBMTP_destroy_file_t(files); LIBMTP_Release_Device(device); printf("OK.\n"); exit (0); }
static PyObject* file_metadata(LIBMTP_mtpdevice_t *device, PyObject *errs, uint32_t item_id, uint32_t storage_id) { LIBMTP_file_t *nf; PyObject *ans = NULL; Py_BEGIN_ALLOW_THREADS; nf = LIBMTP_Get_Filemetadata(device, item_id); Py_END_ALLOW_THREADS; if (nf == NULL) dump_errorstack(device, errs); else { ans = build_file_metadata(nf, storage_id); LIBMTP_destroy_file_t(nf); } return ans; }
static int recursive_get_files(LIBMTP_mtpdevice_t *dev, uint32_t storage_id, uint32_t parent_id, PyObject *ans, PyObject *errs, PyObject *callback, unsigned int level) { LIBMTP_file_t *f, *files; PyObject *entry, *r; int ok = 1, recurse; Py_BEGIN_ALLOW_THREADS; files = LIBMTP_Get_Files_And_Folders(dev, storage_id, parent_id); Py_END_ALLOW_THREADS; if (files == NULL) return ok; for (f = files; ok && f != NULL; f = f->next) { entry = build_file_metadata(f, storage_id); if (entry == NULL) { ok = 0; } else { r = PyObject_CallFunction(callback, "OI", entry, level); recurse = (r != NULL && PyObject_IsTrue(r)) ? 1 : 0; Py_XDECREF(r); if (PyList_Append(ans, entry) != 0) { ok = 0; } Py_DECREF(entry); } if (ok && recurse && f->filetype == LIBMTP_FILETYPE_FOLDER) { if (!recursive_get_files(dev, storage_id, f->item_id, ans, errs, callback, level+1)) { ok = 0; } } } // Release memory f = files; while (f != NULL) { files = f; f = f->next; LIBMTP_destroy_file_t(files); } return ok; }
static void delete_done_cb (LIBMTP_mtpdevice_t *device, TracksDeletedCallbackData *data) { LIBMTP_folder_t *folders; LIBMTP_file_t *files; data->actually_free = FALSE; update_free_space_cb (device, RB_MTP_SOURCE (data->source)); /* if any of the folders we just deleted from are now empty, delete them */ folders = LIBMTP_Get_Folder_List (device); files = LIBMTP_Get_Filelisting_With_Callback (device, NULL, NULL); if (folders != NULL) { GHashTableIter iter; gpointer key; g_hash_table_iter_init (&iter, data->check_folders); while (g_hash_table_iter_next (&iter, &key, NULL)) { LIBMTP_folder_t *f; LIBMTP_folder_t *c; LIBMTP_file_t *file; uint32_t folder_id = GPOINTER_TO_UINT(key); while (folder_id != device->default_music_folder && folder_id != 0) { f = LIBMTP_Find_Folder (folders, folder_id); if (f == NULL) { rb_debug ("unable to find folder %u", folder_id); break; } /* don't delete folders with children that we didn't just delete */ for (c = f->child; c != NULL; c = c->sibling) { if (g_hash_table_lookup (data->check_folders, GUINT_TO_POINTER (c->folder_id)) == NULL) { break; } } if (c != NULL) { rb_debug ("folder %s has children", f->name); break; } /* don't delete folders that contain files */ for (file = files; file != NULL; file = file->next) { if (file->parent_id == folder_id) { break; } } if (file != NULL) { rb_debug ("folder %s contains at least one file: %s", f->name, file->filename); break; } /* ok, the folder is empty */ rb_debug ("deleting empty folder %s", f->name); LIBMTP_Delete_Object (device, f->folder_id); /* if the folder we just deleted has siblings, the parent * can't be empty. */ if (f->sibling != NULL) { rb_debug ("folder %s has siblings, can't delete parent", f->name); break; } folder_id = f->parent_id; } } LIBMTP_destroy_folder_t (folders); } else { rb_debug ("unable to get device folder list"); } /* clean up the file list */ while (files != NULL) { LIBMTP_file_t *n; n = files->next; LIBMTP_destroy_file_t (files); files = n; } g_idle_add ((GSourceFunc) delete_done_idle_cb, data); }
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 void download_track (RBMtpThread *thread, RBMtpThreadTask *task) { LIBMTP_file_t *fileinfo; LIBMTP_error_t *stack; GError *error = NULL; GFile *dir; RBMtpDownloadCallback cb = (RBMtpDownloadCallback) task->callback; /* first, check there's enough space to copy it */ fileinfo = LIBMTP_Get_Filemetadata (thread->device, task->track_id); if (fileinfo == NULL) { stack = LIBMTP_Get_Errorstack (thread->device); rb_debug ("unable to get track metadata for %u: %s", task->track_id, stack->error_text); error = g_error_new (RB_MTP_THREAD_ERROR, RB_MTP_THREAD_ERROR_GET_TRACK, _("Unable to copy file from MTP device: %s"), stack->error_text); LIBMTP_Clear_Errorstack (thread->device); cb (task->track_id, NULL, error, task->user_data); g_error_free (error); return; } if (task->filename[0] == '\0') { dir = g_file_new_for_path (g_get_tmp_dir ()); } else { GFile *file = g_file_new_for_path (task->filename); dir = g_file_get_parent (file); g_object_unref (file); } rb_debug ("checking for %" G_GINT64_FORMAT " bytes available", fileinfo->filesize); if (rb_check_dir_has_space (dir, fileinfo->filesize) == FALSE) { char *dpath = g_file_get_path (dir); rb_debug ("not enough space in %s", dpath); error = g_error_new (RB_MTP_THREAD_ERROR, RB_MTP_THREAD_ERROR_NO_SPACE, _("Not enough space in %s"), dpath); g_free (dpath); } LIBMTP_destroy_file_t (fileinfo); g_object_unref (dir); if (error != NULL) { rb_debug ("bailing out due to error: %s", error->message); cb (task->track_id, NULL, error, task->user_data); g_error_free (error); return; } if (task->filename[0] == '\0') { /* download to a temporary file */ int fd; GError *tmperror = NULL; g_free (task->filename); fd = g_file_open_tmp ("rb-mtp-temp-XXXXXX", &task->filename, &tmperror); if (fd == -1) { rb_debug ("unable to open temporary file: %s", tmperror->message); error = g_error_new (RB_MTP_THREAD_ERROR, RB_MTP_THREAD_ERROR_TEMPFILE, _("Unable to open temporary file: %s"), tmperror->message); g_error_free (tmperror); cb (task->track_id, NULL, error, task->user_data); g_error_free (error); return; } else { rb_debug ("downloading track %u to file descriptor %d", task->track_id, fd); if (LIBMTP_Get_Track_To_File_Descriptor (thread->device, task->track_id, fd, NULL, NULL)) { stack = LIBMTP_Get_Errorstack (thread->device); rb_debug ("unable to retrieve track %u: %s", task->track_id, stack->error_text); error = g_error_new (RB_MTP_THREAD_ERROR, RB_MTP_THREAD_ERROR_GET_TRACK, _("Unable to copy file from MTP device: %s"), stack->error_text); LIBMTP_Clear_Errorstack (thread->device); cb (task->track_id, NULL, error, task->user_data); g_error_free (error); close (fd); remove (task->filename); return; } rb_debug ("done downloading track"); close (fd); } } else { if (LIBMTP_Get_Track_To_File (thread->device, task->track_id, task->filename, NULL, NULL)) { stack = LIBMTP_Get_Errorstack (thread->device); error = g_error_new (RB_MTP_THREAD_ERROR, RB_MTP_THREAD_ERROR_GET_TRACK, _("Unable to copy file from MTP device: %s"), stack->error_text); LIBMTP_Clear_Errorstack (thread->device); cb (task->track_id, NULL, error, task->user_data); g_error_free (error); return; } } cb (task->track_id, task->filename, NULL, task->user_data); }
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; }