1 /* --------------------------------------------------------------------------
2
3 MusicBrainz -- The Internet music metadatabase
4
5 Copyright (C) 2000 Robert Kaye
6 Copyright (C) 1999 Marc E E van Woerkom
7 Copyright (C) 1999 Ben Wong
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
23 $Id: mb_irix.cpp,v 1.2 2000/09/22 14:15:02 robert Exp $
24
25 ----------------------------------------------------------------------------*/
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <errno.h>
31 #include <sys/types.h>
32 #include <sys/ioctl.h>
33 #include <sys/socket.h>
34 #include <sys/stat.h>
35 #include <unistd.h>
36 #include <fcntl.h>
37 #include <assert.h>
38
39 #include <netinet/in.h>
40 #include <signal.h>
41
42 #include "mb.h"
43 #include "diskid.h"
44 #include "config.h"
45
46
47 // Irix will just magically find the CD-ROM when told to open NULL.
48 MUSICBRAINZ_DEVICE DEFAULT_DEVICE = 0;
49
50
ReadTOCHeader(CDPLAYER * fd,int & first,int & last)51 int ReadTOCHeader(CDPLAYER* fd,
52 int& first,
53 int& last)
54 {
55 CDSTATUS tochdr;
56
57 // CDgetstatus returns 0 on error but we return 0 on success.
58 int ret = !CDgetstatus(fd, &tochdr);
59
60 if (!ret)
61 {
62 first = tochdr.first;
63 last = tochdr.last;
64 }
65
66 return ret;
67 }
68
69
ReadTOCEntry(CDPLAYER * fd,int track,int & lba)70 int ReadTOCEntry(CDPLAYER* fd,
71 int track,
72 int& lba)
73 {
74 CDTRACKINFO trackinfo;
75
76 // CDgettrackinfo returns 0 on error but we return 0 on success.
77 int ret = !CDgettrackinfo(fd, track, &trackinfo);
78
79 if (!ret)
80 {
81 // trackinfo has Min/Sec/Frame but we want a Logical Block Address.
82 lba = CDmsftoblock(fd,
83 trackinfo.start_min,
84 trackinfo.start_sec,
85 trackinfo.start_frame);
86 }
87
88 return ret;
89 }
90
91
92 // Return one past the *end* of the track requested instead of the
93 // start. (Equivalent to "start of the next track" but works even when
94 // the next track doesn't exist).
95
ReadTOCEntryEnd(CDPLAYER * fd,int track,int & lba)96 int ReadTOCEntryEnd(CDPLAYER* fd,
97 int track,
98 int &lba)
99 {
100 CDTRACKINFO trackinfo;
101
102 // CDgettrackinfo returns 0 on error but we return 0 on success.
103 int ret = !CDgettrackinfo(fd, track, &trackinfo);
104 if (!ret)
105 {
106 // trackinfo has Min/Sec/Frame but we want a Logical Block Address.
107 lba = CDmsftoblock(fd,
108 trackinfo.start_min+trackinfo.total_min,
109 trackinfo.start_sec+trackinfo.total_sec,
110 trackinfo.start_frame+trackinfo.total_frame)+1;
111 }
112
113 return ret;
114 }
115
116
ReadTOC(MUSICBRAINZ_DEVICE device,MUSICBRAINZ_CDINFO & cdinfo)117 bool DiskId::ReadTOC(MUSICBRAINZ_DEVICE device,
118 MUSICBRAINZ_CDINFO& cdinfo)
119 {
120 CDSTATUS status;
121 CDPLAYER *fd = CDopen(device, "r");
122 int first, last;
123 int lba, i;
124 char err[256];
125
126 if (!fd || !CDgetstatus(fd, &status))
127 {
128 sprintf(err, "Cannot open %s",
129 device ? device : "any CD-ROM");
130
131 if (!fd)
132 sprintf(err + strlen(err), ": %s", strerror(errno));
133
134 ReportError(err);
135
136 return false;
137 }
138
139 // Check if the CD-ROM is ready, has a disk in it, isn't already playing.
140 if (status.state != CD_READY)
141 {
142 strcpy(err, "The CD-ROM isn't ready. Reason: ");
143
144 switch (status.state) {
145 case CD_NODISC:
146 strcat(err, "The drive does not have a CD loaded.");
147 break;
148
149 case CD_CDROM:
150 strcat(err, "The drive is loaded with a CD-ROM. Subsequent ");
151 strcat(err, "play or read operations will return I/O errors.");
152 break;
153
154 case CD_ERROR:
155 strcat(err, "An error occurred while trying to read the disc or");
156 strcat(err, " it table of contents.");
157 break;
158
159 case CD_PLAYING:
160 strcat(err, "The drive is in CD player mode playing an audio ");
161 strcat(err, "CD through its audio jacks.");
162 break;
163
164 case CD_PAUSED:
165 case CD_STILL:
166 strcat(err, "The drive is in CD player mode with play paused.");
167 break;
168
169 default:
170 strcat(err, "An unknown error occured.");
171 }
172 ReportError(err);
173
174 return false;
175 }
176
177 // Initialize cdinfo to all zeroes.
178 memset(&cdinfo, 0, sizeof(MUSICBRAINZ_CDINFO));
179
180 // Find the number of the first track (usually 1) and the last track.
181 if (ReadTOCHeader(fd, first, last))
182 {
183 ReportError("Cannot read table of contents.");
184 CDclose(fd);
185 return false;
186 }
187
188 // Do some basic error checking.
189 if (last==0)
190 {
191 ReportError("This disk has no tracks.");
192 CDclose(fd);
193 return false;
194 }
195
196 // Get the block address for the end of the audio data.
197 // The "LEADOUT" track is the track beyond the final audio track
198 // so we're looking for the block address of the LEADOUT track.
199 ReadTOCEntryEnd(fd, last, lba);
200 cdinfo.FrameOffset[0] = lba + 150;
201
202 // Now, for every track, find out the block address where it starts.
203 for (i = first; i <= last; i++)
204 {
205 ReadTOCEntry(fd, i, lba);
206 cdinfo.FrameOffset[i] = lba + 150;
207 }
208
209 cdinfo.FirstTrack = first;
210 cdinfo.LastTrack = last;
211
212 CDclose(fd);
213
214 return true;
215 }
216
217