Mercurial > ~darius > hgwebdir.cgi > cddb-stuff
comparison cddb-id.c @ 3:74031379d3cb CDDB-STUFF_1_0
Initial revision
author | darius |
---|---|
date | Wed, 09 Aug 2000 02:18:47 +0000 |
parents | |
children | ad83a38c3f5a |
comparison
equal
deleted
inserted
replaced
2:5cead4da1db9 | 3:74031379d3cb |
---|---|
1 #include <stdio.h> | |
2 #include <stdlib.h> | |
3 #include <unistd.h> | |
4 #include <sysexits.h> | |
5 #include <fcntl.h> | |
6 #include <sys/errno.h> | |
7 #include <sys/ioctl.h> | |
8 #include <sys/cdio.h> | |
9 | |
10 int cddb_sum(int n); | |
11 unsigned long cddb_discid(int tot_trks, struct cd_toc_entry *cdtoc); | |
12 void usage(void); | |
13 | |
14 int | |
15 main(int argc, char **argv) | |
16 { | |
17 int cd_fd, tot_tracks, i, machine, disc_length, tracknums; | |
18 unsigned long disc_id; | |
19 struct ioc_toc_header toc_head; | |
20 struct ioc_read_toc_entry toc_entries_head; | |
21 struct cd_toc_entry *toc_entries; | |
22 char cd_path[256], ch; | |
23 | |
24 /* Default CD path */ | |
25 strcpy(cd_path, "/dev/cd0c"); | |
26 | |
27 /* Default to human readable */ | |
28 machine = 0; | |
29 | |
30 /* Default to no track number stuff */ | |
31 tracknums = 0; | |
32 | |
33 while ((ch = getopt(argc, argv, "f:mhn")) != -1) { | |
34 switch(ch) { | |
35 case 'f': | |
36 if (strlen(optarg) > 255) { | |
37 warnx("Filename too long"); | |
38 exit(EX_USAGE); | |
39 } | |
40 | |
41 strcpy(cd_path, optarg); | |
42 break; | |
43 | |
44 case 'm': | |
45 machine = 1; | |
46 break; | |
47 | |
48 case 'n': | |
49 tracknums = 1; | |
50 break; | |
51 | |
52 case '?': | |
53 case 'h': | |
54 default: | |
55 usage(); | |
56 break; | |
57 } | |
58 } | |
59 | |
60 if ((cd_fd = open(cd_path, O_RDWR)) == -1) { | |
61 warnx("Failed to open %s, reason: %s", cd_path, strerror(errno)); | |
62 exit(EX_IOERR); | |
63 } | |
64 | |
65 if (ioctl(cd_fd, CDIOREADTOCHEADER, &toc_head) == -1) { | |
66 warnx("Failed to get TOC header, reason: %s", strerror(errno)); | |
67 exit(EX_UNAVAILABLE); | |
68 } | |
69 | |
70 tot_tracks = toc_head.ending_track - toc_head.starting_track + 1; | |
71 | |
72 toc_entries = (struct cd_toc_entry *)malloc(sizeof(struct cd_toc_entry) * (tot_tracks + 1)); | |
73 if (toc_entries == NULL) { | |
74 warnx("Couldn't allocate memeory for TOC entries"); | |
75 exit(EX_UNAVAILABLE); | |
76 } | |
77 | |
78 toc_entries_head.data = toc_entries; | |
79 toc_entries_head.data_len = sizeof(struct cd_toc_entry) * (tot_tracks + 1); | |
80 toc_entries_head.starting_track = 0; | |
81 toc_entries_head.address_format = CD_MSF_FORMAT; | |
82 | |
83 if (ioctl(cd_fd, CDIOREADTOCENTRYS, &toc_entries_head) == -1) { | |
84 warnx("Failed to get TOC entries, reason: %s\n", strerror(errno)); | |
85 exit(EX_UNAVAILABLE); | |
86 } | |
87 | |
88 if (tracknums) { | |
89 for (i = 1; i <= tot_tracks; i++) | |
90 if (!(toc_entries[i].control & 4)) | |
91 printf("%d ", i); | |
92 | |
93 printf("\n"); | |
94 | |
95 exit(0); | |
96 } | |
97 | |
98 disc_id = cddb_discid(tot_tracks, toc_entries); | |
99 disc_length = (toc_entries[tot_tracks].addr.msf.minute * 60) + | |
100 (toc_entries[tot_tracks].addr.msf.second); | |
101 | |
102 if (machine == 0) { | |
103 printf("Start track = %d, end track = %d, length = %d\n", toc_head.starting_track, | |
104 toc_head.ending_track, toc_head.len); | |
105 printf("Disc ID is %08x\n", disc_id); | |
106 printf("Length is %d seconds\n", disc_length); | |
107 } else { | |
108 printf("%08x", disc_id); | |
109 } | |
110 | |
111 for (i = 0; i < tot_tracks; i++) { | |
112 if (machine == 0) { | |
113 printf("Track %d, Minute = %d, Second = %d, Frame = %d, Type = %s, Offset = %d\n", | |
114 toc_entries[i].track, toc_entries[i].addr.msf.minute, | |
115 toc_entries[i].addr.msf.second, toc_entries[i].addr.msf.frame, | |
116 (toc_entries[i].control & 4) ? "data" : "audio", | |
117 (toc_entries[i].addr.msf.minute * 60 * 75) + | |
118 (toc_entries[i].addr.msf.second * 75) + | |
119 toc_entries[i].addr.msf.frame); | |
120 } else { | |
121 printf(" %d", (toc_entries[i].addr.msf.minute * 60 * 75) + | |
122 (toc_entries[i].addr.msf.second * 75) + | |
123 toc_entries[i].addr.msf.frame); | |
124 } | |
125 | |
126 } | |
127 | |
128 if (machine == 1) { | |
129 printf(" %d\n", disc_length); | |
130 } | |
131 } | |
132 | |
133 int | |
134 cddb_sum(int n) | |
135 { | |
136 int ret; | |
137 | |
138 /* For backward compatibility this algorithm must not change */ | |
139 | |
140 ret = 0; | |
141 | |
142 while (n > 0) { | |
143 ret = ret + (n % 10); | |
144 n = n / 10; | |
145 } | |
146 | |
147 return (ret); | |
148 } | |
149 | |
150 unsigned long | |
151 cddb_discid(int tot_trks, struct cd_toc_entry *cdtoc) | |
152 { | |
153 int i, | |
154 t = 0, | |
155 n = 0; | |
156 | |
157 /* For backward compatibility this algorithm must not change */ | |
158 | |
159 i = 0; | |
160 | |
161 while (i < tot_trks) { | |
162 n = n + cddb_sum((cdtoc[i].addr.msf.minute * 60) | |
163 + cdtoc[i].addr.msf.second); | |
164 i++; | |
165 } | |
166 t = ((cdtoc[tot_trks].addr.msf.minute * 60) + | |
167 cdtoc[tot_trks].addr.msf.second) - | |
168 ((cdtoc[0].addr.msf.minute * 60) + | |
169 cdtoc[0].addr.msf.second); | |
170 | |
171 return ((n % 0xff) << 24 | t << 8 | tot_trks); | |
172 } | |
173 | |
174 void | |
175 usage(void) | |
176 { | |
177 printf("Usage:\n"); | |
178 printf("cddb-id [-f <cd-dev>] [-m]\n"); | |
179 printf("<cd-dev> is the cd device to use (Default: /dev/cd0c)\n"); | |
180 printf("-m causes machine readable output\n"); | |
181 exit(EX_USAGE); | |
182 } |