1 /*
2 * This file has been modified for the cdrkit suite.
3 *
4 * The behaviour and appearence of the program code below can differ to a major
5 * extent from the version distributed by the original author(s).
6 *
7 * For details, see Changelog file distributed with the cdrkit package. If you
8 * received this file from another source then ask the distributing person for
9 * a log of modifications.
10 *
11 */
12
13 /* @(#)dvd_reader.c 1.3 04/03/04 joerg */
14 /*
15 * Copyright (C) 2001, 2002 Billy Biggs <vektor@dumbterm.net>,
16 * H�kan Hjort <d95hjort@dtek.chalmers.se>,
17 * Olaf Beck <olaf_sc@yahoo.com>
18 * (I only did the cut down no other contribs)
19 * J�rg Schilling <schilling@fokus.gmd.de>
20 * (making the code portable)
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 2 of the License, or (at
24 * your option) any later version.
25 *
26 * This program is distributed in the hope that it will be useful, but
27 * WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
29 * General Public License for more details.
30 *
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 */
35
36 /*
37 * NOTE: This is a cut down version of libdvdread for genisoimage, due
38 * to portability issues with the current libdvdread according to
39 * the maintainer of genisoimage.
40 * This cut down version only reads from a harddisk file structure
41 * and it only implements the functions necessary inorder to make
42 * genisoimage produce valid DVD-Video images.
43 * DON'T USE THIS LIBRARY IN ANY OTHER PROGRAM GET THE REAL
44 * LIBDVDREAD INSTEAD
45 */
46 #ifdef DVD_VIDEO
47
48 #include "genisoimage.h"
49 #include <fctldefs.h>
50 #include <schily.h>
51
52 #include "dvd_reader.h"
53
54 struct dvd_file_s {
55 /* Basic information. */
56 dvd_reader_t *dvd;
57
58 /* Calculated at open-time, size in blocks. */
59 ssize_t filesize;
60 };
61
62
63 void DVDCloseFile(dvd_file_t *dvd_file);
64 static dvd_file_t *DVDOpenFilePath(dvd_reader_t *dvd, char *filename);
65 static dvd_file_t *DVDOpenVOBPath(dvd_reader_t *dvd, int title, int menu);
66 dvd_file_t *DVDOpenFile(dvd_reader_t *dvd, int titlenum,
67 dvd_read_domain_t domain);
68 static dvd_reader_t *DVDOpenPath(const char *path_root);
69 dvd_reader_t *DVDOpen(const char *path);
70 void DVDClose(dvd_reader_t *dvd);
71 ssize_t DVDFileSize(dvd_file_t *dvd_file);
72
73
74 /*
75 * Free a DVD file
76 */
77 void
DVDCloseFile(dvd_file_t * dvd_file)78 DVDCloseFile(dvd_file_t *dvd_file)
79 {
80 free(dvd_file);
81 dvd_file = 0;
82 }
83
84
85 /*
86 * Stat a IFO or BUP file from a DVD directory tree.
87 */
88 static dvd_file_t *
DVDOpenFilePath(dvd_reader_t * dvd,char * filename)89 DVDOpenFilePath(dvd_reader_t *dvd, char *filename)
90 {
91
92 char full_path[PATH_MAX + 1];
93 dvd_file_t *dvd_file;
94 struct stat fileinfo;
95
96 /* Get the full path of the file. */
97
98 snprintf(full_path, sizeof (full_path),
99 "%s/%s", dvd->path_root, filename);
100
101
102 dvd_file = (dvd_file_t *) e_malloc(sizeof (dvd_file_t));
103 if (!dvd_file)
104 return (0);
105 dvd_file->dvd = dvd;
106 dvd_file->filesize = 0;
107
108 if (stat(full_path, &fileinfo) < 0) {
109 free(dvd_file);
110 return (0);
111 }
112 dvd_file->filesize = fileinfo.st_size / DVD_VIDEO_LB_LEN;
113
114 return (dvd_file);
115 }
116
117
118 /*
119 * Stat a VOB file from a DVD directory tree.
120 */
121 static dvd_file_t *
DVDOpenVOBPath(dvd_reader_t * dvd,int title,int menu)122 DVDOpenVOBPath(dvd_reader_t *dvd, int title, int menu)
123 {
124
125 char filename[PATH_MAX + 1];
126 struct stat fileinfo;
127 dvd_file_t *dvd_file;
128 int i;
129
130 dvd_file = (dvd_file_t *) e_malloc(sizeof (dvd_file_t));
131 if (!dvd_file)
132 return (0);
133 dvd_file->dvd = dvd;
134 dvd_file->filesize = 0;
135
136 if (menu) {
137 if (title == 0) {
138 snprintf(filename, sizeof (filename),
139 "%s/VIDEO_TS/VIDEO_TS.VOB", dvd->path_root);
140 } else {
141 snprintf(filename, sizeof (filename),
142 "%s/VIDEO_TS/VTS_%02i_0.VOB", dvd->path_root, title);
143 }
144 if (stat(filename, &fileinfo) < 0) {
145 free(dvd_file);
146 return (0);
147 }
148 dvd_file->filesize = fileinfo.st_size / DVD_VIDEO_LB_LEN;
149 } else {
150 for (i = 0; i < 9; ++i) {
151
152 snprintf(filename, sizeof (filename),
153 "%s/VIDEO_TS/VTS_%02i_%i.VOB", dvd->path_root, title, i + 1);
154 if (stat(filename, &fileinfo) < 0) {
155 break;
156 }
157
158 dvd_file->filesize += fileinfo.st_size / DVD_VIDEO_LB_LEN;
159 }
160 }
161
162 return (dvd_file);
163 }
164
165 /*
166 * Stat a DVD file from a DVD directory tree
167 */
168 EXPORT dvd_file_t *
DVDOpenFile(dvd_reader_t * dvd,int titlenum,dvd_read_domain_t domain)169 DVDOpenFile(dvd_reader_t *dvd, int titlenum, dvd_read_domain_t domain)
170 {
171 char filename[MAX_UDF_FILE_NAME_LEN];
172
173 switch (domain) {
174
175 case DVD_READ_INFO_FILE:
176 if (titlenum == 0) {
177 snprintf(filename, sizeof (filename),
178 "/VIDEO_TS/VIDEO_TS.IFO");
179 } else {
180 snprintf(filename, sizeof (filename),
181 "/VIDEO_TS/VTS_%02i_0.IFO", titlenum);
182 }
183 break;
184
185 case DVD_READ_INFO_BACKUP_FILE:
186 if (titlenum == 0) {
187 snprintf(filename, sizeof (filename),
188 "/VIDEO_TS/VIDEO_TS.BUP");
189 } else {
190 snprintf(filename, sizeof (filename),
191 "/VIDEO_TS/VTS_%02i_0.BUP", titlenum);
192 }
193 break;
194
195 case DVD_READ_MENU_VOBS:
196 return (DVDOpenVOBPath(dvd, titlenum, 1));
197
198 case DVD_READ_TITLE_VOBS:
199 if (titlenum == 0)
200 return (0);
201 return (DVDOpenVOBPath(dvd, titlenum, 0));
202
203 default:
204 #ifdef USE_LIBSCHILY
205 errmsgno(EX_BAD, "Invalid domain for file open.\n");
206 #else
207 fprintf(stderr, "Invalid domain for file open.\n");
208 #endif
209 return (0);
210 }
211 return (DVDOpenFilePath(dvd, filename));
212 }
213
214
215
216 /*
217 * Stat a DVD directory structure
218 */
219 static dvd_reader_t *
DVDOpenPath(const char * path_root)220 DVDOpenPath(const char *path_root)
221 {
222 dvd_reader_t *dvd;
223
224 dvd = (dvd_reader_t *) e_malloc(sizeof (dvd_reader_t));
225 if (!dvd)
226 return (0);
227 dvd->path_root = strdup(path_root);
228
229 return (dvd);
230 }
231
232
233 /*
234 * Stat a DVD structure - this one only works with directory structures
235 */
236 dvd_reader_t *
DVDOpen(const char * path)237 DVDOpen(const char *path)
238 {
239 struct stat fileinfo;
240 int ret;
241
242 if (!path)
243 return (0);
244
245 ret = stat(path, &fileinfo);
246 if (ret < 0) {
247 /* If we can't stat the file, give up */
248 #ifdef USE_LIBSCHILY
249 errmsg("Can't stat %s\n", path);
250 #else
251 fprintf(stderr, "Can't stat %s\n", path);
252 perror("");
253 #endif
254 return (0);
255 }
256
257
258 if (S_ISDIR(fileinfo.st_mode)) {
259 return (DVDOpenPath(path));
260 }
261
262 /* If it's none of the above, screw it. */
263 #ifdef USE_LIBSCHILY
264 errmsgno(EX_BAD, "Could not open %s\n", path);
265 #else
266 fprintf(stderr, "Could not open %s\n", path);
267 #endif
268 return (0);
269 }
270
271 /*
272 * Free a DVD structure - this one will only close a directory tree
273 */
274 void
DVDClose(dvd_reader_t * dvd)275 DVDClose(dvd_reader_t *dvd)
276 {
277 if (dvd) {
278 if (dvd->path_root) free(dvd->path_root);
279 free(dvd);
280 dvd = 0;
281 }
282 }
283
284
285
286 /*
287 * Return the size of a DVD file
288 */
289 ssize_t
DVDFileSize(dvd_file_t * dvd_file)290 DVDFileSize(dvd_file_t *dvd_file)
291 {
292 return (dvd_file->filesize);
293 }
294
295 #endif /* DVD_VIDEO */
296