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 }