void list_plugins (cli_infos_t *infos, xmmsc_result_t *res) { const gchar *name, *desc, *err; xmmsv_t *val; val = xmmsc_result_get_value (res); if (!xmmsv_get_error (val, &err)) { xmmsv_list_iter_t *it; xmmsv_get_list_iter (val, &it); for (xmmsv_list_iter_first (it); xmmsv_list_iter_valid (it); xmmsv_list_iter_next (it)) { xmmsv_t *elem; xmmsv_list_iter_entry (it, &elem); xmmsv_dict_entry_get_string (elem, "shortname", &name); xmmsv_dict_entry_get_string (elem, "description", &desc); g_printf ("%s - %s\n", name, desc); } } else { g_printf (_("Server error: %s\n"), err); } xmmsc_result_unref (res); cli_infos_loop_resume (infos); }
static gboolean run_tests (xmms_medialib_t *medialib, xmmsv_t *testcases, xmms_test_predicate predicate, gint format, const gchar *datasetname) { xmmsv_list_iter_t *it; xmmsv_t *dict; gboolean result = TRUE; xmmsv_get_list_iter (testcases, &it); while (xmmsv_list_iter_entry (it, &dict)) { xmmsv_t *content, *specification, *expected, *coll; const gchar *name; xmmsv_dict_entry_get_string (dict, "name", &name); xmmsv_dict_get (dict, "medialib", &content); xmmsv_dict_get (dict, "specification", &specification); xmmsv_dict_get (dict, "collection", &coll); xmmsv_dict_get (dict, "expected", &expected); result &= predicate (medialib, name, content, coll, specification, expected, format, datasetname); xmmsv_list_iter_next (it); } return result; }
static void run_tests (xmms_medialib_t *medialib, xmmsv_t *testcases, xmms_test_predicate predicate, gint format, const gchar *datasetname) { xmmsv_list_iter_t *it; xmmsv_get_list_iter (testcases, &it); while (xmmsv_list_iter_valid (it)) { xmmsv_t *dict, *content, *specification, *holder, *expected; xmmsv_coll_t *coll; const gchar *name; dict = NULL; g_assert (xmmsv_list_iter_entry (it, &dict)); xmmsv_dict_entry_get_string (dict, "name", &name); xmmsv_dict_get (dict, "medialib", &content); xmmsv_dict_get (dict, "specification", &specification); xmmsv_dict_get (dict, "collection", &holder); xmmsv_dict_get (dict, "expected", &expected); xmmsv_get_coll (holder, &coll); predicate (medialib, name, content, coll, specification, expected, format, datasetname); xmmsv_list_iter_next (it); } }
/* Extract the string value out of a xmmsv_t object. */ static const gchar * value_get_dict_string (xmmsv_t *val, const gchar *key) { const gchar *s; xmmsv_dict_entry_get_string (val, key, &s); return s; }
static xmmsv_t * parse_collection (xmmsv_t *dict) { xmmsv_coll_type_t type = 0; xmmsv_t *coll; xmmsv_t *attributes, *operands, *list; const char *name; assert (xmmsv_is_type (dict, XMMSV_TYPE_DICT)); xmmsv_dict_entry_get_string (dict, "type", &name); assert (collection_type_from_string (name, &type)); coll = xmmsv_new_coll (type); if (xmmsv_dict_get (dict, "attributes", &attributes)) parse_attributes (coll, attributes); if (xmmsv_dict_get (dict, "operands", &operands)) parse_operands (coll, operands); if (xmmsv_dict_get (dict, "idlist", &list)) parse_idlist (coll, list); return coll; }
/** * Signals callback */ static void xmms_playlist_updater_need_update (xmms_object_t *object, xmmsv_t *val, gpointer udata) { xmms_playlist_updater_t *updater = (xmms_playlist_updater_t *) udata; const gchar *plname, *ns; if (xmmsv_dict_entry_get_string (val, "namespace", &ns)) { if (g_strcmp0 (ns, XMMS_COLLECTION_NS_PLAYLISTS) != 0) { return; } } if (!xmmsv_dict_entry_get_string (val, "name", &plname)) { return; } xmms_playlist_updater_push (updater, plname); }
static void on_collection_changed (xmms_object_t *object, xmmsv_t *val, gpointer udata) { xmms_playlist_t *playlist = (xmms_playlist_t *) udata; const gchar *ns, *name; g_return_if_fail (playlist); g_return_if_fail (xmmsv_is_type (val, XMMSV_TYPE_DICT)); g_return_if_fail (xmmsv_dict_entry_get_string (val, "namespace", &ns)); if (strcmp (ns, XMMS_COLLECTION_NS_PLAYLISTS) != 0) { /* Not a playlist, not our concern... */ return; } g_return_if_fail (xmmsv_dict_entry_get_string (val, "name", &name)); XMMS_PLAYLIST_CHANGED_MSG (XMMS_PLAYLIST_CHANGED_UPDATE, 0, name); }
static int handle_stats (xmmsv_t *v, void *userdata) { const gchar *tstr; if (xmmsv_dict_entry_get_string (v, "version", &tstr)) { server_version = g_strdup (tstr); } return TRUE; }
static gint update_active_playlist (xmmsv_t *val, void *udata) { cli_infos_t *infos = (cli_infos_t *) udata; cli_cache_t *cache = infos->cache; xmmsc_result_t *refres; gint pos, newpos, type; gint id; const gchar *name; xmmsv_dict_entry_get_int (val, "type", &type); xmmsv_dict_entry_get_int (val, "position", &pos); xmmsv_dict_entry_get_int (val, "id", &id); xmmsv_dict_entry_get_string (val, "name", &name); /* Active playlist not changed, nevermind */ if (strcmp (name, cache->active_playlist_name) != 0) { return TRUE; } /* Apply changes to the cached playlist */ switch (type) { case XMMS_PLAYLIST_CHANGED_ADD: g_array_append_val (cache->active_playlist, id); break; case XMMS_PLAYLIST_CHANGED_INSERT: g_array_insert_val (cache->active_playlist, pos, id); break; case XMMS_PLAYLIST_CHANGED_MOVE: xmmsv_dict_entry_get_int (val, "newposition", &newpos); g_array_remove_index (cache->active_playlist, pos); g_array_insert_val (cache->active_playlist, newpos, id); break; case XMMS_PLAYLIST_CHANGED_REMOVE: g_array_remove_index (cache->active_playlist, pos); break; case XMMS_PLAYLIST_CHANGED_SHUFFLE: case XMMS_PLAYLIST_CHANGED_SORT: case XMMS_PLAYLIST_CHANGED_CLEAR: /* Oops, reload the whole playlist */ refres = xmmsc_playlist_list_entries (infos->conn, XMMS_ACTIVE_PLAYLIST); xmmsc_result_notifier_set (refres, &refresh_active_playlist, infos->cache); xmmsc_result_unref (refres); freshness_requested (&cache->freshness_active_playlist); break; } return TRUE; }
void plugin_config_setup (xmmsc_connection_t *con) { xmmsc_result_t* res; xmmsv_t *val; const gchar *err, *name; /* call only once */ g_assert(plugins == NULL ); /* get translation of plugins/configs */ plugin_config_init_translation(); /* get list of available plugins */ res = xmmsc_main_list_plugins (con, XMMS_PLUGIN_TYPE_OUTPUT); /* we havn't entered async xmmsc_mainloop, so it's ok todo sync ops */ xmmsc_result_wait (res); val = xmmsc_result_get_value (res); if (!xmmsv_get_error (val, &err)) { xmmsv_list_iter_t *it; xmmsv_get_list_iter (val, &it); for (xmmsv_list_iter_first (it); xmmsv_list_iter_valid (it); xmmsv_list_iter_next (it)) { xmmsv_t *elem; Plugin *plugin; xmmsv_list_iter_entry (it, &elem); xmmsv_dict_entry_get_string (elem, "shortname", &name); /* not blacklisted */ if ( g_strrstr( PLUGIN_BLACKLIST, name ) != NULL ) continue; plugin = g_slice_new( Plugin ); plugin->name = g_strdup(name); plugin->config = NULL; plugins = g_list_append(plugins, plugin); } } else { g_error ( "Server error: %s", err); } xmmsc_result_unref (res); /* get configuration options */ res = xmmsc_config_list_values (con ); xmmsc_result_wait (res); val = xmmsc_result_get_value (res); xmmsv_dict_foreach( val, plugin_config_setup_parameter, NULL); }
static int handle_config (xmmsv_t *v, void *userdata) { const gchar *value; if (!xmmsv_dict_entry_get_string (v, "output.plugin", &value)) return TRUE; g_free (output_plugin); output_plugin = g_strdup (value); return TRUE; }
static gint update_active_playlist_name (xmmsv_t *val, void *udata) { cli_cache_t *cache = (cli_cache_t *) udata; gint type; const gchar *name, *newname; xmmsv_dict_entry_get_int (val, "type", &type); xmmsv_dict_entry_get_string (val, "name", &name); /* Active playlist have not been renamed */ if (strcmp (name, cache->active_playlist_name) != 0) { return TRUE; } if (type == XMMS_COLLECTION_CHANGED_RENAME) { g_free (cache->active_playlist_name); xmmsv_dict_entry_get_string (val, "newname", &newname); cache->active_playlist_name = g_strdup (newname); } return TRUE; }
static int updater_config_changed (xmmsv_t *value, void *udata) { updater_t *updater = (updater_t *) udata; const gchar *path; g_return_val_if_fail (updater, FALSE); if (xmmsv_dict_entry_get_string (value, "clients.mlibupdater.watch_dirs", &path)) { if (*path) { updater_switch_directory (updater, path); } } return TRUE; }
static int handle_config_changed (xmmsv_t *v, void *data) { xmonitor_t *mon = data; const gchar *val = NULL; int s; s = xmmsv_dict_entry_get_string (v, "clients.mlibupdater.watch_dirs", &val); if (s) { do_watch_dir (mon, val); } return TRUE; /* keep broadcast alive */ }
/** * Recursively scan a directory for media files. * * @return a reverse sorted list of encoded urls */ static gboolean process_dir (xmms_medialib_t *medialib, xmmsv_t *entries, const gchar *directory, xmms_error_t *error) { xmmsv_list_iter_t *it; xmmsv_t *list, *val; list = xmms_xform_browse (directory, error); if (!list) { return FALSE; } xmmsv_get_list_iter (list, &it); while (xmmsv_list_iter_entry (it, &val)) { const gchar *str; gint isdir; xmmsv_dict_entry_get_string (val, "path", &str); xmmsv_dict_entry_get_int (val, "isdir", &isdir); if (isdir == 1) { process_dir (medialib, entries, str, error); } else { xmms_medialib_session_t *session; xmms_medialib_entry_t entry; do { session = xmms_medialib_session_begin (medialib); entry = xmms_medialib_entry_new_encoded (session, str, error); } while (!xmms_medialib_session_commit (session)); if (entry) { xmmsv_coll_idlist_append (entries, entry); } } xmmsv_list_iter_remove (it); } xmmsv_unref (list); return TRUE; }
static void print_server_stats (xmmsc_result_t *res) { gint uptime; const gchar *version, *err; xmmsv_t *val; val = xmmsc_result_get_value (res); if (!xmmsv_get_error (val, &err)) { xmmsv_dict_entry_get_string (val, "version", &version); xmmsv_dict_entry_get_int (val, "uptime", &uptime); g_printf ("uptime = %d\n" "version = %s\n", uptime, version); } else { g_printf ("Server error: %s\n", err); } }
void xmms_playlist_changed_msg_send (xmms_playlist_t *playlist, xmmsv_t *dict) { const gchar *plname; gint type; g_return_if_fail (playlist); g_return_if_fail (dict); /* If local playlist change, trigger a COLL_CHANGED signal */ if (xmmsv_dict_entry_get_int (dict, "type", &type) && xmmsv_dict_entry_get_string (dict, "name", &plname) && type != XMMS_PLAYLIST_CHANGED_UPDATE) { XMMS_COLLECTION_PLAYLIST_CHANGED_MSG (playlist->colldag, plname); } xmms_object_emit (XMMS_OBJECT (playlist), XMMS_IPC_SIGNAL_PLAYLIST_CHANGED, dict); }
static int handle_mediainfo (xmmsv_t *v, void *userdata) { static const gchar *props[] = {"chain", NULL}; static const gchar *pref[] = {"server", NULL}; GString *str; const gchar *tstr; gint tint, i; xmmsv_t *dict; str = g_string_new (""); /* convert propdict to dict */ dict = xmmsv_propdict_to_dict (v, pref); for (i = 0; props[i]; i++) { switch (xmmsv_dict_entry_get_type (dict, props[i])) { case XMMSV_TYPE_STRING: if (xmmsv_dict_entry_get_string (dict, props[i], &tstr)) { g_string_append_printf (str, "%s=%s\n", props[i], tstr); } break; case XMMSV_TYPE_INT32: if (xmmsv_dict_entry_get_int (dict, props[i], &tint)) { g_string_append_printf (str, "%s=%d\n", props[i], tint); } break; default: /* noop */ break; } } send_msg ("New media", str); g_string_free (str, TRUE); return TRUE; /* keep broadcast alive */ }
static gint normalize_aggregate_function (xmmsv_t *fetch, xmms_error_t *err) { const gchar *name; guint32 aggregate; if (xmmsv_dict_entry_get_type (fetch, "aggregate") == XMMSV_TYPE_NONE) { xmmsv_dict_set_string (fetch, "aggregate", "first"); } /* Default to first as the aggregation function */ if (!xmmsv_dict_entry_get_string (fetch, "aggregate", &name)) { xmms_error_set (err, XMMS_ERROR_INVAL, "'aggregate' must be a string."); return -1; } if (!aggregate_value_from_string (name, &aggregate)) { const gchar *message = "'aggregate' must be 'first', 'sum', 'max', 'min', 'list', 'set', 'random', or 'avg'"; xmms_error_set (err, XMMS_ERROR_INVAL, message); return -1; } return aggregate; }
/** * Converts a fetch specification in xmmsv_t form into a * fetch_spec_t structure */ xmms_fetch_spec_t * xmms_fetch_spec_new (xmmsv_t *fetch, xmms_fetch_info_t *info, s4_sourcepref_t *prefs, xmms_error_t *err) { const char *type; if (xmmsv_get_type (fetch) != XMMSV_TYPE_DICT) { xmms_error_set (err, XMMS_ERROR_INVAL, "A fetch specification must be a dict."); return NULL; } if (xmmsv_dict_entry_get_type (fetch, "type") == XMMSV_TYPE_NONE) { xmmsv_dict_set_string (fetch, "type", "metadata"); } if (!xmmsv_dict_entry_get_string (fetch, "type", &type)) { xmms_error_set (err, XMMS_ERROR_INVAL, "A fetch specification must have a type."); return NULL; } if (strcmp (type, "metadata") == 0) { return xmms_fetch_spec_new_metadata (fetch, info, prefs, err); } else if (strcmp (type, "cluster-list") == 0) { return xmms_fetch_spec_new_cluster_list (fetch, info, prefs, err); } else if (strcmp (type, "cluster-dict") == 0) { return xmms_fetch_spec_new_cluster_dict (fetch, info, prefs, err); } else if (strcmp (type, "organize") == 0) { return xmms_fetch_spec_new_organize (fetch, info, prefs, err); } else if (strcmp (type, "count") == 0) { return xmms_fetch_spec_new_count (fetch, info, prefs, err); } xmms_error_set (err, XMMS_ERROR_INVAL, "Unknown fetch type."); return NULL; }
/** * TODO: Should check for '/' in the key, and set source if found. */ static void populate_medialib (xmms_medialib_t *medialib, xmmsv_t *content) { xmms_medialib_session_t *session; xmms_medialib_entry_t entry = 0; xmmsv_list_iter_t *lit; session = xmms_medialib_session_begin (medialib); xmmsv_get_list_iter (content, &lit); while (xmmsv_list_iter_valid (lit)) { xmmsv_dict_iter_t *dit; xmms_error_t err; xmmsv_t *dict; xmms_error_reset (&err); xmmsv_list_iter_entry (lit, &dict); if (xmmsv_dict_has_key (dict, "url")) { const gchar *url; xmmsv_dict_entry_get_string (dict, "url", &url); entry = xmms_medialib_entry_new (session, url, &err); } else { gchar *url; url = g_strdup_printf ("file://%d.mp3", entry + 1); entry = xmms_medialib_entry_new (session, url, &err); g_free (url); } xmmsv_get_dict_iter (dict, &dit); while (xmmsv_dict_iter_valid (dit)) { const gchar *key, *source; gchar **parts; xmmsv_t *container; xmmsv_dict_iter_pair (dit, &key, &container); parts = g_strsplit (key, "/", 2); key = (parts[1] != NULL) ? parts[1] : key; source = (parts[1] != NULL) ? parts[0] : NULL; if (xmmsv_is_type (container, XMMSV_TYPE_STRING)) { const gchar *value; xmmsv_get_string (container, &value); if (source != NULL) { xmms_medialib_entry_property_set_str_source (session, entry, key, value, source); } else { xmms_medialib_entry_property_set_str (session, entry, key, value); } } else { gint32 value; xmmsv_get_int (container, &value); if (source != NULL) { xmms_medialib_entry_property_set_int_source (session, entry, key, value, source); } else { xmms_medialib_entry_property_set_int (session, entry, key, value); } } g_strfreev (parts); xmmsv_dict_iter_next (dit); } xmmsv_list_iter_next (lit); } xmms_medialib_session_commit (session); }
/** * Retrieve a string attribute from the given collection. * * @param coll The collection to retrieve the attribute from. * @param key The name of the attribute. * @param value The value of the attribute if found (owned by the collection). * @return 1 if the attribute was found, 0 otherwise */ int xmmsv_coll_attribute_get_string (xmmsv_t *coll, const char *key, const char **value) { x_return_val_if_fail (xmmsv_is_type (coll, XMMSV_TYPE_COLL), 0); return xmmsv_dict_entry_get_string (coll->value.coll->attributes, key, value); }
void format_pretty_list (xmmsc_connection_t *conn, GList *list) { guint count = 0; GList *n; gint columns; gchar *format_header, *format_rows; columns = find_terminal_width (); format_header = make_justified_columns_format (columns, 's'); format_rows = make_justified_columns_format (columns, 'd'); print_padded_string (columns, '-', TRUE, "-[Result]-"); print_info (format_header, "Id", "Artist", "Album", "Title"); for (n = list; n; n = g_list_next (n)) { const gchar *title; xmmsc_result_t *res; xmmsv_t *propdict, *val; gint mid = XPOINTER_TO_INT (n->data); if (!mid) { print_error ("Empty result!"); } res = xmmsc_medialib_get_info (conn, mid); xmmsc_result_wait (res); propdict = xmmsc_result_get_value (res); val = xmmsv_propdict_to_dict (propdict, NULL); if (xmmsv_dict_entry_get_string (val, "title", &title)) { const gchar *artist, *album; if (!xmmsv_dict_entry_get_string (val, "artist", &artist)) { artist = "Unknown"; } if (!xmmsv_dict_entry_get_string (val, "album", &album)) { album = "Unknown"; } print_info (format_rows, mid, artist, album, title); } else { const gchar *url; xmmsv_dict_entry_get_string (val, "url", &url); if (url) { gchar *filename = g_path_get_basename (url); if (filename) { print_info ("%-5.5d| %s", mid, filename); g_free (filename); } } } count++; xmmsv_unref (val); xmmsc_result_unref (res); } print_padded_string (columns, '-', FALSE, "-[Count:%6.d]-----", count); g_free (format_header); g_free (format_rows); }
/** * Decodes a cluster fetch specification from a dictionary. * The 'cluster-by' must be one of 'id', 'position' or 'value'. If set * to 'value', then an additional 'cluster-field' will be used to specify * which meta data attribute to cluster on. */ static xmms_fetch_spec_t * xmms_fetch_spec_new_cluster (xmmsv_t *fetch, xmms_fetch_info_t *info, s4_sourcepref_t *prefs, xmms_error_t *err) { xmmsv_t *cluster_by, *cluster_field, *cluster_data; xmms_fetch_spec_t *data, *spec = NULL; s4_sourcepref_t *sp; const gchar *value = NULL; const gchar *field = NULL; const gchar *fallback = NULL; gint cluster_type; if (!xmmsv_dict_get (fetch, "cluster-by", &cluster_by)) { cluster_by = xmmsv_new_string ("value"); xmmsv_dict_set (fetch, "cluster-by", cluster_by); xmmsv_unref (cluster_by); } if (!xmmsv_dict_entry_get_string (fetch, "cluster-by", &value)) { const gchar *message = "'cluster-by' must be a string."; xmms_error_set (err, XMMS_ERROR_INVAL, message); return NULL; } xmmsv_get_string (cluster_by, &value); if (!cluster_by_from_string (value, &cluster_type)) { const gchar *message = "'cluster-by' must be 'id', 'position', or 'value'."; xmms_error_set (err, XMMS_ERROR_INVAL, message); return NULL; } if (cluster_type == CLUSTER_BY_VALUE) { if (!xmmsv_dict_entry_get_string (fetch, "cluster-field", &field)) { const gchar *message = "'cluster-field' must if 'cluster-by' is 'value'."; xmms_error_set (err, XMMS_ERROR_INVAL, message); return NULL; } } if (!xmmsv_dict_get (fetch, "data", &cluster_data)) { const gchar *message = "Required field 'data' not set in cluster."; xmms_error_set (err, XMMS_ERROR_INVAL, message); return NULL; } if (xmmsv_dict_entry_get_type (fetch, "cluster-fallback") == XMMSV_TYPE_NONE) { fallback = NULL; } else if (!xmmsv_dict_entry_get_string (fetch, "cluster-fallback", &fallback)) { const gchar *message = "Optional field 'default' must be a string."; xmms_error_set (err, XMMS_ERROR_INVAL, message); return NULL; } sp = normalize_source_preferences (fetch, prefs, err); if (xmms_error_iserror (err)) { return NULL; } data = xmms_fetch_spec_new (cluster_data, info, sp, err); if (xmms_error_iserror (err)) { s4_sourcepref_unref (sp); return NULL; } spec = g_new0 (xmms_fetch_spec_t, 1); spec->data.cluster.data = data; spec->data.cluster.type = cluster_type; spec->data.cluster.fallback = fallback; switch (spec->data.cluster.type) { case CLUSTER_BY_ID: spec->data.cluster.column = xmms_fetch_info_add_song_id(info, cluster_field); break; case CLUSTER_BY_VALUE: xmmsv_dict_get (fetch, "cluster-field", &cluster_field); spec->data.cluster.column = xmms_fetch_info_add_key (info, cluster_field, field, sp); break; case CLUSTER_BY_POSITION: /* do nothing */ break; default: g_assert_not_reached (); } s4_sourcepref_unref (sp); return spec; }
void cmd_list (xmmsc_connection_t *conn, gint argc, gchar **argv) { gchar *playlist = NULL; xmmsc_result_t *res; xmmsv_t *val; xmmsv_list_iter_t *it; gulong total_playtime = 0; gint p = 0; guint pos = 0; if (argc > 2) { playlist = argv[2]; } res = xmmsc_playlist_current_pos (conn, playlist); xmmsc_result_wait (res); val = xmmsc_result_get_value (res); if (!xmmsv_is_error (val)) { if (!xmmsv_dict_entry_get_int (val, "position", &p)) { print_error ("Broken resultset"); } xmmsc_result_unref (res); } res = xmmsc_playlist_list_entries (conn, playlist); xmmsc_result_wait (res); val = xmmsc_result_get_value (res); if (xmmsv_is_error (val)) { print_error ("%s", xmmsv_get_error_old (val)); } xmmsv_get_list_iter (val, &it); while (xmmsv_list_iter_valid (it)) { xmmsc_result_t *info_res; xmmsv_t *val_id, *propdict, *info_val; gchar line[80]; gint playtime = 0; guint ui; xmmsv_list_iter_entry (it, &val_id); if (!xmmsv_get_uint (val_id, &ui)) { print_error ("Broken resultset"); } info_res = xmmsc_medialib_get_info (conn, ui); xmmsc_result_wait (info_res); propdict = xmmsc_result_get_value (info_res); info_val = xmmsv_propdict_to_dict (propdict, NULL); if (xmmsv_is_error (info_val)) { print_error ("%s", xmmsv_get_error_old (info_val)); } if (xmmsv_dict_entry_get_int (info_val, "duration", &playtime)) { total_playtime += playtime; } if (val_has_key (info_val, "channel")) { if (val_has_key (info_val, "title")) { xmmsc_entry_format (line, sizeof (line), "[stream] ${title}", info_val); } else { xmmsc_entry_format (line, sizeof (line), "${channel}", info_val); } } else if (!val_has_key (info_val, "title")) { const gchar *url; gchar dur[10]; xmmsc_entry_format (dur, sizeof (dur), "(${minutes}:${seconds})", info_val); if (xmmsv_dict_entry_get_string (info_val, "url", &url)) { gchar *filename = g_path_get_basename (url); if (filename) { g_snprintf (line, sizeof (line), "%s %s", filename, dur); g_free (filename); } else { g_snprintf (line, sizeof (line), "%s %s", url, dur); } } } else { xmmsc_entry_format (line, sizeof (line), listformat, info_val); } if (p == pos) { print_info ("->[%d/%d] %s", pos, ui, line); } else { print_info (" [%d/%d] %s", pos, ui, line); } pos++; xmmsc_result_unref (info_res); xmmsv_unref (info_val); xmmsv_list_iter_next (it); } xmmsc_result_unref (res); /* rounding */ total_playtime += 500; print_info ("\nTotal playtime: %d:%02d:%02d", total_playtime / 3600000, (total_playtime / 60000) % 60, (total_playtime / 1000) % 60); }