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 # include <sys/types.h>
17 # include <sys/buf.h>
18
19 # include <sun/dkio.h>
20
21 # include <scsi/targets/srdef.h>
22 # include <scsi/impl/uscsi.h>
23
24 /*# include <sundev/srreg.h>*/
25
26 # include <stdio.h>
27
28 char cdrom[] = "/dev/rsr0";
29
30 extern void cdrom_open();
31 extern char *cdrom_status_string();
32 extern unsigned int cdrom_get_track();
33 extern unsigned long *cdrom_get_times();
34 extern unsigned long *ulong_malloc();
35
36 static int cdrom_fd;
37
38 unsigned long cdrom_mintrack;
39 unsigned long cdrom_maxtrack;
40 unsigned long *cdrom_times;
41
main()42 main() {
43 cdrom_open();
44
45 printf("status: %s\n", cdrom_status_string(cdrom_get_status()));
46
47 cdrom_times = cdrom_get_times();
48 cdrom_print_toc();
49 }
50
51 void
cdrom_open()52 cdrom_open() {
53 if ((cdrom_fd = open(cdrom, 0)) == -1) {
54 fprintf(stderr, "open: ");
55 perror(cdrom);
56
57 exit(1);
58 }
59 }
60
61 unsigned long *
cdrom_get_times()62 cdrom_get_times() {
63 struct cdrom_tochdr tochdr;
64 struct cdrom_tocentry tocentry;
65 extern unsigned long *ulong_malloc();
66 unsigned long trk, trk_total, otime;
67 unsigned long *cdrom_times;
68
69 if (cdrom_read_tochdr(&tochdr) == -1)
70 return(NULL);
71
72 cdrom_mintrack = tochdr.cdth_trk0;
73 cdrom_maxtrack = tochdr.cdth_trk1;
74
75 cdrom_times = ulong_malloc(cdrom_maxtrack - cdrom_mintrack + 1);
76
77 otime = 0;
78
79 for (trk = cdrom_mintrack; trk <= cdrom_maxtrack; trk++) {
80 if (cdrom_read_tocentry(trk, &tocentry) == -1)
81 return(NULL);
82
83 trk_total = ((int) tocentry.cdte_addr.msf.minute * 60) +
84 (int) tocentry.cdte_addr.msf.second;
85
86 trk_total -= otime;
87 otime += trk_total;
88
89 if (trk != cdrom_mintrack)
90 cdrom_times[trk - cdrom_mintrack - 1] = trk_total;
91 }
92
93 if (cdrom_read_tocentry(CDROM_LEADOUT, &tocentry) == -1)
94 return(NULL);
95
96 trk_total = ((int) tocentry.cdte_addr.msf.minute * 60) +
97 (int) tocentry.cdte_addr.msf.second;
98
99 trk_total -= otime;
100
101 cdrom_times[trk - cdrom_mintrack - 1] = trk_total;
102
103 return(cdrom_times);
104 }
105
106 unsigned long *
ulong_malloc(n)107 ulong_malloc(n) {
108 extern char *malloc();
109 unsigned long *ptr;
110
111 ptr = (unsigned long *) calloc(n, sizeof(unsigned long));
112 if (ptr == NULL) {
113 perror("malloc");
114 exit(1);
115 }
116
117 return(ptr);
118 }
119
cdrom_print_toc()120 cdrom_print_toc() {
121 unsigned long trk, trk_total;
122
123 for (trk = cdrom_mintrack; trk <= cdrom_maxtrack; trk++) {
124 trk_total = cdrom_times[trk - cdrom_mintrack];
125 printf("%02u:%02u\n", trk_total/60, trk_total%60);
126 }
127 }
128
cdrom_read_tocentry(trk,tocentry)129 cdrom_read_tocentry(trk, tocentry)
130 int trk;
131 struct cdrom_tocentry *tocentry;
132 {
133 tocentry->cdte_track = trk;
134 tocentry->cdte_format = CDROM_MSF;
135
136 if (ioctl(cdrom_fd, CDROMREADTOCENTRY, (char *) tocentry) == -1) {
137 fprintf(stderr, "ioctl(cdromreadtocentry): ");
138 perror(cdrom);
139
140 return(-1);
141 }
142
143 return(0);
144 }
145
146 int
cdrom_read_tochdr(tochdr)147 cdrom_read_tochdr(tochdr)
148 struct cdrom_tochdr *tochdr;
149 {
150 if (ioctl(cdrom_fd, CDROMREADTOCHDR, (char *) tochdr) == -1) {
151 fprintf(stderr, "ioctl(cdromreadtochdr): ");
152 perror(cdrom);
153
154 return(-1);
155 }
156
157 return(0);
158 }
159
160 int
cdrom_get_status()161 cdrom_get_status() {
162 struct cdrom_subchnl subchnl;
163
164 if (ioctl(cdrom_fd, CDROMSUBCHNL, (char *) &subchnl) == -1) {
165 fprintf(stderr, "ioctl(cdromsubchnl): ");
166 perror(cdrom);
167
168 return(-1);
169 }
170
171 return(subchnl.cdsc_audiostatus);
172 }
173
174 unsigned int
cdrom_get_track()175 cdrom_get_track() {
176 struct cdrom_subchnl subchnl;
177
178 if (ioctl(cdrom_fd, CDROMSUBCHNL, (char *) &subchnl) == -1) {
179 fprintf(stderr, "ioctl(cdromsubchnl): ");
180 perror(cdrom);
181
182 return(-1);
183 }
184
185 return(subchnl.cdsc_trk);
186 }
187
188 char *
cdrom_status_string(status)189 cdrom_status_string(status) {
190 static char buf[512];
191 typedef struct _status_table {
192 unsigned int st_val;
193 char *st_str;
194 } status_table;
195 static status_table st_table[] = {
196 { CDROM_AUDIO_INVALID, "audio status not supported" },
197 { CDROM_AUDIO_PLAY, "audio play operation in progress" },
198 { CDROM_AUDIO_PAUSED, "audio play operation paused" },
199 { CDROM_AUDIO_COMPLETED,"audio play successfully completed" },
200 { CDROM_AUDIO_ERROR, "audio play stopped due to error" },
201 { CDROM_AUDIO_NO_STATUS,"no current audio status to return" },
202 { -1, NULL }
203 };
204 status_table *st;
205
206 switch (status) {
207 case CDROM_AUDIO_PLAY:
208 sprintf(buf, "playing track %d",
209 (unsigned int) cdrom_get_track());
210 return(buf);
211
212 case CDROM_AUDIO_PAUSED:
213 sprintf(buf, "paused on track %d",
214 (unsigned int) cdrom_get_track());
215 return(buf);
216 }
217
218 for (st = &st_table[0]; st->st_str != NULL; st++) {
219 if (status == st->st_val)
220 return(st->st_str);
221 }
222
223 return("invalid status value");
224 }
225