static void _push_dir_cb (GFile *file, GAsyncResult *res, MpdStorageDevice *self) { MpdStorageDevicePrivate *priv = GET_PRIVATE (self); GFileEnumerator *enumerator; GError *error = NULL; g_return_if_fail (G_IS_FILE (file)); /* Debug */ char *indent = g_strnfill (g_slist_length (priv->dir_stack), ' '); char *path = g_file_get_path (file); g_debug ("%s%s", indent, path); g_free (path); g_free (indent); enumerator = g_file_enumerate_children_finish (file, res, &error); if (error) { g_critical ("%s : %s", G_STRLOC, error->message); g_clear_error (&error); return; } /* g_file_enumerator_get_container () fails on us. */ g_object_set_data_full (G_OBJECT (enumerator), "path", g_file_get_path (file), g_free); priv->dir_stack = g_slist_prepend (priv->dir_stack, g_object_ref (enumerator)); enumerate_dir (self); g_object_unref (enumerator); }
static int process_suffix(const char *prefixes, const char *suffix) { const char *p; char *f; Hashmap *top, *bottom=NULL; int r = 0, k; Iterator i; int n_found = 0; assert(prefixes); assert(suffix); top = hashmap_new(string_hash_func, string_compare_func); if (!top) { r = -ENOMEM; goto finish; } bottom = hashmap_new(string_hash_func, string_compare_func); if (!bottom) { r = -ENOMEM; goto finish; } NULSTR_FOREACH(p, prefixes) { _cleanup_free_ char *t = NULL; t = strjoin(p, "/", suffix, NULL); if (!t) { r = -ENOMEM; goto finish; } k = enumerate_dir(top, bottom, t); if (k < 0) r = k; log_debug("Looking at %s", t); }
static void enumerate_dir (MpdStorageDevice *self) { MpdStorageDevicePrivate *priv = GET_PRIVATE (self); GFileEnumerator *enumerator; GFileInfo *info; GError *error = NULL; g_return_if_fail (priv->dir_stack); enumerator = G_FILE_ENUMERATOR (priv->dir_stack->data); g_return_if_fail (G_IS_FILE_ENUMERATOR (enumerator)); while (NULL != (info = g_file_enumerator_next_file (enumerator, NULL, &error))) { char const *content_type = g_file_info_get_content_type (info); char const *name = g_file_info_get_name (info); /* Debug */ char *indent = g_strnfill (g_slist_length (priv->dir_stack), ' '); g_debug ("%s%s %s", indent, name, content_type); g_free (indent); /* Do not recurse into "dot" directories, they are use for trash. */ if (0 == g_strcmp0 ("inode/directory", content_type) && name[0] != '.') { char const *path = g_object_get_data (G_OBJECT (enumerator), "path"); char *subpath = g_build_filename (path, name, NULL); GFile *subdir = file_new_for_path (subpath); /* Push and recurse. */ push_dir_async (self, subdir); file_destroy (subdir); g_free (subpath); break; } else if (g_str_has_prefix (content_type, "audio/") || g_str_has_prefix (content_type, "image/") || g_str_has_prefix (content_type, "video/")) { /* Media found. */ char const *path = g_object_get_data (G_OBJECT (enumerator), "path"); char *filename = g_build_filename (path, name, NULL); priv->media_files = g_slist_prepend (priv->media_files, filename); priv->media_files_size += g_file_info_get_size (info); } g_object_unref (info); } if (info) { /* Broke out of loop, not done yet. */ g_object_unref (info); } else { /* Directory finished, pop. */ g_object_unref (enumerator); priv->dir_stack = g_slist_delete_link (priv->dir_stack, priv->dir_stack); if (priv->dir_stack) { enumerate_dir (self); } else { /* Done iterating. */ g_signal_emit_by_name (self, "has-media", (bool) priv->media_files); } } if (error) { g_critical ("%s : %s", G_STRLOC, error->message); g_clear_error (&error); } }