1 /*
2 * cdrom.c: This file handles all the CDROM routines, in BitchX
3 *
4 * Written by Tom Zickel
5 * a.k.a. IceBreak on the irc
6 *
7 * Copyright(c) 1996
8 * Modified Colten Edwards aka panasync.
9 *
10 */
11
12 /* Version 0.2 22/07/97 written by IceBreak (ice_break@hotmail.com) */
13 /* 0.2: Finnally I rewrote the playing method inside the cdrom player to work
14 * with msf instead of lba, and frames instead of tracks, this should fix
15 * all the compability problems that the cdroms player had with some
16 * cdroms. I also fixed some bugs and better problem messages.
17 * FreeBSD support added by Eric A. Griff aka setjmp!eagriff@*.global2000.net
18 *
19 */
20
21 #include "irc.h"
22 static char cvsrevision[] = "$Id: cdrom.c 3 2008-02-25 09:49:14Z keaston $";
23 CVS_REVISION(cdrom_c)
24 #include "struct.h"
25
26 #include "ircaux.h"
27 #include "cdrom.h"
28 #include "output.h"
29 #include "misc.h"
30 #include "vars.h"
31 #define MAIN_SOURCE
32 #include "modval.h"
33
34 #define cparse(s) convert_output_format(s, NULL, NULL)
35
36 static int drive = 0;
37
38 static char cdrom_prompt[]="%gC%Gd%gROM%w";
39
40 #ifndef __FreeBSD__
41 static struct cdrom_tochdr hdr;
42 static struct cdrom_ti ti;
43 #else
44 static struct ioc_toc_header hdr;
45 #endif
46
47 static struct cdrom_etocentry TocEntry[101];
48
49 int cd_init(char *);
50
51 #ifndef __FreeBSD__
play_chunk(int start,int end)52 void play_chunk(int start, int end)
53 {
54 struct cdrom_msf msf;
55
56 end--;
57 if (start >= end)
58 start = end-1;
59
60 msf.cdmsf_min0 = start / (60*75);
61 msf.cdmsf_sec0 = (start % (60*75)) / 75;
62 msf.cdmsf_frame0 = start % 75;
63 msf.cdmsf_min1 = end / (60*75);
64 msf.cdmsf_sec1 = (end % (60*75)) / 75;
65 msf.cdmsf_frame1 = end % 75;
66
67 if (ioctl(drive, CDROMSTART))
68 {
69 put_it("%s: Could not start the cdrom",cparse(cdrom_prompt));
70 return;
71 }
72 if (ioctl(drive, CDROMPLAYMSF, &msf))
73 {
74 put_it("%s: Could not play the track",cparse(cdrom_prompt));
75 return;
76 }
77 }
78 #endif
79
check_cdrom_str(void)80 static int check_cdrom_str(void)
81 {
82 char *str;
83 if ((str = get_string_var(CD_DEVICE_VAR)))
84 {
85 if (!drive)
86 cd_init(str);
87 return 1;
88 }
89 put_it("%s: /SET CD_DEVICE - The name of the CDROM device",cparse(cdrom_prompt));
90 return 0;
91 }
92
cd_init(char * dev)93 int cd_init(char *dev)
94 {
95 #if 0
96 unsigned char msf_ent[3];
97 unsigned char msf1_ent[3];
98 #endif
99 int i, pos;
100
101 if (((drive = open(dev, 0)) < 0))
102 {
103 if (errno == EACCES)
104 put_it("%s: you dont have access to the cdrom driver",cparse(cdrom_prompt));
105 return (-1);
106 }
107
108 if (ioctl(drive, CDROMREADTOCHDR, &hdr))
109 {
110 put_it("%s: Can't get TocHeader",cparse(cdrom_prompt));
111 return (-2);
112 }
113
114 #ifndef __FreeBSD__
115 for (i=1;i<=hdr.cdth_trk1+1;i++)
116 {
117 if (i!=hdr.cdth_trk1+1)
118 TocEntry[i].cdte_track = i;
119 else
120 TocEntry[i].cdte_track = CDROM_LEADOUT;
121 TocEntry[i].cdte_format = CDROM_MSF;
122 if (ioctl(drive,CDROMREADTOCENTRY,&TocEntry[i]))
123 put_it("%s: Can't get TocEntry #%d",cparse(cdrom_prompt), i);
124 else
125 {
126 TocEntry[i].avoid=TocEntry[i].cdte_ctrl & CDROM_DATA_TRACK ? 1 : 0;
127 TocEntry[i].m_length = TocEntry[i].cdte_addr.msf.minute * 60 + TocEntry[i].cdte_addr.msf.second;
128 TocEntry[i].m_start = TocEntry[i].m_length * 75 + TocEntry[i].cdte_addr.msf.frame;
129 }
130 }
131
132 pos = TocEntry[1].m_length;
133
134 for (i=1;i<=hdr.cdth_trk1+1;i++)
135 {
136 TocEntry[i].m_length = TocEntry[i+1].m_length - pos;
137 pos = TocEntry[i+1].m_length;
138 if (TocEntry[i].avoid)
139 TocEntry[i].m_length = (TocEntry[i+1].m_start - TocEntry[i+1].m_start) *2;
140 }
141 return (hdr.cdth_trk1);
142 #else
143 for (i = hdr.starting_track; i <= hdr.ending_track; i++)
144 {
145 TocEntry[i].avoid=0;
146 TocEntry[i].m_start=1;
147 TocEntry[i].m_length=1;
148 }
149 return (hdr.ending_track);
150 #endif
151 }
152
check_mount(char * device)153 static int check_mount(char *device)
154 {
155 #ifndef __FreeBSD__
156 FILE *fp;
157 struct mntent *mnt;
158
159 if ((fp = setmntent(MOUNTED, "r")) == NULL)
160 return 0;
161
162 while ((mnt = getmntent (fp)) != NULL)
163 {
164 if (!strcmp (mnt->mnt_type, "iso9660") && !strcmp (mnt->mnt_fsname, device))
165 {
166 endmntent(fp);
167 return 0;
168 }
169 }
170 endmntent (fp);
171 #else
172 struct statfs *mntinfo;
173 int i,count;
174
175 if(!(count=getmntinfo(&mntinfo,MNT_WAIT|MOUNT_CD9660)))
176 return 0;
177
178 for(i=0; i<count; i++)
179 if(strstr(mntinfo[i].f_mntfromname,device))
180 return 0;
181 #endif
182 return 1;
183 }
184
set_cd_device(Window * win,char * str,int blah)185 void set_cd_device(Window *win, char *str, int blah)
186 {
187 if (drive)
188 close(drive);
189 if (!str || !check_mount(str))
190 {
191 put_it("%s: ERROR: CDROM is already mounted, please unmount, and try again",cparse(cdrom_prompt));
192 set_string_var(CD_DEVICE_VAR,NULL);
193 return;
194 }
195
196 if (cd_init(str) < 0)
197 {
198 put_it("%s: ERROR: Could not initalize the CDROM, check if a disk is inside",cparse(cdrom_prompt));
199 set_string_var(CD_DEVICE_VAR,NULL);
200 return;
201 }
202 put_it("%s: CDROM device is now set to - %s",cparse(cdrom_prompt),str);
203 set_string_var(CD_DEVICE_VAR,str);
204 }
205
BUILT_IN_COMMAND(cd_stop)206 BUILT_IN_COMMAND(cd_stop)
207 {
208 if (!check_cdrom_str())
209 return;
210
211 if (ioctl(drive,CDROMSTOP))
212 put_it("%s: Couldnt stop the cdrom",cparse(cdrom_prompt));
213 else
214 put_it("%s: Stopped playing cdrom",cparse(cdrom_prompt));
215 }
216
BUILT_IN_COMMAND(cd_eject)217 BUILT_IN_COMMAND(cd_eject)
218 {
219 if (!check_cdrom_str())
220 return;
221
222 if (!drive)
223 return;
224 if (ioctl(drive,CDROMEJECT))
225 put_it("%s: Couldnt eject the cdrom tray",cparse(cdrom_prompt));
226 else
227 put_it("%s: Ejected cdrom tray",cparse(cdrom_prompt));
228 close(drive);
229 drive=0;
230 }
231
BUILT_IN_COMMAND(cd_play)232 BUILT_IN_COMMAND(cd_play)
233 {
234 int tn;
235 char *trackn;
236
237 #ifndef __FreeBSD__
238 unsigned char first, last;
239 struct cdrom_tochdr tocHdr;
240 #else
241 struct ioc_play_track cdrom_play_args;
242 int result;
243 #endif
244
245 if (!check_cdrom_str() || !drive)
246 return;
247
248 if (args && *args)
249 {
250 trackn = next_arg(args, &args);
251 tn = atoi(trackn);
252
253 #ifndef __FreeBSD__
254 if (ioctl(drive,CDROMREADTOCHDR,&tocHdr))
255 {
256 put_it("%s: Couldnt get cdrom heder",cparse(cdrom_prompt));
257 return;
258 }
259
260 first = tocHdr.cdth_trk0;
261 last = tocHdr.cdth_trk1;
262 ti.cdti_trk0=tn;
263
264 if (ti.cdti_trk0<first)
265 ti.cdti_trk0=first;
266 if (ti.cdti_trk0>last)
267 ti.cdti_trk0=last;
268
269 ti.cdti_ind0=0;
270 ti.cdti_trk1=last;
271 ti.cdti_ind1=0;
272 #else
273 if (tn < hdr.starting_track)
274 tn=hdr.starting_track;
275 if (tn > hdr.ending_track)
276 tn=hdr.ending_track;
277 #endif
278
279 if (TocEntry[tn].avoid==0)
280 {
281 #ifndef __FreeBSD__
282 play_chunk(TocEntry[tn].m_start,TocEntry[last+1].m_start - 1);
283 #else
284 cdrom_play_args.start_track=tn;
285 cdrom_play_args.start_index=1;
286 cdrom_play_args.end_track=hdr.ending_track;
287 cdrom_play_args.end_index=1;
288 (void)ioctl(drive,CDIOCPLAYTRACKS,&cdrom_play_args);
289 #endif
290 put_it("%s: Playing track number #%d",cparse(cdrom_prompt),tn);
291 }
292 else
293 put_it("%s: Cannot play track #%d (Might be data track)",cparse(cdrom_prompt),tn);
294 }
295 else
296 put_it("%s: Usage: /cdplay <track number>",cparse(cdrom_prompt));
297
298 }
299
BUILT_IN_COMMAND(cd_list)300 BUILT_IN_COMMAND(cd_list)
301 {
302 int i;
303
304 if (!check_cdrom_str())
305 return;
306 #ifndef __FreeBSD__
307 for (i=1;i<=hdr.cdth_trk1;i++)
308 #else
309 for (i = hdr.starting_track; i < hdr.ending_track; i++)
310 #endif
311 {
312 put_it("%s: Track #%02d: %02d:%02d:%02d %02d:%02d:%02d",
313 cparse(cdrom_prompt),
314 i,
315 TocEntry[i].m_length / (60*75),
316 (TocEntry[i].m_length % (60*75)) / 75,
317 TocEntry[i].m_length % 75,
318 TocEntry[i].m_start / (60*75),
319 (TocEntry[i].m_start % (60*75)) /75,
320 TocEntry[i].m_start % 75
321 );
322 }
323 }
324
BUILT_IN_COMMAND(cd_volume)325 BUILT_IN_COMMAND(cd_volume)
326 {
327 char *left, *right;
328 #ifndef __FreeBSD__
329 struct cdrom_volctrl volctrl;
330 #else
331 struct ioc_vol volctrl;
332 #endif
333
334 if (!check_cdrom_str())
335 return;
336
337 if (args && *args)
338 {
339 left=next_arg(args, &args);
340 right=next_arg(args, &args);
341 ioctl(drive, CDROMVOLREAD, &volctrl);
342 if (left && *left)
343 #ifndef __FreeBSD__
344 volctrl.channel0 = atoi(left);
345 #else
346 volctrl.vol[0] = atoi(left);
347 #endif
348 if (right && *right)
349 #ifndef __FreeBSD__
350 volctrl.channel1 = atoi(right);
351 #else
352 volctrl.vol[1] = atoi(right);
353 #endif
354 if (ioctl(drive,CDROMVOLCTRL,&volctrl))
355 put_it("%s: Couldnt set cdrom volume",cparse(cdrom_prompt));
356 else
357 put_it("%s: CDROM Volume is now <%d> <%d>",cparse(cdrom_prompt),
358 #ifndef __FreeBSD__
359 volctrl.channel0,volctrl.channel1);
360 #else
361 volctrl.vol[0],volctrl.vol[1]);
362 #endif
363 }
364 else
365 put_it("%s: Usage: /cdvol <left> <right>",cparse(cdrom_prompt));
366 }
367
BUILT_IN_COMMAND(cd_pause)368 BUILT_IN_COMMAND(cd_pause)
369 {
370 static int cpause = 0;
371 if (!check_cdrom_str())
372 return;
373 if (ioctl(drive, !cpause?CDROMPAUSE:CDROMRESUME))
374 put_it("%s: Couldnt pause/resume your cdrom",cparse(cdrom_prompt));
375 else
376 put_it("%s: %s",cparse(cdrom_prompt),!cpause?"Your cdrom has been paused":"Your cdrom has been resumed");
377 cpause ^= 1;
378 }
379
BUILT_IN_COMMAND(cd_help)380 BUILT_IN_COMMAND(cd_help)
381 {
382 put_it("%s: CDPLAY - Play a CDROM Track Number",cparse(cdrom_prompt));
383 put_it("%s: CDSTOP - Make the CDROM Stop playing",cparse(cdrom_prompt));
384 put_it("%s: CDEJECT - Eject the CDROM Tray",cparse(cdrom_prompt));
385 put_it("%s: CDVOL - Set's the CDROM Volume",cparse(cdrom_prompt));
386 put_it("%s: CDLIST - List of CDROM tracks",cparse(cdrom_prompt));
387 put_it("%s: CDPAUSE - Pause/resume the CDROM",cparse(cdrom_prompt));
388 }
389
390 #if 0
391 char *status_cdrom(window)
392 Window *window;
393 {
394 static char text[BIG_BUFFER_SIZE];
395
396 if ((drive) && (get_string_var(CD_DEVICE_VAR)))
397 {
398 rc=ioctl(drive,CDROMSUBCHNL,&subchnl);
399 strcpy(text,"[CD:");
400 if (subchnl.cdsc_audiostatus==CDROM_AUDIO_PLAY)
401 {
402 strcat(text,"P");
403 strcat(text,":");
404 strcat(text,ltoa((long)subchnl.cdsc_trk));
405 } else {
406 strcat(text,"S");
407 }
408 strcat(text,"]");
409 return(text);
410 }
411 else
412 return (empty_string);
413 }
414 #endif
415