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 # include <sun/dkio.h>
19 # include <scsi/targets/srdef.h>
20 
21 # include <stdio.h>
22 
23 char cdrom[] =	"/dev/rsr0";
24 
25 extern char *	cdrom_status();
26 
main()27 main() {
28 	int			fd;
29 
30 	if ((fd = open(cdrom, 0)) == -1) {
31 		fprintf(stderr, "open: ");
32 		perror(cdrom);
33 		exit(1);
34 	}
35 
36 	printf("status: %s\n", cdrom_status(fd));
37 
38 	cdrom_toc(fd, CDROM_MSF);
39 
40 	cdrom_subchnl(fd, CDROM_MSF);
41 }
42 
cdrom_toc(fd,fmt)43 cdrom_toc(fd, fmt) {
44 	struct cdrom_tochdr	tochdr;
45 	struct cdrom_tocentry	tocentry;
46 	int			trk;
47 	int			otime, trk_total;
48 
49 	if (cdrom_read_tochdr(fd, &tochdr) == -1)
50 		return;
51 
52 	printf("TRACK\tTIME\tFRAME\tTYPE\n");
53 
54 	otime = 0;
55 
56 	for (trk = tochdr.cdth_trk0; trk <= tochdr.cdth_trk1; trk++) {
57 		if (cdrom_read_tocentry(fd, trk, fmt, &tocentry) == -1)
58 			return;
59 
60 		trk_total = ((int) tocentry.cdte_addr.msf.minute * 60) +
61 			(int) tocentry.cdte_addr.msf.second;
62 
63 		trk_total -= otime;
64 
65 		if (otime != 0) {
66 			printf("%d\t%02d:%02d", trk-1,
67 			       trk_total / 60,
68 			       trk_total % 60);
69 
70 			printf("\t%d", (int) tocentry.cdte_addr.msf.frame);
71 
72 			if (tocentry.cdte_ctrl & CDROM_DATA_TRACK)
73 				printf("\tdata");
74 			else
75 				printf("\taudio");
76 
77 			printf("\n");
78 		}
79 
80 		otime += trk_total;
81 	}
82 
83 	if (cdrom_read_tocentry(fd, CDROM_LEADOUT, fmt, &tocentry) == -1)
84 		return;
85 
86 	trk_total = ((int) tocentry.cdte_addr.msf.minute * 60) +
87 		(int) tocentry.cdte_addr.msf.second;
88 
89 	trk_total -= otime;
90 
91 	printf("%d\t%02d:%02d", trk-1,
92 	       trk_total / 60,
93 	       trk_total % 60);
94 
95 	printf("\t%d", (int) tocentry.cdte_addr.msf.frame);
96 
97 	if (tocentry.cdte_ctrl & CDROM_DATA_TRACK)
98 		printf("\tdata");
99 	else
100 		printf("\taudio");
101 
102 	printf("\n");
103 }
104 
cdrom_read_tocentry(fd,trk,fmt,tocentry)105 cdrom_read_tocentry(fd, trk, fmt, tocentry)
106 	int			fd;
107 	int			trk, fmt;
108 	struct cdrom_tocentry	*tocentry;
109 {
110 	tocentry->cdte_track = trk;
111 	tocentry->cdte_format = fmt;
112 
113 	if (ioctl(fd, CDROMREADTOCENTRY, (char *) tocentry) == -1) {
114 		fprintf(stderr, "ioctl(cdromreadtocentry): ");
115 		perror(cdrom);
116 
117 		return(-1);
118 	}
119 
120 	return(0);
121 }
122 
cdrom_read_tochdr(fd,tochdr)123 cdrom_read_tochdr(fd, tochdr)
124 	int			fd;
125 	struct cdrom_tochdr	*tochdr;
126 {
127 	if (ioctl(fd, CDROMREADTOCHDR, (char *) tochdr) == -1) {
128 		fprintf(stderr, "ioctl(cdromreadtochdr): ");
129 		perror(cdrom);
130 
131 		return(-1);
132 	}
133 
134 	return(0);
135 }
136 
137 char *
cdrom_status(fd)138 cdrom_status(fd) {
139 	static char		buf[512];
140 	struct cdrom_subchnl	subchnl;
141 
142 	if (ioctl(fd, CDROMSUBCHNL, (char *) &subchnl) == -1) {
143 		fprintf(stderr, "ioctl(cdromsubchnl): ");
144 		perror(cdrom);
145 		exit(1);
146 	}
147 
148 	switch (subchnl.cdsc_audiostatus) {
149 		case CDROM_AUDIO_INVALID:
150 		return("invalid");
151 		break;
152 
153 		case CDROM_AUDIO_PLAY:
154 		sprintf(buf, "playing track %d", (int) subchnl.cdsc_trk);
155 		return(buf);
156 		break;
157 
158 		case CDROM_AUDIO_PAUSED:
159 		sprintf(buf, "paused on track %d", (int) subchnl.cdsc_trk);
160 		return(buf);
161 		break;
162 
163 		case CDROM_AUDIO_COMPLETED:
164 		return("completed");
165 		break;
166 
167 		case CDROM_AUDIO_ERROR:
168 		return("error");
169 		break;
170 
171 		case CDROM_AUDIO_NO_STATUS:
172 		return("no status");
173 		break;
174 	}
175 
176 	return("bad value in cdsc_audiostatus");
177 }
178 
cdrom_subchnl(fd,fmt)179 cdrom_subchnl(fd, fmt) {
180 	struct cdrom_subchnl	subchnl;
181 
182 	if (ioctl(fd, CDROMSUBCHNL, (char *) &subchnl) == -1) {
183 		fprintf(stderr, "ioctl(cdromsubchnl): ");
184 		perror(cdrom);
185 		exit(1);
186 	}
187 
188 	printf("subchnl:\n");
189 
190 	printf("format=0x%x\n", (unsigned int) subchnl.cdsc_format);
191 	printf("adr=%u\n", (unsigned int) subchnl.cdsc_adr);
192 	printf("ctrl=%u\n", (unsigned int) subchnl.cdsc_ctrl);
193 	printf("trk=%u\n", (unsigned int) subchnl.cdsc_trk);
194 	printf("ind=%u\n", (unsigned int) subchnl.cdsc_ind);
195 
196 	printf("absaddr=%02u:%02u %u\n",
197 	       (unsigned int) subchnl.cdsc_absaddr.msf.minute,
198 	       (unsigned int) subchnl.cdsc_absaddr.msf.second,
199 	       (unsigned int) subchnl.cdsc_absaddr.msf.frame);
200 
201 	printf("reladdr=%02u:%02u %u\n",
202 	       (unsigned int) subchnl.cdsc_reladdr.msf.minute,
203 	       (unsigned int) subchnl.cdsc_reladdr.msf.second,
204 	       (unsigned int) subchnl.cdsc_reladdr.msf.frame);
205 }
206