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 #include "irc.h"
13 #include "ircaux.h"
14 #include "./cdrom.h"
15 #include "output.h"
16 #include "misc.h"
17 #include "vars.h"
18
19 #define cparse(s) convert_output_format(s, NULL, NULL)
20
21 static int drive = 0;
22
23 static char cdrom_prompt[]="%gC%Gd%gROM%w";
24
25 static struct cdrom_tochdr hdr;
26 static struct cdrom_etocentry TocEntry[101];
27 static struct cdrom_ti ti;
28
29 static char *cd_device = NULL;
30
31
check_cdrom_str(void)32 static int check_cdrom_str(void)
33 {
34 if (cd_device)
35 return 1;
36 put_it("%s: CD_DEVICE (/SET) - The name of the CDROM device",cparse(cdrom_prompt));
37 return 0;
38 }
39
lba2msf(int lba,unsigned char * msf)40 static void lba2msf(int lba, unsigned char *msf)
41 {
42 lba += CD_BLOCK_OFFSET;
43 msf[0] = lba / (CD_SECS*CD_FRAMES);
44 lba %= CD_SECS*CD_FRAMES;
45 msf[1] = lba / CD_FRAMES;
46 msf[2] = lba % CD_FRAMES;
47 }
48
cd_init(char * dev)49 int cd_init(char *dev)
50 {
51 unsigned char msf_ent[3];
52 unsigned char msf1_ent[3];
53 int i, rc;
54
55 if (!dev || ((drive = open(dev, O_RDWR)) < 0))
56 return (-1);
57
58 if ((rc = ioctl(drive, CDROMREADTOCHDR, &hdr)) == -1)
59 {
60 put_it("%s: can't get TocHeader (error %d).",cparse(cdrom_prompt), rc);
61 return (-2);
62 }
63
64 for (i=1;i<=hdr.cdth_trk1+1;i++)
65 {
66 if (i!=hdr.cdth_trk1+1)
67 TocEntry[i].cdte_track = i;
68 else
69 TocEntry[i].cdte_track = CDROM_LEADOUT;
70 TocEntry[i].cdte_format = CDROM_LBA;
71 TocEntry[i].avoid=TocEntry[i].cdte_ctrl & CDROM_DATA_TRACK ? 1 : 0;
72 if ((rc = ioctl(drive,CDROMREADTOCENTRY,&TocEntry[i])) != 0)
73 put_it("%s: can't get TocEntry #%d (error %d).",cparse(cdrom_prompt), i,rc);
74 else
75 lba2msf(TocEntry[i].cdte_addr.lba,&msf_ent[0]);
76 }
77
78 for (i=1;i<=hdr.cdth_trk1+1;i++)
79 {
80 ioctl(drive,CDROMREADTOCENTRY,&TocEntry[i]);
81 lba2msf(TocEntry[i].cdte_addr.lba,&msf_ent[0]);
82 ioctl(drive,CDROMREADTOCENTRY,&TocEntry[i+1]);
83 lba2msf(TocEntry[i+1].cdte_addr.lba,&msf1_ent[0]);
84 TocEntry[i].length = (msf1_ent[0] * 60 + msf1_ent[1])-
85 (msf_ent[0] * 60 + msf_ent[1]);
86 }
87 return (hdr.cdth_trk1);
88 }
89
check_mount(char * device)90 static int check_mount(char *device)
91 {
92 FILE *fp;
93 struct mntent *mnt;
94
95 if ((fp = setmntent(MOUNTED, "r")) == NULL)
96 return 0;
97
98 while ((mnt = getmntent (fp)) != NULL)
99 {
100 if ((strcmp (mnt->mnt_type, "iso9660") == 0) && (strcmp (mnt->mnt_fsname, device) == 0))
101 {
102 endmntent(fp);
103 return 0;
104 }
105 }
106 endmntent (fp);
107 return 1;
108 }
109
set_cd_device(IrcCommandDll * interp,char * command,char * args,char * subargs)110 void set_cd_device(IrcCommandDll *interp, char *command, char *args, char *subargs)
111 {
112 char *str;
113 int code;
114 if (!(str = next_arg(args , &args)))
115 {
116 return;
117 }
118 if (drive)
119 close(drive);
120 if (check_mount(str) == 0)
121 {
122 put_it("%s: ERROR: CDROM is already mounted, please unmount, and try again",cparse(cdrom_prompt));
123 new_free(&cd_device);
124 return;
125 }
126
127 if ((code = cd_init(str)) < 0)
128 {
129 put_it("%s: ERROR(%d): Could not initalize the CDROM, check if a disk is inside",cparse(cdrom_prompt), code);
130 new_free(&cd_device);
131 return;
132 }
133 put_it("%s: CDROM device is now set to - %s",cparse(cdrom_prompt),str);
134 malloc_strcpy(&cd_device, str);
135 }
136
cd_stop(IrcCommandDll * interp,char * command,char * args,char * subargs)137 void cd_stop(IrcCommandDll *interp, char *command, char *args, char *subargs)
138 {
139 if (!check_cdrom_str())
140 return;
141 put_it("%s: Stopped playing cdrom",cparse(cdrom_prompt));
142 ioctl(drive,CDROMSTOP);
143 }
144
cd_eject(IrcCommandDll * interp,char * command,char * args,char * subargs)145 void cd_eject(IrcCommandDll *interp, char *command, char *args, char *subargs)
146 {
147 if (!check_cdrom_str())
148 return;
149
150 put_it("%s: ejected cdrom tray",cparse(cdrom_prompt));
151 ioctl(drive,CDROMEJECT);
152 close(drive);
153 drive=0;
154 }
155
cd_play(IrcCommandDll * interp,char * command,char * args,char * subargs)156 void cd_play(IrcCommandDll *interp, char *command, char *args, char *subargs)
157 {
158
159 int tn;
160 char *trackn;
161 unsigned char first, last;
162 struct cdrom_tochdr tocHdr;
163
164 if (!check_cdrom_str() || !drive)
165 return;
166
167 if (args && *args)
168 {
169 trackn=next_arg(args, &args);
170 tn=atoi(trackn);
171
172 ioctl(drive,CDROMREADTOCHDR,&tocHdr);
173
174 first = tocHdr.cdth_trk0;
175 last = tocHdr.cdth_trk1;
176 ti.cdti_trk0=tn;
177
178 if (ti.cdti_trk0<first)
179 ti.cdti_trk0=first;
180 if (ti.cdti_trk0>last)
181 ti.cdti_trk0=last;
182
183 ti.cdti_ind0=0;
184 ti.cdti_trk1=last;
185 ti.cdti_ind1=0;
186
187 if (TocEntry[tn].avoid==0)
188 {
189 ioctl(drive,CDROMSTOP);
190 ioctl(drive,CDROMPLAYTRKIND,&ti);
191 put_it("%s: Playing track number #%d",cparse(cdrom_prompt),tn);
192 }
193 else
194 put_it("%s: Cannot play track #%d (Might be data track)",cparse(cdrom_prompt),tn);
195 }
196 else
197 put_it("%s: Usage: /cdplay <track number>",cparse(cdrom_prompt));
198
199 }
200
cd_list(IrcCommandDll * interp,char * command,char * args,char * subargs)201 void cd_list(IrcCommandDll *interp, char *command, char *args, char *subargs)
202 {
203 int i;
204 unsigned char msf_ent[3];
205 struct cdrom_subchnl subchnl;
206
207 if (!check_cdrom_str())
208 return;
209 ioctl(drive,CDROMSUBCHNL,&subchnl);
210 for (i=1;i<=hdr.cdth_trk1;i++)
211 {
212 if ((subchnl.cdsc_audiostatus==CDROM_AUDIO_PLAY) && (subchnl.cdsc_trk == i))
213 {
214 lba2msf(TocEntry[i].cdte_addr.lba,&msf_ent[0]);
215 put_it("%s: Track #%02d: %02d:%02d %02d:%02d (*)",
216 cparse(cdrom_prompt),
217 TocEntry[i].cdte_track,
218 msf_ent[0],
219 msf_ent[1],
220 (TocEntry[i].length/60) % 60,
221 TocEntry[i].length % 60);
222 }
223 else
224 {
225 lba2msf(TocEntry[i].cdte_addr.lba,&msf_ent[0]);
226 put_it("%s: Track #%02d: %02d:%02d %02d:%02d",
227 cparse(cdrom_prompt),
228 TocEntry[i].cdte_track,
229 msf_ent[0],
230 msf_ent[1],
231 (TocEntry[i].length/60) % 60,
232 TocEntry[i].length % 60);
233 }
234 }
235 }
236
cd_volume(IrcCommandDll * interp,char * command,char * args,char * subargs)237 void cd_volume(IrcCommandDll *interp, char *command, char *args, char *subargs)
238 {
239 char *left, *right;
240 struct cdrom_volctrl volctrl;
241
242 if (!check_cdrom_str())
243 return;
244
245 if (args && *args)
246 {
247 left=next_arg(args, &args);
248 right=next_arg(args, &args);
249 if (left && *left)
250 volctrl.channel0=atoi(left);
251 if (right && *right)
252 volctrl.channel1=atoi(right);
253 ioctl(drive,CDROMVOLCTRL,&volctrl);
254 put_it("%s: CDROM Volume is now <%d> <%d>",cparse(cdrom_prompt),volctrl.channel0,volctrl.channel1);
255 }
256 else
257 put_it("%s: Usage: /cdvol <left> <right>",cparse(cdrom_prompt));
258 }
259
cd_pause(IrcCommandDll * interp,char * command,char * args,char * subargs)260 void cd_pause(IrcCommandDll *interp, char *command, char *args, char *subargs)
261 {
262 static int cpause = 0;
263 if (!check_cdrom_str())
264 return;
265 ioctl(drive, !cpause?CDROMPAUSE:CDROMRESUME);
266 cpause ^= 1;
267 }
268
cd_help(IrcCommandDll * interp,char * command,char * args,char * subargs)269 void cd_help(IrcCommandDll *interp, char *command, char *args, char *subargs)
270 {
271 put_it("%s: CDPLAY - Play a CDROM Track Number",cparse(cdrom_prompt));
272 put_it("%s: CDSTOP - Make the CDROM Stop playing",cparse(cdrom_prompt));
273 put_it("%s: CDEJECT - Eject the CDROM Tray",cparse(cdrom_prompt));
274 put_it("%s: CDVOL - Set's the CDROM Volume",cparse(cdrom_prompt));
275 put_it("%s: CDLIST - List of CDROM tracks",cparse(cdrom_prompt));
276 put_it("%s: CDPAUSE - Pause/resume the CDROM",cparse(cdrom_prompt));
277 }
278
279 int
Cdrom_Init(interp)280 Cdrom_Init(interp)
281 IrcCommandDll **interp; /* Interpreter in which the package is
282 * to be made available. */
283 {
284 IrcCommandDll *new;
285 new = (IrcCommandDll *) new_malloc(sizeof(IrcCommandDll));
286 new->name = m_strdup("cdstop");
287 new->func = cd_stop;
288 add_to_list((List **)interp, (List *)new);
289 new = (IrcCommandDll *) new_malloc(sizeof(IrcCommandDll));
290 new->name = m_strdup("cdplay");
291 new->func = cd_play;
292 add_to_list((List **)interp, (List *)new);
293 new = (IrcCommandDll *) new_malloc(sizeof(IrcCommandDll));
294 new->name = m_strdup("cdeject");
295 new->func = cd_eject;
296 add_to_list((List **)interp, (List *)new);
297 new = (IrcCommandDll *) new_malloc(sizeof(IrcCommandDll));
298 new->name = m_strdup("cdlist");
299 new->func = cd_list;
300 add_to_list((List **)interp, (List *)new);
301 new = (IrcCommandDll *) new_malloc(sizeof(IrcCommandDll));
302 new->name = m_strdup("cdhelp");
303 new->func = cd_help;
304 add_to_list((List **)interp, (List *)new);
305 new = (IrcCommandDll *) new_malloc(sizeof(IrcCommandDll));
306 new->name = m_strdup("cdvolume");
307 new->func = cd_volume;
308 add_to_list((List **)interp, (List *)new);
309 new = (IrcCommandDll *) new_malloc(sizeof(IrcCommandDll));
310 new->name = m_strdup("cdpause");
311 new->func = cd_pause;
312 add_to_list((List **)interp, (List *)new);
313 new = (IrcCommandDll *) new_malloc(sizeof(IrcCommandDll));
314 new->name = m_strdup("cddevice");
315 new->func = set_cd_device;
316 add_to_list((List **)interp, (List *)new);
317 put_it("%s: Module loaded and ready. /cddevice <dev> to start", cparse(cdrom_prompt));
318 put_it("%s: /cdhelp for list of new commands.", cparse(cdrom_prompt));
319 return 0;
320 }