+#ifdef HAVE_LIBID3TAG
+
+#include <id3tag.h>
+
+static char *get_latin1(id3_ucs4_t const *string)
+{
+ if (!string)
+ return NULL;
+ return (char *)id3_ucs4_latin1duplicate(string);
+}
+
+static char *get_stringlist(union id3_field *field)
+{
+ unsigned int k, nstrings = id3_field_getnstrings(field);
+ char *result = NULL;
+
+ for (k = 0; k < nstrings; k++) {
+ char *tmp = (char *)get_latin1(id3_field_getstrings(field, k));
+ if (result) {
+ char *tmp2 = result;
+ result = make_message("%s %s", tmp2, tmp);
+ free(tmp);
+ free(tmp2);
+ } else
+ result = tmp;
+ }
+ return result;
+}
+
+static char *get_string(union id3_field *field)
+{
+ id3_ucs4_t const *string = id3_field_getfullstring(field);
+
+ return get_latin1(string);
+}
+
+#define FOR_EACH_FIELD(f, j, fr) for (j = 0; j < (fr)->nfields && \
+ (f = id3_frame_field((fr), j)); j++)
+
+static char *get_strings(struct id3_frame *fr)
+{
+ int j;
+ union id3_field *field;
+
+ FOR_EACH_FIELD(field, j, fr) {
+ enum id3_field_type type = id3_field_type(field);
+
+ if (type == ID3_FIELD_TYPE_STRINGLIST)
+ return get_stringlist(field);
+ if (type == ID3_FIELD_TYPE_STRINGFULL)
+ return get_string(field);
+ }
+ return NULL;
+}
+
+static char *mp3_get_id3(__a_unused unsigned char *map,
+ __a_unused size_t numbytes, int fd)
+{
+ int i;
+ struct id3_tag *id3_t;
+ char *title = NULL, *artist = NULL, *album = NULL, *year = NULL,
+ *comment = NULL, *result;
+ struct id3_file *id3_f = id3_file_fdopen(fd, ID3_FILE_MODE_READONLY);
+
+ if (!id3_f)
+ goto no_tag;
+ id3_t = id3_file_tag(id3_f);
+ if (!id3_t)
+ goto no_tag;
+ for (i = 0; i < id3_t->nframes; i++) {
+ struct id3_frame *fr = id3_t->frames[i];
+ if (!strcmp(fr->id, "TIT2")) {
+ if (!title)
+ title = get_strings(fr);
+ continue;
+ }
+ if (!strcmp(fr->id, "TPE1")) {
+ if (!artist)
+ artist = get_strings(fr);
+ continue;
+ }
+ if (!strcmp(fr->id, "TALB")) {
+ if (!album)
+ album = get_strings(fr);
+ continue;
+ }
+ if (!strcmp(fr->id, "TDRC")) {
+ if (!year)
+ year = get_strings(fr);
+ continue;
+ }
+ if (!strcmp(fr->id, "COMM")) {
+ if (!comment)
+ comment = get_strings(fr);
+ continue;
+ }
+ }
+ id3_file_close(id3_f);
+ result = make_taginfo(title, artist, album, year, comment);
+ free(title);
+ free(artist);
+ free(album);
+ free(year);
+ free(comment);
+ return result;
+no_tag:
+ if (id3_f)
+ id3_file_close(id3_f);
+ return make_message("%s: (no id3 v1/v2 tag)\n%s:\n",
+ status_item_list[SI_TAGINFO1],
+ status_item_list[SI_TAGINFO2]);
+}
+
+#else /* HAVE_LIBID3TAG */
+