source: trunk/src/testing/bin/fileServer/misc/mmpython/disc/cdrommodule.c @ 4

Revision 4, 7.3 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

Line 
1/*
2 * cdrommodule.c
3 * Python extension module for reading in audio CD-ROM data
4 *
5 * Please port me to other OSes besides Linux, Solaris, OpenBSD,
6 * and FreeBSD!
7 *
8 * See the README for info.
9 *
10 * Written 17 Nov 1999 by Ben Gertzfield <che@debian.org>
11 * This work is released under the GNU GPL, version 2 or later.
12 *
13 * FreeBSD support by Michael Yoon <michael@yoon.org>
14 * OpenBSD support added by Alexander Guy <alex@andern.org>
15 *
16 * Thanks to Viktor Fougstedt <viktor@dtek.chalmers.se> for info
17 * on the <sys/cdio.h> include file to make this work on Solaris!
18 *
19 * Release version 1.2
20 *
21 *
22 *
23 * changes for mmpython:
24 *
25 * $Log: cdrommodule.c,v $
26 * Revision 1.2  2003/06/23 19:26:16  dischi
27 * Fixed bug in the cdrommodule that the file was not closed after usage.
28 * The result was a drive you can't eject while the program (e.g. Freevo)
29 * is running. Added cvs log for DiscID and cdrommodule to keep track of
30 * all changes we did for mmpython.
31 *
32 *
33 * CVS ID: $Id: cdrommodule.c,v 1.2 2003/06/23 19:26:16 dischi Exp $
34 */
35
36#include "Python.h"
37#include <fcntl.h>
38#include <sys/ioctl.h>
39
40#ifdef __linux__
41#include <linux/cdrom.h>
42#endif
43
44#if defined(sun) || defined(__FreeBSD__) || defined(__OpenBSD__)
45#include <sys/cdio.h>
46#endif
47
48/*
49 * Since FreeBSD has identical support but different names for lots
50 * of these structs and constants, we'll just #define CDDB_WHATEVER
51 * so that we don't have to repeat the code.
52 */
53
54#ifdef __FreeBSD__
55
56#define CDDB_TOC_HEADER_STRUCT ioc_toc_header
57#define CDDB_STARTING_TRACK_FIELD starting_track
58#define CDDB_ENDING_TRACK_FIELD ending_track
59#define CDDB_READ_TOC_HEADER_FLAG CDIOREADTOCHEADER
60#define CDDB_TOC_ENTRY_STRUCT ioc_read_toc_single_entry
61#define CDDB_TRACK_FIELD track
62#define CDDB_FORMAT_FIELD address_format
63#define CDDB_MSF_FORMAT CD_MSF_FORMAT
64#define CDDB_ADDR_FIELD entry.addr
65#define CDDB_READ_TOC_ENTRY_FLAG CDIOREADTOCENTRY
66#define CDDB_CDROM_LEADOUT 0xaa
67#define CDDB_DEFAULT_CDROM_DEVICE "/dev/cdrom"
68#define CDDB_DEFAULT_CDROM_FLAGS 0
69
70#elif defined(__OpenBSD__)
71
72#define CDDB_TOC_HEADER_STRUCT ioc_toc_header
73#define CDDB_STARTING_TRACK_FIELD starting_track
74#define CDDB_ENDING_TRACK_FIELD ending_track
75#define CDDB_READ_TOC_HEADER_FLAG CDIOREADTOCHEADER
76#define CDDB_TOC_ENTRY_STRUCT ioc_read_toc_entry
77#define CDDB_TRACK_FIELD starting_track
78#define CDDB_FORMAT_FIELD address_format
79#define CDDB_MSF_FORMAT CD_MSF_FORMAT 
80#define CDDB_ADDR_FIELD data->addr
81#define CDDB_READ_TOC_ENTRY_FLAG CDIOREADTOCENTRIES
82#define CDDB_CDROM_LEADOUT 0xaa
83#define CDDB_DEFAULT_CDROM_DEVICE "/dev/cdrom"
84#define CDDB_DEFAULT_CDROM_FLAGS 0
85
86#else /* Linux and Solaris */
87
88#define CDDB_TOC_HEADER_STRUCT cdrom_tochdr
89#define CDDB_STARTING_TRACK_FIELD cdth_trk0
90#define CDDB_ENDING_TRACK_FIELD cdth_trk1
91#define CDDB_READ_TOC_HEADER_FLAG CDROMREADTOCHDR
92#define CDDB_TOC_ENTRY_STRUCT cdrom_tocentry
93#define CDDB_TRACK_FIELD cdte_track
94#define CDDB_FORMAT_FIELD cdte_format
95#define CDDB_MSF_FORMAT CDROM_MSF
96#define CDDB_ADDR_FIELD cdte_addr
97#define CDDB_READ_TOC_ENTRY_FLAG CDROMREADTOCENTRY
98#define CDDB_CDROM_LEADOUT CDROM_LEADOUT
99
100#ifdef sun
101#define CDDB_DEFAULT_CDROM_DEVICE "/dev/vol/alias/cdrom0"
102#else
103#define CDDB_DEFAULT_CDROM_DEVICE "/dev/cdrom"
104#endif /* sun */
105
106#define CDDB_DEFAULT_CDROM_FLAGS O_RDONLY | O_NONBLOCK
107
108#endif /* __FreeBSD__ */
109
110static PyObject *cdrom_error;
111
112static PyObject *cdrom_toc_header(PyObject *self, PyObject *args)
113{
114    struct CDDB_TOC_HEADER_STRUCT hdr;
115    PyObject *cdrom_fileobj;
116    int cdrom_fd;
117
118    if (!PyArg_ParseTuple(args, "O!", &PyFile_Type, &cdrom_fileobj))
119        return NULL;
120
121    cdrom_fd = fileno(PyFile_AsFile(cdrom_fileobj));
122
123    if (ioctl(cdrom_fd, CDDB_READ_TOC_HEADER_FLAG, &hdr) < 0) {
124        PyErr_SetFromErrno(cdrom_error);
125        return NULL;
126    }
127   
128    return Py_BuildValue("bb", hdr.CDDB_STARTING_TRACK_FIELD,
129                         hdr.CDDB_ENDING_TRACK_FIELD);
130}
131
132static PyObject *cdrom_toc_entry(PyObject *self, PyObject *args)
133{
134    struct CDDB_TOC_ENTRY_STRUCT entry;
135    PyObject *cdrom_fileobj;
136    int cdrom_fd;
137    unsigned char track;
138
139#if defined(__OpenBSD__)
140    struct cd_toc_entry data;
141#endif
142
143    if (!PyArg_ParseTuple(args, "O!b", &PyFile_Type, &cdrom_fileobj, &track))
144        return  NULL;
145
146    cdrom_fd = fileno(PyFile_AsFile(cdrom_fileobj));
147
148    entry.CDDB_TRACK_FIELD = track;
149    entry.CDDB_FORMAT_FIELD = CDDB_MSF_FORMAT;
150
151#if defined(__OpenBSD__)
152    entry.data = &data;
153    entry.data_len = sizeof(data);
154#endif
155
156    if (ioctl(cdrom_fd, CDDB_READ_TOC_ENTRY_FLAG, &entry) < 0) {
157        PyErr_SetFromErrno(cdrom_error);
158        return NULL;
159    }
160
161    return Py_BuildValue("bbb", entry.CDDB_ADDR_FIELD.msf.minute,
162                         entry.CDDB_ADDR_FIELD.msf.second,
163                         entry.CDDB_ADDR_FIELD.msf.frame);
164}
165
166static PyObject *cdrom_leadout(PyObject *self, PyObject *args)
167{
168    struct CDDB_TOC_ENTRY_STRUCT entry;
169    PyObject *cdrom_fileobj;
170    int cdrom_fd;
171
172#if defined(__OpenBSD__)
173    struct cd_toc_entry data;
174#endif
175
176    if (!PyArg_ParseTuple(args, "O!", &PyFile_Type, &cdrom_fileobj))
177        return  NULL;
178
179    cdrom_fd = fileno(PyFile_AsFile(cdrom_fileobj));
180
181    entry.CDDB_TRACK_FIELD = CDDB_CDROM_LEADOUT;
182    entry.CDDB_FORMAT_FIELD = CDDB_MSF_FORMAT;
183
184#if defined(__OpenBSD__)
185    entry.data = &data;
186    entry.data_len = sizeof(data);
187#endif
188
189    if (ioctl(cdrom_fd, CDDB_READ_TOC_ENTRY_FLAG, &entry) < 0) {
190        PyErr_SetFromErrno(cdrom_error);
191        return NULL;
192    }
193
194    return Py_BuildValue("bbb", entry.CDDB_ADDR_FIELD.msf.minute,
195                         entry.CDDB_ADDR_FIELD.msf.second,
196                         entry.CDDB_ADDR_FIELD.msf.frame);
197}
198
199int cdrom_close(FILE *cdrom_file)
200{
201  return 0;
202}
203
204static PyObject *cdrom_really_close(PyObject *self, PyObject *args)
205{
206    PyObject *cdrom_fileobj;
207    int cdrom_fd;
208
209#if defined(__OpenBSD__)
210    struct cd_toc_entry data;
211#endif
212
213    if (!PyArg_ParseTuple(args, "O!", &PyFile_Type, &cdrom_fileobj))
214        return  NULL;
215
216    cdrom_fd = fileno(PyFile_AsFile(cdrom_fileobj));
217    close(cdrom_fd);
218    return Py_BuildValue("b", 1);
219}
220
221static PyObject* cdrom_open(PyObject *self, PyObject *args)
222{
223    int cdrom_fd;
224    FILE *cdrom_file;
225    char *cdrom_device = CDDB_DEFAULT_CDROM_DEVICE;
226    int cdrom_open_flags = CDDB_DEFAULT_CDROM_FLAGS;
227
228    PyObject *cdrom_file_object;
229
230    if (!PyArg_ParseTuple(args, "|si", &cdrom_device, &cdrom_open_flags))
231        return NULL;
232
233    cdrom_fd = open(cdrom_device, cdrom_open_flags);
234
235    if (cdrom_fd == -1) {
236        PyErr_SetFromErrno(cdrom_error);
237        return NULL;
238    }
239   
240    cdrom_file = fdopen(cdrom_fd, "r");
241
242    if (cdrom_file == NULL) {
243        PyErr_SetFromErrno(cdrom_error);
244        return NULL;
245    }
246
247    cdrom_file_object = PyFile_FromFile(cdrom_file, cdrom_device, "r", cdrom_close);
248
249    if (cdrom_file_object == NULL) {
250        PyErr_SetString(cdrom_error, "Internal conversion from file pointer to Python object failed");
251        fclose(cdrom_file);
252        return NULL;
253    }
254
255    return Py_BuildValue("O", cdrom_file_object);
256}
257
258static PyMethodDef cdrom_methods[] = {
259    { "toc_header", cdrom_toc_header, METH_VARARGS },
260    { "toc_entry", cdrom_toc_entry, METH_VARARGS },
261    { "leadout", cdrom_leadout, METH_VARARGS},
262    { "open", cdrom_open, METH_VARARGS},
263    { "close", cdrom_really_close, METH_VARARGS},
264    { NULL, NULL }
265};
266
267void initcdrom(void)
268{
269    PyObject *module, *dict;
270
271    module = Py_InitModule("cdrom", cdrom_methods);
272    dict = PyModule_GetDict(module);
273    cdrom_error = PyErr_NewException("cdrom.error", NULL, NULL);
274    PyDict_SetItemString(dict, "error", cdrom_error);
275}
Note: See TracBrowser for help on using the repository browser.