patch zlib check
[platform/upstream/cdrkit.git] / genisoimage / dvd_reader.c
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
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 *
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 *
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 *
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 *
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 *
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
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
290 DVDFileSize(dvd_file_t *dvd_file)
291 {
292         return (dvd_file->filesize);
293 }
294
295 #endif /* DVD_VIDEO */