325 lines
9.4 KiB
Plaintext
Raw Normal View History

$OpenBSD: patch-src_vm_vm_c,v 1.1 2012/09/26 00:04:09 brad Exp $
- Reset the vm if necessary
- Use vm_close() w/in vm.c where appropriate
- Add the static function vm_close()
- Check the return value of dvd_read_name
- Rewrite dvd_read_name to return a value
- Prevent general CPP macro from causing strange behavior
- Replace assert w/ a conditional and a null return
- Initialize link_values
- Pointer validation fixing
- Return 0 instead of an assert
--- src/vm/vm.c.orig Wed Sep 5 14:18:33 2012
+++ src/vm/vm.c Wed Sep 5 14:18:50 2012
@@ -59,7 +59,7 @@
#endif
/*
-#define STRICT
+#define DVDNAV_STRICT
*/
/* Local prototypes */
@@ -101,8 +101,8 @@ static int get_PGCN(vm_t *vm);
static pgcit_t* get_MENU_PGCIT(vm_t *vm, ifo_handle_t *h, uint16_t lang);
static pgcit_t* get_PGCIT(vm_t *vm);
-
/* Helper functions */
+static void vm_close(vm_t *vm);
#ifdef TRACE
static void vm_print_current_domain_state(vm_t *vm) {
@@ -162,64 +162,86 @@ static int os2_open(const char *name, int oflag)
}
#endif
-static void dvd_read_name(char *name, char *serial, const char *device) {
- /* Because we are compiling with _FILE_OFFSET_BITS=64
- * all off_t are 64bit.
- */
- off_t off;
- int fd, i;
- uint8_t data[DVD_VIDEO_LB_LEN];
+static int dvd_read_name(char *name, char *serial, const char *device) {
+ /* Because we are compiling with _FILE_OFFSET_BITS=64
+ * all off_t are 64bit.
+ */
+ off_t off;
+ ssize_t read_size = 0;
+ int fd = -1, i;
+ uint8_t data[DVD_VIDEO_LB_LEN];
- /* Read DVD name */
- fd = open(device, O_RDONLY);
- if (fd > 0) {
- off = lseek( fd, 32 * (off_t) DVD_VIDEO_LB_LEN, SEEK_SET );
- if( off == ( 32 * (off_t) DVD_VIDEO_LB_LEN ) ) {
- off = read( fd, data, DVD_VIDEO_LB_LEN );
- close(fd);
- if (off == ( (off_t) DVD_VIDEO_LB_LEN )) {
- fprintf(MSG_OUT, "libdvdnav: DVD Title: ");
- for(i=25; i < 73; i++ ) {
- if((data[i] == 0)) break;
- if((data[i] > 32) && (data[i] < 127)) {
- fprintf(MSG_OUT, "%c", data[i]);
- } else {
- fprintf(MSG_OUT, " ");
- }
- }
- strncpy(name, (char*) &data[25], 48);
- name[48] = 0;
- fprintf(MSG_OUT, "\nlibdvdnav: DVD Serial Number: ");
- for(i=73; i < 89; i++ ) {
- if((data[i] == 0)) break;
- if((data[i] > 32) && (data[i] < 127)) {
- fprintf(MSG_OUT, "%c", data[i]);
- } else {
- fprintf(MSG_OUT, " ");
- }
- }
- strncpy(serial, (char*) &data[73], (i-73));
- serial[14] = 0;
- fprintf(MSG_OUT, "\nlibdvdnav: DVD Title (Alternative): ");
- for(i=89; i < 128; i++ ) {
- if((data[i] == 0)) break;
- if((data[i] > 32) && (data[i] < 127)) {
- fprintf(MSG_OUT, "%c", data[i]);
- } else {
- fprintf(MSG_OUT, " ");
- }
- }
- fprintf(MSG_OUT, "\n");
- } else {
- fprintf(MSG_OUT, "libdvdnav: Can't read name block. Probably not a DVD-ROM device.\n");
- }
- } else {
- fprintf(MSG_OUT, "libdvdnav: Can't seek to block %u\n", 32 );
- }
- close(fd);
+ /* Read DVD name */
+ if (device == NULL) {
+ fprintf(MSG_OUT, "libdvdnav: Device name string NULL\n");
+ goto fail;
+ }
+ if ((fd = open(device, O_RDONLY)) == -1) {
+ fprintf(MSG_OUT, "libdvdnav: Unable to open device file %s.\n", device);
+ goto fail;
+ }
+
+ if ((off = lseek( fd, 32 * (off_t) DVD_VIDEO_LB_LEN, SEEK_SET )) == (off_t) - 1) {
+ fprintf(MSG_OUT, "libdvdnav: Unable to seek to the title block %u.\n", 32);
+ goto fail;
+ }
+
+ if( off != ( 32 * (off_t) DVD_VIDEO_LB_LEN ) ) {
+ fprintf(MSG_OUT, "libdvdnav: Can't seek to block %u\n", 32 );
+ goto fail;
+ }
+
+ if ((read_size = read( fd, data, DVD_VIDEO_LB_LEN )) == -1) {
+ fprintf(MSG_OUT, "libdvdnav: Can't read name block. Probably not a DVD-ROM device.\n");
+ goto fail;
+ }
+
+ close(fd);
+ fd = -1;
+ if (read_size != DVD_VIDEO_LB_LEN) {
+ fprintf(MSG_OUT, "libdvdnav: Can't read name block. Probably not a DVD-ROM device.\n");
+ goto fail;
+ }
+
+ fprintf(MSG_OUT, "libdvdnav: DVD Title: ");
+ for(i=25; i < 73; i++ ) {
+ if((data[i] == 0)) break;
+ if((data[i] > 32) && (data[i] < 127)) {
+ fprintf(MSG_OUT, "%c", data[i]);
} else {
- fprintf(MSG_OUT, "NAME OPEN FAILED\n");
+ fprintf(MSG_OUT, " ");
+ }
}
+ strncpy(name, (char*) &data[25], 48);
+ name[48] = 0;
+ fprintf(MSG_OUT, "\nlibdvdnav: DVD Serial Number: ");
+ for(i=73; i < 89; i++ ) {
+ if((data[i] == 0)) break;
+ if((data[i] > 32) && (data[i] < 127)) {
+ fprintf(MSG_OUT, "%c", data[i]);
+ } else {
+ fprintf(MSG_OUT, " ");
+ }
+ }
+ strncpy(serial, (char*) &data[73], (i-73));
+ serial[14] = 0;
+ fprintf(MSG_OUT, "\nlibdvdnav: DVD Title (Alternative): ");
+ for(i=89; i < 128; i++ ) {
+ if((data[i] == 0)) break;
+ if((data[i] > 32) && (data[i] < 127)) {
+ fprintf(MSG_OUT, "%c", data[i]);
+ } else {
+ fprintf(MSG_OUT, " ");
+ }
+ }
+ fprintf(MSG_OUT, "\n");
+ return 1;
+
+fail:
+ if (fd >= 0)
+ close(fd);
+
+ return 0;
}
static int ifoOpenNewVTSI(vm_t *vm, dvd_reader_t *dvd, int vtsN) {
@@ -268,7 +290,7 @@ vm_t* vm_new_vm() {
}
void vm_free_vm(vm_t *vm) {
- vm_stop(vm);
+ vm_close(vm);
free(vm);
}
@@ -294,6 +316,12 @@ dvd_reader_t *vm_get_dvd_reader(vm_t *vm) {
/* Basic Handling */
int vm_start(vm_t *vm) {
+ if (vm->stopped) {
+ if (!vm_reset(vm, NULL))
+ return 0;
+
+ vm->stopped = 0;
+ }
/* Set pgc to FP (First Play) pgc */
set_FP_PGC(vm);
process_command(vm, play_PGC(vm));
@@ -301,6 +329,10 @@ int vm_start(vm_t *vm) {
}
void vm_stop(vm_t *vm) {
+ vm->stopped = 1;
+}
+
+static void vm_close(vm_t *vm) {
if(vm->vmgi) {
ifoClose(vm->vmgi);
vm->vmgi=NULL;
@@ -352,7 +384,7 @@ int vm_reset(vm_t *vm, const char *dvdroot) {
if (vm->dvd && dvdroot) {
/* a new dvd device has been requested */
- vm_stop(vm);
+ vm_close(vm);
}
if (!vm->dvd) {
vm->dvd = DVDOpen(dvdroot);
@@ -390,8 +422,8 @@ int vm_reset(vm_t *vm, const char *dvdroot) {
/* return 0; Not really used for now.. */
}
/* ifoRead_TXTDT_MGI(vmgi); Not implemented yet */
- dvd_read_name(vm->dvd_name, vm->dvd_serial, dvdroot);
- vm->map = remap_loadmap(vm->dvd_name);
+ if (dvd_read_name(vm->dvd_name, vm->dvd_serial, dvdroot) == 1)
+ vm->map = remap_loadmap(vm->dvd_name);
}
if (vm->vmgi) {
int i, mask;
@@ -414,7 +446,8 @@ vm_t *vm_new_copy(vm_t *source) {
int pgcN = get_PGCN(source);
int pgN = (source->state).pgN;
- assert(pgcN);
+ if (target == NULL || pgcN == 0)
+ goto fail;
memcpy(target, source, sizeof(vm_t));
@@ -424,15 +457,22 @@ vm_t *vm_new_copy(vm_t *source) {
if (vtsN > 0) {
(target->state).vtsN = 0;
if (!ifoOpenNewVTSI(target, target->dvd, vtsN))
- assert(0);
+ goto fail;
/* restore pgc pointer into the new vtsi */
if (!set_PGCN(target, pgcN))
- assert(0);
+ goto fail;
+
(target->state).pgN = pgN;
}
return target;
+
+fail:
+ if (target != NULL)
+ vm_free_vm(target);
+
+ return NULL;
}
void vm_merge(vm_t *target, vm_t *source) {
@@ -1050,7 +1090,7 @@ static link_t play_PGC_PG(vm_t *vm, int pgN) {
}
static link_t play_PGC_post(vm_t *vm) {
- link_t link_values;
+ link_t link_values = { LinkNoLink, 0, 0, 0 };
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: play_PGC_post:\n");
@@ -1129,7 +1169,7 @@ static link_t play_Cell(vm_t *vm) {
case 1: /* Angle block */
/* Loop and check each cell instead? So we don't get outside the block? */
(vm->state).cellN += (vm->state).AGL_REG - 1;
-#ifdef STRICT
+#ifdef DVDNAV_STRICT
assert((vm->state).cellN <= (vm->state).pgc->nr_of_cells);
assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode != 0);
assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type == 1);
@@ -1187,15 +1227,6 @@ static link_t play_Cell_post(vm_t *vm) {
if(cell->cell_cmd_nr != 0) {
link_t link_values;
-/* These asserts are now not needed.
- * Some DVDs have no cell commands listed in the PGC,
- * but the Cell itself points to a cell command that does not exist.
- * For this situation, just ignore the cell command and continue.
- *
- * assert((vm->state).pgc->command_tbl != NULL);
- * assert((vm->state).pgc->command_tbl->nr_of_cell >= cell->cell_cmd_nr);
- */
-
if ((vm->state).pgc->command_tbl != NULL &&
(vm->state).pgc->command_tbl->nr_of_cell >= cell->cell_cmd_nr) {
#ifdef TRACE
@@ -1762,7 +1793,8 @@ static int set_PGCN(vm_t *vm, int pgcN) {
pgcit_t *pgcit;
pgcit = get_PGCIT(vm);
- assert(pgcit != NULL); /* ?? Make this return -1 instead */
+ if (pgcit == NULL)
+ return 0;
if(pgcN < 1 || pgcN > pgcit->nr_of_pgci_srp) {
#ifdef TRACE
@@ -1797,12 +1829,11 @@ static int set_PGN(vm_t *vm) {
(vm->state).pgN = new_pgN;
if((vm->state).domain == VTS_DOMAIN) {
- playback_type_t *pb_ty;
if((vm->state).TTN_REG > vm->vmgi->tt_srpt->nr_of_srpts)
return 0; /* ?? */
- pb_ty = &vm->vmgi->tt_srpt->title[(vm->state).TTN_REG - 1].pb_ty;
- vm_get_current_title_part(vm, &dummy, &part);
- (vm->state).PTTN_REG = part;
+
+ vm_get_current_title_part(vm, &dummy, &part);
+ (vm->state).PTTN_REG = part;
}
return 1;
}