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