1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <ctype.h>
5 #include <unistd.h>
6 
7 /* Field Length offsets
8  *  Tag 3 0-2
9  *  Songname 30 3-32
10  *  Artist 30 33-62
11  *  Album 30 63-92
12  *  Year 4 93-96
13  *  Comment 30 97-126
14  *  or{
15  *    Comment 28 97-124
16  *    zero 1 125
17  *    Tracknum 1 126
18  *  }
19  *  Genre 1 127
20  */
21 
22 struct s_id3 {
23     char tag[3];
24     char songname[30];
25     char artist[30];
26     char album[30];
27     char year[4];
28     char comment[30];
29 //  char comment[28];
30 //  unsigned char empty;
31 //  unsigned char tracknum;
32     unsigned char genre;
33 } id3;
34 
35 
36 #define NUM_GENRE 148
37 
38 const char *genre_list[NUM_GENRE+1]={
39 	"Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk",
40 	"Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies",
41 	"Other", "Pop", "R&B", "Rap", "Reggae", "Rock",
42 	"Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks",
43 	"Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk",
44 	"Fusion", "Trance", "Classical", "Instrumental", "Acid", "House",
45 	"Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass",
46 	"Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock",
47 	"Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk",
48 	"Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta",
49 	"Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret",
50 	"New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer", "Lo-Fi",
51 	"Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical",
52 	"Rock & Roll", "Hard Rock", "Folk", "Folk/Rock", "National Folk", "Swing",
53 	"Fast-Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde",
54 	"Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band",
55 	"Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson",
56 	"Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus",
57 	"Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba",
58 	"Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet",
59 	"Punk Rock", "Drum Solo", "A capella", "Euro-House", "Dance Hall",
60 	"Goa", "Drum & Bass", "Club House", "Hardcore", "Terror",
61 	"Indie", "BritPop", "NegerPunk", "Polsk Punk", "Beat",
62 	"Christian Gangsta", "Heavy Metal", "Black Metal", "Crossover", "Contemporary C",
63 	"Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", "JPop",
64 	"SynthPop",
65 	NULL
66 };
67 
68 
69 /*
70 @I ID3:<a><b><c>
71 
72 Status message after loading a song (ID3 song info)
73 
74 a = title (exactly 30 chars)
75 b = artist (exactly 30 chars)
76 c = album (exactly 30 chars)
77 d = year (exactly 4 chars)
78 e = comment (exactly 30 chars)
79 f = genre (string)
80 */
81 
82 
out_id3_info(int fd,char * filename,int remote)83 void out_id3_info(int fd, char *filename, int remote)
84 {
85     char *p;
86 
87     if (remote)
88 	printf("@I ");
89 
90     memset(id3.tag, 0, sizeof(id3.tag));
91 
92     lseek(fd, -128, SEEK_END);
93     read(fd, &id3, sizeof(id3));
94     lseek(fd, 0, SEEK_SET);
95 
96     if (! strncmp(id3.tag, "TAG", 3)) {
97 	/* Ignore id3 v1.1 trackinfo stuff */
98 	if (id3.comment[28] == '\0') {
99 	    id3.comment[28] = ' ';
100 	    id3.comment[29] = ' ';
101 	}
102 	if (remote) {
103 	    printf("ID3:");
104 	    printf("%-30.30s", id3.songname);
105 	    printf("%-30.30s", id3.artist);
106 	    printf("%-30.30s", id3.album);
107 	    printf("%-4.4s", id3.year);
108 	    printf("%-30.30s", id3.comment);
109 	    printf("%s", (id3.genre < NUM_GENRE) ? genre_list[id3.genre] : "unknown");
110 	    printf("\n");
111 	} else {
112 	    printf(" Title:   %.30s\n", id3.songname);
113 	    printf(" Artist:  %.30s\n", id3.artist);
114 	    printf(" Album:   %.30s\n", id3.album);
115 	    printf(" Year:    %.4s\n", id3.year);
116 	    printf(" Comment: %.30s\n", id3.comment);
117 	    printf(" Genre:   %s\n", (id3.genre < NUM_GENRE) ? genre_list[id3.genre] : "unknown");
118 	    printf("\n");
119 	}
120     } else {
121 	if (remote) {
122 	    p = strrchr(filename, '/');
123 	    if (p)
124 		printf("%s\n", p + 1);
125 	    else
126 		printf("%s\n", filename);
127 	}
128     }
129 }
130