1 /*
2 * Copyright (C) 1990 Regents of the University of California.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and
5 * its documentation for any purpose is hereby granted without fee,
6 * provided that the above copyright notice appear in all copies and that
7 * both that copyright notice and this permission notice appear in
8 * supporting documentation, and that the name of the University of
9 * California not be used in advertising or publicity pertaining to
10 * distribution of the software without specific, written prior
11 * permission. the University of California makes no representations
12 * about the suitability of this software for any purpose. It is provided
13 * "as is" without express or implied warranty.
14 */
15
16 static int c;
17
18 # if defined(sun)
19 # include <stdio.h>
20
21 # include <sys/file.h>
22 # include <sys/types.h>
23 # include <sys/param.h>
24 # include <sys/stat.h>
25
26 # include <sun/dkio.h>
27
28 # include <mntent.h>
29 # include <string.h>
30
31 # include <sys/buf.h>
32 # ifdef sun4c
33 # include <scsi/targets/srdef.h>
34 # else
35 # include <sundev/srreg.h>
36 # endif
37
38 # include <sys/time.h>
39
40 # include "debug.h"
41 # include "cdrom_sun.h"
42
43 extern char *device;
44 # if defined(notdef)
45 extern void cdrom_print_toc();
46 # endif /* defined(notdef) */
47
48 static char cdrom[] = "/dev/rsr0";
49
50 cdrom_info cdi;
51 char info_filename[256];
52 FILE *disc_info = NULL;
53
54 static int cdrom_fd = -1;
55
get_stored_info()56 get_stored_info()
57 {
58 int i,n;
59 char line[100];
60 char *title;
61
62 if ( cdi.maxtrack == 0) {
63 return(0);
64 }
65 for (i = 0, n = 0; i < cdi.maxtrack; i++)
66 n = n + ((i+1) * cdi.times[i]);
67 n = n / cdi.maxtrack;
68
69 disc_title = NULL;
70 if (cdInfoDir != NULL)
71 sprintf(info_filename, "%s/cd.%d", cdInfoDir, n);
72 else
73 sprintf(info_filename, "cd.%d", n);
74
75 if ((disc_info = fopen(info_filename, "r")) != NULL)
76 {
77 fgets(line, 100, disc_info);
78 title = strchr(line, ':');
79 if (title != NULL)
80 {
81 *(strchr(title, '\n')) = '\0';
82 disc_title = strdup(title + 1);
83 }
84 fgets(line, 100, disc_info);
85 sscanf(line, "Program: %s", program_str);
86 }
87 if (disc_title == NULL) {
88 disc_title = NOTITLESTR;
89 }
90 }
91
92 int
cdrom_open()93 cdrom_open() {
94 int n;
95 extern void update_title();
96
97 if (cdrom_fd != -1)
98 return(cdi.curtrack);
99
100 if (device != NULL) {
101 if ((cdrom_fd = open(device, O_RDONLY)) == -1) {
102 debug-printf(stderr, "open: ");
103 return(-1);
104 }
105 } else {
106 if ((cdrom_fd = open(cdrom, O_RDONLY)) == -1) {
107 debug-printf(stderr, "open: ");
108 return(-1);
109 }
110 }
111
112 if (cdrom_get_times() == -1) {
113 cdrom_close();
114 return(-1);
115 }
116
117 if ((n = cdrom_get_curtrack()) == -1)
118 return(-1);
119
120 get_stored_info();
121
122 update_title();
123
124 if (cdi.state & CDROM_STATE_PLAY)
125 cdi.curtrack = n;
126
127 if (cdi.state & CDROM_STATE_SHUFFLE)
128 shuffle_setup();
129
130 return(cdi.curtrack);
131 }
132
133 void
cdrom_close()134 cdrom_close() {
135 if (cdrom_fd == -1)
136 return;
137
138 if (cdi.times != NULL) {
139 free((char *) cdi.times);
140 free((char *) cdi.addrs);
141 cdi.times = NULL;
142 cdi.addrs = NULL;
143 }
144
145 (void) close(cdrom_fd);
146 cdrom_fd = -1;
147 }
148
149
150 int
cdrom_start()151 cdrom_start() {
152 if (cdrom_fd == -1)
153 return(-1);
154
155 if (ioctl(cdrom_fd, CDROMSTART) == -1) {
156 perror("ioctl(cdromstart)");
157 return(-1);
158 }
159
160 return(0);
161 }
162
163 int
cdrom_stop()164 cdrom_stop() {
165 if (cdrom_fd == -1)
166 return(-1);
167
168 if (ioctl(cdrom_fd, CDROMSTOP) == -1) {
169 perror("ioctl(cdromstop)");
170 return(-1);
171 }
172
173 return(0);
174 }
175
176 int
cdrom_eject()177 cdrom_eject() {
178 if (cdrom_fd == -1)
179 return(-1);
180
181 if (ioctl(cdrom_fd, CDROMEJECT) == -1) {
182 perror("ioctl(cdromeject)");
183 return(-1);
184 }
185
186 return(0);
187 }
188
189 int
cdrom_pause()190 cdrom_pause() {
191 if (cdrom_fd == -1)
192 return(-1);
193
194 if (ioctl(cdrom_fd, CDROMPAUSE) == -1) {
195 perror("ioctl(cdrompause)");
196 return(-1);
197 }
198
199 return(0);
200 }
201
202 int
cdrom_resume()203 cdrom_resume() {
204 if (cdrom_fd == -1)
205 return(-1);
206
207 if (ioctl(cdrom_fd, CDROMRESUME) == -1) {
208 perror("ioctl(cdromresume)");
209 return(-1);
210 }
211
212 return(0);
213 }
214
215 int
cdrom_volume(left_vol,right_vol)216 cdrom_volume(left_vol, right_vol)
217 int left_vol;
218 int right_vol;
219 {
220 struct cdrom_volctrl vol;
221
222 if (cdrom_fd == -1)
223 return(-1);
224
225 vol.channel0 = left_vol;
226 vol.channel1 = right_vol;
227
228 if (ioctl(cdrom_fd, CDROMVOLCTRL, &vol) == -1) {
229 perror("ioctl(cdromvolctrl)");
230 return(-1);
231 }
232
233 return(0);
234 }
235
236 int
cdrom_get_times()237 cdrom_get_times() {
238 struct cdrom_tochdr tochdr;
239 extern unsigned short *ushort_malloc();
240 extern struct msf *msf_malloc();
241 unsigned long trk, trk_total, otime;
242 struct msf msf;
243
244 if (cdrom_read_tochdr(&tochdr) == -1)
245 return(-1);
246
247 cdi.mintrack = tochdr.cdth_trk0;
248 cdi.maxtrack = tochdr.cdth_trk1;
249
250 if (cdi.times != NULL)
251 {
252 free((char *) cdi.times);
253 free((char *) cdi.addrs);
254 cdi.times = NULL;
255 cdi.addrs = NULL;
256 }
257
258 cdi.times = ushort_malloc(cdi.maxtrack - cdi.mintrack + 1);
259 cdi.addrs = msf_malloc(cdi.maxtrack - cdi.mintrack + 2);
260
261 otime = 0;
262
263 for (trk = cdi.mintrack; trk <= cdi.maxtrack; trk++) {
264 if (cdrom_get_msf(trk, &msf, &trk_total) == -1)
265 return(-1);
266
267 /* record start address for each track (track 1 starts at 0)*/
268 cdi.addrs[trk - cdi.mintrack] = msf;
269
270 trk_total -= otime;
271
272 /* use start time of next track as length of previous */
273 if (otime != 0)
274 {
275 cdi.times[trk - cdi.mintrack - 1] = trk_total;
276 }
277
278 otime += trk_total;
279
280 }
281
282 /* find start of leadout to get length of last track */
283 if (cdrom_get_msf(CDROM_LEADOUT, &msf, &trk_total) == -1)
284 return(-1);
285
286 /* recode leadout start address */
287 cdi.addrs[trk - cdi.mintrack] = msf;
288 trk_total -= otime;
289 otime += trk_total;
290
291 cdi.times[trk - cdi.mintrack - 1] = trk_total;
292
293 return(0);
294 }
295
296 # if defined(notdef)
297 static void
cdrom_print_toc()298 cdrom_print_toc() {
299 unsigned long trk, trk_total;
300
301 for (trk = cdi.mintrack; trk <= cdi.maxtrack; trk++) {
302 trk_total = cdi.times[trk - cdi.mintrack];
303 debug_printf(1, "%02u:%02u\n", trk_total/60, trk_total%60);
304 }
305 }
306 # endif /* defined(notdef) */
307
308 int
cdrom_get_curtrack()309 cdrom_get_curtrack() {
310 struct cdrom_subchnl subchnl;
311
312 if (cdrom_fd == -1)
313 return(-1);
314
315 if (ioctl(cdrom_fd, CDROMSUBCHNL, (char *) &subchnl) == -1) {
316 fprintf(stderr, "ioctl(cdromsubchnl): ");
317 perror(cdrom);
318 return(-1);
319 }
320
321 switch (subchnl.cdsc_audiostatus) {
322 case CDROM_AUDIO_INVALID:
323 return(-1);
324
325 /* playing track subchnl.cdsc_trk */
326 case CDROM_AUDIO_PLAY:
327 return((int) subchnl.cdsc_trk);
328
329 /* paused on track subchnl.cdsc_trk */
330 case CDROM_AUDIO_PAUSED:
331 return((int) subchnl.cdsc_trk);
332
333 /* punt */
334 case CDROM_AUDIO_COMPLETED:
335 return(0);
336
337 case CDROM_AUDIO_ERROR:
338 return(-1);
339
340 /* punt */
341 case CDROM_AUDIO_NO_STATUS:
342 debug_printf(1, "cdrom_get_curtrack: no status\n");
343 return(0);
344 }
345
346 /* bad value in cdsc_audiostatus */
347 return(-1);
348 }
349
350 int
cdrom_get_msf(track,msf,length)351 cdrom_get_msf(track, msf, length)
352 unsigned long track;
353 struct msf *msf;
354 unsigned long *length;
355 {
356 struct cdrom_tocentry tocentry;
357
358 if (cdrom_read_tocentry(track, &tocentry) == -1)
359 return(-1);
360
361 msf->minute = tocentry.cdte_addr.msf.minute;
362 msf->second = tocentry.cdte_addr.msf.second;
363 msf->frame = tocentry.cdte_addr.msf.frame;
364
365 *length = ((int) tocentry.cdte_addr.msf.minute * 60) +
366 (int) tocentry.cdte_addr.msf.second;
367
368 return(0);
369 }
370
371 int
cdrom_get_curmsf(msf)372 cdrom_get_curmsf(msf)
373 struct msf *msf;
374 {
375 struct cdrom_subchnl subchnl;
376
377 if (cdrom_fd == -1)
378 return(-1);
379
380 subchnl.cdsc_format = CDROM_MSF;
381
382 if (ioctl(cdrom_fd, CDROMSUBCHNL, (char *) &subchnl) == -1) {
383 perror("ioctl(cdromsubchnl)");
384 return(-1);
385 }
386
387 msf->minute = subchnl.cdsc_absaddr.msf.minute;
388 msf->second = subchnl.cdsc_absaddr.msf.second;
389 msf->frame = subchnl.cdsc_absaddr.msf.frame;
390
391 return (0);
392
393 }
394
395 int
cdrom_play_track(start_track,end_track)396 cdrom_play_track(start_track, end_track)
397 unsigned char start_track;
398 unsigned char end_track;
399 {
400 struct cdrom_ti ti;
401
402 if (cdrom_fd == -1)
403 return(-1);
404
405 ti.cdti_trk0 = start_track;
406 ti.cdti_ind0 = 1;
407 ti.cdti_trk1 = end_track;
408 ti.cdti_ind1 = 1;
409
410 if (ioctl(cdrom_fd, CDROMPLAYTRKIND, &ti) == -1) {
411 perror("ioctl(cdromplaytrkind)");
412 return(-1);
413 }
414
415 return(0);
416 }
417
418 int
cdrom_play_msf(start_msf,end_msf)419 cdrom_play_msf(start_msf, end_msf)
420 struct msf *start_msf;
421 struct msf *end_msf;
422 {
423 struct cdrom_msf play_addr;
424
425 if (cdrom_fd == -1)
426 return(-1);
427
428 play_addr.cdmsf_min0 = start_msf->minute;
429 play_addr.cdmsf_sec0 = start_msf->second;
430 play_addr.cdmsf_frame0 = start_msf->frame;
431 play_addr.cdmsf_min1 = end_msf->minute;
432 play_addr.cdmsf_sec1 = end_msf->second;
433 play_addr.cdmsf_frame1 = end_msf->frame;
434
435 if (ioctl(cdrom_fd, CDROMPLAYMSF, &play_addr) == -1) {
436 perror("ioctl(cdromplaymsf)");
437 return(-1);
438 }
439
440 return(0);
441 }
442 int
cdrom_read_tocentry(track,tocentry)443 cdrom_read_tocentry(track, tocentry)
444 unsigned int track;
445 struct cdrom_tocentry *tocentry;
446 {
447 if (cdrom_fd == -1)
448 return(-1);
449
450 tocentry->cdte_track = track;
451 tocentry->cdte_format = CDROM_MSF;
452
453 if (ioctl(cdrom_fd, CDROMREADTOCENTRY, (char *) tocentry) == -1) {
454 perror("ioctl(cdromreadtocentry)");
455 return(-1);
456 }
457
458 return(0);
459 }
460
461 int
cdrom_read_tochdr(tochdr)462 cdrom_read_tochdr(tochdr)
463 struct cdrom_tochdr *tochdr;
464 {
465 if (cdrom_fd == -1)
466 return(-1);
467
468 if (ioctl(cdrom_fd, CDROMREADTOCHDR, (char *) tochdr) == -1) {
469 debug-printf(stderr,"ioctl(cdromreadtochdr): ");
470 /* perror("ioctl(cdromreadtochdr)"); */
471 return(-1);
472 }
473
474 return(0);
475 }
476
477 int
cdrom_status()478 cdrom_status() {
479 struct cdrom_subchnl subchnl;
480
481 if (cdrom_fd == -1)
482 return(-1);
483
484 if (ioctl(cdrom_fd, CDROMSUBCHNL, (char *) &subchnl) == -1) {
485 fprintf(stderr, "ioctl(cdromsubchnl): ");
486 perror(cdrom);
487 exit(1);
488 }
489
490 switch (subchnl.cdsc_audiostatus) {
491 case CDROM_AUDIO_INVALID:
492 return(CDROM_INVALID);
493
494 case CDROM_AUDIO_PLAY:
495 return(CDROM_PLAYING);
496
497 case CDROM_AUDIO_PAUSED:
498 return(CDROM_PAUSED);
499
500 case CDROM_AUDIO_COMPLETED:
501 return(CDROM_COMPLETED);
502
503 case CDROM_AUDIO_ERROR:
504 return(CDROM_ERROR);
505
506 case CDROM_AUDIO_NO_STATUS:
507 return(CDROM_NO_STATUS);
508 }
509
510 return(-1);
511 }
512
513 # if defined(notused)
514 int
cdrom_playing(track)515 cdrom_playing(track)
516 int *track;
517 {
518 struct cdrom_subchnl sc;
519
520 if (cdrom_fd == -1)
521 return(-1);
522
523 sc.cdsc_format = CDROM_MSF;
524 if (ioctl(cdrom_fd, CDROMSUBCHNL, &sc) == -1) {
525 perror("ioctl(cdromsubchnl)");
526 return(-1);
527 }
528
529 *track = sc.cdsc_trk;
530
531 if (sc.cdsc_audiostatus == CDROM_AUDIO_PLAY)
532 return(1);
533
534 return(0);
535 }
536 # endif /* defined(notused) */
537
538 # if defined(notused)
539 int
cdrom_paused(track)540 cdrom_paused(track)
541 int *track;
542 {
543 struct cdrom_subchnl sc;
544
545 if (cdrom_fd == -1)
546 return(-1);
547
548 sc.cdsc_format = CDROM_MSF;
549 if (ioctl(cdrom_fd, CDROMSUBCHNL, &sc) == -1) {
550 perror("ioctl(cdromsubchnl)");
551 return(-1);
552 }
553
554 *track = sc.cdsc_trk;
555
556 if (sc.cdsc_audiostatus == CDROM_AUDIO_PAUSED)
557 return(1);
558
559 return(0);
560 }
561 # endif /* defined(notused) */
562
563 # if defined(notused)
564 int
mounted(name)565 mounted(name)
566 char *name;
567 {
568 char buf[MAXPATHLEN], *cp;
569 struct stat st;
570 dev_t bdevno;
571 FILE *fp;
572 struct mntent *mnt;
573
574 /*
575 * Get the block device corresponding to the raw device opened,
576 * and find its device number.
577 */
578 if (stat(name, &st) != 0) {
579 (void) fprintf(stderr, "stat: ");
580 perror(name);
581 return(UNMOUNTED);
582 }
583
584 /*
585 * If this is a raw device, we have to build the block device name.
586 */
587 if ((st.st_mode & S_IFMT) == S_IFCHR) {
588 if ((cp = strchr(name, 'r')) != NULL)
589 cp++;
590
591 (void) sprintf(buf, "/dev/%s", cp);
592 if (stat(buf, &st) != 0) {
593 (void) fprintf(stderr, "stat: ");
594 perror(buf);
595 return(UNMOUNTED);
596 }
597 }
598
599 if ((st.st_mode & S_IFMT) != S_IFBLK)
600 return(UNMOUNTED);
601
602 bdevno = st.st_rdev & (dev_t)(~0x07); /* Mask out partition. */
603
604 /*
605 * Now go through the mtab, looking at all hsfs filesystems.
606 * Compare the device mounted with our bdevno.
607 */
608 if ((fp = setmntent(MOUNTED, "r")) == NULL) {
609 (void) fprintf(stderr, "couldn't open %s\n", MOUNTED);
610 return(UNMOUNTED);
611 }
612
613 while ((mnt = getmntent(fp)) != NULL) {
614 /* avoid obvious excess stat(2)'s */
615 if (strcmp(mnt->mnt_type, "hsfs") != 0)
616 continue;
617
618 if (stat(mnt->mnt_fsname, &st) != 0)
619 continue;
620
621 if (((st.st_mode & S_IFMT) == S_IFBLK) &&
622 ((st.st_rdev & (dev_t)(~0x07)) == bdevno)) {
623 (void) endmntent(fp);
624 return(STILL_MOUNTED);
625 }
626 }
627
628 (void) endmntent(fp);
629
630 return(UNMOUNTED);
631 }
632 # endif /* defined(notused) */
633
634 unsigned short *
ushort_malloc(n)635 ushort_malloc(n)
636 int n;
637 {
638 extern char *calloc();
639 unsigned short *ptr;
640
641 ptr = (unsigned short *) calloc(n, sizeof(unsigned short));
642 if (ptr == NULL) {
643 perror("calloc");
644 exit(1);
645 }
646
647 return(ptr);
648 }
649
650 struct msf *
msf_malloc(n)651 msf_malloc(n)
652 int n;
653 {
654 extern char *calloc();
655 struct msf *ptr;
656
657 ptr = (struct msf *) calloc(n, sizeof(struct msf));
658 if (ptr == NULL) {
659 perror("calloc");
660 exit(1);
661 }
662
663 return(ptr);
664 }
665
666 int
cdrom_disp_cdi()667 cdrom_disp_cdi() {
668 int trk;
669
670 fprintf(stderr,"CDI structure:\n");
671 fprintf(stderr,"\tcurtrack: %d\n",cdi.curtrack);
672 fprintf(stderr,"\tmin: %d max: %d total: %d\n",
673 cdi.mintrack, cdi.maxtrack, cdi.ntracks);
674 fprintf(stderr,"\tdur: %d state: %2x\n",cdi.duration, cdi.state);
675 fprintf(stderr,"\tcurrand: %d lastprog: %d\n",
676 cdi.currand, cdi.lastprog);
677 fprintf(stderr,"\n\tTracklist:\n");
678 if (cdi.maxtrack != cdi.mintrack) {
679 for (trk=cdi.mintrack; trk<=cdi.maxtrack; trk++) {
680 fprintf(stderr,"\t%3d: %d %02d:%02d %d\n",trk,cdi.times[trk],
681 cdi.addrs[trk].minute,cdi.addrs[trk].second,
682 cdi.addrs[trk].frame);
683 }
684 }
685 }
686
687 # endif /* defined(sun) */
688