static id3v2_tag* id3v2_get_tag(int fd) { unsigned char *c; id3v2_header *header; id3v2_frame_list *frame_list; id3v2_frame *frame; id3v2_tag *tag = NULL; int i; if(lseek(fd, 0L, SEEK_SET) == -1) return NULL; c = (unsigned char*)xmallocd0(1024, "id3v2_get_tag:c"); if(read(fd, c, 10) < 10) goto exit_on_error; c[10] = 0; if(strncmp(c, "ID3", 3)) goto exit_on_error; header = XMALLOCD0(id3v2_header, "id3v2_get_tag:header"); header->version_minor = c[3]; header->version_revision = c[4]; header->flags = c[5]; header->unsyncronization = (c[5] & 128) >> 7; header->has_extended_header = (c[5] & 64) >> 6; header->is_experimental = (c[5] & 32) >> 5; header->has_footer = (c[5] & 16) >> 4; header->total_tag_size = id3_unsync32(c, 6) + 10; if(header->has_footer) header->total_tag_size += 10; tag = XMALLOCD0(id3v2_tag, "id3v2_get_tag:tag"); /* check if version is supported */ if(c[3] != 3 && c[3] != 4) { xfree(c); tag->header = header; tag->frame_list = NULL; return tag; } frame_list = XMALLOCD0(id3v2_frame_list, "id3v2_get_tag:frame_list"); frame_list->start = frame_list; /* assigning header and frame list to tag */ tag->header = header; tag->frame_list = frame_list; if(header->has_extended_header) { id3v2_extended_header *xt_header = XMALLOCD0(id3v2_extended_header, "id3v2_get_tag:id3v2_extended_header"); header->extended_header = xt_header; read(fd, c, 4); /* get length of extended header */ xt_header->size = id3_unsync32(c, 0); read(fd, c, 1); /* get number of flags */ xt_header->no_flag_bytes = (c[0] > 0) ? c[0] : 1; read(fd, c, xt_header->no_flag_bytes); /* get flag bytes */ xt_header->is_update = (c[0] & 64) >> 6; xt_header->crc_data_present = (c[0] & 32) >> 5; xt_header->restrictions = (c[0] & 16) >> 4; /* Flag data */ if(xt_header->is_update) read(fd, c, 1); /* Data length ind. is 0 -skip */ if(xt_header->crc_data_present) { read(fd, c, 1); /* data length - shoud be 5 */ if(*c != 5) goto exit_on_error; /* else things might break badly */ xt_header->crc_data_length = *c; xt_header->crc_data = xmallocd0(*c, "id3v2_get_tag:xt_header->crc_data"); read(fd, xt_header->crc_data, *c); } if(xt_header->restrictions) { read(fd, c, 1); /* data length - shoud be 1 */ if(*c != 1) goto exit_on_error; xt_header->restrictions_data_length = *c; xt_header->restrictions_data = xmallocd0(*c, "id3v2_get_tag:xt_header->restrictions_data"); read(fd, xt_header->restrictions_data, *c); } }
header = XMALLOCD0(id3v2_header, "id3v2_get_tag:header"); header->version_minor = c[3]; header->version_revision = c[4]; header->flags = c[5]; header->unsyncronization = (c[5] & 128) >> 7; //[email protected] if( 2!=header->version_minor ) { header->has_extended_header = (c[5] & 64) >> 6; header->is_experimental = (c[5] & 32) >> 5; header->has_footer = (c[5] & 16) >> 4; } header->total_tag_size = id3_unsync32(c, 6) + 10; if(header->has_footer) header->total_tag_size += 10; tag = XMALLOCD0(id3v2_tag, "id3v2_get_tag:tag"); /* check if version is supported */ if( c[3] != 2 && c[3] != 3 && c[3] != 4 ) { xfree(c); tag->header = header; tag->frame_list = NULL; return tag; } frame_list = XMALLOCD0(id3v2_frame_list, "id3v2_get_tag:frame_list");