1 /* @(#)dvd_file.c	1.16 18/09/17 joerg */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static	UConst char sccsid[] =
5 	"@(#)dvd_file.c	1.16 18/09/17 joerg";
6 #endif
7 /*
8  * DVD_AUD_VID code
9  *  Copyright (c) 2002 Olaf Beck - olaf_sc@yahoo.com
10  *  Copyright (c) 2002-2015 J�rg Schilling <joerg@schily.net>
11  */
12 /*
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License version 2
15  * as published by the Free Software Foundation.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License along with
23  * this program; see the file COPYING.  If not, write to the Free Software
24  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25  */
26 
27 #ifdef DVD_AUD_VID
28 
29 #include "mkisofs.h"
30 #include <schily/schily.h>
31 #include "dvd_reader.h"
32 #include "dvd_file.h"
33 #include "ifo_read.h"
34 
35 LOCAL	void	bsort		__PR((int sector[], int title[], int size));
36 LOCAL	void	uniq		__PR((int sector[], int title[],
37 					int title_sets_array[],
38 					int sector_sets_array[], int titles));
39 LOCAL	void	DVDFreeFileSetArrays __PR((int *sector, int *title, int *title_sets_array,
40 					int *sector_sets_array));
41 EXPORT	void	DVDFreeFileSet	__PR((title_set_info_t *title_set_info));
42 EXPORT	title_set_info_t *DVDGetFileSet __PR((char *dvd));
43 EXPORT	int	DVDGetFilePad	__PR((title_set_info_t *title_set_info, char *name));
44 
45 
46 LOCAL void
bsort(sector,title,size)47 bsort(sector, title, size)
48 	int	sector[];
49 	int	title[];
50 	int	size;
51 {
52 	int	temp_title;
53 	int	temp_sector;
54 	int	i;
55 	int	j;
56 
57 	for (i = 0; i < size; i++) {
58 		for (j = 0; j < size; j++) {
59 			if (sector[i] < sector[j]) {
60 				temp_sector = sector[i];
61 				temp_title = title[i];
62 				sector[i] = sector[j];
63 				title[i] = title[j];
64 				sector[j] = temp_sector;
65 				title[j] = temp_title;
66 			}
67 		}
68 	}
69 }
70 
71 
72 LOCAL void
uniq(sector,title,title_sets_array,sector_sets_array,titles)73 uniq(sector, title, title_sets_array, sector_sets_array, titles)
74 	int	sector[];
75 	int	title[];
76 	int	title_sets_array[];
77 	int	sector_sets_array[];
78 	int	titles;
79 {
80 	int	i;
81 	int	j;
82 
83 
84 	for (i = 0, j = 0; j < titles; ) {
85 		if (sector[j] != sector[j+1]) {
86 			title_sets_array[i]  = title[j];
87 			sector_sets_array[i] = sector[j];
88 #ifdef DEBUG
89 			fprintf(stderr, _("Sector offset is %d\n"), sector_sets_array[i]);
90 #endif
91 			i++;
92 			j++;
93 		} else {
94 			do {
95 				if (j < titles)
96 					j++;
97 
98 			} while (sector[j] == sector[j+1]);
99 
100 		}
101 	}
102 
103 }
104 
105 LOCAL void
DVDFreeFileSetArrays(sector,title,title_sets_array,sector_sets_array)106 DVDFreeFileSetArrays(sector, title, title_sets_array, sector_sets_array)
107 	int	*sector;
108 	int	*title;
109 	int	*title_sets_array;
110 	int	*sector_sets_array;
111 {
112 	free(sector);
113 	free(title);
114 	free(title_sets_array);
115 	free(sector_sets_array);
116 }
117 
118 EXPORT void
DVDFreeFileSet(title_set_info)119 DVDFreeFileSet(title_set_info)
120 	title_set_info_t *title_set_info;
121 {
122 	free(title_set_info->title_set);
123 	free(title_set_info);
124 }
125 
126 EXPORT title_set_info_t *
DVDGetFileSet(dvd)127 DVDGetFileSet(dvd)
128 	char	*dvd;
129 {
130 	/*
131 	 * TODO  Fix close of files if
132 	 *	we error out
133 	 *	We also assume that all
134 	 *	DVD files are of valid
135 	 *	size i.e. file%2048 == 0
136 	 */
137 
138 	/* title interation */
139 	int		title_sets;
140 	int		titles;
141 	int		counter;
142 	int		i;
143 
144 	/* DVD file structures */
145 	dvd_reader_t	*_dvd = NULL;
146 
147 	ifo_handle_t	*vmg_ifo = NULL;
148 	ifo_handle_t	*vts_ifo = NULL;
149 
150 	dvd_file_t	*vmg_vob_file = NULL;
151 	dvd_file_t	*vmg_ifo_file = NULL;
152 
153 	dvd_file_t	*vts_ifo_file = NULL;
154 	dvd_file_t	*vts_menu_file = NULL;
155 	dvd_file_t	*vts_title_file = NULL;
156 
157 	/* The sizes it self of each file */
158 	int		ifo;
159 	int		bup;
160 	int		menu_vob;
161 	int		title_vob;
162 
163 	/* Arrays keeping the title - filset relationship */
164 	int		*sector;
165 	int		*title;
166 	int		*title_sets_array;
167 	int		*sector_sets_array;
168 
169 	/* DVD Video files */
170 	struct stat	fileinfo;
171 	char		temppoint[PATH_MAX + 1];
172 
173 	/* The Title Set Info struct*/
174 	title_set_info_t *title_set_info;
175 
176 	/* Temporary mount point - to be used later */
177 	char		mountpoint[PATH_MAX + 1];
178 
179 	strncpy(mountpoint, dvd, sizeof (mountpoint));
180 	mountpoint[sizeof (mountpoint)-1] = '\0';
181 
182 
183 	_dvd = DVDOpen(dvd);
184 	if (!_dvd) {
185 		errmsgno(EX_BAD, _("Can't open device '%s'.\n"), dvd);
186 		return (0);
187 	}
188 	vmg_ifo = ifoOpen(_dvd, 0);
189 	if (!vmg_ifo) {
190 		errmsgno(EX_BAD, _("Can't open VMG info for '%s'.\n"), dvd);
191 		/* Close the DVD */
192 		DVDClose(_dvd);
193 		return (0);
194 	}
195 
196 	/* Check mount point */
197 
198 	snprintf(temppoint, sizeof (temppoint),
199 				"%s/VIDEO_TS/VIDEO_TS.IFO", mountpoint);
200 
201 
202 	if (stat(temppoint, &fileinfo) < 0) {
203 		/* If we can't stat the file, give up */
204 		errmsg(_("Can't stat '%s'.\n"), temppoint);
205 		return (0);
206 	}
207 
208 
209 
210 	title_sets = vmg_ifo->vmgi_mat->vmg_nr_of_title_sets;
211 	titles = vmg_ifo->tt_srpt->nr_of_srpts;
212 
213 	sector = e_malloc(titles * sizeof (int));
214 	memset(sector, 0, titles * sizeof (int));
215 	title = e_malloc(titles * sizeof (int));
216 	title_sets_array = e_malloc(title_sets * sizeof (int));
217 	sector_sets_array = e_malloc(title_sets * sizeof (int));
218 	title_set_info = (title_set_info_t *)e_malloc(sizeof (title_set_info_t));
219 	title_set_info->title_set = (title_set_t *)e_malloc((title_sets + 1) *
220 							sizeof (title_set_t));
221 
222 	title_set_info->num_titles = title_sets;
223 
224 
225 	/* Fill and sort the arrays for titles*/
226 
227 	if (titles >= 1) {
228 		for (counter = 0; counter < titles; counter++) {
229 			sector[counter] = vmg_ifo->tt_srpt->title[counter].title_set_sector;
230 			title[counter]  = counter + 1;
231 		}
232 	}
233 
234 	/* Yes, we should probably do a better sort than B - but what the heck*/
235 	bsort(sector, title, titles);
236 
237 
238 	/*
239 	 * Since title sets and titles are not the same we will need to sort
240 	 * out "bogus" titles
241 	 */
242 
243 	uniq(sector, title, title_sets_array, sector_sets_array, titles);
244 
245 
246 	/* Open VIDEO_TS.VOB is present */
247 
248 	vmg_vob_file = DVDOpenFile(_dvd, 0, DVD_READ_MENU_VOBS);
249 
250 	/* Check VIDEO_TS title set */
251 
252 	vmg_ifo_file = DVDOpenFile(_dvd, 0, DVD_READ_INFO_FILE);
253 
254 	if ((vmg_vob_file == 0) && vmg_ifo->vmgi_mat->vmg_last_sector + 1
255 			< 2 * DVDFileSize(vmg_ifo_file)) {
256 		errmsgno(EX_BAD, _("IFO is not of correct size aborting.\n"));
257 		DVDFreeFileSetArrays(sector, title, title_sets_array,
258 					sector_sets_array);
259 		DVDFreeFileSet(title_set_info);
260 		return (0);
261 	} else if ((vmg_vob_file != 0) && (vmg_ifo->vmgi_mat->vmg_last_sector
262 		    + 1  < 2 * DVDFileSize(vmg_ifo_file) +
263 		    DVDFileSize(vmg_vob_file))) {
264 		errmsgno(EX_BAD, _("Either VIDEO_TS.IFO or VIDEO_TS.VOB is not of correct size.\n"));
265 		DVDFreeFileSetArrays(sector, title, title_sets_array,
266 					sector_sets_array);
267 		DVDFreeFileSet(title_set_info);
268 		return (0);
269 	}
270 
271 	/* Find the actuall right size of VIDEO_TS.IFO */
272 	if (vmg_vob_file == 0) {
273 		if (vmg_ifo->vmgi_mat->vmg_last_sector + 1 > 2
274 				*  DVDFileSize(vmg_ifo_file)) {
275 			ifo = vmg_ifo->vmgi_mat->vmg_last_sector
276 				- DVDFileSize(vmg_ifo_file) + 1;
277 		} else {
278 			ifo = vmg_ifo->vmgi_mat->vmgi_last_sector + 1;
279 		}
280 	} else {
281 		if (vmg_ifo->vmgi_mat->vmgi_last_sector + 1
282 				< vmg_ifo->vmgi_mat->vmgm_vobs) {
283 			ifo = vmg_ifo->vmgi_mat->vmgm_vobs;
284 		} else {
285 			ifo = vmg_ifo->vmgi_mat->vmgi_last_sector + 1;
286 		}
287 	}
288 
289 	title_set_info->title_set[0].size_ifo = ifo * 2048;
290 	title_set_info->title_set[0].realsize_ifo = fileinfo.st_size;
291 	title_set_info->title_set[0].pad_ifo = ifo - DVDFileSize(vmg_ifo_file);
292 
293 	/* Find the actuall right size of VIDEO_TS.VOB */
294 	if (vmg_vob_file != 0) {
295 		if (ifo + DVDFileSize(vmg_ifo_file) +
296 		    DVDFileSize(vmg_vob_file) - 1 <
297 		    vmg_ifo->vmgi_mat->vmg_last_sector) {
298 				menu_vob = vmg_ifo->vmgi_mat->vmg_last_sector -
299 						ifo - DVDFileSize(vmg_ifo_file) + 1;
300 		} else {
301 			menu_vob = vmg_ifo->vmgi_mat->vmg_last_sector
302 			- ifo - DVDFileSize(vmg_ifo_file) + 1;
303 		}
304 
305 		snprintf(temppoint, sizeof (temppoint),
306 				"%s/VIDEO_TS/VIDEO_TS.VOB", mountpoint);
307 		if (stat(temppoint, &fileinfo) < 0) {
308 			errmsg(_("calc: Can't stat '%s'.\n"), temppoint);
309 			DVDFreeFileSetArrays(sector, title, title_sets_array,
310 						sector_sets_array);
311 			DVDFreeFileSet(title_set_info);
312 			return (0);
313 		}
314 
315 		title_set_info->title_set[0].realsize_menu = fileinfo.st_size;
316 		title_set_info->title_set[0].pad_menu = menu_vob -
317 						DVDFileSize(vmg_vob_file);
318 		title_set_info->title_set[0].size_menu = menu_vob * 2048;
319 		DVDCloseFile(vmg_vob_file);
320 	} else {
321 		title_set_info->title_set[0].size_menu = 0;
322 		title_set_info->title_set[0].realsize_menu = 0;
323 		title_set_info->title_set[0].pad_menu = 0;
324 		menu_vob = 0;
325 	}
326 
327 
328 	/* Finding the actuall right size of VIDEO_TS.BUP */
329 	if (title_sets >= 1) {
330 		bup = sector_sets_array[0] - menu_vob - ifo;
331 	} else {
332 		/* Just in case we burn a DVD-Video without any title_sets */
333 		bup = vmg_ifo->vmgi_mat->vmg_last_sector + 1 - menu_vob - ifo;
334 	}
335 
336 	/* Never trust the BUP file - use a copy of the IFO */
337 	snprintf(temppoint, sizeof (temppoint),
338 				"%s/VIDEO_TS/VIDEO_TS.IFO", mountpoint);
339 
340 	if (stat(temppoint, &fileinfo) < 0) {
341 		errmsg(_("calc: Can't stat '%s'.\n"), temppoint);
342 		DVDFreeFileSetArrays(sector, title, title_sets_array,
343 					sector_sets_array);
344 		DVDFreeFileSet(title_set_info);
345 		return (0);
346 	}
347 
348 	title_set_info->title_set[0].realsize_bup = fileinfo.st_size;
349 	title_set_info->title_set[0].size_bup = bup * 2048;
350 	title_set_info->title_set[0].pad_bup = bup - DVDFileSize(vmg_ifo_file);
351 
352 	/* Take care of the titles which we don't have in VMG */
353 
354 	title_set_info->title_set[0].number_of_vob_files = 0;
355 	title_set_info->title_set[0].realsize_vob[0] = 0;
356 	title_set_info->title_set[0].pad_title = 0;
357 
358 	DVDCloseFile(vmg_ifo_file);
359 
360 	if (title_sets >= 1) {
361 		for (counter = 0; counter < title_sets; counter++) {
362 
363 			vts_ifo = ifoOpen(_dvd, counter + 1);
364 
365 			if (!vts_ifo) {
366 				errmsgno(EX_BAD, _("Can't open VTS info.\n"));
367 				DVDFreeFileSetArrays(sector, title,
368 					title_sets_array, sector_sets_array);
369 				DVDFreeFileSet(title_set_info);
370 				return (0);
371 			}
372 
373 			snprintf(temppoint, sizeof (temppoint),
374 				"%s/VIDEO_TS/VTS_%02i_0.IFO",
375 				mountpoint, counter + 1);
376 
377 			if (stat(temppoint, &fileinfo) < 0) {
378 				errmsg(_("calc: Can't stat '%s'.\n"), temppoint);
379 				DVDFreeFileSetArrays(sector, title,
380 					title_sets_array, sector_sets_array);
381 				DVDFreeFileSet(title_set_info);
382 				return (0);
383 			}
384 
385 
386 			/* Test if VTS_XX_0.VOB is present */
387 
388 			vts_menu_file = DVDOpenFile(_dvd, counter + 1,
389 					DVD_READ_MENU_VOBS);
390 
391 			/* Test if VTS_XX_X.VOB are present */
392 
393 			vts_title_file = DVDOpenFile(_dvd, counter + 1,
394 						DVD_READ_TITLE_VOBS);
395 
396 			/* Check VIDEO_TS.IFO */
397 
398 			vts_ifo_file = DVDOpenFile(_dvd, counter + 1,
399 							DVD_READ_INFO_FILE);
400 
401 			/*
402 			 * Checking that title will fit in the
403 			 * space given by the ifo file
404 			 */
405 
406 
407 			if (vts_ifo->vtsi_mat->vts_last_sector + 1
408 				< 2 * DVDFileSize(vts_ifo_file)) {
409 				errmsgno(EX_BAD, _("IFO is not of correct size aborting.\n"));
410 				DVDFreeFileSetArrays(sector, title,
411 					title_sets_array, sector_sets_array);
412 				DVDFreeFileSet(title_set_info);
413 				return (0);
414 			} else if ((vts_title_file != 0) &&
415 				    (vts_menu_file != 0) &&
416 				    (vts_ifo->vtsi_mat->vts_last_sector + 1
417 				    < 2 * DVDFileSize(vts_ifo_file) +
418 				    DVDFileSize(vts_title_file) +
419 				    DVDFileSize(vts_menu_file))) {
420 				errmsgno(EX_BAD, _("Either VIDEO_TS.IFO or VIDEO_TS.VOB is not of correct size.\n"));
421 				DVDFreeFileSetArrays(sector, title,
422 					title_sets_array, sector_sets_array);
423 				DVDFreeFileSet(title_set_info);
424 				return (0);
425 			} else if ((vts_title_file != 0) &&
426 				    (vts_menu_file == 0) &&
427 				    (vts_ifo->vtsi_mat->vts_last_sector + 1
428 				    < 2 * DVDFileSize(vts_ifo_file) +
429 				    DVDFileSize(vts_title_file))) {
430 				errmsgno(EX_BAD, _("Either VIDEO_TS.IFO or VIDEO_TS.VOB is not of correct size.\n"));
431 				DVDFreeFileSetArrays(sector, title,
432 					title_sets_array, sector_sets_array);
433 				DVDFreeFileSet(title_set_info);
434 				return (0);
435 			} else if ((vts_menu_file != 0) &&
436 				    (vts_title_file == 0) &&
437 				    (vts_ifo->vtsi_mat->vts_last_sector + 1
438 				    < 2 * DVDFileSize(vts_ifo_file) +
439 				    DVDFileSize(vts_menu_file))) {
440 				errmsgno(EX_BAD, _("Either VIDEO_TS.IFO or VIDEO_TS.VOB is not of correct size.\n"));
441 				DVDFreeFileSetArrays(sector, title,
442 					title_sets_array, sector_sets_array);
443 				DVDFreeFileSet(title_set_info);
444 				return (0);
445 			}
446 
447 
448 			/* Find the actuall right size of VTS_XX_0.IFO */
449 			if ((vts_title_file == 0) && (vts_menu_file == 0)) {
450 				if (vts_ifo->vtsi_mat->vts_last_sector + 1 >
451 				    2 * DVDFileSize(vts_ifo_file)) {
452 					ifo = vts_ifo->vtsi_mat->vts_last_sector
453 						- DVDFileSize(vts_ifo_file) + 1;
454 				} else {
455 					ifo = vts_ifo->vtsi_mat->vts_last_sector
456 						- DVDFileSize(vts_ifo_file) + 1;
457 				}
458 			} else if (vts_title_file == 0) {
459 				if (vts_ifo->vtsi_mat->vtsi_last_sector + 1 <
460 				    vts_ifo->vtsi_mat->vtstt_vobs) {
461 					ifo = vmg_ifo->vtsi_mat->vtstt_vobs;
462 				} else {
463 					ifo = vmg_ifo->vtsi_mat->vtstt_vobs;
464 				}
465 			} else {
466 				if (vts_ifo->vtsi_mat->vtsi_last_sector + 1 <
467 				    vts_ifo->vtsi_mat->vtsm_vobs) {
468 					ifo = vts_ifo->vtsi_mat->vtsm_vobs;
469 				} else {
470 					ifo = vts_ifo->vtsi_mat->vtsi_last_sector + 1;
471 				}
472 			}
473 			title_set_info->title_set[counter + 1].size_ifo =
474 						ifo * 2048;
475 			title_set_info->title_set[counter + 1].realsize_ifo =
476 						fileinfo.st_size;
477 			title_set_info->title_set[counter + 1].pad_ifo =
478 						ifo - DVDFileSize(vts_ifo_file);
479 
480 
481 			/* Find the actuall right size of VTS_XX_0.VOB */
482 			if (vts_menu_file != 0) {
483 				if (vts_ifo->vtsi_mat->vtsm_vobs == 0)  {
484 					/*
485 					 * Apparently start sector 0 means that
486 					 * VTS_XX_0.VOB is empty after all...
487 					 */
488 					menu_vob = 0;
489 					if (DVDFileSize(vts_menu_file) != 0) {
490 						/*
491 						 * Paranoia: we most likely never
492 						 * come here...
493 						 */
494 						errmsgno(EX_BAD,
495 							_("%s/VIDEO_TS/VTS_%02i_0.IFO appears to be corrupted.\n"),
496 							mountpoint, counter+1);
497 						return (0);
498 					}
499 				} else if ((vts_title_file != 0) &&
500 					(vts_ifo->vtsi_mat->vtstt_vobs -
501 					vts_ifo->vtsi_mat->vtsm_vobs >
502 						DVDFileSize(vts_menu_file))) {
503 					menu_vob = vts_ifo->vtsi_mat->vtstt_vobs -
504 							vts_ifo->vtsi_mat->vtsm_vobs;
505 				} else if ((vts_title_file == 0) &&
506 					    (vts_ifo->vtsi_mat->vtsm_vobs +
507 					    DVDFileSize(vts_menu_file) +
508 					    DVDFileSize(vts_ifo_file) - 1 <
509 					    vts_ifo->vtsi_mat->vts_last_sector)) {
510 					menu_vob = vts_ifo->vtsi_mat->vts_last_sector
511 						- DVDFileSize(vts_ifo_file)
512 						- vts_ifo->vtsi_mat->vtsm_vobs + 1;
513 				} else {
514 					menu_vob = vts_ifo->vtsi_mat->vtstt_vobs -
515 							vts_ifo->vtsi_mat->vtsm_vobs;
516 				}
517 
518 				snprintf(temppoint, sizeof (temppoint),
519 					"%s/VIDEO_TS/VTS_%02i_0.VOB", mountpoint, counter + 1);
520 
521 				if (stat(temppoint, &fileinfo)  < 0) {
522 					errmsg(_("calc: Can't stat '%s'.\n"), temppoint);
523 					DVDFreeFileSetArrays(sector, title,
524 						title_sets_array, sector_sets_array);
525 					DVDFreeFileSet(title_set_info);
526 					return (0);
527 				}
528 
529 				title_set_info->title_set[counter + 1].realsize_menu = fileinfo.st_size;
530 				title_set_info->title_set[counter + 1].size_menu = menu_vob * 2048;
531 				title_set_info->title_set[counter + 1].pad_menu = menu_vob - DVDFileSize(vts_menu_file);
532 
533 			} else {
534 				title_set_info->title_set[counter + 1].size_menu = 0;
535 				title_set_info->title_set[counter + 1].realsize_menu = 0;
536 				title_set_info->title_set[counter + 1].pad_menu = 0;
537 				menu_vob = 0;
538 			}
539 
540 
541 			/* Find the actuall total size of VTS_XX_[1 to 9].VOB */
542 
543 			if (vts_title_file != 0) {
544 				if (ifo + menu_vob + DVDFileSize(vts_ifo_file) -
545 				    1 < vts_ifo->vtsi_mat->vts_last_sector) {
546 				    title_vob = vts_ifo->vtsi_mat->vts_last_sector
547 						+ 1 - ifo - menu_vob -
548 						DVDFileSize(vts_ifo_file);
549 				} else {
550 					title_vob = vts_ifo->vtsi_mat->vts_last_sector +
551 						1 - ifo - menu_vob -
552 						DVDFileSize(vts_ifo_file);
553 				}
554 				/*
555 				 * Find out how many vob files
556 				 * and the size of them
557 				 */
558 				for (i = 0; i < 9; ++i) {
559 					snprintf(temppoint, sizeof (temppoint),
560 						"%s/VIDEO_TS/VTS_%02i_%i.VOB",
561 						mountpoint, counter + 1, i + 1);
562 					if (stat(temppoint, &fileinfo) < 0) {
563 						break;
564 					}
565 					title_set_info->title_set[counter + 1].realsize_vob[i] = fileinfo.st_size;
566 				}
567 				title_set_info->title_set[counter + 1].number_of_vob_files = i;
568 				title_set_info->title_set[counter + 1].size_title = title_vob * 2048;
569 				title_set_info->title_set[counter + 1].pad_title = title_vob - DVDFileSize(vts_title_file);
570 			} else {
571 				title_set_info->title_set[counter + 1].number_of_vob_files = 0;
572 				title_set_info->title_set[counter + 1].realsize_vob[0] = 0;
573 				title_set_info->title_set[counter + 1].size_title = 0;
574 				title_set_info->title_set[counter + 1].pad_title = 0;
575 				title_vob = 0;
576 
577 			}
578 
579 
580 			/* Find the actuall total size of VTS_XX_0.BUP */
581 			if (title_sets - 1 > counter) {
582 				bup = sector_sets_array[counter+1]
583 					- sector_sets_array[counter]
584 					- title_vob - menu_vob - ifo;
585 			} else {
586 				bup = vts_ifo->vtsi_mat->vts_last_sector + 1
587 					- title_vob - menu_vob - ifo;
588 			}
589 
590 			/* Never trust the BUP use a copy of the IFO */
591 			snprintf(temppoint, sizeof (temppoint),
592 				"%s/VIDEO_TS/VTS_%02i_0.IFO",
593 				mountpoint, counter + 1);
594 
595 			if (stat(temppoint, &fileinfo) < 0) {
596 				errmsg(_("calc: Can't stat '%s'\n"), temppoint);
597 				DVDFreeFileSetArrays(sector, title,
598 					title_sets_array, sector_sets_array);
599 				DVDFreeFileSet(title_set_info);
600 				return (0);
601 			}
602 
603 			title_set_info->title_set[counter + 1].size_bup =
604 						bup * 2048;
605 			title_set_info->title_set[counter + 1].realsize_bup =
606 						fileinfo.st_size;
607 			title_set_info->title_set[counter + 1].pad_bup =
608 						bup - DVDFileSize(vts_ifo_file);
609 
610 
611 			/* Closing files */
612 
613 			if (vts_menu_file != 0) {
614 				DVDCloseFile(vts_menu_file);
615 			}
616 
617 			if (vts_title_file != 0) {
618 				DVDCloseFile(vts_title_file);
619 			}
620 
621 
622 			if (vts_ifo_file != 0) {
623 				DVDCloseFile(vts_ifo_file);
624 			}
625 
626 			ifoClose(vts_ifo);
627 
628 		}
629 
630 	}
631 
632 	DVDFreeFileSetArrays(sector, title, title_sets_array, sector_sets_array);
633 
634 	/* Close the VMG ifo file we got all the info we need */
635 	ifoClose(vmg_ifo);
636 
637 
638 	/* Close the DVD */
639 	DVDClose(_dvd);
640 
641 	/* Return the actuall info*/
642 	return (title_set_info);
643 
644 
645 }
646 
647 EXPORT int
DVDGetFilePad(title_set_info,name)648 DVDGetFilePad(title_set_info, name)
649 	title_set_info_t *title_set_info;
650 	char	*name;
651 {
652 	char	title_a[3];
653 	char	vob_a[2];
654 	int	title;
655 	int	vob;
656 
657 	title_a[0] = title_a[1] = title_a[2] = '\0';
658 	vob_a[0] = vob_a[1] = '\0';
659 
660 	if (name[0] != 'V') {
661 		return (0);
662 	}
663 	if (memcmp(name, "VIDEO_TS", 8) == 0) {
664 		if (strstr(name, ".IFO") != 0) {
665 			return (title_set_info->title_set[0].pad_ifo);
666 		} else if (strstr(name, ".VOB") != 0) {
667 			return (title_set_info->title_set[0].pad_menu);
668 		} else if (strstr(name, ".BUP") != 0) {
669 			return (title_set_info->title_set[0].pad_bup);
670 		} else {
671 			return (0);
672 		}
673 	} else if (memcmp(name, "VTS_", 4) == 0) {
674 		title_a[0] = name[4];
675 		title_a[1] = name[5];
676 		title_a[2] = '\0';
677 		vob_a[0] = name[7];
678 		vob_a[1] = '\0';
679 		title = atoi(title_a);
680 		vob = atoi(vob_a);
681 		if (title > title_set_info->num_titles) {
682 			return (0);
683 		} else {
684 			if (strstr(name, ".IFO") != 0) {
685 				return (title_set_info->title_set[title].pad_ifo);
686 			} else if (strstr(name, ".BUP") != 0) {
687 				return (title_set_info->title_set[title].pad_bup);
688 			} else if (vob == 0) {
689 				return (title_set_info->title_set[title].pad_menu);
690 			} else if (vob == title_set_info->title_set[title].number_of_vob_files) {
691 				return (title_set_info->title_set[title].pad_title);
692 			} else {
693 				return (0);
694 			}
695 		}
696 	} else {
697 		return (0);
698 	}
699 }
700 
701 #endif /*DVD_AUD_VID*/
702