diff -Naur dvdbackup/Makefile dvdbackup-p/Makefile
--- dvdbackup/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ dvdbackup-p/Makefile	2007-08-18 15:38:45.000000000 +0200
@@ -0,0 +1,9 @@
+#!/usr/bin/make -f
+
+dvdbackup: 
+	cd src && make dvdbackup
+
+clean:
+	cd src && make clean
+
+.PHONY: clean dvdbackup
diff -Naur dvdbackup/README dvdbackup-p/README
--- dvdbackup/README	2002-07-30 07:30:54.000000000 +0200
+++ dvdbackup-p/README	2007-08-18 15:38:45.000000000 +0200
@@ -45,6 +45,10 @@
 		This action creates a valid DVD-Video structure
 		of the feature title set
 
+		Note that this will not result in an image immediately 
+		watchable - you will need another program like dvdauthor
+		to help construct the IFO files.
+
 		dvdbackup defaults to get the 16:9 version of the
 		main feature if a 4:3 is also present on the DVD.
 		To get the 4:3 version use -a 0.
@@ -64,6 +68,10 @@
 		This action creates a valid DVD-Video structure
 		of the specified title set
 
+		Note that this will not result in an image immediately 
+		watchable - you will need another program like dvdauthor
+		to help construct the IFO files.
+                
 
 	To backup a title:
 
diff -Naur dvdbackup/src/dvdbackup.c dvdbackup-p/src/dvdbackup.c
--- dvdbackup/src/dvdbackup.c	2002-08-05 08:08:39.000000000 +0200
+++ dvdbackup-p/src/dvdbackup.c	2007-08-18 15:38:45.000000000 +0200
@@ -30,6 +30,7 @@
 #include <unistd.h>
 #include <string.h>
 #include <limits.h>
+#include <stdint.h>
 #include <dvdread/dvd_reader.h>
 #include <dvdread/ifo_read.h>
 #include <dvdread/ifo_print.h>
@@ -76,6 +77,12 @@
   titles_t	*titles;
 } titles_info_t;
 
+typedef enum {
+  STRATEGY_ABORT,
+  STRATEGY_SKIP_BLOCK,
+  STRATEGY_SKIP_MULTIBLOCK
+} read_error_strategy_t;
+
 
 void bsort_max_to_min(int sector[], int title[], int size);
 
@@ -85,11 +92,11 @@
 
 	Gerneral backup information:
 		If your backup directory is /my/dvd/backup/dir/
-		specified with the "-o" flag. Then dvdbackup
+		specified with the "-o" flag, then dvdbackup
 		will create a DVD-Video structure under
 		/my/dvd/backup/dir/TITLE_NAME/VIDEO_TS.
 
-		Since the title is "uniq" you can use the same dir
+		Since the title is "unique" you can use the same dir
 		for all your DVD backups. If it happens to have a
 		generic title dvdbackup will exit with a return value
 		of 2. And you will need to specify a title name with
@@ -171,7 +178,7 @@
 		To backup to chapter 20 from the first chapter use only -e 20
 
 		You can skip the -t switch and let the program guess the title although
-		it's not recomened.
+		it's not recommended.
 
 		If you specify a chapter that his higher than the last chapter of the title
 		dvdbackup will turncate to the highest chapter of the title.
@@ -180,12 +187,12 @@
 		0 on success
 		1 on usage error
 		2 on title name error
-		-1 on failur
+		-1 on failure
 
 
 	Todo - i.e. what's on the agenda.
 		Make the main feature guessing algoritm better. Not that it doesn't do
-		it's job, but it's implementation it's that great. I would also like
+		its job, but its implementation isn't that great. I would also like
 		to preserve more information about the main feature since that would
 		let me preform better implementations in other functions that depends
 		on the titles_info_t and title_set_info_t strcutures.
@@ -210,6 +217,7 @@
 	fprintf(stderr,"\t-v X\t\twhere X is the amount of verbosity\n");
 	fprintf(stderr,"\t-I\t\tfor information about the DVD\n");
 	fprintf(stderr,"\t-o directory\twhere directory is your backup target\n");
+	fprintf(stderr,"\t-n name\t\t(optional) set the title - useful if autodetection fails\n");
 	fprintf(stderr,"\t-M\t\tbackup the whole DVD\n");
 	fprintf(stderr,"\t-F\t\tbackup the main feature of the DVD\n");
 	fprintf(stderr,"\t-T X\t\tbackup title set X\n");
@@ -217,12 +225,13 @@
 	fprintf(stderr,"\t-s X\t\tbackup from chapter X\n");
 	fprintf(stderr,"\t-e X\t\tbackup to chapter X\n");
 	fprintf(stderr,"\t-a 0\t\tto get aspect ratio 4:3 instead of 16:9 if both are present\n");
+	fprintf(stderr,"\t-r {a,b,m}\t\tselect read error handling: a=abort (default), b=skip block, m=skip multiple blocks\n");
 	fprintf(stderr,"\t-h\t\tprint a brief usage message\n");
 	fprintf(stderr,"\t-?\t\tprint a brief usage message\n\n");
 	fprintf(stderr,"\t-i is manditory\n");
 	fprintf(stderr,"\t-o is manditory except if you use -I\n");
 	fprintf(stderr,"\t-a is option to the -F switch and has no effect on other options\n");
-	fprintf(stderr,"\t-s and -e should prefereibly be used together with -t \n\n");
+	fprintf(stderr,"\t-s and -e should preferably be used together with -t \n\n");
 	exit(1);
 }
 
@@ -230,7 +239,7 @@
 	if ( (size_array[reference]/size_array[target] == 1) &&
 	     ((size_array[reference] * 2 - size_array[target])/ size_array[target] == 1) &&
 	     ((size_array[reference]%size_array[target] * 3) < size_array[reference]) ) {
-		/* We have a dual DVD with two feature films - now lets see if they have the same amount of chapters*/
+		/* We have a dual DVD with two feature films - now let's see if they have the same amount of chapters*/
 		return(1);
 	} else {
 		return(0);
@@ -297,11 +306,10 @@
 
 
 	/* Loop variables */
-	int i, f;
-
+	int i;
 
 	/* Vob control */
-	int vob;
+	int vob = 1;
 
 	/* Temp filename,dirname */
 	char targetname[PATH_MAX];
@@ -315,17 +323,15 @@
 
 	int size;
 	int left;
-	int leftover;
+	int vobsize = 524288;
 
 	/* Buffer size in DVD sectors */
 	/* Currently set to 1MB */
 	int buff = 512;
-	int tsize;
 
 
 	/* Offsets */
 	int soffset;
-	int offset;
 
 
 	/* DVD handler */
@@ -333,236 +339,133 @@
 
 	int title_set;
 	int number_of_vob_files;
-
+	
 #ifdef DEBUG
 	fprintf(stderr,"DVDWriteCells: length is %d\n", length);
-
 #endif
 
 
 	title_set = titles_info->titles[titles - 1].title_set;
 	number_of_vob_files = title_set_info->title_set[title_set].number_of_vob_files;
 #ifdef DEBUG
-		fprintf(stderr,"DVDWriteCells: title set is %d\n", title_set);
-		fprintf(stderr,"DVDWriteCells: vob files are %d\n", number_of_vob_files);
-
+	fprintf(stderr,"DVDWriteCells: title set is %d\n", title_set);
+	fprintf(stderr,"DVDWriteCells: vob files are %d\n", number_of_vob_files);
 #endif
 
-
-
 	/* Remove all old files silently if they exists */
 
 	for ( i = 0 ; i < 10 ; i++ ) {
 		sprintf(targetname,"%s/%s/VIDEO_TS/VTS_%02i_%i.VOB",targetdir, title_name, title_set, i + 1);
 #ifdef DEBUG
 		fprintf(stderr,"DVDWriteCells: file is %s\n", targetname);
-
 #endif
-
 		unlink( targetname);
-
 	}
 
 
-
-
-	/* Loop through all sectors and find the right vob */
-	for (f = 0; f < length ; f++) {
-
-		soffset=0;
-		offset=0;
-
-
-		/* Now figure which vob we will use and write to that vob and if there is a left over write to the next vob*/
-
-		for ( i = 0; i < number_of_vob_files ; i++ ) {
-
-
-			tsize = title_set_info->title_set[title_set].size_vob[i];
-
-			if (tsize%2048 != 0) {
-				fprintf(stderr, "The Title VOB number %d of title set %d doesn't have a valid DVD size\n", i + 1, title_set);
-				return(1);
-			} else {
-				soffset = offset;
-				offset = offset + tsize/2048;
-			}
-#ifdef DEBUG
-			fprintf(stderr,"DVDWriteCells: soffset is %d\n", soffset);
-			fprintf(stderr,"DVDWriteCells: offset is %d\n", offset);
-#endif
-			/* Find out if this is the right vob */
-			if( soffset <= cell_start_sector[f]  && offset > cell_start_sector[f] ) {
 #ifdef DEBUG
-				fprintf(stderr,"DVDWriteCells: got it \n");
-#endif
-				leftover=0;
-				soffset = cell_start_sector[f];
-				if ( cell_end_sector[f] > offset ) {
-					leftover = cell_end_sector[f] - offset + 1;
-				} else {
-					size = cell_end_sector[f] - cell_start_sector[f] + 1;
-				}
-#ifdef DEBUG
-				fprintf(stderr,"DVDWriteCells: size is %d\n", size);
+	for (i = 0; i < number_of_vob_files ; i++) {
+	    fprintf(stderr,"vob %i size: %d\n", i + 1, title_set_info->title_set[title_set].size_vob[i]);
+	}
 #endif
-				vob = i + 1;
-				break;
-			}
 
-		}
+	/* Create VTS_XX_X.VOB */
+	if (title_set == 0) {
+		fprintf(stderr,"Don't try to copy chapters from the VMG domain; there aren't any\n");
+		return(1);
+	} else {
+		sprintf(targetname,"%s/%s/VIDEO_TS/VTS_%02i_%i.VOB",targetdir, title_name, title_set, vob);
+	}
+
 #ifdef DEBUG
-		fprintf(stderr,"DVDWriteCells: Writing soffset is %d and leftover is %d\n", soffset, leftover);
+	fprintf(stderr,"DVDWriteCells: 1\n");
 #endif
 
-
-
-
-		/* Create VTS_XX_X.VOB */
-		if (title_set == 0) {
-			fprintf(stderr,"Don't try to copy chapters from the VMG domain there aren't any\n");
-			return(1);
-		} else {
-			sprintf(targetname,"%s/%s/VIDEO_TS/VTS_%02i_%i.VOB",targetdir, title_name, title_set, vob);
-		}
+	if ((buffer = (unsigned char *)malloc(buff * 2048 * sizeof(unsigned char))) == NULL) {
+		fprintf(stderr, "Out of memory copying %s\n", targetname);
+		return(1);
+	}
 
 #ifdef DEBUG
-		fprintf(stderr,"DVDWriteCells: 1\n");
+	fprintf(stderr,"DVDWriteCells: 2\n");
 #endif
 
 
-		if ((buffer = (unsigned char *)malloc(buff * 2048 * sizeof(unsigned char))) == NULL) {
-			fprintf(stderr, "Out of memory coping %s\n", targetname);
-			return(1);
-		}
+	if ((streamout = open(targetname, O_WRONLY | O_CREAT | O_APPEND, 0666)) == -1) {
+		fprintf(stderr, "Error creating %s\n", targetname);
+		perror("");
+		return(1);
+	}
 
 #ifdef DEBUG
-		fprintf(stderr,"DVDWriteCells: 2\n");
+	fprintf(stderr,"DVDWriteCells: 3\n");
 #endif
 
 
-		if ((streamout = open(targetname, O_WRONLY | O_CREAT | O_APPEND, 0644)) == -1) {
-			fprintf(stderr, "Error creating %s\n", targetname);
-			perror("");
-			return(1);
-		}
+	if ((dvd_file = DVDOpenFile(dvd, title_set, DVD_READ_TITLE_VOBS))== 0) {
+		fprintf(stderr, "Failed opening TITLE VOB\n");
+		free(buffer);
+		close(streamout);
+		return(1);
+	}
+
+	size = 0;
+	left = cell_end_sector[length-1] - cell_start_sector[0] + 1;
+	soffset = cell_start_sector[0];
 
 #ifdef DEBUG
-		fprintf(stderr,"DVDWriteCells: 3\n");
+	fprintf(stderr,"DVDWriteCells: left is %d\n", left);
 #endif
 
+	while( left > 0 ) {
 
-		if ((dvd_file = DVDOpenFile(dvd, title_set, DVD_READ_TITLE_VOBS))== 0) {
-			fprintf(stderr, "Faild opending TITLE VOB\n");
+		if (buff > left) {
+			buff = left;
+		}
+		if ( DVDReadBlocks(dvd_file,soffset,buff, buffer) != buff) {
+			fprintf(stderr, "Error reading MENU VOB\n");
 			free(buffer);
+			DVDCloseFile(dvd_file);
 			close(streamout);
 			return(1);
 		}
 
-		left = size;
-
+		if (write(streamout,buffer,buff *  2048) != buff * 2048) {
+			fprintf(stderr, "Error writing TITLE VOB\n");
+			free(buffer);
+			close(streamout);
+			return(1);
+		}
 #ifdef DEBUG
-		fprintf(stderr,"DVDWriteCells: left is %d\n", left);
+		fprintf(stderr,"Current soffset changed from %i to ",soffset);
 #endif
-
-		while( left > 0 ) {
-
-			if (buff > left) {
-				buff = left;
-			}
-			if ( DVDReadBlocks(dvd_file,soffset,buff, buffer) != buff) {
-				fprintf(stderr, "Error reading MENU VOB\n");
-				free(buffer);
-				DVDCloseFile(dvd_file);
-				close(streamout);
-				return(1);
-			}
-
-
-			if (write(streamout,buffer,buff *  2048) != buff * 2048) {
-				fprintf(stderr, "Error writing TITLE VOB\n");
-				free(buffer);
-				close(streamout);
-				return(1);
-			}
-
-			soffset = soffset + buff;
-			left = left - buff;
-
+		soffset = soffset + buff;
+		left = left - buff;
+		size = size + buff;
+		if ((size >= vobsize) && (left > 0)) {
+#ifdef DEBUG
+		    fprintf(stderr,"size: %i, vobsize: %i\n ",size, vobsize);
+#endif
+		    close(streamout);
+		    vob = vob + 1;
+		    size = 0;
+		    sprintf(targetname,"%s/%s/VIDEO_TS/VTS_%02i_%i.VOB",targetdir, title_name, title_set, vob);
+		    if ((streamout = open(targetname, O_WRONLY | O_CREAT | O_APPEND, 0666)) == -1) {
+			fprintf(stderr, "Error creating %s\n", targetname);
+			perror("");
+			return(1);
+		    }
 		}
+#ifdef DEBUG
+		fprintf(stderr,"%i\n",soffset);
+#endif
 
-		DVDCloseFile(dvd_file);
-		free(buffer);
-		close(streamout);
-
-
-		if ( leftover != 0 ) {
-
-			vob = vob + 1;
-
-			if (title_set == 0) {
-				fprintf(stderr,"Don't try to copy chapters from the VMG domain there aren't any\n");
-				return(1);
-			} else {
-				sprintf(targetname,"%s/%s/VIDEO_TS/VTS_%02i_%i.VOB",targetdir, title_name, title_set, vob);
-			}
-
-
-			if ((buffer = (unsigned char *)malloc(buff * 2048 * sizeof(unsigned char))) == NULL) {
-				fprintf(stderr, "Out of memory coping %s\n", targetname);
-				close(streamout);
-				return(1);
-			}
-
-
-			if ((streamout = open(targetname, O_WRONLY | O_CREAT | O_APPEND, 0644)) == -1) {
-				fprintf(stderr, "Error creating %s\n", targetname);
-				perror("");
-				return(1);
-			}
-
-
-			if ((dvd_file = DVDOpenFile(dvd, title_set, DVD_READ_TITLE_VOBS))== 0) {
-				fprintf(stderr, "Faild opending TITLE VOB\n");
-				free(buffer);
-				close(streamout);
-				return(1);
-			}
-
-			left = leftover;
-
-			while( left > 0 ) {
-
-				if (buff > left) {
-					buff = left;
-				}
-				if ( DVDReadBlocks(dvd_file,offset,buff, buffer) != buff) {
-					fprintf(stderr, "Error reading MENU VOB\n");
-					free(buffer);
-					DVDCloseFile(dvd_file);
-					close(streamout);
-					return(1);
-				}
-
-
-				if (write(streamout,buffer,buff *  2048) != buff * 2048) {
-					fprintf(stderr, "Error writing TITLE VOB\n");
-					free(buffer);
-					close(streamout);
-					return(1);
-				}
-
-				offset = offset + buff;
-				left = left - buff;
-
-			}
+	}
 
-			DVDCloseFile(dvd_file);
-			free(buffer);
-			close(streamout);
-		}
+	DVDCloseFile(dvd_file);
+	free(buffer);
+	close(streamout);
 
-	}
 	return(0);
 }
 
@@ -734,7 +637,7 @@
 		channels_channel_array[counter] = channels;
 		title_set_channel_array[counter] = counter + 1;
 
-		/* For tiles_info */
+		/* For titles_info */
 		for (f=0; f < titles_info->number_of_titles ; f++ ) {
 			if ( titles_info->titles[f].title_set == counter + 1 ) {
 				titles_info->titles[f].aspect_ratio = vmg_ifo->vts_atrt->vts[counter].vtstt_vobs_video_attr.display_aspect_ratio;
@@ -782,8 +685,8 @@
 	 to consider the second one a feature title we are doing two checks (biggest  + biggest - second) /second == 1
 	 and biggest%second * 3 < biggest */
 
-	if ( CheckSizeArray(size_size_array, 0, 1)  == 1 ) {
-		/* We have a dual DVD with two feature films - now lets see if they have the same amount of chapters*/
+	if ( title_sets > 1 && CheckSizeArray(size_size_array, 0, 1)  == 1 ) {
+		/* We have a dual DVD with two feature films - now let's see if they have the same amount of chapters*/
 
 		chapters_1 = 0;
 		for (i=0 ; i < titles ; i++ ) {
@@ -820,7 +723,7 @@
 			} else {
 				/* Okay we didn't have the prefered aspect ratio - just make the biggest one a candidate */
 				/* please send  report if this happens*/
-				fprintf(stderr, "You have encountered a very special DVD, please send a bug report along with all IFO files from this title\n");
+				fprintf(stderr, "You have encountered a very special DVD; please send a bug report along with all IFO files from this title\n");
 				candidate = title_set_size_array[0];
 			}
 			dual = 1;
@@ -840,7 +743,7 @@
 				      0 , candidate, title_sets);
 
 
-	/* Now lets see if we can find our candidate among the top most chapters */
+	/* Now let's see if we can find our candidate among the top most chapters */
 	found_chapter=6;
 	temp = chapter_chapter_array[0];
 	for (i=0 ; (i < titles) && (i < 4) ; i++ ) {
@@ -907,7 +810,7 @@
 				      channels_channel_array, title_set_channel_array,
 				      0 , candidate, title_sets);
 
-	/* Now lets see if we can find our candidate among the top most chapters */
+	/* Now let's see if we can find our candidate among the top most chapters */
 
 	found_chapter=5;
 	temp = chapter_chapter_array[0];
@@ -970,7 +873,7 @@
 
 	/* Make a dual array with number of audio streams, sub picture streams
 	 and title sets. Tradtionaly the main film has many audio streams
-	 since it's supposed be synconised e.g. a English film syncronised/dubbed
+	 since it's supposed be synchronised e.g. a English film synchronised/dubbed
 	 in German. We are also keeping track of sub titles since it's also indication
 	 of the main film*/
 
@@ -983,7 +886,7 @@
 	/* Yes a lot of rant - but it helps me think - some sketch on paper or in the mind
 	 I sketch in the comments - beside it will help you understand the code*/
 
-	/* Okay lets see if the biggest one has most chapters, it also has more subtitles
+	/* Okay let's see if the biggest one has most chapters, it also has more subtitles
 	 and audio tracks than the second one and it's title one.
 	 Done it must be the main film
 
@@ -994,7 +897,7 @@
 
 	 Now we fetch the 16:9 by default unless the forced to do 4:3
 	 First check which one is which.
-	 If the 16:9 is the biggest one and has the same or more subtile, audio streams
+	 If the 16:9 is the biggest one and has the same or more subtitle, audio streams
 	 then we are happy unless we are in force 4:3 mode :(
 	 The same goes in reverse if we are in force 4:3 mode
 
@@ -1022,7 +925,7 @@
 
 
 
-int DVDCopyTileVobX(dvd_reader_t * dvd, title_set_info_t * title_set_info, int title_set, int vob, char * targetdir,char * title_name) {
+int DVDCopyTileVobX(dvd_reader_t * dvd, title_set_info_t * title_set_info, int title_set, int vob, char * targetdir,char * title_name, read_error_strategy_t errorstrat) {
 
 	/* Loop variable */
 	int i;
@@ -1036,6 +939,8 @@
 	unsigned char * buffer=NULL;
 	unsigned char buffy; /* :-) */
 
+	unsigned char * bufferZero=NULL;
+
 	/* File Handler */
 	int streamout;
 
@@ -1047,25 +952,27 @@
 	int buff = 512;
 	int offset = 0;
 	int tsize;
+	int toRead = buff;
+	int actRead; /* number of buffers actually read */
 
 	/* DVD handler */
 	dvd_file_t   *	dvd_file=NULL;
 
 	if (title_set_info->number_of_title_sets + 1 < title_set) {
-		fprintf(stderr,"Faild num title test\n");
+		fprintf(stderr,"Failed num title test\n");
 		return(1);
 	}
 
 	if (title_set_info->title_set[title_set].number_of_vob_files < vob ) {
-		fprintf(stderr,"Faild vob test\n");
+		fprintf(stderr,"Failed vob test\n");
 		return(1);
 	}
 
 	if (title_set_info->title_set[title_set].size_vob[0] == 0 ) {
-		fprintf(stderr,"Faild vob 1 size test\n");
+		fprintf(stderr,"Failed vob 1 size test\n");
 		return(0);
 	} else if (title_set_info->title_set[title_set].size_vob[vob - 1] == 0 ) {
-		fprintf(stderr,"Faild vob %d test\n", vob);
+		fprintf(stderr,"Failed vob %d test\n", vob);
 		return(0);
 	} else {
 		size = title_set_info->title_set[title_set].size_vob[vob - 1]/2048;
@@ -1080,7 +987,7 @@
 
 	/* Create VTS_XX_X.VOB */
 	if (title_set == 0) {
-		fprintf(stderr,"Don't try to copy a Title VOB from the VMG domain there aren't any\n");
+		fprintf(stderr,"Don't try to copy a Title VOB from the VMG domain; there aren't any\n");
 		return(1);
 	} else {
 		sprintf(targetname,"%s/%s/VIDEO_TS/VTS_%02i_%i.VOB",targetdir, title_name, title_set, vob);
@@ -1109,14 +1016,14 @@
 			fprintf(stderr,"The Title %s file is not valid, it may be a directory\n", targetname);
 			return(1);
 		} else {
-			if ((streamout = open(targetname, O_WRONLY | O_TRUNC, 0644)) == -1) {
+			if ((streamout = open(targetname, O_WRONLY | O_TRUNC, 0666)) == -1) {
 				fprintf(stderr, "Error opening %s\n", targetname);
 				perror("");
 				return(1);
 			}
 		}
 	} else {
-		if ((streamout = open(targetname, O_WRONLY | O_CREAT, 0644)) == -1) {
+		if ((streamout = open(targetname, O_WRONLY | O_CREAT, 0666)) == -1) {
 			fprintf(stderr, "Error creating %s\n", targetname);
 			perror("");
 			return(1);
@@ -1126,14 +1033,21 @@
 	left = size;
 
 	if ((buffer = (unsigned char *)malloc(buff * 2048 * sizeof(buffy))) == NULL) {
-		fprintf(stderr, "Out of memory coping %s\n", targetname);
+		fprintf(stderr, "Out of memory copying %s\n", targetname);
+		close(streamout);
+		return(1);
+	}
+
+	if ((bufferZero = (unsigned char *)calloc(buff * 2048, sizeof(buffy))) == NULL) {
+		fprintf(stderr, "Out of memory (2) copying %s\n", targetname);
+		free(buffer);
 		close(streamout);
 		return(1);
 	}
 
 
 	if ((dvd_file = DVDOpenFile(dvd, title_set, DVD_READ_TITLE_VOBS))== 0) {
-		fprintf(stderr, "Faild opending TITLE VOB\n");
+		fprintf(stderr, "Failed opening TITLE VOB\n");
 		free(buffer);
 		close(streamout);
 		return(1);
@@ -1141,35 +1055,77 @@
 
 	while( left > 0 ) {
 
-		if (buff > left) {
-			buff = left;
+		if (toRead > left) {
+			toRead = left;
 		}
-		if ( DVDReadBlocks(dvd_file,offset,buff, buffer) != buff) {
-			fprintf(stderr, "Error reading MENU VOB\n");
-			free(buffer);
-			DVDCloseFile(dvd_file);
-			close(streamout);
-			return(1);
+		if ( (actRead = DVDReadBlocks(dvd_file,offset,toRead, buffer)) != toRead) {
+		  if (actRead>=0)
+		    fprintf(stderr, "Error reading TITLE VOB at block %d\n", offset+actRead);
+		  else
+		    fprintf(stderr, "Error reading TITLE VOB at block %d, read error returned\n", offset);
 		}
 
 
-		if (write(streamout,buffer,buff *  2048) != buff * 2048) {
-			fprintf(stderr, "Error writing TITLE VOB\n");
-			free(buffer);
-			close(streamout);
-			return(1);
+		if (actRead>0) {
+		  if (write(streamout,buffer,actRead *  2048) != actRead * 2048) {
+		    fprintf(stderr, "Error writing TITLE VOB\n");
+		    DVDCloseFile(dvd_file);
+		    free(buffer);
+		    free(bufferZero);
+		    close(streamout);
+		    return(1);
+		  }
+		}
+
+		if (actRead!=toRead) {
+		  int numBlanks=0;
+
+		  if (actRead<0) {
+		    actRead=0;
+		  }
+
+		  switch (errorstrat) {
+		    case STRATEGY_ABORT:
+		      fprintf(stderr, "aborting\n");
+		      DVDCloseFile(dvd_file);
+		      free(buffer);
+		      free(bufferZero);
+		      close(streamout);
+		      return(1);
+
+		    case STRATEGY_SKIP_BLOCK:
+		      numBlanks=1;
+		      fprintf(stderr, "padding single block\n");
+		      break;
+		    case STRATEGY_SKIP_MULTIBLOCK:
+		      numBlanks=(toRead-actRead);
+		      fprintf(stderr, "padding %d blocks\n", numBlanks);
+		      break;
+		  }
+
+		  if (write(streamout,bufferZero,numBlanks*2048) != numBlanks*2048) {
+		    fprintf(stderr, "Error writing TITLE VOB (padding)\n");
+		    DVDCloseFile(dvd_file);
+		    free(buffer);
+		    free(bufferZero);
+		    close(streamout);
+		    return(1);
+		  }
+
+		  // pretend we read what we padded
+		  actRead+=numBlanks;
 		}
 
-		offset = offset + buff;
-		left = left - buff;
+		offset = offset + actRead;
+		left = left - actRead;
 
 	}
 
 	DVDCloseFile(dvd_file);
 	free(buffer);
+	free(bufferZero);
 	close(streamout);
 	return(0);
-
 }
 
 
@@ -1229,14 +1185,14 @@
 			fprintf(stderr,"The Menu %s file is not valid, it may be a directory\n", targetname);
 			return(1);
 		} else {
-			if ((streamout = open(targetname, O_WRONLY | O_TRUNC, 0644)) == -1) {
+			if ((streamout = open(targetname, O_WRONLY | O_TRUNC, 0666)) == -1) {
 				fprintf(stderr, "Error opening %s\n", targetname);
 				perror("");
 				return(1);
 			}
 		}
 	} else {
-		if ((streamout = open(targetname, O_WRONLY | O_CREAT, 0644)) == -1) {
+		if ((streamout = open(targetname, O_WRONLY | O_CREAT, 0666)) == -1) {
 			fprintf(stderr, "Error creating %s\n", targetname);
 			perror("");
 			return(1);
@@ -1246,14 +1202,14 @@
 	left = size;
 
 	if ((buffer = (unsigned char *)malloc(buff * 2048 * sizeof(buffy))) == NULL) {
-		fprintf(stderr, "Out of memory coping %s\n", targetname);
+		fprintf(stderr, "Out of memory copying %s\n", targetname);
 		close(streamout);
 		return(1);
 	}
 
 
 	if ((dvd_file = DVDOpenFile(dvd, title_set, DVD_READ_MENU_VOBS))== 0) {
-		fprintf(stderr, "Faild opending MENU VOB\n");
+		fprintf(stderr, "Failed opening MENU VOB\n");
 		free(buffer);
 		close(streamout);
 		return(1);
@@ -1341,14 +1297,14 @@
 			fprintf(stderr,"The IFO %s file is not valid, it may be a directory\n", targetname);
 			return(1);
 		} else {
-			if ((streamout = open(targetname, O_WRONLY | O_TRUNC, 0644)) == -1) {
+			if ((streamout = open(targetname, O_WRONLY | O_TRUNC, 0666)) == -1) {
 				fprintf(stderr, "Error opening %s\n", targetname);
 				perror("");
 				return(1);
 			}
 		}
 	} else {
-		if ((streamout = open(targetname, O_WRONLY | O_CREAT, 0644)) == -1) {
+		if ((streamout = open(targetname, O_WRONLY | O_CREAT, 0666)) == -1) {
 			fprintf(stderr, "Error creating %s\n", targetname);
 			perror("");
 			return(1);
@@ -1359,14 +1315,14 @@
 
 
 	if ((buffer = (unsigned char *)malloc(size * sizeof(buffy))) == NULL) {
-		fprintf(stderr, "Out of memory coping %s\n", targetname);
+		fprintf(stderr, "Out of memory copying %s\n", targetname);
 		close(streamout);
 		return(1);
 	}
 
 
 	if ((dvd_file = DVDOpenFile(dvd, title_set, DVD_READ_INFO_FILE))== 0) {
-		fprintf(stderr, "Faild opending IFO for tile set %d\n", title_set);
+		fprintf(stderr, "Failed opening IFO for title set %d\n", title_set);
 		free(buffer);
 		close(streamout);
 		return(1);
@@ -1419,14 +1375,14 @@
 			fprintf(stderr,"The BUP %s file is not valid, it may be a directory\n", targetname);
 			return(1);
 		} else {
-			if ((streamout = open(targetname, O_WRONLY | O_TRUNC, 0644)) == -1) {
+			if ((streamout = open(targetname, O_WRONLY | O_TRUNC, 0666)) == -1) {
 				fprintf(stderr, "Error opening %s\n", targetname);
 				perror("");
 				return(1);
 			}
 		}
 	} else {
-		if ((streamout = open(targetname, O_WRONLY | O_CREAT, 0644)) == -1) {
+		if ((streamout = open(targetname, O_WRONLY | O_CREAT, 0666)) == -1) {
 			fprintf(stderr, "Error creating %s\n", targetname);
 			perror("");
 			return(1);
@@ -1438,14 +1394,14 @@
 	/* Copy VIDEO_TS.BUP or VTS_XX_0.BUP, since it's a small file try to copy it in one shot */
 
 	if ((buffer = (unsigned char *)malloc(size * sizeof(buffy))) == NULL) {
-		fprintf(stderr, "Out of memory coping %s\n", targetname);
+		fprintf(stderr, "Out of memory copying %s\n", targetname);
 		close(streamout);
 		return(1);
 	}
 
 
 	if ((dvd_file = DVDOpenFile(dvd, title_set, DVD_READ_INFO_BACKUP_FILE))== 0) {
-		fprintf(stderr, "Faild opending BUP for title set %d\n", title_set);
+		fprintf(stderr, "Failed opening BUP for title set %d\n", title_set);
 		free(buffer);
 		close(streamout);
 		return(1);
@@ -1487,7 +1443,7 @@
 	return(0);
 }
 
-int DVDMirrorTitleX(dvd_reader_t * dvd, title_set_info_t *  title_set_info, int title_set, char * targetdir,char * title_name) {
+int DVDMirrorTitleX(dvd_reader_t * dvd, title_set_info_t *  title_set_info, int title_set, char * targetdir,char * title_name, read_error_strategy_t errorstrat) {
 
 	/* Loop through the vobs */
 	int i;
@@ -1506,7 +1462,7 @@
 #ifdef DEBUG
 		fprintf(stderr,"In the VOB copy loop for %d\n", i);
 #endif		
-		if ( DVDCopyTileVobX(dvd, title_set_info, title_set, i + 1, targetdir, title_name) != 0 ) {
+		if ( DVDCopyTileVobX(dvd, title_set_info, title_set, i + 1, targetdir, title_name, errorstrat) != 0 ) {
 		return(1);
 		}
 	}
@@ -1524,7 +1480,7 @@
 	/* Open DVD device */
 
 	if ( !(filehandle = open(device, O_RDONLY)) ) {
-		fprintf(stderr, "Can't open secified device %s - check your DVD device\n", device);
+		fprintf(stderr, "Can't open specified device %s - check your DVD device\n", device);
 		return(1);
 	}
 
@@ -1656,8 +1612,7 @@
 
 
 	/* DVD Video files */
-	char	filename[MAXNAME];
-	int	size;
+        dvd_stat_t statbuf;
 
 	/*DVD ifo handler*/
 	ifo_handle_t * 	vmg_ifo=NULL;
@@ -1687,10 +1642,8 @@
 
 	/* Find VIDEO_TS.IFO is present - must be present since we did a ifo open 0*/
 
-	sprintf(filename,"/VIDEO_TS/VIDEO_TS.IFO");
-
-	if ( UDFFindFile(_dvd, filename, &size) != 0 ) {
-		title_set_info->title_set[0].size_ifo = size;
+       if ( DVDFileStat(_dvd, 0, DVD_READ_INFO_FILE, &statbuf) != -1 ) {
+               title_set_info->title_set[0].size_ifo = statbuf.size;
 	} else {
 		DVDFreeTitleSetInfo(title_set_info);
 		return(0);
@@ -1700,20 +1653,17 @@
 
 	/* Find VIDEO_TS.VOB if present*/
 
-	sprintf(filename,"/VIDEO_TS/VIDEO_TS.VOB");
-
-	if ( UDFFindFile(_dvd, filename, &size) != 0 ) {
-		title_set_info->title_set[0].size_menu = size;
+       if ( DVDFileStat(_dvd, 0, DVD_READ_MENU_VOBS, &statbuf) != -1 ) {
+               title_set_info->title_set[0].size_menu = statbuf.size;
 	} else {
 		title_set_info->title_set[0].size_menu = 0 ;
 	}
 
 	/* Find VIDEO_TS.BUP if present */
 
-	sprintf(filename,"/VIDEO_TS/VIDEO_TS.BUP");
+       if (DVDFileStat(_dvd, 0, DVD_READ_INFO_BACKUP_FILE, &statbuf) != -1) {
+               title_set_info->title_set[0].size_bup = statbuf.size;
 
-	if ( UDFFindFile(_dvd, filename, &size) != 0 ) {
-		title_set_info->title_set[0].size_bup = size;
 	} else {
 		DVDFreeTitleSetInfo(title_set_info);
 		return(0);
@@ -1745,10 +1695,8 @@
 			}
 
 
-			sprintf(filename,"/VIDEO_TS/VTS_%02i_0.IFO",counter + 1);
-
-			if ( UDFFindFile(_dvd, filename, &size) != 0 ) {
-				title_set_info->title_set[counter + 1].size_ifo = size;
+                       if ( DVDFileStat(_dvd, counter + 1, DVD_READ_INFO_FILE, &statbuf) != -1) {
+                               title_set_info->title_set[counter+1].size_ifo = statbuf.size;
 			} else {
 				DVDFreeTitleSetInfo(title_set_info);
 				return(0);
@@ -1761,10 +1709,8 @@
 
 			/* Find VTS_XX_0.VOB if present*/
 
-			sprintf(filename,"/VIDEO_TS/VTS_%02i_0.VOB", counter + 1);
-
-			if ( UDFFindFile(_dvd, filename, &size) != 0 ) {
-				title_set_info->title_set[counter + 1].size_menu = size;
+                       if ( DVDFileStat(_dvd, counter + 1, DVD_READ_MENU_VOBS, &statbuf) != -1) {
+                               title_set_info->title_set[counter + 1].size_menu = statbuf.size;
 			} else {
 				title_set_info->title_set[counter + 1].size_menu = 0 ;
 			}
@@ -1777,12 +1723,12 @@
 
 			/* Find all VTS_XX_[1 to 9].VOB files if they are present*/
 
-			for( i = 0; i < 9; ++i ) {
-				sprintf(filename,"/VIDEO_TS/VTS_%02i_%i.VOB", counter + 1, i + 1 );
-				if(UDFFindFile(_dvd, filename, &size) == 0 ) {
-					break;
+                       i = 0;
+                       if ( DVDFileStat(_dvd, counter + 1, DVD_READ_TITLE_VOBS, &statbuf) != -1) {
+                               for ( i = 0; i < statbuf.nr_parts; ++i) {
+                                       title_set_info->title_set[counter + 1].size_vob[i] = statbuf.parts_size[i];
 				}
-				title_set_info->title_set[counter + 1].size_vob[i] = size;
+
 			}
 			title_set_info->title_set[counter + 1].number_of_vob_files = i;
 
@@ -1791,10 +1737,8 @@
 			}
 
 
-			sprintf(filename,"/VIDEO_TS/VTS_%02i_0.BUP", counter + 1);
-
-			if ( UDFFindFile(_dvd, filename, &size) != 0 ) {
-				title_set_info->title_set[counter +1].size_bup = size;
+                       if ( DVDFileStat(_dvd, counter + 1, DVD_READ_INFO_BACKUP_FILE, &statbuf) != -1) {
+                               title_set_info->title_set[counter + 1].size_bup = statbuf.size;
 			} else {
 				DVDFreeTitleSetInfo(title_set_info);
 				return(0);
@@ -1833,7 +1777,7 @@
 
 }
 
-int DVDMirror(dvd_reader_t * _dvd, char * targetdir,char * title_name) {
+int DVDMirror(dvd_reader_t * _dvd, char * targetdir,char * title_name, read_error_strategy_t errorstrat) {
 
 	int i;
 	title_set_info_t * title_set_info=NULL;
@@ -1845,14 +1789,14 @@
 	}
 
 	if ( DVDMirrorVMG(_dvd, title_set_info, targetdir, title_name) != 0 ) {
-		fprintf(stderr,"Mirror of VMG faild\n");
+		fprintf(stderr,"Mirror of VMG failed\n");
 		DVDFreeTitleSetInfo(title_set_info);
 		return(1);
 	}
 
 	for ( i=0; i < title_set_info->number_of_title_sets; i++) {
-		if ( DVDMirrorTitleX(_dvd, title_set_info, i + 1, targetdir, title_name) != 0 ) {
-			fprintf(stderr,"Mirror of Title set %d faild\n", i + 1);
+		if ( DVDMirrorTitleX(_dvd, title_set_info, i + 1, targetdir, title_name, errorstrat) != 0 ) {
+			fprintf(stderr,"Mirror of Title set %d failed\n", i + 1);
 			DVDFreeTitleSetInfo(title_set_info);
 			return(1);
 		}
@@ -1860,7 +1804,7 @@
 	return(0);
 }
 
-int DVDMirrorTitleSet(dvd_reader_t * _dvd, char * targetdir,char * title_name, int title_set) {
+int DVDMirrorTitleSet(dvd_reader_t * _dvd, char * targetdir,char * title_name, int title_set, read_error_strategy_t errorstrat) {
 
 	title_set_info_t * title_set_info=NULL;
 
@@ -1884,13 +1828,13 @@
 
 	if ( title_set == 0 ) {
 		if ( DVDMirrorVMG(_dvd, title_set_info, targetdir, title_name) != 0 ) {
-			fprintf(stderr,"Mirror of Title set 0 (VMG) faild\n");
+			fprintf(stderr,"Mirror of Title set 0 (VMG) failed\n");
 			DVDFreeTitleSetInfo(title_set_info);
 			return(1);
 		}
 	} else {
-		if ( DVDMirrorTitleX(_dvd, title_set_info, title_set, targetdir, title_name) != 0 ) {
-			fprintf(stderr,"Mirror of Title set %d faild\n", title_set);
+		if ( DVDMirrorTitleX(_dvd, title_set_info, title_set, targetdir, title_name, errorstrat) != 0 ) {
+			fprintf(stderr,"Mirror of Title set %d failed\n", title_set);
 			DVDFreeTitleSetInfo(title_set_info);
 			return(1);
 		}
@@ -1899,7 +1843,7 @@
 	return(0);
 }
 
-int DVDMirrorMainFeature(dvd_reader_t * _dvd, char * targetdir,char * title_name) {
+int DVDMirrorMainFeature(dvd_reader_t * _dvd, char * targetdir,char * title_name, read_error_strategy_t errorstrat) {
 
 	title_set_info_t * title_set_info=NULL;
 	titles_info_t * titles_info=NULL;
@@ -1907,7 +1851,7 @@
 
 	titles_info = DVDGetInfo(_dvd);
 	if (!titles_info) {
-		fprintf(stderr, "Guess work of main feature film faild\n");
+		fprintf(stderr, "Guess work of main feature film failed\n");
 		return(1);
 	}
 
@@ -1917,8 +1861,8 @@
 		return(1);
 	}
 
-	if ( DVDMirrorTitleX(_dvd, title_set_info, titles_info->main_title_set, targetdir, title_name) != 0 ) {
-		fprintf(stderr,"Mirror of main featur file which is title set %d faild\n", titles_info->main_title_set);
+	if ( DVDMirrorTitleX(_dvd, title_set_info, titles_info->main_title_set, targetdir, title_name, errorstrat) != 0 ) {
+		fprintf(stderr,"Mirror of main feature file which is title set %d failed\n", titles_info->main_title_set);
 		DVDFreeTitleSetInfo(title_set_info);
 		return(1);
 	}
@@ -1951,7 +1895,7 @@
 
 	titles_info = DVDGetInfo(_dvd);
 	if (!titles_info) {
-		fprintf(stderr, "Faild to obtain titles information\n");
+		fprintf(stderr, "Failed to obtain titles information\n");
 		return(1);
 	}
 
@@ -1976,7 +1920,7 @@
 
 	vts_ifo_info = ifoOpen(_dvd, titles_info->titles[titles - 1].title_set);
 	if(!vts_ifo_info) {
-		fprintf(stderr, "Coundn't open tile_set %d IFO file\n", titles_info->titles[titles - 1].title_set);
+		fprintf(stderr, "Coundn't open title_set %d IFO file\n", titles_info->titles[titles - 1].title_set);
 		DVDFreeTitlesInfo(titles_info);
 		DVDFreeTitleSetInfo(title_set_info);
 		return(1);
@@ -1986,12 +1930,12 @@
 
 	if (end_chapter > titles_info->titles[titles - 1].chapters) {
 		end_chapter = titles_info->titles[titles - 1].chapters;
-		fprintf(stderr, "Turncated the end_chapter only %d chapters in %d title\n", end_chapter,titles);
+		fprintf(stderr, "Truncated the end_chapter; only %d chapters in %d title\n", end_chapter,titles);
 	}
 
 	if (start_chapter > titles_info->titles[titles - 1].chapters) {
 		start_chapter = titles_info->titles[titles - 1].chapters;
-		fprintf(stderr, "Turncated the end_chapter only %d chapters in %d title\n", end_chapter,titles);
+		fprintf(stderr, "Truncated the end_chapter; only %d chapters in %d title\n", end_chapter,titles);
 	}
 
 
@@ -2118,7 +2062,7 @@
 
 	titles_info = DVDGetInfo(_dvd);
 	if (!titles_info) {
-		fprintf(stderr, "Faild to obtain titles information\n");
+		fprintf(stderr, "Failed to obtain titles information\n");
 		return(1);
 	}
 
@@ -2151,7 +2095,7 @@
 
 	titles_info = DVDGetInfo(_dvd);
 	if (!titles_info) {
-		fprintf(stderr, "Guess work of main feature film faild\n");
+		fprintf(stderr, "Guess work of main feature film failed\n");
 		return(1);
 	}
 
@@ -2164,7 +2108,7 @@
 	DVDGetTitleName(dvd,title_name);
 
 
-	fprintf(stdout,"\n\n\nDVD-Video information of the DVD with tile %s\n\n", title_name);
+	fprintf(stdout,"\n\n\nDVD-Video information of the DVD with title %s\n\n", title_name);
 
 	/* Print file structure */
 
@@ -2218,8 +2162,8 @@
 					}
 				}
 			}
-			fprintf(stdout,"\tThe main feature has a maximum of %d chapter(s) in on of it's titles\n", chapters);
-			fprintf(stdout,"\tThe main feature has a maximum of %d audio channel(s) in on of it's titles\n", channels);
+			fprintf(stdout,"\tThe main feature has a maximum of %d chapter(s) in on of its titles\n", chapters);
+			fprintf(stdout,"\tThe main feature has a maximum of %d audio channel(s) in on of its titles\n", channels);
 			break;
                 }
 
@@ -2248,7 +2192,7 @@
 			if (titles_info->titles[i].title_set == f + 1) {
 				fprintf(stdout,"\t\t\tTitle %d:\n", i + 1);
 				fprintf(stdout,"\t\t\t\tTitle %d has %d chapter(s)\n", i + 1, titles_info->titles[i].chapters);
-				fprintf(stdout,"\t\t\t\tTitle %d has %d audio channle(s)\n", i + 1, titles_info->titles[i].audio_channels);
+				fprintf(stdout,"\t\t\t\tTitle %d has %d audio channel(s)\n", i + 1, titles_info->titles[i].audio_channels);
 			}
 		}
 	}
@@ -2276,6 +2220,8 @@
 	int do_feature = 0;
 	int do_info = 0;
 
+	read_error_strategy_t errorstrat =
+	  STRATEGY_ABORT;
 
 
 	int return_code;
@@ -2290,6 +2236,7 @@
 	char * end_chapter_temp=NULL;
 	char * titles_temp=NULL;
 	char * title_set_temp=NULL;
+	char * errorstrat_temp=NULL;
 
 
 	/* Title of the DVD */
@@ -2311,8 +2258,13 @@
 
 	/*Todo do isdigit check */
 
-	while ((flags = getopt(argc, argv, "MFI?hi:v:a:o:n:s:e:t:T:")) != -1) {
+	while ((flags = getopt(argc, argv, "MFI?hi:v:a:o:n:s:e:t:T:r:")) != -1) {
 		switch (flags) {
+		case 'r':
+			if(optarg[0]=='-') usage();
+			errorstrat_temp=optarg;
+			break;
+
 		case 'i':
       			if(optarg[0]=='-') usage();
       			dvd = optarg;
@@ -2380,6 +2332,17 @@
 		exit(1);
 	}
 
+	if (errorstrat_temp == NULL || errorstrat_temp[0]=='a') {
+		errorstrat=STRATEGY_ABORT;
+	} else if (errorstrat_temp[0]=='b') {
+	  	errorstrat=STRATEGY_SKIP_BLOCK;
+	} else if (errorstrat_temp[0]=='m') {
+	  	errorstrat=STRATEGY_SKIP_MULTIBLOCK;
+	} else {
+	  	usage();
+		exit(1);
+	}
+
 	if(verbose_temp == NULL) {
 		verbose = 0;
 	} else {
@@ -2482,14 +2445,14 @@
 			exit(1);
 		}
 		if (strstr(title_name, "DVD_VIDEO") != NULL) {
-			fprintf(stderr,"The DVD-Video title on the disk is DVD_VIDEO which is to generic please provide a title with the -n switch\n");
+			fprintf(stderr,"The DVD-Video title on the disk is DVD_VIDEO, which is too generic; please provide a title with the -n switch\n");
 			DVDClose(_dvd);
 			exit(2);
 		}
 
 	} else {
 		if (strlen(provided_title_name) > 32) {
-			fprintf(stderr,"The title name specified is longer than 32 charachters, truncating the title name\n");
+			fprintf(stderr,"The title name specified is longer than 32 characters; truncating the title name\n");
 			strncpy(title_name,provided_title_name, 32);
 			title_name[32]='\0';
 		} else {
@@ -2503,11 +2466,11 @@
 
 	if (stat(targetname, &fileinfo) == 0) {
 		if (! S_ISDIR(fileinfo.st_mode)) {
-			fprintf(stderr,"The target directory is not valid, it may be a ordinary file\n");
+			fprintf(stderr,"The target directory is not valid; it may be a ordinary file\n");
 		}
 	} else {
-		if (mkdir(targetname, S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
-			fprintf(stderr,"Faild creating target directory\n");
+		if (mkdir(targetname, 0777) != 0) {
+			fprintf(stderr,"Failed creating target directory\n");
 			perror("");
 			DVDClose(_dvd);
 			exit(-1);
@@ -2519,11 +2482,11 @@
 
 	if (stat(targetname, &fileinfo) == 0) {
 		if (! S_ISDIR(fileinfo.st_mode)) {
-			fprintf(stderr,"The title directory is not valid, it may be a ordinary file\n");
+			fprintf(stderr,"The title directory is not valid; it may be a ordinary file\n");
 		}
 	} else {
-		if (mkdir(targetname, S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
-			fprintf(stderr,"Faild creating title directory\n");
+		if (mkdir(targetname, 0777) != 0) {
+			fprintf(stderr,"Failed creating title directory\n");
 			perror("");
 			DVDClose(_dvd);
 			exit(-1);
@@ -2534,11 +2497,11 @@
 
 	if (stat(targetname, &fileinfo) == 0) {
 		if (! S_ISDIR(fileinfo.st_mode)) {
-			fprintf(stderr,"The VIDEO_TS directory is not valid, it may be a ordinary file\n");
+			fprintf(stderr,"The VIDEO_TS directory is not valid; it may be a ordinary file\n");
 		}
 	} else {
-		if (mkdir(targetname, S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
-			fprintf(stderr,"Faild creating VIDEO_TS directory\n");
+		if (mkdir(targetname, 0777) != 0) {
+			fprintf(stderr,"Failed creating VIDEO_TS directory\n");
 			perror("");
 			DVDClose(_dvd);
 			exit(-1);
@@ -2552,8 +2515,8 @@
 
 
 	if(do_mirror) {
-		if ( DVDMirror(_dvd, targetdir, title_name)  != 0 ) {
-			fprintf(stderr, "Mirror of DVD faild\n");
+		if ( DVDMirror(_dvd, targetdir, title_name, errorstrat)  != 0 ) {
+			fprintf(stderr, "Mirror of DVD failed\n");
 			return_code = -1;
 		} else {
 			return_code = 0;
@@ -2565,8 +2528,8 @@
 
 
 	if (do_title_set) {
-		if (DVDMirrorTitleSet(_dvd, targetdir, title_name, title_set) != 0) {
-			fprintf(stderr, "Mirror of title set %d faild\n", title_set);
+		if (DVDMirrorTitleSet(_dvd, targetdir, title_name, title_set, errorstrat) != 0) {
+			fprintf(stderr, "Mirror of title set %d failed\n", title_set);
 			return_code = -1;
 		} else {
 			return_code  = 0;
@@ -2580,8 +2543,8 @@
 
 
 	if(do_feature) {
-		if ( DVDMirrorMainFeature(_dvd, targetdir, title_name)  != 0 ) {
-			fprintf(stderr, "Mirror of main feature film of DVD faild\n");
+		if ( DVDMirrorMainFeature(_dvd, targetdir, title_name, errorstrat)  != 0 ) {
+			fprintf(stderr, "Mirror of main feature film of DVD failed\n");
 			return_code = -1;
 		} else {
 			return_code = 0;
@@ -2590,7 +2553,7 @@
 
 	if(do_titles) {
 		if (DVDMirrorTitles(_dvd, targetdir, title_name, titles) != 0) {
-			fprintf(stderr, "Mirror of title  %d faild\n", titles);
+			fprintf(stderr, "Mirror of title  %d failed\n", titles);
 			return_code = -1;
 		} else {
 			return_code  = 0;
@@ -2600,7 +2563,7 @@
 
 	if(do_chapter) {
 		if (DVDMirrorChapters(_dvd, targetdir, title_name, start_chapter, end_chapter, titles) != 0) {
-			fprintf(stderr, "Mirror of chapters %d to %d in title %d faild\n", start_chapter, end_chapter, titles);
+			fprintf(stderr, "Mirror of chapters %d to %d in title %d failed\n", start_chapter, end_chapter, titles);
 			return_code = -1;
 		} else {
 			return_code  = 0;
diff -Naur dvdbackup/src/Makefile dvdbackup-p/src/Makefile
--- dvdbackup/src/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ dvdbackup-p/src/Makefile	2007-08-18 15:38:45.000000000 +0200
@@ -0,0 +1,15 @@
+#!/usr/bin/make -f
+
+COPTS = -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
+
+CFLAGS += -Wall $(COPTS)
+
+LDFLAGS += -ldvdread
+
+dvdbackup: dvdbackup.c
+	$(CC) $(CFLAGS) $(COPTS) $(LDFLAGS) -o $@ $<
+
+clean:
+	rm -f dvdbackup
+
+.PHONY: clean dvdbackup
